CYCLUS
timer.cc
Go to the documentation of this file.
1 // Implements the Timer class
2 #include "timer.h"
3 
4 #include <iostream>
5 #include <string>
6 
7 #include "agent.h"
8 #include "error.h"
9 #include "logger.h"
10 #include "sim_init.h"
11 
12 namespace cyclus {
13 
14 void Timer::RunSim() {
15  CLOG(LEV_INFO1) << "Simulation set to run from start="
16  << 0 << " to end=" << si_.duration;
17  CLOG(LEV_INFO1) << "Beginning simulation";
18 
19  ExchangeManager<Material> matl_manager(ctx_);
20  ExchangeManager<Product> genrsrc_manager(ctx_);
21  while (time_ < si_.duration) {
22  CLOG(LEV_INFO1) << "Current time: " << time_;
23 
24  if (want_snapshot_) {
25  want_snapshot_ = false;
26  SimInit::Snapshot(ctx_);
27  }
28 
29  // run through phases
30  DoBuild();
31  CLOG(LEV_INFO2) << "Beginning Tick for time: " << time_;
32  DoTick();
33  CLOG(LEV_INFO2) << "Beginning DRE for time: " << time_;
34  DoResEx(&matl_manager, &genrsrc_manager);
35  CLOG(LEV_INFO2) << "Beginning Tock for time: " << time_;
36  DoTock();
37  DoDecom();
38 
39  time_++;
40 
41  if (want_kill_) {
42  break;
43  }
44  }
45 
46  ctx_->NewDatum("Finish")
47  ->AddVal("EarlyTerm", want_kill_)
48  ->AddVal("EndTime", time_-1)
49  ->Record();
50 
51  SimInit::Snapshot(ctx_); // always do a snapshot at the end of every simulation
52 }
53 
54 void Timer::DoBuild() {
55  // build queued agents
56  std::vector<std::pair<std::string, Agent*> > build_list = build_queue_[time_];
57  for (int i = 0; i < build_list.size(); ++i) {
58  Agent* m = ctx_->CreateAgent<Agent>(build_list[i].first);
59  Agent* parent = build_list[i].second;
60  CLOG(LEV_INFO3) << "Building a " << build_list[i].first
61  << " from parent " << build_list[i].second;
62  m->Build(parent);
63  if (parent != NULL) {
64  parent->BuildNotify(m);
65  } else {
66  CLOG(LEV_DEBUG1) << "Hey! Listen! Built an Agent without a Parent.";
67  }
68  }
69 }
70 
71 void Timer::DoTick() {
72  for (std::map<int, TimeListener*>::iterator agent = tickers_.begin();
73  agent != tickers_.end();
74  agent++) {
75  agent->second->Tick();
76  }
77 }
78 
79 void Timer::DoResEx(ExchangeManager<Material>* matmgr,
80  ExchangeManager<Product>* genmgr) {
81  matmgr->Execute();
82  genmgr->Execute();
83 }
84 
85 void Timer::DoTock() {
86  for (std::map<int, TimeListener*>::iterator agent = tickers_.begin();
87  agent != tickers_.end();
88  agent++) {
89  agent->second->Tock();
90  }
91 
93  std::set<Agent*> ags = ctx_->agent_list_;
94  std::set<Agent*>::iterator it;
95  for (it = ags.begin(); it != ags.end(); ++it) {
96  Agent* a = *it;
97  if (a->enter_time() == -1) {
98  continue; // skip agents that aren't alive
99  }
100  RecordInventories(a);
101  }
102  }
103 }
104 
105 
106 void Timer::RecordInventories(Agent* a) {
107  Inventories invs = a->SnapshotInv();
108  Inventories::iterator it2;
109  for (it2 = invs.begin(); it2 != invs.end(); ++it2) {
110  std::string name = it2->first;
111  std::vector<Resource::Ptr> mats = it2->second;
112  if (mats.empty() || ResCast<Material>(mats[0]) == NULL) {
113  continue; // skip non-material inventories
114  }
115 
116  Material::Ptr m = ResCast<Material>(mats[0]->Clone());
117  for (int i = 1; i < mats.size(); i++) {
118  m->Absorb(ResCast<Material>(mats[i]->Clone()));
119  }
120  RecordInventory(a, name, m);
121  }
122 }
123 
124 void Timer::RecordInventory(Agent* a, std::string name, Material::Ptr m) {
125  if (si_.explicit_inventory) {
126  CompMap c = m->comp()->mass();
127  compmath::Normalize(&c, m->quantity());
128  CompMap::iterator it;
129  for (it = c.begin(); it != c.end(); ++it) {
130  ctx_->NewDatum("ExplicitInventory")
131  ->AddVal("AgentId", a->id())
132  ->AddVal("Time", time_)
133  ->AddVal("InventoryName", name)
134  ->AddVal("NucId", it->first)
135  ->AddVal("Quantity", it->second)
136  ->Record();
137  }
138  }
139 
140  if (si_.explicit_inventory_compact) {
141  CompMap c = m->comp()->mass();
142  compmath::Normalize(&c, 1);
143  ctx_->NewDatum("ExplicitInventoryCompact")
144  ->AddVal("AgentId", a->id())
145  ->AddVal("Time", time_)
146  ->AddVal("InventoryName", name)
147  ->AddVal("Quantity", m->quantity())
148  ->AddVal("Composition", c)
149  ->Record();
150  }
151 }
152 
153 void Timer::DoDecom() {
154  // decommission queued agents
155  std::vector<Agent*> decom_list = decom_queue_[time_];
156  for (int i = 0; i < decom_list.size(); ++i) {
157  Agent* m = decom_list[i];
158  if (m->parent() != NULL) {
159  m->parent()->DecomNotify(m);
160  }
161  m->Decommission();
162  }
163 }
164 
166  tickers_[agent->id()] = agent;
167 }
168 
170  tickers_.erase(tl->id());
171 }
172 
173 void Timer::SchedBuild(Agent* parent, std::string proto_name, int t) {
174  if (t <= time_) {
175  throw ValueError("Cannot schedule build for t < [current-time]");
176  }
177  build_queue_[t].push_back(std::make_pair(proto_name, parent));
178 }
179 
180 void Timer::SchedDecom(Agent* m, int t) {
181  if (t < time_) {
182  throw ValueError("Cannot schedule decommission for t < [current-time]");
183  }
184 
185  // It is possible that a single agent may be scheduled for decommissioning
186  // multiple times. If this happens, we cannot just add it to the queue again
187  // - the duplicate entries will result in a double delete attempt and
188  // segfaults and otherwise bad things. Remove previous decommissionings
189  // before scheduling this new one.
190  std::map<int, std::vector<Agent*> >::iterator it;
191  bool done = false;
192  for (it = decom_queue_.begin(); it != decom_queue_.end(); ++it) {
193  int t = it->first;
194  std::vector<Agent*> ags = it->second;
195  for (int i = 0; i < ags.size(); i++) {
196  if (ags[i] == m) {
197  CLOG(LEV_WARN) << "scheduled over previous decommissioning of " << m->id();
198  decom_queue_[t].erase(decom_queue_[t].begin()+i);
199  done = true;
200  break;
201  }
202  }
203  if (done) {
204  break;
205  }
206  }
207 
208  decom_queue_[t].push_back(m);
209 }
210 
211 int Timer::time() {
212  return time_;
213 }
214 
215 void Timer::Reset() {
216  tickers_.clear();
217  build_queue_.clear();
218  decom_queue_.clear();
219  si_ = SimInfo(0);
220 }
221 
223  if (si.m0 < 1 || si.m0 > 12) {
224  throw ValueError("Invalid month0; must be between 1 and 12 (inclusive).");
225  }
226 
227  want_kill_ = false;
228  ctx_ = ctx;
229  time_ = 0;
230  si_ = si;
231 
232  if (si.branch_time > -1) {
233  time_ = si.branch_time;
234  }
235 }
236 
237 int Timer::dur() {
238  return si_.duration;
239 }
240 
241 Timer::Timer() : time_(0), si_(0), want_snapshot_(false), want_kill_(false) {}
242 
243 } // namespace cyclus
Information helpful for simulation users and developers alike.
Definition: logger.h:54
virtual void Decommission()
Decommissions the agent, removing it from the simulation.
Definition: agent.cc:168
int branch_time
timestep at which simulation branching occurs if any
Definition: context.h:96
For values that are too big, too small, etc.
Definition: error.h:41
void RegisterTimeListener(TimeListener *agent)
Registers an agent to receive tick/tock notifications every timestep.
Definition: timer.cc:165
boost::shared_ptr< Material > Ptr
Definition: material.h:75
std::string name(int nuc)
Definition: pyne.cc:2940
int duration
length of the simulation in timesteps (months)
Definition: context.h:80
The ExchangeManager is designed to house all of the internals involved in executing a resource exchan...
void UnregisterTimeListener(TimeListener *tl)
Removes an agent from receiving tick/tock notifications.
Definition: timer.cc:169
int dur()
Returns the duration of the simulation this Timer&#39;s timing.
Definition: timer.cc:237
virtual void DecomNotify(Agent *m)
Called when a new child of this agent is about to be decommissioned.
Definition: agent.h:318
std::map< Nuc, double > CompMap
a raw definition of nuclides and corresponding (dimensionless quantities).
Definition: composition.h:17
#define CLOG(level)
Definition: logger.h:39
void Reset()
resets all data (registered listeners, etc.) to empty or initial state
Definition: timer.cc:215
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:139
bool explicit_inventory
True if per-agent inventories should be explicitly queried/recorded every time step in a table (i...
Definition: context.h:109
std::map< std::string, std::vector< Resource::Ptr > > Inventories
map<inventory_name, vector<resources_in_inventory> >.
Definition: agent.h:35
virtual const int id() const =0
int parent(int nuc, unsigned int rx, std::string z="n")
Definition: pyne.cc:6621
void Initialize(Context *ctx, SimInfo si)
Sets intial time-related parameters for the simulation.
Definition: timer.cc:222
Information helpful for simulation users and developers alike - least verbose.
Definition: logger.h:53
T * CreateAgent(std::string proto_name)
Create a new agent by cloning the named prototype.
Definition: context.h:178
Datum * AddVal(const char *field, boost::spirit::hold_any val, std::vector< int > *shape=NULL)
Add an arbitrary field-value pair to the datum.
Definition: datum.cc:12
int m0
start month for the simulation: Jan = 1, ..., Dec = 12
Definition: context.h:86
static void Snapshot(Context *ctx)
Records a snapshot of the current state of the simulation being managed by ctx into the simulation&#39;s ...
Definition: sim_init.cc:73
int time()
Returns the current time, in months since the simulation started.
Definition: timer.cc:211
The TimeListener class is an inheritable class for any Agent that requires knowlege of ticks and tock...
Definition: time_listener.h:23
void Execute()
execute the full resource sequence
void RunSim()
Runs the simulation.
Definition: timer.cc:14
Use to report questionable simulation state (use extremely sparingly)
Definition: logger.h:52
Container for a static simulation-global parameters that both describe the simulation and affect its ...
Definition: context.h:37
Code providing rudimentary logging capability for the Cyclus core.
A simulation context provides access to necessary simulation-global functions and state...
Definition: context.h:128
bool explicit_inventory_compact
True if per-agent inventories should be explicitly queried/recorded every time step in a table (i...
Definition: context.h:114
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
Agent * parent() const
Returns parent of this agent. Returns NULL if the agent has no parent.
Definition: agent.h:375
debugging information - least verbose
Definition: logger.h:58
Information helpful for simulation users and developers alike.
Definition: logger.h:55
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
void Record()
Record this datum to its Recorder.
Definition: datum.cc:24
virtual const int id() const
The agent instance&#39;s unique ID within a simulation.
Definition: agent.h:354
void SchedBuild(Agent *parent, std::string proto_name, int t)
Schedules the named prototype to be built for the specified parent at timestep t. ...
Definition: timer.cc:173
void SchedDecom(Agent *m, int time)
Schedules the given Agent to be decommissioned at the specified timestep t.
Definition: timer.cc:180
Datum * NewDatum(std::string title)
See Recorder::NewDatum documentation.
Definition: context.cc:237
virtual Inventories SnapshotInv()=0
Snapshots an agent&#39;s resource inventories to the database.
void Normalize(CompMap *v, double val)
The sum of quantities of all nuclides of v is normalized to val.
Definition: comp_math.cc:63
enable_if< has_const_iterator< T >::value, typename T::const_iterator >::type begin(const T &c)