CYCLUS
Loading...
Searching...
No Matches
total_inv_tracker.h
Go to the documentation of this file.
1#ifndef CYCLUS_SRC_TOOLKIT_TOTAL_INV_TRACKER_H_
2#define CYCLUS_SRC_TOOLKIT_TOTAL_INV_TRACKER_H_
3
4#include "error.h"
5#include "res_buf.h"
6
7namespace cyclus {
8namespace toolkit {
9
10/// TotalInvTracker is a helper class that tracks the total inventory of
11/// multiple ResBufs. This can be useful when a single agent uses multiple
12/// buffers to manage their process, but a limit should be placed on their
13/// combined inventory, such as a agent- or facility-wide maximum inventory.
14/// Like ResBufs, TotalInvTracker has an infinite capacity unless explicitly
15/// changed.
16///
17/// TotalInvTracker does not hold any inventory itself, it only tracks the
18/// quantities of other ResBufs. TotalInvTracker currently tracks quantities
19/// alone, not compositions.
20///
21/// @code
22/// class MyAgent : public cyclus:: Facility {
23/// public:
24/// EnterNotify() {
25/// cyclus::Facility::EnterNotify();
26/// tracker_.Init({&inventory_, &outventory_}, facility_max_inv_size_);
27///
28/// cyclus::MatlBuyPolicy p;
29/// p.Init(this, &inventory_, "inventory", &tracker_);
30/// }
31/// protected:
32/// cyclus::toolkit::ResBuf<cyclus::Material> inventory_;
33/// cyclus::toolkit::ResBuf<cyclus::Material> outventory_;
34///
35/// double facility_max_inv_size_ = 1000;
36/// cyclus::toolkit::TotalInvTracker tracker_;
37/// }
38
39class TotalInvTracker {
40 public:
41 /// Creates an uninitialized tracker. The Init function MUST be called before
42 /// the tracker is used.
43 TotalInvTracker()
44 : max_inv_size_(std::numeric_limits<double>::max()), qty_(0){};
45
46 TotalInvTracker(std::vector<ResBuf<Material>*> bufs,
47 double max_inv_size = std::numeric_limits<double>::max()) {
48 Init(bufs, max_inv_size);
49 }
50
51 ~TotalInvTracker(){};
52
53 /// Initializes the tracker with the given ResBufs. The tracker will have
54 /// infinite capacity unless explicitly changed.
55 void Init(std::vector<ResBuf<Material>*> bufs,
56 double max_inv_size = std::numeric_limits<double>::max()) {
57 if (bufs.size() == 0) {
58 throw ValueError(
59 "TotalInvTracker must be initialized with at least one ResBuf");
60 }
61 bufs_ = bufs;
62 if (max_inv_size <= 0) {
63 throw ValueError(
64 "TotalInvTracker must be initialized with a positive capacity");
65 }
66 max_inv_size_ = max_inv_size;
67 }
68
69 /// Returns the total quantity of all tracked ResBufs.
70 /// @throws ValueError if the tracker has not been initialized (zero)
71 inline double quantity() {
72 int num = num_bufs();
73 qty_ = 0;
74 for (int i = 0; i < num; i++) {
75 qty_ += bufs_[i]->quantity();
76 }
77 return qty_;
78 }
79
80 /// Returns the total capacity that could go in the ResBufs. Either the
81 /// capacity of the TotalInvTracker, or the sum of each ResBuf's capacity,
82 /// whichever is lower.
83 inline double capacity() {
84 return std::min(total_capacity_bufs(), max_inv_size_);
85 }
86
87 // Returns the sum of the capacities of all buffers. Does not include the
88 // capacity of the tracker
89 inline double total_capacity_bufs() {
90 int num = num_bufs();
91 double cap = 0;
92 for (int i = 0; i < num; i++) {
93 cap += bufs_[i]->capacity();
94 }
95 return cap;
96 }
97
98 /// Returns the total capacity of the traker. Does not include ResBufs
99 inline double tracker_capacity() { return max_inv_size_; }
100
101 /// Returns the remaining facility-wide space across all tracked ResBufs.
102 inline double space() { return std::max(0.0, capacity() - quantity()); }
103
104 /// Returns the remaining space in the given ResBuf, considering the
105 /// facility-wide limitations.
106 inline double constrained_buf_space(ResBuf<Material>* buf) {
107 return std::min(buf->space(), space());
108 }
109
110 /// Returns true if there are no resources in any buffer
111 inline bool empty() { return quantity() == 0; }
112
113 /// Returns number of buffers being tracked
114 /// @throws ValueError if the tracker has not been initialized (zero)
115 inline int num_bufs() {
116 int num = bufs_.size();
117 if (num == 0) {
118 throw ValueError(
119 "TotalInvTracker has not been initialized, no buffers to track");
120 }
121 return num;
122 }
123
124 /// Change the total capacity across all ResBufs. The new capacity must be
125 /// greater than the current quantity.
126 /// @throws ValueError if the new capacity is less than the current quantity
127 void set_capacity(double cap) {
128 if (quantity() - cap > eps_rsrc()) {
129 std::stringstream ss;
130 ss << std::setprecision(17) << "new capacity " << cap
131 << " lower than existing quantity " << quantity();
132 throw ValueError(ss.str());
133 }
134 max_inv_size_ = cap;
135 }
136
137 bool buf_in_tracker(ResBuf<Material>* buf) {
138 for (int i = 0; i < num_bufs(); i++) {
139 if (bufs_[i] == buf) {
140 return true;
141 }
142 }
143 return false;
144 }
145
146 private:
147 double max_inv_size_;
148 double qty_;
149 std::vector<ResBuf<Material>*> bufs_;
150};
151
152} // namespace toolkit
153} // namespace cyclus
154
155#endif // CYCLUS_SRC_TOOLKIT_TOTAL_INV_TRACKER_H_
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