CYCLUS
agent.h
Go to the documentation of this file.
1 #ifndef CYCLUS_SRC_AGENT_H_
2 #define CYCLUS_SRC_AGENT_H_
3 
4 #include <map>
5 #include <set>
6 #include <string>
7 #include <vector>
8 
9 #include <boost/shared_ptr.hpp>
10 
11 #include "db_init.h"
12 #include "dynamic_module.h"
13 #include "infile_tree.h"
14 #include "exchange_context.h"
15 #include "pyne.h"
16 #include "query_backend.h"
17 #include "resource.h"
18 #include "state_wrangler.h"
19 
20 // Undefines isnan from pyne
21 #ifdef isnan
22  #undef isnan
23 #endif
24 
25 class SimInitTest;
26 
27 namespace cyclus {
28 
29 class Ider {
30  public:
31  virtual const int id() const = 0;
32 };
33 
34 class Material;
35 class Product;
36 
37 /// map<inventory_name, vector<resources_in_inventory> >. Used by agents in
38 /// their #SnapshotInv and #InitInv functions for saving+loading their internal
39 /// resource inventories.
40 typedef std::map<std::string, std::vector<Resource::Ptr> > Inventories;
41 
42 /// The abstract base class used by all types of agents
43 /// that live and interact in a simulation.
44 ///
45 /// There are several functions that must be implemented in support of simulation
46 /// initialization, snapshotting and restart: #InfileToDb,
47 /// InitFrom(QueryableBackend*), #Snapshot, #SnapshotInv, and #InitInv. These
48 /// functions all do inter-related things. Notably, the #InfileToDb, #InitFrom,
49 /// and #Snapshot functions must all write/read to/from the same database tables
50 /// (and table schemas).
51 class Agent : public StateWrangler, virtual public Ider {
52  friend class SimInit;
53  friend class ::SimInitTest;
54 
55  public:
56  /// Creates a new agent that is managed by the given context. Note that the
57  /// context takes ownership of its agents' memory and so agents should
58  /// generally never be created on the stack.
59  Agent(Context* ctx);
60 
61  /// Removes references to self from simulation context, parent, children,
62  /// etc. All subclass destructors should also be virtual.
63  virtual ~Agent();
64 
65  virtual std::string version() { return "unspecified"; }
66 
67  /// Returns a newly created/allocated prototype that is an exact copy of this.
68  /// All initialization and state cloning operations should be done in the
69  /// agent's InitFrom(Agent*) function. The new agent instance should NOT be
70  /// created using a default copy-constructor. New agent instances should
71  /// generally be created using a constructor that takes a single Context
72  /// argument (the same context of the agent being cloned). Example:
73  ///
74  /// @code
75  /// class MyAgentClass : virtual public Agent {
76  /// ...
77  ///
78  /// virtual Agent* Clone() {
79  /// MyAgentClass* m = new MyAgentClass(context());
80  /// m->InitFrom(this);
81  /// return m;
82  /// };
83  ///
84  /// ...
85  /// };
86  /// @endcode
87  virtual Agent* Clone() = 0;
88 
89  /// Translates info for the agent from an input file to the database by
90  /// reading parameters from the passed InfileTree (parsed from xml) and
91  /// recording data via the DbInit variable. The simulation id and agent id
92  /// are automatically injected in all data transfered to the database through
93  /// DbInit. This function must be implemented by all agents. This function must
94  /// call the superclass' InfileToDb function before doing any other work.
95  ///
96  /// Agent parameters in the InfileTree are scoped in the "agent/*/" path.
97  /// The superclass InitFrom expects the scope InfileTree passed to it to be
98  /// unchanged from the agent's InfileTree arg.
99  ///
100  ///
101  /// Example:
102  ///
103  /// @code
104  /// class MyAgentClass : virtual public cyclus::Facility {
105  /// // ...
106  ///
107  /// void InfileToDb(cyclus::InfileTree* tree, cyclus::DbInit di) {
108  /// cyclus::Facility::InitFrom(tree);
109  ///
110  /// // now do MyAgentClass' initialitions, e.g.:
111  /// tree = tree->Query("agent/*"); // rescope the InfileTree
112  ///
113  /// // retrieve all agent params
114  /// std::string recipe = tree->GetString("recipe");
115  /// std::string in_commod = tree->GetString("in_commod");
116  /// double cap = cyclus::Query<double>(tree, "cap");
117  /// di.NewDatum("MyAgentTable1")
118  /// ->AddVal("recipe", recipe)
119  /// ->AddVal("in_commod", in_commod)
120  /// ->AddVal("cap", cap)
121  /// ->Record();
122  /// // ...
123  /// };
124  ///
125  /// // ...
126  /// };
127  /// @endcode
128  ///
129  /// @warning because 'SimId' 'SimTime', and 'AgentId' fields are automatically
130  /// injected, those labels cannot be used for any other fields.
131  ///
132  /// @warning this function MUST NOT modify the agent's state.
133  virtual void InfileToDb(InfileTree* qe, DbInit di);
134 
135  /// Intializes an agent's internal state from the database. Appropriate
136  /// simulation id, agent id, and time filters are automatically included in
137  /// all queries. If the agent is a direct subclass of the Agent class, than
138  /// it should NOT call its superclass' InitFrom(QueryableBackend*) function.
139  /// If, however, it is a subclasses other Agent subclasses (e.g. subclass of
140  /// Facility, Region, etc.), then it MUST call its superclass'
141  /// InitFrom(QueryableBackend*) function. Example:
142  ///
143  /// @code
144  /// class MyAgentClass : virtual public cyclus::Facility {
145  /// // ...
146  ///
147  /// void InitFrom(cyclus::QueryableBackend* b) {
148  /// cyclus::Facility::InitFrom(b);
149  ///
150  /// cyclus::QueryResult qr = b->Query("MyAgentTable1", NULL);
151  /// recipe = qr.GetVal<std::string>("recipe");
152  /// in_commod = qr.GetVal<std::string>("in_commod");
153  /// cap = qr.GetVal<double>("cap");
154  ///
155  /// // ...
156  /// };
157  ///
158  /// std::string recipe;
159  /// std::string in_commod;
160  /// double cap;
161  ///
162  /// // ...
163  /// };
164  ///
165  /// @endcode
166  ///
167  /// @warning Agents should NOT create any resource objects in this function.
168  virtual void InitFrom(QueryableBackend* b);
169 
170  /// Snapshots agent-internal state to the database via the DbInit var di. The
171  /// simulation id , agent id, and the simulation time are automatically
172  /// injected in all information transfered to the database through DbInit.
173  /// If the agent is a direct subclass of the Agent class, than it should NOT
174  /// call its superclass' Snapshot function. If, however, it subclasses
175  /// other Agent subclasses (e.g. subclass of Facility, Region, etc.), then it
176  /// MUST call its superclass' Snapshot function. Example:
177  ///
178  /// @code
179  /// class MyAgentClass : virtual public cyclus::Facility {
180  /// // ...
181  ///
182  /// void Snapshot(cyclus::DbInit di) {
183  /// cyclus::Facility::Snapshot(di);
184  ///
185  /// di.NewDatum("MyAgentTable1")
186  /// ->AddVal("recipe", recipe)
187  /// ->AddVal("in_commod", in_commod)
188  /// ->AddVal("cap", cap)
189  /// ->Record();
190  ///
191  /// // ...
192  /// };
193  ///
194  /// std::string recipe;
195  /// std::string in_commod;
196  /// double cap;
197  ///
198  /// // ...
199  /// };
200  ///
201  /// @endcode
202  ///
203  /// @warning because 'SimId' 'SimTime', and 'AgentId' fields are automatically
204  /// injected, those labels cannot be used for any other fields.
205  ///
206  /// @warning This function MUST NOT modify the agent's internal state.
207  /// @warning Do not record any information via the context's NewDatum
208  /// function.
209  virtual void Snapshot(DbInit di) = 0;
210 
211  /// Provides an agent's initial inventory of resources before a simulation
212  /// begins. The resources are keyed in the same way as given in the agent's
213  /// SnapshotInv function. Agents should iterate through each named inventory
214  /// provided and populate their corresponding resource containers with the
215  /// given resources.
216  ///
217  /// @code
218  /// class MyAgentClass : virtual public cyclus::Facility {
219  /// // ...
220  ///
221  /// void InitInv(cyclus::Inventories& inv) {
222  /// buf1.Push(inv["buf1"]);
223  /// buf2.Push(inv["buf2"]);
224  ///
225  /// // ...
226  /// };
227  ///
228  /// cyclus::toolkit::ResBuf<Material> buf1;
229  /// cyclus::toolkit::ResBuf<Material> buf2;
230  ///
231  /// // ...
232  /// };
233  ///
234  /// @endcode
235  ///
236  /// @warning agents should not modify any state outside the container filling
237  virtual void InitInv(Inventories& inv) = 0;
238 
239  /// Snapshots an agent's resource inventories to the database. The set of
240  /// resources in each container should be stored under a string key unique
241  /// for that container that will be used when re-initializing inventories for
242  /// restarted simulations in the InitInv function.
243  ///
244  /// @code
245  /// class MyAgentClass : virtual public cyclus::Facility {
246  /// // ...
247  ///
248  /// cyclus::Inventories SnapshotInv() {
249  /// cyclus::Inventories invs;
250  /// cyclus::toolkit::ResVec rs = buf1.PopNRes(buf1.count());
251  /// buf1.Push(rs); // Snapshot must not change agent's state
252  /// invs["buf1"] = rs;
253  /// rs = buf2.PopNRes(buf2.count());
254  /// buf2.Push(rs); // Snapshot must not change agent's state
255  /// invs["buf2"] = rs;
256  ///
257  /// // ...
258  ///
259  /// return invs;
260  /// };
261  ///
262  /// cyclus::toolkit::ResBuf<Material> buf1;
263  /// cyclus::toolkit::ResBuf<Material> buf2;
264  ///
265  /// // ...
266  /// };
267  ///
268  /// @endcode
269  ///
270  /// @warning This function MUST NOT modify the agent's internal state.
271  virtual Inventories SnapshotInv() = 0;
272 
273  /// recursively prints the parent-child tree
274  std::string PrintChildren();
275 
276  /// returns a vector of strings representing the parent-child tree
277  /// at the node for Agent m
278  /// @param m the agent node to base as the root of this print tree
279  std::vector<std::string> GetTreePrintOuts(Agent* m);
280 
281  /// returns true if this agent is in the parent-child family tree of an other
282  /// agent
283  /// @param other the other agent
284  bool InFamilyTree(Agent* other);
285 
286  /// returns true if this agent is an ancestor of an other agent (i.e., resides
287  /// above an other agent in the family tree)
288  /// @param other the other agent
289  bool AncestorOf(Agent* other);
290 
291  /// returns true if this agent is an decendent of an other agent (i.e., resides
292  /// below an other agent in the family tree)
293  /// @param other the other agent
294  bool DecendentOf(Agent* other);
295 
296  /// Called when the agent enters the smiulation as an active participant and
297  /// is only ever called once. Agents should NOT register for services (such
298  /// as ticks/tocks and resource exchange) in this function. If agents implement
299  /// this function, they must call their superclass' Build function at the
300  /// BEGINING of their Build function.
301  ///
302  /// @param parent this agent's parent. NULL if this agent has no parent.
303  virtual void Build(Agent* parent);
304 
305  /// Called to give the agent an opportunity to register for services (e.g.
306  /// ticks/tocks and resource exchange). Note that this may be called more
307  /// than once, and so agents should track their registrations carefully. If
308  /// agents implement this function, they must call their superclass's
309  /// EnterNotify function at the BEGINNING of their EnterNotify function.
310  virtual void EnterNotify();
311 
312  /// Called when a new child of this agent has just been built. It is possible
313  /// for this function to be called before the simulation has started when
314  /// initially existing agents are being setup.
315  virtual void BuildNotify(Agent* m) {}
316 
317  /// Called when a child of this agent is about to be decommissioned.
318  virtual void DecomNotify(Agent* m) {}
319 
320  /// Decommissions the agent, removing it from the simulation. Results in
321  /// destruction of the agent object. If agents write their own Decommission
322  /// function, they must call their superclass' Decommission function at the END of
323  /// their Decommission function.
324  virtual void Decommission();
325 
326  /// default implementation for material preferences.
327  virtual void AdjustMatlPrefs(PrefMap<Material>::type& prefs) {}
328 
329  /// default implementation for material preferences.
331 
332  /// Returns an agent's xml rng schema for initializing from input files. All
333  /// concrete agents should override this function. This must validate the same
334  /// xml input that the InfileToDb function receives.
335  virtual std::string schema() {
336  return "<text />\n";
337  }
338 
339  /// Returns an agent's json annotations for all state variables and any other
340  /// information the developer wishes to provide. All concrete agents should
341  /// override this function.
344  }
345 
346  /// Returns the agent's prototype.
347  inline const std::string prototype() const { return prototype_; }
348 
349  /// Sets the agent's prototype. This should generally NEVER be called
350  /// explicitly by code outside the cyclus kernel.
351  inline void prototype(std::string p) { prototype_ = p; }
352 
353  /// The agent instance's unique ID within a simulation.
354  virtual const int id() const { return id_; }
355 
356  /// The string representation of the agent spec that uniquely identifies the
357  /// concrete agent class/module. See CEP21 for details..
358  inline std::string spec() { return spec_; }
359 
360  /// Sets this agent's agent spec. This should generally NEVER be called
361  /// explicitly by code outside the cyclus kernel.
362  inline void spec(std::string new_impl) { spec_ = new_impl; }
363 
364  /// Returns a string that describes the agent subclass (e.g. Region,
365  /// Facility, etc.)
366  inline const std::string kind() const { return kind_; }
367 
368  /// Returns this agent's simulation context.
369  inline Context* context() const { return ctx_; }
370 
371  /// Description of this agent.
372  virtual std::string str();
373 
374  /// Returns parent of this agent. Returns NULL if the agent has no parent.
375  inline Agent* parent() const { return parent_; }
376 
377  /// Returns the id for this agent's parent. Returns -1 if this agent has no
378  /// parent.
379  inline const int parent_id() const { return parent_id_; }
380 
381  /// Returns the time step at which this agent's Build function was called (-1 if
382  /// the agent has never been built).
383  inline const int enter_time() const { return enter_time_; }
384 
385  ///Sets the number of time steps this agent operates between building and
386  /// decommissioning (-1 if the agent has an infinite lifetime). This should
387  /// generally only be called BEFORE an agent is added to a context as a
388  /// prototype. Throws ValueError if the agent has already been deployed.
389  void lifetime(int n_timesteps);
390 
391  /// Sets the number of time steps this agent operates between building and
392  /// decommissioning (-1 if the agent has an infinite lifetime).
393  void lifetime_force(int n_timesteps);
394 
395  /// Returns the number of time steps this agent operates between building and
396  /// decommissioning (-1 if the agent has an infinite lifetime).
397  inline const int lifetime() const { return lifetime_; }
398 
399  /// Returns the default time step at which this agent will exit the
400  /// simulation (-1 if the agent has an infinite lifetime).
401  ///
402  /// Deomissioning happens at the end of a time step. With a lifetime of 1, we
403  /// expect an agent to go through only 1 entire time step. In this case, the
404  /// agent should be decommissioned on the same time step it was
405  /// created. Therefore, for agents with non-infinite lifetimes, the exit_time
406  /// will be the enter time plus its lifetime less 1.
407  inline const int exit_time() const {
408  if (lifetime() == -1)
409  return -1;
410  return enter_time_ + lifetime_ - 1;
411  }
412 
413  /// Returns a list of children this agent has
414  inline const std::set<Agent*>& children() const { return children_; }
415 
416  protected:
417  /// Initializes a agent by copying parameters from the passed agent m. This
418  /// function must be implemented by all agents. This function must call the
419  /// superclass' InitFrom function. The InitFrom function should only initialize
420  /// this class' members - not inherited state. The superclass InitFrom should
421  /// generally be called before any other work is done.
422  ///
423  /// @param m the agent containing state that should be used to initialize this
424  /// agent.
425  ///
426  /// Example:
427  ///
428  /// @code
429  /// class MyAgentClass : virtual public cyclus::Facility {
430  /// // ...
431  ///
432  /// void InitFrom(MyAgentClass* m) {
433  /// cyclus::Facility::InitFrom(m); // call superclass' InitFrom
434  /// // now do MyAgentClass' initialitions, e.g.:
435  /// my_var_ = m->my_var_;
436  /// // ...
437  /// };
438  ///
439  /// // ...
440  /// };
441  /// @endcode
442  void InitFrom(Agent* m);
443 
444  /// adds agent-specific information prefix to an error message
445  virtual std::string InformErrorMsg(std::string msg);
446 
447  /// describes the agent subclass (e.g. Region, Inst, etc.). The in-kernel
448  /// subclasses must set this variable in their constructor(s).
450 
451  private:
452  /// length of time this agent is intended to operate
453  int lifetime_;
454 
455  /// Prevents creation/use of copy constructors (including in subclasses).
456  /// Cloning and InitFrom should be used instead.
457  Agent(const Agent& m) {}
458 
459  /// adds an agent to the transaction table
460  void AddToTable();
461 
462  /// connects an agent to its parent.
463  void Connect(Agent* parent);
464 
465  /// Stores the next available facility ID
466  static int next_id_;
467 
468  /// children of this agent
469  std::set<Agent*> children_;
470 
471  /// parent of this agent
472  Agent* parent_;
473 
474  /// parent's ID of this agent
475  /// Note: we keep the parent id in the agent so we can reference it
476  /// even if the parent is deallocated.
477  int parent_id_;
478 
479  /// born on date of this agent
480  int enter_time_;
481 
482  std::string prototype_;
483 
484  /// concrete type of a agent (e.g. "MyReactorAgent")
485  std::string spec_;
486 
487  /// an instance-unique ID for the agent
488  int id_;
489 
490  Context* ctx_;
491 };
492 
493 } // namespace cyclus
494 
495 #endif // CYCLUS_SRC_AGENT_H_
An abjstract interface that must be implemented by all simulation agents and all agent member variabl...
virtual std::string version()
Definition: agent.h:65
const int enter_time() const
Returns the time step at which this agent&#39;s Build function was called (-1 if the agent has never been...
Definition: agent.h:383
double b(int nuc)
Computes the scattering length [cm] from the coherent and incoherent components.
Definition: pyne.cc:11180
const int exit_time() const
Returns the default time step at which this agent will exit the simulation (-1 if the agent has an in...
Definition: agent.h:407
const std::string prototype() const
Returns the agent&#39;s prototype.
Definition: agent.h:347
A class for extracting information from a given XML parser.
Definition: infile_tree.h:22
virtual const int id() const
The agent instance&#39;s unique ID within a simulation.
Definition: agent.h:354
Represents a JSON value.
Definition: pyne.h:3224
virtual void BuildNotify(Agent *m)
Called when a new child of this agent has just been built.
Definition: agent.h:315
virtual void DecomNotify(Agent *m)
Called when a child of this agent is about to be decommissioned.
Definition: agent.h:318
virtual std::string schema()
Returns an agent&#39;s xml rng schema for initializing from input files.
Definition: agent.h:335
std::map< std::string, std::vector< Resource::Ptr > > Inventories
map<inventory_name, vector<resources_in_inventory> >.
Definition: agent.h:35
A Product is a general type of resource in the Cyclus simulation, and is a catch-all for non-standard...
Definition: product.h:18
std::map< Request< T > *, std::map< Bid< T > *, double > > type
std::string spec()
The string representation of the agent spec that uniquely identifies the concrete agent class/module...
Definition: agent.h:358
object value (collection of name/value pairs).
Definition: pyne.h:3145
virtual const int id() const =0
const std::string kind() const
Returns a string that describes the agent subclass (e.g.
Definition: agent.h:366
int parent(int nuc, unsigned int rx, std::string z="n")
Definition: pyne.cc:6621
Context * context() const
Returns this agent&#39;s simulation context.
Definition: agent.h:369
std::string kind_
describes the agent subclass (e.g.
Definition: agent.h:449
virtual Json::Value annotations()
Returns an agent&#39;s json annotations for all state variables and any other information the developer w...
Definition: agent.h:342
virtual void AdjustProductPrefs(PrefMap< Product >::type &prefs)
default implementation for material preferences.
Definition: agent.h:330
DbInit provides an interface for agents to record data to the output db that automatically injects th...
Definition: db_init.h:14
void prototype(std::string p)
Sets the agent&#39;s prototype.
Definition: agent.h:351
Agent * parent() const
Returns parent of this agent. Returns NULL if the agent has no parent.
Definition: agent.h:375
const int lifetime() const
Returns the number of time steps this agent operates between building and decommissioning (-1 if the ...
Definition: agent.h:397
A simulation context provides access to necessary simulation-global functions and state...
Definition: context.h:130
The abstract base class used by all types of agents that live and interact in a simulation.
Definition: agent.h:51
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or.org/Osi/browser/trunk.
Definition: agent.cc:14
The material class is primarily responsible for enabling basic material manipulation while helping en...
Definition: material.h:71
Handles initialization of a simulation from the output database.
Definition: sim_init.h:24
virtual void AdjustMatlPrefs(PrefMap< Material >::type &prefs)
default implementation for material preferences.
Definition: agent.h:327
const int parent_id() const
Returns the id for this agent&#39;s parent.
Definition: agent.h:379
const std::set< Agent * > & children() const
Returns a list of children this agent has.
Definition: agent.h:414
Interface implemented by backends that support rudimentary querying.
void spec(std::string new_impl)
Sets this agent&#39;s agent spec.
Definition: agent.h:362