diff --git a/src/storage.cc b/src/storage.cc index 9fc563e17..d37748ad7 100644 --- a/src/storage.cc +++ b/src/storage.cc @@ -183,9 +183,10 @@ void Storage::EnterNotify() { buy_policy.Start(); std::string package_name_ = context()->GetPackage(package)->name(); + std::string tu_name_ = context()->GetTransportUnit(transport_unit)->name(); if (out_commods.size() == 1) { sell_policy.Init(this, &stocks, std::string("stocks"), 1e+299, false, - sell_quantity, package_name_) + sell_quantity, package_name_, tu_name_) .Set(out_commods.front()) .Start(); diff --git a/src/storage.h b/src/storage.h index 01186fdf4..0674eba57 100644 --- a/src/storage.h +++ b/src/storage.h @@ -437,6 +437,14 @@ class Storage "uilabel": "Package"} std::string package; + #pragma cyclus var {"default": "unrestricted", \ + "tooltip": "Output transport unit", \ + "doc": "Outgoing material, after packaging, will be "\ + "further restricted by transport unit when trading.", \ + "uitype": "transportunit", \ + "uilabel": "Transport Unit"} + std::string transport_unit; + #pragma cyclus var {"tooltip":"Incoming material buffer"} cyclus::toolkit::ResBuf inventory; diff --git a/src/storage_tests.cc b/src/storage_tests.cc index f28a9d686..adb4891d7 100644 --- a/src/storage_tests.cc +++ b/src/storage_tests.cc @@ -1041,6 +1041,59 @@ TEST_F(StorageTest, PackageMerge) { EXPECT_EQ(1, qr_res.GetVal("Quantity", 1)); } +TEST_F(StorageTest, TransportUnit) { + std::string config = + " commodity " + " commodity1 " + " 3 " + " foo" + " bar"; + + int simdur = 3; + + cyclus::MockSim sim(cyclus::AgentSpec (":cycamore:Storage"), config, simdur); + sim.context()->AddPackage("foo", 1, 1, "first"); + cyclus::Package::Ptr p = sim.context()->GetPackage("foo"); + sim.context()->AddTransportUnit("bar", 2, 2, "first"); + + sim.AddSource("commodity").Finalize(); + sim.AddSink("commodity1").Finalize(); + + int id = sim.Run(); + + std::vector tr_conds; + tr_conds.push_back(cyclus::Cond("Commodity", "==", std::string("commodity1"))); + + cyclus::QueryResult qr_trans = sim.db().Query("Transactions", &tr_conds); + // 6 transactions. While all three units could be packaged in one time step, + // the transport unit only allows two packages to be transported. Therefore, + // zero transactions the first timestep (material coming to storage from + // source). Then only two packages can be shipped at time step 1. Then the + // two packages plus the leftover material is able to ship four packages, + // two transport units in time 2 + EXPECT_EQ(6, qr_trans.rows.size()); + + EXPECT_EQ(1, qr_trans.GetVal("Time", 0)); + EXPECT_EQ(1, qr_trans.GetVal("Time", 1)); + EXPECT_EQ(2, qr_trans.GetVal("Time", 2)); + EXPECT_EQ(2, qr_trans.GetVal("Time", 3)); + EXPECT_EQ(2, qr_trans.GetVal("Time", 4)); + EXPECT_EQ(2, qr_trans.GetVal("Time", 5)); + + for (int i = 0; i < qr_trans.rows.size(); i++) { + std::cerr << "transaction " << i << "is at time " << qr_trans.GetVal("Time", i) << std::endl; + } + + std::vector res_conds; + res_conds.push_back(cyclus::Cond("PackageName", "==", p->name())); + cyclus::QueryResult qr_res = sim.db().Query("Resources", &res_conds); + // All pkgd resources are size 1 + EXPECT_EQ(6, qr_res.rows.size()); + + EXPECT_EQ(1, qr_res.GetVal("Quantity", 0)); + EXPECT_EQ(1, qr_res.GetVal("Quantity", 5)); +} + } // namespace cycamore // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -