4using cyclus::Composition;
5using cyclus::toolkit::ResBuf;
6using cyclus::toolkit::MatVec;
12 : cyclus::Facility(ctx) {}
14cyclus::Inventories Separations::SnapshotInv() {
15 cyclus::Inventories invs;
20 invs[
"leftover-inv-name"] = leftover.PopNRes(leftover.count());
21 leftover.Push(invs[
"leftover-inv-name"]);
22 invs[
"feed-inv-name"] = feed.PopNRes(feed.count());
23 feed.Push(invs[
"feed-inv-name"]);
25 std::map<std::string, ResBuf<Material> >::iterator it;
26 for (it = streambufs.begin(); it != streambufs.end(); ++it) {
27 invs[it->first] = it->second.PopNRes(it->second.count());
28 it->second.Push(invs[it->first]);
34void Separations::InitInv(cyclus::Inventories& inv) {
35 leftover.Push(inv[
"leftover-inv-name"]);
36 feed.Push(inv[
"feed-inv-name"]);
38 cyclus::Inventories::iterator it;
39 for (it = inv.begin(); it != inv.end(); ++it) {
40 streambufs[it->first].Push(it->second);
44typedef std::pair<double, std::map<int, double> >
Stream;
45typedef std::map<std::string, Stream>
StreamSet;
47void Separations::EnterNotify() {
48 cyclus::Facility::EnterNotify();
49 std::map<int, double> efficiency_;
51 StreamSet::iterator it;
52 std::map<int, double>::iterator it2;
54 for (it = streams_.begin(); it != streams_.end(); ++it) {
55 std::string name = it->first;
56 Stream stream = it->second;
57 double cap = stream.first;
59 streambufs[name].capacity(cap);
62 for (it2 = stream.second.begin(); it2 != stream.second.end(); it2++) {
63 efficiency_[it2->first] += it2->second;
69 std::vector<int> eff_pb_;
70 for (it2 = efficiency_.begin(); it2 != efficiency_.end(); it2++) {
71 if (it2->second > 1) {
72 eff_pb_.push_back(it2->first);
76 if (eff_pb_.size() > 0) {
78 ss <<
"In " << prototype() <<
", ";
79 ss <<
"the following nuclide(s) have a cumulative separation efficiency "
81 for (
int i = 0; i < eff_pb_.size(); i++) {
82 ss <<
"\n " << eff_pb_[i];
83 if (i < eff_pb_.size() - 1) {
90 throw cyclus::ValueError(ss.str());
93 if (feed_commod_prefs.size() == 0) {
94 for (
int i = 0; i < feed_commods.size(); i++) {
95 feed_commod_prefs.push_back(cyclus::kDefaultPref);
100void Separations::Tick() {
101 using cyclus::toolkit::RecordTimeSeries;
102 if (feed.count() == 0) {
105 double pop_qty = std::min(throughput, feed.quantity());
106 Material::Ptr mat = feed.Pop(pop_qty, cyclus::eps_rsrc());
107 double orig_qty = mat->quantity();
109 StreamSet::iterator it;
111 std::map<std::string, Material::Ptr> stagedsep;
112 Record(
"Separating", orig_qty,
"feed");
113 for (it = streams_.begin(); it != streams_.end(); ++it) {
115 std::string name = it->first;
117 double frac = streambufs[name].space() / stagedsep[name]->quantity();
118 if (frac < maxfrac) {
123 std::map<std::string, Material::Ptr>::iterator itf;
124 for (itf = stagedsep.begin(); itf != stagedsep.end(); ++itf) {
125 std::string name = itf->first;
126 Material::Ptr m = itf->second;
127 if (m->quantity() > 0) {
128 double qty = m->quantity();
129 if (m->quantity() > mat->quantity()) {
130 qty = mat->quantity();
132 streambufs[name].Push(
133 mat->ExtractComp(qty * maxfrac, m->comp()));
134 Record(
"Separated", qty * maxfrac, name);
136 cyclus::toolkit::RecordTimeSeries<double>(
"supply"+name,
this,
137 streambufs[name].quantity());
141 if (mat->quantity() > 0) {
148 feed.Push(mat->ExtractQty((1 - maxfrac) * orig_qty));
149 if (mat->quantity() > 0) {
154 cyclus::toolkit::RecordTimeSeries<double>(
"supply"+leftover_commod,
this,
155 leftover.quantity());
161Material::Ptr
SepMaterial(std::map<int, double> effs, Material::Ptr mat) {
162 using cyclus::CompMap;
164 CompMap cm = mat->comp()->mass();
165 cyclus::compmath::Normalize(&cm, mat->quantity());
169 CompMap::iterator it;
170 for (it = cm.begin(); it != cm.end(); ++it) {
172 int elem = (nuc / 10000000) * 10000000;
174 if (effs.count(nuc) > 0) {
176 }
else if (effs.count(elem) > 0) {
182 double qty = it->second;
183 double sepqty = qty * eff;
184 sepcomp[nuc] = sepqty;
188 Composition::Ptr c = Composition::CreateFromMass(sepcomp);
189 return Material::CreateUntracked(tot_qty, c);
192std::set<cyclus::RequestPortfolio<Material>::Ptr>
193Separations::GetMatlRequests() {
194 using cyclus::RequestPortfolio;
195 using cyclus::toolkit::RecordTimeSeries;
196 std::set<RequestPortfolio<Material>::Ptr> ports;
198 int t = context()->time();
199 int t_exit = exit_time();
202 std::vector<double>::iterator result;
203 result = std::max_element(feed_commod_prefs.begin(), feed_commod_prefs.end());
204 int maxindx = std::distance(feed_commod_prefs.begin(), result);
205 cyclus::toolkit::RecordTimeSeries<double>(
"demand"+feed_commods[maxindx],
207 if (t_exit >= 0 && (feed.quantity() >= (t_exit - t) * throughput)) {
209 }
else if (feed.space() < cyclus::eps_rsrc()) {
213 bool exclusive =
false;
214 RequestPortfolio<Material>::Ptr port(
new RequestPortfolio<Material>());
216 Material::Ptr m = cyclus::NewBlankMaterial(feed.space());
217 if (!feed_recipe.empty()) {
218 Composition::Ptr c = context()->GetRecipe(feed_recipe);
219 m = Material::CreateUntracked(feed.space(), c);
222 std::vector<Request<Material>*> reqs;
223 for (
int i = 0; i < feed_commods.size(); i++) {
224 std::string commod = feed_commods[i];
225 double pref = feed_commod_prefs[i];
226 reqs.push_back(port->AddRequest(m,
this, commod, pref, exclusive));
228 port->AddMutualReqs(reqs);
234void Separations::GetMatlTrades(
235 const std::vector<cyclus::Trade<Material> >& trades,
236 std::vector<std::pair<cyclus::Trade<Material>, Material::Ptr> >&
240 std::vector<Trade<Material> >::const_iterator it;
241 for (
int i = 0; i < trades.size(); i++) {
242 std::string commod = trades[i].request->commodity();
243 if (commod == leftover_commod) {
244 double amt = std::min(leftover.quantity(), trades[i].amt);
245 Material::Ptr m = leftover.Pop(amt, cyclus::eps_rsrc());
246 responses.push_back(std::make_pair(trades[i], m));
247 }
else if (streambufs.count(commod) > 0) {
248 double amt = std::min(streambufs[commod].quantity(), trades[i].amt);
249 Material::Ptr m = streambufs[commod].Pop(amt, cyclus::eps_rsrc());
250 responses.push_back(std::make_pair(trades[i], m));
252 throw cyclus::ValueError(
"invalid commodity " + commod +
253 " on trade matched to prototype " + prototype());
258void Separations::AcceptMatlTrades(
259 const std::vector<std::pair<cyclus::Trade<Material>, Material::Ptr> >&
261 std::vector<std::pair<cyclus::Trade<Material>,
262 Material::Ptr> >::const_iterator trade;
264 for (trade = responses.begin(); trade != responses.end(); ++trade) {
265 feed.Push(trade->second);
269std::set<cyclus::BidPortfolio<Material>::Ptr> Separations::GetMatlBids(
270 cyclus::CommodMap<Material>::type& commod_requests) {
271 using cyclus::BidPortfolio;
272 bool exclusive =
false;
273 std::set<BidPortfolio<Material>::Ptr> ports;
276 std::map<std::string, ResBuf<Material> >::iterator it;
277 for (it = streambufs.begin(); it != streambufs.end(); ++it) {
278 std::string commod = it->first;
279 std::vector<Request<Material>*>& reqs = commod_requests[commod];
280 if (reqs.size() == 0) {
282 }
else if (streambufs[commod].quantity() < cyclus::eps_rsrc()) {
286 MatVec mats = streambufs[commod].PopN(streambufs[commod].count());
287 streambufs[commod].Push(mats);
289 BidPortfolio<Material>::Ptr port(
new BidPortfolio<Material>());
291 for (
int j = 0; j < reqs.size(); j++) {
292 Request<Material>* req = reqs[j];
294 for (
int k = 0; k < mats.size(); k++) {
295 Material::Ptr m = mats[k];
296 tot_bid += m->quantity();
300 if (m->quantity() > cyclus::eps_rsrc()) {
301 port->AddBid(req, m,
this, exclusive);
304 if (tot_bid >= req->target()->quantity()) {
310 double tot_qty = streambufs[commod].quantity();
311 cyclus::CapacityConstraint<Material> cc(tot_qty);
312 port->AddConstraint(cc);
317 std::vector<Request<Material>*>& reqs = commod_requests[leftover_commod];
318 if (reqs.size() > 0 && leftover.quantity() >= cyclus::eps_rsrc()) {
319 MatVec mats = leftover.PopN(leftover.count());
322 BidPortfolio<Material>::Ptr port(
new BidPortfolio<Material>());
324 for (
int j = 0; j < reqs.size(); j++) {
325 Request<Material>* req = reqs[j];
327 for (
int k = 0; k < mats.size(); k++) {
328 Material::Ptr m = mats[k];
329 tot_bid += m->quantity();
333 if (m->quantity() > cyclus::eps_rsrc()) {
334 port->AddBid(req, m,
this, exclusive);
337 if (tot_bid >= req->target()->quantity()) {
343 cyclus::CapacityConstraint<Material> cc(leftover.quantity());
344 port->AddConstraint(cc);
351void Separations::Tock() {}
353bool Separations::CheckDecommissionCondition() {
354 if (leftover.count() > 0) {
358 std::map<std::string, ResBuf<Material> >::iterator it;
359 for (it = streambufs.begin(); it != streambufs.end(); ++it) {
360 if (it->second.count() > 0) {
368void Separations::Record(std::string name,
double val, std::string type) {
370 ->NewDatum(
"SeparationEvents")
371 ->AddVal(
"AgentId",
id())
372 ->AddVal(
"Time", context()->time())
373 ->AddVal(
"Event", name)
374 ->AddVal(
"Value", val)
375 ->AddVal(
"Type", type)
380 return new Separations(ctx);
Separations(cyclus::Context *ctx)
Material::Ptr SepMaterial(std::map< int, double > effs, Material::Ptr mat)
std::pair< double, std::map< int, double > > Stream
std::map< std::string, Stream > StreamSet
cyclus::Agent * ConstructSeparations(cyclus::Context *ctx)