9 : cyclus::Facility(ctx) {
10 inventory_tracker.Init({&inventory, &stocks, &ready, &processing}, cyclus::CY_LARGE_DOUBLE);
11 cyclus::Warn<cyclus::EXPERIMENTAL_WARNING>(
12 "The Storage Facility is experimental.");};
17#pragma cyclus def schema cycamore::Storage
19#pragma cyclus def annotations cycamore::Storage
21#pragma cyclus def initinv cycamore::Storage
23#pragma cyclus def snapshotinv cycamore::Storage
25#pragma cyclus def infiletodb cycamore::Storage
27#pragma cyclus def snapshot cycamore::Storage
29#pragma cyclus def clone cycamore::Storage
32void Storage::InitFrom(Storage* m) {
33#pragma cyclus impl initfromcopy cycamore::Storage
34 cyclus::toolkit::CommodityProducer::Copy(m);
38void Storage::InitFrom(cyclus::QueryableBackend* b) {
39#pragma cyclus impl initfromdb cycamore::Storage
41 cyclus::toolkit::Commodity commod = cyclus::toolkit::Commodity(out_commods.front());
42 cyclus::toolkit::CommodityProducer::Add(commod);
43 cyclus::toolkit::CommodityProducer::SetCapacity(commod, throughput);
47void Storage::EnterNotify() {
48 cyclus::Facility::EnterNotify();
50 inventory_tracker.set_capacity(max_inv_size);
51 if (reorder_point < 0 && cumulative_cap <= 0) {
52 InitBuyPolicyParameters();
53 buy_policy.Init(
this, &inventory, std::string(
"inventory"),
54 &inventory_tracker, throughput, active_dist_,
55 dormant_dist_, size_dist_);
57 else if (cumulative_cap > 0) {
58 InitBuyPolicyParameters();
59 buy_policy.Init(
this, &inventory, std::string(
"inventory"),
60 &inventory_tracker, throughput, cumulative_cap,
63 else if (reorder_quantity > 0) {
64 if (reorder_point + reorder_quantity > max_inv_size) {
65 throw cyclus::ValueError(
66 "reorder_point + reorder_quantity must be less than or equal to max_inv_size");
68 buy_policy.Init(
this, &inventory, std::string(
"inventory"),
69 &inventory_tracker, throughput,
"RQ",
70 reorder_quantity, reorder_point);
73 buy_policy.Init(
this, &inventory, std::string(
"inventory"),
74 &inventory_tracker, throughput,
"sS",
75 max_inv_size, reorder_point);
80 cyclus::Composition::Ptr comp = cyclus::Composition::CreateFromAtom(v);
81 if (in_recipe !=
"") {
82 comp = context()->GetRecipe(in_recipe);
85 if (in_commod_prefs.size() == 0) {
86 for (
int i = 0; i < in_commods.size(); ++i) {
87 in_commod_prefs.push_back(cyclus::kDefaultPref);
89 }
else if (in_commod_prefs.size() != in_commods.size()) {
91 ss <<
"in_commod_prefs has " << in_commod_prefs.size()
92 <<
" values, expected " << in_commods.size();
93 throw cyclus::ValueError(ss.str());
96 for (
int i = 0; i != in_commods.size(); ++i) {
97 buy_policy.Set(in_commods[i], comp, in_commod_prefs[i]);
101 std::string package_name_ = context()->GetPackage(package)->name();
102 std::string tu_name_ = context()->GetTransportUnit(transport_unit)->name();
103 if (out_commods.size() == 1) {
104 sell_policy.Init(
this, &stocks, std::string(
"stocks"), cyclus::CY_LARGE_DOUBLE,
false,
105 sell_quantity, package_name_, tu_name_)
106 .Set(out_commods.front())
110 std::stringstream ss;
111 ss <<
"out_commods has " << out_commods.size() <<
" values, expected 1.";
112 throw cyclus::ValueError(ss.str());
115 InitializePosition();
119std::string Storage::str() {
120 std::stringstream ss;
121 std::string ans, out_str;
122 if (out_commods.size() == 1) {
123 out_str = out_commods.front();
127 if (cyclus::toolkit::CommodityProducer::Produces(
128 cyclus::toolkit::Commodity(out_str))) {
133 ss << cyclus::Facility::str();
134 ss <<
" has facility parameters {"
136 <<
" Output Commodity = " << out_str <<
",\n"
137 <<
" Residence Time = " << residence_time <<
",\n"
138 <<
" Throughput = " << throughput <<
",\n"
139 <<
" commod producer members: "
140 <<
" produces " << out_str <<
"?:" << ans <<
"'}";
145void Storage::Tick() {
148 LOG(cyclus::LEV_INFO3,
"ComCnv") << prototype() <<
" is ticking {";
150 LOG(cyclus::LEV_INFO5,
"ComCnv") <<
"Processing = " << processing.quantity() <<
", ready = " << ready.quantity() <<
", stocks = " << stocks.quantity() <<
" and max inventory = " << max_inv_size;
152 LOG(cyclus::LEV_INFO4,
"ComCnv") <<
"current capacity " << max_inv_size <<
" - " << processing.quantity() <<
" - " << ready.quantity() <<
" - " << stocks.quantity() <<
" = " << current_capacity();
154 if (current_capacity() > cyclus::eps_rsrc()) {
155 LOG(cyclus::LEV_INFO4,
"ComCnv")
156 <<
" has capacity for " << current_capacity() <<
".";
158 LOG(cyclus::LEV_INFO3,
"ComCnv") <<
"}";
162void Storage::Tock() {
163 LOG(cyclus::LEV_INFO3,
"ComCnv") << prototype() <<
" is tocking {";
167 LOG(cyclus::LEV_INFO4,
"ComCnv") <<
"processing currently holds " << processing.quantity() <<
". ready currently holds " << ready.quantity() <<
".";
169 if (ready_time() >= 0 || residence_time == 0 && !inventory.empty()) {
170 ReadyMatl_(ready_time());
173 LOG(cyclus::LEV_INFO5,
"ComCnv") <<
"Ready now holds " << ready.quantity() <<
" kg.";
175 if (ready.quantity() > throughput) {
176 LOG(cyclus::LEV_INFO5,
"ComCnv") <<
"Up to " << throughput <<
" kg will be placed in stocks based on throughput limits. ";
179 ProcessMat_(throughput);
181 std::vector<double>::iterator result;
182 result = std::max_element(in_commod_prefs.begin(), in_commod_prefs.end());
183 int maxindx = std::distance(in_commod_prefs.begin(), result);
185 demand = current_capacity();
187 cyclus::toolkit::RecordTimeSeries<double>(
"demand"+in_commods[maxindx],
this, demand);
191 cyclus::toolkit::RecordTimeSeries<double>(
"supply"+out_commods[0],
this,
194 LOG(cyclus::LEV_INFO4,
"ComCnv") <<
"process has "
195 << processing.quantity() <<
". Ready has " << ready.quantity() <<
". Stocks has " << stocks.quantity() <<
".";
196 LOG(cyclus::LEV_INFO3,
"ComCnv") <<
"}";
200void Storage::AddMat_(cyclus::Material::Ptr mat) {
201 LOG(cyclus::LEV_INFO5,
"ComCnv") << prototype() <<
" is initially holding "
202 << inventory.quantity() <<
" total.";
206 }
catch (cyclus::Error& e) {
207 e.msg(Agent::InformErrorMsg(e.msg()));
211 LOG(cyclus::LEV_INFO5,
"ComCnv")
212 << prototype() <<
" added " << mat->quantity()
213 <<
" of material to its inventory, which is holding "
214 << inventory.quantity() <<
" total.";
218void Storage::BeginProcessing_() {
219 while (inventory.count() > 0) {
221 processing.Push(inventory.Pop());
222 entry_times.push_back(context()->time());
224 LOG(cyclus::LEV_DEBUG2,
"ComCnv")
225 <<
"Storage " << prototype()
226 <<
" added resources to processing at t= " << context()->time();
227 }
catch (cyclus::Error& e) {
228 e.msg(Agent::InformErrorMsg(e.msg()));
235void Storage::ProcessMat_(
double cap) {
236 if (!ready.empty()) {
238 double max_pop = std::min(cap, ready.quantity());
240 if (discrete_handling) {
241 if (max_pop == ready.quantity()) {
242 stocks.Push(ready.PopN(ready.count()));
244 double cap_pop = ready.Peek()->quantity();
245 while (cap_pop <= max_pop && !ready.empty()) {
246 stocks.Push(ready.Pop());
247 cap_pop += ready.empty() ? 0 : ready.Peek()->quantity();
251 stocks.Push(ready.Pop(max_pop, cyclus::eps_rsrc()));
254 LOG(cyclus::LEV_INFO4,
"ComCnv") <<
"Storage " << prototype()
255 <<
" moved resources"
256 <<
" from ready to stocks"
257 <<
" at t= " << context()->time();
258 }
catch (cyclus::Error& e) {
259 e.msg(Agent::InformErrorMsg(e.msg()));
266void Storage::ReadyMatl_(
int time) {
267 LOG(cyclus::LEV_INFO5,
"ComCnv") <<
"Placing material into ready";
271 while (!entry_times.empty() && entry_times.front() <= time) {
272 entry_times.pop_front();
276 ready.Push(processing.PopN(to_ready));
281 return new Storage(ctx);
Storage(cyclus::Context *ctx)
cyclus::Agent * ConstructStorage(cyclus::Context *ctx)