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)