CYCAMORE
Loading...
Searching...
No Matches
build/cycamore/conversion.cc
Go to the documentation of this file.
1
2#line 1 "/cycamore/src/conversion.cc"
3#include <algorithm>
4#include <sstream>
5
6#include <boost/lexical_cast.hpp>
7#include "toolkit/mat_query.h"
8
9#include "conversion.h"
10
11using cyclus::RequestPortfolio;
12using cyclus::BidPortfolio;
13using cyclus::CommodMap;
14using cyclus::Request;
15using cyclus::Trade;
16using cyclus::Material;
17using cyclus::CapacityConstraint;
18using cyclus::toolkit::ResBuf;
19using cyclus::toolkit::RecordTimeSeries;
20
21namespace cycamore {
22
23// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
24Conversion::Conversion(cyclus::Context* ctx)
25 : cyclus::Facility(ctx) {
26
27 // Make our Resource Buffers bulk buffers
28 input = ResBuf<Material>(true);
29 output = ResBuf<Material>(true);
30 }
31
32// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
34std::string Conversion::schema() {
35 return ""
36 "<interleave>\n"
37 " <optional>\n"
38 " <element name=\"latitude\">\n"
39 " <a:documentation>Latitude of the agent's geographical position. The value should be expressed in degrees as a double.</a:documentation>\n"
40 " <data type=\"double\"/>\n"
41 " </element>\n"
42 " </optional>\n"
43 " <optional>\n"
44 " <element name=\"longitude\">\n"
45 " <a:documentation>Longitude of the agent's geographical position. The value should be expressed in degrees as a double.</a:documentation>\n"
46 " <data type=\"double\"/>\n"
47 " </element>\n"
48 " </optional>\n"
49 " <element name=\"incommods\">\n"
50 " <oneOrMore>\n"
51 " <element name=\"val\">\n"
52 " <data type=\"string\"/>\n"
53 " </element>\n"
54 " </oneOrMore>\n"
55 " </element>\n"
56 " <element name=\"outcommod\">\n"
57 " <a:documentation>Output commodity on which the conversion facility offers material.</a:documentation>\n"
58 " <data type=\"string\"/>\n"
59 " </element>\n"
60 " <optional>\n"
61 " <element name=\"throughput\">\n"
62 " <a:documentation>throughput the facility can convert at each time step</a:documentation>\n"
63 " <data type=\"double\"/>\n"
64 " </element>\n"
65 " </optional>\n"
66 " <optional>\n"
67 " <element name=\"input_capacity\">\n"
68 " <a:documentation>Total capacity of the input buffer. The amount requested per time step is the minimum the conversion throughput and this capacity minus the amount of material in the input buffer.</a:documentation>\n"
69 " <data type=\"double\"/>\n"
70 " </element>\n"
71 " </optional>\n"
72 "</interleave>\n";
73};
74#line 32 "/cycamore/src/conversion.cc"
75
77 Json::Value root;
78 Json::Reader reader;
79 bool parsed_ok = reader.parse(
80 "{\"name\":\"cycamore::Conversion\",\"entity\":\"facility\""
81 ",\"parents\":[\"cyclus::Facility\",\"cyclus::toolkit::P"
82 "osition\"],\"all_parents\":[\"EconomicEntity\",\"cyclus:"
83 ":Agent\",\"cyclus::Facility\",\"cyclus::Ider\",\"cyclus:"
84 ":StateWrangler\",\"cyclus::TimeListener\",\"cyclus::Tr"
85 "ader\",\"cyclus::toolkit::Position\"],\"vars\":{\"latitu"
86 "de\":{\"default\":0.0,\"uilabel\":\"Geographical "
87 "latitude in degrees as a double\",\"doc\":\"Latitude "
88 "of the agent's geographical position. The value "
89 "should be expressed in degrees as a double.\",\"type"
90 "\":\"double\",\"index\":0,\"shape\":[-"
91 "1],\"alias\":\"latitude\",\"tooltip\":\"latitude\"},\"longi"
92 "tude\":{\"default\":0.0,\"uilabel\":\"Geographical "
93 "longitude in degrees as a double\",\"doc\":\"Longitude"
94 " of the agent's geographical position. The value "
95 "should be expressed in degrees as a double.\",\"type"
96 "\":\"double\",\"index\":1,\"shape\":[-"
97 "1],\"alias\":\"longitude\",\"tooltip\":\"longitude\"},\"inc"
98 "ommods\":{\"tooltip\":[\"input "
99 "commodities\",\"\"],\"doc\":\"commodities that the "
100 "conversion facility accepts\",\"uilabel\":[\"List of "
101 "Input Commodities\",\"\"],\"uitype\":[\"oneormore\",\"inco"
102 "mmodity\"],\"type\":[\"std::vector\",\"std::string\"],\"in"
103 "dex\":2,\"shape\":[-1,-"
104 "1],\"alias\":[\"incommods\",\"val\"]},\"outcommod\":{\"tool"
105 "tip\":\"output commodity\",\"doc\":\"Output commodity on"
106 " which the conversion facility offers "
107 "material.\",\"uilabel\":\"Output Commodity\",\"uitype\":\""
108 "outcommodity\",\"type\":\"std::string\",\"index\":3,\"shap"
109 "e\":[-"
110 "1],\"alias\":\"outcommod\"},\"throughput\":{\"default\":1e"
111 "+299,\"tooltip\":\"conversion throughput per "
112 "timestep\",\"uilabel\":\"Maximum conversion throughput"
113 "\",\"uitype\":\"range\",\"range\":[0.0,1e+299],\"doc\":\"thr"
114 "oughput the facility can convert at each time step"
115 "\",\"type\":\"double\",\"index\":4,\"shape\":[-"
116 "1],\"alias\":\"throughput\"},\"input_capacity\":{\"defaul"
117 "t\":1e+299,\"tooltip\":\"input buffer "
118 "capacity\",\"uilabel\":\"Maximum Storage of Input Buff"
119 "er\",\"uitype\":\"range\",\"range\":[0.0,1e+299],\"doc\":\"T"
120 "otal capacity of the input buffer. The amount "
121 "requested per time step is the minimum the "
122 "conversion throughput and this capacity minus the "
123 "amount of material in the input buffer.\",\"type\":\"d"
124 "ouble\",\"index\":5,\"shape\":[-"
125 "1],\"alias\":\"input_capacity\"},\"input\":{\"capacity\":\""
126 "input_capacity\",\"type\":[\"cyclus::toolkit::ResBuf\","
127 "\"cyclus::Material\"],\"index\":6,\"shape\":[-1,-"
128 "1]}},\"doc\":\" A conversion facility that accepts "
129 "materials and products and with a \\n fixed "
130 "throughput (per time step) converts them into its "
131 "outcommod. \"}", root);
132 if (!parsed_ok) {
133 throw cyclus::ValueError("failed to parse annotations for cycamore::Conversion.");
134 }
135 return root;
136};
137
138void Conversion::InfileToDb(cyclus::InfileTree* tree, cyclus::DbInit di) {
139 cyclus::Facility::InfileToDb(tree, di);
140 int rawcycpp_shape_latitude[1] = {-1};
141 cycpp_shape_latitude = std::vector<int>(rawcycpp_shape_latitude, rawcycpp_shape_latitude + 1);
142 int rawcycpp_shape_longitude[1] = {-1};
143 cycpp_shape_longitude = std::vector<int>(rawcycpp_shape_longitude, rawcycpp_shape_longitude + 1);
144 int rawcycpp_shape_incommods[2] = {-1, -1};
145 cycpp_shape_incommods = std::vector<int>(rawcycpp_shape_incommods, rawcycpp_shape_incommods + 2);
146 int rawcycpp_shape_outcommod[1] = {-1};
147 cycpp_shape_outcommod = std::vector<int>(rawcycpp_shape_outcommod, rawcycpp_shape_outcommod + 1);
148 int rawcycpp_shape_throughput[1] = {-1};
149 cycpp_shape_throughput = std::vector<int>(rawcycpp_shape_throughput, rawcycpp_shape_throughput + 1);
150 int rawcycpp_shape_input_capacity[1] = {-1};
151 cycpp_shape_input_capacity = std::vector<int>(rawcycpp_shape_input_capacity, rawcycpp_shape_input_capacity + 1);
152 int rawcycpp_shape_input[2] = {-1, -1};
153 cycpp_shape_input = std::vector<int>(rawcycpp_shape_input, rawcycpp_shape_input + 2);
154 cyclus::InfileTree* sub = tree->SubTree("config/*");
155 int i;
156 int n;
157 if (sub->NMatches("latitude") > 0) {
158 {
159 double latitude_val = cyclus::Query<double>(sub, "latitude");
160 latitude = latitude_val;
161 }
162 } else {
163 double latitude_tmp = 0.0;
164 latitude = latitude_tmp;
165 }
166 if (sub->NMatches("longitude") > 0) {
167 {
168 double longitude_val = cyclus::Query<double>(sub, "longitude");
169 longitude = longitude_val;
170 }
171 } else {
172 double longitude_tmp = 0.0;
173 longitude = longitude_tmp;
174 }
175 {
176 cyclus::InfileTree* bub = sub->SubTree("incommods", 0);
177 cyclus::InfileTree* sub = bub;
178 int n1 = sub->NMatches("val");
179 std::vector< std::string > incommods_val;
180 incommods_val.resize(n1);
181 for (int i1 = 0; i1 < n1; ++i1) {
182 std::string elem;
183 {
184 std::string elem_in = cyclus::Query<std::string>(sub, "val", i1);
185 elem = elem_in;
186 }
187 incommods_val[i1] = elem;
188 }
189 incommods = incommods_val;
190 }
191 {
192 std::string outcommod_val = cyclus::Query<std::string>(sub, "outcommod");
193 outcommod = outcommod_val;
194 }
195 if (sub->NMatches("throughput") > 0) {
196 {
197 double throughput_val = cyclus::Query<double>(sub, "throughput");
198 throughput = throughput_val;
199 }
200 } else {
201 double throughput_tmp = 1e+299;
202 throughput = throughput_tmp;
203 }
204 if (sub->NMatches("input_capacity") > 0) {
205 {
206 double input_capacity_val = cyclus::Query<double>(sub, "input_capacity");
207 input_capacity = input_capacity_val;
208 }
209 } else {
210 double input_capacity_tmp = 1e+299;
211 input_capacity = input_capacity_tmp;
212 }
213 di.NewDatum("Info")
214 ->AddVal("latitude", latitude, &cycpp_shape_latitude)
215 ->AddVal("longitude", longitude, &cycpp_shape_longitude)
216 ->AddVal("incommods", incommods, &cycpp_shape_incommods)
217 ->AddVal("outcommod", outcommod, &cycpp_shape_outcommod)
218 ->AddVal("throughput", throughput, &cycpp_shape_throughput)
219 ->AddVal("input_capacity", input_capacity, &cycpp_shape_input_capacity)
220 ->Record();
221};
222
223void Conversion::Snapshot(cyclus::DbInit di) {
224 di.NewDatum("Info")
225 ->AddVal("latitude", latitude, &cycpp_shape_latitude)
226 ->AddVal("longitude", longitude, &cycpp_shape_longitude)
227 ->AddVal("incommods", incommods, &cycpp_shape_incommods)
228 ->AddVal("outcommod", outcommod, &cycpp_shape_outcommod)
229 ->AddVal("throughput", throughput, &cycpp_shape_throughput)
230 ->AddVal("input_capacity", input_capacity, &cycpp_shape_input_capacity)
231 ->Record();
232};
233
234cyclus::Inventories Conversion::SnapshotInv() {
235 cyclus::Inventories invs;
236 invs["input"] = input.PopNRes(input.count());
237 input.Push(invs["input"]);
238 return invs;
239};
240
241void Conversion::InitInv(cyclus::Inventories& inv) {
242 input.Push(inv["input"]);
243
244};
245
246cyclus::Agent* Conversion::Clone() {
247 cycamore::Conversion* m = new cycamore::Conversion(context());
248 m->InitFrom(this);
249 return m;
250};
251
252void Conversion::InitFrom(cyclus::QueryableBackend* b) {
253 cyclus::Facility::InitFrom(b);
254 int rawcycpp_shape_latitude[1] = {-1};
255 cycpp_shape_latitude = std::vector<int>(rawcycpp_shape_latitude, rawcycpp_shape_latitude + 1);
256 int rawcycpp_shape_longitude[1] = {-1};
257 cycpp_shape_longitude = std::vector<int>(rawcycpp_shape_longitude, rawcycpp_shape_longitude + 1);
258 int rawcycpp_shape_incommods[2] = {-1, -1};
259 cycpp_shape_incommods = std::vector<int>(rawcycpp_shape_incommods, rawcycpp_shape_incommods + 2);
260 int rawcycpp_shape_outcommod[1] = {-1};
261 cycpp_shape_outcommod = std::vector<int>(rawcycpp_shape_outcommod, rawcycpp_shape_outcommod + 1);
262 int rawcycpp_shape_throughput[1] = {-1};
263 cycpp_shape_throughput = std::vector<int>(rawcycpp_shape_throughput, rawcycpp_shape_throughput + 1);
264 int rawcycpp_shape_input_capacity[1] = {-1};
265 cycpp_shape_input_capacity = std::vector<int>(rawcycpp_shape_input_capacity, rawcycpp_shape_input_capacity + 1);
266 int rawcycpp_shape_input[2] = {-1, -1};
267 cycpp_shape_input = std::vector<int>(rawcycpp_shape_input, rawcycpp_shape_input + 2);
268 cyclus::QueryResult qr = b->Query("Info", NULL);
269 latitude = qr.GetVal<double>("latitude");
270 longitude = qr.GetVal<double>("longitude");
271 incommods = qr.GetVal<std::vector< std::string > >("incommods");
272 outcommod = qr.GetVal<std::string>("outcommod");
273 throughput = qr.GetVal<double>("throughput");
274 input_capacity = qr.GetVal<double>("input_capacity");
275 input.capacity(input_capacity);
276};
277
279 cyclus::Facility::InitFrom(m);
280 int rawcycpp_shape_latitude[1] = {-1};
281 cycpp_shape_latitude = std::vector<int>(rawcycpp_shape_latitude, rawcycpp_shape_latitude + 1);
282 int rawcycpp_shape_longitude[1] = {-1};
283 cycpp_shape_longitude = std::vector<int>(rawcycpp_shape_longitude, rawcycpp_shape_longitude + 1);
284 int rawcycpp_shape_incommods[2] = {-1, -1};
285 cycpp_shape_incommods = std::vector<int>(rawcycpp_shape_incommods, rawcycpp_shape_incommods + 2);
286 int rawcycpp_shape_outcommod[1] = {-1};
287 cycpp_shape_outcommod = std::vector<int>(rawcycpp_shape_outcommod, rawcycpp_shape_outcommod + 1);
288 int rawcycpp_shape_throughput[1] = {-1};
289 cycpp_shape_throughput = std::vector<int>(rawcycpp_shape_throughput, rawcycpp_shape_throughput + 1);
290 int rawcycpp_shape_input_capacity[1] = {-1};
291 cycpp_shape_input_capacity = std::vector<int>(rawcycpp_shape_input_capacity, rawcycpp_shape_input_capacity + 1);
292 int rawcycpp_shape_input[2] = {-1, -1};
293 cycpp_shape_input = std::vector<int>(rawcycpp_shape_input, rawcycpp_shape_input + 2);
294 latitude = m->latitude;
295 longitude = m->longitude;
296 incommods = m->incommods;
297 outcommod = m->outcommod;
300 input.capacity(m->input.capacity());
301};
302#line 42 "/cycamore/src/conversion.cc"
303
304// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
306 cyclus::Facility::EnterNotify();
307 InitializePosition();
308}
309
310// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
311std::string Conversion::str() {
312 using std::string;
313 using std::vector;
314 std::stringstream ss;
315 ss << cyclus::Facility::str();
316
317 string msg = "";
318 msg += "accepts commodities ";
319 for (vector<string>::iterator commod = incommods.begin();
320 commod != incommods.end();
321 commod++) {
322 msg += (commod == incommods.begin() ? "{" : ", ");
323 msg += (*commod);
324 }
325 msg += "} until its input is full at ";
326 msg += std::to_string(input.capacity());
327 msg += " kg.";
328
329 msg += "} and converts ";
330 msg += std::to_string(throughput);
331 msg += " kg/timestep into commodity ";
332 ss << msg << outcommod;
333 return "" + ss.str();
334}
335
336// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
338 Convert();
339}
340
341// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
343
344// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
346 return input.capacity() - input.quantity();
347}
348
349// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
351 if (input.quantity() > 0) {
352 output.Push(input.Pop(std::min(input.quantity(), throughput)));
353 }
354}
355
356// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
357std::set<RequestPortfolio<Material>::Ptr> Conversion::GetMatlRequests() {
358 std::set<RequestPortfolio<Material>::Ptr> ports;
359
360 // Check if we need material
361 double available_capacity = AvailableFeedstockCapacity();
362 if (available_capacity <= 0) return ports;
363
364 // Create request portfolio
365 RequestPortfolio<Material>::Ptr port(new RequestPortfolio<Material>());
366
367 // Create material request with no recipe
368 Material::Ptr mat = cyclus::NewBlankMaterial(available_capacity);
369
370
371 // Add request for all commodities using default preference
372 for (std::vector<std::string>::iterator it = incommods.begin();
373 it != incommods.end(); ++it) {
374 Request<Material>* req = port->AddRequest(mat, this, *it);
375 }
376
377 // Add capacity constraint to ensure we never get more feed than capacity
378 CapacityConstraint<Material> cc(available_capacity);
379 port->AddConstraint(cc);
380
381 ports.insert(port);
382 return ports;
383}
384
385// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
386std::set<BidPortfolio<Material>::Ptr> Conversion::GetMatlBids(
387 CommodMap<Material>::type& commod_requests) {
388 std::set<BidPortfolio<Material>::Ptr> ports;
389
390 // Check if we have material to offer
391 if (output.quantity() <= 0) return ports;
392
393 // Create bid portfolio
394 BidPortfolio<Material>::Ptr port(new BidPortfolio<Material>());
395
396 // Respond to requests for our commodity
397 std::vector<Request<Material>*>& requests = commod_requests[outcommod];
398 for (std::vector<Request<Material>*>::iterator it = requests.begin();
399 it != requests.end(); ++it) {
400
401 double available = output.quantity();
402 double requested = (*it)->target()->quantity();
403 double offer_qty = std::min(available, requested);
404
405 if (offer_qty > 0) {
406 Material::Ptr offer = Material::CreateUntracked(offer_qty, output.Peek()->comp());
407 port->AddBid(*it, offer, this); // Note: *it, not **it
408 }
409 }
410
411 // Add capacity constraint so we never give out more than we have
412 CapacityConstraint<Material> cc(output.quantity());
413 port->AddConstraint(cc);
414
415 ports.insert(port);
416 return ports;
417}
418
419// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
421 const std::vector<std::pair<Trade<Material>, Material::Ptr>>& responses) {
422
423 for (std::vector<std::pair<Trade<Material>, Material::Ptr>>::const_iterator it =
424 responses.begin(); it != responses.end(); ++it) {
425
426
427 // Add material to the input buffer
428 input.Push(it->second);
429
430 }
431}
432
433// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
435 const std::vector<Trade<Material>>& trades,
436 std::vector<std::pair<Trade<Material>, Material::Ptr>>& responses) {
437
438 for (std::vector<Trade<Material>>::const_iterator it = trades.begin();
439 it != trades.end(); ++it) {
440
441 Material::Ptr response = output.Pop(it->amt);
442
443 responses.push_back(std::make_pair(*it, response));
444 }
445}
446
447// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
448extern "C" cyclus::Agent* ConstructConversion(cyclus::Context* ctx) {
449 return new Conversion(ctx);
450}
451
452} // namespace cycamore
This facility acts as a simple conversion facility from its input commodity to its output commodity.
double throughput
Conversion throughput per timestep.
cyclus::toolkit::ResBuf< cyclus::Material > input
this facility holds a certain amount of material
std::vector< int > cycpp_shape_input
virtual std::set< cyclus::RequestPortfolio< cyclus::Material >::Ptr > GetMatlRequests()
Conversion Facilities request Materials of their given commodity.
virtual void InitInv(cyclus::Inventories &inv)
virtual void Snapshot(cyclus::DbInit di)
virtual void InfileToDb(cyclus::InfileTree *tree, cyclus::DbInit di)
virtual cyclus::Agent * Clone()
virtual Json::Value annotations()
cyclus::toolkit::ResBuf< cyclus::Material > output
a buffer for outgoing material
std::vector< int > cycpp_shape_outcommod
virtual std::set< cyclus::BidPortfolio< cyclus::Material >::Ptr > GetMatlBids(cyclus::CommodMap< cyclus::Material >::type &commod_requests)
virtual void AcceptMatlTrades(const std::vector< std::pair< cyclus::Trade< cyclus::Material >, cyclus::Material::Ptr > > &responses)
Conversion Facilities place accepted trade Materials in their Inventory.
virtual void InitFrom(cycamore::Conversion *m)
virtual cyclus::Inventories SnapshotInv()
virtual void GetMatlTrades(const std::vector< cyclus::Trade< cyclus::Material > > &trades, std::vector< std::pair< cyclus::Trade< cyclus::Material >, cyclus::Material::Ptr > > &responses)
std::vector< int > cycpp_shape_throughput
std::vector< int > cycpp_shape_input_capacity
Conversion(cyclus::Context *ctx)
std::vector< int > cycpp_shape_incommods
std::vector< std::string > incommods
all facilities must have at least one input commodity
cyclus::Agent * ConstructConversion(cyclus::Context *ctx)