CYCAMORE
src/storage.cc
Go to the documentation of this file.
1 // storage.cc
2 // Implements the Storage class
3 #include "storage.h"
4 
5 namespace storage {
6 
7 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8 Storage::Storage(cyclus::Context* ctx)
9  : cyclus::Facility(ctx),
10  latitude(0.0),
11  longitude(0.0),
13  cyclus::Warn<cyclus::EXPERIMENTAL_WARNING>(
14  "The Storage Facility is experimental.");};
15 
16 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
17 // pragmas
18 
19 #pragma cyclus def schema storage::Storage
20 
21 #pragma cyclus def annotations storage::Storage
22 
23 #pragma cyclus def initinv storage::Storage
24 
25 #pragma cyclus def snapshotinv storage::Storage
26 
27 #pragma cyclus def infiletodb storage::Storage
28 
29 #pragma cyclus def snapshot storage::Storage
30 
31 #pragma cyclus def clone storage::Storage
32 
33 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
34 void Storage::InitFrom(Storage* m) {
35 #pragma cyclus impl initfromcopy storage::Storage
36  cyclus::toolkit::CommodityProducer::Copy(m);
37 }
38 
39 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
40 void Storage::InitFrom(cyclus::QueryableBackend* b) {
41 #pragma cyclus impl initfromdb storage::Storage
42 
43  using cyclus::toolkit::Commodity;
44  Commodity commod = Commodity(out_commods.front());
45  cyclus::toolkit::CommodityProducer::Add(commod);
46  cyclus::toolkit::CommodityProducer::SetCapacity(commod, throughput);
47 }
48 
49 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
50 void Storage::EnterNotify() {
51  cyclus::Facility::EnterNotify();
52  buy_policy.Init(this, &inventory, std::string("inventory"));
53 
54  // dummy comp, use in_recipe if provided
55  cyclus::CompMap v;
56  cyclus::Composition::Ptr comp = cyclus::Composition::CreateFromAtom(v);
57  if (in_recipe != "") {
58  comp = context()->GetRecipe(in_recipe);
59  }
60 
61  if (in_commod_prefs.size() == 0) {
62  for (int i = 0; i < in_commods.size(); ++i) {
63  in_commod_prefs.push_back(cyclus::kDefaultPref);
64  }
65  } else if (in_commod_prefs.size() != in_commods.size()) {
66  std::stringstream ss;
67  ss << "in_commod_prefs has " << in_commod_prefs.size()
68  << " values, expected " << in_commods.size();
69  throw cyclus::ValueError(ss.str());
70  }
71 
72  for (int i = 0; i != in_commods.size(); ++i) {
73  buy_policy.Set(in_commods[i], comp, in_commod_prefs[i]);
74  }
75  buy_policy.Start();
76 
77  if (out_commods.size() == 1) {
78  sell_policy.Init(this, &stocks, std::string("stocks"))
79  .Set(out_commods.front())
80  .Start();
81  } else {
82  std::stringstream ss;
83  ss << "out_commods has " << out_commods.size() << " values, expected 1.";
84  throw cyclus::ValueError(ss.str());
85  }
87 }
88 
89 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
91  std::stringstream ss;
92  std::string ans, out_str;
93  if (out_commods.size() == 1) {
94  out_str = out_commods.front();
95  } else {
96  out_str = "";
97  }
98  if (cyclus::toolkit::CommodityProducer::Produces(
99  cyclus::toolkit::Commodity(out_str))) {
100  ans = "yes";
101  } else {
102  ans = "no";
103  }
104  ss << cyclus::Facility::str();
105  ss << " has facility parameters {"
106  << "\n"
107  << " Output Commodity = " << out_str << ",\n"
108  << " Residence Time = " << residence_time << ",\n"
109  << " Throughput = " << throughput << ",\n"
110  << " commod producer members: "
111  << " produces " << out_str << "?:" << ans << "'}";
112  return ss.str();
113 }
114 
115 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
116 void Storage::Tick() {
117  // Set available capacity for Buy Policy
118  inventory.capacity(current_capacity());
119 
120  LOG(cyclus::LEV_INFO3, "ComCnv") << prototype() << " is ticking {";
121 
122  if (current_capacity() > cyclus::eps_rsrc()) {
123  LOG(cyclus::LEV_INFO4, "ComCnv")
124  << " has capacity for " << current_capacity() << " kg of material.";
125  }
126  LOG(cyclus::LEV_INFO3, "ComCnv") << "}";
127 }
128 
129 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
130 void Storage::Tock() {
131  using cyclus::toolkit::RecordTimeSeries;
132  LOG(cyclus::LEV_INFO3, "ComCnv") << prototype() << " is tocking {";
133 
134  BeginProcessing_(); // place unprocessed inventory into processing
135 
136  if (ready_time() >= 0 || residence_time == 0 && !inventory.empty()) {
137  ReadyMatl_(ready_time()); // place processing into ready
138  }
139 
140  ProcessMat_(throughput); // place ready into stocks
141 
142 
143  std::vector<double>::iterator result;
144  result = std::max_element(in_commod_prefs.begin(), in_commod_prefs.end());
145  int maxindx = std::distance(in_commod_prefs.begin(), result);
146  cyclus::toolkit::RecordTimeSeries<double>("demand"+in_commods[maxindx], this,
147  current_capacity());
148  // Multiple commodity tracking is not supported, user can only
149  // provide one value for out_commods, despite it being a vector of strings.
150  cyclus::toolkit::RecordTimeSeries<double>("supply"+out_commods[0], this,
151  stocks.quantity());
152  LOG(cyclus::LEV_INFO3, "ComCnv") << "}";
153 }
154 
155 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
156 void Storage::AddMat_(cyclus::Material::Ptr mat) {
157  LOG(cyclus::LEV_INFO5, "ComCnv") << prototype() << " is initially holding "
158  << inventory.quantity() << " total.";
159 
160  try {
161  inventory.Push(mat);
162  } catch (cyclus::Error& e) {
163  e.msg(Agent::InformErrorMsg(e.msg()));
164  throw e;
165  }
166 
167  LOG(cyclus::LEV_INFO5, "ComCnv")
168  << prototype() << " added " << mat->quantity()
169  << " of material to its inventory, which is holding "
170  << inventory.quantity() << " total.";
171 }
172 
173 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
175  while (inventory.count() > 0) {
176  try {
177  processing.Push(inventory.Pop());
178  entry_times.push_back(context()->time());
179 
180  LOG(cyclus::LEV_DEBUG2, "ComCnv")
181  << "Storage " << prototype()
182  << " added resources to processing at t= " << context()->time();
183  } catch (cyclus::Error& e) {
184  e.msg(Agent::InformErrorMsg(e.msg()));
185  throw e;
186  }
187  }
188 }
189 
190 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
191 void Storage::ProcessMat_(double cap) {
192  using cyclus::Material;
193  using cyclus::ResCast;
194  using cyclus::toolkit::ResBuf;
195  using cyclus::toolkit::Manifest;
196 
197  if (!ready.empty()) {
198  try {
199  double max_pop = std::min(cap, ready.quantity());
200 
201  if (discrete_handling) {
202  if (max_pop == ready.quantity()) {
203  stocks.Push(ready.PopN(ready.count()));
204  } else {
205  double cap_pop = ready.Peek()->quantity();
206  while (cap_pop <= max_pop && !ready.empty()) {
207  stocks.Push(ready.Pop());
208  cap_pop += ready.empty() ? 0 : ready.Peek()->quantity();
209  }
210  }
211  } else {
212  stocks.Push(ready.Pop(max_pop, cyclus::eps_rsrc()));
213  }
214 
215  LOG(cyclus::LEV_INFO1, "ComCnv") << "Storage " << prototype()
216  << " moved resources"
217  << " from ready to stocks"
218  << " at t= " << context()->time();
219  } catch (cyclus::Error& e) {
220  e.msg(Agent::InformErrorMsg(e.msg()));
221  throw e;
222  }
223  }
224 }
225 
226 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
227 void Storage::ReadyMatl_(int time) {
228  using cyclus::toolkit::ResBuf;
229 
230  int to_ready = 0;
231 
232  while (!entry_times.empty() && entry_times.front() <= time) {
233  entry_times.pop_front();
234  ++to_ready;
235  }
236 
237  ready.Push(processing.PopN(to_ready));
238 }
239 
241  std::string specification = this->spec();
242  context()
243  ->NewDatum("AgentPosition")
244  ->AddVal("Spec", specification)
245  ->AddVal("Prototype", this->prototype())
246  ->AddVal("AgentId", id())
247  ->AddVal("Latitude", latitude)
248  ->AddVal("Longitude", longitude)
249  ->Record();
250 }
251 
252 
253 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
254 extern "C" cyclus::Agent* ConstructStorage(cyclus::Context* ctx) {
255  return new Storage(ctx);
256 }
257 
258 } // namespace storage
void AddMat_(cyclus::Material::Ptr mat)
adds a material into the incoming commodity inventory
virtual std::string str()
A verbose printer for the Storage Facility.
cyclus::toolkit::ResBuf< cyclus::Material > ready
virtual void Tock()
The handleTick function specific to the Storage.
virtual void EnterNotify()
Sets up the Storage Facility&#39;s trade requests.
cyclus::toolkit::MatlBuyPolicy buy_policy
double longitude
double current_capacity() const
current maximum amount that can be added to processing
virtual void Tick()
The handleTick function specific to the Storage.
std::vector< double > in_commod_prefs
cycamore::GrowthRegion string
int ready_time()
returns the time key for ready materials
virtual void InitFrom(storage::Storage *m)
cyclus::toolkit::ResBuf< cyclus::Material > stocks
cyclus::toolkit::MatlSellPolicy sell_policy
cyclus::toolkit::Position coordinates
cyclus::toolkit::ResBuf< cyclus::Material > processing
cyclus::toolkit::ResBuf< cyclus::Material > inventory
cyclus::Agent * ConstructStorage(cyclus::Context *ctx)
std::vector< std::string > in_commods
void ReadyMatl_(int time)
move ready resources from processing to ready at a certain time
void BeginProcessing_()
Move all unprocessed inventory to processing.
std::vector< std::string > out_commods
void ProcessMat_(double cap)
Move as many ready resources as allowable into stocks.
Storage(cyclus::Context *ctx)