CYCLUS
Loading...
Searching...
No Matches
matl_buy_policy.cc
Go to the documentation of this file.
1#include "matl_buy_policy.h"
2
3#include <sstream>
4
5#include "error.h"
6
7#define LG(X) LOG(LEV_##X, "buypol")
8#define LGH(X) \
9 LOG(LEV_##X, "buypol") << "policy " << name_ << " (agent " \
10 << Trader::manager()->prototype() << "-" \
11 << Trader::manager()->id() << "): "
12
13namespace cyclus {
14namespace toolkit {
15
17 Trader(NULL),
18 name_(""),
19 throughput_(std::numeric_limits<double>::max()),
20 quantize_(-1),
21 fill_to_(std::numeric_limits<double>::max()),
22 req_at_(std::numeric_limits<double>::max()),
23 cumulative_cap_(-1),
24 cycle_total_inv_(0),
25 active_dist_(NULL),
26 dormant_dist_(NULL),
27 size_dist_(NULL){
29 "MatlBuyPolicy is experimental and its API may be subject to change");
30}
31
33 if (manager() != NULL)
35}
36
38 throughput_ = std::numeric_limits<double>::max();
39 quantize_ = -1;
40 fill_to_ = std::numeric_limits<double>::max();
41 req_at_ = std::numeric_limits<double>::max();
42 cumulative_cap_ = -1;
43 cycle_total_inv_ = 0;
44 active_dist_ = NULL;
45 dormant_dist_ = NULL;
46 size_dist_ = NULL;
47 return *this;
48}
49
50void MatlBuyPolicy::set_manager(Agent* m) {
51 if (m != NULL) {
53 }
54 else {
55 std::stringstream ss;
56 ss << "No manager set on Buy Policy " << name_;
57 throw ValueError(ss.str());
58 }
59}
60
61void MatlBuyPolicy::set_total_inv_tracker(TotalInvTracker* t) {
62 if (t == NULL){
63 std::vector<ResBuf<Material>*> bufs = {buf_};
64 buf_tracker_->Init(bufs, buf_->capacity());
65 }
66 else if (!t->buf_in_tracker(buf_)) {
67 std::stringstream ss;
68 ss << "TotalInvTracker does not contain ResBuf used in buy policy";
69 throw ValueError(ss.str());
70 }
71 else {
72 buf_tracker_ = t;
73 }
74}
75
76void MatlBuyPolicy::set_inv_policy(std::string inv_policy, double fill, double req_at) {
77 set_req_at(req_at);
78 std::transform(inv_policy.begin(), inv_policy.end(), inv_policy.begin(), ::tolower);
79 if ((inv_policy == "ss")) {
80 set_fill_to(fill);
81 }
82 else if ((inv_policy == "rq") || (inv_policy == "qr")) {
83 set_quantize(fill);
84 // maximum amount that an RQ policy could achieve is req_at + fill
85 set_fill_to(req_at + fill);
86 }
87 else {
88 throw ValueError("Invalid inventory policy");
89 }
90}
91
92void MatlBuyPolicy::set_fill_to(double x) {
93 assert(x > 0);
94 fill_to_ = std::min(x, buf_->capacity());
95}
96
97void MatlBuyPolicy::set_req_at(double x) {
98 assert(x >= 0);
99 req_at_ = std::min(x, buf_->capacity());
100}
101
102void MatlBuyPolicy::set_cumulative_cap(double x) {
103 assert(x > 0);
104 cumulative_cap_ = std::min(x, buf_->capacity());
105}
106
107void MatlBuyPolicy::set_quantize(double x) {
108 assert(x != 0);
109 quantize_ = x;
110}
111
112void MatlBuyPolicy::set_throughput(double x) {
113 assert(x >= 0);
114 throughput_ = x;
115}
116
117void MatlBuyPolicy::init_active_dormant() {
118 if (active_dist_ == NULL) {
119 active_dist_ = boost::shared_ptr<FixedIntDist>(new FixedIntDist(1));
120 }
121 if (dormant_dist_ == NULL) {
122 dormant_dist_ = boost::shared_ptr<FixedIntDist>(new FixedIntDist(-1));
123 }
124 if (size_dist_ == NULL) {
125 size_dist_ = boost::shared_ptr<FixedDoubleDist>(new FixedDoubleDist(1.0));
126 }
127
128 if (size_dist_->max() > 1) {
129 throw ValueError("Size distribution cannot have a max greater than 1.");
130 }
131
133 LGH(INFO4) << "first active time end: " << next_active_end_ << std::endl;
134
135 if (dormant_dist_->sample() < 0) {
136 next_dormant_end_ = -1;
137 LGH(INFO4) << "dormant length -1, always active" << std::endl;
138 }
139 else if (use_cumulative_capacity()) {
140 next_dormant_end_ = -1;
141 LGH(INFO4) << "dormant length set at -1 for first active period of cumulative capacity cycle" << std::endl;
142 }
143 else {
145 LGH(INFO4) << "first dormant time end: " << next_dormant_end_ << std::endl;
146 }
147}
148
150 std::string name, TotalInvTracker* buf_tracker) {
151 set_manager(manager);
152 buf_ = buf;
153 name_ = name;
154 set_total_inv_tracker(buf_tracker);
155 init_active_dormant();
156 return *this;
157}
158
160 std::string name, TotalInvTracker* buf_tracker,
161 double throughput, boost::shared_ptr<IntDistribution> active_dist,
162 boost::shared_ptr<IntDistribution> dormant_dist,
163 boost::shared_ptr<DoubleDistribution> size_dist) {
164 set_manager(manager);
165 buf_ = buf;
166 name_ = name;
167 set_total_inv_tracker(buf_tracker);
168 set_throughput(throughput);
169 active_dist_ = active_dist;
170 dormant_dist_ = dormant_dist;
171 size_dist_ = size_dist;
172 init_active_dormant();
173 return *this;
174}
175
177 std::string name, TotalInvTracker* buf_tracker,
178 double throughput, double quantize) {
179 set_manager(manager);
180 buf_ = buf;
181 name_ = name;
182 set_total_inv_tracker(buf_tracker);
183 set_throughput(throughput);
184 set_quantize(quantize);
185 init_active_dormant();
186 return *this;
187}
188
190 std::string name,
191 TotalInvTracker* buf_tracker,
192 double throughput,
193 std::string inv_policy,
194 double fill_behav, double req_at) {
195 set_manager(manager);
196 buf_ = buf;
197 name_ = name;
198 set_total_inv_tracker(buf_tracker);
199 set_inv_policy(inv_policy, fill_behav, req_at);
200 set_throughput(throughput);
201 init_active_dormant();
202 return *this;
203}
204
206 std::string name,
207 TotalInvTracker* buf_tracker,
208 std::string inv_policy,
209 double fill_behav, double req_at) {
210 set_manager(manager);
211 buf_ = buf;
212 name_ = name;
213 set_total_inv_tracker(buf_tracker);
214 set_inv_policy(inv_policy, fill_behav, req_at);
215 init_active_dormant();
216 return *this;
217}
218
220 std::string name,
221 TotalInvTracker* buf_tracker,
222 double throughput, double cumulative_cap,
223 boost::shared_ptr<IntDistribution> dormant_dist) {
224 set_manager(manager);
225 buf_ = buf;
226 name_ = name;
227 set_total_inv_tracker(buf_tracker);
228 set_throughput(throughput);
229 set_cumulative_cap(cumulative_cap);
230 dormant_dist_ = dormant_dist;
231 init_active_dormant();
232 return *this;
233}
234
235MatlBuyPolicy& MatlBuyPolicy::Set(std::string commod) {
236 CompMap c;
237 c[10010000] = 1e-100;
238 return Set(commod, Composition::CreateFromMass(c), 1.0);
239}
240
242 return Set(commod, c, 1.0);
243}
244
246 double pref) {
247 CommodDetail d;
248 d.comp = c;
249 d.pref = pref;
250 commod_details_[commod] = d;
251 return *this;
252}
253
255
256 commod_details_.erase(commod);
257 return *this;
258}
259
261 if (manager() == NULL) {
262 std::stringstream ss;
263 ss << "No manager set on Buy Policy " << name_;
264 throw ValueError(ss.str());
265 }
266 manager()->context()->RegisterTrader(this);
267}
268
270 if (manager() == NULL) {
271 std::stringstream ss;
272 ss << "No manager set on Buy Policy " << name_;
273 throw ValueError(ss.str());
274 }
275 manager()->context()->UnregisterTrader(this);
276}
277
278std::set<RequestPortfolio<Material>::Ptr> MatlBuyPolicy::GetMatlRequests() {
279 rsrc_commods_.clear();
280 std::set<RequestPortfolio<Material>::Ptr> ports;
281
282 double amt = 0;
283
284 int current_time_ = manager()->context()->time();
285
286 double max_request_amt = use_cumulative_capacity() ? cumulative_cap_ - cycle_total_inv_ : std::numeric_limits<double>::max();
287
288 if (MakeReq() && !dormant(current_time_)) {
289 amt = std::min(TotalAvailable() * SampleRequestSize(), max_request_amt);
290 }
291 else { LGH(INFO3) << "in dormant period, no request" << std::endl; }
292
294
295 if (amt < eps())
296 return ports;
297
298 bool excl = Excl();
299 double req_amt = ReqQty(amt);
300 int n_req = NReq(amt);
301 LGH(INFO3) << "requesting " << amt << " kg via " << n_req << " request(s)" << std::endl;
302
303 // one portfolio for each request
304 for (int i = 0; i != n_req; i++) {
306 std::vector<Request<Material>*> mreqs;
307 std::map<std::string, CommodDetail>::iterator it;
308 for (it = commod_details_.begin(); it != commod_details_.end(); ++it) {
309 std::string commod = it->first;
310 CommodDetail d = it->second;
311 LG(INFO3) << " - one " << amt << " kg request of " << commod;
312 Material::Ptr m = Material::CreateUntracked(req_amt, d.comp);
313 Request<Material>* r = port->AddRequest(m, this, commod, d.pref, excl);
314 mreqs.push_back(r);
315 }
316 port->AddMutualReqs(mreqs);
317 ports.insert(port);
318 }
319
320 return ports;
321}
322
324 const std::vector<std::pair<Trade<Material>, Material::Ptr> >& resps) {
325 std::vector<std::pair<Trade<Material>, Material::Ptr> >::const_iterator it;
326 rsrc_commods_.clear();
327 for (it = resps.begin(); it != resps.end(); ++it) {
328 rsrc_commods_[it->second] = it->first.request->commodity();
329 LGH(INFO3) << "got " << it->second->quantity() << " kg of "
330 << it->first.request->commodity() << std::endl;
331 buf_->Push(it->second);
332 // cumulative capacity handling
334 cycle_total_inv_ += it->second->quantity();
335 }
336 }
337 // check if cumulative cap has been reached. If yes, then sample for dormant
338 // length and reset cycle_total_inv
339 if (use_cumulative_capacity() && (
340 (cumulative_cap_ - cycle_total_inv_) < eps_rsrc())) {
342 LGH(INFO3) << "cycle cumulative inventory has been reached. Dormant period will end at " << next_dormant_end_ << std::endl;
343 cycle_total_inv_ = 0;
344 }
345}
346
348 int active_length = active_dist_->sample();
349 next_active_end_ = active_length + manager()->context()->time();
350 if (manager() != NULL) {
352 RecordActiveDormantTime(manager()->context()->time(), "CumulativeCap", active_length);
353 } else {
354 RecordActiveDormantTime(manager()->context()->time(), "Active", active_length);
355 }
356 }
357 return;
358};
359
361 int dormant_length;
362 int dormant_start;
364 // cumulative_cap dormant portion is updated only after the active cycle
365 // ends, because it's based on actual material recieved and not a dist
366 // that can be sampled at any time. Therefore, need the +1 when
367 // because next_active_end_ is not useful
368 dormant_length = dormant_dist_->sample();
369 dormant_start = manager()->context()->time() + 1;
370 }
371 else if (next_dormant_end_ >= 0) {
372 // dormant dist is used, and so is active dist. Just need to sample for
373 // length and add to active cycle
374 dormant_length = dormant_dist_->sample();
375 dormant_start = std::max(next_active_end_, 1);
376 } else { // next_active_end_ < 0 used to indicate always active. Do not enter dormant
377 return;
378 }
379 next_dormant_end_ = dormant_length + dormant_start;
380 if (manager() != NULL) {
381 RecordActiveDormantTime(dormant_start, "Dormant", dormant_length);
382 }
383 return;
384}
385
387 return size_dist_->sample();
388}
389
391 if (manager()->context()->time() == next_dormant_end_) {
392 if (use_cumulative_capacity()) { next_dormant_end_ = -1; }
393 else {
395
397 LGH(INFO4) << "end of dormant period, next active time end: " << next_active_end_ << ", and next dormant time end: " << next_dormant_end_ << std::endl;
398 }
399 }
400 return;
401}
402
403void MatlBuyPolicy::RecordActiveDormantTime(int time, std::string type, int length) {
404 manager()->context()->NewDatum("BuyPolActiveDormant")
405 ->AddVal("Agent", manager()->id())
406 ->AddVal("Time", time)
407 ->AddVal("Type", type)
408 ->AddVal("Length", length)
409 ->Record();
410 return;
411}
412
413} // namespace toolkit
414} // namespace cyclus
The abstract base class used by all types of agents that live and interact in a simulation.
Definition agent.h:49
Context * context() const
Returns this agent's simulation context.
Definition agent.h:367
static Ptr CreateFromMass(CompMap v)
Creates a new composition from v with its components having appropriate mass-based ratios.
boost::shared_ptr< Composition > Ptr
Definition composition.h:43
void UnregisterTrader(Trader *e)
Unregisters an agent as a participant in resource exchanges.
Definition context.h:181
Datum * NewDatum(std::string title)
See Recorder::NewDatum documentation.
Definition context.cc:361
void RegisterTrader(Trader *e)
Registers an agent as a participant in resource exchanges.
Definition context.h:176
virtual int time()
Returns the current simulation timestep.
Definition context.cc:323
Datum * AddVal(const char *field, boost::spirit::hold_any val, std::vector< int > *shape=NULL)
Add an arbitrary field-value pair to the datum.
Definition datum.cc:22
void Record()
Record this datum to its Recorder.
Definition datum.cc:35
boost::shared_ptr< Material > Ptr
Definition material.h:75
static Ptr CreateUntracked(double quantity, Composition::Ptr c)
Creates a new material resource that does not actually exist as part of the simulation and is untrack...
Definition material.cc:24
A RequestPortfolio is a group of (possibly constrained) requests for resources.
void AddMutualReqs(const std::vector< Request< T > * > &rs)
adds a collection of requests (already having been registered with this portfolio) as multicommodity ...
Request< T > * AddRequest(boost::shared_ptr< T > target, Trader *requester, std::string commodity, double preference, bool exclusive, cost_function_t cost_function)
add a request to the portfolio
boost::shared_ptr< RequestPortfolio< T > > Ptr
A Request encapsulates all the information required to communicate the needs of an agent in the Dynam...
Definition request.h:29
A simple API for agents that wish to exchange resources in the simulation.
Definition trader.h:24
Agent * manager_
Definition trader.h:88
virtual Agent * manager()
Definition trader.h:28
For values that are too big, too small, etc.
Definition error.h:41
MatlBuyPolicy performs semi-automatic inventory management of a material buffer by making requests an...
void Stop()
Unregisters this policy as a trader in the current simulation.
int NReq(double amt) const
the number of requests made per each commodity
MatlBuyPolicy & Set(std::string commod)
Instructs the policy to fill its buffer with requests on the given commodity of composition c and the...
virtual std::set< RequestPortfolio< Material >::Ptr > GetMatlRequests()
Trader Methods.
void Start()
Registers this policy as a trader in the current simulation.
virtual void AcceptMatlTrades(const std::vector< std::pair< Trade< Material >, Material::Ptr > > &resps)
default implementation for material trade acceptance
bool Excl() const
whether trades will be denoted as exclusive or not
MatlBuyPolicy & Init(Agent *manager, ResBuf< Material > *buf, std::string name, TotalInvTracker *buf_tracker)
Configures the policy to keep buf filled to a certain fraction of its capacity every time step.
MatlBuyPolicy & Unset(std::string commod)
Instructs the policy to stop requesting a speific commodity.
MatlBuyPolicy & ResetBehavior()
Reset a material buy policy parameters that govern its behavior to the default state.
double TotalAvailable() const
the total amount available to request
bool MakeReq() const
whether a request can be made
void RecordActiveDormantTime(int time, std::string type, int length)
MatlBuyPolicy()
Creates an uninitialized policy.
double ReqQty(double amt) const
the amount requested per each request
ResBuf is a helper class that provides semi-automated management of a collection of resources (e....
Definition res_buf.h:62
#define LG(X)
#define LGH(X)
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or....
Definition agent.cc:14
double eps_rsrc()
an epsilon value to be used by resources
Definition cyc_limits.h:19
std::map< Nuc, double > CompMap
a raw definition of nuclides and corresponding (dimensionless quantities).
Definition composition.h:17
double eps()
a generic epsilon value
Definition cyc_limits.h:12
void Warn(const std::string &msg)
Issue a warning with the approriate message, accoring to the current warning settings.
Definition error.h:115
A Trade is a simple container that associates a request for a resource with a bid for that resource.
Definition trade.h:16