2#line 1 "/cycamore/src/fuel_fab.cc"
8using cyclus::Composition;
11#define SHOW(X) std::cout << std::setprecision(17) << __FILE__ << ":" << __LINE__ << ": " #X " = " << X << "\n"
12#line 12 "/cycamore/src/fuel_fab.cc"
19 Composition::Ptr c_topup, std::string spectrum)
29 Material::Ptr m, cyclus::Arc
const* a = NULL,
30 cyclus::ExchangeTranslationContext<Material>
const* ctx =
42 return cyclus::CY_LARGE_DOUBLE;
59 Composition::Ptr c_topup, std::string spectrum)
69 Material::Ptr m, cyclus::Arc
const* a = NULL,
70 cyclus::ExchangeTranslationContext<Material>
const* ctx =
81 return cyclus::CY_LARGE_DOUBLE;
98 Composition::Ptr c_topup, std::string spectrum)
108 Material::Ptr m, cyclus::Arc
const* a = NULL,
109 cyclus::ExchangeTranslationContext<Material>
const* ctx =
120 return cyclus::CY_LARGE_DOUBLE;
135 : cyclus::Facility(ctx),
141 cyclus::Facility::EnterNotify();
148 std::stringstream ss;
150 <<
" fiss_commod_prefs vals, expected " <<
fiss_commods.size();
151 throw cyclus::ValidationError(ss.str());
159 std::stringstream ss;
161 <<
" fill_commod_prefs vals, expected " <<
fill_commods.size();
162 throw cyclus::ValidationError(ss.str());
165 InitializePosition();
169 using cyclus::RequestPortfolio;
171 std::set<RequestPortfolio<Material>::Ptr> ports;
173 bool exclusive =
false;
175 if (
fiss.space() > cyclus::eps_rsrc()) {
176 RequestPortfolio<Material>::Ptr port(
new RequestPortfolio<Material>());
178 Material::Ptr m = cyclus::NewBlankMaterial(
fiss.space());
180 Composition::Ptr c = context()->GetRecipe(
fiss_recipe);
181 m = Material::CreateUntracked(
fiss.space(), c);
184 std::vector<cyclus::Request<Material>*> reqs;
188 reqs.push_back(port->AddRequest(m,
this, commod, pref, exclusive));
191 port->AddMutualReqs(reqs);
195 if (
fill.space() > cyclus::eps_rsrc()) {
196 RequestPortfolio<Material>::Ptr port(
new RequestPortfolio<Material>());
198 Material::Ptr m = cyclus::NewBlankMaterial(
fill.space());
200 Composition::Ptr c = context()->GetRecipe(
fill_recipe);
201 m = Material::CreateUntracked(
fill.space(), c);
204 std::vector<cyclus::Request<Material>*> reqs;
208 reqs.push_back(port->AddRequest(m,
this, commod, pref, exclusive));
211 port->AddMutualReqs(reqs);
215 if (
topup.space() > cyclus::eps_rsrc()) {
216 RequestPortfolio<Material>::Ptr port(
new RequestPortfolio<Material>());
218 Material::Ptr m = cyclus::NewBlankMaterial(
topup.space());
220 Composition::Ptr c = context()->GetRecipe(
topup_recipe);
221 m = Material::CreateUntracked(
topup.space(), c);
223 cyclus::Request<Material>* r =
232bool Contains(std::vector<std::string> vec, std::string s) {
233 for (
int i = 0; i < vec.size(); i++) {
242 const std::vector<std::pair<cyclus::Trade<Material>, Material::Ptr> >&
244 std::vector<std::pair<cyclus::Trade<Material>,
245 Material::Ptr> >::const_iterator trade;
247 for (trade = responses.begin(); trade != responses.end(); ++trade) {
248 std::string commod = trade->first.request->commodity();
249 double req_qty = trade->first.request->target()->quantity();
250 cyclus::Request<Material>* req = trade->first.request;
251 Material::Ptr m = trade->second;
259 throw cyclus::ValueError(
"cycamore::FuelFab was overmatched on requests");
267 if (
fill.count() > 1) {
268 fill.Push(cyclus::toolkit::Squash(
fill.PopN(
fill.count())));
270 if (
fiss.count() > 1) {
271 fiss.Push(cyclus::toolkit::Squash(
fiss.PopN(
fiss.count())));
273 if (
topup.count() > 1) {
279 cyclus::CommodMap<Material>::type& commod_requests) {
280 using cyclus::BidPortfolio;
282 std::set<BidPortfolio<Material>::Ptr> ports;
283 std::vector<cyclus::Request<Material>*>& reqs = commod_requests[
outcommod];
287 }
else if (reqs.size() == 0) {
294 if (
fill.count() > 0) {
295 c_fill =
fill.Peek()->comp();
303 Composition::Ptr c_topup = c_fill;
304 if (
topup.count() > 0) {
305 c_topup =
topup.Peek()->comp();
314 Composition::Ptr c_fiss = c_fill;
315 if (
fiss.count() > 0) {
316 c_fiss =
fiss.Peek()->comp();
323 BidPortfolio<Material>::Ptr port(
new BidPortfolio<Material>());
324 for (
int j = 0; j < reqs.size(); j++) {
325 cyclus::Request<Material>* req = reqs[j];
327 Composition::Ptr tgt = req->target()->comp();
329 double tgt_qty = req->target()->quantity();
331 double fiss_frac =
HighFrac(w_fill, w_tgt, w_fiss);
332 double fill_frac = 1 - fiss_frac;
335 Material::Ptr m1 = Material::CreateUntracked(fiss_frac * tgt_qty, c_fiss);
336 Material::Ptr m2 = Material::CreateUntracked(fill_frac * tgt_qty, c_fill);
339 bool exclusive =
false;
340 port->AddBid(req, m1,
this, exclusive);
345 double topup_frac =
HighFrac(w_fiss, w_tgt, w_topup);
346 double fiss_frac = 1 - topup_frac;
350 Material::CreateUntracked(topup_frac * tgt_qty, c_topup);
351 Material::Ptr m2 = Material::CreateUntracked(fiss_frac * tgt_qty, c_fiss);
354 bool exclusive =
false;
355 port->AddBid(req, m1,
this, exclusive);
356 }
else if (
fiss.count() > 0 &&
fill.count() > 0 ||
361 std::stringstream ss;
362 ss <<
"prototype '" << prototype()
363 <<
"': Input stream weights/reactivity do not span "
364 "the requested material weight.";
365 cyclus::Warn<cyclus::VALUE_WARNING>(ss.str());
369 cyclus::Converter<Material>::Ptr fissconv(
370 new FissConverter(c_fill, c_fiss, c_topup,
spectrum));
371 cyclus::Converter<Material>::Ptr fillconv(
372 new FillConverter(c_fill, c_fiss, c_topup,
spectrum));
373 cyclus::Converter<Material>::Ptr topupconv(
374 new TopupConverter(c_fill, c_fiss, c_topup,
spectrum));
377 cyclus::CapacityConstraint<Material> fissc(std::max(
fiss.quantity(), cyclus::CY_NEAR_ZERO),
379 cyclus::CapacityConstraint<Material> fillc(std::max(
fill.quantity(), cyclus::CY_NEAR_ZERO),
381 cyclus::CapacityConstraint<Material> topupc(std::max(
topup.quantity(), cyclus::CY_NEAR_ZERO),
383 port->AddConstraint(fillc);
384 port->AddConstraint(fissc);
385 port->AddConstraint(topupc);
387 cyclus::CapacityConstraint<Material> cc(
throughput);
388 port->AddConstraint(cc);
394 const std::vector<cyclus::Trade<Material> >& trades,
395 std::vector<std::pair<cyclus::Trade<Material>, Material::Ptr> >&
402 if (
fill.count() > 0) {
406 if (
topup.count() > 0) {
410 if (
fiss.count() > 0) {
414 std::vector<cyclus::Trade<Material> >::const_iterator it;
416 for (
int i = 0; i < trades.size(); i++) {
417 Material::Ptr tgt = trades[i].request->target();
420 double qty = trades[i].amt;
421 double wfiss = w_fiss;
425 std::stringstream ss;
426 ss <<
"FuelFab was matched above throughput limit: " << tot <<
" > "
428 throw cyclus::ValueError(ss.str());
431 if (
fiss.count() == 0) {
433 double fillqty = qty;
434 if (std::abs(fillqty -
fill.quantity()) < cyclus::eps_rsrc()) {
435 fillqty = std::min(
fill.quantity(), qty);
438 std::make_pair(trades[i],
fill.Pop(fillqty, cyclus::eps_rsrc())));
441 double fissqty = qty;
442 if (std::abs(fissqty -
fiss.quantity()) < cyclus::eps_rsrc()) {
443 fissqty = std::min(
fiss.quantity(), qty);
446 std::make_pair(trades[i],
fiss.Pop(fissqty, cyclus::eps_rsrc())));
448 double fiss_frac =
HighFrac(w_fill, w_tgt, w_fiss);
449 double fill_frac =
LowFrac(w_fill, w_tgt, w_fiss);
455 double fissqty = fiss_frac * qty;
456 if (std::abs(fissqty -
fiss.quantity()) < cyclus::eps_rsrc()) {
457 fissqty = std::min(
fiss.quantity(), fiss_frac * qty);
459 double fillqty = fill_frac * qty;
460 if (std::abs(fillqty -
fill.quantity()) < cyclus::eps_rsrc()) {
461 fillqty = std::min(
fill.quantity(), fill_frac * qty);
464 Material::Ptr m =
fiss.Pop(fissqty, cyclus::eps_rsrc());
467 m->Absorb(
fill.Pop(fillqty, cyclus::eps_rsrc()));
469 responses.push_back(std::make_pair(trades[i], m));
471 double topup_frac =
HighFrac(w_fiss, w_tgt, w_topup);
472 double fiss_frac = 1 - topup_frac;
478 double fissqty = fiss_frac * qty;
479 if (std::abs(fissqty -
fiss.quantity()) < cyclus::eps_rsrc()) {
480 fissqty = std::min(
fiss.quantity(), fiss_frac * qty);
482 double topupqty = topup_frac * qty;
483 if (std::abs(topupqty -
topup.quantity()) < cyclus::eps_rsrc()) {
484 topupqty = std::min(
topup.quantity(), topup_frac * qty);
487 Material::Ptr m =
fiss.Pop(fissqty, cyclus::eps_rsrc());
489 if (topup_frac > 0) {
490 m->Absorb(
topup.Pop(topupqty, cyclus::eps_rsrc()));
492 responses.push_back(std::make_pair(trades[i], m));
514double CosiWeight(Composition::Ptr c,
const std::string& spectrum) {
515 cyclus::CompMap cm = c->atom();
516 cyclus::compmath::Normalize(&cm);
518 if (spectrum ==
"thermal") {
519 double nu_pu239 = 2.85;
520 double nu_u233 = 2.5;
521 double nu_u235 = 2.43;
523 double nu_pu241 = nu_pu239;
525 static std::map<int, double> absorb_xs;
526 static std::map<int, double> fiss_xs;
527 static double p_u238 = 0;
528 static double p_pu239 = 0;
530 double fiss_u238 = simple_xs(922380000,
"fission",
"thermal");
531 double absorb_u238 = simple_xs(922380000,
"absorption",
"thermal");
532 p_u238 = nu_u238 * fiss_u238 - absorb_u238;
534 double fiss_pu239 = simple_xs(942390000,
"fission",
"thermal");
535 double absorb_pu239 = simple_xs(942390000,
"absorption",
"thermal");
536 p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239;
539 cyclus::CompMap::iterator it;
541 for (it = cm.begin(); it != cm.end(); ++it) {
542 cyclus::Nuc nuc = it->first;
544 if (nuc == 922350000) {
546 }
else if (nuc == 922330000) {
548 }
else if (nuc == 942390000) {
550 }
else if (nuc == 942410000) {
556 if (absorb_xs.count(nuc) == 0) {
558 fiss = simple_xs(nuc,
"fission",
"thermal");
559 absorb = simple_xs(nuc,
"absorption",
"thermal");
560 absorb_xs[nuc] = absorb;
562 }
catch (pyne::InvalidSimpleXS err) {
568 absorb = absorb_xs[nuc];
571 double p = nu * fiss - absorb;
572 w += it->second * (p - p_u238) / (p_pu239 - p_u238);
575 }
else if (spectrum ==
"fission_spectrum_ave") {
576 double nu_pu239 = 3.1;
577 double nu_u233 = 2.63;
578 double nu_u235 = 2.58;
580 double nu_pu241 = nu_pu239;
582 static std::map<int, double> absorb_xs;
583 static std::map<int, double> fiss_xs;
584 static double p_u238 = 0;
585 static double p_pu239 = 0;
588 simple_xs(922380000,
"fission",
"fission_spectrum_ave");
590 simple_xs(922380000,
"absorption",
"fission_spectrum_ave");
591 p_u238 = nu_u238 * fiss_u238 - absorb_u238;
594 simple_xs(942390000,
"fission",
"fission_spectrum_ave");
595 double absorb_pu239 =
596 simple_xs(942390000,
"absorption",
"fission_spectrum_ave");
597 p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239;
600 cyclus::CompMap::iterator it;
602 for (it = cm.begin(); it != cm.end(); ++it) {
603 cyclus::Nuc nuc = it->first;
605 if (nuc == 922350000) {
607 }
else if (nuc == 922330000) {
609 }
else if (nuc == 942390000) {
611 }
else if (nuc == 942410000) {
617 if (absorb_xs.count(nuc) == 0) {
619 fiss = simple_xs(nuc,
"fission",
"fission_spectrum_ave");
620 absorb = simple_xs(nuc,
"absorption",
"fission_spectrum_ave");
621 absorb_xs[nuc] = absorb;
623 }
catch (pyne::InvalidSimpleXS err) {
629 absorb = absorb_xs[nuc];
632 double p = nu * fiss - absorb;
633 w += it->second * (p - p_u238) / (p_pu239 - p_u238);
637 double nu_pu239 = 3.1;
638 double nu_u233 = 2.63;
639 double nu_u235 = 2.58;
641 double nu_pu241 = nu_pu239;
643 double fiss_u238 = simple_xs(922380000,
"fission", spectrum);
644 double absorb_u238 = simple_xs(922380000,
"absorption", spectrum);
645 double p_u238 = nu_u238 * fiss_u238 - absorb_u238;
647 double fiss_pu239 = simple_xs(942390000,
"fission", spectrum);
648 double absorb_pu239 = simple_xs(942390000,
"absorption", spectrum);
649 double p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239;
651 cyclus::CompMap::iterator it;
653 for (it = cm.begin(); it != cm.end(); ++it) {
654 cyclus::Nuc nuc = it->first;
656 if (nuc == 922350000) {
658 }
else if (nuc == 922330000) {
660 }
else if (nuc == 942390000) {
662 }
else if (nuc == 942410000) {
669 fiss = simple_xs(nuc,
"fission", spectrum);
670 absorb = simple_xs(nuc,
"absorption", spectrum);
671 }
catch (pyne::InvalidSimpleXS err) {
676 double p = nu * fiss - absorb;
677 w += it->second * (p - p_u238) / (p_pu239 - p_u238);
686 Composition::Ptr c2) {
687 cyclus::CompMap n1 = c1->atom();
688 cyclus::CompMap n2 = c2->atom();
689 cyclus::compmath::Normalize(&n1, atomfrac);
690 cyclus::compmath::Normalize(&n2, 1 - atomfrac);
692 cyclus::CompMap::iterator it;
695 for (it = n1.begin(); it != n1.end(); ++it) {
696 mass1 += it->second * pyne::atomic_mass(it->first);
700 for (it = n2.begin(); it != n2.end(); ++it) {
701 mass2 += it->second * pyne::atomic_mass(it->first);
704 return mass1 / (mass1 + mass2);
707double HighFrac(
double w_low,
double w_target,
double w_high,
double eps) {
709 throw cyclus::ValueError(
"low and high weights cannot meet target");
710 }
else if (w_low == w_high && w_target == w_low) {
713 double f = std::abs((w_target - w_low) / (w_high - w_low));
716 }
else if (f < eps) {
722double LowFrac(
double w_low,
double w_target,
double w_high,
double eps) {
723 return 1 -
HighFrac(w_low, w_target, w_high, eps);
731 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)