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