CYCAMORE
src/mixer_tests.cc
Go to the documentation of this file.
1 #include "mixer.h"
2 
3 #include "agent_tests.h"
4 #include "context.h"
5 #include "cyclus.h"
6 #include "equality_helpers.h"
7 #include "facility_tests.h"
8 
9 #include <gtest/gtest.h>
10 
11 using cyclus::QueryResult;
12 
13 namespace cycamore {
14 
15 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
16 
17 typedef std::vector<
18  std::pair<std::pair<double, double>, std::map<std::string, double> > >
19  t_instream;
20 
21 cyclus::Composition::Ptr c_pustream() {
22  using pyne::nucname::id;
23 
24  cyclus::CompMap m;
25  m[id("pu239")] = 100;
26  m[id("pu240")] = 10;
27  m[id("pu241")] = 1;
28  m[id("pu242")] = 1;
29  return cyclus::Composition::CreateFromMass(m);
30 };
31 
32 cyclus::Composition::Ptr c_natu() {
33  using pyne::nucname::id;
34 
35  cyclus::CompMap m;
36  m[id("u235")] = 0.007;
37  m[id("u238")] = 0.993;
38  return cyclus::Composition::CreateFromMass(m);
39 };
40 
41 cyclus::Composition::Ptr c_uox() {
42  using pyne::nucname::id;
43 
44  cyclus::CompMap m;
45  m[id("u235")] = 0.04;
46  m[id("u238")] = 0.96;
47  return cyclus::Composition::CreateFromMass(m);
48 };
49 
50 class MixerTest : public ::testing::Test {
51  public:
52  typedef cyclus::toolkit::ResBuf<cyclus::Material> InvBuffer;
53 
54  cyclus::TestContext tc_;
56 
57  virtual void SetUp() {
58  mf_facility_ = new Mixer(tc_.get());
59 
60  std::vector<std::map<std::string, double> > in_commods;
61  {
62  std::map<std::string, double> in_com;
63  in_com.insert(std::pair<std::string, double>("in_c1", 1));
64  in_commods.push_back(in_com);
65  }
66  {
67  std::map<std::string, double> in_com;
68  in_com.insert(std::pair<std::string, double>("in_c2", 1));
69  in_commods.push_back(in_com);
70  }
71  {
72  std::map<std::string, double> in_com;
73  in_com.insert(std::pair<std::string, double>("in_c3", 1));
74  in_commods.push_back(in_com);
75  }
76 
77  std::vector<double> in_ratios = {1, 1, 1};
78  std::vector<double> in_caps = {30, 20, 10};
79  SetIn_stream(in_commods, in_ratios, in_caps);
80 
81  SetOutStream_comds("out_com");
82  }
83  virtual void TearDown() { delete mf_facility_; }
84 
85  std::vector<std::map<std::string, double> > in_coms;
86  std::vector<double> in_frac;
87  std::vector<double> in_cap;
88 
90  double out_cap;
91 
92  double throughput;
93 
94  void SetThroughput(double thpt) {
95  throughput = thpt;
96  mf_facility_->throughput = thpt;
97  }
98 
99  void SetIn_stream(t_instream streams) {
100  mf_facility_->streams_ = streams;
101 
102  in_frac.clear();
103  in_cap.clear();
104  for (int i = 0; i < streams.size(); i++) {
105  in_frac.push_back(streams[i].first.first);
106  in_cap.push_back(streams[i].first.second);
107  }
108  }
109 
110  void SetIn_stream(std::vector<std::map<std::string, double> > in_stream,
111  std::vector<double> ratios, std::vector<double> caps) {
112  t_instream instream_tmp;
113  for (int i = 0; i < in_stream.size(); i++) {
114  std::pair<double, double> info_mtp =
115  std::pair<double, double>(ratios[i], caps[i]);
116  instream_tmp.push_back(
117  std::pair<std::pair<double, double>, std::map<std::string, double> >(
118  info_mtp, in_stream[i]));
119  }
120  SetIn_stream(instream_tmp);
121  }
122 
123  void SetStream_ratio(std::vector<double> new_ratios) {
124  for (int i = 0; i < new_ratios.size(); i++) {
125  mf_facility_->streams_[i].first.first = new_ratios[i];
126  }
127 
128  mf_facility_->mixing_ratios = new_ratios;
129  }
130 
131  void SetStream_capacity(std::vector<double> new_caps) {
132  for (int i = 0; i < new_caps.size(); i++) {
133  mf_facility_->streams_[i].first.second = new_caps[i];
134  }
135 
136  mf_facility_->in_buf_sizes = new_caps;
137  }
138 
140  out_com = com;
141  mf_facility_->out_commod = com;
142  }
143 
144  void SetOutStream_capacity(double cap) {
145  out_cap = cap;
146  mf_facility_->out_buf_size = cap;
147  }
148 
149  void SetInputInv(std::vector<cyclus::Material::Ptr> mat) {
150  for (int i = 0; i < mat.size(); i++) {
151  std::string name = "in_stream_" + std::to_string(i);
152  mf_facility_->streambufs[name].Push(mat[i]);
153  }
154  }
155 
156  std::vector<double> GetStream_ratio() { return mf_facility_->mixing_ratios; }
157 
158  std::vector<double> GetStream_capacity() {
159  return mf_facility_->in_buf_sizes;
160  }
161 
162  std::string GetOutStream_comds() { return mf_facility_->out_commod; }
163 
164  double GetOutStream_capacity() { return mf_facility_->out_buf_size; }
165 
166  double GetThroughput() { return mf_facility_->throughput; }
167 
168  InvBuffer* GetOutPutBuffer() { return &mf_facility_->output; }
169 
170  std::map<std::string, InvBuffer> GetStreamBuffer() {
171  return mf_facility_->streambufs;
172  }
173 };
174 
175 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
176 // Checking that ratios correctly default to 1/N.
177 TEST_F(MixerTest, StreamDefaultRatio) {
179  SetThroughput(1e200);
181 
182  double ext_val = 1.0 / 3.0;
183  std::vector<double> strm_ratio_ = GetStream_ratio();
184 
185  //
186  for (int i = 0; i < in_coms.size(); i++) {
187  EXPECT_DOUBLE_EQ(ext_val, strm_ratio_[i]);
188  }
189 }
190 
191 // Test things about the mixing ratio normalisation.
192 TEST_F(MixerTest, StreamRatio) {
193  // Checking renormalisation when sum of ratio is grester tham 1.
194  std::vector<double> in_cap_ = {30, 20, 10};
195  std::vector<double> in_frac_ = {2, 1, 5};
196  in_cap_ = {30, 20, 10};
197 
198  SetStream_ratio(in_frac_);
199  SetStream_capacity(in_cap_);
201  SetThroughput(1e200);
203 
204  std::vector<double> strm_ratio_ = GetStream_ratio();
205  double sum = 0.0;
206  for (int i = 0; i < strm_ratio_.size(); i++) {
207  sum += strm_ratio_[i];
208  }
209 
210  EXPECT_DOUBLE_EQ(sum, 1) << "Ratios normalized incorrectly: want 1, got "
211  << sum;
212 
213  // Checking renormalisation when sum of ratio is smaller tham 1.
214  in_frac_ = {0.1, 0.2, 0.5};
216  SetThroughput(1e200);
217 
218  SetStream_ratio(in_frac_);
220  strm_ratio_ = GetStream_ratio();
221 
222  sum = 0;
223  for (int i = 0; i < strm_ratio_.size(); i++) {
224  sum += strm_ratio_[i];
225  }
226 
227  EXPECT_DOUBLE_EQ(sum, 1) << "Ratios normalized incorrectly: want 1, got "
228  << sum;
229 }
230 
231 // Check the correct mixing cyclus::Composition
232 TEST_F(MixerTest, MixingComposition) {
233  using cyclus::Material;
234 
235  std::vector<double> in_frac_ = {0.80, 0.15, 0.05};
236  SetStream_ratio(in_frac_);
237 
239 
240  SetThroughput(1e200);
241 
242  std::vector<Material::Ptr> mat;
243  mat.push_back(Material::CreateUntracked(in_cap[0], c_natu()));
244  mat.push_back(Material::CreateUntracked(in_cap[1], c_pustream()));
245  mat.push_back(Material::CreateUntracked(in_cap[2], c_uox()));
246 
247  SetInputInv(mat);
248  mf_facility_->Tick();
249 
250  cyclus::CompMap v_0 = c_natu()->mass();
251  cyclus::compmath::Normalize(&v_0, in_frac_[0]);
252  cyclus::CompMap v_1 = c_pustream()->mass();
253  cyclus::compmath::Normalize(&v_1, in_frac_[1]);
254  cyclus::CompMap v_2 = c_uox()->mass();
255  cyclus::compmath::Normalize(&v_2, in_frac_[2]);
256  cyclus::CompMap v = v_0;
257  v = cyclus::compmath::Add(v, v_1);
258  v = cyclus::compmath::Add(v, v_2);
259 
260  InvBuffer* buffer = GetOutPutBuffer();
261  Material::Ptr final_mat = cyclus::ResCast<Material>(buffer->PopBack());
262  cyclus::CompMap final_comp = final_mat->comp()->mass();
263 
264 
265  cyclus::compmath::Normalize(&v, 1);
266  cyclus::compmath::Normalize(&final_comp, 1);
267 
268  cyclus::CompMap sum_v = cyclus::compmath::Add(v, final_comp);
269 
270  cyclus::CompMap::iterator it;
271  for (it = sum_v.begin(); it != sum_v.end(); it++) {
272  EXPECT_DOUBLE_EQ(final_comp[it->first], v[it->first])
273  << "Unexpected difference on nuclide " << it->first << ".";
274  }
275 }
276 
277 // Check the throughput constrain
278 TEST_F(MixerTest, Throughput) {
279  using cyclus::Material;
280 
281  std::vector<double> in_frac_ = {0.80, 0.15, 0.05};
282 
283  SetStream_ratio(in_frac_);
284 
286 
287  SetThroughput(0.5);
288 
289  std::vector<Material::Ptr> mat;
290  mat.push_back(Material::CreateUntracked(in_cap[0], c_natu()));
291  mat.push_back(Material::CreateUntracked(in_cap[1], c_pustream()));
292  mat.push_back(Material::CreateUntracked(in_cap[2], c_uox()));
293  SetInputInv(mat);
294 
295  mf_facility_->Tick();
296 
297  std::vector<double> cap;
298  for (int i = 0; i < in_coms.size(); i++) {
299  cap.push_back(in_cap[i] - 0.5 * in_frac[i]);
300  }
301 
302  std::map<std::string, InvBuffer> streambuf = GetStreamBuffer();
303 
304  for (int i = 0; i < in_coms.size(); i++) {
305  std::string name = "in_stream_" + std::to_string(i);
306  double buf_size = in_cap[i];
307  double buf_ratio = in_frac[i];
308  double buf_inv = streambuf[name].quantity();
309 
310  // checking that each input buf was reduce of the correct amount
311  // (constrained by the throughput"
312  EXPECT_EQ(buf_size - 0.5 * buf_ratio, buf_inv)
313  << " one (or more) input "
314  "buffer inventory was not drawn from in the correct ratio.";
315  }
316 
317  // output buffer size should be equal to the throuput size
318  EXPECT_EQ(throughput, GetOutPutBuffer()->quantity())
319  << " mixing was not "
320  "correctly constrained by throughput.";
321 }
322 
323 // multiple input streams can be correctly requested and used as
324 // material inventory.
325 TEST(MixerTests, MultipleFissStreams) {
326  std::string config =
327  "<in_streams>"
328  "<stream>"
329  "<info>"
330  "<mixing_ratio>0.8</mixing_ratio>"
331  "<buf_size>2.5</buf_size>"
332  "</info>"
333  "<commodities>"
334  "<item>"
335  "<commodity>stream1</commodity>"
336  "<pref>1</pref>"
337  "</item>"
338  "</commodities>"
339  "</stream>"
340  "<stream>"
341  "<info>"
342  "<mixing_ratio>0.15</mixing_ratio>"
343  "<buf_size>3</buf_size>"
344  "</info>"
345  "<commodities>"
346  "<item>"
347  "<commodity>stream2</commodity>"
348  "<pref>1</pref>"
349  "</item>"
350  "</commodities>"
351  "</stream>"
352  "<stream>"
353  "<info>"
354  "<mixing_ratio>0.05</mixing_ratio>"
355  "<buf_size>5</buf_size>"
356  "</info>"
357  "<commodities>"
358  "<item>"
359  "<commodity>stream3</commodity>"
360  "<pref>1</pref>"
361  "</item>"
362  "</commodities>"
363  "</stream>"
364  "</in_streams>"
365  "<out_commod>mixedstream</out_commod>"
366  "<outputbuf_size>0</outputbuf_size>"
367  "<throughput>0</throughput>";
368  int simdur = 1;
369  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Mixer"), config, simdur);
370  sim.AddSource("stream1").recipe("unatstream").capacity(1).Finalize();
371  sim.AddSource("stream2").recipe("uoxstream").capacity(1).Finalize();
372  sim.AddSource("stream3").recipe("pustream").capacity(1).Finalize();
373  sim.AddRecipe("unatstream", c_natu());
374  sim.AddRecipe("uoxstream", c_pustream());
375  sim.AddRecipe("pustream", c_uox());
376  int id = sim.Run();
377 
378  // Checking the number of transaction is as expected 3.
379  cyclus::QueryResult qr = sim.db().Query("Transactions", NULL);
380  EXPECT_EQ(3, qr.rows.size());
381 
382  // Checking that all input stream get one transaction each.
383  std::vector<cyclus::Cond> conds;
384  conds.push_back(cyclus::Cond("Commodity", "==", std::string("stream1")));
385  qr = sim.db().Query("Transactions", &conds);
386  EXPECT_EQ(1, qr.rows.size());
387 
388  conds[0] = cyclus::Cond("Commodity", "==", std::string("stream2"));
389  qr = sim.db().Query("Transactions", &conds);
390  EXPECT_EQ(1, qr.rows.size());
391 
392  conds[0] = cyclus::Cond("Commodity", "==", std::string("stream3"));
393  qr = sim.db().Query("Transactions", &conds);
394  EXPECT_EQ(1, qr.rows.size());
395 }
396 
397 // multiple input streams can be correctly requested and used as
398 // material inventory.
399 TEST(MixerTests, CompleteMixingProcess) {
400  std::string config =
401  "<in_streams>"
402  "<stream>"
403  "<info>"
404  "<mixing_ratio>0.8</mixing_ratio>"
405  "<buf_size>2.5</buf_size>"
406  "</info>"
407  "<commodities>"
408  "<item>"
409  "<commodity>stream1</commodity>"
410  "<pref>1</pref>"
411  "</item>"
412  "</commodities>"
413  "</stream>"
414  "<stream>"
415  "<info>"
416  "<mixing_ratio>0.15</mixing_ratio>"
417  "<buf_size>3</buf_size>"
418  "</info>"
419  "<commodities>"
420  "<item>"
421  "<commodity>stream2</commodity>"
422  "<pref>1</pref>"
423  "</item>"
424  "</commodities>"
425  "</stream>"
426  "<stream>"
427  "<info>"
428  "<mixing_ratio>0.05</mixing_ratio>"
429  "<buf_size>5</buf_size>"
430  "</info>"
431  "<commodities>"
432  "<item>"
433  "<commodity>stream3</commodity>"
434  "<pref>1</pref>"
435  "</item>"
436  "</commodities>"
437  "</stream>"
438  "</in_streams>"
439  "<out_commod>mixedstream</out_commod>"
440  "<outputbuf_size>10</outputbuf_size>"
441  "<throughput>1</throughput>";
442  int simdur = 2;
443  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Mixer"), config, simdur);
444  sim.AddSource("stream1").recipe("unatstream").capacity(1).Finalize();
445  sim.AddSource("stream2").recipe("uoxstream").capacity(1).Finalize();
446  sim.AddSource("stream3").recipe("pustream").capacity(1).Finalize();
447  sim.AddRecipe("unatstream", c_natu());
448  sim.AddRecipe("uoxstream", c_pustream());
449  sim.AddRecipe("pustream", c_uox());
450 
451  sim.AddSink("mixedstream").capacity(10).Finalize();
452  int id = sim.Run();
453 
454  // Checking that all input stream get one transaction each.
455  std::vector<cyclus::Cond> conds;
456  conds.push_back(cyclus::Cond("Commodity", "==", std::string("mixedstream")));
457  cyclus::QueryResult qr = sim.db().Query("Transactions", &conds);
458  EXPECT_EQ(1, qr.rows.size());
459 
460  cyclus::Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));
461  EXPECT_DOUBLE_EQ(1., m->quantity());
462 }
463 
464 TEST(MixerTests, PositionInitialize) {
465  std::string config =
466  "<in_streams>"
467  "<stream>"
468  "<info>"
469  "<mixing_ratio>0.8</mixing_ratio>"
470  "<buf_size>2.5</buf_size>"
471  "</info>"
472  "<commodities>"
473  "<item>"
474  "<commodity>stream1</commodity>"
475  "<pref>1</pref>"
476  "</item>"
477  "</commodities>"
478  "</stream>"
479  "<stream>"
480  "<info>"
481  "<mixing_ratio>0.15</mixing_ratio>"
482  "<buf_size>3</buf_size>"
483  "</info>"
484  "<commodities>"
485  "<item>"
486  "<commodity>stream2</commodity>"
487  "<pref>1</pref>"
488  "</item>"
489  "</commodities>"
490  "</stream>"
491  "<stream>"
492  "<info>"
493  "<mixing_ratio>0.05</mixing_ratio>"
494  "<buf_size>5</buf_size>"
495  "</info>"
496  "<commodities>"
497  "<item>"
498  "<commodity>stream3</commodity>"
499  "<pref>1</pref>"
500  "</item>"
501  "</commodities>"
502  "</stream>"
503  "</in_streams>"
504  "<out_commod>mixedstream</out_commod>"
505  "<outputbuf_size>0</outputbuf_size>"
506  "<throughput>0</throughput>";
507  int simdur = 1;
508  cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Mixer"), config, simdur);
509  sim.AddSource("stream1").recipe("unatstream").capacity(1).Finalize();
510  sim.AddSource("stream2").recipe("uoxstream").capacity(1).Finalize();
511  sim.AddSource("stream3").recipe("pustream").capacity(1).Finalize();
512  sim.AddRecipe("unatstream", c_natu());
513  sim.AddRecipe("uoxstream", c_pustream());
514  sim.AddRecipe("pustream", c_uox());
515  int id = sim.Run();
516 
517  QueryResult qr = sim.db().Query("AgentPosition", NULL);
518  EXPECT_EQ(qr.GetVal<double>("Latitude"), 0.0);
519  EXPECT_EQ(qr.GetVal<double>("Longitude"), 0.0);
520 }
521 
522 } // namespace cycamore
std::vector< double > in_buf_sizes
std::string GetOutStream_comds()
void SetStream_ratio(std::vector< double > new_ratios)
cyclus::Composition::Ptr c_pustream()
std::vector< double > GetStream_ratio()
void SetThroughput(double thpt)
InvBuffer * GetOutPutBuffer()
void SetOutStream_comds(std::string com)
cyclus::Composition::Ptr c_uox()
std::vector< double > GetStream_capacity()
cycamore::GrowthRegion string
cyclus::toolkit::ResBuf< cyclus::Material > output
void SetIn_stream(t_instream streams)
std::map< std::string, InvBuffer > GetStreamBuffer()
cyclus::toolkit::ResBuf< cyclus::Material > InvBuffer
TEST(MixerTests, MultipleFissStreams)
cyclus::Composition::Ptr c_natu()
virtual void SetUp()
void SetInputInv(std::vector< cyclus::Material::Ptr > mat)
void SetIn_stream(std::vector< std::map< std::string, double > > in_stream, std::vector< double > ratios, std::vector< double > caps)
void SetStream_capacity(std::vector< double > new_caps)
std::vector< std::map< std::string, double > > in_coms
virtual void TearDown()
std::vector< std::pair< std::pair< double, double >, std::map< std::string, double > > > t_instream
void SetOutStream_capacity(double cap)
Mixer mixes N streams with fixed, static, user-specified ratios into a single output stream...
std::vector< double > mixing_ratios
std::map< std::string, cyclus::toolkit::ResBuf< cyclus::Material > > streambufs
std::vector< std::pair< std::pair< double, double >, std::map< std::string, double > > > streams_
TEST_F(EnrichmentTest, RequestQty)