CYCAMORE
Loading...
Searching...
No Matches
src/enrichment_tests.cc
Go to the documentation of this file.
1#include <gtest/gtest.h>
2
3#include <sstream>
4
5#include "facility_tests.h"
6#include "toolkit/mat_query.h"
7#include "agent_tests.h"
8#include "resource_helpers.h"
9#include "infile_tree.h"
10#include "env.h"
11
12#include "enrichment_tests.h"
13
14using cyclus::QueryResult;
15using cyclus::Cond;
16using cyclus::CompMap;
17using cyclus::Material;
18using pyne::nucname::id;
19
20namespace cycamore {
21
22Composition::Ptr c_nou235() {
23 CompMap m;
24 m[922380000] = 1.0;
25 return Composition::CreateFromMass(m);
26};
27Composition::Ptr c_natu1() {
28 CompMap m;
29 m[922350000] = 0.007;
30 m[922380000] = 0.993;
31 return Composition::CreateFromMass(m);
32};
33Composition::Ptr c_natu2() {
34 CompMap m;
35 m[922350000] = 0.01;
36 m[922380000] = 0.99;
37 return Composition::CreateFromMass(m);
38};
39Composition::Ptr c_leu() {
40 CompMap m;
41 m[922350000] = 0.04;
42 m[922380000] = 0.96;
43 return Composition::CreateFromMass(m);
44};
45Composition::Ptr c_heu() {
46 CompMap m;
47 m[922350000] = 0.20;
48 m[922380000] = 0.80;
49 return Composition::CreateFromMass(m);
50};
51
52// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
53TEST_F(EnrichmentTest, RequestQty) {
54 // this tests verifies that requests for input material are fulfilled
55 // without providing any extra
56
57 std::string config =
58 " <feed_commod>natu</feed_commod> "
59 " <feed_recipe>natu1</feed_recipe> "
60 " <product_commod>enr_u</product_commod> "
61 " <tails_commod>tails</tails_commod> "
62 " <max_feed_inventory>1.0</max_feed_inventory> "
63 " <tails_assay>0.003</tails_assay> ";
64
65 int simdur = 1;
66 cyclus::MockSim sim(cyclus::AgentSpec
67 (":cycamore:Enrichment"), config, simdur);
68 sim.AddRecipe("natu1", c_natu1());
69
70 sim.AddSource("natu")
71 .recipe("natu1")
72 .Finalize();
73
74 int id = sim.Run();
75
76 std::vector<Cond> conds;
77 conds.push_back(Cond("Commodity", "==", std::string("natu")));
78 QueryResult qr = sim.db().Query("Transactions", &conds);
79 Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));
80
81 // Should be only one transaction into the EF,
82 // and it should be exactly 1kg of natu
83 EXPECT_EQ(1.0, qr.rows.size());
84 EXPECT_NEAR(1.0, m->quantity(), cyclus::CY_NEAR_ZERO) <<
85 "matched trade provides the wrong quantity of material";
86}
87
88// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
89TEST_F(EnrichmentTest, CheckSWUConstraint) {
90 // Tests that request for enrichment that exceeds the SWU constraint
91 // fulfilled only up to the available SWU.
92 // Also confirms that initial_feed flag works.
93 // 388 SWU = 10kg 80% enriched HEU from 486kg feed matl
94
95 std::string config =
96 " <feed_commod>natu</feed_commod> "
97 " <feed_recipe>natu1</feed_recipe> "
98 " <product_commod>enr_u</product_commod> "
99 " <tails_commod>tails</tails_commod> "
100 " <tails_assay>0.003</tails_assay> "
101 " <initial_feed>1000</initial_feed> "
102 " <swu_capacity>195</swu_capacity> ";
103
104 int simdur = 1;
105
106 cyclus::MockSim sim(cyclus::AgentSpec
107 (":cycamore:Enrichment"), config, simdur);
108
109 sim.AddRecipe("natu1", c_natu1());
110 sim.AddRecipe("heu", c_heu());
111
112 sim.AddSink("enr_u")
113 .recipe("heu")
114 .capacity(10)
115 .Finalize();
116
117 int id = sim.Run();
118
119 std::vector<Cond> conds;
120 conds.push_back(Cond("Commodity", "==", std::string("enr_u")));
121 QueryResult qr = sim.db().Query("Transactions", &conds);
122 Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));
123
124 EXPECT_EQ(1.0, qr.rows.size());
125 EXPECT_NEAR(5.0, m->quantity(), 0.1) <<
126 "traded quantity exceeds SWU constraint";
127}
128
129// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
130TEST_F(EnrichmentTest, CheckCapConstraint) {
131 // Tests that a request for more material than is available in
132 // inventory is partially filled with only the inventory quantity.
133
134 std::string config =
135 " <feed_commod>natu</feed_commod> "
136 " <feed_recipe>natu1</feed_recipe> "
137 " <product_commod>enr_u</product_commod> "
138 " <tails_commod>tails</tails_commod> "
139 " <tails_assay>0.003</tails_assay> "
140 " <initial_feed>243</initial_feed> ";
141
142 int simdur = 1;
143
144 cyclus::MockSim sim(cyclus::AgentSpec
145 (":cycamore:Enrichment"), config, simdur);
146
147
148 sim.AddRecipe("natu1", c_natu1());
149 sim.AddRecipe("heu", c_heu());
150
151 sim.AddSink("enr_u")
152 .recipe("heu")
153 .capacity(10)
154 .Finalize();
155
156 int id = sim.Run();
157
158 std::vector<Cond> conds;
159 conds.push_back(Cond("Commodity", "==", std::string("enr_u")));
160 QueryResult qr = sim.db().Query("Transactions", &conds);
161 Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));
162
163 EXPECT_EQ(1.0, qr.rows.size());
164 EXPECT_LE(m->quantity(), 5.0) <<
165 "traded quantity exceeds capacity constraint";
166}
167
168// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
169TEST_F(EnrichmentTest, RequestEnrich) {
170 // this tests verifies that requests for output material exceeding
171 // the maximum allowed enrichment are not fulfilled.
172
173 std::string config =
174 " <feed_commod>natu</feed_commod> "
175 " <feed_recipe>natu1</feed_recipe> "
176 " <product_commod>enr_u</product_commod> "
177 " <tails_commod>tails</tails_commod> "
178 " <tails_assay>0.003</tails_assay> "
179 " <max_enrich>0.19</max_enrich> ";
180
181 int simdur = 2;
182 cyclus::MockSim sim(cyclus::AgentSpec
183 (":cycamore:Enrichment"), config, simdur);
184 sim.AddRecipe("natu1", c_natu1());
185 sim.AddRecipe("leu", c_leu());
186 sim.AddRecipe("heu", c_heu());
187
188 sim.AddSource("natu")
189 .recipe("natu1")
190 .Finalize();
191 sim.AddSink("enr_u")
192 .recipe("leu")
193 .capacity(1.0)
194 .Finalize();
195 sim.AddSink("enr_u")
196 .recipe("heu")
197 .Finalize();
198
199 int id = sim.Run();
200
201 std::vector<Cond> conds;
202 conds.push_back(Cond("Commodity", "==", std::string("enr_u")));
203 QueryResult qr = sim.db().Query("Transactions", &conds);
204 Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));
205
206 // Should be only one transaction out of the EF,
207 // and it should be 1kg of LEU
208 EXPECT_EQ(1.0, qr.rows.size());
209 EXPECT_NEAR(1.0, m->quantity(), 0.01) <<
210 "Not providing the requested quantity" ;
211
212 CompMap got = m->comp()->mass();
213 CompMap want = c_leu()->mass();
214 cyclus::compmath::Normalize(&got);
215 cyclus::compmath::Normalize(&want);
216
217 CompMap::iterator it;
218 for (it = want.begin(); it != want.end(); ++it) {
219 EXPECT_DOUBLE_EQ(it->second, got[it->first]) <<
220 "nuclide qty off: " << pyne::nucname::name(it->first);
221 }
222}
223
224// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
225TEST_F(EnrichmentTest, TradeTails) {
226 // this tests whether tails are being traded.
227
228 std::string config =
229 " <feed_commod>natu</feed_commod> "
230 " <feed_recipe>natu1</feed_recipe> "
231 " <product_commod>enr_u</product_commod> "
232 " <tails_commod>tails</tails_commod> "
233 " <tails_assay>0.003</tails_assay> ";
234
235 // time 1-source to EF, 2-Enrich, add to tails, 3-tails avail. for trade
236 int simdur = 3;
237 cyclus::MockSim sim(cyclus::AgentSpec
238 (":cycamore:Enrichment"), config, simdur);
239 sim.AddRecipe("natu1", c_natu1());
240 sim.AddRecipe("leu", c_leu());
241
242 sim.AddSource("natu")
243 .recipe("natu1")
244 .Finalize();
245 sim.AddSink("enr_u")
246 .recipe("leu")
247 .Finalize();
248 sim.AddSink("tails")
249 .Finalize();
250
251 int id = sim.Run();
252
253 std::vector<Cond> conds;
254 conds.push_back(Cond("Commodity", "==", std::string("tails")));
255 QueryResult qr = sim.db().Query("Transactions", &conds);
256
257 // Should be exactly one tails transaction
258 EXPECT_EQ(1, qr.rows.size());
259
260}
261// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
262 TEST_F(EnrichmentTest, TailsQty) {
263 // this tests whether tails are being traded at correct quantity when
264 // requested amount is larger than qty in a single tails-buffer element
265
266 std::string config =
267 " <feed_commod>natu</feed_commod> "
268 " <feed_recipe>natu1</feed_recipe> "
269 " <product_commod>enr_u</product_commod> "
270 " <tails_commod>tails</tails_commod> "
271 " <tails_assay>0.003</tails_assay> ";
272
273 // time 1-source to EF, 2-Enrich, add to tails, 3-tails avail. for trade
274 int simdur = 3;
275 cyclus::MockSim sim(cyclus::AgentSpec
276 (":cycamore:Enrichment"), config, simdur);
277 sim.AddRecipe("natu1", c_natu1());
278 sim.AddRecipe("leu", c_leu());
279
280 sim.AddSource("natu")
281 .recipe("natu1")
282 .Finalize();
283 sim.AddSink("enr_u")
284 .recipe("leu")
285 .capacity(0.5)
286 .Finalize();
287 sim.AddSink("enr_u")
288 .recipe("leu")
289 .capacity(0.5)
290 .Finalize();
291 sim.AddSink("tails")
292 .Finalize();
293
294 int id = sim.Run();
295
296 std::vector<Cond> conds;
297 conds.push_back(Cond("Commodity", "==", std::string("tails")));
298 QueryResult qr = sim.db().Query("Transactions", &conds);
299 Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));
300
301 // Should be 2 tails transactions, one from each LEU sink, each 4.125kg.
302 // Q * (e_p - e_f)/(e_f - e_t) = 0.5 * (0.04 - 0.007)/(0.007 - 0.003) = 4.125
303 EXPECT_EQ(2, qr.rows.size());
304
305 cyclus::SqlStatement::Ptr stmt = sim.db().db().Prepare(
306 "SELECT SUM(r.Quantity) FROM Transactions AS t"
307 " INNER JOIN Resources AS r ON r.ResourceId = t.ResourceId"
308 " WHERE t.Commodity = ?;"
309 );
310
311 stmt->BindText(1, "tails");
312 stmt->Step();
313 EXPECT_NEAR(8.25,stmt->GetDouble(0), 0.01) <<
314 "Not providing the requested quantity" ;
315}
316
317// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
318TEST_F(EnrichmentTest, BidPrefs) {
319 // This tests that natu sources are preference-ordered by
320 // U235 content
321
322 std::string config =
323 " <feed_commod>natu</feed_commod> "
324 " <feed_recipe>natu1</feed_recipe> "
325 " <product_commod>enr_u</product_commod> "
326 " <tails_commod>tails</tails_commod> "
327 " <tails_assay>0.003</tails_assay> "
328 " <max_feed_inventory>1.0</max_feed_inventory> ";
329
330 int simdur = 1;
331 cyclus::MockSim sim(cyclus::AgentSpec
332 (":cycamore:Enrichment"), config, simdur);
333 sim.AddRecipe("natu1", c_natu1());
334 sim.AddRecipe("natu2", c_natu2());
335
336 sim.AddSource("natu")
337 .recipe("natu1")
338 .capacity(1)
339 .Finalize();
340
341 sim.AddSource("natu")
342 .recipe("natu2")
343 .capacity(1)
344 .Finalize();
345
346 int id = sim.Run();
347
348 std::vector<Cond> conds;
349 conds.push_back(Cond("Commodity", "==", std::string("natu")));
350 QueryResult qr = sim.db().Query("Transactions", &conds);
351
352 // should trade only with #2 since it has higher U235
353 EXPECT_EQ(1, qr.rows.size());
354
355 Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));
356 CompMap got = m->comp()->mass();
357 CompMap want = c_natu2()->mass();
358 cyclus::compmath::Normalize(&got);
359 cyclus::compmath::Normalize(&want);
360
361 CompMap::iterator it;
362 for (it = want.begin(); it != want.end(); ++it) {
363 EXPECT_DOUBLE_EQ(it->second, got[it->first]) <<
364 "nuclide qty off: " << pyne::nucname::name(it->first);
365 }
366
367}
368// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
369 TEST_F(EnrichmentTest, NoBidPrefs) {
370 // This tests that preference-ordering for sources
371 // turns off correctly if flag is used
372
373 std::string config =
374 " <feed_commod>natu</feed_commod> "
375 " <feed_recipe>natu1</feed_recipe> "
376 " <product_commod>enr_u</product_commod> "
377 " <tails_commod>tails</tails_commod> "
378 " <tails_assay>0.003</tails_assay> "
379 " <max_feed_inventory>2.0</max_feed_inventory> "
380 " <order_prefs>0</order_prefs> ";
381
382 int simdur = 1;
383 cyclus::MockSim sim(cyclus::AgentSpec
384 (":cycamore:Enrichment"), config, simdur);
385 sim.AddRecipe("natu1", c_natu1());
386 sim.AddRecipe("natu2", c_natu2());
387
388 sim.AddSource("natu")
389 .recipe("natu1")
390 .capacity(1)
391 .Finalize();
392
393 sim.AddSource("natu")
394 .recipe("natu2")
395 .capacity(1)
396 .Finalize();
397
398 int id = sim.Run();
399
400 std::vector<Cond> conds;
401 conds.push_back(Cond("Commodity", "==", std::string("natu")));
402 QueryResult qr = sim.db().Query("Transactions", &conds);
403
404 // should trade with both to meet its capacity limit
405 EXPECT_EQ(2, qr.rows.size());
406 }
407
408// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
409TEST_F(EnrichmentTest, ZeroU235) {
410 // Test that offers of natu with no u235 content are rejected
411
412 std::string config =
413 " <feed_commod>natu</feed_commod> "
414 " <feed_recipe>natu1</feed_recipe> "
415 " <product_commod>enr_u</product_commod> "
416 " <tails_commod>tails</tails_commod> "
417 " <tails_assay>0.003</tails_assay> "
418 " <max_feed_inventory>1.0</max_feed_inventory> ";
419
420 int simdur = 1;
421 cyclus::MockSim sim(cyclus::AgentSpec
422 (":cycamore:Enrichment"), config, simdur);
423 sim.AddRecipe("no_u235", c_nou235());
424 sim.AddRecipe("natu1", c_natu1());
425
426 sim.AddSource("natu")
427 .recipe("no_u235")
428 .capacity(1)
429 .Finalize();
430
431 int id = sim.Run();
432
433 std::vector<Cond> conds;
434 conds.push_back(Cond("Commodity", "==", std::string("natu")));
435 // DB table should be empty since there are no transactions
436 EXPECT_THROW(sim.db().Query("Transactions", &conds),
437 std::exception);
438}
439
440// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
442 cyclus::Env::SetNucDataPath();
443 cyclus::Context* ctx = tc_.get();
444 src_facility = new Enrichment(ctx);
445 trader = tc_.trader();
447 SetUpSource();
448}
449
450// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
452 delete src_facility;
453}
454
455// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
457 cyclus::Context* ctx = tc_.get();
458
459 feed_commod = "incommod";
460 product_commod = "outcommod";
461 tails_commod = "tailscommod";
462
463 feed_recipe = "recipe";
464 feed_assay = 0.0072;
465
466 CompMap v;
467 v[922350000] = feed_assay;
468 v[922380000] = 1 - feed_assay;
469 recipe = cyclus::Composition::CreateFromMass(v);
470 ctx->AddRecipe(feed_recipe, recipe);
471
472 tails_assay = 0.002;
473 swu_capacity = 100; //**
474 inv_size = 5;
475
476 reserves = 105.5;
477}
478
479// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
490}
491
492// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
493Material::Ptr EnrichmentTest::GetMat(double qty) {
494 return Material::CreateUntracked(qty,
495 tc_.get()->GetRecipe(feed_recipe));
496}
497
498// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
499void EnrichmentTest::DoAddMat(Material::Ptr mat) {
500 src_facility->AddMat_(mat);
501}
502
503// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
504Material::Ptr EnrichmentTest::DoRequest() {
505 return src_facility->Request_();
506}
507
508// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
509Material::Ptr
510EnrichmentTest::DoOffer(Material::Ptr mat) {
511 return src_facility->Offer_(mat);
512}
513
514// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
515Material::Ptr
516EnrichmentTest::DoEnrich(Material::Ptr mat, double qty) {
517 return src_facility->Enrich_(mat, qty);
518}
519
520// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
521TEST_F(EnrichmentTest, Request) {
522 // Tests that quantity in material request is accurate
523 double req = inv_size;
524 double add = 0;
525 Material::Ptr mat = DoRequest();
526 EXPECT_DOUBLE_EQ(mat->quantity(), req);
527 EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(feed_recipe));
528
529 add = 2 * inv_size / 3;
530 req -= add;
531 DoAddMat(GetMat(add));
532 mat = DoRequest();
533 EXPECT_DOUBLE_EQ(mat->quantity(), req);
534 EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(feed_recipe));
535
536 add = inv_size / 3;
537 req = 0;
538 DoAddMat(GetMat(add));
539 mat = DoRequest();
540 EXPECT_DOUBLE_EQ(mat->quantity(), req);
541 EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(feed_recipe));
542}
543
544// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
545TEST_F(EnrichmentTest, ValidReq) {
546 // Tests that material requests have U235/(U235+U238) > tails assay
547 using cyclus::Composition;
548
549 double qty = 4.5; // some magic number
550
551 CompMap v1;
552 v1[922350000] = 1;
553 Material::Ptr mat = Material::CreateUntracked
554 (qty,Composition::CreateFromAtom(v1));
555 EXPECT_FALSE(src_facility->ValidReq(mat)); // u238 = 0
556
557 CompMap v2;
558 v2[922350000] = tails_assay;
559 v2[922380000] = 1 - tails_assay;
560 mat = Material::CreateUntracked(qty, Composition::CreateFromAtom(v2));
561 // u235 / (u235 + u238) <= tails_assay
562 EXPECT_FALSE(src_facility->ValidReq(mat));
563
564 CompMap v3;
565 v3[922350000] = 1;
566 v3[922380000] = 1;
567 mat = Material::CreateUntracked(qty, Composition::CreateFromAtom(v3));
568 EXPECT_TRUE(src_facility->ValidReq(mat)); // valid
569}
570
571// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
572 TEST_F(EnrichmentTest, ConstraintConverters) {
573 // Tests the SWU and NatU converters to make sure that amount of
574 // feed and SWU required are correct to fulfill the enrichment request.
575 using cyclus::toolkit::MatQuery;
576 using cyclus::Composition;
577
578 cyclus::Env::SetNucDataPath();
579
580 double qty = 5; // 5 kg
581 double product_assay = 0.05; // of 5 w/o enriched U
582 CompMap v;
583 v[922350000] = product_assay;
584 v[922380000] = 1 - product_assay;
585 v[94239] = 0.5; // 94239 shouldn't be taken into account
586 Material::Ptr target = Material::CreateUntracked(
587 qty, Composition::CreateFromMass(v));
588
589 std::set<cyclus::Nuc> nucs;
590 nucs.insert(922350000);
591 nucs.insert(922380000);
592
593 MatQuery mq(target);
594 double mass_frac = mq.mass_frac(nucs);
595
596 SWUConverter swuc(feed_assay, tails_assay);
597 NatUConverter natuc(feed_assay, tails_assay);
598
599 Material::Ptr offer = DoOffer(target);
600
601 EXPECT_NEAR(swuc.convert(target), swuc.convert(offer), 0.001);
602 EXPECT_NEAR(natuc.convert(target) * mass_frac, natuc.convert(offer), 0.001);
603}
604
605// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
606TEST_F(EnrichmentTest, Enrich) {
607 // this test asks the facility to enrich a material that results in an amount
608 // of natural uranium required that is exactly its inventory level. that
609 // inventory will be comprised of two materials to test the manifest/absorb
610 // strategy employed in Enrich_.
611 using cyclus::toolkit::MatQuery;
612 using cyclus::Composition;
613 using cyclus::toolkit::Assays;
614 using cyclus::toolkit::UraniumAssayMass;
615 using cyclus::toolkit::SwuRequired;
616 using cyclus::toolkit::FeedQty;
617
618 double qty = 5; // kg
619 double product_assay = 0.05; // of 5 w/o enriched U
620 CompMap v;
621 v[922350000] = product_assay;
622 v[922380000] = 1 - product_assay;
623 // target qty need not be = to request qty
624 Material::Ptr target = Material::CreateUntracked(
625 qty + 10, Composition::CreateFromMass(v));
626
627 Assays assays(feed_assay, UraniumAssayMass(target), tails_assay);
628 double swu_req = SwuRequired(qty, assays);
629 double natu_req = FeedQty(qty, assays);
630 double tails_qty = TailsQty(qty, assays);
631
632 double swu_cap = swu_req * 5;
633 src_facility->SwuCapacity(swu_cap);
634 src_facility->SetMaxInventorySize(natu_req);
635 DoAddMat(GetMat(natu_req / 2));
636 DoAddMat(GetMat(natu_req / 2));
637
638 Material::Ptr response;
639 EXPECT_NO_THROW(response = DoEnrich(target, qty));
640 EXPECT_DOUBLE_EQ(src_facility->Tails().quantity(), tails_qty);
641
642 MatQuery q(response);
643 EXPECT_EQ(response->quantity(), qty);
644 EXPECT_EQ(q.mass_frac(922350000), product_assay);
645 EXPECT_EQ(q.mass_frac(922380000), 1 - product_assay);
646
647 // test too much natu request
648 DoAddMat(GetMat(natu_req - 1));
649 EXPECT_THROW(response = DoEnrich(target, qty), cyclus::Error);
650}
651
652// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
653TEST_F(EnrichmentTest, Response) {
654 // this test asks the facility to respond to multiple requests for enriched
655 // uranium. two requests are provided, whose total equals the swu capacity of
656 // the facility while not exceeding its inventory capacity (that's taken care
657 // of in the Enrich tests).
658 //
659 // note that response quantity and quality need not be tested, because they
660 // are covered by the Enrich and RequestEnrich tests
661 using cyclus::Bid;
662 using cyclus::Request;
663 using cyclus::Trade;
664 using cyclus::toolkit::Assays;
665 using cyclus::toolkit::FeedQty;
666 using cyclus::toolkit::SwuRequired;
667 using cyclus::toolkit::UraniumAssayMass;
668
669 // problem set up
670 std::vector< Trade<Material> > trades;
671 std::vector<std::pair<Trade<Material>,
672 Material::Ptr> > responses;
673
674 double qty = 5; // kg
675 double trade_qty = qty / 3;
676 double product_assay = 0.05; // of 5 w/o enriched U
677
678 CompMap v;
679 v[922350000] = product_assay;
680 v[922380000] = 1 - product_assay;
681 // target qty need not be = to request qty
682 Material::Ptr target = Material::CreateUntracked(
683 qty + 10, cyclus::Composition::CreateFromMass(v));
684
685 Assays assays(feed_assay, UraniumAssayMass(target), tails_assay);
686 double swu_req = SwuRequired(qty, assays);
687 double natu_req = FeedQty(qty, assays);
688
689 src_facility->SetMaxInventorySize(natu_req * 4); // not capacitated by nat
690 src_facility->SwuCapacity(swu_req); // swu capacitated
691
692 src_facility->GetMatlTrades(trades, responses);
693
694 // set up state
695 DoAddMat(GetMat(natu_req * 2));
696
697 src_facility->GetMatlTrades(trades, responses);
698
699 Request<Material>* req =
700 Request<Material>::Create(target, trader, product_commod);
701 Bid<Material>* bid = Bid<Material>::Create(req, target, src_facility);
702 Trade<Material> trade(req, bid, trade_qty);
703 trades.push_back(trade);
704
705 // 2 trades, SWU = SWU cap
706 ASSERT_GT(src_facility->SwuCapacity() - 2 * swu_req / 3,
707 -1 * cyclus::eps());
708 trades.push_back(trade);
709 responses.clear();
710 EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses));
711 EXPECT_EQ(responses.size(), 2);
712}
713
714// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
715TEST_F(EnrichmentTest, PositionInitialize) {
716 // this tests verifies the initialization of the latitude variable
717
718 std::string config =
719 " <feed_commod>natu</feed_commod> "
720 " <feed_recipe>natu1</feed_recipe> "
721 " <product_commod>enr_u</product_commod> "
722 " <tails_commod>tails</tails_commod> "
723 " <max_feed_inventory>1.0</max_feed_inventory> "
724 " <tails_assay>0.003</tails_assay> ";
725
726 int simdur = 1;
727 cyclus::MockSim sim(cyclus::AgentSpec
728 (":cycamore:Enrichment"), config, simdur);
729 sim.AddRecipe("natu1", c_natu1());
730
731 sim.AddSource("natu")
732 .recipe("natu1")
733 .Finalize();
734
735 int id = sim.Run();
736
737 QueryResult qr = sim.db().Query("AgentPosition", NULL);
738 EXPECT_EQ(qr.GetVal<double>("Latitude"), 0.0);
739 EXPECT_EQ(qr.GetVal<double>("Longitude"), 0.0);
740}
741
742TEST_F(EnrichmentTest, PositionInitialize2) {
743 // this tests verifies the initialization of the longitude
744 // variable
745
746 std::string config =
747 " <feed_commod>natu</feed_commod> "
748 " <feed_recipe>natu1</feed_recipe> "
749 " <product_commod>enr_u</product_commod> "
750 " <tails_commod>tails</tails_commod> "
751 " <max_feed_inventory>1.0</max_feed_inventory> "
752 " <tails_assay>0.003</tails_assay> "
753 " <latitude>50.0</latitude> "
754 " <longitude>35.0</longitude> ";
755
756 int simdur = 1;
757 cyclus::MockSim sim(cyclus::AgentSpec
758 (":cycamore:Enrichment"), config, simdur);
759 sim.AddRecipe("natu1", c_natu1());
760
761 sim.AddSource("natu")
762 .recipe("natu1")
763 .Finalize();
764
765 int id = sim.Run();
766
767 QueryResult qr = sim.db().Query("AgentPosition", NULL);
768 EXPECT_EQ(qr.GetVal<double>("Latitude"), 50.0);
769 EXPECT_EQ(qr.GetVal<double>("Longitude"), 35.0);
770}
771
772
773} // namespace cycamore
774
775// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
776cyclus::Agent* EnrichmentConstructor(cyclus::Context* ctx) {
777 return new cycamore::Enrichment(ctx);
778}
779
780// required to get functionality in cyclus agent unit tests library
781#ifndef CYCLUS_AGENT_TESTS_CONNECTED
784#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected
785#endif // CYCLUS_AGENT_TESTS_CONNECTED
786
787// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
788INSTANTIATE_TEST_SUITE_P(EnrichmentFac, FacilityTests,
789 Values(&EnrichmentConstructor));
790INSTANTIATE_TEST_SUITE_P(EnrichmentFac, AgentTests,
791 Values(&EnrichmentConstructor));
cyclus::Material::Ptr DoOffer(cyclus::Material::Ptr mat)
cyclus::Material::Ptr DoEnrich(cyclus::Material::Ptr mat, double qty)
cyclus::Material::Ptr GetMat(double qty)
void DoAddMat(cyclus::Material::Ptr mat)
The Enrichment facility is a simple Agent that enriches natural uranium in a Cyclus simulation.
cyclus::Material::Ptr Request_()
generates a request for this facility given its current state.
void SwuCapacity(double capacity)
cyclus::Material::Ptr Enrich_(cyclus::Material::Ptr mat, double qty)
cyclus::Material::Ptr Offer_(cyclus::Material::Ptr req)
Generates a material offer for a given request.
void SetMaxInventorySize(double size)
void AddMat_(cyclus::Material::Ptr mat)
adds a material into the natural uranium inventory
Composition::Ptr c_natu2()
Composition::Ptr c_heu()
Composition::Ptr c_nou235()
Composition::Ptr c_natu1()
TEST_F(EnrichmentTest, RequestQty)
Composition::Ptr c_leu()
static int cyclus_agent_tests_connected
INSTANTIATE_TEST_SUITE_P(EnrichmentFac, FacilityTests, Values(&EnrichmentConstructor))
cyclus::Agent * EnrichmentConstructor(cyclus::Context *ctx)
int ConnectAgentTests()