diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1a0fa1180c..b37decedcb 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -27,7 +27,7 @@ Since last release * Adds support for Cython3 (#1636) * Adds TotalInvTracker, which allows an inventory cap to be set for multiple resource buffers, and is now required for material buy policy (#1646) * AddMutalReqs and AddReciepe functions and exclusive bids in python API of DRE (#1584) -* Created Package class and optional declaration of packages in input files (#1673) +* Created Package class and optional declaration of packages in input files (#1673), package id is a member of resources (materials/products) (#1675) **Changed:** diff --git a/src/context.cc b/src/context.cc index 1bcb0bc4f3..cea27a6e0b 100644 --- a/src/context.cc +++ b/src/context.cc @@ -203,13 +203,23 @@ void Context::AddPackage(std::string name, double fill_min, double fill_max, ->Record(); } -Package::Ptr Context::GetPackage(std::string name) { +Package::Ptr Context::GetPackageByName(std::string name) { if (packages_.count(name) == 0) { throw KeyError("Invalid package name " + name); } return packages_[name]; } +Package::Ptr Context::GetPackageById(int id) { + // iterate through the list of packages to get the one package with the correct id + std::map::iterator it; + for (it = packages_.begin(); it != packages_.end(); ++it) { + if (it->second->id() == id) { + return it->second; + } + } +} + void Context::InitSim(SimInfo si) { NewDatum("Info") ->AddVal("Handle", si.handle) diff --git a/src/context.h b/src/context.h index 5bbad65dea..0b45786dc9 100644 --- a/src/context.h +++ b/src/context.h @@ -256,7 +256,9 @@ class Context { std::string strategy = "first"); // Retrieve a registered package. - Package::Ptr GetPackage(std::string name); + Package::Ptr GetPackageByName(std::string name); + + Package::Ptr GetPackageById(int id); int random(); diff --git a/src/material.cc b/src/material.cc index 6f3d8c8097..1823835b3d 100644 --- a/src/material.cc +++ b/src/material.cc @@ -15,15 +15,15 @@ const ResourceType Material::kType = "Material"; Material::~Material() {} Material::Ptr Material::Create(Agent* creator, double quantity, - Composition::Ptr c) { - Material::Ptr m(new Material(creator->context(), quantity, c)); + Composition::Ptr c, int package_id) { + Material::Ptr m(new Material(creator->context(), quantity, c, package_id)); m->tracker_.Create(creator); return m; } Material::Ptr Material::CreateUntracked(double quantity, Composition::Ptr c) { - Material::Ptr m(new Material(NULL, quantity, c)); + Material::Ptr m(new Material(NULL, quantity, c, default_package_id_)); return m; } @@ -48,6 +48,7 @@ void Material::Record(Context* ctx) const { ctx_->NewDatum("MaterialInfo") ->AddVal("ResourceId", state_id()) ->AddVal("PrevDecayTime", prev_decay_time_) + ->AddVal("PackageId", package_id_) ->Record(); comp_->Record(ctx); @@ -87,8 +88,7 @@ Material::Ptr Material::ExtractComp(double qty, Composition::Ptr c, } qty_ -= qty; - - Material::Ptr other(new Material(ctx_, qty, c)); + Material::Ptr other(new Material(ctx_, qty, c, default_package_id_)); // Decay called on the extracted material should have the same dt as for // this material regardless of composition. @@ -141,6 +141,30 @@ void Material::Transmute(Composition::Ptr c) { } } +void Material::ChangePackageId(int new_package_id) { + if (ctx_ != NULL) { + throw ValueError("Package Id cannot be changed with NULL context"); + } + if (new_package_id == package_id_) { + // no change needed + return; + } + else if (new_package_id == default_package_id_) { + // default has functionally no restrictions + package_id_ = new_package_id; + return; + } + + Package::Ptr p = ctx_->GetPackageById(package_id_); + double min = p->fill_min(); + double max = p->fill_max(); + if (qty_ >= min && qty_ <= max) { + package_id_ = new_package_id; + } else { + throw ValueError("Material quantity is outside of package fill limits."); + } +} + void Material::Decay(int curr_time) { if (ctx_ != NULL && ctx_->sim_info().decay == "never") { return; @@ -218,12 +242,13 @@ Composition::Ptr Material::comp() { return comp_; } -Material::Material(Context* ctx, double quantity, Composition::Ptr c) +Material::Material(Context* ctx, double quantity, Composition::Ptr c, int package_id) : qty_(quantity), comp_(c), tracker_(ctx, this), ctx_(ctx), - prev_decay_time_(0) { + prev_decay_time_(0), + package_id_(package_id) { if (ctx != NULL) { prev_decay_time_ = ctx->time(); } else { @@ -236,4 +261,8 @@ Material::Ptr NewBlankMaterial(double quantity) { return Material::CreateUntracked(quantity, comp); } +int Material::package_id() { + return package_id_; +} + } // namespace cyclus diff --git a/src/material.h b/src/material.h index 958cac7498..4a1de69af3 100644 --- a/src/material.h +++ b/src/material.h @@ -81,7 +81,7 @@ class Material: public Resource { /// pointer to the agent creating the resource (usually will be the caller's /// "this" pointer). All future output data recorded will be done using the /// creator's context. - static Ptr Create(Agent* creator, double quantity, Composition::Ptr c); + static Ptr Create(Agent* creator, double quantity, Composition::Ptr c, int package_id = default_package_id_); /// Creates a new material resource that does not actually exist as part of /// the simulation and is untracked. @@ -153,8 +153,14 @@ class Material: public Resource { /// DEPRECATED - use non-const comp() function. Composition::Ptr comp() const; + int package_id(); + + /// Changes the package id. Checks that the resource fits the package + /// type minimum and maximum mass criteria. + void ChangePackageId(int new_package_id = default_package_id_); + protected: - Material(Context* ctx, double quantity, Composition::Ptr c); + Material(Context* ctx, double quantity, Composition::Ptr c, int package_id = default_package_id_); private: Context* ctx_; @@ -162,6 +168,7 @@ class Material: public Resource { Composition::Ptr comp_; int prev_decay_time_; ResTracker tracker_; + int package_id_; }; /// Creates and returns a new material with the specified quantity and a diff --git a/src/package.cc b/src/package.cc index 8dc79eda42..5e2e394b47 100644 --- a/src/package.cc +++ b/src/package.cc @@ -20,12 +20,8 @@ Package::Ptr Package::Create(std::string name, double fill_min, double fill_max, Ptr p(new Package(name, fill_min, fill_max, strategy)); return p; } - -int Package::id() { - return id_; -} -Package::Package() : id_(next_id_++), fill_min_(0), fill_max_(std::numeric_limits::max()), strategy_("first") {} +Package::Package() : id_(next_id_++), fill_min_(0), fill_max_(std::numeric_limits::max()) {} Package::Package(std::string name, double fill_min, double fill_max, std::string strategy) : name_(name), id_(next_id_++), fill_min_(fill_min), fill_max_(fill_max), strategy_(strategy) {} diff --git a/src/package.h b/src/package.h index 4244c23576..20e6a53862 100644 --- a/src/package.h +++ b/src/package.h @@ -19,7 +19,16 @@ class Package { // create a new package type static Ptr Create(std::string name, double fill_min, double fill_max, std::string strategy); - int id(); + // returns package id + int id() const { return id_; } + // returns package name + std::string name() const { return name_; } + // returns package fill min + double fill_min() const { return fill_min_; } + // returns package fill max + double fill_max() const { return fill_max_; } + // returns package strategy + std::string strategy() const { return strategy_; } protected: Package(); diff --git a/src/product.cc b/src/product.cc index 3ab8da1ae9..39fc25fa47 100644 --- a/src/product.cc +++ b/src/product.cc @@ -12,17 +12,18 @@ int Product::next_qualid_ = 1; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Product::Ptr Product::Create(Agent* creator, double quantity, - std::string quality) { + std::string quality, int package_id) { if (qualids_.count(quality) == 0) { qualids_[quality] = next_qualid_++; creator->context()->NewDatum("Products") ->AddVal("QualId", qualids_[quality]) ->AddVal("Quality", quality) + ->AddVal("PackageId", package_id) ->Record(); } // the next lines must come after qual id setting - Product::Ptr r(new Product(creator->context(), quantity, quality)); + Product::Ptr r(new Product(creator->context(), quantity, quality, package_id)); r->tracker_.Create(creator); return r; } @@ -62,7 +63,7 @@ Product::Ptr Product::Extract(double quantity) { quantity_ -= quantity; - Product::Ptr other(new Product(ctx_, quantity, quality_)); + Product::Ptr other(new Product(ctx_, quantity, quality_, package_id_)); tracker_.Extract(&other->tracker_); return other; } @@ -72,11 +73,40 @@ Resource::Ptr Product::ExtractRes(double qty) { return boost::static_pointer_cast(Extract(qty)); } +int Product::package_id() { + return package_id_; +} + +void Product::ChangePackageId(int new_package_id) { + if (ctx_ != NULL) { + throw ValueError("Package Id cannot be changed with NULL context"); + } + if (new_package_id == package_id_) { + // no change needed + return; + } + else if (new_package_id == default_package_id_) { + // default has functionally no restrictions + package_id_ = new_package_id; + return; + } + + Package::Ptr p = ctx_->GetPackageById(package_id_); + double min = p->fill_min(); + double max = p->fill_max(); + if (quantity_ >= min && quantity_ <= max) { + package_id_ = new_package_id; + } else { + throw ValueError("Material quantity is outside of package fill limits."); + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Product::Product(Context* ctx, double quantity, std::string quality) +Product::Product(Context* ctx, double quantity, std::string quality, int package_id) : quality_(quality), quantity_(quantity), tracker_(ctx, this), - ctx_(ctx) {} + ctx_(ctx), + package_id_(package_id) {} } // namespace cyclus diff --git a/src/product.h b/src/product.h index 6f0e9ee8c7..0c41dff89d 100644 --- a/src/product.h +++ b/src/product.h @@ -28,7 +28,7 @@ class Product : public Resource { /// pointer to the agent creating the resource (usually will be the caller's /// "this" pointer). All future output data recorded will be done using the /// creator's context. - static Ptr Create(Agent* creator, double quantity, std::string quality); + static Ptr Create(Agent* creator, double quantity, std::string quality, int package_id = default_package_id_); /// Creates a new product that does not actually exist as part of /// the simulation and is untracked. @@ -71,11 +71,17 @@ class Product : public Resource { /// @throws ValueError 'other' resource is of different quality void Absorb(Product::Ptr other); + // Returns the package id. + int package_id(); + + /// Changes the product's package id + void ChangePackageId(int new_package_id); + private: /// @param ctx the simulation context /// @param quantity is a double indicating the quantity /// @param quality the resource quality - Product(Context* ctx, double quantity, std::string quality); + Product(Context* ctx, double quantity, std::string quality, int package_id = default_package_id_); // map static std::map qualids_; @@ -85,6 +91,7 @@ class Product : public Resource { std::string quality_; double quantity_; ResTracker tracker_; + int package_id_; }; } // namespace cyclus diff --git a/src/resource.h b/src/resource.h index b13b52431e..04ff568250 100644 --- a/src/resource.h +++ b/src/resource.h @@ -79,6 +79,8 @@ class Resource { /// @return a new resource object with same state id and quantity == quantity virtual Ptr ExtractRes(double quantity) = 0; + protected: + const static int default_package_id_ = 1; private: static int nextstate_id_; static int nextobj_id_;