CYCAMORE
Loading...
Searching...
No Matches
src/sink.cc
Go to the documentation of this file.
1// Implements the Sink class
2#include <algorithm>
3#include <sstream>
4
5#include <boost/lexical_cast.hpp>
6
7#include "sink.h"
8
9namespace cycamore {
10
11// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
12Sink::Sink(cyclus::Context* ctx)
13 : cyclus::Facility(ctx),
14 capacity(std::numeric_limits<double>::max()),
15 keep_packaging(true) {
16 SetMaxInventorySize(std::numeric_limits<double>::max());}
17
18// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
19Sink::~Sink() {}
20
21#pragma cyclus def schema cycamore::Sink
22
23#pragma cyclus def annotations cycamore::Sink
24
25#pragma cyclus def infiletodb cycamore::Sink
26
27#pragma cyclus def snapshot cycamore::Sink
28
29#pragma cyclus def snapshotinv cycamore::Sink
30
31#pragma cyclus def initinv cycamore::Sink
32
33#pragma cyclus def clone cycamore::Sink
34
35#pragma cyclus def initfromdb cycamore::Sink
36
37#pragma cyclus def initfromcopy cycamore::Sink
38
39// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
40void Sink::EnterNotify() {
41 cyclus::Facility::EnterNotify();
42 LOG(cyclus::LEV_INFO4, "SnkFac") << " using random behavior " << random_size_type;
43
44 inventory.keep_packaging(keep_packaging);
45
46 if (in_commod_prefs.size() == 0) {
47 for (int i = 0; i < in_commods.size(); ++i) {
48 in_commod_prefs.push_back(cyclus::kDefaultPref);
49 }
50 } else if (in_commod_prefs.size() != in_commods.size()) {
51 std::stringstream ss;
52 ss << "in_commod_prefs has " << in_commod_prefs.size()
53 << " values, expected " << in_commods.size();
54 throw cyclus::ValueError(ss.str());
55 }
58 SetRequestAmt();
59 SetNextBuyTime();
60
61 if (random_size_type != "None") {
62 LOG(cyclus::LEV_INFO4, "SnkFac") << "Sink " << this->id()
63 << " is using random behavior "
64 << random_size_type
65 << " for determining request size.";
66 }
67 if (random_frequency_type != "None") {
68 LOG(cyclus::LEV_INFO4, "SnkFac") << "Sink " << this->id()
69 << " is using random behavior "
70 << random_frequency_type
71 << " for determining request frequency.";
72 }
73
74 InitializePosition();
75}
76
77// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
78std::string Sink::str() {
79 using std::string;
80 using std::vector;
81 std::stringstream ss;
82 ss << cyclus::Facility::str();
83
84 string msg = "";
85 msg += "accepts commodities ";
86 for (vector<string>::iterator commod = in_commods.begin();
87 commod != in_commods.end();
88 commod++) {
89 msg += (commod == in_commods.begin() ? "{" : ", ");
90 msg += (*commod);
91 }
92 msg += "} until its inventory is full at ";
93 ss << msg << inventory.capacity() << " kg.";
94 return "" + ss.str();
95}
96
97// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
98std::set<cyclus::RequestPortfolio<cyclus::Material>::Ptr>
99Sink::GetMatlRequests() {
100 using cyclus::Material;
101 using cyclus::RequestPortfolio;
102 using cyclus::Request;
103 using cyclus::Composition;
104
105 std::set<RequestPortfolio<Material>::Ptr> ports;
106 RequestPortfolio<Material>::Ptr port(new RequestPortfolio<Material>());
107 Material::Ptr mat;
108
110 if (requestAmt > SpaceAvailable()) {
111 SetRequestAmt();
112 }
113
114 if (recipe_name.empty()) {
115 mat = cyclus::NewBlankMaterial(requestAmt);
116 } else {
117 Composition::Ptr rec = this->context()->GetRecipe(recipe_name);
118 mat = cyclus::Material::CreateUntracked(requestAmt, rec);
119 }
120
121 if (requestAmt > cyclus::eps()) {
122 std::vector<Request<Material>*> mutuals;
123 for (int i = 0; i < in_commods.size(); i++) {
124 mutuals.push_back(port->AddRequest(mat, this, in_commods[i], in_commod_prefs[i]));
125
126 }
127 port->AddMutualReqs(mutuals);
128 ports.insert(port);
129 } // if amt > eps
130 return ports;
131}
132
133// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
134std::set<cyclus::RequestPortfolio<cyclus::Product>::Ptr>
135Sink::GetGenRsrcRequests() {
136 using cyclus::CapacityConstraint;
137 using cyclus::Product;
138 using cyclus::RequestPortfolio;
139
140 std::set<RequestPortfolio<Product>::Ptr> ports;
141 RequestPortfolio<Product>::Ptr
142 port(new RequestPortfolio<Product>());
143
144 if (requestAmt > cyclus::eps()) {
145 CapacityConstraint<Product> cc(requestAmt);
146 port->AddConstraint(cc);
147
148 std::vector<std::string>::const_iterator it;
149 for (it = in_commods.begin(); it != in_commods.end(); ++it) {
150 std::string quality = ""; // not clear what this should be..
151 Product::Ptr rsrc = Product::CreateUntracked(requestAmt, quality);
152 port->AddRequest(rsrc, this, *it);
153 }
154
155 ports.insert(port);
156 } // if amt > eps
157 return ports;
158}
159
160// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
161void Sink::AcceptMatlTrades(
162 const std::vector< std::pair<cyclus::Trade<cyclus::Material>,
163 cyclus::Material::Ptr> >& responses) {
164 std::vector< std::pair<cyclus::Trade<cyclus::Material>,
165 cyclus::Material::Ptr> >::const_iterator it;
166 for (it = responses.begin(); it != responses.end(); ++it) {
167 inventory.Push(it->second);
168 }
169}
170
171// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
172void Sink::AcceptGenRsrcTrades(
173 const std::vector< std::pair<cyclus::Trade<cyclus::Product>,
174 cyclus::Product::Ptr> >& responses) {
175 std::vector< std::pair<cyclus::Trade<cyclus::Product>,
176 cyclus::Product::Ptr> >::const_iterator it;
177 for (it = responses.begin(); it != responses.end(); ++it) {
178 inventory.Push(it->second);
179 }
180}
181
182// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
183void Sink::Tick() {
184 using std::string;
185 using std::vector;
186 LOG(cyclus::LEV_INFO3, "SnkFac") << "Sink " << this->id() << " is ticking {";
187
188 if (nextBuyTime == -1) {
189 SetRequestAmt();
190 }
191 else if (nextBuyTime == context()->time()) {
192 SetRequestAmt();
193 SetNextBuyTime();
194
195 LOG(cyclus::LEV_INFO4, "SnkFac") << "Sink " << this->id()
196 << " has reached buying time. The next buy time will be time step " << nextBuyTime;
197 }
198 else {
199 requestAmt = 0;
200 }
201
202 // inform the simulation about what the sink facility will be requesting
203 if (requestAmt > cyclus::eps()) {
204 LOG(cyclus::LEV_INFO4, "SnkFac") << "Sink " << this->id()
205 << " has request amount " << requestAmt
206 << " kg of " << in_commods[0] << ".";
207 for (vector<string>::iterator commod = in_commods.begin();
208 commod != in_commods.end();
209 commod++) {
210 LOG(cyclus::LEV_INFO4, "SnkFac") << "Sink " << this->id()
211 << " will request " << requestAmt
212 << " kg of " << *commod << ".";
213 cyclus::toolkit::RecordTimeSeries<double>("demand"+*commod, this,
214 requestAmt);
215 }
216 }
217 LOG(cyclus::LEV_INFO3, "SnkFac") << "}";
218}
219
220// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
221void Sink::Tock() {
222 LOG(cyclus::LEV_INFO3, "SnkFac") << prototype() << " is tocking {";
223
224 // On the tock, the sink facility doesn't really do much.
225 // Maybe someday it will record things.
226 // For now, lets just print out what we have at each timestep.
227 LOG(cyclus::LEV_INFO4, "SnkFac") << "Sink " << this->id()
228 << " is holding " << inventory.quantity()
229 << " units of material at the close of timestep "
230 << context()->time() << ".";
231 LOG(cyclus::LEV_INFO3, "SnkFac") << "}";
232}
233
234void Sink::SetRequestAmt() {
235 double amt = SpaceAvailable();
236 if (amt < cyclus::eps()) {
237 requestAmt = 0;
238 }
239
240 if (random_size_type == "None") {
241 requestAmt = amt;
242 }
243 else if (random_size_type == "UniformReal") {
244 requestAmt = context()->random_uniform_real(0, amt);
245 }
246 else if (random_size_type == "NormalReal") {
247 requestAmt = context()->random_normal_real(amt * random_size_mean,
248 amt * random_size_stddev,
249 0, amt);
250 }
251 else {
252 requestAmt = amt;
253 }
254 return;
255}
256
257void Sink::SetNextBuyTime() {
258 if (random_frequency_type == "None") {
259 nextBuyTime = -1;
260 }
261 else if (random_frequency_type == "UniformInt") {
262 nextBuyTime = context()->time() + context()->random_uniform_int(random_frequency_min, random_frequency_max);
263 }
264 else if (random_frequency_type == "NormalInt") {
265 nextBuyTime = context()->time() + context()->random_normal_int(random_frequency_mean, random_frequency_stddev, random_frequency_min, random_frequency_max);
266 }
267 else {
268 nextBuyTime = -1;
269 }
270 return;
271}
272
273// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
274extern "C" cyclus::Agent* ConstructSink(cyclus::Context* ctx) {
275 return new Sink(ctx);
276}
277
278} // namespace cycamore
Sink(cyclus::Context *ctx)
cyclus::Agent * ConstructSink(cyclus::Context *ctx)