Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Package management by context and handling of repackaging process #1729

Merged
merged 32 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
9dc611e
move GetFillMass and PackageResource to resource class
nuclearkatie Apr 11, 2024
d70e503
split GetFillMass and PackageResource
nuclearkatie Apr 15, 2024
efa4ed9
upon intialization, context creates unpackaged type
nuclearkatie Apr 15, 2024
215f588
allow creation of unpackaged type with id always =1
nuclearkatie Apr 15, 2024
1499ce7
repackage
nuclearkatie Apr 15, 2024
0d232f2
resource packaging tests
nuclearkatie Apr 15, 2024
1d14fd3
changelog
nuclearkatie Apr 15, 2024
4fad47d
don't have to dynamic cast resource after extract
nuclearkatie Apr 15, 2024
219e113
remove unused old package call
nuclearkatie Apr 15, 2024
cfd94e3
unpackaged name
nuclearkatie Apr 15, 2024
0983c42
no default create package
nuclearkatie Apr 15, 2024
ab3c697
try singleton pattern for unpackaged
gonuke Apr 16, 2024
f530690
add const
gonuke Apr 16, 2024
9b44b17
pass the unpackaged by reference
gonuke Apr 16, 2024
8f3e31a
fix reference location
gonuke Apr 16, 2024
ec39b33
fix initializers
gonuke Apr 16, 2024
359e96f
remove consts
gonuke Apr 16, 2024
3b78c8d
resolve build final errors
gonuke Apr 16, 2024
9b95834
tidy up construction in singleton accesor
gonuke Apr 16, 2024
df2fdf4
Merge pull request #2 from gonuke/unpackage_singleton
nuclearkatie Apr 16, 2024
b508d8d
defaults for package create
nuclearkatie Apr 16, 2024
e8fd577
default strategy
nuclearkatie Apr 16, 2024
fa988fb
Make package virtual - Apply suggestions from code review
nuclearkatie Apr 17, 2024
8f47fcb
add package returns void
nuclearkatie Apr 17, 2024
6e63f52
no friend class needed for package
nuclearkatie Apr 17, 2024
391b5d7
no package in resource
nuclearkatie Apr 17, 2024
7264510
Return resource type - Apply suggestions from code review
nuclearkatie Apr 22, 2024
dc6d366
cast to resource?
nuclearkatie Apr 22, 2024
a402c01
promote Package to parent class with templating
gonuke Apr 25, 2024
29fb87d
Merge pull request #3 from gonuke/mv_packaging
nuclearkatie Apr 26, 2024
8684292
test packaged size
nuclearkatie Apr 30, 2024
7092890
indenting
nuclearkatie Apr 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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, #1699, #1712), package id is default unpackaged (#1711) and is a member of
* Created Package class and optional declaration of packages in input files (#1673, #1699, #1712, #1729), package id is default unpackaged (#1711) and is a member of
resources (materials/products) (#1675). Can pop resources as packaged from resource buffer, pushing resource onto a buffer defaults to stripping packaging (#1683)
* CI support for Rocky Linux (#1691)
* Added support for a ResBuf to behave as a single bulk storage with mixing & extraction of resources (#1687)
Expand Down
10 changes: 8 additions & 2 deletions src/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ Context::Context(Timer* ti, Recorder* rec)
solver_(NULL),
trans_id_(0),
si_(0) {

rng_ = new RandomNumberGenerator();
}

Expand Down Expand Up @@ -192,7 +191,7 @@ Composition::Ptr Context::GetRecipe(std::string name) {
return recipes_[name];
}

void Context::AddPackage(std::string name, double fill_min, double fill_max,
Package::Ptr Context::AddPackage(std::string name, double fill_min, double fill_max,
std::string strategy) {
packages_[name] = Package::Create(name, fill_min, fill_max, strategy);
NewDatum("Packages")
Expand All @@ -201,16 +200,23 @@ void Context::AddPackage(std::string name, double fill_min, double fill_max,
->AddVal("FillMax", fill_max)
->AddVal("Strategy", strategy)
->Record();
return packages_[name];
}

Package::Ptr Context::GetPackageByName(std::string name) {
if (name == Package::unpackaged_name()) {
return Package::unpackaged();
}
if (packages_.count(name) == 0) {
throw KeyError("Invalid package name " + name);
}
return packages_[name];
}

Package::Ptr Context::GetPackageById(int id) {
if (id == Package::unpackaged_id()) {
return Package::unpackaged();
}
if (id < 0) {
throw ValueError("Invalid package id " + std::to_string(id));
}
Expand Down
6 changes: 3 additions & 3 deletions src/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,9 @@ class Context {

/// Adds a package type to a simulation-wide accessible list.
/// Agents should NOT add their own packages.
void AddPackage(std::string name, double fill_min = 0,
double fill_max = std::numeric_limits<double>::max(),
std::string strategy = "first");
Package::Ptr AddPackage(std::string name, double fill_min = 0,
nuclearkatie marked this conversation as resolved.
Show resolved Hide resolved
double fill_max = std::numeric_limits<double>::max(),
std::string strategy = "first");
nuclearkatie marked this conversation as resolved.
Show resolved Hide resolved

// Retrieve a registered package.
Package::Ptr GetPackageByName(std::string name);
Expand Down
18 changes: 18 additions & 0 deletions src/material.cc
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,24 @@ double Material::DecayHeat() {
return decay_heat;
}

std::vector<Material::Ptr> Material::Package(Package::Ptr pkg) {
std::vector<Material::Ptr> ms_pkgd;
Material::Ptr m_pkgd;

double fill_mass = pkg->GetFillMass(quantity());
if (fill_mass == 0) {
return ms_pkgd;
}

while (quantity() > pkg->fill_min()) {
double pkg_fill = std::min(quantity(), fill_mass);
m_pkgd = boost::dynamic_pointer_cast<Material>(ExtractRes(pkg_fill));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like this is the only line that really forces this method to be replicated 3 times... I'll have to dust off my C++ polymorphism to see if there's a better way...

m_pkgd->ChangePackageId(pkg->id());
ms_pkgd.push_back(m_pkgd);
}
return ms_pkgd;
}

Composition::Ptr Material::comp() const {
throw Error("comp() const is deprecated - use non-const comp() function."
" Recompilation should fix the problem.");
Expand Down
3 changes: 3 additions & 0 deletions src/material.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ class Material: public Resource {
/// type minimum and maximum mass criteria.
virtual void ChangePackageId(int new_package_id = Package::unpackaged_id());

/// Packages the material
std::vector<Material::Ptr> Package(Package::Ptr pkg);
gonuke marked this conversation as resolved.
Show resolved Hide resolved

protected:
Material(Context* ctx, double quantity, Composition::Ptr c, int package_id = Package::unpackaged_id());

Expand Down
86 changes: 40 additions & 46 deletions src/package.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,71 +4,65 @@
namespace cyclus {

// unpackaged id is 1, so start the user-declared packaging id at 2
int Package::next_id_ = 2;
int Package::next_package_id_ = 2;
Package::Ptr Package::unpackaged_ = NULL;

template <class T>
double Package::GetFillMass(typename T::Ptr r) {
if (r->quantity() < fill_min_) {
Package::Ptr Package::Create(std::string name, double fill_min, double fill_max, std::string strategy) {
if (fill_min < 0 || fill_max < 0) {
throw ValueError("fill_min and fill_max must be non-negative");
}
else if (fill_min > fill_max) {
throw ValueError("fill_min must be less than or equal to fill_max");
}
Ptr p(new Package(name, fill_min, fill_max, strategy));
return p;
}

// singleton pattern:
// if the static member is not yet set, create a new object
// otherwise return the object that already exists
Package::Ptr& Package::unpackaged() {

if (!unpackaged_) {
unpackaged_ = Ptr(new Package(unpackaged_name_));
}

return unpackaged_;
}

double Package::GetFillMass(double qty) {
if (qty < fill_min_) {
// less than one pkg of material available
return 0;
}

std::vector<typename T::Ptr> rs;
typename T::Ptr r_pkgd;
double fill_mass;
if (strategy_ == "first") {
fill_mass = fill_max_;
} else if (strategy_ == "equal") {
int num_min_fill = std::floor(r->quantity() / fill_min_);
int num_max_fill = std::ceil(r->quantity() / fill_max_);
int num_min_fill = std::floor(qty / fill_min_);
int num_max_fill = std::ceil(qty / fill_max_);
if (num_min_fill >= num_max_fill) {
// all material can fit in a package
double fill_mass = r->quantity() / num_max_fill;
double fill_mass = qty / num_max_fill;
} else {
// some material will remain unpackaged, fill up as many max packages as possible
fill_mass = fill_max_;
}
}
return fill_mass;
}

template <class T>
std::vector<typename T::Ptr> Package::PackageResource(typename T::Ptr r) {
std::vector<typename T::Ptr> rs_pkgd;
typename T::Ptr r_pkgd;

double fill_mass = GetFillMass(r);
if (fill_mass ==0) {
return rs_pkgd;
}

while (r->quantity() > fill_min_) {
double pkg_fill = std::min(r->quantity(), fill_mass);
r_pkgd = boost::dynamic_pointer_cast<T>(r->ExtractRes(pkg_fill));
r_pkgd->ChangePackageId(id_);
rs_pkgd.push_back(r_pkgd);
}
return rs_pkgd;
}

Package::Ptr Package::Create() {
Ptr p(new Package());
return p;
}

Package::Ptr Package::Create(std::string name, double fill_min, double fill_max, std::string strategy) {
if (fill_min < 0 || fill_max < 0) {
throw ValueError("fill_min and fill_max must be non-negative");
}
else if (fill_min > fill_max) {
throw ValueError("fill_min must be less than or equal to fill_max");
Package::Package(std::string name, double fill_min, double fill_max, std::string strategy) :
name_(name), fill_min_(fill_min), fill_max_(fill_max), strategy_(strategy) {
if (name == unpackaged_name_) {
if (unpackaged_) {
throw ValueError("can't create a new package with name 'unpackaged'");
}
id_ = unpackaged_id_;
} else {
id_ = next_package_id_++;
}
}
Ptr p(new Package(name, fill_min, fill_max, strategy));
return p;
}

Package::Package() : id_(next_id_++), fill_min_(0), fill_max_(std::numeric_limits<double>::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) {}

} // namespace cyclus
41 changes: 22 additions & 19 deletions src/package.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,17 @@ namespace cyclus {

/// Packager is a class that packages materials into discrete items in ways that mimic realistic nuclear material handling. Packages will eventually be a required parameter of resources.
class Package {

friend class Context;
nuclearkatie marked this conversation as resolved.
Show resolved Hide resolved
public:
typedef boost::shared_ptr<Package> Ptr;

// create a new package type. Should be called by the context only
// (see Context::AddPackage), unless you want an untracked package
// type (which you probably don't)
static Ptr Create(std::string name, double fill_min = 0,
double fill_max = std::numeric_limits<double>::max(),
std::string strategy = "first");

/// Returns optimal fill mass for a resource to be packaged. Can be used
/// to determine how to respond to requests for material, and to actually
/// package and send off trades.
Expand All @@ -30,20 +37,7 @@ class Package {
/// quantity = 5, fill_min = 3, fill_max = 4. num_min_fill = floor(5/3) = 1,
/// num_max_fill = ceil(5/4) = 2. num_min_fill < num_max_fill, so fill to
/// the max.
template <class T>
double GetFillMass(typename T::Ptr r);

/// Repackages a single resource into a package. If some quantity of the
/// resource cannot be packaged using the given packaging strategy and
/// restrictions, the remainder is left in the resource object.
template <class T>
std::vector<typename T::Ptr> PackageResource(typename T::Ptr r);

// create a new package type with default values
static Ptr Create();

// create a new package type
static Ptr Create(std::string name, double fill_min, double fill_max, std::string strategy);
double GetFillMass(double qty);

// returns package id
int id() const { return id_; }
Expand All @@ -59,13 +53,22 @@ class Package {
// returns the unpackaged id (1)
static int unpackaged_id() { return unpackaged_id_; }

protected:
Package();
Package(std::string name, double fill_min, double fill_max, std::string strategy);
// returns the unpackaged package name
static std::string unpackaged_name() { return unpackaged_name_; }

// returns the unpackaged singleton object
static Ptr& unpackaged();

private:
Package(std::string name,
double fill_min = 0,
double fill_max = std::numeric_limits<double>::max(),
std::string strategy = "first");

static const int unpackaged_id_ = 1;
static int next_id_;
static constexpr char unpackaged_name_[11] = "unpackaged";
static Ptr unpackaged_;
static int next_package_id_;

std::string name_;
int id_;
Expand Down
21 changes: 19 additions & 2 deletions src/product.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ void Product::ChangePackageId(int new_package_id) {
package_id_ = new_package_id;
return;
}

Package::Ptr p = ctx_->GetPackageById(package_id_);
Package::Ptr p = ctx_->GetPackageById(new_package_id);
double min = p->fill_min();
double max = p->fill_max();
if (quantity_ >= min && quantity_ <= max) {
Expand All @@ -98,6 +97,24 @@ void Product::ChangePackageId(int new_package_id) {
}
}

std::vector<Product::Ptr> Product::Package(Package::Ptr pkg) {
std::vector<Product::Ptr> ps_pkgd;
Product::Ptr p_pkgd;

double fill_mass = pkg->GetFillMass(quantity());
if (fill_mass == 0) {
return ps_pkgd;
}

while (quantity() > pkg->fill_min()) {
double pkg_fill = std::min(quantity(), fill_mass);
p_pkgd = boost::dynamic_pointer_cast<Product>(ExtractRes(pkg_fill));
p_pkgd->ChangePackageId(pkg->id());
ps_pkgd.push_back(p_pkgd);
}
return ps_pkgd;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Product::Product(Context* ctx, double quantity, std::string quality, int package_id)
: quality_(quality),
Expand Down
3 changes: 3 additions & 0 deletions src/product.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ class Product : public Resource {
/// Changes the product's package id
virtual void ChangePackageId(int new_package_id = Package::unpackaged_id());

// Packages the product
std::vector<Product::Ptr> Package(Package::Ptr pkg);
gonuke marked this conversation as resolved.
Show resolved Hide resolved

private:
/// @param ctx the simulation context
/// @param quantity is a double indicating the quantity
Expand Down
18 changes: 18 additions & 0 deletions src/resource.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,22 @@ void Resource::BumpStateId() {
nextstate_id_++;
}

std::vector<Resource::Ptr> Resource::Package(Package::Ptr pkg) {
std::vector<Resource::Ptr> rs_pkgd;
Resource::Ptr r_pkgd;

double fill_mass = pkg->GetFillMass(quantity());
if (fill_mass == 0) {
return rs_pkgd;
}

while (quantity() > pkg->fill_min()) {
double pkg_fill = std::min(quantity(), fill_mass);
r_pkgd = ExtractRes(pkg_fill);
nuclearkatie marked this conversation as resolved.
Show resolved Hide resolved
r_pkgd->ChangePackageId(pkg->id());
rs_pkgd.push_back(r_pkgd);
}
return rs_pkgd;
}

} // namespace cyclus
5 changes: 5 additions & 0 deletions src/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ class Resource {
/// Changes the product's package id
virtual void ChangePackageId(int new_package_id = Package::unpackaged_id()) {};

/// Repackages a single resource into a package. If some quantity of the
/// resource cannot be packaged using the given packaging strategy and
/// restrictions, the remainder is left in the resource object.
std::vector<Resource::Ptr> Package(Package::Ptr pkg);
nuclearkatie marked this conversation as resolved.
Show resolved Hide resolved

private:
static int nextstate_id_;
static int nextobj_id_;
Expand Down
3 changes: 0 additions & 3 deletions src/xml_file_loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,6 @@ void XMLFileLoader::LoadRecipes() {

void XMLFileLoader::LoadPackages() {
InfileTree xqe(*parser_);
// create default package
ctx_->AddPackage("default", 0, std::numeric_limits<int>::max(), "first");

std::string query = "/*/package";
int num_packages = xqe.NMatches(query);
Expand All @@ -344,7 +342,6 @@ void XMLFileLoader::LoadPackages() {

std::string strategy = cyclus::OptionalQuery<std::string>(qe, "strategy", "first");

boost::shared_ptr<Package> p = Package::Create(name, fill_min, fill_max, strategy);
ctx_->AddPackage(name, fill_min, fill_max, strategy);
}
}
Expand Down
Loading
Loading