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