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