1#line 1 "/cycamore/src/enrichment.cc"
11#include <boost/lexical_cast.hpp>
13using cyclus::Material;
19 : cyclus::Facility(ctx),
36 ss << cyclus::Facility::str() <<
" with enrichment facility parameters:"
47 Facility::Build(parent);
53 LOG(cyclus::LEV_DEBUG2,
"EnrFac") <<
"Enrichment "
54 <<
" entering the simuluation: ";
55 LOG(cyclus::LEV_DEBUG2,
"EnrFac") <<
str();
59 cyclus::Facility::EnterNotify();
71 using cyclus::toolkit::RecordTimeSeries;
72 LOG(cyclus::LEV_INFO4,
"EnrFac") << prototype() <<
" used "
75 LOG(cyclus::LEV_INFO4,
"EnrFac") << prototype() <<
" used "
82std::set<cyclus::RequestPortfolio<Material>::Ptr>
84 using cyclus::RequestPortfolio;
86 std::set<RequestPortfolio<Material>::Ptr> ports;
87 RequestPortfolio<Material>::Ptr port(
new RequestPortfolio<Material>());
89 double amt = mat->quantity();
91 if (amt > cyclus::eps_rsrc()) {
101 cyclus::Bid<Material>* j) {
102 Material::Ptr mat_i = i->offer();
103 Material::Ptr mat_j = j->offer();
105 cyclus::toolkit::MatQuery mq_i(mat_i);
106 cyclus::toolkit::MatQuery mq_j(mat_j);
108 return ((mq_i.mass(922350000) / mq_i.qty()) <=
109 (mq_j.mass(922350000) / mq_j.qty()));
115 cyclus::PrefMap<Material>::type& prefs) {
122 cyclus::PrefMap<Material>::type::iterator reqit;
125 for (reqit = prefs.begin(); reqit != prefs.end(); ++reqit) {
126 std::vector<Bid<Material>*> bids_vector;
127 std::map<Bid<Material>*,
double>::iterator mit;
128 for (mit = reqit->second.begin(); mit != reqit->second.end(); ++mit) {
129 Bid<Material>* bid = mit->first;
130 bids_vector.push_back(bid);
132 std::sort(bids_vector.begin(), bids_vector.end(),
SortBids);
135 double n_bids = bids_vector.size();
138 for (
int bidit = 0; bidit < bids_vector.size(); bidit++) {
139 int new_pref = bidit + 1;
143 Material::Ptr mat = bids_vector[bidit]->offer();
144 cyclus::toolkit::MatQuery mq(mat);
145 if (mq.mass(922350000) == 0) {
151 (reqit->second)[bids_vector[bidit]] = new_pref;
158 const std::vector<std::pair<cyclus::Trade<Material>,
159 Material::Ptr> >& responses) {
162 std::vector<std::pair<cyclus::Trade<Material>,
163 Material::Ptr> >::const_iterator it;
164 for (it = responses.begin(); it != responses.end(); ++it) {
171 cyclus::CommodMap<Material>::type& out_requests) {
172 using cyclus::BidPortfolio;
173 using cyclus::CapacityConstraint;
174 using cyclus::Converter;
175 using cyclus::Request;
176 using cyclus::toolkit::MatVec;
177 using cyclus::toolkit::RecordTimeSeries;
179 std::set<BidPortfolio<Material>::Ptr> ports;
184 BidPortfolio<Material>::Ptr tails_port(
new BidPortfolio<Material>());
186 std::vector<Request<Material>*>& tails_requests =
188 std::vector<Request<Material>*>::iterator it;
189 for (it = tails_requests.begin(); it != tails_requests.end(); ++it) {
194 for (
int k = 0; k < mats.size(); k++) {
195 Material::Ptr m = mats[k];
196 Request<Material>* req = *it;
197 tails_port->AddBid(req, m,
this);
202 CapacityConstraint<Material> tails_constraint(
tails.quantity());
203 tails_port->AddConstraint(tails_constraint);
204 LOG(cyclus::LEV_INFO5,
"EnrFac") << prototype()
205 <<
" adding tails capacity constraint of "
207 ports.insert(tails_port);
211 BidPortfolio<Material>::Ptr commod_port(
new BidPortfolio<Material>());
213 std::vector<Request<Material>*>& commod_requests =
215 std::vector<Request<Material>*>::iterator it;
216 for (it = commod_requests.begin(); it != commod_requests.end(); ++it) {
217 Request<Material>* req = *it;
218 Material::Ptr mat = req->target();
219 double request_enrich = cyclus::toolkit::UraniumAssayMass(mat);
222 (cyclus::AlmostEq(request_enrich,
max_enrich)))) {
223 Material::Ptr offer =
Offer_(req->target());
224 commod_port->AddBid(req, offer,
this);
231 CapacityConstraint<Material> natu(
inventory.quantity(), nc);
232 commod_port->AddConstraint(swu);
233 commod_port->AddConstraint(natu);
235 LOG(cyclus::LEV_INFO5,
"EnrFac")
236 << prototype() <<
" adding a swu constraint of " << swu.capacity();
237 LOG(cyclus::LEV_INFO5,
"EnrFac")
238 << prototype() <<
" adding a natu constraint of " << natu.capacity();
239 ports.insert(commod_port);
246 cyclus::toolkit::MatQuery q(mat);
247 double u235 = q.atom_frac(922350000);
248 double u238 = q.atom_frac(922380000);
249 return (u238 > 0 && u235 / (u235 + u238) >
tails_assay);
254 const std::vector<cyclus::Trade<Material> >& trades,
255 std::vector<std::pair<cyclus::Trade<Material>,
256 Material::Ptr> >& responses) {
262 std::vector<Trade<Material>>::const_iterator it;
263 for (it = trades.begin(); it != trades.end(); ++it) {
264 double qty = it->amt;
265 std::string commod_type = it->bid->request()->commodity();
266 Material::Ptr response;
270 LOG(cyclus::LEV_INFO5,
"EnrFac")
271 << prototype() <<
" just received an order"
273 double pop_qty = std::min(qty,
tails.quantity());
274 response =
tails.Pop(pop_qty, cyclus::eps_rsrc());
276 LOG(cyclus::LEV_INFO5,
"EnrFac")
277 << prototype() <<
" just received an order"
279 response =
Enrich_(it->bid->offer(), qty);
281 responses.push_back(std::make_pair(*it, response));
284 if (cyclus::IsNegative(
tails.quantity())) {
285 std::stringstream ss;
286 ss <<
"is being asked to provide more than its current inventory.";
287 throw cyclus::ValueError(Agent::InformErrorMsg(ss.str()));
290 throw cyclus::ValueError(
"EnrFac " + prototype() +
291 " is being asked to provide more than" +
292 " its SWU capacity.");
299 cyclus::CompMap cm = mat->comp()->atom();
300 bool extra_u =
false;
301 bool other_elem =
false;
302 for (cyclus::CompMap::const_iterator it = cm.begin(); it != cm.end(); ++it) {
303 if (pyne::nucname::znum(it->first) == 92) {
304 if (pyne::nucname::anum(it->first) != 235 &&
305 pyne::nucname::anum(it->first) != 238 && it->second > 0) {
308 }
else if (it->second > 0) {
313 cyclus::Warn<cyclus::VALUE_WARNING>(
314 "More than 2 isotopes of U. "
315 "Istopes other than U-235, U-238 are sent directly to tails.");
318 cyclus::Warn<cyclus::VALUE_WARNING>(
319 "Non-uranium elements are "
320 "sent directly to tails.");
323 LOG(cyclus::LEV_INFO5,
"EnrFac") << prototype() <<
" is initially holding "
328 }
catch (cyclus::Error& e) {
329 e.msg(Agent::InformErrorMsg(e.msg()));
333 LOG(cyclus::LEV_INFO5,
"EnrFac")
334 << prototype() <<
" added " << mat->quantity() <<
" of " <<
feed_commod
335 <<
" to its inventory, which is holding " <<
inventory.quantity()
342 return Material::CreateUntracked(qty,
348 cyclus::toolkit::MatQuery q(mat);
349 cyclus::CompMap comp;
350 comp[922350000] = q.atom_frac(922350000);
351 comp[922380000] = q.atom_frac(922380000);
352 return Material::CreateUntracked(
353 mat->quantity(), cyclus::Composition::CreateFromAtom(comp));
358 using cyclus::toolkit::Assays;
359 using cyclus::toolkit::UraniumAssayMass;
360 using cyclus::toolkit::SwuRequired;
361 using cyclus::toolkit::FeedQty;
362 using cyclus::toolkit::TailsQty;
366 double swu_req = SwuRequired(qty, assays);
367 double natu_req = FeedQty(qty, assays);
372 Material::Ptr natu_matl =
inventory.Pop(pop_qty, cyclus::eps_rsrc());
375 cyclus::toolkit::MatQuery mq(natu_matl);
376 std::set<cyclus::Nuc> nucs;
377 nucs.insert(922350000);
378 nucs.insert(922380000);
379 double natu_frac = mq.mass_frac(nucs);
380 double feed_req = natu_req / natu_frac;
386 if (cyclus::AlmostEq(feed_req,
inventory.quantity())) {
389 r =
inventory.Pop(feed_req, cyclus::eps_rsrc());
391 }
catch (cyclus::Error& e) {
393 std::stringstream ss;
394 ss <<
" tried to remove " << feed_req <<
" from its inventory of size "
396 <<
" and the conversion of the material into natu is "
398 throw cyclus::ValueError(Agent::InformErrorMsg(ss.str()));
403 cyclus::Composition::Ptr comp = mat->comp();
404 Material::Ptr response = r->ExtractComp(qty, comp);
413 LOG(cyclus::LEV_INFO5,
"EnrFac") << prototype()
414 <<
" has performed an enrichment: ";
415 LOG(cyclus::LEV_INFO5,
"EnrFac") <<
" * Feed Qty: " << feed_req;
416 LOG(cyclus::LEV_INFO5,
"EnrFac") <<
" * Feed Assay: "
417 << assays.Feed() * 100;
418 LOG(cyclus::LEV_INFO5,
"EnrFac") <<
" * Product Qty: " << qty;
419 LOG(cyclus::LEV_INFO5,
"EnrFac") <<
" * Product Assay: "
420 << assays.Product() * 100;
421 LOG(cyclus::LEV_INFO5,
"EnrFac") <<
" * Tails Qty: "
422 << TailsQty(qty, assays);
423 LOG(cyclus::LEV_INFO5,
"EnrFac") <<
" * Tails Assay: "
424 << assays.Tails() * 100;
425 LOG(cyclus::LEV_INFO5,
"EnrFac") <<
" * SWU: " << swu_req;
426 LOG(cyclus::LEV_INFO5,
"EnrFac") <<
" * Current SWU capacity: "
434 using cyclus::Context;
437 LOG(cyclus::LEV_DEBUG1,
"EnrFac") << prototype()
438 <<
" has enriched a material:";
439 LOG(cyclus::LEV_DEBUG1,
"EnrFac") <<
" * Amount: " << natural_u;
440 LOG(cyclus::LEV_DEBUG1,
"EnrFac") <<
" * SWU: " << swu;
442 Context* ctx = Agent::context();
443 ctx->NewDatum(
"Enrichments")
444 ->AddVal(
"AgentId",
id())
445 ->AddVal(
"Time", ctx->time())
446 ->AddVal(
"Natural_Uranium", natural_u)
456 Material::Ptr fission_matl =
457 inventory.Pop(pop_qty, cyclus::eps_rsrc());
459 return cyclus::toolkit::UraniumAssayMass(fission_matl);
The Enrichment facility is a simple Agent that enriches natural uranium in a Cyclus simulation.
cyclus::Material::Ptr Request_()
generates a request for this facility given its current state.
double current_swu_capacity
cyclus::Material::Ptr Enrich_(cyclus::Material::Ptr mat, double qty)
cyclus::Material::Ptr Offer_(cyclus::Material::Ptr req)
Generates a material offer for a given request.
std::string product_commod
virtual void EnterNotify()
virtual std::set< cyclus::RequestPortfolio< cyclus::Material >::Ptr > GetMatlRequests()
The Enrichment request Materials of its given commodity.
virtual void Tock()
Each facility is prompted to its end-of-time-step stuff on the tock of the timer.
cyclus::toolkit::ResBuf< cyclus::Material > tails
bool ValidReq(const cyclus::Material::Ptr mat)
Determines if a particular material is a valid request to respond to.
double intra_timestep_swu_
virtual ~Enrichment()
Destructor for the Enrichment class.
virtual void AdjustMatlPrefs(cyclus::PrefMap< cyclus::Material >::type &prefs)
The Enrichment adjusts preferences for offers of natural uranium it has received to maximize U-235 co...
double SwuCapacity() const
virtual std::string str()
Print information about this agent.
virtual void AcceptMatlTrades(const std::vector< std::pair< cyclus::Trade< cyclus::Material >, cyclus::Material::Ptr > > &responses)
The Enrichment place accepted trade Materials in their Inventory.
double FeedAssay()
calculates the feed assay based on the unenriched inventory
virtual std::set< cyclus::BidPortfolio< cyclus::Material >::Ptr > GetMatlBids(cyclus::CommodMap< cyclus::Material >::type &commod_requests)
Responds to each request for this facility's commodity.
virtual void Tick()
Each facility is prompted to do its beginning-of-time-step stuff at the tick of the timer.
void RecordEnrichment_(double natural_u, double swu)
records and enrichment with the cyclus::Recorder
double intra_timestep_feed_
Enrichment(cyclus::Context *ctx)
Constructor for the Enrichment class.
cyclus::toolkit::ResBuf< cyclus::Material > inventory
virtual void GetMatlTrades(const std::vector< cyclus::Trade< cyclus::Material > > &trades, std::vector< std::pair< cyclus::Trade< cyclus::Material >, cyclus::Material::Ptr > > &responses)
respond to each trade with a material enriched to the appropriate level given this facility's invento...
virtual void Build(cyclus::Agent *parent)
perform module-specific tasks when entering the simulation
void AddMat_(cyclus::Material::Ptr mat)
adds a material into the natural uranium inventory
cyclus::Agent * ConstructEnrichment(cyclus::Context *ctx)
bool SortBids(cyclus::Bid< Material > *i, cyclus::Bid< Material > *j)