CYCAMORE
src/reactor_tests.cc
Go to the documentation of this file.
1 #include <gtest/gtest.h>
2 
3 #include <sstream>
4 
5 #include "cyclus.h"
6 
7 using pyne::nucname::id;
8 using cyclus::Composition;
9 using cyclus::Material;
10 using cyclus::QueryResult;
11 using cyclus::Cond;
12 using cyclus::toolkit::MatQuery;
13 
14 namespace cycamore {
15 namespace reactortests {
16 
17 Composition::Ptr c_uox() {
18  cyclus::CompMap m;
19  m[id("u235")] = 0.04;
20  m[id("u238")] = 0.96;
21  return Composition::CreateFromMass(m);
22 };
23 
24 Composition::Ptr c_mox() {
25  cyclus::CompMap m;
26  m[id("u235")] = .7;
27  m[id("u238")] = 100;
28  m[id("pu239")] = 3.3;
29  return Composition::CreateFromMass(m);
30 };
31 
32 Composition::Ptr c_spentuox() {
33  cyclus::CompMap m;
34  m[id("u235")] = .8;
35  m[id("u238")] = 100;
36  m[id("pu239")] = 1;
37  return Composition::CreateFromMass(m);
38 };
39 
40 Composition::Ptr c_spentmox() {
41  cyclus::CompMap m;
42  m[id("u235")] = .2;
43  m[id("u238")] = 100;
44  m[id("pu239")] = .9;
45  return Composition::CreateFromMass(m);
46 };
47 
48 Composition::Ptr c_water() {
49  cyclus::CompMap m;
50  m[id("O16")] = 1;
51  m[id("H1")] = 2;
52  return Composition::CreateFromAtom(m);
53 };
54 
55 // Test that with a zero refuel_time and a zero capacity fresh fuel buffer
56 // (the default), fuel can be ordered and the cycle started with no time step
57 // delay.
58 TEST(ReactorTests, JustInTimeOrdering) {
59  std::string config =
60  " <fuel_inrecipes> <val>lwr_fresh</val> </fuel_inrecipes> "
61  " <fuel_outrecipes> <val>lwr_spent</val> </fuel_outrecipes> "
62  " <fuel_incommods> <val>enriched_u</val> </fuel_incommods> "
63  " <fuel_outcommods> <val>waste</val> </fuel_outcommods> "
64  " <fuel_prefs> <val>1.0</val> </fuel_prefs> "
65  ""
66  " <cycle_time>1</cycle_time> "
67  " <refuel_time>0</refuel_time> "
68  " <assem_size>300</assem_size> "
69  " <n_assem_core>1</n_assem_core> "
70  " <n_assem_batch>1</n_assem_batch> ";
71 
72  int simdur = 50;
73  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur);
74  sim.AddSource("enriched_u").Finalize();
75  sim.AddRecipe("lwr_fresh", c_uox());
76  sim.AddRecipe("lwr_spent", c_spentuox());
77  int id = sim.Run();
78 
79  QueryResult qr = sim.db().Query("Transactions", NULL);
80  EXPECT_EQ(simdur, qr.rows.size()) << "failed to order+run on fresh fuel inside 1 time step";
81 }
82 
83 // tests that the correct number of assemblies are popped from the core each
84 // cycle.
85 TEST(ReactorTests, BatchSizes) {
86  std::string config =
87  " <fuel_inrecipes> <val>uox</val> </fuel_inrecipes> "
88  " <fuel_outrecipes> <val>spentuox</val> </fuel_outrecipes> "
89  " <fuel_incommods> <val>uox</val> </fuel_incommods> "
90  " <fuel_outcommods> <val>waste</val> </fuel_outcommods> "
91  ""
92  " <cycle_time>1</cycle_time> "
93  " <refuel_time>0</refuel_time> "
94  " <assem_size>1</assem_size> "
95  " <n_assem_core>7</n_assem_core> "
96  " <n_assem_batch>3</n_assem_batch> ";
97 
98  int simdur = 50;
99  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur);
100  sim.AddSource("uox").Finalize();
101  sim.AddRecipe("uox", c_uox());
102  sim.AddRecipe("spentuox", c_spentuox());
103  int id = sim.Run();
104 
105  QueryResult qr = sim.db().Query("Transactions", NULL);
106  // 7 for initial core, 3 per time step for each new batch for remainder
107  EXPECT_EQ(7+3*(simdur-1), qr.rows.size());
108 }
109 
110 // tests that the refueling period between cycle end and start of the next
111 // cycle is honored.
112 TEST(ReactorTests, RefuelTimes) {
113  std::string config =
114  " <fuel_inrecipes> <val>uox</val> </fuel_inrecipes> "
115  " <fuel_outrecipes> <val>spentuox</val> </fuel_outrecipes> "
116  " <fuel_incommods> <val>uox</val> </fuel_incommods> "
117  " <fuel_outcommods> <val>waste</val> </fuel_outcommods> "
118  ""
119  " <cycle_time>4</cycle_time> "
120  " <refuel_time>3</refuel_time> "
121  " <assem_size>1</assem_size> "
122  " <n_assem_core>1</n_assem_core> "
123  " <n_assem_batch>1</n_assem_batch> ";
124 
125  int simdur = 49;
126  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur);
127  sim.AddSource("uox").Finalize();
128  sim.AddRecipe("uox", c_uox());
129  sim.AddRecipe("spentuox", c_spentuox());
130  int id = sim.Run();
131 
132  QueryResult qr = sim.db().Query("Transactions", NULL);
133  int cyclet = 4;
134  int refuelt = 3;
135  int n_assem_want = simdur/(cyclet+refuelt)+1; // +1 for initial core
136  EXPECT_EQ(n_assem_want, qr.rows.size());
137 }
138 
139 // tests that new fuel is ordered immediately following cycle end - at the
140 // start of the refueling period - not before and not after. - thie is subtly
141 // different than RefuelTimes test and is not a duplicate of it.
142 TEST(ReactorTests, OrderAtRefuelStart) {
143  std::string config =
144  " <fuel_inrecipes> <val>uox</val> </fuel_inrecipes> "
145  " <fuel_outrecipes> <val>spentuox</val> </fuel_outrecipes> "
146  " <fuel_incommods> <val>uox</val> </fuel_incommods> "
147  " <fuel_outcommods> <val>waste</val> </fuel_outcommods> "
148  ""
149  " <cycle_time>4</cycle_time> "
150  " <refuel_time>3</refuel_time> "
151  " <assem_size>1</assem_size> "
152  " <n_assem_core>1</n_assem_core> "
153  " <n_assem_batch>1</n_assem_batch> ";
154 
155  int simdur = 7;
156  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur);
157  sim.AddSource("uox").Finalize();
158  sim.AddRecipe("uox", c_uox());
159  sim.AddRecipe("spentuox", c_spentuox());
160  int id = sim.Run();
161 
162  QueryResult qr = sim.db().Query("Transactions", NULL);
163  int cyclet = 4;
164  int refuelt = 3;
165  int n_assem_want = simdur/(cyclet+refuelt)+1; // +1 for initial core
166  EXPECT_EQ(n_assem_want, qr.rows.size());
167 }
168 
169 // tests that the reactor handles requesting multiple types of fuel correctly
170 // - with proper inventory constraint honoring, etc.
171 TEST(ReactorTests, MultiFuelMix) {
172  std::string config =
173  " <fuel_inrecipes> <val>uox</val> <val>mox</val> </fuel_inrecipes> "
174  " <fuel_outrecipes> <val>spentuox</val> <val>spentmox</val> </fuel_outrecipes> "
175  " <fuel_incommods> <val>uox</val> <val>mox</val> </fuel_incommods> "
176  " <fuel_outcommods> <val>waste</val> <val>waste</val> </fuel_outcommods> "
177  ""
178  " <cycle_time>1</cycle_time> "
179  " <refuel_time>0</refuel_time> "
180  " <assem_size>1</assem_size> "
181  " <n_assem_fresh>3</n_assem_fresh> "
182  " <n_assem_core>3</n_assem_core> "
183  " <n_assem_batch>3</n_assem_batch> ";
184 
185  // it is important that the sources have cumulative capacity greater than
186  // the reactor can take on a single time step - to test that inventory
187  // capacity constraints are being set properly. It is also important that
188  // each source is smaller capacity thatn the reactor orders on each time
189  // step to make it easy to compute+check the number of transactions.
190  int simdur = 50;
191  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur);
192  sim.AddSource("uox").capacity(2).Finalize();
193  sim.AddSource("mox").capacity(2).Finalize();
194  sim.AddRecipe("uox", c_uox());
195  sim.AddRecipe("spentuox", c_spentuox());
196  sim.AddRecipe("mox", c_spentuox());
197  sim.AddRecipe("spentmox", c_spentuox());
198  int id = sim.Run();
199 
200  QueryResult qr = sim.db().Query("Transactions", NULL);
201  // +3 is for fresh fuel inventory
202  EXPECT_EQ(3*simdur+3, qr.rows.size());
203 }
204 
205 // tests that the reactor halts operation when it has no more room in its
206 // spent fuel inventory buffer.
207 TEST(ReactorTests, FullSpentInventory) {
208  std::string config =
209  " <fuel_inrecipes> <val>uox</val> </fuel_inrecipes> "
210  " <fuel_outrecipes> <val>spentuox</val> </fuel_outrecipes> "
211  " <fuel_incommods> <val>uox</val> </fuel_incommods> "
212  " <fuel_outcommods> <val>waste</val> </fuel_outcommods> "
213  ""
214  " <cycle_time>1</cycle_time> "
215  " <refuel_time>0</refuel_time> "
216  " <assem_size>1</assem_size> "
217  " <n_assem_core>1</n_assem_core> "
218  " <n_assem_batch>1</n_assem_batch> "
219  " <n_assem_spent>3</n_assem_spent> ";
220 
221  int simdur = 10;
222  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur);
223  sim.AddSource("uox").Finalize();
224  sim.AddRecipe("uox", c_uox());
225  sim.AddRecipe("spentuox", c_spentuox());
226  int id = sim.Run();
227 
228  QueryResult qr = sim.db().Query("Transactions", NULL);
229  int n_assem_spent = 3;
230 
231  // +1 is for the assembly in the core + the three in spent
232  EXPECT_EQ(n_assem_spent+1, qr.rows.size());
233 }
234 
235 // tests that the reactor cycle is delayed as expected when it is unable to
236 // acquire fuel in time for the next cycle start. This checks that after a
237 // cycle is delayed past an original scheduled start time, as soon as enough fuel is
238 // received, a new cycle pattern is established starting from the delayed
239 // start time.
240 TEST(ReactorTests, FuelShortage) {
241  std::string config =
242  " <fuel_inrecipes> <val>uox</val> </fuel_inrecipes> "
243  " <fuel_outrecipes> <val>spentuox</val> </fuel_outrecipes> "
244  " <fuel_incommods> <val>uox</val> </fuel_incommods> "
245  " <fuel_outcommods> <val>waste</val> </fuel_outcommods> "
246  ""
247  " <cycle_time>7</cycle_time> "
248  " <refuel_time>0</refuel_time> "
249  " <assem_size>1</assem_size> "
250  " <n_assem_core>3</n_assem_core> "
251  " <n_assem_batch>3</n_assem_batch> ";
252 
253  int simdur = 50;
254  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur);
255  sim.AddSource("uox").lifetime(1).Finalize(); // provide initial full batch
256  sim.AddSource("uox").start(9).lifetime(1).capacity(2).Finalize(); // provide partial batch post cycle-end
257  sim.AddSource("uox").start(15).Finalize(); // provide remainder of batch much later
258  sim.AddRecipe("uox", c_uox());
259  sim.AddRecipe("spentuox", c_spentuox());
260  int id = sim.Run();
261 
262  // check that we never got a full refueled batch during refuel period
263  std::vector<Cond> conds;
264  conds.push_back(Cond("Time", "<", 15));
265  QueryResult qr = sim.db().Query("Transactions", &conds);
266  EXPECT_EQ(5, qr.rows.size());
267 
268  // after being delayed past original scheduled start of new cycle, we got
269  // final assembly for core.
270  conds.clear();
271  conds.push_back(Cond("Time", "==", 15));
272  qr = sim.db().Query("Transactions", &conds);
273  EXPECT_EQ(1, qr.rows.size());
274 
275  // all during the next (delayed) cycle we shouldn't be requesting any new fuel
276  conds.clear();
277  conds.push_back(Cond("Time", "<", 21));
278  qr = sim.db().Query("Transactions", &conds);
279  EXPECT_EQ(6, qr.rows.size());
280 
281  // as soon as this delayed cycle ends, we should be requesting/getting 3 new batches
282  conds.clear();
283  conds.push_back(Cond("Time", "==", 22));
284  qr = sim.db().Query("Transactions", &conds);
285  EXPECT_EQ(3, qr.rows.size());
286 }
287 
288 // tests that discharged fuel is transmuted properly immediately at cycle end.
289 TEST(ReactorTests, DischargedFuelTransmute) {
290  std::string config =
291  " <fuel_inrecipes> <val>uox</val> </fuel_inrecipes> "
292  " <fuel_outrecipes> <val>spentuox</val> </fuel_outrecipes> "
293  " <fuel_incommods> <val>uox</val> </fuel_incommods> "
294  " <fuel_outcommods> <val>waste</val> </fuel_outcommods> "
295  ""
296  " <cycle_time>4</cycle_time> "
297  " <refuel_time>3</refuel_time> "
298  " <assem_size>1</assem_size> "
299  " <n_assem_core>1</n_assem_core> "
300  " <n_assem_batch>1</n_assem_batch> ";
301 
302  int simdur = 7;
303  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur);
304  sim.AddSource("uox").Finalize();
305  sim.AddSink("waste").Finalize();
306  sim.AddRecipe("uox", c_uox());
307  Composition::Ptr spentuox = c_spentuox();
308  sim.AddRecipe("spentuox", spentuox);
309  int id = sim.Run();
310 
311  std::vector<Cond> conds;
312  conds.push_back(Cond("SenderId", "==", id));
313  int resid = sim.db().Query("Transactions", &conds).GetVal<int>("ResourceId");
314  Material::Ptr m = sim.GetMaterial(resid);
315  MatQuery mq(m);
316  EXPECT_EQ(spentuox->id(), m->comp()->id());
317  EXPECT_TRUE(mq.mass(942390000) > 0) << "transmuted spent fuel doesn't have Pu239";
318 }
319 
320 // tests that spent fuel is offerred on correct commods according to the
321 // incommod it was received on - esp when dealing with multiple fuel commods
322 // simultaneously.
323 TEST(ReactorTests, SpentFuelProperCommodTracking) {
324  std::string config =
325  " <fuel_inrecipes> <val>uox</val> <val>mox</val> </fuel_inrecipes> "
326  " <fuel_outrecipes> <val>spentuox</val> <val>spentmox</val> </fuel_outrecipes> "
327  " <fuel_incommods> <val>uox</val> <val>mox</val> </fuel_incommods> "
328  " <fuel_outcommods> <val>waste1</val> <val>waste2</val> </fuel_outcommods> "
329  ""
330  " <cycle_time>1</cycle_time> "
331  " <refuel_time>0</refuel_time> "
332  " <assem_size>1</assem_size> "
333  " <n_assem_core>3</n_assem_core> "
334  " <n_assem_batch>3</n_assem_batch> ";
335 
336  int simdur = 7;
337  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur);
338  sim.AddSource("uox").capacity(1).Finalize();
339  sim.AddSource("mox").capacity(2).Finalize();
340  sim.AddSink("waste1").Finalize();
341  sim.AddSink("waste2").Finalize();
342  sim.AddRecipe("uox", c_uox());
343  sim.AddRecipe("spentuox", c_spentuox());
344  sim.AddRecipe("mox", c_mox());
345  sim.AddRecipe("spentmox", c_spentmox());
346  int id = sim.Run();
347 
348  std::vector<Cond> conds;
349  conds.push_back(Cond("SenderId", "==", id));
350  conds.push_back(Cond("Commodity", "==", std::string("waste1")));
351  QueryResult qr = sim.db().Query("Transactions", &conds);
352  EXPECT_EQ(simdur-1, qr.rows.size());
353 
354  conds[1] = Cond("Commodity", "==", std::string("waste2"));
355  qr = sim.db().Query("Transactions", &conds);
356  EXPECT_EQ(2*(simdur-1), qr.rows.size());
357 }
358 
359 // The user can optionally omit fuel preferences. In the case where
360 // preferences are adjusted, the ommitted preference vector must be populated
361 // with default values - if it wasn't then preferences won't be adjusted
362 // correctly and the reactor could segfault. Check that this doesn't happen.
363 TEST(ReactorTests, PrefChange) {
364  // it is important that the fuel_prefs not be present in the config below.
365  std::string config =
366  " <fuel_inrecipes> <val>lwr_fresh</val> </fuel_inrecipes> "
367  " <fuel_outrecipes> <val>lwr_spent</val> </fuel_outrecipes> "
368  " <fuel_incommods> <val>enriched_u</val> </fuel_incommods> "
369  " <fuel_outcommods> <val>waste</val> </fuel_outcommods> "
370  ""
371  " <cycle_time>1</cycle_time> "
372  " <refuel_time>0</refuel_time> "
373  " <assem_size>300</assem_size> "
374  " <n_assem_core>1</n_assem_core> "
375  " <n_assem_batch>1</n_assem_batch> "
376  ""
377  " <pref_change_times> <val>25</val> </pref_change_times>"
378  " <pref_change_commods> <val>enriched_u</val> </pref_change_commods>"
379  " <pref_change_values> <val>-1</val> </pref_change_values>";
380 
381  int simdur = 50;
382  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur);
383  sim.AddSource("enriched_u").Finalize();
384  sim.AddRecipe("lwr_fresh", c_uox());
385  sim.AddRecipe("lwr_spent", c_spentuox());
386  int id = sim.Run();
387 
388  QueryResult qr = sim.db().Query("Transactions", NULL);
389  EXPECT_EQ(25, qr.rows.size()) << "failed to adjust preferences properly";
390 }
391 
392 TEST(ReactorTests, RecipeChange) {
393  // it is important that the fuel_prefs not be present in the config below.
394  std::string config =
395  " <fuel_inrecipes> <val>lwr_fresh</val> </fuel_inrecipes> "
396  " <fuel_outrecipes> <val>lwr_spent</val> </fuel_outrecipes> "
397  " <fuel_incommods> <val>enriched_u</val> </fuel_incommods> "
398  " <fuel_outcommods> <val>waste</val> </fuel_outcommods> "
399  ""
400  " <cycle_time>1</cycle_time> "
401  " <refuel_time>0</refuel_time> "
402  " <assem_size>300</assem_size> "
403  " <n_assem_core>1</n_assem_core> "
404  " <n_assem_batch>1</n_assem_batch> "
405  ""
406  " <recipe_change_times> <val>25</val> <val>35</val> </recipe_change_times>"
407  " <recipe_change_commods> <val>enriched_u</val> <val>enriched_u</val> </recipe_change_commods>"
408  " <recipe_change_in> <val>water</val> <val>water</val> </recipe_change_in>"
409  " <recipe_change_out> <val>lwr_spent</val> <val>water</val> </recipe_change_out>";
410 
411  int simdur = 50;
412  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur);
413  sim.AddSource("enriched_u").Finalize();
414  sim.AddSink("waste").Finalize();
415  sim.AddRecipe("lwr_fresh", c_uox());
416  sim.AddRecipe("lwr_spent", c_spentuox());
417  sim.AddRecipe("water", c_water());
418  int aid = sim.Run();
419 
420  std::vector<Cond> conds;
421  QueryResult qr;
422 
423  // check that received recipe is not water
424  conds.clear();
425  conds.push_back(Cond("Time", "==", 24));
426  conds.push_back(Cond("ReceiverId", "==", aid));
427  qr = sim.db().Query("Transactions", &conds);
428  MatQuery mq = MatQuery(sim.GetMaterial(qr.GetVal<int>("ResourceId")));
429 
430  EXPECT_TRUE(0 < mq.qty());
431  EXPECT_TRUE(0 == mq.mass(id("H1")));
432 
433  // check that received recipe changed to water
434  conds.clear();
435  conds.push_back(Cond("Time", "==", 26));
436  conds.push_back(Cond("ReceiverId", "==", aid));
437  qr = sim.db().Query("Transactions", &conds);
438  mq = MatQuery(sim.GetMaterial(qr.GetVal<int>("ResourceId")));
439 
440  EXPECT_TRUE(0 < mq.qty());
441  EXPECT_TRUE(0 < mq.mass(id("H1")));
442 
443  // check that sent recipe is not water
444  conds.clear();
445  conds.push_back(Cond("Time", "==", 34));
446  conds.push_back(Cond("SenderId", "==", aid));
447  qr = sim.db().Query("Transactions", &conds);
448  mq = MatQuery(sim.GetMaterial(qr.GetVal<int>("ResourceId")));
449 
450  EXPECT_TRUE(0 < mq.qty());
451  EXPECT_TRUE(0 == mq.mass(id("H1")));
452 
453  // check that sent recipe changed to water
454  conds.clear();
455  conds.push_back(Cond("Time", "==", 36));
456  conds.push_back(Cond("SenderId", "==", aid));
457  qr = sim.db().Query("Transactions", &conds);
458  mq = MatQuery(sim.GetMaterial(qr.GetVal<int>("ResourceId")));
459 
460  EXPECT_TRUE(0 < mq.qty());
461  EXPECT_TRUE(0 < mq.mass(id("H1")));
462 }
463 
464 TEST(ReactorTests, Retire) {
465  std::string config =
466  " <fuel_inrecipes> <val>lwr_fresh</val> </fuel_inrecipes> "
467  " <fuel_outrecipes> <val>lwr_spent</val> </fuel_outrecipes> "
468  " <fuel_incommods> <val>enriched_u</val> </fuel_incommods> "
469  " <fuel_outcommods> <val>waste</val> </fuel_outcommods> "
470  ""
471  " <cycle_time>7</cycle_time> "
472  " <refuel_time>0</refuel_time> "
473  " <assem_size>300</assem_size> "
474  " <n_assem_fresh>1</n_assem_fresh> "
475  " <n_assem_core>3</n_assem_core> "
476  " <n_assem_batch>1</n_assem_batch> "
477  " <power_cap>1</power_cap> "
478  "";
479 
480  int dur = 50;
481  int life = 36;
482  int cycle_time = 7;
483  int refuel_time = 0;
484  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, dur, life);
485  sim.AddSource("enriched_u").Finalize();
486  sim.AddSink("waste").Finalize();
487  sim.AddRecipe("lwr_fresh", c_uox());
488  sim.AddRecipe("lwr_spent", c_spentuox());
489  int id = sim.Run();
490 
491  int ncore = 3;
492  int nbatch = 1;
493 
494  // reactor should stop requesting new fresh fuel as it approaches retirement
495  int nassem_recv =
496  static_cast<int>(ceil(static_cast<double>(life) / 7.0)) * nbatch +
497  (ncore - nbatch);
498 
499  std::vector<Cond> conds;
500  conds.push_back(Cond("ReceiverId", "==", id));
501  QueryResult qr = sim.db().Query("Transactions", &conds);
502  EXPECT_EQ(nassem_recv, qr.rows.size())
503  << "failed to stop ordering near retirement";
504 
505  // reactor should discharge all fuel before/by retirement
506  conds.clear();
507  conds.push_back(Cond("SenderId", "==", id));
508  qr = sim.db().Query("Transactions", &conds);
509  EXPECT_EQ(nassem_recv, qr.rows.size())
510  << "failed to discharge all material by retirement time";
511 
512  // reactor should record power entry on the time step it retires if operating
513  int time_online = life / (cycle_time + refuel_time) * cycle_time + std::min(life % (cycle_time + refuel_time), cycle_time);
514  conds.clear();
515  conds.push_back(Cond("AgentId", "==", id));
516  conds.push_back(Cond("Value", ">", 0));
517  qr = sim.db().Query("TimeSeriesPower", &conds);
518  EXPECT_EQ(time_online, qr.rows.size())
519  << "failed to generate power for the correct number of time steps";
520 }
521 
522 } // namespace reactortests
523 } // namespace cycamore
524 
cycamore::GrowthRegion string
TEST(ReactorTests, JustInTimeOrdering)