• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

cyclus / cyclus / 22637541524

03 Mar 2026 06:36PM UTC coverage: 36.671% (+0.004%) from 36.667%
22637541524

Pull #1940

github

web-flow
Merge 58f61b19d into d6b55cfa3
Pull Request #1940: Make Recipes Required by Schema Validation

8 of 8 new or added lines in 1 file covered. (100.0%)

3 existing lines in 2 files now uncovered.

52625 of 143506 relevant lines covered (36.67%)

16241.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.79
/src/sim_init.cc
1
#include "sim_init.h"
2

3
#include "greedy_preconditioner.h"
4
#include "greedy_solver.h"
5
#include "platform.h"
6
#include "prog_solver.h"
7
#include "region.h"
8

9
namespace cyclus {
10

11
class Dummy : public Region {
12
 public:
13
  Dummy(Context* ctx) : Region(ctx) {}
229✔
14
  Dummy* Clone() { return NULL; }
×
15
};
16

17
SimInit::SimInit() : rec_(NULL), ctx_(NULL) {}
237✔
18

19
SimInit::~SimInit() {
237✔
20
  if (ctx_ != NULL) {
237✔
21
    delete ctx_;
233✔
22
  }
23
}
237✔
24

25
void SimInit::Init(Recorder* r, QueryableBackend* b) {
229✔
26
  Recorder tmprec;
229✔
27
  rec_ = &tmprec;  // use dummy recorder to avoid re-recording
229✔
28
  InitBase(b, r->sim_id(), 0);
229✔
29
  ctx_->rec_ = r;  // switch back before running sim
229✔
30
}
229✔
31

32
void SimInit::Restart(QueryableBackend* b, boost::uuids::uuid sim_id, int t) {
4✔
33
  Warn<EXPERIMENTAL_WARNING>(
4✔
34
      "restart capability is not finalized and fully"
35
      " tested. Its behavior may change in future"
36
      " releases.");
37
  rec_ = new Recorder();
4✔
38
  InitBase(b, sim_id, t);
4✔
39
  si_.parent_sim = sim_id;
4✔
40
  si_.parent_type = "restart";
4✔
41
  si_.branch_time = t;
4✔
42
  ctx_->InitSim(si_);  // explicitly force this to show up in the new
4✔
43
                       // simulations output db
44
}
4✔
45

46
void SimInit::Branch(QueryableBackend* b, boost::uuids::uuid prev_sim_id, int t,
×
47
                     boost::uuids::uuid new_sim_id) {
48
  throw Error("simulation branching feature not implemented");
×
49
}
50

51
void SimInit::InitBase(QueryableBackend* b, boost::uuids::uuid simid, int t) {
233✔
52
  ctx_ = new Context(&ti_, rec_);
233✔
53

54
  std::vector<Cond> conds;
55
  conds.push_back(Cond("SimId", "==", simid));
466✔
56
  b_ = new CondInjector(b, conds);
466✔
57
  t_ = t;
233✔
58
  simid_ = simid;
233✔
59

60
  // this sequence is imporant!!!
61
  LoadInfo();
233✔
62
  LoadRecipes();
233✔
63
  LoadPackages();
233✔
64
  LoadTransportUnits();
233✔
65
  LoadSolverInfo();
233✔
66
  LoadPrototypes();
233✔
67
  LoadInitialAgents();
233✔
68
  LoadInventories();
233✔
69
  LoadBuildSched();
233✔
70
  LoadDecomSched();
233✔
71
  LoadNextIds();
233✔
72

73
  // delete all buffered data that we don't want to be re-recorded in the
74
  // output db
75
  rec_->Flush();
233✔
76
}
233✔
77

78
void SimInit::Snapshot(Context* ctx) {
534✔
79
  ctx->NewDatum("Snapshots")->AddVal("Time", ctx->time())->Record();
1,068✔
80

81
  // snapshot all agent internal state
82
  std::set<Agent*> mlist = ctx->agent_list_;
83
  std::set<Agent*>::iterator it;
84
  for (it = mlist.begin(); it != mlist.end(); ++it) {
9,883✔
85
    Agent* m = *it;
9,349✔
86
    if (m->enter_time() != -1) {
9,349✔
87
      SimInit::SnapAgent(m);
7,509✔
88
    }
89
  }
90

91
  // snapshot all next ids
92
  ctx->NewDatum("NextIds")
93
      ->AddVal("Time", ctx->time())
534✔
94
      ->AddVal("Object", std::string("Agent"))
1,068✔
95
      ->AddVal("NextId", Agent::next_id_)
96
      ->Record();
2,670✔
97
  ctx->NewDatum("NextIds")
98
      ->AddVal("Time", ctx->time())
534✔
99
      ->AddVal("Object", std::string("Transaction"))
1,068✔
100
      ->AddVal("NextId", ctx->trans_id_)
101
      ->Record();
2,670✔
102
  ctx->NewDatum("NextIds")
103
      ->AddVal("Time", ctx->time())
534✔
104
      ->AddVal("Object", std::string("Composition"))
1,068✔
105
      ->AddVal("NextId", Composition::next_id_)
106
      ->Record();
2,670✔
107
  ctx->NewDatum("NextIds")
108
      ->AddVal("Time", ctx->time())
534✔
109
      ->AddVal("Object", std::string("ResourceState"))
1,068✔
110
      ->AddVal("NextId", Resource::nextstate_id_)
111
      ->Record();
2,670✔
112
  ctx->NewDatum("NextIds")
113
      ->AddVal("Time", ctx->time())
534✔
114
      ->AddVal("Object", std::string("ResourceObj"))
1,068✔
115
      ->AddVal("NextId", Resource::nextobj_id_)
116
      ->Record();
2,670✔
117
  ctx->NewDatum("NextIds")
118
      ->AddVal("Time", ctx->time())
534✔
119
      ->AddVal("Object", std::string("Product"))
1,068✔
120
      ->AddVal("NextId", Product::next_qualid_)
121
      ->Record();
2,670✔
122
}
534✔
123

124
void SimInit::SnapAgent(Agent* m) {
9,034✔
125
  // call manually without agent impl injected to keep all Agent state in a
126
  // single, consolidated db table
127
  m->Agent::Snapshot(DbInit(m, true));
9,034✔
128

129
  m->Snapshot(DbInit(m));
9,034✔
130
  Inventories invs = m->SnapshotInv();
9,034✔
131
  Context* ctx = m->context();
132

133
  Inventories::iterator it;
134
  for (it = invs.begin(); it != invs.end(); ++it) {
10,290✔
135
    std::string name = it->first;
136
    std::vector<Resource::Ptr> inv = it->second;
1,256✔
137
    for (int i = 0; i < inv.size(); ++i) {
7,980✔
138
      ctx->NewDatum("AgentStateInventories")
139
          ->AddVal("AgentId", m->id())
6,724✔
140
          ->AddVal("SimTime", ctx->time())
6,724✔
141
          ->AddVal("InventoryName", name)
142
          ->AddVal("ResourceId", inv[i]->state_id())
143
          ->Record();
40,344✔
144
    }
145
  }
1,256✔
146
}
9,034✔
147

148
void SimInit::LoadInfo() {
233✔
149
  QueryResult qr = b_->Query("Info", NULL);
233✔
150
  int dur = qr.GetVal<int>("Duration");
233✔
151
  int y0 = qr.GetVal<int>("InitialYear");
233✔
152
  int m0 = qr.GetVal<int>("InitialMonth");
233✔
153
  std::string h = qr.GetVal<std::string>("Handle");
233✔
154
  QueryResult dq = b_->Query("DecayMode", NULL);
233✔
155
  std::string d = dq.GetVal<std::string>("Decay");
466✔
156
  si_ = SimInfo(dur, y0, m0, h, d);
233✔
157

158
  si_.seed = qr.GetVal<int>("Seed");
233✔
159
  si_.stride = qr.GetVal<int>("Stride");
233✔
160

161
  si_.parent_sim = qr.GetVal<boost::uuids::uuid>("ParentSimId");
233✔
162

163
  qr = b_->Query("TimeStepDur", NULL);
233✔
164
  // TODO: when the backends support uint64_t, the int template here
165
  // should be updated to uint64_t.
166
  si_.dt = qr.GetVal<int>("DurationSecs");
233✔
167

168
  qr = b_->Query("Epsilon", NULL);
233✔
169
  si_.eps = qr.GetVal<double>("GenericEpsilon");
233✔
170
  si_.eps_rsrc = qr.GetVal<double>("ResourceEpsilon");
233✔
171

172
  qr = b_->Query("InfoExplicitInv", NULL);
233✔
173
  si_.explicit_inventory = qr.GetVal<bool>("RecordInventory");
233✔
174
  si_.explicit_inventory_compact = qr.GetVal<bool>("RecordInventoryCompact");
233✔
175

176
  ctx_->InitSim(si_);
233✔
177
}
466✔
178

179
void SimInit::LoadRecipes() {
233✔
180
  QueryResult qr;
181
  try {
182
    qr = b_->Query("Recipes", NULL);
233✔
UNCOV
183
  } catch (std::exception err) {
×
184
    return;
UNCOV
185
  }  // table doesn't exist (okay)
×
186

187
  for (int i = 0; i < qr.rows.size(); ++i) {
506✔
188
    std::string recipe = qr.GetVal<std::string>("Recipe", i);
273✔
189
    int stateid = qr.GetVal<int>("QualId", i);
273✔
190
    Composition::Ptr c = LoadComposition(b_, stateid);
273✔
191
    ctx_->AddRecipe(recipe, c);
1,092✔
192
  }
193
}
233✔
194

195
void SimInit::LoadPackages() {
233✔
196
  QueryResult qr;
197
  try {
198
    qr = b_->Query("Packages", NULL);
233✔
199
  } catch (std::exception err) {
40✔
200
    return;
201
  }  // table doesn't exist (okay)
40✔
202

203
  for (int i = 0; i < qr.rows.size(); ++i) {
386✔
204
    std::string name = qr.GetVal<std::string>("PackageName", i);
193✔
205
    double fill_min = qr.GetVal<double>("FillMin", i);
193✔
206
    double fill_max = qr.GetVal<double>("FillMax", i);
193✔
207
    std::string strategy = qr.GetVal<std::string>("Strategy", i);
386✔
208

209
    if (name != Package::unpackaged_name()) {
193✔
210
      ctx_->AddPackage(name, fill_min, fill_max, strategy);
×
211
    } else {
212
      ctx_->RecordPackage(Package::unpackaged());
579✔
213
    }
214
  }
215
}
233✔
216

217
void SimInit::LoadTransportUnits() {
233✔
218
  QueryResult qr;
219
  try {
220
    qr = b_->Query("TransportUnits", NULL);
233✔
221
  } catch (std::exception err) {
233✔
222
    return;
223
  }  // table doesn't exist (okay)
233✔
224

225
  for (int i = 0; i < qr.rows.size(); ++i) {
×
226
    std::string name = qr.GetVal<std::string>("TransportUnitName", i);
×
227
    int fill_min = qr.GetVal<int>("FillMin", i);
×
228
    int fill_max = qr.GetVal<int>("FillMax", i);
×
229
    std::string strategy = qr.GetVal<std::string>("Strategy", i);
×
230

231
    if (name != TransportUnit::unrestricted_name()) {
×
232
      ctx_->AddTransportUnit(name, fill_min, fill_max, strategy);
×
233
    } else {
234
      ctx_->RecordTransportUnit(TransportUnit::unrestricted());
×
235
    }
236
  }
237
}
233✔
238

239
void* SimInit::LoadPreconditioner(std::string name) {
153✔
240
  using std::map;
241
  using std::string;
242
  void* precon = NULL;
243
  map<string, double> commod_order;
244
  try {
245
    QueryResult qr = b_->Query("CommodPriority", NULL);
153✔
246
    for (int i = 0; i < qr.rows.size(); ++i) {
×
247
      std::string commod = qr.GetVal<string>("Commodity", i);
×
248
      double order = qr.GetVal<double>("SolutionOrder", i);
×
249
      commod_order[commod] = order;
×
250
    }
251
  } catch (std::exception err) {
153✔
252
    return NULL;
253
  }  // table doesn't exist (okay)
153✔
254

255
  // actually create and return the preconditioner
256
  if (name == "greedy") {
×
257
    precon =
258
        new GreedyPreconditioner(commod_order, GreedyPreconditioner::REVERSE);
×
259
  } else {
260
    throw ValueError(
×
261
        "The name of the preconditioner was not recognized, "
262
        "got '" +
×
263
        name + "'.");
×
264
  }
265
  return precon;
266
}
267

268
ExchangeSolver* SimInit::LoadGreedySolver(bool exclusive,
153✔
269
                                          std::set<std::string> tables) {
270
  using std::set;
271
  using std::string;
272
  ExchangeSolver* solver;
273
  void* precon = NULL;
274
  string precon_name = string("greedy");
153✔
275

276
  string solver_info = string("GreedySolverInfo");
153✔
277
  if (0 < tables.count(solver_info)) {
278
    QueryResult qr = b_->Query(solver_info, NULL);
339✔
279
    if (qr.rows.size() > 0) {
113✔
280
      precon_name = qr.GetVal<string>("Preconditioner");
226✔
281
    }
282
  }
113✔
283

284
  precon = LoadPreconditioner(precon_name);
153✔
285
  if (precon == NULL) {
153✔
286
    solver = new GreedySolver(exclusive);
153✔
287
  } else {
288
    solver = new GreedySolver(exclusive,
289
                              reinterpret_cast<GreedyPreconditioner*>(precon));
×
290
  }
291
  return solver;
153✔
292
}
293

294
ExchangeSolver* SimInit::LoadCoinSolver(bool exclusive,
80✔
295
                                        std::set<std::string> tables) {
296
#if CYCLUS_HAS_COIN
297
  ExchangeSolver* solver;
298
  double timeout;
299
  bool verbose, mps;
300

301
  std::string solver_info = "CoinSolverInfo";
80✔
302
  if (0 < tables.count(solver_info)) {
303
    QueryResult qr = b_->Query(solver_info, NULL);
160✔
304
    timeout = qr.GetVal<double>("Timeout");
80✔
305
    verbose = qr.GetVal<bool>("Verbose");
80✔
306
    mps = qr.GetVal<bool>("Mps");
80✔
307
  }
80✔
308

309
  // set timeout to default if input value is non-positive
310
  timeout = timeout <= 0 ? ProgSolver::kDefaultTimeout : timeout;
80✔
311
  solver = new ProgSolver("cbc", timeout, exclusive, verbose, mps);
160✔
312
  return solver;
80✔
313
#else
314
  throw cyclus::Error(
315
      "Cyclus was not compiled with COIN support, cannot load solver.");
316
#endif
317
}
318

319
void SimInit::LoadSolverInfo() {
233✔
320
  using std::set;
321
  using std::string;
322
  // context will delete solver
323
  ExchangeSolver* solver;
324
  string solver_name;
325
  bool exclusive_orders;
326

327
  // load in possible Solver info, needs to be optional to
328
  // maintain backwards compatibility, defaults above.
329
  set<string> tables = b_->Tables();
233✔
330
  string solver_info = string("SolverInfo");
233✔
331
  if (0 < tables.count(solver_info)) {
332
    QueryResult qr = b_->Query(solver_info, NULL);
699✔
333
    if (qr.rows.size() > 0) {
233✔
334
      solver_name = qr.GetVal<string>("Solver");
466✔
335
      exclusive_orders = qr.GetVal<bool>("ExclusiveOrders");
466✔
336
    }
337
  }
233✔
338

339
  if (solver_name == "greedy") {
233✔
340
    solver = LoadGreedySolver(exclusive_orders, tables);
306✔
341
  } else if (solver_name == "coin-or") {
80✔
342
    solver = LoadCoinSolver(exclusive_orders, tables);
160✔
343
  } else {
344
    throw ValueError(
×
345
        "The name of the solver was not recognized, "
346
        "got '" +
×
347
        solver_name + "'.");
×
348
  }
349

350
  ctx_->solver(solver);
233✔
351
}
233✔
352

353
void SimInit::LoadPrototypes() {
233✔
354
  QueryResult qr = b_->Query("Prototypes", NULL);
233✔
355
  for (int i = 0; i < qr.rows.size(); ++i) {
968✔
356
    std::string proto = qr.GetVal<std::string>("Prototype", i);
735✔
357
    int agentid = qr.GetVal<int>("AgentId", i);
735✔
358
    std::string impl = qr.GetVal<std::string>("Spec", i);
1,470✔
359
    AgentSpec spec(impl);
735✔
360

361
    Agent* m = DynamicModule::Make(ctx_, spec);
735✔
362
    m->id_ = agentid;
735✔
363

364
    // note that we don't filter by SimTime here because prototypes remain
365
    // static over the life of the simulation and we only snapshot them once
366
    // when the simulation is initialized.
367
    std::vector<Cond> conds;
368
    conds.push_back(Cond("AgentId", "==", agentid));
1,470✔
369
    CondInjector ci(b_, conds);
735✔
370
    PrefixInjector pi(&ci, "AgentState");
735✔
371

372
    // call manually without agent impl injected
373
    m->Agent::InitFrom(&pi);
735✔
374

375
    pi = PrefixInjector(&ci, "AgentState" + spec.Sanitize());
2,205✔
376
    m->InitFrom(&pi);
735✔
377
    ctx_->AddPrototype(proto, m);
2,205✔
378
  }
735✔
379
}
233✔
380

381
void SimInit::LoadInitialAgents() {
233✔
382
  // DO NOT call the agents' Build methods because the agents might modify the
383
  // state of their children and/or the simulation in ways that are only meant
384
  // to be done once; remember that we are initializing agents from a
385
  // simulation that was already started.
386

387
  // find all agents that are alive at the current timestep
388
  std::vector<Cond> conds;
389
  conds.push_back(Cond("EnterTime", "<=", t_));
466✔
390
  QueryResult qentry = b_->Query("AgentEntry", &conds);
466✔
391
  std::map<int, int> parentmap;   // map<agentid, parentid>
392
  std::map<int, Agent*> unbuilt;  // map<agentid, agent_ptr>
393
  for (int i = 0; i < qentry.rows.size(); ++i) {
1,880✔
394
    if (t_ > 0 && qentry.GetVal<int>("EnterTime", i) == t_) {
1,667✔
395
      // agent is scheduled to be built already
396
      continue;
8✔
397
    }
398
    int id = qentry.GetVal<int>("AgentId", i);
1,643✔
399
    std::vector<Cond> conds;
400
    conds.push_back(Cond("AgentId", "==", id));
3,286✔
401
    conds.push_back(Cond("ExitTime", "<", t_));
3,286✔
402
    try {
403
      QueryResult qexit = b_->Query("AgentExit", &conds);
1,651✔
404
      if (qexit.rows.size() != 0) {
8✔
405
        continue;  // agent was decomissioned before t_ - skip
406
      }
407
    } catch (std::exception err) {
1,643✔
408
    }  // table doesn't exist (okay)
1,635✔
409

410
    // if the agent wasn't decommissioned before t_ create and init it
411

412
    std::string proto = qentry.GetVal<std::string>("Prototype", i);
1,639✔
413
    std::string impl = qentry.GetVal<std::string>("Spec", i);
3,278✔
414
    AgentSpec spec(impl);
1,639✔
415
    Agent* m = DynamicModule::Make(ctx_, spec);
1,639✔
416

417
    // agent-kernel init
418
    m->prototype_ = proto;
1,639✔
419
    m->id_ = id;
1,639✔
420
    m->enter_time_ = qentry.GetVal<int>("EnterTime", i);
1,639✔
421
    unbuilt[id] = m;
1,639✔
422
    parentmap[id] = qentry.GetVal<int>("ParentId", i);
1,639✔
423

424
    // agent-custom init
425
    conds.pop_back();
426
    conds.push_back(Cond("SimTime", "==", t_));
3,278✔
427
    CondInjector ci(b_, conds);
1,639✔
428
    PrefixInjector pi(&ci, "AgentState");
1,639✔
429
    m->Agent::InitFrom(&pi);
1,639✔
430
    pi = PrefixInjector(&ci, "AgentState" + spec.Sanitize());
4,917✔
431
    m->InitFrom(&pi);
1,639✔
432
  }
3,282✔
433

434
  // construct agent hierarchy starting at roots (no parent) down
435
  std::map<int, Agent*>::iterator it = unbuilt.begin();
436
  std::vector<Agent*> enter_list;
437
  while (unbuilt.size() > 0) {
1,872✔
438
    int id = it->first;
1,639✔
439
    Agent* m = it->second;
1,639✔
440
    int parentid = parentmap[id];
1,639✔
441

442
    if (parentid == -1) {  // root agent
1,639✔
443
      m->Connect(NULL);
273✔
444
      agents_[id] = m;
273✔
445
      ++it;
446
      unbuilt.erase(id);
447
      enter_list.push_back(m);
273✔
448
    } else if (agents_.count(parentid) > 0) {  // parent is built
449
      m->Connect(agents_[parentid]);
1,366✔
450
      agents_[id] = m;
1,366✔
451
      ++it;
452
      unbuilt.erase(id);
453
      enter_list.push_back(m);
1,366✔
454
    } else {  // parent not built yet
455
      ++it;
456
    }
457
    if (it == unbuilt.end()) {
1,639✔
458
      it = unbuilt.begin();
459
    }
460
  }
461

462
  // notify all agents that they are active in a simulation AFTER the
463
  // parent-child hierarchy has been reconstructed.
464
  for (int i = 0; i < enter_list.size(); ++i) {
1,872✔
465
    enter_list[i]->EnterNotify();
1,639✔
466
  }
467
}
233✔
468

469
void SimInit::LoadInventories() {
233✔
470
  std::map<int, Agent*>::iterator it;
471
  for (it = agents_.begin(); it != agents_.end(); ++it) {
333✔
472
    Agent* m = it->second;
285✔
473
    std::vector<Cond> conds;
474
    conds.push_back(Cond("SimTime", "==", t_));
570✔
475
    conds.push_back(Cond("AgentId", "==", m->id()));
570✔
476
    QueryResult qr;
477
    try {
478
      qr = b_->Query("AgentStateInventories", &conds);
385✔
479
    } catch (std::exception err) {
185✔
480
      return;
481
    }  // table doesn't exist (okay)
185✔
482

483
    Inventories invs;
484
    for (int i = 0; i < qr.rows.size(); ++i) {
328✔
485
      std::string inv_name = qr.GetVal<std::string>("InventoryName", i);
228✔
486
      int state_id = qr.GetVal<int>("ResourceId", i);
228✔
487
      invs[inv_name].push_back(LoadResource(ctx_, b_, state_id));
456✔
488
    }
489
    m->InitInv(invs);
100✔
490
  }
285✔
491
}
492

493
void SimInit::LoadBuildSched() {
233✔
494
  std::vector<Cond> conds;
495
  conds.push_back(Cond("BuildTime", ">", t_));
466✔
496
  QueryResult qr;
497
  try {
498
    qr = b_->Query("BuildSchedule", &conds);
233✔
499
  } catch (std::exception err) {
193✔
500
    return;
501
  }  // table doesn't exist (okay)
193✔
502

503
  for (int i = 0; i < qr.rows.size(); ++i) {
116✔
504
    int t = qr.GetVal<int>("BuildTime", i);
76✔
505
    int parentid = qr.GetVal<int>("ParentId", i);
76✔
506
    std::string proto = qr.GetVal<std::string>("Prototype", i);
76✔
507
    ctx_->SchedBuild(agents_[parentid], proto, t);
228✔
508
  }
509
}
233✔
510

511
void SimInit::LoadDecomSched() {
233✔
512
  std::vector<Cond> conds;
513
  conds.push_back(Cond("DecomTime", ">=", t_));
466✔
514
  QueryResult qr;
515
  try {
516
    qr = b_->Query("DecomSchedule", &conds);
233✔
517
  } catch (std::exception err) {
173✔
518
    return;
519
  }  // table doesn't exist (okay)
173✔
520

521
  for (int i = 0; i < qr.rows.size(); ++i) {
156✔
522
    int t = qr.GetVal<int>("DecomTime", i);
96✔
523
    int agentid = qr.GetVal<int>("AgentId", i);
96✔
524
    ctx_->SchedDecom(agents_[agentid], t);
96✔
525
  }
526
}
233✔
527

528
void SimInit::LoadNextIds() {
233✔
529
  std::vector<Cond> conds;
530
  conds.push_back(Cond("Time", "==", t_));
466✔
531
  QueryResult qr = b_->Query("NextIds", &conds);
233✔
532
  for (int i = 0; i < qr.rows.size(); ++i) {
1,631✔
533
    std::string obj = qr.GetVal<std::string>("Object", i);
2,796✔
534
    if (obj == "Agent") {
1,398✔
535
      Agent::next_id_ = qr.GetVal<int>("NextId", i);
233✔
536
    } else if (obj == "Transaction") {
1,165✔
537
      ctx_->trans_id_ = qr.GetVal<int>("NextId", i);
233✔
538
    } else if (obj == "Composition") {
932✔
539
      Composition::next_id_ = qr.GetVal<int>("NextId", i);
233✔
540
    } else if (obj == "ResourceState") {
699✔
541
      Resource::nextstate_id_ = qr.GetVal<int>("NextId", i);
233✔
542
    } else if (obj == "ResourceObj") {
466✔
543
      Resource::nextobj_id_ = qr.GetVal<int>("NextId", i);
233✔
544
    } else if (obj == "Product") {
233✔
545
      Product::next_qualid_ = qr.GetVal<int>("NextId", i);
233✔
546
    } else {
547
      throw IOError("Unexpected value in NextIds table: " + obj);
×
548
    }
549
  }
550
}
233✔
551

552
Material::Ptr SimInit::BuildMaterial(QueryableBackend* b, int resid) {
1✔
553
  Timer ti;
1✔
554
  Recorder rec;
1✔
555
  Context ctx(&ti, &rec);
1✔
556

557
  // manually make this "untracked" to prevent segfaulting and other such
558
  // terrors because the created context is destructed by SimInit at the end
559
  // of this function.
560
  Material::Ptr m = ResCast<Material>(SimInit::LoadResource(&ctx, b, resid));
2✔
561
  m->tracker_.DontTrack();
1✔
562
  m->ctx_ = NULL;
1✔
563
  return m;
1✔
564
}
1✔
565

566
Product::Ptr SimInit::BuildProduct(QueryableBackend* b, int resid) {
×
567
  Timer ti;
×
568
  Recorder rec;
×
569
  Context ctx(&ti, &rec);
×
570

571
  // manually make this "untracked" to prevent segfaulting and other such
572
  // terrors because the created context is destructed by SimInit at the end
573
  // of this function.
574
  Product::Ptr p = ResCast<Product>(SimInit::LoadResource(&ctx, b, resid));
×
575
  p->tracker_.DontTrack();
×
576
  p->ctx_ = NULL;
×
577
  return p;
×
578
}
×
579

580
Resource::Ptr SimInit::LoadResource(Context* ctx, QueryableBackend* b,
229✔
581
                                    int state_id) {
582
  std::vector<Cond> conds;
583
  conds.push_back(Cond("ResourceId", "==", state_id));
458✔
584
  QueryResult qr = b->Query("Resources", &conds);
229✔
585
  ResourceType type = qr.GetVal<ResourceType>("Type");
229✔
586
  int obj_id = qr.GetVal<int>("ObjId");
229✔
587

588
  Resource::Ptr r;
229✔
589
  if (type == Material::kType) {
229✔
590
    r = LoadMaterial(ctx, b, state_id);
458✔
591
  } else if (type == Product::kType) {
×
592
    r = LoadProduct(ctx, b, state_id);
×
593
  } else {
594
    throw IOError("Invalid resource type in output database: " + type);
×
595
  }
596

597
  r->state_id_ = state_id;
229✔
598
  r->obj_id_ = obj_id;
229✔
599
  return r;
229✔
600
}
229✔
601

602
Material::Ptr SimInit::LoadMaterial(Context* ctx, QueryableBackend* b,
229✔
603
                                    int state_id) {
604
  // get special material object state
605
  std::vector<Cond> conds;
606
  conds.push_back(Cond("ResourceId", "==", state_id));
458✔
607
  QueryResult qr = b->Query("MaterialInfo", &conds);
229✔
608
  int prev_decay = qr.GetVal<int>("PrevDecayTime");
458✔
609

610
  // get general resource object info
611
  conds.clear();
612
  conds.push_back(Cond("ResourceId", "==", state_id));
458✔
613
  qr = b->Query("Resources", &conds);
229✔
614
  double qty = qr.GetVal<double>("Quantity");
229✔
615
  int stateid = qr.GetVal<int>("QualId");
229✔
616

617
  // create the composition and material
618
  Composition::Ptr comp = LoadComposition(b, stateid);
229✔
619
  Agent* dummy = new Dummy(ctx);
229✔
620
  Material::Ptr mat = Material::Create(dummy, qty, comp);
458✔
621
  mat->prev_decay_time_ = prev_decay;
229✔
622
  ctx->DelAgent(dummy);
229✔
623

624
  return mat;
229✔
625
}
229✔
626

627
Composition::Ptr SimInit::LoadComposition(QueryableBackend* b, int stateid) {
502✔
628
  std::vector<Cond> conds;
629
  conds.push_back(Cond("QualId", "==", stateid));
1,004✔
630
  QueryResult qr = b->Query("Compositions", &conds);
1,004✔
631
  CompMap cm;
632
  for (int i = 0; i < qr.rows.size(); ++i) {
1,346✔
633
    int nucid = qr.GetVal<int>("NucId", i);
844✔
634
    double mass_frac = qr.GetVal<double>("MassFrac", i);
844✔
635
    cm[nucid] = mass_frac;
844✔
636
  }
637
  Composition::Ptr c = Composition::CreateFromMass(cm);
1,004✔
638
  c->recorded_ = true;
502✔
639
  c->id_ = stateid;
502✔
640
  return c;
502✔
641
}
502✔
642

643
Product::Ptr SimInit::LoadProduct(Context* ctx, QueryableBackend* b,
×
644
                                  int state_id) {
645
  // get general resource object info
646
  std::vector<Cond> conds;
647
  conds.push_back(Cond("ResourceId", "==", state_id));
×
648
  QueryResult qr = b->Query("Resources", &conds);
×
649
  double qty = qr.GetVal<double>("Quantity");
×
650
  int stateid = qr.GetVal<int>("QualId");
×
651

652
  // get special Product internal state
653
  conds.clear();
654
  conds.push_back(Cond("QualId", "==", stateid));
×
655
  qr = b->Query("Products", &conds);
×
656
  std::string quality = qr.GetVal<std::string>("Quality");
×
657

658
  // set static quality-stateid map to have same vals as db
659
  Product::qualids_[quality] = stateid;
×
660

661
  Agent* dummy = new Dummy(ctx);
×
662
  Product::Ptr r = Product::Create(dummy, qty, quality);
×
663
  ctx->DelAgent(dummy);
×
664
  return r;
×
665
}
×
666

667
}  // namespace cyclus
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc