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