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