|
| 1 | +#include <algorithm> |
| 2 | +#include <sstream> |
| 3 | + |
| 4 | +#include <boost/lexical_cast.hpp> |
| 5 | +#include "toolkit/mat_query.h" |
| 6 | + |
| 7 | +#include "conversion.h" |
| 8 | + |
| 9 | +using cyclus::RequestPortfolio; |
| 10 | +using cyclus::BidPortfolio; |
| 11 | +using cyclus::CommodMap; |
| 12 | +using cyclus::Request; |
| 13 | +using cyclus::Trade; |
| 14 | +using cyclus::Material; |
| 15 | +using cyclus::CapacityConstraint; |
| 16 | +using cyclus::toolkit::ResBuf; |
| 17 | +using cyclus::toolkit::RecordTimeSeries; |
| 18 | + |
| 19 | +namespace cycamore { |
| 20 | + |
| 21 | +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 22 | +Conversion::Conversion(cyclus::Context* ctx) |
| 23 | + : cyclus::Facility(ctx) { |
| 24 | + |
| 25 | + // Make our Resource Buffers bulk buffers |
| 26 | + input = ResBuf<Material>(true); |
| 27 | + output = ResBuf<Material>(true); |
| 28 | + } |
| 29 | + |
| 30 | +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 31 | +Conversion::~Conversion() {} |
| 32 | + |
| 33 | +#pragma cyclus def schema cycamore::Conversion |
| 34 | +#pragma cyclus def annotations cycamore::Conversion |
| 35 | +#pragma cyclus def infiletodb cycamore::Conversion |
| 36 | +#pragma cyclus def snapshot cycamore::Conversion |
| 37 | +#pragma cyclus def snapshotinv cycamore::Conversion |
| 38 | +#pragma cyclus def initinv cycamore::Conversion |
| 39 | +#pragma cyclus def clone cycamore::Conversion |
| 40 | +#pragma cyclus def initfromdb cycamore::Conversion |
| 41 | +#pragma cyclus def initfromcopy cycamore::Conversion |
| 42 | + |
| 43 | +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 44 | +void Conversion::EnterNotify() { |
| 45 | + cyclus::Facility::EnterNotify(); |
| 46 | + InitializePosition(); |
| 47 | +} |
| 48 | + |
| 49 | +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 50 | +std::string Conversion::str() { |
| 51 | + using std::string; |
| 52 | + using std::vector; |
| 53 | + std::stringstream ss; |
| 54 | + ss << cyclus::Facility::str(); |
| 55 | + |
| 56 | + string msg = ""; |
| 57 | + msg += "accepts commodities "; |
| 58 | + for (vector<string>::iterator commod = incommods.begin(); |
| 59 | + commod != incommods.end(); |
| 60 | + commod++) { |
| 61 | + msg += (commod == incommods.begin() ? "{" : ", "); |
| 62 | + msg += (*commod); |
| 63 | + } |
| 64 | + msg += "} until its input is full at "; |
| 65 | + msg += std::to_string(input.capacity()); |
| 66 | + msg += " kg."; |
| 67 | + |
| 68 | + msg += "} and converts "; |
| 69 | + msg += std::to_string(throughput); |
| 70 | + msg += " kg/timestep into commodity "; |
| 71 | + ss << msg << outcommod; |
| 72 | + return "" + ss.str(); |
| 73 | +} |
| 74 | + |
| 75 | +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 76 | +void Conversion::Tick() { |
| 77 | + Convert(); |
| 78 | +} |
| 79 | + |
| 80 | +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 81 | +void Conversion::Tock() {} |
| 82 | + |
| 83 | +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 84 | +double Conversion::AvailableFeedstockCapacity() { |
| 85 | + return input.capacity() - input.quantity(); |
| 86 | +} |
| 87 | + |
| 88 | +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 89 | +void Conversion::Convert() { |
| 90 | + if (input.quantity() > 0) { |
| 91 | + output.Push(input.Pop(std::min(input.quantity(), throughput))); |
| 92 | + } |
| 93 | +} |
| 94 | + |
| 95 | +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 96 | +std::set<RequestPortfolio<Material>::Ptr> Conversion::GetMatlRequests() { |
| 97 | + std::set<RequestPortfolio<Material>::Ptr> ports; |
| 98 | + |
| 99 | + // Check if we need material |
| 100 | + double available_capacity = AvailableFeedstockCapacity(); |
| 101 | + if (available_capacity <= 0) return ports; |
| 102 | + |
| 103 | + // Create request portfolio |
| 104 | + RequestPortfolio<Material>::Ptr port(new RequestPortfolio<Material>()); |
| 105 | + |
| 106 | + // Create material request with no recipe |
| 107 | + Material::Ptr mat = cyclus::NewBlankMaterial(available_capacity); |
| 108 | + |
| 109 | + |
| 110 | + // Add request for all commodities using default preference |
| 111 | + for (std::vector<std::string>::iterator it = incommods.begin(); |
| 112 | + it != incommods.end(); ++it) { |
| 113 | + Request<Material>* req = port->AddRequest(mat, this, *it); |
| 114 | + } |
| 115 | + |
| 116 | + // Add capacity constraint to ensure we never get more feed than capacity |
| 117 | + CapacityConstraint<Material> cc(available_capacity); |
| 118 | + port->AddConstraint(cc); |
| 119 | + |
| 120 | + ports.insert(port); |
| 121 | + return ports; |
| 122 | +} |
| 123 | + |
| 124 | +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 125 | +std::set<BidPortfolio<Material>::Ptr> Conversion::GetMatlBids( |
| 126 | + CommodMap<Material>::type& commod_requests) { |
| 127 | + std::set<BidPortfolio<Material>::Ptr> ports; |
| 128 | + |
| 129 | + // Check if we have material to offer |
| 130 | + if (output.quantity() <= 0) return ports; |
| 131 | + |
| 132 | + // Create bid portfolio |
| 133 | + BidPortfolio<Material>::Ptr port(new BidPortfolio<Material>()); |
| 134 | + |
| 135 | + // Respond to requests for our commodity |
| 136 | + std::vector<Request<Material>*>& requests = commod_requests[outcommod]; |
| 137 | + for (std::vector<Request<Material>*>::iterator it = requests.begin(); |
| 138 | + it != requests.end(); ++it) { |
| 139 | + |
| 140 | + double available = output.quantity(); |
| 141 | + double requested = (*it)->target()->quantity(); |
| 142 | + double offer_qty = std::min(available, requested); |
| 143 | + |
| 144 | + if (offer_qty > 0) { |
| 145 | + Material::Ptr offer = Material::CreateUntracked(offer_qty, output.Peek()->comp()); |
| 146 | + port->AddBid(*it, offer, this); // Note: *it, not **it |
| 147 | + } |
| 148 | + } |
| 149 | + |
| 150 | + // Add capacity constraint so we never give out more than we have |
| 151 | + CapacityConstraint<Material> cc(output.quantity()); |
| 152 | + port->AddConstraint(cc); |
| 153 | + |
| 154 | + ports.insert(port); |
| 155 | + return ports; |
| 156 | +} |
| 157 | + |
| 158 | +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 159 | +void Conversion::AcceptMatlTrades( |
| 160 | + const std::vector<std::pair<Trade<Material>, Material::Ptr>>& responses) { |
| 161 | + |
| 162 | + for (std::vector<std::pair<Trade<Material>, Material::Ptr>>::const_iterator it = |
| 163 | + responses.begin(); it != responses.end(); ++it) { |
| 164 | + |
| 165 | + |
| 166 | + // Add material to the input buffer |
| 167 | + input.Push(it->second); |
| 168 | + |
| 169 | + } |
| 170 | +} |
| 171 | + |
| 172 | +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 173 | +void Conversion::GetMatlTrades( |
| 174 | + const std::vector<Trade<Material>>& trades, |
| 175 | + std::vector<std::pair<Trade<Material>, Material::Ptr>>& responses) { |
| 176 | + |
| 177 | + for (std::vector<Trade<Material>>::const_iterator it = trades.begin(); |
| 178 | + it != trades.end(); ++it) { |
| 179 | + |
| 180 | + Material::Ptr response = output.Pop(it->amt); |
| 181 | + |
| 182 | + responses.push_back(std::make_pair(*it, response)); |
| 183 | + } |
| 184 | +} |
| 185 | + |
| 186 | +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 187 | +extern "C" cyclus::Agent* ConstructConversion(cyclus::Context* ctx) { |
| 188 | + return new Conversion(ctx); |
| 189 | +} |
| 190 | + |
| 191 | +} // namespace cycamore |
| 192 | + |
0 commit comments