CYCLUS
context.h
Go to the documentation of this file.
1 #ifndef CYCLUS_SRC_CONTEXT_H_
2 #define CYCLUS_SRC_CONTEXT_H_
3 
4 #include <map>
5 #include <set>
6 #include <string>
7 #include <stdint.h>
8 
9 #ifndef CYCPP
10 // The cyclus preprocessor cannot handle this file since there are two
11 // unmatch open braces '{' inside of strings that don't have cooresponding
12 // closed braces '}'
13 #include <boost/uuid/uuid_generators.hpp>
14 #endif
15 
16 #include "composition.h"
17 #include "agent.h"
18 #include "greedy_solver.h"
19 #include "pyhooks.h"
20 #include "recorder.h"
21 
22 const uint64_t kDefaultTimeStepDur = 2629846;
23 
24 class SimInitTest;
25 
26 namespace cyclus {
27 
28 class Datum;
29 class ExchangeSolver;
30 class Recorder;
31 class Trader;
32 class Timer;
33 class TimeListener;
34 class SimInit;
35 class DynamicModule;
36 
37 /// Container for a static simulation-global parameters that both describe
38 /// the simulation and affect its behavior.
39 class SimInfo {
40  public:
41  /// @brief constructs a SimInfo instance with default variables
42  /// @return a SimInfo instance
43  SimInfo();
44 
45  /// @brief constructs a SimInfo instance using some default variables
46  /// @param dur simulation duration in number of timesteps
47  /// @param y0 start year for the simulation
48  /// @param m0 start month for the simulation
49  /// @param handle is this simulation's unique simulation handle
50  /// @return a SimInfo instance
51  SimInfo(int dur, int y0 = 2010, int m0 = 1,
52  std::string handle = "");
53 
54  /// @brief constructs a SimInfo instance using no default variables
55  /// @param dur simulation duration in number of timesteps
56  /// @param y0 start year for the simulation
57  /// @param m0 start month for the simulation
58  /// @param handle is this simulation's unique simulation handle
59  /// @param d the decay data member, "never" for no decay. "manual" otherwise
60  /// @return a SimInfo instance
61  SimInfo(int dur, int y0, int m0,
63 
64  /// @brief constructs a SimInfo instance
65  /// @param dur simulation duration in number of timesteps
66  /// @param parent_sim the uuid of the parent simulation
67  /// @param branch_time
68  /// @param parent_type a string indicating the type of the parent simulation
69  /// @param handle is this simulation's unique simulation handle
70  /// @return a SimInfo instance
71  SimInfo(int dur, boost::uuids::uuid parent_sim,
73  std::string handle = "");
74 
75  /// user-defined label associated with a particular simulation
77 
78  /// "manual" if use of the decay function is allowed, "never" otherwise
80 
81  /// length of the simulation in timesteps (months)
82  int duration;
83 
84  /// start year for the simulation (e.g. 1973);
85  int y0;
86 
87  /// start month for the simulation: Jan = 1, ..., Dec = 12
88  int m0;
89 
90  /// id for the parent simulation if any
91  boost::uuids::uuid parent_sim;
92 
93  /// One of "init", "branch", "restart" indicating the relationship of this
94  /// simulation to its parent simulation.
96 
97  /// timestep at which simulation branching occurs if any
99 
100  /// Duration in seconds of a single time step in the simulation.
101  uint64_t dt;
102 
103  /// Epsilon in the simulation.
104  double eps;
105 
106  /// Epsilon for resources in the simulation.
107  double eps_rsrc;
108 
109  /// True if per-agent inventories should be explicitly queried/recorded
110  /// every time step in a table (i.e. agent ID, Time, Nuclide, Quantity).
112 
113  /// True if per-agent inventories should be explicitly queried/recorded
114  /// every time step in a table (i.e. agent ID, Time, Quantity,
115  /// Composition-object and/or reference).
117 };
118 
119 /// A simulation context provides access to necessary simulation-global
120 /// functions and state. All code that writes to the output database, needs to
121 /// know simulation time, creates/builds facilities, and/or uses loaded
122 /// composition recipes will need a context pointer. In general, all global
123 /// state should be accessed through a simulation context.
124 ///
125 /// @warning the context takes ownership of and manages the lifetime/destruction
126 /// of all agents constructed with it (including Cloned agents). Agents should
127 /// generally NEVER be allocated on the stack.
128 /// @warning the context takes ownership of the solver and will manage its
129 /// destruction.
130 class Context {
131  public:
132  friend class ::SimInitTest;
133  friend class SimInit;
134  friend class Agent;
135  friend class Timer;
136 
137  /// Creates a new context working with the specified timer and datum manager.
138  /// The timer does not have to be initialized (yet).
139  Context(Timer* ti, Recorder* rec);
140 
141  /// Clean up resources including destructing the solver and all agents the
142  /// context is aware of.
143  ~Context();
144 
145  /// See Recorder::sim_id documentation.
146  boost::uuids::uuid sim_id();
147 
148  /// Adds a prototype to a simulation-wide accessible list, a prototype **can
149  /// not** be added more than once.
150  /// @param name the prototype name
151  /// @param m a pointer to the agent prototype
152  /// @param overwrite, allow overwrites to the prototype listing, default: false
153  /// @throws if overwrite is false and a prototype name has already been added
154  /// @{
155  void AddPrototype(std::string name, Agent* m);
156  void AddPrototype(std::string name, Agent* m, bool overwrite);
157  /// @}
158 
159  /// Registers an agent as a participant in resource exchanges. Agents should
160  /// register from their Deploy method.
161  inline void RegisterTrader(Trader* e) {
162  traders_.insert(e);
163  }
164 
165  /// Unregisters an agent as a participant in resource exchanges.
166  inline void UnregisterTrader(Trader* e) {
167  traders_.erase(e);
168  }
169 
170  /// @return the current set of traders registered for resource exchange.
171  inline const std::set<Trader*>& traders() const {
172  return traders_;
173  }
174 
175  /// Create a new agent by cloning the named prototype. The returned agent is
176  /// not initialized as a simulation participant.
177  ///
178  /// @warning this method should generally NOT be used by agents.
179  template <class T>
180  T* CreateAgent(std::string proto_name) {
181  if (protos_.count(proto_name) == 0) {
182  throw KeyError("Invalid prototype name " + proto_name);
183  }
184 
185  Agent* m = protos_[proto_name];
186  T* casted(NULL);
187  Agent* clone = m->Clone();
188  casted = dynamic_cast<T*>(clone);
189  if (casted == NULL) {
190  PyDelAgent(clone->id());
191  DelAgent(clone);
192  throw CastError("Invalid cast for prototype " + proto_name);
193  }
194  return casted;
195  }
196 
197  /// Destructs and cleans up m (and it's children recursively).
198  ///
199  /// @warning this method should generally NOT be used by agents.
200  void DelAgent(Agent* m);
201 
202  /// Schedules the named prototype to be built for the specified parent at
203  /// timestep t. The default t=-1 results in the build being scheduled for the
204  /// next build phase (i.e. the start of the next timestep).
205  void SchedBuild(Agent* parent, std::string proto_name, int t = -1);
206 
207  /// Schedules the given Agent to be decommissioned at the specified timestep
208  /// t. The default t=-1 results in the decommission being scheduled for the
209  /// next decommission phase (i.e. the end of the current timestep).
210  void SchedDecom(Agent* m, int time = -1);
211 
212  /// Adds a composition recipe to a simulation-wide accessible list.
213  /// Agents should NOT add their own recipes.
214  void AddRecipe(std::string name, Composition::Ptr c);
215 
216  /// Retrieve a registered recipe. This is intended for retrieving
217  /// compositions loaded from an input file(s) at the start of a
218  /// simulation and NOT for communicating compositions between facilities
219  /// during the simulation.
220  Composition::Ptr GetRecipe(std::string name);
221 
222  /// Registers an agent to receive tick/tock notifications every timestep.
223  /// Agents should register from their Deploy method.
224  void RegisterTimeListener(TimeListener* tl);
225 
226  /// Removes an agent from receiving tick/tock notifications.
227  /// Agents should unregister from their Decommission method.
228  void UnregisterTimeListener(TimeListener* tl);
229 
230  /// Initializes the simulation time parameters. Should only be called once -
231  /// NOT idempotent.
232  void InitSim(SimInfo si);
233 
234  /// Returns the current simulation timestep.
235  virtual int time();
236 
237  /// Returns the duration of a single time step in seconds.
238  inline uint64_t dt() {return si_.dt;};
239 
240  /// Return static simulation info.
241  inline SimInfo sim_info() const {
242  return si_;
243  }
244 
245  /// See Recorder::NewDatum documentation.
246  Datum* NewDatum(std::string title);
247 
248  /// Schedules a snapshot of simulation state to output database to occur at
249  /// the beginning of the next timestep.
250  void Snapshot();
251 
252  /// Schedules the simulation to be terminated at the end of this timestep.
253  void KillSim();
254 
255  /// @return the next transaction id
256  inline int NextTransactionID() {
257  return trans_id_++;
258  }
259 
260  /// Returns the exchange solver associated with this context
262  if (solver_ == NULL) {
263  solver_ = new GreedySolver(false, NULL);
264  }
265  return solver_;
266  }
267 
268  /// sets the solver associated with this context
269  void solver(ExchangeSolver* solver) {
270  solver_ = solver;
271  solver_->sim_ctx(this);
272  }
273 
274  /// @return the number of agents of a given prototype currently in the
275  /// simulation
276  inline int n_prototypes(std::string type) {
277  return n_prototypes_[type];
278  }
279 
280  /// @return the number of agents of a given implementation currently in the
281  /// simulation
282  inline int n_specs(std::string impl) {
283  return n_specs_[impl];
284  }
285 
286  private:
287  /// Registers an agent as a participant in the simulation.
288  inline void RegisterAgent(Agent* a) {
289  n_prototypes_[a->prototype()]++;
290  n_specs_[a->spec()]++;
291  }
292 
293  /// Unregisters an agent as a participant in the simulation.
294  inline void UnregisterAgent(Agent* a) {
295  n_prototypes_[a->prototype()]--;
296  n_specs_[a->spec()]--;
297  }
298 
299  /// contains archetype specs of all agents for which version have already
300  /// been recorded in the db
301  std::set<std::string> rec_ver_;
302 
303  std::map<std::string, Agent*> protos_;
304  std::map<std::string, Composition::Ptr> recipes_;
305  std::set<Agent*> agent_list_;
306  std::set<Trader*> traders_;
307  std::map<std::string, int> n_prototypes_;
308  std::map<std::string, int> n_specs_;
309 
310  SimInfo si_;
311  Timer* ti_;
312  ExchangeSolver* solver_;
313  Recorder* rec_;
314  int trans_id_;
315 };
316 
317 } // namespace cyclus
318 
319 #endif // CYCLUS_SRC_CONTEXT_H_
const std::set< Trader * > & traders() const
Definition: context.h:171
int n_prototypes(std::string type)
Definition: context.h:276
SimInfo sim_info() const
Return static simulation info.
Definition: context.h:241
void RegisterTrader(Trader *e)
Registers an agent as a participant in resource exchanges.
Definition: context.h:161
boost::shared_ptr< Composition > Ptr
Definition: composition.h:43
std::string handle
user-defined label associated with a particular simulation
Definition: context.h:76
const std::string prototype() const
Returns the agent&#39;s prototype.
Definition: agent.h:347
int branch_time
timestep at which simulation branching occurs if any
Definition: context.h:98
double eps
Epsilon in the simulation.
Definition: context.h:104
virtual const int id() const
The agent instance&#39;s unique ID within a simulation.
Definition: agent.h:354
std::string name(int nuc)
Definition: pyne.cc:2940
int duration
length of the simulation in timesteps (months)
Definition: context.h:82
A simple API for agents that wish to exchange resources in the simulation.
Definition: trader.h:24
int y0
start year for the simulation (e.g. 1973);
Definition: context.h:85
For failed casts that shouldn&#39;t.
Definition: error.h:65
bool explicit_inventory
True if per-agent inventories should be explicitly queried/recorded every time step in a table (i...
Definition: context.h:111
void sim_ctx(Context *c)
simulation context get/set
std::string spec()
The string representation of the agent spec that uniquely identifies the concrete agent class/module...
Definition: agent.h:358
void solver(ExchangeSolver *solver)
sets the solver associated with this context
Definition: context.h:269
uint64_t dt
Duration in seconds of a single time step in the simulation.
Definition: context.h:101
Used to specify and send a collection of key-value pairs to the Recorder for recording.
Definition: datum.h:15
const uint64_t kDefaultTimeStepDur
Definition: context.h:22
void UnregisterTrader(Trader *e)
Unregisters an agent as a participant in resource exchanges.
Definition: context.h:166
int parent(int nuc, unsigned int rx, std::string z="n")
Definition: pyne.cc:6621
boost::uuids::uuid parent_sim
id for the parent simulation if any
Definition: context.h:91
T * CreateAgent(std::string proto_name)
Create a new agent by cloning the named prototype.
Definition: context.h:180
std::string decay
"manual" if use of the decay function is allowed, "never" otherwise
Definition: context.h:79
double eps_rsrc
Epsilon for resources in the simulation.
Definition: context.h:107
int NextTransactionID()
Definition: context.h:256
int n_specs(std::string impl)
Definition: context.h:282
int m0
start month for the simulation: Jan = 1, ..., Dec = 12
Definition: context.h:88
SimInfo()
constructs a SimInfo instance with default variables
Definition: context.cc:19
Collects and manages output data generation for the cyclus core and agents during a simulation...
Definition: recorder.h:45
std::string parent_type
One of "init", "branch", "restart" indicating the relationship of this simulation to its parent simul...
Definition: context.h:95
uint64_t dt()
Returns the duration of a single time step in seconds.
Definition: context.h:238
The TimeListener class is an inheritable class for any Agent that requires knowlege of ticks and tock...
Definition: time_listener.h:23
virtual Agent * Clone()=0
Returns a newly created/allocated prototype that is an exact copy of this.
Container for a static simulation-global parameters that both describe the simulation and affect its ...
Definition: context.h:39
A simulation context provides access to necessary simulation-global functions and state...
Definition: context.h:130
bool explicit_inventory_compact
True if per-agent inventories should be explicitly queried/recorded every time step in a table (i...
Definition: context.h:116
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
a very simple interface for solving translated resource exchanges
void PyDelAgent(int i)
Removes a single Python agent from the reference cache.
Definition: pyhooks.cc:129
Handles initialization of a simulation from the output database.
Definition: sim_init.h:24
ExchangeSolver * solver()
Returns the exchange solver associated with this context.
Definition: context.h:261
For failed retrieval/insertion of key-based data into/from data structures.
Definition: error.h:47
The GreedySolver provides the implementation for a "greedy" solution to a resource exchange graph...
Definition: greedy_solver.h:63
Controls simulation timestepping and inter-timestep phases.
Definition: timer.h:22