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