6using cyclus::Composition;
10 std::cout << std::setprecision(17) << __FILE__ << ":" << __LINE__ \
11 << ": " #X " = " << X << "\n"
15class FissConverter :
public cyclus::Converter<Material> {
18 Composition::Ptr c_topup, std::string spectrum)
28 Material::Ptr m, cyclus::Arc
const* a = NULL,
29 cyclus::ExchangeTranslationContext<Material>
const* ctx =
41 return cyclus::CY_LARGE_DOUBLE;
55class FillConverter :
public cyclus::Converter<Material> {
58 Composition::Ptr c_topup, std::string spectrum)
68 Material::Ptr m, cyclus::Arc
const* a = NULL,
69 cyclus::ExchangeTranslationContext<Material>
const* ctx =
80 return cyclus::CY_LARGE_DOUBLE;
94class TopupConverter :
public cyclus::Converter<Material> {
97 Composition::Ptr c_topup, std::string spectrum)
107 Material::Ptr m, cyclus::Arc
const* a = NULL,
108 cyclus::ExchangeTranslationContext<Material>
const* ctx =
119 return cyclus::CY_LARGE_DOUBLE;
134 : cyclus::Facility(ctx),
143 cyclus::Facility::EnterNotify();
150 std::stringstream ss;
152 <<
" fiss_commod_prefs vals, expected " <<
fiss_commods.size();
153 throw cyclus::ValidationError(ss.str());
161 std::stringstream ss;
163 <<
" fill_commod_prefs vals, expected " <<
fill_commods.size();
164 throw cyclus::ValidationError(ss.str());
170 using cyclus::RequestPortfolio;
172 std::set<RequestPortfolio<Material>::Ptr> ports;
174 bool exclusive =
false;
176 if (
fiss.space() > cyclus::eps_rsrc()) {
177 RequestPortfolio<Material>::Ptr port(
new RequestPortfolio<Material>());
179 Material::Ptr m = cyclus::NewBlankMaterial(
fiss.space());
181 Composition::Ptr c = context()->GetRecipe(
fiss_recipe);
182 m = Material::CreateUntracked(
fiss.space(), c);
185 std::vector<cyclus::Request<Material>*> reqs;
189 reqs.push_back(port->AddRequest(m,
this, commod, pref, exclusive));
192 port->AddMutualReqs(reqs);
196 if (
fill.space() > cyclus::eps_rsrc()) {
197 RequestPortfolio<Material>::Ptr port(
new RequestPortfolio<Material>());
199 Material::Ptr m = cyclus::NewBlankMaterial(
fill.space());
201 Composition::Ptr c = context()->GetRecipe(
fill_recipe);
202 m = Material::CreateUntracked(
fill.space(), c);
205 std::vector<cyclus::Request<Material>*> reqs;
209 reqs.push_back(port->AddRequest(m,
this, commod, pref, exclusive));
212 port->AddMutualReqs(reqs);
216 if (
topup.space() > cyclus::eps_rsrc()) {
217 RequestPortfolio<Material>::Ptr port(
new RequestPortfolio<Material>());
219 Material::Ptr m = cyclus::NewBlankMaterial(
topup.space());
221 Composition::Ptr c = context()->GetRecipe(
topup_recipe);
222 m = Material::CreateUntracked(
topup.space(), c);
224 cyclus::Request<Material>* r =
233bool Contains(std::vector<std::string> vec, std::string s) {
234 for (
int i = 0; i < vec.size(); i++) {
243 const std::vector<std::pair<cyclus::Trade<Material>, Material::Ptr> >&
245 std::vector<std::pair<cyclus::Trade<Material>,
246 Material::Ptr> >::const_iterator trade;
248 for (trade = responses.begin(); trade != responses.end(); ++trade) {
249 std::string commod = trade->first.request->commodity();
250 double req_qty = trade->first.request->target()->quantity();
251 cyclus::Request<Material>* req = trade->first.request;
252 Material::Ptr m = trade->second;
260 throw cyclus::ValueError(
"cycamore::FuelFab was overmatched on requests");
268 if (
fill.count() > 1) {
269 fill.Push(cyclus::toolkit::Squash(
fill.PopN(
fill.count())));
271 if (
fiss.count() > 1) {
272 fiss.Push(cyclus::toolkit::Squash(
fiss.PopN(
fiss.count())));
274 if (
topup.count() > 1) {
280 cyclus::CommodMap<Material>::type& commod_requests) {
281 using cyclus::BidPortfolio;
283 std::set<BidPortfolio<Material>::Ptr> ports;
284 std::vector<cyclus::Request<Material>*>& reqs = commod_requests[
outcommod];
288 }
else if (reqs.size() == 0) {
295 if (
fill.count() > 0) {
296 c_fill =
fill.Peek()->comp();
304 Composition::Ptr c_topup = c_fill;
305 if (
topup.count() > 0) {
306 c_topup =
topup.Peek()->comp();
315 Composition::Ptr c_fiss = c_fill;
316 if (
fiss.count() > 0) {
317 c_fiss =
fiss.Peek()->comp();
324 BidPortfolio<Material>::Ptr port(
new BidPortfolio<Material>());
325 for (
int j = 0; j < reqs.size(); j++) {
326 cyclus::Request<Material>* req = reqs[j];
328 Composition::Ptr tgt = req->target()->comp();
330 double tgt_qty = req->target()->quantity();
332 double fiss_frac =
HighFrac(w_fill, w_tgt, w_fiss);
333 double fill_frac = 1 - fiss_frac;
336 Material::Ptr m1 = Material::CreateUntracked(fiss_frac * tgt_qty, c_fiss);
337 Material::Ptr m2 = Material::CreateUntracked(fill_frac * tgt_qty, c_fill);
340 bool exclusive =
false;
341 port->AddBid(req, m1,
this, exclusive);
346 double topup_frac =
HighFrac(w_fiss, w_tgt, w_topup);
347 double fiss_frac = 1 - topup_frac;
351 Material::CreateUntracked(topup_frac * tgt_qty, c_topup);
352 Material::Ptr m2 = Material::CreateUntracked(fiss_frac * tgt_qty, c_fiss);
355 bool exclusive =
false;
356 port->AddBid(req, m1,
this, exclusive);
357 }
else if (
fiss.count() > 0 &&
fill.count() > 0 ||
362 std::stringstream ss;
363 ss <<
"prototype '" << prototype()
364 <<
"': Input stream weights/reactivity do not span "
365 "the requested material weight.";
366 cyclus::Warn<cyclus::VALUE_WARNING>(ss.str());
370 cyclus::Converter<Material>::Ptr fissconv(
371 new FissConverter(c_fill, c_fiss, c_topup,
spectrum));
372 cyclus::Converter<Material>::Ptr fillconv(
373 new FillConverter(c_fill, c_fiss, c_topup,
spectrum));
374 cyclus::Converter<Material>::Ptr topupconv(
375 new TopupConverter(c_fill, c_fiss, c_topup,
spectrum));
378 cyclus::CapacityConstraint<Material> fissc(std::max(
fiss.quantity(), cyclus::CY_NEAR_ZERO),
380 cyclus::CapacityConstraint<Material> fillc(std::max(
fill.quantity(), cyclus::CY_NEAR_ZERO),
382 cyclus::CapacityConstraint<Material> topupc(std::max(
topup.quantity(), cyclus::CY_NEAR_ZERO),
384 port->AddConstraint(fillc);
385 port->AddConstraint(fissc);
386 port->AddConstraint(topupc);
388 cyclus::CapacityConstraint<Material> cc(
throughput);
389 port->AddConstraint(cc);
395 const std::vector<cyclus::Trade<Material> >& trades,
396 std::vector<std::pair<cyclus::Trade<Material>, Material::Ptr> >&
403 if (
fill.count() > 0) {
407 if (
topup.count() > 0) {
411 if (
fiss.count() > 0) {
415 std::vector<cyclus::Trade<Material> >::const_iterator it;
417 for (
int i = 0; i < trades.size(); i++) {
418 Material::Ptr tgt = trades[i].request->target();
421 double qty = trades[i].amt;
422 double wfiss = w_fiss;
426 std::stringstream ss;
427 ss <<
"FuelFab was matched above throughput limit: " << tot <<
" > "
429 throw cyclus::ValueError(ss.str());
432 if (
fiss.count() == 0) {
434 double fillqty = qty;
435 if (std::abs(fillqty -
fill.quantity()) < cyclus::eps_rsrc()) {
436 fillqty = std::min(
fill.quantity(), qty);
439 std::make_pair(trades[i],
fill.Pop(fillqty, cyclus::eps_rsrc())));
442 double fissqty = qty;
443 if (std::abs(fissqty -
fiss.quantity()) < cyclus::eps_rsrc()) {
444 fissqty = std::min(
fiss.quantity(), qty);
447 std::make_pair(trades[i],
fiss.Pop(fissqty, cyclus::eps_rsrc())));
449 double fiss_frac =
HighFrac(w_fill, w_tgt, w_fiss);
450 double fill_frac =
LowFrac(w_fill, w_tgt, w_fiss);
456 double fissqty = fiss_frac * qty;
457 if (std::abs(fissqty -
fiss.quantity()) < cyclus::eps_rsrc()) {
458 fissqty = std::min(
fiss.quantity(), fiss_frac * qty);
460 double fillqty = fill_frac * qty;
461 if (std::abs(fillqty -
fill.quantity()) < cyclus::eps_rsrc()) {
462 fillqty = std::min(
fill.quantity(), fill_frac * qty);
465 Material::Ptr m =
fiss.Pop(fissqty, cyclus::eps_rsrc());
468 m->Absorb(
fill.Pop(fillqty, cyclus::eps_rsrc()));
470 responses.push_back(std::make_pair(trades[i], m));
472 double topup_frac =
HighFrac(w_fiss, w_tgt, w_topup);
473 double fiss_frac = 1 - topup_frac;
479 double fissqty = fiss_frac * qty;
480 if (std::abs(fissqty -
fiss.quantity()) < cyclus::eps_rsrc()) {
481 fissqty = std::min(
fiss.quantity(), fiss_frac * qty);
483 double topupqty = topup_frac * qty;
484 if (std::abs(topupqty -
topup.quantity()) < cyclus::eps_rsrc()) {
485 topupqty = std::min(
topup.quantity(), topup_frac * qty);
488 Material::Ptr m =
fiss.Pop(fissqty, cyclus::eps_rsrc());
490 if (topup_frac > 0) {
491 m->Absorb(
topup.Pop(topupqty, cyclus::eps_rsrc()));
493 responses.push_back(std::make_pair(trades[i], m));
499 std::string specification = this->spec();
501 ->NewDatum(
"AgentPosition")
502 ->AddVal(
"Spec", specification)
503 ->AddVal(
"Prototype", this->prototype())
504 ->AddVal(
"AgentId",
id())
511 return new FuelFab(ctx);
527double CosiWeight(Composition::Ptr c,
const std::string& spectrum) {
528 cyclus::CompMap cm = c->atom();
529 cyclus::compmath::Normalize(&cm);
531 if (spectrum ==
"thermal") {
532 double nu_pu239 = 2.85;
533 double nu_u233 = 2.5;
534 double nu_u235 = 2.43;
536 double nu_pu241 = nu_pu239;
538 static std::map<int, double> absorb_xs;
539 static std::map<int, double> fiss_xs;
540 static double p_u238 = 0;
541 static double p_pu239 = 0;
543 double fiss_u238 = simple_xs(922380000,
"fission",
"thermal");
544 double absorb_u238 = simple_xs(922380000,
"absorption",
"thermal");
545 p_u238 = nu_u238 * fiss_u238 - absorb_u238;
547 double fiss_pu239 = simple_xs(942390000,
"fission",
"thermal");
548 double absorb_pu239 = simple_xs(942390000,
"absorption",
"thermal");
549 p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239;
552 cyclus::CompMap::iterator it;
554 for (it = cm.begin(); it != cm.end(); ++it) {
555 cyclus::Nuc nuc = it->first;
557 if (nuc == 922350000) {
559 }
else if (nuc == 922330000) {
561 }
else if (nuc == 942390000) {
563 }
else if (nuc == 942410000) {
569 if (absorb_xs.count(nuc) == 0) {
571 fiss = simple_xs(nuc,
"fission",
"thermal");
572 absorb = simple_xs(nuc,
"absorption",
"thermal");
573 absorb_xs[nuc] = absorb;
575 }
catch (pyne::InvalidSimpleXS err) {
581 absorb = absorb_xs[nuc];
584 double p = nu * fiss - absorb;
585 w += it->second * (p - p_u238) / (p_pu239 - p_u238);
588 }
else if (spectrum ==
"fission_spectrum_ave") {
589 double nu_pu239 = 3.1;
590 double nu_u233 = 2.63;
591 double nu_u235 = 2.58;
593 double nu_pu241 = nu_pu239;
595 static std::map<int, double> absorb_xs;
596 static std::map<int, double> fiss_xs;
597 static double p_u238 = 0;
598 static double p_pu239 = 0;
601 simple_xs(922380000,
"fission",
"fission_spectrum_ave");
603 simple_xs(922380000,
"absorption",
"fission_spectrum_ave");
604 p_u238 = nu_u238 * fiss_u238 - absorb_u238;
607 simple_xs(942390000,
"fission",
"fission_spectrum_ave");
608 double absorb_pu239 =
609 simple_xs(942390000,
"absorption",
"fission_spectrum_ave");
610 p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239;
613 cyclus::CompMap::iterator it;
615 for (it = cm.begin(); it != cm.end(); ++it) {
616 cyclus::Nuc nuc = it->first;
618 if (nuc == 922350000) {
620 }
else if (nuc == 922330000) {
622 }
else if (nuc == 942390000) {
624 }
else if (nuc == 942410000) {
630 if (absorb_xs.count(nuc) == 0) {
632 fiss = simple_xs(nuc,
"fission",
"fission_spectrum_ave");
633 absorb = simple_xs(nuc,
"absorption",
"fission_spectrum_ave");
634 absorb_xs[nuc] = absorb;
636 }
catch (pyne::InvalidSimpleXS err) {
642 absorb = absorb_xs[nuc];
645 double p = nu * fiss - absorb;
646 w += it->second * (p - p_u238) / (p_pu239 - p_u238);
650 double nu_pu239 = 3.1;
651 double nu_u233 = 2.63;
652 double nu_u235 = 2.58;
654 double nu_pu241 = nu_pu239;
656 double fiss_u238 = simple_xs(922380000,
"fission", spectrum);
657 double absorb_u238 = simple_xs(922380000,
"absorption", spectrum);
658 double p_u238 = nu_u238 * fiss_u238 - absorb_u238;
660 double fiss_pu239 = simple_xs(942390000,
"fission", spectrum);
661 double absorb_pu239 = simple_xs(942390000,
"absorption", spectrum);
662 double p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239;
664 cyclus::CompMap::iterator it;
666 for (it = cm.begin(); it != cm.end(); ++it) {
667 cyclus::Nuc nuc = it->first;
669 if (nuc == 922350000) {
671 }
else if (nuc == 922330000) {
673 }
else if (nuc == 942390000) {
675 }
else if (nuc == 942410000) {
682 fiss = simple_xs(nuc,
"fission", spectrum);
683 absorb = simple_xs(nuc,
"absorption", spectrum);
684 }
catch (pyne::InvalidSimpleXS err) {
689 double p = nu * fiss - absorb;
690 w += it->second * (p - p_u238) / (p_pu239 - p_u238);
699 Composition::Ptr c2) {
700 cyclus::CompMap n1 = c1->atom();
701 cyclus::CompMap n2 = c2->atom();
702 cyclus::compmath::Normalize(&n1, atomfrac);
703 cyclus::compmath::Normalize(&n2, 1 - atomfrac);
705 cyclus::CompMap::iterator it;
708 for (it = n1.begin(); it != n1.end(); ++it) {
709 mass1 += it->second * pyne::atomic_mass(it->first);
713 for (it = n2.begin(); it != n2.end(); ++it) {
714 mass2 += it->second * pyne::atomic_mass(it->first);
717 return mass1 / (mass1 + mass2);
720double HighFrac(
double w_low,
double w_target,
double w_high,
double eps) {
722 throw cyclus::ValueError(
"low and high weights cannot meet target");
723 }
else if (w_low == w_high && w_target == w_low) {
726 double f = std::abs((w_target - w_low) / (w_high - w_low));
729 }
else if (f < eps) {
735double LowFrac(
double w_low,
double w_target,
double w_high,
double eps) {
736 return 1 -
HighFrac(w_low, w_target, w_high, eps);
741bool ValidWeights(
double w_low,
double w_target,
double w_high) {
744 return w_low <= w_target && w_target <= w_high;
FillConverter(Composition::Ptr c_fill, Composition::Ptr c_fiss, Composition::Ptr c_topup, std::string spectrum)
Composition::Ptr c_topup_
virtual double convert(Material::Ptr m, cyclus::Arc const *a=NULL, cyclus::ExchangeTranslationContext< Material > const *ctx=NULL) const
FissConverter(Composition::Ptr c_fill, Composition::Ptr c_fiss, Composition::Ptr c_topup, std::string spectrum)
virtual double convert(Material::Ptr m, cyclus::Arc const *a=NULL, cyclus::ExchangeTranslationContext< Material > const *ctx=NULL) const
Composition::Ptr c_topup_
FuelFab(cyclus::Context *ctx)
void RecordPosition()
Records an agent's latitude and longitude to the output db.
virtual void EnterNotify()
virtual void AcceptMatlTrades(const std::vector< std::pair< cyclus::Trade< cyclus::Material >, cyclus::Material::Ptr > > &responses)
cyclus::toolkit::ResBuf< cyclus::Material > fill
std::map< cyclus::Request< cyclus::Material > *, std::string > req_inventories_
virtual void GetMatlTrades(const std::vector< cyclus::Trade< cyclus::Material > > &trades, std::vector< std::pair< cyclus::Trade< cyclus::Material >, cyclus::Material::Ptr > > &responses)
virtual std::set< cyclus::RequestPortfolio< cyclus::Material >::Ptr > GetMatlRequests()
std::vector< double > fill_commod_prefs
virtual std::set< cyclus::BidPortfolio< cyclus::Material >::Ptr > GetMatlBids(cyclus::CommodMap< cyclus::Material >::type &commod_requests)
cyclus::toolkit::ResBuf< cyclus::Material > topup
cyclus::toolkit::ResBuf< cyclus::Material > fiss
std::vector< std::string > fiss_commods
std::vector< std::string > fill_commods
std::vector< double > fiss_commod_prefs
virtual double convert(Material::Ptr m, cyclus::Arc const *a=NULL, cyclus::ExchangeTranslationContext< Material > const *ctx=NULL) const
Composition::Ptr c_topup_
virtual ~TopupConverter()
TopupConverter(Composition::Ptr c_fill, Composition::Ptr c_fiss, Composition::Ptr c_topup, std::string spectrum)
double HighFrac(double w_low, double w_target, double w_high, double eps)
double CosiWeight(Composition::Ptr c, const std::string &spectrum)
cyclus::Agent * ConstructFuelFab(cyclus::Context *ctx)
bool ValidWeights(double w_low, double w_target, double w_high)
double AtomToMassFrac(double atomfrac, Composition::Ptr c1, Composition::Ptr c2)
bool Contains(std::vector< std::string > vec, std::string s)
double LowFrac(double w_low, double w_target, double w_high, double eps)
cyclus::toolkit::Position coordinates