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