CYCAMORE
Loading...
Searching...
No Matches
src/source.cc
Go to the documentation of this file.
1#include "source.h"
2
3#include <sstream>
4#include <limits>
5
6#include <boost/lexical_cast.hpp>
7
8namespace cycamore {
9
10Source::Source(cyclus::Context* ctx)
11 : cyclus::Facility(ctx),
12 throughput(std::numeric_limits<double>::max()),
13 inventory_size(std::numeric_limits<double>::max()),
14 package(cyclus::Package::unpackaged_name()),
15 transport_unit(cyclus::TransportUnit::unrestricted_name()) {}
16
17Source::~Source() {}
18
19void Source::InitFrom(Source* m) {
20 #pragma cyclus impl initfromcopy cycamore::Source
21 cyclus::toolkit::CommodityProducer::Copy(m);
22}
23
24void Source::InitFrom(cyclus::QueryableBackend* b) {
25 #pragma cyclus impl initfromdb cycamore::Source
26 namespace tk = cyclus::toolkit;
27 tk::CommodityProducer::Add(tk::Commodity(outcommod),
28 tk::CommodInfo(throughput, throughput));
29}
30
31std::string Source::str() {
32 namespace tk = cyclus::toolkit;
33 std::stringstream ss;
34 std::string ans;
35 if (cyclus::toolkit::CommodityProducer::Produces(
36 cyclus::toolkit::Commodity(outcommod))) {
37 ans = "yes";
38 } else {
39 ans = "no";
40 }
41 ss << cyclus::Facility::str() << " supplies commodity '" << outcommod
42 << "' with recipe '" << outrecipe << "' at a throughput of "
43 << throughput << " kg per time step "
44 << " commod producer members: "
45 << " produces " << outcommod << "?: " << ans
46 << " throughput: " << cyclus::toolkit::CommodityProducer::Capacity(outcommod)
47 << " with package type: " << package
48 << " and transport unit type: " << transport_unit
49 << " cost: " << cyclus::toolkit::CommodityProducer::Cost(outcommod);
50 return ss.str();
51}
52
53void Source::EnterNotify() {
54 cyclus::Facility::EnterNotify();
55 InitializePosition();
56}
57
58void Source::Build(cyclus::Agent* parent) {
59 Facility::Build(parent);
60
61 using cyclus::CompMap;
62 using cyclus::Composition;
63 using cyclus::Material;
64
65 // create all source inventory and place into buf
66 cyclus::Material::Ptr all_inv;
67 Composition::Ptr blank_comp = Composition::CreateFromMass(CompMap());
68 all_inv = (outrecipe.empty() || context() == NULL) ? \
69 Material::Create(this, inventory_size, blank_comp) : \
70 Material::Create(this, inventory_size, context()->GetRecipe(outrecipe));
71 inventory.Push(all_inv);
72
73}
74
75std::set<cyclus::BidPortfolio<cyclus::Material>::Ptr> Source::GetMatlBids(
76 cyclus::CommodMap<cyclus::Material>::type& commod_requests) {
77 using cyclus::BidPortfolio;
78 using cyclus::CapacityConstraint;
79 using cyclus::Material;
80 using cyclus::Package;
81 using cyclus::Request;
82 using cyclus::TransportUnit;
83
84 double max_qty = std::min(throughput, inventory.quantity());
85 cyclus::toolkit::RecordTimeSeries<double>("supply"+outcommod, this,
86 max_qty);
87 LOG(cyclus::LEV_INFO3, "Source") << prototype() << " is bidding up to "
88 << max_qty << " kg of " << outcommod;
89 LOG(cyclus::LEV_INFO5, "Source") << "stats: " << str();
90
91 std::set<BidPortfolio<Material>::Ptr> ports;
92 if (max_qty < cyclus::eps()) {
93 return ports;
94 } else if (commod_requests.count(outcommod) == 0) {
95 return ports;
96 }
97
98 BidPortfolio<Material>::Ptr port(new BidPortfolio<Material>());
99 std::vector<Request<Material>*>& requests = commod_requests[outcommod];
100 std::vector<Request<Material>*>::iterator it;
101 for (it = requests.begin(); it != requests.end(); ++it) {
102 Request<Material>* req = *it;
103 Material::Ptr target = req->target();
104 double qty = std::min(target->quantity(), max_qty);
105
106 // calculate packaging
107 std::vector<double> bids = context()->GetPackage(package)->GetFillMass(qty);
108
109 // calculate transport units
110 int shippable_pkgs = context()->GetTransportUnit(transport_unit)
111 ->MaxShippablePackages(bids.size());
112 if (shippable_pkgs < bids.size()) {
113 bids.erase(bids.begin() + shippable_pkgs, bids.end());
114 }
115
116 std::vector<double>::iterator bit;
117 for (bit = bids.begin(); bit != bids.end(); ++bit) {
118 Material::Ptr m;
119 m = outrecipe.empty() ? \
120 Material::CreateUntracked(*bit, target->comp()) : \
121 Material::CreateUntracked(*bit, context()->GetRecipe(outrecipe));
122 port->AddBid(req, m, this);
123 }
124 }
125
126 CapacityConstraint<Material> cc(max_qty);
127 port->AddConstraint(cc);
128 ports.insert(port);
129 return ports;
130}
131
132void Source::GetMatlTrades(
133 const std::vector<cyclus::Trade<cyclus::Material> >& trades,
134 std::vector<std::pair<cyclus::Trade<cyclus::Material>,
135 cyclus::Material::Ptr> >& responses) {
136 using cyclus::Material;
137 using cyclus::Trade;
138
139 int shippable_trades = context()->GetTransportUnit(transport_unit)
140 ->MaxShippablePackages(trades.size());
141
142 std::vector<Trade<Material> >::const_iterator it;
143 for (it = trades.begin(); it != trades.end(); ++it) {
144 if (shippable_trades > 0) {
145 double qty = it->amt;
146
147 Material::Ptr m = inventory.Pop(qty);
148
149 std::vector<Material::Ptr> m_pkgd = m->Package<Material>(context()->GetPackage(package));
150
151 if (m->quantity() > cyclus::eps()) {
152 // If not all material is packaged successfully, return the excess
153 // amount to the inventory
154 inventory.Push(m);
155 }
156
157 Material::Ptr response;
158 if (m_pkgd.size() > 0) {
159 // Because we responded (in GetMatlBids) with individual package-sized
160 // bids, each packaged vector is guaranteed to have no more than one
161 // package in it. This single packaged resource is our response
162 response = m_pkgd[0];
163 shippable_trades -= 1;
164 } else {
165 // If packaging failed, respond with a zero (empty) material
166 response = Material::CreateUntracked(0, m->comp());
167 }
168
169 if (outrecipe.empty() && response->comp() != it->request->target()->comp()) {
170 response->Transmute(it->request->target()->comp());
171 }
172
173 responses.push_back(std::make_pair(*it, response));
174 LOG(cyclus::LEV_INFO5, "Source") << prototype() << " sent an order"
175 << " for " << response->quantity() << " of " << outcommod;
176 }
177 }
178}
179
180extern "C" cyclus::Agent* ConstructSource(cyclus::Context* ctx) {
181 return new Source(ctx);
182}
183
184} // namespace cycamore
Source(cyclus::Context *ctx)
cyclus::Agent * ConstructSource(cyclus::Context *ctx)