CYCAMORE
src/mixer.cc
Go to the documentation of this file.
1 #include <sstream>
2 
3 #include "mixer.h"
4 
5 namespace cycamore {
6 
7 Mixer::Mixer(cyclus::Context* ctx) : cyclus::Facility(ctx), throughput(0) {
8  cyclus::Warn<cyclus::EXPERIMENTAL_WARNING>(
9  "the Mixer archetype is experimental");
10 }
11 
12 cyclus::Inventories Mixer::SnapshotInv() {
13  cyclus::Inventories invs;
14 
15  // these inventory names are intentionally convoluted so as to not clash
16  // with the user-specified stream commods that are used as the Mixer
17  // streams inventory names.
18  invs["output-inv-name"] = output.PopNRes(output.count());
19  output.Push(invs["output-inv-name"]);
20 
21  std::map<std::string, cyclus::toolkit::ResBuf<cyclus::Material> >::iterator
22  it;
23  for (it = streambufs.begin(); it != streambufs.end(); ++it) {
24  invs[it->first] = it->second.PopNRes(it->second.count());
25  it->second.Push(invs[it->first]);
26  }
27  return invs;
28 }
29 
30 void Mixer::InitInv(cyclus::Inventories& inv) {
31  inv["output-inv-name"] = output.PopNRes(output.count());
32  output.Push(inv["output-inv-name"]);
33 
34  cyclus::Inventories::iterator it;
35  for (it = inv.begin(); it != inv.end(); ++it) {
36  streambufs[it->first].Push(it->second);
37  }
38 }
39 
40 void Mixer::EnterNotify() {
41  cyclus::Facility::EnterNotify();
42 
43  mixing_ratios.clear();
44  in_buf_sizes.clear();
45  in_commods.clear();
46 
47  // initialisation internal variable
48  for (int i = 0; i < streams_.size(); i++) {
49  mixing_ratios.push_back(streams_[i].first.first);
50  in_buf_sizes.push_back(streams_[i].first.second);
51 
52  std::string name = "in_stream_" + std::to_string(i);
53  double cap = in_buf_sizes[i];
54  if (cap >= 0) {
55  streambufs[name].capacity(cap);
56  }
57  in_commods.push_back(streams_[i].second);
58  }
59 
60  // ratio normalisation
61  if (mixing_ratios.size() != in_commods.size()) {
62  std::stringstream ss;
63  ss << "prototype '" << prototype() << "' has " << mixing_ratios.size()
64  << " commodity fraction values, expected " << in_commods.size();
65  throw cyclus::ValidationError(ss.str());
66 
67  } else {
68  double frac_sum = 0.0;
69  for (int i = 0; i < mixing_ratios.size(); i++) frac_sum += mixing_ratios[i];
70 
71  if (frac_sum != 1.0) {
72  std::stringstream ss;
73  ss << "prototype '" << prototype() << "': the sum of mixing fractions is "
74  "not 1, renormalization will be "
75  "done.";
76  cyclus::Warn<cyclus::VALUE_WARNING>(ss.str());
77  }
78  if (frac_sum != 0) {
79  for (int i = 0; i < mixing_ratios.size(); i++) {
80  mixing_ratios[i] *= 1.0 / frac_sum;
81  }
82  } else {
83  for (int i = 0; i < mixing_ratios.size(); i++) {
84  mixing_ratios[i] = 1.0 / (mixing_ratios.size());
85  }
86  }
87  }
88 
89  sell_policy.Init(this, &output, "output").Set(out_commod).Start();
90 }
91 
92 void Mixer::Tick() {
93  if (output.quantity() < output.capacity()) {
94  double tgt_qty = output.space();
95 
96  for (int i = 0; i < mixing_ratios.size(); i++) {
97  std::string name = "in_stream_" + std::to_string(i);
98  tgt_qty =
99  std::min(tgt_qty, streambufs[name].quantity() / mixing_ratios[i]);
100  }
101 
102  tgt_qty = std::min(tgt_qty, throughput);
103 
104  if (tgt_qty > 0) {
105  cyclus::Material::Ptr m;
106  for (int i = 0; i < mixing_ratios.size(); i++) {
107  std::string name = "in_stream_" + std::to_string(i);
108  double pop_qty = mixing_ratios[i] * tgt_qty;
109  if (i == 0) {
110  m = streambufs[name].Pop(pop_qty, cyclus::eps_rsrc());
111  } else {
112  cyclus::Material::Ptr m_ =
113  streambufs[name].Pop(pop_qty, cyclus::eps_rsrc());
114  m->Absorb(m_);
115  }
116  }
117  output.Push(m);
118  }
119  }
120 }
121 
122 std::set<cyclus::RequestPortfolio<cyclus::Material>::Ptr>
124  using cyclus::RequestPortfolio;
125 
126  std::set<RequestPortfolio<cyclus::Material>::Ptr> ports;
127 
128  for (int i = 0; i < in_commods.size(); i++) {
129  std::string name = "in_stream_" + std::to_string(i);
130 
131  if (streambufs[name].space() > cyclus::eps_rsrc()) {
132  RequestPortfolio<cyclus::Material>::Ptr port(
133  new RequestPortfolio<cyclus::Material>());
134 
135  cyclus::Material::Ptr m;
136  m = cyclus::NewBlankMaterial(streambufs[name].space());
137 
138  std::vector<cyclus::Request<cyclus::Material>*> reqs;
139 
140  std::map<std::string, double>::iterator it;
141  for (it = in_commods[i].begin() ; it != in_commods[i].end(); it++) {
142  std::string commod = it->first;
143  double pref = it->second;
144  reqs.push_back(port->AddRequest(m, this, commod , pref, false));
145  req_inventories_[reqs.back()] = name;
146  }
147  port->AddMutualReqs(reqs);
148  ports.insert(port);
149  }
150  }
151  return ports;
152 }
153 
155  const std::vector<std::pair<cyclus::Trade<cyclus::Material>,
156  cyclus::Material::Ptr> >& responses) {
157  std::vector<std::pair<cyclus::Trade<cyclus::Material>,
158  cyclus::Material::Ptr> >::const_iterator trade;
159 
160  for (trade = responses.begin(); trade != responses.end(); ++trade) {
161  cyclus::Request<cyclus::Material>* req = trade->first.request;
162  cyclus::Material::Ptr m = trade->second;
163 
164  std::string name = req_inventories_[req];
165  bool assigned = false;
166  std::map<std::string, cyclus::toolkit::ResBuf<cyclus::Material> >::iterator
167  it;
168 
169  for (it = streambufs.begin(); it != streambufs.end(); it++) {
170  if (name == it->first) {
171  it->second.Push(m);
172  assigned = true;
173  break;
174  }
175  }
176  if (!assigned) {
177  throw cyclus::ValueError("cycamore::Mixer was overmatched on requests");
178  }
179  }
180 
181  req_inventories_.clear();
182 }
183 
184 extern "C" cyclus::Agent* ConstructMixer(cyclus::Context* ctx) {
185  return new Mixer(ctx);
186 }
187 }
virtual std::set< cyclus::RequestPortfolio< cyclus::Material >::Ptr > GetMatlRequests()
std::vector< double > in_buf_sizes
virtual void AcceptMatlTrades(const std::vector< std::pair< cyclus::Trade< cyclus::Material >, cyclus::Material::Ptr > > &responses)
cyclus::Agent * ConstructMixer(cyclus::Context *ctx)
virtual cyclus::Inventories SnapshotInv()
std::map< cyclus::Request< cyclus::Material > *, std::string > req_inventories_
cycamore::GrowthRegion string
cyclus::toolkit::ResBuf< cyclus::Material > output
cyclus::toolkit::MatlSellPolicy sell_policy
Mixer(cyclus::Context *ctx)
std::vector< double > mixing_ratios
virtual void InitInv(cyclus::Inventories &inv)
std::map< std::string, cyclus::toolkit::ResBuf< cyclus::Material > > streambufs
std::vector< std::pair< std::pair< double, double >, std::map< std::string, double > > > streams_
std::vector< std::map< std::string, double > > in_commods