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),
140 cyclus::Facility::EnterNotify();
147 std::stringstream ss;
149 <<
" fiss_commod_prefs vals, expected " <<
fiss_commods.size();
150 throw cyclus::ValidationError(ss.str());
158 std::stringstream ss;
160 <<
" fill_commod_prefs vals, expected " <<
fill_commods.size();
161 throw cyclus::ValidationError(ss.str());
164 InitializePosition();
168 using cyclus::RequestPortfolio;
170 std::set<RequestPortfolio<Material>::Ptr> ports;
172 bool exclusive =
false;
174 if (
fiss.space() > cyclus::eps_rsrc()) {
175 RequestPortfolio<Material>::Ptr port(
new RequestPortfolio<Material>());
177 Material::Ptr m = cyclus::NewBlankMaterial(
fiss.space());
179 Composition::Ptr c = context()->GetRecipe(
fiss_recipe);
180 m = Material::CreateUntracked(
fiss.space(), c);
183 std::vector<cyclus::Request<Material>*> reqs;
187 reqs.push_back(port->AddRequest(m,
this, commod, pref, exclusive));
190 port->AddMutualReqs(reqs);
194 if (
fill.space() > cyclus::eps_rsrc()) {
195 RequestPortfolio<Material>::Ptr port(
new RequestPortfolio<Material>());
197 Material::Ptr m = cyclus::NewBlankMaterial(
fill.space());
199 Composition::Ptr c = context()->GetRecipe(
fill_recipe);
200 m = Material::CreateUntracked(
fill.space(), c);
203 std::vector<cyclus::Request<Material>*> reqs;
207 reqs.push_back(port->AddRequest(m,
this, commod, pref, exclusive));
210 port->AddMutualReqs(reqs);
214 if (
topup.space() > cyclus::eps_rsrc()) {
215 RequestPortfolio<Material>::Ptr port(
new RequestPortfolio<Material>());
217 Material::Ptr m = cyclus::NewBlankMaterial(
topup.space());
219 Composition::Ptr c = context()->GetRecipe(
topup_recipe);
220 m = Material::CreateUntracked(
topup.space(), c);
222 cyclus::Request<Material>* r =
231bool Contains(std::vector<std::string> vec, std::string s) {
232 for (
int i = 0; i < vec.size(); i++) {
241 const std::vector<std::pair<cyclus::Trade<Material>, Material::Ptr> >&
243 std::vector<std::pair<cyclus::Trade<Material>,
244 Material::Ptr> >::const_iterator trade;
246 for (trade = responses.begin(); trade != responses.end(); ++trade) {
247 std::string commod = trade->first.request->commodity();
248 double req_qty = trade->first.request->target()->quantity();
249 cyclus::Request<Material>* req = trade->first.request;
250 Material::Ptr m = trade->second;
258 throw cyclus::ValueError(
"cycamore::FuelFab was overmatched on requests");
266 if (
fill.count() > 1) {
267 fill.Push(cyclus::toolkit::Squash(
fill.PopN(
fill.count())));
269 if (
fiss.count() > 1) {
270 fiss.Push(cyclus::toolkit::Squash(
fiss.PopN(
fiss.count())));
272 if (
topup.count() > 1) {
278 cyclus::CommodMap<Material>::type& commod_requests) {
279 using cyclus::BidPortfolio;
281 std::set<BidPortfolio<Material>::Ptr> ports;
282 std::vector<cyclus::Request<Material>*>& reqs = commod_requests[
outcommod];
286 }
else if (reqs.size() == 0) {
293 if (
fill.count() > 0) {
294 c_fill =
fill.Peek()->comp();
302 Composition::Ptr c_topup = c_fill;
303 if (
topup.count() > 0) {
304 c_topup =
topup.Peek()->comp();
313 Composition::Ptr c_fiss = c_fill;
314 if (
fiss.count() > 0) {
315 c_fiss =
fiss.Peek()->comp();
322 BidPortfolio<Material>::Ptr port(
new BidPortfolio<Material>());
323 for (
int j = 0; j < reqs.size(); j++) {
324 cyclus::Request<Material>* req = reqs[j];
326 Composition::Ptr tgt = req->target()->comp();
328 double tgt_qty = req->target()->quantity();
330 double fiss_frac =
HighFrac(w_fill, w_tgt, w_fiss);
331 double fill_frac = 1 - fiss_frac;
334 Material::Ptr m1 = Material::CreateUntracked(fiss_frac * tgt_qty, c_fiss);
335 Material::Ptr m2 = Material::CreateUntracked(fill_frac * tgt_qty, c_fill);
338 bool exclusive =
false;
339 port->AddBid(req, m1,
this, exclusive);
344 double topup_frac =
HighFrac(w_fiss, w_tgt, w_topup);
345 double fiss_frac = 1 - topup_frac;
349 Material::CreateUntracked(topup_frac * tgt_qty, c_topup);
350 Material::Ptr m2 = Material::CreateUntracked(fiss_frac * tgt_qty, c_fiss);
353 bool exclusive =
false;
354 port->AddBid(req, m1,
this, exclusive);
355 }
else if (
fiss.count() > 0 &&
fill.count() > 0 ||
360 std::stringstream ss;
361 ss <<
"prototype '" << prototype()
362 <<
"': Input stream weights/reactivity do not span "
363 "the requested material weight.";
364 cyclus::Warn<cyclus::VALUE_WARNING>(ss.str());
368 cyclus::Converter<Material>::Ptr fissconv(
369 new FissConverter(c_fill, c_fiss, c_topup,
spectrum));
370 cyclus::Converter<Material>::Ptr fillconv(
371 new FillConverter(c_fill, c_fiss, c_topup,
spectrum));
372 cyclus::Converter<Material>::Ptr topupconv(
373 new TopupConverter(c_fill, c_fiss, c_topup,
spectrum));
376 cyclus::CapacityConstraint<Material> fissc(std::max(
fiss.quantity(), cyclus::CY_NEAR_ZERO),
378 cyclus::CapacityConstraint<Material> fillc(std::max(
fill.quantity(), cyclus::CY_NEAR_ZERO),
380 cyclus::CapacityConstraint<Material> topupc(std::max(
topup.quantity(), cyclus::CY_NEAR_ZERO),
382 port->AddConstraint(fillc);
383 port->AddConstraint(fissc);
384 port->AddConstraint(topupc);
386 cyclus::CapacityConstraint<Material> cc(
throughput);
387 port->AddConstraint(cc);
393 const std::vector<cyclus::Trade<Material> >& trades,
394 std::vector<std::pair<cyclus::Trade<Material>, Material::Ptr> >&
401 if (
fill.count() > 0) {
405 if (
topup.count() > 0) {
409 if (
fiss.count() > 0) {
413 std::vector<cyclus::Trade<Material> >::const_iterator it;
415 for (
int i = 0; i < trades.size(); i++) {
416 Material::Ptr tgt = trades[i].request->target();
419 double qty = trades[i].amt;
420 double wfiss = w_fiss;
424 std::stringstream ss;
425 ss <<
"FuelFab was matched above throughput limit: " << tot <<
" > "
427 throw cyclus::ValueError(ss.str());
430 if (
fiss.count() == 0) {
432 double fillqty = qty;
433 if (std::abs(fillqty -
fill.quantity()) < cyclus::eps_rsrc()) {
434 fillqty = std::min(
fill.quantity(), qty);
437 std::make_pair(trades[i],
fill.Pop(fillqty, cyclus::eps_rsrc())));
440 double fissqty = qty;
441 if (std::abs(fissqty -
fiss.quantity()) < cyclus::eps_rsrc()) {
442 fissqty = std::min(
fiss.quantity(), qty);
445 std::make_pair(trades[i],
fiss.Pop(fissqty, cyclus::eps_rsrc())));
447 double fiss_frac =
HighFrac(w_fill, w_tgt, w_fiss);
448 double fill_frac =
LowFrac(w_fill, w_tgt, w_fiss);
454 double fissqty = fiss_frac * qty;
455 if (std::abs(fissqty -
fiss.quantity()) < cyclus::eps_rsrc()) {
456 fissqty = std::min(
fiss.quantity(), fiss_frac * qty);
458 double fillqty = fill_frac * qty;
459 if (std::abs(fillqty -
fill.quantity()) < cyclus::eps_rsrc()) {
460 fillqty = std::min(
fill.quantity(), fill_frac * qty);
463 Material::Ptr m =
fiss.Pop(fissqty, cyclus::eps_rsrc());
466 m->Absorb(
fill.Pop(fillqty, cyclus::eps_rsrc()));
468 responses.push_back(std::make_pair(trades[i], m));
470 double topup_frac =
HighFrac(w_fiss, w_tgt, w_topup);
471 double fiss_frac = 1 - topup_frac;
477 double fissqty = fiss_frac * qty;
478 if (std::abs(fissqty -
fiss.quantity()) < cyclus::eps_rsrc()) {
479 fissqty = std::min(
fiss.quantity(), fiss_frac * qty);
481 double topupqty = topup_frac * qty;
482 if (std::abs(topupqty -
topup.quantity()) < cyclus::eps_rsrc()) {
483 topupqty = std::min(
topup.quantity(), topup_frac * qty);
486 Material::Ptr m =
fiss.Pop(fissqty, cyclus::eps_rsrc());
488 if (topup_frac > 0) {
489 m->Absorb(
topup.Pop(topupqty, cyclus::eps_rsrc()));
491 responses.push_back(std::make_pair(trades[i], m));
513double CosiWeight(Composition::Ptr c,
const std::string& spectrum) {
514 cyclus::CompMap cm = c->atom();
515 cyclus::compmath::Normalize(&cm);
517 if (spectrum ==
"thermal") {
518 double nu_pu239 = 2.85;
519 double nu_u233 = 2.5;
520 double nu_u235 = 2.43;
522 double nu_pu241 = nu_pu239;
524 static std::map<int, double> absorb_xs;
525 static std::map<int, double> fiss_xs;
526 static double p_u238 = 0;
527 static double p_pu239 = 0;
529 double fiss_u238 = simple_xs(922380000,
"fission",
"thermal");
530 double absorb_u238 = simple_xs(922380000,
"absorption",
"thermal");
531 p_u238 = nu_u238 * fiss_u238 - absorb_u238;
533 double fiss_pu239 = simple_xs(942390000,
"fission",
"thermal");
534 double absorb_pu239 = simple_xs(942390000,
"absorption",
"thermal");
535 p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239;
538 cyclus::CompMap::iterator it;
540 for (it = cm.begin(); it != cm.end(); ++it) {
541 cyclus::Nuc nuc = it->first;
543 if (nuc == 922350000) {
545 }
else if (nuc == 922330000) {
547 }
else if (nuc == 942390000) {
549 }
else if (nuc == 942410000) {
555 if (absorb_xs.count(nuc) == 0) {
557 fiss = simple_xs(nuc,
"fission",
"thermal");
558 absorb = simple_xs(nuc,
"absorption",
"thermal");
559 absorb_xs[nuc] = absorb;
561 }
catch (pyne::InvalidSimpleXS err) {
567 absorb = absorb_xs[nuc];
570 double p = nu * fiss - absorb;
571 w += it->second * (p - p_u238) / (p_pu239 - p_u238);
574 }
else if (spectrum ==
"fission_spectrum_ave") {
575 double nu_pu239 = 3.1;
576 double nu_u233 = 2.63;
577 double nu_u235 = 2.58;
579 double nu_pu241 = nu_pu239;
581 static std::map<int, double> absorb_xs;
582 static std::map<int, double> fiss_xs;
583 static double p_u238 = 0;
584 static double p_pu239 = 0;
587 simple_xs(922380000,
"fission",
"fission_spectrum_ave");
589 simple_xs(922380000,
"absorption",
"fission_spectrum_ave");
590 p_u238 = nu_u238 * fiss_u238 - absorb_u238;
593 simple_xs(942390000,
"fission",
"fission_spectrum_ave");
594 double absorb_pu239 =
595 simple_xs(942390000,
"absorption",
"fission_spectrum_ave");
596 p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239;
599 cyclus::CompMap::iterator it;
601 for (it = cm.begin(); it != cm.end(); ++it) {
602 cyclus::Nuc nuc = it->first;
604 if (nuc == 922350000) {
606 }
else if (nuc == 922330000) {
608 }
else if (nuc == 942390000) {
610 }
else if (nuc == 942410000) {
616 if (absorb_xs.count(nuc) == 0) {
618 fiss = simple_xs(nuc,
"fission",
"fission_spectrum_ave");
619 absorb = simple_xs(nuc,
"absorption",
"fission_spectrum_ave");
620 absorb_xs[nuc] = absorb;
622 }
catch (pyne::InvalidSimpleXS err) {
628 absorb = absorb_xs[nuc];
631 double p = nu * fiss - absorb;
632 w += it->second * (p - p_u238) / (p_pu239 - p_u238);
636 double nu_pu239 = 3.1;
637 double nu_u233 = 2.63;
638 double nu_u235 = 2.58;
640 double nu_pu241 = nu_pu239;
642 double fiss_u238 = simple_xs(922380000,
"fission", spectrum);
643 double absorb_u238 = simple_xs(922380000,
"absorption", spectrum);
644 double p_u238 = nu_u238 * fiss_u238 - absorb_u238;
646 double fiss_pu239 = simple_xs(942390000,
"fission", spectrum);
647 double absorb_pu239 = simple_xs(942390000,
"absorption", spectrum);
648 double p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239;
650 cyclus::CompMap::iterator it;
652 for (it = cm.begin(); it != cm.end(); ++it) {
653 cyclus::Nuc nuc = it->first;
655 if (nuc == 922350000) {
657 }
else if (nuc == 922330000) {
659 }
else if (nuc == 942390000) {
661 }
else if (nuc == 942410000) {
668 fiss = simple_xs(nuc,
"fission", spectrum);
669 absorb = simple_xs(nuc,
"absorption", spectrum);
670 }
catch (pyne::InvalidSimpleXS err) {
675 double p = nu * fiss - absorb;
676 w += it->second * (p - p_u238) / (p_pu239 - p_u238);
685 Composition::Ptr c2) {
686 cyclus::CompMap n1 = c1->atom();
687 cyclus::CompMap n2 = c2->atom();
688 cyclus::compmath::Normalize(&n1, atomfrac);
689 cyclus::compmath::Normalize(&n2, 1 - atomfrac);
691 cyclus::CompMap::iterator it;
694 for (it = n1.begin(); it != n1.end(); ++it) {
695 mass1 += it->second * pyne::atomic_mass(it->first);
699 for (it = n2.begin(); it != n2.end(); ++it) {
700 mass2 += it->second * pyne::atomic_mass(it->first);
703 return mass1 / (mass1 + mass2);
706double HighFrac(
double w_low,
double w_target,
double w_high,
double eps) {
708 throw cyclus::ValueError(
"low and high weights cannot meet target");
709 }
else if (w_low == w_high && w_target == w_low) {
712 double f = std::abs((w_target - w_low) / (w_high - w_low));
715 }
else if (f < eps) {
721double LowFrac(
double w_low,
double w_target,
double w_high,
double eps) {
722 return 1 -
HighFrac(w_low, w_target, w_high, eps);
727bool ValidWeights(
double w_low,
double w_target,
double w_high) {
730 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 takes in 2 streams of material and mixes them in ratios in order to supply material that matc...
FuelFab(cyclus::Context *ctx)
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)