From 95c1de3b3a51a653f7c09e4f1413ae3201d3cb87 Mon Sep 17 00:00:00 2001 From: opotowsky Date: Wed, 1 Oct 2014 08:42:02 -0500 Subject: [PATCH 001/314] updating sink to include option for requesting a particular composition --- src/sink.cc | 9 ++++++++- src/sink.h | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/sink.cc b/src/sink.cc index deedef78a7..774ba1c412 100644 --- a/src/sink.cc +++ b/src/sink.cc @@ -67,7 +67,14 @@ Sink::GetMatlRequests() { std::set::Ptr> ports; RequestPortfolio::Ptr port(new RequestPortfolio()); double amt = RequestAmt(); - Material::Ptr mat = cyclus::NewBlankMaterial(amt); + Material::Ptr mat; + + if (composition == "") { + mat = cyclus::NewBlankMaterial(amt); + } else { + this->context()->GetRecipe(composition); + mat = cyclus::Material::CreateUntracked(amt, this); + } if (amt > cyclus::eps()) { CapacityConstraint cc(amt); diff --git a/src/sink.h b/src/sink.h index b98142815e..c6eac4d966 100644 --- a/src/sink.h +++ b/src/sink.h @@ -174,6 +174,11 @@ class Sink : public cyclus::Facility { "accept at each time step"} double capacity; + #pragma cyclus var {"default": "", "tooltip": "request composition", \ + "doc": "name of recipe to use for material " \ + "requests"} + std::string composition; + /// max inventory size #pragma cyclus var {"default": 1e299, \ "tooltip": "sink maximum inventory size", \ From 5bd3bc8075ffef3b461c74965c6e5ceea7058c44 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Thu, 9 Oct 2014 08:39:30 -0500 Subject: [PATCH 002/314] tried changing sink to allow recipe, not currently working --- src/sink.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sink.cc b/src/sink.cc index 774ba1c412..e7aebc93d6 100644 --- a/src/sink.cc +++ b/src/sink.cc @@ -72,8 +72,8 @@ Sink::GetMatlRequests() { if (composition == "") { mat = cyclus::NewBlankMaterial(amt); } else { - this->context()->GetRecipe(composition); - mat = cyclus::Material::CreateUntracked(amt, this); + Composition::Ptr c = this->context()->GetRecipe(composition); + mat = cyclus::Material::CreateUntracked(amt, c); } if (amt > cyclus::eps()) { From 73e4f9760049763e700dc13bbce804bd0de55cc8 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Thu, 9 Oct 2014 10:16:10 -0500 Subject: [PATCH 003/314] sink now allows for user-specified input material --- src/sink.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sink.cc b/src/sink.cc index e7aebc93d6..04b4c64554 100644 --- a/src/sink.cc +++ b/src/sink.cc @@ -63,6 +63,7 @@ Sink::GetMatlRequests() { using cyclus::Material; using cyclus::RequestPortfolio; using cyclus::Request; + using cyclus::Composition; std::set::Ptr> ports; RequestPortfolio::Ptr port(new RequestPortfolio()); From 20f917b6b369a842dabc1e09b789235f0ac39302 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Thu, 9 Oct 2014 12:05:34 -0500 Subject: [PATCH 004/314] Improved test for empty composition as suggested by Scopatz --- src/sink.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sink.cc b/src/sink.cc index 04b4c64554..0308c5ea2c 100644 --- a/src/sink.cc +++ b/src/sink.cc @@ -70,7 +70,7 @@ Sink::GetMatlRequests() { double amt = RequestAmt(); Material::Ptr mat; - if (composition == "") { + if (composition.empty()) { mat = cyclus::NewBlankMaterial(amt); } else { Composition::Ptr c = this->context()->GetRecipe(composition); From e4ee26ce2829a7f211706a9778b65334a067b3c7 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Thu, 9 Oct 2014 14:51:45 -0500 Subject: [PATCH 005/314] changed composition references to recipe for consistency with existing documentation --- src/sink.cc | 6 +++--- src/sink.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sink.cc b/src/sink.cc index 0308c5ea2c..6bfa9b65a0 100644 --- a/src/sink.cc +++ b/src/sink.cc @@ -70,11 +70,11 @@ Sink::GetMatlRequests() { double amt = RequestAmt(); Material::Ptr mat; - if (composition.empty()) { + if (recipe_name.empty()) { mat = cyclus::NewBlankMaterial(amt); } else { - Composition::Ptr c = this->context()->GetRecipe(composition); - mat = cyclus::Material::CreateUntracked(amt, c); + Composition::Ptr rec = this->context()->GetRecipe(recipe_name); + mat = cyclus::Material::CreateUntracked(amt, rec); } if (amt > cyclus::eps()) { diff --git a/src/sink.h b/src/sink.h index c6eac4d966..ea953f25da 100644 --- a/src/sink.h +++ b/src/sink.h @@ -174,10 +174,10 @@ class Sink : public cyclus::Facility { "accept at each time step"} double capacity; - #pragma cyclus var {"default": "", "tooltip": "request composition", \ + #pragma cyclus var {"default": "", "tooltip": "requested composition", \ "doc": "name of recipe to use for material " \ "requests"} - std::string composition; + std::string recipe_name; /// max inventory size #pragma cyclus var {"default": 1e299, \ From fd75ff249b381a73fe10bb6f84d9b9ab2f7f6b96 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 5 Jan 2015 13:05:05 -0600 Subject: [PATCH 006/314] adding a new regression test file --- tests/test_new_regression.py | 84 ++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 tests/test_new_regression.py diff --git a/tests/test_new_regression.py b/tests/test_new_regression.py new file mode 100644 index 0000000000..a26a92a634 --- /dev/null +++ b/tests/test_new_regression.py @@ -0,0 +1,84 @@ +#! /usr/bin/env python + +from nose.tools import assert_equal, assert_true +import os +import tables +import numpy as np +import uuid +from tools import check_cmd +from helper import table_exist, find_ids +from cyclus_tools import run_cyclus + +class TestRegression(object): + def __init__(self): + self.outf_ = str(uuid.uuid4()) + ".h5" + self.inf_ = None + + def __del__(self): + if os.path.isfile(self.outf_): + print("removing {0}".format(self.outf_)) + os.remove(self.outf_) + + def setup(self): + if not self.inf_: + raise TypeError(("self.inf_ must be set in derived classes " + "to run regression tests.")) + run_cyclus("cyclus", os.getcwd(), self.inf_, self.outf_) + + with tables.open_file(self.outf_, mode="r") as f: + # Get specific tables and columns + agent_entry = f.get_node("/AgentEntry")[:] + agent_exit = f.get_node("/AgentExit")[:] if "/AgentExit" in f \ + else None + resources = f.get_node("/Resources")[:] + transactions = f.get_node("/Transactions")[:] + + # Find agent ids of source and sink facilities + self.agent_ids = agent_entry["AgentId"] + self.agent_impl = agent_entry["Spec"] + self.depl_time = agent_entry["EnterTime"] + if agent_exit: + self.exit_ids = agent_exit["AgentId"] + self.exit_time = agent_exit["ExitTime"] + + # Check transactions + self.sender_ids = transactions["SenderId"] + self.receiver_ids = transactions["ReceiverId"] + self.trans_time = transactions["Time"] + self.trans_resource = transactions["ResourceId"] + + # Track transacted resources + self.resource_ids = resources["ResourceId"] + self.quantities = resources["Quantity"] + + def teardown(self): + if os.path.isfile(self.outf_): + print("removing {0}".format(self.outf_)) + os.remove(self.outf_) + +class TestPhysorEnrichment(TestRegression): + def __init__(self): + super(TestPhysorEnrichment, self).__init__() + self.inf_ = "../input/physor/1_Enrichment_2_Reactor.xml" + print(self.outf_) + + def setup(self): + super(TestPhysorEnrichment, self).setup() + self.rx_id = find_ids(":cycamore:BatchReactor", + self.agent_impl, self.agent_ids) + self.enr_id = find_ids(":cycamore:EnrichmentFacility", + self.agent_impl, self.agent_ids) + + with tables.open_file(self.outf_, mode="r") as f: + self.enrichments = f.get_node("/Enrichments")[:] + + def test_deploy(self): + # Test for 3 sources and 4 sinks are deployed in the simulation + assert_equal(len(self.rx_id), 2) + assert_equal(len(self.enr_id), 1) + + def test_swu(self): + exp = [6.9, 10, 4.14, 6.9] + obs = [np.sum(self.enrichments["SWU"][self.enrichments["Time"] == t]) \ + for t in range(4)] + np.testing.assert_almost_equal(exp, obs) From 3533e169501cc2042a2d797086428dba370498e1 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 5 Jan 2015 14:14:12 -0600 Subject: [PATCH 007/314] added enrichment tests to new reg test --- tests/test_new_regression.py | 66 +++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/tests/test_new_regression.py b/tests/test_new_regression.py index a26a92a634..57ee83075d 100644 --- a/tests/test_new_regression.py +++ b/tests/test_new_regression.py @@ -27,30 +27,12 @@ def setup(self): with tables.open_file(self.outf_, mode="r") as f: # Get specific tables and columns - agent_entry = f.get_node("/AgentEntry")[:] - agent_exit = f.get_node("/AgentExit")[:] if "/AgentExit" in f \ + self.agent_entry = f.get_node("/AgentEntry")[:] + self.agent_exit = f.get_node("/AgentExit")[:] if "/AgentExit" in f \ else None - resources = f.get_node("/Resources")[:] - transactions = f.get_node("/Transactions")[:] + self.resources = f.get_node("/Resources")[:] + self.transactions = f.get_node("/Transactions")[:] - # Find agent ids of source and sink facilities - self.agent_ids = agent_entry["AgentId"] - self.agent_impl = agent_entry["Spec"] - self.depl_time = agent_entry["EnterTime"] - if agent_exit: - self.exit_ids = agent_exit["AgentId"] - self.exit_time = agent_exit["ExitTime"] - - # Check transactions - self.sender_ids = transactions["SenderId"] - self.receiver_ids = transactions["ReceiverId"] - self.trans_time = transactions["Time"] - self.trans_resource = transactions["ResourceId"] - - # Track transacted resources - self.resource_ids = resources["ResourceId"] - self.quantities = resources["Quantity"] - def teardown(self): if os.path.isfile(self.outf_): print("removing {0}".format(self.outf_)) @@ -60,25 +42,53 @@ class TestPhysorEnrichment(TestRegression): def __init__(self): super(TestPhysorEnrichment, self).__init__() self.inf_ = "../input/physor/1_Enrichment_2_Reactor.xml" - print(self.outf_) def setup(self): super(TestPhysorEnrichment, self).setup() + tbl = self.agent_entry self.rx_id = find_ids(":cycamore:BatchReactor", - self.agent_impl, self.agent_ids) + tbl["Spec"], tbl["AgentId"]) self.enr_id = find_ids(":cycamore:EnrichmentFacility", - self.agent_impl, self.agent_ids) + tbl["Spec"], tbl["AgentId"]) with tables.open_file(self.outf_, mode="r") as f: self.enrichments = f.get_node("/Enrichments")[:] def test_deploy(self): - # Test for 3 sources and 4 sinks are deployed in the simulation assert_equal(len(self.rx_id), 2) assert_equal(len(self.enr_id), 1) def test_swu(self): + enr = self.enrichments exp = [6.9, 10, 4.14, 6.9] - obs = [np.sum(self.enrichments["SWU"][self.enrichments["Time"] == t]) \ + obs = [np.sum(enr["SWU"][enr["Time"] == t]) for t in range(4)] + np.testing.assert_almost_equal(exp, obs, decimal=2) + + def test_nu(self): + enr = self.enrichments + exp = [13.03, 16.54, 7.83, 13.03] + obs = [np.sum(enr["Natural_Uranium"][enr["Time"] == t]) \ for t in range(4)] - np.testing.assert_almost_equal(exp, obs) + np.testing.assert_almost_equal(exp, obs, decimal=2) + + def test_xactions(self): + xa = self.transactions + rs = self.resources + + rqtys = {x["ResourceId"]: x["Quantity"] for x in rs \ + if x["ResourceId"] in xa["ResourceId"]} + torxtrs = {i: [rqtys[x["ResourceId"]] \ + for x in xa[xa["ReceiverId"] == i]] \ + for i in self.rx_id} + transfers = sorted(torxtrs.values()) + + exp = [1, 0.8, 0.2, 1] + obs = transfers[0] + msg = "Testing that first reactor gets less than it wants." + np.testing.assert_almost_equal(exp, obs, decimal=2, err_msg=msg) + + exp = [1, 1, 1, 1] + obs = transfers[1] + msg = "Testing that second reactor gets what it wants." + np.testing.assert_almost_equal(exp, obs, decimal=2) + From 1368c811381b318537b682c62bda5e86ea55c576 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 5 Jan 2015 14:53:31 -0600 Subject: [PATCH 008/314] added 2source3reactor to new regression test format --- tests/test_new_regression.py | 85 ++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/tests/test_new_regression.py b/tests/test_new_regression.py index 57ee83075d..828a1a405f 100644 --- a/tests/test_new_regression.py +++ b/tests/test_new_regression.py @@ -32,6 +32,9 @@ def setup(self): else None self.resources = f.get_node("/Resources")[:] self.transactions = f.get_node("/Transactions")[:] + self.rsrc_qtys = { + x["ResourceId"]: x["Quantity"] for x in self.resources} + def teardown(self): if os.path.isfile(self.outf_): @@ -75,9 +78,7 @@ def test_xactions(self): xa = self.transactions rs = self.resources - rqtys = {x["ResourceId"]: x["Quantity"] for x in rs \ - if x["ResourceId"] in xa["ResourceId"]} - torxtrs = {i: [rqtys[x["ResourceId"]] \ + torxtrs = {i: [self.rsrc_qtys[x["ResourceId"]] \ for x in xa[xa["ReceiverId"] == i]] \ for i in self.rx_id} transfers = sorted(torxtrs.values()) @@ -92,3 +93,81 @@ def test_xactions(self): msg = "Testing that second reactor gets what it wants." np.testing.assert_almost_equal(exp, obs, decimal=2) + +class TestPhysorSources(TestRegression): + def __init__(self): + super(TestPhysorSources, self).__init__() + self.inf_ = "../input/physor/2_Sources_3_Reactors.xml" + + def setup(self): + super(TestPhysorSources, self).setup() + + # identify each reactor and supplier by id + tbl = self.agent_entry + rx_id = find_ids(":cycamore:BatchReactor", + tbl["Spec"], tbl["AgentId"]) + self.r1, self.r2, self.r3 = tuple(rx_id) + s_id = find_ids(":cycamore:Source", + tbl["Spec"], tbl["AgentId"]) + self.smox = self.transactions[0]["SenderId"] + s_id.remove(self.smox) + self.suox = s_id[0] + + def test_rxtr_deployment(self): + depl_time = {x["AgentId"]: x["EnterTime"] for x in self.agent_entry} + + assert_equal(depl_time[self.r1], 1) + assert_equal(depl_time[self.r2], 2) + assert_equal(depl_time[self.r3], 3) + + def test_rxtr1_xactions(self): + xa = self.transactions + + mox_exp = [0, 1, 1, 1, 0] + obs = np.zeros(5) + rows = xa[np.logical_and(xa["ReceiverId"] == self.r1, + xa["SenderId"] == self.smox)] + obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] + np.testing.assert_almost_equal(mox_exp, obs) + + uox_exp = [0, 0, 0, 0, 1] + obs = np.zeros(5) + rows = xa[np.logical_and(xa["ReceiverId"] == self.r1, + xa["SenderId"] == self.suox)] + obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] + np.testing.assert_almost_equal(uox_exp, obs) + + def test_rxtr2_xactions(self): + xa = self.transactions + + mox_exp = [0, 0, 1, 1, 1] + obs = np.zeros(5) + rows = xa[np.logical_and(xa["ReceiverId"] == self.r2, + xa["SenderId"] == self.smox)] + obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] + np.testing.assert_almost_equal(mox_exp, obs) + + uox_exp = [0, 0, 0, 0, 0] + obs = np.zeros(5) + rows = xa[np.logical_and(xa["ReceiverId"] == self.r2, + xa["SenderId"] == self.suox)] + obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] + np.testing.assert_almost_equal(uox_exp, obs) + + def test_rxtr3_xactions(self): + xa = self.transactions + + mox_exp = [0, 0, 0, 0.5, 1] + obs = np.zeros(5) + rows = xa[np.logical_and(xa["ReceiverId"] == self.r3, + xa["SenderId"] == self.smox)] + obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] + np.testing.assert_almost_equal(mox_exp, obs) + + uox_exp = [0, 0, 0, 0.5, 0] + obs = np.zeros(5) + rows = xa[np.logical_and(xa["ReceiverId"] == self.r3, + xa["SenderId"] == self.suox)] + obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] + np.testing.assert_almost_equal(uox_exp, obs) + From f5277125c66396109a05cb272c27ad7b9132d178 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 5 Jan 2015 15:17:23 -0600 Subject: [PATCH 009/314] added docs to physor tests --- tests/test_new_regression.py | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/tests/test_new_regression.py b/tests/test_new_regression.py index 828a1a405f..abcf5769a5 100644 --- a/tests/test_new_regression.py +++ b/tests/test_new_regression.py @@ -10,9 +10,15 @@ from cyclus_tools import run_cyclus class TestRegression(object): + """A base class for all regression tests. A derived class is required for + each new input file to be tested. Each derived class *must* declare an `inf` + member in their `__ini__` function that points to the input file to be + tested, e.g., `self.inf_ = ./path/to/my/input_file.xml. See below for + examples. + """ def __init__(self): self.outf_ = str(uuid.uuid4()) + ".h5" - self.inf_ = None + self.inf = None def __del__(self): if os.path.isfile(self.outf_): @@ -20,10 +26,10 @@ def __del__(self): os.remove(self.outf_) def setup(self): - if not self.inf_: - raise TypeError(("self.inf_ must be set in derived classes " + if not self.inf: + raise TypeError(("self.inf must be set in derived classes " "to run regression tests.")) - run_cyclus("cyclus", os.getcwd(), self.inf_, self.outf_) + run_cyclus("cyclus", os.getcwd(), self.inf, self.outf_) with tables.open_file(self.outf_, mode="r") as f: # Get specific tables and columns @@ -42,9 +48,13 @@ def teardown(self): os.remove(self.outf_) class TestPhysorEnrichment(TestRegression): + """This class tests the 1_Enrichment_2_Reactor.xml file related to the + Cyclus Physor 2014 publication. The number of key facilities, the enrichment + values, and the transactions to each reactor are tested. + """ def __init__(self): super(TestPhysorEnrichment, self).__init__() - self.inf_ = "../input/physor/1_Enrichment_2_Reactor.xml" + self.inf = "../input/physor/1_Enrichment_2_Reactor.xml" def setup(self): super(TestPhysorEnrichment, self).setup() @@ -63,12 +73,16 @@ def test_deploy(self): def test_swu(self): enr = self.enrichments + # this can be updated if/when we can call into the cyclus::toolkit's + # enrichment module from python exp = [6.9, 10, 4.14, 6.9] obs = [np.sum(enr["SWU"][enr["Time"] == t]) for t in range(4)] np.testing.assert_almost_equal(exp, obs, decimal=2) def test_nu(self): enr = self.enrichments + # this can be updated if/when we can call into the cyclus::toolkit's + # enrichment module from python exp = [13.03, 16.54, 7.83, 13.03] obs = [np.sum(enr["Natural_Uranium"][enr["Time"] == t]) \ for t in range(4)] @@ -83,6 +97,8 @@ def test_xactions(self): for i in self.rx_id} transfers = sorted(torxtrs.values()) + # this can be updated if/when we can call into the cyclus::toolkit's + # enrichment module from python exp = [1, 0.8, 0.2, 1] obs = transfers[0] msg = "Testing that first reactor gets less than it wants." @@ -93,11 +109,14 @@ def test_xactions(self): msg = "Testing that second reactor gets what it wants." np.testing.assert_almost_equal(exp, obs, decimal=2) - class TestPhysorSources(TestRegression): + """This class tests the 2_Sources_3_Reactor.xml file related to the Cyclus + Physor 2014 publication. Reactor deployment and transactions between + suppliers and reactors are tested. + """ def __init__(self): super(TestPhysorSources, self).__init__() - self.inf_ = "../input/physor/2_Sources_3_Reactors.xml" + self.inf = "../input/physor/2_Sources_3_Reactors.xml" def setup(self): super(TestPhysorSources, self).setup() From 6cd462ada61fb0a000674729664ee674cc7cf07f Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 5 Jan 2015 15:21:19 -0600 Subject: [PATCH 010/314] updated regression tests to be query-based. old regression tests have been moved to a separate file to be removed --- tests/test_new_regression.py | 192 ------------------------- tests/test_regression.py | 270 +++++++++++++++++++++++------------ tests/test_regression_old.py | 100 +++++++++++++ 3 files changed, 281 insertions(+), 281 deletions(-) delete mode 100644 tests/test_new_regression.py create mode 100644 tests/test_regression_old.py diff --git a/tests/test_new_regression.py b/tests/test_new_regression.py deleted file mode 100644 index abcf5769a5..0000000000 --- a/tests/test_new_regression.py +++ /dev/null @@ -1,192 +0,0 @@ -#! /usr/bin/env python - -from nose.tools import assert_equal, assert_true -import os -import tables -import numpy as np -import uuid -from tools import check_cmd -from helper import table_exist, find_ids -from cyclus_tools import run_cyclus - -class TestRegression(object): - """A base class for all regression tests. A derived class is required for - each new input file to be tested. Each derived class *must* declare an `inf` - member in their `__ini__` function that points to the input file to be - tested, e.g., `self.inf_ = ./path/to/my/input_file.xml. See below for - examples. - """ - def __init__(self): - self.outf_ = str(uuid.uuid4()) + ".h5" - self.inf = None - - def __del__(self): - if os.path.isfile(self.outf_): - print("removing {0}".format(self.outf_)) - os.remove(self.outf_) - - def setup(self): - if not self.inf: - raise TypeError(("self.inf must be set in derived classes " - "to run regression tests.")) - run_cyclus("cyclus", os.getcwd(), self.inf, self.outf_) - - with tables.open_file(self.outf_, mode="r") as f: - # Get specific tables and columns - self.agent_entry = f.get_node("/AgentEntry")[:] - self.agent_exit = f.get_node("/AgentExit")[:] if "/AgentExit" in f \ - else None - self.resources = f.get_node("/Resources")[:] - self.transactions = f.get_node("/Transactions")[:] - self.rsrc_qtys = { - x["ResourceId"]: x["Quantity"] for x in self.resources} - - - def teardown(self): - if os.path.isfile(self.outf_): - print("removing {0}".format(self.outf_)) - os.remove(self.outf_) - -class TestPhysorEnrichment(TestRegression): - """This class tests the 1_Enrichment_2_Reactor.xml file related to the - Cyclus Physor 2014 publication. The number of key facilities, the enrichment - values, and the transactions to each reactor are tested. - """ - def __init__(self): - super(TestPhysorEnrichment, self).__init__() - self.inf = "../input/physor/1_Enrichment_2_Reactor.xml" - - def setup(self): - super(TestPhysorEnrichment, self).setup() - tbl = self.agent_entry - self.rx_id = find_ids(":cycamore:BatchReactor", - tbl["Spec"], tbl["AgentId"]) - self.enr_id = find_ids(":cycamore:EnrichmentFacility", - tbl["Spec"], tbl["AgentId"]) - - with tables.open_file(self.outf_, mode="r") as f: - self.enrichments = f.get_node("/Enrichments")[:] - - def test_deploy(self): - assert_equal(len(self.rx_id), 2) - assert_equal(len(self.enr_id), 1) - - def test_swu(self): - enr = self.enrichments - # this can be updated if/when we can call into the cyclus::toolkit's - # enrichment module from python - exp = [6.9, 10, 4.14, 6.9] - obs = [np.sum(enr["SWU"][enr["Time"] == t]) for t in range(4)] - np.testing.assert_almost_equal(exp, obs, decimal=2) - - def test_nu(self): - enr = self.enrichments - # this can be updated if/when we can call into the cyclus::toolkit's - # enrichment module from python - exp = [13.03, 16.54, 7.83, 13.03] - obs = [np.sum(enr["Natural_Uranium"][enr["Time"] == t]) \ - for t in range(4)] - np.testing.assert_almost_equal(exp, obs, decimal=2) - - def test_xactions(self): - xa = self.transactions - rs = self.resources - - torxtrs = {i: [self.rsrc_qtys[x["ResourceId"]] \ - for x in xa[xa["ReceiverId"] == i]] \ - for i in self.rx_id} - transfers = sorted(torxtrs.values()) - - # this can be updated if/when we can call into the cyclus::toolkit's - # enrichment module from python - exp = [1, 0.8, 0.2, 1] - obs = transfers[0] - msg = "Testing that first reactor gets less than it wants." - np.testing.assert_almost_equal(exp, obs, decimal=2, err_msg=msg) - - exp = [1, 1, 1, 1] - obs = transfers[1] - msg = "Testing that second reactor gets what it wants." - np.testing.assert_almost_equal(exp, obs, decimal=2) - -class TestPhysorSources(TestRegression): - """This class tests the 2_Sources_3_Reactor.xml file related to the Cyclus - Physor 2014 publication. Reactor deployment and transactions between - suppliers and reactors are tested. - """ - def __init__(self): - super(TestPhysorSources, self).__init__() - self.inf = "../input/physor/2_Sources_3_Reactors.xml" - - def setup(self): - super(TestPhysorSources, self).setup() - - # identify each reactor and supplier by id - tbl = self.agent_entry - rx_id = find_ids(":cycamore:BatchReactor", - tbl["Spec"], tbl["AgentId"]) - self.r1, self.r2, self.r3 = tuple(rx_id) - s_id = find_ids(":cycamore:Source", - tbl["Spec"], tbl["AgentId"]) - self.smox = self.transactions[0]["SenderId"] - s_id.remove(self.smox) - self.suox = s_id[0] - - def test_rxtr_deployment(self): - depl_time = {x["AgentId"]: x["EnterTime"] for x in self.agent_entry} - - assert_equal(depl_time[self.r1], 1) - assert_equal(depl_time[self.r2], 2) - assert_equal(depl_time[self.r3], 3) - - def test_rxtr1_xactions(self): - xa = self.transactions - - mox_exp = [0, 1, 1, 1, 0] - obs = np.zeros(5) - rows = xa[np.logical_and(xa["ReceiverId"] == self.r1, - xa["SenderId"] == self.smox)] - obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - np.testing.assert_almost_equal(mox_exp, obs) - - uox_exp = [0, 0, 0, 0, 1] - obs = np.zeros(5) - rows = xa[np.logical_and(xa["ReceiverId"] == self.r1, - xa["SenderId"] == self.suox)] - obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - np.testing.assert_almost_equal(uox_exp, obs) - - def test_rxtr2_xactions(self): - xa = self.transactions - - mox_exp = [0, 0, 1, 1, 1] - obs = np.zeros(5) - rows = xa[np.logical_and(xa["ReceiverId"] == self.r2, - xa["SenderId"] == self.smox)] - obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - np.testing.assert_almost_equal(mox_exp, obs) - - uox_exp = [0, 0, 0, 0, 0] - obs = np.zeros(5) - rows = xa[np.logical_and(xa["ReceiverId"] == self.r2, - xa["SenderId"] == self.suox)] - obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - np.testing.assert_almost_equal(uox_exp, obs) - - def test_rxtr3_xactions(self): - xa = self.transactions - - mox_exp = [0, 0, 0, 0.5, 1] - obs = np.zeros(5) - rows = xa[np.logical_and(xa["ReceiverId"] == self.r3, - xa["SenderId"] == self.smox)] - obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - np.testing.assert_almost_equal(mox_exp, obs) - - uox_exp = [0, 0, 0, 0.5, 0] - obs = np.zeros(5) - rows = xa[np.logical_and(xa["ReceiverId"] == self.r3, - xa["SenderId"] == self.suox)] - obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - np.testing.assert_almost_equal(uox_exp, obs) - diff --git a/tests/test_regression.py b/tests/test_regression.py index 454990193d..abcf5769a5 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -1,100 +1,192 @@ #! /usr/bin/env python +from nose.tools import assert_equal, assert_true import os -import json -import hashlib -import urllib +import tables +import numpy as np import uuid -from nose.tools import assert_true -from nose import with_setup - -from cyclus_tools import run_cyclus, compare_determ, compare_nondeterm - -sim_files = {} -fetchdir = "fetch" - -def setup(): - global sim_files - if not os.path.isdir(fetchdir): - os.makedirs(fetchdir) - with open("reflist.json") as f: - refs = json.load(f) - cyclus_ref = refs[-1]["cyclus-ref"] - cycamore_ref = refs[-1]["cycamore-ref"] - refs = [r for r in refs - if r["cyclus-ref"] == cyclus_ref - and r["cycamore-ref"] == cycamore_ref] - base_url = "http://regtests.fuelcycle.org/" - for r in refs: - fpath = os.path.join(fetchdir, r["fname"]) - if not os.path.exists(fpath): - try: - urllib.urlretrieve(base_url+r["fname"], fpath) - except AttributeError: # try python 3.1+ api version - urllib.request.urlretrieve(base_url+r["fname"], fpath) - h = hashlib.sha1() - with open(fpath, "rb") as f: - h.update(f.read()) - if h.hexdigest() != r["sha1-checksum"]: - raise RuntimeError("They tooks our data!!! All our rackspace are belong to them.") - sim_files[r["input-file"]] = fpath +from tools import check_cmd +from helper import table_exist, find_ids +from cyclus_tools import run_cyclus class TestRegression(object): + """A base class for all regression tests. A derived class is required for + each new input file to be tested. Each derived class *must* declare an `inf` + member in their `__ini__` function that points to the input file to be + tested, e.g., `self.inf_ = ./path/to/my/input_file.xml. See below for + examples. + """ def __init__(self): - self.in_dir_ = "../input" - self.tmp_files_ = {} - for root, dirs, files in os.walk(self.in_dir_): - for f in files: - self.tmp_files_[f] = str(uuid.uuid4()) + ".h5" + self.outf_ = str(uuid.uuid4()) + ".h5" + self.inf = None def __del__(self): - for inf, outf in self.tmp_files_.items(): - if os.path.isfile(outf): - print("removing {0}".format(outf)) - os.remove(outf) - + if os.path.isfile(self.outf_): + print("removing {0}".format(self.outf_)) + os.remove(self.outf_) + + def setup(self): + if not self.inf: + raise TypeError(("self.inf must be set in derived classes " + "to run regression tests.")) + run_cyclus("cyclus", os.getcwd(), self.inf, self.outf_) + + with tables.open_file(self.outf_, mode="r") as f: + # Get specific tables and columns + self.agent_entry = f.get_node("/AgentEntry")[:] + self.agent_exit = f.get_node("/AgentExit")[:] if "/AgentExit" in f \ + else None + self.resources = f.get_node("/Resources")[:] + self.transactions = f.get_node("/Transactions")[:] + self.rsrc_qtys = { + x["ResourceId"]: x["Quantity"] for x in self.resources} + + def teardown(self): - for inf, outf in self.tmp_files_.items(): - if os.path.isfile(outf): - print("removing {0}".format(outf)) - os.remove(outf) - - def test_regression(self, check_deterministic=False): - """Test for all inputs in sim_files. Checks if reference and current cyclus - output is the same. - - Parameters - ---------- - check_deterministic : bool - If True, also test determinisitc equality of simulations + if os.path.isfile(self.outf_): + print("removing {0}".format(self.outf_)) + os.remove(self.outf_) + +class TestPhysorEnrichment(TestRegression): + """This class tests the 1_Enrichment_2_Reactor.xml file related to the + Cyclus Physor 2014 publication. The number of key facilities, the enrichment + values, and the transactions to each reactor are tested. + """ + def __init__(self): + super(TestPhysorEnrichment, self).__init__() + self.inf = "../input/physor/1_Enrichment_2_Reactor.xml" + + def setup(self): + super(TestPhysorEnrichment, self).setup() + tbl = self.agent_entry + self.rx_id = find_ids(":cycamore:BatchReactor", + tbl["Spec"], tbl["AgentId"]) + self.enr_id = find_ids(":cycamore:EnrichmentFacility", + tbl["Spec"], tbl["AgentId"]) + + with tables.open_file(self.outf_, mode="r") as f: + self.enrichments = f.get_node("/Enrichments")[:] + + def test_deploy(self): + assert_equal(len(self.rx_id), 2) + assert_equal(len(self.enr_id), 1) + + def test_swu(self): + enr = self.enrichments + # this can be updated if/when we can call into the cyclus::toolkit's + # enrichment module from python + exp = [6.9, 10, 4.14, 6.9] + obs = [np.sum(enr["SWU"][enr["Time"] == t]) for t in range(4)] + np.testing.assert_almost_equal(exp, obs, decimal=2) + + def test_nu(self): + enr = self.enrichments + # this can be updated if/when we can call into the cyclus::toolkit's + # enrichment module from python + exp = [13.03, 16.54, 7.83, 13.03] + obs = [np.sum(enr["Natural_Uranium"][enr["Time"] == t]) \ + for t in range(4)] + np.testing.assert_almost_equal(exp, obs, decimal=2) + + def test_xactions(self): + xa = self.transactions + rs = self.resources + + torxtrs = {i: [self.rsrc_qtys[x["ResourceId"]] \ + for x in xa[xa["ReceiverId"] == i]] \ + for i in self.rx_id} + transfers = sorted(torxtrs.values()) + + # this can be updated if/when we can call into the cyclus::toolkit's + # enrichment module from python + exp = [1, 0.8, 0.2, 1] + obs = transfers[0] + msg = "Testing that first reactor gets less than it wants." + np.testing.assert_almost_equal(exp, obs, decimal=2, err_msg=msg) + + exp = [1, 1, 1, 1] + obs = transfers[1] + msg = "Testing that second reactor gets what it wants." + np.testing.assert_almost_equal(exp, obs, decimal=2) + +class TestPhysorSources(TestRegression): + """This class tests the 2_Sources_3_Reactor.xml file related to the Cyclus + Physor 2014 publication. Reactor deployment and transactions between + suppliers and reactors are tested. + """ + def __init__(self): + super(TestPhysorSources, self).__init__() + self.inf = "../input/physor/2_Sources_3_Reactors.xml" + + def setup(self): + super(TestPhysorSources, self).setup() + + # identify each reactor and supplier by id + tbl = self.agent_entry + rx_id = find_ids(":cycamore:BatchReactor", + tbl["Spec"], tbl["AgentId"]) + self.r1, self.r2, self.r3 = tuple(rx_id) + s_id = find_ids(":cycamore:Source", + tbl["Spec"], tbl["AgentId"]) + self.smox = self.transactions[0]["SenderId"] + s_id.remove(self.smox) + self.suox = s_id[0] + + def test_rxtr_deployment(self): + depl_time = {x["AgentId"]: x["EnterTime"] for x in self.agent_entry} + + assert_equal(depl_time[self.r1], 1) + assert_equal(depl_time[self.r2], 2) + assert_equal(depl_time[self.r3], 3) + + def test_rxtr1_xactions(self): + xa = self.transactions + + mox_exp = [0, 1, 1, 1, 0] + obs = np.zeros(5) + rows = xa[np.logical_and(xa["ReceiverId"] == self.r1, + xa["SenderId"] == self.smox)] + obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] + np.testing.assert_almost_equal(mox_exp, obs) + + uox_exp = [0, 0, 0, 0, 1] + obs = np.zeros(5) + rows = xa[np.logical_and(xa["ReceiverId"] == self.r1, + xa["SenderId"] == self.suox)] + obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] + np.testing.assert_almost_equal(uox_exp, obs) + + def test_rxtr2_xactions(self): + xa = self.transactions + + mox_exp = [0, 0, 1, 1, 1] + obs = np.zeros(5) + rows = xa[np.logical_and(xa["ReceiverId"] == self.r2, + xa["SenderId"] == self.smox)] + obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] + np.testing.assert_almost_equal(mox_exp, obs) + + uox_exp = [0, 0, 0, 0, 0] + obs = np.zeros(5) + rows = xa[np.logical_and(xa["ReceiverId"] == self.r2, + xa["SenderId"] == self.suox)] + obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] + np.testing.assert_almost_equal(uox_exp, obs) + + def test_rxtr3_xactions(self): + xa = self.transactions + + mox_exp = [0, 0, 0, 0.5, 1] + obs = np.zeros(5) + rows = xa[np.logical_and(xa["ReceiverId"] == self.r3, + xa["SenderId"] == self.smox)] + obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] + np.testing.assert_almost_equal(mox_exp, obs) - WARNING: the tests require cyclus executable to be included in PATH - """ - for root, dirs, files in os.walk(self.in_dir_): - for f in files: - if not f.endswith('.xml'): - continue - tmp_file = self.tmp_files_[f] - run_cyclus("cyclus", os.getcwd(), os.path.join(root, f), - tmp_file) - - if os.path.isfile(tmp_file): - if f not in sim_files: - continue # nada to do, just making sure it runs - if check_deterministic: - determ = compare_determ(sim_files[f], tmp_file, - verbose=True) - assert_true(determ) - else: - nondeterm = compare_nondeterm(sim_files[f], tmp_file) - assert_true(nondeterm) - - if os.path.isfile(tmp_file): - print("removing {0}".format(tmp_file)) - os.remove(tmp_file) - - tmp_file = tmp_file.split('.')[0] + '.sqlite' - - if os.path.isfile(tmp_file): - print("removing {0}".format(tmp_file)) - os.remove(tmp_file) + uox_exp = [0, 0, 0, 0.5, 0] + obs = np.zeros(5) + rows = xa[np.logical_and(xa["ReceiverId"] == self.r3, + xa["SenderId"] == self.suox)] + obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] + np.testing.assert_almost_equal(uox_exp, obs) + diff --git a/tests/test_regression_old.py b/tests/test_regression_old.py new file mode 100644 index 0000000000..454990193d --- /dev/null +++ b/tests/test_regression_old.py @@ -0,0 +1,100 @@ +#! /usr/bin/env python + +import os +import json +import hashlib +import urllib +import uuid +from nose.tools import assert_true +from nose import with_setup + +from cyclus_tools import run_cyclus, compare_determ, compare_nondeterm + +sim_files = {} +fetchdir = "fetch" + +def setup(): + global sim_files + if not os.path.isdir(fetchdir): + os.makedirs(fetchdir) + with open("reflist.json") as f: + refs = json.load(f) + cyclus_ref = refs[-1]["cyclus-ref"] + cycamore_ref = refs[-1]["cycamore-ref"] + refs = [r for r in refs + if r["cyclus-ref"] == cyclus_ref + and r["cycamore-ref"] == cycamore_ref] + base_url = "http://regtests.fuelcycle.org/" + for r in refs: + fpath = os.path.join(fetchdir, r["fname"]) + if not os.path.exists(fpath): + try: + urllib.urlretrieve(base_url+r["fname"], fpath) + except AttributeError: # try python 3.1+ api version + urllib.request.urlretrieve(base_url+r["fname"], fpath) + h = hashlib.sha1() + with open(fpath, "rb") as f: + h.update(f.read()) + if h.hexdigest() != r["sha1-checksum"]: + raise RuntimeError("They tooks our data!!! All our rackspace are belong to them.") + sim_files[r["input-file"]] = fpath + +class TestRegression(object): + def __init__(self): + self.in_dir_ = "../input" + self.tmp_files_ = {} + for root, dirs, files in os.walk(self.in_dir_): + for f in files: + self.tmp_files_[f] = str(uuid.uuid4()) + ".h5" + + def __del__(self): + for inf, outf in self.tmp_files_.items(): + if os.path.isfile(outf): + print("removing {0}".format(outf)) + os.remove(outf) + + def teardown(self): + for inf, outf in self.tmp_files_.items(): + if os.path.isfile(outf): + print("removing {0}".format(outf)) + os.remove(outf) + + def test_regression(self, check_deterministic=False): + """Test for all inputs in sim_files. Checks if reference and current cyclus + output is the same. + + Parameters + ---------- + check_deterministic : bool + If True, also test determinisitc equality of simulations + + WARNING: the tests require cyclus executable to be included in PATH + """ + for root, dirs, files in os.walk(self.in_dir_): + for f in files: + if not f.endswith('.xml'): + continue + tmp_file = self.tmp_files_[f] + run_cyclus("cyclus", os.getcwd(), os.path.join(root, f), + tmp_file) + + if os.path.isfile(tmp_file): + if f not in sim_files: + continue # nada to do, just making sure it runs + if check_deterministic: + determ = compare_determ(sim_files[f], tmp_file, + verbose=True) + assert_true(determ) + else: + nondeterm = compare_nondeterm(sim_files[f], tmp_file) + assert_true(nondeterm) + + if os.path.isfile(tmp_file): + print("removing {0}".format(tmp_file)) + os.remove(tmp_file) + + tmp_file = tmp_file.split('.')[0] + '.sqlite' + + if os.path.isfile(tmp_file): + print("removing {0}".format(tmp_file)) + os.remove(tmp_file) From f5689be6627a07bd7bbdd42ea5be8e35a395c9cd Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 5 Jan 2015 15:33:38 -0600 Subject: [PATCH 011/314] framework for creating and managing reflists of regression dbs removed; all regression tests now based solely on the query-approach --- tests/analysis.py | 150 --------------------- tests/create_references.py | 17 --- tests/cyclus_tools.py | 130 ------------------ tests/helper.py | 59 ++++----- tests/ref.py | 211 ------------------------------ tests/reflist.json | 170 ------------------------ tests/test_cases.py | 6 - tests/test_dynamic_capacitated.py | 3 +- tests/test_growth.py | 3 +- tests/test_regression.py | 4 +- tests/test_regression_old.py | 100 -------------- tests/tools.py | 98 -------------- tests/visitors.py | 140 -------------------- 13 files changed, 28 insertions(+), 1063 deletions(-) delete mode 100644 tests/analysis.py delete mode 100755 tests/create_references.py delete mode 100644 tests/cyclus_tools.py delete mode 100644 tests/ref.py delete mode 100644 tests/reflist.json delete mode 100644 tests/test_cases.py delete mode 100644 tests/test_regression_old.py delete mode 100644 tests/tools.py delete mode 100644 tests/visitors.py diff --git a/tests/analysis.py b/tests/analysis.py deleted file mode 100644 index 5f29c319e6..0000000000 --- a/tests/analysis.py +++ /dev/null @@ -1,150 +0,0 @@ -from __future__ import print_function -from __future__ import division - -import subprocess -from multiprocessing import Pool, Manager, cpu_count -from collections import defaultdict -import argparse as ap -import time - -import test_regression as tst - -diff_tbl = """table is different""" -diff_col = """Column""" - -def collect(args): - """collects information on a determinisitic regression test run - """ - tbl_freq, col_freq = args - - rtn = subprocess.Popen( - ["python", "-c", - "import test_regression as t; " + - "t.setup(); obj = t.TestRegression();" + - "obj.test_regression(check_deterministic=True)"], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - out, err = rtn.communicate() - #print out, err - - for line in out.split("\n"): - line = line.strip() - if diff_tbl in line.strip(): - tbl_name = line.split()[0] - tbl_freq[tbl_name] = \ - tbl_freq[tbl_name] + 1 if tbl_name in tbl_freq else 1 - if diff_col in line.strip(): - col_name = line.split()[1] - col_freq.append((tbl_name, col_name)) - -def proxy_lst_to_dict(lst): - """converts the col_freq list into a dictionary for easier processing - """ - col_freq = defaultdict(lambda: defaultdict(int)) - for tbl, col in lst: - col_freq[tbl][col] += 1 - return col_freq - -def determ_analysis(niter=1000): - """ - Calls deterministic regression tests for a number of iterations and reports - findings of nondeterminism to a file. - - Parameters - ---------- - niter : int - The number of times to run regression tests - - fname : str - The output filename to report to - - Returns - ------- - tbl_freq, col_freq : 2-tuple of dicts - tbl_freq is a frequency map of nondeterministic tables - col_freq is a frequency map of nondeterminisitc columns, - per table - """ - m = Manager() - - tbl_freq = m.dict() - col_freq = m.list() - - # collect - nproc = cpu_count() - count = nproc if nproc == 1 else nproc - 1 - pool = Pool(count) - - print("Beginning iterations on " + str(nproc) + " processors.") - args = ((tbl_freq, col_freq) for i in range(niter)) - jobs = pool.map_async(collect, args) - while not jobs.ready(): - print('{0:.1%} of jobs left to start.'.format( - jobs._number_left / niter)) - time.sleep(5.0) - if not jobs.successful(): - raise ValueError("At least one job failed.") - pool.close() - pool.join() - print("Finished iterations.") - - # convert from proxy - col_freq = proxy_lst_to_dict(col_freq) - tbl_freq = {item[0]: item[1] for item in tbl_freq.items()} - - # normalize - for tbl, dic in col_freq.iteritems(): - for col, freq in dic.iteritems(): - dic[col] = "{0:.2f}".format(float(freq) / tbl_freq[tbl]) - for k, v in tbl_freq.iteritems(): - tbl_freq[k] = "{0:.2f}".format(float(v) / niter) - - return tbl_freq, col_freq - -def report(tbl_freq, col_freq, fname="report"): - """ - Prints the results of determ_analysis to a file - - Parameters - ---------- - tbl_freq : dict - the table frequency output from determ_analysis - - col_freq : dict - the column frequency output from determ_analysis - - fname : str - the output file name to print to - """ - lines = [] - lines.append("Table values are reported as percent nondeterministic" + - " of total runs.\n\n") - lines.append("Column values are reported as percent nondeterministic" + - " of all table nondeterminism occurrences.\n\n") - if len(tbl_freq) == 0: - lines.append("No nondeterminism found.") - for tbl, freq in tbl_freq.iteritems(): - lines.append(tbl + " " + freq + "\n") - for col, freq in col_freq[tbl].iteritems(): - lines.append(" " + col + " " + freq + "\n") - with open(fname, "w") as f: - f.writelines(lines) - - -def main(): - description = "A module for analyzing the (non)determinism of Cyclus output." - - parser = ap.ArgumentParser(description=description) - - niter = 'the number of regression test runs to perform' - parser.add_argument('-n', '--niterations', type=int, help=niter, - default=100) - - out = 'the file to write the report to' - parser.add_argument('--out', help=out, default='report') - - args = parser.parse_args() - tbl_freq, col_freq = determ_analysis(args.niterations) - report(tbl_freq, col_freq, args.out) - -if __name__ == "__main__": - main() diff --git a/tests/create_references.py b/tests/create_references.py deleted file mode 100755 index 5c27bea806..0000000000 --- a/tests/create_references.py +++ /dev/null @@ -1,17 +0,0 @@ -#! /usr/bin/env python - -import os - -from cyclus_tools import run_cyclus -from testcases import sim_files - -def main(): - """Creates reference databases. Assumes that cyclus is included into PATH. - """ - cwd = os.getcwd() - - # Run cyclus - run_cyclus("cyclus", cwd, sim_files) - -if __name__ == "__main__": - main() diff --git a/tests/cyclus_tools.py b/tests/cyclus_tools.py deleted file mode 100644 index 913d45535d..0000000000 --- a/tests/cyclus_tools.py +++ /dev/null @@ -1,130 +0,0 @@ -import os -from tools import check_cmd - -import numpy as np -import tables - -import visitors - -def run_cyclus(cyclus, cwd, in_path, out_path): - """Runs cyclus with various inputs and creates output databases - """ - holdsrtn = [1] # needed because nose does not send() to test generator - # make sure the output target directory exists - cmd = [cyclus, "-o", out_path, "--input-file", in_path] - check_cmd(cmd, cwd, holdsrtn) - -def compare_nondeterm(path1, path2): - """Compares two Cyclus HDF5 databases assuming non-deterministic AgentIDs - and TransactionIDs. - - Returns - ------- - rtn : bool - True if both databases are the same, taking into account - nondeterministic id assignments. - """ - v1 = visitors.HDF5RegressionVisitor(path1) - v2 = visitors.HDF5RegressionVisitor(path2) - return v1.walk() == v2.walk() - -def compare_determ(path1, path2, verbose=True): - """Compares two Cyclus HDF5 databases assuming deterministic AgentIDs and - TransactionIDs - - Returns - ------- - rtn : bool - True if both databases are identical other than their SimIDs - """ - dbs_same = True - db_one = tables.open_file(path1, mode = "r") - db_two = tables.open_file(path2, mode = "r") - path_one = [] - path_two = [] - - for node in db_one.walk_nodes(classname = "Table"): - path_one.append(node._v_pathname) - - for node in db_two.walk_nodes(classname = "Table"): - path_two.append(node._v_pathname) - - # Check if databases contain the same tables - if not np.all(path_one == path_two): - if verbose: - print("The number or names of tables in databases are not the same.") - print(path_one) - print(path_two) - # Close databases - db_one.close() - db_two.close() - dbs_same = False - return dbs_same - - paths = path_one - - for path in paths: - data_one = db_one.get_node(path)[:] - data_two = db_two.get_node(path)[:] - names = [] - - for name in data_one.dtype.names: - if name != "SimID": - names.append(name) - - data_one = data_one[names] - data_two = data_two[names] - - if np.all(data_one == data_two): - continue - - dbs_same = False - if verbose: - msg = "" - msg += path.replace("/", "") - msg += " table is different in the databases.\n" - msg += determ_err_msg(names, data_one, data_two) - print(msg) - - # Close databases - db_one.close() - db_two.close() - return dbs_same - -def determ_err_msg(names, data_one, data_two): - """Returns a string describing the deterministic difference between two - databases. - """ - msg = "" - # Investigation of the differences - # check if the lengths are different - if len(data_one) != len(data_two): - msg += "Length mismatch: " + str(len(data_one)) + ", " + str(len(data_two)) - else: - for name in names: - column_one = data_one[name] - column_two = data_two[name] - # check if data types are the same - if column_one.dtype != column_two.dtype: - msg += "Datatypes in column " + name +" are different." - msg += str(column_one.dtype) - msg += str(column_two.dtype) - elif not np.all(column_one == column_two): - msg += "Column " + name - diff = np.equal(column_one, column_two) - # find indices and elements for numerical values - indices = np.where(diff==False) - # check if whole table is different - if len(indices) == len(column_one): - msg += " is completely different" - else: - # provide mismatch percentage - mismatch = 100*float(len(indices))/len(column_one) - msg += " has a mismatch of" - msg += " {0:.2f}".format(mismatch) + "% \n" - msg += "Indices of different objects are:\n" - msg += str(indices[0]) + "\n" - msg += "The different elements on these indices: \n" - msg += str(column_one[indices]) + "\n" - msg += str(column_two[indices]) + "\n" - return msg diff --git a/tests/helper.py b/tests/helper.py index af5d9ebd61..a4fd6def29 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -1,9 +1,11 @@ """A set of tools for use in integration tests.""" import os from hashlib import sha1 - +import subprocess import numpy as np import tables +import tempfile +from nose.tools import assert_equal def hasher(x): return int(sha1(x.encode()).hexdigest(), 16) @@ -49,38 +51,27 @@ def exit_times(agent_id, exit_table): return exit_times -def create_sim_input(ref_input, k_factor_in, k_factor_out): - """Creates xml input file from a reference xml input file. - - Changes k_factor_in and k_factor_out in a simulation input - files for KFacility. - - Args: - ref_input: A reference xml input file with k_factors. - k_factor_in: A new k_factor for requests. - k_factor_out: A new conversion factor for offers. - - Returns: - A path to the created file. It is created in the same - directory as the reference input file. +def run_cyclus(cyclus, cwd, in_path, out_path): + """Runs cyclus with various inputs and creates output databases """ - # File to be created - fw_path = ref_input.split(".xml")[0] + "_" + str(k_factor_in) + \ - "_" + str(k_factor_out) + ".xml" - fw = open(fw_path, "w") - fr = open(ref_input, "r") - for f in fr: - if f.count("k_factor_in"): - f = f.split("<")[0] + "" + str(k_factor_in) + \ - "\n" - elif f.count("k_factor_out"): - f = f.split("<")[0] + "" + str(k_factor_out) + \ - "\n" + holdsrtn = [1] # needed because nose does not send() to test generator + # make sure the output target directory exists + cmd = [cyclus, "-o", out_path, "--input-file", in_path] + check_cmd(cmd, cwd, holdsrtn) - fw.write(f) - - # Closing open files - fr.close() - fw.close() - - return fw_path +def check_cmd(args, cwd, holdsrtn): + """Runs a command in a subprocess and verifies that it executed properly. + """ + if not isinstance(args, basestring): + args = " ".join(args) + print("TESTING: running command in {0}:\n\n{1}\n".format(cwd, args)) + env = dict(os.environ) + env['_'] = subprocess.check_output(['which', 'cyclus'], cwd=cwd).strip() + f = tempfile.NamedTemporaryFile() + rtn = subprocess.call(args, shell=True, cwd=cwd, stdout=f, stderr=f, env=env) + if rtn != 0: + f.seek(0) + print("STDOUT + STDERR:\n\n" + f.read().decode()) + f.close() + holdsrtn[0] = rtn + assert_equal(rtn, 0) diff --git a/tests/ref.py b/tests/ref.py deleted file mode 100644 index 12c2440b7d..0000000000 --- a/tests/ref.py +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/python - -from __future__ import print_function -import hashlib -import subprocess as sp -import argparse -import json -import os.path -import uuid -import multiprocessing -import shutil -import importlib -import sys -import pyrax -pyrax.set_setting("identity_type", "rackspace") - -def gen_main(args): - # create sandbox dir - sandbox_path = '/tmp/refgen-' + str(uuid.uuid4()) - install_path = os.path.join(sandbox_path, 'install') - os.makedirs(install_path) - - # fetch and build cyclus - cyclus_path = os.path.join(sandbox_path, 'cyclus') - build_path = prepare_repo(args.cyclus_repo, cyclus_path) - tags = repo_tags(cyclus_path) - if args.cyclus_refspec == '': - args.cyclus_refspec = tags[-1] - checkout(cyclus_path, args.cyclus_refspec) - build_cyclus(build_path, install_path, prefix_path = args.cmake_prefix, boost = args.boost_root, coin = args.coin_root) - - # fetch and build cycamore - cycamore_path = os.path.join(sandbox_path, 'cycamore') - build_path = prepare_repo(args.cycamore_repo, cycamore_path) - tags = repo_tags(cycamore_path) - if args.cycamore_refspec == '': - args.cycamore_refspec = tags[-1] - checkout(cycamore_path, args.cycamore_refspec) - build_cycamore(build_path, install_path, prefix_path = args.cmake_prefix, boost = args.boost_root, coin = args.coin_root) - - # run cyclus simulations - sys.path.insert(0, os.path.join(cycamore_path, "tests")) - mod = importlib.import_module("test_cases") - for infile in mod.sim_files: - run_cyclus(install_path, infile, args.cyclus_refspec, args.cycamore_refspec) - - # cleanup - shutil.rmtree(sandbox_path) - -def prepare_repo(url, dst_path): - """ Clones a repo, creates a build dir. - """ - sp.check_call(['git', 'clone', url, dst_path]) - build_path = os.path.join(dst_path, "build") - os.makedirs(build_path) - return build_path - -def checkout(repo_path, commit): - """ Checks out the specified commit in a repo. - """ - cwd = os.getcwd() - os.chdir(repo_path) - sp.check_call(['git', 'checkout', commit]) - os.chdir(cwd) - -def repo_tags(repo_path): - """ Returns a sorted list of all tags in the repo (most recent last). - """ - #git tag | xargs -I@ git log --format=format:"%ai @%n" -1 @ | sort | awk '{print $4}' - cwd = os.getcwd() - os.chdir(repo_path) - git = sp.Popen(['git', 'tag'], stdout = sp.PIPE) - xargs = sp.Popen(['xargs', '-I@', 'git', 'log', '--format=format:"%ai @%n"', '-1', '@'], stdin = git.stdout, stdout = sp.PIPE) - sort = sp.Popen(['sort'], stdin = xargs.stdout, stdout = sp.PIPE) - awk = sp.Popen(['awk', '{print $4}'], stdin = sort.stdout, stdout = sp.PIPE) - (tagstext, _) = awk.communicate() - tags = tagstext.decode().split('\n')[1:-1] - os.chdir(cwd) - return tags - -def build_cyclus(build_path, install_path, prefix_path = '', boost = '', coin = ''): - cmd = ['cmake', '..', '-DCMAKE_INSTALL_PREFIX=' + os.path.abspath(install_path)] - if prefix_path != '': - cmd.append('-DCMAKE_PREFIX_PATH=' + os.path.abspath(prefix_path)) - if boost != '': - cmd.append('-DBOOST_ROOT=' + os.path.abspath(boost)) - if coin != '': - cmd.append('-DCOIN_ROOT_DIR=' + os.path.abspath(coin)) - cwd = os.getcwd() - os.chdir(build_path) - - sp.check_call(cmd) - sp.check_call(['make', '-j', str(multiprocessing.cpu_count())]) - sp.check_call(['make', 'install']) - os.chdir(cwd) - -def build_cycamore(build_path, install_path, prefix_path = '', boost = '', coin = ''): - cmd = ['cmake', '..', '-DCMAKE_INSTALL_PREFIX=' + os.path.abspath(install_path), '-DCYCLUS_ROOT_DIR=' + install_path] - if prefix_path != '': - cmd.append('-DCMAKE_PREFIX_PATH=' + os.path.abspath(prefix_path)) - if boost != '': - cmd.append('-DBOOST_ROOT=' + os.path.abspath(boost)) - if coin != '': - cmd.append('-DCOIN_ROOT_DIR=' + os.path.abspath(coin)) - cwd = os.getcwd() - os.chdir(build_path) - - sp.check_call(cmd) - sp.check_call(['make', '-j', str(multiprocessing.cpu_count())]) - sp.check_call(['make', 'install']) - os.chdir(cwd) - -def run_cyclus(install_path, input_file, cyclus_ref, cycamore_ref): - out_file = encode_dbname(cyclus_ref, cycamore_ref, input_file) - cyclus = os.path.join(install_path, 'bin', 'cyclus') - sp.check_call([cyclus, '-o', out_file, input_file]) - -def encode_dbname(cyclus_ref, cycamore_ref, input_file): - in_name, _ = os.path.splitext(os.path.basename(input_file)) - return cyclus_ref + '_' + cycamore_ref + '_' + in_name + '.h5' - -def decode_dbname(fname): - base, _ = os.path.splitext(fname) - parts = base.split('_') - cyclus_ref = parts[0] - cycamore_ref = parts[1] - infile = '_'.join(parts[2:]) + '.xml' - return (cyclus_ref, cycamore_ref, infile) - -def add_main(args): - # retrieve existing reflist - reflist = [] - if os.path.exists(args.reflist): - with open(args.reflist) as f: - data = f.read() - reflist = json.loads(data) - - # add new ref dbs and hashes to reflist - for refname in args.ref_dbs: - if refname in [entry['fname'] for entry in reflist]: - print(refname + ' is already in reflist \'' + args.reflist + '\'') - - with open(refname, 'rb') as f: - data = f.read() - h = hashlib.sha1() - h.update(data) - (cyclus_ref, cycamore_ref, infile) = decode_dbname(refname) - reflist.append({ - 'fname': refname, - 'sha1-checksum': h.hexdigest(), - 'cyclus-ref': cyclus_ref, - 'cycamore-ref': cycamore_ref, - 'input-file': infile - }) - - push_rackspace(refname, args.rs_cred) - - # update reflist - data = json.dumps(reflist, indent=4) - with open(args.reflist, 'w') as f: - f.write(data) - -def push_rackspace(fname, cred_file='rs.cred'): - creds_file = os.path.expanduser(cred_file) - pyrax.set_credential_file(cred_file) - cf = pyrax.cloudfiles - with open(fname, 'rb') as f: - fdata = f.read() - obj = cf.store_object("cyclus", fname, fdata) - -def fetch_refdbs(cyclus_ref, cycamore_ref, dst_path = '.'): - cwd = os.getcwd() - os.chdir(dst_path) - os.chdir(cwd) - -if __name__ == '__main__': - desc = 'Generates cyclus reference databases for regression testing' - p = argparse.ArgumentParser(description=desc) - subs = p.add_subparsers(help='sub-command help') - - # gen subcommand - sub_gen = subs.add_parser('gen', help='create a new reference db set') - help = 'force generate new ref-db rather than fetch remotely' - sub_gen.add_argument('-f,--force', type=bool, help=help, default=False) - help = 'location of cycamore repo' - sub_gen.add_argument('--cyclus-repo', help=help, default='https://github.com/cyclus/cyclus.git') - help = 'location of cycamore repo' - sub_gen.add_argument('--cycamore-repo', help=help, default='https://github.com/cyclus/cycamore.git') - help = 'git refspec for cyclus commit to generate reference from. Blank defaults to the most recent tag.' - sub_gen.add_argument('--cyclus-refspec', help=help, default='') - help = 'git refspec for cycamore commit to generate reference from. Blank defaults to the most recent tag.' - sub_gen.add_argument('--cycamore-refspec', help=help, default='') - help = 'the relative path to the Coin-OR libraries directory' - sub_gen.add_argument('--coin-root', help=help, default = '') - help = 'the relative path to the Boost libraries directory' - sub_gen.add_argument('--boost-root', help=help, default = '') - help = 'the cmake prefix path for use with FIND_PACKAGE, ' - help += 'FIND_PATH, FIND_PROGRAM, or FIND_LIBRARY macros' - sub_gen.add_argument('--cmake-prefix', help=help, default = '') - sub_gen.set_defaults(func=gen_main) - - # add subcommand - sub_add = subs.add_parser('add', help='add a new reference db set to the project') - sub_add.add_argument('ref_dbs', metavar='FILE', nargs='+', help='list of reference db files') - sub_add.add_argument('--reflist', help='filename of reflist', default='./reflist.json') - sub_add.add_argument('--rs-cred', help='rackspace credentials file', default='rs.cred') - sub_add.set_defaults(func=add_main) - - args = p.parse_args() - args.func(args) - diff --git a/tests/reflist.json b/tests/reflist.json deleted file mode 100644 index f0620067f3..0000000000 --- a/tests/reflist.json +++ /dev/null @@ -1,170 +0,0 @@ -[ - { - "cyclus-ref": "fc5bbee", - "sha1-checksum": "451b951e378c2883c506568ff7763119e23281db", - "input-file": "1_Enrichment_2_Reactor.xml", - "fname": "fc5bbee_8b2d61c_1_Enrichment_2_Reactor.h5", - "cycamore-ref": "8b2d61c" - }, - { - "cyclus-ref": "fc5bbee", - "sha1-checksum": "e7028d6c70ff6606792d90045d0a3495590e46d9", - "input-file": "2_Sources_3_Reactors.xml", - "fname": "fc5bbee_8b2d61c_2_Sources_3_Reactors.h5", - "cycamore-ref": "8b2d61c" - }, - { - "cycamore-ref": "v0.4-rc1", - "sha1-checksum": "0060c462e82a5c23db7cf5f10b2b1a1e67462125", - "input-file": "1_Enrichment_2_Reactor.xml", - "fname": "v0.4-rc1_v0.4-rc1_1_Enrichment_2_Reactor.h5", - "cyclus-ref": "v0.4-rc1" - }, - { - "cycamore-ref": "v0.4-rc1", - "sha1-checksum": "be0d48a5bc229c4d46d8d72de63fa6da4f4097ae", - "input-file": "2_Sources_3_Reactors.xml", - "fname": "v0.4-rc1_v0.4-rc1_2_Sources_3_Reactors.h5", - "cyclus-ref": "v0.4-rc1" - }, - { - "cyclus-ref": "v0.4", - "sha1-checksum": "3249ab2b874e71aef722e292986a96263b96c6c5", - "input-file": "1_Enrichment_2_Reactor.xml", - "fname": "v0.4_v0.4_1_Enrichment_2_Reactor.h5", - "cycamore-ref": "v0.4" - }, - { - "cyclus-ref": "v0.4", - "sha1-checksum": "89b930987402f04c84831d8ec4e8b2e61e0116e8", - "input-file": "2_Sources_3_Reactors.xml", - "fname": "v0.4_v0.4_2_Sources_3_Reactors.h5", - "cycamore-ref": "v0.4" - }, - { - "cycamore-ref": "0.4.1", - "sha1-checksum": "5b747f39b8c8ddd5e26563f8090384eb290b8248", - "input-file": "1_Enrichment_2_Reactor.xml", - "fname": "0.4.1_0.4.1_1_Enrichment_2_Reactor.h5", - "cyclus-ref": "0.4.1" - }, - { - "cycamore-ref": "0.4.1", - "sha1-checksum": "1aa69d570a672ebff869c04de64e178c7bc4d488", - "input-file": "2_Sources_3_Reactors.xml", - "fname": "0.4.1_0.4.1_2_Sources_3_Reactors.h5", - "cyclus-ref": "0.4.1" - }, - { - "cyclus-ref": "0.4.2", - "sha1-checksum": "4e95d446a2dc167786845974119584804b3c3eca", - "input-file": "1_Enrichment_2_Reactor.xml", - "fname": "0.4.2_0.4.2_1_Enrichment_2_Reactor.h5", - "cycamore-ref": "0.4.2" - }, - { - "cyclus-ref": "0.4.2", - "sha1-checksum": "c64b84195f17f5ab68e3efc409044d35b3ce134d", - "input-file": "2_Sources_3_Reactors.xml", - "fname": "0.4.2_0.4.2_2_Sources_3_Reactors.h5", - "cycamore-ref": "0.4.2" - }, - { - "cycamore-ref": "0.4.3", - "sha1-checksum": "687c40669300671cc7e81cc6f8b3b0e467fc880c", - "input-file": "1_Enrichment_2_Reactor.xml", - "fname": "0.4.3_0.4.3_1_Enrichment_2_Reactor.h5", - "cyclus-ref": "0.4.3" - }, - { - "cycamore-ref": "0.4.3", - "sha1-checksum": "d7acf9f1ec5bd90059bb38640f3ea6d0d64126f9", - "input-file": "2_Sources_3_Reactors.xml", - "fname": "0.4.3_0.4.3_2_Sources_3_Reactors.h5", - "cyclus-ref": "0.4.3" - }, - { - "cyclus-ref": "0.4.4", - "sha1-checksum": "e0b9bae64c15d1b3de4204836228b35c06a82fe2", - "input-file": "1_Enrichment_2_Reactor.xml", - "fname": "0.4.4_0.4.4_1_Enrichment_2_Reactor.h5", - "cycamore-ref": "0.4.4" - }, - { - "cyclus-ref": "0.4.4", - "sha1-checksum": "c179b2297b923664906e77ea23045d4e1c442773", - "input-file": "2_Sources_3_Reactors.xml", - "fname": "0.4.4_0.4.4_2_Sources_3_Reactors.h5", - "cycamore-ref": "0.4.4" - }, - { - "cycamore-ref": "1.0", - "sha1-checksum": "1ff53f7af4fe9357ee724264b6b895cd6a5c955d", - "input-file": "1_Enrichment_2_Reactor.xml", - "fname": "1.0_1.0_1_Enrichment_2_Reactor.h5", - "cyclus-ref": "1.0" - }, - { - "cycamore-ref": "1.0", - "sha1-checksum": "41d798d76de4ce6277880c125b058c1bc9a7db94", - "input-file": "2_Sources_3_Reactors.xml", - "fname": "1.0_1.0_2_Sources_3_Reactors.h5", - "cyclus-ref": "1.0" - }, - { - "cyclus-ref": "1.0.0-rc4", - "sha1-checksum": "2df6acb1aeb8304fea6dbf91f6773dcee4b421e0", - "input-file": "1_Enrichment_2_Reactor.xml", - "fname": "1.0.0-rc4_1.0.0-rc4_1_Enrichment_2_Reactor.h5", - "cycamore-ref": "1.0.0-rc4" - }, - { - "cyclus-ref": "1.0.0-rc4", - "sha1-checksum": "9de63fb594eeef3da316e73ea3dd05035a476548", - "input-file": "2_Sources_3_Reactors.xml", - "fname": "1.0.0-rc4_1.0.0-rc4_2_Sources_3_Reactors.h5", - "cycamore-ref": "1.0.0-rc4" - }, - { - "cycamore-ref": "1.1.0", - "sha1-checksum": "ef73b03e4236f707d9b618ffbaa8f3acd715d37e", - "input-file": "1_Enrichment_2_Reactor.xml", - "fname": "1.1.0_1.1.0_1_Enrichment_2_Reactor.h5", - "cyclus-ref": "1.1.0" - }, - { - "cycamore-ref": "1.1.0", - "sha1-checksum": "5e27c9ad6ba2dd80de0060a986939619e2d5a490", - "input-file": "2_Sources_3_Reactors.xml", - "fname": "1.1.0_1.1.0_2_Sources_3_Reactors.h5", - "cyclus-ref": "1.1.0" - }, - { - "cyclus-ref": "v1.1.1", - "sha1-checksum": "2218597542aafd19e558580eee696f0faad99c63", - "input-file": "1_Enrichment_2_Reactor.xml", - "fname": "v1.1.1_v1.1.1_1_Enrichment_2_Reactor.h5", - "cycamore-ref": "v1.1.1" - }, - { - "cyclus-ref": "v1.1.1", - "sha1-checksum": "ec3bf30bad33ec6babc320458aac56910f0ff77a", - "input-file": "2_Sources_3_Reactors.xml", - "fname": "v1.1.1_v1.1.1_2_Sources_3_Reactors.h5", - "cycamore-ref": "v1.1.1" - }, - { - "cycamore-ref": "v1.2.0", - "sha1-checksum": "d6b317d8bb28197e33af8cdd6f497b7383c84539", - "input-file": "1_Enrichment_2_Reactor.xml", - "fname": "v1.2.0_v1.2.0_1_Enrichment_2_Reactor.h5", - "cyclus-ref": "v1.2.0" - }, - { - "cycamore-ref": "v1.2.0", - "sha1-checksum": "966d77cb9a62effd5888537a39abb20853c85b62", - "input-file": "2_Sources_3_Reactors.xml", - "fname": "v1.2.0_v1.2.0_2_Sources_3_Reactors.h5", - "cyclus-ref": "v1.2.0" - } -] \ No newline at end of file diff --git a/tests/test_cases.py b/tests/test_cases.py deleted file mode 100644 index 2829c1e4aa..0000000000 --- a/tests/test_cases.py +++ /dev/null @@ -1,6 +0,0 @@ - -#List of input files and reference databases -sim_files = [ - '../input/physor/1_Enrichment_2_Reactor.xml', - '../input/physor/2_Sources_3_Reactors.xml' - ] diff --git a/tests/test_dynamic_capacitated.py b/tests/test_dynamic_capacitated.py index ab3d180971..cd0c948240 100644 --- a/tests/test_dynamic_capacitated.py +++ b/tests/test_dynamic_capacitated.py @@ -5,8 +5,7 @@ import tables import numpy as np import uuid -from tools import check_cmd -from helper import table_exist, find_ids +from helper import check_cmd, table_exist, find_ids def test_dynamic_capacitated(): """Tests dynamic capacity restraints involving changes in the number of diff --git a/tests/test_growth.py b/tests/test_growth.py index 8b6c4e57b7..0fdbac2ffc 100644 --- a/tests/test_growth.py +++ b/tests/test_growth.py @@ -5,8 +5,7 @@ import tables import numpy as np import uuid -from tools import check_cmd -from helper import table_exist, find_ids +from helper import check_cmd, table_exist, find_ids def test_growth(): """Tests GrowthRegion, ManagerInst, and Source over a 4-time step diff --git a/tests/test_regression.py b/tests/test_regression.py index abcf5769a5..47487b4763 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -5,9 +5,7 @@ import tables import numpy as np import uuid -from tools import check_cmd -from helper import table_exist, find_ids -from cyclus_tools import run_cyclus +from helper import check_cmd, run_cyclus, table_exist, find_ids class TestRegression(object): """A base class for all regression tests. A derived class is required for diff --git a/tests/test_regression_old.py b/tests/test_regression_old.py deleted file mode 100644 index 454990193d..0000000000 --- a/tests/test_regression_old.py +++ /dev/null @@ -1,100 +0,0 @@ -#! /usr/bin/env python - -import os -import json -import hashlib -import urllib -import uuid -from nose.tools import assert_true -from nose import with_setup - -from cyclus_tools import run_cyclus, compare_determ, compare_nondeterm - -sim_files = {} -fetchdir = "fetch" - -def setup(): - global sim_files - if not os.path.isdir(fetchdir): - os.makedirs(fetchdir) - with open("reflist.json") as f: - refs = json.load(f) - cyclus_ref = refs[-1]["cyclus-ref"] - cycamore_ref = refs[-1]["cycamore-ref"] - refs = [r for r in refs - if r["cyclus-ref"] == cyclus_ref - and r["cycamore-ref"] == cycamore_ref] - base_url = "http://regtests.fuelcycle.org/" - for r in refs: - fpath = os.path.join(fetchdir, r["fname"]) - if not os.path.exists(fpath): - try: - urllib.urlretrieve(base_url+r["fname"], fpath) - except AttributeError: # try python 3.1+ api version - urllib.request.urlretrieve(base_url+r["fname"], fpath) - h = hashlib.sha1() - with open(fpath, "rb") as f: - h.update(f.read()) - if h.hexdigest() != r["sha1-checksum"]: - raise RuntimeError("They tooks our data!!! All our rackspace are belong to them.") - sim_files[r["input-file"]] = fpath - -class TestRegression(object): - def __init__(self): - self.in_dir_ = "../input" - self.tmp_files_ = {} - for root, dirs, files in os.walk(self.in_dir_): - for f in files: - self.tmp_files_[f] = str(uuid.uuid4()) + ".h5" - - def __del__(self): - for inf, outf in self.tmp_files_.items(): - if os.path.isfile(outf): - print("removing {0}".format(outf)) - os.remove(outf) - - def teardown(self): - for inf, outf in self.tmp_files_.items(): - if os.path.isfile(outf): - print("removing {0}".format(outf)) - os.remove(outf) - - def test_regression(self, check_deterministic=False): - """Test for all inputs in sim_files. Checks if reference and current cyclus - output is the same. - - Parameters - ---------- - check_deterministic : bool - If True, also test determinisitc equality of simulations - - WARNING: the tests require cyclus executable to be included in PATH - """ - for root, dirs, files in os.walk(self.in_dir_): - for f in files: - if not f.endswith('.xml'): - continue - tmp_file = self.tmp_files_[f] - run_cyclus("cyclus", os.getcwd(), os.path.join(root, f), - tmp_file) - - if os.path.isfile(tmp_file): - if f not in sim_files: - continue # nada to do, just making sure it runs - if check_deterministic: - determ = compare_determ(sim_files[f], tmp_file, - verbose=True) - assert_true(determ) - else: - nondeterm = compare_nondeterm(sim_files[f], tmp_file) - assert_true(nondeterm) - - if os.path.isfile(tmp_file): - print("removing {0}".format(tmp_file)) - os.remove(tmp_file) - - tmp_file = tmp_file.split('.')[0] + '.sqlite' - - if os.path.isfile(tmp_file): - print("removing {0}".format(tmp_file)) - os.remove(tmp_file) diff --git a/tests/tools.py b/tests/tools.py deleted file mode 100644 index f9b0abc778..0000000000 --- a/tests/tools.py +++ /dev/null @@ -1,98 +0,0 @@ -from __future__ import print_function - -import os -import re -import sys -import imp -import shutil -import unittest -import subprocess -import tempfile -from contextlib import contextmanager - -from nose.tools import assert_true, assert_equal -from nose.plugins.attrib import attr -from nose.plugins.skip import SkipTest - -if sys.version_info[0] >= 3: - basestring = str - -unit = attr('unit') -integration = attr('integration') - -def cleanfs(paths): - """Removes the paths from the file system.""" - for p in paths: - p = os.path.join(*p) - if os.path.isfile(p): - os.remove(p) - elif os.path.isdir(p): - shutil.rmtree(p) - -def check_cmd(args, cwd, holdsrtn): - """Runs a command in a subprocess and verifies that it executed properly. - """ - if not isinstance(args, basestring): - args = " ".join(args) - print("TESTING: running command in {0}:\n\n{1}\n".format(cwd, args)) - env = dict(os.environ) - env['_'] = subprocess.check_output(['which', 'cyclus'], cwd=cwd).strip() - f = tempfile.NamedTemporaryFile() - rtn = subprocess.call(args, shell=True, cwd=cwd, stdout=f, stderr=f, env=env) - if rtn != 0: - f.seek(0) - print("STDOUT + STDERR:\n\n" + f.read().decode()) - f.close() - holdsrtn[0] = rtn - assert_equal(rtn, 0) - -@contextmanager -def clean_import(name, paths=None): - """Imports and returns a module context manager and then removes - all modules which didn't originally exist when exiting the block. - Be sure to delete any references to the returned module prior to - exiting the context. - """ - sys.path = paths + sys.path - origmods = set(sys.modules.keys()) - mod = imp.load_module(name, *imp.find_module(name, paths)) - yield mod - sys.path = sys.path[len(paths):] - del mod - newmods = set(sys.modules.keys()) - origmods - for newmod in newmods: - del sys.modules[newmod] - -TESTNAME_RE = re.compile('(?:^|[\\b_\\.-])[Tt]est') - -def modtests(mod): - """Finds all of the tests in a module.""" - tests = [] - for name in dir(mod): - if TESTNAME_RE.match(name) is None: - continue - test = getattr(mod, name) - if test is unittest.TestCase: - continue - tests.append(test) - return tests - -def dirtests(d): - """Finds all of the test files in a directory.""" - files = os.listdir(d) - filenames = [] - for file in files: - if not file.endswith('.py'): - continue - if TESTNAME_RE.match(file) is None: - - continue - filenames.append(file[:-3]) - return filenames - -def skip_then_continue(msg=""): - """A simple function to yield such that a test is marked as skipped - and we may continue on our merry way. A message may be optionally passed - to this function. - """ - raise SkipTest(msg) diff --git a/tests/visitors.py b/tests/visitors.py deleted file mode 100644 index 255f3a5ec2..0000000000 --- a/tests/visitors.py +++ /dev/null @@ -1,140 +0,0 @@ -from __future__ import print_function - -import re -from collections import defaultdict - -import numpy as np -import tables - -_invar_table_names = {"agents": "AgentEntry", - "rsrcs": "Resources"} - -_agent_key = "AgentId" -_agent_schema = ["Kind", "Spec", "Prototype", "ParentId", "EnterTime"] - -_simulation_time_info_schema = ["InitialYear", "InitialMonth", - "Duration"] - -_xaction_schema = ["SenderId", "ReceiverId", "ResourceId", "Commodity", - "Time"] - -_rsrc_key = "ResourceId" -_rsrc_schema = ["Type", "TimeCreated", "Quantity", "Units"] - -_agent_id_names = ["ParentId", "SenderId", "ReceiverId"] -_rsrc_id_names = ["ResourceId"] - -class HDF5RegressionVisitor(object): - """ An HDF5RegressionVisitor visits a number of Cyclus HDF5 tables, - returning objects that can be equality-comparable with other visitors. - """ - - def __init__(self, db_path): - """Parameters - ---------- - db_path : str - The path to an HDF5 database - """ - self._db = tables.open_file(db_path, mode = "r") - self.agent_invariants = self._populate_agent_invariants() - self.rsrc_invariants = self._populate_rsrc_invariants() - - def __del__(self): - self._db.close() - - def _populate_agent_invariants(self): - invars = {} - table = self._db.get_node(self._db.root, - name=_invar_table_names["agents"], - classname="Table") - for row in table.iterrows(): - a_id = row["AgentId"] - p_id = row["ParentId"] - p_invar = None - # print(p_id, a_id) - if p_id != -1: - if p_id not in invars: - raise KeyError("Parent with id " + str(a_id) +\ - " not previously registered.") - else: - p_invar = invars[p_id] - newrow = [] - for i in _agent_schema: - if i in _agent_id_names: - newrow.append(p_invar) - elif isinstance(row[i], np.ndarray): - newrow.append(tuple(row[i])) - else: - newrow.append(row[i]) - invars[a_id] = tuple(newrow) - return invars - - def _populate_rsrc_invariants(self): - table = self._db.get_node(self._db.root, - name = _invar_table_names["rsrcs"], - classname = "Table") - d = {} - for row in table.iterrows(): - entry = [] - for item in _rsrc_schema: - if isinstance(row[item], np.ndarray): - entry.append(tuple(row[item])) - else: - entry.append(row[item]) - d[row[_rsrc_key]] = tuple(entry) - return d - - def _xaction_entry(self, row): - entry = [] - for item in _xaction_schema: - if item in _agent_id_names: - entry.append(self.agent_invariants[row[item]]) - elif item in _rsrc_id_names: - entry.append(self.rsrc_invariants[row[item]]) - else: - entry.append(row[item]) - return tuple(tuple(i) if isinstance(i, np.ndarray) else i for i in entry) - - def walk(self): - """Visits all tables, populating an equality-comparable object - """ - ret = set() - for table in self._db.walk_nodes(classname = "Table"): - tblname = re.sub('([A-Z]+)', r'\1', table._v_name).lower() - methname = 'visit_' + tblname - if hasattr(self, methname): - print("visiting ", tblname) - meth = getattr(self, methname) - obj = meth(table) - ret.add(obj) - return ret - - def visit_agententry(self, table): - d = {} - for row in table.iterrows(): - entry = [] - for i in _agent_schema: - if i in _agent_id_names: - entry.append(self.agent_invariants[row[_agent_key]]) - elif isinstance(row[i], np.ndarray): - entry.append(tuple(row[i])) - else: - entry.append(row[i]) - d[self.agent_invariants[row[_agent_key]]] = tuple(entry) - return tuple((k, d[k]) for k in sorted(d.keys())) - - def visit_info(self, table): - return tuple(row[i] for i in _simulation_time_info_schema - for row in table.iterrows()) - - def visit_transactions(self, table): - xactions = [] - tmin = table[0]["Time"] - tmax = table[-1]["Time"] - xactions = [] - for i in range(tmin, tmax + 1): - entry = set() - for row in table.where('Time ==' + str(i)): - entry.add(self._xaction_entry(row)) - xactions.append(frozenset(entry)) - return tuple(xactions) From 28f25e08ddd977a3500f71e841a1c48b0a70bb0d Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 5 Jan 2015 15:48:29 -0600 Subject: [PATCH 012/314] moved dynamic capacitated test into regression tests --- tests/test_dynamic_capacitated.py | 140 ------------------------------ tests/test_regression.py | 108 ++++++++++++++++++++++- 2 files changed, 107 insertions(+), 141 deletions(-) delete mode 100644 tests/test_dynamic_capacitated.py diff --git a/tests/test_dynamic_capacitated.py b/tests/test_dynamic_capacitated.py deleted file mode 100644 index cd0c948240..0000000000 --- a/tests/test_dynamic_capacitated.py +++ /dev/null @@ -1,140 +0,0 @@ -#! /usr/bin/env python - -from nose.tools import assert_equal, assert_true -import os -import tables -import numpy as np -import uuid -from helper import check_cmd, table_exist, find_ids - -def test_dynamic_capacitated(): - """Tests dynamic capacity restraints involving changes in the number of - source and sink facilities. - - A source facility is expected to offer a commodity of amount 1, - and a sink facility is expected to request for a commodity of amount 1. - Therefore, number of facilities correspond to the amounts of offers - and requests. - - At time step 1, 3 source facilities and 2 sink facilities are deployed, and - at time step 2, additional 2 sink facilities are deployed. After time - step 2, the older 2 sink facilities are decommissioned. - According to this deployment schedule, at time step 1, only 2 transactions - are expected, the number of sink facilities being the constraint; whereas, - at time step 2, only 3 transactions are expected, the number of source - facilities being the constraint. At time step 3, after decommissioning 2 - older sink facilities, the remaining number of sink facilities becomes - the constraint, resulting in the same transaction amount as in time step 1. - """ - # Cyclus simulation input for dynamic capacitated - sim_inputs = ["./input/dynamic_capacitated.xml"] - - for sim_input in sim_inputs: - holdsrtn = [1] # needed because nose does not send() to test generator - tmp_file = str(uuid.uuid4()) + ".h5" - cmd = ["cyclus", "-o", tmp_file, "--input-file", sim_input] - yield check_cmd, cmd, '.', holdsrtn - rtn = holdsrtn[0] - if rtn != 0: - return # don't execute further commands - - output = tables.open_file(tmp_file, mode = "r") - # Tables of interest - paths = ["/AgentEntry", "/Resources", "/Transactions", "/AgentExit"] - # Check if these tables exist - yield assert_true, table_exist(output, paths) - if not table_exist(output, paths): - output.close() - if os.path.isfile(tmp_file): - print("removing {0}".format(tmp_file)) - os.remove(tmp_file) - return # don't execute further commands - - # Get specific tables and columns - agent_entry = output.get_node("/AgentEntry")[:] - agent_exit = output.get_node("/AgentExit")[:] - resources = output.get_node("/Resources")[:] - transactions = output.get_node("/Transactions")[:] - - # Find agent ids of source and sink facilities - agent_ids = agent_entry["AgentId"] - agent_impl = agent_entry["Spec"] - depl_time = agent_entry["EnterTime"] - exit_time = agent_exit["ExitTime"] - exit_ids = agent_exit["AgentId"] - - source_id = find_ids(":agents:Source", agent_impl, agent_ids) - sink_id = find_ids(":agents:Sink", agent_impl, agent_ids) - - # Test for 3 sources and 4 sinks are deployed in the simulation - yield assert_equal, len(source_id), 3 - yield assert_equal, len(sink_id), 4 - - # Test that source facilities are all deployed at time step 1 - for s in source_id: - yield assert_equal, depl_time[np.where(agent_ids == s)], 1 - # Test that first 2 sink facilities are deployed at time step 1 - # and decommissioned at time step 2 - for i in [0, 1]: - yield assert_equal,\ - depl_time[np.where(agent_ids == sink_id[i])], 1 - yield assert_equal,\ - exit_time[np.where(exit_ids == sink_id[i])], 2 - # Test that second 2 sink facilities are deployed at time step 2 - # and decommissioned at time step 3 - for i in [2, 3]: - yield assert_equal,\ - depl_time[np.where(agent_ids == sink_id[i])], 2 - yield assert_equal,\ - exit_time[np.where(exit_ids == sink_id[i])], 3 - - # Check transactions - sender_ids = transactions["SenderId"] - receiver_ids = transactions["ReceiverId"] - trans_time = transactions["Time"] - trans_resource = transactions["ResourceId"] - # Track transacted resources - resource_ids = resources["ResourceId"] - quantities = resources["Quantity"] - - # Check that transactions are between sources and sinks only - for s in sender_ids: - yield assert_equal, len(np.where(source_id == s)[0]), 1 - - for r in receiver_ids: - yield assert_equal, len(np.where(sink_id == r)[0]), 1 - - # Total expected number of transactions - yield assert_equal, len(trans_time), 7 - # Check that at time step 1, there are 2 transactions - yield assert_equal, len(np.where(trans_time == 1)[0]), 2 - # Check that at time step 2, there are 3 transactions - yield assert_equal, len(np.where(trans_time == 2)[0]), 3 - # Check that at time step 3, there are 2 transactions - yield assert_equal, len(np.where(trans_time == 3)[0]), 2 - - # Check that at time step 1, there are 2 transactions with total - # amount of 2 - quantity = 0 - for t in np.where(trans_time == 1)[0]: - quantity += quantities[np.where(resource_ids == trans_resource[t])] - yield assert_equal, quantity, 2 - - # Check that at time step 2, there are 3 transactions with total - # amount of 3 - quantity = 0 - for t in np.where(trans_time == 2)[0]: - quantity += quantities[np.where(resource_ids == trans_resource[t])] - yield assert_equal, quantity, 3 - - # Check that at time step 3, there are 2 transactions with total - # amount of 2 - quantity = 0 - for t in np.where(trans_time == 3)[0]: - quantity += quantities[np.where(resource_ids == trans_resource[t])] - yield assert_equal, quantity, 2 - - output.close() - if os.path.isfile(tmp_file): - print("removing {0}".format(tmp_file)) - os.remove(tmp_file) diff --git a/tests/test_regression.py b/tests/test_regression.py index 47487b4763..96826c49a9 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -187,4 +187,110 @@ def test_rxtr3_xactions(self): xa["SenderId"] == self.suox)] obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] np.testing.assert_almost_equal(uox_exp, obs) - + +class TestDynamicCapacitated(TestRegression): + """Tests dynamic capacity restraints involving changes in the number of + source and sink facilities. + + A source facility is expected to offer a commodity of amount 1, + and a sink facility is expected to request for a commodity of amount 1. + Therefore, number of facilities correspond to the amounts of offers + and requests. + + At time step 1, 3 source facilities and 2 sink facilities are deployed, and + at time step 2, additional 2 sink facilities are deployed. After time + step 2, the older 2 sink facilities are decommissioned. + According to this deployment schedule, at time step 1, only 2 transactions + are expected, the number of sink facilities being the constraint; whereas, + at time step 2, only 3 transactions are expected, the number of source + facilities being the constraint. At time step 3, after decommissioning 2 + older sink facilities, the remaining number of sink facilities becomes + the constraint, resulting in the same transaction amount as in time step 1. + """ + def __init__(self): + super(TestDynamicCapacitated, self).__init__() + self.inf = "./input/dynamic_capacitated.xml" + + def setup(self): + super(TestDynamicCapacitated, self).setup() + + # Find agent ids of source and sink facilities + self.agent_ids = self.agent_entry["AgentId"] + self.agent_impl = self.agent_entry["Spec"] + self.depl_time = self.agent_entry["EnterTime"] + self.exit_time = self.agent_exit["ExitTime"] + self.exit_ids = self.agent_exit["AgentId"] + self.source_id = find_ids(":agents:Source", self.agent_impl, self.agent_ids) + self.sink_id = find_ids(":agents:Sink", self.agent_impl, self.agent_ids) + + # Check transactions + self.sender_ids = self.transactions["SenderId"] + self.receiver_ids = self.transactions["ReceiverId"] + self.trans_time = self.transactions["Time"] + self.trans_resource = self.transactions["ResourceId"] + + # Track transacted resources + self.resource_ids = self.resources["ResourceId"] + self.quantities = self.resources["Quantity"] + + def test_source_deployment(self): + # test number of sources + assert_equal(len(self.source_id), 3) + # Test that source facilities are all deployed at time step 1 + for s in self.source_id: + assert_equal(self.depl_time[np.where(self.agent_ids == s)], 1) + + def test_sink_deployment(self): + # test number of sinks + assert_equal(len(self.sink_id), 4) + # Test that first 2 sink facilities are deployed at time step 1 + # and decommissioned at time step 2 + for i in [0, 1]: + assert_equal(self.depl_time[np.where(self.agent_ids == self.sink_id[i])], 1) + assert_equal(self.exit_time[np.where(self.exit_ids == self.sink_id[i])], 2) + # Test that second 2 sink facilities are deployed at time step 2 + # and decommissioned at time step 3 + for i in [2, 3]: + assert_equal(self.depl_time[np.where(self.agent_ids == self.sink_id[i])], 2) + assert_equal(self.exit_time[np.where(self.exit_ids == self.sink_id[i])], 3) + + def test_xaction_general(self): + # Check that transactions are between sources and sinks only + for s in self.sender_ids: + assert_equal(len(np.where(self.source_id == s)[0]), 1) + for r in self.receiver_ids: + assert_equal(len(np.where(self.sink_id == r)[0]), 1) + # Total expected number of transactions + assert_equal(len(self.trans_time), 7) + # Check that at time step 1, there are 2 transactions + assert_equal(len(np.where(self.trans_time == 1)[0]), 2) + # Check that at time step 2, there are 3 transactions + assert_equal(len(np.where(self.trans_time == 2)[0]), 3) + # Check that at time step 3, there are 2 transactions + assert_equal(len(np.where(self.trans_time == 3)[0]), 2) + + def test_xaction_specific(self): + # Check that at time step 1, there are 2 transactions with total + # amount of 2 + quantity = 0 + for t in np.where(self.trans_time == 1)[0]: + quantity += self.quantities[ + np.where(self.resource_ids == self.trans_resource[t])] + assert_equal(quantity, 2) + + # Check that at time step 2, there are 3 transactions with total + # amount of 3 + quantity = 0 + for t in np.where(self.trans_time == 2)[0]: + quantity += self.quantities[ + np.where(self.resource_ids == self.trans_resource[t])] + assert_equal(quantity, 3) + + # Check that at time step 3, there are 2 transactions with total + # amount of 2 + quantity = 0 + for t in np.where(self.trans_time == 3)[0]: + quantity += self.quantities[ + np.where(self.resource_ids == self.trans_resource[t])] + assert_equal(quantity, 2) + From 4e245050d5269c36dd6dc504d84b26c0f920da92 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 5 Jan 2015 15:51:03 -0600 Subject: [PATCH 013/314] moved growth test into regression tests --- tests/test_growth.py | 61 ---------------------------------------- tests/test_regression.py | 28 ++++++++++++++++++ 2 files changed, 28 insertions(+), 61 deletions(-) delete mode 100644 tests/test_growth.py diff --git a/tests/test_growth.py b/tests/test_growth.py deleted file mode 100644 index 0fdbac2ffc..0000000000 --- a/tests/test_growth.py +++ /dev/null @@ -1,61 +0,0 @@ -#! /usr/bin/env python - -from nose.tools import assert_equal, assert_true -import os -import tables -import numpy as np -import uuid -from helper import check_cmd, table_exist, find_ids - -def test_growth(): - """Tests GrowthRegion, ManagerInst, and Source over a 4-time step - simulation. - - A linear growth demand (y = x + 2) is provided to the growth region. Two - Sources are allowed in the ManagerInst, with capacities of 2 and 1.1, - respectively. At t=1, a 2-capacity Source is expected to be built, and at - t=2 and t=3, 1-capacity Sources are expected to be built. - """ - holdsrtn = [1] # needed because nose does not send() to test generator - sim_input = "./input/growth.xml" - tmp_file = str(uuid.uuid4()) + ".h5" - cmd = ["cyclus", "-o", tmp_file, "--input-file", sim_input] - yield check_cmd, cmd, '.', holdsrtn - rtn = holdsrtn[0] - if rtn != 0: - return # don't execute further commands - - output = tables.open_file(tmp_file, mode = "r") - # Tables of interest - paths = ["/AgentEntry",] - # Check if these tables exist - yield assert_true, table_exist(output, paths) - if not table_exist(output, paths): - output.close() - if os.path.isfile(tmp_file): - print("removing {0}".format(tmp_file)) - os.remove(tmp_file) - return # don't execute further commands - - # Get specific tables and columns - agent_entry = output.get_node("/AgentEntry")[:] - - # Find agent ids of source and sink facilities - agent_ids = agent_entry["AgentId"] - proto = agent_entry["Prototype"] - depl_time = agent_entry["EnterTime"] - - source1_id = find_ids("Source1", proto, agent_ids) - source2_id = find_ids("Source2", proto, agent_ids) - - assert_equal(len(source2_id), 1) - assert_equal(len(source1_id), 2) - - assert_equal(depl_time[np.where(agent_ids == source2_id[0])], 1) - assert_equal(depl_time[np.where(agent_ids == source1_id[0])], 2) - assert_equal(depl_time[np.where(agent_ids == source1_id[1])], 3) - - output.close() - if os.path.isfile(tmp_file): - print("removing {0}".format(tmp_file)) - os.remove(tmp_file) diff --git a/tests/test_regression.py b/tests/test_regression.py index 96826c49a9..6cd815ab8d 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -294,3 +294,31 @@ def test_xaction_specific(self): np.where(self.resource_ids == self.trans_resource[t])] assert_equal(quantity, 2) +class TestGrowth(TestRegression): + """Tests GrowthRegion, ManagerInst, and Source over a 4-time step + simulation. + + A linear growth demand (y = x + 2) is provided to the growth region. Two + Sources are allowed in the ManagerInst, with capacities of 2 and 1.1, + respectively. At t=1, a 2-capacity Source is expected to be built, and at + t=2 and t=3, 1-capacity Sources are expected to be built. + """ + def __init__(self): + super(TestGrowth, self).__init__() + self.inf = "./input/growth.xml" + + def test_deployment(self): + agent_ids = self.agent_entry["AgentId"] + proto = self.agent_entry["Prototype"] + depl_time = self.agent_entry["EnterTime"] + + source1_id = find_ids("Source1", proto, agent_ids) + source2_id = find_ids("Source2", proto, agent_ids) + + assert_equal(len(source2_id), 1) + assert_equal(len(source1_id), 2) + + assert_equal(depl_time[np.where(agent_ids == source2_id[0])], 1) + assert_equal(depl_time[np.where(agent_ids == source1_id[0])], 2) + assert_equal(depl_time[np.where(agent_ids == source1_id[1])], 3) + From 7975fb18ff67ba6d968cb089c0392b41b07a1a6b Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 5 Jan 2015 16:26:35 -0600 Subject: [PATCH 014/314] line length update for dc reg test --- tests/test_regression.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index 6cd815ab8d..908d574f0d 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -220,7 +220,8 @@ def setup(self): self.depl_time = self.agent_entry["EnterTime"] self.exit_time = self.agent_exit["ExitTime"] self.exit_ids = self.agent_exit["AgentId"] - self.source_id = find_ids(":agents:Source", self.agent_impl, self.agent_ids) + self.source_id = find_ids(":agents:Source", self.agent_impl, + self.agent_ids) self.sink_id = find_ids(":agents:Sink", self.agent_impl, self.agent_ids) # Check transactions @@ -246,13 +247,17 @@ def test_sink_deployment(self): # Test that first 2 sink facilities are deployed at time step 1 # and decommissioned at time step 2 for i in [0, 1]: - assert_equal(self.depl_time[np.where(self.agent_ids == self.sink_id[i])], 1) - assert_equal(self.exit_time[np.where(self.exit_ids == self.sink_id[i])], 2) + assert_equal( + self.depl_time[np.where(self.agent_ids == self.sink_id[i])], 1) + assert_equal( + self.exit_time[np.where(self.exit_ids == self.sink_id[i])], 2) # Test that second 2 sink facilities are deployed at time step 2 # and decommissioned at time step 3 for i in [2, 3]: - assert_equal(self.depl_time[np.where(self.agent_ids == self.sink_id[i])], 2) - assert_equal(self.exit_time[np.where(self.exit_ids == self.sink_id[i])], 3) + assert_equal( + self.depl_time[np.where(self.agent_ids == self.sink_id[i])], 2) + assert_equal( + self.exit_time[np.where(self.exit_ids == self.sink_id[i])], 3) def test_xaction_general(self): # Check that transactions are between sources and sinks only From dea3f52c4ac1cb3d91a0c3feeb8cf63d47ed0482 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 5 Jan 2015 21:14:55 -0600 Subject: [PATCH 015/314] tests now use unittest --- tests/test_regression.py | 47 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index 908d574f0d..7dcdf7298b 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -6,15 +6,17 @@ import numpy as np import uuid from helper import check_cmd, run_cyclus, table_exist, find_ids +from unittest import TestCase -class TestRegression(object): +class TestRegression(TestCase): """A base class for all regression tests. A derived class is required for each new input file to be tested. Each derived class *must* declare an `inf` - member in their `__ini__` function that points to the input file to be + member in their `__init__` function that points to the input file to be tested, e.g., `self.inf_ = ./path/to/my/input_file.xml. See below for examples. """ - def __init__(self): + def __init__(self, *args, **kwargs): + super(TestRegression, self).__init__(*args, **kwargs) self.outf_ = str(uuid.uuid4()) + ".h5" self.inf = None @@ -23,7 +25,7 @@ def __del__(self): print("removing {0}".format(self.outf_)) os.remove(self.outf_) - def setup(self): + def setUp(self): if not self.inf: raise TypeError(("self.inf must be set in derived classes " "to run regression tests.")) @@ -38,9 +40,8 @@ def setup(self): self.transactions = f.get_node("/Transactions")[:] self.rsrc_qtys = { x["ResourceId"]: x["Quantity"] for x in self.resources} - - - def teardown(self): + + def tearDown(self): if os.path.isfile(self.outf_): print("removing {0}".format(self.outf_)) os.remove(self.outf_) @@ -50,12 +51,12 @@ class TestPhysorEnrichment(TestRegression): Cyclus Physor 2014 publication. The number of key facilities, the enrichment values, and the transactions to each reactor are tested. """ - def __init__(self): - super(TestPhysorEnrichment, self).__init__() + def __init__(self, *args, **kwargs): + super(TestPhysorEnrichment, self).__init__(*args, **kwargs) self.inf = "../input/physor/1_Enrichment_2_Reactor.xml" - def setup(self): - super(TestPhysorEnrichment, self).setup() + def setUp(self): + super(TestPhysorEnrichment, self).setUp() tbl = self.agent_entry self.rx_id = find_ids(":cycamore:BatchReactor", tbl["Spec"], tbl["AgentId"]) @@ -64,7 +65,7 @@ def setup(self): with tables.open_file(self.outf_, mode="r") as f: self.enrichments = f.get_node("/Enrichments")[:] - + def test_deploy(self): assert_equal(len(self.rx_id), 2) assert_equal(len(self.enr_id), 1) @@ -112,12 +113,12 @@ class TestPhysorSources(TestRegression): Physor 2014 publication. Reactor deployment and transactions between suppliers and reactors are tested. """ - def __init__(self): - super(TestPhysorSources, self).__init__() + def __init__(self, *args, **kwargs): + super(TestPhysorSources, self).__init__(*args, **kwargs) self.inf = "../input/physor/2_Sources_3_Reactors.xml" - def setup(self): - super(TestPhysorSources, self).setup() + def setUp(self): + super(TestPhysorSources, self).setUp() # identify each reactor and supplier by id tbl = self.agent_entry @@ -207,13 +208,13 @@ class TestDynamicCapacitated(TestRegression): older sink facilities, the remaining number of sink facilities becomes the constraint, resulting in the same transaction amount as in time step 1. """ - def __init__(self): - super(TestDynamicCapacitated, self).__init__() + def __init__(self, *args, **kwargs): + super(TestDynamicCapacitated, self).__init__(*args, **kwargs) self.inf = "./input/dynamic_capacitated.xml" - def setup(self): - super(TestDynamicCapacitated, self).setup() - + def setUp(self): + super(TestDynamicCapacitated, self).setUp() + # Find agent ids of source and sink facilities self.agent_ids = self.agent_entry["AgentId"] self.agent_impl = self.agent_entry["Spec"] @@ -308,8 +309,8 @@ class TestGrowth(TestRegression): respectively. At t=1, a 2-capacity Source is expected to be built, and at t=2 and t=3, 1-capacity Sources are expected to be built. """ - def __init__(self): - super(TestGrowth, self).__init__() + def __init__(self, *args, **kwargs): + super(TestGrowth, self).__init__(*args, **kwargs) self.inf = "./input/growth.xml" def test_deployment(self): From eb523197b0fb796874583f7108bffed8c5af3962 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 5 Jan 2015 21:17:11 -0600 Subject: [PATCH 016/314] pep8 import groupings --- tests/helper.py | 4 ++-- tests/test_regression.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/helper.py b/tests/helper.py index a4fd6def29..c6188264fa 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -1,10 +1,10 @@ """A set of tools for use in integration tests.""" import os -from hashlib import sha1 +import tempfile import subprocess +from hashlib import sha1 import numpy as np import tables -import tempfile from nose.tools import assert_equal def hasher(x): diff --git a/tests/test_regression.py b/tests/test_regression.py index 7dcdf7298b..cd60f88bb9 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -2,11 +2,11 @@ from nose.tools import assert_equal, assert_true import os +from unittest import TestCase import tables import numpy as np import uuid from helper import check_cmd, run_cyclus, table_exist, find_ids -from unittest import TestCase class TestRegression(TestCase): """A base class for all regression tests. A derived class is required for From 24b6d4bd4191f9b2e63d2d0e6543ae2b85794097 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 5 Jan 2015 21:19:24 -0600 Subject: [PATCH 017/314] helper.py comments updated --- tests/helper.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/helper.py b/tests/helper.py index c6188264fa..112235dccb 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -2,11 +2,17 @@ import os import tempfile import subprocess +import sys from hashlib import sha1 import numpy as np import tables from nose.tools import assert_equal +if sys.version_info[0] > 3: + str_types = (bytes, str) +else: + str_types = (str, unicode) + def hasher(x): return int(sha1(x.encode()).hexdigest(), 16) @@ -62,16 +68,15 @@ def run_cyclus(cyclus, cwd, in_path, out_path): def check_cmd(args, cwd, holdsrtn): """Runs a command in a subprocess and verifies that it executed properly. """ - if not isinstance(args, basestring): + if not isinstance(args, str_types): args = " ".join(args) print("TESTING: running command in {0}:\n\n{1}\n".format(cwd, args)) env = dict(os.environ) env['_'] = subprocess.check_output(['which', 'cyclus'], cwd=cwd).strip() - f = tempfile.NamedTemporaryFile() - rtn = subprocess.call(args, shell=True, cwd=cwd, stdout=f, stderr=f, env=env) - if rtn != 0: - f.seek(0) - print("STDOUT + STDERR:\n\n" + f.read().decode()) - f.close() + with tempfile.NamedTemporaryFile() as f: + rtn = subprocess.call(args, shell=True, cwd=cwd, stdout=f, stderr=f, env=env) + if rtn != 0: + f.seek(0) + print("STDOUT + STDERR:\n\n" + f.read().decode()) holdsrtn[0] = rtn assert_equal(rtn, 0) From 17481b7e3045fd246e9272ebe5d0a8566db7e582 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 5 Jan 2015 21:21:06 -0600 Subject: [PATCH 018/314] importing np.testing structs --- tests/test_regression.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index cd60f88bb9..6464ac3eae 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -5,6 +5,7 @@ from unittest import TestCase import tables import numpy as np +from numpy.testing import assert_almost_equal import uuid from helper import check_cmd, run_cyclus, table_exist, find_ids @@ -76,7 +77,7 @@ def test_swu(self): # enrichment module from python exp = [6.9, 10, 4.14, 6.9] obs = [np.sum(enr["SWU"][enr["Time"] == t]) for t in range(4)] - np.testing.assert_almost_equal(exp, obs, decimal=2) + assert_almost_equal(exp, obs, decimal=2) def test_nu(self): enr = self.enrichments @@ -85,7 +86,7 @@ def test_nu(self): exp = [13.03, 16.54, 7.83, 13.03] obs = [np.sum(enr["Natural_Uranium"][enr["Time"] == t]) \ for t in range(4)] - np.testing.assert_almost_equal(exp, obs, decimal=2) + assert_almost_equal(exp, obs, decimal=2) def test_xactions(self): xa = self.transactions @@ -101,12 +102,12 @@ def test_xactions(self): exp = [1, 0.8, 0.2, 1] obs = transfers[0] msg = "Testing that first reactor gets less than it wants." - np.testing.assert_almost_equal(exp, obs, decimal=2, err_msg=msg) + assert_almost_equal(exp, obs, decimal=2, err_msg=msg) exp = [1, 1, 1, 1] obs = transfers[1] msg = "Testing that second reactor gets what it wants." - np.testing.assert_almost_equal(exp, obs, decimal=2) + assert_almost_equal(exp, obs, decimal=2) class TestPhysorSources(TestRegression): """This class tests the 2_Sources_3_Reactor.xml file related to the Cyclus @@ -146,14 +147,14 @@ def test_rxtr1_xactions(self): rows = xa[np.logical_and(xa["ReceiverId"] == self.r1, xa["SenderId"] == self.smox)] obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - np.testing.assert_almost_equal(mox_exp, obs) + assert_almost_equal(mox_exp, obs) uox_exp = [0, 0, 0, 0, 1] obs = np.zeros(5) rows = xa[np.logical_and(xa["ReceiverId"] == self.r1, xa["SenderId"] == self.suox)] obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - np.testing.assert_almost_equal(uox_exp, obs) + assert_almost_equal(uox_exp, obs) def test_rxtr2_xactions(self): xa = self.transactions @@ -163,14 +164,14 @@ def test_rxtr2_xactions(self): rows = xa[np.logical_and(xa["ReceiverId"] == self.r2, xa["SenderId"] == self.smox)] obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - np.testing.assert_almost_equal(mox_exp, obs) + assert_almost_equal(mox_exp, obs) uox_exp = [0, 0, 0, 0, 0] obs = np.zeros(5) rows = xa[np.logical_and(xa["ReceiverId"] == self.r2, xa["SenderId"] == self.suox)] obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - np.testing.assert_almost_equal(uox_exp, obs) + assert_almost_equal(uox_exp, obs) def test_rxtr3_xactions(self): xa = self.transactions @@ -180,14 +181,14 @@ def test_rxtr3_xactions(self): rows = xa[np.logical_and(xa["ReceiverId"] == self.r3, xa["SenderId"] == self.smox)] obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - np.testing.assert_almost_equal(mox_exp, obs) + assert_almost_equal(mox_exp, obs) uox_exp = [0, 0, 0, 0.5, 0] obs = np.zeros(5) rows = xa[np.logical_and(xa["ReceiverId"] == self.r3, xa["SenderId"] == self.suox)] obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - np.testing.assert_almost_equal(uox_exp, obs) + assert_almost_equal(uox_exp, obs) class TestDynamicCapacitated(TestRegression): """Tests dynamic capacity restraints involving changes in the number of From c805f41bfa7aeefaf7d43ee900cddb477c42fefe Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 5 Jan 2015 21:21:18 -0600 Subject: [PATCH 019/314] adding comp and info tables --- tests/test_regression.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_regression.py b/tests/test_regression.py index 6464ac3eae..e3625caa6f 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -39,6 +39,8 @@ def setUp(self): else None self.resources = f.get_node("/Resources")[:] self.transactions = f.get_node("/Transactions")[:] + self.compositions = f.get_node("/Compositions")[:] + self.info = f.get_node("/Info")[:] self.rsrc_qtys = { x["ResourceId"]: x["Quantity"] for x in self.resources} From f428e71c286ee33a98efc1988db61f5cb61e4484 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 7 Jan 2015 09:01:58 -0600 Subject: [PATCH 020/314] import groupings and array_almost_equal --- tests/test_regression.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index e3625caa6f..73c2453a67 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -1,12 +1,14 @@ #! /usr/bin/env python -from nose.tools import assert_equal, assert_true import os from unittest import TestCase + import tables -import numpy as np -from numpy.testing import assert_almost_equal import uuid +import numpy as np +from numpy.testing import assert_array_almost_equal +from nose.tools import assert_equal, assert_true + from helper import check_cmd, run_cyclus, table_exist, find_ids class TestRegression(TestCase): @@ -79,7 +81,7 @@ def test_swu(self): # enrichment module from python exp = [6.9, 10, 4.14, 6.9] obs = [np.sum(enr["SWU"][enr["Time"] == t]) for t in range(4)] - assert_almost_equal(exp, obs, decimal=2) + assert_array_almost_equal(exp, obs, decimal=2) def test_nu(self): enr = self.enrichments @@ -88,7 +90,7 @@ def test_nu(self): exp = [13.03, 16.54, 7.83, 13.03] obs = [np.sum(enr["Natural_Uranium"][enr["Time"] == t]) \ for t in range(4)] - assert_almost_equal(exp, obs, decimal=2) + assert_array_almost_equal(exp, obs, decimal=2) def test_xactions(self): xa = self.transactions @@ -104,12 +106,12 @@ def test_xactions(self): exp = [1, 0.8, 0.2, 1] obs = transfers[0] msg = "Testing that first reactor gets less than it wants." - assert_almost_equal(exp, obs, decimal=2, err_msg=msg) + assert_array_almost_equal(exp, obs, decimal=2, err_msg=msg) exp = [1, 1, 1, 1] obs = transfers[1] msg = "Testing that second reactor gets what it wants." - assert_almost_equal(exp, obs, decimal=2) + assert_array_almost_equal(exp, obs, decimal=2) class TestPhysorSources(TestRegression): """This class tests the 2_Sources_3_Reactor.xml file related to the Cyclus @@ -149,14 +151,14 @@ def test_rxtr1_xactions(self): rows = xa[np.logical_and(xa["ReceiverId"] == self.r1, xa["SenderId"] == self.smox)] obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - assert_almost_equal(mox_exp, obs) + assert_array_almost_equal(mox_exp, obs) uox_exp = [0, 0, 0, 0, 1] obs = np.zeros(5) rows = xa[np.logical_and(xa["ReceiverId"] == self.r1, xa["SenderId"] == self.suox)] obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - assert_almost_equal(uox_exp, obs) + assert_array_almost_equal(uox_exp, obs) def test_rxtr2_xactions(self): xa = self.transactions @@ -166,14 +168,14 @@ def test_rxtr2_xactions(self): rows = xa[np.logical_and(xa["ReceiverId"] == self.r2, xa["SenderId"] == self.smox)] obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - assert_almost_equal(mox_exp, obs) + assert_array_almost_equal(mox_exp, obs) uox_exp = [0, 0, 0, 0, 0] obs = np.zeros(5) rows = xa[np.logical_and(xa["ReceiverId"] == self.r2, xa["SenderId"] == self.suox)] obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - assert_almost_equal(uox_exp, obs) + assert_array_almost_equal(uox_exp, obs) def test_rxtr3_xactions(self): xa = self.transactions @@ -183,14 +185,14 @@ def test_rxtr3_xactions(self): rows = xa[np.logical_and(xa["ReceiverId"] == self.r3, xa["SenderId"] == self.smox)] obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - assert_almost_equal(mox_exp, obs) + assert_array_almost_equal(mox_exp, obs) uox_exp = [0, 0, 0, 0.5, 0] obs = np.zeros(5) rows = xa[np.logical_and(xa["ReceiverId"] == self.r3, xa["SenderId"] == self.suox)] obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - assert_almost_equal(uox_exp, obs) + assert_array_almost_equal(uox_exp, obs) class TestDynamicCapacitated(TestRegression): """Tests dynamic capacity restraints involving changes in the number of From 202eb1c3f89f2c35bc2a57d065f1f3cf552d612c Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 7 Jan 2015 09:37:18 -0600 Subject: [PATCH 021/314] outf_ to outf, thought this change was made already.. --- tests/test_regression.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index 73c2453a67..ccf50cfc35 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -20,21 +20,21 @@ class TestRegression(TestCase): """ def __init__(self, *args, **kwargs): super(TestRegression, self).__init__(*args, **kwargs) - self.outf_ = str(uuid.uuid4()) + ".h5" + self.outf = str(uuid.uuid4()) + ".h5" self.inf = None def __del__(self): - if os.path.isfile(self.outf_): - print("removing {0}".format(self.outf_)) - os.remove(self.outf_) + if os.path.isfile(self.outf): + print("removing {0}".format(self.outf)) + os.remove(self.outf) def setUp(self): if not self.inf: raise TypeError(("self.inf must be set in derived classes " "to run regression tests.")) - run_cyclus("cyclus", os.getcwd(), self.inf, self.outf_) + run_cyclus("cyclus", os.getcwd(), self.inf, self.outf) - with tables.open_file(self.outf_, mode="r") as f: + with tables.open_file(self.outf, mode="r") as f: # Get specific tables and columns self.agent_entry = f.get_node("/AgentEntry")[:] self.agent_exit = f.get_node("/AgentExit")[:] if "/AgentExit" in f \ @@ -47,9 +47,9 @@ def setUp(self): x["ResourceId"]: x["Quantity"] for x in self.resources} def tearDown(self): - if os.path.isfile(self.outf_): - print("removing {0}".format(self.outf_)) - os.remove(self.outf_) + if os.path.isfile(self.outf): + print("removing {0}".format(self.outf)) + os.remove(self.outf) class TestPhysorEnrichment(TestRegression): """This class tests the 1_Enrichment_2_Reactor.xml file related to the @@ -68,7 +68,7 @@ def setUp(self): self.enr_id = find_ids(":cycamore:EnrichmentFacility", tbl["Spec"], tbl["AgentId"]) - with tables.open_file(self.outf_, mode="r") as f: + with tables.open_file(self.outf, mode="r") as f: self.enrichments = f.get_node("/Enrichments")[:] def test_deploy(self): From 01d0bbe75826aded0a531fbfec40db39de31d23e Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 10 Feb 2015 16:30:35 -0600 Subject: [PATCH 022/314] added sink test --- src/sink_tests.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/sink_tests.cc b/src/sink_tests.cc index e82888c573..dd54f4324e 100644 --- a/src/sink_tests.cc +++ b/src/sink_tests.cc @@ -178,6 +178,34 @@ TEST_F(SinkTest, Accept) { src_facility->AcceptMatlTrades(responses); EXPECT_DOUBLE_EQ(qty, src_facility->InventorySize()); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(SinkTest, InRecipe){ +// Create a context + using cyclus::RequestPortfolio; + using cyclus::Material; + using cyclus::Request; + cyclus::Recorder rec; + cyclus::Timer ti; + cyclus::Context ctx(&ti, &rec); + // define some test material in the context + cyclus::CompMap m; + m[922350000] = 1; + m[922580000] = 2; + cyclus::Composition::Ptr c = cyclus::Composition::CreateFromMass(m); +ctx.AddRecipe("some_u",c) ; +// create a sink facility to interact with the DRE +cycamore::Sink* snk = new cycamore::Sink(&ctx); +snk->AddCommodity("some_u"); +std::set::Ptr> ports = +snk->GetMatlRequests(); +ASSERT_EQ(ports.size(), 1); +const std::vector*>& requests = +ports.begin()->get()->requests(); +ASSERT_EQ(requests.size(), 1); +Request* req = *requests.begin(); +EXPECT_EQ(req->requester(), snk); +EXPECT_EQ(req->commodity(),"some_u"); +} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TEST_F(SinkTest, Print) { From 9cccc6989da9e76cc445996a959c5dc06e93e27c Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 10 Feb 2015 16:45:36 -0600 Subject: [PATCH 023/314] fixed whitespace formatting --- src/sink_tests.cc | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/sink_tests.cc b/src/sink_tests.cc index a4458d8027..1926840c14 100644 --- a/src/sink_tests.cc +++ b/src/sink_tests.cc @@ -185,24 +185,30 @@ TEST_F(SinkTest, InRecipe){ cyclus::Recorder rec; cyclus::Timer ti; cyclus::Context ctx(&ti, &rec); + // define some test material in the context cyclus::CompMap m; m[922350000] = 1; m[922580000] = 2; + cyclus::Composition::Ptr c = cyclus::Composition::CreateFromMass(m); -ctx.AddRecipe("some_u",c) ; -// create a sink facility to interact with the DRE -cycamore::Sink* snk = new cycamore::Sink(&ctx); -snk->AddCommodity("some_u"); -std::set::Ptr> ports = -snk->GetMatlRequests(); -ASSERT_EQ(ports.size(), 1); -const std::vector*>& requests = -ports.begin()->get()->requests(); -ASSERT_EQ(requests.size(), 1); -Request* req = *requests.begin(); -EXPECT_EQ(req->requester(), snk); -EXPECT_EQ(req->commodity(),"some_u"); + ctx.AddRecipe("some_u",c) ; + + // create a sink facility to interact with the DRE + cycamore::Sink* snk = new cycamore::Sink(&ctx); + snk->AddCommodity("some_u"); + + std::set::Ptr> ports = + snk->GetMatlRequests(); + ASSERT_EQ(ports.size(), 1); + + const std::vector*>& requests = + ports.begin()->get()->requests(); + ASSERT_EQ(requests.size(), 1); + + Request* req = *requests.begin(); + EXPECT_EQ(req->requester(), snk); + EXPECT_EQ(req->commodity(),"some_u"); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From f5a054815f1f53089a4a86facee3fc1a34f6ed09 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Wed, 11 Feb 2015 10:48:06 -0600 Subject: [PATCH 024/314] added uitype and clarifying documentation for in_recipe --- src/sink.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sink.h b/src/sink.h index a0ee06deb0..f7389ffc59 100644 --- a/src/sink.h +++ b/src/sink.h @@ -176,8 +176,9 @@ class Sink : public cyclus::Facility { double capacity; #pragma cyclus var {"default": "", "tooltip": "requested composition", \ - "doc": "name of recipe to use for material " \ - "requests"} + "doc": "name of recipe to use for material requests, where " \ + "the default (empty string) is to accept everything", \ + "uitype": "recipe"} std::string recipe_name; /// max inventory size From 69c345e7f803656917e5da9e1b155b3e2a04ca19 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 12 Feb 2015 10:45:07 -0600 Subject: [PATCH 025/314] fix reg tests to run for py3+ and fix an array == int issue --- tests/helper.py | 2 +- tests/test_regression.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/helper.py b/tests/helper.py index 112235dccb..831f98facc 100644 --- a/tests/helper.py +++ b/tests/helper.py @@ -8,7 +8,7 @@ import tables from nose.tools import assert_equal -if sys.version_info[0] > 3: +if sys.version_info[0] >= 3: str_types = (bytes, str) else: str_types = (str, unicode) diff --git a/tests/test_regression.py b/tests/test_regression.py index ccf50cfc35..13c930f7a7 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -254,16 +254,16 @@ def test_sink_deployment(self): # and decommissioned at time step 2 for i in [0, 1]: assert_equal( - self.depl_time[np.where(self.agent_ids == self.sink_id[i])], 1) + self.depl_time[np.where(self.agent_ids == self.sink_id[i])][0], 1) assert_equal( - self.exit_time[np.where(self.exit_ids == self.sink_id[i])], 2) + self.exit_time[np.where(self.exit_ids == self.sink_id[i])][0], 2) # Test that second 2 sink facilities are deployed at time step 2 # and decommissioned at time step 3 for i in [2, 3]: assert_equal( - self.depl_time[np.where(self.agent_ids == self.sink_id[i])], 2) + self.depl_time[np.where(self.agent_ids == self.sink_id[i])][0], 2) assert_equal( - self.exit_time[np.where(self.exit_ids == self.sink_id[i])], 3) + self.exit_time[np.where(self.exit_ids == self.sink_id[i])][0], 3) def test_xaction_general(self): # Check that transactions are between sources and sinks only From cc723478f14478b0965ffa103fa80226153e7cc7 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Tue, 17 Feb 2015 12:04:31 -0600 Subject: [PATCH 026/314] this fixes dynamic capacitated tests to work with the new established convention of agents being decommissioned at the end of start+lifetime-1 --- tests/input/dynamic_capacitated.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/input/dynamic_capacitated.xml b/tests/input/dynamic_capacitated.xml index 980e3da2e3..b36c883cb4 100644 --- a/tests/input/dynamic_capacitated.xml +++ b/tests/input/dynamic_capacitated.xml @@ -27,7 +27,7 @@ Sink - 1 + 2 From dfacdf439351bb25b748ea9048008d5fc4f84680 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 11 Mar 2015 11:24:54 -0500 Subject: [PATCH 027/314] deploy now fully code gen'd and supports lifetime setting --- src/deploy_inst.cc | 23 +++++++++++++++++----- src/deploy_inst.h | 49 ++++++++++++++++++++++++++++------------------ 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/src/deploy_inst.cc b/src/deploy_inst.cc index f243d2e543..b79a7b11a2 100644 --- a/src/deploy_inst.cc +++ b/src/deploy_inst.cc @@ -77,11 +77,24 @@ void DeployInst::Snapshot(cyclus::DbInit di) { void DeployInst::Build(cyclus::Agent* parent) { cyclus::Institution::Build(parent); BuildSched::iterator it; - for (it = build_sched_.begin(); it != build_sched_.end(); ++it) { - int t = it->first; - std::vector protos = it->second; - for (int i = 0; i < protos.size(); ++i) { - context()->SchedBuild(this, protos[i], t); + for (int i = 0; i < prototypes.size(); i++) { + std::string proto = prototypes[i]; + + std::stringstream ss; + ss << proto; + + if (lifetimes.size() == prototypes.size()) { + cyclus::Agent* a = context()->CreateAgent(proto); + a->lifetime_ = lifetimes[i]; + + ss << "_life" << lifetimes[i]; + proto = ss.str(); + context()->AddPrototype(proto, a); + } + + int t = build_times[i]; + for (int j = 0; j < n_build[i]; j++) { + context()->SchedBuild(this, proto, t); } } } diff --git a/src/deploy_inst.h b/src/deploy_inst.h index 0526ff2fc1..5e252565a7 100644 --- a/src/deploy_inst.h +++ b/src/deploy_inst.h @@ -18,34 +18,45 @@ typedef std::map > BuildSched; /// This agent implements a simple institution agent that deploys /// specific facilities as defined explicitly in the input file. class DeployInst : public cyclus::Institution { + #pragma cyclus note {"doc": "An institution that owns, operates, and " \ + "deploys facilities manually defined in " \ + "the input file."} public: DeployInst(cyclus::Context* ctx); virtual ~DeployInst(); - #pragma cyclus decl clone - - #pragma cyclus decl schema - - #pragma cyclus decl infiletodb - - #pragma cyclus decl initfromdb - - #pragma cyclus decl initfromcopy - - #pragma cyclus decl snapshot - - #pragma cyclus def annotations - - #pragma cyclus note {"doc": "An institution that owns, operates, and " \ - "deploys facilities manually defined in " \ - "the input file."} + #pragma cyclus virtual void Build(cyclus::Agent* parent); protected: - /// a collection of orders to build - BuildSched build_sched_; + #pragma cyclus var { \ + "doc": "Ordered list of prototypes to build.", \ + "uitype": ("onormore", "prototype"), \ + } + std::vector prototypes; + + #pragma cyclus var { \ + "doc": "Number of each prototype in prototypes var to build (same order).", \ + "uitype": ("onormore", "prototype"), \ + } + std::vector n_build; + + #pragma cyclus var { \ + "doc": "Time step on which to build agents given in prototypes (same order).", \ + "uitype": ("onormore", "prototype"), \ + } + std::vector build_times; + + #pragma cyclus var { \ + "doc": "Lifetimes for each prototype in protos (same order)." \ + " If unspecified, defaults to the lifetimes as specified in the original prototype definitions." \ + " A new prototype is created for each lifetime with the suffix '_life[lifetime]'.", \ + "default": [], \ + "uitype": "prototype", \ + } + std::vector lifetimes; }; } // namespace cycamore From d2f072e80d2af31886462fb7a6448d1798d69a7a Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 11 Mar 2015 12:27:43 -0500 Subject: [PATCH 028/314] added docs --- src/deploy_inst.cc | 2 +- src/deploy_inst.h | 42 ++++++++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/deploy_inst.cc b/src/deploy_inst.cc index b79a7b11a2..07770634c8 100644 --- a/src/deploy_inst.cc +++ b/src/deploy_inst.cc @@ -87,7 +87,7 @@ void DeployInst::Build(cyclus::Agent* parent) { cyclus::Agent* a = context()->CreateAgent(proto); a->lifetime_ = lifetimes[i]; - ss << "_life" << lifetimes[i]; + ss << "_life_" << lifetimes[i]; proto = ss.str(); context()->AddPrototype(proto, a); } diff --git a/src/deploy_inst.h b/src/deploy_inst.h index 5e252565a7..0c0e95f185 100644 --- a/src/deploy_inst.h +++ b/src/deploy_inst.h @@ -11,16 +11,24 @@ namespace cycamore { typedef std::map > BuildSched; -/// @class DeployInst -/// The DeployInst class inherits from the Institution -/// class and is dynamically loaded by the Agent class when requested. -/// -/// This agent implements a simple institution agent that deploys -/// specific facilities as defined explicitly in the input file. +// Builds and manages agents (facilities) according to a manually specified +// deployment schedule. Deployed agents are automatically decommissioned at +// the end of their lifetime. The user specifies a list of prototypes for +// each and corresponding build times, number to build, and (optionally) +// lifetimes. The same prototype can be specified multiple times with any +// combination of the same or different build times, build number, and +// lifetimes. class DeployInst : public cyclus::Institution { - #pragma cyclus note {"doc": "An institution that owns, operates, and " \ - "deploys facilities manually defined in " \ - "the input file."} + #pragma cyclus note { \ + "doc": \ + "Builds and manages agents (facilities) according to a manually specified" \ + " deployment schedule. Deployed agents are automatically decommissioned at" \ + " the end of their lifetime. The user specifies a list of prototypes for" \ + " each and corresponding build times, number to build, and (optionally)" \ + " lifetimes. The same prototype can be specified multiple times with any" \ + " combination of the same or different build times, build number, and" \ + " lifetimes. " \ + } public: DeployInst(cyclus::Context* ctx); @@ -38,23 +46,21 @@ class DeployInst : public cyclus::Institution { std::vector prototypes; #pragma cyclus var { \ - "doc": "Number of each prototype in prototypes var to build (same order).", \ - "uitype": ("onormore", "prototype"), \ + "doc": "Time step on which to build agents given in prototypes (same order).", \ } - std::vector n_build; + std::vector build_times; #pragma cyclus var { \ - "doc": "Time step on which to build agents given in prototypes (same order).", \ - "uitype": ("onormore", "prototype"), \ + "doc": "Number of each prototype in prototypes var to build (same order).", \ } - std::vector build_times; + std::vector n_build; #pragma cyclus var { \ "doc": "Lifetimes for each prototype in protos (same order)." \ - " If unspecified, defaults to the lifetimes as specified in the original prototype definitions." \ - " A new prototype is created for each lifetime with the suffix '_life[lifetime]'.", \ + " These lifetimes override the lifetimes in the original prototype definition." \ + " If unspecified, lifetimes from the original prototype definitions are used." \ + " A new prototype is created for each lifetime with the suffix '_life_[lifetime]'.", \ "default": [], \ - "uitype": "prototype", \ } std::vector lifetimes; }; From 922d0f7c8aa1411f6f471adccee8c718e016577a Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 12 Mar 2015 13:33:40 -0500 Subject: [PATCH 029/314] remove now code-gen'd methods --- src/deploy_inst.cc | 69 +--------------------------------------------- 1 file changed, 1 insertion(+), 68 deletions(-) diff --git a/src/deploy_inst.cc b/src/deploy_inst.cc index 07770634c8..07186d25b4 100644 --- a/src/deploy_inst.cc +++ b/src/deploy_inst.cc @@ -7,73 +7,6 @@ DeployInst::DeployInst(cyclus::Context* ctx) : cyclus::Institution(ctx) {} DeployInst::~DeployInst() {} -#pragma cyclus def clone cycamore::DeployInst - -std::string DeployInst::schema() { - return - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n"; -} - -void DeployInst::InfileToDb(cyclus::InfileTree* qe, cyclus::DbInit di) { - cyclus::Institution::InfileToDb(qe, di); - qe = qe->SubTree("config/*"); - - int nOrders = qe->NMatches("buildorder"); - for (int i = 0; i < nOrders; i++) { - cyclus::InfileTree* order = qe->SubTree("buildorder", i); - int n = cyclus::Query(order, "number"); - for (int j = 0; j < n; ++j) { - di.NewDatum("BuildOrder") - ->AddVal("prototype", order->GetString("prototype")) - ->AddVal("date", cyclus::Query(order, "date")) - ->Record(); - } - } -} - -void DeployInst::InitFrom(cyclus::QueryableBackend* b) { - cyclus::Institution::InitFrom(b); - cyclus::QueryResult qr = b->Query("BuildOrder", NULL); - for (int i = 0; i < qr.rows.size(); i++) { - std::string proto = qr.GetVal("prototype", i); - int t = qr.GetVal("date", i); - build_sched_[t].push_back(proto); - } -} - -void DeployInst::InitFrom(DeployInst* m) { - cyclus::Institution::InitFrom(m); - build_sched_ = m->build_sched_; -} - -void DeployInst::Snapshot(cyclus::DbInit di) { - cyclus::Institution::Snapshot(di); - - BuildSched::iterator it; - for (it = build_sched_.begin(); it != build_sched_.end(); ++it) { - int t = it->first; - std::vector protos = it->second; - for (int i = 0; i < protos.size(); ++i) { - di.NewDatum("BuildOrder") - ->AddVal("prototype", protos[i]) - ->AddVal("date", t) - ->Record(); - } - } -} - void DeployInst::Build(cyclus::Agent* parent) { cyclus::Institution::Build(parent); BuildSched::iterator it; @@ -85,7 +18,7 @@ void DeployInst::Build(cyclus::Agent* parent) { if (lifetimes.size() == prototypes.size()) { cyclus::Agent* a = context()->CreateAgent(proto); - a->lifetime_ = lifetimes[i]; + a->Agent::lifetime_ = lifetimes[i]; ss << "_life_" << lifetimes[i]; proto = ss.str(); From 6a642ede1087849b1a7b42e51df3d7b6977b026d Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 13 Mar 2015 10:54:41 -0500 Subject: [PATCH 030/314] fix/clarify documentation --- src/deploy_inst.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/deploy_inst.h b/src/deploy_inst.h index 0c0e95f185..ef27c890de 100644 --- a/src/deploy_inst.h +++ b/src/deploy_inst.h @@ -59,7 +59,8 @@ class DeployInst : public cyclus::Institution { "doc": "Lifetimes for each prototype in protos (same order)." \ " These lifetimes override the lifetimes in the original prototype definition." \ " If unspecified, lifetimes from the original prototype definitions are used." \ - " A new prototype is created for each lifetime with the suffix '_life_[lifetime]'.", \ + " Although a new prototype is created in the Prototypes table for each lifetime with the suffix '_life_[lifetime]'," \ + " all deployed agents themselves will have the same original prototype name (and so will the Agents tables).", \ "default": [], \ } std::vector lifetimes; From e9b44b357c74687ca27ac90dce134ecdf25da018 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 13 Mar 2015 10:58:08 -0500 Subject: [PATCH 031/314] skeleton for deploy inst tests --- src/deploy_inst_tests.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/deploy_inst_tests.cc b/src/deploy_inst_tests.cc index 983250a599..7615c45358 100644 --- a/src/deploy_inst_tests.cc +++ b/src/deploy_inst_tests.cc @@ -5,27 +5,27 @@ #include "institution_tests.h" #include "agent_tests.h" -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Agent* DeployInstitutionConstructor(cyclus::Context* ctx) { - return new cycamore::DeployInst(ctx); +TEST(DeployInstTests, ProtoNames) { } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -class DeployInstTest : public ::testing::Test { - protected: - virtual void SetUp() {} +TEST(DeployInstTests, BuildTimes) { +} - virtual void TearDown() {} -}; +TEST(DeployInstTests, FiniteLifetimes) { +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // required to get functionality in cyclus agent unit tests library +cyclus::Agent* DeployInstitutionConstructor(cyclus::Context* ctx) { + return new cycamore::DeployInst(ctx); +} + #ifndef CYCLUS_AGENT_TESTS_CONNECTED int ConnectAgentTests(); static int cyclus_agent_tests_connected = ConnectAgentTests(); #define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected #endif // CYCLUS_AGENT_TESTS_CONNECTED -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INSTANTIATE_TEST_CASE_P(DeployInst, InstitutionTests, Values(&DeployInstitutionConstructor)); INSTANTIATE_TEST_CASE_P(DeployInst, AgentTests, From 43e86aeb6b970262575b481a214a822d920496be Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 13 Mar 2015 14:50:20 -0500 Subject: [PATCH 032/314] added deployment tests --- CMakeLists.txt | 3 ++ src/deploy_inst.cc | 2 +- src/deploy_inst_tests.cc | 95 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 336fb1cd1e..4985e62e56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,9 @@ IF(NOT CYCLUS_DOC_ONLY) FIND_PACKAGE(COIN REQUIRED) set(LIBS ${LIBS} ${COIN_LIBRARIES}) + FIND_PACKAGE( Sqlite3 REQUIRED ) + SET(LIBS ${LIBS} ${SQLITE3_LIBRARIES}) + # include the agent directories SET(CYCAMORE_INCLUDE_DIR ${CYCAMORE_INCLUDE_DIR} tests ${CYCLUS_CORE_INCLUDE_DIR}/..) diff --git a/src/deploy_inst.cc b/src/deploy_inst.cc index 07186d25b4..260fe86d15 100644 --- a/src/deploy_inst.cc +++ b/src/deploy_inst.cc @@ -18,7 +18,7 @@ void DeployInst::Build(cyclus::Agent* parent) { if (lifetimes.size() == prototypes.size()) { cyclus::Agent* a = context()->CreateAgent(proto); - a->Agent::lifetime_ = lifetimes[i]; + a->lifetime(lifetimes[i]); ss << "_life_" << lifetimes[i]; proto = ss.str(); diff --git a/src/deploy_inst_tests.cc b/src/deploy_inst_tests.cc index 7615c45358..9d1657966e 100644 --- a/src/deploy_inst_tests.cc +++ b/src/deploy_inst_tests.cc @@ -5,13 +5,108 @@ #include "institution_tests.h" #include "agent_tests.h" +// make sure that the deployed agent's prototype name is identical to the +// originally specified prototype name - this is important to test because +// DeployInst does some mucking around with registering name-modded prototypes +// in order to deal with lifetime setting. TEST(DeployInstTests, ProtoNames) { + std::string config = + " foobar " + " 1 " + " 3 " + " 2 " + ; + + int simdur = 5; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:DeployInst"), config, simdur); + sim.DummyProto("foobar"); + int id = sim.Run(); + + cyclus::SqlStatement::Ptr stmt = sim.db().db().Prepare( + "SELECT COUNT(*) FROM AgentEntry WHERE Prototype = 'foobar';" + ); + stmt->Step(); + EXPECT_EQ(3, stmt->GetInt(0)); } TEST(DeployInstTests, BuildTimes) { + std::string config = + " foobar foobar " + " 1 3 " + " 1 7 " + ; + + int simdur = 5; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:DeployInst"), config, simdur); + sim.DummyProto("foobar"); + int id = sim.Run(); + + cyclus::SqlStatement::Ptr stmt = sim.db().db().Prepare( + "SELECT COUNT(*) FROM AgentEntry WHERE Prototype = 'foobar' AND EnterTime = 1;" + ); + stmt->Step(); + EXPECT_EQ(1, stmt->GetInt(0)); + + stmt = sim.db().db().Prepare( + "SELECT COUNT(*) FROM AgentEntry WHERE Prototype = 'foobar' AND EnterTime = 3;" + ); + stmt->Step(); + EXPECT_EQ(7, stmt->GetInt(0)); } +// make sure that specified lifetimes are honored both in agent's table record +// and in decommissioning. TEST(DeployInstTests, FiniteLifetimes) { + std::string config = + " foobar foobar foobar " + " 1 1 2 " + " 1 7 3 " + " 1 2 -1 " + ; + + int simdur = 5; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:DeployInst"), config, simdur); + sim.DummyProto("foobar"); + int id = sim.Run(); + + // check agent deployment + cyclus::SqlStatement::Ptr stmt = sim.db().db().Prepare( + "SELECT COUNT(*) FROM AgentEntry WHERE Prototype = 'foobar' AND EnterTime = 1 AND Lifetime = 1;" + ); + stmt->Step(); + EXPECT_EQ(1, stmt->GetInt(0)); + + stmt = sim.db().db().Prepare( + "SELECT COUNT(*) FROM AgentEntry WHERE Prototype = 'foobar' AND EnterTime = 1 AND Lifetime = 2;" + ); + stmt->Step(); + EXPECT_EQ(7, stmt->GetInt(0)); + + stmt = sim.db().db().Prepare( + "SELECT COUNT(*) FROM AgentEntry WHERE Prototype = 'foobar' AND EnterTime = 2 AND Lifetime = -1;" + ); + stmt->Step(); + EXPECT_EQ(3, stmt->GetInt(0)); + + // check decommissioning + stmt = sim.db().db().Prepare( + "SELECT COUNT(*) FROM AgentEntry As e JOIN AgentExit AS x ON x.AgentId = e.AgentId WHERE e.Prototype = 'foobar' AND x.ExitTime = 1;" + ); + stmt->Step(); + EXPECT_EQ(1, stmt->GetInt(0)); + + stmt = sim.db().db().Prepare( + "SELECT COUNT(*) FROM AgentEntry As e JOIN AgentExit AS x ON x.AgentId = e.AgentId WHERE e.Prototype = 'foobar' AND x.ExitTime = 2;" + ); + stmt->Step(); + EXPECT_EQ(7, stmt->GetInt(0)); + + // agent with -1 lifetime should not be in AgentExit table + stmt = sim.db().db().Prepare( + "SELECT COUNT(*) FROM AgentExit;" + ); + stmt->Step(); + EXPECT_EQ(8, stmt->GetInt(0)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From dff9e7e761721f8c1fa3a76e0bf38cb3497949f0 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 23 Mar 2015 14:27:56 -0500 Subject: [PATCH 033/314] update input files for new deployinst schema --- input/physor/2_Sources_3_Reactors.xml | 48 +++++++++++++-------------- tests/input/dynamic_capacitated.xml | 32 +++++++++--------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/input/physor/2_Sources_3_Reactors.xml b/input/physor/2_Sources_3_Reactors.xml index d9ee17ff8b..742a968528 100755 --- a/input/physor/2_Sources_3_Reactors.xml +++ b/input/physor/2_Sources_3_Reactors.xml @@ -182,31 +182,29 @@ SingleInstitution - - UOX_Source - 1 - 1 - - - MOX_Source - 1 - 1 - - - Reactor1 - 1 - 1 - - - Reactor2 - 1 - 2 - - - Reactor3 - 1 - 3 - + + UOX_Source + MOX_Source + Reactor1 + Reactor2 + Reactor3 + + + + 1 + 1 + 1 + 2 + 3 + + + + 1 + 1 + 1 + 1 + 1 + diff --git a/tests/input/dynamic_capacitated.xml b/tests/input/dynamic_capacitated.xml index b36c883cb4..8b9de23502 100644 --- a/tests/input/dynamic_capacitated.xml +++ b/tests/input/dynamic_capacitated.xml @@ -47,21 +47,23 @@ SingleInstitution - - Source - 3 - 1 - - - Sink - 2 - 1 - - - Sink - 2 - 2 - + + Source + Sink + Sink + + + + 1 + 1 + 2 + + + + 3 + 2 + 2 + From 1c828b088a615a4b5430ea37c3e5b0f806fa1c6f Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 23 Mar 2015 16:07:56 -0500 Subject: [PATCH 034/314] validate parallel vector lenghts are consistent --- src/deploy_inst.cc | 18 ++++++++++++++++++ src/deploy_inst.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/src/deploy_inst.cc b/src/deploy_inst.cc index 260fe86d15..0e2990595a 100644 --- a/src/deploy_inst.cc +++ b/src/deploy_inst.cc @@ -32,6 +32,24 @@ void DeployInst::Build(cyclus::Agent* parent) { } } +void DeployInst::EnterNotify() { + cyclus::Institution::EnterNotify(); + int n = prototypes.size(); + if (build_times.size() != n) { + std::stringstream ss; + ss << "prototype '" << prototype() << "' has " << build_times.size() << " build_times vals, expected " << n; + throw cyclus::ValueError(ss.str()); + } else if (n_build.size() != n) { + std::stringstream ss; + ss << "prototype '" << prototype() << "' has " << n_build.size() << " n_build vals, expected " << n; + throw cyclus::ValueError(ss.str()); + } else if (lifetimes.size() > 0 && lifetimes.size() != n) { + std::stringstream ss; + ss << "prototype '" << prototype() << "' has " << lifetimes.size() << " lifetimes vals, expected " << n; + throw cyclus::ValueError(ss.str()); + } +} + extern "C" cyclus::Agent* ConstructDeployInst(cyclus::Context* ctx) { return new DeployInst(ctx); } diff --git a/src/deploy_inst.h b/src/deploy_inst.h index ef27c890de..7e06002df4 100644 --- a/src/deploy_inst.h +++ b/src/deploy_inst.h @@ -38,6 +38,8 @@ class DeployInst : public cyclus::Institution { virtual void Build(cyclus::Agent* parent); + virtual void EnterNotify(); + protected: #pragma cyclus var { \ "doc": "Ordered list of prototypes to build.", \ From deae4d4ce4e1451a72f525fe35382c46fc7e0d97 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 7 Jan 2015 10:46:32 -0600 Subject: [PATCH 035/314] start skeleton for new reactor --- src/CMakeLists.txt | 2 + src/reactor.cc | 21 ++++++ src/reactor.h | 174 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 197 insertions(+) create mode 100644 src/reactor.cc create mode 100644 src/reactor.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c7ab466fb9..c85d3d11a2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,8 @@ USE_CYCLUS("cycamore" "batch_reactor") +USE_CYCLUS("cycamore" "reactor") + USE_CYCLUS("cycamore" "enrichment_facility") #USE_CYCLUS("cycamore" "inpro_reactor") diff --git a/src/reactor.cc b/src/reactor.cc new file mode 100644 index 0000000000..5922da2f4d --- /dev/null +++ b/src/reactor.cc @@ -0,0 +1,21 @@ +#include "reactor.h" + +namespace cycamore { + +Reactor::Reactor(cyclus::Context* ctx) + : cyclus::Facility(ctx), + n_batches(0), + assem_size(0), + integral_assem(0), + n_assem_core(0), + n_assem_spent(0), + n_assem_fresh(0), + cycle_time(0), + refuel_time(0), + cycle_step(0) { + cyclus::Warn("the Reactor archetype " + "is experimental"); +} + +} // namespace cycamore + diff --git a/src/reactor.h b/src/reactor.h new file mode 100644 index 0000000000..fb2f769d3a --- /dev/null +++ b/src/reactor.h @@ -0,0 +1,174 @@ +#ifndef CYCAMORE_SRC_REACTOR_H_ +#define CYCAMORE_SRC_REACTOR_H_ + +#include "cyclus.h" + +using cyclus::Material; +using cyclus::toolkit::ResBuf; + +namespace cycamore { + +// Configurable parameters: +// +// * n_batches (double) - the inverse of the core fraction discharged per cycle +// +// * assem_size (double) - the mass in kg of a single assembly +// +// * n_assem_core (int) - the number of assemblies that constitute a core. +// +// * n_assem_spent (int, default infinite) - the number of spent fuel assemblies +// that can be stored +// +// * n_assem_fresh (int, default n_assem_core) - the number of fresh assemblies to keep on +// hand +// +// * integral_assem (bool, default true) - true if requests require DRE to +// match all or nothing of each assembly. Note that this is different from +// and roughly orthogonal to whether the reactor is operating in discrete or +// continuous assembly mode. “True” is the recommended value for this +// variable. “False” can result in materials being combined resulting in +// incorrect transmutations. +// +// The Reactor will have 3 resource buffers (all with automatically computed +// capacities based on above params): +// +// * fresh: capacity = n_assem_fresh * assem_size +// +// * core: capacity = n_assem_core * assem_size +// +// * spent: capacity = n_assem_spent * assem_size +// +// The reactor will always try to keep its fresh_fuel and core buffers full. +// The cycle progresses/runs only if the reactor is in active operation. The +// following conditions result in reactor operation being suspended: +// +// * There are not enough full assemblies (with unspent life) to provide a full core +// +// * There is no room in the spent_fuel buffer to discharge a fully-burned assembly to. +// +// If a reactor is operating in discrete assembly mode, when it receives fresh +// fuel, it discretizes the material into assembly quanta (of size +// assem_size). Discrete assembly mode is the recommended mode of operation +// for a reactor. If a partial assembly is received, it is stored until +// enough material can be acquired to complete the full assembly. In this +// mode, partial assemblies may not be inserted into the core. When in this +// mode, resources will never be split/combined by the reactor post assembly +// discretization. If integral_assem is false, then this discretization will +// happen upon extraction of an assembly’s worth of material from the fresh +// inventory for placement into the core. If integral_assem is true, then +// this discretization will happen automatically as part of resource exchange. +// Under either of the following conditions, a reactor will operate in +// discrete assembly mode: +// +// * n_assem_core == n_batches: pop one assembly per cycle +// +// * n_assem_core > 1: pop floor(n_assem_core / n_batches) assemblies per cycle +// +// If neither of those conditions are met (i.e. n_assem_core == 1 && n_assem_core != +// n_batches), then the reactor will operate in continuous assembly mode. In +// this mode it discharges 1 / n_batches fraction of the single assembly from +// the core at the end of each cycle, and the same quantity will be +// extracted/split from the (not assembly discretized) fresh fresh fuel buffer +// (or requested on DRE if no fresh) and inserted into the core. +// +// Time to make it code generatable? - Yes Bring into compliance? - Yes. +// The BatchReactor currently has no state variables. A UINT type might be +// useful here. We should scavenge the batch reactor for pieces as we +// reimplement a new code-generated version. +// +// * integral_assem == true, discrete assembly mode - discretization is automatic - Pop() from fresh buffer. +// +// * integral_assem == false, discrete assembly mode - discretization upon extraction from fresh buffer. Just ExtractQty from fresh buffer +// +// * integral_assem == true, continuous assembly mode - discretization doesn’t matter. Just ExtractQty from fresh buffer. +// +// * integral_assem == false, continuous assembly mode - discretization doesn’t matter. Just ExtractQty from fresh buffer. +// +// Meta-data associated with resource objects in inventory (e.g. the in-commod +// on which they were received) should be associated with resources based on +// obj_id. This is necessary for handling the case where integral_assem is +// true in discrete assembly mode where resources are combined inside buffers +// during extraction. + +class Reactor : public cyclus::Facility { + public: + Reactor(cyclus::Context* ctx); + virtual ~Reactor() {}; + + virtual void EnterNotify() {}; + virtual void Tick() {}; + virtual void Tock() {}; + + #pragma cyclus + + private: + // inventory and core params + #pragma cyclus var {} + double n_batches; + #pragma cyclus var {} + double assem_size; + #pragma cyclus var {'default': 1} + bool integral_assem; + #pragma cyclus var {'default': 'n_batches'} + int n_assem_core; + #pragma cyclus var {'default': 1e250} + int n_assem_spent; + #pragma cyclus var {'default': 'n_assem_core'} + int n_assem_fresh; + + // cycle params + #pragma cyclus var {} + int cycle_time; + #pragma cyclus var {} + int refuel_time; + #pragma cyclus var {'default': 0} + int cycle_step; + + // fuel specifications + #pragma cyclus var {} + std::vector incommods; + #pragma cyclus var {} + std::vector inrecipes; + #pragma cyclus var {} + std::vector outrecipes; + #pragma cyclus var {} + std::vector outcommods; + #pragma cyclus var {'default': []} // if this is empty, assume zero for all + std::vector incommod_prefs; + + // This variable should be hidden/unavailable in ui. Maps resource id's to + // the incommods through which they were received. + #pragma cyclus var {} + std::map res_commods; + + // preference changes + #pragma cyclus var {'default': []} + std::vector pref_change_times; + #pragma cyclus var {'default': []} + std::vector pref_change_commods; + #pragma cyclus var {'default': []} + std::vector pref_change_values; + + // recipe changes + #pragma cyclus var {'default': []} + std::vector recipe_change_times; + #pragma cyclus var {'default': []} + std::vector recipe_change_commods; + #pragma cyclus var {'default': []} + std::vector recipe_change_incommods; + #pragma cyclus var {'default': []} + std::vector recipe_change_outcommods; + + // Resource inventories + #pragma cyclus var {'capacity': 'n_assem_fresh * assem_size'} + ResBuf fresh; + #pragma cyclus var {'capacity': 'n_assem_core * assem_size'} + ResBuf core; + #pragma cyclus var {'capacity': 'n_assem_spent * assem_size'} + ResBuf spent; + +}; + +} // namespace cycamore + +#endif // CYCAMORE_SRC_REACTOR_H_ From e1b82302bc9789b1b2cded75ae368c46ca3bbbee Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 7 Jan 2015 16:17:53 -0600 Subject: [PATCH 036/314] more work on inventory management and core logic --- src/reactor.cc | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ src/reactor.h | 92 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 148 insertions(+), 33 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index 5922da2f4d..b37bf344bc 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -17,5 +17,94 @@ Reactor::Reactor(cyclus::Context* ctx) "is experimental"); } +void Reactor::Tick() { + if (cycle_step == cycle_time) { + Transmute(); + } else if (cycle_step == cycle_time + refuel_time) { + Discharge(); + Load(); + } + + // update preferences + + // update recipes +} + +// DRE code here - request enough fuel to fill fresh and core inventories. Fill core first. + +void Reactor::Tock() { + if (cycle_step >= cycle_time) { + Load(); + } + + if (cycle_step < cycle_time + refuel_time || core.space() < cyclus::eps()) { + // move forward if in cycle operation or refueling, but halt if waiting + // for fuel at beginning of cycle. + cycle_step++; + } + if (cycle_step > cycle_time + refuel_time) { + cycle_step = 0; + } +} + +void Reactor::Transmute() { + MatVect old; + if (discrete_mode()) { + old = core.PopN(assem_per_discharge()); + } else { + old = core.PopQty(assem_per_discharge() * assem_size); + } + MatVect tail = core.PopN(core.count()); + + for (int i = 0; i < old.size(); i++) { + int id = old[i]->obj_id(); + old[i]->Transmute(context()->GetRecipe(fuel_outrecipe(id))); + } + core.Push(old); + core.Push(tail); +} + +void Reactor::Discharge() { + double qty_pop = assem_per_discharge() * assem_size; + if (spent.space() < qty_pop) { + return; // not enough space in spent fuel inventory + } + + MatVect old; + if (discrete_mode()) { + old = core.PopN(assem_per_discharge()); + } else { + old = core.PopQty(qty_pop); + } + + spent.Push(old); +} + +void Reactor::Load() { + if (core.space() < cyclus::eps()) { + return; // core is full + } + + if (discrete_mode()) { + while (core.space() > assem_size && fresh.quantity() >= assem_size) { + if (integral_assem) { + core.Push(fresh.Pop()); + } else { + core.Push(fresh.Pop(assem_size)); + } + } + } else { + core.Push(fresh.Pop(std::min(core.space(), fresh.quantity()))); + } +} + } // namespace cycamore +double Reactor::assem_per_discharge() { + if (discrete_mode()) { + return static_cast(n_assem_core / n_batches); + } else { + return static_cast(n_assem_core) / n_batches; + } +} + diff --git a/src/reactor.h b/src/reactor.h index fb2f769d3a..8eec8e4bf4 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -102,18 +102,33 @@ class Reactor : public cyclus::Facility { #pragma cyclus private: + std::string fuel_outcommod(int obj_id); + std::string fuel_inrecipe(int obj_id); + std::string fuel_outrecipe(int obj_id); + std::string fuel_pref(int obj_id); + /// Returns true if the reactor is operating in discrete assembly mode. + bool discrete_mode() {return n_assem_core > 1 || n_batches == 1}; + + /// discharge a batch from the core + void Discharge(); + + /// top up core inventory if possible + void Load(); + + double assem_per_discharge(); + // inventory and core params #pragma cyclus var {} double n_batches; #pragma cyclus var {} double assem_size; - #pragma cyclus var {'default': 1} + #pragma cyclus var {"default": 1} bool integral_assem; - #pragma cyclus var {'default': 'n_batches'} + #pragma cyclus var {"default": 'n_batches'} int n_assem_core; - #pragma cyclus var {'default': 1e250} + #pragma cyclus var {"default": 1000000000} int n_assem_spent; - #pragma cyclus var {'default': 'n_assem_core'} + #pragma cyclus var {"default": 'n_assem_core'} int n_assem_fresh; // cycle params @@ -121,52 +136,63 @@ class Reactor : public cyclus::Facility { int cycle_time; #pragma cyclus var {} int refuel_time; - #pragma cyclus var {'default': 0} + #pragma cyclus var { \ + "default": 0, \ + "doc": "number of time steps since the beginning of the last cycle", \ + } int cycle_step; // fuel specifications - #pragma cyclus var {} - std::vector incommods; - #pragma cyclus var {} - std::vector inrecipes; - #pragma cyclus var {} - std::vector outrecipes; - #pragma cyclus var {} - std::vector outcommods; - #pragma cyclus var {'default': []} // if this is empty, assume zero for all - std::vector incommod_prefs; - - // This variable should be hidden/unavailable in ui. Maps resource id's to - // the incommods through which they were received. + #pragma cyclus var { \ + "uitype": ["oneormore", "incommodity"], \ + } + std::vector fuel_incommods; + #pragma cyclus var { \ + "uitype": ["oneormore", "recipe"], \ + } + std::vector fuel_inrecipes; + #pragma cyclus var { \ + "uitype": ["oneormore", "recipe"], \ + } + std::vector fuel_outrecipes; + #pragma cyclus var { \ + "uitype": ["oneormore", "incommodity"], \ + } + std::vector fuel_outcommods; + #pragma cyclus var {"default": []} // if this is empty, assume zero for all + std::vector fuel_prefs; + + // This variable should be hidden/unavailable in ui. Maps resource object + // id's to the incommods through which they were received. #pragma cyclus var {} std::map res_commods; + // Resource inventories + #pragma cyclus var {'capacity': 'n_assem_fresh * assem_size'} + ResBuf fresh; + #pragma cyclus var {'capacity': 'n_assem_core * assem_size'} + ResBuf core; + #pragma cyclus var {'capacity': 'n_assem_spent * assem_size'} + ResBuf spent; + // preference changes - #pragma cyclus var {'default': []} + #pragma cyclus var {"default": []} std::vector pref_change_times; - #pragma cyclus var {'default': []} + #pragma cyclus var {"default": []} std::vector pref_change_commods; - #pragma cyclus var {'default': []} + #pragma cyclus var {"default": []} std::vector pref_change_values; // recipe changes - #pragma cyclus var {'default': []} + #pragma cyclus var {"default": []} std::vector recipe_change_times; - #pragma cyclus var {'default': []} + #pragma cyclus var {"default": []} std::vector recipe_change_commods; - #pragma cyclus var {'default': []} + #pragma cyclus var {"default": []} std::vector recipe_change_incommods; - #pragma cyclus var {'default': []} + #pragma cyclus var {"default": []} std::vector recipe_change_outcommods; - // Resource inventories - #pragma cyclus var {'capacity': 'n_assem_fresh * assem_size'} - ResBuf fresh; - #pragma cyclus var {'capacity': 'n_assem_core * assem_size'} - ResBuf core; - #pragma cyclus var {'capacity': 'n_assem_spent * assem_size'} - ResBuf spent; - }; } // namespace cycamore From 7dd2ad4e28e1688128826329e22747c20f365195 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 8 Jan 2015 10:42:23 -0600 Subject: [PATCH 037/314] fix compile errors. fill out fuel funcs. other fixes --- src/reactor.cc | 82 +++++++++++++++++++++++++++++++++++++------------- src/reactor.h | 40 +++++++++++++----------- 2 files changed, 83 insertions(+), 39 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index b37bf344bc..08fb5dd410 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -1,5 +1,10 @@ #include "reactor.h" +using cyclus::Material; +using cyclus::toolkit::ResBuf; +using cyclus::toolkit::MatVec; +using cyclus::KeyError; + namespace cycamore { Reactor::Reactor(cyclus::Context* ctx) @@ -33,51 +38,46 @@ void Reactor::Tick() { // DRE code here - request enough fuel to fill fresh and core inventories. Fill core first. void Reactor::Tock() { + cycle_step++; + if (cycle_step >= cycle_time) { Load(); } - - if (cycle_step < cycle_time + refuel_time || core.space() < cyclus::eps()) { - // move forward if in cycle operation or refueling, but halt if waiting - // for fuel at beginning of cycle. - cycle_step++; - } - if (cycle_step > cycle_time + refuel_time) { + if (cycle_step > cycle_time + refuel_time && core.space() < cyclus::eps()) { cycle_step = 0; } } void Reactor::Transmute() { - MatVect old; + MatVec old; if (discrete_mode()) { old = core.PopN(assem_per_discharge()); } else { - old = core.PopQty(assem_per_discharge() * assem_size); + old.push_back(core.Pop(assem_per_discharge() * assem_size)); } - MatVect tail = core.PopN(core.count()); for (int i = 0; i < old.size(); i++) { - int id = old[i]->obj_id(); - old[i]->Transmute(context()->GetRecipe(fuel_outrecipe(id))); + old[i]->Transmute(context()->GetRecipe(fuel_outrecipe(old[i]))); } + + MatVec tail = core.PopN(core.count()); core.Push(old); core.Push(tail); } -void Reactor::Discharge() { +bool Reactor::Discharge() { double qty_pop = assem_per_discharge() * assem_size; if (spent.space() < qty_pop) { - return; // not enough space in spent fuel inventory + return false; // not enough space in spent fuel inventory } - MatVect old; if (discrete_mode()) { - old = core.PopN(assem_per_discharge()); + spent.Push(core.PopN(assem_per_discharge())); } else { - old = core.PopQty(qty_pop); + // Transmute already discretized the batch to extract into a single object + spent.Push(core.Pop()); } - - spent.Push(old); + return true; } void Reactor::Load() { @@ -98,8 +98,6 @@ void Reactor::Load() { } } -} // namespace cycamore - double Reactor::assem_per_discharge() { if (discrete_mode()) { return static_cast(n_assem_core / n_batches); @@ -108,3 +106,45 @@ double Reactor::assem_per_discharge() { } } +std::string Reactor::fuel_incommod(Material::Ptr m) { + int i = res_indexes[m->obj_id()]; + if (i >= fuel_incommods.size()) { + throw KeyError("cycamore::Reactor - no incommod for material object"); + } + return fuel_incommods[i]; +} + +std::string Reactor::fuel_outcommod(Material::Ptr m) { + int i = res_indexes[m->obj_id()]; + if (i >= fuel_outcommods.size()) { + throw KeyError("cycamore::Reactor - no outcommod for material object"); + } + return fuel_outcommods[i]; +} + +std::string Reactor::fuel_inrecipe(Material::Ptr m) { + int i = res_indexes[m->obj_id()]; + if (i >= fuel_inrecipes.size()) { + throw KeyError("cycamore::Reactor - no inrecipe for material object"); + } + return fuel_inrecipes[i]; +} + +std::string Reactor::fuel_outrecipe(Material::Ptr m) { + int i = res_indexes[m->obj_id()]; + if (i >= fuel_outrecipes.size()) { + throw KeyError("cycamore::Reactor - no outrecipe for material object"); + } + return fuel_outrecipes[i]; +} + +double Reactor::fuel_pref(Material::Ptr m) { + int i = res_indexes[m->obj_id()]; + if (i >= fuel_prefs.size()) { + return 0; + } + return fuel_prefs[i]; +} + +} // namespace cycamore + diff --git a/src/reactor.h b/src/reactor.h index 8eec8e4bf4..fedfd347ff 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -3,9 +3,6 @@ #include "cyclus.h" -using cyclus::Material; -using cyclus::toolkit::ResBuf; - namespace cycamore { // Configurable parameters: @@ -96,25 +93,32 @@ class Reactor : public cyclus::Facility { virtual ~Reactor() {}; virtual void EnterNotify() {}; - virtual void Tick() {}; - virtual void Tock() {}; + virtual void Tick(); + virtual void Tock(); #pragma cyclus private: - std::string fuel_outcommod(int obj_id); - std::string fuel_inrecipe(int obj_id); - std::string fuel_outrecipe(int obj_id); - std::string fuel_pref(int obj_id); + std::string fuel_incommod(cyclus::Material::Ptr m); + std::string fuel_outcommod(cyclus::Material::Ptr m); + std::string fuel_inrecipe(cyclus::Material::Ptr m); + std::string fuel_outrecipe(cyclus::Material::Ptr m); + double fuel_pref(cyclus::Material::Ptr m); + /// Returns true if the reactor is operating in discrete assembly mode. - bool discrete_mode() {return n_assem_core > 1 || n_batches == 1}; + bool discrete_mode() {return n_assem_core > 1 || n_batches == 1;}; - /// discharge a batch from the core - void Discharge(); + /// Discharge a batch from the core if there is room in the spent fuel + /// inventory. Returns true if a batch was successfully discharged. + bool Discharge(); - /// top up core inventory if possible + /// Top up core inventory if possible. void Load(); + /// Transmute the batch in the core that is about to be discharged to its + /// fully burnt state as defined by its outrecipe. + void Transmute(); + double assem_per_discharge(); // inventory and core params @@ -163,17 +167,17 @@ class Reactor : public cyclus::Facility { std::vector fuel_prefs; // This variable should be hidden/unavailable in ui. Maps resource object - // id's to the incommods through which they were received. + // id's to the index for the incommod through which they were received. #pragma cyclus var {} - std::map res_commods; + std::map res_indexes; // Resource inventories #pragma cyclus var {'capacity': 'n_assem_fresh * assem_size'} - ResBuf fresh; + cyclus::toolkit::ResBuf fresh; #pragma cyclus var {'capacity': 'n_assem_core * assem_size'} - ResBuf core; + cyclus::toolkit::ResBuf core; #pragma cyclus var {'capacity': 'n_assem_spent * assem_size'} - ResBuf spent; + cyclus::toolkit::ResBuf spent; // preference changes #pragma cyclus var {"default": []} From 261aaa44e6dc2418f0235cfdfeed28c1187cef4d Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 8 Jan 2015 12:10:42 -0600 Subject: [PATCH 038/314] implemented requesting and material receiving. --- src/reactor.cc | 106 ++++++++++++++++++++++++++++++++++----- src/reactor.h | 131 ++++++++++++++++++++++++++++++------------------- 2 files changed, 174 insertions(+), 63 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index 08fb5dd410..415975b90f 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -1,9 +1,11 @@ #include "reactor.h" using cyclus::Material; +using cyclus::Composition; using cyclus::toolkit::ResBuf; using cyclus::toolkit::MatVec; using cyclus::KeyError; +using cyclus::ValueError; namespace cycamore { @@ -11,10 +13,9 @@ Reactor::Reactor(cyclus::Context* ctx) : cyclus::Facility(ctx), n_batches(0), assem_size(0), - integral_assem(0), n_assem_core(0), - n_assem_spent(0), - n_assem_fresh(0), + n_batch_spent(0), + n_batch_fresh(0), cycle_time(0), refuel_time(0), cycle_step(0) { @@ -35,7 +36,75 @@ void Reactor::Tick() { // update recipes } -// DRE code here - request enough fuel to fill fresh and core inventories. Fill core first. +std::set::Ptr> +Reactor::GetMatlRequests() { + using cyclus::RequestPortfolio; + using cyclus::Request; + + std::set::Ptr> ports; + RequestPortfolio::Ptr port(new RequestPortfolio()); + Material::Ptr m; + + if (discrete_mode()) { + int n_assem_order = static_cast(core.space() / assem_size) + + static_cast(fresh.space() / assem_size); + for (int i = 0; i < n_assem_order; i++) { + std::vector*> mreqs; + for (int j = 0; j < fuel_incommods.size(); j++) { + std::string commod = fuel_incommods[j]; + double pref = fuel_prefs[j]; + Composition::Ptr recipe = context()->GetRecipe(fuel_inrecipes[j]); + m = Material::CreateUntracked(assem_size, recipe); + Request* r = port->AddRequest(m, this, commod, pref, true); + mreqs.push_back(r); + } + port->AddMutualReqs(mreqs); + } + } else { + double qty_order = core.space() + fresh.space(); + std::vector*> mreqs; + for (int i = 0; i < fuel_incommods.size(); i++) { + std::string commod = fuel_incommods[i]; + double pref = fuel_prefs[i]; + Composition::Ptr recipe = context()->GetRecipe(fuel_inrecipes[i]); + m = Material::CreateUntracked(qty_order, recipe); + Request* r = port->AddRequest(m, this, commod, pref); + mreqs.push_back(r); + } + port->AddMutualReqs(mreqs); + } + + ports.insert(port); + return ports; +} + +void Reactor::AcceptMatlTrades( + const std::vector< std::pair, + Material::Ptr> >& responses) { + + std::vector< std::pair, + cyclus::Material::Ptr> >::const_iterator trade; + + for (trade = responses.begin(); trade != responses.end(); ++trade) { + std::string commod = trade->first.request->commodity(); + Material::Ptr m = trade->second; + index_res(m, commod); + + if (core.space() >= m->quantity()) { + // discrete or continuous mode with enough room in core for entire mat + core.Push(m); + } else if (!discrete_mode()) { + // continuous mode and must split material between core and fresh bufs + Material::Ptr m2 = m->ExtractQty(core.space()); + index_res(m2, commod); + core.Push(m2); + fresh.Push(m); + } else { + // discrete mode and no room in core + fresh.Push(m); + } + } +} void Reactor::Tock() { cycle_step++; @@ -50,6 +119,9 @@ void Reactor::Tock() { void Reactor::Transmute() { MatVec old; + // we don't need min(assem_per_discharge()..., core.quantity()) because + // this function is+should only be called at the end of an operational cycle - + // which can only happen if the core is full. if (discrete_mode()) { old = core.PopN(assem_per_discharge()); } else { @@ -66,16 +138,18 @@ void Reactor::Transmute() { } bool Reactor::Discharge() { - double qty_pop = assem_per_discharge() * assem_size; + // we do need min's here in case we ever decide to discharge non-fully + // batches from a core (e.g. discharge entire core at decommissioning). + double qty_pop = std::min(assem_per_discharge() * assem_size, core.quantity()); if (spent.space() < qty_pop) { return false; // not enough space in spent fuel inventory } if (discrete_mode()) { - spent.Push(core.PopN(assem_per_discharge())); + int npop = std::min((int)assem_per_discharge(), core.count()); + spent.Push(core.PopN(npop)); } else { - // Transmute already discretized the batch to extract into a single object - spent.Push(core.Pop()); + spent.Push(core.Pop(qty_pop)); } return true; } @@ -87,11 +161,7 @@ void Reactor::Load() { if (discrete_mode()) { while (core.space() > assem_size && fresh.quantity() >= assem_size) { - if (integral_assem) { - core.Push(fresh.Pop()); - } else { - core.Push(fresh.Pop(assem_size)); - } + core.Push(fresh.Pop()); } } else { core.Push(fresh.Pop(std::min(core.space(), fresh.quantity()))); @@ -146,5 +216,15 @@ double Reactor::fuel_pref(Material::Ptr m) { return fuel_prefs[i]; } +void Reactor::index_res(cyclus::Resource::Ptr m, std::string incommod) { + for (int i = 0; i < fuel_incommods.size(); i++) { + if (fuel_incommods[i] == incommod) { + res_indexes[m->obj_id()] = i; + return; + } + } + throw ValueError("cycamore::Reactor - received unsupported incommod material"); +} + } // namespace cycamore diff --git a/src/reactor.h b/src/reactor.h index fedfd347ff..a310cf2ea3 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -19,13 +19,6 @@ namespace cycamore { // * n_assem_fresh (int, default n_assem_core) - the number of fresh assemblies to keep on // hand // -// * integral_assem (bool, default true) - true if requests require DRE to -// match all or nothing of each assembly. Note that this is different from -// and roughly orthogonal to whether the reactor is operating in discrete or -// continuous assembly mode. “True” is the recommended value for this -// variable. “False” can result in materials being combined resulting in -// incorrect transmutations. -// // The Reactor will have 3 resource buffers (all with automatically computed // capacities based on above params): // @@ -44,16 +37,13 @@ namespace cycamore { // * There is no room in the spent_fuel buffer to discharge a fully-burned assembly to. // // If a reactor is operating in discrete assembly mode, when it receives fresh -// fuel, it discretizes the material into assembly quanta (of size +// fuel, it only requests and accepts material in discrete assembly quanta (of size // assem_size). Discrete assembly mode is the recommended mode of operation // for a reactor. If a partial assembly is received, it is stored until // enough material can be acquired to complete the full assembly. In this // mode, partial assemblies may not be inserted into the core. When in this // mode, resources will never be split/combined by the reactor post assembly -// discretization. If integral_assem is false, then this discretization will -// happen upon extraction of an assembly’s worth of material from the fresh -// inventory for placement into the core. If integral_assem is true, then -// this discretization will happen automatically as part of resource exchange. +// discretization. // Under either of the following conditions, a reactor will operate in // discrete assembly mode: // @@ -65,27 +55,20 @@ namespace cycamore { // n_batches), then the reactor will operate in continuous assembly mode. In // this mode it discharges 1 / n_batches fraction of the single assembly from // the core at the end of each cycle, and the same quantity will be -// extracted/split from the (not assembly discretized) fresh fresh fuel buffer -// (or requested on DRE if no fresh) and inserted into the core. +// extracted/split from the (not assembly discretized) fresh fuel buffer +// (or requested on DRE if no fresh) and inserted into the core. Material can +// be requested+accepted in non-assembly sized quanta. // // Time to make it code generatable? - Yes Bring into compliance? - Yes. // The BatchReactor currently has no state variables. A UINT type might be // useful here. We should scavenge the batch reactor for pieces as we // reimplement a new code-generated version. // -// * integral_assem == true, discrete assembly mode - discretization is automatic - Pop() from fresh buffer. -// -// * integral_assem == false, discrete assembly mode - discretization upon extraction from fresh buffer. Just ExtractQty from fresh buffer -// -// * integral_assem == true, continuous assembly mode - discretization doesn’t matter. Just ExtractQty from fresh buffer. -// -// * integral_assem == false, continuous assembly mode - discretization doesn’t matter. Just ExtractQty from fresh buffer. -// // Meta-data associated with resource objects in inventory (e.g. the in-commod // on which they were received) should be associated with resources based on -// obj_id. This is necessary for handling the case where integral_assem is -// true in discrete assembly mode where resources are combined inside buffers -// during extraction. +// obj_id. This is necessary for handling the case where in continuous +// assembly mode where resources are potentially combined/split inside +// buffers during extraction - and also when decay could change Resource::id. class Reactor : public cyclus::Facility { public: @@ -96,6 +79,12 @@ class Reactor : public cyclus::Facility { virtual void Tick(); virtual void Tock(); + void AcceptMatlTrades( + const std::vector< std::pair, + cyclus::Material::Ptr> >& responses); + + std::set::Ptr> GetMatlRequests(); + #pragma cyclus private: @@ -105,6 +94,9 @@ class Reactor : public cyclus::Facility { std::string fuel_outrecipe(cyclus::Material::Ptr m); double fuel_pref(cyclus::Material::Ptr m); + /// Store fuel info index for the given resource received on incommod. + void index_res(cyclus::Resource::Ptr m, std::string incommod); + /// Returns true if the reactor is operating in discrete assembly mode. bool discrete_mode() {return n_assem_core > 1 || n_batches == 1;}; @@ -112,7 +104,7 @@ class Reactor : public cyclus::Facility { /// inventory. Returns true if a batch was successfully discharged. bool Discharge(); - /// Top up core inventory if possible. + /// Top up core inventory as much as possible. void Load(); /// Transmute the batch in the core that is about to be discharged to its @@ -122,48 +114,72 @@ class Reactor : public cyclus::Facility { double assem_per_discharge(); // inventory and core params - #pragma cyclus var {} + #pragma cyclus var { \ + "doc": "", \ + } double n_batches; - #pragma cyclus var {} + #pragma cyclus var { \ + "doc": "", \ + } double assem_size; - #pragma cyclus var {"default": 1} - bool integral_assem; - #pragma cyclus var {"default": 'n_batches'} + #pragma cyclus var { \ + "default": "n_batches", \ + } int n_assem_core; - #pragma cyclus var {"default": 1000000000} - int n_assem_spent; - #pragma cyclus var {"default": 'n_assem_core'} - int n_assem_fresh; + #pragma cyclus var { \ + "default": 1000000000, \ + } + int n_batch_spent; + #pragma cyclus var { \ + "default": 1, \ + } + int n_batch_fresh; // cycle params - #pragma cyclus var {} + #pragma cyclus var { \ + "doc": "", \ + } int cycle_time; - #pragma cyclus var {} + #pragma cyclus var { \ + "doc": "", \ + } int refuel_time; #pragma cyclus var { \ "default": 0, \ - "doc": "number of time steps since the beginning of the last cycle", \ + "doc": "Number of time steps since the beginning of the last cycle.", \ } int cycle_step; // fuel specifications #pragma cyclus var { \ "uitype": ["oneormore", "incommodity"], \ + "doc": "Ordered list of input commodities for requesting fuel.", \ } std::vector fuel_incommods; #pragma cyclus var { \ "uitype": ["oneormore", "recipe"], \ + "doc": "Fresh fuel recipes to request for each of the given fuel_incommods (same order).", \ } std::vector fuel_inrecipes; #pragma cyclus var { \ "uitype": ["oneormore", "recipe"], \ + "doc": "Spent fuel recipes corresponding to the given fuel_incommods (by order)." \ + " Fuel received via a particular incommod is transmuted to the recipe specified" \ + " here after being burned during a cycle.", \ } std::vector fuel_outrecipes; #pragma cyclus var { \ "uitype": ["oneormore", "incommodity"], \ + "doc": "Output commodities on which to offer spent fuel for each of the given" \ + " incommods (same order)." \ } std::vector fuel_outcommods; - #pragma cyclus var {"default": []} // if this is empty, assume zero for all + #pragma cyclus var { \ + "default": [], \ + "doc": "The preference for each type of fresh fuel requested via the given" \ + " incommods (same order). If no preferences are specified, zero is" \ + " used for all fuel requests.", \ + } std::vector fuel_prefs; // This variable should be hidden/unavailable in ui. Maps resource object @@ -171,30 +187,45 @@ class Reactor : public cyclus::Facility { #pragma cyclus var {} std::map res_indexes; - // Resource inventories - #pragma cyclus var {'capacity': 'n_assem_fresh * assem_size'} + // Resource inventories - these must be defined AFTER/BELOW the member vars + // referenced (e.g. n_batch_fresh, assem_size, etc.). + #pragma cyclus var {"capacity": "assem_per_discharge() * assem_size * n_batch_fresh"} cyclus::toolkit::ResBuf fresh; - #pragma cyclus var {'capacity': 'n_assem_core * assem_size'} + #pragma cyclus var {"capacity": "n_assem_core * assem_size"} cyclus::toolkit::ResBuf core; - #pragma cyclus var {'capacity': 'n_assem_spent * assem_size'} + #pragma cyclus var {"capacity": "assem_per_discharge() * assem_size * n_batch_spent"} cyclus::toolkit::ResBuf spent; // preference changes - #pragma cyclus var {"default": []} + #pragma cyclus var { \ + "default": [], \ + } std::vector pref_change_times; - #pragma cyclus var {"default": []} + #pragma cyclus var { \ + "default": [], \ + } std::vector pref_change_commods; - #pragma cyclus var {"default": []} + #pragma cyclus var { \ + "default": [], \ + } std::vector pref_change_values; // recipe changes - #pragma cyclus var {"default": []} + #pragma cyclus var { \ + "default": [], \ + } std::vector recipe_change_times; - #pragma cyclus var {"default": []} + #pragma cyclus var { \ + "default": [], \ + } std::vector recipe_change_commods; - #pragma cyclus var {"default": []} + #pragma cyclus var { \ + "default": [], \ + } std::vector recipe_change_incommods; - #pragma cyclus var {"default": []} + #pragma cyclus var { \ + "default": [], \ + } std::vector recipe_change_outcommods; }; From 33c73c4b95f271b12d0882cbd8a73b4297c39b73 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 8 Jan 2015 15:47:21 -0600 Subject: [PATCH 039/314] implemented bidding. removed continuous assem mode. --- src/reactor.cc | 178 ++++++++++++++++++++++++++++++------------------- src/reactor.h | 33 ++++++--- 2 files changed, 133 insertions(+), 78 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index 415975b90f..fb6121f454 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -6,6 +6,7 @@ using cyclus::toolkit::ResBuf; using cyclus::toolkit::MatVec; using cyclus::KeyError; using cyclus::ValueError; +using cyclus::Request; namespace cycamore { @@ -14,8 +15,8 @@ Reactor::Reactor(cyclus::Context* ctx) n_batches(0), assem_size(0), n_assem_core(0), - n_batch_spent(0), - n_batch_fresh(0), + n_assem_spent(0), + n_assem_fresh(0), cycle_time(0), refuel_time(0), cycle_step(0) { @@ -39,36 +40,21 @@ void Reactor::Tick() { std::set::Ptr> Reactor::GetMatlRequests() { using cyclus::RequestPortfolio; - using cyclus::Request; std::set::Ptr> ports; RequestPortfolio::Ptr port(new RequestPortfolio()); Material::Ptr m; - if (discrete_mode()) { - int n_assem_order = static_cast(core.space() / assem_size) - + static_cast(fresh.space() / assem_size); - for (int i = 0; i < n_assem_order; i++) { - std::vector*> mreqs; - for (int j = 0; j < fuel_incommods.size(); j++) { - std::string commod = fuel_incommods[j]; - double pref = fuel_prefs[j]; - Composition::Ptr recipe = context()->GetRecipe(fuel_inrecipes[j]); - m = Material::CreateUntracked(assem_size, recipe); - Request* r = port->AddRequest(m, this, commod, pref, true); - mreqs.push_back(r); - } - port->AddMutualReqs(mreqs); - } - } else { - double qty_order = core.space() + fresh.space(); + int n_assem_order = n_assem_core - core.count() + + n_assem_fresh - fresh.count(); + for (int i = 0; i < n_assem_order; i++) { std::vector*> mreqs; - for (int i = 0; i < fuel_incommods.size(); i++) { - std::string commod = fuel_incommods[i]; - double pref = fuel_prefs[i]; - Composition::Ptr recipe = context()->GetRecipe(fuel_inrecipes[i]); - m = Material::CreateUntracked(qty_order, recipe); - Request* r = port->AddRequest(m, this, commod, pref); + for (int j = 0; j < fuel_incommods.size(); j++) { + std::string commod = fuel_incommods[j]; + double pref = fuel_prefs[j]; + Composition::Ptr recipe = context()->GetRecipe(fuel_inrecipes[j]); + m = Material::CreateUntracked(assem_size, recipe); + Request* r = port->AddRequest(m, this, commod, pref, true); mreqs.push_back(r); } port->AddMutualReqs(mreqs); @@ -90,51 +76,94 @@ void Reactor::AcceptMatlTrades( Material::Ptr m = trade->second; index_res(m, commod); - if (core.space() >= m->quantity()) { - // discrete or continuous mode with enough room in core for entire mat + if (core.count() < n_assem_core) { core.Push(m); - } else if (!discrete_mode()) { - // continuous mode and must split material between core and fresh bufs - Material::Ptr m2 = m->ExtractQty(core.space()); - index_res(m2, commod); - core.Push(m2); - fresh.Push(m); } else { - // discrete mode and no room in core fresh.Push(m); } } } +std::set::Ptr> +Reactor::GetMatlBids(cyclus::CommodMap::type& + commod_requests) { + using cyclus::BidPortfolio; + + std::set::Ptr> ports; + + for (int i = 0; i < fuel_outcommods.size(); i++) { + std::string commod = fuel_outcommods[i]; + MatVec mats = SpentResFor(commod); + std::vector*>& reqs = commod_requests[commod]; + if (mats.size() == 0 || reqs.size() == 0) { + continue; + } + + BidPortfolio::Ptr port(new BidPortfolio()); + + for (int j = 0; j < reqs.size(); j++) { + Request* req = reqs[j]; + double tot_bid = 0; + for (int k = 0; k < mats.size(); k++) { + Material::Ptr m = mats[k]; + tot_bid += m->quantity(); + port->AddBid(req, m, this, true); + if (tot_bid >= req->target()->quantity()) { + break; + } + } + } + + double tot_qty = 0; + for (int j = 0; j < mats.size(); j++) { + tot_qty += mats[j]->quantity(); + } + cyclus::CapacityConstraint cc(tot_qty); + port->AddConstraint(cc); + ports.insert(port); + } + + return ports; +} + +void Reactor::GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + Material::Ptr> >& responses) { + using cyclus::Trade; + + std::vector< cyclus::Trade >::const_iterator it; + for (int i = 0; i < trades.size(); i++) { + std::string commod = trades[i].request->commodity(); + Material::Ptr m = PopSpentRes(commod); + responses.push_back(std::make_pair(trades[i], m)); + res_indexes.erase(m->obj_id()); + } +} + void Reactor::Tock() { cycle_step++; if (cycle_step >= cycle_time) { Load(); } - if (cycle_step > cycle_time + refuel_time && core.space() < cyclus::eps()) { + if (cycle_step > cycle_time + refuel_time && core.count() == n_assem_core) { cycle_step = 0; } } void Reactor::Transmute() { - MatVec old; // we don't need min(assem_per_discharge()..., core.quantity()) because // this function is+should only be called at the end of an operational cycle - // which can only happen if the core is full. - if (discrete_mode()) { - old = core.PopN(assem_per_discharge()); - } else { - old.push_back(core.Pop(assem_per_discharge() * assem_size)); - } + MatVec old = core.PopN(assem_per_discharge()); + MatVec tail = core.PopN(core.count()); + core.Push(old); + core.Push(tail); for (int i = 0; i < old.size(); i++) { old[i]->Transmute(context()->GetRecipe(fuel_outrecipe(old[i]))); } - - MatVec tail = core.PopN(core.count()); - core.Push(old); - core.Push(tail); } bool Reactor::Discharge() { @@ -145,35 +174,19 @@ bool Reactor::Discharge() { return false; // not enough space in spent fuel inventory } - if (discrete_mode()) { - int npop = std::min((int)assem_per_discharge(), core.count()); - spent.Push(core.PopN(npop)); - } else { - spent.Push(core.Pop(qty_pop)); - } + int npop = std::min(assem_per_discharge(), core.count()); + spent.Push(core.PopN(npop)); return true; } void Reactor::Load() { - if (core.space() < cyclus::eps()) { - return; // core is full - } - - if (discrete_mode()) { - while (core.space() > assem_size && fresh.quantity() >= assem_size) { - core.Push(fresh.Pop()); - } - } else { - core.Push(fresh.Pop(std::min(core.space(), fresh.quantity()))); + while (core.count() < n_assem_core && fresh.count() > 0) { + core.Push(fresh.Pop()); } } -double Reactor::assem_per_discharge() { - if (discrete_mode()) { - return static_cast(n_assem_core / n_batches); - } else { - return static_cast(n_assem_core) / n_batches; - } +int Reactor::assem_per_discharge() { + return static_cast(n_assem_core / n_batches); } std::string Reactor::fuel_incommod(Material::Ptr m) { @@ -225,6 +238,35 @@ void Reactor::index_res(cyclus::Resource::Ptr m, std::string incommod) { } throw ValueError("cycamore::Reactor - received unsupported incommod material"); } + +Material::Ptr Reactor::PopSpentRes(std::string outcommod) { + MatVec mats = spent.PopN(spent.count()); + Material::Ptr m; + bool found = false; + for (int i = 0; i < mats.size(); i++) { + std::string commod = fuel_outcommod(mats[i]); + if (!found && commod == outcommod) { + m = mats[i]; + found = true; + } else { + spent.Push(mats[i]); + } + } + return m; +} +MatVec Reactor::SpentResFor(std::string outcommod) { + MatVec mats = spent.PopN(spent.count()); + MatVec found; + spent.Push(mats); + for (int i = 0; i < mats.size(); i++) { + std::string commod = fuel_outcommod(mats[i]); + if (commod == outcommod) { + found.push_back(mats[i]); + } + } + return found; +} + } // namespace cycamore diff --git a/src/reactor.h b/src/reactor.h index a310cf2ea3..e5e51ff041 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -85,6 +85,15 @@ class Reactor : public cyclus::Facility { std::set::Ptr> GetMatlRequests(); + virtual std::set::Ptr> + GetMatlBids(cyclus::CommodMap::type& + commod_requests); + + virtual void GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses); + #pragma cyclus private: @@ -111,9 +120,13 @@ class Reactor : public cyclus::Facility { /// fully burnt state as defined by its outrecipe. void Transmute(); - double assem_per_discharge(); + int assem_per_discharge(); + + cyclus::toolkit::MatVec SpentResFor(std::string outcommod); + + cyclus::Material::Ptr PopSpentRes(std::string outcommod); - // inventory and core params + //////////// inventory and core params //////////// #pragma cyclus var { \ "doc": "", \ } @@ -129,13 +142,13 @@ class Reactor : public cyclus::Facility { #pragma cyclus var { \ "default": 1000000000, \ } - int n_batch_spent; + int n_assem_spent; #pragma cyclus var { \ "default": 1, \ } - int n_batch_fresh; + int n_assem_fresh; - // cycle params + ///////// cycle params /////////// #pragma cyclus var { \ "doc": "", \ } @@ -150,7 +163,7 @@ class Reactor : public cyclus::Facility { } int cycle_step; - // fuel specifications + /////// fuel specifications ///////// #pragma cyclus var { \ "uitype": ["oneormore", "incommodity"], \ "doc": "Ordered list of input commodities for requesting fuel.", \ @@ -189,14 +202,14 @@ class Reactor : public cyclus::Facility { // Resource inventories - these must be defined AFTER/BELOW the member vars // referenced (e.g. n_batch_fresh, assem_size, etc.). - #pragma cyclus var {"capacity": "assem_per_discharge() * assem_size * n_batch_fresh"} + #pragma cyclus var {"capacity": "n_assem_fresh * assem_size"} cyclus::toolkit::ResBuf fresh; #pragma cyclus var {"capacity": "n_assem_core * assem_size"} cyclus::toolkit::ResBuf core; - #pragma cyclus var {"capacity": "assem_per_discharge() * assem_size * n_batch_spent"} + #pragma cyclus var {"capacity": "n_assem_spent * assem_size"} cyclus::toolkit::ResBuf spent; - // preference changes + /////////// preference changes /////////// #pragma cyclus var { \ "default": [], \ } @@ -210,7 +223,7 @@ class Reactor : public cyclus::Facility { } std::vector pref_change_values; - // recipe changes + ///////////// recipe changes /////////// #pragma cyclus var { \ "default": [], \ } From 7a71355a1b33871c8237f61491e64202ea3fc200 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 8 Jan 2015 16:19:40 -0600 Subject: [PATCH 040/314] udpate comments --- src/reactor.h | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/src/reactor.h b/src/reactor.h index e5e51ff041..0ccb200487 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -22,7 +22,7 @@ namespace cycamore { // The Reactor will have 3 resource buffers (all with automatically computed // capacities based on above params): // -// * fresh: capacity = n_assem_fresh * assem_size +// * fresh: capacity = n_assem_fresh * assem_size + eps // // * core: capacity = n_assem_core * assem_size // @@ -43,32 +43,18 @@ namespace cycamore { // enough material can be acquired to complete the full assembly. In this // mode, partial assemblies may not be inserted into the core. When in this // mode, resources will never be split/combined by the reactor post assembly -// discretization. -// Under either of the following conditions, a reactor will operate in -// discrete assembly mode: +// discretization. Number of assemblies discharged per cycle is computed: // -// * n_assem_core == n_batches: pop one assembly per cycle +// floor(n_assem_core / n_batches) // -// * n_assem_core > 1: pop floor(n_assem_core / n_batches) assemblies per cycle -// -// If neither of those conditions are met (i.e. n_assem_core == 1 && n_assem_core != -// n_batches), then the reactor will operate in continuous assembly mode. In -// this mode it discharges 1 / n_batches fraction of the single assembly from -// the core at the end of each cycle, and the same quantity will be -// extracted/split from the (not assembly discretized) fresh fuel buffer -// (or requested on DRE if no fresh) and inserted into the core. Material can -// be requested+accepted in non-assembly sized quanta. -// -// Time to make it code generatable? - Yes Bring into compliance? - Yes. -// The BatchReactor currently has no state variables. A UINT type might be -// useful here. We should scavenge the batch reactor for pieces as we -// reimplement a new code-generated version. +// If that number is zero or results in a significantly rounded batch size, +// the reactor will throw an exception or print a warning respectively. // // Meta-data associated with resource objects in inventory (e.g. the in-commod // on which they were received) should be associated with resources based on -// obj_id. This is necessary for handling the case where in continuous -// assembly mode where resources are potentially combined/split inside -// buffers during extraction - and also when decay could change Resource::id. +// obj_id. This is necessary for maintaining continuity in the face of +// potential decay calcs and other things that might change the regular +// Resource::id. class Reactor : public cyclus::Facility { public: From 435f722fc8ba3cf3f4af7e42bb904c38148346e3 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 9 Jan 2015 10:26:15 -0600 Subject: [PATCH 041/314] implement pref and recipe changing --- src/reactor.cc | 31 +++++++++++++++++++++++++++++++ src/reactor.h | 7 ++----- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index fb6121f454..623f6765ed 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -31,10 +31,41 @@ void Reactor::Tick() { Discharge(); Load(); } + + int t = context()->time(); // update preferences + for (int i = 0; i < pref_change_times.size(); i++) { + int change_t = pref_change_times[i]; + if (t != change_t) { + continue; + } + + std::string incommod = pref_change_commods[i]; + for (int j = 0; j < fuel_incommods.size(); j++) { + if (fuel_incommods[j] == incommod) { + fuel_prefs[j] = pref_change_values[i]; + break; + } + } + } // update recipes + for (int i = 0; i < recipe_change_times.size(); i++) { + int change_t = recipe_change_times[i]; + if (t != change_t) { + continue; + } + + std::string incommod = recipe_change_commods[i]; + for (int j = 0; j < fuel_incommods.size(); j++) { + if (fuel_incommods[j] == incommod) { + fuel_inrecipes[j] = recipe_change_in[i]; + fuel_outrecipes[j] = recipe_change_out[i]; + break; + } + } + } } std::set::Ptr> diff --git a/src/reactor.h b/src/reactor.h index 0ccb200487..b0fa6483e7 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -92,9 +92,6 @@ class Reactor : public cyclus::Facility { /// Store fuel info index for the given resource received on incommod. void index_res(cyclus::Resource::Ptr m, std::string incommod); - /// Returns true if the reactor is operating in discrete assembly mode. - bool discrete_mode() {return n_assem_core > 1 || n_batches == 1;}; - /// Discharge a batch from the core if there is room in the spent fuel /// inventory. Returns true if a batch was successfully discharged. bool Discharge(); @@ -221,11 +218,11 @@ class Reactor : public cyclus::Facility { #pragma cyclus var { \ "default": [], \ } - std::vector recipe_change_incommods; + std::vector recipe_change_in; #pragma cyclus var { \ "default": [], \ } - std::vector recipe_change_outcommods; + std::vector recipe_change_out; }; From 46593f0709464898c6b351e729856640d2dbf95e Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 9 Jan 2015 12:16:03 -0600 Subject: [PATCH 042/314] change from double n_batches paradigm to int n_assem_batch --- src/reactor.cc | 14 +++++--------- src/reactor.h | 8 +++----- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index 623f6765ed..b4265edd65 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -12,7 +12,7 @@ namespace cycamore { Reactor::Reactor(cyclus::Context* ctx) : cyclus::Facility(ctx), - n_batches(0), + n_assem_batch(0), assem_size(0), n_assem_core(0), n_assem_spent(0), @@ -184,10 +184,10 @@ void Reactor::Tock() { } void Reactor::Transmute() { - // we don't need min(assem_per_discharge()..., core.quantity()) because + // we don't need min(n_assem_batch * assem_size, core.quantity()) because // this function is+should only be called at the end of an operational cycle - // which can only happen if the core is full. - MatVec old = core.PopN(assem_per_discharge()); + MatVec old = core.PopN(n_assem_batch); MatVec tail = core.PopN(core.count()); core.Push(old); core.Push(tail); @@ -200,12 +200,12 @@ void Reactor::Transmute() { bool Reactor::Discharge() { // we do need min's here in case we ever decide to discharge non-fully // batches from a core (e.g. discharge entire core at decommissioning). - double qty_pop = std::min(assem_per_discharge() * assem_size, core.quantity()); + double qty_pop = std::min(n_assem_batch * assem_size, core.quantity()); if (spent.space() < qty_pop) { return false; // not enough space in spent fuel inventory } - int npop = std::min(assem_per_discharge(), core.count()); + int npop = std::min(n_assem_batch, core.count()); spent.Push(core.PopN(npop)); return true; } @@ -216,10 +216,6 @@ void Reactor::Load() { } } -int Reactor::assem_per_discharge() { - return static_cast(n_assem_core / n_batches); -} - std::string Reactor::fuel_incommod(Material::Ptr m) { int i = res_indexes[m->obj_id()]; if (i >= fuel_incommods.size()) { diff --git a/src/reactor.h b/src/reactor.h index b0fa6483e7..bb1cf9e757 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -103,8 +103,6 @@ class Reactor : public cyclus::Facility { /// fully burnt state as defined by its outrecipe. void Transmute(); - int assem_per_discharge(); - cyclus::toolkit::MatVec SpentResFor(std::string outcommod); cyclus::Material::Ptr PopSpentRes(std::string outcommod); @@ -113,13 +111,13 @@ class Reactor : public cyclus::Facility { #pragma cyclus var { \ "doc": "", \ } - double n_batches; + int n_assem_batch; #pragma cyclus var { \ "doc": "", \ } double assem_size; #pragma cyclus var { \ - "default": "n_batches", \ + "doc": "", \ } int n_assem_core; #pragma cyclus var { \ @@ -127,7 +125,7 @@ class Reactor : public cyclus::Facility { } int n_assem_spent; #pragma cyclus var { \ - "default": 1, \ + "default": 0, \ } int n_assem_fresh; From 3c26f99918ec1257a4cd1361ddd1647102821dde Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 9 Jan 2015 12:54:02 -0600 Subject: [PATCH 043/314] fix empty portfolio bug --- src/reactor.cc | 10 ++++++++++ src/reactor.h | 7 +++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index b4265edd65..fa617519ae 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -78,6 +78,10 @@ Reactor::GetMatlRequests() { int n_assem_order = n_assem_core - core.count() + n_assem_fresh - fresh.count(); + if (n_assem_order == 0) { + return ports; + } + for (int i = 0; i < n_assem_order; i++) { std::vector*> mreqs; for (int j = 0; j < fuel_incommods.size(); j++) { @@ -149,6 +153,8 @@ Reactor::GetMatlBids(cyclus::CommodMap::type& for (int j = 0; j < mats.size(); j++) { tot_qty += mats[j]->quantity(); } + std::cout << "mats.size() = " << mats.size() << "\n"; + std::cout << "tot_qty = " << tot_qty << "\n"; cyclus::CapacityConstraint cc(tot_qty); port->AddConstraint(cc); ports.insert(port); @@ -295,5 +301,9 @@ MatVec Reactor::SpentResFor(std::string outcommod) { return found; } +extern "C" cyclus::Agent* ConstructReactor(cyclus::Context* ctx) { + return new Reactor(ctx); +} + } // namespace cycamore diff --git a/src/reactor.h b/src/reactor.h index bb1cf9e757..c864f71185 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -61,7 +61,6 @@ class Reactor : public cyclus::Facility { Reactor(cyclus::Context* ctx); virtual ~Reactor() {}; - virtual void EnterNotify() {}; virtual void Tick(); virtual void Tock(); @@ -178,9 +177,13 @@ class Reactor : public cyclus::Facility { // This variable should be hidden/unavailable in ui. Maps resource object // id's to the index for the incommod through which they were received. - #pragma cyclus var {} + #pragma cyclus var {"default": {}} std::map res_indexes; + // TODO: do we need this? + std::vector init_core_fuel; + std::vector init_core_assem; + // Resource inventories - these must be defined AFTER/BELOW the member vars // referenced (e.g. n_batch_fresh, assem_size, etc.). #pragma cyclus var {"capacity": "n_assem_fresh * assem_size"} From 5c63a595dc8bc77d1508abb7e6caadb9e99d460a Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 9 Jan 2015 14:16:50 -0600 Subject: [PATCH 044/314] fix bugs --- src/reactor.cc | 35 ++++++++++++++++++++++++----------- src/reactor.h | 2 +- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index fa617519ae..76fc8950af 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -27,7 +27,8 @@ Reactor::Reactor(cyclus::Context* ctx) void Reactor::Tick() { if (cycle_step == cycle_time) { Transmute(); - } else if (cycle_step == cycle_time + refuel_time) { + } + if (cycle_step == cycle_time + refuel_time) { Discharge(); Load(); } @@ -153,8 +154,6 @@ Reactor::GetMatlBids(cyclus::CommodMap::type& for (int j = 0; j < mats.size(); j++) { tot_qty += mats[j]->quantity(); } - std::cout << "mats.size() = " << mats.size() << "\n"; - std::cout << "tot_qty = " << tot_qty << "\n"; cyclus::CapacityConstraint cc(tot_qty); port->AddConstraint(cc); ports.insert(port); @@ -179,20 +178,35 @@ void Reactor::GetMatlTrades( } void Reactor::Tock() { - cycle_step++; + // "if" prevents starting cycle after initial deployment until core is full + // even though cycle_step is its initial zero. + if (cycle_step > 0 || core.count() == n_assem_core) { + cycle_step++; + } + + // The following "if" is necessary here if cycle_time+refuel_time = 1 in + // case we didn't have a full core in the Tick, but we got enough during + // resource exchange. In this case, we want to still burn a batch this + // timestep - and every time step as long as fuel can be received. + if (cycle_step == 1 && refuel_time == 0) { + Transmute(); + Discharge(); + } if (cycle_step >= cycle_time) { Load(); } - if (cycle_step > cycle_time + refuel_time && core.count() == n_assem_core) { + + if (cycle_step >= cycle_time + refuel_time && core.count() == n_assem_core) { cycle_step = 0; } } void Reactor::Transmute() { - // we don't need min(n_assem_batch * assem_size, core.quantity()) because - // this function is+should only be called at the end of an operational cycle - - // which can only happen if the core is full. + if (core.count() < n_assem_core) { + return; + } + MatVec old = core.PopN(n_assem_batch); MatVec tail = core.PopN(core.count()); core.Push(old); @@ -217,9 +231,8 @@ bool Reactor::Discharge() { } void Reactor::Load() { - while (core.count() < n_assem_core && fresh.count() > 0) { - core.Push(fresh.Pop()); - } + int n = std::min(n_assem_core - core.count(), fresh.count()); + core.Push(fresh.PopN(n)); } std::string Reactor::fuel_incommod(Material::Ptr m) { diff --git a/src/reactor.h b/src/reactor.h index c864f71185..14f873a12c 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -138,7 +138,7 @@ class Reactor : public cyclus::Facility { } int refuel_time; #pragma cyclus var { \ - "default": 0, \ + "default": "cycle_time + refuel_time + 1", \ "doc": "Number of time steps since the beginning of the last cycle.", \ } int cycle_step; From 63f35491105892486267c60e34b3fc96538ca5fc Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 9 Jan 2015 15:34:31 -0600 Subject: [PATCH 045/314] fix cycle step handling and simplify --- src/reactor.cc | 43 ++++++++++++++----------------------------- src/reactor.h | 7 ++++++- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index 76fc8950af..510cfa9f75 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -19,20 +19,13 @@ Reactor::Reactor(cyclus::Context* ctx) n_assem_fresh(0), cycle_time(0), refuel_time(0), - cycle_step(0) { + cycle_step(0), + discharged(false) { cyclus::Warn("the Reactor archetype " "is experimental"); } void Reactor::Tick() { - if (cycle_step == cycle_time) { - Transmute(); - } - if (cycle_step == cycle_time + refuel_time) { - Discharge(); - Load(); - } - int t = context()->time(); // update preferences @@ -178,35 +171,30 @@ void Reactor::GetMatlTrades( } void Reactor::Tock() { + if (cycle_step >= cycle_time + refuel_time && core.count() == n_assem_core) { + discharged = false; + cycle_step = 0; + } + // "if" prevents starting cycle after initial deployment until core is full // even though cycle_step is its initial zero. if (cycle_step > 0 || core.count() == n_assem_core) { cycle_step++; } - // The following "if" is necessary here if cycle_time+refuel_time = 1 in - // case we didn't have a full core in the Tick, but we got enough during - // resource exchange. In this case, we want to still burn a batch this - // timestep - and every time step as long as fuel can be received. - if (cycle_step == 1 && refuel_time == 0) { + if (cycle_step == cycle_time) { Transmute(); - Discharge(); } - + if (cycle_step >= cycle_time && !discharged) { + discharged = Discharge(); + } if (cycle_step >= cycle_time) { Load(); } - - if (cycle_step >= cycle_time + refuel_time && core.count() == n_assem_core) { - cycle_step = 0; - } } void Reactor::Transmute() { - if (core.count() < n_assem_core) { - return; - } - + // safe to assume full core. MatVec old = core.PopN(n_assem_batch); MatVec tail = core.PopN(core.count()); core.Push(old); @@ -218,11 +206,8 @@ void Reactor::Transmute() { } bool Reactor::Discharge() { - // we do need min's here in case we ever decide to discharge non-fully - // batches from a core (e.g. discharge entire core at decommissioning). - double qty_pop = std::min(n_assem_batch * assem_size, core.quantity()); - if (spent.space() < qty_pop) { - return false; // not enough space in spent fuel inventory + if (n_assem_spent - spent.count() < n_assem_batch) { + return false; // not enough room in spent buffer } int npop = std::min(n_assem_batch, core.count()); diff --git a/src/reactor.h b/src/reactor.h index 14f873a12c..9d6bce0b53 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -138,7 +138,7 @@ class Reactor : public cyclus::Facility { } int refuel_time; #pragma cyclus var { \ - "default": "cycle_time + refuel_time + 1", \ + "default": 0, \ "doc": "Number of time steps since the beginning of the last cycle.", \ } int cycle_step; @@ -193,6 +193,7 @@ class Reactor : public cyclus::Facility { #pragma cyclus var {"capacity": "n_assem_spent * assem_size"} cyclus::toolkit::ResBuf spent; + /////////// preference changes /////////// #pragma cyclus var { \ "default": [], \ @@ -225,6 +226,10 @@ class Reactor : public cyclus::Facility { } std::vector recipe_change_out; + // should be hidden in ui (internal only). True if fuel has been discharged + // this cycle. + #pragma cyclus var {"default": 0} + bool discharged; }; } // namespace cycamore From 049527b06d9d5f3cadb51570a1f454b911bcd2fa Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 9 Jan 2015 16:17:16 -0600 Subject: [PATCH 046/314] add amazing event logging to output db --- src/reactor.cc | 35 +++++++++++++++++++++++++++++++++++ src/reactor.h | 3 +++ 2 files changed, 38 insertions(+) diff --git a/src/reactor.cc b/src/reactor.cc index 510cfa9f75..023d4a958c 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -100,6 +100,11 @@ void Reactor::AcceptMatlTrades( std::vector< std::pair, cyclus::Material::Ptr> >::const_iterator trade; + std::stringstream ss; + ss << "LOAD: " << std::min((int)responses.size(), n_assem_core - core.count()) + << " assemblies"; + Record(ss.str()); + for (trade = responses.begin(); trade != responses.end(); ++trade) { std::string commod = trade->first.request->commodity(); Material::Ptr m = trade->second; @@ -176,6 +181,10 @@ void Reactor::Tock() { cycle_step = 0; } + if (cycle_step == 0 && core.count() == n_assem_core) { + Record("CYCLE: start"); + } + // "if" prevents starting cycle after initial deployment until core is full // even though cycle_step is its initial zero. if (cycle_step > 0 || core.count() == n_assem_core) { @@ -184,6 +193,7 @@ void Reactor::Tock() { if (cycle_step == cycle_time) { Transmute(); + Record("CYCLE: end"); } if (cycle_step >= cycle_time && !discharged) { discharged = Discharge(); @@ -200,6 +210,10 @@ void Reactor::Transmute() { core.Push(old); core.Push(tail); + std::stringstream ss; + ss << "TRANSMUTE: " << old.size() << " assemblies"; + Record(ss.str()); + for (int i = 0; i < old.size(); i++) { old[i]->Transmute(context()->GetRecipe(fuel_outrecipe(old[i]))); } @@ -207,16 +221,29 @@ void Reactor::Transmute() { bool Reactor::Discharge() { if (n_assem_spent - spent.count() < n_assem_batch) { + Record("DISCHARGE: failed"); return false; // not enough room in spent buffer } int npop = std::min(n_assem_batch, core.count()); + + std::stringstream ss; + ss << "DISCHARGE: " << npop << " assemblies"; + Record(ss.str()); + spent.Push(core.PopN(npop)); return true; } void Reactor::Load() { int n = std::min(n_assem_core - core.count(), fresh.count()); + if (n == 0) { + return; + } + + std::stringstream ss; + ss << "LOAD: " << n << " assemblies"; + Record(ss.str()); core.Push(fresh.PopN(n)); } @@ -299,6 +326,14 @@ MatVec Reactor::SpentResFor(std::string outcommod) { return found; } +void Reactor::Record(std::string name) { + context()->NewDatum("ReactorEvents") + ->AddVal("AgentId", id()) + ->AddVal("Time", context()->time()) + ->AddVal("Event", name) + ->Record(); +} + extern "C" cyclus::Agent* ConstructReactor(cyclus::Context* ctx) { return new Reactor(ctx); } diff --git a/src/reactor.h b/src/reactor.h index 9d6bce0b53..67f413f146 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -102,6 +102,9 @@ class Reactor : public cyclus::Facility { /// fully burnt state as defined by its outrecipe. void Transmute(); + /// record a reactor event + void Record(std::string name); + cyclus::toolkit::MatVec SpentResFor(std::string outcommod); cyclus::Material::Ptr PopSpentRes(std::string outcommod); From 46ba08006ca48e0a0094f22079b4f8f13568d0eb Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 9 Jan 2015 16:29:34 -0600 Subject: [PATCH 047/314] work around DRE bug --- src/reactor.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index 023d4a958c..6e58519651 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -67,7 +67,6 @@ Reactor::GetMatlRequests() { using cyclus::RequestPortfolio; std::set::Ptr> ports; - RequestPortfolio::Ptr port(new RequestPortfolio()); Material::Ptr m; int n_assem_order = n_assem_core - core.count() @@ -77,6 +76,7 @@ Reactor::GetMatlRequests() { } for (int i = 0; i < n_assem_order; i++) { + RequestPortfolio::Ptr port(new RequestPortfolio()); std::vector*> mreqs; for (int j = 0; j < fuel_incommods.size(); j++) { std::string commod = fuel_incommods[j]; @@ -87,9 +87,9 @@ Reactor::GetMatlRequests() { mreqs.push_back(r); } port->AddMutualReqs(mreqs); + ports.insert(port); } - ports.insert(port); return ports; } From 1b523df31012f1bf5a60e8f658d1d305edb21dbf Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 12 Jan 2015 11:32:44 -0600 Subject: [PATCH 048/314] improve event recording and shift time step/sequence of transmute-discharge-load event into tick --- src/reactor.cc | 54 +++++++++++++++++-------------- src/reactor.h | 86 ++++++++++++++++++++++++++++---------------------- 2 files changed, 80 insertions(+), 60 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index 6e58519651..a12aafa9cb 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -26,6 +26,22 @@ Reactor::Reactor(cyclus::Context* ctx) } void Reactor::Tick() { + // The following code must go in the Tick so they fire on the time step + // following the cycle_step update - allowing for the all reactor events to + // occur and be recorded on the "beginning" of a time step. Another reason they + // can't go at the beginnin of the Tock is so that resource exchange has a + // chance to occur after the discharge on this same time step. + if (cycle_step == cycle_time) { + Transmute(); + Record("CYCLE_END", ""); + } + if (cycle_step >= cycle_time && !discharged) { + discharged = Discharge(); + } + if (cycle_step >= cycle_time) { + Load(); + } + int t = context()->time(); // update preferences @@ -101,9 +117,11 @@ void Reactor::AcceptMatlTrades( cyclus::Material::Ptr> >::const_iterator trade; std::stringstream ss; - ss << "LOAD: " << std::min((int)responses.size(), n_assem_core - core.count()) - << " assemblies"; - Record(ss.str()); + int nload = std::min((int)responses.size(), n_assem_core - core.count()); + if (nload > 0) { + ss << nload << " assemblies"; + Record("LOAD", ss.str()); + } for (trade = responses.begin(); trade != responses.end(); ++trade) { std::string commod = trade->first.request->commodity(); @@ -182,7 +200,7 @@ void Reactor::Tock() { } if (cycle_step == 0 && core.count() == n_assem_core) { - Record("CYCLE: start"); + Record("CYCLE_START", ""); } // "if" prevents starting cycle after initial deployment until core is full @@ -190,17 +208,6 @@ void Reactor::Tock() { if (cycle_step > 0 || core.count() == n_assem_core) { cycle_step++; } - - if (cycle_step == cycle_time) { - Transmute(); - Record("CYCLE: end"); - } - if (cycle_step >= cycle_time && !discharged) { - discharged = Discharge(); - } - if (cycle_step >= cycle_time) { - Load(); - } } void Reactor::Transmute() { @@ -211,8 +218,8 @@ void Reactor::Transmute() { core.Push(tail); std::stringstream ss; - ss << "TRANSMUTE: " << old.size() << " assemblies"; - Record(ss.str()); + ss << old.size() << " assemblies"; + Record("TRANSMUTE", ss.str()); for (int i = 0; i < old.size(); i++) { old[i]->Transmute(context()->GetRecipe(fuel_outrecipe(old[i]))); @@ -221,15 +228,15 @@ void Reactor::Transmute() { bool Reactor::Discharge() { if (n_assem_spent - spent.count() < n_assem_batch) { - Record("DISCHARGE: failed"); + Record("DISCHARGE", "failed"); return false; // not enough room in spent buffer } int npop = std::min(n_assem_batch, core.count()); std::stringstream ss; - ss << "DISCHARGE: " << npop << " assemblies"; - Record(ss.str()); + ss << npop << " assemblies"; + Record("DISCHARGE", ss.str()); spent.Push(core.PopN(npop)); return true; @@ -242,8 +249,8 @@ void Reactor::Load() { } std::stringstream ss; - ss << "LOAD: " << n << " assemblies"; - Record(ss.str()); + ss << n << " assemblies"; + Record("LOAD", ss.str()); core.Push(fresh.PopN(n)); } @@ -326,11 +333,12 @@ MatVec Reactor::SpentResFor(std::string outcommod) { return found; } -void Reactor::Record(std::string name) { +void Reactor::Record(std::string name, std::string val) { context()->NewDatum("ReactorEvents") ->AddVal("AgentId", id()) ->AddVal("Time", context()->time()) ->AddVal("Event", name) + ->AddVal("Value", val) ->Record(); } diff --git a/src/reactor.h b/src/reactor.h index 67f413f146..fc03ca26cb 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -7,10 +7,11 @@ namespace cycamore { // Configurable parameters: // -// * n_batches (double) - the inverse of the core fraction discharged per cycle -// // * assem_size (double) - the mass in kg of a single assembly // +// * n_assem_batch (int) - number of assemblies discharged per batch at the +// end of an operational cycle +// // * n_assem_core (int) - the number of assemblies that constitute a core. // // * n_assem_spent (int, default infinite) - the number of spent fuel assemblies @@ -22,33 +23,25 @@ namespace cycamore { // The Reactor will have 3 resource buffers (all with automatically computed // capacities based on above params): // -// * fresh: capacity = n_assem_fresh * assem_size + eps +// * fresh: capacity = n_assem_fresh * assem_size // // * core: capacity = n_assem_core * assem_size // // * spent: capacity = n_assem_spent * assem_size // // The reactor will always try to keep its fresh_fuel and core buffers full. +// If the fresh fuel buffer has zero capacity (i.e. n_assem_fresh == 0), then +// the reactor will not order new fuel until the next batch is discharged from +// the core - i.e. "just-in-time" ordering. // The cycle progresses/runs only if the reactor is in active operation. The // following conditions result in reactor operation being suspended: // // * There are not enough full assemblies (with unspent life) to provide a full core // -// * There is no room in the spent_fuel buffer to discharge a fully-burned assembly to. -// -// If a reactor is operating in discrete assembly mode, when it receives fresh -// fuel, it only requests and accepts material in discrete assembly quanta (of size -// assem_size). Discrete assembly mode is the recommended mode of operation -// for a reactor. If a partial assembly is received, it is stored until -// enough material can be acquired to complete the full assembly. In this -// mode, partial assemblies may not be inserted into the core. When in this -// mode, resources will never be split/combined by the reactor post assembly -// discretization. Number of assemblies discharged per cycle is computed: +// * There is no room in the spent_fuel buffer to discharge a fully-burned assembly into. // -// floor(n_assem_core / n_batches) -// -// If that number is zero or results in a significantly rounded batch size, -// the reactor will throw an exception or print a warning respectively. +// A reactor only requests and accepts material in discrete assembly quanta (of size +// assem_size). Resources will never be split/combined by the reactor. // // Meta-data associated with resource objects in inventory (e.g. the in-commod // on which they were received) should be associated with resources based on @@ -103,7 +96,7 @@ class Reactor : public cyclus::Facility { void Transmute(); /// record a reactor event - void Record(std::string name); + void Record(std::string name, std::string val); cyclus::toolkit::MatVec SpentResFor(std::string outcommod); @@ -111,38 +104,48 @@ class Reactor : public cyclus::Facility { //////////// inventory and core params //////////// #pragma cyclus var { \ - "doc": "", \ + "doc": "Number of assemblies that constitute a single batch." \ + "This is the number of assemblies discharged from the core fully burned each cycle.", \ } int n_assem_batch; #pragma cyclus var { \ - "doc": "", \ + "doc": "Mass (kg) of a single assembly.", \ + "units": "kg", \ } double assem_size; #pragma cyclus var { \ "doc": "", \ + "doc": "Number of assemblies that constitute a full core.", \ } int n_assem_core; #pragma cyclus var { \ "default": 1000000000, \ + "doc": "Number of spent fuel assemblies that can be stored on-site before reactor operation stalls.", \ } int n_assem_spent; #pragma cyclus var { \ "default": 0, \ + "doc": "Number of fresh fuel assemblies to keep on-hand.", \ } int n_assem_fresh; ///////// cycle params /////////// #pragma cyclus var { \ - "doc": "", \ + "doc": "The duration of a full operational cycle (excluding refueling time) in time steps.", \ + "units": "time step duration", \ } int cycle_time; #pragma cyclus var { \ - "doc": "", \ + "doc": "The duration of a full refueling period - the time between a cycle end" \ + " and the start of the next cycle.", \ + "units": "time steps", \ } int refuel_time; #pragma cyclus var { \ "default": 0, \ - "doc": "Number of time steps since the beginning of the last cycle.", \ + "doc": "Number of time steps since the start of the last cycle." \ + " Only set this if you know what you are doing", \ + "units": "time steps", \ } int cycle_step; @@ -154,39 +157,35 @@ class Reactor : public cyclus::Facility { std::vector fuel_incommods; #pragma cyclus var { \ "uitype": ["oneormore", "recipe"], \ - "doc": "Fresh fuel recipes to request for each of the given fuel_incommods (same order).", \ + "doc": "Fresh fuel recipes to request for each of the given fuel input commodities (same order).", \ } std::vector fuel_inrecipes; #pragma cyclus var { \ "uitype": ["oneormore", "recipe"], \ - "doc": "Spent fuel recipes corresponding to the given fuel_incommods (by order)." \ - " Fuel received via a particular incommod is transmuted to the recipe specified" \ + "doc": "Spent fuel recipes corresponding to the given fuel input commodities (same order)." \ + " Fuel received via a particular input commodity is transmuted to the recipe specified" \ " here after being burned during a cycle.", \ } std::vector fuel_outrecipes; #pragma cyclus var { \ "uitype": ["oneormore", "incommodity"], \ - "doc": "Output commodities on which to offer spent fuel for each of the given" \ - " incommods (same order)." \ + "doc": "Output commodities on which to offer spent fuel originally received as each particular " \ + " input commodity (same order)." \ } std::vector fuel_outcommods; #pragma cyclus var { \ "default": [], \ - "doc": "The preference for each type of fresh fuel requested via the given" \ - " incommods (same order). If no preferences are specified, zero is" \ - " used for all fuel requests.", \ + "doc": "The preference for each type of fresh fuel requested corresponding to each input" \ + " commodity (same order). If no preferences are specified, zero is" \ + " used for all fuel requests (default).", \ } std::vector fuel_prefs; // This variable should be hidden/unavailable in ui. Maps resource object // id's to the index for the incommod through which they were received. - #pragma cyclus var {"default": {}} + #pragma cyclus var {"default": {}, "doc": "This should NEVER be set manually."} std::map res_indexes; - // TODO: do we need this? - std::vector init_core_fuel; - std::vector init_core_assem; - // Resource inventories - these must be defined AFTER/BELOW the member vars // referenced (e.g. n_batch_fresh, assem_size, etc.). #pragma cyclus var {"capacity": "n_assem_fresh * assem_size"} @@ -200,38 +199,51 @@ class Reactor : public cyclus::Facility { /////////// preference changes /////////// #pragma cyclus var { \ "default": [], \ + "doc": "The time step on which to change the request preference for a " \ + "particular fresh fuel type.", \ } std::vector pref_change_times; #pragma cyclus var { \ "default": [], \ + "doc": "The input commodity for a particular fuel preference change." \ + " Same order as and direct correspondence to the specified preference change time steps.", \ } std::vector pref_change_commods; #pragma cyclus var { \ "default": [], \ + "doc": "The new/changed request preference for a particular fresh fuel." \ + " Same order as and direct correspondence to the specified preference change time steps.", \ } std::vector pref_change_values; ///////////// recipe changes /////////// #pragma cyclus var { \ "default": [], \ + "doc": "The time step on which to change the input-output recipe pair for a requested fresh fuel.", \ } std::vector recipe_change_times; #pragma cyclus var { \ "default": [], \ + "doc": "The input commodity indicating fresh fuel for which recipes will be changed." \ + " Same order as and direct correspondence to the specified recipe change time steps.", \ } std::vector recipe_change_commods; #pragma cyclus var { \ "default": [], \ + "doc": "The new input recipe to use for this recipe change." \ + " Same order as and direct correspondence to the specified recipe change time steps.", \ } std::vector recipe_change_in; #pragma cyclus var { \ "default": [], \ + "doc": "The new output recipe to use for this recipe change." \ + " Same order as and direct correspondence to the specified recipe change time steps.", \ } std::vector recipe_change_out; // should be hidden in ui (internal only). True if fuel has been discharged // this cycle. - #pragma cyclus var {"default": 0} + #pragma cyclus var {"default": 0, "doc": "This should NEVER be set manually."} bool discharged; }; From 9e0a18f39a03c18b67038fe71f9611d5b41da01a Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 14 Jan 2015 14:24:19 -0600 Subject: [PATCH 049/314] improve annotations and comments --- src/reactor.h | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/reactor.h b/src/reactor.h index fc03ca26cb..ea8c02254f 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -95,17 +95,23 @@ class Reactor : public cyclus::Facility { /// fully burnt state as defined by its outrecipe. void Transmute(); - /// record a reactor event + /// Records a reactor event to the output db with the given name and note val. void Record(std::string name, std::string val); + /// Returns pointers to all the spent fuel materials that should be offered + /// on a particular outcommod without removing them from the spent + /// fuel buffer. cyclus::toolkit::MatVec SpentResFor(std::string outcommod); + /// Returns a single assembly for the specified outcommod - removing it from + /// the spent fuel buffer. cyclus::Material::Ptr PopSpentRes(std::string outcommod); //////////// inventory and core params //////////// #pragma cyclus var { \ "doc": "Number of assemblies that constitute a single batch." \ - "This is the number of assemblies discharged from the core fully burned each cycle.", \ + "This is the number of assemblies discharged from the core fully burned each cycle." \ + "Batch size is equivalent to ``n_assem_batch / n_assem_core``.", \ } int n_assem_batch; #pragma cyclus var { \ @@ -114,7 +120,6 @@ class Reactor : public cyclus::Facility { } double assem_size; #pragma cyclus var { \ - "doc": "", \ "doc": "Number of assemblies that constitute a full core.", \ } int n_assem_core; @@ -125,19 +130,19 @@ class Reactor : public cyclus::Facility { int n_assem_spent; #pragma cyclus var { \ "default": 0, \ - "doc": "Number of fresh fuel assemblies to keep on-hand.", \ + "doc": "Number of fresh fuel assemblies to keep on-hand if possible.", \ } int n_assem_fresh; ///////// cycle params /////////// #pragma cyclus var { \ "doc": "The duration of a full operational cycle (excluding refueling time) in time steps.", \ - "units": "time step duration", \ + "units": "time steps", \ } int cycle_time; #pragma cyclus var { \ - "doc": "The duration of a full refueling period - the time between a cycle end" \ - " and the start of the next cycle.", \ + "doc": "The duration of a full refueling period - the minimum time between" \ + " a cycle end and the start of the next cycle.", \ "units": "time steps", \ } int refuel_time; @@ -152,7 +157,7 @@ class Reactor : public cyclus::Facility { /////// fuel specifications ///////// #pragma cyclus var { \ "uitype": ["oneormore", "incommodity"], \ - "doc": "Ordered list of input commodities for requesting fuel.", \ + "doc": "Ordered list of input commodities on which to requesting fuel.", \ } std::vector fuel_incommods; #pragma cyclus var { \ @@ -195,7 +200,6 @@ class Reactor : public cyclus::Facility { #pragma cyclus var {"capacity": "n_assem_spent * assem_size"} cyclus::toolkit::ResBuf spent; - /////////// preference changes /////////// #pragma cyclus var { \ "default": [], \ @@ -207,6 +211,7 @@ class Reactor : public cyclus::Facility { "default": [], \ "doc": "The input commodity for a particular fuel preference change." \ " Same order as and direct correspondence to the specified preference change time steps.", \ + "uitype": ["oneormore", "incommodity"], \ } std::vector pref_change_commods; #pragma cyclus var { \ @@ -226,18 +231,21 @@ class Reactor : public cyclus::Facility { "default": [], \ "doc": "The input commodity indicating fresh fuel for which recipes will be changed." \ " Same order as and direct correspondence to the specified recipe change time steps.", \ + "uitype": ["oneormore", "incommodity"], \ } std::vector recipe_change_commods; #pragma cyclus var { \ "default": [], \ "doc": "The new input recipe to use for this recipe change." \ " Same order as and direct correspondence to the specified recipe change time steps.", \ + "uitype": ["oneormore", "recipe"], \ } std::vector recipe_change_in; #pragma cyclus var { \ "default": [], \ "doc": "The new output recipe to use for this recipe change." \ " Same order as and direct correspondence to the specified recipe change time steps.", \ + "uitype": ["oneormore", "recipe"], \ } std::vector recipe_change_out; From bbd31750be25978f432ddca794da2bd3bce90f30 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 14 Jan 2015 16:25:53 -0600 Subject: [PATCH 050/314] improve performance by using temporary data structures --- src/reactor.cc | 68 ++++++++++++++++++++++++++++++++------------------ src/reactor.h | 19 ++++++++------ 2 files changed, 55 insertions(+), 32 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index a12aafa9cb..fc05f96f76 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -76,6 +76,7 @@ void Reactor::Tick() { } } } + } std::set::Ptr> @@ -143,11 +144,19 @@ Reactor::GetMatlBids(cyclus::CommodMap::type& std::set::Ptr> ports; + bool gotmats = false; + std::map all_mats; for (int i = 0; i < fuel_outcommods.size(); i++) { std::string commod = fuel_outcommods[i]; - MatVec mats = SpentResFor(commod); std::vector*>& reqs = commod_requests[commod]; - if (mats.size() == 0 || reqs.size() == 0) { + if (reqs.size() == 0) { + continue; + } else if (!gotmats) { + all_mats = PeekSpent(); + } + + MatVec mats = all_mats[commod]; + if (mats.size() == 0) { continue; } @@ -184,13 +193,16 @@ void Reactor::GetMatlTrades( Material::Ptr> >& responses) { using cyclus::Trade; + std::map mats = PopSpent(); std::vector< cyclus::Trade >::const_iterator it; for (int i = 0; i < trades.size(); i++) { std::string commod = trades[i].request->commodity(); - Material::Ptr m = PopSpentRes(commod); + Material::Ptr m = mats[commod].back(); + mats[commod].pop_back(); responses.push_back(std::make_pair(trades[i], m)); res_indexes.erase(m->obj_id()); } + PushSpent(mats); // return leftovers back to spent buffer } void Reactor::Tock() { @@ -226,6 +238,17 @@ void Reactor::Transmute() { } } +std::map Reactor::PeekSpent() { + std::map mapped; + MatVec mats = spent.PopN(spent.count()); + spent.Push(mats); + for (int i = 0; i < mats.size(); i++) { + std::string commod = fuel_outcommod(mats[i]); + mapped[commod].push_back(mats[i]); + } + return mapped; +} + bool Reactor::Discharge() { if (n_assem_spent - spent.count() < n_assem_batch) { Record("DISCHARGE", "failed"); @@ -304,35 +327,32 @@ void Reactor::index_res(cyclus::Resource::Ptr m, std::string incommod) { throw ValueError("cycamore::Reactor - received unsupported incommod material"); } -Material::Ptr Reactor::PopSpentRes(std::string outcommod) { +std::map Reactor::PopSpent() { MatVec mats = spent.PopN(spent.count()); - Material::Ptr m; - bool found = false; + std::map mapped; for (int i = 0; i < mats.size(); i++) { std::string commod = fuel_outcommod(mats[i]); - if (!found && commod == outcommod) { - m = mats[i]; - found = true; - } else { - spent.Push(mats[i]); - } + mapped[commod].push_back(mats[i]); + } + + // needed so we trade away oldest assemblies first + std::map::iterator it; + for (it = mapped.begin(); it != mapped.end(); ++it) { + std::reverse(it->second.begin(), it->second.end()); } - return m; + + return mapped; } -MatVec Reactor::SpentResFor(std::string outcommod) { - MatVec mats = spent.PopN(spent.count()); - MatVec found; - spent.Push(mats); - for (int i = 0; i < mats.size(); i++) { - std::string commod = fuel_outcommod(mats[i]); - if (commod == outcommod) { - found.push_back(mats[i]); - } +void Reactor::PushSpent(std::map leftover) { + std::map::iterator it; + for (it = leftover.begin(); it != leftover.end(); ++it) { + // undo reverse in PopSpent to make sure oldest assemblies come out first + std::reverse(it->second.begin(), it->second.end()); + spent.Push(it->second); } - return found; } - + void Reactor::Record(std::string name, std::string val) { context()->NewDatum("ReactorEvents") ->AddVal("AgentId", id()) diff --git a/src/reactor.h b/src/reactor.h index ea8c02254f..382d59dadd 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -57,11 +57,11 @@ class Reactor : public cyclus::Facility { virtual void Tick(); virtual void Tock(); - void AcceptMatlTrades( + virtual void AcceptMatlTrades( const std::vector< std::pair, cyclus::Material::Ptr> >& responses); - std::set::Ptr> GetMatlRequests(); + virtual std::set::Ptr> GetMatlRequests(); virtual std::set::Ptr> GetMatlBids(cyclus::CommodMap::type& @@ -98,14 +98,17 @@ class Reactor : public cyclus::Facility { /// Records a reactor event to the output db with the given name and note val. void Record(std::string name, std::string val); - /// Returns pointers to all the spent fuel materials that should be offered - /// on a particular outcommod without removing them from the spent - /// fuel buffer. - cyclus::toolkit::MatVec SpentResFor(std::string outcommod); + /// Complement of PopSpent - must be called with all materials passed that + /// were not traded away to other agents. + void PushSpent(std::map leftover); - /// Returns a single assembly for the specified outcommod - removing it from + /// Returns all spent assemblies indexed by outcommod - removing them from /// the spent fuel buffer. - cyclus::Material::Ptr PopSpentRes(std::string outcommod); + std::map PopSpent(); + + /// Returns all spent assemblies indexed by outcommod without removing them + /// from the spent fuel buffer. + std::map PeekSpent(); //////////// inventory and core params //////////// #pragma cyclus var { \ From 92c48e7c8cb3812546a1e9319f4bc397c528a2c5 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 15 Jan 2015 11:17:26 -0600 Subject: [PATCH 051/314] added nice doc comment/note to reactor class --- src/reactor.h | 123 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 44 deletions(-) diff --git a/src/reactor.h b/src/reactor.h index 382d59dadd..72a62a5e8d 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -5,51 +5,86 @@ namespace cycamore { -// Configurable parameters: -// -// * assem_size (double) - the mass in kg of a single assembly -// -// * n_assem_batch (int) - number of assemblies discharged per batch at the -// end of an operational cycle -// -// * n_assem_core (int) - the number of assemblies that constitute a core. -// -// * n_assem_spent (int, default infinite) - the number of spent fuel assemblies -// that can be stored -// -// * n_assem_fresh (int, default n_assem_core) - the number of fresh assemblies to keep on -// hand -// -// The Reactor will have 3 resource buffers (all with automatically computed -// capacities based on above params): -// -// * fresh: capacity = n_assem_fresh * assem_size -// -// * core: capacity = n_assem_core * assem_size -// -// * spent: capacity = n_assem_spent * assem_size -// -// The reactor will always try to keep its fresh_fuel and core buffers full. -// If the fresh fuel buffer has zero capacity (i.e. n_assem_fresh == 0), then -// the reactor will not order new fuel until the next batch is discharged from -// the core - i.e. "just-in-time" ordering. -// The cycle progresses/runs only if the reactor is in active operation. The -// following conditions result in reactor operation being suspended: -// -// * There are not enough full assemblies (with unspent life) to provide a full core -// -// * There is no room in the spent_fuel buffer to discharge a fully-burned assembly into. -// -// A reactor only requests and accepts material in discrete assembly quanta (of size -// assem_size). Resources will never be split/combined by the reactor. -// -// Meta-data associated with resource objects in inventory (e.g. the in-commod -// on which they were received) should be associated with resources based on -// obj_id. This is necessary for maintaining continuity in the face of -// potential decay calcs and other things that might change the regular -// Resource::id. - +/// Reactor is a simple, general reactor based on static compositional +/// transformations to model fuel burnup. The user specifies a set of input +/// fuels and corresponding burnt compositions that fuel is transformed to when +/// it is discharged from the core. No incremental transmutation takes place. +/// Rather, at the end of an operational cycle, the batch being discharged from +/// the core is instantaneously transmuted from its original fresh fuel +/// composition into its spent fuel form. +/// +/// Each fuel is identified by a specific input commodity and has an associated +/// input recipe (nuclide composition), output recipe, output commidity, and +/// preference. The preference identifies which input fuels are preferred when +/// requesting. Changes in these preferences can be specified as a function of +/// time using the pref_change variables. Changes in the input-output recipe +/// compositions can also be specified as a function of time using the +/// recipe_change variables. +/// +/// The reactor treats fuel as individual assemblies that are never split, +/// combined or otherwise treated in any non-discrete way. Fuel is requested +/// in full-or-nothing assembly sized quanta. If real-world assembly modeling +/// is unnecessary, parameters can be adjusted (e.g. n_assem_core, assem_size, +/// n_assem_batch). At the end of every cycle, a full batch is discharged from +/// the core consisting of n_assem_batch assemblies of assem_size kg. The +/// reactor also has a specifiable refueling time period following the end of +/// each cycle at the end of which it will resume operation on the next cycle +/// *if* it has enough fuel for a full core; otherwise it waits until it has +/// enough fresh fuel assemblies. +/// +/// In addition to its core, the reactor has an on-hand fresh fuel inventory +/// and a spent fuel inventory whose capacities are specified by n_assem_fresh +/// and n_assem_spent respectively. Each time step the reactor will attempt to +/// acquire enough fresh fuel to fill its fresh fuel inventory (and its core if +/// the core isn't currently full). If the fresh fuel inventory has zero +/// capacity, fuel will be ordered just-in-time after the end of each +/// operational cycle before the next begins. If the spent fuel inventory +/// becomes full, the reactor will halt operation at the end of the next cycle +/// until there is more room. Each time step, the reactor will try to trade +/// away as much of its spent fuel inventory as possible. class Reactor : public cyclus::Facility { +#pragma cyclus note { \ +"niche": "reactor", \ +"doc": \ + "Reactor is a simple, general reactor based on static compositional" \ + "transformations to model fuel burnup. The user specifies a set of input" \ + "fuels and corresponding burnt compositions that fuel is transformed to when" \ + "it is discharged from the core. No incremental transmutation takes place." \ + "Rather, at the end of an operational cycle, the batch being discharged from" \ + "the core is instantaneously transmuted from its original fresh fuel" \ + "composition into its spent fuel form." \ + "\n\n" \ + "Each fuel is identified by a specific input commodity and has an associated" \ + "input recipe (nuclide composition), output recipe, output commidity, and" \ + "preference. The preference identifies which input fuels are preferred when" \ + "requesting. Changes in these preferences can be specified as a function of" \ + "time using the pref_change variables. Changes in the input-output recipe" \ + "compositions can also be specified as a function of time using the" \ + "recipe_change variables." \ + "\n\n" \ + "The reactor treats fuel as individual assemblies that are never split," \ + "combined or otherwise treated in any non-discrete way. Fuel is requested" \ + "in full-or-nothing assembly sized quanta. If real-world assembly modeling" \ + "is unnecessary, parameters can be adjusted (e.g. n_assem_core, assem_size," \ + "n_assem_batch). At the end of every cycle, a full batch is discharged from" \ + "the core consisting of n_assem_batch assemblies of assem_size kg. The" \ + "reactor also has a specifiable refueling time period following the end of" \ + "each cycle at the end of which it will resume operation on the next cycle" \ + "*if* it has enough fuel for a full core; otherwise it waits until it has" \ + "enough fresh fuel assemblies." \ + "\n\n" \ + "In addition to its core, the reactor has an on-hand fresh fuel inventory" \ + "and a spent fuel inventory whose capacities are specified by n_assem_fresh" \ + "and n_assem_spent respectively. Each time step the reactor will attempt to" \ + "acquire enough fresh fuel to fill its fresh fuel inventory (and its core if" \ + "the core isn't currently full). If the fresh fuel inventory has zero" \ + "capacity, fuel will be ordered just-in-time after the end of each" \ + "operational cycle before the next begins. If the spent fuel inventory" \ + "becomes full, the reactor will halt operation at the end of the next cycle" \ + "until there is more room. Each time step, the reactor will try to trade" \ + "away as much of its spent fuel inventory as possible.", \ +} + public: Reactor(cyclus::Context* ctx); virtual ~Reactor() {}; From cfca3f7e8ce2c5fbdd690789eda166fb50b53705 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 16 Jan 2015 12:14:44 -0600 Subject: [PATCH 052/314] housekeeping --- src/reactor.cc | 36 ++++++++++++++++++------------------ src/reactor.h | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index fc05f96f76..725182d94a 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -110,6 +110,24 @@ Reactor::GetMatlRequests() { return ports; } +void Reactor::GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + Material::Ptr> >& responses) { + using cyclus::Trade; + + std::map mats = PopSpent(); + std::vector< cyclus::Trade >::const_iterator it; + for (int i = 0; i < trades.size(); i++) { + std::string commod = trades[i].request->commodity(); + Material::Ptr m = mats[commod].back(); + mats[commod].pop_back(); + responses.push_back(std::make_pair(trades[i], m)); + res_indexes.erase(m->obj_id()); + } + PushSpent(mats); // return leftovers back to spent buffer +} + void Reactor::AcceptMatlTrades( const std::vector< std::pair, Material::Ptr> >& responses) { @@ -187,24 +205,6 @@ Reactor::GetMatlBids(cyclus::CommodMap::type& return ports; } -void Reactor::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - Material::Ptr> >& responses) { - using cyclus::Trade; - - std::map mats = PopSpent(); - std::vector< cyclus::Trade >::const_iterator it; - for (int i = 0; i < trades.size(); i++) { - std::string commod = trades[i].request->commodity(); - Material::Ptr m = mats[commod].back(); - mats[commod].pop_back(); - responses.push_back(std::make_pair(trades[i], m)); - res_indexes.erase(m->obj_id()); - } - PushSpent(mats); // return leftovers back to spent buffer -} - void Reactor::Tock() { if (cycle_step >= cycle_time + refuel_time && core.count() == n_assem_core) { discharged = false; diff --git a/src/reactor.h b/src/reactor.h index 72a62a5e8d..5ed90e3687 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -126,7 +126,7 @@ class Reactor : public cyclus::Facility { /// Top up core inventory as much as possible. void Load(); - /// Transmute the batch in the core that is about to be discharged to its + /// Transmute the batch that is about to be discharged from the core to its /// fully burnt state as defined by its outrecipe. void Transmute(); From 930778fdb91ff5abdf1bcf968f2c87d410b91587 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 11 Feb 2015 15:36:54 -0600 Subject: [PATCH 053/314] added 1st mock sim test for reactor - more to come --- src/reactor_tests.cc | 49 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/reactor_tests.cc diff --git a/src/reactor_tests.cc b/src/reactor_tests.cc new file mode 100644 index 0000000000..fb4088b5a9 --- /dev/null +++ b/src/reactor_tests.cc @@ -0,0 +1,49 @@ +#include + +#include + +#include "cyclus.h" + +using pyne::nucname::id; +using cyclus::Composition; +using cyclus::QueryResult; +using cyclus::Cond; + +namespace cycamore { + +TEST(ReactorTests, JustInTimeOrdering) { + cyclus::CompMap m; + m[id("U235")] = .05; + m[id("U238")] = .95; + Composition::Ptr fresh = Composition::CreateFromMass(m); + m.clear(); + m[id("U235")] = .01; + m[id("U238")] = .99; + Composition::Ptr spent = Composition::CreateFromMass(m); + + std::string config = + " lwr_fresh " + " lwr_spent " + " enriched_u " + " waste " + " 1.0 " + "" + " 1 " + " 0 " + " 300 " + " 1 " + " 1 "; + + int simdur = 50; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur); + sim.AddSource("enriched_u").Finalize(); + sim.AddRecipe("lwr_fresh", fresh); + sim.AddRecipe("lwr_spent", spent); + int id = sim.Run(); + + QueryResult qr = sim.db().Query("Transactions", NULL); + EXPECT_EQ(simdur, qr.rows.size()) << "failed to order+run on fresh fuel inside 1 time step"; +} + +} // namespace cycamore + From 9f8e5ecfa1d498048b2889fa79d9d2ca2d6679c7 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 12 Feb 2015 15:45:00 -0600 Subject: [PATCH 054/314] fix preference defaulting - lots of code assums fuel_prefs is the same length as fuel_outcommods --- src/reactor.cc | 10 ++++++++++ src/reactor.h | 1 + 2 files changed, 11 insertions(+) diff --git a/src/reactor.cc b/src/reactor.cc index 725182d94a..7b5aafd8d7 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -25,6 +25,16 @@ Reactor::Reactor(cyclus::Context* ctx) "is experimental"); } +void Reactor::EnterNotify() { + cyclus::Facility::EnterNotify(); + + if (fuel_prefs.size() == 0) { + for (int i = 0; i < fuel_outcommods.size(); i++) { + fuel_prefs.push_back(0); + } + } +} + void Reactor::Tick() { // The following code must go in the Tick so they fire on the time step // following the cycle_step update - allowing for the all reactor events to diff --git a/src/reactor.h b/src/reactor.h index 5ed90e3687..391e0da6ff 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -91,6 +91,7 @@ class Reactor : public cyclus::Facility { virtual void Tick(); virtual void Tock(); + virtual void EnterNotify(); virtual void AcceptMatlTrades( const std::vector< std::pair, From 525546c9bc415e4fd94e638708388b90e68e21d3 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 13 Feb 2015 14:11:58 -0600 Subject: [PATCH 055/314] adding more tests to reactor --- src/reactor.cc | 2 + src/reactor_tests.cc | 200 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 186 insertions(+), 16 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index 7b5aafd8d7..94efe7986c 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -28,6 +28,8 @@ Reactor::Reactor(cyclus::Context* ctx) void Reactor::EnterNotify() { cyclus::Facility::EnterNotify(); + // If the user ommitted fuel_prefs, we set it to zeros for each fuel + // type. Without this segfaults could occur - yuck. if (fuel_prefs.size() == 0) { for (int i = 0; i < fuel_outcommods.size(); i++) { fuel_prefs.push_back(0); diff --git a/src/reactor_tests.cc b/src/reactor_tests.cc index fb4088b5a9..305aba3e41 100644 --- a/src/reactor_tests.cc +++ b/src/reactor_tests.cc @@ -8,25 +8,58 @@ using pyne::nucname::id; using cyclus::Composition; using cyclus::QueryResult; using cyclus::Cond; +using cyclus::toolkit::MatQuery; namespace cycamore { -TEST(ReactorTests, JustInTimeOrdering) { +Composition::Ptr c_uox() { + cyclus::CompMap m; + m[id("u235")] = 0.04; + m[id("u238")] = 0.96; + return Composition::CreateFromMass(m); +}; + +Composition::Ptr c_mox() { + cyclus::CompMap m; + m[id("u235")] = .7; + m[id("u238")] = 100; + m[id("pu239")] = 3.3; + return Composition::CreateFromMass(m); +}; + +Composition::Ptr c_spentuox() { + cyclus::CompMap m; + m[id("u235")] = .8; + m[id("u238")] = 100; + m[id("pu239")] = 1; + return Composition::CreateFromMass(m); +}; + +Composition::Ptr c_spentmox() { cyclus::CompMap m; - m[id("U235")] = .05; - m[id("U238")] = .95; - Composition::Ptr fresh = Composition::CreateFromMass(m); - m.clear(); - m[id("U235")] = .01; - m[id("U238")] = .99; - Composition::Ptr spent = Composition::CreateFromMass(m); + m[id("u235")] = .2; + m[id("u238")] = 100; + m[id("pu239")] = .9; + return Composition::CreateFromMass(m); +}; +Composition::Ptr c_water() { + cyclus::CompMap m; + m[id("O16")] = 1; + m[id("H1")] = 2; + return Composition::CreateFromAtom(m); +}; + +// Test that with a zero refuel_time and a zero capacity fresh fuel buffer +// (the default), fuel can be ordered and the cycle started with no time step +// delay. +TEST(ReactorTests, JustInTimeOrdering) { std::string config = - " lwr_fresh " - " lwr_spent " - " enriched_u " - " waste " - " 1.0 " + " lwr_fresh " + " lwr_spent " + " enriched_u " + " waste " + " 1.0 " "" " 1 " " 0 " @@ -37,13 +70,148 @@ TEST(ReactorTests, JustInTimeOrdering) { int simdur = 50; cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur); sim.AddSource("enriched_u").Finalize(); - sim.AddRecipe("lwr_fresh", fresh); - sim.AddRecipe("lwr_spent", spent); + sim.AddRecipe("lwr_fresh", c_uox()); + sim.AddRecipe("lwr_spent", c_spentuox()); int id = sim.Run(); QueryResult qr = sim.db().Query("Transactions", NULL); EXPECT_EQ(simdur, qr.rows.size()) << "failed to order+run on fresh fuel inside 1 time step"; } -} // namespace cycamore +// The user can optionally omit fuel preferences. In the case where +// preferences are adjusted, the ommitted preference vector must be populated +// with default values - if it wasn't then preferences won't be adjusted +// correctly and the reactor could segfault. Check that this doesn't happen. +TEST(ReactorTests, PrefChange) { + // it is important that the fuel_prefs not be present in the config below. + std::string config = + " lwr_fresh " + " lwr_spent " + " enriched_u " + " waste " + "" + " 1 " + " 0 " + " 300 " + " 1 " + " 1 " + "" + " 25 " + " enriched_u " + " -1 "; + + int simdur = 50; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur); + sim.AddSource("enriched_u").Finalize(); + sim.AddRecipe("lwr_fresh", c_uox()); + sim.AddRecipe("lwr_spent", c_spentuox()); + int id = sim.Run(); + + QueryResult qr = sim.db().Query("Transactions", NULL); + EXPECT_EQ(25, qr.rows.size()) << "failed to adjust preferences properly"; +} + +// tests that the reactor handles requesting multiple types of fuel correctly +// - with proper inventory constraints, etc. +TEST(ReactorTests, MultiFuelMix) { + FAIL() << "not implemented"; +} + +// tests that the reactor halts operation when it has no more room in its +// spent fuel inventory buffer. +TEST(ReactorTests, FullSpentInventory) { + FAIL() << "not implemented"; +} + +// tests that the reactor cycle is delayed as expected when it is unable to +// acquire fuel in time for the next cycle start. +TEST(ReactorTests, FuelShortage) { + FAIL() << "not implemented"; +} + +// tests that the refueling period between cycle end and start of the next +// cycle is honored. +TEST(ReactorTests, RefuelTimes) { + FAIL() << "not implemented"; +} + +// tests that the correct number of assemblies are popped from the core each +// cycle. +TEST(ReactorTests, BatchSizes) { + FAIL() << "not implemented"; +} + +TEST(ReactorTests, RecipeChange) { + // it is important that the fuel_prefs not be present in the config below. + std::string config = + " lwr_fresh " + " lwr_spent " + " enriched_u " + " waste " + "" + " 1 " + " 0 " + " 300 " + " 1 " + " 1 " + "" + " 25 35 " + " enriched_u enriched_u " + " water water " + " lwr_spent water "; + + int simdur = 50; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur); + sim.AddSource("enriched_u").Finalize(); + sim.AddSink("waste").Finalize(); + sim.AddRecipe("lwr_fresh", c_uox()); + sim.AddRecipe("lwr_spent", c_spentuox()); + sim.AddRecipe("water", c_water()); + int aid = sim.Run(); + + std::vector conds; + QueryResult qr; + + // check that received recipe is not water + conds.clear(); + conds.push_back(Cond("Time", "==", 24)); + conds.push_back(Cond("ReceiverId", "==", aid)); + qr = sim.db().Query("Transactions", &conds); + MatQuery mq = MatQuery(sim.GetMaterial(qr.GetVal("ResourceId"))); + + EXPECT_TRUE(0 < mq.qty()); + EXPECT_TRUE(0 == mq.mass(id("H1"))); + + // check that received recipe changed to water + conds.clear(); + conds.push_back(Cond("Time", "==", 26)); + conds.push_back(Cond("ReceiverId", "==", aid)); + qr = sim.db().Query("Transactions", &conds); + mq = MatQuery(sim.GetMaterial(qr.GetVal("ResourceId"))); + + EXPECT_TRUE(0 < mq.qty()); + EXPECT_TRUE(0 < mq.mass(id("H1"))); + + // check that sent recipe is not water + conds.clear(); + conds.push_back(Cond("Time", "==", 34)); + conds.push_back(Cond("SenderId", "==", aid)); + qr = sim.db().Query("Transactions", &conds); + mq = MatQuery(sim.GetMaterial(qr.GetVal("ResourceId"))); + + EXPECT_TRUE(0 < mq.qty()); + EXPECT_TRUE(0 == mq.mass(id("H1"))); + + // check that sent recipe changed to water + conds.clear(); + conds.push_back(Cond("Time", "==", 36)); + conds.push_back(Cond("SenderId", "==", aid)); + qr = sim.db().Query("Transactions", &conds); + mq = MatQuery(sim.GetMaterial(qr.GetVal("ResourceId"))); + + EXPECT_TRUE(0 < mq.qty()); + EXPECT_TRUE(0 < mq.mass(id("H1"))); +} + +} // namespace cycamore From f1410717bdf2e9d797918b7207b85d4d271fd8db Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 16 Feb 2015 15:58:30 -0600 Subject: [PATCH 056/314] more tests for reactor --- src/reactor_tests.cc | 164 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 134 insertions(+), 30 deletions(-) diff --git a/src/reactor_tests.cc b/src/reactor_tests.cc index 305aba3e41..f448651228 100644 --- a/src/reactor_tests.cc +++ b/src/reactor_tests.cc @@ -78,6 +78,140 @@ TEST(ReactorTests, JustInTimeOrdering) { EXPECT_EQ(simdur, qr.rows.size()) << "failed to order+run on fresh fuel inside 1 time step"; } +// tests that the correct number of assemblies are popped from the core each +// cycle. +TEST(ReactorTests, BatchSizes) { + std::string config = + " uox " + " spentuox " + " uox " + " waste " + "" + " 1 " + " 0 " + " 1 " + " 7 " + " 3 "; + + int simdur = 50; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur); + sim.AddSource("uox").Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("spentuox", c_spentuox()); + int id = sim.Run(); + + QueryResult qr = sim.db().Query("Transactions", NULL); + // 7 for initial core, 3 per time step for each new batch for remainder + EXPECT_EQ(7+3*(simdur-1), qr.rows.size()); +} + +// tests that the refueling period between cycle end and start of the next +// cycle is honored. +TEST(ReactorTests, RefuelTimes) { + std::string config = + " uox " + " spentuox " + " uox " + " waste " + "" + " 4 " + " 3 " + " 1 " + " 1 " + " 1 "; + + int simdur = 49; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur); + sim.AddSource("uox").Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("spentuox", c_spentuox()); + int id = sim.Run(); + + QueryResult qr = sim.db().Query("Transactions", NULL); + int cyclet = 4; + int refuelt = 3; + int n_assem_want = simdur/(cyclet+refuelt)+1; // +1 for initial core + EXPECT_EQ(n_assem_want, qr.rows.size()); +} + +// tests that new fuel is ordered immediately following cycle end - at the +// start of the refueling period - not before and not after. - thie is subtly +// different than RefuelTimes test and is not a duplicate of it. +TEST(ReactorTests, OrderAtRefuelStart) { + std::string config = + " uox " + " spentuox " + " uox " + " waste " + "" + " 4 " + " 3 " + " 1 " + " 1 " + " 1 "; + + int simdur = 7; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur); + sim.AddSource("uox").Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("spentuox", c_spentuox()); + int id = sim.Run(); + + QueryResult qr = sim.db().Query("Transactions", NULL); + int cyclet = 4; + int refuelt = 3; + int n_assem_want = simdur/(cyclet+refuelt)+1; // +1 for initial core + EXPECT_EQ(n_assem_want, qr.rows.size()); +} + +// tests that the reactor handles requesting multiple types of fuel correctly +// - with proper inventory constraint honoring, etc. +TEST(ReactorTests, MultiFuelMix) { + std::string config = + " uox mox " + " spentuox spentmox " + " uox mox " + " waste waste " + "" + " 1 " + " 0 " + " 1 " + " 3 " + " 3 " + " 3 "; + + // it is important that the sources have cumulative capacity greater than + // the reactor can take on a single time step - to test that inventory + // capacity constraints are being set properly. It is also important that + // each source is smaller capacity thatn the reactor orders on each time + // step to make it easy to compute+check the number of transactions. + int simdur = 50; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur); + sim.AddSource("uox").capacity(2).Finalize(); + sim.AddSource("mox").capacity(2).Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("spentuox", c_spentuox()); + sim.AddRecipe("mox", c_spentuox()); + sim.AddRecipe("spentmox", c_spentuox()); + int id = sim.Run(); + + QueryResult qr = sim.db().Query("Transactions", NULL); + // +3 is for fresh fuel inventory + EXPECT_EQ(3*simdur+3, qr.rows.size()); +} + +// tests that the reactor halts operation when it has no more room in its +// spent fuel inventory buffer. +TEST(ReactorTests, FullSpentInventory) { + FAIL() << "not implemented"; +} + +// tests that the reactor cycle is delayed as expected when it is unable to +// acquire fuel in time for the next cycle start. +TEST(ReactorTests, FuelShortage) { + FAIL() << "not implemented"; +} + // The user can optionally omit fuel preferences. In the case where // preferences are adjusted, the ommitted preference vector must be populated // with default values - if it wasn't then preferences won't be adjusted @@ -111,36 +245,6 @@ TEST(ReactorTests, PrefChange) { EXPECT_EQ(25, qr.rows.size()) << "failed to adjust preferences properly"; } -// tests that the reactor handles requesting multiple types of fuel correctly -// - with proper inventory constraints, etc. -TEST(ReactorTests, MultiFuelMix) { - FAIL() << "not implemented"; -} - -// tests that the reactor halts operation when it has no more room in its -// spent fuel inventory buffer. -TEST(ReactorTests, FullSpentInventory) { - FAIL() << "not implemented"; -} - -// tests that the reactor cycle is delayed as expected when it is unable to -// acquire fuel in time for the next cycle start. -TEST(ReactorTests, FuelShortage) { - FAIL() << "not implemented"; -} - -// tests that the refueling period between cycle end and start of the next -// cycle is honored. -TEST(ReactorTests, RefuelTimes) { - FAIL() << "not implemented"; -} - -// tests that the correct number of assemblies are popped from the core each -// cycle. -TEST(ReactorTests, BatchSizes) { - FAIL() << "not implemented"; -} - TEST(ReactorTests, RecipeChange) { // it is important that the fuel_prefs not be present in the config below. std::string config = From 487c54f48189695e3190b3b8ea83a961f4ed7a62 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 16 Feb 2015 15:59:37 -0600 Subject: [PATCH 057/314] another test placeholder --- src/reactor_tests.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/reactor_tests.cc b/src/reactor_tests.cc index f448651228..e3a06e9d68 100644 --- a/src/reactor_tests.cc +++ b/src/reactor_tests.cc @@ -212,6 +212,11 @@ TEST(ReactorTests, FuelShortage) { FAIL() << "not implemented"; } +// tests that discharged fuel is transmuted properly immediately at cycle end. +TEST(ReactorTests, DischargedFuelTransmute) { + FAIL() << "not implemented"; +} + // The user can optionally omit fuel preferences. In the case where // preferences are adjusted, the ommitted preference vector must be populated // with default values - if it wasn't then preferences won't be adjusted From d7c4519b2ea5c937bfa586ff371e881fd74eafd0 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 16 Feb 2015 16:28:00 -0600 Subject: [PATCH 058/314] more tests --- src/reactor_tests.cc | 56 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/src/reactor_tests.cc b/src/reactor_tests.cc index e3a06e9d68..53fb19cf63 100644 --- a/src/reactor_tests.cc +++ b/src/reactor_tests.cc @@ -6,6 +6,7 @@ using pyne::nucname::id; using cyclus::Composition; +using cyclus::Material; using cyclus::QueryResult; using cyclus::Cond; using cyclus::toolkit::MatQuery; @@ -203,7 +204,31 @@ TEST(ReactorTests, MultiFuelMix) { // tests that the reactor halts operation when it has no more room in its // spent fuel inventory buffer. TEST(ReactorTests, FullSpentInventory) { - FAIL() << "not implemented"; + std::string config = + " uox " + " spentuox " + " uox " + " waste " + "" + " 1 " + " 0 " + " 1 " + " 1 " + " 1 " + " 3 "; + + int simdur = 10; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur); + sim.AddSource("uox").Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("spentuox", c_spentuox()); + int id = sim.Run(); + + QueryResult qr = sim.db().Query("Transactions", NULL); + int n_assem_spent = 3; + + // +1 is for the assembly in the core + the three in spent + EXPECT_EQ(n_assem_spent+1, qr.rows.size()); } // tests that the reactor cycle is delayed as expected when it is unable to @@ -214,7 +239,34 @@ TEST(ReactorTests, FuelShortage) { // tests that discharged fuel is transmuted properly immediately at cycle end. TEST(ReactorTests, DischargedFuelTransmute) { - FAIL() << "not implemented"; + std::string config = + " uox " + " spentuox " + " uox " + " waste " + "" + " 4 " + " 3 " + " 1 " + " 1 " + " 1 "; + + int simdur = 7; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur); + sim.AddSource("uox").Finalize(); + sim.AddSink("waste").Finalize(); + sim.AddRecipe("uox", c_uox()); + Composition::Ptr spentuox = c_spentuox(); + sim.AddRecipe("spentuox", spentuox); + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("SenderId", "==", id)); + int resid = sim.db().Query("Transactions", &conds).GetVal("ResourceId"); + Material::Ptr m = sim.GetMaterial(resid); + MatQuery mq(m); + EXPECT_EQ(spentuox->id(), m->comp()->id()); + EXPECT_TRUE(mq.mass(942390000) > 0) << "transmuted spent fuel doesn't have Pu239"; } // The user can optionally omit fuel preferences. In the case where From af83c1c9f2cd89c94e4b27d77576276b19a2b6c8 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Tue, 17 Feb 2015 10:43:20 -0600 Subject: [PATCH 059/314] finish reactor tests --- src/reactor_tests.cc | 51 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/src/reactor_tests.cc b/src/reactor_tests.cc index 53fb19cf63..f142be6c92 100644 --- a/src/reactor_tests.cc +++ b/src/reactor_tests.cc @@ -232,9 +232,56 @@ TEST(ReactorTests, FullSpentInventory) { } // tests that the reactor cycle is delayed as expected when it is unable to -// acquire fuel in time for the next cycle start. +// acquire fuel in time for the next cycle start. This checks that after a +// cycle is delayed past an original scheduled start time, as soon as enough fuel is +// received, a new cycle pattern is established starting from the delayed +// start time. TEST(ReactorTests, FuelShortage) { - FAIL() << "not implemented"; + std::string config = + " uox " + " spentuox " + " uox " + " waste " + "" + " 7 " + " 0 " + " 1 " + " 3 " + " 3 "; + + int simdur = 50; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur); + sim.AddSource("uox").lifetime(1).Finalize(); // provide initial full batch + sim.AddSource("uox").start(9).lifetime(1).capacity(2).Finalize(); // provide partial batch post cycle-end + sim.AddSource("uox").start(15).Finalize(); // provide remainder of batch much later + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("spentuox", c_spentuox()); + int id = sim.Run(); + + // check that we never got a full refueled batch + std::vector conds; + conds.push_back(Cond("Time", "<", 15)); + QueryResult qr = sim.db().Query("Transactions", &conds); + EXPECT_EQ(5, qr.rows.size()); + + // after being delayed past original scheduled start of new cycle, we got + // final assembly for core. + conds.clear(); + conds.push_back(Cond("Time", "==", 15)); + qr = sim.db().Query("Transactions", &conds); + EXPECT_EQ(1, qr.rows.size()); + + // all during the next cycle we shouldn't be requesting any new fuel + conds.clear(); + conds.push_back(Cond("Time", "<", 21)); + qr = sim.db().Query("Transactions", &conds); + EXPECT_EQ(6, qr.rows.size()); + + // as soon as this cycle ends, we should be requesting/getting 3 new batches + conds.clear(); + conds.push_back(Cond("Time", "==", 22)); + qr = sim.db().Query("Transactions", &conds); + EXPECT_EQ(3, qr.rows.size()); } // tests that discharged fuel is transmuted properly immediately at cycle end. From 7ec3bc9861bfc90dd3a33b94879080a4b802476a Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Tue, 24 Feb 2015 09:47:36 -0600 Subject: [PATCH 060/314] clarify some comments --- src/reactor.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/reactor.h b/src/reactor.h index 391e0da6ff..73b9ac3bc9 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -242,54 +242,54 @@ class Reactor : public cyclus::Facility { /////////// preference changes /////////// #pragma cyclus var { \ "default": [], \ - "doc": "The time step on which to change the request preference for a " \ + "doc": "A time step on which to change the request preference for a " \ "particular fresh fuel type.", \ } std::vector pref_change_times; #pragma cyclus var { \ "default": [], \ "doc": "The input commodity for a particular fuel preference change." \ - " Same order as and direct correspondence to the specified preference change time steps.", \ + " Same order as and direct correspondence to the specified preference change times.", \ "uitype": ["oneormore", "incommodity"], \ } std::vector pref_change_commods; #pragma cyclus var { \ "default": [], \ "doc": "The new/changed request preference for a particular fresh fuel." \ - " Same order as and direct correspondence to the specified preference change time steps.", \ + " Same order as and direct correspondence to the specified preference change times.", \ } std::vector pref_change_values; ///////////// recipe changes /////////// #pragma cyclus var { \ "default": [], \ - "doc": "The time step on which to change the input-output recipe pair for a requested fresh fuel.", \ + "doc": "A time step on which to change the input-output recipe pair for a requested fresh fuel.", \ } std::vector recipe_change_times; #pragma cyclus var { \ "default": [], \ "doc": "The input commodity indicating fresh fuel for which recipes will be changed." \ - " Same order as and direct correspondence to the specified recipe change time steps.", \ + " Same order as and direct correspondence to the specified recipe change times.", \ "uitype": ["oneormore", "incommodity"], \ } std::vector recipe_change_commods; #pragma cyclus var { \ "default": [], \ "doc": "The new input recipe to use for this recipe change." \ - " Same order as and direct correspondence to the specified recipe change time steps.", \ + " Same order as and direct correspondence to the specified recipe change times.", \ "uitype": ["oneormore", "recipe"], \ } std::vector recipe_change_in; #pragma cyclus var { \ "default": [], \ "doc": "The new output recipe to use for this recipe change." \ - " Same order as and direct correspondence to the specified recipe change time steps.", \ + " Same order as and direct correspondence to the specified recipe change times.", \ "uitype": ["oneormore", "recipe"], \ } std::vector recipe_change_out; - // should be hidden in ui (internal only). True if fuel has been discharged - // this cycle. + // should be hidden in ui (internal only). True if fuel has already been + // discharged this cycle. #pragma cyclus var {"default": 0, "doc": "This should NEVER be set manually."} bool discharged; }; From f619e63c12d932d785f1bdc65e8cc81b2e1c03ab Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Sat, 28 Feb 2015 12:21:18 -0600 Subject: [PATCH 061/314] added another test and some clarifying comments --- src/reactor.h | 11 ++++++----- src/reactor_tests.cc | 45 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/reactor.h b/src/reactor.h index 73b9ac3bc9..70137afcc4 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -225,11 +225,6 @@ class Reactor : public cyclus::Facility { } std::vector fuel_prefs; - // This variable should be hidden/unavailable in ui. Maps resource object - // id's to the index for the incommod through which they were received. - #pragma cyclus var {"default": {}, "doc": "This should NEVER be set manually."} - std::map res_indexes; - // Resource inventories - these must be defined AFTER/BELOW the member vars // referenced (e.g. n_batch_fresh, assem_size, etc.). #pragma cyclus var {"capacity": "n_assem_fresh * assem_size"} @@ -292,6 +287,12 @@ class Reactor : public cyclus::Facility { // discharged this cycle. #pragma cyclus var {"default": 0, "doc": "This should NEVER be set manually."} bool discharged; + + // This variable should be hidden/unavailable in ui. Maps resource object + // id's to the index for the incommod through which they were received. + #pragma cyclus var {"default": {}, "doc": "This should NEVER be set manually."} + std::map res_indexes; + }; } // namespace cycamore diff --git a/src/reactor_tests.cc b/src/reactor_tests.cc index f142be6c92..2db792a282 100644 --- a/src/reactor_tests.cc +++ b/src/reactor_tests.cc @@ -258,7 +258,7 @@ TEST(ReactorTests, FuelShortage) { sim.AddRecipe("spentuox", c_spentuox()); int id = sim.Run(); - // check that we never got a full refueled batch + // check that we never got a full refueled batch during refuel period std::vector conds; conds.push_back(Cond("Time", "<", 15)); QueryResult qr = sim.db().Query("Transactions", &conds); @@ -271,13 +271,13 @@ TEST(ReactorTests, FuelShortage) { qr = sim.db().Query("Transactions", &conds); EXPECT_EQ(1, qr.rows.size()); - // all during the next cycle we shouldn't be requesting any new fuel + // all during the next (delayed) cycle we shouldn't be requesting any new fuel conds.clear(); conds.push_back(Cond("Time", "<", 21)); qr = sim.db().Query("Transactions", &conds); EXPECT_EQ(6, qr.rows.size()); - // as soon as this cycle ends, we should be requesting/getting 3 new batches + // as soon as this delayed cycle ends, we should be requesting/getting 3 new batches conds.clear(); conds.push_back(Cond("Time", "==", 22)); qr = sim.db().Query("Transactions", &conds); @@ -316,6 +316,45 @@ TEST(ReactorTests, DischargedFuelTransmute) { EXPECT_TRUE(mq.mass(942390000) > 0) << "transmuted spent fuel doesn't have Pu239"; } +// tests that spent fuel is offerred on correct commods according to the +// incommod it was received on - esp when dealing with multiple fuel commods +// simultaneously. +TEST(ReactorTests, SpentFuelProperCommodTracking) { + std::string config = + " uox mox " + " spentuox spentmox " + " uox mox " + " waste1 waste2 " + "" + " 1 " + " 0 " + " 1 " + " 3 " + " 3 "; + + int simdur = 7; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, simdur); + sim.AddSource("uox").capacity(1).Finalize(); + sim.AddSource("mox").capacity(2).Finalize(); + sim.AddSink("waste1").Finalize(); + sim.AddSink("waste2").Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("spentuox", c_spentuox()); + sim.AddRecipe("mox", c_mox()); + sim.AddRecipe("spentmox", c_spentmox()); + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("SenderId", "==", id)); + conds.push_back(Cond("Commodity", "==", std::string("waste1"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + EXPECT_EQ(simdur-1, qr.rows.size()); + + conds[1] = Cond("Commodity", "==", std::string("waste2")); + qr = sim.db().Query("Transactions", &conds); + EXPECT_EQ(2*(simdur-1), qr.rows.size()); +} + // The user can optionally omit fuel preferences. In the case where // preferences are adjusted, the ommitted preference vector must be populated // with default values - if it wasn't then preferences won't be adjusted From 70cdfcbab0ef0a7dc909371095aacb1d6b71f3c8 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 11 Mar 2015 12:28:39 -0500 Subject: [PATCH 062/314] fix spacing in reactor note --- src/reactor.h | 60 +++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/reactor.h b/src/reactor.h index 70137afcc4..26ef1e47db 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -47,42 +47,42 @@ class Reactor : public cyclus::Facility { "niche": "reactor", \ "doc": \ "Reactor is a simple, general reactor based on static compositional" \ - "transformations to model fuel burnup. The user specifies a set of input" \ - "fuels and corresponding burnt compositions that fuel is transformed to when" \ - "it is discharged from the core. No incremental transmutation takes place." \ - "Rather, at the end of an operational cycle, the batch being discharged from" \ - "the core is instantaneously transmuted from its original fresh fuel" \ - "composition into its spent fuel form." \ + " transformations to model fuel burnup. The user specifies a set of input" \ + " fuels and corresponding burnt compositions that fuel is transformed to when" \ + " it is discharged from the core. No incremental transmutation takes place." \ + " Rather, at the end of an operational cycle, the batch being discharged from" \ + " the core is instantaneously transmuted from its original fresh fuel" \ + " composition into its spent fuel form." \ "\n\n" \ "Each fuel is identified by a specific input commodity and has an associated" \ - "input recipe (nuclide composition), output recipe, output commidity, and" \ - "preference. The preference identifies which input fuels are preferred when" \ - "requesting. Changes in these preferences can be specified as a function of" \ - "time using the pref_change variables. Changes in the input-output recipe" \ - "compositions can also be specified as a function of time using the" \ - "recipe_change variables." \ + " input recipe (nuclide composition), output recipe, output commidity, and" \ + " preference. The preference identifies which input fuels are preferred when" \ + " requesting. Changes in these preferences can be specified as a function of" \ + " time using the pref_change variables. Changes in the input-output recipe" \ + " compositions can also be specified as a function of time using the" \ + " recipe_change variables." \ "\n\n" \ "The reactor treats fuel as individual assemblies that are never split," \ - "combined or otherwise treated in any non-discrete way. Fuel is requested" \ - "in full-or-nothing assembly sized quanta. If real-world assembly modeling" \ - "is unnecessary, parameters can be adjusted (e.g. n_assem_core, assem_size," \ - "n_assem_batch). At the end of every cycle, a full batch is discharged from" \ - "the core consisting of n_assem_batch assemblies of assem_size kg. The" \ - "reactor also has a specifiable refueling time period following the end of" \ - "each cycle at the end of which it will resume operation on the next cycle" \ - "*if* it has enough fuel for a full core; otherwise it waits until it has" \ - "enough fresh fuel assemblies." \ + " combined or otherwise treated in any non-discrete way. Fuel is requested" \ + " in full-or-nothing assembly sized quanta. If real-world assembly modeling" \ + " is unnecessary, parameters can be adjusted (e.g. n_assem_core, assem_size," \ + " n_assem_batch). At the end of every cycle, a full batch is discharged from" \ + " the core consisting of n_assem_batch assemblies of assem_size kg. The" \ + " reactor also has a specifiable refueling time period following the end of" \ + " each cycle at the end of which it will resume operation on the next cycle" \ + " *if* it has enough fuel for a full core; otherwise it waits until it has" \ + " enough fresh fuel assemblies." \ "\n\n" \ "In addition to its core, the reactor has an on-hand fresh fuel inventory" \ - "and a spent fuel inventory whose capacities are specified by n_assem_fresh" \ - "and n_assem_spent respectively. Each time step the reactor will attempt to" \ - "acquire enough fresh fuel to fill its fresh fuel inventory (and its core if" \ - "the core isn't currently full). If the fresh fuel inventory has zero" \ - "capacity, fuel will be ordered just-in-time after the end of each" \ - "operational cycle before the next begins. If the spent fuel inventory" \ - "becomes full, the reactor will halt operation at the end of the next cycle" \ - "until there is more room. Each time step, the reactor will try to trade" \ - "away as much of its spent fuel inventory as possible.", \ + " and a spent fuel inventory whose capacities are specified by n_assem_fresh" \ + " and n_assem_spent respectively. Each time step the reactor will attempt to" \ + " acquire enough fresh fuel to fill its fresh fuel inventory (and its core if" \ + " the core isn't currently full). If the fresh fuel inventory has zero" \ + " capacity, fuel will be ordered just-in-time after the end of each" \ + " operational cycle before the next begins. If the spent fuel inventory" \ + " becomes full, the reactor will halt operation at the end of the next cycle" \ + " until there is more room. Each time step, the reactor will try to trade" \ + " away as much of its spent fuel inventory as possible.", \ } public: From 4b26479c85a1c0aedcc6af73a62343a4d0f56f7b Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 25 Mar 2015 12:30:11 -0500 Subject: [PATCH 063/314] parallel vector input validation --- src/reactor.cc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/reactor.cc b/src/reactor.cc index 94efe7986c..306e1f5fab 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -35,6 +35,31 @@ void Reactor::EnterNotify() { fuel_prefs.push_back(0); } } + + // input consistency checking: + int n = recipe_change_times.size(); + std::stringstream ss; + if (recipe_change_commods.size() != n) { + ss << "prototype '" << prototype() << "' has " << recipe_change_commods.size() << " recipe_change_commods vals, expected " << n << "\n"; + } + if (recipe_change_in.size() != n) { + ss << "prototype '" << prototype() << "' has " << recipe_change_in.size() << " recipe_change_in vals, expected " << n << "\n"; + } + if (recipe_change_out.size() != n) { + ss << "prototype '" << prototype() << "' has " << recipe_change_out.size() << " recipe_change_out vals, expected " << n << "\n"; + } + + n = pref_change_times.size(); + if (pref_change_commods.size() != n) { + ss << "prototype '" << prototype() << "' has " << pref_change_commods.size() << " pref_change_commods vals, expected " << n << "\n"; + } + if (pref_change_values.size() != n) { + ss << "prototype '" << prototype() << "' has " << pref_change_values.size() << " pref_change_values vals, expected " << n << "\n"; + } + + if (ss.str().size() > 0) { + throw cyclus::ValueError(ss.str()); + } } void Reactor::Tick() { From 88624ec58b34d4900894f0991147dba7e55aeafa Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 30 Mar 2015 12:02:37 -0500 Subject: [PATCH 064/314] added namespace to reactor tests --- src/reactor_tests.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/reactor_tests.cc b/src/reactor_tests.cc index 2db792a282..8c743e5cf4 100644 --- a/src/reactor_tests.cc +++ b/src/reactor_tests.cc @@ -12,6 +12,7 @@ using cyclus::Cond; using cyclus::toolkit::MatQuery; namespace cycamore { +namespace reactortests { Composition::Ptr c_uox() { cyclus::CompMap m; @@ -460,5 +461,6 @@ TEST(ReactorTests, RecipeChange) { EXPECT_TRUE(0 < mq.mass(id("H1"))); } +} // namespace reactortests } // namespace cycamore From 1ec31b8c3fa527aa545ae575a9d9ad7d26bf1447 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Tue, 31 Mar 2015 13:04:18 -0500 Subject: [PATCH 065/314] add power time series --- src/reactor.cc | 8 ++++++++ src/reactor.h | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/src/reactor.cc b/src/reactor.cc index 306e1f5fab..41e2cda8ea 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -20,6 +20,7 @@ Reactor::Reactor(cyclus::Context* ctx) cycle_time(0), refuel_time(0), cycle_step(0), + power_cap(0), discharged(false) { cyclus::Warn("the Reactor archetype " "is experimental"); @@ -252,6 +253,13 @@ void Reactor::Tock() { Record("CYCLE_START", ""); } + if (cycle_step >= 0 && cycle_step < cycle_time && + core.count() == n_assem_core) { + cyclus::toolkit::RecordTimeSeries(this, power_cap); + } else { + cyclus::toolkit::RecordTimeSeries(this, 0); + } + // "if" prevents starting cycle after initial deployment until core is full // even though cycle_step is its initial zero. if (cycle_step > 0 || core.count() == n_assem_core) { diff --git a/src/reactor.h b/src/reactor.h index 26ef1e47db..5e176783ed 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -293,6 +293,13 @@ class Reactor : public cyclus::Facility { #pragma cyclus var {"default": {}, "doc": "This should NEVER be set manually."} std::map res_indexes; + #pragma cyclus var { \ + "default": 0, \ + "doc": "Amount of electrical power the facility produces when operating normally.", \ + "units": "MWe", \ + } + double power_cap; + }; } // namespace cycamore From 5ad1c84f813e9be9d89a97a4a69f0eeb5787db66 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 8 Apr 2015 08:26:02 -0500 Subject: [PATCH 066/314] clang-format --- src/reactor.cc | 82 ++++++++++++++++++++++++++------------------------ src/reactor.h | 19 ++++++------ 2 files changed, 52 insertions(+), 49 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index 41e2cda8ea..97a7602770 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -22,8 +22,9 @@ Reactor::Reactor(cyclus::Context* ctx) cycle_step(0), power_cap(0), discharged(false) { - cyclus::Warn("the Reactor archetype " - "is experimental"); + cyclus::Warn( + "the Reactor archetype " + "is experimental"); } void Reactor::EnterNotify() { @@ -41,21 +42,27 @@ void Reactor::EnterNotify() { int n = recipe_change_times.size(); std::stringstream ss; if (recipe_change_commods.size() != n) { - ss << "prototype '" << prototype() << "' has " << recipe_change_commods.size() << " recipe_change_commods vals, expected " << n << "\n"; + ss << "prototype '" << prototype() << "' has " + << recipe_change_commods.size() + << " recipe_change_commods vals, expected " << n << "\n"; } if (recipe_change_in.size() != n) { - ss << "prototype '" << prototype() << "' has " << recipe_change_in.size() << " recipe_change_in vals, expected " << n << "\n"; + ss << "prototype '" << prototype() << "' has " << recipe_change_in.size() + << " recipe_change_in vals, expected " << n << "\n"; } if (recipe_change_out.size() != n) { - ss << "prototype '" << prototype() << "' has " << recipe_change_out.size() << " recipe_change_out vals, expected " << n << "\n"; + ss << "prototype '" << prototype() << "' has " << recipe_change_out.size() + << " recipe_change_out vals, expected " << n << "\n"; } n = pref_change_times.size(); if (pref_change_commods.size() != n) { - ss << "prototype '" << prototype() << "' has " << pref_change_commods.size() << " pref_change_commods vals, expected " << n << "\n"; + ss << "prototype '" << prototype() << "' has " << pref_change_commods.size() + << " pref_change_commods vals, expected " << n << "\n"; } if (pref_change_values.size() != n) { - ss << "prototype '" << prototype() << "' has " << pref_change_values.size() << " pref_change_values vals, expected " << n << "\n"; + ss << "prototype '" << prototype() << "' has " << pref_change_values.size() + << " pref_change_values vals, expected " << n << "\n"; } if (ss.str().size() > 0) { @@ -66,7 +73,8 @@ void Reactor::EnterNotify() { void Reactor::Tick() { // The following code must go in the Tick so they fire on the time step // following the cycle_step update - allowing for the all reactor events to - // occur and be recorded on the "beginning" of a time step. Another reason they + // occur and be recorded on the "beginning" of a time step. Another reason + // they // can't go at the beginnin of the Tock is so that resource exchange has a // chance to occur after the discharge on this same time step. if (cycle_step == cycle_time) { @@ -114,18 +122,16 @@ void Reactor::Tick() { } } } - } -std::set::Ptr> -Reactor::GetMatlRequests() { +std::set::Ptr> Reactor::GetMatlRequests() { using cyclus::RequestPortfolio; std::set::Ptr> ports; Material::Ptr m; - int n_assem_order = n_assem_core - core.count() - + n_assem_fresh - fresh.count(); + int n_assem_order = + n_assem_core - core.count() + n_assem_fresh - fresh.count(); if (n_assem_order == 0) { return ports; } @@ -149,13 +155,13 @@ Reactor::GetMatlRequests() { } void Reactor::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - Material::Ptr> >& responses) { + const std::vector >& trades, + std::vector, Material::Ptr> >& + responses) { using cyclus::Trade; std::map mats = PopSpent(); - std::vector< cyclus::Trade >::const_iterator it; + std::vector >::const_iterator it; for (int i = 0; i < trades.size(); i++) { std::string commod = trades[i].request->commodity(); Material::Ptr m = mats[commod].back(); @@ -163,15 +169,13 @@ void Reactor::GetMatlTrades( responses.push_back(std::make_pair(trades[i], m)); res_indexes.erase(m->obj_id()); } - PushSpent(mats); // return leftovers back to spent buffer + PushSpent(mats); // return leftovers back to spent buffer } -void Reactor::AcceptMatlTrades( - const std::vector< std::pair, - Material::Ptr> >& responses) { - - std::vector< std::pair, - cyclus::Material::Ptr> >::const_iterator trade; +void Reactor::AcceptMatlTrades(const std::vector< + std::pair, Material::Ptr> >& responses) { + std::vector, + cyclus::Material::Ptr> >::const_iterator trade; std::stringstream ss; int nload = std::min((int)responses.size(), n_assem_core - core.count()); @@ -193,9 +197,8 @@ void Reactor::AcceptMatlTrades( } } -std::set::Ptr> -Reactor::GetMatlBids(cyclus::CommodMap::type& - commod_requests) { +std::set::Ptr> Reactor::GetMatlBids( + cyclus::CommodMap::type& commod_requests) { using cyclus::BidPortfolio; std::set::Ptr> ports; @@ -297,7 +300,7 @@ std::map Reactor::PeekSpent() { bool Reactor::Discharge() { if (n_assem_spent - spent.count() < n_assem_batch) { Record("DISCHARGE", "failed"); - return false; // not enough room in spent buffer + return false; // not enough room in spent buffer } int npop = std::min(n_assem_batch, core.count()); @@ -369,7 +372,8 @@ void Reactor::index_res(cyclus::Resource::Ptr m, std::string incommod) { return; } } - throw ValueError("cycamore::Reactor - received unsupported incommod material"); + throw ValueError( + "cycamore::Reactor - received unsupported incommod material"); } std::map Reactor::PopSpent() { @@ -388,7 +392,7 @@ std::map Reactor::PopSpent() { return mapped; } - + void Reactor::PushSpent(std::map leftover) { std::map::iterator it; for (it = leftover.begin(); it != leftover.end(); ++it) { @@ -397,19 +401,19 @@ void Reactor::PushSpent(std::map leftover) { spent.Push(it->second); } } - + void Reactor::Record(std::string name, std::string val) { - context()->NewDatum("ReactorEvents") - ->AddVal("AgentId", id()) - ->AddVal("Time", context()->time()) - ->AddVal("Event", name) - ->AddVal("Value", val) - ->Record(); + context() + ->NewDatum("ReactorEvents") + ->AddVal("AgentId", id()) + ->AddVal("Time", context()->time()) + ->AddVal("Event", name) + ->AddVal("Value", val) + ->Record(); } extern "C" cyclus::Agent* ConstructReactor(cyclus::Context* ctx) { return new Reactor(ctx); } -} // namespace cycamore - +} // namespace cycamore diff --git a/src/reactor.h b/src/reactor.h index 5e176783ed..641ce47aa5 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -87,26 +87,25 @@ class Reactor : public cyclus::Facility { public: Reactor(cyclus::Context* ctx); - virtual ~Reactor() {}; + virtual ~Reactor(){}; virtual void Tick(); virtual void Tock(); virtual void EnterNotify(); - virtual void AcceptMatlTrades( - const std::vector< std::pair, - cyclus::Material::Ptr> >& responses); + virtual void AcceptMatlTrades(const std::vector, cyclus::Material::Ptr> >& responses); - virtual std::set::Ptr> GetMatlRequests(); + virtual std::set::Ptr> + GetMatlRequests(); - virtual std::set::Ptr> - GetMatlBids(cyclus::CommodMap::type& - commod_requests); + virtual std::set::Ptr> GetMatlBids( + cyclus::CommodMap::type& commod_requests); virtual void GetMatlTrades( - const std::vector< cyclus::Trade >& trades, + const std::vector >& trades, std::vector, - cyclus::Material::Ptr> >& responses); + cyclus::Material::Ptr> >& responses); #pragma cyclus From c42baa70bce661ac6f7b1eba3e70ccd5aebf0bb1 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 8 Apr 2015 08:27:12 -0500 Subject: [PATCH 067/314] remove trailing whitespace --- src/reactor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactor.h b/src/reactor.h index 641ce47aa5..6e98566179 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -212,7 +212,7 @@ class Reactor : public cyclus::Facility { std::vector fuel_outrecipes; #pragma cyclus var { \ "uitype": ["oneormore", "incommodity"], \ - "doc": "Output commodities on which to offer spent fuel originally received as each particular " \ + "doc": "Output commodities on which to offer spent fuel originally received as each particular " \ " input commodity (same order)." \ } std::vector fuel_outcommods; From f35e813fb2674ef46d85efb170dc3d42a4787835 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 8 Apr 2015 08:53:36 -0500 Subject: [PATCH 068/314] clang-format --- src/deploy_inst.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/deploy_inst.cc b/src/deploy_inst.cc index 0e2990595a..0c66e698db 100644 --- a/src/deploy_inst.cc +++ b/src/deploy_inst.cc @@ -37,15 +37,18 @@ void DeployInst::EnterNotify() { int n = prototypes.size(); if (build_times.size() != n) { std::stringstream ss; - ss << "prototype '" << prototype() << "' has " << build_times.size() << " build_times vals, expected " << n; + ss << "prototype '" << prototype() << "' has " << build_times.size() + << " build_times vals, expected " << n; throw cyclus::ValueError(ss.str()); } else if (n_build.size() != n) { std::stringstream ss; - ss << "prototype '" << prototype() << "' has " << n_build.size() << " n_build vals, expected " << n; + ss << "prototype '" << prototype() << "' has " << n_build.size() + << " n_build vals, expected " << n; throw cyclus::ValueError(ss.str()); } else if (lifetimes.size() > 0 && lifetimes.size() != n) { std::stringstream ss; - ss << "prototype '" << prototype() << "' has " << lifetimes.size() << " lifetimes vals, expected " << n; + ss << "prototype '" << prototype() << "' has " << lifetimes.size() + << " lifetimes vals, expected " << n; throw cyclus::ValueError(ss.str()); } } From e9489477bf83959dda571d18ac5dc7193323ba6f Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 9 Jan 2015 16:31:22 -0600 Subject: [PATCH 069/314] Remove BatchReactor and related files. Update input files and tests to use new reactor. --- input/batch_reactor/batch_rxtr_2_cycles.xml | 199 ---- input/batch_reactor/batch_rxtr_lifetime.xml | 191 ---- input/batch_reactor/hwr.xml | 249 ----- input/batch_reactor/lwr.xml | 249 ----- input/batch_reactor/preferences.xml | 119 --- input/enrichment/1_src_enr_rxtr_sink.xml | 30 +- input/physor/1_Enrichment_2_Reactor.xml | 117 +-- input/physor/2_Sources_3_Reactors.xml | 176 +--- src/CMakeLists.txt | 4 - src/batch_reactor.cc | 1049 ------------------- src/batch_reactor.h | 445 -------- src/batch_reactor_tests.cc | 400 ------- src/batch_reactor_tests.h | 72 -- tests/test_regression.py | 95 +- 14 files changed, 148 insertions(+), 3247 deletions(-) delete mode 100644 input/batch_reactor/batch_rxtr_2_cycles.xml delete mode 100644 input/batch_reactor/batch_rxtr_lifetime.xml delete mode 100644 input/batch_reactor/hwr.xml delete mode 100644 input/batch_reactor/lwr.xml delete mode 100644 input/batch_reactor/preferences.xml delete mode 100644 src/batch_reactor.cc delete mode 100644 src/batch_reactor.h delete mode 100644 src/batch_reactor_tests.cc delete mode 100644 src/batch_reactor_tests.h diff --git a/input/batch_reactor/batch_rxtr_2_cycles.xml b/input/batch_reactor/batch_rxtr_2_cycles.xml deleted file mode 100644 index 5dacac3fe4..0000000000 --- a/input/batch_reactor/batch_rxtr_2_cycles.xml +++ /dev/null @@ -1,199 +0,0 @@ - - - - - 27 - 1 - 2000 - - - - - cycamore - Source - - - cycamore - BatchReactor - - - cycamore - Sink - - - agents - NullRegion - - - agents - NullInst - - - - - Source - - - enriched_u - 1.0e10 - lwr_fuel_recipe - - - - - - LWR_Reactor - 26 - - - - enriched_u - lwr_fuel_recipe - waste - lwr_used_fuel_recipe - - 10 - 2 - 4 - 7.8707064e4 - - lwr_power - 1000 - 1000 - - - - - - - Sink - - - - waste - - 1.0e10 - - - - - - SingleRegion - - - SingleInstitution - - - Source - 1 - - - LWR_Reactor - 1 - - - Sink - 1 - - - - - - - - natl_u - mass - - 922350000 - 0.711 - - - 922380000 - 99.289 - - - - - lwr_fuel_recipe - mass - - 922350000 - 4.0 - - - 922380000 - 96.0 - - - - - lwr_used_fuel_recipe - mass - - 922350000 - 156.729 - - - 922360000 - 102.103 - - - 922380000 - 18280.324 - - - 932370000 - 13.656 - - - 942380000 - 5.043 - - - 942390000 - 106.343 - - - 942400000 - 41.357 - - - 942410000 - 36.477 - - - 942420000 - 15.387 - - - 952410000 - 1.234 - - - - - - - 952430000 - 3.607 - - - 962440000 - 0.431 - - - 962450000 - 1.263 - - - - diff --git a/input/batch_reactor/batch_rxtr_lifetime.xml b/input/batch_reactor/batch_rxtr_lifetime.xml deleted file mode 100644 index 3fce5536bb..0000000000 --- a/input/batch_reactor/batch_rxtr_lifetime.xml +++ /dev/null @@ -1,191 +0,0 @@ - - - - - 482 - 1 - 2000 - - - - - cycamore - Source - - - cycamore - BatchReactor - - - agents - NullRegion - - - agents - NullInst - - - cycamore - Sink - - - - - Source - - - enriched_u - 1.0e10 - lwr_fuel_recipe - - - - - - LWR_Reactor - 480 - - - - enriched_u - lwr_fuel_recipe - waste - lwr_used_fuel_recipe - - 10 - 2 - 4 - 19676.766 - - lwr_power - 1000 - 1000 - - - - - - - Sink - - - - waste - - 1.0e10 - - - - - - SingleRegion - - - SingleInstitution - - - Source - 1 - - - LWR_Reactor - 1 - - - Sink - 1 - - - - - - - - natl_u - mass - - 922350000 - 0.711 - - - 922380000 - 99.289 - - - - - lwr_fuel_recipe - mass - - 922350000 - 4.0 - - - 922380000 - 96.0 - - - - - lwr_used_fuel_recipe - mass - - 922350000 - 156.729 - - - 922360000 - 102.103 - - - 922380000 - 18280.324 - - - 932370000 - 13.656 - - - 942380000 - 5.043 - - - 942390000 - 106.343 - - - 942400000 - 41.357 - - - 942410000 - 36.477 - - - 942420000 - 15.387 - - - 952410000 - 1.234 - - - - - - - 952430000 - 3.607 - - - 962440000 - 0.431 - - - 962450000 - 1.263 - - - - diff --git a/input/batch_reactor/hwr.xml b/input/batch_reactor/hwr.xml deleted file mode 100644 index 5438f256d4..0000000000 --- a/input/batch_reactor/hwr.xml +++ /dev/null @@ -1,249 +0,0 @@ - - - - - 482 - 11 - 2007 - - - - - cycamore - Source - - - cycamore - BatchReactor - - - cycamore - Sink - - - agents - NullRegion - - - agents - NullInst - - - - - Source - - - enriched_u - natl_u - - - - - - HW_Reactor - 480 - - - - enriched_u - natl_u - waste - hwr_used_fuel_recipe - - 10 - 2 - 1 - 1.39142873e5 - - hwr_power - 600 - 600 - - - - - - - Sink - - - - waste - - - - - - - SingleRegion - - - SingleInstitution - - - Source - 1 - - - HW_Reactor - 1 - - - Sink - 1 - - - - - - - - natl_u - mass - - 922350000 - 0.711 - - - 922380000 - 99.289 - - - - - lwr_fuel_recipe - mass - - 922350000 - 4.0 - - - 922380000 - 96.0 - - - - - lwr_used_fuel_recipe - mass - - 922350000 - 156.729 - - - 922360000 - 102.103 - - - 922380000 - 18280.324 - - - 932370000 - 13.656 - - - 942380000 - 5.043 - - - 942390000 - 106.343 - - - 942400000 - 41.357 - - - 942410000 - 36.477 - - - 942420000 - 15.387 - - - 952410000 - 1.234 - - - - - - - 952430000 - 3.607 - - - 962440000 - 0.431 - - - 962450000 - 1.263 - - - - - hwr_used_fuel_recipe - mass - - 922350000 - 330.478 - - - 922360000 - 98.944 - - - 922380000 - 137171.079 - - - 932370000 - 3.604 - - - 942380000 - 0.459 - - - 942390000 - 369.87 - - - 942400000 - 133.16 - - - 942410000 - 25.227 - - - 942420000 - 5.468 - - - 952410000 - 0.195 - - - - - - - 952430000 - 0.167 - - - 962440000 - 0.07 - - - 962450000 - 0.014 - - - - diff --git a/input/batch_reactor/lwr.xml b/input/batch_reactor/lwr.xml deleted file mode 100644 index 0936bd8fa2..0000000000 --- a/input/batch_reactor/lwr.xml +++ /dev/null @@ -1,249 +0,0 @@ - - - - - 482 - 11 - 2007 - - - - - cycamore - Source - - - cycamore - BatchReactor - - - cycamore - Sink - - - agents - NullRegion - - - agents - NullInst - - - - - Source - - - enriched_u - lwr_fuel_recipe - - - - - - LW_Reactor - 480 - - - - enriched_u - lwr_fuel_recipe - waste - hwr_used_fuel_recipe - - 10 - 2 - 4 - 7.8707064e4 - - lwr_power - 1000 - 1000 - - - - - - - Sink - - - - waste - - - - - - - SingleRegion - - - SingleInstitution - - - Source - 1 - - - LW_Reactor - 1 - - - Sink - 1 - - - - - - - - natl_u - mass - - 922350000 - 0.711 - - - 922380000 - 99.289 - - - - - lwr_fuel_recipe - mass - - 922350000 - 4.0 - - - 922380000 - 96.0 - - - - - lwr_used_fuel_recipe - mass - - 922350000 - 156.729 - - - 922360000 - 102.103 - - - 922380000 - 18280.324 - - - 932370000 - 13.656 - - - 942380000 - 5.043 - - - 942390000 - 106.343 - - - 942400000 - 41.357 - - - 942410000 - 36.477 - - - 942420000 - 15.387 - - - 952410000 - 1.234 - - - - - - - 952430000 - 3.607 - - - 962440000 - 0.431 - - - 962450000 - 1.263 - - - - - hwr_used_fuel_recipe - mass - - 922350000 - 330.478 - - - 922360000 - 98.944 - - - 922380000 - 137171.079 - - - 932370000 - 3.604 - - - 942380000 - 0.459 - - - 942390000 - 369.87 - - - 942400000 - 133.16 - - - 942410000 - 25.227 - - - 942420000 - 5.468 - - - 952410000 - 0.195 - - - - - - - 952430000 - 0.167 - - - 962440000 - 0.07 - - - 962450000 - 0.014 - - - - diff --git a/input/batch_reactor/preferences.xml b/input/batch_reactor/preferences.xml deleted file mode 100644 index ec27566b45..0000000000 --- a/input/batch_reactor/preferences.xml +++ /dev/null @@ -1,119 +0,0 @@ - - - - - 10 - 1 - 2000 - - - - - cycamore - Source - - - cycamore - BatchReactor - - - cycamore - Sink - - - agents - NullRegion - - - agents - NullInst - - - - - Source - - - used_commodity - 1 - commod_recipe - - - - - - Reactor - - - - used_commodity - commod_recipe - processed_commodity - commod_recipe - - 1 - 1 - 1 - - power - 10 - 10 - - - used_commodity - 1.0 - - - - - - - Sink - - - - used_commodity - processed_commodity - - 2 - - - - - - SingleRegion - - - SingleInstitution - - - Source - 1 - - - Reactor - 1 - - - Sink - 1 - - - - - - - - commod_recipe - mass - - 010010000 - 1 - - - - diff --git a/input/enrichment/1_src_enr_rxtr_sink.xml b/input/enrichment/1_src_enr_rxtr_sink.xml index 7a7cc42008..bf73b347b4 100644 --- a/input/enrichment/1_src_enr_rxtr_sink.xml +++ b/input/enrichment/1_src_enr_rxtr_sink.xml @@ -11,7 +11,7 @@ cycamoreSink cycamoreSource cycamoreEnrichmentFacility - cycamoreBatchReactor + cycamoreReactor agentsNullRegion agentsNullInst @@ -43,22 +43,18 @@ Reactor - - - enriched_u - fuel_recipe - waste - used_fuel_recipe - - 1 - 1 - 2 - - power - 10 - 10 - - + + fuel_recipe + used_fuel_recipe + enriched_u + waste + + 1 + 0 + 2 + 1 + 1 + diff --git a/input/physor/1_Enrichment_2_Reactor.xml b/input/physor/1_Enrichment_2_Reactor.xml index 1a41469cbf..bb04eadb8d 100755 --- a/input/physor/1_Enrichment_2_Reactor.xml +++ b/input/physor/1_Enrichment_2_Reactor.xml @@ -8,22 +8,10 @@ - - cycamore - EnrichmentFacility - - - cycamore - BatchReactor - - - agents - NullRegion - - - agents - NullInst - + cycamore EnrichmentFacility + cycamore Reactor + agents NullRegion + agents NullInst @@ -43,78 +31,43 @@ Reactor1 - - - enriched_u - lwr_fuel_recipe - waste - lwr_used_fuel_recipe - - 1 - 1 - 1 - 0 - - - 1 - enriched_u - lwr_fuel_recipe - - - - enriched_u - lwr_fuel_recipe2 - - - - enriched_u - lwr_fuel_recipe - - - - lwr_power - .928 - 64 - - - enriched_u - 1.0 - - + + lwr_fuel_recipe + lwr_used_fuel_recipe + enriched_u + waste + 1.0 + + 1 + 0 + 0.1 + 10 + 10 + + 1 2 + enriched_u enriched_u + lwr_fuel_recipe2 lwr_fuel_recipe + lwr_used_fuel_recipe lwr_used_fuel_recipe + Reactor2 - - - enriched_u - lwr_fuel_recipe - waste - lwr_used_fuel_recipe - - 1 - 1 - 1 - 0 - - - 1 - enriched_u - lwr_fuel_recipe - - - - lwr_power - .928 - 64 - - - enriched_u - 0.5 - - + + lwr_fuel_recipe + lwr_used_fuel_recipe + enriched_u + waste + 0.5 + + 1 + 0 + 0.1 + 10 + 10 + diff --git a/input/physor/2_Sources_3_Reactors.xml b/input/physor/2_Sources_3_Reactors.xml index 742a968528..30e6632a6f 100755 --- a/input/physor/2_Sources_3_Reactors.xml +++ b/input/physor/2_Sources_3_Reactors.xml @@ -8,22 +8,10 @@ - - cycamore - Source - - - cycamore - BatchReactor - - - agents - NullRegion - - - cycamore - DeployInst - + cycamore Source + cycamore Reactor + agents NullRegion + cycamore DeployInst @@ -32,7 +20,7 @@ uox uox_fuel_recipe - 2.5 + 2.500000001 @@ -43,7 +31,7 @@ mox mox_fuel_recipe - 2.5 + 2.500000001 @@ -51,125 +39,63 @@ Reactor1 - - - uox - uox_fuel_recipe - waste - uox_used_fuel_recipe - - - mox - mox_fuel_recipe - waste - mox_used_fuel_recipe - - 1 - 1 - 1 - 0 - - - 1 - mox - mox_fuel_recipe - - - - lwr_power - .928 - 64 - - - mox - 1.0 - - - uox - 2.0 - - - + + + uox_fuel_recipe mox_fuel_recipe + uox_used_fuel_recipe mox_used_fuel_recipe + uox mox + waste waste + 0.0 1.0 + + 1 + 0 + 0.1 + 10 + 10 + + 4 + uox + 2.0 + + Reactor2 - - - uox - uox_fuel_recipe - waste - uox_used_fuel_recipe - - - mox - mox_fuel_recipe - waste - mox_used_fuel_recipe - - 1 - 1 - 1 - 0 - - - 1 - mox - mox_fuel_recipe - - - - lwr_power - .928 - 64 - - - mox - 1.0 - - + + uox_fuel_recipe mox_fuel_recipe + uox_used_fuel_recipe mox_used_fuel_recipe + uox mox + waste waste + 0.0 1.0 + + 1 + 0 + 0.1 + 10 + 10 + Reactor3 - - - uox - uox_fuel_recipe - waste - uox_used_fuel_recipe - - - mox - mox_fuel_recipe - waste - mox_used_fuel_recipe - - 1 - 1 - 1 - 0 - - - 1 - mox - mox_fuel_recipe - - - - lwr_power - .928 - 64 - - - mox - 0.5 - - + + uox_fuel_recipe mox_fuel_recipe + uox_used_fuel_recipe mox_used_fuel_recipe + uox mox + waste waste + 0.0 0.5 + + 1 + 0 + 0.1 + 10 + 10 + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c85d3d11a2..3f7ae00400 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,13 +1,9 @@ # ------------------- Add all Concrete Agents ---------------------------- -USE_CYCLUS("cycamore" "batch_reactor") - USE_CYCLUS("cycamore" "reactor") USE_CYCLUS("cycamore" "enrichment_facility") -#USE_CYCLUS("cycamore" "inpro_reactor") - USE_CYCLUS("cycamore" "sink") USE_CYCLUS("cycamore" "source") diff --git a/src/batch_reactor.cc b/src/batch_reactor.cc deleted file mode 100644 index ebde933459..0000000000 --- a/src/batch_reactor.cc +++ /dev/null @@ -1,1049 +0,0 @@ -// Implements the BatchReactor class -#include "batch_reactor.h" - -#include -#include - -namespace cycamore { - -// static members -std::map BatchReactor::phase_names_ = - std::map(); - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -BatchReactor::BatchReactor(cyclus::Context* ctx) - : cyclus::Facility(ctx), - process_time_(1), - preorder_time_(0), - refuel_time_(0), - start_time_(-1), - to_begin_time_(std::numeric_limits::max()), - n_batches_(1), - n_load_(1), - n_reserves_(0), - batch_size_(1), - phase_(INITIAL) { - cyclus::Warn("the BatchReactor agent " - "is considered experimental."); - if (phase_names_.empty()) { - SetUpPhaseNames_(); - } - spillover_ = cyclus::NewBlankMaterial(0); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -BatchReactor::~BatchReactor() {} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::string BatchReactor::schema() { - return - " \n" - + crctx_.schema() + - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n"; -} - -void BatchReactor::InitFrom(cyclus::QueryableBackend* b) { - cyclus::Facility::InitFrom(b); - - crctx_.InitFrom(b); - - // facility info - cyclus::QueryResult qr = b->Query("Info", NULL); - process_time_ = qr.GetVal("processtime"); - preorder_time_ = qr.GetVal("preorder_t"); - refuel_time_ = qr.GetVal("refueltime"); - start_time_ = qr.GetVal("starttime"); - to_begin_time_ = qr.GetVal("tobegintime"); - n_batches_ = qr.GetVal("nbatches"); - n_load_ = qr.GetVal("nreload"); - n_reserves_ = qr.GetVal("norder"); - batch_size_ = qr.GetVal("batchsize"); - phase_ = static_cast(qr.GetVal("phase")); - - std::string out_commod = qr.GetVal("out_commod"); - cyclus::toolkit::CommodityProducer::Add(out_commod); - cyclus::toolkit::CommodityProducer:: - SetCapacity(out_commod, qr.GetVal("out_commod_cap")); - cyclus::toolkit::CommodityProducer:: - SetCost(out_commod, qr.GetVal("out_commod_cap")); - - // initial condition inventories - std::vector conds; - conds.push_back(cyclus::Cond("inventory", "==", std::string("reserves"))); - qr = b->Query("InitialInv", &conds); - ics_.AddReserves( - qr.GetVal("nbatches"), - qr.GetVal("recipe"), - qr.GetVal("commod") - ); - conds[0] = cyclus::Cond("inventory", "==", std::string("core")); - qr = b->Query("InitialInv", &conds); - ics_.AddCore( - qr.GetVal("nbatches"), - qr.GetVal("recipe"), - qr.GetVal("commod") - ); - conds[0] = cyclus::Cond("inventory", "==", std::string("storage")); - qr = b->Query("InitialInv", &conds); - ics_.AddStorage( - qr.GetVal("nbatches"), - qr.GetVal("recipe"), - qr.GetVal("commod") - ); - - // trade preferences - try { - qr.Reset(); - qr = b->Query("CommodPrefs", NULL); - } catch(std::exception err) {} // table doesn't exist (okay) - for (int i = 0; i < qr.rows.size(); ++i) { - std::string c = qr.GetVal("incommodity", i); - commod_prefs_[c] = qr.GetVal("preference", i); - } - - // pref changes - try { - qr.Reset(); - qr = b->Query("PrefChanges", NULL); - } catch(std::exception err) {} // table doesn't exist (okay) - for (int i = 0; i < qr.rows.size(); ++i) { - std::string c = qr.GetVal("incommodity", i); - int t = qr.GetVal("time", i); - double new_pref = qr.GetVal("new_pref", i); - pref_changes_[t].push_back(std::make_pair(c, new_pref)); - } - - // pref changes - try { - qr.Reset(); - qr = b->Query("RecipeChanges", NULL); - } catch(std::exception err) {} // table doesn't exist (okay) - for (int i = 0; i < qr.rows.size(); ++i) { - std::string c = qr.GetVal("incommodity", i); - int t = qr.GetVal("time", i); - std::string new_recipe = qr.GetVal("new_recipe", i); - recipe_changes_[t].push_back(std::make_pair(c, new_recipe)); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactor::InfileToDb(cyclus::InfileTree* qe, cyclus::DbInit di) { - cyclus::Facility::InfileToDb(qe, di); - qe = qe->SubTree("config/*"); - - using cyclus::toolkit::Commodity; - using cyclus::toolkit::CommodityProducer; - using cyclus::OptionalQuery; - using cyclus::Query; - using cyclus::InfileTree; - using std::string; - - crctx_.InfileToDb(qe, di); - - // facility data - int processtime = Query(qe, "processtime"); - int nbatches = Query(qe, "nbatches"); - double batchsize = Query(qe, "batchsize"); - int refuel_t = OptionalQuery(qe, "refueltime", refuel_time()); - int preorder_t = OptionalQuery(qe, "orderlookahead", preorder_time()); - int nreload = OptionalQuery(qe, "nreload", n_load()); - int norder = OptionalQuery(qe, "norder", n_reserves()); - - InfileTree* commodity = qe->SubTree("commodity_production"); - std::string out_commod = commodity->GetString("commodity"); - double commod_cap = Query(commodity, "capacity"); - double commod_cost = Query(commodity, "cost"); - - di.NewDatum("Info") - ->AddVal("processtime", processtime) - ->AddVal("nbatches", nbatches) - ->AddVal("batchsize", batchsize) - ->AddVal("refueltime", refuel_t) - ->AddVal("preorder_t", preorder_t) - ->AddVal("nreload", nreload) - ->AddVal("norder", norder) - ->AddVal("starttime", -1) - ->AddVal("tobegintime", std::numeric_limits::max()) - ->AddVal("phase", static_cast(INITIAL)) - ->AddVal("out_commod", out_commod) - ->AddVal("out_commod_cap", commod_cap) - ->AddVal("out_commod_cost", commod_cost) - ->Record(); - - // initial condition inventories - std::vector inv_names; - inv_names.push_back("reserves"); - inv_names.push_back("core"); - inv_names.push_back("storage"); - for (int i = 0; i < inv_names.size(); ++i) { - int n = 0; - std::string recipe; - std::string commod; - if (qe->NMatches("initial_condition") > 0) { - InfileTree* ic = qe->SubTree("initial_condition"); - if (ic->NMatches(inv_names[i]) > 0) { - InfileTree* reserves = ic->SubTree(inv_names[i]); - n = Query(reserves, "nbatches"); - recipe = reserves->GetString("recipe"); - commod = reserves->GetString("commodity"); - } - } - di.NewDatum("InitialInv") - ->AddVal("inventory", inv_names[i]) - ->AddVal("nbatches", n) - ->AddVal("recipe", recipe) - ->AddVal("commod", commod) - ->Record(); - } - - // trade preferences - int nprefs = qe->NMatches("commod_pref"); - std::string c; - for (int i = 0; i < nprefs; i++) { - InfileTree* cp = qe->SubTree("commod_pref", i); - di.NewDatum("CommodPrefs") - ->AddVal("incommodity", cp->GetString("incommodity")) - ->AddVal("preference", Query(cp, "preference")) - ->Record(); - } - - // pref changes - int nchanges = qe->NMatches("pref_change"); - for (int i = 0; i < nchanges; i++) { - InfileTree* cp = qe->SubTree("pref_change", i); - di.NewDatum("PrefChanges") - ->AddVal("incommodity", cp->GetString("incommodity")) - ->AddVal("new_pref", Query(cp, "new_pref")) - ->AddVal("time", Query(cp, "time")) - ->Record(); - } - - // recipe changes - nchanges = qe->NMatches("recipe_change"); - for (int i = 0; i < nchanges; i++) { - InfileTree* cp = qe->SubTree("recipe_change", i); - di.NewDatum("RecipeChanges") - ->AddVal("incommodity", cp->GetString("incommodity")) - ->AddVal("new_recipe", cp->GetString("new_recipe")) - ->AddVal("time", Query(cp, "time")) - ->Record(); - } -} - -void BatchReactor::Snapshot(cyclus::DbInit di) { - cyclus::Facility::Snapshot(di); - crctx_.Snapshot(di); - - std::set:: - iterator it; - it = cyclus::toolkit::CommodityProducer::ProducedCommodities().begin(); - std::string out_commod = it->name(); - double cost = cyclus::toolkit::CommodityProducer::Cost(out_commod); - double cap = cyclus::toolkit::CommodityProducer::Capacity(out_commod); - di.NewDatum("Info") - ->AddVal("processtime", process_time_) - ->AddVal("nbatches", n_batches_) - ->AddVal("batchsize", batch_size_) - ->AddVal("refueltime", refuel_time_) - ->AddVal("preorder_t", preorder_time_) - ->AddVal("nreload", n_load_) - ->AddVal("norder", n_reserves_) - ->AddVal("starttime", start_time_) - ->AddVal("tobegintime", to_begin_time_) - ->AddVal("phase", static_cast(phase_)) - ->AddVal("out_commod", out_commod) - ->AddVal("out_commod_cap", cap) - ->AddVal("out_commod_cost", cost) - ->Record(); - - // initial condition inventories - di.NewDatum("InitialInv") - ->AddVal("inventory", std::string("reserves")) - ->AddVal("nbatches", ics_.n_reserves) - ->AddVal("recipe", ics_.reserves_rec) - ->AddVal("commod", ics_.reserves_commod) - ->Record(); - di.NewDatum("InitialInv") - ->AddVal("inventory", std::string("core")) - ->AddVal("nbatches", ics_.n_core) - ->AddVal("recipe", ics_.core_rec) - ->AddVal("commod", ics_.core_commod) - ->Record(); - di.NewDatum("InitialInv") - ->AddVal("inventory", std::string("storage")) - ->AddVal("nbatches", ics_.n_storage) - ->AddVal("recipe", ics_.storage_rec) - ->AddVal("commod", ics_.storage_commod) - ->Record(); - - // trade preferences - std::map::iterator it2 = commod_prefs_.begin(); - for (; it2 != commod_prefs_.end(); ++it2) { - di.NewDatum("CommodPrefs") - ->AddVal("incommodity", it2->first) - ->AddVal("preference", it2->second) - ->Record(); - } - - // pref changes - std::map > >::iterator it3; - for (it3 = pref_changes_.begin(); it3 != pref_changes_.end(); ++it3) { - int t = it3->first; - for (int i = 0; i < it3->second.size(); ++i) { - std::string commod = it3->second[i].first; - double pref = it3->second[i].second; - di.NewDatum("PrefChanges") - ->AddVal("incommodity", commod) - ->AddVal("new_pref", pref) - ->AddVal("time", t) - ->Record(); - } - } - - // recipe changes - std::map > >:: - iterator it4; - for (it4 = recipe_changes_.begin(); it4 != recipe_changes_.end(); ++it4) { - int t = it4->first; - for (int i = 0; i < it4->second.size(); ++i) { - std::string commod = it4->second[i].first; - std::string recipe = it4->second[i].second; - di.NewDatum("RecipeChanges") - ->AddVal("incommodity", commod) - ->AddVal("new_recipe", recipe) - ->AddVal("time", t) - ->Record(); - } - } -} - -void BatchReactor::InitInv(cyclus::Inventories& invs) { - reserves_.PushAll(invs["reserves"]); - core_.PushAll(invs["core"]); - spillover_ = cyclus::ResCast(invs["spillover"][0]); - - cyclus::Inventories::iterator it; - for (it = invs.begin(); it != invs.end(); ++it) { - std::string name = it->first; - if (name.find("storage-") == 0) { - storage_[name].PushAll(it->second); - } - } -} - -cyclus::Inventories BatchReactor::SnapshotInv() { - cyclus::Inventories invs; - invs["reserves"] = reserves_.PopN(reserves_.count()); - reserves_.PushAll(invs["reserves"]); - invs["core"] = core_.PopN(core_.count()); - core_.PushAll(invs["core"]); - std::vector v; - v.push_back(spillover_); - invs["spillover"] = v; - std::map::iterator it; - for (it = storage_.begin(); it != storage_.end(); ++it) { - std::string name = it->first; - invs["storage-" + name] = it->second.PopN(it->second.count()); - it->second.PushAll(invs["storage-" + name]); - } - return invs; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Agent* BatchReactor::Clone() { - BatchReactor* m = new BatchReactor(context()); - m->InitFrom(this); - return m; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactor::InitFrom(BatchReactor* m) { - Facility::InitFrom(m); - - // in/out - crctx_ = m->crctx_; - - // facility params - process_time(m->process_time()); - preorder_time(m->preorder_time()); - refuel_time(m->refuel_time()); - n_batches(m->n_batches()); - n_load(m->n_load()); - n_reserves(m->n_reserves()); - batch_size(m->batch_size()); - - // commodity production - cyclus::toolkit::CommodityProducer::Copy(m); - - // ics - ics(m->ics()); - - // trade preferences - commod_prefs(m->commod_prefs()); - pref_changes_ = m->pref_changes_; - - // recipe changes - recipe_changes_ = m->recipe_changes_; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::string BatchReactor::str() { - std::stringstream ss; - ss << cyclus::Facility::str(); - ss << " has facility parameters {" << "\n" - << " Process Time = " << process_time() << ",\n" - << " Refuel Time = " << refuel_time() << ",\n" - << " Preorder Time = " << preorder_time() << ",\n" - << " Core Loading = " << n_batches() * batch_size() << ",\n" - << " Batches Per Core = " << n_batches() << ",\n" - << " Batches Per Load = " << n_load() << ",\n" - << " Batches To Reserve = " << n_reserves() << ",\n" - << "'}"; - return ss.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactor::Build(cyclus::Agent* parent) { - using cyclus::Material; - - Facility::Build(parent); - phase(INITIAL); - std::string rec = crctx_.in_recipe(*crctx_.in_commods().begin()); - spillover_ = Material::Create(this, 0.0, context()->GetRecipe(rec)); - - Material::Ptr mat; - for (int i = 0; i < ics_.n_reserves; ++i) { - mat = Material::Create(this, - batch_size(), - context()->GetRecipe(ics_.reserves_rec)); - assert(ics_.reserves_commod != ""); - crctx_.AddRsrc(ics_.reserves_commod, mat); - reserves_.Push(mat); - } - for (int i = 0; i < ics_.n_core; ++i) { - mat = Material::Create(this, - batch_size(), - context()->GetRecipe(ics_.core_rec)); - assert(ics_.core_commod != ""); - crctx_.AddRsrc(ics_.core_commod, mat); - core_.Push(mat); - } - for (int i = 0; i < ics_.n_storage; ++i) { - mat = Material::Create(this, - batch_size(), - context()->GetRecipe(ics_.storage_rec)); - assert(ics_.storage_commod != ""); - crctx_.AddRsrc(ics_.storage_commod, mat); - storage_[ics_.storage_commod].Push(mat); - } - - LOG(cyclus::LEV_DEBUG2, "BReact") << "Batch Reactor entering the simuluation"; - LOG(cyclus::LEV_DEBUG2, "BReact") << str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactor::Tick() { - int time = context()->time(); - LOG(cyclus::LEV_INFO3, "BReact") << prototype() << " is ticking at time " - << time << " {"; - - LOG(cyclus::LEV_DEBUG4, "BReact") << "Current facility parameters for " - << prototype() - << " at the beginning of the tick are:"; - LOG(cyclus::LEV_DEBUG4, "BReact") << " Phase: " << phase_names_[phase_]; - LOG(cyclus::LEV_DEBUG4, "BReact") << " Start time: " << start_time_; - LOG(cyclus::LEV_DEBUG4, "BReact") << " End time: " << end_time(); - LOG(cyclus::LEV_DEBUG4, "BReact") << " Order time: " << order_time(); - LOG(cyclus::LEV_DEBUG4, "BReact") << " NReserves: " << reserves_.count(); - LOG(cyclus::LEV_DEBUG4, "BReact") << " NCore: " << core_.count(); - LOG(cyclus::LEV_DEBUG4, "BReact") << " NStorage: " << StorageCount(); - LOG(cyclus::LEV_DEBUG4, "BReact") << " Spillover Qty: " - << spillover_->quantity(); - - if (lifetime() != -1 && context()->time() >= enter_time() + lifetime()) { - int ncore = core_.count(); - LOG(cyclus::LEV_DEBUG1, "BReact") << "lifetime reached, moving out:" - << ncore << " batches."; - for (int i = 0; i < ncore; ++i) { - MoveBatchOut_(); // unload - } - } else { - switch (phase()) { - case WAITING: - if (n_core() == n_batches() && - to_begin_time() <= context()->time()) { - phase(PROCESS); - } - break; - - case INITIAL: - // special case for a core primed to go - if (n_core() == n_batches()) { - phase(PROCESS); - } - break; - } - } - - // change preferences if its time - if (pref_changes_.count(time)) { - std::vector< std::pair< std::string, double> >& - changes = pref_changes_[time]; - for (int i = 0; i < changes.size(); i++) { - commod_prefs_[changes[i].first] = changes[i].second; - } - } - - // change recipes if its time - if (recipe_changes_.count(time)) { - std::vector< std::pair< std::string, std::string> >& - changes = recipe_changes_[time]; - for (int i = 0; i < changes.size(); i++) { - assert(changes[i].first != ""); - assert(changes[i].second != ""); - crctx_.UpdateInRec(changes[i].first, changes[i].second); - } - } - - LOG(cyclus::LEV_DEBUG3, "BReact") << "Current facility parameters for " - << prototype() - << " at the end of the tick are:"; - LOG(cyclus::LEV_DEBUG3, "BReact") << " Phase: " << phase_names_[phase_]; - LOG(cyclus::LEV_DEBUG3, "BReact") << " Start time: " << start_time_; - LOG(cyclus::LEV_DEBUG3, "BReact") << " End time: " << end_time(); - LOG(cyclus::LEV_DEBUG3, "BReact") << " Order time: " << order_time(); - LOG(cyclus::LEV_DEBUG3, "BReact") << " NReserves: " << reserves_.count(); - LOG(cyclus::LEV_DEBUG3, "BReact") << " NCore: " << core_.count(); - LOG(cyclus::LEV_DEBUG3, "BReact") << " NStorage: " << StorageCount(); - LOG(cyclus::LEV_DEBUG3, "BReact") << " Spillover Qty: " - << spillover_->quantity(); - LOG(cyclus::LEV_INFO3, "BReact") << "}"; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactor::Tock() { - int time = context()->time(); - LOG(cyclus::LEV_INFO3, "BReact") << prototype() << " is tocking {"; - LOG(cyclus::LEV_DEBUG4, "BReact") << "Current facility parameters for " - << prototype() - << " at the beginning of the tock are:"; - LOG(cyclus::LEV_DEBUG4, "BReact") << " Phase: " << phase_names_[phase_]; - LOG(cyclus::LEV_DEBUG4, "BReact") << " Start time: " << start_time_; - LOG(cyclus::LEV_DEBUG4, "BReact") << " End time: " << end_time(); - LOG(cyclus::LEV_DEBUG4, "BReact") << " Order time: " << order_time(); - LOG(cyclus::LEV_DEBUG4, "BReact") << " NReserves: " << reserves_.count(); - LOG(cyclus::LEV_DEBUG4, "BReact") << " NCore: " << core_.count(); - LOG(cyclus::LEV_DEBUG4, "BReact") << " NStorage: " << StorageCount(); - LOG(cyclus::LEV_DEBUG4, "BReact") << " Spillover Qty: " - << spillover_->quantity(); - - switch (phase()) { - case PROCESS: - if (time == end_time()) { - for (int i = 0; i < std::min(n_load(), core_.count()); ++i) { - MoveBatchOut_(); // unload - } - Refuel_(); // reload - phase(WAITING); - } - break; - default: - Refuel_(); // always try to reload if possible - break; - } - - LOG(cyclus::LEV_DEBUG3, "BReact") << "Current facility parameters for " - << prototype() - << " at the end of the tock are:"; - LOG(cyclus::LEV_DEBUG3, "BReact") << " Phase: " << phase_names_[phase_]; - LOG(cyclus::LEV_DEBUG3, "BReact") << " Start time: " << start_time_; - LOG(cyclus::LEV_DEBUG3, "BReact") << " End time: " << end_time(); - LOG(cyclus::LEV_DEBUG3, "BReact") << " Order time: " << order_time(); - LOG(cyclus::LEV_DEBUG3, "BReact") << " NReserves: " << reserves_.count(); - LOG(cyclus::LEV_DEBUG3, "BReact") << " NCore: " << core_.count(); - LOG(cyclus::LEV_DEBUG3, "BReact") << " NStorage: " << StorageCount(); - LOG(cyclus::LEV_DEBUG3, "BReact") << " Spillover Qty: " - << spillover_->quantity(); - LOG(cyclus::LEV_INFO3, "BReact") << "}"; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -BatchReactor::GetMatlRequests() { - using cyclus::RequestPortfolio; - using cyclus::Material; - - std::set::Ptr> set; - double order_size; - - switch (phase()) { - // the initial phase requests as much fuel as necessary to achieve an entire - // core - case INITIAL: - order_size = n_batches() * batch_size() - - core_.quantity() - reserves_.quantity() - - spillover_->quantity(); - if (preorder_time() == 0) { - order_size += batch_size() * n_reserves(); - } - if (order_size > 0) { - RequestPortfolio::Ptr p = GetOrder_(order_size); - set.insert(p); - } - break; - - // the default case is to request the reserve amount if the order time has - // been reached - default: - // double fuel_need = (n_reserves() + n_batches() - n_core()) * batch_size(); - double fuel_need = (n_reserves() + n_load()) * batch_size(); - double fuel_have = reserves_.quantity() + spillover_->quantity(); - order_size = fuel_need - fuel_have; - bool ordering = order_time() <= context()->time() && order_size > 0; - - LOG(cyclus::LEV_DEBUG5, "BReact") << "BatchReactor " << prototype() - << " is deciding whether to order -"; - LOG(cyclus::LEV_DEBUG5, "BReact") << " Needs fuel amt: " << fuel_need; - LOG(cyclus::LEV_DEBUG5, "BReact") << " Has fuel amt: " << fuel_have; - LOG(cyclus::LEV_DEBUG5, "BReact") << " Order amt: " << order_size; - LOG(cyclus::LEV_DEBUG5, "BReact") << " Order time: " << order_time(); - LOG(cyclus::LEV_DEBUG5, "BReact") << " Current time: " - << context()->time(); - LOG(cyclus::LEV_DEBUG5, "BReact") << " Ordering?: " - << ((ordering == true) ? "yes" : "no"); - - if (ordering) { - RequestPortfolio::Ptr p = GetOrder_(order_size); - set.insert(p); - } - break; - } - - return set; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactor::AcceptMatlTrades( - const std::vector< std::pair, - cyclus::Material::Ptr> >& responses) { - using cyclus::Material; - - std::map mat_commods; - - std::vector< std::pair, - cyclus::Material::Ptr> >::const_iterator trade; - - // blob each material by commodity - std::string commod; - Material::Ptr mat; - for (trade = responses.begin(); trade != responses.end(); ++trade) { - commod = trade->first.request->commodity(); - mat = trade->second; - if (mat_commods.count(commod) == 0) { - mat_commods[commod] = mat; - } else { - mat_commods[commod]->Absorb(mat); - } - } - - // add each blob to reserves - std::map::iterator it; - for (it = mat_commods.begin(); it != mat_commods.end(); ++it) { - AddBatches_(it->first, it->second); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -BatchReactor::GetMatlBids(cyclus::CommodMap::type& - commod_requests) { - using cyclus::BidPortfolio; - using cyclus::Material; - - std::set::Ptr> ports; - - const std::set& commods = crctx_.out_commods(); - std::set::const_iterator it; - for (it = commods.begin(); it != commods.end(); ++it) { - BidPortfolio::Ptr port = GetBids_(commod_requests, - *it, - &storage_[*it]); - if (!port->bids().empty()) { - ports.insert(port); - } - } - - return ports; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactor::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses) { - using cyclus::Material; - using cyclus::Trade; - - std::vector< cyclus::Trade >::const_iterator it; - for (it = trades.begin(); it != trades.end(); ++it) { - LOG(cyclus::LEV_INFO5, "BReact") << prototype() - << " just received an order."; - - std::string commodity = it->request->commodity(); - double qty = it->amt; - Material::Ptr response = TradeResponse_(qty, &storage_[commodity]); - - responses.push_back(std::make_pair(*it, response)); - LOG(cyclus::LEV_INFO5, "BatchReactor") << prototype() - << " just received an order" - << " for " << qty - << " of " << commodity; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int BatchReactor::StorageCount() { - int count = 0; - std::map::const_iterator it; - for (it = storage_.begin(); it != storage_.end(); ++it) { - count += it->second.count(); - } - return count; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactor::phase(BatchReactor::Phase p) { - LOG(cyclus::LEV_DEBUG2, "BReact") << "BatchReactor " << prototype() - << " is changing phases -"; - LOG(cyclus::LEV_DEBUG2, "BReact") << " * from phase: " << phase_names_[phase_]; - LOG(cyclus::LEV_DEBUG2, "BReact") << " * to phase: " << phase_names_[p]; - - switch (p) { - case PROCESS: - start_time(context()->time()); - } - phase_ = p; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactor::Refuel_() { - while (n_core() < n_batches() && reserves_.count() > 0) { - MoveBatchIn_(); - if (n_core() == n_batches()) { - to_begin_time_ = start_time_ + process_time_ + refuel_time_; - } - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactor::MoveBatchIn_() { - LOG(cyclus::LEV_DEBUG2, "BReact") << "BatchReactor " << prototype() - << " added a batch to its core."; - try { - core_.Push(reserves_.Pop()); - } catch (cyclus::Error& e) { - e.msg(Agent::InformErrorMsg(e.msg())); - throw e; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactor::MoveBatchOut_() { - using cyclus::Material; - using cyclus::ResCast; - - LOG(cyclus::LEV_DEBUG2, "BReact") << "BatchReactor " << prototype() - << " removed a batch from its core."; - try { - Material::Ptr mat = ResCast(core_.Pop()); - std::string incommod = crctx_.commod(mat); - assert(incommod != ""); - std::string outcommod = crctx_.out_commod(incommod); - assert(outcommod != ""); - std::string outrecipe = crctx_.out_recipe(incommod); - assert(outrecipe != ""); - mat->Transmute(context()->GetRecipe(outrecipe)); - crctx_.UpdateRsrc(outcommod, mat); - storage_[outcommod].Push(mat); - } catch (cyclus::Error& e) { - e.msg(Agent::InformErrorMsg(e.msg())); - throw e; - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::RequestPortfolio::Ptr -BatchReactor::GetOrder_(double size) { - using cyclus::CapacityConstraint; - using cyclus::Material; - using cyclus::RequestPortfolio; - using cyclus::Request; - - RequestPortfolio::Ptr port(new RequestPortfolio()); - - const std::set& commods = crctx_.in_commods(); - std::set::const_iterator it; - std::string recipe; - Material::Ptr mat; - - std::vector*> mreqs; - for (it = commods.begin(); it != commods.end(); ++it) { - recipe = crctx_.in_recipe(*it); - assert(recipe != ""); - mat = Material::CreateUntracked(size, context()->GetRecipe(recipe)); - Request* r = port->AddRequest(mat, this, *it, commod_prefs_[*it]); - mreqs.push_back(r); - - LOG(cyclus::LEV_DEBUG3, "BReact") << "BatchReactor " << prototype() - << " is making an order:"; - LOG(cyclus::LEV_DEBUG3, "BReact") << " size: " << size; - LOG(cyclus::LEV_DEBUG3, "BReact") << " commodity: " << *it; - LOG(cyclus::LEV_DEBUG3, "BReact") << " preference: " - << commod_prefs_[*it]; - } - port->AddMutualReqs(mreqs); - - return port; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactor::AddBatches_(std::string commod, cyclus::Material::Ptr mat) { - using cyclus::Material; - using cyclus::ResCast; - - LOG(cyclus::LEV_DEBUG3, "BReact") << "BatchReactor " << prototype() - << " is adding " << mat->quantity() - << " of material to its reserves."; - - // this is a hack! Whatever *was* left in spillover now magically becomes this - // new commodity. We need to do something different (maybe) for recycle. - spillover_->Absorb(mat); - - while (!cyclus::IsNegative(spillover_->quantity() - batch_size())) { - Material::Ptr batch; - // this is a hack to deal with close-to-equal issues between batch size and - // the amount of fuel in spillover - if (spillover_->quantity() >= batch_size()) { - batch = spillover_->ExtractQty(batch_size()); - } else { - batch = spillover_->ExtractQty(spillover_->quantity()); - } - assert(commod != ""); - crctx_.AddRsrc(commod, batch); - reserves_.Push(batch); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::BidPortfolio::Ptr BatchReactor::GetBids_( - cyclus::CommodMap::type& commod_requests, - std::string commod, - cyclus::toolkit::ResourceBuff* buffer) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::Composition; - using cyclus::Converter; - using cyclus::Material; - using cyclus::Request; - using cyclus::ResCast; - using cyclus::toolkit::ResourceBuff; - - BidPortfolio::Ptr port(new BidPortfolio()); - - if (commod_requests.count(commod) > 0 && buffer->quantity() > 0) { - std::vector*>& requests = commod_requests[commod]; - - // get offer composition - Material::Ptr back = ResCast(buffer->Pop(ResourceBuff::BACK)); - Composition::Ptr comp = back->comp(); - buffer->Push(back); - - std::vector*>::iterator it; - for (it = requests.begin(); it != requests.end(); ++it) { - Request* req = *it; - double qty = std::min(req->target()->quantity(), buffer->quantity()); - Material::Ptr offer = Material::CreateUntracked(qty, comp); - port->AddBid(req, offer, this); - } - - CapacityConstraint cc(buffer->quantity()); - port->AddConstraint(cc); - } - - return port; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr BatchReactor::TradeResponse_( - double qty, - cyclus::toolkit::ResourceBuff* buffer) { - using cyclus::Material; - using cyclus::ResCast; - - std::vector manifest; - try { - // pop amount from inventory and blob it into one material - manifest = ResCast(buffer->PopQty(qty)); - } catch (cyclus::Error& e) { - e.msg(Agent::InformErrorMsg(e.msg())); - throw e; - } - - Material::Ptr response = manifest[0]; - crctx_.RemoveRsrc(response); - for (int i = 1; i < manifest.size(); i++) { - crctx_.RemoveRsrc(manifest[i]); - response->Absorb(manifest[i]); - } - return response; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactor::SetUpPhaseNames_() { - phase_names_.insert(std::make_pair(INITIAL, "initialization")); - phase_names_.insert(std::make_pair(PROCESS, "processing batch(es)")); - phase_names_.insert(std::make_pair(WAITING, "waiting for fuel")); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern "C" cyclus::Agent* ConstructBatchReactor(cyclus::Context* ctx) { - return new BatchReactor(ctx); -} - -} // namespace cycamore diff --git a/src/batch_reactor.h b/src/batch_reactor.h deleted file mode 100644 index e5d537219e..0000000000 --- a/src/batch_reactor.h +++ /dev/null @@ -1,445 +0,0 @@ -#ifndef CYCAMORE_SRC_BATCH_REACTOR_H_ -#define CYCAMORE_SRC_BATCH_REACTOR_H_ - -#include -#include -#include - -#include "cyclus.h" - -// forward declarations -namespace cycamore { -class BatchReactor; -} // namespace cycamore -namespace cyclus { -class Context; -} // namespace cyclus - -namespace cycamore { - -/// @class BatchReactor -/// -/// @section introduction Introduction -/// The BatchReactor is a facility that agents batch processing. It has three -/// storage areas which hold batches of materials: reserves, core, and -/// storage. Incoming material orders are placed into reserves, from which the -/// core is provided batches during refueling. When a process has been -/// completed, batches are moved from the core into storage. Requests for -/// material are bid upon based on the state of the material in storage. -/// -/// The Reactor can manage multiple input-output commodity pairs, and keeps -/// track of the pair that each batch belongs to. Batches move through the -/// system independently of their input/output commodity types, but when batches -/// reach the storage area, they are offered as bids dependent on their output -/// commodity type. -/// -/// @section params Parameters -/// A BatchReactor has the following tunable parameters: -/// #. batch_size : the size of batches -/// #. n_batches : the number of batches that constitute a full core -/// #. process_time : the number of timesteps a batch process takes -/// #. n_load : the number of batches processed at any given time (i.e., -/// n_load is unloaded and reloaded after a process is finished -/// #. n_reserves : the preferred number of batches in reserve -/// #. preorder_time : the amount of time before a process is finished to -/// order fuel -/// #. refuel_time : the number of timesteps required to reload the core after -/// a process has finished -/// -/// The BatchReactor also maintains a cyclus::CommodityRecipeContext, which -/// allows it to track incommodity-inrecipe/outcommodity-outrecipe groupings. -/// -/// @section operation Operation -/// After a BatchReactor enters the simulation, it will begin processing its -/// first batch load on the Tick after its core has been filled. -/// -/// It will maintain its "processing" state for process_time() time steps, -/// including the timestep on which it began. It will unload n_load() batches -/// from its core on the Tock of that time step. For example, if a reactor -/// begins its process at time 1 and has a process_time equal to 10, it will -/// unload batches on the Tock of time step 10. -/// -/// Starting at the next time step, the reactor will attempt to refuel itself -/// from whatever batches exist in its reserves container (i.e, already-ordered -/// fuel). Assuming its core buffer has been refueled, it will wait reload_time -/// timesteps. On the tick of the following timestep, the process will begin -/// again. Using the previous example, assume that the refuel_time is equal to -/// two and that the core buffer has been refueled appropriately. The refueling -/// "phase" will begin on time step 11, and will end on the Tock of time step -/// 12. The process will begin again on time step 13 (analogous to its state -/// originally at time step 1). -/// -/// @section end End of Life -/// If the current time step is equivalent to the facility's lifetime, the -/// reactor will move all material in its core to its storage containers. -/// -/// @section requests Requests -/// A BatchReactor will make as many requests as it has possible input -/// commodities. It provides a constraint based on a total request amount -/// determined by its batch_size, n_load, and n_reserves parameters. The -/// n_reserves parameter allows agenters to order fuel in advance of when it is -/// needed. The fuel order size is batch_size * (n_load + n_reserves). These -/// requests are made if the current simulation time is less than or equal to -/// the reactor's current order_time(), which is determined by the ending time -/// of the current process less a look ahead time, the preorder_time(). -/// -/// A special case exists when the reactor first enters the simulation, where it -/// will order as much fuel as is needed to fill its full core. -/// -/// @section bids Bids -/// A BatchReactor will bid on any request for any of its out_commodities, as -/// long as there is a positive quantity of material in its storage area -/// associated with that output commodity. -/// -/// @section ics Initial Conditions -/// A BatchReactor can be deployed with any number of batches in its reserve, -/// core, and storage buffers. Recipes and commodities for each of these batch -/// groupings must be specified. -/// -/// @todo add decommissioning behavior if material is still in storage -/// -/// @warning The BatchReactor is considered experimental. -/// @warning preference time changing is based on *full simulation time*, not -/// relative time -/// @warning the reactor's commodity context *can not* currently remove -/// resources reliably because of toolkit::ResourceBuff::PopQty()'s implementation. -/// Resource removal from the context requires pointer equality -/// in order to remove material, and PopQty will split resources, making new -/// pointers. -/// @warning the reactor uses a hackish way to input materials into its -/// reserves. See the AddBatches_ member function. -class BatchReactor - : public cyclus::Facility, - public cyclus::toolkit::CommodityProducer { - public: - /// @brief defines all possible phases this facility can be in - enum Phase { - INITIAL, ///< The initial phase, after the facility is built but before it is - /// filled - PROCESS, ///< The processing phase - WAITING, ///< The waiting phase, while the facility is waiting for fuel - /// between processes - }; - - /// @brief a struct for initial conditions - struct InitCond { - InitCond() : n_reserves(0), n_core(0), n_storage(0) {} - - void AddReserves(int n, std::string rec, std::string commod) { - n_reserves = n; - reserves_rec = rec; - reserves_commod = commod; - } - - void AddCore(int n, std::string rec, std::string commod) { - n_core = n; - core_rec = rec; - core_commod = commod; - } - - void AddStorage(int n, std::string rec, std::string commod) { - n_storage = n; - storage_rec = rec; - storage_commod = commod; - } - - int n_reserves; - std::string reserves_rec; - std::string reserves_commod; - - int n_core; - std::string core_rec; - std::string core_commod; - - int n_storage; - std::string storage_rec; - std::string storage_commod; - }; - - // --- Module Members --- - /// @param ctx the cyclus context for access to simulation-wide parameters - BatchReactor(cyclus::Context* ctx); - - virtual ~BatchReactor(); - - #pragma cyclus def annotations - - #pragma cyclus note {"doc": "A reactor facility that has three storage " \ - "areas that hold batches of materials: " \ - "reserves, core, and storage. It can manage " \ - "multiple input-output commodity pairs."} - - virtual cyclus::Agent* Clone(); - - virtual void InfileToDb(cyclus::InfileTree* qe, cyclus::DbInit di); - - virtual void InitFrom(cyclus::QueryableBackend* b); - - virtual void Snapshot(cyclus::DbInit di); - - virtual void InitInv(cyclus::Inventories& invs); - - virtual cyclus::Inventories SnapshotInv(); - - virtual std::string schema(); - - /// initialize members from a different agent - void InitFrom(BatchReactor* m); - - /// Print information about this agent - virtual std::string str(); - // --- - - // --- Facility Members --- - /// perform module-specific tasks when entering the simulation - virtual void Build(cyclus::Agent* parent); - // --- - - // --- Agent Members --- - /// The Tick function specific to the BatchReactor. - /// @param time the time of the tick - virtual void Tick(); - - /// The Tick function specific to the BatchReactor. - /// @param time the time of the tock - virtual void Tock(); - - /// @brief The BatchReactor requests Materials of its given - /// commodity. - virtual std::set::Ptr> - GetMatlRequests(); - - /// @brief The BatchReactor places accepted trade Materials in their - /// Inventory - virtual void AcceptMatlTrades( - const std::vector< std::pair, - cyclus::Material::Ptr> >& responses); - - /// @brief Responds to each request for this facility's commodity. If a given - /// request is more than this facility's inventory or SWU capacity, it will - /// offer its minimum of its capacities. - virtual std::set::Ptr> - GetMatlBids(cyclus::CommodMap::type& - commod_requests); - - /// @brief respond to each trade with a material enriched to the appropriate - /// level given this facility's inventory - /// - /// @param trades all trades in which this trader is the supplier - /// @param responses a container to populate with responses to each trade - virtual void GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses); - // --- - - // --- BatchReactor Members --- - /// @return the total number of batches in storage - int StorageCount(); - - /// @brief the processing time required for a full batch process before - /// refueling - inline void process_time(int t) { - process_time_ = t; - } - inline int process_time() const { - return process_time_; - } - - /// @brief the time it takes to refuel - inline void refuel_time(int t) { - refuel_time_ = t; - } - inline int refuel_time() const { - return refuel_time_; - } - - /// @brief the amount of time an order should be placed for new fuel before a - /// process is finished - inline void preorder_time(int t) { - preorder_time_ = t; - } - inline int preorder_time() const { - return preorder_time_; - } - - /// @brief the starting time of the last (current) process - inline void start_time(int t) { - start_time_ = t; - } - inline int start_time() const { - return start_time_; - } - - /// @brief the ending time of the last (current) process - /// @warning the - 1 is to ensure that a 1 period process time that begins on - /// the tick ends on the tock - inline int end_time() const { - return start_time() + process_time() - 1; - } - - /// @brief the beginning time for the next phase, set internally - inline int to_begin_time() const { - return to_begin_time_; - } - - /// @brief the time orders should be taking place for the next refueling - inline int order_time() const { - return end_time() - preorder_time(); - } - - /// @brief the number of batches in a full reactor - inline void n_batches(int n) { - n_batches_ = n; - } - inline int n_batches() const { - return n_batches_; - } - - /// @brief the number of batches in reactor refuel loading/unloading - inline void n_load(int n) { - n_load_ = n; - } - inline int n_load() const { - return n_load_; - } - - /// @brief the preferred number of fresh fuel batches to keep in reserve - inline void n_reserves(int n) { - n_reserves_ = n; - } - inline int n_reserves() const { - return n_reserves_; - } - - /// @brief the number of batches currently in the reactor - inline int n_core() const { - return core_.count(); - } - - /// @brief the size of a batch - inline void batch_size(double size) { - batch_size_ = size; - } - inline double batch_size() { - return batch_size_; - } - - /// @brief this facility's commodity-recipe context - inline void crctx(const cyclus::toolkit::CommodityRecipeContext& crctx) { - crctx_ = crctx; - } - inline cyclus::toolkit::CommodityRecipeContext crctx() const { - return crctx_; - } - - /// @brief this facility's initial conditions - inline void ics(const InitCond& ics) { - ics_ = ics; - } - inline InitCond ics() const { - return ics_; - } - - /// @brief the current phase - void phase(Phase p); - inline Phase phase() const { - return phase_; - } - - /// @brief this facility's preference for input commodities - inline void commod_prefs(const std::map& prefs) { - commod_prefs_ = prefs; - } - inline const std::map& commod_prefs() const { - return commod_prefs_; - } - - protected: - /// @brief moves a batch from core_ to storage_ - virtual void MoveBatchOut_(); - - /// @brief gets bids for a commodity from a buffer - cyclus::BidPortfolio::Ptr GetBids_( - cyclus::CommodMap::type& commod_requests, - std::string commod, - cyclus::toolkit::ResourceBuff* buffer); - - /// @brief returns a qty of material from a buffer - cyclus::Material::Ptr TradeResponse_(double qty, - cyclus::toolkit::ResourceBuff* buffer); - - /// @brief a cyclus::toolkit::ResourceBuff for material while they are inside the core, - /// with all materials guaranteed to be of batch_size_ - cyclus::toolkit::ResourceBuff core_; - - /// @brief a cyclus::toolkit::ResourceBuff for material once they leave the core. - /// there is one storage for each outcommodity - /// @warning no guarantee can be made to the size of each item in storage_, as - /// requests can be met that are larger or smaller than batch_size_ - std::map storage_; - - private: - /// @brief refuels the reactor until it is full or reserves_ is out of - /// batches. If the core is full after refueling, the Phase is set to PROCESS. - void Refuel_(); - - /// @brief moves a batch from reserves_ to core_ - void MoveBatchIn_(); - - /// @brief construct a request portfolio for an order of a given size - cyclus::RequestPortfolio::Ptr GetOrder_(double size); - - /// @brief Add a blob of incoming material to reserves_ - /// - /// The last material to join reserves_ is first investigated to see if it is - /// of batch_size_. If not, material from mat is added to it and it is - /// returned to reserves_. If more material remains, chunks of batch_size_ are - /// removed and added to reserves_. The final chunk may be <= batch_size_. - void AddBatches_(std::string commod, cyclus::Material::Ptr mat); - - /// @brief adds phase names to phase_names_ map - void SetUpPhaseNames_(); - - static std::map phase_names_; - int process_time_; - int preorder_time_; - int refuel_time_; - int start_time_; - int to_begin_time_; - int n_batches_; - int n_load_; - int n_reserves_; - double batch_size_; - Phase phase_; - - InitCond ics_; - - cyclus::toolkit::CommodityRecipeContext crctx_; - - /// @warning as is, the int key is **simulation time**, i.e., context()->time - /// == key. This should be fixed for future use! - std::map > > - recipe_changes_; - - /// @brief preferences for each input commodity - std::map commod_prefs_; - - /// @warning as is, the int key is **simulation time**, i.e., context()->time - /// == key. This should be fixed for future use! - std::map > > pref_changes_; - - /// @brief allows only batches to enter reserves_ - cyclus::Material::Ptr spillover_; - - /// @brief a cyclus::toolkit::ResourceBuff for material before they enter the core, - /// with all materials guaranteed to be of batch_size_ - cyclus::toolkit::ResourceBuff reserves_; - - friend class BatchReactorTest; - // --- -}; - -} // namespace cycamore - -#endif // CYCAMORE_SRC_BATCH_REACTOR_H_ diff --git a/src/batch_reactor_tests.cc b/src/batch_reactor_tests.cc deleted file mode 100644 index 5a3f374088..0000000000 --- a/src/batch_reactor_tests.cc +++ /dev/null @@ -1,400 +0,0 @@ -#include "batch_reactor_tests.h" - -#include - -#include "composition.h" -#include "error.h" -#include "facility_tests.h" -#include "agent_tests.h" -#include "agent.h" -#include "infile_tree.h" - -#include "toolkit/commodity.h" - -namespace cycamore { - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool operator==(const BatchReactor::InitCond& l, - const BatchReactor::InitCond& r) { - bool reserves = (l.n_reserves != 0 && - l.n_reserves == r.n_reserves && - l.reserves_rec == r.reserves_rec && - l.reserves_commod == r.reserves_commod); - bool core = (l.n_core != 0 && - l.n_core == r.n_core && - l.core_rec == r.core_rec && - l.core_commod == r.core_commod); - bool storage = (l.n_storage != 0 && - l.n_storage == r.n_storage && - l.storage_rec == r.storage_rec && - l.storage_commod == r.storage_commod); - return (reserves && core && storage); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactorTest::SetUp() { - src_facility = new BatchReactor(tc_.get()); - InitParameters(); - SetUpSource(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactorTest::TearDown() { - delete src_facility; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactorTest::InitParameters() { - // init params - in_c1 = "in_c1"; - in_c2 = "in_c2"; - out_c1 = "out_c1"; - out_c2 = "out_c2"; - in_r1 = "in_r1"; - in_r2 = "in_r2"; - out_r1 = "out_r1"; - out_r2 = "out_r2"; - crctx.AddInCommod(in_c1, in_r1, out_c1, out_r1); - crctx.AddInCommod(in_c2, in_r2, out_c2, out_r2); - - n_batches = 5; - n_load = 2; - n_reserves = 3; - process_time = 10; - refuel_time = 2; - preorder_time = 1; - batch_size = 4.5; - - commodity = "power"; - capacity = 200; - cost = capacity; - - // init conds - rsrv_c = in_c1; - rsrv_r = in_r1; - core_c = in_c2; - core_r = in_r2; - stor_c = out_c1; - stor_r = out_r1; - rsrv_n = 2; - core_n = 3; - stor_n = 1; - ics.AddReserves(rsrv_n, rsrv_r, rsrv_c); - ics.AddCore(core_n, core_r, core_c); - ics.AddStorage(stor_n, stor_r, stor_c); - - // commod prefs - frompref1 = 7.5; - topref1 = frompref1 - 1; - frompref2 = 5.5; - topref2 = frompref2 - 2; - commod_prefs[in_c1] = frompref1; - commod_prefs[in_c2] = frompref2; - - // changes - change_time = 5; - pref_changes[change_time].push_back(std::make_pair(in_c1, topref1)); - pref_changes[change_time].push_back(std::make_pair(in_c2, topref2)); - recipe_changes[change_time].push_back(std::make_pair(in_c1, in_r2)); - - cyclus::CompMap v; - v[922350000] = 1; - v[922380000] = 2; - cyclus::Composition::Ptr recipe = cyclus::Composition::CreateFromAtom(v); - tc_.get()->AddRecipe(in_r1, recipe); - tc_.get()->AddRecipe(in_r2, recipe); - - v[94239] = 0.25; - recipe = cyclus::Composition::CreateFromAtom(v); - tc_.get()->AddRecipe(out_r1, recipe); - tc_.get()->AddRecipe(out_r2, recipe); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactorTest::SetUpSource() { - src_facility->crctx(crctx); - src_facility->n_batches(n_batches); - src_facility->n_load(n_load); - src_facility->n_reserves(n_reserves); - src_facility->process_time(process_time); - src_facility->refuel_time(refuel_time); - src_facility->preorder_time(preorder_time); - src_facility->batch_size(batch_size); - src_facility->ics(ics); - - src_facility->Add(commodity); - src_facility->cyclus::toolkit::CommodityProducer:: - SetCapacity(commodity, capacity); - src_facility->cyclus::toolkit::CommodityProducer:: - SetCost(commodity, capacity); - - src_facility->commod_prefs(commod_prefs); - - src_facility->pref_changes_[change_time].push_back( - std::make_pair(in_c1, topref1)); - src_facility->pref_changes_[change_time].push_back( - std::make_pair(in_c2, topref2)); - src_facility->recipe_changes_[change_time].push_back( - std::make_pair(in_c1, in_r2)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactorTest::TestBuffs(int nreserves, int ncore, int nstorage) { - EXPECT_EQ(nreserves, src_facility->reserves_.count()); - EXPECT_EQ(ncore, src_facility->core_.count()); - EXPECT_EQ(nstorage, src_facility->storage_[out_c1].count()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactorTest::TestReserveBatches(cyclus::Material::Ptr mat, - std::string commod, - int n, - double qty) { - src_facility->AddBatches_(commod, mat); - EXPECT_EQ(n, src_facility->reserves_.count()); - EXPECT_DOUBLE_EQ(qty, src_facility->spillover_->quantity()); - - cyclus::Material::Ptr back = cyclus::ResCast( - src_facility->reserves_.Pop(cyclus::toolkit::ResourceBuff::BACK)); - EXPECT_EQ(commod, src_facility->crctx_.commod(back)); - src_facility->reserves_.Push(back); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactorTest::TestBatchIn(int n_core, int n_reserves) { - src_facility->MoveBatchIn_(); - EXPECT_EQ(n_core, src_facility->n_core()); - EXPECT_EQ(n_reserves, src_facility->reserves_.count()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactorTest::TestBatchOut(int n_core, int n_storage) { - src_facility->MoveBatchOut_(); - EXPECT_EQ(n_core, src_facility->n_core()); - EXPECT_EQ(n_storage, src_facility->storage_[out_c1].count()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void BatchReactorTest::TestInitState(BatchReactor* fac) { - EXPECT_EQ(crctx, fac->crctx()); - EXPECT_EQ(n_batches, fac->n_batches()); - EXPECT_EQ(n_load, fac->n_load()); - EXPECT_EQ(n_reserves, fac->n_reserves()); - EXPECT_EQ(process_time, fac->process_time()); - EXPECT_EQ(refuel_time, fac->refuel_time()); - EXPECT_EQ(preorder_time, fac->preorder_time()); - EXPECT_EQ(batch_size, fac->batch_size()); - EXPECT_EQ(0, fac->n_core()); - EXPECT_EQ(BatchReactor::INITIAL, fac->phase()); - EXPECT_EQ(ics, fac->ics()); - - cyclus::toolkit::Commodity commod(commodity); - EXPECT_TRUE(fac->Produces(commod)); - EXPECT_EQ(capacity, fac->Capacity(commod)); - EXPECT_EQ(cost, fac->Cost(commod)); - - EXPECT_EQ(commod_prefs, fac->commod_prefs()); - - EXPECT_EQ(pref_changes, fac->pref_changes_); - EXPECT_EQ(recipe_changes, fac->recipe_changes_); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(BatchReactorTest, InitialState) { - TestInitState(src_facility); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(BatchReactorTest, DISABLED_XMLInit) { - std::stringstream ss; - ss << "" - << "fooname" - << "" - << "" - << " " - << " " << in_c1 << "" - << " " << in_r1 << "" - << " " << out_c1 << "" - << " " << out_r1 << "" - << " " - << " " - << " " << in_c2 << "" - << " " << in_r2 << "" - << " " << out_c2 << "" - << " " << out_r2 << "" - << " " - << " " << process_time << "" - << " " << n_batches << "" - << " " << batch_size << "" - << " " << refuel_time << "" - << " " << preorder_time << "" - << " " << n_reserves << "" - << " " << n_load << "" - << " " - << " " - << " " << rsrv_n << "" - << " " << rsrv_c << "" - << " " << rsrv_r << "" - << " " - << " " - << " " << core_n << "" - << " " << core_c << "" - << " " << core_r << "" - << " " - << " " - << " " << stor_n << "" - << " " << stor_c << "" - << " " << stor_r << "" - << " " - << " " - << " " - << " " << in_c1 << "" - << " " << in_r2 << "" - << " " - << " " - << " " - << " " << commodity << "" - << " " << capacity << "" - << " " << cost << "" - << " " - << " " - << " " << in_c1 << "" - << " " << frompref1 << "" - << " " - << " " - << " " << in_c2 << "" - << " " << frompref2 << "" - << " " - << " " - << " " << in_c1 << "" - << " " << topref1 << "" - << " " - << " " - << " " - << " " << in_c2 << "" - << " " << topref2 << "" - << " " - << " " - << "" - << "" - << ""; - - cyclus::XMLParser p; - p.Init(ss); - cyclus::InfileTree engine(p); - cycamore::BatchReactor* fac = new cycamore::BatchReactor(tc_.get()); - // fac->InitFrom(&engine); - - TestInitState(fac); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(BatchReactorTest, Clone) { - cycamore::BatchReactor* cloned_fac = - dynamic_cast(src_facility->Clone()); - TestInitState(cloned_fac); - delete cloned_fac; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(BatchReactorTest, Print) { - EXPECT_NO_THROW(std::string s = src_facility->str()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(BatchReactorTest, Tick) { - EXPECT_EQ(src_facility->commod_prefs().at(in_c1), frompref1); - EXPECT_EQ(src_facility->commod_prefs().at(in_c2), frompref2); - EXPECT_EQ(src_facility->crctx().in_recipe(in_c1), in_r1); - tc_.get()->time(change_time); - EXPECT_NO_THROW(src_facility->Tick();); - EXPECT_EQ(src_facility->commod_prefs().at(in_c1), topref1); - EXPECT_EQ(src_facility->commod_prefs().at(in_c2), topref2); - EXPECT_EQ(src_facility->crctx().in_recipe(in_c1), in_r2); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(BatchReactorTest, Tock) { - int time = 1; - EXPECT_NO_THROW(src_facility->Tock()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(BatchReactorTest, StartProcess) { - int t = tc_.get()->time(); - src_facility->phase(BatchReactor::PROCESS); - EXPECT_EQ(t, src_facility->start_time()); - EXPECT_EQ(t + process_time - 1, src_facility->end_time()); - EXPECT_EQ(t + process_time - preorder_time - 1, src_facility->order_time()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(BatchReactorTest, InitCond) { - cyclus::Env::SetNucDataPath(); - src_facility->Build(NULL); - TestBuffs(rsrv_n, core_n, stor_n); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(BatchReactorTest, AddBatches) { - using cyclus::Material; - - Material::Ptr mat = cyclus::NewBlankMaterial(batch_size); - // mat to add, commodity, reserves, qty of spillover - TestReserveBatches(mat, in_c1, 1, 0); - - mat = cyclus::NewBlankMaterial(batch_size - (1 + cyclus::eps())); - TestReserveBatches(mat, in_c1, 1, batch_size - (1 + cyclus::eps())); - - mat = cyclus::NewBlankMaterial((1 + cyclus::eps())); - TestReserveBatches(mat, in_c1, 2, 0); - - mat = cyclus::NewBlankMaterial(batch_size + (1 + cyclus::eps())); - TestReserveBatches(mat, in_c1, 3, 1 + cyclus::eps()); - - mat = cyclus::NewBlankMaterial(batch_size - (1 + cyclus::eps())); - TestReserveBatches(mat, in_c1, 4, 0); - - mat = cyclus::NewBlankMaterial(1 + cyclus::eps()); - TestReserveBatches(mat, in_c1, 4, 1 + cyclus::eps()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(BatchReactorTest, BatchInOut) { - using cyclus::Material; - - EXPECT_THROW(TestBatchIn(1, 0), cyclus::Error); - - Material::Ptr mat = cyclus::NewBlankMaterial(batch_size); - TestReserveBatches(mat, in_c1, 1, 0); - TestBatchIn(1, 0); - - mat = cyclus::NewBlankMaterial(batch_size * 2); - TestReserveBatches(mat, in_c1, 2, 0); - TestBatchIn(2, 1); - - TestBatchOut(1, 1); - TestBatchOut(0, 2); - - EXPECT_THROW(TestBatchOut(1, 0), cyclus::Error); -} - -} // namespace cycamore - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Agent* BatchReactorConstructor(cyclus::Context* ctx) { - return new cycamore::BatchReactor(ctx); -} - -// required to get functionality in cyclus agent unit tests library -#ifndef CYCLUS_AGENT_TESTS_CONNECTED -int ConnectAgentTests(); -static int cyclus_agent_tests_connected = ConnectAgentTests(); -#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected -#endif // CYCLUS_AGENT_TESTS_CONNECTED - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// INSTANTIATE_TEST_CASE_P(BatchReactor, FacilityTests, -// Values(&BatchReactorConstructor)); -INSTANTIATE_TEST_CASE_P(BatchReactor, AgentTests, - Values(&BatchReactorConstructor)); diff --git a/src/batch_reactor_tests.h b/src/batch_reactor_tests.h deleted file mode 100644 index 1390a4d948..0000000000 --- a/src/batch_reactor_tests.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef CYCAMORE_SRC_BATCH_REACTOR_TESTS_H_ -#define CYCAMORE_SRC_BATCH_REACTOR_TESTS_H_ - -#include - -#include -#include - -#include "batch_reactor.h" -#include "test_context.h" - -namespace cycamore { - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -class BatchReactorTest : public ::testing::Test { - protected: - cyclus::TestContext tc_; - BatchReactor* src_facility; - - // init params - std::string in_c1, in_c2, out_c1, out_c2; - std::string in_r1, in_r2, out_r1, out_r2; - cyclus::toolkit::CommodityRecipeContext crctx; - - int n_batches, n_load, n_reserves; - int process_time, refuel_time, preorder_time; - double batch_size; - - std::string commodity; - double capacity, cost; - - // init conds - std::string rsrv_c, rsrv_r, core_c, core_r, stor_c, stor_r; - int rsrv_n, core_n, stor_n; - BatchReactor::InitCond ics; - - // changes changes - int change_time; - double frompref1, topref1, frompref2, topref2; - std::map commod_prefs; - std::map > > pref_changes; - std::map > > - recipe_changes; - - virtual void SetUp(); - virtual void TearDown(); - void InitParameters(); - void SetUpSource(); - - /// @brief tests the initial state of a facility - void TestInitState(BatchReactor* fac); - - /// @brief tests the number of batches in each buffer - void TestBuffs(int nreserves, int ncore, int nstorage); - - /// @brief tests the BatchReactor's reserves_, by calling AddBatches_(mat), - /// and confirming that there are n items and the last item has quantity qty - void TestReserveBatches(cyclus::Material::Ptr mat, std::string commod, - int n, double qty); - - /// @brief calls MoveBatchIn_ and tests that the number of objects in core_ is - /// n_core and the number of objects in reserves_ is n_reserves - void TestBatchIn(int n_core, int n_reserves); - - /// @brief calls MoveBatchOut_ and tests that the number of objects in core_ is - /// n_core and the number of objects in storage_ is n_storage - void TestBatchOut(int n_core, int n_storage); -}; - -} // namespace cycamore - -#endif // CYCAMORE_SRC_BATCH_REACTOR_TESTS_H_ diff --git a/tests/test_regression.py b/tests/test_regression.py index 13c930f7a7..a918ea96e9 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -7,6 +7,7 @@ import uuid import numpy as np from numpy.testing import assert_array_almost_equal +from numpy.testing import assert_almost_equal from nose.tools import assert_equal, assert_true from helper import check_cmd, run_cyclus, table_exist, find_ids @@ -63,7 +64,7 @@ def __init__(self, *args, **kwargs): def setUp(self): super(TestPhysorEnrichment, self).setUp() tbl = self.agent_entry - self.rx_id = find_ids(":cycamore:BatchReactor", + self.rx_id = find_ids(":cycamore:Reactor", tbl["Spec"], tbl["AgentId"]) self.enr_id = find_ids(":cycamore:EnrichmentFacility", tbl["Spec"], tbl["AgentId"]) @@ -79,7 +80,8 @@ def test_swu(self): enr = self.enrichments # this can be updated if/when we can call into the cyclus::toolkit's # enrichment module from python - exp = [6.9, 10, 4.14, 6.9] + # with old BatchReactor: exp = [6.9, 10, 4.14, 6.9] + exp = [6.9 , 9.66, 4.48, 6.9] obs = [np.sum(enr["SWU"][enr["Time"] == t]) for t in range(4)] assert_array_almost_equal(exp, obs, decimal=2) @@ -87,7 +89,9 @@ def test_nu(self): enr = self.enrichments # this can be updated if/when we can call into the cyclus::toolkit's # enrichment module from python - exp = [13.03, 16.54, 7.83, 13.03] + + # with old BatchReactor: exp = [13.03, 16.54, 7.83, 13.03] + exp = [13.03, 15.9 , 8.47, 13.03] obs = [np.sum(enr["Natural_Uranium"][enr["Time"] == t]) \ for t in range(4)] assert_array_almost_equal(exp, obs, decimal=2) @@ -103,15 +107,20 @@ def test_xactions(self): # this can be updated if/when we can call into the cyclus::toolkit's # enrichment module from python - exp = [1, 0.8, 0.2, 1] - obs = transfers[0] + msg = "Testing that first reactor gets less than it wants." - assert_array_almost_equal(exp, obs, decimal=2, err_msg=msg) + exp = 3 + obs = transfers[0] + assert_almost_equal(exp, sum(obs)) + # with old BatchReactor: exp = [1, 0.8, 0.2, 1] + # with old BatchReactor: assert_array_almost_equal(exp, obs, decimal=2, err_msg=msg) - exp = [1, 1, 1, 1] - obs = transfers[1] msg = "Testing that second reactor gets what it wants." - assert_array_almost_equal(exp, obs, decimal=2) + exp = 4 + obs = transfers[1] + assert_almost_equal(exp, sum(obs)) + # with old BatchReactor: exp = [1, 1, 1, 1] + # with old BatchReactor: assert_array_almost_equal(exp, obs, decimal=2, err_msg=msg) class TestPhysorSources(TestRegression): """This class tests the 2_Sources_3_Reactor.xml file related to the Cyclus @@ -127,7 +136,7 @@ def setUp(self): # identify each reactor and supplier by id tbl = self.agent_entry - rx_id = find_ids(":cycamore:BatchReactor", + rx_id = find_ids(":cycamore:Reactor", tbl["Spec"], tbl["AgentId"]) self.r1, self.r2, self.r3 = tuple(rx_id) s_id = find_ids(":cycamore:Source", @@ -144,55 +153,49 @@ def test_rxtr_deployment(self): assert_equal(depl_time[self.r3], 3) def test_rxtr1_xactions(self): - xa = self.transactions - mox_exp = [0, 1, 1, 1, 0] - obs = np.zeros(5) - rows = xa[np.logical_and(xa["ReceiverId"] == self.r1, - xa["SenderId"] == self.smox)] - obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - assert_array_almost_equal(mox_exp, obs) + txs = [0, 0, 0, 0, 0] + for tx in self.transactions: + if tx['ReceiverId'] == self.r1 and tx['SenderId'] == self.smox: + txs[tx['Time']] += self.rsrc_qtys[tx['ResourceId']] + assert_array_almost_equal(mox_exp, txs) uox_exp = [0, 0, 0, 0, 1] - obs = np.zeros(5) - rows = xa[np.logical_and(xa["ReceiverId"] == self.r1, - xa["SenderId"] == self.suox)] - obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - assert_array_almost_equal(uox_exp, obs) + txs = [0, 0, 0, 0, 0] + for tx in self.transactions: + if tx['ReceiverId'] == self.r1 and tx['SenderId'] == self.suox: + txs[tx['Time']] += self.rsrc_qtys[tx['ResourceId']] + assert_array_almost_equal(uox_exp, txs) def test_rxtr2_xactions(self): - xa = self.transactions - mox_exp = [0, 0, 1, 1, 1] - obs = np.zeros(5) - rows = xa[np.logical_and(xa["ReceiverId"] == self.r2, - xa["SenderId"] == self.smox)] - obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - assert_array_almost_equal(mox_exp, obs) + txs = [0, 0, 0, 0, 0] + for tx in self.transactions: + if tx['ReceiverId'] == self.r2 and tx['SenderId'] == self.smox: + txs[tx['Time']] += self.rsrc_qtys[tx['ResourceId']] + assert_array_almost_equal(mox_exp, txs) uox_exp = [0, 0, 0, 0, 0] - obs = np.zeros(5) - rows = xa[np.logical_and(xa["ReceiverId"] == self.r2, - xa["SenderId"] == self.suox)] - obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - assert_array_almost_equal(uox_exp, obs) + txs = [0, 0, 0, 0, 0] + for tx in self.transactions: + if tx['ReceiverId'] == self.r2 and tx['SenderId'] == self.suox: + txs[tx['Time']] += self.rsrc_qtys[tx['ResourceId']] + assert_array_almost_equal(uox_exp, txs) def test_rxtr3_xactions(self): - xa = self.transactions - mox_exp = [0, 0, 0, 0.5, 1] - obs = np.zeros(5) - rows = xa[np.logical_and(xa["ReceiverId"] == self.r3, - xa["SenderId"] == self.smox)] - obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - assert_array_almost_equal(mox_exp, obs) + txs = [0, 0, 0, 0, 0] + for tx in self.transactions: + if tx['ReceiverId'] == self.r3 and tx['SenderId'] == self.smox: + txs[tx['Time']] += self.rsrc_qtys[tx['ResourceId']] + assert_array_almost_equal(mox_exp, txs) uox_exp = [0, 0, 0, 0.5, 0] - obs = np.zeros(5) - rows = xa[np.logical_and(xa["ReceiverId"] == self.r3, - xa["SenderId"] == self.suox)] - obs[rows["Time"]] = [self.rsrc_qtys[x] for x in rows["ResourceId"]] - assert_array_almost_equal(uox_exp, obs) + txs = [0, 0, 0, 0, 0] + for tx in self.transactions: + if tx['ReceiverId'] == self.r3 and tx['SenderId'] == self.suox: + txs[tx['Time']] += self.rsrc_qtys[tx['ResourceId']] + assert_array_almost_equal(uox_exp, txs) class TestDynamicCapacitated(TestRegression): """Tests dynamic capacity restraints involving changes in the number of From b7ce1cd5df4dccc8c7e58a53c98dafc59957e303 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 8 Apr 2015 10:54:05 -0500 Subject: [PATCH 070/314] improve 1_enrich_2_reactor tests to check sum qty of transactions per time step --- input/physor/1_Enrichment_2_Reactor.xml | 2 +- tests/test_regression.py | 39 +++++++++++-------------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/input/physor/1_Enrichment_2_Reactor.xml b/input/physor/1_Enrichment_2_Reactor.xml index bb04eadb8d..4bd592d051 100755 --- a/input/physor/1_Enrichment_2_Reactor.xml +++ b/input/physor/1_Enrichment_2_Reactor.xml @@ -22,7 +22,7 @@ natl_u enriched_u 0.003 - 10 + 10.01 1e5 diff --git a/tests/test_regression.py b/tests/test_regression.py index a918ea96e9..a4bdb04616 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -81,7 +81,7 @@ def test_swu(self): # this can be updated if/when we can call into the cyclus::toolkit's # enrichment module from python # with old BatchReactor: exp = [6.9, 10, 4.14, 6.9] - exp = [6.9 , 9.66, 4.48, 6.9] + exp = [6.9, 10., 4.14, 6.9] obs = [np.sum(enr["SWU"][enr["Time"] == t]) for t in range(4)] assert_array_almost_equal(exp, obs, decimal=2) @@ -91,36 +91,31 @@ def test_nu(self): # enrichment module from python # with old BatchReactor: exp = [13.03, 16.54, 7.83, 13.03] - exp = [13.03, 15.9 , 8.47, 13.03] + exp = [13.03, 16.55, 7.82, 13.03] obs = [np.sum(enr["Natural_Uranium"][enr["Time"] == t]) \ for t in range(4)] assert_array_almost_equal(exp, obs, decimal=2) def test_xactions(self): - xa = self.transactions - rs = self.resources + # reactor 1 transactions + exp = [1, 1, 1, 1] + txs = [0, 0, 0, 0] + for tx in self.transactions: + if tx['ReceiverId'] == self.rx_id[0]: + txs[tx['Time']] += self.rsrc_qtys[tx['ResourceId']] - torxtrs = {i: [self.rsrc_qtys[x["ResourceId"]] \ - for x in xa[xa["ReceiverId"] == i]] \ - for i in self.rx_id} - transfers = sorted(torxtrs.values()) + msg = "Testing that first reactor gets less than it wants." + assert_array_almost_equal(exp, txs, decimal=2, err_msg=msg) - # this can be updated if/when we can call into the cyclus::toolkit's - # enrichment module from python + # reactor 2 transactions + exp = [1, 0.8, 0.2, 1] + txs = [0, 0, 0, 0] + for tx in self.transactions: + if tx['ReceiverId'] == self.rx_id[1]: + txs[tx['Time']] += self.rsrc_qtys[tx['ResourceId']] - msg = "Testing that first reactor gets less than it wants." - exp = 3 - obs = transfers[0] - assert_almost_equal(exp, sum(obs)) - # with old BatchReactor: exp = [1, 0.8, 0.2, 1] - # with old BatchReactor: assert_array_almost_equal(exp, obs, decimal=2, err_msg=msg) - msg = "Testing that second reactor gets what it wants." - exp = 4 - obs = transfers[1] - assert_almost_equal(exp, sum(obs)) - # with old BatchReactor: exp = [1, 1, 1, 1] - # with old BatchReactor: assert_array_almost_equal(exp, obs, decimal=2, err_msg=msg) + assert_array_almost_equal(exp, txs, decimal=2, err_msg=msg) class TestPhysorSources(TestRegression): """This class tests the 2_Sources_3_Reactor.xml file related to the Cyclus From 540754952f233dc50ae6556d2ffaf50d15ee208d Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Tue, 13 Jan 2015 16:18:09 -0600 Subject: [PATCH 071/314] sketching out fab --- src/fuel_fab.cc | 151 +++++++++++++++++++++++++++++++++++++++ src/fuel_fab.h | 184 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 335 insertions(+) create mode 100644 src/fuel_fab.cc create mode 100644 src/fuel_fab.h diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc new file mode 100644 index 0000000000..056e96486d --- /dev/null +++ b/src/fuel_fab.cc @@ -0,0 +1,151 @@ +#include "recipe_mixer.h" +#include "kitlus/fuel_match.h" + +#define LG(X) LOG(cyclus::LEV_##X, "RecMix") + +using cyclus::Material; +using cyclus::Composition; +using cyclus::ResCast; + +namespace cycamore { + +FuelFab::FuelFab(cyclus::Context* ctx) + : cyclus::Facility(ctx), + fill_size_(0), + fiss_size_(0), + throughput_(0) {} + +void FuelFab::EnterNotify() { + cyclus::Facility::EnterNotify(); + + fillpolicy_.Init(this, &fill_, "filler") + .Set(fill_commod_, context()->GetRecipe(fill_recipe_)) + .Start(); + fisspolicy_.Init(this, &fiss_, "fissile") + .Set(fiss_commod_, context()->GetRecipe(fiss_recipe_)) + .Start(); +} + +void FuelFab::Tick() { + LG(INFO3) << "FuelFab id=" << id() << " is ticking"; + LG(INFO4) << "filler quantity = " << fill_.quantity(); + LG(INFO4) << "fissile quantity = " << fiss_.quantity(); + LG(INFO4) << "outbuf quantity = " << out_.quantity(); + double qty = std::min(throughput_, out_.space()); + if (fill_.quantity() < cyclus::eps() || fiss_.quantity() < cyclus::eps() || qty < cyclus::eps()) { + return; + } + + Material::Ptr m_fill = fill.Push(Squash(fill.PopN(fill.count()))); + Material::Ptr m_fiss = fiss.Push(Squash(fiss.PopN(fiss.count()))); + + // determine frac needed from each input stream + Composition::Ptr tgt = context()->GetRecipe(outrecipe_); + double frac2 = kitlus::CosiFissileFrac(tgt, m1->comp(), m2->comp()); + double frac1 = 1 - frac2; + if (frac2 < 0) { + fill_.Push(m1); + fiss_.Push(m2); + LG(ERROR) << "fiss stream has too low reactivity"; + return; + } + + LG(INFO4) << "fill frac = " << frac1; + LG(INFO4) << "fiss frac = " << frac2; + + // deal with stream quantity and out buf space constraints + double qty1 = frac1 * qty; + double qty2 = frac2 * qty; + double qty1diff = m1->quantity() - qty1; + double qty2diff = m2->quantity() - qty2; + if (qty1diff >= 0 && qty2diff >= 0) { + // not constrained by inbuf quantities + } else if (qty1diff < qty2diff ) { + // constrained by fiss_ + LG(INFO5) << "Constrained by incommod '" << fill_commod_ + << "' - reducing qty from " << qty + << " to " << m1->quantity() / frac1; + qty = m1->quantity() / frac1; + } else { + // constrained by inbuf2 + LG(INFO5) << "Constrained by incommod '" << fiss_commod_ + << "' - reducing qty from " << qty + << " to " << m2->quantity() / frac2; + qty = m2->quantity() / frac2; + } + + Material::Ptr mix = m1->ExtractQty(std::min(frac1 * qty, m1->quantity())); + mix->Absorb(m2->ExtractQty(std::min(frac2 * qty, m2->quantity()))); + + cyclus::toolkit::MatQuery mq(mix); + LG(INFO4) << "Mixed " << mix->quantity() << " kg to recipe"; + LG(INFO5) << " u238 = " << mq.mass_frac(922380000); + LG(INFO5) << " u235 = " << mq.mass_frac(922350000); + LG(INFO5) << "Pu239 = " << mq.mass_frac(942390000); + + out_.Push(mix); + if (m1->quantity() > 0) { + fill_.Push(m1); + } + if (m2->quantity() > 0) { + fiss_.Push(m2); + } +} + +std::set::Ptr> +FuelFab::GetMatlBids(cyclus::CommodMap::type& + commod_requests) { + using cyclus::BidPortfolio; + + std::set::Ptr> ports; + + Material::Ptr m_fill = Squash(fill.PopN(fill.count())); + Material::Ptr m_fiss = Squash(fiss.PopN(fiss.count())); + Material::Ptr m_topup = Squash(topup.PopN(topup.count())); + topup.Push(m_topup); + fiss.Push(m_fiss); + fill.Push(m_fill); + + std::vector*>& reqs = commod_requests[outcommod]; + + BidPortfolio::Ptr port(new BidPortfolio()); + for (int j = 0; j < reqs.size(); j++) { + Request* req = reqs[j]; + double tot_bid = 0; + for (int k = 0; k < mats.size(); k++) { + Material::Ptr m = mats[k]; + tot_bid += m->quantity(); + port->AddBid(req, m, this, true); + if (tot_bid >= req->target()->quantity()) { + break; + } + } + } + + double w_fill = CosiWeight(m_fill->comp(), spectrum); + double w_fiss = CosiWeight(m_fiss->comp(), spectrum); + double w_topup = CosiWeight(m_topup->comp(), spectrum); + Converter::Ptr fillconv(new FissConverter(w_fill, w_fiss, w_topup, spectrum)); + Converter::Ptr fissconv(new FillConverter(w_fill, w_fiss, w_topup, spectrum)); + Converter::Ptr topupconv(new TopupConverter(w_fill, w_fiss, w_topup, spectrum)); + CapacityConstraint fillc(fill.quantity(), fillconv); + CapacityConstraint fissc(fiss.quantity(), fissconv); + CapacityConstraint topupc(topup.quantity(), topupconv); + port->AddConstraint(fillc); + port->AddConstraint(fissc); + port->AddConstraint(topupc); + + cyclus::CapacityConstraint cc(throughput); + port->AddConstraint(cc); + ports.insert(port); + return ports; +} + +} // namespace cycamore + +extern "C" cyclus::Agent* ConstructFuelFab(cyclus::Context* ctx) { + return new FuelFab(ctx); +} + + + diff --git a/src/fuel_fab.h b/src/fuel_fab.h new file mode 100644 index 0000000000..4f7e534807 --- /dev/null +++ b/src/fuel_fab.h @@ -0,0 +1,184 @@ +#ifndef CYCAMORE_SRC_FUEL_FAB_H_ +#define CYCAMORE_SRC_FUEL_FAB_H_ + +#include +#include "cyclus.h" +#include "kitlus/sell_policy.h" +#include "kitlus/buy_policy.h" + +using kitlus::BuyPolicy; +using kitlus::SellPolicy; + +namespace cycamore { + +class FuelFab : public cyclus::Facility { + public: + FuelFab(cyclus::Context* ctx); + virtual ~FuelFab() {}; + virtual std::string str() {return "";}; + + virtual void EnterNotify(); + + #pragma cyclus + + virtual void Tick(); + virtual void Tock() {}; + + private: + #pragma cyclus var {} + std::vector fill_commods; + #pragma cyclus var {} + std::vector fill_commod_prefs; + #pragma cyclus var {} + std::string fill_recipe; + #pragma cyclus var {} + double fill_size; + #pragma cyclus var {'capacity': 'fill_size'} + cyclus::toolkit::ResBuf fill; + + #pragma cyclus var {} + std::vector fiss_commods; + #pragma cyclus var {} + std::vector fiss_commod_prefs; + #pragma cyclus var {} + double fiss_size; + #pragma cyclus var {'capacity': 'fiss_size'} + cyclus::toolkit::ResBuf fiss; + + #pragma cyclus var {} + std::string topup_commod; + #pragma cyclus var {} + double topup_size; + #pragma cyclus var {'capacity': 'topup_size'} + cyclus::toolkit::ResBuf topup; + + #pragma cyclus var {} + std::string outcommod; + + #pragma cyclus var { \ + "doc": "'fission' for fast reactor compositions or 'thermal' for slow reactors.", \ + } + std::string spectrum; + + #pragma cyclus var {} + double throughput; + + BuyPolicy fillpolicy_; + BuyPolicy fisspolicy_; +}; + +class FissConverter : public cyclus::Converter { + public: + FissConverter( + double w_fill, + double w_fiss, + double w_topup, + std::string spectrum, + ) : w_fiss_(w_fiss), w_topup_(w_topup), w_fill_(w_fill), spec_(spectrum) {} + + virtual ~FissConverter() {} + + virtual double convert( + cyclus::Material::Ptr m, + cyclus::Arc const * a = NULL, + cyclus::ExchangeTranslationContext const * ctx = NULL) const { + + double w_tgt = CosiWeight(m->comp(), spec_); + int check = CosiCheck(w_tgt, w_fill_, w_fiss_); + int check_topup = CosiCheck(w_tgt, w_fill_, w_topup_); + + if (check == 0) { + return CosiFissileFrac(w_tgt, w_fill_, w_fiss_) * m->quantity(); + } else if (check_topup == 0) { + // use fiss inventory as filler, and topup as fissile + return 1 - CosiFissileFrac(w_tgt, w_fiss_, w_topup_) * m->quantity(); + } else { + return 1e200; + } + } + + private: + std::string spec_; + double w_fiss_; + double w_topup_; + double w_fill_; +}; + +class FillConverter : public cyclus::Converter { + public: + FillConverter( + double w_fill, + double w_fiss, + double w_topup, + std::string spectrum, + ) : w_fiss_(w_fiss), w_topup_(w_topup), w_fill_(w_fill), spec_(spectrum) {} + + virtual ~FillConverter() {} + + virtual double convert( + cyclus::Material::Ptr m, + cyclus::Arc const * a = NULL, + cyclus::ExchangeTranslationContext const * ctx = NULL) const { + + double w_tgt = CosiWeight(m->comp(), spec_); + int check = CosiCheck(w_tgt, w_fill_, w_fiss_); + int check_topup = CosiCheck(w_tgt, w_fill_, w_topup_); + + if (check == 0) { + return 1 - CosiFissileFrac(w_tgt, w_fill_, w_fiss_) * m->quantity(); + } else if (check_topup == 0) { + // switched fissile inventory to filler so don't need any filler inventory + return 0; + } else { + return 1e200; + } + } + + private: + std::string spec_; + double w_fiss_; + double w_topup_; + double w_fill_; +}; + +class TopupConverter : public cyclus::Converter { + public: + TopupConverter( + double w_fill, + double w_fiss, + double w_topup, + std::string spectrum, + ) : w_fiss_(w_fiss), w_topup_(w_topup), w_fill_(w_fill), spec_(spectrum) {} + + virtual ~TopupConverter() {} + + virtual double convert( + cyclus::Material::Ptr m, + cyclus::Arc const * a = NULL, + cyclus::ExchangeTranslationContext const * ctx = NULL) const { + + double w_tgt = CosiWeight(m->comp(), spec_); + int check = CosiCheck(w_tgt, w_fill_, w_fiss_); + int check_topup = CosiCheck(w_tgt, w_fill_, w_topup_); + + if (check == 0) { + return 0; + } else if (check_topup == 0) { + // switched fissile inventory to filler and topup as fissile + return CosiFissileFrac(w_tgt, w_fiss_, w_topup_) * m->quantity(); + } else { + return 1e200; + } + } + + private: + std::string spec_; + double w_fiss_; + double w_topup_; + double w_fill_; +}; + +} // namespace cycamore + + +#endif // CYCAMORE_SRC_FUEL_FAB_H_ From 62324715209853097667cb079c8f32c767aa73f4 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 11 Feb 2015 14:33:55 -0600 Subject: [PATCH 072/314] fuel fab compiles - bidding is implemented --- src/CMakeLists.txt | 2 + src/fuel_fab.cc | 381 +++++++++++++++++++++++++++++++++------------ src/fuel_fab.h | 141 ++--------------- 3 files changed, 295 insertions(+), 229 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3f7ae00400..5701534c73 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,8 @@ USE_CYCLUS("cycamore" "reactor") +USE_CYCLUS("cycamore" "fuel_fab") + USE_CYCLUS("cycamore" "enrichment_facility") USE_CYCLUS("cycamore" "sink") diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index 056e96486d..ed11ebac01 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -1,96 +1,204 @@ -#include "recipe_mixer.h" -#include "kitlus/fuel_match.h" - -#define LG(X) LOG(cyclus::LEV_##X, "RecMix") +#include "fuel_fab.h" using cyclus::Material; using cyclus::Composition; -using cyclus::ResCast; +using pyne::simple_xs; namespace cycamore { -FuelFab::FuelFab(cyclus::Context* ctx) - : cyclus::Facility(ctx), - fill_size_(0), - fiss_size_(0), - throughput_(0) {} - -void FuelFab::EnterNotify() { - cyclus::Facility::EnterNotify(); - - fillpolicy_.Init(this, &fill_, "filler") - .Set(fill_commod_, context()->GetRecipe(fill_recipe_)) - .Start(); - fisspolicy_.Init(this, &fiss_, "fissile") - .Set(fiss_commod_, context()->GetRecipe(fiss_recipe_)) - .Start(); -} +double CosiWeight(cyclus::Composition::Ptr c, std::string spectrum) { + cyclus::CompMap cm = c->mass(); + cyclus::compmath::Normalize(&cm); + + double nu_pu239 = 2.85; + double nu_u233 = 2.5; + double nu_u235 = 2.4; + + double fiss_u238 = simple_xs("u238", "fission", spectrum); + double absorb_u238 = simple_xs("u238", "absorption", spectrum); + double nu_u238 = 0; + double p_u238 = nu_u238 * fiss_u238 - absorb_u238; + + double fiss_pu239 = simple_xs("Pu239", "fission", spectrum); + double absorb_pu239 = simple_xs("Pu239", "absorption", spectrum); + double p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239; + + cyclus::CompMap::iterator it; + double w = 0; + for (it = cm.begin(); it != cm.end(); ++it) { + cyclus::Nuc nuc = it->first; + double nu = 0; + if (nuc == 922350000) { + nu = nu_u235; + } else if (nuc == 922330000) { + nu = nu_u233; + } else if (nuc == 942390000) { + nu = nu_pu239; + } -void FuelFab::Tick() { - LG(INFO3) << "FuelFab id=" << id() << " is ticking"; - LG(INFO4) << "filler quantity = " << fill_.quantity(); - LG(INFO4) << "fissile quantity = " << fiss_.quantity(); - LG(INFO4) << "outbuf quantity = " << out_.quantity(); - double qty = std::min(throughput_, out_.space()); - if (fill_.quantity() < cyclus::eps() || fiss_.quantity() < cyclus::eps() || qty < cyclus::eps()) { - return; + double fiss = 0; + double absorb = 0; + try { + fiss = simple_xs(nuc, "fission", spectrum); + absorb = simple_xs(nuc, "absorption", spectrum); + } catch(pyne::InvalidSimpleXS err) { + fiss = 0; + absorb = 0; + } + + double p = nu * fiss - absorb; + w += it->second * (p - p_u238) / (p_pu239 - p_u238); } + return w; +} - Material::Ptr m_fill = fill.Push(Squash(fill.PopN(fill.count()))); - Material::Ptr m_fiss = fiss.Push(Squash(fiss.PopN(fiss.count()))); - - // determine frac needed from each input stream - Composition::Ptr tgt = context()->GetRecipe(outrecipe_); - double frac2 = kitlus::CosiFissileFrac(tgt, m1->comp(), m2->comp()); - double frac1 = 1 - frac2; - if (frac2 < 0) { - fill_.Push(m1); - fiss_.Push(m2); - LG(ERROR) << "fiss stream has too low reactivity"; - return; +double CosiFissileFrac(double w_tgt, double w_fill, double w_fiss) { + if (w_fiss == w_fill && w_tgt == w_fiss) { + return 1; + } else if (w_fiss == w_fill) { + throw cyclus::ValueError("fissile and filler weights are the same"); } + return (w_tgt - w_fill) / (w_fiss - w_fill); +} + +double CosiFissileFrac(cyclus::Composition::Ptr target, + cyclus::Composition::Ptr filler, + cyclus::Composition::Ptr fissile, + std::string spectrum) { + double w_fill = CosiWeight(filler, spectrum); + double w_fiss = CosiWeight(fissile, spectrum); + double w_tgt = CosiWeight(target, spectrum); + return CosiFissileFrac(w_tgt, w_fill, w_fiss); +} + +double CosiFillerFrac(double w_tgt, double w_fill, double w_fiss) { + return 1-CosiFissileFrac(w_tgt, w_fill, w_fiss); +} - LG(INFO4) << "fill frac = " << frac1; - LG(INFO4) << "fiss frac = " << frac2; - - // deal with stream quantity and out buf space constraints - double qty1 = frac1 * qty; - double qty2 = frac2 * qty; - double qty1diff = m1->quantity() - qty1; - double qty2diff = m2->quantity() - qty2; - if (qty1diff >= 0 && qty2diff >= 0) { - // not constrained by inbuf quantities - } else if (qty1diff < qty2diff ) { - // constrained by fiss_ - LG(INFO5) << "Constrained by incommod '" << fill_commod_ - << "' - reducing qty from " << qty - << " to " << m1->quantity() / frac1; - qty = m1->quantity() / frac1; +// Returns true if the given weights can be used to compute valid mixing +// fractions of the filler and fissile streams to hit the target. +bool CosiValid(double w_target, double w_filler, double w_fissile) { + // w_target must be in between w_filler and w_fissile for the cosi + // equivalence technique to work - so we must check for this + if (w_filler <= w_target && w_target <= w_fissile) { + return true; + } else if (w_fissile <= w_target && w_target <= w_filler) { + return true; } else { - // constrained by inbuf2 - LG(INFO5) << "Constrained by incommod '" << fiss_commod_ - << "' - reducing qty from " << qty - << " to " << m2->quantity() / frac2; - qty = m2->quantity() / frac2; + return false; } +} + +class FissConverter : public cyclus::Converter { + public: + FissConverter( + double w_fill, + double w_fiss, + double w_topup, + std::string spectrum + ) : w_fiss_(w_fiss), w_topup_(w_topup), w_fill_(w_fill), spec_(spectrum) {} - Material::Ptr mix = m1->ExtractQty(std::min(frac1 * qty, m1->quantity())); - mix->Absorb(m2->ExtractQty(std::min(frac2 * qty, m2->quantity()))); + virtual ~FissConverter() {} - cyclus::toolkit::MatQuery mq(mix); - LG(INFO4) << "Mixed " << mix->quantity() << " kg to recipe"; - LG(INFO5) << " u238 = " << mq.mass_frac(922380000); - LG(INFO5) << " u235 = " << mq.mass_frac(922350000); - LG(INFO5) << "Pu239 = " << mq.mass_frac(942390000); + virtual double convert( + cyclus::Material::Ptr m, + cyclus::Arc const * a = NULL, + cyclus::ExchangeTranslationContext const * ctx = NULL) const { - out_.Push(mix); - if (m1->quantity() > 0) { - fill_.Push(m1); + double w_tgt = CosiWeight(m->comp(), spec_); + if (CosiValid(w_tgt, w_fill_, w_fiss_)) { + return CosiFissileFrac(w_tgt, w_fill_, w_fiss_) * m->quantity(); + } else if (CosiValid(w_tgt, w_fiss_, w_topup_)) { + // use fiss inventory as filler, and topup as fissile + return CosiFillerFrac(w_tgt, w_fiss_, w_topup_) * m->quantity(); + } else { + // don't bid at all + return 1e200; + } } - if (m2->quantity() > 0) { - fiss_.Push(m2); + + private: + std::string spec_; + double w_fiss_; + double w_topup_; + double w_fill_; +}; + +class FillConverter : public cyclus::Converter { + public: + FillConverter( + double w_fill, + double w_fiss, + double w_topup, + std::string spectrum + ) : w_fiss_(w_fiss), w_topup_(w_topup), w_fill_(w_fill), spec_(spectrum) {} + + virtual ~FillConverter() {} + + virtual double convert( + cyclus::Material::Ptr m, + cyclus::Arc const * a = NULL, + cyclus::ExchangeTranslationContext const * ctx = NULL) const { + + double w_tgt = CosiWeight(m->comp(), spec_); + if (CosiValid(w_tgt, w_fill_, w_fiss_)) { + return CosiFillerFrac(w_tgt, w_fill_, w_fiss_) * m->quantity(); + } else if (CosiValid(w_tgt, w_fiss_, w_topup_)) { + // switched fissile inventory to filler so don't need any filler inventory + return 0; + } else { + // don't bid at all + return 1e200; + } } -} + + private: + std::string spec_; + double w_fiss_; + double w_topup_; + double w_fill_; +}; + +class TopupConverter : public cyclus::Converter { + public: + TopupConverter( + double w_fill, + double w_fiss, + double w_topup, + std::string spectrum + ) : w_fiss_(w_fiss), w_topup_(w_topup), w_fill_(w_fill), spec_(spectrum) {} + + virtual ~TopupConverter() {} + + virtual double convert( + cyclus::Material::Ptr m, + cyclus::Arc const * a = NULL, + cyclus::ExchangeTranslationContext const * ctx = NULL) const { + + double w_tgt = CosiWeight(m->comp(), spec_); + if (CosiValid(w_tgt, w_fill_, w_fiss_)) { + return 0; + } else if (CosiValid(w_tgt, w_fiss_, w_topup_)) { + // switched fissile inventory to filler and topup as fissile + return CosiFissileFrac(w_tgt, w_fiss_, w_topup_) * m->quantity(); + } else { + // don't bid at all + return 1e200; + } + } + + private: + std::string spec_; + double w_fiss_; + double w_topup_; + double w_fill_; +}; + +FuelFab::FuelFab(cyclus::Context* ctx) + : cyclus::Facility(ctx), + fill_size(0), + fiss_size(0), + throughput(0) {} std::set::Ptr> FuelFab::GetMatlBids(cyclus::CommodMap::type& @@ -98,39 +206,65 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& using cyclus::BidPortfolio; std::set::Ptr> ports; + if (fiss.empty()) { + return ports; + } + + Material::Ptr m_fiss = fiss.Peek(); + double w_fiss = CosiWeight(m_fiss->comp(), spectrum); - Material::Ptr m_fill = Squash(fill.PopN(fill.count())); - Material::Ptr m_fiss = Squash(fiss.PopN(fiss.count())); - Material::Ptr m_topup = Squash(topup.PopN(topup.count())); - topup.Push(m_topup); - fiss.Push(m_fiss); - fill.Push(m_fill); + Material::Ptr m_fill; + Material::Ptr m_topup; + double w_fill = 0; + double w_topup = 0; + if (fill.count() > 0) { + m_fill = fill.Peek(); + w_fill = CosiWeight(m_fill->comp(), spectrum); + } + if (topup.count() > 0) { + m_topup = topup.Peek(); + w_topup = CosiWeight(m_topup->comp(), spectrum); + } - std::vector*>& reqs = commod_requests[outcommod]; + std::vector*>& reqs = commod_requests[outcommod]; BidPortfolio::Ptr port(new BidPortfolio()); for (int j = 0; j < reqs.size(); j++) { - Request* req = reqs[j]; - double tot_bid = 0; - for (int k = 0; k < mats.size(); k++) { - Material::Ptr m = mats[k]; - tot_bid += m->quantity(); - port->AddBid(req, m, this, true); - if (tot_bid >= req->target()->quantity()) { - break; - } - } + cyclus::Request* req = reqs[j]; + + Composition::Ptr tgt = req->target()->comp(); + double w_tgt = CosiWeight(tgt, spectrum); + double tgt_qty = req->target()->quantity(); + if (fill.count() > 0 && CosiValid(w_tgt, w_fill, w_fiss)) { + double fiss_frac = CosiFissileFrac(w_tgt, w_fill, w_fiss); + double fill_frac = 1 - fiss_frac; + Material::Ptr m1 = Material::CreateUntracked(fiss_frac * tgt_qty, m_fiss->comp()); + Material::Ptr m2 = Material::CreateUntracked(fill_frac * tgt_qty, m_fill->comp()); + m1->Absorb(m2); + + bool exclusive = false; + port->AddBid(req, m1, this, exclusive); + } else if (fill.count() > 0 && topup.count() > 0 && CosiValid(w_tgt, w_fiss, w_topup)) { + // only bid with topup if we have filler - otherwise we might be able to + // meet target with filler when we get it. we should only use topup + // when the fissile has too poor neutronics. + double topup_frac = CosiFissileFrac(w_tgt, w_fiss, w_topup); + double fiss_frac = 1 - topup_frac; + Material::Ptr m1 = Material::CreateUntracked(topup_frac * tgt_qty, m_topup->comp()); + Material::Ptr m2 = Material::CreateUntracked(fiss_frac * tgt_qty, m_fiss->comp()); + m1->Absorb(m2); + + bool exclusive = false; + port->AddBid(req, m1, this, exclusive); + } // else can't meet the target - don't bid } - double w_fill = CosiWeight(m_fill->comp(), spectrum); - double w_fiss = CosiWeight(m_fiss->comp(), spectrum); - double w_topup = CosiWeight(m_topup->comp(), spectrum); - Converter::Ptr fillconv(new FissConverter(w_fill, w_fiss, w_topup, spectrum)); - Converter::Ptr fissconv(new FillConverter(w_fill, w_fiss, w_topup, spectrum)); - Converter::Ptr topupconv(new TopupConverter(w_fill, w_fiss, w_topup, spectrum)); - CapacityConstraint fillc(fill.quantity(), fillconv); - CapacityConstraint fissc(fiss.quantity(), fissconv); - CapacityConstraint topupc(topup.quantity(), topupconv); + cyclus::Converter::Ptr fillconv(new FissConverter(w_fill, w_fiss, w_topup, spectrum)); + cyclus::Converter::Ptr fissconv(new FillConverter(w_fill, w_fiss, w_topup, spectrum)); + cyclus::Converter::Ptr topupconv(new TopupConverter(w_fill, w_fiss, w_topup, spectrum)); + cyclus::CapacityConstraint fillc(fill.quantity(), fillconv); + cyclus::CapacityConstraint fissc(fiss.quantity(), fissconv); + cyclus::CapacityConstraint topupc(topup.quantity(), topupconv); port->AddConstraint(fillc); port->AddConstraint(fissc); port->AddConstraint(topupc); @@ -141,11 +275,52 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& return ports; } -} // namespace cycamore +void FuelFab::GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + Material::Ptr> >& responses) { + using cyclus::Trade; + + Material::Ptr m_fiss = fiss.Peek(); + double w_fiss = CosiWeight(m_fiss->comp(), spectrum); + + Material::Ptr m_fill = fill.Peek(); + double w_fill = CosiWeight(m_fill->comp(), spectrum); + + Material::Ptr m_topup; + double w_topup = 0; + if (topup.count() > 0) { + m_topup = topup.Peek(); + w_topup = CosiWeight(m_topup->comp(), spectrum); + } + + std::vector< cyclus::Trade >::const_iterator it; + for (int i = 0; i < trades.size(); i++) { + Material::Ptr tgt = trades[i].request->target(); + double w_tgt = CosiWeight(tgt->comp(), spectrum); + double qty = tgt->quantity(); + + if (CosiValid(w_tgt, w_fill, w_fiss)) { + double fiss_frac = CosiFissileFrac(w_tgt, w_fill, w_fiss); + double fill_frac = 1 - fiss_frac; + + Material::Ptr m = fiss.Pop(fiss_frac*qty); + m->Absorb(fill.Pop(fill_frac*qty)); + responses.push_back(std::make_pair(trades[i], m)); + } else { + double topup_frac = CosiFissileFrac(w_tgt, w_fiss, w_topup); + double fiss_frac = 1 - topup_frac; + + Material::Ptr m = topup.Pop(topup_frac*qty); + m->Absorb(fiss.Pop(fiss_frac*qty)); + responses.push_back(std::make_pair(trades[i], m)); + } + } +} extern "C" cyclus::Agent* ConstructFuelFab(cyclus::Context* ctx) { return new FuelFab(ctx); } - +} // namespace cycamore diff --git a/src/fuel_fab.h b/src/fuel_fab.h index 4f7e534807..66196d8bae 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -3,11 +3,6 @@ #include #include "cyclus.h" -#include "kitlus/sell_policy.h" -#include "kitlus/buy_policy.h" - -using kitlus::BuyPolicy; -using kitlus::SellPolicy; namespace cycamore { @@ -15,15 +10,21 @@ class FuelFab : public cyclus::Facility { public: FuelFab(cyclus::Context* ctx); virtual ~FuelFab() {}; - virtual std::string str() {return "";}; - - virtual void EnterNotify(); #pragma cyclus - virtual void Tick(); + virtual void Tick() {}; virtual void Tock() {}; + virtual std::set::Ptr> + GetMatlBids(cyclus::CommodMap::type& + commod_requests); + + virtual void GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses); + private: #pragma cyclus var {} std::vector fill_commods; @@ -34,7 +35,7 @@ class FuelFab : public cyclus::Facility { #pragma cyclus var {} double fill_size; #pragma cyclus var {'capacity': 'fill_size'} - cyclus::toolkit::ResBuf fill; + cyclus::toolkit::ResBuf fill; #pragma cyclus var {} std::vector fiss_commods; @@ -43,14 +44,16 @@ class FuelFab : public cyclus::Facility { #pragma cyclus var {} double fiss_size; #pragma cyclus var {'capacity': 'fiss_size'} - cyclus::toolkit::ResBuf fiss; + cyclus::toolkit::ResBuf fiss; #pragma cyclus var {} std::string topup_commod; #pragma cyclus var {} + std::string topup_recipe; + #pragma cyclus var {} double topup_size; #pragma cyclus var {'capacity': 'topup_size'} - cyclus::toolkit::ResBuf topup; + cyclus::toolkit::ResBuf topup; #pragma cyclus var {} std::string outcommod; @@ -62,120 +65,6 @@ class FuelFab : public cyclus::Facility { #pragma cyclus var {} double throughput; - - BuyPolicy fillpolicy_; - BuyPolicy fisspolicy_; -}; - -class FissConverter : public cyclus::Converter { - public: - FissConverter( - double w_fill, - double w_fiss, - double w_topup, - std::string spectrum, - ) : w_fiss_(w_fiss), w_topup_(w_topup), w_fill_(w_fill), spec_(spectrum) {} - - virtual ~FissConverter() {} - - virtual double convert( - cyclus::Material::Ptr m, - cyclus::Arc const * a = NULL, - cyclus::ExchangeTranslationContext const * ctx = NULL) const { - - double w_tgt = CosiWeight(m->comp(), spec_); - int check = CosiCheck(w_tgt, w_fill_, w_fiss_); - int check_topup = CosiCheck(w_tgt, w_fill_, w_topup_); - - if (check == 0) { - return CosiFissileFrac(w_tgt, w_fill_, w_fiss_) * m->quantity(); - } else if (check_topup == 0) { - // use fiss inventory as filler, and topup as fissile - return 1 - CosiFissileFrac(w_tgt, w_fiss_, w_topup_) * m->quantity(); - } else { - return 1e200; - } - } - - private: - std::string spec_; - double w_fiss_; - double w_topup_; - double w_fill_; -}; - -class FillConverter : public cyclus::Converter { - public: - FillConverter( - double w_fill, - double w_fiss, - double w_topup, - std::string spectrum, - ) : w_fiss_(w_fiss), w_topup_(w_topup), w_fill_(w_fill), spec_(spectrum) {} - - virtual ~FillConverter() {} - - virtual double convert( - cyclus::Material::Ptr m, - cyclus::Arc const * a = NULL, - cyclus::ExchangeTranslationContext const * ctx = NULL) const { - - double w_tgt = CosiWeight(m->comp(), spec_); - int check = CosiCheck(w_tgt, w_fill_, w_fiss_); - int check_topup = CosiCheck(w_tgt, w_fill_, w_topup_); - - if (check == 0) { - return 1 - CosiFissileFrac(w_tgt, w_fill_, w_fiss_) * m->quantity(); - } else if (check_topup == 0) { - // switched fissile inventory to filler so don't need any filler inventory - return 0; - } else { - return 1e200; - } - } - - private: - std::string spec_; - double w_fiss_; - double w_topup_; - double w_fill_; -}; - -class TopupConverter : public cyclus::Converter { - public: - TopupConverter( - double w_fill, - double w_fiss, - double w_topup, - std::string spectrum, - ) : w_fiss_(w_fiss), w_topup_(w_topup), w_fill_(w_fill), spec_(spectrum) {} - - virtual ~TopupConverter() {} - - virtual double convert( - cyclus::Material::Ptr m, - cyclus::Arc const * a = NULL, - cyclus::ExchangeTranslationContext const * ctx = NULL) const { - - double w_tgt = CosiWeight(m->comp(), spec_); - int check = CosiCheck(w_tgt, w_fill_, w_fiss_); - int check_topup = CosiCheck(w_tgt, w_fill_, w_topup_); - - if (check == 0) { - return 0; - } else if (check_topup == 0) { - // switched fissile inventory to filler and topup as fissile - return CosiFissileFrac(w_tgt, w_fiss_, w_topup_) * m->quantity(); - } else { - return 1e200; - } - } - - private: - std::string spec_; - double w_fiss_; - double w_topup_; - double w_fill_; }; } // namespace cycamore From 2ec017637d155b75cd2bb489420dd2e8fd5716f9 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 12 Feb 2015 15:07:16 -0600 Subject: [PATCH 073/314] implement requesting for fab --- src/fuel_fab.cc | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ src/fuel_fab.h | 44 ++++++++++++++++---- 2 files changed, 143 insertions(+), 8 deletions(-) diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index ed11ebac01..8e618ab16e 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -200,6 +200,113 @@ FuelFab::FuelFab(cyclus::Context* ctx) fiss_size(0), throughput(0) {} +void FuelFab::EnterNotify() { + cyclus::Facility::EnterNotify(); + + if (fiss_commod_prefs.size() == 0) { + for (int i = 0; i < fiss_commods.size(); i++) { + fiss_commod_prefs.push_back(0); + } + } +} + +std::set::Ptr> +FuelFab::GetMatlRequests() { + using cyclus::RequestPortfolio; + + std::set::Ptr> ports; + + bool exclusive = false; + + if (fiss.space() > cyclus::eps()) { + RequestPortfolio::Ptr port(new RequestPortfolio()); + + Material::Ptr m = cyclus::NewBlankMaterial(fiss.space()); + if (!fiss_recipe.empty()) { + Composition::Ptr c = context()->GetRecipe(fiss_recipe); + m = Material::CreateUntracked(fiss.space(), c); + } + + for (int i = 0; i < fiss_commods.size(); i++) { + std::string commod = fiss_commods[i]; + double pref = fiss_commod_prefs[i]; + + port->AddRequest(m, this, commod, pref, exclusive); + } + + // TODO (BUG): this needs to be a less-than constraint, but that + // functionality doesn't exist for DRE yet. + cyclus::CapacityConstraint cc(fiss.space()); + port->AddConstraint(cc); + ports.insert(port); + } + + if (fill.space() > cyclus::eps()) { + RequestPortfolio::Ptr port(new RequestPortfolio()); + + Material::Ptr m = cyclus::NewBlankMaterial(fill.space()); + if (!fill_recipe.empty()) { + Composition::Ptr c = context()->GetRecipe(fill_recipe); + m = Material::CreateUntracked(fill.space(), c); + } + port->AddRequest(m, this, fill_commod, fill_pref, exclusive); + ports.insert(port); + } + + if (topup.space() > cyclus::eps()) { + RequestPortfolio::Ptr port(new RequestPortfolio()); + + Material::Ptr m = cyclus::NewBlankMaterial(topup.space()); + if (!topup_recipe.empty()) { + Composition::Ptr c = context()->GetRecipe(topup_recipe); + m = Material::CreateUntracked(topup.space(), c); + } + port->AddRequest(m, this, topup_commod, topup_pref, exclusive); + ports.insert(port); + } + + return ports; +} + +bool Contains(std::vector vec, std::string s) { + for (int i = 0; i < vec.size(); i++) { + if (vec[i] == s) { + return true; + } + } + return false; +} + +void FuelFab::AcceptMatlTrades( + const std::vector< std::pair, + Material::Ptr> >& responses) { + + std::vector< std::pair, + cyclus::Material::Ptr> >::const_iterator trade; + + for (trade = responses.begin(); trade != responses.end(); ++trade) { + std::string commod = trade->first.request->commodity(); + double req_qty = trade->first.request->target()->quantity(); + Material::Ptr m = trade->second; + + // the checks of req_qty <= inventorySpace are important in circumstances + // where fill_commod, topup_commod, and any of the fiss_commods may be the + // same as each other. Currently the case where topup_commod or + // fill_commod are one or both inside fiss_commods, trades for each + // inventory can get mixed up, + // TODO: handle same commod case inventory discrimination more robustly. + if (commod == fill_commod && req_qty <= fill.space()) { + fill.Push(m); + } else if (commod == topup_commod && req_qty <= topup.space()) { + topup.Push(m); + } else if (Contains(fiss_commods, commod) && req_qty <= fiss.space()) { + fiss.Push(m); + } else { + throw cyclus::ValueError("cycamore::FuelFab was overmatched on requests"); + } + } +} + std::set::Ptr> FuelFab::GetMatlBids(cyclus::CommodMap::type& commod_requests) { diff --git a/src/fuel_fab.h b/src/fuel_fab.h index 66196d8bae..a8ccc3757a 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -15,6 +15,7 @@ class FuelFab : public cyclus::Facility { virtual void Tick() {}; virtual void Tock() {}; + virtual void EnterNotify(); virtual std::set::Ptr> GetMatlBids(cyclus::CommodMap::type& @@ -25,13 +26,21 @@ class FuelFab : public cyclus::Facility { std::vector, cyclus::Material::Ptr> >& responses); + virtual void AcceptMatlTrades( + const std::vector< std::pair, + cyclus::Material::Ptr> >& responses); + + virtual std::set::Ptr> GetMatlRequests(); + private: #pragma cyclus var {} - std::vector fill_commods; - #pragma cyclus var {} - std::vector fill_commod_prefs; + std::string fill_commod; #pragma cyclus var {} std::string fill_recipe; + #pragma cyclus var { \ + "default": 0, \ + } + double fill_pref; #pragma cyclus var {} double fill_size; #pragma cyclus var {'capacity': 'fill_size'} @@ -39,18 +48,37 @@ class FuelFab : public cyclus::Facility { #pragma cyclus var {} std::vector fiss_commods; - #pragma cyclus var {} - std::vector fiss_commod_prefs; + #pragma cyclus var { \ + "default": [], \ + "doc": "If unspecified, default is to use zero for all preferences.", \ + } + std::vector fiss_commod_prefs; + #pragma cyclus var { \ + "default": "", \ + "doc": "If unspecified, default is to use a dummy blank recipe", \ + } + std::string fiss_recipe; #pragma cyclus var {} double fiss_size; #pragma cyclus var {'capacity': 'fiss_size'} cyclus::toolkit::ResBuf fiss; - #pragma cyclus var {} + #pragma cyclus var { \ + "doc": "", \ + "default": "", \ + } std::string topup_commod; - #pragma cyclus var {} + #pragma cyclus var { \ + "default": "", \ + } std::string topup_recipe; - #pragma cyclus var {} + #pragma cyclus var { \ + "default": 0, \ + } + double topup_pref; + #pragma cyclus var { \ + "default": 0, \ + } double topup_size; #pragma cyclus var {'capacity': 'topup_size'} cyclus::toolkit::ResBuf topup; From 95e2410f165d70fe5da1f90ee8dc3077122e98a0 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 12 Feb 2015 16:28:45 -0600 Subject: [PATCH 074/314] fix zero capacity constraint bug --- src/fuel_fab.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index 8e618ab16e..bc5e357dd6 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -366,12 +366,14 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& } // else can't meet the target - don't bid } - cyclus::Converter::Ptr fillconv(new FissConverter(w_fill, w_fiss, w_topup, spectrum)); cyclus::Converter::Ptr fissconv(new FillConverter(w_fill, w_fiss, w_topup, spectrum)); + cyclus::Converter::Ptr fillconv(new FissConverter(w_fill, w_fiss, w_topup, spectrum)); cyclus::Converter::Ptr topupconv(new TopupConverter(w_fill, w_fiss, w_topup, spectrum)); - cyclus::CapacityConstraint fillc(fill.quantity(), fillconv); cyclus::CapacityConstraint fissc(fiss.quantity(), fissconv); - cyclus::CapacityConstraint topupc(topup.quantity(), topupconv); + // important! - the std::max calls prevent CapacityConstraint throwing a zero cap exception + // TODO: write a test to check for this capacity adjustment + cyclus::CapacityConstraint fillc(std::max(fill.quantity(), 1e-100), fillconv); + cyclus::CapacityConstraint topupc(std::max(topup.quantity(), 1e-100), topupconv); port->AddConstraint(fillc); port->AddConstraint(fissc); port->AddConstraint(topupc); From 724dcd5f18fd73baa67762019f807985ba713043 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Tue, 24 Feb 2015 10:51:22 -0600 Subject: [PATCH 075/314] skeleton of fab tests --- src/fuel_fab_tests.cc | 102 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/fuel_fab_tests.cc diff --git a/src/fuel_fab_tests.cc b/src/fuel_fab_tests.cc new file mode 100644 index 0000000000..adc8a5ca4a --- /dev/null +++ b/src/fuel_fab_tests.cc @@ -0,0 +1,102 @@ +#include + +#include + +#include "cyclus.h" + +using pyne::nucname::id; +using cyclus::Composition; +using cyclus::Material; +using cyclus::QueryResult; +using cyclus::Cond; +using cyclus::toolkit::MatQuery; + +namespace cycamore { + +Composition::Ptr c_uox() { + cyclus::CompMap m; + m[id("u235")] = 0.04; + m[id("u238")] = 0.96; + return Composition::CreateFromMass(m); +}; + +Composition::Ptr c_mox() { + cyclus::CompMap m; + m[id("u235")] = .7; + m[id("u238")] = 100; + m[id("pu239")] = 3.3; + return Composition::CreateFromMass(m); +}; + +Composition::Ptr c_natu() { + cyclus::CompMap m; + m[id("u235")] = .007; + m[id("u238")] = .993; + return Composition::CreateFromMass(m); +}; + +Composition::Ptr c_pustream() { + cyclus::CompMap m; + m[id("pu239")] = 100; + m[id("pu240")] = 10; + m[id("pu241")] = 1; + m[id("pu242")] = 1; + return Composition::CreateFromMass(m); +}; + +Composition::Ptr c_pustreamlow() { + cyclus::CompMap m; + m[id("pu239")] = 80; + m[id("pu240")] = 10; + m[id("pu241")] = 1; + m[id("pu242")] = 1; + return Composition::CreateFromMass(m); +}; + +Composition::Ptr c_pustreambad() { + cyclus::CompMap m; + m[id("pu239")] = 10; + m[id("pu240")] = 10; + m[id("pu241")] = 1; + m[id("pu242")] = 1; + return Composition::CreateFromMass(m); +}; + +Composition::Ptr c_water() { + cyclus::CompMap m; + m[id("O16")] = 1; + m[id("H1")] = 2; + return Composition::CreateFromAtom(m); +}; + +TEST(FuelFabTests, JustInTimeOrdering) { + std::string config = + "commod" + "recipe" + "1" + "" + " commod commod " + "1" + "" + "commod" + "recipe" + "1" + "" + "commod" + "thermal" + "1" + ; + + int simdur = 50; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + //sim.AddSource("enriched_u").Finalize(); + //sim.AddRecipe("lwr_fresh", c_uox()); + //sim.AddRecipe("lwr_spent", c_spentuox()); + //int id = sim.Run(); + + //QueryResult qr = sim.db().Query("Transactions", NULL); + //EXPECT_EQ(simdur, qr.rows.size()) << "failed to order+run on fresh fuel inside 1 time step"; +} + +} // namespace cycamore + From 3239082351e53214b08a702651933f58cbe4402a Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 25 Feb 2015 15:02:23 -0600 Subject: [PATCH 076/314] wrote a few tests and subbed out others --- src/fuel_fab.cc | 212 ++++++++++++++++++-------------------- src/fuel_fab.h | 7 +- src/fuel_fab_tests.cc | 231 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 328 insertions(+), 122 deletions(-) diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index bc5e357dd6..7deab641e2 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -6,89 +6,6 @@ using pyne::simple_xs; namespace cycamore { -double CosiWeight(cyclus::Composition::Ptr c, std::string spectrum) { - cyclus::CompMap cm = c->mass(); - cyclus::compmath::Normalize(&cm); - - double nu_pu239 = 2.85; - double nu_u233 = 2.5; - double nu_u235 = 2.4; - - double fiss_u238 = simple_xs("u238", "fission", spectrum); - double absorb_u238 = simple_xs("u238", "absorption", spectrum); - double nu_u238 = 0; - double p_u238 = nu_u238 * fiss_u238 - absorb_u238; - - double fiss_pu239 = simple_xs("Pu239", "fission", spectrum); - double absorb_pu239 = simple_xs("Pu239", "absorption", spectrum); - double p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239; - - cyclus::CompMap::iterator it; - double w = 0; - for (it = cm.begin(); it != cm.end(); ++it) { - cyclus::Nuc nuc = it->first; - double nu = 0; - if (nuc == 922350000) { - nu = nu_u235; - } else if (nuc == 922330000) { - nu = nu_u233; - } else if (nuc == 942390000) { - nu = nu_pu239; - } - - double fiss = 0; - double absorb = 0; - try { - fiss = simple_xs(nuc, "fission", spectrum); - absorb = simple_xs(nuc, "absorption", spectrum); - } catch(pyne::InvalidSimpleXS err) { - fiss = 0; - absorb = 0; - } - - double p = nu * fiss - absorb; - w += it->second * (p - p_u238) / (p_pu239 - p_u238); - } - return w; -} - -double CosiFissileFrac(double w_tgt, double w_fill, double w_fiss) { - if (w_fiss == w_fill && w_tgt == w_fiss) { - return 1; - } else if (w_fiss == w_fill) { - throw cyclus::ValueError("fissile and filler weights are the same"); - } - return (w_tgt - w_fill) / (w_fiss - w_fill); -} - -double CosiFissileFrac(cyclus::Composition::Ptr target, - cyclus::Composition::Ptr filler, - cyclus::Composition::Ptr fissile, - std::string spectrum) { - double w_fill = CosiWeight(filler, spectrum); - double w_fiss = CosiWeight(fissile, spectrum); - double w_tgt = CosiWeight(target, spectrum); - return CosiFissileFrac(w_tgt, w_fill, w_fiss); -} - -double CosiFillerFrac(double w_tgt, double w_fill, double w_fiss) { - return 1-CosiFissileFrac(w_tgt, w_fill, w_fiss); -} - -// Returns true if the given weights can be used to compute valid mixing -// fractions of the filler and fissile streams to hit the target. -bool CosiValid(double w_target, double w_filler, double w_fissile) { - // w_target must be in between w_filler and w_fissile for the cosi - // equivalence technique to work - so we must check for this - if (w_filler <= w_target && w_target <= w_fissile) { - return true; - } else if (w_fissile <= w_target && w_target <= w_filler) { - return true; - } else { - return false; - } -} - class FissConverter : public cyclus::Converter { public: FissConverter( @@ -106,11 +23,11 @@ class FissConverter : public cyclus::Converter { cyclus::ExchangeTranslationContext const * ctx = NULL) const { double w_tgt = CosiWeight(m->comp(), spec_); - if (CosiValid(w_tgt, w_fill_, w_fiss_)) { - return CosiFissileFrac(w_tgt, w_fill_, w_fiss_) * m->quantity(); - } else if (CosiValid(w_tgt, w_fiss_, w_topup_)) { + if (ValidWeights(w_fill_, w_tgt, w_fiss_)) { + return HighFrac(w_fill_, w_tgt, w_fiss_) * m->quantity(); + } else if (ValidWeights(w_fiss_, w_tgt, w_topup_)) { // use fiss inventory as filler, and topup as fissile - return CosiFillerFrac(w_tgt, w_fiss_, w_topup_) * m->quantity(); + return LowFrac(w_fiss_, w_tgt, w_topup_) * m->quantity(); } else { // don't bid at all return 1e200; @@ -141,9 +58,9 @@ class FillConverter : public cyclus::Converter { cyclus::ExchangeTranslationContext const * ctx = NULL) const { double w_tgt = CosiWeight(m->comp(), spec_); - if (CosiValid(w_tgt, w_fill_, w_fiss_)) { - return CosiFillerFrac(w_tgt, w_fill_, w_fiss_) * m->quantity(); - } else if (CosiValid(w_tgt, w_fiss_, w_topup_)) { + if (ValidWeights(w_fill_, w_tgt, w_fiss_)) { + return LowFrac(w_fill_, w_tgt, w_fiss_) * m->quantity(); + } else if (ValidWeights(w_fiss_, w_tgt, w_topup_)) { // switched fissile inventory to filler so don't need any filler inventory return 0; } else { @@ -176,11 +93,11 @@ class TopupConverter : public cyclus::Converter { cyclus::ExchangeTranslationContext const * ctx = NULL) const { double w_tgt = CosiWeight(m->comp(), spec_); - if (CosiValid(w_tgt, w_fill_, w_fiss_)) { + if (ValidWeights(w_fill_, w_tgt, w_fiss_)) { return 0; - } else if (CosiValid(w_tgt, w_fiss_, w_topup_)) { + } else if (ValidWeights(w_fiss_, w_tgt, w_topup_)) { // switched fissile inventory to filler and topup as fissile - return CosiFissileFrac(w_tgt, w_fiss_, w_topup_) * m->quantity(); + return HighFrac(w_fiss_, w_tgt, w_topup_) * m->quantity(); } else { // don't bid at all return 1e200; @@ -227,17 +144,13 @@ FuelFab::GetMatlRequests() { m = Material::CreateUntracked(fiss.space(), c); } + std::vector*> reqs; for (int i = 0; i < fiss_commods.size(); i++) { std::string commod = fiss_commods[i]; double pref = fiss_commod_prefs[i]; - - port->AddRequest(m, this, commod, pref, exclusive); + reqs.push_back(port->AddRequest(m, this, commod, pref, exclusive)); } - - // TODO (BUG): this needs to be a less-than constraint, but that - // functionality doesn't exist for DRE yet. - cyclus::CapacityConstraint cc(fiss.space()); - port->AddConstraint(cc); + port->AddMutualReqs(reqs); ports.insert(port); } @@ -289,17 +202,17 @@ void FuelFab::AcceptMatlTrades( double req_qty = trade->first.request->target()->quantity(); Material::Ptr m = trade->second; - // the checks of req_qty <= inventorySpace are important in circumstances + // the checks of "m->quantity() <= [inventory].space()" are important in circumstances // where fill_commod, topup_commod, and any of the fiss_commods may be the // same as each other. Currently the case where topup_commod or // fill_commod are one or both inside fiss_commods, trades for each // inventory can get mixed up, // TODO: handle same commod case inventory discrimination more robustly. - if (commod == fill_commod && req_qty <= fill.space()) { + if (commod == fill_commod && m->quantity() <= fill.space()) { fill.Push(m); - } else if (commod == topup_commod && req_qty <= topup.space()) { + } else if (commod == topup_commod && m->quantity() <= topup.space()) { topup.Push(m); - } else if (Contains(fiss_commods, commod) && req_qty <= fiss.space()) { + } else if (Contains(fiss_commods, commod) && m->quantity() <= fiss.space()) { fiss.Push(m); } else { throw cyclus::ValueError("cycamore::FuelFab was overmatched on requests"); @@ -342,8 +255,8 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& Composition::Ptr tgt = req->target()->comp(); double w_tgt = CosiWeight(tgt, spectrum); double tgt_qty = req->target()->quantity(); - if (fill.count() > 0 && CosiValid(w_tgt, w_fill, w_fiss)) { - double fiss_frac = CosiFissileFrac(w_tgt, w_fill, w_fiss); + if (fill.count() > 0 && ValidWeights(w_fill, w_tgt, w_fiss)) { + double fiss_frac = HighFrac(w_fill, w_tgt, w_fiss); double fill_frac = 1 - fiss_frac; Material::Ptr m1 = Material::CreateUntracked(fiss_frac * tgt_qty, m_fiss->comp()); Material::Ptr m2 = Material::CreateUntracked(fill_frac * tgt_qty, m_fill->comp()); @@ -351,11 +264,11 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& bool exclusive = false; port->AddBid(req, m1, this, exclusive); - } else if (fill.count() > 0 && topup.count() > 0 && CosiValid(w_tgt, w_fiss, w_topup)) { + } else if (fill.count() > 0 && topup.count() > 0 && ValidWeights(w_fiss, w_tgt, w_topup)) { // only bid with topup if we have filler - otherwise we might be able to // meet target with filler when we get it. we should only use topup // when the fissile has too poor neutronics. - double topup_frac = CosiFissileFrac(w_tgt, w_fiss, w_topup); + double topup_frac = HighFrac(w_fiss, w_tgt, w_topup); double fiss_frac = 1 - topup_frac; Material::Ptr m1 = Material::CreateUntracked(topup_frac * tgt_qty, m_topup->comp()); Material::Ptr m2 = Material::CreateUntracked(fiss_frac * tgt_qty, m_fiss->comp()); @@ -409,15 +322,15 @@ void FuelFab::GetMatlTrades( double w_tgt = CosiWeight(tgt->comp(), spectrum); double qty = tgt->quantity(); - if (CosiValid(w_tgt, w_fill, w_fiss)) { - double fiss_frac = CosiFissileFrac(w_tgt, w_fill, w_fiss); + if (ValidWeights(w_fill, w_tgt, w_fiss)) { + double fiss_frac = HighFrac(w_fill, w_tgt, w_fiss); double fill_frac = 1 - fiss_frac; Material::Ptr m = fiss.Pop(fiss_frac*qty); m->Absorb(fill.Pop(fill_frac*qty)); responses.push_back(std::make_pair(trades[i], m)); } else { - double topup_frac = CosiFissileFrac(w_tgt, w_fiss, w_topup); + double topup_frac = HighFrac(w_fiss, w_tgt, w_topup); double fiss_frac = 1 - topup_frac; Material::Ptr m = topup.Pop(topup_frac*qty); @@ -431,5 +344,82 @@ extern "C" cyclus::Agent* ConstructFuelFab(cyclus::Context* ctx) { return new FuelFab(ctx); } +// Returns the weight of c using 1 group cross sections of type spectrum +// which must be one of: +// +// * thermal +// * thermal_maxwell_ave +// * fission_spectrum_ave +// * resonance_integral +// * fourteen_MeV +// +// The weight is calculated as "(nu*sigma_f - sigma_a) * N". +double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { + cyclus::CompMap cm = c->atom(); + cyclus::compmath::Normalize(&cm); + + double nu_pu239 = 2.85; + double nu_u233 = 2.5; + double nu_u235 = 2.4; + + double fiss_u238 = simple_xs("u238", "fission", spectrum); + double absorb_u238 = simple_xs("u238", "absorption", spectrum); + double nu_u238 = 0; + double p_u238 = nu_u238 * fiss_u238 - absorb_u238; + + double fiss_pu239 = simple_xs("Pu239", "fission", spectrum); + double absorb_pu239 = simple_xs("Pu239", "absorption", spectrum); + double p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239; + + cyclus::CompMap::iterator it; + double w = 0; + for (it = cm.begin(); it != cm.end(); ++it) { + cyclus::Nuc nuc = it->first; + double nu = 0; + if (nuc == 922350000) { + nu = nu_u235; + } else if (nuc == 922330000) { + nu = nu_u233; + } else if (nuc == 942390000) { + nu = nu_pu239; + } + + double fiss = 0; + double absorb = 0; + try { + fiss = simple_xs(nuc, "fission", spectrum); + absorb = simple_xs(nuc, "absorption", spectrum); + } catch(pyne::InvalidSimpleXS err) { + fiss = 0; + absorb = 0; + } + + double p = nu * fiss - absorb; + w += it->second * (p - p_u238) / (p_pu239 - p_u238); + } + return w; +} + +double HighFrac(double w_low, double w_target, double w_high) { + if (!ValidWeights(w_low, w_target, w_high)) { + throw cyclus::ValueError("low and high weights cannot meet target"); + } else if (w_low == w_high && w_target == w_low) { + return 1; + } + return (w_target - w_low) / (w_high - w_low); +} + +double LowFrac(double w_low, double w_target, double w_high) { + return 1 - HighFrac(w_low, w_target, w_high); +} + +// Returns true if the given weights can be used to linearly interpolate valid +// mixing fractions of the filler and fissile streams to hit the target. +bool ValidWeights(double w_low, double w_target, double w_high) { + // w_tgt must be in between w_fill and w_fiss for the equivalence + // interpolation to work. + return w_low <= w_target && w_target <= w_high; +} + } // namespace cycamore diff --git a/src/fuel_fab.h b/src/fuel_fab.h index a8ccc3757a..82d937e410 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -6,6 +6,11 @@ namespace cycamore { +double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum); +bool ValidWeights(double w_low, double w_tgt, double w_high); +double LowFrac(double w_low, double w_tgt, double w_high); +double HighFrac(double w_low, double w_tgt, double w_high); + class FuelFab : public cyclus::Facility { public: FuelFab(cyclus::Context* ctx); @@ -87,7 +92,7 @@ class FuelFab : public cyclus::Facility { std::string outcommod; #pragma cyclus var { \ - "doc": "'fission' for fast reactor compositions or 'thermal' for slow reactors.", \ + "doc": "'fission_spectrum_ave' for fast reactor compositions or 'thermal' for slow reactors.", \ } std::string spectrum; diff --git a/src/fuel_fab_tests.cc b/src/fuel_fab_tests.cc index adc8a5ca4a..3d6cc9f549 100644 --- a/src/fuel_fab_tests.cc +++ b/src/fuel_fab_tests.cc @@ -1,11 +1,12 @@ -#include +#include "fuel_fab.h" +#include #include - #include "cyclus.h" using pyne::nucname::id; using cyclus::Composition; +using cyclus::CompMap; using cyclus::Material; using cyclus::QueryResult; using cyclus::Cond; @@ -14,14 +15,14 @@ using cyclus::toolkit::MatQuery; namespace cycamore { Composition::Ptr c_uox() { - cyclus::CompMap m; + CompMap m; m[id("u235")] = 0.04; m[id("u238")] = 0.96; return Composition::CreateFromMass(m); }; Composition::Ptr c_mox() { - cyclus::CompMap m; + CompMap m; m[id("u235")] = .7; m[id("u238")] = 100; m[id("pu239")] = 3.3; @@ -29,14 +30,14 @@ Composition::Ptr c_mox() { }; Composition::Ptr c_natu() { - cyclus::CompMap m; + CompMap m; m[id("u235")] = .007; m[id("u238")] = .993; return Composition::CreateFromMass(m); }; Composition::Ptr c_pustream() { - cyclus::CompMap m; + CompMap m; m[id("pu239")] = 100; m[id("pu240")] = 10; m[id("pu241")] = 1; @@ -45,7 +46,7 @@ Composition::Ptr c_pustream() { }; Composition::Ptr c_pustreamlow() { - cyclus::CompMap m; + CompMap m; m[id("pu239")] = 80; m[id("pu240")] = 10; m[id("pu241")] = 1; @@ -54,7 +55,7 @@ Composition::Ptr c_pustreamlow() { }; Composition::Ptr c_pustreambad() { - cyclus::CompMap m; + CompMap m; m[id("pu239")] = 10; m[id("pu240")] = 10; m[id("pu241")] = 1; @@ -63,13 +64,102 @@ Composition::Ptr c_pustreambad() { }; Composition::Ptr c_water() { - cyclus::CompMap m; + CompMap m; m[id("O16")] = 1; m[id("H1")] = 2; return Composition::CreateFromAtom(m); }; -TEST(FuelFabTests, JustInTimeOrdering) { +TEST(FuelFabTests, CosiWeight) { + cyclus::Env::SetNucDataPath(); + CompMap m; + m[942390000] = 1; + Composition::Ptr c = Composition::CreateFromMass(m); + double w = CosiWeight(c, "thermal"); + EXPECT_DOUBLE_EQ(1.0, w); + + m.clear(); + m[922380000] = 1; + c = Composition::CreateFromMass(m); + w = CosiWeight(c, "thermal"); + EXPECT_DOUBLE_EQ(0.0, w); + + m.clear(); + m[942390000] = 1; + c = Composition::CreateFromMass(m); + w = CosiWeight(c, "fission_spectrum_ave"); + EXPECT_DOUBLE_EQ(1.0, w); + + m.clear(); + m[922380000] = 1; + c = Composition::CreateFromMass(m); + w = CosiWeight(c, "fission_spectrum_ave"); + EXPECT_DOUBLE_EQ(0.0, w); + + m.clear(); + m[922380000] = 1; + m[942390000] = 1; + c = Composition::CreateFromAtom(m); + w = CosiWeight(c, "thermal"); + EXPECT_DOUBLE_EQ(0.5, w) << "might be using mass-fractions instead of atom"; + + m.clear(); + m[922380000] = 1; + m[942390000] = 1; + c = Composition::CreateFromAtom(m); + w = CosiWeight(c, "fission_spectrum_ave"); + EXPECT_DOUBLE_EQ(0.5, w) << "might be using mass-fractions instead of atom"; + + m.clear(); + m[922380000] = 1; + m[942390000] = 1; + m[922350000] = 1; + c = Composition::CreateFromAtom(m); + double w_therm = CosiWeight(c, "thermal"); + double w_fast = CosiWeight(c, "fission_spectrum_ave"); + EXPECT_GT(w_therm, w_fast); +} + +TEST(FuelFabTests, HighFrac) { + double w_fill = CosiWeight(c_natu(), "thermal"); + double w_fiss = CosiWeight(c_pustream(), "thermal"); + double w_target = CosiWeight(c_uox(), "thermal"); + + EXPECT_THROW(HighFrac(w_fiss, w_target, w_fill), cyclus::ValueError); + EXPECT_THROW(HighFrac(w_target, w_fill, w_fiss), cyclus::ValueError); + EXPECT_THROW(HighFrac(w_target, w_fiss, w_fill), cyclus::ValueError); + + double f = HighFrac(w_fill, w_target, w_fiss); + EXPECT_DOUBLE_EQ((w_target-w_fill)/(w_fiss-w_fill), f); +} + +TEST(FuelFabTests, LowFrac) { + double w_fill = CosiWeight(c_natu(), "thermal"); + double w_fiss = CosiWeight(c_pustream(), "thermal"); + double w_target = CosiWeight(c_uox(), "thermal"); + + EXPECT_THROW(LowFrac(w_fiss, w_target, w_fill), cyclus::ValueError); + EXPECT_THROW(LowFrac(w_target, w_fill, w_fiss), cyclus::ValueError); + EXPECT_THROW(LowFrac(w_target, w_fiss, w_fill), cyclus::ValueError); + + double f = LowFrac(w_fill, w_target, w_fiss); + EXPECT_DOUBLE_EQ((w_fiss-w_target)/(w_fiss-w_fill), f); +} + +TEST(FuelFabTests, ValidWeights) { + double w_fill = CosiWeight(c_natu(), "thermal"); + double w_fiss = CosiWeight(c_pustream(), "thermal"); + double w_target = CosiWeight(c_uox(), "thermal"); + + EXPECT_EQ(true, ValidWeights(w_fill, w_target, w_fiss)); + EXPECT_EQ(false, ValidWeights(w_fiss, w_target, w_fill)); + EXPECT_EQ(false, ValidWeights(w_target, w_fill, w_fiss)); + EXPECT_EQ(false, ValidWeights(w_fiss, w_fill, w_target)); + EXPECT_EQ(false, ValidWeights(w_target, w_fiss, w_fill)); + EXPECT_EQ(false, ValidWeights(w_fill, w_fiss, w_target)); +} + +TEST(FuelFabTests, Template) { std::string config = "commod" "recipe" @@ -98,5 +188,126 @@ TEST(FuelFabTests, JustInTimeOrdering) { //EXPECT_EQ(simdur, qr.rows.size()) << "failed to order+run on fresh fuel inside 1 time step"; } +// request (and receive) a specific recipe for fissile stream correctly. +TEST(FuelFabTests, FissRecipe) { + std::string config = + "dummy" + "natu" + "1" + "" + " stream1 stream2 stream3 " + "2.5" + "spentuox" + "" + "dummyout" + "thermal" + "0" + ; + + int simdur = 1; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("stream1").Finalize(); + sim.AddRecipe("spentuox", c_pustream()); + sim.AddRecipe("natu", c_natu()); + int id = sim.Run(); + + int resid = sim.db().Query("Transactions", NULL).GetVal("ResourceId"); + CompMap got = sim.GetMaterial(resid)->comp()->mass(); + CompMap want = c_pustream()->mass(); + cyclus::compmath::Normalize(&got); + cyclus::compmath::Normalize(&want); + CompMap::iterator it; + for (it = want.begin(); it != want.end(); ++it) { + EXPECT_DOUBLE_EQ(it->second, got[it->first]) << "nuclide qty off: " << pyne::nucname::name(it->first); + } +} + +// multiple fissile streams can be correctly requested and used as +// fissile material inventory. +TEST(FuelFabTests, MultipleFissStreams) { + std::string config = + "dummy" + "natu" + "1" + "" + " stream1 stream2 stream3 " + "2.5" + "" + "dummyout" + "thermal" + "0" + ; + + int simdur = 1; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("stream1").recipe("spentuox").capacity(1).Finalize(); + sim.AddSource("stream2").recipe("spentuox").capacity(1).Finalize(); + sim.AddSource("stream3").recipe("spentuox").capacity(1).Finalize(); + sim.AddRecipe("spentuox", c_pustream()); + sim.AddRecipe("natu", c_natu()); + int id = sim.Run(); + + QueryResult qr = sim.db().Query("Transactions", NULL); + EXPECT_EQ(3, qr.rows.size()); + + std::vector conds; + conds.push_back(Cond("Commodity", "==", std::string("stream1"))); + qr = sim.db().Query("Transactions", &conds); + EXPECT_EQ(1, qr.rows.size()); + + conds[0] = Cond("Commodity", "==", std::string("stream2")); + qr = sim.db().Query("Transactions", &conds); + EXPECT_EQ(1, qr.rows.size()); + + conds[0] = Cond("Commodity", "==", std::string("stream3")); + qr = sim.db().Query("Transactions", &conds); + EXPECT_EQ(1, qr.rows.size()); +} + +// fill, fiss, and topup inventories are all requested for and +// filled as expected +TEST(FuelFabTests, FillInventories) { + FAIL() << "not implemented"; +} + +// throughput is properly restricted when faced with many fuel +// requests and with ample material inventory. +TEST(FuelFabTests, ThroughputLimit) { + FAIL() << "not implemented"; +} + +// supplied fuel has proper equivalence weights as requested. +TEST(FuelFabTests, CorrectMixing) { + FAIL() << "not implemented"; +} + +// fuel is requested requiring more filler than is available with plenty of +// fissile. +TEST(FuelFabTests, FillConstrained) { + FAIL() << "not implemented"; +} + +// fuel is requested requiring more fissile material than is available with +// plenty of filler. +TEST(FuelFabTests, FissConstrained) { + FAIL() << "not implemented"; +} + +// swap to topup inventory because fissile has too low reactivity. +TEST(FuelFabTests, SwapTopup) { + FAIL() << "not implemented"; +} + +// swap to topup inventory but are limited by topup inventory quantity. +TEST(FuelFabTests, SwapTopup_TopupConstrained) { + FAIL() << "not implemented"; +} + +// swap to topup inventory but are limited by fissile (used as filler) +// inventory. +TEST(FuelFabTests, SwapTopup_FissConstrained) { + FAIL() << "not implemented"; +} + } // namespace cycamore From 67b64b1d32076f0421d69d77e6a61ed6c896840b Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 25 Feb 2015 15:12:21 -0600 Subject: [PATCH 077/314] another test stub --- src/fuel_fab_tests.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/fuel_fab_tests.cc b/src/fuel_fab_tests.cc index 3d6cc9f549..2e8939f096 100644 --- a/src/fuel_fab_tests.cc +++ b/src/fuel_fab_tests.cc @@ -264,6 +264,11 @@ TEST(FuelFabTests, MultipleFissStreams) { EXPECT_EQ(1, qr.rows.size()); } +// fissile stream preferences can be specified. +TEST(FuelFabTests, FissStreamPrefs) { + FAIL() << "not implemented"; +} + // fill, fiss, and topup inventories are all requested for and // filled as expected TEST(FuelFabTests, FillInventories) { From 0a174ef6cee4278924cfba93a7f1d85cb229db19 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 26 Feb 2015 13:50:55 -0600 Subject: [PATCH 078/314] tmp - fixing bugs adding tests --- src/fuel_fab.cc | 131 +++++++++++++++------- src/fuel_fab.h | 4 +- src/fuel_fab_tests.cc | 254 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 315 insertions(+), 74 deletions(-) diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index 7deab641e2..41eb0d12ac 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -4,6 +4,9 @@ using cyclus::Material; using cyclus::Composition; using pyne::simple_xs; +#define SHOW(X) \ + std::cout << __FILE__ << ":" << __LINE__ << ": "#X" = " << X << "\n" + namespace cycamore { class FissConverter : public cyclus::Converter { @@ -24,6 +27,7 @@ class FissConverter : public cyclus::Converter { double w_tgt = CosiWeight(m->comp(), spec_); if (ValidWeights(w_fill_, w_tgt, w_fiss_)) { + std::cout << std::setprecision(17) << "fissconvert=" << HighFrac(w_fill_, w_tgt, w_fiss_) * m->quantity() << "\n"; return HighFrac(w_fill_, w_tgt, w_fiss_) * m->quantity(); } else if (ValidWeights(w_fiss_, w_tgt, w_topup_)) { // use fiss inventory as filler, and topup as fissile @@ -59,6 +63,10 @@ class FillConverter : public cyclus::Converter { double w_tgt = CosiWeight(m->comp(), spec_); if (ValidWeights(w_fill_, w_tgt, w_fiss_)) { + std::cout << std::setprecision(17) << "w_tgt = " << w_tgt << "\n"; + std::cout << std::setprecision(17) << "w_fiss = " << w_fiss_ << "\n"; + std::cout << std::setprecision(17) << "w_fill = " << w_fill_ << "\n"; + std::cout << std::setprecision(17) << "fillconvert=" << LowFrac(w_fill_, w_tgt, w_fiss_) * m->quantity() << "\n"; return LowFrac(w_fill_, w_tgt, w_fiss_) * m->quantity(); } else if (ValidWeights(w_fiss_, w_tgt, w_topup_)) { // switched fissile inventory to filler so don't need any filler inventory @@ -94,6 +102,7 @@ class TopupConverter : public cyclus::Converter { double w_tgt = CosiWeight(m->comp(), spec_); if (ValidWeights(w_fill_, w_tgt, w_fiss_)) { + std::cout << "topupconvert=0\n"; return 0; } else if (ValidWeights(w_fiss_, w_tgt, w_topup_)) { // switched fissile inventory to filler and topup as fissile @@ -226,24 +235,38 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& using cyclus::BidPortfolio; std::set::Ptr> ports; - if (fiss.empty()) { + if (throughput == 0) { return ports; } - Material::Ptr m_fiss = fiss.Peek(); - double w_fiss = CosiWeight(m_fiss->comp(), spectrum); - Material::Ptr m_fill; - Material::Ptr m_topup; + Composition::Ptr c_fill; + Composition::Ptr c_fiss; + Composition::Ptr c_topup; double w_fill = 0; double w_topup = 0; if (fill.count() > 0) { - m_fill = fill.Peek(); - w_fill = CosiWeight(m_fill->comp(), spectrum); + c_fill = fill.Peek()->comp(); + w_fill = CosiWeight(c_fill, spectrum); + } else if (!fill_recipe.empty()) { + c_fill = context()->GetRecipe(fill_recipe); + w_fill = CosiWeight(c_fill, spectrum); } if (topup.count() > 0) { - m_topup = topup.Peek(); - w_topup = CosiWeight(m_topup->comp(), spectrum); + c_topup = topup.Peek()->comp(); + w_topup = CosiWeight(c_topup, spectrum); + } else if (!topup_recipe.empty()) { + c_topup = context()->GetRecipe(topup_recipe); + w_topup = CosiWeight(c_topup, spectrum); + } + + double w_fiss = w_fill; // this allows trading just fill with no fiss inventory + if (fiss.count() > 0) { + c_fiss = fiss.Peek()->comp(); + w_fiss = CosiWeight(c_fiss, spectrum); + } else if (!fiss_recipe.empty()) { + c_fiss = context()->GetRecipe(fiss_recipe); + w_fiss = CosiWeight(c_fiss, spectrum); } std::vector*>& reqs = commod_requests[outcommod]; @@ -255,23 +278,25 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& Composition::Ptr tgt = req->target()->comp(); double w_tgt = CosiWeight(tgt, spectrum); double tgt_qty = req->target()->quantity(); - if (fill.count() > 0 && ValidWeights(w_fill, w_tgt, w_fiss)) { + if (ValidWeights(w_fill, w_tgt, w_fiss)) { + std::cout << "bidding with fill and fiss tgt_qty=" << tgt_qty << "\n"; double fiss_frac = HighFrac(w_fill, w_tgt, w_fiss); double fill_frac = 1 - fiss_frac; - Material::Ptr m1 = Material::CreateUntracked(fiss_frac * tgt_qty, m_fiss->comp()); - Material::Ptr m2 = Material::CreateUntracked(fill_frac * tgt_qty, m_fill->comp()); + Material::Ptr m1 = Material::CreateUntracked(fiss_frac * tgt_qty, c_fiss); + Material::Ptr m2 = Material::CreateUntracked(fill_frac * tgt_qty, c_fill); m1->Absorb(m2); bool exclusive = false; port->AddBid(req, m1, this, exclusive); - } else if (fill.count() > 0 && topup.count() > 0 && ValidWeights(w_fiss, w_tgt, w_topup)) { + } else if (0 && topup.count() > 0 && ValidWeights(w_fiss, w_tgt, w_topup)) { + std::cout << "bidding with fiss and topup\n"; // only bid with topup if we have filler - otherwise we might be able to // meet target with filler when we get it. we should only use topup // when the fissile has too poor neutronics. double topup_frac = HighFrac(w_fiss, w_tgt, w_topup); double fiss_frac = 1 - topup_frac; - Material::Ptr m1 = Material::CreateUntracked(topup_frac * tgt_qty, m_topup->comp()); - Material::Ptr m2 = Material::CreateUntracked(fiss_frac * tgt_qty, m_fiss->comp()); + Material::Ptr m1 = Material::CreateUntracked(topup_frac * tgt_qty, c_topup); + Material::Ptr m2 = Material::CreateUntracked(fiss_frac * tgt_qty, c_fiss); m1->Absorb(m2); bool exclusive = false; @@ -279,14 +304,15 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& } // else can't meet the target - don't bid } - cyclus::Converter::Ptr fissconv(new FillConverter(w_fill, w_fiss, w_topup, spectrum)); - cyclus::Converter::Ptr fillconv(new FissConverter(w_fill, w_fiss, w_topup, spectrum)); + SHOW(fill.quantity()); + SHOW(fiss.quantity()); + cyclus::Converter::Ptr fissconv(new FissConverter(w_fill, w_fiss, w_topup, spectrum)); + cyclus::Converter::Ptr fillconv(new FillConverter(w_fill, w_fiss, w_topup, spectrum)); cyclus::Converter::Ptr topupconv(new TopupConverter(w_fill, w_fiss, w_topup, spectrum)); - cyclus::CapacityConstraint fissc(fiss.quantity(), fissconv); // important! - the std::max calls prevent CapacityConstraint throwing a zero cap exception - // TODO: write a test to check for this capacity adjustment - cyclus::CapacityConstraint fillc(std::max(fill.quantity(), 1e-100), fillconv); - cyclus::CapacityConstraint topupc(std::max(topup.quantity(), 1e-100), topupconv); + cyclus::CapacityConstraint fissc(std::max(fiss.quantity(), 1e-10), fissconv); + cyclus::CapacityConstraint fillc(std::max(fill.quantity(), 1e-10), fillconv); + cyclus::CapacityConstraint topupc(std::max(topup.quantity(), 1e-10), topupconv); port->AddConstraint(fillc); port->AddConstraint(fissc); port->AddConstraint(topupc); @@ -303,38 +329,61 @@ void FuelFab::GetMatlTrades( Material::Ptr> >& responses) { using cyclus::Trade; - Material::Ptr m_fiss = fiss.Peek(); - double w_fiss = CosiWeight(m_fiss->comp(), spectrum); - - Material::Ptr m_fill = fill.Peek(); - double w_fill = CosiWeight(m_fill->comp(), spectrum); - - Material::Ptr m_topup; + double w_fill = 0; + if (fill.count() > 0) { // it's possible to only need fissile inventory for a trade + CosiWeight(fill.Peek()->comp(), spectrum); + } double w_topup = 0; if (topup.count() > 0) { - m_topup = topup.Peek(); - w_topup = CosiWeight(m_topup->comp(), spectrum); + w_topup = CosiWeight(topup.Peek()->comp(), spectrum); } + double w_fiss = 0; + if (fiss.count() > 0) { + w_fiss = CosiWeight(fiss.Peek()->comp(), spectrum); + } + + std::cout << "w_fill=" << w_fill << "\n"; + std::cout << "w_fiss=" << w_fiss << "\n"; + std::cout << "w_topup=" << w_topup << "\n"; std::vector< cyclus::Trade >::const_iterator it; + double tot = 0; for (int i = 0; i < trades.size(); i++) { Material::Ptr tgt = trades[i].request->target(); double w_tgt = CosiWeight(tgt->comp(), spectrum); double qty = tgt->quantity(); + double wfiss = w_fiss; - if (ValidWeights(w_fill, w_tgt, w_fiss)) { + tot += qty; + if (tot > throughput + cyclus::eps()) { + throw cyclus::ValueError("FuelFab was matched above throughput limit"); + } + + if (fiss.count() == 0) { + // we must use filler to satisfy this request + responses.push_back(std::make_pair(trades[i], fill.Pop(qty))); + } else if (fill.count() == 0) { + // we must use fissile to satisfy this request + responses.push_back(std::make_pair(trades[i], fiss.Pop(qty))); + } else if (ValidWeights(w_fill, w_tgt, w_fiss)) { double fiss_frac = HighFrac(w_fill, w_tgt, w_fiss); double fill_frac = 1 - fiss_frac; Material::Ptr m = fiss.Pop(fiss_frac*qty); - m->Absorb(fill.Pop(fill_frac*qty)); + // this if block prevents zero qty ResBuf pop exceptions + if (fill_frac > 0) { + m->Absorb(fill.Pop(fill_frac*qty)); + } responses.push_back(std::make_pair(trades[i], m)); } else { double topup_frac = HighFrac(w_fiss, w_tgt, w_topup); double fiss_frac = 1 - topup_frac; - Material::Ptr m = topup.Pop(topup_frac*qty); - m->Absorb(fiss.Pop(fiss_frac*qty)); + Material::Ptr m = fiss.Pop(fiss_frac*qty); + // this if block prevents zero qty ResBuf pop exceptions + if (topup_frac > 0) { + m->Absorb(topup.Pop(topup_frac*qty)); + } responses.push_back(std::make_pair(trades[i], m)); } } @@ -400,17 +449,23 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { return w; } -double HighFrac(double w_low, double w_target, double w_high) { +double HighFrac(double w_low, double w_target, double w_high, double eps) { if (!ValidWeights(w_low, w_target, w_high)) { throw cyclus::ValueError("low and high weights cannot meet target"); } else if (w_low == w_high && w_target == w_low) { return 1; } - return (w_target - w_low) / (w_high - w_low); + double f = std::abs((w_target - w_low) / (w_high - w_low)); + if (1-f < eps) { + return 1; + } else if (f < eps) { + return 0; + } + return f; } -double LowFrac(double w_low, double w_target, double w_high) { - return 1 - HighFrac(w_low, w_target, w_high); +double LowFrac(double w_low, double w_target, double w_high, double eps) { + return 1 - HighFrac(w_low, w_target, w_high, eps); } // Returns true if the given weights can be used to linearly interpolate valid diff --git a/src/fuel_fab.h b/src/fuel_fab.h index 82d937e410..3e00c5a374 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -8,8 +8,8 @@ namespace cycamore { double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum); bool ValidWeights(double w_low, double w_tgt, double w_high); -double LowFrac(double w_low, double w_tgt, double w_high); -double HighFrac(double w_low, double w_tgt, double w_high); +double LowFrac(double w_low, double w_tgt, double w_high, double eps = 1e-6); +double HighFrac(double w_low, double w_tgt, double w_high, double eps = 1e-6); class FuelFab : public cyclus::Facility { public: diff --git a/src/fuel_fab_tests.cc b/src/fuel_fab_tests.cc index 2e8939f096..021da61e4e 100644 --- a/src/fuel_fab_tests.cc +++ b/src/fuel_fab_tests.cc @@ -159,35 +159,6 @@ TEST(FuelFabTests, ValidWeights) { EXPECT_EQ(false, ValidWeights(w_fill, w_fiss, w_target)); } -TEST(FuelFabTests, Template) { - std::string config = - "commod" - "recipe" - "1" - "" - " commod commod " - "1" - "" - "commod" - "recipe" - "1" - "" - "commod" - "thermal" - "1" - ; - - int simdur = 50; - cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); - //sim.AddSource("enriched_u").Finalize(); - //sim.AddRecipe("lwr_fresh", c_uox()); - //sim.AddRecipe("lwr_spent", c_spentuox()); - //int id = sim.Run(); - - //QueryResult qr = sim.db().Query("Transactions", NULL); - //EXPECT_EQ(simdur, qr.rows.size()) << "failed to order+run on fresh fuel inside 1 time step"; -} - // request (and receive) a specific recipe for fissile stream correctly. TEST(FuelFabTests, FissRecipe) { std::string config = @@ -266,19 +237,234 @@ TEST(FuelFabTests, MultipleFissStreams) { // fissile stream preferences can be specified. TEST(FuelFabTests, FissStreamPrefs) { - FAIL() << "not implemented"; + std::string config = + "dummy" + "natu" + "1" + "" + " stream1 stream2 stream3 " + " 1.0 0.0 2.0 " + "1.5" + "" + "dummyout" + "thermal" + "0" + ; + + int simdur = 1; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("stream1").recipe("spentuox").capacity(1).Finalize(); + sim.AddSource("stream2").recipe("spentuox").capacity(1).Finalize(); + sim.AddSource("stream3").recipe("spentuox").capacity(1).Finalize(); + sim.AddRecipe("spentuox", c_pustream()); + sim.AddRecipe("natu", c_natu()); + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==", std::string("stream1"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); + EXPECT_DOUBLE_EQ(0.5, m->quantity()); + + conds[0] = Cond("Commodity", "==", std::string("stream2")); + qr = sim.db().Query("Transactions", &conds); + EXPECT_EQ(0, qr.rows.size()); + + conds[0] = Cond("Commodity", "==", std::string("stream3")); + qr = sim.db().Query("Transactions", &conds); + m = sim.GetMaterial(qr.GetVal("ResourceId")); + EXPECT_DOUBLE_EQ(1.0, m->quantity()); +} + +// zero throughput must not result in a zero capacity constraint excception. +TEST(FuelFabTests, ZeroThroughput) { + std::string config = + "natu" + "natu" + "3.9" + "" + " spentuox " + "spentuox" + "3.5" + "" + "uox" + "uox" + "3.3" + "" + "dummyout" + "thermal" + "0" + ; + + int simdur = 10; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("uox").capacity(1).Finalize(); + sim.AddSource("spentuox").capacity(1).Finalize(); + sim.AddSource("natu").capacity(1).Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("spentuox", c_pustream()); + sim.AddRecipe("natu", c_natu()); + EXPECT_NO_THROW(sim.Run()); } // fill, fiss, and topup inventories are all requested for and -// filled as expected -TEST(FuelFabTests, FillInventories) { - FAIL() << "not implemented"; +// filled as expected. Inventory size constraints are properly +// enforced after they are full. +TEST(FuelFabTests, FillAllInventories) { + std::string config = + "natu" + "natu" + "3.9" + "" + " spentuox " + "spentuox" + "3.5" + "" + "uox" + "uox" + "3.3" + "" + "dummyout" + "thermal" + "1" + ; + + int simdur = 10; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("uox").capacity(1).Finalize(); + sim.AddSource("spentuox").capacity(1).Finalize(); + sim.AddSource("natu").capacity(1).Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("spentuox", c_pustream()); + sim.AddRecipe("natu", c_natu()); + int id = sim.Run(); + + cyclus::SqlStatement::Ptr stmt = sim.db().db().Prepare( + "SELECT SUM(r.Quantity) FROM Transactions AS t" + " INNER JOIN Resources AS r ON r.ResourceId = t.ResourceId" + " WHERE t.Commodity = ?;" + ); + + stmt->BindText(1, "natu"); + stmt->Step(); + EXPECT_DOUBLE_EQ(3.9, stmt->GetDouble(0)); + stmt->Reset(); + stmt->BindText(1, "spentuox"); + stmt->Step(); + EXPECT_DOUBLE_EQ(3.5, stmt->GetDouble(0)); + stmt->Reset(); + stmt->BindText(1, "uox"); + stmt->Step(); + EXPECT_DOUBLE_EQ(3.3, stmt->GetDouble(0)); +} + +// Meet a request requiring zero fill inventory when we have zero fill +// inventory quantity. +TEST(FuelFabTests, ProvideStraightFiss_WithZeroFill) { + std::string config = + "nothing" + "natu" + "100" + "" + " anything " + "spentuox" + "100" + "" + "recyclefuel" + "thermal" + "100" + ; + int simdur = 6; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("anything").Finalize(); + sim.AddSink("recyclefuel").recipe("spentuox").capacity(100).Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("spentuox", c_pustream()); + sim.AddRecipe("natu", c_natu()); + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==", std::string("recyclefuel"))); + QueryResult qr = sim.db().Query("Transactions", NULL); + // 6 = 3 receives of inventory, 3 sells of recycled fuel + EXPECT_EQ(6, qr.rows.size()); +} + +TEST(FuelFabTests, ProvideStraightFill_ZeroFiss) { + std::string config = + "anything" + "natu" + "100" + "" + " nothing " + "spentuox" + "100" + "" + "recyclefuel" + "thermal" + "100" + ; + int simdur = 6; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("anything").Finalize(); + sim.AddSink("recyclefuel").recipe("natu").capacity(100).Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("spentuox", c_pustream()); + sim.AddRecipe("natu", c_natu()); + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==", std::string("recyclefuel"))); + QueryResult qr = sim.db().Query("Transactions", NULL); + // 6 = 3 receives of inventory, 3 sells of recycled fuel + EXPECT_EQ(6, qr.rows.size()); } // throughput is properly restricted when faced with many fuel // requests and with ample material inventory. TEST(FuelFabTests, ThroughputLimit) { - FAIL() << "not implemented"; + std::string config = + "anything" + "natu" + "100" + "" + " anything " + "pustream" + "100" + "" + "recyclefuel" + "thermal" + "3" + ; + double throughput = 3; + + int simdur = 5; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("anything").lifetime(1).Finalize(); + sim.AddSink("recyclefuel").recipe("uox").capacity(2*throughput).Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("pustream", c_pustream()); + sim.AddRecipe("natu", c_natu()); + int id = sim.Run(); + + QueryResult qr = sim.db().Query("Transactions", NULL); + EXPECT_LT(2, qr.rows.size()); + + cyclus::SqlStatement::Ptr stmt = sim.db().db().Prepare( + "SELECT SUM(r.Quantity) FROM Transactions AS t" + " INNER JOIN Resources AS r ON r.ResourceId = t.ResourceId" + " WHERE t.Commodity = 'recyclefuel';" + ); + + stmt->Step(); + EXPECT_DOUBLE_EQ(throughput * (simdur-1), stmt->GetDouble(0)); + + stmt = sim.db().db().Prepare( + "SELECT COUNT(*) FROM Transactions WHERE Commodity = 'recyclefuel';" + ); + + stmt->Step(); + EXPECT_DOUBLE_EQ(simdur-1, stmt->GetDouble(0)); } // supplied fuel has proper equivalence weights as requested. From 8c33824f8dc4f65ec6a6332bc712c21ba9beb67b Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 26 Feb 2015 16:36:06 -0600 Subject: [PATCH 079/314] Two bugs fixed: * trades for fissile vs filler inventories were getting mixed up because they came from requests on the same commodity * GetTrades was using the trade's bid's target quantity instead of the matched trade.amt --- src/fuel_fab.cc | 47 ++++++++++++++++------------------------------- src/fuel_fab.h | 4 ++++ 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index 41eb0d12ac..1216c9ddee 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -5,7 +5,7 @@ using cyclus::Composition; using pyne::simple_xs; #define SHOW(X) \ - std::cout << __FILE__ << ":" << __LINE__ << ": "#X" = " << X << "\n" + std::cout << std::setprecision(17) << __FILE__ << ":" << __LINE__ << ": "#X" = " << X << "\n" namespace cycamore { @@ -27,7 +27,6 @@ class FissConverter : public cyclus::Converter { double w_tgt = CosiWeight(m->comp(), spec_); if (ValidWeights(w_fill_, w_tgt, w_fiss_)) { - std::cout << std::setprecision(17) << "fissconvert=" << HighFrac(w_fill_, w_tgt, w_fiss_) * m->quantity() << "\n"; return HighFrac(w_fill_, w_tgt, w_fiss_) * m->quantity(); } else if (ValidWeights(w_fiss_, w_tgt, w_topup_)) { // use fiss inventory as filler, and topup as fissile @@ -63,10 +62,6 @@ class FillConverter : public cyclus::Converter { double w_tgt = CosiWeight(m->comp(), spec_); if (ValidWeights(w_fill_, w_tgt, w_fiss_)) { - std::cout << std::setprecision(17) << "w_tgt = " << w_tgt << "\n"; - std::cout << std::setprecision(17) << "w_fiss = " << w_fiss_ << "\n"; - std::cout << std::setprecision(17) << "w_fill = " << w_fill_ << "\n"; - std::cout << std::setprecision(17) << "fillconvert=" << LowFrac(w_fill_, w_tgt, w_fiss_) * m->quantity() << "\n"; return LowFrac(w_fill_, w_tgt, w_fiss_) * m->quantity(); } else if (ValidWeights(w_fiss_, w_tgt, w_topup_)) { // switched fissile inventory to filler so don't need any filler inventory @@ -102,7 +97,6 @@ class TopupConverter : public cyclus::Converter { double w_tgt = CosiWeight(m->comp(), spec_); if (ValidWeights(w_fill_, w_tgt, w_fiss_)) { - std::cout << "topupconvert=0\n"; return 0; } else if (ValidWeights(w_fiss_, w_tgt, w_topup_)) { // switched fissile inventory to filler and topup as fissile @@ -158,6 +152,7 @@ FuelFab::GetMatlRequests() { std::string commod = fiss_commods[i]; double pref = fiss_commod_prefs[i]; reqs.push_back(port->AddRequest(m, this, commod, pref, exclusive)); + req_inventories_[reqs.back()] = "fiss"; } port->AddMutualReqs(reqs); ports.insert(port); @@ -171,7 +166,8 @@ FuelFab::GetMatlRequests() { Composition::Ptr c = context()->GetRecipe(fill_recipe); m = Material::CreateUntracked(fill.space(), c); } - port->AddRequest(m, this, fill_commod, fill_pref, exclusive); + cyclus::Request* r = port->AddRequest(m, this, fill_commod, fill_pref, exclusive); + req_inventories_[r] = "fill"; ports.insert(port); } @@ -183,7 +179,8 @@ FuelFab::GetMatlRequests() { Composition::Ptr c = context()->GetRecipe(topup_recipe); m = Material::CreateUntracked(topup.space(), c); } - port->AddRequest(m, this, topup_commod, topup_pref, exclusive); + cyclus::Request* r = port->AddRequest(m, this, topup_commod, topup_pref, exclusive); + req_inventories_[r] = "topup"; ports.insert(port); } @@ -209,24 +206,19 @@ void FuelFab::AcceptMatlTrades( for (trade = responses.begin(); trade != responses.end(); ++trade) { std::string commod = trade->first.request->commodity(); double req_qty = trade->first.request->target()->quantity(); + cyclus::Request* req = trade->first.request; Material::Ptr m = trade->second; - - // the checks of "m->quantity() <= [inventory].space()" are important in circumstances - // where fill_commod, topup_commod, and any of the fiss_commods may be the - // same as each other. Currently the case where topup_commod or - // fill_commod are one or both inside fiss_commods, trades for each - // inventory can get mixed up, - // TODO: handle same commod case inventory discrimination more robustly. - if (commod == fill_commod && m->quantity() <= fill.space()) { + if (req_inventories_[req] == "fill") { fill.Push(m); - } else if (commod == topup_commod && m->quantity() <= topup.space()) { + } else if (req_inventories_[req] == "topup") { topup.Push(m); - } else if (Contains(fiss_commods, commod) && m->quantity() <= fiss.space()) { + } else if (req_inventories_[req] == "fiss") { fiss.Push(m); } else { throw cyclus::ValueError("cycamore::FuelFab was overmatched on requests"); } } + req_inventories_.clear(); } std::set::Ptr> @@ -239,7 +231,6 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& return ports; } - Composition::Ptr c_fill; Composition::Ptr c_fiss; Composition::Ptr c_topup; @@ -279,7 +270,6 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& double w_tgt = CosiWeight(tgt, spectrum); double tgt_qty = req->target()->quantity(); if (ValidWeights(w_fill, w_tgt, w_fiss)) { - std::cout << "bidding with fill and fiss tgt_qty=" << tgt_qty << "\n"; double fiss_frac = HighFrac(w_fill, w_tgt, w_fiss); double fill_frac = 1 - fiss_frac; Material::Ptr m1 = Material::CreateUntracked(fiss_frac * tgt_qty, c_fiss); @@ -288,8 +278,7 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& bool exclusive = false; port->AddBid(req, m1, this, exclusive); - } else if (0 && topup.count() > 0 && ValidWeights(w_fiss, w_tgt, w_topup)) { - std::cout << "bidding with fiss and topup\n"; + } else if (topup.count() > 0 && ValidWeights(w_fiss, w_tgt, w_topup)) { // only bid with topup if we have filler - otherwise we might be able to // meet target with filler when we get it. we should only use topup // when the fissile has too poor neutronics. @@ -304,8 +293,6 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& } // else can't meet the target - don't bid } - SHOW(fill.quantity()); - SHOW(fiss.quantity()); cyclus::Converter::Ptr fissconv(new FissConverter(w_fill, w_fiss, w_topup, spectrum)); cyclus::Converter::Ptr fillconv(new FillConverter(w_fill, w_fiss, w_topup, spectrum)); cyclus::Converter::Ptr topupconv(new TopupConverter(w_fill, w_fiss, w_topup, spectrum)); @@ -342,21 +329,19 @@ void FuelFab::GetMatlTrades( w_fiss = CosiWeight(fiss.Peek()->comp(), spectrum); } - std::cout << "w_fill=" << w_fill << "\n"; - std::cout << "w_fiss=" << w_fiss << "\n"; - std::cout << "w_topup=" << w_topup << "\n"; - std::vector< cyclus::Trade >::const_iterator it; double tot = 0; for (int i = 0; i < trades.size(); i++) { Material::Ptr tgt = trades[i].request->target(); double w_tgt = CosiWeight(tgt->comp(), spectrum); - double qty = tgt->quantity(); + double qty = trades[i].amt; double wfiss = w_fiss; tot += qty; if (tot > throughput + cyclus::eps()) { - throw cyclus::ValueError("FuelFab was matched above throughput limit"); + std::stringstream ss; + ss << "FuelFab was matched above throughput limit: " << tot << " > " << throughput; + throw cyclus::ValueError(ss.str()); } if (fiss.count() == 0) { diff --git a/src/fuel_fab.h b/src/fuel_fab.h index 3e00c5a374..ca0869f687 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -98,6 +98,10 @@ class FuelFab : public cyclus::Facility { #pragma cyclus var {} double throughput; + + // intra-time-step state - no need to be a state var + // map + std::map*, std::string> req_inventories_; }; } // namespace cycamore From d0fc16a4357cd6af41c2dee579b9db493b909df2 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 2 Mar 2015 14:58:00 -0600 Subject: [PATCH 080/314] Fixed improper stream frac usage: The mixing fractions computed using the COSI weights were being used improperly. The COSI weight is an atom-based weight and so the fractions calculated from it are correspondingly atom fractions. Since Cyclus does all material mixing on a mass-basis, the fractions need to first be converted to mass-based fractions. The AtomToMassFrac function was added to do this. The constraint converters for DRE, and all places in the code that use the fractional interpolation based on weights (i.e. uses of HighFrac and LowFrac) need to also convert the ratios to mass-based. Added tests to check that this is occurring correctly. --- src/fuel_fab.cc | 114 ++++++++++++++++++++++++++++++++---------- src/fuel_fab.h | 1 + src/fuel_fab_tests.cc | 65 +++++++++++++++++++++++- 3 files changed, 152 insertions(+), 28 deletions(-) diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index 1216c9ddee..83e5753f3d 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -12,11 +12,15 @@ namespace cycamore { class FissConverter : public cyclus::Converter { public: FissConverter( - double w_fill, - double w_fiss, - double w_topup, + Composition::Ptr c_fill, + Composition::Ptr c_fiss, + Composition::Ptr c_topup, std::string spectrum - ) : w_fiss_(w_fiss), w_topup_(w_topup), w_fill_(w_fill), spec_(spectrum) {} + ) : c_fiss_(c_fiss), c_topup_(c_topup), c_fill_(c_fill), spec_(spectrum) { + w_fiss_ = CosiWeight(c_fiss, spectrum); + w_fill_ = CosiWeight(c_fill, spectrum); + w_topup_ = CosiWeight(c_topup, spectrum); + } virtual ~FissConverter() {} @@ -27,10 +31,12 @@ class FissConverter : public cyclus::Converter { double w_tgt = CosiWeight(m->comp(), spec_); if (ValidWeights(w_fill_, w_tgt, w_fiss_)) { - return HighFrac(w_fill_, w_tgt, w_fiss_) * m->quantity(); + double frac = HighFrac(w_fill_, w_tgt, w_fiss_); + return AtomToMassFrac(frac, c_fiss_, c_fill_) * m->quantity(); } else if (ValidWeights(w_fiss_, w_tgt, w_topup_)) { // use fiss inventory as filler, and topup as fissile - return LowFrac(w_fiss_, w_tgt, w_topup_) * m->quantity(); + double frac = LowFrac(w_fiss_, w_tgt, w_topup_); + return AtomToMassFrac(frac, c_fiss_, c_topup_) * m->quantity(); } else { // don't bid at all return 1e200; @@ -42,16 +48,23 @@ class FissConverter : public cyclus::Converter { double w_fiss_; double w_topup_; double w_fill_; + Composition::Ptr c_fiss_; + Composition::Ptr c_fill_; + Composition::Ptr c_topup_; }; class FillConverter : public cyclus::Converter { public: FillConverter( - double w_fill, - double w_fiss, - double w_topup, + Composition::Ptr c_fill, + Composition::Ptr c_fiss, + Composition::Ptr c_topup, std::string spectrum - ) : w_fiss_(w_fiss), w_topup_(w_topup), w_fill_(w_fill), spec_(spectrum) {} + ) : c_fiss_(c_fiss), c_topup_(c_topup), c_fill_(c_fill), spec_(spectrum) { + w_fiss_ = CosiWeight(c_fiss, spectrum); + w_fill_ = CosiWeight(c_fill, spectrum); + w_topup_ = CosiWeight(c_topup, spectrum); + } virtual ~FillConverter() {} @@ -62,7 +75,8 @@ class FillConverter : public cyclus::Converter { double w_tgt = CosiWeight(m->comp(), spec_); if (ValidWeights(w_fill_, w_tgt, w_fiss_)) { - return LowFrac(w_fill_, w_tgt, w_fiss_) * m->quantity(); + double frac = LowFrac(w_fill_, w_tgt, w_fiss_); + return AtomToMassFrac(frac, c_fill_, c_fiss_) * m->quantity(); } else if (ValidWeights(w_fiss_, w_tgt, w_topup_)) { // switched fissile inventory to filler so don't need any filler inventory return 0; @@ -77,16 +91,23 @@ class FillConverter : public cyclus::Converter { double w_fiss_; double w_topup_; double w_fill_; + Composition::Ptr c_fiss_; + Composition::Ptr c_fill_; + Composition::Ptr c_topup_; }; class TopupConverter : public cyclus::Converter { public: TopupConverter( - double w_fill, - double w_fiss, - double w_topup, + Composition::Ptr c_fill, + Composition::Ptr c_fiss, + Composition::Ptr c_topup, std::string spectrum - ) : w_fiss_(w_fiss), w_topup_(w_topup), w_fill_(w_fill), spec_(spectrum) {} + ) : c_fiss_(c_fiss), c_topup_(c_topup), c_fill_(c_fill), spec_(spectrum) { + w_fiss_ = CosiWeight(c_fiss, spectrum); + w_fill_ = CosiWeight(c_fill, spectrum); + w_topup_ = CosiWeight(c_topup, spectrum); + } virtual ~TopupConverter() {} @@ -100,7 +121,8 @@ class TopupConverter : public cyclus::Converter { return 0; } else if (ValidWeights(w_fiss_, w_tgt, w_topup_)) { // switched fissile inventory to filler and topup as fissile - return HighFrac(w_fiss_, w_tgt, w_topup_) * m->quantity(); + double frac = HighFrac(w_fiss_, w_tgt, w_topup_); + return AtomToMassFrac(frac, c_topup_, c_fiss_) * m->quantity(); } else { // don't bid at all return 1e200; @@ -112,6 +134,9 @@ class TopupConverter : public cyclus::Converter { double w_fiss_; double w_topup_; double w_fill_; + Composition::Ptr c_fiss_; + Composition::Ptr c_fill_; + Composition::Ptr c_topup_; }; FuelFab::FuelFab(cyclus::Context* ctx) @@ -231,18 +256,18 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& return ports; } - Composition::Ptr c_fill; - Composition::Ptr c_fiss; - Composition::Ptr c_topup; double w_fill = 0; - double w_topup = 0; + Composition::Ptr c_fill; // no default needed - this is non-optional parameter if (fill.count() > 0) { c_fill = fill.Peek()->comp(); w_fill = CosiWeight(c_fill, spectrum); - } else if (!fill_recipe.empty()) { + } else { c_fill = context()->GetRecipe(fill_recipe); w_fill = CosiWeight(c_fill, spectrum); } + + double w_topup = 0; + Composition::Ptr c_topup = c_fill; if (topup.count() > 0) { c_topup = topup.Peek()->comp(); w_topup = CosiWeight(c_topup, spectrum); @@ -252,6 +277,7 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& } double w_fiss = w_fill; // this allows trading just fill with no fiss inventory + Composition::Ptr c_fiss = c_fill; if (fiss.count() > 0) { c_fiss = fiss.Peek()->comp(); w_fiss = CosiWeight(c_fiss, spectrum); @@ -272,6 +298,8 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& if (ValidWeights(w_fill, w_tgt, w_fiss)) { double fiss_frac = HighFrac(w_fill, w_tgt, w_fiss); double fill_frac = 1 - fiss_frac; + fiss_frac = AtomToMassFrac(fiss_frac, c_fiss, c_fill); + fill_frac = AtomToMassFrac(fill_frac, c_fill, c_fiss); Material::Ptr m1 = Material::CreateUntracked(fiss_frac * tgt_qty, c_fiss); Material::Ptr m2 = Material::CreateUntracked(fill_frac * tgt_qty, c_fill); m1->Absorb(m2); @@ -284,6 +312,8 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& // when the fissile has too poor neutronics. double topup_frac = HighFrac(w_fiss, w_tgt, w_topup); double fiss_frac = 1 - topup_frac; + fiss_frac = AtomToMassFrac(fiss_frac, c_fiss, c_topup); + topup_frac = AtomToMassFrac(topup_frac, c_topup, c_fiss); Material::Ptr m1 = Material::CreateUntracked(topup_frac * tgt_qty, c_topup); Material::Ptr m2 = Material::CreateUntracked(fiss_frac * tgt_qty, c_fiss); m1->Absorb(m2); @@ -293,9 +323,9 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& } // else can't meet the target - don't bid } - cyclus::Converter::Ptr fissconv(new FissConverter(w_fill, w_fiss, w_topup, spectrum)); - cyclus::Converter::Ptr fillconv(new FillConverter(w_fill, w_fiss, w_topup, spectrum)); - cyclus::Converter::Ptr topupconv(new TopupConverter(w_fill, w_fiss, w_topup, spectrum)); + cyclus::Converter::Ptr fissconv(new FissConverter(c_fill, c_fiss, c_topup, spectrum)); + cyclus::Converter::Ptr fillconv(new FillConverter(c_fill, c_fiss, c_topup, spectrum)); + cyclus::Converter::Ptr topupconv(new TopupConverter(c_fill, c_fiss, c_topup, spectrum)); // important! - the std::max calls prevent CapacityConstraint throwing a zero cap exception cyclus::CapacityConstraint fissc(std::max(fiss.quantity(), 1e-10), fissconv); cyclus::CapacityConstraint fillc(std::max(fill.quantity(), 1e-10), fillconv); @@ -318,7 +348,7 @@ void FuelFab::GetMatlTrades( double w_fill = 0; if (fill.count() > 0) { // it's possible to only need fissile inventory for a trade - CosiWeight(fill.Peek()->comp(), spectrum); + w_fill = CosiWeight(fill.Peek()->comp(), spectrum); } double w_topup = 0; if (topup.count() > 0) { @@ -352,7 +382,9 @@ void FuelFab::GetMatlTrades( responses.push_back(std::make_pair(trades[i], fiss.Pop(qty))); } else if (ValidWeights(w_fill, w_tgt, w_fiss)) { double fiss_frac = HighFrac(w_fill, w_tgt, w_fiss); - double fill_frac = 1 - fiss_frac; + double fill_frac = LowFrac(w_fill, w_tgt, w_fiss); + fiss_frac = AtomToMassFrac(fiss_frac, fiss.Peek()->comp(), fill.Peek()->comp()); + fill_frac = AtomToMassFrac(fill_frac, fill.Peek()->comp(), fiss.Peek()->comp()); Material::Ptr m = fiss.Pop(fiss_frac*qty); // this if block prevents zero qty ResBuf pop exceptions @@ -363,6 +395,8 @@ void FuelFab::GetMatlTrades( } else { double topup_frac = HighFrac(w_fiss, w_tgt, w_topup); double fiss_frac = 1 - topup_frac; + topup_frac = AtomToMassFrac(topup_frac, topup.Peek()->comp(), fiss.Peek()->comp()); + fiss_frac = AtomToMassFrac(fiss_frac, fiss.Peek()->comp(), topup.Peek()->comp()); Material::Ptr m = fiss.Pop(fiss_frac*qty); // this if block prevents zero qty ResBuf pop exceptions @@ -387,7 +421,10 @@ extern "C" cyclus::Agent* ConstructFuelFab(cyclus::Context* ctx) { // * resonance_integral // * fourteen_MeV // -// The weight is calculated as "(nu*sigma_f - sigma_a) * N". +// The weight is calculated as "(nu*sigma_f - sigma_a) * N". Since weights +// are computed based on nuclide atom fractions, corresponding computed +// material/mixing fractions will also be atom-based naturally and will need +// to be converted to mass-based for actual material object mixing. double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { cyclus::CompMap cm = c->atom(); cyclus::compmath::Normalize(&cm); @@ -434,6 +471,29 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { return w; } +// Convert an atom frac (n1/(n1+n2) to a mass frac (m1/(m1+m2) given +// corresponding compositions c1 and c2. +double AtomToMassFrac(double atomfrac, Composition::Ptr c1, Composition::Ptr c2) { + cyclus::CompMap n1 = c1->atom(); + cyclus::CompMap n2 = c2->atom(); + cyclus::compmath::Normalize(&n1, atomfrac); + cyclus::compmath::Normalize(&n2, 1-atomfrac); + + cyclus::CompMap::iterator it; + + double mass1 = 0; + for (it = n1.begin(); it != n1.end(); ++it) { + mass1 += it->second * pyne::atomic_mass(it->first); + } + + double mass2 = 0; + for (it = n2.begin(); it != n2.end(); ++it) { + mass2 += it->second * pyne::atomic_mass(it->first); + } + + return mass1 / (mass1 + mass2); +} + double HighFrac(double w_low, double w_target, double w_high, double eps) { if (!ValidWeights(w_low, w_target, w_high)) { throw cyclus::ValueError("low and high weights cannot meet target"); diff --git a/src/fuel_fab.h b/src/fuel_fab.h index ca0869f687..74a6ce5e19 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -10,6 +10,7 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum); bool ValidWeights(double w_low, double w_tgt, double w_high); double LowFrac(double w_low, double w_tgt, double w_high, double eps = 1e-6); double HighFrac(double w_low, double w_tgt, double w_high, double eps = 1e-6); +double AtomToMassFrac(double atomfrac, cyclus::Composition::Ptr c1, cyclus::Composition::Ptr c2); class FuelFab : public cyclus::Facility { public: diff --git a/src/fuel_fab_tests.cc b/src/fuel_fab_tests.cc index 021da61e4e..6654348f6e 100644 --- a/src/fuel_fab_tests.cc +++ b/src/fuel_fab_tests.cc @@ -120,6 +120,25 @@ TEST(FuelFabTests, CosiWeight) { EXPECT_GT(w_therm, w_fast); } +TEST(FuelFabTests, CosiWeight_Mixed) { + double w_fill = CosiWeight(c_natu(), "thermal"); + double w_fiss = CosiWeight(c_pustream(), "thermal"); + double w_target = CosiWeight(c_uox(), "thermal"); + + double fiss_frac = HighFrac(w_fill, w_target, w_fiss); + double fill_frac = LowFrac(w_fill, w_target, w_fiss); + + // correct frac's from atom-based into mass-based for mixing + fiss_frac = AtomToMassFrac(fiss_frac, c_pustream(), c_natu()); + fill_frac = AtomToMassFrac(fill_frac, c_natu(), c_pustream()); + + Material::Ptr m1 = Material::CreateUntracked(fiss_frac, c_pustream()); + Material::Ptr m2 = Material::CreateUntracked(fill_frac, c_natu()); + m1->Absorb(m2); + double got = CosiWeight(m1->comp(), "thermal"); + EXPECT_LT(std::abs((w_target-got)/w_target), 0.00001) << "mixed composition not within 0.001% of target"; +} + TEST(FuelFabTests, HighFrac) { double w_fill = CosiWeight(c_natu(), "thermal"); double w_fiss = CosiWeight(c_pustream(), "thermal"); @@ -469,7 +488,51 @@ TEST(FuelFabTests, ThroughputLimit) { // supplied fuel has proper equivalence weights as requested. TEST(FuelFabTests, CorrectMixing) { - FAIL() << "not implemented"; + std::string config = + "natu" + "natu" + "100" + "" + " pustream " + "pustream" + "100" + "" + "recyclefuel" + "thermal" + "100" + ; + int simdur = 3; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("pustream").Finalize(); + sim.AddSource("natu").Finalize(); + sim.AddSink("recyclefuel").recipe("uox").capacity(10).lifetime(2).Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("pustream", c_pustream()); + sim.AddRecipe("natu", c_natu()); + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==", std::string("recyclefuel"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + EXPECT_EQ(1, qr.rows.size()); + + Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); + double got = CosiWeight(m->comp(), "thermal"); + double w_target = CosiWeight(c_uox(), "thermal"); + EXPECT_LT(std::abs((w_target-got)/w_target), 0.00001) << "mixed composition not within 0.001% of target"; + + conds.push_back(Cond("Time", "==", 2)); + + // TODO: do hand calcs to verify expected vals below - they are just regression values currently. + conds[0] = Cond("Commodity", "==", std::string("natu")); + qr = sim.db().Query("Transactions", &conds); + m = sim.GetMaterial(qr.GetVal("ResourceId")); + EXPECT_NEAR(9.7457947, m->quantity(), 1e-6) << "mixed wrong amount of Nat. U stream"; + + conds[0] = Cond("Commodity", "==", std::string("pustream")); + qr = sim.db().Query("Transactions", &conds); + m = sim.GetMaterial(qr.GetVal("ResourceId")); + EXPECT_NEAR(0.2542052, m->quantity(), 1e-6) << "mixed wrong amount of Pu stream"; } // fuel is requested requiring more filler than is available with plenty of From 427dd1aec1003086794f6bfd899e2dce8a748387 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 2 Mar 2015 16:28:19 -0600 Subject: [PATCH 081/314] constrained by fiss and fill inv tests --- src/fuel_fab_tests.cc | 82 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/src/fuel_fab_tests.cc b/src/fuel_fab_tests.cc index 6654348f6e..a548b8c1a9 100644 --- a/src/fuel_fab_tests.cc +++ b/src/fuel_fab_tests.cc @@ -538,13 +538,91 @@ TEST(FuelFabTests, CorrectMixing) { // fuel is requested requiring more filler than is available with plenty of // fissile. TEST(FuelFabTests, FillConstrained) { - FAIL() << "not implemented"; + std::string config = + "natu" + "natu" + "1" + "" + " pustream " + "pustream" + "10000" + "" + "recyclefuel" + "thermal" + "10000" + ; + double fillinv = 1; + int simdur = 2; + + double w_fill = CosiWeight(c_natu(), "thermal"); + double w_fiss = CosiWeight(c_pustream(), "thermal"); + double w_target = CosiWeight(c_uox(), "thermal"); + double fiss_frac = HighFrac(w_fill, w_target, w_fiss); + double fill_frac = LowFrac(w_fill, w_target, w_fiss); + fiss_frac = AtomToMassFrac(fiss_frac, c_pustream(), c_natu()); + fill_frac = AtomToMassFrac(fill_frac, c_natu(), c_pustream()); + double max_provide = fillinv / fill_frac; + + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("pustream").lifetime(1).Finalize(); + sim.AddSource("natu").lifetime(1).Finalize(); + sim.AddSink("recyclefuel").recipe("uox").capacity(2 * max_provide).Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("pustream", c_pustream()); + sim.AddRecipe("natu", c_natu()); + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==", std::string("recyclefuel"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); + + EXPECT_NEAR(max_provide, m->quantity(), 1e-10) << "matched trades require more fill than available"; } // fuel is requested requiring more fissile material than is available with // plenty of filler. TEST(FuelFabTests, FissConstrained) { - FAIL() << "not implemented"; + std::string config = + "natu" + "natu" + "10000" + "" + " pustream " + "pustream" + "1" + "" + "recyclefuel" + "thermal" + "10000" + ; + double fissinv = 1; + int simdur = 2; + + double w_fill = CosiWeight(c_natu(), "thermal"); + double w_fiss = CosiWeight(c_pustream(), "thermal"); + double w_target = CosiWeight(c_uox(), "thermal"); + double fiss_frac = HighFrac(w_fill, w_target, w_fiss); + double fill_frac = LowFrac(w_fill, w_target, w_fiss); + fiss_frac = AtomToMassFrac(fiss_frac, c_pustream(), c_natu()); + fill_frac = AtomToMassFrac(fill_frac, c_natu(), c_pustream()); + double max_provide = fissinv / fiss_frac; + + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("pustream").lifetime(1).Finalize(); + sim.AddSource("natu").lifetime(1).Finalize(); + sim.AddSink("recyclefuel").recipe("uox").capacity(2 * max_provide).Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("pustream", c_pustream()); + sim.AddRecipe("natu", c_natu()); + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==", std::string("recyclefuel"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); + + EXPECT_NEAR(max_provide, m->quantity(), 1e-10) << "matched trades require more fill than available"; } // swap to topup inventory because fissile has too low reactivity. From 87a878e2eaa1ed01ca30898a1d89167b01fc114b Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 2 Mar 2015 17:19:03 -0600 Subject: [PATCH 082/314] implement last tests and fix bug where when switching to topup with empty fill inventory, straight fiss was used --- src/fuel_fab.cc | 6 +- src/fuel_fab_tests.cc | 213 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 207 insertions(+), 12 deletions(-) diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index 83e5753f3d..01c49e5534 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -375,10 +375,10 @@ void FuelFab::GetMatlTrades( } if (fiss.count() == 0) { - // we must use filler to satisfy this request + // use straight filler to satisfy this request responses.push_back(std::make_pair(trades[i], fill.Pop(qty))); - } else if (fill.count() == 0) { - // we must use fissile to satisfy this request + } else if (fill.count() == 0 && ValidWeights(w_fill, w_tgt, w_fiss)) { + // use straight fissile to satisfy this request responses.push_back(std::make_pair(trades[i], fiss.Pop(qty))); } else if (ValidWeights(w_fill, w_tgt, w_fiss)) { double fiss_frac = HighFrac(w_fill, w_tgt, w_fiss); diff --git a/src/fuel_fab_tests.cc b/src/fuel_fab_tests.cc index a548b8c1a9..f5f54af61b 100644 --- a/src/fuel_fab_tests.cc +++ b/src/fuel_fab_tests.cc @@ -56,7 +56,7 @@ Composition::Ptr c_pustreamlow() { Composition::Ptr c_pustreambad() { CompMap m; - m[id("pu239")] = 10; + m[id("pu239")] = 1; m[id("pu240")] = 10; m[id("pu241")] = 1; m[id("pu242")] = 1; @@ -577,7 +577,7 @@ TEST(FuelFabTests, FillConstrained) { QueryResult qr = sim.db().Query("Transactions", &conds); Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); - EXPECT_NEAR(max_provide, m->quantity(), 1e-10) << "matched trades require more fill than available"; + EXPECT_NEAR(max_provide, m->quantity(), 1e-10) << "matched trade uses more fill than available"; } // fuel is requested requiring more fissile material than is available with @@ -622,23 +622,218 @@ TEST(FuelFabTests, FissConstrained) { QueryResult qr = sim.db().Query("Transactions", &conds); Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); - EXPECT_NEAR(max_provide, m->quantity(), 1e-10) << "matched trades require more fill than available"; + EXPECT_NEAR(max_provide, m->quantity(), 1e-10) << "matched trade uses more fill than available"; } // swap to topup inventory because fissile has too low reactivity. TEST(FuelFabTests, SwapTopup) { - FAIL() << "not implemented"; + std::string config = + "natu" + "natu" + "10000" + "" + " pustreambad " + "pustreambad" + "10000" + "" + "pustream" + "pustream" + "10000" + "" + "recyclefuel" + "thermal" + "10000" + ; + int simdur = 3; + double sink_cap = 10; + + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("pustream").Finalize(); + sim.AddSource("pustreambad").Finalize(); + sim.AddSource("natu").Finalize(); + sim.AddSink("recyclefuel").recipe("uox").capacity(sink_cap).lifetime(2).Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("pustream", c_pustream()); + sim.AddRecipe("pustreambad", c_pustreambad()); + sim.AddRecipe("natu", c_natu()); + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==", std::string("recyclefuel"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + ASSERT_EQ(1, qr.rows.size()) << "failed to meet fuel request"; + Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); + EXPECT_NEAR(sink_cap, m->quantity(), 1e-10) << "supplied fuel was constrained too much"; + + conds[0] = Cond("Commodity", "==", std::string("natu")); + conds.push_back(Cond("Time", "==", 2)); + qr = sim.db().Query("Transactions", &conds); + ASSERT_EQ(0, qr.rows.size()) << "failed to swith to topup - used fill - uh oh"; + + conds[0] = Cond("Commodity", "==", std::string("pustream")); + conds.push_back(Cond("Time", "==", 2)); + qr = sim.db().Query("Transactions", &conds); + ASSERT_EQ(1, qr.rows.size()) << "didn't get more topup after supposedly using it - why?"; } -// swap to topup inventory but are limited by topup inventory quantity. +TEST(FuelFabTests, SwapTopup_ZeroFill) { + std::string config = + "natu" + "natu" + "0" + "" + " pustreambad " + "pustreambad" + "10000" + "" + "pustream" + "pustream" + "10000" + "" + "recyclefuel" + "thermal" + "10000" + ; + int simdur = 3; + double sink_cap = 10; + + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("pustream").Finalize(); + sim.AddSource("pustreambad").Finalize(); + sim.AddSource("natu").Finalize(); + sim.AddSink("recyclefuel").recipe("uox").capacity(sink_cap).lifetime(2).Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("pustream", c_pustream()); + sim.AddRecipe("pustreambad", c_pustreambad()); + sim.AddRecipe("natu", c_natu()); + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==", std::string("recyclefuel"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + ASSERT_EQ(1, qr.rows.size()) << "failed to meet fuel request"; + Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); + EXPECT_NEAR(sink_cap, m->quantity(), 1e-10) << "supplied fuel was constrained too much"; + + conds[0] = Cond("Commodity", "==", std::string("pustream")); + conds.push_back(Cond("Time", "==", 2)); + qr = sim.db().Query("Transactions", &conds); + ASSERT_EQ(1, qr.rows.size()) << "failed to use topup - why?"; + + conds[0] = Cond("Commodity", "==", std::string("pustreambad")); + conds.push_back(Cond("Time", "==", 2)); + qr = sim.db().Query("Transactions", &conds); + ASSERT_EQ(1, qr.rows.size()) << "failed to use fiss - why?"; +} + +// swap to topup inventory but are limited by topup inventory quantity. This +// test makes sure the provided fuel is much less than requested due to a +// small topup inventory despite a surplus of fill that can't be used due to +// the fiss stream not having a high enough weight (so we must use topup with +// fiss). TEST(FuelFabTests, SwapTopup_TopupConstrained) { - FAIL() << "not implemented"; + std::string config = + "natu" + "natu" + "10000" + "" + " pustreambad " + "pustreambad" + "10000" + "" + "pustream" + "pustream" + "1" + "" + "recyclefuel" + "thermal" + "10000" + ; + double topupinv = 1; + int simdur = 2; + + // compute max fuel mass providable in a single time step + double w_fiss = CosiWeight(c_pustreambad(), "thermal"); + double w_topup = CosiWeight(c_pustream(), "thermal"); + double w_target = CosiWeight(c_uox(), "thermal"); + double topup_frac = HighFrac(w_fiss, w_target, w_topup); + double fiss_frac = LowFrac(w_fiss, w_target, w_topup); + fiss_frac = AtomToMassFrac(fiss_frac, c_pustreambad(), c_pustream()); + topup_frac = AtomToMassFrac(topup_frac, c_pustream(), c_pustreambad()); + double max_provide = topupinv / topup_frac; + + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("pustream").Finalize(); + sim.AddSource("pustreambad").Finalize(); + sim.AddSource("natu").Finalize(); + sim.AddSink("recyclefuel").recipe("uox").capacity(2 * max_provide).Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("pustream", c_pustream()); + sim.AddRecipe("pustreambad", c_pustreambad()); + sim.AddRecipe("natu", c_natu()); + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==", std::string("recyclefuel"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + ASSERT_EQ(1, qr.rows.size()) << "failed to meet fuel request"; + Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); + + EXPECT_NEAR(max_provide, m->quantity(), 1e-10) << "matched trade uses more fiss than available"; } -// swap to topup inventory but are limited by fissile (used as filler) -// inventory. +// swap to topup inventory but are limited by fiss inventory quantity. This +// test makes sure the provided fuel is much less than requested due to a +// small fiss inventory. TEST(FuelFabTests, SwapTopup_FissConstrained) { - FAIL() << "not implemented"; + std::string config = + "natu" + "natu" + "0" + "" + " pustreambad " + "pustreambad" + "1" + "" + "pustream" + "pustream" + "10000" + "" + "recyclefuel" + "thermal" + "10000" + ; + double fissinv = 1; + int simdur = 2; + + // compute max fuel mass providable in a single time step + double w_fiss = CosiWeight(c_pustreambad(), "thermal"); + double w_topup = CosiWeight(c_pustream(), "thermal"); + double w_target = CosiWeight(c_uox(), "thermal"); + double topup_frac = HighFrac(w_fiss, w_target, w_topup); + double fiss_frac = LowFrac(w_fiss, w_target, w_topup); + fiss_frac = AtomToMassFrac(fiss_frac, c_pustreambad(), c_pustream()); + topup_frac = AtomToMassFrac(topup_frac, c_pustream(), c_pustreambad()); + double max_provide = fissinv / fiss_frac; + + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("pustream").Finalize(); + sim.AddSource("pustreambad").Finalize(); + sim.AddSource("natu").Finalize(); + sim.AddSink("recyclefuel").recipe("uox").capacity(2 * max_provide).Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("pustream", c_pustream()); + sim.AddRecipe("pustreambad", c_pustreambad()); + sim.AddRecipe("natu", c_natu()); + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==", std::string("recyclefuel"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + ASSERT_EQ(1, qr.rows.size()) << "failed to meet fuel request"; + Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); + + EXPECT_NEAR(max_provide, m->quantity(), 1e-10) << "matched trade uses more fiss than available"; } } // namespace cycamore From 6d7161f0fde5cf20bdf7d7133fc805ab5f08a184 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Tue, 3 Mar 2015 12:24:21 -0600 Subject: [PATCH 083/314] added state var docs and class level documentation --- src/fuel_fab.h | 164 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 142 insertions(+), 22 deletions(-) diff --git a/src/fuel_fab.h b/src/fuel_fab.h index 74a6ce5e19..659f5e2ec5 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -6,13 +6,93 @@ namespace cycamore { -double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum); -bool ValidWeights(double w_low, double w_tgt, double w_high); -double LowFrac(double w_low, double w_tgt, double w_high, double eps = 1e-6); -double HighFrac(double w_low, double w_tgt, double w_high, double eps = 1e-6); -double AtomToMassFrac(double atomfrac, cyclus::Composition::Ptr c1, cyclus::Composition::Ptr c2); - +/// FuelFab takes in 2 streams of material and mixes them in ratios in order to +/// supply material that matches some neutronics properties of reqeusted +/// material. It uses an equivalence type method (TODO: cite equivalence +/// method) inspired by a similar approach in the COSI fuel cycle simulator. +/// +/// The FuelFab has 3 input inventories: fissile stream, filler stream, and an +/// optional top-up inventory. All materials received into each inventory are +/// always combined into a single material (i.e. a single fissile material, a +/// single filler material, etc.). The input streams and requested fuel +/// composition are each assigned weights based on summing: +/// +/// N * (p_i - p_U238) / (p_Pu239 - p_U238) +/// +/// for each nuclide where: +/// +/// +/// - p = nu*sigma_f - sigma_a for the nuclide +/// - p_U238 is p for pure U238 +/// - p_Pu239 is p for pure Pu239 +/// - N is the nuclide's atom fraction +/// - nu is the average # neutrons per fission +/// - sigma_f is the microscopic fission cross-section +/// - sigma_a is the microscopic neutron absorption cross-section +/// +/// The cross sections are from the simple cross section library in PyNE. They +/// can be set to either a thermal or fast neutron spectrum. A linear +/// interpolation is performed using the weights of the fissile, filler, and +/// target streams. The interpolation is used to compute a mixing ratio of the +/// input streams that matches the target weight. In the event that the target +/// weight is higher than the fissile stream weight, the FuelFab will attempt +/// to use the top-up and fissile input streams together instead of the fissile +/// and filler streams. All supplied material will always have the same weight +/// as the requested material. +/// +/// The supplying of mixed material is constrained by available inventory +/// quantities and a per time step throughput limit. Requests for fuel +/// material larger than the throughput can never be met. Fissile inventory +/// can be requested/received via one or more commodities. The DRE request +/// preference for each of these commodities can also optionally be specified. +/// By default, the top-up inventory size is zero, and it is not used for +/// mixing. class FuelFab : public cyclus::Facility { +#pragma cyclus note { \ +"doc": \ + "FuelFab takes in 2 streams of material and mixes them in ratios in order to" \ + "supply material that matches some neutronics properties of reqeusted" \ + "material. It uses an equivalence type method (TODO: cite equivalence" \ + "method) inspired by a similar approach in the COSI fuel cycle simulator." \ + "\n\n" \ + "The FuelFab has 3 input inventories: fissile stream, filler stream, and an" \ + "optional top-up inventory. All materials received into each inventory are" \ + "always combined into a single material (i.e. a single fissile material, a" \ + "single filler material, etc.). The input streams and requested fuel" \ + "composition are each assigned weights based on summing:" \ + "\n\n" \ + " N * (p_i - p_U238) / (p_Pu239 - p_U238)" \ + "\n\n" \ + "for each nuclide where:" \ + "\n\n" \ + "\n\n" \ + " - p = nu*sigma_f - sigma_a for the nuclide" \ + " - p_U238 is p for pure U238" \ + " - p_Pu239 is p for pure Pu239" \ + " - N is the nuclide's atom fraction" \ + " - nu is the average # neutrons per fission" \ + " - sigma_f is the microscopic fission cross-section" \ + " - sigma_a is the microscopic neutron absorption cross-section" \ + "\n\n" \ + "The cross sections are from the simple cross section library in PyNE. They" \ + "can be set to either a thermal or fast neutron spectrum. A linear" \ + "interpolation is performed using the weights of the fissile, filler, and" \ + "target streams. The interpolation is used to compute a mixing ratio of the" \ + "input streams that matches the target weight. In the event that the target" \ + "weight is higher than the fissile stream weight, the FuelFab will attempt" \ + "to use the top-up and fissile input streams together instead of the fissile" \ + "and filler streams. All supplied material will always have the same weight" \ + "as the requested material." \ + "\n\n" \ + "The supplying of mixed material is constrained by available inventory" \ + "quantities and a per time step throughput limit. Requests for fuel" \ + "material larger than the throughput can never be met. Fissile inventory" \ + "can be requested/received via one or more commodities. The DRE request" \ + "preference for each of these commodities can also optionally be specified." \ + "By default, the top-up inventory size is zero, and it is not used for" \ + "mixing. " \ + "", \ +} public: FuelFab(cyclus::Context* ctx); virtual ~FuelFab() {}; @@ -39,65 +119,99 @@ class FuelFab : public cyclus::Facility { virtual std::set::Ptr> GetMatlRequests(); private: - #pragma cyclus var {} + #pragma cyclus var { \ + "doc": "Commodity on which to request material for filler stream.", \ + "uitype": "incommodity", \ + } std::string fill_commod; - #pragma cyclus var {} + #pragma cyclus var { \ + "doc": "Name of recipe to be used in filler material stream requests.", \ + "uitype": "recipe", \ + } std::string fill_recipe; #pragma cyclus var { \ + "doc": "Filler material stream request preference.", \ "default": 0, \ } double fill_pref; - #pragma cyclus var {} + #pragma cyclus var { \ + "doc": "Size of filler material stream inventory.", \ + "units": "kg", \ + } double fill_size; - #pragma cyclus var {'capacity': 'fill_size'} + #pragma cyclus var {"capacity": "fill_size"} cyclus::toolkit::ResBuf fill; - #pragma cyclus var {} + #pragma cyclus var { \ + "doc": "Ordered list of commodities on which to requesting fissile stream material.", \ + "uitype": ["oneormore", "incommodity"], \ + } std::vector fiss_commods; #pragma cyclus var { \ "default": [], \ - "doc": "If unspecified, default is to use zero for all preferences.", \ + "doc": "Fissile stream commodity request preferences for each of the given fissile commodities (same order)." \ + " If unspecified, default is to use zero for all preferences.", \ } std::vector fiss_commod_prefs; #pragma cyclus var { \ + "doc": "Name for recipe to be used in fissile stream requests." \ + " Empty string results in use of an empty dummy recipe.", \ + "uitype": "recipe", \ "default": "", \ - "doc": "If unspecified, default is to use a dummy blank recipe", \ } std::string fiss_recipe; - #pragma cyclus var {} + #pragma cyclus var { \ + "doc": "Size of fissile material stream inventory.", \ + "units": "kg", \ + } double fiss_size; - #pragma cyclus var {'capacity': 'fiss_size'} + #pragma cyclus var {"capacity": "fiss_size"} cyclus::toolkit::ResBuf fiss; #pragma cyclus var { \ - "doc": "", \ + "doc": "Commodity on which to request material for top-up stream." \ + " This MUST be set if 'topup_size > 0'.", \ "default": "", \ + "uitype": "incommodity", \ } std::string topup_commod; #pragma cyclus var { \ + "doc": "Name of recipe to be used in top-up material stream requests." \ + " This MUST be set if 'topup_size > 0'.", \ + "uitype": "recipe", \ "default": "", \ } std::string topup_recipe; #pragma cyclus var { \ + "doc": "Top-up material stream request preference.", \ "default": 0, \ } double topup_pref; #pragma cyclus var { \ + "doc": "Size of top-up material stream inventory.", \ + "units": "kg", \ "default": 0, \ } double topup_size; - #pragma cyclus var {'capacity': 'topup_size'} + #pragma cyclus var {"capacity": "topup_size"} cyclus::toolkit::ResBuf topup; - #pragma cyclus var {} - std::string outcommod; - #pragma cyclus var { \ - "doc": "'fission_spectrum_ave' for fast reactor compositions or 'thermal' for slow reactors.", \ + "doc": "The type of cross-sections to use for composition property calculation." \ + " Use 'fission_spectrum_ave' for fast reactor compositions or 'thermal' for slow reactors.", \ } std::string spectrum; - #pragma cyclus var {} + #pragma cyclus var { \ + "doc": "Commodity on which to offer/supply mixed fuel material.", \ + "uitype": "outcommodity", \ + } + std::string outcommod; + + #pragma cyclus var { \ + "doc": "Maximum number of kg of fuel material that can be supplied per time step.", \ + "units": "kg", \ + } double throughput; // intra-time-step state - no need to be a state var @@ -105,6 +219,12 @@ class FuelFab : public cyclus::Facility { std::map*, std::string> req_inventories_; }; +double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum); +bool ValidWeights(double w_low, double w_tgt, double w_high); +double LowFrac(double w_low, double w_tgt, double w_high, double eps = 1e-6); +double HighFrac(double w_low, double w_tgt, double w_high, double eps = 1e-6); +double AtomToMassFrac(double atomfrac, cyclus::Composition::Ptr c1, cyclus::Composition::Ptr c2); + } // namespace cycamore From cf932f6db35d7b3988fc26022e54102928395758 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 11 Mar 2015 12:31:33 -0500 Subject: [PATCH 084/314] fix spacing in fab note --- src/fuel_fab.h | 60 ++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/src/fuel_fab.h b/src/fuel_fab.h index 659f5e2ec5..4d016b3ecd 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -21,7 +21,6 @@ namespace cycamore { /// /// for each nuclide where: /// -/// /// - p = nu*sigma_f - sigma_a for the nuclide /// - p_U238 is p for pure U238 /// - p_Pu239 is p for pure Pu239 @@ -51,46 +50,45 @@ class FuelFab : public cyclus::Facility { #pragma cyclus note { \ "doc": \ "FuelFab takes in 2 streams of material and mixes them in ratios in order to" \ - "supply material that matches some neutronics properties of reqeusted" \ - "material. It uses an equivalence type method (TODO: cite equivalence" \ - "method) inspired by a similar approach in the COSI fuel cycle simulator." \ + " supply material that matches some neutronics properties of reqeusted" \ + " material. It uses an equivalence type method (TODO: cite equivalence" \ + " method) inspired by a similar approach in the COSI fuel cycle simulator." \ "\n\n" \ "The FuelFab has 3 input inventories: fissile stream, filler stream, and an" \ - "optional top-up inventory. All materials received into each inventory are" \ - "always combined into a single material (i.e. a single fissile material, a" \ - "single filler material, etc.). The input streams and requested fuel" \ - "composition are each assigned weights based on summing:" \ + " optional top-up inventory. All materials received into each inventory are" \ + " always combined into a single material (i.e. a single fissile material, a" \ + " single filler material, etc.). The input streams and requested fuel" \ + " composition are each assigned weights based on summing:" \ "\n\n" \ " N * (p_i - p_U238) / (p_Pu239 - p_U238)" \ "\n\n" \ "for each nuclide where:" \ - "\n\n" \ - "\n\n" \ - " - p = nu*sigma_f - sigma_a for the nuclide" \ - " - p_U238 is p for pure U238" \ - " - p_Pu239 is p for pure Pu239" \ - " - N is the nuclide's atom fraction" \ - " - nu is the average # neutrons per fission" \ - " - sigma_f is the microscopic fission cross-section" \ - " - sigma_a is the microscopic neutron absorption cross-section" \ + "\n" \ + "\n - p = nu*sigma_f - sigma_a for the nuclide" \ + "\n - p_U238 is p for pure U238" \ + "\n - p_Pu239 is p for pure Pu239" \ + "\n - N is the nuclide's atom fraction" \ + "\n - nu is the average # neutrons per fission" \ + "\n - sigma_f is the microscopic fission cross-section" \ + "\n - sigma_a is the microscopic neutron absorption cross-section" \ "\n\n" \ "The cross sections are from the simple cross section library in PyNE. They" \ - "can be set to either a thermal or fast neutron spectrum. A linear" \ - "interpolation is performed using the weights of the fissile, filler, and" \ - "target streams. The interpolation is used to compute a mixing ratio of the" \ - "input streams that matches the target weight. In the event that the target" \ - "weight is higher than the fissile stream weight, the FuelFab will attempt" \ - "to use the top-up and fissile input streams together instead of the fissile" \ - "and filler streams. All supplied material will always have the same weight" \ - "as the requested material." \ + " can be set to either a thermal or fast neutron spectrum. A linear" \ + " interpolation is performed using the weights of the fissile, filler, and" \ + " target streams. The interpolation is used to compute a mixing ratio of the" \ + " input streams that matches the target weight. In the event that the target" \ + " weight is higher than the fissile stream weight, the FuelFab will attempt" \ + " to use the top-up and fissile input streams together instead of the fissile" \ + " and filler streams. All supplied material will always have the same weight" \ + " as the requested material." \ "\n\n" \ "The supplying of mixed material is constrained by available inventory" \ - "quantities and a per time step throughput limit. Requests for fuel" \ - "material larger than the throughput can never be met. Fissile inventory" \ - "can be requested/received via one or more commodities. The DRE request" \ - "preference for each of these commodities can also optionally be specified." \ - "By default, the top-up inventory size is zero, and it is not used for" \ - "mixing. " \ + " quantities and a per time step throughput limit. Requests for fuel" \ + " material larger than the throughput can never be met. Fissile inventory" \ + " can be requested/received via one or more commodities. The DRE request" \ + " preference for each of these commodities can also optionally be specified." \ + " By default, the top-up inventory size is zero, and it is not used for" \ + " mixing. " \ "", \ } public: From 8f4446e99c26ec9ccec02c8c6c84872a9efe86e6 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 30 Mar 2015 12:01:25 -0500 Subject: [PATCH 085/314] add namespace to fab tests --- src/fuel_fab_tests.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fuel_fab_tests.cc b/src/fuel_fab_tests.cc index f5f54af61b..2d2a5fa2dc 100644 --- a/src/fuel_fab_tests.cc +++ b/src/fuel_fab_tests.cc @@ -13,6 +13,7 @@ using cyclus::Cond; using cyclus::toolkit::MatQuery; namespace cycamore { +namespace fuelfabtests { Composition::Ptr c_uox() { CompMap m; @@ -836,5 +837,6 @@ TEST(FuelFabTests, SwapTopup_FissConstrained) { EXPECT_NEAR(max_provide, m->quantity(), 1e-10) << "matched trade uses more fiss than available"; } +} // namespace fuelfabtests } // namespace cycamore From aa913391dd62d46b1085bfb7a374763a8741e910 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Tue, 31 Mar 2015 17:45:25 -0500 Subject: [PATCH 086/314] speed up cosiweight function using fast-paths and cacheing of cross sections --- src/fuel_fab.cc | 164 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 133 insertions(+), 31 deletions(-) diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index 01c49e5534..c25e3fe9a3 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -252,8 +252,12 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& using cyclus::BidPortfolio; std::set::Ptr> ports; + std::vector*>& reqs = commod_requests[outcommod]; + if (throughput == 0) { return ports; + } else if (reqs.size() == 0) { + return ports; } double w_fill = 0; @@ -286,8 +290,6 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& w_fiss = CosiWeight(c_fiss, spectrum); } - std::vector*>& reqs = commod_requests[outcommod]; - BidPortfolio::Ptr port(new BidPortfolio()); for (int j = 0; j < reqs.size(); j++) { cyclus::Request* req = reqs[j]; @@ -432,43 +434,143 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { double nu_pu239 = 2.85; double nu_u233 = 2.5; double nu_u235 = 2.4; - - double fiss_u238 = simple_xs("u238", "fission", spectrum); - double absorb_u238 = simple_xs("u238", "absorption", spectrum); double nu_u238 = 0; - double p_u238 = nu_u238 * fiss_u238 - absorb_u238; - double fiss_pu239 = simple_xs("Pu239", "fission", spectrum); - double absorb_pu239 = simple_xs("Pu239", "absorption", spectrum); - double p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239; + if (spectrum == "thermal") { + static std::map absorb_xs; + static std::map fiss_xs; + static double p_u238 = 0; + static double p_pu239 = 0; + if (p_u238 == 0) { + double fiss_u238 = simple_xs(922380000, "fission", "thermal"); + double absorb_u238 = simple_xs(922380000, "absorption", "thermal"); + p_u238 = nu_u238 * fiss_u238 - absorb_u238; + + double fiss_pu239 = simple_xs(942390000, "fission", "thermal"); + double absorb_pu239 = simple_xs(942390000, "absorption", "thermal"); + p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239; + } - cyclus::CompMap::iterator it; - double w = 0; - for (it = cm.begin(); it != cm.end(); ++it) { - cyclus::Nuc nuc = it->first; - double nu = 0; - if (nuc == 922350000) { - nu = nu_u235; - } else if (nuc == 922330000) { - nu = nu_u233; - } else if (nuc == 942390000) { - nu = nu_pu239; + cyclus::CompMap::iterator it; + double w = 0; + for (it = cm.begin(); it != cm.end(); ++it) { + cyclus::Nuc nuc = it->first; + double nu = 0; + if (nuc == 922350000) { + nu = nu_u235; + } else if (nuc == 922330000) { + nu = nu_u233; + } else if (nuc == 942390000) { + nu = nu_pu239; + } + + double fiss = 0; + double absorb = 0; + if (absorb_xs.count(nuc) == 0) { + try { + fiss = simple_xs(nuc, "fission", "thermal"); + absorb = simple_xs(nuc, "absorption", "thermal"); + absorb_xs[nuc] = absorb; + fiss_xs[nuc] = fiss; + } catch(pyne::InvalidSimpleXS err) { + fiss = 0; + absorb = 0; + } + } else { + fiss = fiss_xs[nuc]; + absorb = absorb_xs[nuc]; + } + + double p = nu * fiss - absorb; + w += it->second * (p - p_u238) / (p_pu239 - p_u238); + } + return w; + } else if (spectrum == "fission_spectrum_ave") { + static std::map absorb_xs; + static std::map fiss_xs; + static double p_u238 = 0; + static double p_pu239 = 0; + if (p_u238 == 0) { + double fiss_u238 = simple_xs(922380000, "fission", "fission_spectrum_ave"); + double absorb_u238 = simple_xs(922380000, "absorption", "fission_spectrum_ave"); + p_u238 = nu_u238 * fiss_u238 - absorb_u238; + + double fiss_pu239 = simple_xs(942390000, "fission", "fission_spectrum_ave"); + double absorb_pu239 = simple_xs(942390000, "absorption", "fission_spectrum_ave"); + p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239; } - double fiss = 0; - double absorb = 0; - try { - fiss = simple_xs(nuc, "fission", spectrum); - absorb = simple_xs(nuc, "absorption", spectrum); - } catch(pyne::InvalidSimpleXS err) { - fiss = 0; - absorb = 0; + cyclus::CompMap::iterator it; + double w = 0; + for (it = cm.begin(); it != cm.end(); ++it) { + cyclus::Nuc nuc = it->first; + double nu = 0; + if (nuc == 922350000) { + nu = nu_u235; + } else if (nuc == 922330000) { + nu = nu_u233; + } else if (nuc == 942390000) { + nu = nu_pu239; + } + + double fiss = 0; + double absorb = 0; + if (absorb_xs.count(nuc) == 0) { + try { + fiss = simple_xs(nuc, "fission", "fission_spectrum_ave"); + absorb = simple_xs(nuc, "absorption", "fission_spectrum_ave"); + absorb_xs[nuc] = absorb; + fiss_xs[nuc] = fiss; + } catch(pyne::InvalidSimpleXS err) { + fiss = 0; + absorb = 0; + } + } else { + fiss = fiss_xs[nuc]; + absorb = absorb_xs[nuc]; + } + + double p = nu * fiss - absorb; + w += it->second * (p - p_u238) / (p_pu239 - p_u238); } + return w; + } else { + double fiss_u238 = simple_xs(922380000, "fission", spectrum); + double absorb_u238 = simple_xs(922380000, "absorption", spectrum); + double p_u238 = nu_u238 * fiss_u238 - absorb_u238; + + double fiss_pu239 = simple_xs(942390000, "fission", spectrum); + double absorb_pu239 = simple_xs(942390000, "absorption", spectrum); + double p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239; + + cyclus::CompMap::iterator it; + double w = 0; + for (it = cm.begin(); it != cm.end(); ++it) { + cyclus::Nuc nuc = it->first; + double nu = 0; + if (nuc == 922350000) { + nu = nu_u235; + } else if (nuc == 922330000) { + nu = nu_u233; + } else if (nuc == 942390000) { + nu = nu_pu239; + } - double p = nu * fiss - absorb; - w += it->second * (p - p_u238) / (p_pu239 - p_u238); + double fiss = 0; + double absorb = 0; + try { + fiss = simple_xs(nuc, "fission", spectrum); + absorb = simple_xs(nuc, "absorption", spectrum); + } catch(pyne::InvalidSimpleXS err) { + fiss = 0; + absorb = 0; + } + + double p = nu * fiss - absorb; + w += it->second * (p - p_u238) / (p_pu239 - p_u238); + } + return w; } - return w; } // Convert an atom frac (n1/(n1+n2) to a mass frac (m1/(m1+m2) given From 407caaaa4a1041688982f6083a8a0c4d971c132b Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 8 Apr 2015 08:45:02 -0500 Subject: [PATCH 087/314] clang-format --- src/fuel_fab.cc | 185 ++++++++++++++++++++++++------------------------ src/fuel_fab.h | 27 ++++--- 2 files changed, 106 insertions(+), 106 deletions(-) diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index c25e3fe9a3..077fe69f26 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -4,19 +4,17 @@ using cyclus::Material; using cyclus::Composition; using pyne::simple_xs; -#define SHOW(X) \ - std::cout << std::setprecision(17) << __FILE__ << ":" << __LINE__ << ": "#X" = " << X << "\n" +#define SHOW(X) \ + std::cout << std::setprecision(17) << __FILE__ << ":" << __LINE__ \ + << ": " #X " = " << X << "\n" namespace cycamore { class FissConverter : public cyclus::Converter { public: - FissConverter( - Composition::Ptr c_fill, - Composition::Ptr c_fiss, - Composition::Ptr c_topup, - std::string spectrum - ) : c_fiss_(c_fiss), c_topup_(c_topup), c_fill_(c_fill), spec_(spectrum) { + FissConverter(Composition::Ptr c_fill, Composition::Ptr c_fiss, + Composition::Ptr c_topup, std::string spectrum) + : c_fiss_(c_fiss), c_topup_(c_topup), c_fill_(c_fill), spec_(spectrum) { w_fiss_ = CosiWeight(c_fiss, spectrum); w_fill_ = CosiWeight(c_fill, spectrum); w_topup_ = CosiWeight(c_topup, spectrum); @@ -24,11 +22,9 @@ class FissConverter : public cyclus::Converter { virtual ~FissConverter() {} - virtual double convert( - cyclus::Material::Ptr m, - cyclus::Arc const * a = NULL, - cyclus::ExchangeTranslationContext const * ctx = NULL) const { - + virtual double convert(cyclus::Material::Ptr m, cyclus::Arc const* a = NULL, + cyclus::ExchangeTranslationContext< + cyclus::Material> const* ctx = NULL) const { double w_tgt = CosiWeight(m->comp(), spec_); if (ValidWeights(w_fill_, w_tgt, w_fiss_)) { double frac = HighFrac(w_fill_, w_tgt, w_fiss_); @@ -55,12 +51,9 @@ class FissConverter : public cyclus::Converter { class FillConverter : public cyclus::Converter { public: - FillConverter( - Composition::Ptr c_fill, - Composition::Ptr c_fiss, - Composition::Ptr c_topup, - std::string spectrum - ) : c_fiss_(c_fiss), c_topup_(c_topup), c_fill_(c_fill), spec_(spectrum) { + FillConverter(Composition::Ptr c_fill, Composition::Ptr c_fiss, + Composition::Ptr c_topup, std::string spectrum) + : c_fiss_(c_fiss), c_topup_(c_topup), c_fill_(c_fill), spec_(spectrum) { w_fiss_ = CosiWeight(c_fiss, spectrum); w_fill_ = CosiWeight(c_fill, spectrum); w_topup_ = CosiWeight(c_topup, spectrum); @@ -68,11 +61,9 @@ class FillConverter : public cyclus::Converter { virtual ~FillConverter() {} - virtual double convert( - cyclus::Material::Ptr m, - cyclus::Arc const * a = NULL, - cyclus::ExchangeTranslationContext const * ctx = NULL) const { - + virtual double convert(cyclus::Material::Ptr m, cyclus::Arc const* a = NULL, + cyclus::ExchangeTranslationContext< + cyclus::Material> const* ctx = NULL) const { double w_tgt = CosiWeight(m->comp(), spec_); if (ValidWeights(w_fill_, w_tgt, w_fiss_)) { double frac = LowFrac(w_fill_, w_tgt, w_fiss_); @@ -98,12 +89,9 @@ class FillConverter : public cyclus::Converter { class TopupConverter : public cyclus::Converter { public: - TopupConverter( - Composition::Ptr c_fill, - Composition::Ptr c_fiss, - Composition::Ptr c_topup, - std::string spectrum - ) : c_fiss_(c_fiss), c_topup_(c_topup), c_fill_(c_fill), spec_(spectrum) { + TopupConverter(Composition::Ptr c_fill, Composition::Ptr c_fiss, + Composition::Ptr c_topup, std::string spectrum) + : c_fiss_(c_fiss), c_topup_(c_topup), c_fill_(c_fill), spec_(spectrum) { w_fiss_ = CosiWeight(c_fiss, spectrum); w_fill_ = CosiWeight(c_fill, spectrum); w_topup_ = CosiWeight(c_topup, spectrum); @@ -111,11 +99,9 @@ class TopupConverter : public cyclus::Converter { virtual ~TopupConverter() {} - virtual double convert( - cyclus::Material::Ptr m, - cyclus::Arc const * a = NULL, - cyclus::ExchangeTranslationContext const * ctx = NULL) const { - + virtual double convert(cyclus::Material::Ptr m, cyclus::Arc const* a = NULL, + cyclus::ExchangeTranslationContext< + cyclus::Material> const* ctx = NULL) const { double w_tgt = CosiWeight(m->comp(), spec_); if (ValidWeights(w_fill_, w_tgt, w_fiss_)) { return 0; @@ -140,10 +126,7 @@ class TopupConverter : public cyclus::Converter { }; FuelFab::FuelFab(cyclus::Context* ctx) - : cyclus::Facility(ctx), - fill_size(0), - fiss_size(0), - throughput(0) {} + : cyclus::Facility(ctx), fill_size(0), fiss_size(0), throughput(0) {} void FuelFab::EnterNotify() { cyclus::Facility::EnterNotify(); @@ -155,8 +138,7 @@ void FuelFab::EnterNotify() { } } -std::set::Ptr> -FuelFab::GetMatlRequests() { +std::set::Ptr> FuelFab::GetMatlRequests() { using cyclus::RequestPortfolio; std::set::Ptr> ports; @@ -191,7 +173,8 @@ FuelFab::GetMatlRequests() { Composition::Ptr c = context()->GetRecipe(fill_recipe); m = Material::CreateUntracked(fill.space(), c); } - cyclus::Request* r = port->AddRequest(m, this, fill_commod, fill_pref, exclusive); + cyclus::Request* r = + port->AddRequest(m, this, fill_commod, fill_pref, exclusive); req_inventories_[r] = "fill"; ports.insert(port); } @@ -204,7 +187,8 @@ FuelFab::GetMatlRequests() { Composition::Ptr c = context()->GetRecipe(topup_recipe); m = Material::CreateUntracked(topup.space(), c); } - cyclus::Request* r = port->AddRequest(m, this, topup_commod, topup_pref, exclusive); + cyclus::Request* r = + port->AddRequest(m, this, topup_commod, topup_pref, exclusive); req_inventories_[r] = "topup"; ports.insert(port); } @@ -221,12 +205,10 @@ bool Contains(std::vector vec, std::string s) { return false; } -void FuelFab::AcceptMatlTrades( - const std::vector< std::pair, - Material::Ptr> >& responses) { - - std::vector< std::pair, - cyclus::Material::Ptr> >::const_iterator trade; +void FuelFab::AcceptMatlTrades(const std::vector< + std::pair, Material::Ptr> >& responses) { + std::vector, + cyclus::Material::Ptr> >::const_iterator trade; for (trade = responses.begin(); trade != responses.end(); ++trade) { std::string commod = trade->first.request->commodity(); @@ -246,9 +228,8 @@ void FuelFab::AcceptMatlTrades( req_inventories_.clear(); } -std::set::Ptr> -FuelFab::GetMatlBids(cyclus::CommodMap::type& - commod_requests) { +std::set::Ptr> FuelFab::GetMatlBids( + cyclus::CommodMap::type& commod_requests) { using cyclus::BidPortfolio; std::set::Ptr> ports; @@ -261,7 +242,8 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& } double w_fill = 0; - Composition::Ptr c_fill; // no default needed - this is non-optional parameter + Composition::Ptr + c_fill; // no default needed - this is non-optional parameter if (fill.count() > 0) { c_fill = fill.Peek()->comp(); w_fill = CosiWeight(c_fill, spectrum); @@ -280,7 +262,8 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& w_topup = CosiWeight(c_topup, spectrum); } - double w_fiss = w_fill; // this allows trading just fill with no fiss inventory + double w_fiss = + w_fill; // this allows trading just fill with no fiss inventory Composition::Ptr c_fiss = c_fill; if (fiss.count() > 0) { c_fiss = fiss.Peek()->comp(); @@ -316,22 +299,30 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& double fiss_frac = 1 - topup_frac; fiss_frac = AtomToMassFrac(fiss_frac, c_fiss, c_topup); topup_frac = AtomToMassFrac(topup_frac, c_topup, c_fiss); - Material::Ptr m1 = Material::CreateUntracked(topup_frac * tgt_qty, c_topup); + Material::Ptr m1 = + Material::CreateUntracked(topup_frac * tgt_qty, c_topup); Material::Ptr m2 = Material::CreateUntracked(fiss_frac * tgt_qty, c_fiss); m1->Absorb(m2); bool exclusive = false; port->AddBid(req, m1, this, exclusive); - } // else can't meet the target - don't bid + } // else can't meet the target - don't bid } - cyclus::Converter::Ptr fissconv(new FissConverter(c_fill, c_fiss, c_topup, spectrum)); - cyclus::Converter::Ptr fillconv(new FillConverter(c_fill, c_fiss, c_topup, spectrum)); - cyclus::Converter::Ptr topupconv(new TopupConverter(c_fill, c_fiss, c_topup, spectrum)); - // important! - the std::max calls prevent CapacityConstraint throwing a zero cap exception - cyclus::CapacityConstraint fissc(std::max(fiss.quantity(), 1e-10), fissconv); - cyclus::CapacityConstraint fillc(std::max(fill.quantity(), 1e-10), fillconv); - cyclus::CapacityConstraint topupc(std::max(topup.quantity(), 1e-10), topupconv); + cyclus::Converter::Ptr fissconv( + new FissConverter(c_fill, c_fiss, c_topup, spectrum)); + cyclus::Converter::Ptr fillconv( + new FillConverter(c_fill, c_fiss, c_topup, spectrum)); + cyclus::Converter::Ptr topupconv( + new TopupConverter(c_fill, c_fiss, c_topup, spectrum)); + // important! - the std::max calls prevent CapacityConstraint throwing a zero + // cap exception + cyclus::CapacityConstraint fissc(std::max(fiss.quantity(), 1e-10), + fissconv); + cyclus::CapacityConstraint fillc(std::max(fill.quantity(), 1e-10), + fillconv); + cyclus::CapacityConstraint topupc(std::max(topup.quantity(), 1e-10), + topupconv); port->AddConstraint(fillc); port->AddConstraint(fissc); port->AddConstraint(topupc); @@ -343,25 +334,26 @@ FuelFab::GetMatlBids(cyclus::CommodMap::type& } void FuelFab::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - Material::Ptr> >& responses) { + const std::vector >& trades, + std::vector, Material::Ptr> >& + responses) { using cyclus::Trade; double w_fill = 0; - if (fill.count() > 0) { // it's possible to only need fissile inventory for a trade + if (fill.count() > + 0) { // it's possible to only need fissile inventory for a trade w_fill = CosiWeight(fill.Peek()->comp(), spectrum); } double w_topup = 0; if (topup.count() > 0) { w_topup = CosiWeight(topup.Peek()->comp(), spectrum); } - double w_fiss = 0; + double w_fiss = 0; if (fiss.count() > 0) { w_fiss = CosiWeight(fiss.Peek()->comp(), spectrum); } - std::vector< cyclus::Trade >::const_iterator it; + std::vector >::const_iterator it; double tot = 0; for (int i = 0; i < trades.size(); i++) { Material::Ptr tgt = trades[i].request->target(); @@ -372,8 +364,9 @@ void FuelFab::GetMatlTrades( tot += qty; if (tot > throughput + cyclus::eps()) { std::stringstream ss; - ss << "FuelFab was matched above throughput limit: " << tot << " > " << throughput; - throw cyclus::ValueError(ss.str()); + ss << "FuelFab was matched above throughput limit: " << tot << " > " + << throughput; + throw cyclus::ValueError(ss.str()); } if (fiss.count() == 0) { @@ -385,25 +378,29 @@ void FuelFab::GetMatlTrades( } else if (ValidWeights(w_fill, w_tgt, w_fiss)) { double fiss_frac = HighFrac(w_fill, w_tgt, w_fiss); double fill_frac = LowFrac(w_fill, w_tgt, w_fiss); - fiss_frac = AtomToMassFrac(fiss_frac, fiss.Peek()->comp(), fill.Peek()->comp()); - fill_frac = AtomToMassFrac(fill_frac, fill.Peek()->comp(), fiss.Peek()->comp()); + fiss_frac = + AtomToMassFrac(fiss_frac, fiss.Peek()->comp(), fill.Peek()->comp()); + fill_frac = + AtomToMassFrac(fill_frac, fill.Peek()->comp(), fiss.Peek()->comp()); - Material::Ptr m = fiss.Pop(fiss_frac*qty); + Material::Ptr m = fiss.Pop(fiss_frac * qty); // this if block prevents zero qty ResBuf pop exceptions if (fill_frac > 0) { - m->Absorb(fill.Pop(fill_frac*qty)); + m->Absorb(fill.Pop(fill_frac * qty)); } responses.push_back(std::make_pair(trades[i], m)); } else { double topup_frac = HighFrac(w_fiss, w_tgt, w_topup); double fiss_frac = 1 - topup_frac; - topup_frac = AtomToMassFrac(topup_frac, topup.Peek()->comp(), fiss.Peek()->comp()); - fiss_frac = AtomToMassFrac(fiss_frac, fiss.Peek()->comp(), topup.Peek()->comp()); + topup_frac = + AtomToMassFrac(topup_frac, topup.Peek()->comp(), fiss.Peek()->comp()); + fiss_frac = + AtomToMassFrac(fiss_frac, fiss.Peek()->comp(), topup.Peek()->comp()); - Material::Ptr m = fiss.Pop(fiss_frac*qty); + Material::Ptr m = fiss.Pop(fiss_frac * qty); // this if block prevents zero qty ResBuf pop exceptions if (topup_frac > 0) { - m->Absorb(topup.Pop(topup_frac*qty)); + m->Absorb(topup.Pop(topup_frac * qty)); } responses.push_back(std::make_pair(trades[i], m)); } @@ -416,7 +413,7 @@ extern "C" cyclus::Agent* ConstructFuelFab(cyclus::Context* ctx) { // Returns the weight of c using 1 group cross sections of type spectrum // which must be one of: -// +// // * thermal // * thermal_maxwell_ave // * fission_spectrum_ave @@ -472,7 +469,7 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { absorb = simple_xs(nuc, "absorption", "thermal"); absorb_xs[nuc] = absorb; fiss_xs[nuc] = fiss; - } catch(pyne::InvalidSimpleXS err) { + } catch (pyne::InvalidSimpleXS err) { fiss = 0; absorb = 0; } @@ -491,12 +488,16 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { static double p_u238 = 0; static double p_pu239 = 0; if (p_u238 == 0) { - double fiss_u238 = simple_xs(922380000, "fission", "fission_spectrum_ave"); - double absorb_u238 = simple_xs(922380000, "absorption", "fission_spectrum_ave"); + double fiss_u238 = + simple_xs(922380000, "fission", "fission_spectrum_ave"); + double absorb_u238 = + simple_xs(922380000, "absorption", "fission_spectrum_ave"); p_u238 = nu_u238 * fiss_u238 - absorb_u238; - double fiss_pu239 = simple_xs(942390000, "fission", "fission_spectrum_ave"); - double absorb_pu239 = simple_xs(942390000, "absorption", "fission_spectrum_ave"); + double fiss_pu239 = + simple_xs(942390000, "fission", "fission_spectrum_ave"); + double absorb_pu239 = + simple_xs(942390000, "absorption", "fission_spectrum_ave"); p_pu239 = nu_pu239 * fiss_pu239 - absorb_pu239; } @@ -521,7 +522,7 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { absorb = simple_xs(nuc, "absorption", "fission_spectrum_ave"); absorb_xs[nuc] = absorb; fiss_xs[nuc] = fiss; - } catch(pyne::InvalidSimpleXS err) { + } catch (pyne::InvalidSimpleXS err) { fiss = 0; absorb = 0; } @@ -561,7 +562,7 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { try { fiss = simple_xs(nuc, "fission", spectrum); absorb = simple_xs(nuc, "absorption", spectrum); - } catch(pyne::InvalidSimpleXS err) { + } catch (pyne::InvalidSimpleXS err) { fiss = 0; absorb = 0; } @@ -575,11 +576,12 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { // Convert an atom frac (n1/(n1+n2) to a mass frac (m1/(m1+m2) given // corresponding compositions c1 and c2. -double AtomToMassFrac(double atomfrac, Composition::Ptr c1, Composition::Ptr c2) { +double AtomToMassFrac(double atomfrac, Composition::Ptr c1, + Composition::Ptr c2) { cyclus::CompMap n1 = c1->atom(); cyclus::CompMap n2 = c2->atom(); cyclus::compmath::Normalize(&n1, atomfrac); - cyclus::compmath::Normalize(&n2, 1-atomfrac); + cyclus::compmath::Normalize(&n2, 1 - atomfrac); cyclus::CompMap::iterator it; @@ -603,7 +605,7 @@ double HighFrac(double w_low, double w_target, double w_high, double eps) { return 1; } double f = std::abs((w_target - w_low) / (w_high - w_low)); - if (1-f < eps) { + if (1 - f < eps) { return 1; } else if (f < eps) { return 0; @@ -623,5 +625,4 @@ bool ValidWeights(double w_low, double w_target, double w_high) { return w_low <= w_target && w_target <= w_high; } -} // namespace cycamore - +} // namespace cycamore diff --git a/src/fuel_fab.h b/src/fuel_fab.h index 4d016b3ecd..f689084cfe 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -45,7 +45,7 @@ namespace cycamore { /// can be requested/received via one or more commodities. The DRE request /// preference for each of these commodities can also optionally be specified. /// By default, the top-up inventory size is zero, and it is not used for -/// mixing. +/// mixing. class FuelFab : public cyclus::Facility { #pragma cyclus note { \ "doc": \ @@ -93,28 +93,27 @@ class FuelFab : public cyclus::Facility { } public: FuelFab(cyclus::Context* ctx); - virtual ~FuelFab() {}; + virtual ~FuelFab(){}; - #pragma cyclus +#pragma cyclus - virtual void Tick() {}; - virtual void Tock() {}; + virtual void Tick(){}; + virtual void Tock(){}; virtual void EnterNotify(); - virtual std::set::Ptr> - GetMatlBids(cyclus::CommodMap::type& - commod_requests); + virtual std::set::Ptr> GetMatlBids( + cyclus::CommodMap::type& commod_requests); virtual void GetMatlTrades( - const std::vector< cyclus::Trade >& trades, + const std::vector >& trades, std::vector, - cyclus::Material::Ptr> >& responses); + cyclus::Material::Ptr> >& responses); - virtual void AcceptMatlTrades( - const std::vector< std::pair, - cyclus::Material::Ptr> >& responses); + virtual void AcceptMatlTrades(const std::vector, cyclus::Material::Ptr> >& responses); - virtual std::set::Ptr> GetMatlRequests(); + virtual std::set::Ptr> + GetMatlRequests(); private: #pragma cyclus var { \ From 06e4b7639faad224870a9f681f7b9f97c3065abc Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 8 Apr 2015 11:49:19 -0500 Subject: [PATCH 088/314] doc fix and add equivalence citation --- src/fuel_fab.h | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/fuel_fab.h b/src/fuel_fab.h index f689084cfe..1b96b48a71 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -8,8 +8,8 @@ namespace cycamore { /// FuelFab takes in 2 streams of material and mixes them in ratios in order to /// supply material that matches some neutronics properties of reqeusted -/// material. It uses an equivalence type method (TODO: cite equivalence -/// method) inspired by a similar approach in the COSI fuel cycle simulator. +/// material. It uses an equivalence type method [1] +/// inspired by a similar approach in the COSI fuel cycle simulator. /// /// The FuelFab has 3 input inventories: fissile stream, filler stream, and an /// optional top-up inventory. All materials received into each inventory are @@ -46,13 +46,19 @@ namespace cycamore { /// preference for each of these commodities can also optionally be specified. /// By default, the top-up inventory size is zero, and it is not used for /// mixing. +/// +/// @code +/// [1] Baker, A. R., and R. W. Ross. "Comparison of the value of plutonium and +/// uranium isotopes in fast reactors." Proceedings of the Conference on +/// Breeding. Economics, and Safety in Large Fast Power Reactors. 1963. +/// @endcode class FuelFab : public cyclus::Facility { #pragma cyclus note { \ "doc": \ "FuelFab takes in 2 streams of material and mixes them in ratios in order to" \ " supply material that matches some neutronics properties of reqeusted" \ - " material. It uses an equivalence type method (TODO: cite equivalence" \ - " method) inspired by a similar approach in the COSI fuel cycle simulator." \ + " material. It uses an equivalence type method [1]" \ + " inspired by a similar approach in the COSI fuel cycle simulator." \ "\n\n" \ "The FuelFab has 3 input inventories: fissile stream, filler stream, and an" \ " optional top-up inventory. All materials received into each inventory are" \ @@ -89,6 +95,10 @@ class FuelFab : public cyclus::Facility { " preference for each of these commodities can also optionally be specified." \ " By default, the top-up inventory size is zero, and it is not used for" \ " mixing. " \ + "\n\n" \ + "[1] Baker, A. R., and R. W. Ross. \"Comparison of the value of plutonium and" \ + " uranium isotopes in fast reactors.\" Proceedings of the Conference on" \ + " Breeding. Economics, and Safety in Large Fast Power Reactors. 1963." \ "", \ } public: @@ -195,7 +205,7 @@ class FuelFab : public cyclus::Facility { #pragma cyclus var { \ "doc": "The type of cross-sections to use for composition property calculation." \ - " Use 'fission_spectrum_ave' for fast reactor compositions or 'thermal' for slow reactors.", \ + " Use 'fission_spectrum_ave' for fast reactor compositions or 'thermal' for thermal reactors.", \ } std::string spectrum; From 6e40cc4d7b10b51c8febe8ee1d81bc84e73b046e Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 8 Apr 2015 12:27:28 -0500 Subject: [PATCH 089/314] set stage for better energy dependent nu --- src/fuel_fab.cc | 20 +++++++++++++++----- src/fuel_fab_tests.cc | 4 ++-- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index 077fe69f26..90456aed2f 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -428,12 +428,12 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { cyclus::CompMap cm = c->atom(); cyclus::compmath::Normalize(&cm); - double nu_pu239 = 2.85; - double nu_u233 = 2.5; - double nu_u235 = 2.4; - double nu_u238 = 0; - if (spectrum == "thermal") { + double nu_pu239 = 2.85; + double nu_u233 = 2.5; + double nu_u235 = 2.43; + double nu_u238 = 0; + static std::map absorb_xs; static std::map fiss_xs; static double p_u238 = 0; @@ -483,6 +483,11 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { } return w; } else if (spectrum == "fission_spectrum_ave") { + double nu_pu239 = 3.1; + double nu_u233 = 2.63; + double nu_u235 = 2.58; + double nu_u238 = 0; + static std::map absorb_xs; static std::map fiss_xs; static double p_u238 = 0; @@ -536,6 +541,11 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { } return w; } else { + double nu_pu239 = 3.1; + double nu_u233 = 2.63; + double nu_u235 = 2.58; + double nu_u238 = 0; + double fiss_u238 = simple_xs(922380000, "fission", spectrum); double absorb_u238 = simple_xs(922380000, "absorption", spectrum); double p_u238 = nu_u238 * fiss_u238 - absorb_u238; diff --git a/src/fuel_fab_tests.cc b/src/fuel_fab_tests.cc index 2d2a5fa2dc..a72dcaff00 100644 --- a/src/fuel_fab_tests.cc +++ b/src/fuel_fab_tests.cc @@ -528,12 +528,12 @@ TEST(FuelFabTests, CorrectMixing) { conds[0] = Cond("Commodity", "==", std::string("natu")); qr = sim.db().Query("Transactions", &conds); m = sim.GetMaterial(qr.GetVal("ResourceId")); - EXPECT_NEAR(9.7457947, m->quantity(), 1e-6) << "mixed wrong amount of Nat. U stream"; + EXPECT_NEAR(9.73958936, m->quantity(), 1e-6) << "mixed wrong amount of Nat. U stream"; conds[0] = Cond("Commodity", "==", std::string("pustream")); qr = sim.db().Query("Transactions", &conds); m = sim.GetMaterial(qr.GetVal("ResourceId")); - EXPECT_NEAR(0.2542052, m->quantity(), 1e-6) << "mixed wrong amount of Pu stream"; + EXPECT_NEAR(0.2604106, m->quantity(), 1e-6) << "mixed wrong amount of Pu stream"; } // fuel is requested requiring more filler than is available with plenty of From 9d985e8b5c5ebd1b1f8f90db9fa04eae14636681 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 8 Apr 2015 16:44:11 -0500 Subject: [PATCH 090/314] made reactor commodity producer --- src/reactor.cc | 35 +++++++++++++++++++++++++++++++++++ src/reactor.h | 13 +++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index 97a7602770..e3e0b376dc 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -21,15 +21,50 @@ Reactor::Reactor(cyclus::Context* ctx) refuel_time(0), cycle_step(0), power_cap(0), + power_commod("power"), discharged(false) { cyclus::Warn( "the Reactor archetype " "is experimental"); } +#pragma cyclus def clone cycamore::Reactor + +#pragma cyclus def schema cycamore::Reactor + +#pragma cyclus def annotations cycamore::Reactor + +#pragma cyclus def infiletodb cycamore::Reactor + +#pragma cyclus def snapshot cycamore::Reactor + +#pragma cyclus def snapshotinv cycamore::Reactor + +#pragma cyclus def initinv cycamore::Reactor + +void Reactor::InitFrom(Reactor* m) { + #pragma cyclus impl initfromcopy cycamore::Reactor + cyclus::toolkit::CommodityProducer::Copy(m); +} + +void Reactor::InitFrom(cyclus::QueryableBackend* b) { + #pragma cyclus impl initfromdb cycamore::Reactor + + power_commod_ = cyclus::toolkit::Commodity(power_commod); + cyclus::toolkit::CommodityProducer::Add(power_commod_); + cyclus::toolkit::CommodityProducer::SetCapacity(power_commod_, power_cap); + cyclus::toolkit::CommodityProducer::SetCost(power_commod_, power_cap); +} + void Reactor::EnterNotify() { cyclus::Facility::EnterNotify(); + // setup commodity producer values + power_commod_ = cyclus::toolkit::Commodity(power_commod); + cyclus::toolkit::CommodityProducer::Add(power_commod_); + cyclus::toolkit::CommodityProducer::SetCapacity(power_commod_, power_cap); + cyclus::toolkit::CommodityProducer::SetCost(power_commod_, power_cap); + // If the user ommitted fuel_prefs, we set it to zeros for each fuel // type. Without this segfaults could occur - yuck. if (fuel_prefs.size() == 0) { diff --git a/src/reactor.h b/src/reactor.h index 6e98566179..61356d39ea 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -42,7 +42,8 @@ namespace cycamore { /// becomes full, the reactor will halt operation at the end of the next cycle /// until there is more room. Each time step, the reactor will try to trade /// away as much of its spent fuel inventory as possible. -class Reactor : public cyclus::Facility { +class Reactor : public cyclus::Facility, + public cyclus::toolkit::CommodityProducer { #pragma cyclus note { \ "niche": "reactor", \ "doc": \ @@ -107,7 +108,7 @@ class Reactor : public cyclus::Facility { std::vector, cyclus::Material::Ptr> >& responses); - #pragma cyclus + #pragma cyclus decl private: std::string fuel_incommod(cyclus::Material::Ptr m); @@ -299,6 +300,14 @@ class Reactor : public cyclus::Facility { } double power_cap; + #pragma cyclus var { \ + "default": "power", \ + "doc": "The name of the 'power' commodity used in conjunction with a deployment curve.", \ + } + std::string power_commod; + + // internal use only + cyclus::toolkit::Commodity power_commod_; }; } // namespace cycamore From f9119a1d3fd20be06f5f05a6a403a80c4b06ef85 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 8 Apr 2015 17:24:42 -0500 Subject: [PATCH 091/314] don't need to reset producer values on enter notify --- src/reactor.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index e3e0b376dc..dbdfc4849d 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -58,13 +58,7 @@ void Reactor::InitFrom(cyclus::QueryableBackend* b) { void Reactor::EnterNotify() { cyclus::Facility::EnterNotify(); - - // setup commodity producer values - power_commod_ = cyclus::toolkit::Commodity(power_commod); - cyclus::toolkit::CommodityProducer::Add(power_commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(power_commod_, power_cap); - cyclus::toolkit::CommodityProducer::SetCost(power_commod_, power_cap); - + // If the user ommitted fuel_prefs, we set it to zeros for each fuel // type. Without this segfaults could occur - yuck. if (fuel_prefs.size() == 0) { From 6b415e6914d1aed6dd198bc16c3b416eb5ce7006 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 8 Apr 2015 17:25:04 -0500 Subject: [PATCH 092/314] fix bad ending tag --- input/enrichment/1_src_enr_rxtr_sink.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/enrichment/1_src_enr_rxtr_sink.xml b/input/enrichment/1_src_enr_rxtr_sink.xml index bf73b347b4..a9752d1ed1 100644 --- a/input/enrichment/1_src_enr_rxtr_sink.xml +++ b/input/enrichment/1_src_enr_rxtr_sink.xml @@ -46,7 +46,7 @@ fuel_recipe used_fuel_recipe - enriched_u + enriched_u waste 1 From ff4cbd55146fb4c5e605344f2de67ad8e6186ac7 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 8 Apr 2015 17:25:19 -0500 Subject: [PATCH 093/314] linear enr now works as it did before --- input/enrichment/linear_src_enr_rxtr_sink.xml | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/input/enrichment/linear_src_enr_rxtr_sink.xml b/input/enrichment/linear_src_enr_rxtr_sink.xml index bd09a23eab..61a03fd3ff 100644 --- a/input/enrichment/linear_src_enr_rxtr_sink.xml +++ b/input/enrichment/linear_src_enr_rxtr_sink.xml @@ -11,7 +11,7 @@ cycamoreSink cycamoreSource cycamoreEnrichmentFacility - cycamoreBatchReactor + cycamoreReactor cycamoreGrowthRegion cycamoreManagerInst @@ -43,22 +43,21 @@ Reactor - - - enriched_u - fuel_recipe - waste - used_fuel_recipe - - 1 - 1 - 2 - - power - 10 - 10 - - + + fuel_recipe + used_fuel_recipe + enriched_u + waste + + 1 + 0 + 2 + 1 + 1 + + power + 10 + @@ -111,6 +110,7 @@ Source Enrichment + Reactor Sink From 9d24958b24c7dd6243cd50383a132f5ee4df5e67 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 8 Apr 2015 17:27:42 -0500 Subject: [PATCH 094/314] updating other enrichment input files --- input/enrichment/natu_capacitated.xml | 34 +++++++++++++-------------- input/enrichment/swu_capacitated.xml | 34 +++++++++++++-------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/input/enrichment/natu_capacitated.xml b/input/enrichment/natu_capacitated.xml index e363e5c392..542bd34b72 100644 --- a/input/enrichment/natu_capacitated.xml +++ b/input/enrichment/natu_capacitated.xml @@ -11,7 +11,7 @@ cycamoreSink cycamoreSource cycamoreEnrichmentFacility - cycamoreBatchReactor + cycamoreReactor cycamoreGrowthRegion cycamoreManagerInst @@ -43,22 +43,21 @@ Reactor - - - enriched_u - fuel_recipe - waste - used_fuel_recipe - - 1 - 1 - 2 - - power - 10 - 10 - - + + fuel_recipe + used_fuel_recipe + enriched_u + waste + + 1 + 0 + 2 + 1 + 1 + + power + 10 + @@ -111,6 +110,7 @@ Source Enrichment + Reactor Sink diff --git a/input/enrichment/swu_capacitated.xml b/input/enrichment/swu_capacitated.xml index 35215a1d9f..8fcf64c5a3 100644 --- a/input/enrichment/swu_capacitated.xml +++ b/input/enrichment/swu_capacitated.xml @@ -11,7 +11,7 @@ cycamoreSink cycamoreSource cycamoreEnrichmentFacility - cycamoreBatchReactor + cycamoreReactor cycamoreGrowthRegion cycamoreManagerInst @@ -44,22 +44,21 @@ Reactor - - - enriched_u - fuel_recipe - waste - used_fuel_recipe - - 1 - 1 - 2 - - power - 10 - 10 - - + + fuel_recipe + used_fuel_recipe + enriched_u + waste + + 1 + 0 + 2 + 1 + 1 + + power + 10 + @@ -112,6 +111,7 @@ Source Enrichment + Reactor Sink From c31ef0b2d1d1c7423c71fcf9a045d70c8d63d1ea Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 8 Apr 2015 22:51:58 -0500 Subject: [PATCH 095/314] simplifying reactor commodity produce usage --- src/reactor.cc | 7 +++---- src/reactor.h | 3 --- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index dbdfc4849d..0ab3dab409 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -50,10 +50,9 @@ void Reactor::InitFrom(Reactor* m) { void Reactor::InitFrom(cyclus::QueryableBackend* b) { #pragma cyclus impl initfromdb cycamore::Reactor - power_commod_ = cyclus::toolkit::Commodity(power_commod); - cyclus::toolkit::CommodityProducer::Add(power_commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(power_commod_, power_cap); - cyclus::toolkit::CommodityProducer::SetCost(power_commod_, power_cap); + using cyclus::toolkit as tk; + tk::CommodityProducer::Add(tk::Commodity(power_commod), + tk::CommodInfo(power_cap, power_cap)); } void Reactor::EnterNotify() { diff --git a/src/reactor.h b/src/reactor.h index 61356d39ea..aedffb01d5 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -305,9 +305,6 @@ class Reactor : public cyclus::Facility, "doc": "The name of the 'power' commodity used in conjunction with a deployment curve.", \ } std::string power_commod; - - // internal use only - cyclus::toolkit::Commodity power_commod_; }; } // namespace cycamore From c7e48d7cd0c089742b403fca9de4f451c8308d87 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 9 Apr 2015 08:24:38 -0500 Subject: [PATCH 096/314] fixing namespace for tk --- src/reactor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactor.cc b/src/reactor.cc index 0ab3dab409..975e392bc3 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -50,7 +50,7 @@ void Reactor::InitFrom(Reactor* m) { void Reactor::InitFrom(cyclus::QueryableBackend* b) { #pragma cyclus impl initfromdb cycamore::Reactor - using cyclus::toolkit as tk; + namespace tk = cyclus::toolkit; tk::CommodityProducer::Add(tk::Commodity(power_commod), tk::CommodInfo(power_cap, power_cap)); } From 072254626260402fde6d809b9efcc0062a503c4f Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 11 Feb 2015 14:33:12 -0600 Subject: [PATCH 097/314] generalizing and finalizing source for 1.3 --- input/enrichment/1_src_enr_rxtr_sink.xml | 6 +- input/enrichment/linear_src_enr_rxtr_sink.xml | 6 +- input/enrichment/natu_capacitated.xml | 6 +- input/enrichment/swu_capacitated.xml | 6 +- .../source_1_lifetime_sink_1.xml | 6 +- input/minimal-input/source_1_sink_1.xml | 6 +- .../source_3_lifetime_sink_1.xml | 6 +- input/minimal-input/source_3_sink_1.xml | 6 +- input/physor/2_Sources_3_Reactors.xml | 12 +- src/source.cc | 158 +++++------- src/source.h | 226 +++++------------- src/source_tests.cc | 69 +----- src/source_tests.h | 21 +- tests/input/growth.xml | 12 +- 14 files changed, 186 insertions(+), 360 deletions(-) diff --git a/input/enrichment/1_src_enr_rxtr_sink.xml b/input/enrichment/1_src_enr_rxtr_sink.xml index bf73b347b4..67b136991d 100644 --- a/input/enrichment/1_src_enr_rxtr_sink.xml +++ b/input/enrichment/1_src_enr_rxtr_sink.xml @@ -20,9 +20,9 @@ Source - natl_u - 1000 - natl_u + natl_u + natl_u + 1000 diff --git a/input/enrichment/linear_src_enr_rxtr_sink.xml b/input/enrichment/linear_src_enr_rxtr_sink.xml index bd09a23eab..59ae399f22 100644 --- a/input/enrichment/linear_src_enr_rxtr_sink.xml +++ b/input/enrichment/linear_src_enr_rxtr_sink.xml @@ -20,9 +20,9 @@ Source - natl_u - 1000 - natl_u + natl_u + natl_u + 1000 diff --git a/input/enrichment/natu_capacitated.xml b/input/enrichment/natu_capacitated.xml index e363e5c392..301079c6b9 100644 --- a/input/enrichment/natu_capacitated.xml +++ b/input/enrichment/natu_capacitated.xml @@ -20,9 +20,9 @@ Source - natl_u - 1000 - natl_u + natl_u + natl_u + 1000 diff --git a/input/enrichment/swu_capacitated.xml b/input/enrichment/swu_capacitated.xml index 35215a1d9f..3851da121a 100644 --- a/input/enrichment/swu_capacitated.xml +++ b/input/enrichment/swu_capacitated.xml @@ -20,9 +20,9 @@ Source - natl_u - 1000 - natl_u + natl_u + natl_u + 1000 diff --git a/input/minimal-input/source_1_lifetime_sink_1.xml b/input/minimal-input/source_1_lifetime_sink_1.xml index 0cbc316658..59b59ded62 100644 --- a/input/minimal-input/source_1_lifetime_sink_1.xml +++ b/input/minimal-input/source_1_lifetime_sink_1.xml @@ -31,9 +31,9 @@ 5 - commodity - commod_recipe - 1 + commodity + commod_recipe + 1 diff --git a/input/minimal-input/source_1_sink_1.xml b/input/minimal-input/source_1_sink_1.xml index 8b96e8d193..c21acbf9b4 100644 --- a/input/minimal-input/source_1_sink_1.xml +++ b/input/minimal-input/source_1_sink_1.xml @@ -30,9 +30,9 @@ SomeSource - commodity - 1 - commod_recipe + commodity + commod_recipe + 1 diff --git a/input/minimal-input/source_3_lifetime_sink_1.xml b/input/minimal-input/source_3_lifetime_sink_1.xml index 07a897342e..4f7197ad74 100644 --- a/input/minimal-input/source_3_lifetime_sink_1.xml +++ b/input/minimal-input/source_3_lifetime_sink_1.xml @@ -19,9 +19,9 @@ 5 - commodity - 1 - commod_recipe + commodity + commod_recipe + 1 diff --git a/input/minimal-input/source_3_sink_1.xml b/input/minimal-input/source_3_sink_1.xml index 78621f4a24..7efc34a570 100644 --- a/input/minimal-input/source_3_sink_1.xml +++ b/input/minimal-input/source_3_sink_1.xml @@ -18,9 +18,9 @@ Source - commodity - 1 - commod_recipe + commodity + commod_recipe + 1 diff --git a/input/physor/2_Sources_3_Reactors.xml b/input/physor/2_Sources_3_Reactors.xml index 30e6632a6f..b7eb93131d 100755 --- a/input/physor/2_Sources_3_Reactors.xml +++ b/input/physor/2_Sources_3_Reactors.xml @@ -18,9 +18,9 @@ UOX_Source - uox - uox_fuel_recipe - 2.500000001 + uox + uox_fuel_recipe + 2.500000001 @@ -29,9 +29,9 @@ MOX_Source - mox - mox_fuel_recipe - 2.500000001 + mox + mox_fuel_recipe + 2.500000001 diff --git a/src/source.cc b/src/source.cc index 0cfe5d3aec..8ec1b43f7b 100644 --- a/src/source.cc +++ b/src/source.cc @@ -7,31 +7,13 @@ namespace cycamore { -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source::Source(cyclus::Context* ctx) : cyclus::Facility(ctx), - out_commod(""), - recipe_name(""), - capacity(std::numeric_limits::max()) {} + throughput(std::numeric_limits::max()), + inventory_size(std::numeric_limits::max()) {} -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Source::~Source() {} -#pragma cyclus def clone cycamore::Source - -#pragma cyclus def schema cycamore::Source - -#pragma cyclus def annotations cycamore::Source - -#pragma cyclus def infiletodb cycamore::Source - -#pragma cyclus def snapshot cycamore::Source - -#pragma cyclus def snapshotinv cycamore::Source - -#pragma cyclus def initinv cycamore::Source - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Source::InitFrom(Source* m) { #pragma cyclus impl initfromcopy cycamore::Source cyclus::toolkit::CommodityProducer::Copy(m); @@ -39,71 +21,38 @@ void Source::InitFrom(Source* m) { void Source::InitFrom(cyclus::QueryableBackend* b) { #pragma cyclus impl initfromdb cycamore::Source - - commod_ = cyclus::toolkit::Commodity(out_commod); - cyclus::toolkit::CommodityProducer::Add(commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); - cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); + cyclus::toolkit::CommodityProducer::Add(outcommod); + cyclus::toolkit::CommodityProducer::SetCapacity(outcommod, throughput); + cyclus::toolkit::CommodityProducer::SetCost(outcommod, throughput); } void Source::EnterNotify() { Facility::EnterNotify(); - commod_ = cyclus::toolkit::Commodity(out_commod); - cyclus::toolkit::CommodityProducer::Add(commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); - cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); + cyclus::toolkit::CommodityProducer::Add(outcommod); + cyclus::toolkit::CommodityProducer::SetCapacity(outcommod, throughput); + cyclus::toolkit::CommodityProducer::SetCost(outcommod, throughput); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - std::string Source::str() { std::stringstream ss; std::string ans; - if (cyclus::toolkit::CommodityProducer:: - Produces(cyclus::toolkit::Commodity(out_commod))) { + if (cyclus::toolkit::CommodityProducer::Produces( + cyclus::toolkit::Commodity(outcommod))) { ans = "yes"; } else { ans = "no"; } - ss << cyclus::Facility::str() - << " supplies commodity '" - << out_commod << "' with recipe '" - << recipe_name << "' at a capacity of " - << capacity << " kg per time step " - << " commod producer members: " << " produces " - << out_commod << "?: " << ans - << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(commod_) - << " cost: " << cyclus::toolkit::CommodityProducer::Cost(commod_); + ss << cyclus::Facility::str() << " supplies commodity '" << outcommod + << "' with recipe '" << outrecipe << "' at a throughput of " + << throughput << " kg per time step " + << " commod producer members: " + << " produces " << outcommod << "?: " << ans + << " throughput: " << cyclus::toolkit::CommodityProducer::Capacity(outcommod) + << " cost: " << cyclus::toolkit::CommodityProducer::Cost(outcommod); return ss.str(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Source::Tick() { - LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is ticking {"; - LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity - << " kg of " - << out_commod << "."; - LOG(cyclus::LEV_INFO3, "SrcFac") << "Stats: " << str(); - LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; - current_capacity = capacity; // reset capacity -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Source::Tock() { - LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is tocking {"; - LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr Source::GetOffer( - const cyclus::Material::Ptr target) const { - using cyclus::Material; - double qty = std::min(target->quantity(), capacity); - return Material::CreateUntracked(qty, context()->GetRecipe(recipe_name)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -Source::GetMatlBids( +std::set::Ptr> Source::GetMatlBids( cyclus::CommodMap::type& commod_requests) { using cyclus::Bid; using cyclus::BidPortfolio; @@ -111,59 +60,62 @@ Source::GetMatlBids( using cyclus::Material; using cyclus::Request; - std::set::Ptr> ports; - - if (commod_requests.count(out_commod) > 0) { - BidPortfolio::Ptr port(new BidPortfolio()); + double max_qty = std::min(throughput, inventory_size); + LOG(cyclus::LEV_INFO3, "Source") << prototype() << " is bidding up to " + << max_qty << " kg of " << outcommod; + LOG(cyclus::LEV_INFO5, "Source") << "stats: " << str(); - std::vector*>& requests = - commod_requests[out_commod]; + std::set::Ptr> ports; + if (max_qty < cyclus::eps()) { + return ports; + } else if (commod_requests.count(outcommod) == 0) { + return ports; + } - std::vector*>::iterator it; - for (it = requests.begin(); it != requests.end(); ++it) { - Request* req = *it; - Material::Ptr offer = GetOffer(req->target()); - port->AddBid(req, offer, this); + BidPortfolio::Ptr port(new BidPortfolio()); + std::vector*>& requests = commod_requests[outcommod]; + std::vector*>::iterator it; + for (it = requests.begin(); it != requests.end(); ++it) { + Request* req = *it; + Material::Ptr target = req->target(); + double qty = std::min(target->quantity(), max_qty); + Material::Ptr m = Material::CreateUntracked(qty, target->comp()); + if (!outrecipe.empty()) { + m = Material::CreateUntracked(qty, context()->GetRecipe(outrecipe)); } - - CapacityConstraint cc(capacity); - port->AddConstraint(cc); - ports.insert(port); + port->AddBid(req, m, this); } + + CapacityConstraint cc(max_qty); + port->AddConstraint(cc); + ports.insert(port); return ports; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Source::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, + const std::vector >& trades, std::vector, cyclus::Material::Ptr> >& responses) { using cyclus::Material; using cyclus::Trade; - double provided = 0; - std::vector< cyclus::Trade >::const_iterator it; + std::vector >::const_iterator it; for (it = trades.begin(); it != trades.end(); ++it) { double qty = it->amt; - current_capacity -= qty; - provided += qty; - // @TODO we need a policy on negatives.. - Material::Ptr response = Material::Create(this, qty, - context()->GetRecipe(recipe_name)); + inventory_size -= qty; + + Material::Ptr response; + if (!outrecipe.empty()) { + response = Material::Create(this, qty, context()->GetRecipe(outrecipe)); + } else { + response = Material::Create(this, qty, it->request->target()->comp()); + } responses.push_back(std::make_pair(*it, response)); - LOG(cyclus::LEV_INFO5, "SrcFac") << prototype() << " just received an order" - << " for " << qty - << " of " << out_commod; - } - if (cyclus::IsNegative(current_capacity)) { - std::stringstream ss; - ss << "is being asked to provide " << provided - << " but its capacity is " << capacity << "."; - throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); + LOG(cyclus::LEV_INFO5, "Source") << prototype() << " sent an order" + << " for " << qty << " of " << outcommod; } } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - extern "C" cyclus::Agent* ConstructSource(cyclus::Context* ctx) { return new Source(ctx); } diff --git a/src/source.h b/src/source.h index 9331128d2f..32775f3575 100644 --- a/src/source.h +++ b/src/source.h @@ -10,193 +10,99 @@ namespace cycamore { class Context; -/// @class Source -/// This cyclus::Facility provides a simple source of some capacity -/// (possibly infinite) of some commodity/Recipe. - -/// The Source class inherits from the cyclus::Facility class and is -/// dynamically loaded by the Agent class when requested. - -/// @section introduction Introduction -/// The Source is a facility type in Cyclus capable of providing -/// a finite or infinite.Supply of a particular material to the -/// simulation. A Source generates material of a certain -/// composition and commodity type, then offers that material on the -/// appropriate market. Shipments of this material are executed when the -/// market issues an order that the offer has been matched with a -/// request. - -/// @section agentparams Agent Parameters -/// Source behavior is comprehensively defined by the following -/// parameters: -/// - double capacity: The production capacity of the facility (units -/// vary, but typically kg/month). Capacity is infinite if a negative -/// value is provided. -/// - int startDate: The date on which the facility begins to operate -/// (months). -/// - int lifeTime: The length of time that the facility operates -/// (months). - std::string outCommod: the commodity that this facility -/// produces - double inventorysize: the maximum quantity of material to -/// be held in the inventory -/// - double commodprice: the price of the output material PER UNIT -/// - map outComp - -/// @section optionalparams Optional Parameters -/// Source behavior may also be specified with the following -/// optional parameters which have default values listed here. -/// - double capacityFactor: The ratio of actual production capacity to -/// the rated production capacity. Default is 1 (actual/rated). -/// - double availFactor: The percent of time the facility operates at -/// its capacity factor. Default is 100%. -/// - double capitalCost: The cost of constructing and commissioning -/// this facility. Default is 0 ($). -/// - double opCost: The annual cost of operation and maintenance of -/// this facility. Default is 0 ( $/year). -/// - int constrTime: The number of months it takes to construct and -/// commission this facility. Default is 0 (months). -/// - int decomTime: The number of months it takes to deconstruct and -/// decommission this facility. Default is 0 (months). -/// - Inst* inst: The institution responsible for this facility. -/// - string name: A non-generic name for this facility. - -/// @section detailed Detailed Behavior -/// @subsection finite If Finite Capacity: -/// The Source starts operation when the simulation reaches the -/// month specified as the startDate. It immediately begins to produce -/// material at the rate defined by its capacity. Each month the -/// Source adds the amount it has produced to its inventory. It -/// then offers to the appropriate market exactly as much material as it -/// has in its inventory. If an offer is matched with a request, the -/// Source executes that order by subtracting the quantity from -/// its inventory and sending that amount to the requesting facility. -/// When the simulation time equals the startDate plus the lifeTime, the -/// facility ceases to operate. -/// @subsection infinite If Infinite Capacity: -/// The Source starts operation when the simulation reaches the -/// month specified as the startDate. Each month the Source -/// offers an infinite amount of material to the appropriate market. If -/// there is a request for that material, the Source executes -/// that order by sending that amount to the requesting facility. When -/// the simulation time equals the startDate plus the lifeTime, the -/// facility ceases to operate. - -/// @subsection question Question: -/// What is the best way to allow offers of an infinite amount of -/// material on a market? - +/// This facility acts as a source of material with a fixed throughput (per +/// time step) capacity and a lifetime capacity defined by a total inventory +/// size. It offers its material as a single commodity. If a composition +/// recipe is specified, it provides that single material composition to +/// requesters. If unspecified, the source provides materials with the exact +/// requested compositions. The inventory size and throughput both default to +/// infinite. Supplies material results in corresponding decrease in +/// inventory, and when the inventory size reaches zero, the source can provide +/// no more material. class Source : public cyclus::Facility, public cyclus::toolkit::CommodityProducer { + friend class SourceTest; public: - // --- Module Members --- - /// Constructor for the Source class - /// @param ctx the cyclus context for access to simulation-wide parameters + Source(cyclus::Context* ctx); virtual ~Source(); - #pragma cyclus decl + #pragma cyclus note { \ + "doc": "This facility acts as a source of material with a fixed throughput (per\n" \ + " time step) capacity and a lifetime capacity defined by a total inventory\n" \ + " size. It offers its material as a single commodity. If a composition\n" \ + " recipe is specified, it provides that single material composition to\n" \ + " requesters. If unspecified, the source provides materials with the exact\n" \ + " requested compositions. The inventory size and throughput both default to\n" \ + " infinite. Supplies material results in corresponding decrease in\n" \ + " inventory, and when the inventory size reaches zero, the source can provide\n" \ + " no more material.\n" \ + } - #pragma cyclus note {"doc": "A source facility that provides a " \ - "commodity with a given capacity"} + #pragma cyclus def clone + #pragma cyclus def schema + #pragma cyclus def annotations + #pragma cyclus def infiletodb + #pragma cyclus def snapshot + #pragma cyclus def snapshotinv + #pragma cyclus def initinv - /// Print information about this agent - virtual std::string str(); - // --- + virtual void InitFrom(Source* m); - // --- Agent Members --- - virtual void EnterNotify(); + virtual void InitFrom(cyclus::QueryableBackend* b); - /// Each facility is prompted to do its beginning-of-time-step - /// stuff at the tick of the timer. + virtual void EnterNotify(); - /// @param time is the time to perform the tick - virtual void Tick(); + virtual void Tick() {}; - /// Each facility is prompted to its end-of-time-step - /// stuff on the tock of the timer. + virtual void Tock() {}; - /// @param time is the time to perform the tock - virtual void Tock(); + virtual std::string str(); - /// @brief Responds to each request for this source facility's commodity. - /// If a given request is more than this facility's capacity, it will offer - /// its capacity. virtual std::set::Ptr> GetMatlBids(cyclus::CommodMap::type& commod_requests); - /// @brief respond to each trade with a material made from this facility's - /// recipe - /// - /// @param trades all trades in which this trader is the supplier - /// @param responses a container to populate with responses to each trade virtual void GetMatlTrades( const std::vector< cyclus::Trade >& trades, std::vector, cyclus::Material::Ptr> >& responses); - // --- - - // --- Source Members --- - /// @brief creates a material object to offer to a requester - /// @param target the material target a request desires - cyclus::Material::Ptr GetOffer(const cyclus::Material::Ptr target) const; - - /// sets the output commodity name - /// @param name the commodity name - inline void commodity(std::string name) { out_commod = name; } - /// @return the output commodity - inline std::string commodity() const { return out_commod; } - - /// sets the capacity of a material generated at any given time step - /// @param capacity the production capacity - inline void Capacity(double cap) { - capacity = cap; - current_capacity = capacity; + private: + #pragma cyclus var { \ + "tooltip": "source output commodity", \ + "doc": "Output commodity on which the source offers material.", \ + "uitype": "outcommodity", \ } + std::string outcommod; + + #pragma cyclus var { \ + "tooltip": "name of material recipe to provide", \ + "doc": "Name of composition recipe that this source provides regardless of requested composition." \ + " If empty, source creates and provides whatever compositions are requested.", \ + "default": "", \ + "uitype": "recipe", \ + } + std::string outrecipe; - /// @return the production capacity at any given time step - inline double Capacity() const { return capacity; } - - /// sets the name of the recipe to be produced - /// @param name the recipe name - inline void recipe(std::string name) { recipe_name = name; } - - /// @return the name of the output recipe - inline std::string recipe() const { return recipe_name; } - - /// @return the current timestep's capacity - inline double CurrentCapacity() const { return current_capacity; } + #pragma cyclus var { \ + "default": 1e299, \ + "tooltip": "per time step throughput", \ + "units": "kg/(time step)", \ + "doc": "amount of commodity that can be supplied at each time step", \ + } + double throughput; + + #pragma cyclus var { \ + "doc": "Total amount of material this source has remaining." \ + " Every trade decreases this value by the supplied material quantity'." \ + " When it reaches zero, the source cannot provide any more material.", \ + "default": 1e299, \ + "units": "kg", \ + } + double inventory_size; - private: - cyclus::toolkit::Commodity commod_; - - /// This facility has only one output commodity - #pragma cyclus var {"tooltip": "source output commodity", \ - "doc": "output commodity that the source facility " \ - "supplies", \ - "uitype": "outcommodity"} - std::string out_commod; - - /// Name of the recipe this facility uses. - #pragma cyclus var {"tooltip": "commodity recipe name", \ - "doc": "recipe name for source facility's commodity", \ - "uitype": "recipe"} - std::string recipe_name; - - /// The capacity is defined in terms of the number of units of the - /// recipe that can be provided each time step. A very large number - /// can be provided to represent infinte capacity. - #pragma cyclus var {"default": 1e299, "tooltip": "source capacity", \ - "doc": "amount of commodity that can be supplied " \ - "at each time step"} - double capacity; - - /// The capacity at the current time step - #pragma cyclus var {'derived_init': 'current_capacity = capacity;'} - double current_capacity; - - // --- }; } // namespace cycamore diff --git a/src/source_tests.cc b/src/source_tests.cc index 947dcd429b..eea1d9c38d 100644 --- a/src/source_tests.cc +++ b/src/source_tests.cc @@ -8,7 +8,8 @@ #include "resource_helpers.h" #include "test_context.h" -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +namespace cycamore { + void SourceTest::SetUp() { src_facility = new cycamore::Source(tc.get()); trader = tc.trader(); @@ -16,12 +17,10 @@ void SourceTest::SetUp() { SetUpSource(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void SourceTest::TearDown() { delete src_facility; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void SourceTest::InitParameters() { commod = "commod"; recipe_name = "recipe"; @@ -31,64 +30,28 @@ void SourceTest::InitParameters() { tc.get()->AddRecipe(recipe_name, recipe); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void SourceTest::SetUpSource() { - src_facility->commodity(commod); - src_facility->recipe(recipe_name); - src_facility->Capacity(capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(SourceTest, InitialState) { - EXPECT_EQ(src_facility->Capacity(), capacity); - EXPECT_EQ(src_facility->commodity(), commod); - EXPECT_EQ(src_facility->recipe(), recipe_name); - EXPECT_EQ(src_facility->CurrentCapacity(), capacity); + outcommod(src_facility, commod); + outrecipe(src_facility, recipe_name); + throughput(src_facility, capacity); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TEST_F(SourceTest, Clone) { cyclus::Context* ctx = tc.get(); cycamore::Source* cloned_fac = dynamic_cast (src_facility->Clone()); - EXPECT_EQ(src_facility->commodity(), cloned_fac->commodity()); - EXPECT_EQ(src_facility->Capacity(), cloned_fac->Capacity()); - EXPECT_EQ(src_facility->recipe(), cloned_fac->recipe()); - EXPECT_EQ(src_facility->Capacity(), cloned_fac->CurrentCapacity()); + EXPECT_EQ(outcommod(src_facility), outcommod(cloned_fac)); + EXPECT_EQ(throughput(src_facility), throughput(cloned_fac)); + EXPECT_EQ(outrecipe(src_facility), outrecipe(cloned_fac)); delete cloned_fac; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TEST_F(SourceTest, Print) { EXPECT_NO_THROW(std::string s = src_facility->str()); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(SourceTest, GetOffer) { - using cyclus::Material; - - double qty = capacity - 1; - Material::Ptr mat = cyclus::NewBlankMaterial(qty); - Material::Ptr obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), qty); - EXPECT_EQ(obs_mat->comp(), recipe); - - qty = capacity + 1; - mat = cyclus::NewBlankMaterial(qty); - obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), capacity); - EXPECT_EQ(obs_mat->comp(), recipe); - - qty = capacity; - mat = cyclus::NewBlankMaterial(qty); - obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), capacity); - EXPECT_EQ(obs_mat->comp(), recipe); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TEST_F(SourceTest, AddBids) { using cyclus::Bid; using cyclus::BidPortfolio; @@ -117,7 +80,6 @@ TEST_F(SourceTest, AddBids) { EXPECT_EQ(*constrs.begin(), CapacityConstraint(capacity)); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TEST_F(SourceTest, Response) { using cyclus::Bid; using cyclus::Material; @@ -143,34 +105,24 @@ TEST_F(SourceTest, Response) { trades.push_back(trade); // 1 trade - ASSERT_EQ(src_facility->CurrentCapacity(), capacity); src_facility->GetMatlTrades(trades, responses); EXPECT_EQ(responses.size(), 1); EXPECT_EQ(responses[0].second->quantity(), qty); EXPECT_EQ(responses[0].second->comp(), recipe); // 2 trades, total qty = capacity - ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity - qty); - ASSERT_GT(src_facility->CurrentCapacity() - 2 * qty, -1 * cyclus::eps()); trades.push_back(trade); responses.clear(); EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); EXPECT_EQ(responses.size(), 2); - ASSERT_TRUE(cyclus::AlmostEq(src_facility->CurrentCapacity(), 0)); - - // too much qty, capn! - EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), - cyclus::ValueError); // reset! src_facility->Tick(); - ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity); delete request; delete bid; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - boost::shared_ptr< cyclus::ExchangeContext > SourceTest::GetContext(int nreqs, std::string commod) { using cyclus::Material; @@ -187,7 +139,8 @@ SourceTest::GetContext(int nreqs, std::string commod) { return ec; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +} // namespace cycamore + cyclus::Agent* SourceConstructor(cyclus::Context* ctx) { return new cycamore::Source(ctx); } @@ -199,6 +152,6 @@ static int cyclus_agent_tests_connected = ConnectAgentTests(); #define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected #endif // CYCLUS_AGENT_TESTS_CONNECTED -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INSTANTIATE_TEST_CASE_P(SourceFac, FacilityTests, Values(&SourceConstructor)); INSTANTIATE_TEST_CASE_P(SourceFac, AgentTests, Values(&SourceConstructor)); + diff --git a/src/source_tests.h b/src/source_tests.h index 9eb2aeb400..52413a21e5 100644 --- a/src/source_tests.h +++ b/src/source_tests.h @@ -12,7 +12,8 @@ #include "facility_tests.h" #include "material.h" -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +namespace cycamore { + class SourceTest : public ::testing::Test { public: cyclus::TestContext tc; @@ -27,8 +28,22 @@ class SourceTest : public ::testing::Test { void InitParameters(); void SetUpSource(); - boost::shared_ptr< cyclus::ExchangeContext > - GetContext(int nreqs, std::string commodity); + std::string outrecipe(cycamore::Source* s) { return s->outrecipe; } + std::string outcommod(cycamore::Source* s) { return s->outcommod; } + double throughput(cycamore::Source* s) { return s->throughput; } + + void outrecipe(cycamore::Source* s, std::string recipe) { + s->outrecipe = recipe; + } + void outcommod(cycamore::Source* s, std::string commod) { + s->outcommod = commod; + } + void throughput(cycamore::Source* s, double val) { s->throughput = val; } + + boost::shared_ptr > GetContext( + int nreqs, std::string commodity); }; +} // namespace cycamore + #endif // CYCAMORE_SRC_SOURCE_TESTS_H_ diff --git a/tests/input/growth.xml b/tests/input/growth.xml index 590f04149c..0c38c4c946 100644 --- a/tests/input/growth.xml +++ b/tests/input/growth.xml @@ -30,9 +30,9 @@ Source1 - commodity - commod_recipe - 1.1 + commodity + commod_recipe + 1.1 @@ -41,9 +41,9 @@ Source2 - commodity - commod_recipe - 2 + commodity + commod_recipe + 2 From 356d4b497743213f39df281bbbfcc79748fb3021 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 9 Apr 2015 11:54:27 -0500 Subject: [PATCH 098/314] moved power params --- src/reactor.h | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/reactor.h b/src/reactor.h index aedffb01d5..5452b01892 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -146,6 +146,21 @@ class Reactor : public cyclus::Facility, /// from the spent fuel buffer. std::map PeekSpent(); + + //////////// power params //////////// + #pragma cyclus var { \ + "default": 0, \ + "doc": "Amount of electrical power the facility produces when operating normally.", \ + "units": "MWe", \ + } + double power_cap; + + #pragma cyclus var { \ + "default": "power", \ + "doc": "The name of the 'power' commodity used in conjunction with a deployment curve.", \ + } + std::string power_commod; + //////////// inventory and core params //////////// #pragma cyclus var { \ "doc": "Number of assemblies that constitute a single batch." \ @@ -292,19 +307,6 @@ class Reactor : public cyclus::Facility, // id's to the index for the incommod through which they were received. #pragma cyclus var {"default": {}, "doc": "This should NEVER be set manually."} std::map res_indexes; - - #pragma cyclus var { \ - "default": 0, \ - "doc": "Amount of electrical power the facility produces when operating normally.", \ - "units": "MWe", \ - } - double power_cap; - - #pragma cyclus var { \ - "default": "power", \ - "doc": "The name of the 'power' commodity used in conjunction with a deployment curve.", \ - } - std::string power_commod; }; } // namespace cycamore From ad292c9825dca1e093d48f4796ed8322ad5384a0 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 9 Apr 2015 11:56:22 -0500 Subject: [PATCH 099/314] power_commod->power_name --- src/reactor.cc | 4 ++-- src/reactor.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index 975e392bc3..26b82a644b 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -21,7 +21,7 @@ Reactor::Reactor(cyclus::Context* ctx) refuel_time(0), cycle_step(0), power_cap(0), - power_commod("power"), + power_name("power"), discharged(false) { cyclus::Warn( "the Reactor archetype " @@ -51,7 +51,7 @@ void Reactor::InitFrom(cyclus::QueryableBackend* b) { #pragma cyclus impl initfromdb cycamore::Reactor namespace tk = cyclus::toolkit; - tk::CommodityProducer::Add(tk::Commodity(power_commod), + tk::CommodityProducer::Add(tk::Commodity(power_name), tk::CommodInfo(power_cap, power_cap)); } diff --git a/src/reactor.h b/src/reactor.h index 5452b01892..eb64663777 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -159,7 +159,7 @@ class Reactor : public cyclus::Facility, "default": "power", \ "doc": "The name of the 'power' commodity used in conjunction with a deployment curve.", \ } - std::string power_commod; + std::string power_name; //////////// inventory and core params //////////// #pragma cyclus var { \ From f91ed29c3c24124e533725ebf62519c372439c16 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 9 Apr 2015 12:14:23 -0500 Subject: [PATCH 100/314] same in input files --- input/enrichment/linear_src_enr_rxtr_sink.xml | 2 +- input/enrichment/natu_capacitated.xml | 2 +- input/enrichment/swu_capacitated.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/input/enrichment/linear_src_enr_rxtr_sink.xml b/input/enrichment/linear_src_enr_rxtr_sink.xml index 61a03fd3ff..642586333f 100644 --- a/input/enrichment/linear_src_enr_rxtr_sink.xml +++ b/input/enrichment/linear_src_enr_rxtr_sink.xml @@ -55,7 +55,7 @@ 1 1 - power + power 10 diff --git a/input/enrichment/natu_capacitated.xml b/input/enrichment/natu_capacitated.xml index 542bd34b72..4e4d68cccf 100644 --- a/input/enrichment/natu_capacitated.xml +++ b/input/enrichment/natu_capacitated.xml @@ -55,7 +55,7 @@ 1 1 - power + power 10 diff --git a/input/enrichment/swu_capacitated.xml b/input/enrichment/swu_capacitated.xml index 8fcf64c5a3..0f6281a959 100644 --- a/input/enrichment/swu_capacitated.xml +++ b/input/enrichment/swu_capacitated.xml @@ -56,7 +56,7 @@ 1 1 - power + power 10 From 094e79df4fd89a45da421d64045110157cafefeb Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 8 Apr 2015 22:52:07 -0500 Subject: [PATCH 101/314] simplifying source commodity produce usage --- src/source.cc | 14 ++++---------- src/source.h | 3 --- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/source.cc b/src/source.cc index 8ec1b43f7b..a74a7e275c 100644 --- a/src/source.cc +++ b/src/source.cc @@ -21,19 +21,13 @@ void Source::InitFrom(Source* m) { void Source::InitFrom(cyclus::QueryableBackend* b) { #pragma cyclus impl initfromdb cycamore::Source - cyclus::toolkit::CommodityProducer::Add(outcommod); - cyclus::toolkit::CommodityProducer::SetCapacity(outcommod, throughput); - cyclus::toolkit::CommodityProducer::SetCost(outcommod, throughput); -} - -void Source::EnterNotify() { - Facility::EnterNotify(); - cyclus::toolkit::CommodityProducer::Add(outcommod); - cyclus::toolkit::CommodityProducer::SetCapacity(outcommod, throughput); - cyclus::toolkit::CommodityProducer::SetCost(outcommod, throughput); + namespace tk = cyclus::toolkit; + tk::CommodityProducer::Add(tk::Commodity(outcommod), + tk::CommodInfo(throughput, throughput)); } std::string Source::str() { + namespace tk = cyclus::toolkit; std::stringstream ss; std::string ans; if (cyclus::toolkit::CommodityProducer::Produces( diff --git a/src/source.h b/src/source.h index 32775f3575..90cd9857c0 100644 --- a/src/source.h +++ b/src/source.h @@ -52,8 +52,6 @@ class Source : public cyclus::Facility, virtual void InitFrom(cyclus::QueryableBackend* b); - virtual void EnterNotify(); - virtual void Tick() {}; virtual void Tock() {}; @@ -102,7 +100,6 @@ class Source : public cyclus::Facility, "units": "kg", \ } double inventory_size; - }; } // namespace cycamore From 81f312103dfff648488ad0b280e8fde85d24418d Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 9 Apr 2015 10:03:04 -0500 Subject: [PATCH 102/314] starting to add sql to regression tests --- tests/test_regression.py | 87 ++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 30 deletions(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index a4bdb04616..4b8cc00b47 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -5,12 +5,13 @@ import tables import uuid +import sqlite3 import numpy as np from numpy.testing import assert_array_almost_equal from numpy.testing import assert_almost_equal from nose.tools import assert_equal, assert_true - -from helper import check_cmd, run_cyclus, table_exist, find_ids +import helper +from helper import check_cmd, run_cyclus, table_exist class TestRegression(TestCase): """A base class for all regression tests. A derived class is required for @@ -21,7 +22,9 @@ class TestRegression(TestCase): """ def __init__(self, *args, **kwargs): super(TestRegression, self).__init__(*args, **kwargs) - self.outf = str(uuid.uuid4()) + ".h5" + self.ext = '.sqlite' + self.ext = '.h5' + self.outf = str(uuid.uuid4()) + self.ext self.inf = None def __del__(self): @@ -35,19 +38,48 @@ def setUp(self): "to run regression tests.")) run_cyclus("cyclus", os.getcwd(), self.inf, self.outf) - with tables.open_file(self.outf, mode="r") as f: - # Get specific tables and columns - self.agent_entry = f.get_node("/AgentEntry")[:] - self.agent_exit = f.get_node("/AgentExit")[:] if "/AgentExit" in f \ - else None - self.resources = f.get_node("/Resources")[:] - self.transactions = f.get_node("/Transactions")[:] - self.compositions = f.get_node("/Compositions")[:] - self.info = f.get_node("/Info")[:] + # Get specific tables and columns + if self.ext == '.h5': + with tables.open_file(self.outf, mode="r") as f: + # Get specific tables and columns + self.agent_entry = f.get_node("/AgentEntry")[:] + self.agent_exit = f.get_node("/AgentExit")[:] if "/AgentExit" in f \ + else None + self.resources = f.get_node("/Resources")[:] + self.transactions = f.get_node("/Transactions")[:] + self.compositions = f.get_node("/Compositions")[:] + self.info = f.get_node("/Info")[:] + self.rsrc_qtys = { + x["ResourceId"]: x["Quantity"] for x in self.resources} + else: + self.conn = sqlite3.connect(self.outf) + self.conn.row_factory = sqlite3.Row + self.cur = self.conn.cursor() + self.agent_entry = self.cur.execute('SELECT * FROM AgentEntry').fetchall() + self.agent_exit = self.cur.execute('SELECT * FROM AgentExit').fetchall() + self.resources = self.cur.execute('SELECT * FROM Resources').fetchall() + print(self.resources, self.resources[0]['ResourceId']) + self.transactions = self.cur.execute('SELECT * FROM Transactions').fetchall() + self.compositions = self.cur.execute('SELECT * FROM Compositions').fetchall() + self.info = self.cur.execute('SELECT * FROM Info').fetchall() self.rsrc_qtys = { x["ResourceId"]: x["Quantity"] for x in self.resources} + + def find_ids(self, spec, a, spec_col="Spec", id_col="AgentId"): + if self.ext == '.h5': + return helper.find_ids(spec, a[spec_col], a[id_col]) + else: + pass + + def to_array(self, a, k): + if self.ext == 'sqlite': + return [x[k] for x in a] + else: + return a[k] def tearDown(self): + if self.ext == '.sqlite': + self.conn.close() if os.path.isfile(self.outf): print("removing {0}".format(self.outf)) os.remove(self.outf) @@ -64,10 +96,8 @@ def __init__(self, *args, **kwargs): def setUp(self): super(TestPhysorEnrichment, self).setUp() tbl = self.agent_entry - self.rx_id = find_ids(":cycamore:Reactor", - tbl["Spec"], tbl["AgentId"]) - self.enr_id = find_ids(":cycamore:EnrichmentFacility", - tbl["Spec"], tbl["AgentId"]) + self.rx_id = self.find_ids(":cycamore:Reactor", tbl) + self.enr_id = self.find_ids(":cycamore:EnrichmentFacility", tbl) with tables.open_file(self.outf, mode="r") as f: self.enrichments = f.get_node("/Enrichments")[:] @@ -131,11 +161,9 @@ def setUp(self): # identify each reactor and supplier by id tbl = self.agent_entry - rx_id = find_ids(":cycamore:Reactor", - tbl["Spec"], tbl["AgentId"]) + rx_id = self.find_ids(":cycamore:Reactor", tbl) self.r1, self.r2, self.r3 = tuple(rx_id) - s_id = find_ids(":cycamore:Source", - tbl["Spec"], tbl["AgentId"]) + s_id = self.find_ids(":cycamore:Source", tbl) self.smox = self.transactions[0]["SenderId"] s_id.remove(self.smox) self.suox = s_id[0] @@ -219,14 +247,13 @@ def setUp(self): super(TestDynamicCapacitated, self).setUp() # Find agent ids of source and sink facilities - self.agent_ids = self.agent_entry["AgentId"] - self.agent_impl = self.agent_entry["Spec"] - self.depl_time = self.agent_entry["EnterTime"] - self.exit_time = self.agent_exit["ExitTime"] - self.exit_ids = self.agent_exit["AgentId"] - self.source_id = find_ids(":agents:Source", self.agent_impl, - self.agent_ids) - self.sink_id = find_ids(":agents:Sink", self.agent_impl, self.agent_ids) + self.agent_ids = self.to_array(self.agent_entry, "AgentId") + self.agent_impl = self.to_array(self.agent_entry, "Spec") + self.depl_time = self.to_array(self.agent_entry, "EnterTime") + self.exit_time = self.to_array(self.agent_exit, "ExitTime") + self.exit_ids = self.to_array(self.agent_exit, "AgentId") + self.source_id = self.find_ids(":agents:Source", self.agent_entry) + self.sink_id = self.find_ids(":agents:Sink", self.agent_entry) # Check transactions self.sender_ids = self.transactions["SenderId"] @@ -321,8 +348,8 @@ def test_deployment(self): proto = self.agent_entry["Prototype"] depl_time = self.agent_entry["EnterTime"] - source1_id = find_ids("Source1", proto, agent_ids) - source2_id = find_ids("Source2", proto, agent_ids) + source1_id = self.find_ids("Source1", self.agent_entry, spec_col="Prototype") + source2_id = self.find_ids("Source2", self.agent_entry, spec_col="Prototype") assert_equal(len(source2_id), 1) assert_equal(len(source1_id), 2) From 265d513cce83490e51f6697b49a8367b1a501677 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 9 Apr 2015 10:14:40 -0500 Subject: [PATCH 103/314] pass for test growth --- tests/test_regression.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index 4b8cc00b47..848a483726 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -23,7 +23,7 @@ class TestRegression(TestCase): def __init__(self, *args, **kwargs): super(TestRegression, self).__init__(*args, **kwargs) self.ext = '.sqlite' - self.ext = '.h5' + # self.ext = '.h5' self.outf = str(uuid.uuid4()) + self.ext self.inf = None @@ -56,7 +56,9 @@ def setUp(self): self.conn.row_factory = sqlite3.Row self.cur = self.conn.cursor() self.agent_entry = self.cur.execute('SELECT * FROM AgentEntry').fetchall() - self.agent_exit = self.cur.execute('SELECT * FROM AgentExit').fetchall() + print(self.agent_entry[0]['Prototype']) + print(self.cur.execute("SELECT * FROM sqlite_master WHERE type='table' AND name='AgentExit'").fetchall()) + self.agent_exit = self.cur.execute('SELECT * FROM AgentExit').fetchall() if len(self.cur.execute("SELECT * FROM sqlite_master WHERE type='table' AND name='AgentExit'").fetchall()) > 0 else None self.resources = self.cur.execute('SELECT * FROM Resources').fetchall() print(self.resources, self.resources[0]['ResourceId']) self.transactions = self.cur.execute('SELECT * FROM Transactions').fetchall() @@ -69,11 +71,13 @@ def find_ids(self, spec, a, spec_col="Spec", id_col="AgentId"): if self.ext == '.h5': return helper.find_ids(spec, a[spec_col], a[id_col]) else: - pass + return [x[id_col] for x in a if x[spec_col] == spec] def to_array(self, a, k): - if self.ext == 'sqlite': - return [x[k] for x in a] + if self.ext == '.sqlite': + print('to_array', a, k) + print([x[k] for x in a]) + return np.array([x[k] for x in a]) else: return a[k] @@ -344,9 +348,9 @@ def __init__(self, *args, **kwargs): self.inf = "./input/growth.xml" def test_deployment(self): - agent_ids = self.agent_entry["AgentId"] - proto = self.agent_entry["Prototype"] - depl_time = self.agent_entry["EnterTime"] + agent_ids = self.to_array(self.agent_entry, "AgentId") + proto = self.to_array(self.agent_entry, "Prototype") + depl_time = self.to_array(self.agent_entry, "EnterTime") source1_id = self.find_ids("Source1", self.agent_entry, spec_col="Prototype") source2_id = self.find_ids("Source2", self.agent_entry, spec_col="Prototype") From d5b49c882c8e79e220a97ec357e23e8ebea4691f Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 9 Apr 2015 10:17:53 -0500 Subject: [PATCH 104/314] dyn cap done --- tests/test_regression.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index 848a483726..c51f31bd6a 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -260,14 +260,14 @@ def setUp(self): self.sink_id = self.find_ids(":agents:Sink", self.agent_entry) # Check transactions - self.sender_ids = self.transactions["SenderId"] - self.receiver_ids = self.transactions["ReceiverId"] - self.trans_time = self.transactions["Time"] - self.trans_resource = self.transactions["ResourceId"] + self.sender_ids = self.to_array(self.transactions, "SenderId") + self.receiver_ids = self.to_array(self.transactions, "ReceiverId") + self.trans_time = self.to_array(self.transactions, "Time") + self.trans_resource = self.to_array(self.transactions, "ResourceId") # Track transacted resources - self.resource_ids = self.resources["ResourceId"] - self.quantities = self.resources["Quantity"] + self.resource_ids = self.to_array(self.resources, "ResourceId") + self.quantities = self.to_array(self.resources, "Quantity") def test_source_deployment(self): # test number of sources From 8e2fb54fcf7dd7e13c14f721b95f2ba938543d67 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 9 Apr 2015 10:25:32 -0500 Subject: [PATCH 105/314] enr works except xactions --- tests/test_regression.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index c51f31bd6a..e9ddb3c808 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -45,6 +45,8 @@ def setUp(self): self.agent_entry = f.get_node("/AgentEntry")[:] self.agent_exit = f.get_node("/AgentExit")[:] if "/AgentExit" in f \ else None + self.enrichments = f.get_node("/Enrichments")[:] if "/Enrichments" in f \ + else None self.resources = f.get_node("/Resources")[:] self.transactions = f.get_node("/Transactions")[:] self.compositions = f.get_node("/Compositions")[:] @@ -56,11 +58,12 @@ def setUp(self): self.conn.row_factory = sqlite3.Row self.cur = self.conn.cursor() self.agent_entry = self.cur.execute('SELECT * FROM AgentEntry').fetchall() - print(self.agent_entry[0]['Prototype']) - print(self.cur.execute("SELECT * FROM sqlite_master WHERE type='table' AND name='AgentExit'").fetchall()) + # print(self.agent_entry[0]['Prototype']) + # print(self.cur.execute("SELECT * FROM sqlite_master WHERE type='table' AND name='AgentExit'").fetchall()) self.agent_exit = self.cur.execute('SELECT * FROM AgentExit').fetchall() if len(self.cur.execute("SELECT * FROM sqlite_master WHERE type='table' AND name='AgentExit'").fetchall()) > 0 else None + self.enrichments = self.cur.execute('SELECT * FROM Enrichments').fetchall() if len(self.cur.execute("SELECT * FROM sqlite_master WHERE type='table' AND name='Enrichments'").fetchall()) > 0 else None self.resources = self.cur.execute('SELECT * FROM Resources').fetchall() - print(self.resources, self.resources[0]['ResourceId']) + # print(self.resources, self.resources[0]['ResourceId']) self.transactions = self.cur.execute('SELECT * FROM Transactions').fetchall() self.compositions = self.cur.execute('SELECT * FROM Compositions').fetchall() self.info = self.cur.execute('SELECT * FROM Info').fetchall() @@ -75,8 +78,8 @@ def find_ids(self, spec, a, spec_col="Spec", id_col="AgentId"): def to_array(self, a, k): if self.ext == '.sqlite': - print('to_array', a, k) - print([x[k] for x in a]) + # print('to_array', a, k) + # print([x[k] for x in a]) return np.array([x[k] for x in a]) else: return a[k] @@ -103,9 +106,6 @@ def setUp(self): self.rx_id = self.find_ids(":cycamore:Reactor", tbl) self.enr_id = self.find_ids(":cycamore:EnrichmentFacility", tbl) - with tables.open_file(self.outf, mode="r") as f: - self.enrichments = f.get_node("/Enrichments")[:] - def test_deploy(self): assert_equal(len(self.rx_id), 2) assert_equal(len(self.enr_id), 1) @@ -116,7 +116,7 @@ def test_swu(self): # enrichment module from python # with old BatchReactor: exp = [6.9, 10, 4.14, 6.9] exp = [6.9, 10., 4.14, 6.9] - obs = [np.sum(enr["SWU"][enr["Time"] == t]) for t in range(4)] + obs = [np.sum(self.to_array(enr, "SWU")[self.to_array(enr, "Time") == t]) for t in range(4)] assert_array_almost_equal(exp, obs, decimal=2) def test_nu(self): From d9ca202d7c9d1dd4dfb7e1113b2201c23df29ca4 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 9 Apr 2015 10:30:03 -0500 Subject: [PATCH 106/314] physor now works --- tests/test_regression.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index e9ddb3c808..758684054d 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -126,8 +126,7 @@ def test_nu(self): # with old BatchReactor: exp = [13.03, 16.54, 7.83, 13.03] exp = [13.03, 16.55, 7.82, 13.03] - obs = [np.sum(enr["Natural_Uranium"][enr["Time"] == t]) \ - for t in range(4)] + obs = [np.sum(self.to_array(enr, "Natural_Uranium")[self.to_array(enr, "Time") == t]) for t in range(4)] assert_array_almost_equal(exp, obs, decimal=2) def test_xactions(self): From 223866d68c64da3acb65ad9163031ebd7961f987 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 9 Apr 2015 10:34:03 -0500 Subject: [PATCH 107/314] run hdf5 on linux --- tests/test_regression.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index 758684054d..bf33d9d8d2 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -1,6 +1,7 @@ #! /usr/bin/env python import os +import platform from unittest import TestCase import tables @@ -22,8 +23,7 @@ class TestRegression(TestCase): """ def __init__(self, *args, **kwargs): super(TestRegression, self).__init__(*args, **kwargs) - self.ext = '.sqlite' - # self.ext = '.h5' + self.ext = '.h5' if platform.system() == 'Linux' else '.sqlite' self.outf = str(uuid.uuid4()) + self.ext self.inf = None From d3f1633be6c25472ddafabd85904e2e832707328 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 9 Apr 2015 10:38:34 -0500 Subject: [PATCH 108/314] pep8 --- tests/test_regression.py | 88 +++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index bf33d9d8d2..922fcdc26c 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -43,9 +43,11 @@ def setUp(self): with tables.open_file(self.outf, mode="r") as f: # Get specific tables and columns self.agent_entry = f.get_node("/AgentEntry")[:] - self.agent_exit = f.get_node("/AgentExit")[:] if "/AgentExit" in f \ + self.agent_exit = f.get_node("/AgentExit")[:] \ + if "/AgentExit" in f \ else None - self.enrichments = f.get_node("/Enrichments")[:] if "/Enrichments" in f \ + self.enrichments = f.get_node("/Enrichments")[:] \ + if "/Enrichments" in f \ else None self.resources = f.get_node("/Resources")[:] self.transactions = f.get_node("/Transactions")[:] @@ -57,16 +59,22 @@ def setUp(self): self.conn = sqlite3.connect(self.outf) self.conn.row_factory = sqlite3.Row self.cur = self.conn.cursor() - self.agent_entry = self.cur.execute('SELECT * FROM AgentEntry').fetchall() - # print(self.agent_entry[0]['Prototype']) - # print(self.cur.execute("SELECT * FROM sqlite_master WHERE type='table' AND name='AgentExit'").fetchall()) - self.agent_exit = self.cur.execute('SELECT * FROM AgentExit').fetchall() if len(self.cur.execute("SELECT * FROM sqlite_master WHERE type='table' AND name='AgentExit'").fetchall()) > 0 else None - self.enrichments = self.cur.execute('SELECT * FROM Enrichments').fetchall() if len(self.cur.execute("SELECT * FROM sqlite_master WHERE type='table' AND name='Enrichments'").fetchall()) > 0 else None - self.resources = self.cur.execute('SELECT * FROM Resources').fetchall() - # print(self.resources, self.resources[0]['ResourceId']) - self.transactions = self.cur.execute('SELECT * FROM Transactions').fetchall() - self.compositions = self.cur.execute('SELECT * FROM Compositions').fetchall() - self.info = self.cur.execute('SELECT * FROM Info').fetchall() + exc = self.cur.execute + self.agent_entry = exc('SELECT * FROM AgentEntry').fetchall() + self.agent_exit = exc('SELECT * FROM AgentExit').fetchall() \ + if len(exc( + ("SELECT * FROM sqlite_master WHERE " + "type='table' AND name='AgentExit'")).fetchall()) > 0 \ + else None + self.enrichments = exc('SELECT * FROM Enrichments').fetchall() \ + if len(exc( + ("SELECT * FROM sqlite_master WHERE " + "type='table' AND name='Enrichments'")).fetchall()) > 0 \ + else None + self.resources = exc('SELECT * FROM Resources').fetchall() + self.transactions = exc('SELECT * FROM Transactions').fetchall() + self.compositions = exc('SELECT * FROM Compositions').fetchall() + self.info = exc('SELECT * FROM Info').fetchall() self.rsrc_qtys = { x["ResourceId"]: x["Quantity"] for x in self.resources} @@ -76,10 +84,8 @@ def find_ids(self, spec, a, spec_col="Spec", id_col="AgentId"): else: return [x[id_col] for x in a if x[spec_col] == spec] - def to_array(self, a, k): + def to_ary(self, a, k): if self.ext == '.sqlite': - # print('to_array', a, k) - # print([x[k] for x in a]) return np.array([x[k] for x in a]) else: return a[k] @@ -116,7 +122,8 @@ def test_swu(self): # enrichment module from python # with old BatchReactor: exp = [6.9, 10, 4.14, 6.9] exp = [6.9, 10., 4.14, 6.9] - obs = [np.sum(self.to_array(enr, "SWU")[self.to_array(enr, "Time") == t]) for t in range(4)] + obs = [np.sum(self.to_ary(enr, "SWU")[ + self.to_ary(enr, "Time") == t]) for t in range(4)] assert_array_almost_equal(exp, obs, decimal=2) def test_nu(self): @@ -126,7 +133,8 @@ def test_nu(self): # with old BatchReactor: exp = [13.03, 16.54, 7.83, 13.03] exp = [13.03, 16.55, 7.82, 13.03] - obs = [np.sum(self.to_array(enr, "Natural_Uranium")[self.to_array(enr, "Time") == t]) for t in range(4)] + obs = [np.sum(self.to_ary(enr, "Natural_Uranium")[ + self.to_ary(enr, "Time") == t]) for t in range(4)] assert_array_almost_equal(exp, obs, decimal=2) def test_xactions(self): @@ -250,23 +258,23 @@ def setUp(self): super(TestDynamicCapacitated, self).setUp() # Find agent ids of source and sink facilities - self.agent_ids = self.to_array(self.agent_entry, "AgentId") - self.agent_impl = self.to_array(self.agent_entry, "Spec") - self.depl_time = self.to_array(self.agent_entry, "EnterTime") - self.exit_time = self.to_array(self.agent_exit, "ExitTime") - self.exit_ids = self.to_array(self.agent_exit, "AgentId") + self.agent_ids = self.to_ary(self.agent_entry, "AgentId") + self.agent_impl = self.to_ary(self.agent_entry, "Spec") + self.depl_time = self.to_ary(self.agent_entry, "EnterTime") + self.exit_time = self.to_ary(self.agent_exit, "ExitTime") + self.exit_ids = self.to_ary(self.agent_exit, "AgentId") self.source_id = self.find_ids(":agents:Source", self.agent_entry) self.sink_id = self.find_ids(":agents:Sink", self.agent_entry) # Check transactions - self.sender_ids = self.to_array(self.transactions, "SenderId") - self.receiver_ids = self.to_array(self.transactions, "ReceiverId") - self.trans_time = self.to_array(self.transactions, "Time") - self.trans_resource = self.to_array(self.transactions, "ResourceId") + self.sender_ids = self.to_ary(self.transactions, "SenderId") + self.receiver_ids = self.to_ary(self.transactions, "ReceiverId") + self.trans_time = self.to_ary(self.transactions, "Time") + self.trans_resource = self.to_ary(self.transactions, "ResourceId") # Track transacted resources - self.resource_ids = self.to_array(self.resources, "ResourceId") - self.quantities = self.to_array(self.resources, "Quantity") + self.resource_ids = self.to_ary(self.resources, "ResourceId") + self.quantities = self.to_ary(self.resources, "Quantity") def test_source_deployment(self): # test number of sources @@ -282,16 +290,20 @@ def test_sink_deployment(self): # and decommissioned at time step 2 for i in [0, 1]: assert_equal( - self.depl_time[np.where(self.agent_ids == self.sink_id[i])][0], 1) + self.depl_time[np.where(self.agent_ids == self.sink_id[i])][0], + 1) assert_equal( - self.exit_time[np.where(self.exit_ids == self.sink_id[i])][0], 2) + self.exit_time[np.where(self.exit_ids == self.sink_id[i])][0], + 2) # Test that second 2 sink facilities are deployed at time step 2 # and decommissioned at time step 3 for i in [2, 3]: assert_equal( - self.depl_time[np.where(self.agent_ids == self.sink_id[i])][0], 2) + self.depl_time[np.where(self.agent_ids == self.sink_id[i])][0], + 2) assert_equal( - self.exit_time[np.where(self.exit_ids == self.sink_id[i])][0], 3) + self.exit_time[np.where(self.exit_ids == self.sink_id[i])][0], + 3) def test_xaction_general(self): # Check that transactions are between sources and sinks only @@ -347,12 +359,14 @@ def __init__(self, *args, **kwargs): self.inf = "./input/growth.xml" def test_deployment(self): - agent_ids = self.to_array(self.agent_entry, "AgentId") - proto = self.to_array(self.agent_entry, "Prototype") - depl_time = self.to_array(self.agent_entry, "EnterTime") + agent_ids = self.to_ary(self.agent_entry, "AgentId") + proto = self.to_ary(self.agent_entry, "Prototype") + depl_time = self.to_ary(self.agent_entry, "EnterTime") - source1_id = self.find_ids("Source1", self.agent_entry, spec_col="Prototype") - source2_id = self.find_ids("Source2", self.agent_entry, spec_col="Prototype") + source1_id = self.find_ids("Source1", self.agent_entry, + spec_col="Prototype") + source2_id = self.find_ids("Source2", self.agent_entry, + spec_col="Prototype") assert_equal(len(source2_id), 1) assert_equal(len(source1_id), 2) From dc584d59dd459817f2f0d1a0c5c23ed9d8df5ddd Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Fri, 16 Jan 2015 15:42:36 -0600 Subject: [PATCH 109/314] first cut at checking EF input composition --- src/enrichment_facility.cc | 62 ++++++++++++++++++++++++++++++++------ src/enrichment_facility.h | 47 +++++++++++++++++++++-------- 2 files changed, 87 insertions(+), 22 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 87976a78ab..85fecc7161 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -14,12 +14,14 @@ namespace cycamore { EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) : cyclus::Facility(ctx), tails_assay(0), - feed_assay(0), + feed_assay(0), ///***DO we make Feed Assay derived at line 142??? swu_capacity(0), + // max_enrich(0), ///*** initial_reserves(0), in_commod(""), in_recipe(""), - out_commod("") {} + out_commod(""){} //, + // tails_commod{} /// *** // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EnrichmentFacility::~EnrichmentFacility() {} @@ -34,6 +36,7 @@ std::string EnrichmentFacility::str() { << " * Feed assay: " << FeedAssay() << " * Input cyclus::Commodity: " << in_commodity() << " * Output cyclus::Commodity: " << out_commodity(); + // << " * Tails cyclus::Commodity: " << tails_commodity(); ///*** return ss.str(); } @@ -99,6 +102,8 @@ void EnrichmentFacility::AcceptMatlTrades( } } + ///*** Here is where we check material composition *** + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - std::set::Ptr> EnrichmentFacility::GetMatlBids( @@ -110,6 +115,8 @@ EnrichmentFacility::GetMatlBids( using cyclus::Material; using cyclus::Request; + /// *** add a similar function for tails bids? *** + std::set::Ptr> ports; if (commod_requests.count(out_commod) > 0 && inventory.quantity() > 0) { @@ -127,8 +134,15 @@ EnrichmentFacility::GetMatlBids( } } - Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); - Converter::Ptr nc(new NatUConverter(feed_assay, tails_assay)); + /// *** Need to calculate what actual feed assay is (U235 fraction + ///in unenriched inventory -- currently is calculating based on + /// input recipe instead ) rather than using hard-coded value + Material::Ptr fission_matl=inventory.Pop(inventory.quantity()); + inventory.Push(fission_matl); + double my_feed_assay=cyclus::toolkit::UraniumAssay(fission_matl); //TODO ** change var to feed_assay?? + + Converter::Ptr sc(new SWUConverter(my_feed_assay, tails_assay)); + Converter::Ptr nc(new NatUConverter(my_feed_assay, tails_assay)); CapacityConstraint swu(swu_capacity, sc); CapacityConstraint natu(inventory.quantity(), nc); port->AddConstraint(swu); @@ -153,7 +167,7 @@ bool EnrichmentFacility::ValidReq(const cyclus::Material::Ptr mat) { double u238 = q.atom_frac(922380000); return (u238 > 0 && u235 / (u235 + u238) > TailsAssay()); } - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentFacility::GetMatlTrades( const std::vector< cyclus::Trade >& trades, @@ -180,16 +194,44 @@ void EnrichmentFacility::GetMatlTrades( + " is being asked to provide more than its SWU capacity."); } } - + /// *** Add similar for tails ? **** + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { - if (mat->comp() != context()->GetRecipe(in_recipe)) { + double threshold = 0.001; /// TODO *** What is a reasonable threshold? + cyclus::toolkit::MatQuery q = MatQuery(mat) ; + if (! bool cyclus::toolkit::MatQuery::AlmostEq(context()-> + GetRecipe(in_recipe), threshold)){ throw cyclus::ValueError( "EnrichmentFacility recipe and material composition not the same."); } + // Elements and isotopes other than U-235, U-238 are sent directly to tails + cyclus::CompMap cm = mat->comp()->atom(); + double u_other, non_u ; + for (cyclus::CompMap::const_iterator it=cm.begin(); it !=cm.end; ++it) { + if (pyne::nucname::znum(it->first) == 92){ + if (pyne::nucname::anum(it->first) != 235 && + pyne::nucname::anum(it->first) != 238 ){ + u_other +=it->second.atom_frac(); + } + } + else { + u_other +=it->second.atom_frac() ; + } + } + if (u_other > 0.0){ + cyclus::Warn("More than 2 isotopes of U." \ + "Istopes other than U-235, U-238 are sent directly to tails."); + } + if (non_u > 0.0){ + cyclus::Warn("Non-uranium elements are " \ + "sent directly to tails."); + } + /// TODO: Add FAIL if non-235/238 quantities are too large + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " is initially holding " - << inventory.quantity() << " total."; + << inventory.quantity() << " total."; try { inventory.Push(mat); @@ -220,7 +262,7 @@ cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { return cyclus::Material::CreateUntracked( mat->quantity(), cyclus::Composition::CreateFromAtom(comp)); } - + /// *** bid for input material or offer of output? // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - cyclus::Material::Ptr EnrichmentFacility::Enrich_( cyclus::Material::Ptr mat, @@ -237,7 +279,7 @@ cyclus::Material::Ptr EnrichmentFacility::Enrich_( Assays assays(FeedAssay(), UraniumAssay(mat), TailsAssay()); double swu_req = SwuRequired(qty, assays); double natu_req = FeedQty(qty, assays); - + // pop amount from inventory and blob it into one material std::vector manifest; try { diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index b0d1bb0eec..88fc62cd44 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -174,7 +174,8 @@ class EnrichmentFacility : public cyclus::Facility { virtual std::set::Ptr> GetMatlBids(cyclus::CommodMap::type& commod_requests); - + /// *** ADD RESPONSE FOR TAILS *** + /// @brief respond to each trade with a material enriched to the appropriate /// level given this facility's inventory /// @@ -203,6 +204,12 @@ class EnrichmentFacility : public cyclus::Facility { inline std::string out_commodity() const { return out_commod; } + // inline void tails_commodity(std::string tails_com) { + // tails_commod = tails_com; + // } /// **** + + // inline std::string tails_commodity() const { return tails_commod; } /// *** + inline void InRecipe(std::string in_rec) { in_recipe = in_rec; } inline std::string InRecipe() const { return in_recipe; } @@ -228,16 +235,20 @@ class EnrichmentFacility : public cyclus::Facility { swu_capacity = capacity; current_swu_capacity = swu_capacity; } + // inline void MaxEnrich(double enrichment) { max_enrich_ = enrichment; } /// *** inline double SwuCapacity() const { return swu_capacity; } inline double CurrentSwuCapacity() const { return current_swu_capacity; } + // inline double MaxEnrich() const { return max_enrich; } /// *** + /// @brief this facility's initial conditions inline void InitialReserves(double qty) { initial_reserves = qty; } inline double InitialReserves() const { return initial_reserves; } - inline const cyclus::toolkit::ResourceBuff& Tails() const { return tails; } + inline const cyclus::toolkit::ResBuf& Tails() const { return tails; } + /// *** relevant to tails buffer (but how?) -- It's not used for anything and can be deleted if we decide to make everything a state variable for testing *** private: /// @brief adds a material into the natural uranium inventory @@ -257,7 +268,8 @@ class EnrichmentFacility : public cyclus::Facility { cyclus::Material::Ptr Offer_(cyclus::Material::Ptr req); cyclus::Material::Ptr Enrich_(cyclus::Material::Ptr mat, double qty); - + /// *** max enrichment? *** + /// @brief records and enrichment with the cyclus::Recorder void RecordEnrichment_(double natural_u, double swu); @@ -273,17 +285,28 @@ class EnrichmentFacility : public cyclus::Facility { "doc": "recipe for enrichment facility's input commodity", \ "uitype": "recipe"} std::string in_recipe; + // #pragma cyclus var {"tooltip": "tails commodity", \ + // "doc": "tails commodity that the enrichment facility supplies", \ +// "uitype": "tailscommodity"} + // std::string tails_commod; /// *** - #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ - "doc": "tails assay from the enrichment process"} - double tails_assay; - #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity", \ - "doc": "separative work unit (SWU) capcity of " \ + #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ + "doc": "tails assay from the enrichment process"} + + double tails_assay; + #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity", \ + "doc": "separative work unit (SWU) capcity of " \ "enrichment facility"} double swu_capacity; - #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size", \ + /* #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size", \ "doc": "maximum inventory capacity of natural uranium in " \ "the enrichment facility"} + double enrich_capacity; + */ + #pragma cyclus var {"default": 100, "tooltip": "maximum allowed enrichment", \ + "doc": "maximum allowed enrichment of uranium product in " \ + "the enrichment facility"} /// *** + double max_inv_size; #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves", \ "doc": "amount of natural uranium stored at the " \ @@ -300,9 +323,9 @@ class EnrichmentFacility : public cyclus::Facility { "doc": "feed assay for the enrichment process"} double feed_assay; #pragma cyclus var {'capacity': 'max_inv_size'} - cyclus::toolkit::ResourceBuff inventory; // of natl u - #pragma cyclus var {} - cyclus::toolkit::ResourceBuff tails; // depleted u + cyclus::toolkit::ResBuf inventory; // of natl u + #pragma cyclus var {} + cyclus::toolkit::ResBuf tails; // depleted u friend class EnrichmentFacilityTest; // --- From c047e9bec05f0d78ab8a3d693c93d5ce2f171425 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 20 Jan 2015 14:01:13 -0600 Subject: [PATCH 110/314] added check for multiple isotopes, still working on tails buffer --- src/enrichment_facility.cc | 78 ++++++-- src/enrichment_facility.cc.old | 320 +++++++++++++++++++++++++++++++++ src/enrichment_facility.h | 16 +- src/enrichment_facility.h.old | 313 ++++++++++++++++++++++++++++++++ tests/run_inputs.py | 153 ++++++++++++++++ 5 files changed, 853 insertions(+), 27 deletions(-) create mode 100644 src/enrichment_facility.cc.old create mode 100644 src/enrichment_facility.h.old create mode 100644 tests/run_inputs.py diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 85fecc7161..5fc30b5ce2 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -1,3 +1,9 @@ +/* +What is the difference between feed_assay and FeedAssay? How do I fix FeedAssay and possibly create a new function? +How do I track the tails material going in and out of trades? Make sure request doesnt exceed inventory? +How do I refer to the tails Material in the bids? +*/ + // Implements the EnrichmentFacility class #include "enrichment_facility.h" @@ -14,14 +20,14 @@ namespace cycamore { EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) : cyclus::Facility(ctx), tails_assay(0), - feed_assay(0), ///***DO we make Feed Assay derived at line 142??? + // feed_assay(0), ///***DO we make Feed Assay derived at line 142??? swu_capacity(0), // max_enrich(0), ///*** initial_reserves(0), in_commod(""), in_recipe(""), - out_commod(""){} //, - // tails_commod{} /// *** + out_commod(""), + tails_commod(""){} /// *** // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EnrichmentFacility::~EnrichmentFacility() {} @@ -33,10 +39,10 @@ std::string EnrichmentFacility::str() { << " with enrichment facility parameters:" << " * SWU capacity: " << SwuCapacity() << " * Tails assay: " << TailsAssay() - << " * Feed assay: " << FeedAssay() + << " * Feed assay: " << FeedAssay() //*** Remove?? ** << " * Input cyclus::Commodity: " << in_commodity() - << " * Output cyclus::Commodity: " << out_commodity(); - // << " * Tails cyclus::Commodity: " << tails_commodity(); ///*** + << " * Output cyclus::Commodity: " << out_commodity() + << " * Tails cyclus::Commodity: " << tails_commodity(); ///*** return ss.str(); } @@ -59,6 +65,9 @@ void EnrichmentFacility::Build(cyclus::Agent* parent) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentFacility::Tick() { LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is ticking {"; + /// LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity + // << " kg of " + // << tails_commod << "."; // *** Not needed since no out_commod notification? LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; current_swu_capacity = SwuCapacity(); } @@ -107,7 +116,7 @@ void EnrichmentFacility::AcceptMatlTrades( // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - std::set::Ptr> EnrichmentFacility::GetMatlBids( - cyclus::CommodMap::type& commod_requests) { + cyclus::CommodMap::type& commod_requests){ using cyclus::Bid; using cyclus::BidPortfolio; using cyclus::CapacityConstraint; @@ -115,10 +124,24 @@ EnrichmentFacility::GetMatlBids( using cyclus::Material; using cyclus::Request; - /// *** add a similar function for tails bids? *** - std::set::Ptr> ports; + // *** Add tails bids here + if (commod_requests.count(tails_commod) > 0 && tails.quantity() > 0) { + BidPortfolio::Ptr port(new BidPortfolio()); // ** What is correct Matl? + std::vector*>& requests = + commod_requests[tails_commod]; + + std::vector*>::iterator it; + for (it = requests.begin(); it != requests.end(); ++it) { + Request* req = *it; + if (ValidReq(req->target())) { + Material::Ptr offer = Offer_(req->target()); + port->AddBid(req, offer, this); + } + } + } + // *** Did I set up this loop correctly or is it missing stuff at the end? if (commod_requests.count(out_commod) > 0 && inventory.quantity() > 0) { BidPortfolio::Ptr port(new BidPortfolio()); @@ -139,10 +162,9 @@ EnrichmentFacility::GetMatlBids( /// input recipe instead ) rather than using hard-coded value Material::Ptr fission_matl=inventory.Pop(inventory.quantity()); inventory.Push(fission_matl); - double my_feed_assay=cyclus::toolkit::UraniumAssay(fission_matl); //TODO ** change var to feed_assay?? - - Converter::Ptr sc(new SWUConverter(my_feed_assay, tails_assay)); - Converter::Ptr nc(new NatUConverter(my_feed_assay, tails_assay)); + double feed_assay=cyclus::toolkit::UraniumAssay(fission_matl); + Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); + Converter::Ptr nc(new NatUConverter(feed_assay, tails_assay)); CapacityConstraint swu(swu_capacity, sc); CapacityConstraint natu(inventory.quantity(), nc); port->AddConstraint(swu); @@ -176,16 +198,31 @@ void EnrichmentFacility::GetMatlTrades( using cyclus::Material; using cyclus::Trade; + double tails_for_trade = 0 ; std::vector< Trade >::const_iterator it; for (it = trades.begin(); it != trades.end(); ++it) { Material::Ptr mat = it->bid->offer(); double qty = it->amt; - Material::Ptr response = Enrich_(mat, qty); - responses.push_back(std::make_pair(*it, response)); - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() - << " just received an order" - << " for " << it->amt - << " of " << out_commod; + if /***matl eq tails*/ { //***Should I be using Tails() here instead? + tails -= qty; + tails_for_trade += qty; + Material::Ptr response = Material::Create(this, qty, + context()->GetRecipe(recipe_name)); + if (cyclus::IsNegative(tails.quantity)) { + std::stringstream ss; + ss << "is being asked to provide " << tails_for_trade + << " but its tails inventory is " << tails << "."; + throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); + } */ //*** Is this how to check whether the tails inventory has been used up? + } + else { + Material::Ptr response = Enrich_(mat, qty); + } + responses.push_back(std::make_pair(*it, response)); + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() + << " just received an order" + << " for " << it->amt + << " of " << out_commod; } if (cyclus::IsNegative(current_swu_capacity)) { @@ -290,6 +327,9 @@ cyclus::Material::Ptr EnrichmentFacility::Enrich_( manifest = ResCast(inventory.PopQty(natu_req)); } } catch (cyclus::Error& e) { + Material::Ptr fission_matl=inventory.Pop(inventory.quantity()); + inventory.Push(fission_matl); + double feed_assay=cyclus::toolkit::UraniumAssay(fission_matl); NatUConverter nc(feed_assay, tails_assay); std::stringstream ss; ss << " tried to remove " << natu_req diff --git a/src/enrichment_facility.cc.old b/src/enrichment_facility.cc.old new file mode 100644 index 0000000000..87976a78ab --- /dev/null +++ b/src/enrichment_facility.cc.old @@ -0,0 +1,320 @@ +// Implements the EnrichmentFacility class +#include "enrichment_facility.h" + +#include +#include +#include +#include + +#include + +namespace cycamore { + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) + : cyclus::Facility(ctx), + tails_assay(0), + feed_assay(0), + swu_capacity(0), + initial_reserves(0), + in_commod(""), + in_recipe(""), + out_commod("") {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +EnrichmentFacility::~EnrichmentFacility() {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::string EnrichmentFacility::str() { + std::stringstream ss; + ss << cyclus::Facility::str() + << " with enrichment facility parameters:" + << " * SWU capacity: " << SwuCapacity() + << " * Tails assay: " << TailsAssay() + << " * Feed assay: " << FeedAssay() + << " * Input cyclus::Commodity: " << in_commodity() + << " * Output cyclus::Commodity: " << out_commodity(); + return ss.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::Build(cyclus::Agent* parent) { + using cyclus::Material; + + Facility::Build(parent); + if (initial_reserves > 0) { + inventory.Push( + Material::Create( + this, initial_reserves, context()->GetRecipe(in_recipe))); + } + + LOG(cyclus::LEV_DEBUG2, "EnrFac") << "EnrichmentFacility " + << " entering the simuluation: "; + LOG(cyclus::LEV_DEBUG2, "EnrFac") << str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::Tick() { + LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is ticking {"; + LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; + current_swu_capacity = SwuCapacity(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::Tock() { + LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is tocking {"; + LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::set::Ptr> +EnrichmentFacility::GetMatlRequests() { + using cyclus::Material; + using cyclus::RequestPortfolio; + using cyclus::Request; + + std::set::Ptr> ports; + RequestPortfolio::Ptr port(new RequestPortfolio()); + Material::Ptr mat = Request_(); + double amt = mat->quantity(); + + if (amt > cyclus::eps()) { + port->AddRequest(mat, this, in_commod); + ports.insert(port); + } + + return ports; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::AcceptMatlTrades( + const std::vector< std::pair, + cyclus::Material::Ptr> >& responses) { + // see + // http://stackoverflow.com/questions/5181183/boostshared-ptr-and-inheritance + std::vector< std::pair, + cyclus::Material::Ptr> >::const_iterator it; + for (it = responses.begin(); it != responses.end(); ++it) { + AddMat_(it->second); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::set::Ptr> +EnrichmentFacility::GetMatlBids( + cyclus::CommodMap::type& commod_requests) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::Converter; + using cyclus::Material; + using cyclus::Request; + + std::set::Ptr> ports; + + if (commod_requests.count(out_commod) > 0 && inventory.quantity() > 0) { + BidPortfolio::Ptr port(new BidPortfolio()); + + std::vector*>& requests = + commod_requests[out_commod]; + + std::vector*>::iterator it; + for (it = requests.begin(); it != requests.end(); ++it) { + Request* req = *it; + if (ValidReq(req->target())) { + Material::Ptr offer = Offer_(req->target()); + port->AddBid(req, offer, this); + } + } + + Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); + Converter::Ptr nc(new NatUConverter(feed_assay, tails_assay)); + CapacityConstraint swu(swu_capacity, sc); + CapacityConstraint natu(inventory.quantity(), nc); + port->AddConstraint(swu); + port->AddConstraint(natu); + + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() + << " adding a swu constraint of " + << swu.capacity(); + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() + << " adding a natu constraint of " + << natu.capacity(); + + ports.insert(port); + } + return ports; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EnrichmentFacility::ValidReq(const cyclus::Material::Ptr mat) { + cyclus::toolkit::MatQuery q(mat); + double u235 = q.atom_frac(922350000); + double u238 = q.atom_frac(922380000); + return (u238 > 0 && u235 / (u235 + u238) > TailsAssay()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses) { + using cyclus::Material; + using cyclus::Trade; + + std::vector< Trade >::const_iterator it; + for (it = trades.begin(); it != trades.end(); ++it) { + Material::Ptr mat = it->bid->offer(); + double qty = it->amt; + Material::Ptr response = Enrich_(mat, qty); + responses.push_back(std::make_pair(*it, response)); + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() + << " just received an order" + << " for " << it->amt + << " of " << out_commod; + } + + if (cyclus::IsNegative(current_swu_capacity)) { + throw cyclus::ValueError( + "EnrFac " + prototype() + + " is being asked to provide more than its SWU capacity."); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { + if (mat->comp() != context()->GetRecipe(in_recipe)) { + throw cyclus::ValueError( + "EnrichmentFacility recipe and material composition not the same."); + } + + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " is initially holding " + << inventory.quantity() << " total."; + + try { + inventory.Push(mat); + } catch (cyclus::Error& e) { + e.msg(Agent::InformErrorMsg(e.msg())); + throw e; + } + + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " added " + << mat->quantity() << " of " << in_commod + << " to its inventory, which is holding " + << inventory.quantity() << " total."; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr EnrichmentFacility::Request_() { + double qty = std::max(0.0, MaxInventorySize() - InventorySize()); + return cyclus::Material::CreateUntracked(qty, + context()->GetRecipe(in_recipe)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { + cyclus::toolkit::MatQuery q(mat); + cyclus::CompMap comp; + comp[922350000] = q.atom_frac(922350000); + comp[922380000] = q.atom_frac(922380000); + return cyclus::Material::CreateUntracked( + mat->quantity(), cyclus::Composition::CreateFromAtom(comp)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr EnrichmentFacility::Enrich_( + cyclus::Material::Ptr mat, + double qty) { + using cyclus::Material; + using cyclus::ResCast; + using cyclus::toolkit::Assays; + using cyclus::toolkit::UraniumAssay; + using cyclus::toolkit::SwuRequired; + using cyclus::toolkit::FeedQty; + using cyclus::toolkit::TailsQty; + + // get enrichment parameters + Assays assays(FeedAssay(), UraniumAssay(mat), TailsAssay()); + double swu_req = SwuRequired(qty, assays); + double natu_req = FeedQty(qty, assays); + + // pop amount from inventory and blob it into one material + std::vector manifest; + try { + // required so popping doesn't take out too much + if (cyclus::AlmostEq(natu_req, inventory.quantity())) { + manifest = ResCast(inventory.PopN(inventory.count())); + } else { + manifest = ResCast(inventory.PopQty(natu_req)); + } + } catch (cyclus::Error& e) { + NatUConverter nc(feed_assay, tails_assay); + std::stringstream ss; + ss << " tried to remove " << natu_req + << " from its inventory of size " << inventory.quantity() + << " and the conversion of the material into natu is " + << nc.convert(mat); + throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); + } + Material::Ptr r = manifest[0]; + for (int i = 1; i < manifest.size(); ++i) { + r->Absorb(manifest[i]); + } + + // "enrich" it, but pull out the composition and quantity we require from the + // blob + cyclus::Composition::Ptr comp = mat->comp(); + Material::Ptr response = r->ExtractComp(qty, comp); + tails.Push(r); // add remainder to tails buffer + + current_swu_capacity -= swu_req; + + RecordEnrichment_(natu_req, swu_req); + + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << + " has performed an enrichment: "; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Feed Qty: " + << natu_req; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Feed Assay: " + << assays.Feed() * 100; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Product Qty: " + << qty; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Product Assay: " + << assays.Product() * 100; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Tails Qty: " + << TailsQty(qty, assays); + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Tails Assay: " + << assays.Tails() * 100; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * SWU: " + << swu_req; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Current SWU capacity: " + << CurrentSwuCapacity(); + + return response; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::RecordEnrichment_(double natural_u, double swu) { + using cyclus::Context; + using cyclus::Agent; + + LOG(cyclus::LEV_DEBUG1, "EnrFac") << prototype() + << " has enriched a material:"; + LOG(cyclus::LEV_DEBUG1, "EnrFac") << " * Amount: " << natural_u; + LOG(cyclus::LEV_DEBUG1, "EnrFac") << " * SWU: " << swu; + + Context* ctx = Agent::context(); + ctx->NewDatum("Enrichments") + ->AddVal("ID", id()) + ->AddVal("Time", ctx->time()) + ->AddVal("Natural_Uranium", natural_u) + ->AddVal("SWU", swu) + ->Record(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +extern "C" cyclus::Agent* ConstructEnrichmentFacility(cyclus::Context* ctx) { + return new EnrichmentFacility(ctx); +} + +} // namespace cycamore diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 88fc62cd44..55686ebbf6 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -204,11 +204,11 @@ class EnrichmentFacility : public cyclus::Facility { inline std::string out_commodity() const { return out_commod; } - // inline void tails_commodity(std::string tails_com) { - // tails_commod = tails_com; - // } /// **** + inline void tails_commodity(std::string tails_com) { + tails_commod = tails_com; + } /// **** - // inline std::string tails_commodity() const { return tails_commod; } /// *** + inline std::string tails_commodity() const { return tails_commod; } /// *** inline void InRecipe(std::string in_rec) { in_recipe = in_rec; } @@ -223,7 +223,7 @@ class EnrichmentFacility : public cyclus::Facility { inline double InventorySize() const { return inventory.quantity(); } - inline void FeedAssay(double assay) { feed_assay = assay; } + // inline void FeedAssay(double assay) { feed_assay = assay; } inline double FeedAssay() const { return feed_assay; } @@ -324,11 +324,11 @@ class EnrichmentFacility : public cyclus::Facility { double feed_assay; #pragma cyclus var {'capacity': 'max_inv_size'} cyclus::toolkit::ResBuf inventory; // of natl u - #pragma cyclus var {} - cyclus::toolkit::ResBuf tails; // depleted u + #pragma cyclus var {} + cyclus::toolkit::ResBuf tails; // depleted u friend class EnrichmentFacilityTest; - // --- + // --- }; } // namespace cycamore diff --git a/src/enrichment_facility.h.old b/src/enrichment_facility.h.old new file mode 100644 index 0000000000..b0d1bb0eec --- /dev/null +++ b/src/enrichment_facility.h.old @@ -0,0 +1,313 @@ +#ifndef CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ +#define CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ + +#include + +#include "cyclus.h" + +namespace cycamore { + +/// @class SWUConverter +/// +/// @brief The SWUConverter is a simple Converter class for material to +/// determine the amount of SWU required for their proposed enrichment +class SWUConverter : public cyclus::Converter { + public: + SWUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} + virtual ~SWUConverter() {} + + /// @brief provides a conversion for the SWU required + virtual double convert( + cyclus::Material::Ptr m, + cyclus::Arc const * a = NULL, + cyclus::ExchangeTranslationContext + const * ctx = NULL) const { + cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), + tails_); + return cyclus::toolkit::SwuRequired(m->quantity(), assays); + } + + /// @returns true if Converter is a SWUConverter and feed and tails equal + virtual bool operator==(Converter& other) const { + SWUConverter* cast = dynamic_cast(&other); + return cast != NULL && + feed_ == cast->feed_ && + tails_ == cast->tails_; + } + + private: + double feed_, tails_; +}; + +/// @class NatUConverter +/// +/// @brief The NatUConverter is a simple Converter class for material to +/// determine the amount of natural uranium required for their proposed +/// enrichment +class NatUConverter : public cyclus::Converter { + public: + NatUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} + virtual ~NatUConverter() {} + + /// @brief provides a conversion for the amount of natural Uranium required + virtual double convert( + cyclus::Material::Ptr m, + cyclus::Arc const * a = NULL, + cyclus::ExchangeTranslationContext + const * ctx = NULL) const { + cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), + tails_); + return cyclus::toolkit::FeedQty(m->quantity(), assays); + } + + /// @returns true if Converter is a NatUConverter and feed and tails equal + virtual bool operator==(Converter& other) const { + NatUConverter* cast = dynamic_cast(&other); + return cast != NULL && + feed_ == cast->feed_ && + tails_ == cast->tails_; + } + + private: + double feed_, tails_; +}; + +/// @class EnrichmentFacility +/// +/// @section introduction Introduction +/// The EnrichmentFacility is a simple Agent to agent the enriching of natural +/// Uranium in a Cyclus simulation. It requests its input recipe (nominally +/// natural Uranium), and produces any amount of enriched Uranium, given the its +/// natural uranium inventory constraint and its SWU capacity constraint. +/// +/// @section requests Requests +/// The EnrichmentFacility will request from the cyclus::ResourceExchange a +/// cyclus::Material whose quantity is its remaining inventory capacity and whose +/// composition is that of its input recipe. +/// +/// @section acctrade Accepting Trades +/// The EnrichmentFacility adds any accepted trades to its inventory. +/// +/// @section bids Bids +/// The EnrichmentFacility will bid on any request for its output commodity. It +/// will bid either the request quantity, or the quanity associated with either +/// its SWU constraint or natural uranium constraint, whichever is lower. +/// +/// @section extrades Executing Trades +/// The EnrichmentFacility will execute trades for its output commodity in the +/// following manner: +/// #. Determine the trade's quantity and product assay +/// #. Determine the natural Uranium and SWU requires to create that product +/// #. Remove the required quantity of natural Uranium from its inventory +/// #. Extract the appropriate composition of enriched Uranium +/// #. Send the enriched Uranium as the trade resource +/// +/// @section gotchas Gotchas +/// #. In its current form, the EnrichmentFacility can only accept +/// cyclus::Material having the composition of its input recipe. If a +/// cyclus::Material of a different composition is sent to it, an exception will +/// be thrown. +/// +/// #. During the trading phase, an exception will be thrown if either the +/// EnrichmentFacility's SWU or inventory constraint is breached. +/// +/// @section improvements Improvments +/// The primary improvement to the EnrichmentFacility would be to relax the +/// requirement that all input material have the in_recipe composition (i.e., +/// allow different base enrichments of Uranium). +/// +/// How would I go about doing so? I'd likely develop an EnrichmentBuffer-type +/// class that can be queried as to its SWU and natural Uranium capacity. +class EnrichmentFacility : public cyclus::Facility { + public: + // --- Module Members --- +/// Constructor for the EnrichmentFacility class +/// @param ctx the cyclus context for access to simulation-wide parameters + EnrichmentFacility(cyclus::Context* ctx); + +/// Destructor for the EnrichmentFacility class + virtual ~EnrichmentFacility(); + + #pragma cyclus + + #pragma cyclus note {"doc": "An enrichment facility that intakes a commodity " \ + "(usually natural uranium) and supplies a user-" \ + "specified enriched product based on SWU capacity", \ + "niche": "enrichment"} + +/// Print information about this agent + virtual std::string str(); + // --- + + // --- Facility Members --- + /// perform module-specific tasks when entering the simulation + virtual void Build(cyclus::Agent* parent); + // --- + + // --- Agent Members --- + /// Each facility is prompted to do its beginning-of-time-step + /// stuff at the tick of the timer. + + /// @param time is the time to perform the tick + virtual void Tick(); + + /// Each facility is prompted to its end-of-time-step + /// stuff on the tock of the timer. + + /// @param time is the time to perform the tock + virtual void Tock(); + + /// @brief The EnrichmentFacility request Materials of its given + /// commodity. + virtual std::set::Ptr> + GetMatlRequests(); + + /// @brief The EnrichmentFacility place accepted trade Materials in their + /// Inventory + virtual void AcceptMatlTrades( + const std::vector< std::pair, + cyclus::Material::Ptr> >& responses); + + /// @brief Responds to each request for this facility's commodity. If a given + /// request is more than this facility's inventory or SWU capacity, it will + /// offer its minimum of its capacities. + virtual std::set::Ptr> + GetMatlBids(cyclus::CommodMap::type& + commod_requests); + + /// @brief respond to each trade with a material enriched to the appropriate + /// level given this facility's inventory + /// + /// @param trades all trades in which this trader is the supplier + /// @param responses a container to populate with responses to each trade + virtual void GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses); + // --- + + // --- EnrichmentFacility Members --- + /// @brief Determines if a particular material is a valid request to respond + /// to. Valid requests must contain U235 and U238 and must have a relative + /// U235-to-U238 ratio less than this facility's tails_assay(). + /// @return true if the above description is met by the material + bool ValidReq(const cyclus::Material::Ptr mat); + + inline void in_commodity(std::string in_com) { in_commod = in_com; } + + inline std::string in_commodity() const { return in_commod; } + + inline void out_commodity(std::string out_com) { + out_commod = out_com; + } + + inline std::string out_commodity() const { return out_commod; } + + inline void InRecipe(std::string in_rec) { in_recipe = in_rec; } + + inline std::string InRecipe() const { return in_recipe; } + + inline void SetMaxInventorySize(double size) { + max_inv_size = size; + inventory.set_capacity(size); + } + + inline double MaxInventorySize() const { return inventory.capacity(); } + + inline double InventorySize() const { return inventory.quantity(); } + + inline void FeedAssay(double assay) { feed_assay = assay; } + + inline double FeedAssay() const { return feed_assay; } + + inline void TailsAssay(double assay) { tails_assay = assay; } + + inline double TailsAssay() const { return tails_assay; } + + inline void SwuCapacity(double capacity) { + swu_capacity = capacity; + current_swu_capacity = swu_capacity; + } + + inline double SwuCapacity() const { return swu_capacity; } + + inline double CurrentSwuCapacity() const { return current_swu_capacity; } + + /// @brief this facility's initial conditions + inline void InitialReserves(double qty) { initial_reserves = qty; } + inline double InitialReserves() const { return initial_reserves; } + + inline const cyclus::toolkit::ResourceBuff& Tails() const { return tails; } + + private: + /// @brief adds a material into the natural uranium inventory + /// @throws if the material is not the same composition as the in_recipe + void AddMat_(cyclus::Material::Ptr mat); + + /// @brief generates a request for this facility given its current state. The + /// quantity of the material will be equal to the remaining inventory size. + cyclus::Material::Ptr Request_(); + + /// @brief Generates a material offer for a given request. The response + /// composition will be comprised only of U235 and U238 at their relative ratio + /// in the requested material. The response quantity will be the same as the + /// requested commodity. + /// + /// @param req the requested material being responded to + cyclus::Material::Ptr Offer_(cyclus::Material::Ptr req); + + cyclus::Material::Ptr Enrich_(cyclus::Material::Ptr mat, double qty); + + /// @brief records and enrichment with the cyclus::Recorder + void RecordEnrichment_(double natural_u, double swu); + + #pragma cyclus var {"tooltip": "input commodity", \ + "doc": "commodity that the enrichment facility accepts", \ + "uitype": "incommodity"} + std::string in_commod; + #pragma cyclus var {"tooltip": "output commodity", \ + "doc": "commodity that the enrichment facility supplies", \ + "uitype": "outcommodity"} + std::string out_commod; + #pragma cyclus var {"tooltip": "input commodity recipe", \ + "doc": "recipe for enrichment facility's input commodity", \ + "uitype": "recipe"} + std::string in_recipe; + + #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ + "doc": "tails assay from the enrichment process"} + double tails_assay; + #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity", \ + "doc": "separative work unit (SWU) capcity of " \ + "enrichment facility"} + double swu_capacity; + #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size", \ + "doc": "maximum inventory capacity of natural uranium in " \ + "the enrichment facility"} + double max_inv_size; + #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves", \ + "doc": "amount of natural uranium stored at the " \ + "enrichment facility at the beginning of the " \ + "simulation"} + double initial_reserves; + #pragma cyclus var {'derived_init': 'current_swu_capacity = swu_capacity;'} + double current_swu_capacity; + #pragma cyclus var {\ + 'derived_init': "cyclus::Material::Ptr feed = "\ + "cyclus::Material::CreateUntracked(0, context()->GetRecipe(in_recipe)); "\ + "feed_assay = cyclus::toolkit::UraniumAssay(feed);", \ + "tooltip": "feed assay", \ + "doc": "feed assay for the enrichment process"} + double feed_assay; + #pragma cyclus var {'capacity': 'max_inv_size'} + cyclus::toolkit::ResourceBuff inventory; // of natl u + #pragma cyclus var {} + cyclus::toolkit::ResourceBuff tails; // depleted u + + friend class EnrichmentFacilityTest; + // --- +}; + +} // namespace cycamore + +#endif // CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ diff --git a/tests/run_inputs.py b/tests/run_inputs.py new file mode 100644 index 0000000000..ceb45c2e9e --- /dev/null +++ b/tests/run_inputs.py @@ -0,0 +1,153 @@ +#!/usr/bin/python + +import sys +import subprocess +from subprocess import Popen, PIPE, STDOUT +import os +import re + +def main(): + """This function finds input files, runs them, and prints a summary""" + flag = check_inputs() + input_path = "/Users/mbmcgarry/git/cycamore/../input" + cyclus_path = "/Users/mbmcgarry/.local/include/cyclus/../../bin/cyclus" + files, catalogs, catalognames = get_files(input_path) + copy_catalogs(catalogs,cyclus_path.strip("cyclus")) + summ = Summary() + for name in files : + file_to_test = TestFile(cyclus_path, name, flag) + file_to_test.run() + summ.add_to_summary(file_to_test) + clean_catalogs(cyclus_path.strip("cyclus"),catalognames) + summ.print_summary() + +def check_inputs(): + """This function checks the input arguments""" + if len(sys.argv) > 2: + print_usage() + sys.exit(1) + elif len(sys.argv) == 2: + if re.search("-v*",sys.argv[1]): + flag = sys.argv[1] + else : + print_usage() + sys.exit(1) + elif len(sys.argv) == 1 : + flag = "-v0" + return flag + +def print_usage() : + """This prints the proper way to treat the command line interface""" + print 'Usage: python run_inputs.py\n' + \ + 'Allowed Options : \n' + \ + '-v arg output log verbosity. \n' + \ + ' \ + Can be text: \n' + \ + ' \ + LEV_ERROR (least verbose, default), LEV_WARN,\n' + \ + ' \ + LEV_INFO1 (through 5), and LEV_DEBUG1 (through 5).\n' + \ + ' \ + Or an integer:\n'+ \ + ' \ + 0 (LEV_ERROR equiv) through 11 (LEV_DEBUG5 equiv)\n' + +def get_files(path): + """This function walks the 'path' tree and finds input files""" + catalogs=[] + catalognames=[] + inputs=[] + for root, dirs, files in os.walk(path, followlinks=True): + if '.git' in dirs: + dirs.remove('.git') + for name in files: + if re.search("\.xml",name) : + if re.search("recipebook",name) or \ + re.search("facilitycatalog",name): + catalogs.append(os.path.join(root,name)) + catalognames.append(name) + else : + inputs.append(os.path.join(root, name)) + else : + files.remove(name) + print "The catalogs to be moved are:" + print catalogs + print "The files to be tested are:" + print inputs + return inputs, catalogs, catalognames + +def copy_catalogs(catalogs,cyclus_path) : + """Copies files in the catalogs list to the cyclus executable directory""" + for cat in catalogs : + p = Popen("cp "+cat+" "+cyclus_path, + shell=True, stdout=PIPE, stderr=STDOUT) + +def clean_catalogs(cyclus_path, catalogs) : + """Removes previously copied catalogs from executable directory.""" + for cat in catalogs : + p = Popen("rm "+ os.path.join(cyclus_path,cat), + shell=True, stdout=PIPE, stderr=STDOUT) + +class Summary(): + """An object to hold the results of all the tests""" + def __init__(self): + self.passed = [] + self.failed = [] + + def add_to_summary(self, test_file) : + """Adds a test file to this summary object""" + if test_file.passed : + self.passed.append( test_file.infile ) + else : + self.failed.append( test_file.infile ) + + def print_summary(self) : + """Prints the summary""" + print "Input files passed = " + str(len(self.passed)) + print "Input files failed = " + str(len(self.failed)) + print "Failed input files : " + for test in self.failed : + print test + +class TestFile(): + """An object representing the inputxml file to test""" + def __init__(self, cyclus_path, file_path, flag): + self.infile = file_path + self.cyclus_path = cyclus_path + self.passed=True + self.flag = " "+flag+" " + + def run(self): + """Runs all of the input file tests""" + output = self.get_output() + if self.no_errors(output) : + self.passed = True + else : + self.passed = False + + def get_output(self): + """Returns the output from running the FileTest""" + try : + p = Popen(self.cyclus_path+" "+ self.infile + self.flag, + shell=True, stdout=PIPE, stderr=STDOUT) + io_tuple = p.communicate() + output = io_tuple[0] + except subprocess.CalledProcessError, e: + print(e) + return output + + def no_errors(self, output): + """returns true if there were no errors or segfaults running this TestFile""" + to_ret = True + print "Input file " + self.infile + if re.search("No such file or directory",output) : + print "Cyclus executable not found in path." + elif re.search("ERROR",output) or re.search("Segmentation fault",output): + to_ret = False + print " resulted in errors: " + print output + else : + print " passed. " + return to_ret + +if __name__ == '__main__' : main() From 2d0ad425b2f70694e162138ec3dc3a20694e3b45 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Fri, 23 Jan 2015 14:32:53 -0600 Subject: [PATCH 111/314] check isotope composition and implicit FeedAssay calculation --- src/enrichment_facility.cc | 102 ++++++++++++++----------------- src/enrichment_facility.h | 51 +++++++++------- src/enrichment_facility_tests.cc | 8 +-- 3 files changed, 77 insertions(+), 84 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 5fc30b5ce2..9b5a9bcb49 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -1,5 +1,4 @@ /* -What is the difference between feed_assay and FeedAssay? How do I fix FeedAssay and possibly create a new function? How do I track the tails material going in and out of trades? Make sure request doesnt exceed inventory? How do I refer to the tails Material in the bids? */ @@ -20,14 +19,13 @@ namespace cycamore { EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) : cyclus::Facility(ctx), tails_assay(0), - // feed_assay(0), ///***DO we make Feed Assay derived at line 142??? swu_capacity(0), - // max_enrich(0), ///*** + // max_enrich(0), ///QQ initial_reserves(0), in_commod(""), in_recipe(""), - out_commod(""), - tails_commod(""){} /// *** + out_commod(""){} + // tails_commod(""){} ///QQ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EnrichmentFacility::~EnrichmentFacility() {} @@ -39,10 +37,10 @@ std::string EnrichmentFacility::str() { << " with enrichment facility parameters:" << " * SWU capacity: " << SwuCapacity() << " * Tails assay: " << TailsAssay() - << " * Feed assay: " << FeedAssay() //*** Remove?? ** + << " * Feed assay: " << FeedAssay() //QQ Remove?? << " * Input cyclus::Commodity: " << in_commodity() - << " * Output cyclus::Commodity: " << out_commodity() - << " * Tails cyclus::Commodity: " << tails_commodity(); ///*** + << " * Output cyclus::Commodity: " << out_commodity(); + //QQ << " * Tails cyclus::Commodity: " << tails_commodity(); ///QQ return ss.str(); } @@ -67,7 +65,7 @@ void EnrichmentFacility::Tick() { LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is ticking {"; /// LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity // << " kg of " - // << tails_commod << "."; // *** Not needed since no out_commod notification? + // << tails_commod << "."; //QQ Not needed since no out_commod notification? LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; current_swu_capacity = SwuCapacity(); } @@ -111,7 +109,7 @@ void EnrichmentFacility::AcceptMatlTrades( } } - ///*** Here is where we check material composition *** + ///QQ Here is where we check material composition // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - std::set::Ptr> @@ -125,13 +123,13 @@ EnrichmentFacility::GetMatlBids( using cyclus::Request; std::set::Ptr> ports; - // *** Add tails bids here + /* //QQ Add tails bids here if (commod_requests.count(tails_commod) > 0 && tails.quantity() > 0) { - BidPortfolio::Ptr port(new BidPortfolio()); // ** What is correct Matl? + BidPortfolio::Ptr port(new BidPortfolio()); //QQ What is correct Matl? std::vector*>& requests = commod_requests[tails_commod]; - + std::vector*>::iterator it; for (it = requests.begin(); it != requests.end(); ++it) { Request* req = *it; @@ -141,7 +139,8 @@ EnrichmentFacility::GetMatlBids( } } } - // *** Did I set up this loop correctly or is it missing stuff at the end? + //QQ Did I set up this loop correctly or is it missing stuff at the end? + */ if (commod_requests.count(out_commod) > 0 && inventory.quantity() > 0) { BidPortfolio::Ptr port(new BidPortfolio()); @@ -156,15 +155,8 @@ EnrichmentFacility::GetMatlBids( port->AddBid(req, offer, this); } } - - /// *** Need to calculate what actual feed assay is (U235 fraction - ///in unenriched inventory -- currently is calculating based on - /// input recipe instead ) rather than using hard-coded value - Material::Ptr fission_matl=inventory.Pop(inventory.quantity()); - inventory.Push(fission_matl); - double feed_assay=cyclus::toolkit::UraniumAssay(fission_matl); - Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); - Converter::Ptr nc(new NatUConverter(feed_assay, tails_assay)); + Converter::Ptr sc(new SWUConverter(FeedAssay(), tails_assay)); + Converter::Ptr nc(new NatUConverter(FeedAssay(), tails_assay)); CapacityConstraint swu(swu_capacity, sc); CapacityConstraint natu(inventory.quantity(), nc); port->AddConstraint(swu); @@ -203,7 +195,8 @@ void EnrichmentFacility::GetMatlTrades( for (it = trades.begin(); it != trades.end(); ++it) { Material::Ptr mat = it->bid->offer(); double qty = it->amt; - if /***matl eq tails*/ { //***Should I be using Tails() here instead? + /* + if ?matl eq tails { //Should I be using Tails() here instead? tails -= qty; tails_for_trade += qty; Material::Ptr response = Material::Create(this, qty, @@ -213,11 +206,12 @@ void EnrichmentFacility::GetMatlTrades( ss << "is being asked to provide " << tails_for_trade << " but its tails inventory is " << tails << "."; throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); - } */ //*** Is this how to check whether the tails inventory has been used up? - } + } // Is this how to check whether the tails inventory has been used up? + } else { + */ Material::Ptr response = Enrich_(mat, qty); - } + // } responses.push_back(std::make_pair(*it, response)); LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " just received an order" @@ -231,36 +225,29 @@ void EnrichmentFacility::GetMatlTrades( + " is being asked to provide more than its SWU capacity."); } } - /// *** Add similar for tails ? **** // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { - double threshold = 0.001; /// TODO *** What is a reasonable threshold? - cyclus::toolkit::MatQuery q = MatQuery(mat) ; - if (! bool cyclus::toolkit::MatQuery::AlmostEq(context()-> - GetRecipe(in_recipe), threshold)){ - throw cyclus::ValueError( - "EnrichmentFacility recipe and material composition not the same."); - } // Elements and isotopes other than U-235, U-238 are sent directly to tails cyclus::CompMap cm = mat->comp()->atom(); - double u_other, non_u ; - for (cyclus::CompMap::const_iterator it=cm.begin(); it !=cm.end; ++it) { + bool extra_u = false; + bool other_elem = false; + for (cyclus::CompMap::const_iterator it=cm.begin(); it !=cm.end(); ++it) { if (pyne::nucname::znum(it->first) == 92){ if (pyne::nucname::anum(it->first) != 235 && - pyne::nucname::anum(it->first) != 238 ){ - u_other +=it->second.atom_frac(); + pyne::nucname::anum(it->first) != 238 && it->second > 0){ + extra_u = true; } } - else { - u_other +=it->second.atom_frac() ; + else if (it->second > 0) { + other_elem = true ; } } - if (u_other > 0.0){ + if (extra_u){ cyclus::Warn("More than 2 isotopes of U." \ "Istopes other than U-235, U-238 are sent directly to tails."); } - if (non_u > 0.0){ + if (other_elem){ cyclus::Warn("Non-uranium elements are " \ "sent directly to tails."); } @@ -290,7 +277,7 @@ cyclus::Material::Ptr EnrichmentFacility::Request_() { context()->GetRecipe(in_recipe)); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { cyclus::toolkit::MatQuery q(mat); cyclus::CompMap comp; @@ -299,7 +286,7 @@ cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { return cyclus::Material::CreateUntracked( mat->quantity(), cyclus::Composition::CreateFromAtom(comp)); } - /// *** bid for input material or offer of output? + //QQ bid for input material or offer of output? // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - cyclus::Material::Ptr EnrichmentFacility::Enrich_( cyclus::Material::Ptr mat, @@ -318,19 +305,16 @@ cyclus::Material::Ptr EnrichmentFacility::Enrich_( double natu_req = FeedQty(qty, assays); // pop amount from inventory and blob it into one material - std::vector manifest; + Material::Ptr r; try { // required so popping doesn't take out too much if (cyclus::AlmostEq(natu_req, inventory.quantity())) { - manifest = ResCast(inventory.PopN(inventory.count())); + r = cyclus::toolkit::Squash(inventory.PopN(inventory.count())); } else { - manifest = ResCast(inventory.PopQty(natu_req)); + r = inventory.Pop(natu_req); } } catch (cyclus::Error& e) { - Material::Ptr fission_matl=inventory.Pop(inventory.quantity()); - inventory.Push(fission_matl); - double feed_assay=cyclus::toolkit::UraniumAssay(fission_matl); - NatUConverter nc(feed_assay, tails_assay); + NatUConverter nc(FeedAssay(), tails_assay); std::stringstream ss; ss << " tried to remove " << natu_req << " from its inventory of size " << inventory.quantity() @@ -338,10 +322,6 @@ cyclus::Material::Ptr EnrichmentFacility::Enrich_( << nc.convert(mat); throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); } - Material::Ptr r = manifest[0]; - for (int i = 1; i < manifest.size(); ++i) { - r->Absorb(manifest[i]); - } // "enrich" it, but pull out the composition and quantity we require from the // blob @@ -393,7 +373,15 @@ void EnrichmentFacility::RecordEnrichment_(double natural_u, double swu) { ->AddVal("SWU", swu) ->Record(); } - +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +double EnrichmentFacility::FeedAssay() { + using cyclus::Material; + + cyclus::Material::Ptr fission_matl=inventory.Pop(inventory.quantity()); + inventory.Push(fission_matl); + return cyclus::toolkit::UraniumAssay(fission_matl); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - extern "C" cyclus::Agent* ConstructEnrichmentFacility(cyclus::Context* ctx) { return new EnrichmentFacility(ctx); diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 55686ebbf6..d7667e1145 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -174,7 +174,7 @@ class EnrichmentFacility : public cyclus::Facility { virtual std::set::Ptr> GetMatlBids(cyclus::CommodMap::type& commod_requests); - /// *** ADD RESPONSE FOR TAILS *** + ///QQ ADD RESPONSE FOR TAILS /// @brief respond to each trade with a material enriched to the appropriate /// level given this facility's inventory @@ -204,19 +204,20 @@ class EnrichmentFacility : public cyclus::Facility { inline std::string out_commodity() const { return out_commod; } + /* inline void tails_commodity(std::string tails_com) { tails_commod = tails_com; - } /// **** - - inline std::string tails_commodity() const { return tails_commod; } /// *** + } ///QQ + inline std::string tails_commodity() const { return tails_commod; } ///QQ + */ inline void InRecipe(std::string in_rec) { in_recipe = in_rec; } inline std::string InRecipe() const { return in_recipe; } inline void SetMaxInventorySize(double size) { max_inv_size = size; - inventory.set_capacity(size); + inventory.capacity(size); //QQ } inline double MaxInventorySize() const { return inventory.capacity(); } @@ -224,9 +225,7 @@ class EnrichmentFacility : public cyclus::Facility { inline double InventorySize() const { return inventory.quantity(); } // inline void FeedAssay(double assay) { feed_assay = assay; } - - inline double FeedAssay() const { return feed_assay; } - + inline void TailsAssay(double assay) { tails_assay = assay; } inline double TailsAssay() const { return tails_assay; } @@ -235,20 +234,20 @@ class EnrichmentFacility : public cyclus::Facility { swu_capacity = capacity; current_swu_capacity = swu_capacity; } - // inline void MaxEnrich(double enrichment) { max_enrich_ = enrichment; } /// *** + // inline void MaxEnrich(double enrichment) { max_enrich_ = enrichment; } //QQ inline double SwuCapacity() const { return swu_capacity; } inline double CurrentSwuCapacity() const { return current_swu_capacity; } - // inline double MaxEnrich() const { return max_enrich; } /// *** + // inline double MaxEnrich() const { return max_enrich; } ///QQ /// @brief this facility's initial conditions inline void InitialReserves(double qty) { initial_reserves = qty; } inline double InitialReserves() const { return initial_reserves; } - inline const cyclus::toolkit::ResBuf& Tails() const { return tails; } - /// *** relevant to tails buffer (but how?) -- It's not used for anything and can be deleted if we decide to make everything a state variable for testing *** + inline const cyclus::toolkit::ResBuf& Tails() const { return tails; } + ///QQ relevant to tails buffer (but how?) -- It's not used for anything and can be deleted if we decide to make everything a state variable for testing private: /// @brief adds a material into the natural uranium inventory @@ -268,7 +267,10 @@ class EnrichmentFacility : public cyclus::Facility { cyclus::Material::Ptr Offer_(cyclus::Material::Ptr req); cyclus::Material::Ptr Enrich_(cyclus::Material::Ptr mat, double qty); - /// *** max enrichment? *** + + /// @brief calculates the feed assay based on the unenriched inventory + double FeedAssay(); + /// @brief records and enrichment with the cyclus::Recorder void RecordEnrichment_(double natural_u, double swu); @@ -288,7 +290,7 @@ class EnrichmentFacility : public cyclus::Facility { // #pragma cyclus var {"tooltip": "tails commodity", \ // "doc": "tails commodity that the enrichment facility supplies", \ // "uitype": "tailscommodity"} - // std::string tails_commod; /// *** + // std::string tails_commod; ///QQ #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ "doc": "tails assay from the enrichment process"} @@ -298,16 +300,16 @@ class EnrichmentFacility : public cyclus::Facility { "doc": "separative work unit (SWU) capcity of " \ "enrichment facility"} double swu_capacity; - /* #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size", \ + #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size", \ "doc": "maximum inventory capacity of natural uranium in " \ "the enrichment facility"} - double enrich_capacity; - */ + double max_inv_size; + /* #pragma cyclus var {"default": 100, "tooltip": "maximum allowed enrichment", \ "doc": "maximum allowed enrichment of uranium product in " \ - "the enrichment facility"} /// *** - - double max_inv_size; + "the enrichment facility"} ///QQ + double enrich_capacity; //QQ + */ #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves", \ "doc": "amount of natural uranium stored at the " \ "enrichment facility at the beginning of the " \ @@ -315,18 +317,21 @@ class EnrichmentFacility : public cyclus::Facility { double initial_reserves; #pragma cyclus var {'derived_init': 'current_swu_capacity = swu_capacity;'} double current_swu_capacity; - #pragma cyclus var {\ + /* + #pragma cyclus var { \ 'derived_init': "cyclus::Material::Ptr feed = "\ "cyclus::Material::CreateUntracked(0, context()->GetRecipe(in_recipe)); "\ "feed_assay = cyclus::toolkit::UraniumAssay(feed);", \ "tooltip": "feed assay", \ "doc": "feed assay for the enrichment process"} double feed_assay; + */ + #pragma cyclus var {'capacity': 'max_inv_size'} - cyclus::toolkit::ResBuf inventory; // of natl u + cyclus::toolkit::ResBuf inventory; // of natl u #pragma cyclus var {} cyclus::toolkit::ResBuf tails; // depleted u - + friend class EnrichmentFacilityTest; // --- }; diff --git a/src/enrichment_facility_tests.cc b/src/enrichment_facility_tests.cc index 2b29e622ae..98f8bf4cb1 100644 --- a/src/enrichment_facility_tests.cc +++ b/src/enrichment_facility_tests.cc @@ -57,7 +57,7 @@ void EnrichmentFacilityTest::SetUpSource() { src_facility->in_commodity(in_commod); src_facility->out_commodity(out_commod); src_facility->TailsAssay(tails_assay); - src_facility->FeedAssay(feed_assay); + // src_facility->FeedAssay(feed_assay); src_facility->SetMaxInventorySize(inv_size); src_facility->SwuCapacity(swu_capacity); src_facility->InitialReserves(reserves); @@ -107,7 +107,7 @@ TEST_F(EnrichmentFacilityTest, InitialState) { EXPECT_EQ(in_commod, src_facility->in_commodity()); EXPECT_EQ(out_commod, src_facility->out_commodity()); EXPECT_DOUBLE_EQ(tails_assay, src_facility->TailsAssay()); - EXPECT_DOUBLE_EQ(feed_assay, src_facility->FeedAssay()); + // EXPECT_DOUBLE_EQ(feed_assay, src_facility->FeedAssay()); EXPECT_DOUBLE_EQ(inv_size, src_facility->MaxInventorySize()); EXPECT_DOUBLE_EQ(0.0, src_facility->InventorySize()); EXPECT_DOUBLE_EQ(swu_capacity, src_facility->SwuCapacity()); @@ -148,7 +148,7 @@ TEST_F(EnrichmentFacilityTest, DISABLED_XMLInit) { EXPECT_EQ(in_commod, fac.in_commodity()); EXPECT_EQ(out_commod, fac.out_commodity()); EXPECT_DOUBLE_EQ(tails_assay, fac.TailsAssay()); - EXPECT_DOUBLE_EQ(feed_assay, fac.FeedAssay()); + // EXPECT_DOUBLE_EQ(feed_assay, fac.FeedAssay()); EXPECT_DOUBLE_EQ(inv_size, fac.MaxInventorySize()); EXPECT_DOUBLE_EQ(0.0, fac.InventorySize()); EXPECT_DOUBLE_EQ(swu_capacity, fac.SwuCapacity()); @@ -166,7 +166,7 @@ TEST_F(EnrichmentFacilityTest, Clone) { EXPECT_EQ(in_commod, cloned_fac->in_commodity()); EXPECT_EQ(out_commod, cloned_fac->out_commodity()); EXPECT_DOUBLE_EQ(tails_assay, cloned_fac->TailsAssay()); - EXPECT_DOUBLE_EQ(feed_assay, cloned_fac->FeedAssay()); + // EXPECT_DOUBLE_EQ(feed_assay, cloned_fac->FeedAssay()); EXPECT_DOUBLE_EQ(inv_size, cloned_fac->MaxInventorySize()); EXPECT_DOUBLE_EQ(0.0, cloned_fac->InventorySize()); EXPECT_DOUBLE_EQ(swu_capacity, cloned_fac->SwuCapacity()); From 0caf1e08f94a92035b7e4ee5a85a6349a627aa12 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Fri, 23 Jan 2015 17:16:39 -0600 Subject: [PATCH 112/314] draft tails buffer --- src/enrichment_facility.cc | 118 +++++++++++++++++++------------------ src/enrichment_facility.h | 12 ++-- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 9b5a9bcb49..ebfc5bc3cc 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -24,8 +24,8 @@ EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) initial_reserves(0), in_commod(""), in_recipe(""), - out_commod(""){} - // tails_commod(""){} ///QQ + out_commod(""), + tails_commod(""){} ///QQ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EnrichmentFacility::~EnrichmentFacility() {} @@ -39,8 +39,8 @@ std::string EnrichmentFacility::str() { << " * Tails assay: " << TailsAssay() << " * Feed assay: " << FeedAssay() //QQ Remove?? << " * Input cyclus::Commodity: " << in_commodity() - << " * Output cyclus::Commodity: " << out_commodity(); - //QQ << " * Tails cyclus::Commodity: " << tails_commodity(); ///QQ + << " * Output cyclus::Commodity: " << out_commodity() + << " * Tails cyclus::Commodity: " << tails_commodity(); ///QQ return ss.str(); } @@ -63,9 +63,6 @@ void EnrichmentFacility::Build(cyclus::Agent* parent) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentFacility::Tick() { LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is ticking {"; - /// LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity - // << " kg of " - // << tails_commod << "."; //QQ Not needed since no out_commod notification? LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; current_swu_capacity = SwuCapacity(); } @@ -114,7 +111,7 @@ void EnrichmentFacility::AcceptMatlTrades( // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - std::set::Ptr> EnrichmentFacility::GetMatlBids( - cyclus::CommodMap::type& commod_requests){ + cyclus::CommodMap::type& out_requests){ using cyclus::Bid; using cyclus::BidPortfolio; using cyclus::CapacityConstraint; @@ -123,45 +120,50 @@ EnrichmentFacility::GetMatlBids( using cyclus::Request; std::set::Ptr> ports; - /* //QQ Add tails bids here - if (commod_requests.count(tails_commod) > 0 && tails.quantity() > 0) { - BidPortfolio::Ptr port(new BidPortfolio()); //QQ What is correct Matl? - - std::vector*>& requests = - commod_requests[tails_commod]; - + //QQ + if (out_requests.count(tails_commod) > 0 && tails.quantity() > 0) { + BidPortfolio::Ptr tails_port(new BidPortfolio()); //QQ What is correct Matl? + + std::vector*>& tails_requests = + out_requests[tails_commod]; + std::vector*>::iterator it; - for (it = requests.begin(); it != requests.end(); ++it) { + for (it = tails_requests.begin(); it != tails_requests.end(); ++it) { Request* req = *it; - if (ValidReq(req->target())) { - Material::Ptr offer = Offer_(req->target()); - port->AddBid(req, offer, this); - } + tails_port->AddBid(req, tails.Peek(), this); } + //QQ + // overbidding (bidding on every offer) + // add an overall capacity constraint + CapacityConstraint tc(tails.quantity()); + commod_port->AddConstraint(tc); + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() + << " adding a tails capacity constraint of " + << tails.capacity(); + //QQ + ports.insert(tails_port); } - //QQ Did I set up this loop correctly or is it missing stuff at the end? - */ - if (commod_requests.count(out_commod) > 0 && inventory.quantity() > 0) { - BidPortfolio::Ptr port(new BidPortfolio()); - - std::vector*>& requests = - commod_requests[out_commod]; - + if (out_requests.count(out_commod) > 0 && inventory.quantity() > 0) { + BidPortfolio::Ptr commod_port(new BidPortfolio()); + + std::vector*>& commod_requests = + out_requests[out_commod]; + std::vector*>::iterator it; - for (it = requests.begin(); it != requests.end(); ++it) { + for (it = commod_requests.begin(); it != commod_requests.end(); ++it) { Request* req = *it; if (ValidReq(req->target())) { Material::Ptr offer = Offer_(req->target()); - port->AddBid(req, offer, this); + commod_port->AddBid(req, offer, this); } } Converter::Ptr sc(new SWUConverter(FeedAssay(), tails_assay)); Converter::Ptr nc(new NatUConverter(FeedAssay(), tails_assay)); CapacityConstraint swu(swu_capacity, sc); CapacityConstraint natu(inventory.quantity(), nc); - port->AddConstraint(swu); - port->AddConstraint(natu); - + commod_port->AddConstraint(swu); + commod_port->AddConstraint(natu); + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " adding a swu constraint of " << swu.capacity(); @@ -169,7 +171,7 @@ EnrichmentFacility::GetMatlBids( << " adding a natu constraint of " << natu.capacity(); - ports.insert(port); + ports.insert(commod_port); } return ports; } @@ -190,42 +192,43 @@ void EnrichmentFacility::GetMatlTrades( using cyclus::Material; using cyclus::Trade; - double tails_for_trade = 0 ; std::vector< Trade >::const_iterator it; for (it = trades.begin(); it != trades.end(); ++it) { Material::Ptr mat = it->bid->offer(); double qty = it->amt; - /* - if ?matl eq tails { //Should I be using Tails() here instead? - tails -= qty; - tails_for_trade += qty; - Material::Ptr response = Material::Create(this, qty, - context()->GetRecipe(recipe_name)); - if (cyclus::IsNegative(tails.quantity)) { - std::stringstream ss; - ss << "is being asked to provide " << tails_for_trade - << " but its tails inventory is " << tails << "."; - throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); - } // Is this how to check whether the tails inventory has been used up? - } - else { - */ - Material::Ptr response = Enrich_(mat, qty); - // } - responses.push_back(std::make_pair(*it, response)); + //QQ Figure out whether material is tails or enriched, + // if tails then make transfer of material + + //QQ Need to figure out if the response material is tails or product + if (cyclus::toolkit::Assays::Tails(mat) == tails_assay){ //tails_assay or TailsAssay? + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() + << " just received an order" + << " for " << it->amt + << " of " << tails_commod; + // Do the material moving + tails.Pop(qty); // remove the qty from the Tails buffer Need to send to response. + Material::Ptr response = mat; //QQ Correct? + } else { LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " just received an order" << " for " << it->amt << " of " << out_commod; + + Material::Ptr response = Enrich_(mat, qty); + } + responses.push_back(std::make_pair(*it, response)); + } + if (cyclus::IsNegative(tails.quantity())) { + std::stringstream ss; + ss << "is being asked to provide more than its current inventory." + throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); } - if (cyclus::IsNegative(current_swu_capacity)) { throw cyclus::ValueError( - "EnrFac " + prototype() - + " is being asked to provide more than its SWU capacity."); + "EnrFac " + prototype() + + " is being asked to provide more than its SWU capacity."); } } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { // Elements and isotopes other than U-235, U-238 are sent directly to tails @@ -286,7 +289,6 @@ cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { return cyclus::Material::CreateUntracked( mat->quantity(), cyclus::Composition::CreateFromAtom(comp)); } - //QQ bid for input material or offer of output? // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - cyclus::Material::Ptr EnrichmentFacility::Enrich_( cyclus::Material::Ptr mat, diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index d7667e1145..ba3228bff6 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -174,7 +174,6 @@ class EnrichmentFacility : public cyclus::Facility { virtual std::set::Ptr> GetMatlBids(cyclus::CommodMap::type& commod_requests); - ///QQ ADD RESPONSE FOR TAILS /// @brief respond to each trade with a material enriched to the appropriate /// level given this facility's inventory @@ -204,13 +203,12 @@ class EnrichmentFacility : public cyclus::Facility { inline std::string out_commodity() const { return out_commod; } - /* inline void tails_commodity(std::string tails_com) { tails_commod = tails_com; } ///QQ inline std::string tails_commodity() const { return tails_commod; } ///QQ - */ + inline void InRecipe(std::string in_rec) { in_recipe = in_rec; } inline std::string InRecipe() const { return in_recipe; } @@ -287,10 +285,10 @@ class EnrichmentFacility : public cyclus::Facility { "doc": "recipe for enrichment facility's input commodity", \ "uitype": "recipe"} std::string in_recipe; - // #pragma cyclus var {"tooltip": "tails commodity", \ - // "doc": "tails commodity that the enrichment facility supplies", \ -// "uitype": "tailscommodity"} - // std::string tails_commod; ///QQ + #pragma cyclus var {"tooltip": "tails commodity", \ + "doc": "tails commodity that the enrichment facility supplies", \ + "uitype": "tailscommodity"} + std::string tails_commod; ///QQ #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ "doc": "tails assay from the enrichment process"} From ae5824318c6a9d68137f97bc335affff245ae55d Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 3 Feb 2015 12:51:44 -0600 Subject: [PATCH 113/314] more work on tails buffer --- src/enrichment_facility.cc | 14 ++++++++------ src/enrichment_facility.h | 31 +++++++++++++++---------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index ebfc5bc3cc..536c920747 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -136,7 +136,7 @@ EnrichmentFacility::GetMatlBids( // overbidding (bidding on every offer) // add an overall capacity constraint CapacityConstraint tc(tails.quantity()); - commod_port->AddConstraint(tc); + tails_port->AddConstraint(tc); LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " adding a tails capacity constraint of " << tails.capacity(); @@ -196,17 +196,18 @@ void EnrichmentFacility::GetMatlTrades( for (it = trades.begin(); it != trades.end(); ++it) { Material::Ptr mat = it->bid->offer(); double qty = it->amt; + std::string commod_type = it->bid->request()->commodity() ; //QQ Figure out whether material is tails or enriched, // if tails then make transfer of material //QQ Need to figure out if the response material is tails or product - if (cyclus::toolkit::Assays::Tails(mat) == tails_assay){ //tails_assay or TailsAssay? + if (commod_type == tails_commod){ LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " just received an order" << " for " << it->amt << " of " << tails_commod; // Do the material moving - tails.Pop(qty); // remove the qty from the Tails buffer Need to send to response. + tails.Pop(qty); // remove the qty from the Tails buffer Material::Ptr response = mat; //QQ Correct? } else { LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() @@ -220,13 +221,14 @@ void EnrichmentFacility::GetMatlTrades( } if (cyclus::IsNegative(tails.quantity())) { std::stringstream ss; - ss << "is being asked to provide more than its current inventory." - throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); + ss << "is being asked to provide more than its current inventory." ; + throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); } if (cyclus::IsNegative(current_swu_capacity)) { throw cyclus::ValueError( "EnrFac " + prototype() - + " is being asked to provide more than its SWU capacity."); + + " is being asked to provide more than" + + " its SWU capacity."); } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index ba3228bff6..fa03c6d05e 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -221,7 +221,7 @@ class EnrichmentFacility : public cyclus::Facility { inline double MaxInventorySize() const { return inventory.capacity(); } inline double InventorySize() const { return inventory.quantity(); } - + //QQ: TO BE DELETED // inline void FeedAssay(double assay) { feed_assay = assay; } inline void TailsAssay(double assay) { tails_assay = assay; } @@ -285,22 +285,21 @@ class EnrichmentFacility : public cyclus::Facility { "doc": "recipe for enrichment facility's input commodity", \ "uitype": "recipe"} std::string in_recipe; - #pragma cyclus var {"tooltip": "tails commodity", \ - "doc": "tails commodity that the enrichment facility supplies", \ - "uitype": "tailscommodity"} - std::string tails_commod; ///QQ - - #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ - "doc": "tails assay from the enrichment process"} - - double tails_assay; - #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity", \ - "doc": "separative work unit (SWU) capcity of " \ - "enrichment facility"} + #pragma cyclus var {"tooltip": "tails commodity", \ + "doc": "tails commodity that the enrichment facility supplies", \ + "uitype": "outcommodity"} + std::string tails_commod; //QQ + + #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ + "doc": "tails assay from the enrichment process"} + double tails_assay; + #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity", \ + "doc": "separative work unit (SWU) capcity of " \ + "enrichment facility"} double swu_capacity; - #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size", \ + #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size", \ "doc": "maximum inventory capacity of natural uranium in " \ - "the enrichment facility"} + "the enrichment facility"} double max_inv_size; /* #pragma cyclus var {"default": 100, "tooltip": "maximum allowed enrichment", \ @@ -315,7 +314,7 @@ class EnrichmentFacility : public cyclus::Facility { double initial_reserves; #pragma cyclus var {'derived_init': 'current_swu_capacity = swu_capacity;'} double current_swu_capacity; - /* + /* //QQ: TO BE DELETED #pragma cyclus var { \ 'derived_init': "cyclus::Material::Ptr feed = "\ "cyclus::Material::CreateUntracked(0, context()->GetRecipe(in_recipe)); "\ From 01bb4ffea05c0fe72c2816896bc4eb3d1c2a19ca Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 3 Feb 2015 14:31:58 -0600 Subject: [PATCH 114/314] tails buffer works --- src/enrichment_facility.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 536c920747..5efd914919 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -197,6 +197,7 @@ void EnrichmentFacility::GetMatlTrades( Material::Ptr mat = it->bid->offer(); double qty = it->amt; std::string commod_type = it->bid->request()->commodity() ; + Material::Ptr response ; //QQ Figure out whether material is tails or enriched, // if tails then make transfer of material @@ -208,14 +209,14 @@ void EnrichmentFacility::GetMatlTrades( << " of " << tails_commod; // Do the material moving tails.Pop(qty); // remove the qty from the Tails buffer - Material::Ptr response = mat; //QQ Correct? + response = mat; //QQ Correct? } else { LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " just received an order" << " for " << it->amt << " of " << out_commod; - Material::Ptr response = Enrich_(mat, qty); + response = Enrich_(mat, qty); } responses.push_back(std::make_pair(*it, response)); } From f8fb44093cf70c1dfab5421069c5ebd97a1112fe Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 3 Feb 2015 15:47:09 -0600 Subject: [PATCH 115/314] working on max_enrichment state var --- src/enrichment_facility.cc | 14 +++++++++----- src/enrichment_facility.h | 14 ++++++-------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 5efd914919..a2015bc26d 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -1,6 +1,7 @@ /* -How do I track the tails material going in and out of trades? Make sure request doesnt exceed inventory? -How do I refer to the tails Material in the bids? +How/Where do I check that enrichment limit is a fraction of 1? +Where is the default max enrich set? +Use MaxEnrich or max_enrich? */ // Implements the EnrichmentFacility class @@ -20,7 +21,7 @@ EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) : cyclus::Facility(ctx), tails_assay(0), swu_capacity(0), - // max_enrich(0), ///QQ + max_enrich(0), ///QQ is this defaulting to zero? Where to set default? initial_reserves(0), in_commod(""), in_recipe(""), @@ -122,7 +123,7 @@ EnrichmentFacility::GetMatlBids( std::set::Ptr> ports; //QQ if (out_requests.count(tails_commod) > 0 && tails.quantity() > 0) { - BidPortfolio::Ptr tails_port(new BidPortfolio()); //QQ What is correct Matl? + BidPortfolio::Ptr tails_port(new BidPortfolio()); //QQ std::vector*>& tails_requests = out_requests[tails_commod]; @@ -152,7 +153,10 @@ EnrichmentFacility::GetMatlBids( std::vector*>::iterator it; for (it = commod_requests.begin(); it != commod_requests.end(); ++it) { Request* req = *it; - if (ValidReq(req->target())) { + // Do not offer a bid if the enrichment exceed max. QQ + Material::Ptr mat = Request_(); + double request_enrich = cyclus::toolkit::UraniumAssay(mat) ; + if (ValidReq(req->target()) && (request_enrich <= max_enrich)) { Material::Ptr offer = Offer_(req->target()); commod_port->AddBid(req, offer, this); } diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index fa03c6d05e..62ce803a26 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -232,13 +232,13 @@ class EnrichmentFacility : public cyclus::Facility { swu_capacity = capacity; current_swu_capacity = swu_capacity; } - // inline void MaxEnrich(double enrichment) { max_enrich_ = enrichment; } //QQ + inline void MaxEnrich(double enrichment) { max_enrich_ = enrichment; } //QQ inline double SwuCapacity() const { return swu_capacity; } inline double CurrentSwuCapacity() const { return current_swu_capacity; } - // inline double MaxEnrich() const { return max_enrich; } ///QQ + inline double MaxEnrich() const { return max_enrich; } ///QQ /// @brief this facility's initial conditions inline void InitialReserves(double qty) { initial_reserves = qty; } @@ -301,12 +301,10 @@ class EnrichmentFacility : public cyclus::Facility { "doc": "maximum inventory capacity of natural uranium in " \ "the enrichment facility"} double max_inv_size; - /* - #pragma cyclus var {"default": 100, "tooltip": "maximum allowed enrichment", \ - "doc": "maximum allowed enrichment of uranium product in " \ - "the enrichment facility"} ///QQ - double enrich_capacity; //QQ - */ + #pragma cyclus var {"default": 1.0, "tooltip": "maximum allowed enrichment fraction", \ + "doc": "maximum allowed enrichment fraction of uranium product " \ + "in the enrichment facility"} ///QQ + double max_enrich; //QQ #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves", \ "doc": "amount of natural uranium stored at the " \ "enrichment facility at the beginning of the " \ From 269690bc53a1fd28284823964d56084c0c879344 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Mon, 9 Feb 2015 14:52:56 -0600 Subject: [PATCH 116/314] minor fix to max_enrich --- src/enrichment_facility.cc | 2 +- src/enrichment_facility.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index a2015bc26d..3c0c295086 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -154,7 +154,7 @@ EnrichmentFacility::GetMatlBids( for (it = commod_requests.begin(); it != commod_requests.end(); ++it) { Request* req = *it; // Do not offer a bid if the enrichment exceed max. QQ - Material::Ptr mat = Request_(); + Material::Ptr mat = req->target(); double request_enrich = cyclus::toolkit::UraniumAssay(mat) ; if (ValidReq(req->target()) && (request_enrich <= max_enrich)) { Material::Ptr offer = Offer_(req->target()); diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 62ce803a26..97927349bb 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -232,7 +232,7 @@ class EnrichmentFacility : public cyclus::Facility { swu_capacity = capacity; current_swu_capacity = swu_capacity; } - inline void MaxEnrich(double enrichment) { max_enrich_ = enrichment; } //QQ + inline void MaxEnrich(double enrichment) { max_enrich = enrichment; } //QQ inline double SwuCapacity() const { return swu_capacity; } From 7d7d41caf170fed91be6d02622f5afb2526a60d7 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 10 Feb 2015 11:50:46 -0600 Subject: [PATCH 117/314] modified original input files --- input/enrichment/1_src_enr_rxtr_sink.xml | 1 + input/enrichment/cyclus.sqlite | Bin 0 -> 156672 bytes input/enrichment/linear_src_enr_rxtr_sink.xml | 3 +- input/enrichment/natu_capacitated.xml | 1 + input/enrichment/swu_capacitated.xml | 1 + src/enrichment_facility.cc | 2 - .../fn_behavior/behavior_functions.cc | 7 + .../fn_behavior/behavior_functions.h | 17 + .../fn_behavior/enrichment_facility.cc | 357 +++++++++ .../fn_behavior/enrichment_facility.h | 324 ++++++++ src/meg_old_tests/fn_consider/CMakeLists.txt | 25 + .../fn_consider/enrichment_facility.cc | 392 ++++++++++ .../fn_consider/enrichment_facility.h | 331 ++++++++ .../fn_consider/enrichment_facility_tests.cc | 725 ++++++++++++++++++ .../fn_consider/enrichment_facility_tests.h | 51 ++ 15 files changed, 2234 insertions(+), 3 deletions(-) create mode 100644 input/enrichment/cyclus.sqlite create mode 100644 src/meg_old_tests/fn_behavior/behavior_functions.cc create mode 100644 src/meg_old_tests/fn_behavior/behavior_functions.h create mode 100644 src/meg_old_tests/fn_behavior/enrichment_facility.cc create mode 100644 src/meg_old_tests/fn_behavior/enrichment_facility.h create mode 100644 src/meg_old_tests/fn_consider/CMakeLists.txt create mode 100644 src/meg_old_tests/fn_consider/enrichment_facility.cc create mode 100644 src/meg_old_tests/fn_consider/enrichment_facility.h create mode 100644 src/meg_old_tests/fn_consider/enrichment_facility_tests.cc create mode 100644 src/meg_old_tests/fn_consider/enrichment_facility_tests.h diff --git a/input/enrichment/1_src_enr_rxtr_sink.xml b/input/enrichment/1_src_enr_rxtr_sink.xml index f372c05585..ba9ade40c4 100644 --- a/input/enrichment/1_src_enr_rxtr_sink.xml +++ b/input/enrichment/1_src_enr_rxtr_sink.xml @@ -33,6 +33,7 @@ natl_u enriched_u + ef_tails natl_u 0.003 500 diff --git a/input/enrichment/cyclus.sqlite b/input/enrichment/cyclus.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..70b8fe24ead5431db31d73b83e3c2b0d690fb21c GIT binary patch literal 156672 zcmeEv34C2unfN{D+_z?XFL_I|zvMN|zBXx+_BCD8Hgu&6lr?=#Ufa+tB`+zZh-bsE>eobB?KP5jT-zDE9UnO5s5F!CC+_ivffjlgbTLr|I^ug<_4tVu8 z!mG6&UP~+Cm59NsG6JvCFuaNiXxa3Uufto~Vk(>erhq8eeOwE;7C194ur9X@6mQGX zQr~a_UUlcft9lq-<^Awlva|@^i2P83f9~U2z_q~Z(*kisdIRz~`%~w=@!A)ET${~4 zQ2X8M|M10IZl&el(yM=c#@~&VYXR2+91GC$?z$m-cPP49Z5hZaVp3c4+d(-H*KV^K17V`j=mJcO|;2J*2mM<-N6^+miYkiM+6_fBELY z8FWkkw-{qfbG`-e46qeqIr+WhoiY+L#G4;!BN>f0_$XXi3* z`=3uTyR@zaUSAe)%m3>uJ>A&27Rbi}Zu!s0S}v_?f!CJ>-17hWN>4X7t_AY3fLs3a zv6f5gTHy6%0k{0WzS7f;jcb8?EI{}FVe)IrauMDCmk+N?>sr9Iz!_?ReFPNWi)s5` zAe|?{zsHdu?MClGzsGy={X`-ck`KRvxE(;gcwHUJ70jg%PG&YuWG2V=o;;Sx8ee$B z?%{QNhZB3(t=~4BFyKvlDaVfVR3@=^c>mruhEYDLgv7{>y~CS_cQ-I?Mt% zCo?uTGdnUpr+*NOcpaQ*+H-s=v3}dm^=;>*Cv{<42oshz3EOyZQsIIRnIjCqHenE- zZOvO`hon7ovx+46@Ngsn*d~cay!j%JH{Q^Iu4OuHPalKWZJap{wlRNuE%MA5lgO=^ zlUht!teK+cdYPhT@eqO{0X}>j!2q5|s+KT&eN6C4limUCm>L?RAGJWj$+@^`iOxE}+vJ2{q~nwia{I_WQ!i)}KF8uqiz@ zF*z}JGJhHC({p1-c4yMG=+DocJ`5WrvSz(^9G{%rojE))GyQTnN2arL4!%@pdUotc zW{y^KLqRZJ>W~^W)sl*t%?48}JT^0ZXyUL!1YF9#4eciYW{%H|j?GL>&5RFCr{^X| zkEc3KASQ#Q)L8l$1UPqcsJpAHE7ht0G$>{>V-v?Rqf8M^lo_T{raH|!fFxbPRHqRq zAm+xDdSWuG3C$cDWxrFM z7O){1LQ~A58{B{xR0?xCn@yh_>gwp~TCT}cKnCGd`ts3<=@X;bi7PTgeKc(>5S1|1 zDY8kvDPS!VOuXIvYT1GEA7bUlWc)+NGn2+oNaTrWCHK*+Wj3@Ku1A*9tHz^}R70jZ zC#F@XnG}-Hkj-`^vAk`-Y{aUF<5@^*i*yiV7Y}*W5|h-i*_p9SHaj-~wOx0r)BIBp zCN+JK)+$hffkOW_&FwqgWlAxVor9uI1;B^SYZAy&A=Rm-yeZZ5&0eOKf`w|&TNH27M=!ciE7GE`JgF1u z$sskx>8FmOIYlj~CI*u|KwYh(Q<xwVHHt!jgQ@Qq7(;%mMU}k>+M-vofSq%Pi}v z5Z!D*H+_8SU}lzOT;)qgraEm>Q|fQp!`D*85|U9By^5i6L((fNBbvJ2FE3KuV3bVz z3d5jzQ5+T6e|Mh2lkZF3A-tA3i9;Y;D}w6H@);tCt! z3mY8lfR;}njYg67Ig}2O_DxeriK3+vf7RpJ+tDY~jB1cyJp1O6wop8sE!NA6EOhN? z?~aqE02ap8q#g9_C#H^1rj=@oj{jx6Um~}YHv9~HxQ}arSHS{Dbz1n-b+Yk45caQZP8d%;j z(9z$~+YNuZm$!G1_VxF440iPNbPOCJ_K;d%`1r(9C^c~!ZZz4gGu?zmc|9xt6p)VedqBmTsPIMfa8JRvb6Shrm9GbCCYivnRk58(z zhKUiSp*{~zSm<+K8gTo}^xP2xy7Blds}2pwuJkN)kjzsi3WQBSvPq=G`q}jK*pa<3 zmN3{hoE)1xo;@csn}trlGG&>tz&2*GW3v+nH68a{3KJh0EB%)7Lw#1r`WfioTS40< z4({K+t;Y)7Ff%c|Vf_X(uz7nCn}bp&j5cP*(kHjijA!(ZGK)oZu+^*#%wp4gaj}oi zxvI0epu(4 zsETcyIFzBoU(F`Xto|P$oy-!7Ohd6#XrT}qioMZx zhJtA*b}~ySh=yXPP(v}b{|DUm|5eE7t_arxXMzQ`Q5V5mD{1?`RJuYUKPF!$&ykOj z_mQ`d%Sf7RBLgHsB>W=&B7PkIHGT`8!=v~t+<=SFuh6&9v*;tRSNJVx8ukpYKym4J z(ifx;f}lk|%}eEx%78JyIjZe0991?s(0OHbKC?NwFsV8h+Eg!(#L3j*Q{{?Uxz((@5}q>oT2aHnF@llt@@l!&tewUO>V&K0%JP6Z zwXDn^msSD@sUYQ#9IlWn;~I>uPx#8q<%Vixo(0z?wn=n}+z=0#QEUo47MB~!Enp?U zSPaN5l9UjVQMtAs>9hIV`Fpu6BG<+ZB89W8i~{v_1@oSHM z4`~SNqK6zUk)sWa!@NKuM~dZWl7UStDRQhxjy5u=Wz9vdDU_rAO0ed&8*QCNjumKp zmUSGtG$=>w0#sdN9jGh-Feb}bERrLBO&!ykk}u?wqt%RETYHLlAvO%6E?luSsxl97 zo1t_$t3;Ng(k;FJSW)RC%CB zPMa&9g{-A-OO*$^^Ru(Dc~&0i$~(|8wjEjS>y*>xif|!yA=A+Xs=ki=*wpH?w_Q$~ ztItJ*MoU8*Ee(3*o!tXl+vRAhTvr(|fNBU!TI9M~6Rl1lN1AEz(SK)^;$R5&!|A7A)--EBfJMmILxXeQm>t~C7@|wA7*nj@M~fnw05!0J`t%?1FxomeF)Ccz@v$E&^k1bMWjv*h^B#k zcwQW|iTzSD*2Fq!ZKN+YBN3@X16uwGib^PoWqjG|GOOnwsoZ3#FFrDYPQfM(IBuu( z(&>H;qrovM)A_L#g54ZEN%?N>FsgBNcZaDRP$61}hHY_aOW2ztW#`MKWy(>_b{1Qs zi8H>cEU_@)R*iMI8o1h~YI{xE613%IxaRA<5nnu=MsGM*XkmWukY{Z^WsODW#q(L? zl zU{KK`JS69No3cdqs13iu;1GXqS@!FgUdQK?MqZGaugnak(k zlqj?xQ|V*06;YaVdFPr}OQ1Sv-!TLN`I8KJXs9=9@{ZN7k~~$vttpVVaH1|?K{dU% zu6i|usd?e7l^|^4%&@R#kWV%Y%IQAtEC9bh!)wFIngKb@pMT&BvG)&%sr^6bw*N1q zo^x4T3!JeQNEgud-;2`{d7PXeUHB(3^OrtjqvI<6+Oxn0I?3j*OUB#n6ODdlvE*seF8x>-o|I0@Ro0p?P>{EDo2-(PH?5Gg?ELl|q2(VVzl8jF-)k@P{NHJG>a1uWo-4=|pzD3YDXBbq$GrKbJlJa&oV?0I*ejjU z(tG-%87^b6!YG=rZ;JWi`}UzXE?<->=^$_+dr_MDyo^FQ@{PG^U}?-+YU5J_a*%q6 zp*~>L>9yGmt-#FZ>e>>=W-~LhO$QRE8HqsvuEJ*Lta9dN4uaE? zX)Ey9k#tr+!`GH@OgS0=y6UKEX$Hc9QU+z`|4OB`5}f|I6Yl<7P6+-2em9=P{pf$t zr_tNdxhNt1K>Cn$84z)vzH{YtId>Fe&YJYE*oc!3-q40`*a(Xe73d}_Z zgr+6kz+TY;H(yKGL;x$cGqWe+!zg;A`9;hf7K*TSIX-y_vZQY~sg z|Be5OoMp-4r%0Ub(>QhZB1dvs&wJtVoJN_}cR|rOR>Lh@Fs2%1{&CYBW~vUJZTo&4TSuC6$#S;EDYwoZ zC8$lnRq`nHdr5s5+9JilHj1Lfq0KL1&AH|ZUwr#^lpCH$OT~GoSWg4rvU?!w zUdgsmo$5Ap9j2~4Sy5nL&Cc){e1VX*PE3!hxl-Rj)t0dDwo;B4n7sjMhgpmq4xwdc z=>}{K#K!-%(uhR93f_PIf}96?08ZmC5M2Mwk~!1G^-}PSCR>+hLR3EVwqMsiEwUjvSY3E8$#AmbtyoDq8kL z<~Y#qvaDQ7&%mg(%Au69S$bMT2kry6URgPIsa#ua0D%%_NajwGCCB92q#=Pub;E21 zlo~Ick!zy{2X*8nmrjFdgL>z|OGd`yQ*v#c0n@@A884f(=%K_eeiZhLD?>Y$lDdIo zm&kSMOa((|X%U;S!nIUea)fR?H?oSJx^mfJx_#ZiuCRyJ& zm<=_aFArN1!#E44%2kcfc-}&UstK0umxnEhz>^3DpzVJlg7ZJmliSEeqyhg7e+*xR zH{t^HCG>7UxX&xJK!2eRdXv4_XYae06|Vl=KdfmQJyQJD=BNK++sem(*zm+x-$q`% zhE)A=@Lj+8$ch4B^z#@O;0p@)0`v3r2UJDv{r3eG^{W9o80Qagg-^h@kfL5yQTrfZ zK}9`kfDXn56qN;h3nBFKR9OQx8!(QVQMZpV*6C8BQ{~3|ku9B_=Y!={`|3X3e zFXWg10@MEAbKU*FHWRx)T?@RfEpSdTE&nq4DUIbC>i>(pr2KeYN862@Yk@yc3#875 zc&}OwuNCy_&%P+_|NEp03I6>DI*h)88}Zl31^`OA-Bs+ahf}ao3J$?*6X9?rf;v6l zVp+}5!PdnL4QyVQVDs$S3PfANbf<=CzTUuVll$s6Mz#Q;E{7;91O}-xo8D~)^k{(Q z6V=N75^(P$yGPeptuU`#v|D0k#w;AUU9*`J%*~Z$nPsZR7f&Wpu1>QhTa}oZrPkCw zJ1n7^5DN#YPWtN6+*!+R{g`2)?U_y=%O07T%jzGUmXLI?H5`lnxvqpS-rtXM%5A|c zygk$-0&KF((4CSKnJgFBWeJK)Vhz?76>u70KX9)Fd2)w-MRdZM&6*F_Dff9aFeB`M z!<8fBS@lo1MJp9()x#Y9wghBZxL{h%bqc+1?A*$FmZ?tlvyk?}y)aq0T#;T{V*c*2 zglWdu0yg-~g=SA?8g>(#A#iXsGjYNWQwpbNTDL5PaHZ+G0ptDdDDwR&dTHu#Kz$<>X z55;++*Lq|47bH#EpZkDBl9LW{Q4bgx(Yfuptxk9<27Ma1i z4djYkf!t7M;W5fWMK0(>YMEw9E&zT5Eu2~&tIql5hDHm@6#B?`Ea#((y(XCI4lA7V zQZI&KQ zYsWfBiCyeUImuSWwFW>9p!^Cs$yT5>xDnOpNt$usw}w(ARbNh%%iK;`TA_-|Xf80L z4T-e>kIAoT>0Rym|9!=km@B}wz?orzl{-Pt!6w@OFT&4B;OFfN<2%f z%SaL20`N^hxsPjs*R}<~xi2h*+4ooY!ZEmX06Dz)0~~G{Kn}nAzHl7w7Ql`j`O>4s zaky82gSe|W4mSyK5H}Xb-~s{X>fDLq7~CD;gdZ%9!DRtX_}1bWToK@e_ZRbL{}aVA zy87pcLP2qiF8?{;o)9hnezI30KLHP*p8_AC?36z!_?R?d5d* zAHZ*t$iI-kA=ktCzfR)8Ux&Lt-*kpX$yNJIv_Mn93)53R$3dBrz}jAL&;ifd=G7m3 z>8r~_O@0BT-$CgUQ2HE{UIC@oLFo}tdK{FpfKql)5&hNVOjwMNQN?hSkxfFJ^?*9G>eiGk`593vE)91gU52DLqr%w&s1@LLtJuJ7jMCPIG4OwX0%M@A+avk%SJ^D@tg1&w9Fs@IumMY|k zr$(zT8e`C-yfr)zaZ9j9X(tSYxXO&T%#}14M|B`eTG-kz$S3FnF-ETb_rd)L=2}UC>Gt7OuU+y1iL8FKEGx z*bl@`a~BxIzXWqPA%zx9=%n@Nb~$>O`TvVZ7fR#>au1m$LnI7$e|{X_fG@%w7^4@^ z`_UwL{Rm6{Eyv-$T>?jo6C@z^19Z> zd5HIQn2F=NTb3!r+#I!6H-~)maC~=LgCW?FrFI*%phbM`*{w?rYDbIP=QZR$VJvjN5As z$qwU;m?YDRd9c5=Mi=d@PuA;oEukse(po(a@j5;EDRJ3QOO-;*P0_V_DnZLrHq=&W z2zDqvWYAK<&8u503~EP;u1;#^plXCy_LM8c+!RgK>%>NimagnsG7ry66OWOiJ#BG? zhnu2Pm=^KWS9scx>=@TYSN!&+kF2@p*}|W;zW7*u zIhQ83;&+F>v*tg3_^Gy=H?6N__lr>CPu^u9vy| z#G)$^(3o|_TpFzC`k4cf_doTqdL*Esa<1C>s}H}w;Xjq~zuzeT+ej0U@ptei@tt@M z@4{`^kG>DP{@(-RfW4>-6-qC{NZ|d_Rnq?Xihq4CH|$1BxnItuX|UL$M?hn?MK_mb znI+x21T>~}tMBB}BrW=M2x!duv~y|dEOOceG-f%iT$*}Iyjlb_=6E%8X=*L{Gzn)o4(SRIXgtv-*m~&b zN}UsJv-Vpu>^n}9mcJ4w3bIc60PBZ z*GH>);C0a|9(ZlEk_R4&R`9^9qvbqsD!PORUKx$^z=N?EfF057C$T6G-iKom9=sPv z%Xs2@qNO}=Yc$LQw?socaC5YT2X2fO^T5lZbUUyk!!<;-n3 zC4r-`71&8$9)*p-PVkZ_-3IIs9*fdlzz%RUN;d&Jz>z531MC2oMyUfJ2RO|4|5L#C z|KXwKzfl^e<^P|_C&*po29hNgl3~(8;zYtf!e7LX;Sb=q;p6yXycu`lC0If)qJKh< zp!cFTqA9cwtp?A*MbfXNZ%WTe4@$Q|&tTjr{PZif6E;aZ6qW9Y?cl=ij&0|{KM>!> z-E4iAKem<2@V?ktT=<=_5ib0W*cLAQ_Sj}F{I=L8F8tQmFc*GHY$F$bb8G__ep7rs zz#T!K-Mrn@$}iU+btrB8sj-%)GHUhr4j>H^5Y)rdQ%CtbHen~U(mbV}{jEh%N< zf;+2otv*xZrL=9U^hpk&G}-Gj=VExl1%66 z#t*jk>Y|+u%9K8t>H%BAO+(A)A)Xx6^q|C*6D>UoF*ikz>Z#Hk3NbfD5BKZDMv7KsdOGIe$(VSI6uqdeUE$%T=(uio4@=RD zTH5p|I8*fC3SBFO&sz_x&#E5@}E`@ttSuB^zV=REKn*o?L!Nu14v0>E8BT z27@EPq%xQtYj-q*2R;eur2g!KVE z-TW-wr1!OM)1%@{IO(o^x^6V(y0#j^orZd!NjNQx(oNEh?PuxYIqKZ0SDHSslq_A> zJ~AKq9Xm8_D0x!4t!;}!4n>k9{dPU!e2ltdvo0JtwZF}vroyk4Zf)PB({rTXy4|cy zopf{WutLsHRL_3Fr^9DOP!+YM#gW)S#{kYpfT&Zo=aoZb)A65tm|4z6R=kWimq!I zza3}Qbx1&C)^#!Q zqpgRp5YSLL+In~&m!{FI4=w+t(%;hl{|Cq%Sx=&{_WwAH|M%fq^b7P9dI$9Xmm{C_ z4Ip|gJk4WlaN~y=1;4Xh@@ieDap(&*A2gBLONP%v+LBgCp>ODSwqH6ac@f06AJ98k zoG$LO`!y8;tb6`I`{;b+&y1PLTcxMkE>_6--SemQ4tL<_VW953$Pn)Aop$ z@8|}U{`o_#`}L@B`sa@x&~;<|^K%tqe*gTDQJok%#Z#^4%t!pNJ|O~WAWwDeGt_n_ z!9yms+4$}Q(p~L)b;UUu=s|tJMn}T3bVvK1`N$v8^P4i#zOQY!Le9@X_v=~0Psio= z(ef{oyY=g|PKMzhev&pyfX# z?UKmH$PrQnxBk8hAHa?1N9aMA_uq;tVBhb@q*Fk!$fq;6OmsW?=GmFc=8ib-mg~$l zES5t(pwf|B3Kz+n96lPyMmS-BN5-C9Qr^SAjLmkO!Z;og>d4j0d(6%vjZkb%s_V#( zT-_oW)OfV#67n8?Je(mwG*;$nm1WO<_ZepGn`0`%}gJfI6M?g zuqU;L-PNuAOe9h>$LG`w=7*-!bCaXTQ=KM|$_8}W?Z-piU0q$NPW`7rG0U9xk50qY z4Z0{ZOjDuLtOH2W6-;#=N{>xULJw&u2*fGl7u7w*1RLH3Qk@LIq}pR?P;JsBDh2>K z`sK{JmIlO#4ZsxT%~UGHpfX<}ty;zcGAK<(HQErqtrMxa^u%OVOP0)`QT96pH=CHi znrM|coz13C4s~^ObuHHj6_84o>J%9z-z3fLIlAJPU2RMY@60IUu82 zVv>Tf_zWTpD%Awyh$Iu>}CxhsDC0oIi#jK{WR&%V=&u;SG%P;jZo){&ur!}+zq3I zrqox!cbML=MB($r$~?Pa(pFDBrCMd_YD!ZDYD8{4GnJkmA7xG;3@NHPCMTvdX(+Zf zd+>QuD)?A>Ha+DuZFg4!vIbw0okbHxO9w}iNQ{L%)#)^lIUyj56X1$tV(vJ-oJWhg zISHtz4i#-q2gW!tH<6yyTARrUOMZtdkY=GhGL;>DB56oz$XIz-Ja1U&rjJh@%*?XV zu6*f2Qk^!bDcf(*$_T}%xAO~$_GhTt`GuwwKO=NqX%MvN7|}XeXjEHc4RTFWVipVP zT3E6TFwl&r8Q+o#S$rwPY&1TF5>Xq@WMNa7sZNfDw(JKn)-xE5M58)wsED2bwEY0Yv9?#y6KA~n{ zaZ9Y>w`w#|Jp1O6wop8seTJ78S?F2Q&NU}Z0W6HGNxM{Mc4F%IWLl{M>G(f@FID#c zUrBb7B>pvi9{&}9+{d-Rt8al;dRQOz+Ba1d6@L1;@Y2tJ7{OHWI1@_!4Q z{J9A)hckayfWN<|&yY-TLBJ2SXuP-A(Ml8+vXSu0duuZs83slA$GyA5o+G3+!W z3;I5_bL8v%)LQqceqFViTlb0Dmat4~F+Zs~j7>Nxu2aXF+5PCM$6*%3;marH^p7!T zd??uzOElTWQS5>oNTo6T4xGc~goxpvLBPE3z07Tt3!Gp2ljLdukv`ZEpgbKw?lJ+|8> z4rQo8b-?g6T*z*Yf1AS~xt2EOZ2D9s)7fLOiKBrQX)=rKzWQ2&VDc2J?p6-@_IqHK;{Hiwo@L-5uU|V>OxqOJ^?E z=tt>?_Tz{ua%9KG;r)!62FOSfJ9p@SL=$C5tlP7J`Twnyw$S}QpCs=F55T)g8}Y&o z03XM9;1l5gZv_s*Zouck5AZeUVzd&KOTU-C06WRwCLIAb{i&&heFpw=$G*d`G6Q$I zzJlWG9QaaW4(@bSIi-m@Xv*j;-07uDD7L|YEiliXpKgv*s!j)0P@ytS@Sd)U@q-Jn z;A*23Tj>zwS68-9*GDLUGe$mBjB3g#jngV#)hZ38fCu*}_M<0-s=CUO!0BX|k~w#p zlmty-Rfi~1)FCTOWgR_TTSC$04s>x))upAF5_CEUia4fA6j9nr2W=>*S*NNHC?GBE zF$*io6i_UOUt_NcQUZ>)T6UuM1%UDG;!8{hX{I*?KvuBR6gjiPQhHSYXdtLWw*j*-+HNVooQjAZ0My7z};1WOL2djL3w)N&wg|0|?D z65RgzVYvJEFq{C2;osnY!4KhE!2jO}PNF}eFQN~jo6#{ef~uuINdE$!fbW#%fQkRq z_9=SXr+5s#dlkLy1QxxQD|*{$G`*{P01vs{-UThANp|#fvYVpo9O%+QQwFK+qD18m zqHv*BBswWUr-PtK%@^j{q@jb-HaKVtt$C=X9mpU(?0ReUWK|o*bK=FKRo_anoM@S1 z)!ag9I7)M}eKRHH=xojQO?)a_wr}JI%ggr5D5*1!YPN5n*h+_mjO??N5;%=u$v#O+ z<219Led+-Z*~i{lSF=w`9Ys4^5njS46O`834p_5VEhTa`1bS9$sG$VT*3FiEmR189 zrxCPfvgRsE#Zljx1!(y%m)1$-o8%Gl4mbm_k<`Kpz!%}v{~O>Wz$#pdevbYgMg~`c zr>|DzmA)fA0v`U30*mrAmD5ob!p^#QNl8e0GNW&W3@lxuP&#Y%cyWpJsIt}-NX8W^ z=a$7-C@ej~mg@seF;SpV2=rbfQ2)}XD9{K5dY2NYKN%4PS_XmMzykF*m5Bl^g+OmL z0`)B|6$KiGKyOq6^(DiiKtmAdTUnsK#tD&uE&P?kq39U9lBuO@r!VA$;T+*+E zNb2c?2scDI6z*dol14hQ!3~j=gq9g0;v}1;;Dv~bOA<Zo7MBz#qG*c<66MAz@Od%byZr)wReESr9P$P)>UdGj=rQ$ zQlXL9`#HK4rT-89|Gr6{Aa{}(vWZmVU*gZJgT{ zD?KCKC0(~DUx2lA*pK3lbI~P1woO%fqLz;N=OMVKmJa*pA-JW6j`%sXy&A-oHFTIS z#viVs1AQ@mR}CHKi}5Ko#uwuoYS~QLSUpYzl6)o(}Zqr#Vnh$NKZr^wzWc z0p|^?uaVsh*yu21D3}E!rVnS@SyL=M+sG~kT$u2|Ms~tyVZu8b*(sle31OLz#&u!B zhm-8wk23`zGRGz+CudH;*4?L-!#`0@jK^kXGtx74Z1C^2T1c0{{QnYio9h4PPhau5 z8n_ntbGJY}9ppoWXm9#U3-x;3S5JrdKx1$FEi`ma9%$^1znKPXy&E<@8s}@+&P-+g zOWQIEc+%{<>!C$I{u>_7IM%3=o_S2K6lUmK>6Rp zb`87de@xXK?9*2d)|of>o6bYI=YLrFv22tu><866Ju=~*|A9Rv`Vo|4+GYrgofdss z25jn{|4}bfwpdWNtEs56%t^DL(vh*99@DYIY;j@=>?)$5t8NaQd;UjD0Oc@|d;W)> z-dfqVmkki&Q3T{v1EiVxQ1?l{21O-%ZcC^&NO1 zfl3jw``NVo7sFNF_I<<9e)Q=i}ZczJ%D@#&&uLJ8>((EN6y72X-G1+ zNs1_S^XKUm1vDnjQIKNqlaz5{0^JeXB`G?6R*>=y*KzntoqWz#*?<(CUKyaWm^JM> zENo3b@G91{^X6wwAIMRxX_u3aHN7+@%$oM5mKPJIVJ11waMIfTQo91l02rVs4LX@0r&DFI0`)~*K|9cf#fq#xaiVwk0_i-)2vA~Kb z&F-w!+83whuLC2Lj}I?f|7bfFHnb z!bk8{+>E{G-_Vn=2lx~kg;Ro2=_Tol(!Z5!~rnr>WMJSC^8B=7c%77&93`~hl zRVhT(85=b+bzx>rdpm533rU86#2FWjL`{_vt{hWLyoq8;;^_LAB2rld6wZjKsZt2B ztaNNw4Qi=Uz-(!6#NarQo+{%FL7;JNozZDnRHRSWQwJkS$F8KHDKc&K)UODK#uS_K zD(X+fxos=R;!|1$9z-Br>kbx>4SBvQtQ76lToc2S{^3_W_fTq#05k#-7)QYH`FUgcm zO6%GvjZ+y@KB;O2lDIQ4wIXVPT;z<6mf@ROMzu%Al;KIT2}qoA(MZ&asF5qj6ccY^ z86|OC{bY(rWdl$+BcfJBOCgq(j!V?^R7o;h+S^s#;;eb72O4KXr_-pZQpcBMic4u- zg3>sZF-4}T7D$|JU7?yPH4s&2Y_wFVX4bSvMl(6Yg+Ly@z;)+KR|H{__~p6tea-IX zff!{kJ3gv!TUZW`e_?^Z3}OomKzu^BDq5Ts4bDvky0`H}lHa=Et9}v5%`EW4JvggU&z4U7B zUdsCv4`lcA>HJ@*w3gogeH$4iefSUf@9>@YeB6M3kDfr+gV&EZocMiIx&nwe&j8F% zH=sfL6oYw@vA|dWHLr!FVD7pT_47GRo^^r-yJ?xf38uB9sF}lkG+;2$75L>aw_WMf zP+bo88^q?t;uOqw*P&s%cw_0;XYd(7ZN;|@X2Q!+yPaEEh4LDl3Sa=H#=(U4N&Ll_ z5N6H6gnZ70O$hVpU_uVJ!-O!U4kolyE?`2KV+Rx3nG9>qZ$g-T2NT-41t#o;+4u(3 zZJ*+{nlNoFrzLoTGrE(8}9OkC_#gRz~(NmYBi97r$KvRP&~@krzn=AsZr8S*Q}y698Hw+bh>#Z#d9p9 zR6?ez4v0d0Xt~2g~!exPp>8ZJ>Btr0stJ-T!kh*#Ulk-i_D8 zTK~;xK>D`yPRs6|h0DN}f?{f_y7FotLIJSo~AGa?R-1oB|)keQNozNOC1VPFPEr%f3sC^ht5gF@n=4DCC zWX$RQ0vZ{1L`$*{ndd#DwKYf?*%>VdW8R0fRt2aqcI3?=Y+;l7fmt=FJqr1m)CYo8 zliCI4V^S}TjAByz_?QG8qR+!WKOJyB-6xa{AX1o5ddgU57x1a{SjJLrW3U(xvVEFBIz&#kBlm@@rbe zFDJhzzlIw?Mo0?@;veJB;1A$a_+q>om!tniFQAXHJAihfb`+F;EIlvXE4@h?mo`dL zO|^2j0dkx%Y6)Rdf~hlejF5~R$EBpVhJDwbK7CrQ0cYkw0;3tbA*CBaKEGTCp3DUz zZV3Ao5z0j*Aj2-=oRI93agB2Q2nW9|MC3AD2N#bBf_NkxU_sQuwIc$OheHZUjdI@z zCzPp>CjeR~H;r)c`$DoOj_cu)5f+3a7E&(cWm@1G<$4j0jLDG4TZ!x8ViAFiJ41@S zaV^{{0yG>M(sd!PuNK$CeIf!O4~7(r<65{*L?Gl2NVO!chr2`sLY`F(hHK#(5rL2g zLjFJ_rdNmvggm1NX~lJLg$Sc@9E6jeR%vSB@(>n|ljMFHP7T}}BEa8HBU7#38R9%@ ze=RjwwR%&C6Md8>O0{}Nh!ee+rhBz|J%|&%mS)as^->Tgx|x=+Dth@Sf(t<$QCkwi z1(o#rP~;Douu$5s?1$I!YE%1vHI)DRVHeOfPzUTLDYA@&VI}Yf_zU}Eu_t{ zD&UJWbD-Wx69?*vG;*MFWElraA`KiUE?Y|49H-#QlBCUXpe#}k{Pqq^L8OiY4Mq|i zXdqI{f%+pg9H=i+&4GF&RUD`%QpthJkqQo!M9Mi(T($(PV2@i_9IRjmMq0+9d*>W}z2P+!EyfqEle4%8FzaG-KT=0Hh=aG>)+uAIPm_JModvkQ>Qng2LIzU4;xCd=p>H^?M_mdeDBlJs{$J$(o3=sS?0Z+|U)`)cUh zTTS1dD*Bcy>6=v0H!i1AmQX2i`nw=T-@zz-2cYzWlrsAEmD0C2Oy8ameaj{EO^WFo z7f~sNR7wH;9SG95KS19;KYe?B^zHG|x9p*BBGWe}loJ!;4`4_aOrE2uGX*|Co+EF7 z(!QGvk_7RAH=r-$Pr@kR27D>p1iS_>!$s(q=6V!d3$N31JjZbF<|tu3qKa}1SL z@)4`U6?{ahw49GviI?yZgE-Dd^y3&G(I-dwh+a9uNAy7B&rOe3xs;D+DGBot%_Si| zqOqiek62bz%ttg77x58ET*yb%;{rY+frETRc|m}WSW@8UBVq+UJ|Y_M@)41shmR=5 zG9MAfgpVk|n7XQQj)*-fgV9xk5;qAhabWafYTifRed(sJNw+8ICEZ8)LF|ep>HNP> z+91KdZ=n-d#&00Sd%r^u>49qTEh)F}dblAUnEeVrpc3RQnB|%3bLiAUk2X zty~9-_~;GhI+1owI^1F2rUBt*dHPemk)7Udo{M(*;#(U~ZZlKOD;K=w`;K>X{j-W@Zwza)vf-ED(0j_-*R7k zIEix0wG6ajHj{=syPU=V%{APdMFSIpYYG#79!nhS^~DFvQLd6HvW^`XP{n~ujky`> z%UOY*w1m#5q;Xd;<{))JitYP+@ih?jMi%0TdgI$fMvFS*9~n0xuCjz|La2(W95iqf z(yW0-K}!hj|2NP^dmP&C+o28r4BYVhTT}{n{cc1Tp%dsPbRT*eeGUB=E`)1Ghw!=h z7=8=>Yy3EP2>KcE!iZpioJ}qv*OT{9ct); z)AGMmx>SOHH%K3lJ}G@!`Z@BU1R6xU(NXjU^j`D``X}@vMz{hmhxxw@z6Rd`UV{G~ ze;5CO#7Gx8i;TmZ;hp58^Jct8fVn|lE5N)}UMIlZh}R1+H{lHe%*}YC0CP+IumE#w-6jF%w&Z47{+FPe zB`CR{hZ1}zl;m+J(Oo14bN}DPpT!@-x8W=B0lW#f;Zj%!{1$iuydN0c=YPclf|Pnz zJ|Mt6(>f}^Jl%S+0P|GqMFPx|%@+zVPqbVhz&wu67hoR4=Ls;6;{5{5Bl5Wd%)|0I z0?b2rp8)fqyjOsEpmC1?bARJ*0p`BOvjv!Y8+HjW_bl5fz}$^@2rwVO+Xa}r@HPSF zeR!(?bEkZk0CPujM4A8l6wS+*lJAgDkvXy-*8UPi#xLT}Lpy&PtovPv*FoPufPRMl z89j{Ng|0?vnE7i)Mc@he%hD&L_ewb_Gf!~ z2Yewuu9)%_iEzMI$j22?z7i1*_=@?s0?Jn)!U129j|);hp9lwhUOp~B`2r#w@cH>T zS-SIyn>~CSp)z55nwLg|rV-)eFy+JGtQpCUwI)pY6gK-Pj;S)t$1znlif|xu10Tm! zSuer?-#P_nA8ImP&f?>kE+Zlw$lSumFdOqaEM9MfeD4+o|0m;$#K zuSS{#y?~$LbS4?`Kh8p`^^Q09Mz19&N33-!R| zP#=5*>V+3!1t9_T#D1tRZYB?s&yw#iSpMx1W_cvVi`4z!U`AZc$FV#)B*Hrj`UNUPO)&R&09}RdgdIL#KtIL) zg-ic@<)5ENN~zwZF9!!jpp4H~MrFoCIN*!(aZ$=wA;JM)B_9`~d`m<);4A0j;*_sS zgaf{6KCYbdB}6#jqt`2Nx>^;KuSSFezFI!6lJeDyaKM-3y%C}U6 z1HJ}6u9osOiEzNz%*WMHzBUmK_}clnddk-#!U10^AD5(j9U>g?b@Fiyl&?pG1HR>a z+%n47CBgw;H!c4@l9I^xp$&f!+H%(apQkN%QLY7C3or}t%T+7wSFaM`pggYR<60EBLr($~P#&0p9>0*GT#LX!)-~a}xOxcmRAH_V&FUcK;oKGXOoL66OGYhQETJ z!uR2Kz#QNh%>MV{DlDU)!fAj{qPx-CfYE*Owm@8lts3_3wDe>-AO7ePKKzk5AAWC) z55FtQhu>Pphu>Jrhrcz#Jg5`w-k$ z!OB0mnC}1m4f#*|V0-Z8e_H_EpAM%Z@WGPd2flx_D7v+ceiw%xac zZTBr^+kK1JcHhDxDxsi|zJo7s!!O+`Tt#1%^i@Ik|I+ebguldZ{|WvHpxno`z?ozL ze)r_jARm5LfDgZs-*lhgcMA^ky9HbM-GctS+W!K6`>%+0wEs#^$L7)w)g)YIJM)R|8?}VB=`L9+UafYdh(fCWly<#{ql4v2=E5z8%MS;4Uj8Wx zHyJ)Z9FjD52)a9GvCogf0mJEs~tKs>>F-^dWkM8*+xWRD!;ow}X>yO|z!}o_nNZ!6bf+@rKheO(e&Od@1 z4DTNf?!|il2(CBWe>j9_>5{fzdSLZ$6Qt$81&->&Ip43q?jQI3|EUMwd(k6TG~V(n z_xwLSbK#!<-+$5l-*{b~|7V>!TK$z5?E}D)~poa6D647XyYKo2V~^4>lZ1Z#tyFSfj2x&156Nyu%QHB3k1a)C7u6^ zq9YRQ{rv>FgIrD0WF4u%{|z^QJOiivuEgiTx&I_4=m+R2@b>ctAa$RYVS!2+E@iQ& znsSE(DVO0k83zt}zutu0*5H_qF!$h=$#9JghxPDe#&q=ru9D#v8atVK35};#hTCTB zNW;&a%v86RT}Aa`rn&5Sox^L@y@;u2Co|M5Vd~lEyA<`xn0gKz zs264GaWD|L;wCT5)ZMVNZ_dQDL;z|?c#K)nK{9tWeV=VR*eDNO45 znR<3IL%m=TZj^lJUnTUfms}PNkVpn@rIlogacocj45oD;Zd-V;C8ve48o>W-vJ26CpU%EKidN?D;(_KGO4EMXosYc$H{vhr|A?ZCO z%su8ZowQp>`h?PVZP7@RT`DQIx5v_BYBv`>pXg*n;Ks>8^a0w>1&R(K#Z9!Mi=MA- zXEx!;xSaNMfuK!9FiyL=K+q~8*iQSpK+qy07^IzDAZQj5)YINBdcLNK5`bGvM?}LV z7^81jH&Q$}wshbNN-+9mVi}XqaXZ@=X1PwTZcsIF^s#!u>!zGoDiY8eW|>j0NvZ-I z{ijy&%PHgPdWwe_IPm4*m=h=JL;)NKvpg(UC)5BO8jgZjQ8`g75-=K8oW<7Er~(`s ztPc^7jOqD5ME;$Y*K5JY-`y|=a02}MZ2=E}us;Ci0lti%gqeVw@ky8q*b4jqs<9XS z2l^`b1i2sG3TFf|uud=l*S!U$|B}8TJqNx&?|`!e6V?gtLi{aRA^wtV zh`%Ho;xEaD_)D@O{*r8nza=ZgUy|i-bt_rNjeE&jK6niuJj4gD=7Upw@G3rdB_BM< z2M_SU{e18WKDdt$?&X7*^T9oQa5o>^#Rqrt!5w^XJ0IM}2ejPRY9bk z0}V#nIM6_(l>_zD`M*Zx{NEkWc0UJg_p7L!Ex#(= z$iRXs&)yj>Q7T9WSWuk`DqlfWEvVQ9&48fM5HvA@21(F-2^u>=(k`zw}X$z?t%4kHFX5xJTe+ z@1SQjKkx${flu*KufTQqs7K&z{2W=})_b4G<@R1#;1qh7Eby7PUF2VItDNFTa6J)u zIwt~`i))F%BXx=h9QF+ofjh*0B5=RgM+8n9du4&Y$6g}v_t=V){Ft|3fh+fBk!S4& zk>kO7kt4_iUP(RA1{{-U<@J2{66U+xNgo;H(}$ZV-0zTI&={j|$Lya+A-8vheH#?G zWuO2>`xM`FP$cR6zgPN#Bz*z;`k%v1_*Z09+9hqH6~fDS!N=Z-sZ3&I$6orac-E#r zaxE)-@$-^6HzshXZ1}z&-7}Y-ougtj?ZEA_bln2(m3jR0_*yo|nQwAENap-`TfaBn z(10&srpjJAIWdqU*1NUnlBh&(oWi?EjO_&m)AadUCF9dK_Na^whD*Ompt6L0`PC4xhS+iC3?~1A`e~(%USe4TR!*dShb! zww>$SH0RThSi_r#cem|1mKjUz9p1mU&2Ws(ewtRX!B4nGt}M=*0K?OBnOQ9_Fp0yL zPq0+gdA3a)%FL;`g;F#hS?P;6*Wp~4CQLv@)OS;jL6$}I=OUz6s42apgw&LIDJYf8rIJk((-YYvy(M9}PAVChK6ZR=)5K&Z+ZzqZt>*YJ z)2~=jTtXwTfBUvwyJ(DhtBd98#whJ|Z=1-n&Nlr!N&&qq61|}!5Ub<{=$_A>?CCBo zlpCb*cE}mC%*uym1_wh0luGaQXM1`>K{+Xv7&#_8xGW%-50*16vdY_j9ZyepVnw1m z;FqH`BB0x_&yy=yIQaybW@38g_#DkP#aE10GqZGrM58=dj165!rsukw zkthS3PrX9XeRCBp|Af3mi}738{ogOaj{gcc|9dx@LVeO7rEf`3f@jbxr2WzgN~AoA zQeSl=Jtx7<0&>LTNrdO62*K{E(7Y6dgd|GlrSM~1Q_Ls=0lpq`brHq;{eC`vMWL^J z5MrSWN(C9rTSDwZiWLQm;PV8reR`%Z$oK;Dh6lE*J#yD2qigk(h`j;I2G>*1R}MV( zVbze|ms~?5XUcY_PivlCM;wt{?E`+;y0$2O?1<|sFJ%t|7R7Fl@hT5xh8UX^Hho%k zw?}-d>`R`vV8o4y8KdZNtZ)_qVGCM;C(LP*Ettw$$Rs>jcKd8WRMJBB;YnHo1^5P9 zlHZhs*I%&tzfvgLv#y>BfjUy>)jvc+?3LrXIw}GxN1apu5Q(riA?p&p z&48Pq7!&Sb9t<(tS zk%swOwWfL0vC7$58m`P=45#n3v4V*SoDVl=8L~K3^d1)Y!h|Wuq@cR>yc`2%VzC_u)6id8bTK=nG7*D4@^$ht*!}YkxY1{XwBg_3=K<(Gt_A)S7FfPaZrEIIx+pwr z{&sZYdIl0O-`3F}H>``A3C-W5rXM5Yz|qsSR376`ubJnCp>F_l%e!VXhqB$3Nx9!V zIcgdW^$Zr((`nWnF!4Mxp6wmzuaj$c*6JNk{llUBsM38Jgt^+jM0cXQI6>#~HfF}s zC%4axXL`f6FiTptX(BT@z87vE&vy5BHPp!4EtC@C!L>dcFyxS*h`BQK7kV6dw_FOI@MpsOt}jsm~Gt2Hl+NdJ zi^K2nbT#G0;gjXA#=JPZgmf*-i^GF)M+0!Mx$4>UbT&OUH!(9kPl=K@E`?#PI!0w{ zO$!gV4>*UZto=uykzn=zJ>b!QfOzo>_!hhi7Xr|I&J+u5SnF%pOf!S2*0p9Hwr_G& zYllY0%bj^){TdKLrz{pN#5rlPc8JP=NsC3xuuog8T}>sx5Pi`S>=PGVsl3Ww<&q^` ztMcNgh{wBD=EYGSi**g=#jzwB?Hb67BOZx#_2>#>o9@z-Ft z{{h?#YyBTam!ob#y^f!5>U&smo8mZJS+-K!!?2R>NTC0VP8XgYrcQ>3>%i}X)8$>M z!D1|8Yug?S2o=*ueGDrOXdEGj4Ka$NDCJGrx~YR1eiDpHub304)hv*e>N^%<-xY!@@1!qiK!s<3_C*UYA8iQsAG3V5)R zWeGb=$Vf}`utMFrQgk|adYHNbR-F- ze1&)ZPrd)^bzJ=2sJ%`tz&&3V7M!o;pT;fWyLeGf-PtR^GR2RL9bBsTv9W{0%3)l4 z$EQp=x@QNM@^ADAEBAldYqm1w{I4Bcs+<H^QqX)@TmH4(B3@RH>vgYN{?Ti6HqH~39(=6@BA{{QyQ zF1Csy3c$NtkXE3(m+&VR+;&F=xlpb}p+M=D_5$Tsu}~01OUpm>s>iw~L@LkIzlqC_49B8eIvd;$R_sFCnuG@h9~yK`rDX8lQsM(=%SntQ)Jd(Q68 znX_}wo`r6I=ggzwH z5<*!I>nK6iLuv|xgizLlI!cg5)D#8@p)5~F39`!66b1>QtWq5%$a2*b1_`082XvGm zYlxb{AR&}BSV!f`@=AjFU%u|e5p=%>5+n@@hFPK{Vf^od3_xAM5a|B@1$6z`1M7g} ztiI+g$O9gMPM`D4QPAb{3Oo;xF#e|p`;=E8sP?ws9z^!uGz|pWI}nesk5{jUY`-T) z|5JlQD!UuWNlejExrd8PR#TFb$m%FTR-KxXoJ6gT5@bzMQ<9UY(NTgdUrk9)qFP4@ zvL>o2$w^e{C_&Z)H6=NT@j6P7HBL=QPNGsr39`njDalEU(NTh|$JLbNBp%aIxw5>` z!T6W2d(lZ$XrNq4!uY50|CEAK>lf(y`>xdqo&KuencttF-_KiSJ5&N!K=1Es#z)4R z#wN}EKWPcnm&bp18g$rxuTv+-tUmueY1U9i*XeyJzcBCsWJv<$_ItD``Br~3GrUN?tdKS>rRP+(*ID?RTkIYOS%P=Sqs z@&;LyKsi2oL$Xj!vCEL#_;dng`!63GcC57W09l};1RLikP~d*QT=>n|RSQU?hGI5W z|A=R3UIOJrXM3)iV#9;m*pNVhjlB+Cn)&Kf@|2DeY@CxofsM`S_gYV+$dek1+UWRr z9=#`mu_j;lbU;SRd$aYB?Z5P$+wJGmx4l^!C|7lFrXI5Wdw=+KPigma-VDtQN_9fL zA@@h`|EC!Rm!bY|FTDMC5_JE+V_me~hPQt$w#Hh0%$w#}^RT(qY%oWfh49?(DdT{# z9yXCaWQY1d715#32ha8d%Jz#p+pZt)>P@z3s9^Av1iL0%6DY?oLu!kfV)JKoZpe!X zlmhU;Tt^(olho^g%87kc|nHhwqXZjQB~V~v`HkieIx5IY4HeiJy6_bVl;ekId%2ooaS*q0Spo%< z*`?a-XZtf`sgBCEk&b_>;C(j!gKH`OH-7~3N8sOl1W3DjWV5?V?j>GIplpA4rmb^8 z{R%q%yFue`;~n#Y)mqSHY`FWDciUMuu}8m5rf^ql+sdVzp#Ylo2n_4JmbS#d!A@*D zhfL_vue`i)*Sg#d!#eCO;dap%xY@k=Y-7Bmpxe|6?F6$kvb7EF5@<^}l9tHT(Qny5 zY1Uyd9c`Bmx(ucRmOY9OP2PaUf79-CXeXC;X+yiT8$CYkPM$M+rt22PbfcXR>E?9T z=|D)U+qB$u8>eRHWZj~o9G$A*2UO3knN=sMz zYa9^T_o<;j(Sh*~Th9IMvoD-RZqh$<9{K+7%86W7eb0dMa%&swwm5fv3v^CtsbAZ& zvbl-Y1;@TH4hknP_PaZD*&4XEu#2Kwmz`WQcSeJo8J5%krwj7`^!~pL-v0G9^!?gv zt*|CpCFULTBE0Kox49VJ3DC#5X`D3j*wKwURskrf;_8q0Zy8@R@EXA?fEXoek5vFN z#cs*D_I=bxf>B)il#UX#$0~sM9)aT8V--M*61B%F0GVPp+gy9B0#H(1d&~mHDM5Rz z0#H(s_8wFLs9tZ&mXE_r!h<3JC6v2A4{88tA&R^|DycYHh=vjXB}9*CxW?>31ptLq zYi%hX*Y-U~04gDnlnPT?H2+T_)q*^i1o?j@BuGlg|EIzN8ZRgRFX#VKki&%m{08R# z8+iUdKmPOMKU_4;kAJ8z`_GPlRzFAM|ADZa_m|iI^wWRhFC?R$>)5>upLsC(FMDrB z@tFsc|8XjJCLoynS5nc;Lq=%y66Z}!{>!r1S|ZmTlmAMJYmdqQI3;M0$$urqwa4Ut zj1slSwjE(O#Uk=u01CI z1;h8p6N; literal 0 HcmV?d00001 diff --git a/input/enrichment/linear_src_enr_rxtr_sink.xml b/input/enrichment/linear_src_enr_rxtr_sink.xml index 8b8b177ea4..fc0d29b720 100644 --- a/input/enrichment/linear_src_enr_rxtr_sink.xml +++ b/input/enrichment/linear_src_enr_rxtr_sink.xml @@ -35,7 +35,8 @@ natl_u 1000 enriched_u - 0.003 + ef_tails + 0.003 diff --git a/input/enrichment/natu_capacitated.xml b/input/enrichment/natu_capacitated.xml index 15519a106b..569dd84380 100644 --- a/input/enrichment/natu_capacitated.xml +++ b/input/enrichment/natu_capacitated.xml @@ -35,6 +35,7 @@ natl_u 100 enriched_u + ef_tails 0.003 diff --git a/input/enrichment/swu_capacitated.xml b/input/enrichment/swu_capacitated.xml index 2409339a35..9124fee179 100644 --- a/input/enrichment/swu_capacitated.xml +++ b/input/enrichment/swu_capacitated.xml @@ -35,6 +35,7 @@ natl_u 100 enriched_u + ef_tails 0.003 30.0 diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 3c0c295086..6cafaa52f1 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -1,7 +1,5 @@ /* How/Where do I check that enrichment limit is a fraction of 1? -Where is the default max enrich set? -Use MaxEnrich or max_enrich? */ // Implements the EnrichmentFacility class diff --git a/src/meg_old_tests/fn_behavior/behavior_functions.cc b/src/meg_old_tests/fn_behavior/behavior_functions.cc new file mode 100644 index 0000000000..6d319e4cf8 --- /dev/null +++ b/src/meg_old_tests/fn_behavior/behavior_functions.cc @@ -0,0 +1,7 @@ + + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EveryXTimestep(int curr_time, int interval) { + return curr_time % interval != 0; +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/meg_old_tests/fn_behavior/behavior_functions.h b/src/meg_old_tests/fn_behavior/behavior_functions.h new file mode 100644 index 0000000000..f3be83c90a --- /dev/null +++ b/src/meg_old_tests/fn_behavior/behavior_functions.h @@ -0,0 +1,17 @@ +#ifndef CYCAMORE_SRC_BEHAVIOR_FUNCTIONS_H_ +#define CYCAMORE_SRC_BEHAVIOR_FUNCTIONS_H_ + + +bool EveryXTimestep(int curr_time, int interval); + + + + + + + + + + + +#endif // CYCAMORE_SRC_BEHAVIOR_FUNCTIONS_H_ diff --git a/src/meg_old_tests/fn_behavior/enrichment_facility.cc b/src/meg_old_tests/fn_behavior/enrichment_facility.cc new file mode 100644 index 0000000000..38c3da6cb7 --- /dev/null +++ b/src/meg_old_tests/fn_behavior/enrichment_facility.cc @@ -0,0 +1,357 @@ +// Implements the EnrichmentFacility class +#include "enrichment_facility.h" +#include "behavior_functions.h" + +#include +#include +#include +#include + +#include + +namespace cycamore { + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) + : cyclus::Facility(ctx), + tails_assay(0), + feed_assay(0), + swu_capacity(0), + social_behav(0), //*** + initial_reserves(0), + in_commod(""), + in_recipe(""), + out_commods() {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +EnrichmentFacility::~EnrichmentFacility() {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::string EnrichmentFacility::str() { + std::stringstream ss; + + std::string out_commod_msg = ""; + out_commod_msg += " * Output cyclus::Commodities: " ; + for (std::vector::iterator commod = out_commods.begin(); + commod != out_commods.end(); + commod++) { + out_commod_msg += (commod == out_commods.begin() ? "{" : ", "); + out_commod_msg += (*commod); + } + + ss << cyclus::Facility::str() + << " with enrichment facility parameters:" + << " * SWU capacity: " << SwuCapacity() + << " * Tails assay: " << TailsAssay() + << " * Feed assay: " << FeedAssay() + << " * Input cyclus::Commodity: " << in_commodity() + << out_commod_msg ; + return ss.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::Build(cyclus::Agent* parent) { + using cyclus::Material; + + Facility::Build(parent); + if (initial_reserves > 0) { + inventory.Push( + Material::Create( + this, initial_reserves, context()->GetRecipe(in_recipe))); + } + + LOG(cyclus::LEV_DEBUG2, "EnrFac") << "EnrichmentFacility " + << " entering the simuluation: "; + LOG(cyclus::LEV_DEBUG2, "EnrFac") << str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::Tick() { + LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is ticking {"; + LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; + current_swu_capacity = SwuCapacity(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::Tock() { + LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is tocking {"; + LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::set::Ptr> +EnrichmentFacility::GetMatlRequests() { + using cyclus::Material; + using cyclus::RequestPortfolio; + using cyclus::Request; + + std::set::Ptr> ports; + RequestPortfolio::Ptr port(new RequestPortfolio()); + Material::Ptr mat = Request_(); + double amt = mat->quantity(); + + if (amt > cyclus::eps()) { + port->AddRequest(mat, this, in_commod); + ports.insert(port); + } + + return ports; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::AcceptMatlTrades( + const std::vector< std::pair, + cyclus::Material::Ptr> >& responses) { + // see + // http://stackoverflow.com/questions/5181183/boostshared-ptr-and-inheritance + std::vector< std::pair, + cyclus::Material::Ptr> >::const_iterator it; + for (it = responses.begin(); it != responses.end(); ++it) { + AddMat_(it->second); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::set::Ptr> +EnrichmentFacility::GetMatlBids( + cyclus::CommodMap::type& commod_requests) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::Converter; + using cyclus::Material; + using cyclus::Request; + + std::set::Ptr> ports; + // *** Add to modify preferences for specific timesteps ***// + if (social_behav) { + int cur_time = context()->time(); + // only trade on every 5th timestep + int interval = 5 ; + if (EveryXTimestep(cur_time, interval)) { + return ports; + // if (cur_time % 5 != 0) { + // return ports; + } + } + if (inventory.quantity() <= 0) { + return ports; + } + + BidPortfolio::Ptr port(new BidPortfolio()); + + for (std::vector::iterator commod = out_commods.begin(); + commod != out_commods.end(); + ++commod) { + if (commod_requests.count(*commod) == 0) { + continue; + } + + std::vector*>& requests = + commod_requests[*commod]; + + std::vector*>::iterator it; + for (it = requests.begin(); it != requests.end(); ++it) { + Request* req = *it; + if (ValidReq(req->target())) { + Material::Ptr offer = Offer_(req->target()); + port->AddBid(req, offer, this); + } + } + } //for each out commod + + Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); + Converter::Ptr nc(new NatUConverter(feed_assay, tails_assay)); + CapacityConstraint swu(swu_capacity, sc); + CapacityConstraint natu(inventory.quantity(), nc); + port->AddConstraint(swu); + port->AddConstraint(natu); + + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() + << " adding a swu constraint of " + << swu.capacity(); + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() + << " adding a natu constraint of " + << natu.capacity(); + ports.insert(port); + + return ports; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EnrichmentFacility::ValidReq(const cyclus::Material::Ptr mat) { + cyclus::toolkit::MatQuery q(mat); + double u235 = q.atom_frac(922350000); + double u238 = q.atom_frac(922380000); + return (u238 > 0 && u235 / (u235 + u238) > TailsAssay()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses) { + using cyclus::Material; + using cyclus::Trade; + + std::vector< Trade >::const_iterator it; + for (it = trades.begin(); it != trades.end(); ++it) { + Material::Ptr mat = it->bid->offer(); + double qty = it->amt; + Material::Ptr response = Enrich_(mat, qty); + responses.push_back(std::make_pair(*it, response)); + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() + << " just received an order" + << " for " << it->amt + << " of " << it->bid->request()->commodity() ; + } + + if (cyclus::IsNegative(current_swu_capacity)) { + throw cyclus::ValueError( + "EnrFac " + prototype() + + " is being asked to provide more than its SWU capacity."); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { + if (mat->comp() != context()->GetRecipe(in_recipe)) { + throw cyclus::ValueError( + "EnrichmentFacility recipe and material composition not the same."); + } + + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " is initially holding " + << inventory.quantity() << " total."; + + try { + inventory.Push(mat); + } catch (cyclus::Error& e) { + e.msg(Agent::InformErrorMsg(e.msg())); + throw e; + } + + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " added " + << mat->quantity() << " of " << in_commod + << " to its inventory, which is holding " + << inventory.quantity() << " total."; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr EnrichmentFacility::Request_() { + double qty = std::max(0.0, MaxInventorySize() - InventorySize()); + return cyclus::Material::CreateUntracked(qty, + context()->GetRecipe(in_recipe)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { + cyclus::toolkit::MatQuery q(mat); + cyclus::CompMap comp; + comp[922350000] = q.atom_frac(922350000); + comp[922380000] = q.atom_frac(922380000); + return cyclus::Material::CreateUntracked( + mat->quantity(), cyclus::Composition::CreateFromAtom(comp)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr EnrichmentFacility::Enrich_( + cyclus::Material::Ptr mat, + double qty) { + using cyclus::Material; + using cyclus::ResCast; + using cyclus::toolkit::Assays; + using cyclus::toolkit::UraniumAssay; + using cyclus::toolkit::SwuRequired; + using cyclus::toolkit::FeedQty; + using cyclus::toolkit::TailsQty; + + // get enrichment parameters + Assays assays(FeedAssay(), UraniumAssay(mat), TailsAssay()); + double swu_req = SwuRequired(qty, assays); + double natu_req = FeedQty(qty, assays); + + // pop amount from inventory and blob it into one material + std::vector manifest; + try { + // required so popping doesn't take out too much + if (cyclus::AlmostEq(natu_req, inventory.quantity())) { + manifest = ResCast(inventory.PopN(inventory.count())); + } else { + manifest = ResCast(inventory.PopQty(natu_req)); + } + } catch (cyclus::Error& e) { + NatUConverter nc(feed_assay, tails_assay); + std::stringstream ss; + ss << " tried to remove " << natu_req + << " from its inventory of size " << inventory.quantity() + << " and the conversion of the material into natu is " + << nc.convert(mat); + throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); + } + Material::Ptr r = manifest[0]; + for (int i = 1; i < manifest.size(); ++i) { + r->Absorb(manifest[i]); + } + + // "enrich" it, but pull out the composition and quantity we require from the + // blob + cyclus::Composition::Ptr comp = mat->comp(); + Material::Ptr response = r->ExtractComp(qty, comp); + tails.Push(r); // add remainder to tails buffer + + current_swu_capacity -= swu_req; + + RecordEnrichment_(natu_req, swu_req); + + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << + " has performed an enrichment: "; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Feed Qty: " + << natu_req; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Feed Assay: " + << assays.Feed() * 100; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Product Qty: " + << qty; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Product Assay: " + << assays.Product() * 100; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Tails Qty: " + << TailsQty(qty, assays); + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Tails Assay: " + << assays.Tails() * 100; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * SWU: " + << swu_req; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Current SWU capacity: " + << CurrentSwuCapacity(); + + return response; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::RecordEnrichment_(double natural_u, double swu) { + using cyclus::Context; + using cyclus::Agent; + + LOG(cyclus::LEV_DEBUG1, "EnrFac") << prototype() + << " has enriched a material:"; + LOG(cyclus::LEV_DEBUG1, "EnrFac") << " * Amount: " << natural_u; + LOG(cyclus::LEV_DEBUG1, "EnrFac") << " * SWU: " << swu; + + Context* ctx = Agent::context(); + ctx->NewDatum("Enrichments") + ->AddVal("ID", id()) + ->AddVal("Time", ctx->time()) + ->AddVal("Natural_Uranium", natural_u) + ->AddVal("SWU", swu) + ->Record(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +/* + bool EnrichmentFacility::EveryXTimestep(int curr_time, int interval) { + return curr_time % interval != 0; +} +*/ +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +extern "C" cyclus::Agent* ConstructEnrichmentFacility(cyclus::Context* ctx) { + return new EnrichmentFacility(ctx); +} + +} // namespace cycamore diff --git a/src/meg_old_tests/fn_behavior/enrichment_facility.h b/src/meg_old_tests/fn_behavior/enrichment_facility.h new file mode 100644 index 0000000000..cee712c5c5 --- /dev/null +++ b/src/meg_old_tests/fn_behavior/enrichment_facility.h @@ -0,0 +1,324 @@ +#ifndef CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ +#define CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ + +#include + +#include "cyclus.h" + +namespace cycamore { + +/// @class SWUConverter +/// +/// @brief The SWUConverter is a simple Converter class for material to +/// determine the amount of SWU required for their proposed enrichment +class SWUConverter : public cyclus::Converter { + public: + SWUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} + virtual ~SWUConverter() {} + + /// @brief provides a conversion for the SWU required + virtual double convert( + cyclus::Material::Ptr m, + cyclus::Arc const * a = NULL, + cyclus::ExchangeTranslationContext + const * ctx = NULL) const { + cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), + tails_); + return cyclus::toolkit::SwuRequired(m->quantity(), assays); + } + + /// @returns true if Converter is a SWUConverter and feed and tails equal + virtual bool operator==(Converter& other) const { + SWUConverter* cast = dynamic_cast(&other); + return cast != NULL && + feed_ == cast->feed_ && + tails_ == cast->tails_; + } + + private: + double feed_, tails_; +}; + +/// @class NatUConverter +/// +/// @brief The NatUConverter is a simple Converter class for material to +/// determine the amount of natural uranium required for their proposed +/// enrichment +class NatUConverter : public cyclus::Converter { + public: + NatUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} + virtual ~NatUConverter() {} + + /// @brief provides a conversion for the amount of natural Uranium required + virtual double convert( + cyclus::Material::Ptr m, + cyclus::Arc const * a = NULL, + cyclus::ExchangeTranslationContext + const * ctx = NULL) const { + cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), + tails_); + return cyclus::toolkit::FeedQty(m->quantity(), assays); + } + + /// @returns true if Converter is a NatUConverter and feed and tails equal + virtual bool operator==(Converter& other) const { + NatUConverter* cast = dynamic_cast(&other); + return cast != NULL && + feed_ == cast->feed_ && + tails_ == cast->tails_; + } + + private: + double feed_, tails_; +}; + +/// @class EnrichmentFacility +/// +/// @section introduction Introduction +/// The EnrichmentFacility is a simple Agent to agent the enriching of natural +/// Uranium in a Cyclus simulation. It requests its input recipe (nominally +/// natural Uranium), and produces any amount of enriched Uranium, given the its +/// natural uranium inventory constraint and its SWU capacity constraint. +/// +/// @section requests Requests +/// The EnrichmentFacility will request from the cyclus::ResourceExchange a +/// cyclus::Material whose quantity is its remaining inventory capacity and whose +/// composition is that of its input recipe. +/// +/// @section acctrade Accepting Trades +/// The EnrichmentFacility adds any accepted trades to its inventory. +/// +/// @section bids Bids +/// The EnrichmentFacility will bid on any request for its output commodities. It +/// will bid either the request quantity, or the quanity associated with either +/// its SWU constraint or natural uranium constraint, whichever is lower. +/// +/// @section extrades Executing Trades +/// The EnrichmentFacility will execute trades for its output commodities in the +/// following manner: +/// #. Determine the trade's quantity and product assay +/// #. Determine the natural Uranium and SWU requires to create that product +/// #. Remove the required quantity of natural Uranium from its inventory +/// #. Extract the appropriate composition of enriched Uranium +/// #. Send the enriched Uranium as the trade resource +/// +/// @section gotchas Gotchas +/// #. In its current form, the EnrichmentFacility can only accept +/// cyclus::Material having the composition of its input recipe. If a +/// cyclus::Material of a different composition is sent to it, an exception will +/// be thrown. +/// +/// #. During the trading phase, an exception will be thrown if either the +/// EnrichmentFacility's SWU or inventory constraint is breached. +/// +/// @section improvements Improvments +/// The primary improvement to the EnrichmentFacility would be to relax the +/// requirement that all input material have the in_recipe composition (i.e., +/// allow different base enrichments of Uranium). +/// +/// How would I go about doing so? I'd likely develop an EnrichmentBuffer-type +/// class that can be queried as to its SWU and natural Uranium capacity. +class EnrichmentFacility : public cyclus::Facility { + public: + // --- Module Members --- +/// Constructor for the EnrichmentFacility class +/// @param ctx the cyclus context for access to simulation-wide parameters + EnrichmentFacility(cyclus::Context* ctx); + +/// Destructor for the EnrichmentFacility class + virtual ~EnrichmentFacility(); + + #pragma cyclus + + #pragma cyclus note {"doc": "An enrichment facility that intakes a commodity " \ + "(usually natural uranium) and supplies a user-" \ + "specified enriched product based on SWU capacity", \ + "niche": "enrichment"} + +/// Print information about this agent + virtual std::string str(); + // --- + + // --- Facility Members --- + /// perform module-specific tasks when entering the simulation + virtual void Build(cyclus::Agent* parent); + // --- + + // --- Agent Members --- + /// Each facility is prompted to do its beginning-of-time-step + /// stuff at the tick of the timer. + + /// @param time is the time to perform the tick + virtual void Tick(); + + /// Each facility is prompted to its end-of-time-step + /// stuff on the tock of the timer. + + /// @param time is the time to perform the tock + virtual void Tock(); + + /// @brief The EnrichmentFacility request Materials of its given + /// commodity. + virtual std::set::Ptr> + GetMatlRequests(); + + /// @brief The EnrichmentFacility place accepted trade Materials in their + /// Inventory + virtual void AcceptMatlTrades( + const std::vector< std::pair, + cyclus::Material::Ptr> >& responses); + + /// @brief Responds to each request for this facility's commodity. If a given + /// request is more than this facility's inventory or SWU capacity, it will + /// offer its minimum of its capacities. + virtual std::set::Ptr> + GetMatlBids(cyclus::CommodMap::type& + commod_requests); + + /// @brief respond to each trade with a material enriched to the appropriate + /// level given this facility's inventory + /// + /// @param trades all trades in which this trader is the supplier + /// @param responses a container to populate with responses to each trade + virtual void GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses); + // --- + + // --- EnrichmentFacility Members --- + /// @brief Determines if a particular material is a valid request to respond + /// to. Valid requests must contain U235 and U238 and must have a relative + /// U235-to-U238 ratio less than this facility's tails_assay(). + /// @return true if the above description is met by the material + bool ValidReq(const cyclus::Material::Ptr mat); + + inline void in_commodity(std::string in_com) { in_commod = in_com; } + + inline std::string in_commodity() const { return in_commod; } + + inline void out_commodities(std::vector out_com) { + out_commods = out_com; + } + + inline const std::vector& + out_commodities() const { return out_commods; } + + inline void InRecipe(std::string in_rec) { in_recipe = in_rec; } + + inline std::string InRecipe() const { return in_recipe; } + + inline void SetMaxInventorySize(double size) { + max_inv_size = size; + inventory.set_capacity(size); + } + + inline double MaxInventorySize() const { return inventory.capacity(); } + + inline double InventorySize() const { return inventory.quantity(); } + + inline void FeedAssay(double assay) { feed_assay = assay; } + + inline double FeedAssay() const { return feed_assay; } + + inline void TailsAssay(double assay) { tails_assay = assay; } + + inline double TailsAssay() const { return tails_assay; } + + inline void SwuCapacity(double capacity) { + swu_capacity = capacity; + current_swu_capacity = swu_capacity; + } + inline double SwuCapacity() const { return swu_capacity; } + + inline double CurrentSwuCapacity() const { return current_swu_capacity; } + + /// @brief this facility's initial conditions + inline void InitialReserves(double qty) { initial_reserves = qty; } + inline double InitialReserves() const { return initial_reserves; } + + inline const cyclus::toolkit::ResourceBuff& Tails() const { return tails; } + + private: + /// @brief adds a material into the natural uranium inventory + /// @throws if the material is not the same composition as the in_recipe + void AddMat_(cyclus::Material::Ptr mat); + + /// @brief generates a request for this facility given its current state. The + /// quantity of the material will be equal to the remaining inventory size. + cyclus::Material::Ptr Request_(); + + /// @brief Generates a material offer for a given request. The response + /// composition will be comprised only of U235 and U238 at their relative ratio + /// in the requested material. The response quantity will be the same as the + /// requested commodity. + /// + /// @param req the requested material being responded to + cyclus::Material::Ptr Offer_(cyclus::Material::Ptr req); + + cyclus::Material::Ptr Enrich_(cyclus::Material::Ptr mat, double qty); + + /// @brief records and enrichment with the cyclus::Recorder + void RecordEnrichment_(double natural_u, double swu); + + // bool EveryXTimestep(int curr_time, int interval); + + #pragma cyclus var {"tooltip": "input commodity", \ + "doc": "commodity that the enrichment facility accepts", \ + "uitype": "incommodity"} + std::string in_commod; + + #pragma cyclus var {"tooltip": "output commodities", \ + "doc": "commodities that the enrichment facility supplies"} //, \ + // "uitype": ["oneormore", "outcommodity"]} + std::vector out_commods; + + #pragma cyclus var {"tooltip": "input commodity recipe", \ + "doc": "recipe for enrichment facility's input commodity", \ + "uitype": "recipe"} + std::string in_recipe; + + #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ + "doc": "tails assay from the enrichment process"} + double tails_assay; + #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity", \ + "doc": "separative work unit (SWU) capcity of " \ + "enrichment facility"} + double swu_capacity; + #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size", \ + "doc": "maximum inventory capacity of natural uranium in " \ + "the enrichment facility"} + double max_inv_size; + + #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves", \ + "doc": "amount of natural uranium stored at the " \ + "enrichment facility at the beginning of the " \ + "simulation"} + double initial_reserves; + //*** + #pragma cyclus var {"default": 0, "tooltip": "social behavior" , \ + "doc": "if set to 1 then enable social behavior " \ + "in trade decisions"} + bool social_behav; + //*** + #pragma cyclus var {'derived_init': 'current_swu_capacity = swu_capacity;'} + double current_swu_capacity; + #pragma cyclus var {\ + 'derived_init': "cyclus::Material::Ptr feed = "\ + "cyclus::Material::CreateUntracked(0, context()->GetRecipe(in_recipe)); "\ + "feed_assay = cyclus::toolkit::UraniumAssay(feed);", \ + "tooltip": "feed assay", \ + "doc": "feed assay for the enrichment process"} + double feed_assay; + #pragma cyclus var {'capacity': 'max_inv_size'} + cyclus::toolkit::ResourceBuff inventory; // of natl u + #pragma cyclus var {} + cyclus::toolkit::ResourceBuff tails; // depleted u + + friend class EnrichmentFacilityTest; + // --- +}; + +} // namespace cycamore + +#endif // CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ diff --git a/src/meg_old_tests/fn_consider/CMakeLists.txt b/src/meg_old_tests/fn_consider/CMakeLists.txt new file mode 100644 index 0000000000..c7ab466fb9 --- /dev/null +++ b/src/meg_old_tests/fn_consider/CMakeLists.txt @@ -0,0 +1,25 @@ +# ------------------- Add all Concrete Agents ---------------------------- + +USE_CYCLUS("cycamore" "batch_reactor") + +USE_CYCLUS("cycamore" "enrichment_facility") + +#USE_CYCLUS("cycamore" "inpro_reactor") + +USE_CYCLUS("cycamore" "sink") + +USE_CYCLUS("cycamore" "source") + +USE_CYCLUS("cycamore" "deploy_inst") + +USE_CYCLUS("cycamore" "manager_inst") + +USE_CYCLUS("cycamore" "growth_region") + +INSTALL_CYCLUS_MODULE("cycamore" "" "NONE") + +SET(TestSource ${cycamore_TEST_CC} PARENT_SCOPE) + +# install header files +FILE(GLOB h_files "${CMAKE_CURRENT_SOURCE_DIR}/*.h") +INSTALL(FILES ${h_files} DESTINATION include/cycamore COMPONENT cycamore) diff --git a/src/meg_old_tests/fn_consider/enrichment_facility.cc b/src/meg_old_tests/fn_consider/enrichment_facility.cc new file mode 100644 index 0000000000..344f44645f --- /dev/null +++ b/src/meg_old_tests/fn_consider/enrichment_facility.cc @@ -0,0 +1,392 @@ +// Implements the EnrichmentFacility class +#include "enrichment_facility.h" + +#include +#include +#include +#include + +#include + +namespace cycamore { + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) + : cyclus::Facility(ctx), + tails_assay(0), + feed_assay(0), + swu_capacity(0), + social_behav(0), //*** + initial_reserves(0), + in_commod(""), + in_recipe(""), + out_commods() {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +EnrichmentFacility::~EnrichmentFacility() {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::string EnrichmentFacility::str() { + std::stringstream ss; + + std::string out_commod_msg = ""; + out_commod_msg += " * Output cyclus::Commodities: " ; + for (std::vector::iterator commod = out_commods.begin(); + commod != out_commods.end(); + commod++) { + out_commod_msg += (commod == out_commods.begin() ? "{" : ", "); + out_commod_msg += (*commod); + } + + ss << cyclus::Facility::str() + << " with enrichment facility parameters:" + << " * SWU capacity: " << SwuCapacity() + << " * Tails assay: " << TailsAssay() + << " * Feed assay: " << FeedAssay() + << " * Input cyclus::Commodity: " << in_commodity() + << out_commod_msg ; + return ss.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::Build(cyclus::Agent* parent) { + using cyclus::Material; + + Facility::Build(parent); + if (initial_reserves > 0) { + inventory.Push( + Material::Create( + this, initial_reserves, context()->GetRecipe(in_recipe))); + } + + LOG(cyclus::LEV_DEBUG2, "EnrFac") << "EnrichmentFacility " + << " entering the simuluation: "; + LOG(cyclus::LEV_DEBUG2, "EnrFac") << str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::Tick() { + LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is ticking {"; + LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; + current_swu_capacity = SwuCapacity(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::Tock() { + LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is tocking {"; + LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::set::Ptr> +EnrichmentFacility::GetMatlRequests() { + using cyclus::Material; + using cyclus::RequestPortfolio; + using cyclus::Request; + + std::set::Ptr> ports; + RequestPortfolio::Ptr port(new RequestPortfolio()); + Material::Ptr mat = Request_(); + double amt = mat->quantity(); + + if (amt > cyclus::eps()) { + port->AddRequest(mat, this, in_commod); + ports.insert(port); + } + + return ports; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::AcceptMatlTrades( + const std::vector< std::pair, + cyclus::Material::Ptr> >& responses) { + // see + // http://stackoverflow.com/questions/5181183/boostshared-ptr-and-inheritance + std::vector< std::pair, + cyclus::Material::Ptr> >::const_iterator it; + for (it = responses.begin(); it != responses.end(); ++it) { + AddMat_(it->second); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::set::Ptr> +EnrichmentFacility::GetMatlBids( + cyclus::CommodMap::type& commod_requests) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::Converter; + using cyclus::Material; + using cyclus::Request; + + std::set::Ptr> all_ports; +/* + // returns empty portfolio for all bids at certain timesteps + if (social_behav) { + int cur_time = context()->time(); + // only trade on every 5th timestep + int interval = 5 ; + if (EveryXTimestep(cur_time, interval)) { + return ports; + // if (cur_time % 5 != 0) { + // return all_ports; + } + } +*/ + if (inventory.quantity() <= 0) { + return all_ports; + } + + BidPortfolio::Ptr port = ConsiderMatlRequests(commod_requests); + + Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); + Converter::Ptr nc(new NatUConverter(feed_assay, tails_assay)); + CapacityConstraint swu(swu_capacity, sc); + CapacityConstraint natu(inventory.quantity(), nc); + port->AddConstraint(swu); + port->AddConstraint(natu); + + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() + << " adding a swu constraint of " + << swu.capacity(); + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() + << " adding a natu constraint of " + << natu.capacity(); + all_ports.insert(port); + + return all_ports; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EnrichmentFacility::ValidReq(const cyclus::Material::Ptr mat) { + cyclus::toolkit::MatQuery q(mat); + double u235 = q.atom_frac(922350000); + double u238 = q.atom_frac(922380000); + return (u238 > 0 && u235 / (u235 + u238) > TailsAssay()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses) { + using cyclus::Material; + using cyclus::Trade; + + std::vector< Trade >::const_iterator it; + for (it = trades.begin(); it != trades.end(); ++it) { + Material::Ptr mat = it->bid->offer(); + double qty = it->amt; + Material::Ptr response = Enrich_(mat, qty); + responses.push_back(std::make_pair(*it, response)); + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() + << " just received an order" + << " for " << it->amt + << " of " << it->bid->request()->commodity() ; + } + + if (cyclus::IsNegative(current_swu_capacity)) { + throw cyclus::ValueError( + "EnrFac " + prototype() + + " is being asked to provide more than its SWU capacity."); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { + if (mat->comp() != context()->GetRecipe(in_recipe)) { + throw cyclus::ValueError( + "EnrichmentFacility recipe and material composition not the same."); + } + + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " is initially holding " + << inventory.quantity() << " total."; + + try { + inventory.Push(mat); + } catch (cyclus::Error& e) { + e.msg(Agent::InformErrorMsg(e.msg())); + throw e; + } + + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " added " + << mat->quantity() << " of " << in_commod + << " to its inventory, which is holding " + << inventory.quantity() << " total."; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr EnrichmentFacility::Request_() { + double qty = std::max(0.0, MaxInventorySize() - InventorySize()); + return cyclus::Material::CreateUntracked(qty, + context()->GetRecipe(in_recipe)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { + cyclus::toolkit::MatQuery q(mat); + cyclus::CompMap comp; + comp[922350000] = q.atom_frac(922350000); + comp[922380000] = q.atom_frac(922380000); + return cyclus::Material::CreateUntracked( + mat->quantity(), cyclus::Composition::CreateFromAtom(comp)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr EnrichmentFacility::Enrich_( + cyclus::Material::Ptr mat, + double qty) { + using cyclus::Material; + using cyclus::ResCast; + using cyclus::toolkit::Assays; + using cyclus::toolkit::UraniumAssay; + using cyclus::toolkit::SwuRequired; + using cyclus::toolkit::FeedQty; + using cyclus::toolkit::TailsQty; + + // get enrichment parameters + Assays assays(FeedAssay(), UraniumAssay(mat), TailsAssay()); + double swu_req = SwuRequired(qty, assays); + double natu_req = FeedQty(qty, assays); + + // pop amount from inventory and blob it into one material + std::vector manifest; + try { + // required so popping doesn't take out too much + if (cyclus::AlmostEq(natu_req, inventory.quantity())) { + manifest = ResCast(inventory.PopN(inventory.count())); + } else { + manifest = ResCast(inventory.PopQty(natu_req)); + } + } catch (cyclus::Error& e) { + NatUConverter nc(feed_assay, tails_assay); + std::stringstream ss; + ss << " tried to remove " << natu_req + << " from its inventory of size " << inventory.quantity() + << " and the conversion of the material into natu is " + << nc.convert(mat); + throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); + } + Material::Ptr r = manifest[0]; + for (int i = 1; i < manifest.size(); ++i) { + r->Absorb(manifest[i]); + } + + // "enrich" it, but pull out the composition and quantity we require from the + // blob + cyclus::Composition::Ptr comp = mat->comp(); + Material::Ptr response = r->ExtractComp(qty, comp); + tails.Push(r); // add remainder to tails buffer + + current_swu_capacity -= swu_req; + + RecordEnrichment_(natu_req, swu_req); + + LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << + " has performed an enrichment: "; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Feed Qty: " + << natu_req; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Feed Assay: " + << assays.Feed() * 100; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Product Qty: " + << qty; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Product Assay: " + << assays.Product() * 100; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Tails Qty: " + << TailsQty(qty, assays); + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Tails Assay: " + << assays.Tails() * 100; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * SWU: " + << swu_req; + LOG(cyclus::LEV_INFO5, "EnrFac") << " * Current SWU capacity: " + << CurrentSwuCapacity(); + + return response; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacility::RecordEnrichment_(double natural_u, double swu) { + using cyclus::Context; + using cyclus::Agent; + + LOG(cyclus::LEV_DEBUG1, "EnrFac") << prototype() + << " has enriched a material:"; + LOG(cyclus::LEV_DEBUG1, "EnrFac") << " * Amount: " << natural_u; + LOG(cyclus::LEV_DEBUG1, "EnrFac") << " * SWU: " << swu; + + Context* ctx = Agent::context(); + ctx->NewDatum("Enrichments") + ->AddVal("ID", id()) + ->AddVal("Time", ctx->time()) + ->AddVal("Natural_Uranium", natural_u) + ->AddVal("SWU", swu) + ->Record(); +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +bool EnrichmentFacility::EveryXTimestep(int curr_time, int interval) { + return curr_time % interval != 0; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Decide whether each individual bid will be responded to. +cyclus::BidPortfolio::Ptr +EnrichmentFacility::ConsiderMatlRequests( + cyclus::CommodMap::type& commod_requests) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::Material; + using cyclus::Request; + + // std::set::Ptr> ports; + + BidPortfolio::Ptr port(new BidPortfolio()); + + for (std::vector::iterator commod = out_commods.begin(); + commod != out_commods.end(); + ++commod) { + if (commod_requests.count(*commod) == 0) { + continue; + } + + std::vector*>& requests = + commod_requests[*commod]; + + std::vector*>::iterator it; + for (it = requests.begin(); it != requests.end(); ++it) { + Request* req = *it; + /* add check that request is desirable */ + Material::Ptr mat = Request_(); + double enrich_limit ; + /* if (social_behav) { + enrich_limit = 0.1 ; // do not trade to facilities that want HEU + } else { + enrich_limit = 1.0 ; + } + */ + enrich_limit = 0.1; + double request_enrich = cyclus::toolkit::UraniumAssay(mat) ; + int cur_time = context()->time(); + int interval = 5 ; // only trade on every 5th timestep + if (ValidReq(req->target())) { // This check is always done + if ((request_enrich <= enrich_limit) // LEU facility + || (EveryXTimestep(cur_time, interval))) // HEU every 5th time + { + Material::Ptr offer = Offer_(req->target()); + port->AddBid(req, offer, this); + } + } + } + } //for each out commod + + return port; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +extern "C" cyclus::Agent* ConstructEnrichmentFacility(cyclus::Context* ctx) { + return new EnrichmentFacility(ctx); +} + +} // namespace cycamore diff --git a/src/meg_old_tests/fn_consider/enrichment_facility.h b/src/meg_old_tests/fn_consider/enrichment_facility.h new file mode 100644 index 0000000000..5832eb8fe4 --- /dev/null +++ b/src/meg_old_tests/fn_consider/enrichment_facility.h @@ -0,0 +1,331 @@ +#ifndef CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ +#define CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ + +#include + +#include "cyclus.h" + +namespace cycamore { + +/// @class SWUConverter +/// +/// @brief The SWUConverter is a simple Converter class for material to +/// determine the amount of SWU required for their proposed enrichment +class SWUConverter : public cyclus::Converter { + public: + SWUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} + virtual ~SWUConverter() {} + + /// @brief provides a conversion for the SWU required + virtual double convert( + cyclus::Material::Ptr m, + cyclus::Arc const * a = NULL, + cyclus::ExchangeTranslationContext + const * ctx = NULL) const { + cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), + tails_); + return cyclus::toolkit::SwuRequired(m->quantity(), assays); + } + + /// @returns true if Converter is a SWUConverter and feed and tails equal + virtual bool operator==(Converter& other) const { + SWUConverter* cast = dynamic_cast(&other); + return cast != NULL && + feed_ == cast->feed_ && + tails_ == cast->tails_; + } + + private: + double feed_, tails_; +}; + +/// @class NatUConverter +/// +/// @brief The NatUConverter is a simple Converter class for material to +/// determine the amount of natural uranium required for their proposed +/// enrichment +class NatUConverter : public cyclus::Converter { + public: + NatUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} + virtual ~NatUConverter() {} + + /// @brief provides a conversion for the amount of natural Uranium required + virtual double convert( + cyclus::Material::Ptr m, + cyclus::Arc const * a = NULL, + cyclus::ExchangeTranslationContext + const * ctx = NULL) const { + cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), + tails_); + return cyclus::toolkit::FeedQty(m->quantity(), assays); + } + + /// @returns true if Converter is a NatUConverter and feed and tails equal + virtual bool operator==(Converter& other) const { + NatUConverter* cast = dynamic_cast(&other); + return cast != NULL && + feed_ == cast->feed_ && + tails_ == cast->tails_; + } + + private: + double feed_, tails_; +}; + +/// @class EnrichmentFacility +/// +/// @section introduction Introduction +/// The EnrichmentFacility is a simple Agent to agent the enriching of natural +/// Uranium in a Cyclus simulation. It requests its input recipe (nominally +/// natural Uranium), and produces any amount of enriched Uranium, given the its +/// natural uranium inventory constraint and its SWU capacity constraint. +/// +/// @section requests Requests +/// The EnrichmentFacility will request from the cyclus::ResourceExchange a +/// cyclus::Material whose quantity is its remaining inventory capacity and whose +/// composition is that of its input recipe. +/// +/// @section acctrade Accepting Trades +/// The EnrichmentFacility adds any accepted trades to its inventory. +/// +/// @section bids Bids +/// The EnrichmentFacility will bid on any request for its output commodities. It +/// will bid either the request quantity, or the quanity associated with either +/// its SWU constraint or natural uranium constraint, whichever is lower. +/// +/// @section extrades Executing Trades +/// The EnrichmentFacility will execute trades for its output commodities in the +/// following manner: +/// #. Determine the trade's quantity and product assay +/// #. Determine the natural Uranium and SWU requires to create that product +/// #. Remove the required quantity of natural Uranium from its inventory +/// #. Extract the appropriate composition of enriched Uranium +/// #. Send the enriched Uranium as the trade resource +/// +/// @section gotchas Gotchas +/// #. In its current form, the EnrichmentFacility can only accept +/// cyclus::Material having the composition of its input recipe. If a +/// cyclus::Material of a different composition is sent to it, an exception will +/// be thrown. +/// +/// #. During the trading phase, an exception will be thrown if either the +/// EnrichmentFacility's SWU or inventory constraint is breached. +/// +/// @section improvements Improvments +/// The primary improvement to the EnrichmentFacility would be to relax the +/// requirement that all input material have the in_recipe composition (i.e., +/// allow different base enrichments of Uranium). +/// +/// How would I go about doing so? I'd likely develop an EnrichmentBuffer-type +/// class that can be queried as to its SWU and natural Uranium capacity. +class EnrichmentFacility : public cyclus::Facility { + public: + // --- Module Members --- +/// Constructor for the EnrichmentFacility class +/// @param ctx the cyclus context for access to simulation-wide parameters + EnrichmentFacility(cyclus::Context* ctx); + +/// Destructor for the EnrichmentFacility class + virtual ~EnrichmentFacility(); + + #pragma cyclus + + #pragma cyclus note {"doc": "An enrichment facility that intakes a commodity " \ + "(usually natural uranium) and supplies a user-" \ + "specified enriched product based on SWU capacity", \ + "niche": "enrichment"} + +/// Print information about this agent + virtual std::string str(); + // --- + + // --- Facility Members --- + /// perform module-specific tasks when entering the simulation + virtual void Build(cyclus::Agent* parent); + // --- + + // --- Agent Members --- + /// Each facility is prompted to do its beginning-of-time-step + /// stuff at the tick of the timer. + + /// @param time is the time to perform the tick + virtual void Tick(); + + /// Each facility is prompted to its end-of-time-step + /// stuff on the tock of the timer. + + /// @param time is the time to perform the tock + virtual void Tock(); + + /// @brief The EnrichmentFacility request Materials of its given + /// commodity. + virtual std::set::Ptr> + GetMatlRequests(); + + /// @brief The EnrichmentFacility place accepted trade Materials in their + /// Inventory + virtual void AcceptMatlTrades( + const std::vector< std::pair, + cyclus::Material::Ptr> >& responses); + + /// @brief Responds to each request for this facility's commodity. If a given + /// request is more than this facility's inventory or SWU capacity, it will + /// offer its minimum of its capacities. + virtual std::set::Ptr> + GetMatlBids(cyclus::CommodMap::type& + commod_requests); + + /// @brief respond to each trade with a material enriched to the appropriate + /// level given this facility's inventory + /// + /// @param trades all trades in which this trader is the supplier + /// @param responses a container to populate with responses to each trade + virtual void GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses); + // --- + + // --- EnrichmentFacility Members --- + /// @brief Determines if a particular material is a valid request to respond + /// to. Valid requests must contain U235 and U238 and must have a relative + /// U235-to-U238 ratio less than this facility's tails_assay(). + /// @return true if the above description is met by the material + bool ValidReq(const cyclus::Material::Ptr mat); + + /// @brief Determines if a particular request will be responded to + /// based on user specification such as maximum allowed enrichment + /// or other behavior parameters. + virtual cyclus::BidPortfolio::Ptr + ConsiderMatlRequests(cyclus::CommodMap::type& + commod_requests); + + inline void in_commodity(std::string in_com) { in_commod = in_com; } + + inline std::string in_commodity() const { return in_commod; } + + inline void out_commodities(std::vector out_com) { + out_commods = out_com; + } + + inline const std::vector& + out_commodities() const { return out_commods; } + + inline void InRecipe(std::string in_rec) { in_recipe = in_rec; } + + inline std::string InRecipe() const { return in_recipe; } + + inline void SetMaxInventorySize(double size) { + max_inv_size = size; + inventory.set_capacity(size); + } + + inline double MaxInventorySize() const { return inventory.capacity(); } + + inline double InventorySize() const { return inventory.quantity(); } + + inline void FeedAssay(double assay) { feed_assay = assay; } + + inline double FeedAssay() const { return feed_assay; } + + inline void TailsAssay(double assay) { tails_assay = assay; } + + inline double TailsAssay() const { return tails_assay; } + + inline void SwuCapacity(double capacity) { + swu_capacity = capacity; + current_swu_capacity = swu_capacity; + } + inline double SwuCapacity() const { return swu_capacity; } + + inline double CurrentSwuCapacity() const { return current_swu_capacity; } + + /// @brief this facility's initial conditions + inline void InitialReserves(double qty) { initial_reserves = qty; } + inline double InitialReserves() const { return initial_reserves; } + + inline const cyclus::toolkit::ResourceBuff& Tails() const { return tails; } + + private: + /// @brief adds a material into the natural uranium inventory + /// @throws if the material is not the same composition as the in_recipe + void AddMat_(cyclus::Material::Ptr mat); + + /// @brief generates a request for this facility given its current state. The + /// quantity of the material will be equal to the remaining inventory size. + cyclus::Material::Ptr Request_(); + + /// @brief Generates a material offer for a given request. The response + /// composition will be comprised only of U235 and U238 at their relative ratio + /// in the requested material. The response quantity will be the same as the + /// requested commodity. + /// + /// @param req the requested material being responded to + cyclus::Material::Ptr Offer_(cyclus::Material::Ptr req); + + cyclus::Material::Ptr Enrich_(cyclus::Material::Ptr mat, double qty); + + /// @brief records and enrichment with the cyclus::Recorder + void RecordEnrichment_(double natural_u, double swu); + + bool EveryXTimestep(int curr_time, int interval); + + #pragma cyclus var {"tooltip": "input commodity", \ + "doc": "commodity that the enrichment facility accepts", \ + "uitype": "incommodity"} + std::string in_commod; + + #pragma cyclus var {"tooltip": "output commodities", \ + "doc": "commodities that the enrichment facility supplies"} //, \ + // "uitype": ["oneormore", "outcommodity"]} + std::vector out_commods; + + #pragma cyclus var {"tooltip": "input commodity recipe", \ + "doc": "recipe for enrichment facility's input commodity", \ + "uitype": "recipe"} + std::string in_recipe; + + #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ + "doc": "tails assay from the enrichment process"} + double tails_assay; + #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity", \ + "doc": "separative work unit (SWU) capcity of " \ + "enrichment facility"} + double swu_capacity; + #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size", \ + "doc": "maximum inventory capacity of natural uranium in " \ + "the enrichment facility"} + double max_inv_size; + + #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves", \ + "doc": "amount of natural uranium stored at the " \ + "enrichment facility at the beginning of the " \ + "simulation"} + double initial_reserves; + //*** + #pragma cyclus var {"default": 0, "tooltip": "social behavior" , \ + "doc": "if set to 1 then enable social behavior " \ + "in trade decisions"} + bool social_behav; + //*** + #pragma cyclus var {'derived_init': 'current_swu_capacity = swu_capacity;'} + double current_swu_capacity; + #pragma cyclus var {\ + 'derived_init': "cyclus::Material::Ptr feed = "\ + "cyclus::Material::CreateUntracked(0, context()->GetRecipe(in_recipe)); "\ + "feed_assay = cyclus::toolkit::UraniumAssay(feed);", \ + "tooltip": "feed assay", \ + "doc": "feed assay for the enrichment process"} + double feed_assay; + #pragma cyclus var {'capacity': 'max_inv_size'} + cyclus::toolkit::ResourceBuff inventory; // of natl u + #pragma cyclus var {} + cyclus::toolkit::ResourceBuff tails; // depleted u + + friend class EnrichmentFacilityTest; + // --- +}; + +} // namespace cycamore + +#endif // CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ diff --git a/src/meg_old_tests/fn_consider/enrichment_facility_tests.cc b/src/meg_old_tests/fn_consider/enrichment_facility_tests.cc new file mode 100644 index 0000000000..0d66a62fcf --- /dev/null +++ b/src/meg_old_tests/fn_consider/enrichment_facility_tests.cc @@ -0,0 +1,725 @@ +#include + +#include + +#include "facility_tests.h" +#include "toolkit/mat_query.h" +#include "agent_tests.h" +#include "resource_helpers.h" +#include "infile_tree.h" +#include "env.h" + +#include "enrichment_facility_tests.h" + +namespace cycamore { + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacilityTest::SetUp() { + cyclus::Env::SetNucDataPath(); + cyclus::Context* ctx = tc_.get(); + src_facility = new EnrichmentFacility(ctx); + trader = tc_.trader(); + InitParameters(); + SetUpSource(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacilityTest::TearDown() { + delete src_facility; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacilityTest::InitParameters() { + cyclus::Context* ctx = tc_.get(); + + in_commod = "incommod"; + std::string x [2] = {"acommod", "bcommod"}; + out_commods = std::vector(x, x+2) ; + + in_recipe = "recipe"; + feed_assay = 0.0072; + + cyclus::CompMap v; + v[922350000] = feed_assay; + v[922380000] = 1 - feed_assay; + recipe = cyclus::Composition::CreateFromAtom(v); + ctx->AddRecipe(in_recipe, recipe); + + tails_assay = 0.002; + swu_capacity = 100; + inv_size = 5; + + reserves = 105.5; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacilityTest::SetUpSource() { + src_facility->InRecipe(in_recipe); + src_facility->in_commodity(in_commod); + src_facility->out_commodities(out_commods); + src_facility->TailsAssay(tails_assay); + src_facility->FeedAssay(feed_assay); + src_facility->SetMaxInventorySize(inv_size); + src_facility->SwuCapacity(swu_capacity); + src_facility->InitialReserves(reserves); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr EnrichmentFacilityTest::GetMat(double qty) { + return cyclus::Material::CreateUntracked(qty, + tc_.get()->GetRecipe(in_recipe)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr EnrichmentFacilityTest::GetReqMat(double qty, + double enr) { + cyclus::CompMap v; + v[922350000] = enr; + v[922380000] = 1 - enr; + return cyclus::Material::CreateUntracked( + qty, cyclus::Composition::CreateFromAtom(v)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EnrichmentFacilityTest::DoAddMat(cyclus::Material::Ptr mat) { + src_facility->AddMat_(mat); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr EnrichmentFacilityTest::DoRequest() { + return src_facility->Request_(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr +EnrichmentFacilityTest::DoOffer(cyclus::Material::Ptr mat) { + return src_facility->Offer_(mat); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr +EnrichmentFacilityTest::DoEnrich(cyclus::Material::Ptr mat, double qty) { + return src_facility->Enrich_(mat, qty); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, InitialState) { + EXPECT_EQ(in_recipe, src_facility->InRecipe()); + EXPECT_EQ(in_commod, src_facility->in_commodity()); + // for (int i = 0 ; i < out_commods.size() ; ++i) { + // EXPECT_EQ(out_commods[i],src_facility->out_commodities()[i]) + // } + EXPECT_EQ(out_commods, src_facility->out_commodities()); + EXPECT_DOUBLE_EQ(tails_assay, src_facility->TailsAssay()); + EXPECT_DOUBLE_EQ(feed_assay, src_facility->FeedAssay()); + EXPECT_DOUBLE_EQ(inv_size, src_facility->MaxInventorySize()); + EXPECT_DOUBLE_EQ(0.0, src_facility->InventorySize()); + EXPECT_DOUBLE_EQ(swu_capacity, src_facility->SwuCapacity()); + EXPECT_EQ(reserves, src_facility->InitialReserves()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, DISABLED_XMLInit) { + std::stringstream ss; + + ss << "" + << "fooname" + << "" + << "" + << " " + << " " << in_commod << "" + << " " << in_recipe << "" + << " " << inv_size << "" + << " " + << " " + << " " + << " " << out_commods[0] << "" + << " " << out_commods[1] << "" + << " " + << " " << tails_assay << "" + << " " << swu_capacity << "" + << " " + << " " + << " " << reserves << "" + << " " + << "" + << "" + << ""; + + cyclus::XMLParser p; + p.Init(ss); + cyclus::InfileTree engine(p); + cycamore::EnrichmentFacility fac(tc_.get()); + + // EXPECT_NO_THROW(fac.InitFrom(&engine);); + EXPECT_EQ(in_recipe, fac.InRecipe()); + EXPECT_EQ(in_commod, fac.in_commodity()); + EXPECT_EQ(out_commods, fac.out_commodities()); + EXPECT_DOUBLE_EQ(tails_assay, fac.TailsAssay()); + EXPECT_DOUBLE_EQ(feed_assay, fac.FeedAssay()); + EXPECT_DOUBLE_EQ(inv_size, fac.MaxInventorySize()); + EXPECT_DOUBLE_EQ(0.0, fac.InventorySize()); + EXPECT_DOUBLE_EQ(swu_capacity, fac.SwuCapacity()); + EXPECT_EQ(reserves, fac.InitialReserves()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, Clone) { + cyclus::Context* ctx = tc_.get(); + + cycamore::EnrichmentFacility* cloned_fac = + dynamic_cast(src_facility->Clone()); + + EXPECT_EQ(in_recipe, cloned_fac->InRecipe()); + EXPECT_EQ(in_commod, cloned_fac->in_commodity()); + EXPECT_EQ(out_commods, cloned_fac->out_commodities()); + EXPECT_DOUBLE_EQ(tails_assay, cloned_fac->TailsAssay()); + EXPECT_DOUBLE_EQ(feed_assay, cloned_fac->FeedAssay()); + EXPECT_DOUBLE_EQ(inv_size, cloned_fac->MaxInventorySize()); + EXPECT_DOUBLE_EQ(0.0, cloned_fac->InventorySize()); + EXPECT_DOUBLE_EQ(swu_capacity, cloned_fac->SwuCapacity()); + EXPECT_EQ(reserves, cloned_fac->InitialReserves()); + + delete cloned_fac; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, AddMat) { + EXPECT_THROW(DoAddMat(test_helpers::get_mat()), cyclus::ValueError); + EXPECT_THROW(DoAddMat(GetMat(inv_size + 1)), cyclus::Error); + EXPECT_NO_THROW(DoAddMat(GetMat(inv_size))); + EXPECT_THROW(DoAddMat(GetMat(1)), cyclus::Error); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, Request) { + double req = inv_size; + double add = 0; + cyclus::Material::Ptr mat = DoRequest(); + EXPECT_DOUBLE_EQ(mat->quantity(), req); + EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(in_recipe)); + + add = 2 * inv_size / 3; + req -= add; + DoAddMat(GetMat(add)); + mat = DoRequest(); + EXPECT_DOUBLE_EQ(mat->quantity(), req); + EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(in_recipe)); + + add = inv_size / 3; + req = 0; + DoAddMat(GetMat(add)); + mat = DoRequest(); + EXPECT_DOUBLE_EQ(mat->quantity(), req); + EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(in_recipe)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, Offer) { + using cyclus::CompMap; + using cyclus::Composition; + using cyclus::Material; + using cyclus::toolkit::MatQuery; + + double qty = 4.5; + double u234 = 1.0; + double u235 = 1.0; + double u238 = 2.0; + cyclus::CompMap v; + v[94239] = u234; + v[922350000] = u235; + v[922380000] = u238; + Material::Ptr mat = + DoOffer(Material::CreateUntracked(qty, Composition::CreateFromAtom(v))); + + MatQuery q(mat); + + EXPECT_DOUBLE_EQ(q.atom_frac(94239), 0.0); + EXPECT_DOUBLE_EQ(q.atom_frac(922350000), u235 / (u235 + u238)); + EXPECT_DOUBLE_EQ(q.atom_frac(922380000), u238 / (u235 + u238)); + EXPECT_DOUBLE_EQ(mat->quantity(), qty); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, ValidReq) { + using cyclus::CompMap; + using cyclus::Composition; + using cyclus::Material; + + double qty = 4.5; // some magic number + + cyclus::CompMap v1; + v1[922350000] = 1; + Material::Ptr mat = Material::CreateUntracked(qty, + Composition::CreateFromAtom(v1)); + EXPECT_TRUE(!src_facility->ValidReq(mat)); // u238 = 0 + + cyclus::CompMap v2; + v2[922350000] = tails_assay; + v2[922380000] = 1 - tails_assay; + mat = Material::CreateUntracked(qty, Composition::CreateFromAtom(v2)); + EXPECT_TRUE(!src_facility->ValidReq(mat)); // u235 / (u235 + u238) <= tails_assay + + cyclus::CompMap v3; + v3[922350000] = 1; + v3[922380000] = 1; + mat = Material::CreateUntracked(qty, Composition::CreateFromAtom(v3)); + EXPECT_TRUE(src_facility->ValidReq(mat)); // valid +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, EmptyRequests) { + using cyclus::Material; + using cyclus::RequestPortfolio; + + src_facility->SetMaxInventorySize(src_facility->InventorySize()); + std::set::Ptr> ports = + src_facility->GetMatlRequests(); + ports = src_facility->GetMatlRequests(); + EXPECT_TRUE(ports.empty()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, AddRequests) { + using cyclus::Request; + using cyclus::RequestPortfolio; + using cyclus::CapacityConstraint; + using cyclus::Converter; + using cyclus::Material; + + // a request is made for the current available inventory amount + + std::set::Ptr> ports = + src_facility->GetMatlRequests(); + + ASSERT_EQ(ports.size(), 1); + ASSERT_EQ(ports.begin()->get()->qty(), inv_size); + + const std::vector*>& requests = + ports.begin()->get()->requests(); + ASSERT_EQ(requests.size(), 1); + + Request* req = *requests.begin(); + EXPECT_EQ(req->requester(), src_facility); + EXPECT_EQ(req->commodity(), in_commod); + + const std::set< CapacityConstraint >& constraints = + ports.begin()->get()->constraints(); + EXPECT_EQ(constraints.size(), 0); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, Extract) { + using cyclus::Material; + cyclus::Env::SetNucDataPath(); + double qty = 1000; // 5 kg + Material::Ptr base = GetMat(qty); + double time = tc_.get()->time(); + // cyclus::Material::Create(src_facility, qty, + // tc_.get()->GetRecipe(in_recipe)); + Material::Ptr base2 = GetMat(qty); + base->Absorb(base2); + double product_assay = 0.05; // of 5 w/o enriched U + cyclus::CompMap v; + v[922350000] = product_assay; + v[922380000] = 1 - product_assay; + // target qty need not be = to request qty + Material::Ptr target = cyclus::Material::CreateUntracked( + 5, cyclus::Composition::CreateFromMass(v)); + Material::Ptr response = base->ExtractComp(6, target->comp()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, Accept) { + using cyclus::Bid; + using cyclus::Material; + using cyclus::Request; + using cyclus::Trade; + + // an enrichment facility gets two trades, each for 1/3 of its inv size + // note that comp != recipe is covered by AddMat tests + // note that qty >= inv capacity is covered by toolkit::ResourceBuff tests + + double qty = inv_size / 3; + std::vector< std::pair, + cyclus::Material::Ptr> > responses; + + Request* req1 = + Request::Create(DoRequest(), src_facility, in_commod); + Bid* bid1 = + Bid::Create(req1, GetMat(qty), trader); + + Request* req2 = + Request::Create(DoRequest(), src_facility, in_commod); + Bid* bid2 = Bid::Create(req2, GetMat(qty), trader); + + Trade trade1(req1, bid1, qty); + responses.push_back(std::make_pair(trade1, GetMat(qty))); + Trade trade2(req2, bid2, qty); + responses.push_back(std::make_pair(trade2, GetMat(qty))); + + EXPECT_DOUBLE_EQ(0.0, src_facility->InventorySize()); + src_facility->AcceptMatlTrades(responses); + EXPECT_DOUBLE_EQ(qty * 2, src_facility->InventorySize()); + + delete bid2; + delete bid1; + delete req2; + delete req1; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, AddBids) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::Converter; + using cyclus::ExchangeContext; + using cyclus::Material; + cyclus::Env::SetNucDataPath(); + // an enrichment facility bids on nreqs requests + // note that bid response is covered by Bid tests + // note that validity of requests is covered by ValidReq tests + int nreqs = 5; + int nvalid = 4; + + // set up inventory + double current_size = inv_size / 2; // test something other than max size + DoAddMat(GetMat(current_size)); + + boost::shared_ptr< cyclus::ExchangeContext > + ec = GetContext(nreqs, nvalid); + + std::set::Ptr> ports = + src_facility->GetMatlBids(ec.get()->commod_requests); + + ASSERT_TRUE(ports.size() > 0); + EXPECT_EQ(ports.size(), 1); + + BidPortfolio::Ptr port = *ports.begin(); + EXPECT_EQ(port->bidder(), src_facility); + EXPECT_EQ(port->bids().size(), nvalid); + + const std::set< CapacityConstraint >& constrs = port->constraints(); + Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); + Converter::Ptr nc(new NatUConverter(feed_assay, tails_assay)); + CapacityConstraint swu(swu_capacity, sc); + CapacityConstraint natu(current_size, nc); + EXPECT_EQ(constrs.size(), 2); + EXPECT_TRUE(*constrs.begin() == swu || *(++constrs.begin()) == swu); + EXPECT_TRUE(*constrs.begin() == natu || *(++constrs.begin()) == natu); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +boost::shared_ptr< cyclus::ExchangeContext > +EnrichmentFacilityTest::GetContext(int nreqs, int nvalid) { + using cyclus::ExchangeContext; + using cyclus::Material; + using cyclus::Request; + using test_helpers::get_mat; + + boost::shared_ptr< ExchangeContext > + ec(new ExchangeContext()); + for (int i = 0; i < nvalid; i++) { + ec->AddRequest( + Request::Create(GetReqMat(1.0, 0.05), trader, out_commods[0])); + } + for (int i = 0; i < nreqs - nvalid; i++) { + ec->AddRequest( + // get_mat returns a material of only u235, which is not valid + Request::Create(get_mat(), trader, out_commods[0])); + } + return ec; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, BidConverters) { + // this test is designed to confirm that the bid response behavior matches the + // converter behavior. + using cyclus::CompMap; + using cyclus::Material; + using cyclus::toolkit::MatQuery; + using cyclus::Composition; + using cyclus::toolkit::Assays; + using cyclus::toolkit::UraniumAssay; + using cyclus::toolkit::SwuRequired; + using cyclus::toolkit::FeedQty; + cyclus::Env::SetNucDataPath(); + + double qty = 5; // 5 kg + double product_assay = 0.05; // of 5 w/o enriched U + CompMap v; + v[922350000] = product_assay; + v[922380000] = 1 - product_assay; + v[94239] = 0.5; // 94239 shouldn't be taken into account + Material::Ptr target = Material::CreateUntracked( + qty, Composition::CreateFromMass(v)); + + SWUConverter swuc(feed_assay, tails_assay); + NatUConverter natuc(feed_assay, tails_assay); + + Material::Ptr offer = DoOffer(target); + + EXPECT_NEAR(swuc.convert(target), swuc.convert(offer), 0.001); + EXPECT_NEAR(natuc.convert(target), natuc.convert(offer), 0.001); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, Enrich) { + // this test asks the facility to enrich a material that results in an amount + // of natural uranium required that is exactly its inventory level. that + // inventory will be comprised of two materials to test the manifest/absorb + // strategy employed in Enrich_. + using cyclus::CompMap; + using cyclus::Material; + using cyclus::toolkit::MatQuery; + using cyclus::Composition; + using cyclus::toolkit::Assays; + using cyclus::toolkit::UraniumAssay; + using cyclus::toolkit::SwuRequired; + using cyclus::toolkit::FeedQty; + + double qty = 5; // 5 kg + double product_assay = 0.05; // of 5 w/o enriched U + cyclus::CompMap v; + v[922350000] = product_assay; + v[922380000] = 1 - product_assay; + // target qty need not be = to request qty + Material::Ptr target = cyclus::Material::CreateUntracked( + qty + 10, cyclus::Composition::CreateFromMass(v)); + + Assays assays(feed_assay, UraniumAssay(target), tails_assay); + double swu_req = SwuRequired(qty, assays); + double natu_req = FeedQty(qty, assays); + double tails_qty = TailsQty(qty, assays); + + double swu_cap = swu_req * 5; + src_facility->SwuCapacity(swu_cap); + src_facility->SetMaxInventorySize(natu_req); + DoAddMat(GetMat(natu_req / 2)); + DoAddMat(GetMat(natu_req / 2)); + + Material::Ptr response; + EXPECT_NO_THROW(response = DoEnrich(target, qty)); + EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_cap - swu_req); + EXPECT_DOUBLE_EQ(src_facility->Tails().quantity(), tails_qty); + + MatQuery q(response); + EXPECT_EQ(response->quantity(), qty); + EXPECT_EQ(q.mass_frac(922350000), product_assay); + EXPECT_EQ(q.mass_frac(922380000), 1 - product_assay); + + // test too much natu request + DoAddMat(GetMat(natu_req - 1)); + EXPECT_THROW(response = DoEnrich(target, qty), cyclus::Error); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, Response) { + // this test asks the facility to respond to multiple requests for enriched + // uranium. two requests are provided, whose total equals the swu capacity of + // the facility while not exceeding its inventory capacity (that's taken care + // of in the Enrich tests). + // + // note that response quantity and quality need not be tested, because they + // are covered by the Enrich and Offer tests + using cyclus::Bid; + using cyclus::CompMap; + using cyclus::Composition; + using cyclus::Material; + using cyclus::Request; + using cyclus::Trade; + using cyclus::toolkit::MatQuery; + using cyclus::toolkit::Assays; + using cyclus::toolkit::FeedQty; + using cyclus::toolkit::SwuRequired; + using cyclus::toolkit::UraniumAssay; + using test_helpers::get_mat; + + // problem set up + std::vector< cyclus::Trade > trades; + std::vector, + cyclus::Material::Ptr> > responses; + + double qty = 5; // 5 kg + double trade_qty = qty / 3; + double product_assay = 0.05; // of 5 w/o enriched U + cyclus::CompMap v; + v[922350000] = product_assay; + v[922380000] = 1 - product_assay; + // target qty need not be = to request qty + Material::Ptr target = cyclus::Material::CreateUntracked( + qty + 10, cyclus::Composition::CreateFromMass(v)); + + Assays assays(feed_assay, UraniumAssay(target), tails_assay); + double swu_req = SwuRequired(qty, assays); + double natu_req = FeedQty(qty, assays); + + src_facility->SetMaxInventorySize(natu_req * 4); // not capacitated by nat u + src_facility->SwuCapacity(swu_req); // swu capacitated + + // Null response + src_facility->GetMatlTrades(trades, responses); + EXPECT_NO_THROW(); + EXPECT_EQ(responses.size(), 0); + + // set up state + DoAddMat(GetMat(natu_req * 2)); + + Request* req = + Request::Create(target, trader, out_commods[0]); + Bid* bid = Bid::Create(req, target, src_facility); + Trade trade(req, bid, trade_qty); + trades.push_back(trade); + + // 1 trade, SWU < SWU cap + ASSERT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_req); + src_facility->GetMatlTrades(trades, responses); + ASSERT_EQ(responses.size(), 1); + EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), + swu_req - SwuRequired(trade_qty, assays)); + + // 2 trades, SWU = SWU cap + ASSERT_GT(src_facility->CurrentSwuCapacity() - 2 * swu_req / 3, + -1 * cyclus::eps()); + trades.push_back(trade); + responses.clear(); + EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); + EXPECT_EQ(responses.size(), 2); + EXPECT_TRUE(cyclus::AlmostEq(src_facility->CurrentSwuCapacity(), 0)); + + // too much qty, capn! + trade = Trade(req, bid, 1); // a small number + trades.clear(); + trades.push_back(trade); + EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), + cyclus::ValueError); + + // reset! + src_facility->Tick(); + EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_req); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, TwoCommodResponse) { + // this test asks the facility to fufill multiple requests for different uranium + // enrichment levels. Two requests are provided, whose total is less than the swu capacity of + // the facility while not exceeding its inventory capacity + // + using cyclus::Bid; + using cyclus::CompMap; + using cyclus::Composition; + using cyclus::Material; + using cyclus::Request; + using cyclus::Trade; + using cyclus::toolkit::MatQuery; + using cyclus::toolkit::Assays; + using cyclus::toolkit::FeedQty; + using cyclus::toolkit::SwuRequired; + using cyclus::toolkit::UraniumAssay; + using test_helpers::get_mat; + + // problem set up + std::vector< cyclus::Trade > trades; + std::vector, + cyclus::Material::Ptr> > responses; + + double qty1 = 5; // 5 kg + double trade_qty1 = qty1; + double product_assay1 = 0.04; + double qty2 = 1; // 1 kg + double trade_qty2 = qty2; + double product_assay2 = 0.20; + + cyclus::CompMap v1; + v1[922350000] = product_assay1; + v1[922380000] = 1 - product_assay1; + // target qty need not be = to request qty + Material::Ptr target1 = cyclus::Material::CreateUntracked( + qty1 + 10, cyclus::Composition::CreateFromMass(v1)); + + cyclus::CompMap v2; + v2[922350000] = product_assay2; + v2[922380000] = 1 - product_assay2; + // target qty need not be = to request qty + Material::Ptr target2 = cyclus::Material::CreateUntracked( + qty2 + 10, cyclus::Composition::CreateFromMass(v2)); + + Assays assays1(feed_assay, UraniumAssay(target1), tails_assay); + Assays assays2(feed_assay, UraniumAssay(target2), tails_assay); + double swu_req = SwuRequired(qty1, assays1) + SwuRequired(qty2, assays2) ; + double natu_req = FeedQty(qty1, assays1)+FeedQty(qty2, assays2); + + src_facility->SetMaxInventorySize(natu_req * 4); // not capacitated by nat u + src_facility->SwuCapacity(swu_req); // swu capacitated + + // Null response + src_facility->GetMatlTrades(trades, responses); + EXPECT_NO_THROW(); + EXPECT_EQ(responses.size(), 0); + + // set up state + DoAddMat(GetMat(natu_req * 2)); + + Request* req1 = + Request::Create(target1, trader, out_commods[0]); + Bid* bid1 = Bid::Create(req1, target1, src_facility); + Trade trade1(req1, bid1, trade_qty1); + trades.push_back(trade1); + + Request* req2 = + Request::Create(target2, trader, out_commods[1]); + Bid* bid2 = Bid::Create(req2, target2, src_facility); + Trade trade2(req2, bid2, trade_qty2); + trades.push_back(trade2); + + // 2 trades, SWU = SWU cap + ASSERT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_req); + src_facility->GetMatlTrades(trades, responses); + ASSERT_EQ(responses.size(), 2); + + EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), + swu_req - SwuRequired(trade_qty1, assays1) - + SwuRequired(trade_qty2, assays2)); + + // 2 trades, 2 responses + + // trades.push_back(trade); + // responses.clear(); + // EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); + // EXPECT_EQ(responses.size(), 2); + // EXPECT_TRUE(cyclus::AlmostEq(src_facility->CurrentSwuCapacity(), 0)); + + // // too much qty, capn! + // trade = Trade(req, bid, 1); // a small number + // trades.clear(); + // trades.push_back(trade); + // EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), + // cyclus::ValueError); + + // reset! + src_facility->Tick(); + EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_req); +} + +} // namespace cycamore + +// +// +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Agent* EnrichmentFacilityConstructor(cyclus::Context* ctx) { + return new cycamore::EnrichmentFacility(ctx); +} + +// required to get functionality in cyclus agent unit tests library +#ifndef CYCLUS_AGENT_TESTS_CONNECTED +int ConnectAgentTests(); +static int cyclus_agent_tests_connected = ConnectAgentTests(); +#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected +#endif // CYCLUS_AGENT_TESTS_CONNECTED + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +INSTANTIATE_TEST_CASE_P(EnrichmentFac, FacilityTests, + Values(&EnrichmentFacilityConstructor)); +INSTANTIATE_TEST_CASE_P(EnrichmentFac, AgentTests, + Values(&EnrichmentFacilityConstructor)); diff --git a/src/meg_old_tests/fn_consider/enrichment_facility_tests.h b/src/meg_old_tests/fn_consider/enrichment_facility_tests.h new file mode 100644 index 0000000000..53ea956ebe --- /dev/null +++ b/src/meg_old_tests/fn_consider/enrichment_facility_tests.h @@ -0,0 +1,51 @@ +#ifndef CYCAMORE_SRC_ENRICHMENT_FACILITY_TESTS_ +#define CYCAMORE_SRC_ENRICHMENT_FACILITY_TESTS_ + +#include + +#include + +#include "test_context.h" +#include "env.h" +#include "exchange_context.h" +#include "material.h" + +#include "enrichment_facility.h" + +namespace cycamore { + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +class EnrichmentFacilityTest : public ::testing::Test { + protected: + cyclus::TestContext tc_; + EnrichmentFacility* src_facility; + std::string in_commod, in_recipe; + std::vector out_commods ; + cyclus::Composition::Ptr recipe; + TestFacility* trader; + + double tails_assay, feed_assay, inv_size, commodity_price, swu_capacity; + + double reserves; + + virtual void SetUp(); + virtual void TearDown(); + void InitParameters(); + void SetUpSource(); + cyclus::Material::Ptr GetMat(double qty); + /// @param enr the enrichment percent, i.e. for 5 w/o, enr = 0.05 + cyclus::Material::Ptr GetReqMat(double qty, double enr); + void DoAddMat(cyclus::Material::Ptr mat); + cyclus::Material::Ptr DoRequest(); + cyclus::Material::Ptr DoBid(cyclus::Material::Ptr mat); + cyclus::Material::Ptr DoOffer(cyclus::Material::Ptr mat); + cyclus::Material::Ptr DoEnrich(cyclus::Material::Ptr mat, double qty); + /// @param nreqs the total number of requests + /// @param nvalid the number of requests that are valid + boost::shared_ptr< cyclus::ExchangeContext > + GetContext(int nreqs, int nvalid); +}; + +} // namespace cycamore + +#endif // CYCAMORE_SRC_ENRICHMENT_FACILITY_TESTS_ From 92e48adfbc589a1bbb7685e473d2393aea2b1a7f Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 10 Feb 2015 12:52:46 -0600 Subject: [PATCH 118/314] typo --- input/physor/1_Enrichment_2_Reactor.xml | 1 + src/enrichment_facility.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/input/physor/1_Enrichment_2_Reactor.xml b/input/physor/1_Enrichment_2_Reactor.xml index 4bd592d051..afbb26823f 100755 --- a/input/physor/1_Enrichment_2_Reactor.xml +++ b/input/physor/1_Enrichment_2_Reactor.xml @@ -21,6 +21,7 @@ natl_u natl_u enriched_u + ef_tails 0.003 10.01 1e5 diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 97927349bb..224dcc3a63 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -97,7 +97,7 @@ class NatUConverter : public cyclus::Converter { /// The EnrichmentFacility will execute trades for its output commodity in the /// following manner: /// #. Determine the trade's quantity and product assay -/// #. Determine the natural Uranium and SWU requires to create that product +/// #. Determine the natural Uranium and SWU required to create that product /// #. Remove the required quantity of natural Uranium from its inventory /// #. Extract the appropriate composition of enriched Uranium /// #. Send the enriched Uranium as the trade resource From 645e6de61ad6bb8842c5b9b10448c9b99a4a9628 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 10 Feb 2015 12:54:03 -0600 Subject: [PATCH 119/314] removed sqlite file --- input/enrichment/cyclus.sqlite | Bin 156672 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 input/enrichment/cyclus.sqlite diff --git a/input/enrichment/cyclus.sqlite b/input/enrichment/cyclus.sqlite deleted file mode 100644 index 70b8fe24ead5431db31d73b83e3c2b0d690fb21c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 156672 zcmeEv34C2unfN{D+_z?XFL_I|zvMN|zBXx+_BCD8Hgu&6lr?=#Ufa+tB`+zZh-bsE>eobB?KP5jT-zDE9UnO5s5F!CC+_ivffjlgbTLr|I^ug<_4tVu8 z!mG6&UP~+Cm59NsG6JvCFuaNiXxa3Uufto~Vk(>erhq8eeOwE;7C194ur9X@6mQGX zQr~a_UUlcft9lq-<^Awlva|@^i2P83f9~U2z_q~Z(*kisdIRz~`%~w=@!A)ET${~4 zQ2X8M|M10IZl&el(yM=c#@~&VYXR2+91GC$?z$m-cPP49Z5hZaVp3c4+d(-H*KV^K17V`j=mJcO|;2J*2mM<-N6^+miYkiM+6_fBELY z8FWkkw-{qfbG`-e46qeqIr+WhoiY+L#G4;!BN>f0_$XXi3* z`=3uTyR@zaUSAe)%m3>uJ>A&27Rbi}Zu!s0S}v_?f!CJ>-17hWN>4X7t_AY3fLs3a zv6f5gTHy6%0k{0WzS7f;jcb8?EI{}FVe)IrauMDCmk+N?>sr9Iz!_?ReFPNWi)s5` zAe|?{zsHdu?MClGzsGy={X`-ck`KRvxE(;gcwHUJ70jg%PG&YuWG2V=o;;Sx8ee$B z?%{QNhZB3(t=~4BFyKvlDaVfVR3@=^c>mruhEYDLgv7{>y~CS_cQ-I?Mt% zCo?uTGdnUpr+*NOcpaQ*+H-s=v3}dm^=;>*Cv{<42oshz3EOyZQsIIRnIjCqHenE- zZOvO`hon7ovx+46@Ngsn*d~cay!j%JH{Q^Iu4OuHPalKWZJap{wlRNuE%MA5lgO=^ zlUht!teK+cdYPhT@eqO{0X}>j!2q5|s+KT&eN6C4limUCm>L?RAGJWj$+@^`iOxE}+vJ2{q~nwia{I_WQ!i)}KF8uqiz@ zF*z}JGJhHC({p1-c4yMG=+DocJ`5WrvSz(^9G{%rojE))GyQTnN2arL4!%@pdUotc zW{y^KLqRZJ>W~^W)sl*t%?48}JT^0ZXyUL!1YF9#4eciYW{%H|j?GL>&5RFCr{^X| zkEc3KASQ#Q)L8l$1UPqcsJpAHE7ht0G$>{>V-v?Rqf8M^lo_T{raH|!fFxbPRHqRq zAm+xDdSWuG3C$cDWxrFM z7O){1LQ~A58{B{xR0?xCn@yh_>gwp~TCT}cKnCGd`ts3<=@X;bi7PTgeKc(>5S1|1 zDY8kvDPS!VOuXIvYT1GEA7bUlWc)+NGn2+oNaTrWCHK*+Wj3@Ku1A*9tHz^}R70jZ zC#F@XnG}-Hkj-`^vAk`-Y{aUF<5@^*i*yiV7Y}*W5|h-i*_p9SHaj-~wOx0r)BIBp zCN+JK)+$hffkOW_&FwqgWlAxVor9uI1;B^SYZAy&A=Rm-yeZZ5&0eOKf`w|&TNH27M=!ciE7GE`JgF1u z$sskx>8FmOIYlj~CI*u|KwYh(Q<xwVHHt!jgQ@Qq7(;%mMU}k>+M-vofSq%Pi}v z5Z!D*H+_8SU}lzOT;)qgraEm>Q|fQp!`D*85|U9By^5i6L((fNBbvJ2FE3KuV3bVz z3d5jzQ5+T6e|Mh2lkZF3A-tA3i9;Y;D}w6H@);tCt! z3mY8lfR;}njYg67Ig}2O_DxeriK3+vf7RpJ+tDY~jB1cyJp1O6wop8sE!NA6EOhN? z?~aqE02ap8q#g9_C#H^1rj=@oj{jx6Um~}YHv9~HxQ}arSHS{Dbz1n-b+Yk45caQZP8d%;j z(9z$~+YNuZm$!G1_VxF440iPNbPOCJ_K;d%`1r(9C^c~!ZZz4gGu?zmc|9xt6p)VedqBmTsPIMfa8JRvb6Shrm9GbCCYivnRk58(z zhKUiSp*{~zSm<+K8gTo}^xP2xy7Blds}2pwuJkN)kjzsi3WQBSvPq=G`q}jK*pa<3 zmN3{hoE)1xo;@csn}trlGG&>tz&2*GW3v+nH68a{3KJh0EB%)7Lw#1r`WfioTS40< z4({K+t;Y)7Ff%c|Vf_X(uz7nCn}bp&j5cP*(kHjijA!(ZGK)oZu+^*#%wp4gaj}oi zxvI0epu(4 zsETcyIFzBoU(F`Xto|P$oy-!7Ohd6#XrT}qioMZx zhJtA*b}~ySh=yXPP(v}b{|DUm|5eE7t_arxXMzQ`Q5V5mD{1?`RJuYUKPF!$&ykOj z_mQ`d%Sf7RBLgHsB>W=&B7PkIHGT`8!=v~t+<=SFuh6&9v*;tRSNJVx8ukpYKym4J z(ifx;f}lk|%}eEx%78JyIjZe0991?s(0OHbKC?NwFsV8h+Eg!(#L3j*Q{{?Uxz((@5}q>oT2aHnF@llt@@l!&tewUO>V&K0%JP6Z zwXDn^msSD@sUYQ#9IlWn;~I>uPx#8q<%Vixo(0z?wn=n}+z=0#QEUo47MB~!Enp?U zSPaN5l9UjVQMtAs>9hIV`Fpu6BG<+ZB89W8i~{v_1@oSHM z4`~SNqK6zUk)sWa!@NKuM~dZWl7UStDRQhxjy5u=Wz9vdDU_rAO0ed&8*QCNjumKp zmUSGtG$=>w0#sdN9jGh-Feb}bERrLBO&!ykk}u?wqt%RETYHLlAvO%6E?luSsxl97 zo1t_$t3;Ng(k;FJSW)RC%CB zPMa&9g{-A-OO*$^^Ru(Dc~&0i$~(|8wjEjS>y*>xif|!yA=A+Xs=ki=*wpH?w_Q$~ ztItJ*MoU8*Ee(3*o!tXl+vRAhTvr(|fNBU!TI9M~6Rl1lN1AEz(SK)^;$R5&!|A7A)--EBfJMmILxXeQm>t~C7@|wA7*nj@M~fnw05!0J`t%?1FxomeF)Ccz@v$E&^k1bMWjv*h^B#k zcwQW|iTzSD*2Fq!ZKN+YBN3@X16uwGib^PoWqjG|GOOnwsoZ3#FFrDYPQfM(IBuu( z(&>H;qrovM)A_L#g54ZEN%?N>FsgBNcZaDRP$61}hHY_aOW2ztW#`MKWy(>_b{1Qs zi8H>cEU_@)R*iMI8o1h~YI{xE613%IxaRA<5nnu=MsGM*XkmWukY{Z^WsODW#q(L? zl zU{KK`JS69No3cdqs13iu;1GXqS@!FgUdQK?MqZGaugnak(k zlqj?xQ|V*06;YaVdFPr}OQ1Sv-!TLN`I8KJXs9=9@{ZN7k~~$vttpVVaH1|?K{dU% zu6i|usd?e7l^|^4%&@R#kWV%Y%IQAtEC9bh!)wFIngKb@pMT&BvG)&%sr^6bw*N1q zo^x4T3!JeQNEgud-;2`{d7PXeUHB(3^OrtjqvI<6+Oxn0I?3j*OUB#n6ODdlvE*seF8x>-o|I0@Ro0p?P>{EDo2-(PH?5Gg?ELl|q2(VVzl8jF-)k@P{NHJG>a1uWo-4=|pzD3YDXBbq$GrKbJlJa&oV?0I*ejjU z(tG-%87^b6!YG=rZ;JWi`}UzXE?<->=^$_+dr_MDyo^FQ@{PG^U}?-+YU5J_a*%q6 zp*~>L>9yGmt-#FZ>e>>=W-~LhO$QRE8HqsvuEJ*Lta9dN4uaE? zX)Ey9k#tr+!`GH@OgS0=y6UKEX$Hc9QU+z`|4OB`5}f|I6Yl<7P6+-2em9=P{pf$t zr_tNdxhNt1K>Cn$84z)vzH{YtId>Fe&YJYE*oc!3-q40`*a(Xe73d}_Z zgr+6kz+TY;H(yKGL;x$cGqWe+!zg;A`9;hf7K*TSIX-y_vZQY~sg z|Be5OoMp-4r%0Ub(>QhZB1dvs&wJtVoJN_}cR|rOR>Lh@Fs2%1{&CYBW~vUJZTo&4TSuC6$#S;EDYwoZ zC8$lnRq`nHdr5s5+9JilHj1Lfq0KL1&AH|ZUwr#^lpCH$OT~GoSWg4rvU?!w zUdgsmo$5Ap9j2~4Sy5nL&Cc){e1VX*PE3!hxl-Rj)t0dDwo;B4n7sjMhgpmq4xwdc z=>}{K#K!-%(uhR93f_PIf}96?08ZmC5M2Mwk~!1G^-}PSCR>+hLR3EVwqMsiEwUjvSY3E8$#AmbtyoDq8kL z<~Y#qvaDQ7&%mg(%Au69S$bMT2kry6URgPIsa#ua0D%%_NajwGCCB92q#=Pub;E21 zlo~Ick!zy{2X*8nmrjFdgL>z|OGd`yQ*v#c0n@@A884f(=%K_eeiZhLD?>Y$lDdIo zm&kSMOa((|X%U;S!nIUea)fR?H?oSJx^mfJx_#ZiuCRyJ& zm<=_aFArN1!#E44%2kcfc-}&UstK0umxnEhz>^3DpzVJlg7ZJmliSEeqyhg7e+*xR zH{t^HCG>7UxX&xJK!2eRdXv4_XYae06|Vl=KdfmQJyQJD=BNK++sem(*zm+x-$q`% zhE)A=@Lj+8$ch4B^z#@O;0p@)0`v3r2UJDv{r3eG^{W9o80Qagg-^h@kfL5yQTrfZ zK}9`kfDXn56qN;h3nBFKR9OQx8!(QVQMZpV*6C8BQ{~3|ku9B_=Y!={`|3X3e zFXWg10@MEAbKU*FHWRx)T?@RfEpSdTE&nq4DUIbC>i>(pr2KeYN862@Yk@yc3#875 zc&}OwuNCy_&%P+_|NEp03I6>DI*h)88}Zl31^`OA-Bs+ahf}ao3J$?*6X9?rf;v6l zVp+}5!PdnL4QyVQVDs$S3PfANbf<=CzTUuVll$s6Mz#Q;E{7;91O}-xo8D~)^k{(Q z6V=N75^(P$yGPeptuU`#v|D0k#w;AUU9*`J%*~Z$nPsZR7f&Wpu1>QhTa}oZrPkCw zJ1n7^5DN#YPWtN6+*!+R{g`2)?U_y=%O07T%jzGUmXLI?H5`lnxvqpS-rtXM%5A|c zygk$-0&KF((4CSKnJgFBWeJK)Vhz?76>u70KX9)Fd2)w-MRdZM&6*F_Dff9aFeB`M z!<8fBS@lo1MJp9()x#Y9wghBZxL{h%bqc+1?A*$FmZ?tlvyk?}y)aq0T#;T{V*c*2 zglWdu0yg-~g=SA?8g>(#A#iXsGjYNWQwpbNTDL5PaHZ+G0ptDdDDwR&dTHu#Kz$<>X z55;++*Lq|47bH#EpZkDBl9LW{Q4bgx(Yfuptxk9<27Ma1i z4djYkf!t7M;W5fWMK0(>YMEw9E&zT5Eu2~&tIql5hDHm@6#B?`Ea#((y(XCI4lA7V zQZI&KQ zYsWfBiCyeUImuSWwFW>9p!^Cs$yT5>xDnOpNt$usw}w(ARbNh%%iK;`TA_-|Xf80L z4T-e>kIAoT>0Rym|9!=km@B}wz?orzl{-Pt!6w@OFT&4B;OFfN<2%f z%SaL20`N^hxsPjs*R}<~xi2h*+4ooY!ZEmX06Dz)0~~G{Kn}nAzHl7w7Ql`j`O>4s zaky82gSe|W4mSyK5H}Xb-~s{X>fDLq7~CD;gdZ%9!DRtX_}1bWToK@e_ZRbL{}aVA zy87pcLP2qiF8?{;o)9hnezI30KLHP*p8_AC?36z!_?R?d5d* zAHZ*t$iI-kA=ktCzfR)8Ux&Lt-*kpX$yNJIv_Mn93)53R$3dBrz}jAL&;ifd=G7m3 z>8r~_O@0BT-$CgUQ2HE{UIC@oLFo}tdK{FpfKql)5&hNVOjwMNQN?hSkxfFJ^?*9G>eiGk`593vE)91gU52DLqr%w&s1@LLtJuJ7jMCPIG4OwX0%M@A+avk%SJ^D@tg1&w9Fs@IumMY|k zr$(zT8e`C-yfr)zaZ9j9X(tSYxXO&T%#}14M|B`eTG-kz$S3FnF-ETb_rd)L=2}UC>Gt7OuU+y1iL8FKEGx z*bl@`a~BxIzXWqPA%zx9=%n@Nb~$>O`TvVZ7fR#>au1m$LnI7$e|{X_fG@%w7^4@^ z`_UwL{Rm6{Eyv-$T>?jo6C@z^19Z> zd5HIQn2F=NTb3!r+#I!6H-~)maC~=LgCW?FrFI*%phbM`*{w?rYDbIP=QZR$VJvjN5As z$qwU;m?YDRd9c5=Mi=d@PuA;oEukse(po(a@j5;EDRJ3QOO-;*P0_V_DnZLrHq=&W z2zDqvWYAK<&8u503~EP;u1;#^plXCy_LM8c+!RgK>%>NimagnsG7ry66OWOiJ#BG? zhnu2Pm=^KWS9scx>=@TYSN!&+kF2@p*}|W;zW7*u zIhQ83;&+F>v*tg3_^Gy=H?6N__lr>CPu^u9vy| z#G)$^(3o|_TpFzC`k4cf_doTqdL*Esa<1C>s}H}w;Xjq~zuzeT+ej0U@ptei@tt@M z@4{`^kG>DP{@(-RfW4>-6-qC{NZ|d_Rnq?Xihq4CH|$1BxnItuX|UL$M?hn?MK_mb znI+x21T>~}tMBB}BrW=M2x!duv~y|dEOOceG-f%iT$*}Iyjlb_=6E%8X=*L{Gzn)o4(SRIXgtv-*m~&b zN}UsJv-Vpu>^n}9mcJ4w3bIc60PBZ z*GH>);C0a|9(ZlEk_R4&R`9^9qvbqsD!PORUKx$^z=N?EfF057C$T6G-iKom9=sPv z%Xs2@qNO}=Yc$LQw?socaC5YT2X2fO^T5lZbUUyk!!<;-n3 zC4r-`71&8$9)*p-PVkZ_-3IIs9*fdlzz%RUN;d&Jz>z531MC2oMyUfJ2RO|4|5L#C z|KXwKzfl^e<^P|_C&*po29hNgl3~(8;zYtf!e7LX;Sb=q;p6yXycu`lC0If)qJKh< zp!cFTqA9cwtp?A*MbfXNZ%WTe4@$Q|&tTjr{PZif6E;aZ6qW9Y?cl=ij&0|{KM>!> z-E4iAKem<2@V?ktT=<=_5ib0W*cLAQ_Sj}F{I=L8F8tQmFc*GHY$F$bb8G__ep7rs zz#T!K-Mrn@$}iU+btrB8sj-%)GHUhr4j>H^5Y)rdQ%CtbHen~U(mbV}{jEh%N< zf;+2otv*xZrL=9U^hpk&G}-Gj=VExl1%66 z#t*jk>Y|+u%9K8t>H%BAO+(A)A)Xx6^q|C*6D>UoF*ikz>Z#Hk3NbfD5BKZDMv7KsdOGIe$(VSI6uqdeUE$%T=(uio4@=RD zTH5p|I8*fC3SBFO&sz_x&#E5@}E`@ttSuB^zV=REKn*o?L!Nu14v0>E8BT z27@EPq%xQtYj-q*2R;eur2g!KVE z-TW-wr1!OM)1%@{IO(o^x^6V(y0#j^orZd!NjNQx(oNEh?PuxYIqKZ0SDHSslq_A> zJ~AKq9Xm8_D0x!4t!;}!4n>k9{dPU!e2ltdvo0JtwZF}vroyk4Zf)PB({rTXy4|cy zopf{WutLsHRL_3Fr^9DOP!+YM#gW)S#{kYpfT&Zo=aoZb)A65tm|4z6R=kWimq!I zza3}Qbx1&C)^#!Q zqpgRp5YSLL+In~&m!{FI4=w+t(%;hl{|Cq%Sx=&{_WwAH|M%fq^b7P9dI$9Xmm{C_ z4Ip|gJk4WlaN~y=1;4Xh@@ieDap(&*A2gBLONP%v+LBgCp>ODSwqH6ac@f06AJ98k zoG$LO`!y8;tb6`I`{;b+&y1PLTcxMkE>_6--SemQ4tL<_VW953$Pn)Aop$ z@8|}U{`o_#`}L@B`sa@x&~;<|^K%tqe*gTDQJok%#Z#^4%t!pNJ|O~WAWwDeGt_n_ z!9yms+4$}Q(p~L)b;UUu=s|tJMn}T3bVvK1`N$v8^P4i#zOQY!Le9@X_v=~0Psio= z(ef{oyY=g|PKMzhev&pyfX# z?UKmH$PrQnxBk8hAHa?1N9aMA_uq;tVBhb@q*Fk!$fq;6OmsW?=GmFc=8ib-mg~$l zES5t(pwf|B3Kz+n96lPyMmS-BN5-C9Qr^SAjLmkO!Z;og>d4j0d(6%vjZkb%s_V#( zT-_oW)OfV#67n8?Je(mwG*;$nm1WO<_ZepGn`0`%}gJfI6M?g zuqU;L-PNuAOe9h>$LG`w=7*-!bCaXTQ=KM|$_8}W?Z-piU0q$NPW`7rG0U9xk50qY z4Z0{ZOjDuLtOH2W6-;#=N{>xULJw&u2*fGl7u7w*1RLH3Qk@LIq}pR?P;JsBDh2>K z`sK{JmIlO#4ZsxT%~UGHpfX<}ty;zcGAK<(HQErqtrMxa^u%OVOP0)`QT96pH=CHi znrM|coz13C4s~^ObuHHj6_84o>J%9z-z3fLIlAJPU2RMY@60IUu82 zVv>Tf_zWTpD%Awyh$Iu>}CxhsDC0oIi#jK{WR&%V=&u;SG%P;jZo){&ur!}+zq3I zrqox!cbML=MB($r$~?Pa(pFDBrCMd_YD!ZDYD8{4GnJkmA7xG;3@NHPCMTvdX(+Zf zd+>QuD)?A>Ha+DuZFg4!vIbw0okbHxO9w}iNQ{L%)#)^lIUyj56X1$tV(vJ-oJWhg zISHtz4i#-q2gW!tH<6yyTARrUOMZtdkY=GhGL;>DB56oz$XIz-Ja1U&rjJh@%*?XV zu6*f2Qk^!bDcf(*$_T}%xAO~$_GhTt`GuwwKO=NqX%MvN7|}XeXjEHc4RTFWVipVP zT3E6TFwl&r8Q+o#S$rwPY&1TF5>Xq@WMNa7sZNfDw(JKn)-xE5M58)wsED2bwEY0Yv9?#y6KA~n{ zaZ9Y>w`w#|Jp1O6wop8seTJ78S?F2Q&NU}Z0W6HGNxM{Mc4F%IWLl{M>G(f@FID#c zUrBb7B>pvi9{&}9+{d-Rt8al;dRQOz+Ba1d6@L1;@Y2tJ7{OHWI1@_!4Q z{J9A)hckayfWN<|&yY-TLBJ2SXuP-A(Ml8+vXSu0duuZs83slA$GyA5o+G3+!W z3;I5_bL8v%)LQqceqFViTlb0Dmat4~F+Zs~j7>Nxu2aXF+5PCM$6*%3;marH^p7!T zd??uzOElTWQS5>oNTo6T4xGc~goxpvLBPE3z07Tt3!Gp2ljLdukv`ZEpgbKw?lJ+|8> z4rQo8b-?g6T*z*Yf1AS~xt2EOZ2D9s)7fLOiKBrQX)=rKzWQ2&VDc2J?p6-@_IqHK;{Hiwo@L-5uU|V>OxqOJ^?E z=tt>?_Tz{ua%9KG;r)!62FOSfJ9p@SL=$C5tlP7J`Twnyw$S}QpCs=F55T)g8}Y&o z03XM9;1l5gZv_s*Zouck5AZeUVzd&KOTU-C06WRwCLIAb{i&&heFpw=$G*d`G6Q$I zzJlWG9QaaW4(@bSIi-m@Xv*j;-07uDD7L|YEiliXpKgv*s!j)0P@ytS@Sd)U@q-Jn z;A*23Tj>zwS68-9*GDLUGe$mBjB3g#jngV#)hZ38fCu*}_M<0-s=CUO!0BX|k~w#p zlmty-Rfi~1)FCTOWgR_TTSC$04s>x))upAF5_CEUia4fA6j9nr2W=>*S*NNHC?GBE zF$*io6i_UOUt_NcQUZ>)T6UuM1%UDG;!8{hX{I*?KvuBR6gjiPQhHSYXdtLWw*j*-+HNVooQjAZ0My7z};1WOL2djL3w)N&wg|0|?D z65RgzVYvJEFq{C2;osnY!4KhE!2jO}PNF}eFQN~jo6#{ef~uuINdE$!fbW#%fQkRq z_9=SXr+5s#dlkLy1QxxQD|*{$G`*{P01vs{-UThANp|#fvYVpo9O%+QQwFK+qD18m zqHv*BBswWUr-PtK%@^j{q@jb-HaKVtt$C=X9mpU(?0ReUWK|o*bK=FKRo_anoM@S1 z)!ag9I7)M}eKRHH=xojQO?)a_wr}JI%ggr5D5*1!YPN5n*h+_mjO??N5;%=u$v#O+ z<219Led+-Z*~i{lSF=w`9Ys4^5njS46O`834p_5VEhTa`1bS9$sG$VT*3FiEmR189 zrxCPfvgRsE#Zljx1!(y%m)1$-o8%Gl4mbm_k<`Kpz!%}v{~O>Wz$#pdevbYgMg~`c zr>|DzmA)fA0v`U30*mrAmD5ob!p^#QNl8e0GNW&W3@lxuP&#Y%cyWpJsIt}-NX8W^ z=a$7-C@ej~mg@seF;SpV2=rbfQ2)}XD9{K5dY2NYKN%4PS_XmMzykF*m5Bl^g+OmL z0`)B|6$KiGKyOq6^(DiiKtmAdTUnsK#tD&uE&P?kq39U9lBuO@r!VA$;T+*+E zNb2c?2scDI6z*dol14hQ!3~j=gq9g0;v}1;;Dv~bOA<Zo7MBz#qG*c<66MAz@Od%byZr)wReESr9P$P)>UdGj=rQ$ zQlXL9`#HK4rT-89|Gr6{Aa{}(vWZmVU*gZJgT{ zD?KCKC0(~DUx2lA*pK3lbI~P1woO%fqLz;N=OMVKmJa*pA-JW6j`%sXy&A-oHFTIS z#viVs1AQ@mR}CHKi}5Ko#uwuoYS~QLSUpYzl6)o(}Zqr#Vnh$NKZr^wzWc z0p|^?uaVsh*yu21D3}E!rVnS@SyL=M+sG~kT$u2|Ms~tyVZu8b*(sle31OLz#&u!B zhm-8wk23`zGRGz+CudH;*4?L-!#`0@jK^kXGtx74Z1C^2T1c0{{QnYio9h4PPhau5 z8n_ntbGJY}9ppoWXm9#U3-x;3S5JrdKx1$FEi`ma9%$^1znKPXy&E<@8s}@+&P-+g zOWQIEc+%{<>!C$I{u>_7IM%3=o_S2K6lUmK>6Rp zb`87de@xXK?9*2d)|of>o6bYI=YLrFv22tu><866Ju=~*|A9Rv`Vo|4+GYrgofdss z25jn{|4}bfwpdWNtEs56%t^DL(vh*99@DYIY;j@=>?)$5t8NaQd;UjD0Oc@|d;W)> z-dfqVmkki&Q3T{v1EiVxQ1?l{21O-%ZcC^&NO1 zfl3jw``NVo7sFNF_I<<9e)Q=i}ZczJ%D@#&&uLJ8>((EN6y72X-G1+ zNs1_S^XKUm1vDnjQIKNqlaz5{0^JeXB`G?6R*>=y*KzntoqWz#*?<(CUKyaWm^JM> zENo3b@G91{^X6wwAIMRxX_u3aHN7+@%$oM5mKPJIVJ11waMIfTQo91l02rVs4LX@0r&DFI0`)~*K|9cf#fq#xaiVwk0_i-)2vA~Kb z&F-w!+83whuLC2Lj}I?f|7bfFHnb z!bk8{+>E{G-_Vn=2lx~kg;Ro2=_Tol(!Z5!~rnr>WMJSC^8B=7c%77&93`~hl zRVhT(85=b+bzx>rdpm533rU86#2FWjL`{_vt{hWLyoq8;;^_LAB2rld6wZjKsZt2B ztaNNw4Qi=Uz-(!6#NarQo+{%FL7;JNozZDnRHRSWQwJkS$F8KHDKc&K)UODK#uS_K zD(X+fxos=R;!|1$9z-Br>kbx>4SBvQtQ76lToc2S{^3_W_fTq#05k#-7)QYH`FUgcm zO6%GvjZ+y@KB;O2lDIQ4wIXVPT;z<6mf@ROMzu%Al;KIT2}qoA(MZ&asF5qj6ccY^ z86|OC{bY(rWdl$+BcfJBOCgq(j!V?^R7o;h+S^s#;;eb72O4KXr_-pZQpcBMic4u- zg3>sZF-4}T7D$|JU7?yPH4s&2Y_wFVX4bSvMl(6Yg+Ly@z;)+KR|H{__~p6tea-IX zff!{kJ3gv!TUZW`e_?^Z3}OomKzu^BDq5Ts4bDvky0`H}lHa=Et9}v5%`EW4JvggU&z4U7B zUdsCv4`lcA>HJ@*w3gogeH$4iefSUf@9>@YeB6M3kDfr+gV&EZocMiIx&nwe&j8F% zH=sfL6oYw@vA|dWHLr!FVD7pT_47GRo^^r-yJ?xf38uB9sF}lkG+;2$75L>aw_WMf zP+bo88^q?t;uOqw*P&s%cw_0;XYd(7ZN;|@X2Q!+yPaEEh4LDl3Sa=H#=(U4N&Ll_ z5N6H6gnZ70O$hVpU_uVJ!-O!U4kolyE?`2KV+Rx3nG9>qZ$g-T2NT-41t#o;+4u(3 zZJ*+{nlNoFrzLoTGrE(8}9OkC_#gRz~(NmYBi97r$KvRP&~@krzn=AsZr8S*Q}y698Hw+bh>#Z#d9p9 zR6?ez4v0d0Xt~2g~!exPp>8ZJ>Btr0stJ-T!kh*#Ulk-i_D8 zTK~;xK>D`yPRs6|h0DN}f?{f_y7FotLIJSo~AGa?R-1oB|)keQNozNOC1VPFPEr%f3sC^ht5gF@n=4DCC zWX$RQ0vZ{1L`$*{ndd#DwKYf?*%>VdW8R0fRt2aqcI3?=Y+;l7fmt=FJqr1m)CYo8 zliCI4V^S}TjAByz_?QG8qR+!WKOJyB-6xa{AX1o5ddgU57x1a{SjJLrW3U(xvVEFBIz&#kBlm@@rbe zFDJhzzlIw?Mo0?@;veJB;1A$a_+q>om!tniFQAXHJAihfb`+F;EIlvXE4@h?mo`dL zO|^2j0dkx%Y6)Rdf~hlejF5~R$EBpVhJDwbK7CrQ0cYkw0;3tbA*CBaKEGTCp3DUz zZV3Ao5z0j*Aj2-=oRI93agB2Q2nW9|MC3AD2N#bBf_NkxU_sQuwIc$OheHZUjdI@z zCzPp>CjeR~H;r)c`$DoOj_cu)5f+3a7E&(cWm@1G<$4j0jLDG4TZ!x8ViAFiJ41@S zaV^{{0yG>M(sd!PuNK$CeIf!O4~7(r<65{*L?Gl2NVO!chr2`sLY`F(hHK#(5rL2g zLjFJ_rdNmvggm1NX~lJLg$Sc@9E6jeR%vSB@(>n|ljMFHP7T}}BEa8HBU7#38R9%@ ze=RjwwR%&C6Md8>O0{}Nh!ee+rhBz|J%|&%mS)as^->Tgx|x=+Dth@Sf(t<$QCkwi z1(o#rP~;Douu$5s?1$I!YE%1vHI)DRVHeOfPzUTLDYA@&VI}Yf_zU}Eu_t{ zD&UJWbD-Wx69?*vG;*MFWElraA`KiUE?Y|49H-#QlBCUXpe#}k{Pqq^L8OiY4Mq|i zXdqI{f%+pg9H=i+&4GF&RUD`%QpthJkqQo!M9Mi(T($(PV2@i_9IRjmMq0+9d*>W}z2P+!EyfqEle4%8FzaG-KT=0Hh=aG>)+uAIPm_JModvkQ>Qng2LIzU4;xCd=p>H^?M_mdeDBlJs{$J$(o3=sS?0Z+|U)`)cUh zTTS1dD*Bcy>6=v0H!i1AmQX2i`nw=T-@zz-2cYzWlrsAEmD0C2Oy8ameaj{EO^WFo z7f~sNR7wH;9SG95KS19;KYe?B^zHG|x9p*BBGWe}loJ!;4`4_aOrE2uGX*|Co+EF7 z(!QGvk_7RAH=r-$Pr@kR27D>p1iS_>!$s(q=6V!d3$N31JjZbF<|tu3qKa}1SL z@)4`U6?{ahw49GviI?yZgE-Dd^y3&G(I-dwh+a9uNAy7B&rOe3xs;D+DGBot%_Si| zqOqiek62bz%ttg77x58ET*yb%;{rY+frETRc|m}WSW@8UBVq+UJ|Y_M@)41shmR=5 zG9MAfgpVk|n7XQQj)*-fgV9xk5;qAhabWafYTifRed(sJNw+8ICEZ8)LF|ep>HNP> z+91KdZ=n-d#&00Sd%r^u>49qTEh)F}dblAUnEeVrpc3RQnB|%3bLiAUk2X zty~9-_~;GhI+1owI^1F2rUBt*dHPemk)7Udo{M(*;#(U~ZZlKOD;K=w`;K>X{j-W@Zwza)vf-ED(0j_-*R7k zIEix0wG6ajHj{=syPU=V%{APdMFSIpYYG#79!nhS^~DFvQLd6HvW^`XP{n~ujky`> z%UOY*w1m#5q;Xd;<{))JitYP+@ih?jMi%0TdgI$fMvFS*9~n0xuCjz|La2(W95iqf z(yW0-K}!hj|2NP^dmP&C+o28r4BYVhTT}{n{cc1Tp%dsPbRT*eeGUB=E`)1Ghw!=h z7=8=>Yy3EP2>KcE!iZpioJ}qv*OT{9ct); z)AGMmx>SOHH%K3lJ}G@!`Z@BU1R6xU(NXjU^j`D``X}@vMz{hmhxxw@z6Rd`UV{G~ ze;5CO#7Gx8i;TmZ;hp58^Jct8fVn|lE5N)}UMIlZh}R1+H{lHe%*}YC0CP+IumE#w-6jF%w&Z47{+FPe zB`CR{hZ1}zl;m+J(Oo14bN}DPpT!@-x8W=B0lW#f;Zj%!{1$iuydN0c=YPclf|Pnz zJ|Mt6(>f}^Jl%S+0P|GqMFPx|%@+zVPqbVhz&wu67hoR4=Ls;6;{5{5Bl5Wd%)|0I z0?b2rp8)fqyjOsEpmC1?bARJ*0p`BOvjv!Y8+HjW_bl5fz}$^@2rwVO+Xa}r@HPSF zeR!(?bEkZk0CPujM4A8l6wS+*lJAgDkvXy-*8UPi#xLT}Lpy&PtovPv*FoPufPRMl z89j{Ng|0?vnE7i)Mc@he%hD&L_ewb_Gf!~ z2Yewuu9)%_iEzMI$j22?z7i1*_=@?s0?Jn)!U129j|);hp9lwhUOp~B`2r#w@cH>T zS-SIyn>~CSp)z55nwLg|rV-)eFy+JGtQpCUwI)pY6gK-Pj;S)t$1znlif|xu10Tm! zSuer?-#P_nA8ImP&f?>kE+Zlw$lSumFdOqaEM9MfeD4+o|0m;$#K zuSS{#y?~$LbS4?`Kh8p`^^Q09Mz19&N33-!R| zP#=5*>V+3!1t9_T#D1tRZYB?s&yw#iSpMx1W_cvVi`4z!U`AZc$FV#)B*Hrj`UNUPO)&R&09}RdgdIL#KtIL) zg-ic@<)5ENN~zwZF9!!jpp4H~MrFoCIN*!(aZ$=wA;JM)B_9`~d`m<);4A0j;*_sS zgaf{6KCYbdB}6#jqt`2Nx>^;KuSSFezFI!6lJeDyaKM-3y%C}U6 z1HJ}6u9osOiEzNz%*WMHzBUmK_}clnddk-#!U10^AD5(j9U>g?b@Fiyl&?pG1HR>a z+%n47CBgw;H!c4@l9I^xp$&f!+H%(apQkN%QLY7C3or}t%T+7wSFaM`pggYR<60EBLr($~P#&0p9>0*GT#LX!)-~a}xOxcmRAH_V&FUcK;oKGXOoL66OGYhQETJ z!uR2Kz#QNh%>MV{DlDU)!fAj{qPx-CfYE*Owm@8lts3_3wDe>-AO7ePKKzk5AAWC) z55FtQhu>Pphu>Jrhrcz#Jg5`w-k$ z!OB0mnC}1m4f#*|V0-Z8e_H_EpAM%Z@WGPd2flx_D7v+ceiw%xac zZTBr^+kK1JcHhDxDxsi|zJo7s!!O+`Tt#1%^i@Ik|I+ebguldZ{|WvHpxno`z?ozL ze)r_jARm5LfDgZs-*lhgcMA^ky9HbM-GctS+W!K6`>%+0wEs#^$L7)w)g)YIJM)R|8?}VB=`L9+UafYdh(fCWly<#{ql4v2=E5z8%MS;4Uj8Wx zHyJ)Z9FjD52)a9GvCogf0mJEs~tKs>>F-^dWkM8*+xWRD!;ow}X>yO|z!}o_nNZ!6bf+@rKheO(e&Od@1 z4DTNf?!|il2(CBWe>j9_>5{fzdSLZ$6Qt$81&->&Ip43q?jQI3|EUMwd(k6TG~V(n z_xwLSbK#!<-+$5l-*{b~|7V>!TK$z5?E}D)~poa6D647XyYKo2V~^4>lZ1Z#tyFSfj2x&156Nyu%QHB3k1a)C7u6^ zq9YRQ{rv>FgIrD0WF4u%{|z^QJOiivuEgiTx&I_4=m+R2@b>ctAa$RYVS!2+E@iQ& znsSE(DVO0k83zt}zutu0*5H_qF!$h=$#9JghxPDe#&q=ru9D#v8atVK35};#hTCTB zNW;&a%v86RT}Aa`rn&5Sox^L@y@;u2Co|M5Vd~lEyA<`xn0gKz zs264GaWD|L;wCT5)ZMVNZ_dQDL;z|?c#K)nK{9tWeV=VR*eDNO45 znR<3IL%m=TZj^lJUnTUfms}PNkVpn@rIlogacocj45oD;Zd-V;C8ve48o>W-vJ26CpU%EKidN?D;(_KGO4EMXosYc$H{vhr|A?ZCO z%su8ZowQp>`h?PVZP7@RT`DQIx5v_BYBv`>pXg*n;Ks>8^a0w>1&R(K#Z9!Mi=MA- zXEx!;xSaNMfuK!9FiyL=K+q~8*iQSpK+qy07^IzDAZQj5)YINBdcLNK5`bGvM?}LV z7^81jH&Q$}wshbNN-+9mVi}XqaXZ@=X1PwTZcsIF^s#!u>!zGoDiY8eW|>j0NvZ-I z{ijy&%PHgPdWwe_IPm4*m=h=JL;)NKvpg(UC)5BO8jgZjQ8`g75-=K8oW<7Er~(`s ztPc^7jOqD5ME;$Y*K5JY-`y|=a02}MZ2=E}us;Ci0lti%gqeVw@ky8q*b4jqs<9XS z2l^`b1i2sG3TFf|uud=l*S!U$|B}8TJqNx&?|`!e6V?gtLi{aRA^wtV zh`%Ho;xEaD_)D@O{*r8nza=ZgUy|i-bt_rNjeE&jK6niuJj4gD=7Upw@G3rdB_BM< z2M_SU{e18WKDdt$?&X7*^T9oQa5o>^#Rqrt!5w^XJ0IM}2ejPRY9bk z0}V#nIM6_(l>_zD`M*Zx{NEkWc0UJg_p7L!Ex#(= z$iRXs&)yj>Q7T9WSWuk`DqlfWEvVQ9&48fM5HvA@21(F-2^u>=(k`zw}X$z?t%4kHFX5xJTe+ z@1SQjKkx${flu*KufTQqs7K&z{2W=})_b4G<@R1#;1qh7Eby7PUF2VItDNFTa6J)u zIwt~`i))F%BXx=h9QF+ofjh*0B5=RgM+8n9du4&Y$6g}v_t=V){Ft|3fh+fBk!S4& zk>kO7kt4_iUP(RA1{{-U<@J2{66U+xNgo;H(}$ZV-0zTI&={j|$Lya+A-8vheH#?G zWuO2>`xM`FP$cR6zgPN#Bz*z;`k%v1_*Z09+9hqH6~fDS!N=Z-sZ3&I$6orac-E#r zaxE)-@$-^6HzshXZ1}z&-7}Y-ougtj?ZEA_bln2(m3jR0_*yo|nQwAENap-`TfaBn z(10&srpjJAIWdqU*1NUnlBh&(oWi?EjO_&m)AadUCF9dK_Na^whD*Ompt6L0`PC4xhS+iC3?~1A`e~(%USe4TR!*dShb! zww>$SH0RThSi_r#cem|1mKjUz9p1mU&2Ws(ewtRX!B4nGt}M=*0K?OBnOQ9_Fp0yL zPq0+gdA3a)%FL;`g;F#hS?P;6*Wp~4CQLv@)OS;jL6$}I=OUz6s42apgw&LIDJYf8rIJk((-YYvy(M9}PAVChK6ZR=)5K&Z+ZzqZt>*YJ z)2~=jTtXwTfBUvwyJ(DhtBd98#whJ|Z=1-n&Nlr!N&&qq61|}!5Ub<{=$_A>?CCBo zlpCb*cE}mC%*uym1_wh0luGaQXM1`>K{+Xv7&#_8xGW%-50*16vdY_j9ZyepVnw1m z;FqH`BB0x_&yy=yIQaybW@38g_#DkP#aE10GqZGrM58=dj165!rsukw zkthS3PrX9XeRCBp|Af3mi}738{ogOaj{gcc|9dx@LVeO7rEf`3f@jbxr2WzgN~AoA zQeSl=Jtx7<0&>LTNrdO62*K{E(7Y6dgd|GlrSM~1Q_Ls=0lpq`brHq;{eC`vMWL^J z5MrSWN(C9rTSDwZiWLQm;PV8reR`%Z$oK;Dh6lE*J#yD2qigk(h`j;I2G>*1R}MV( zVbze|ms~?5XUcY_PivlCM;wt{?E`+;y0$2O?1<|sFJ%t|7R7Fl@hT5xh8UX^Hho%k zw?}-d>`R`vV8o4y8KdZNtZ)_qVGCM;C(LP*Ettw$$Rs>jcKd8WRMJBB;YnHo1^5P9 zlHZhs*I%&tzfvgLv#y>BfjUy>)jvc+?3LrXIw}GxN1apu5Q(riA?p&p z&48Pq7!&Sb9t<(tS zk%swOwWfL0vC7$58m`P=45#n3v4V*SoDVl=8L~K3^d1)Y!h|Wuq@cR>yc`2%VzC_u)6id8bTK=nG7*D4@^$ht*!}YkxY1{XwBg_3=K<(Gt_A)S7FfPaZrEIIx+pwr z{&sZYdIl0O-`3F}H>``A3C-W5rXM5Yz|qsSR376`ubJnCp>F_l%e!VXhqB$3Nx9!V zIcgdW^$Zr((`nWnF!4Mxp6wmzuaj$c*6JNk{llUBsM38Jgt^+jM0cXQI6>#~HfF}s zC%4axXL`f6FiTptX(BT@z87vE&vy5BHPp!4EtC@C!L>dcFyxS*h`BQK7kV6dw_FOI@MpsOt}jsm~Gt2Hl+NdJ zi^K2nbT#G0;gjXA#=JPZgmf*-i^GF)M+0!Mx$4>UbT&OUH!(9kPl=K@E`?#PI!0w{ zO$!gV4>*UZto=uykzn=zJ>b!QfOzo>_!hhi7Xr|I&J+u5SnF%pOf!S2*0p9Hwr_G& zYllY0%bj^){TdKLrz{pN#5rlPc8JP=NsC3xuuog8T}>sx5Pi`S>=PGVsl3Ww<&q^` ztMcNgh{wBD=EYGSi**g=#jzwB?Hb67BOZx#_2>#>o9@z-Ft z{{h?#YyBTam!ob#y^f!5>U&smo8mZJS+-K!!?2R>NTC0VP8XgYrcQ>3>%i}X)8$>M z!D1|8Yug?S2o=*ueGDrOXdEGj4Ka$NDCJGrx~YR1eiDpHub304)hv*e>N^%<-xY!@@1!qiK!s<3_C*UYA8iQsAG3V5)R zWeGb=$Vf}`utMFrQgk|adYHNbR-F- ze1&)ZPrd)^bzJ=2sJ%`tz&&3V7M!o;pT;fWyLeGf-PtR^GR2RL9bBsTv9W{0%3)l4 z$EQp=x@QNM@^ADAEBAldYqm1w{I4Bcs+<H^QqX)@TmH4(B3@RH>vgYN{?Ti6HqH~39(=6@BA{{QyQ zF1Csy3c$NtkXE3(m+&VR+;&F=xlpb}p+M=D_5$Tsu}~01OUpm>s>iw~L@LkIzlqC_49B8eIvd;$R_sFCnuG@h9~yK`rDX8lQsM(=%SntQ)Jd(Q68 znX_}wo`r6I=ggzwH z5<*!I>nK6iLuv|xgizLlI!cg5)D#8@p)5~F39`!66b1>QtWq5%$a2*b1_`082XvGm zYlxb{AR&}BSV!f`@=AjFU%u|e5p=%>5+n@@hFPK{Vf^od3_xAM5a|B@1$6z`1M7g} ztiI+g$O9gMPM`D4QPAb{3Oo;xF#e|p`;=E8sP?ws9z^!uGz|pWI}nesk5{jUY`-T) z|5JlQD!UuWNlejExrd8PR#TFb$m%FTR-KxXoJ6gT5@bzMQ<9UY(NTgdUrk9)qFP4@ zvL>o2$w^e{C_&Z)H6=NT@j6P7HBL=QPNGsr39`njDalEU(NTh|$JLbNBp%aIxw5>` z!T6W2d(lZ$XrNq4!uY50|CEAK>lf(y`>xdqo&KuencttF-_KiSJ5&N!K=1Es#z)4R z#wN}EKWPcnm&bp18g$rxuTv+-tUmueY1U9i*XeyJzcBCsWJv<$_ItD``Br~3GrUN?tdKS>rRP+(*ID?RTkIYOS%P=Sqs z@&;LyKsi2oL$Xj!vCEL#_;dng`!63GcC57W09l};1RLikP~d*QT=>n|RSQU?hGI5W z|A=R3UIOJrXM3)iV#9;m*pNVhjlB+Cn)&Kf@|2DeY@CxofsM`S_gYV+$dek1+UWRr z9=#`mu_j;lbU;SRd$aYB?Z5P$+wJGmx4l^!C|7lFrXI5Wdw=+KPigma-VDtQN_9fL zA@@h`|EC!Rm!bY|FTDMC5_JE+V_me~hPQt$w#Hh0%$w#}^RT(qY%oWfh49?(DdT{# z9yXCaWQY1d715#32ha8d%Jz#p+pZt)>P@z3s9^Av1iL0%6DY?oLu!kfV)JKoZpe!X zlmhU;Tt^(olho^g%87kc|nHhwqXZjQB~V~v`HkieIx5IY4HeiJy6_bVl;ekId%2ooaS*q0Spo%< z*`?a-XZtf`sgBCEk&b_>;C(j!gKH`OH-7~3N8sOl1W3DjWV5?V?j>GIplpA4rmb^8 z{R%q%yFue`;~n#Y)mqSHY`FWDciUMuu}8m5rf^ql+sdVzp#Ylo2n_4JmbS#d!A@*D zhfL_vue`i)*Sg#d!#eCO;dap%xY@k=Y-7Bmpxe|6?F6$kvb7EF5@<^}l9tHT(Qny5 zY1Uyd9c`Bmx(ucRmOY9OP2PaUf79-CXeXC;X+yiT8$CYkPM$M+rt22PbfcXR>E?9T z=|D)U+qB$u8>eRHWZj~o9G$A*2UO3knN=sMz zYa9^T_o<;j(Sh*~Th9IMvoD-RZqh$<9{K+7%86W7eb0dMa%&swwm5fv3v^CtsbAZ& zvbl-Y1;@TH4hknP_PaZD*&4XEu#2Kwmz`WQcSeJo8J5%krwj7`^!~pL-v0G9^!?gv zt*|CpCFULTBE0Kox49VJ3DC#5X`D3j*wKwURskrf;_8q0Zy8@R@EXA?fEXoek5vFN z#cs*D_I=bxf>B)il#UX#$0~sM9)aT8V--M*61B%F0GVPp+gy9B0#H(1d&~mHDM5Rz z0#H(s_8wFLs9tZ&mXE_r!h<3JC6v2A4{88tA&R^|DycYHh=vjXB}9*CxW?>31ptLq zYi%hX*Y-U~04gDnlnPT?H2+T_)q*^i1o?j@BuGlg|EIzN8ZRgRFX#VKki&%m{08R# z8+iUdKmPOMKU_4;kAJ8z`_GPlRzFAM|ADZa_m|iI^wWRhFC?R$>)5>upLsC(FMDrB z@tFsc|8XjJCLoynS5nc;Lq=%y66Z}!{>!r1S|ZmTlmAMJYmdqQI3;M0$$urqwa4Ut zj1slSwjE(O#Uk=u01CI z1;h8p6N; From b432e34f8937c04e0f97bc0a9a617caac907b3a0 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Wed, 11 Feb 2015 16:48:17 -0600 Subject: [PATCH 120/314] working on custom pragma for enrichment range --- src/enrichment_facility.h | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 224dcc3a63..e957328122 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -289,26 +289,33 @@ class EnrichmentFacility : public cyclus::Facility { "doc": "tails commodity that the enrichment facility supplies", \ "uitype": "outcommodity"} std::string tails_commod; //QQ - #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ "doc": "tails assay from the enrichment process"} double tails_assay; - #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity", \ + #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity (kgSWU/month)", \ "doc": "separative work unit (SWU) capcity of " \ - "enrichment facility"} + "enrichment facility (kgSWU/month)"} double swu_capacity; - #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size", \ - "doc": "maximum inventory capacity of natural uranium in " \ - "the enrichment facility"} + #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size (kg)", \ + "doc": "maximum total inventory of natural uranium in " \ + "the enrichment facility (kg)"} double max_inv_size; #pragma cyclus var {"default": 1.0, "tooltip": "maximum allowed enrichment fraction", \ - "doc": "maximum allowed enrichment fraction of uranium product " \ + "doc": "maximum allowed weight fraction of U235 in product " \ "in the enrichment facility"} ///QQ - double max_enrich; //QQ - #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves", \ + double max_enrich; +#pragma cyclus var {"schema": '"\\n"'\ + '" \\n"' \ + '" \\n"' \ + '" \\n"' \ + '"\\n"'} + + + //QQ + #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves (kg)", \ "doc": "amount of natural uranium stored at the " \ "enrichment facility at the beginning of the " \ - "simulation"} + "simulation (kg)"} double initial_reserves; #pragma cyclus var {'derived_init': 'current_swu_capacity = swu_capacity;'} double current_swu_capacity; From 5ea3596fc3683c2dbd4a6d0aebbb01986e3bf5d4 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Wed, 18 Feb 2015 12:11:52 -0600 Subject: [PATCH 121/314] bug in material pointer --- src/enrichment_facility.cc | 39 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 6cafaa52f1..8564f73f39 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -1,7 +1,3 @@ -/* -How/Where do I check that enrichment limit is a fraction of 1? -*/ - // Implements the EnrichmentFacility class #include "enrichment_facility.h" @@ -19,7 +15,7 @@ EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) : cyclus::Facility(ctx), tails_assay(0), swu_capacity(0), - max_enrich(0), ///QQ is this defaulting to zero? Where to set default? + max_enrich(0), ///QQ initial_reserves(0), in_commod(""), in_recipe(""), @@ -36,7 +32,7 @@ std::string EnrichmentFacility::str() { << " with enrichment facility parameters:" << " * SWU capacity: " << SwuCapacity() << " * Tails assay: " << TailsAssay() - << " * Feed assay: " << FeedAssay() //QQ Remove?? + << " * Feed assay: " << FeedAssay() << " * Input cyclus::Commodity: " << in_commodity() << " * Output cyclus::Commodity: " << out_commodity() << " * Tails cyclus::Commodity: " << tails_commodity(); ///QQ @@ -104,8 +100,6 @@ void EnrichmentFacility::AcceptMatlTrades( AddMat_(it->second); } } - - ///QQ Here is where we check material composition // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - std::set::Ptr> @@ -134,8 +128,8 @@ EnrichmentFacility::GetMatlBids( //QQ // overbidding (bidding on every offer) // add an overall capacity constraint - CapacityConstraint tc(tails.quantity()); - tails_port->AddConstraint(tc); + CapacityConstraint tails_constraint(tails.quantity()); + tails_port->AddConstraint(tails_constraint); LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " adding a tails capacity constraint of " << tails.capacity(); @@ -196,30 +190,28 @@ void EnrichmentFacility::GetMatlTrades( std::vector< Trade >::const_iterator it; for (it = trades.begin(); it != trades.end(); ++it) { - Material::Ptr mat = it->bid->offer(); double qty = it->amt; std::string commod_type = it->bid->request()->commodity() ; Material::Ptr response ; + //QQ Figure out whether material is tails or enriched, // if tails then make transfer of material - - //QQ Need to figure out if the response material is tails or product if (commod_type == tails_commod){ LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " just received an order" << " for " << it->amt << " of " << tails_commod; // Do the material moving - tails.Pop(qty); // remove the qty from the Tails buffer - response = mat; //QQ Correct? + response = tails.Pop(qty); // remove the qty from the Tails buffer + // std::cout << "TAILS" << std::endl ; } else { LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " just received an order" << " for " << it->amt << " of " << out_commod; - - response = Enrich_(mat, qty); + response = Enrich_(it->bid->offer(), qty); } + // std::cout << "adding material to trade " << std::endl ; responses.push_back(std::make_pair(*it, response)); } if (cyclus::IsNegative(tails.quantity())) { @@ -265,6 +257,8 @@ void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " is initially holding " << inventory.quantity() << " total."; + + try { inventory.Push(mat); } catch (cyclus::Error& e) { @@ -310,7 +304,8 @@ cyclus::Material::Ptr EnrichmentFacility::Enrich_( Assays assays(FeedAssay(), UraniumAssay(mat), TailsAssay()); double swu_req = SwuRequired(qty, assays); double natu_req = FeedQty(qty, assays); - + + // NN HERES THE PROBLEM WITH TOO MUCH U239 // pop amount from inventory and blob it into one material Material::Ptr r; try { @@ -332,9 +327,13 @@ cyclus::Material::Ptr EnrichmentFacility::Enrich_( // "enrich" it, but pull out the composition and quantity we require from the // blob - cyclus::Composition::Ptr comp = mat->comp(); - Material::Ptr response = r->ExtractComp(qty, comp); + // std::cout << "Before enrichment tails inventory is " << tails.quantity() << std::endl ; + + cyclus::Composition::Ptr comp = mat->comp(); //requested EF output composition QQ + Material::Ptr response = r->ExtractComp(qty, comp); //r becomes leftovers, should include U239 tails.Push(r); // add remainder to tails buffer + + // std::cout << "After enrichment tails is . . . ." << tails.quantity() << std::endl ; current_swu_capacity -= swu_req; From c3ac3e7c3e3d02f721af561211ebd857e24e18ed Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Wed, 18 Feb 2015 16:53:13 -0600 Subject: [PATCH 122/314] fixed FeedQty so that non-fissile materials are properly accounted for --- src/enrichment_facility.cc | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 8564f73f39..16e35169a2 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -201,9 +201,7 @@ void EnrichmentFacility::GetMatlTrades( << " just received an order" << " for " << it->amt << " of " << tails_commod; - // Do the material moving - response = tails.Pop(qty); // remove the qty from the Tails buffer - // std::cout << "TAILS" << std::endl ; + response = tails.Pop(qty); } else { LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " just received an order" @@ -211,7 +209,6 @@ void EnrichmentFacility::GetMatlTrades( << " of " << out_commod; response = Enrich_(it->bid->offer(), qty); } - // std::cout << "adding material to trade " << std::endl ; responses.push_back(std::make_pair(*it, response)); } if (cyclus::IsNegative(tails.quantity())) { @@ -288,7 +285,7 @@ cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { return cyclus::Material::CreateUntracked( mat->quantity(), cyclus::Composition::CreateFromAtom(comp)); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - cyclus::Material::Ptr EnrichmentFacility::Enrich_( cyclus::Material::Ptr mat, double qty) { @@ -303,9 +300,22 @@ cyclus::Material::Ptr EnrichmentFacility::Enrich_( // get enrichment parameters Assays assays(FeedAssay(), UraniumAssay(mat), TailsAssay()); double swu_req = SwuRequired(qty, assays); - double natu_req = FeedQty(qty, assays); + double fissile_u_req = FeedQty(qty, assays); + + // Determine the composition of the natural uranium + // (ie. does it contain non-fissile materials?) + Material::Ptr natu_matl=inventory.Pop(inventory.quantity()); + inventory.Push(natu_matl); + + // calculate a multiplier to determine actual amount of raw material + // needed to supply the necessary quantities of U-235, U-238 + cyclus::toolkit::MatQuery mq(natu_matl); + double fissile_mass = mq.mass(922350000) + mq.mass(922380000); + double fissile_multiplier = mq.qty()/fissile_mass; - // NN HERES THE PROBLEM WITH TOO MUCH U239 + // fissile_u_req was calculated assuming only fissile materials present + double natu_req = fissile_u_req*fissile_multiplier; + // pop amount from inventory and blob it into one material Material::Ptr r; try { @@ -327,14 +337,10 @@ cyclus::Material::Ptr EnrichmentFacility::Enrich_( // "enrich" it, but pull out the composition and quantity we require from the // blob - // std::cout << "Before enrichment tails inventory is " << tails.quantity() << std::endl ; - - cyclus::Composition::Ptr comp = mat->comp(); //requested EF output composition QQ - Material::Ptr response = r->ExtractComp(qty, comp); //r becomes leftovers, should include U239 - tails.Push(r); // add remainder to tails buffer + cyclus::Composition::Ptr comp = mat->comp(); + Material::Ptr response = r->ExtractComp(qty, comp); + tails.Push(r); - // std::cout << "After enrichment tails is . . . ." << tails.quantity() << std::endl ; - current_swu_capacity -= swu_req; RecordEnrichment_(natu_req, swu_req); From 94b99977e4b4ab1bb59aa2f5e2ecceceea35a592 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Thu, 19 Feb 2015 14:36:00 -0600 Subject: [PATCH 123/314] changed NonFissileMultiplier to be a toolkit fn --- src/enrichment_facility.cc | 15 ++++----------- src/enrichment_facility.h | 21 +++++++-------------- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 16e35169a2..040e84a361 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -303,18 +303,12 @@ cyclus::Material::Ptr EnrichmentFacility::Enrich_( double fissile_u_req = FeedQty(qty, assays); // Determine the composition of the natural uranium - // (ie. does it contain non-fissile materials?) + // (ie. fraction of non-fissile materials) Material::Ptr natu_matl=inventory.Pop(inventory.quantity()); inventory.Push(natu_matl); - // calculate a multiplier to determine actual amount of raw material - // needed to supply the necessary quantities of U-235, U-238 - cyclus::toolkit::MatQuery mq(natu_matl); - double fissile_mass = mq.mass(922350000) + mq.mass(922380000); - double fissile_multiplier = mq.qty()/fissile_mass; - - // fissile_u_req was calculated assuming only fissile materials present - double natu_req = fissile_u_req*fissile_multiplier; + double non_fissile_mult = cyclus::toolkit::NonFissileMultiplier(natu_matl); + double natu_req = fissile_u_req*non_fissile_mult; // pop amount from inventory and blob it into one material Material::Ptr r; @@ -392,8 +386,7 @@ double EnrichmentFacility::FeedAssay() { cyclus::Material::Ptr fission_matl=inventory.Pop(inventory.quantity()); inventory.Push(fission_matl); return cyclus::toolkit::UraniumAssay(fission_matl); -} - +} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - extern "C" cyclus::Agent* ConstructEnrichmentFacility(cyclus::Context* ctx) { return new EnrichmentFacility(ctx); diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index e957328122..b9366b632b 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -6,7 +6,6 @@ #include "cyclus.h" namespace cycamore { - /// @class SWUConverter /// /// @brief The SWUConverter is a simple Converter class for material to @@ -57,7 +56,11 @@ class NatUConverter : public cyclus::Converter { const * ctx = NULL) const { cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), tails_); - return cyclus::toolkit::FeedQty(m->quantity(), assays); + + double fissile_matl = cyclus::toolkit::FeedQty(m->quantity(), assays); + // double non_fissile_mult = 1.0 ; + double non_fissile_mult = cyclus::toolkit::NonFissileMultiplier(m); + return fissile_matl*non_fissile_mult; } /// @returns true if Converter is a NatUConverter and feed and tails equal @@ -245,7 +248,7 @@ class EnrichmentFacility : public cyclus::Facility { inline double InitialReserves() const { return initial_reserves; } inline const cyclus::toolkit::ResBuf& Tails() const { return tails; } - ///QQ relevant to tails buffer (but how?) -- It's not used for anything and can be deleted if we decide to make everything a state variable for testing + ///QQ It's not used for anything and can be deleted if we decide to make everything a state variable for testing private: /// @brief adds a material into the natural uranium inventory @@ -269,10 +272,9 @@ class EnrichmentFacility : public cyclus::Facility { /// @brief calculates the feed assay based on the unenriched inventory double FeedAssay(); - /// @brief records and enrichment with the cyclus::Recorder void RecordEnrichment_(double natural_u, double swu); - + #pragma cyclus var {"tooltip": "input commodity", \ "doc": "commodity that the enrichment facility accepts", \ "uitype": "incommodity"} @@ -319,15 +321,6 @@ class EnrichmentFacility : public cyclus::Facility { double initial_reserves; #pragma cyclus var {'derived_init': 'current_swu_capacity = swu_capacity;'} double current_swu_capacity; - /* //QQ: TO BE DELETED - #pragma cyclus var { \ - 'derived_init': "cyclus::Material::Ptr feed = "\ - "cyclus::Material::CreateUntracked(0, context()->GetRecipe(in_recipe)); "\ - "feed_assay = cyclus::toolkit::UraniumAssay(feed);", \ - "tooltip": "feed assay", \ - "doc": "feed assay for the enrichment process"} - double feed_assay; - */ #pragma cyclus var {'capacity': 'max_inv_size'} cyclus::toolkit::ResBuf inventory; // of natl u From b49e72c414969cc951aa8e90671e39db0a6b4a17 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Thu, 19 Feb 2015 15:38:47 -0600 Subject: [PATCH 124/314] not-working version of limits on max-enrichment --- src/enrichment_facility.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index b9366b632b..9d92c94fce 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -306,13 +306,14 @@ class EnrichmentFacility : public cyclus::Facility { "doc": "maximum allowed weight fraction of U235 in product " \ "in the enrichment facility"} ///QQ double max_enrich; -#pragma cyclus var {"schema": '"\\n"'\ - '" \\n"' \ - '" \\n"' \ - '" \\n"' \ - '"\\n"'} - - + #pragma cyclus var {"schema": '"\\n"' \ + '" \\n"' \ + '" \\n"' \ + '" \\n"' \ + '" \\n"' \ + '" \\n"' \ + '" \\n"' \ + '"\\n"'} //QQ #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves (kg)", \ "doc": "amount of natural uranium stored at the " \ From 951025d2434c44b53d0698a9d272fe81e4bc596a Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Fri, 20 Feb 2015 09:45:11 -0600 Subject: [PATCH 125/314] minor - changed float to double --- src/enrichment_facility.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 9d92c94fce..6e4645b408 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -308,7 +308,7 @@ class EnrichmentFacility : public cyclus::Facility { double max_enrich; #pragma cyclus var {"schema": '"\\n"' \ '" \\n"' \ - '" \\n"' \ + '" \\n"' \ '" \\n"' \ '" \\n"' \ '" \\n"' \ From daaa63b9b855a3bcdc51e57f03959f32dc79e8f1 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Fri, 20 Feb 2015 11:35:02 -0600 Subject: [PATCH 126/314] max_enrich schema still not working --- src/enrichment_facility.h | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 6e4645b408..2b607a2561 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -302,19 +302,20 @@ class EnrichmentFacility : public cyclus::Facility { "doc": "maximum total inventory of natural uranium in " \ "the enrichment facility (kg)"} double max_inv_size; + #pragma cyclus var {"default": 1.0, "tooltip": "maximum allowed enrichment fraction", \ - "doc": "maximum allowed weight fraction of U235 in product " \ - "in the enrichment facility"} ///QQ + "doc": "maximum allowed weight fraction of U235 in product " \ + "in the enrichment facility", \ + "schema": '" \\n"' \ + '" \\n"' \ + '" \\n"' \ + '" \\n"' \ + '" \\n"' \ + '" \\n"' \ + '" \\n"' \ + '"\\n"'} double max_enrich; - #pragma cyclus var {"schema": '"\\n"' \ - '" \\n"' \ - '" \\n"' \ - '" \\n"' \ - '" \\n"' \ - '" \\n"' \ - '" \\n"' \ - '"\\n"'} - //QQ + //QQ #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves (kg)", \ "doc": "amount of natural uranium stored at the " \ "enrichment facility at the beginning of the " \ From cc41508cae34ad4143d0089fee8f06bf5e0ec365 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Fri, 20 Feb 2015 13:54:59 -0600 Subject: [PATCH 127/314] better schema formatting but parser still fails --- src/enrichment_facility.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 2b607a2561..aa41422d69 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -306,14 +306,16 @@ class EnrichmentFacility : public cyclus::Facility { #pragma cyclus var {"default": 1.0, "tooltip": "maximum allowed enrichment fraction", \ "doc": "maximum allowed weight fraction of U235 in product " \ "in the enrichment facility", \ - "schema": '" \\n"' \ - '" \\n"' \ - '" \\n"' \ - '" \\n"' \ - '" \\n"' \ - '" \\n"' \ - '" \\n"' \ - '"\\n"'} + "schema": ' "\\n"\n' \ + ' " \\n"\n' \ + ' " \\n"\n' \ + ' " \\n"\n'\ + ' " \\n"\n'\ + ' " \\n"\n'\ + ' " \\n"\n'\ + ' " \\n"\n'\ + ' " \\n"\n'\ + ' "\\n"\n'} double max_enrich; //QQ #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves (kg)", \ From ce26d796b087f64cfa0411de86d0f03524984198 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 24 Feb 2015 15:39:00 -0600 Subject: [PATCH 128/314] working on trade prefs --- src/#enrichment_facility.h# | 351 ++++++++++++++++++++++++++++++++++++ src/.#enrichment_facility.h | 1 + src/enrichment_facility.cc | 101 ++++++++++- src/enrichment_facility.h | 22 ++- 4 files changed, 469 insertions(+), 6 deletions(-) create mode 100644 src/#enrichment_facility.h# create mode 120000 src/.#enrichment_facility.h diff --git a/src/#enrichment_facility.h# b/src/#enrichment_facility.h# new file mode 100644 index 0000000000..d4c1f890f3 --- /dev/null +++ b/src/#enrichment_facility.h# @@ -0,0 +1,351 @@ +#ifndef CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ +#define CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ + +#include + +#include "cyclus.h" + +namespace cycamore { +/// @class SWUConverter +/// +/// @brief The SWUConverter is a simple Converter class for material to +/// determine the amount of SWU required for their proposed enrichment +class SWUConverter : public cyclus::Converter { + public: + SWUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} + virtual ~SWUConverter() {} + + /// @brief provides a conversion for the SWU required + virtual double convert( + cyclus::Material::Ptr m, + cyclus::Arc const * a = NULL, + cyclus::ExchangeTranslationContext + const * ctx = NULL) const { + cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), + tails_); + return cyclus::toolkit::SwuRequired(m->quantity(), assays); + } + + /// @returns true if Converter is a SWUConverter and feed and tails equal + virtual bool operator==(Converter& other) const { + SWUConverter* cast = dynamic_cast(&other); + return cast != NULL && + feed_ == cast->feed_ && + tails_ == cast->tails_; + } + + private: + double feed_, tails_; +}; + +/// @class NatUConverter +/// +/// @brief The NatUConverter is a simple Converter class for material to +/// determine the amount of natural uranium required for their proposed +/// enrichment +class NatUConverter : public cyclus::Converter { + public: + NatUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} + virtual ~NatUConverter() {} + + /// @brief provides a conversion for the amount of natural Uranium required + virtual double convert( + cyclus::Material::Ptr m, + cyclus::Arc const * a = NULL, + cyclus::ExchangeTranslationContext + const * ctx = NULL) const { + cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), + tails_); + + double fissile_matl = cyclus::toolkit::FeedQty(m->quantity(), assays); + // double non_fissile_mult = 1.0 ; + double non_fissile_mult = cyclus::toolkit::NonFissileMultiplier(m); + return fissile_matl*non_fissile_mult; + } + + /// @returns true if Converter is a NatUConverter and feed and tails equal + virtual bool operator==(Converter& other) const { + NatUConverter* cast = dynamic_cast(&other); + return cast != NULL && + feed_ == cast->feed_ && + tails_ == cast->tails_; + } + + private: + double feed_, tails_; +}; + +/// @class EnrichmentFacility +/// +/// @section introduction Introduction +/// The EnrichmentFacility is a simple Agent to agent the enriching of natural +/// Uranium in a Cyclus simulation. It requests its input recipe (nominally +/// natural Uranium), and produces any amount of enriched Uranium, given the its +/// natural uranium inventory constraint and its SWU capacity constraint. +/// +/// @section requests Requests +/// The EnrichmentFacility will request from the cyclus::ResourceExchange a +/// cyclus::Material whose quantity is its remaining inventory capacity and whose +/// composition is that of its input recipe. +/// +/// @section acctrade Accepting Trades +/// The EnrichmentFacility adds any accepted trades to its inventory. +/// +/// @section bids Bids +/// The EnrichmentFacility will bid on any request for its output commodity. It +/// will bid either the request quantity, or the quanity associated with either +/// its SWU constraint or natural uranium constraint, whichever is lower. +/// +/// @section extrades Executing Trades +/// The EnrichmentFacility will execute trades for its output commodity in the +/// following manner: +/// #. Determine the trade's quantity and product assay +/// #. Determine the natural Uranium and SWU required to create that product +/// #. Remove the required quantity of natural Uranium from its inventory +/// #. Extract the appropriate composition of enriched Uranium +/// #. Send the enriched Uranium as the trade resource +/// +/// @section gotchas Gotchas +/// #. In its current form, the EnrichmentFacility can only accept +/// cyclus::Material having the composition of its input recipe. If a +/// cyclus::Material of a different composition is sent to it, an exception will +/// be thrown. +/// +/// #. During the trading phase, an exception will be thrown if either the +/// EnrichmentFacility's SWU or inventory constraint is breached. +/// +/// @section improvements Improvments +/// The primary improvement to the EnrichmentFacility would be to relax the +/// requirement that all input material have the in_recipe composition (i.e., +/// allow different base enrichments of Uranium). +/// +/// How would I go about doing so? I'd likely develop an EnrichmentBuffer-type +/// class that can be queried as to its SWU and natural Uranium capacity. +class EnrichmentFacility : public cyclus::Facility { + public: + // --- Module Members --- +/// Constructor for the EnrichmentFacility class +/// @param ctx the cyclus context for access to simulation-wide parameters + EnrichmentFacility(cyclus::Context* ctx); + +/// Destructor for the EnrichmentFacility class + virtual ~EnrichmentFacility(); + + #pragma cyclus + + #pragma cyclus note {"doc": "An enrichment facility that intakes a commodity " \ + "(usually natural uranium) and supplies a user-" \ + "specified enriched product based on SWU capacity", \ + "niche": "enrichment"} + +/// Print information about this agent + virtual std::string str(); + // --- + + // --- Facility Members --- + /// perform module-specific tasks when entering the simulation + virtual void Build(cyclus::Agent* parent); + // --- + + // --- Agent Members --- + /// Each facility is prompted to do its beginning-of-time-step + /// stuff at the tick of the timer. + + /// @param time is the time to perform the tick + virtual void Tick(); + + /// Each facility is prompted to its end-of-time-step + /// stuff on the tock of the timer. + + /// @param time is the time to perform the tock + virtual void Tock(); + + /// @brief The EnrichmentFacility request Materials of its given + /// commodity. + virtual std::set::Ptr> + GetMatlRequests(); + + /// @brief The EnrichmentFacility adjusts preferences for offers of + /// natural uranium it has received to maximize U-235 content + /// If any offers have zero U-235 content then they get a preference = 0 + virtual void AdjustMatlPrefs(cyclus::PrefMap::type& prefs); + + /// @brief The EnrichmentFacility place accepted trade Materials in their + /// Inventory + virtual void AcceptMatlTrades( + const std::vector< std::pair, + cyclus::Material::Ptr> >& responses); + + /// @brief Responds to each request for this facility's commodity. If a given + /// request is more than this facility's inventory or SWU capacity, it will + /// offer its minimum of its capacities. + virtual std::set::Ptr> + GetMatlBids(cyclus::CommodMap::type& + commod_requests); + + /// @brief respond to each trade with a material enriched to the appropriate + /// level given this facility's inventory + /// + /// @param trades all trades in which this trader is the supplier + /// @param responses a container to populate with responses to each trade + virtual void GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses); + // --- + + // --- EnrichmentFacility Members --- + /// @brief Determines if a particular material is a valid request to respond + /// to. Valid requests must contain U235 and U238 and must have a relative + /// U235-to-U238 ratio less than this facility's tails_assay(). + /// @return true if the above description is met by the material + bool ValidReq(const cyclus::Material::Ptr mat); + + inline void in_commodity(std::string in_com) { in_commod = in_com; } + + inline std::string in_commodity() const { return in_commod; } + + inline void out_commodity(std::string out_com) { + out_commod = out_com; + } + + inline std::string out_commodity() const { return out_commod; } + + inline void tails_commodity(std::string tails_com) { + tails_commod = tails_com; + } ///QQ + + inline std::string tails_commodity() const { return tails_commod; } ///QQ + + inline void InRecipe(std::string in_rec) { in_recipe = in_rec; } + + inline std::string InRecipe() const { return in_recipe; } + + inline void SetMaxInventorySize(double size) { + max_inv_size = size; + inventory.capacity(size); //QQ + } + + inline double MaxInventorySize() const { return inventory.capacity(); } + + inline double InventorySize() const { return inventory.quantity(); } + //QQ: TO BE DELETED + // inline void FeedAssay(double assay) { feed_assay = assay; } + + inline void TailsAssay(double assay) { tails_assay = assay; } + + inline double TailsAssay() const { return tails_assay; } + + inline void SwuCapacity(double capacity) { + swu_capacity = capacity; + current_swu_capacity = swu_capacity; + } + inline void MaxEnrich(double enrichment) { max_enrich = enrichment; } //QQ + + inline double SwuCapacity() const { return swu_capacity; } + + inline double CurrentSwuCapacity() const { return current_swu_capacity; } + + inline double MaxEnrich() const { return max_enrich; } ///QQ + + /// @brief this facility's initial conditions + inline void InitialReserves(double qty) { initial_reserves = qty; } + inline double InitialReserves() const { return initial_reserves; } + + inline const cyclus::toolkit::ResBuf& Tails() const { return tails; } + ///QQ It's not used for anything and can be deleted if we decide to make everything a state variable for testing + + private: + /// @brief adds a material into the natural uranium inventory + /// @throws if the material is not the same composition as the in_recipe + void AddMat_(cyclus::Material::Ptr mat); + + /// @brief generates a request for this facility given its current state. The + /// quantity of the material will be equal to the remaining inventory size. + cyclus::Material::Ptr Request_(); + + /// @brief Generates a material offer for a given request. The response + /// composition will be comprised only of U235 and U238 at their relative ratio + /// in the requested material. The response quantity will be the same as the + /// requested commodity. + /// + /// @param req the requested material being responded to + cyclus::Material::Ptr Offer_(cyclus::Material::Ptr req); + + cyclus::Material::Ptr Enrich_(cyclus::Material::Ptr mat, double qty); + + /// @brief calculates the feed assay based on the unenriched inventory + double FeedAssay(); + + /// @brief records and enrichment with the cyclus::Recorder + void RecordEnrichment_(double natural_u, double swu); + + #pragma cyclus var {"tooltip": "input commodity", \ + "doc": "commodity that the enrichment facility accepts", \ + "uitype": "incommodity"} + std::string in_commod; + #pragma cyclus var {"tooltip": "output commodity", \ + "doc": "commodity that the enrichment facility supplies", \ + "uitype": "outcommodity"} + std::string out_commod; + #pragma cyclus var {"tooltip": "input commodity recipe", \ + "doc": "recipe for enrichment facility's input commodity", \ + "uitype": "recipe"} + std::string in_recipe; + #pragma cyclus var {"tooltip": "tails commodity", \ + "doc": "tails commodity that the enrichment facility supplies", \ + "uitype": "outcommodity"} + std::string tails_commod; //QQ + #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ + "doc": "tails assay from the enrichment process"} + double tails_assay; + #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity (kgSWU/month)", \ + "doc": "separative work unit (SWU) capcity of " \ + "enrichment facility (kgSWU/month)"} + double swu_capacity; + #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size (kg)", \ + "doc": "maximum total inventory of natural uranium in " \ + "the enrichment facility (kg)"} + double max_inv_size; + /* + #pragma cyclus var {"default": 1.0, "tooltip": "maximum allowed enrichment fraction", \ + "doc": "maximum allowed weight fraction of U235 in product " \ + "in the enrichment facility", \ + "schema": ' "\\n"\n' \ + ' " \\n"\n' \ + ' " \\n"\n' \ + ' " \\n"\n'\ + ' " \\n"\n'\ + ' " \\n"\n'\ + ' " \\n"\n'\ + ' " \\n"\n'\ + ' " \\n"\n'\ + ' "\\n"\n'} + double max_enrich; + //QQ + */ + #pragma cyclus var {"default": 1.0, "tooltip": "maximum allowed enrichment fraction", \ + "doc": "maximum allowed weight fraction of U235 in product " \ + "in the enrichment facility"} + double max_enrich; + + #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves (kg)", \ + "doc": "amount of natural uranium stored at the " \ + "enrichment facility at the beginning of the " \ + "simulation (kg)"} + double initial_reserves; + #pragma cyclus var {'derived_init': 'current_swu_capacity = swu_capacity;'} + double current_swu_capacity; + + #pragma cyclus var {'capacity': 'max_inv_size'} + cyclus::toolkit::ResBuf inventory; // of natl u + #pragma cyclus var {} + cyclus::toolkit::ResBuf tails; // depleted u + + friend class EnrichmentFacilityTest; + // --- +}; + +} // namespace cycamore + +#endif // CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ diff --git a/src/.#enrichment_facility.h b/src/.#enrichment_facility.h new file mode 120000 index 0000000000..4492a262da --- /dev/null +++ b/src/.#enrichment_facility.h @@ -0,0 +1 @@ +mbmcgarry@dragonfly.91293 \ No newline at end of file diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 040e84a361..fc79e17f06 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -88,6 +88,64 @@ EnrichmentFacility::GetMatlRequests() { return ports; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Sort offers of input material to have higher preference for more +// U-235 content +void EnrichmentFacility::AdjustMatlPrefs( + cyclus::PrefMap::type& prefs) { + using cyclus::Bid; + using cyclus::Material; + using cyclus::Request; + + cyclus::PrefMap::type::iterator reqit; + // PrefMap is map of requests and a map of bids and prefs. (, map) + + // Loop over all requests + for (reqit = prefs.begin(); reqit != prefs.end(); ++reqit) { + // Request* req = reqit->first; + std::map* > u235qty_map ; + + // Make a map with U235 qty as key so Bids can be sorted by qty. + std::map*, double>::iterator bidit; + + for (bidit = reqit->second.begin(); bidit != reqit->second.end(); ++bidit) { + cyclus::Material::Ptr mat = bidit->first->offer(); + double u235qty = -1 ; + cyclus::CompMap cm = mat->comp()->atom(); + for (cyclus::CompMap::const_iterator it=cm.begin(); it !=cm.end(); ++it) { + if (pyne::nucname::anum(it->first) == 235){ + u235qty = it->second; + u235qty_map.insert ((* >(u235qty, bidit)) ; + break ; + } + } // each composition element + } // each Bid for the request + + //THIS ISNT WORKING BECAUSE I CANT HAVE DUPLICATE KEYS. + // NEED TO MAKE A VECTOR AND USE THE ALGORITHM SORT FUNCTION INSTEAD. + + double n_bids = prefs->second.count() ; + int bidct = 0 ; + std::map*, double>::iterator qtyit; + //u235qty map is automatically sorted by U-235 content + for (qtyit = u235qty_map.begin();qtyit != u235qty_map.end(); ++qtyit) + { + bidct++ ; + bid = qtyit->second; + if (qtyit->first == 0) { + reqit->second->first.at(bid) = new_pref; + } + else { + double new_pref = (10/n_bids)*(bidct) ; + reqit->second->first.at(bid) = new_pref; + } + std::cout << "U235 = " << qtyit->first << " New pref is " << + reqit->second->first.at(bid) << std::endl; + } // each Bid again + + } // each Material Request +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentFacility::AcceptMatlTrades( const std::vector< std::pair, @@ -112,7 +170,7 @@ EnrichmentFacility::GetMatlBids( using cyclus::Material; using cyclus::Request; - std::set::Ptr> ports; + Std::set::Ptr> ports; //QQ if (out_requests.count(tails_commod) > 0 && tails.quantity() > 0) { BidPortfolio::Ptr tails_port(new BidPortfolio()); //QQ @@ -386,7 +444,46 @@ double EnrichmentFacility::FeedAssay() { cyclus::Material::Ptr fission_matl=inventory.Pop(inventory.quantity()); inventory.Push(fission_matl); return cyclus::toolkit::UraniumAssay(fission_matl); -} +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Sort bids by u-235 content +bool SortBids ( Bid* i, Bid* j) { + cyclus::Material::Ptr mat_i = i->first->offer(); + cyclus::Material::Ptr mat_j = j->first->offer(); + cyclus::CompMap cm_i = mat_i->comp()->atom(); + cyclus::CompMap cm_j = mat_j->comp()->atom(); + double u235_i ; + double u_235_j ; + + // CAN I USE THE COMP MAP FOR A DIRECT LOOKUP INSTEAD OF THIS LOOP? + + for (cyclus::CompMap::const_iterator it=cm_i.begin(); it !=cm_i.end(); ++it) { + if (pyne::nucname::anum(it->first) == 235){ + u235qty = it->second; + u235qty_map.insert ((* >(u235qty, bidit)) ; + break ; + + + + + return (i <= j ); + +} + + + for (bidit = reqit->second.begin(); bidit != reqit->second.end(); ++bidit) { + cyclus::Material::Ptr mat = bidit->first->offer(); + double u235qty = -1 ; + cyclus::CompMap cm = mat->comp()->atom(); + for (cyclus::CompMap::const_iterator it=cm.begin(); it !=cm.end(); ++it) { + if (pyne::nucname::anum(it->first) == 235){ + u235qty = it->second; + u235qty_map.insert ((* >(u235qty, bidit)) ; + break ; + } + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - extern "C" cyclus::Agent* ConstructEnrichmentFacility(cyclus::Context* ctx) { return new EnrichmentFacility(ctx); diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index aa41422d69..7a3cd9346d 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -165,6 +165,11 @@ class EnrichmentFacility : public cyclus::Facility { virtual std::set::Ptr> GetMatlRequests(); + /// @brief The EnrichmentFacility adjusts preferences for offers of + /// natural uranium it has received to maximize U-235 content + /// If any offers have zero U-235 content then they get a preference = 0 + virtual void AdjustMatlPrefs(cyclus::PrefMap::type& prefs); + /// @brief The EnrichmentFacility place accepted trade Materials in their /// Inventory virtual void AcceptMatlTrades( @@ -175,9 +180,9 @@ class EnrichmentFacility : public cyclus::Facility { /// request is more than this facility's inventory or SWU capacity, it will /// offer its minimum of its capacities. virtual std::set::Ptr> - GetMatlBids(cyclus::CommodMap::type& - commod_requests); - + GetMatlBids(cyclus::CommodMap::type& + commod_requests); + /// @brief respond to each trade with a material enriched to the appropriate /// level given this facility's inventory /// @@ -196,6 +201,9 @@ class EnrichmentFacility : public cyclus::Facility { /// @return true if the above description is met by the material bool ValidReq(const cyclus::Material::Ptr mat); + // Sort bids by u-235 content + bool SortBids (int i, int j) {return (i <= j );} + inline void in_commodity(std::string in_com) { in_commod = in_com; } inline std::string in_commodity() const { return in_commod; } @@ -302,7 +310,7 @@ class EnrichmentFacility : public cyclus::Facility { "doc": "maximum total inventory of natural uranium in " \ "the enrichment facility (kg)"} double max_inv_size; - + /* #pragma cyclus var {"default": 1.0, "tooltip": "maximum allowed enrichment fraction", \ "doc": "maximum allowed weight fraction of U235 in product " \ "in the enrichment facility", \ @@ -318,6 +326,12 @@ class EnrichmentFacility : public cyclus::Facility { ' "\\n"\n'} double max_enrich; //QQ + */ + #pragma cyclus var {"default": 1.0, "tooltip": "maximum allowed enrichment fraction", \ + "doc": "maximum allowed weight fraction of U235 in product " \ + "in the enrichment facility"} + double max_enrich; + #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves (kg)", \ "doc": "amount of natural uranium stored at the " \ "enrichment facility at the beginning of the " \ From 6fc569a6de98e81964531e68583e78a6c395f35e Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Wed, 25 Feb 2015 09:44:02 -0600 Subject: [PATCH 129/314] accidentally missed this change yesterday --- src/#enrichment_facility.h# | 351 ------------------------------------ src/.#enrichment_facility.h | 1 - src/enrichment_facility.h | 3 - 3 files changed, 355 deletions(-) delete mode 100644 src/#enrichment_facility.h# delete mode 120000 src/.#enrichment_facility.h diff --git a/src/#enrichment_facility.h# b/src/#enrichment_facility.h# deleted file mode 100644 index d4c1f890f3..0000000000 --- a/src/#enrichment_facility.h# +++ /dev/null @@ -1,351 +0,0 @@ -#ifndef CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ -#define CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ - -#include - -#include "cyclus.h" - -namespace cycamore { -/// @class SWUConverter -/// -/// @brief The SWUConverter is a simple Converter class for material to -/// determine the amount of SWU required for their proposed enrichment -class SWUConverter : public cyclus::Converter { - public: - SWUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} - virtual ~SWUConverter() {} - - /// @brief provides a conversion for the SWU required - virtual double convert( - cyclus::Material::Ptr m, - cyclus::Arc const * a = NULL, - cyclus::ExchangeTranslationContext - const * ctx = NULL) const { - cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), - tails_); - return cyclus::toolkit::SwuRequired(m->quantity(), assays); - } - - /// @returns true if Converter is a SWUConverter and feed and tails equal - virtual bool operator==(Converter& other) const { - SWUConverter* cast = dynamic_cast(&other); - return cast != NULL && - feed_ == cast->feed_ && - tails_ == cast->tails_; - } - - private: - double feed_, tails_; -}; - -/// @class NatUConverter -/// -/// @brief The NatUConverter is a simple Converter class for material to -/// determine the amount of natural uranium required for their proposed -/// enrichment -class NatUConverter : public cyclus::Converter { - public: - NatUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} - virtual ~NatUConverter() {} - - /// @brief provides a conversion for the amount of natural Uranium required - virtual double convert( - cyclus::Material::Ptr m, - cyclus::Arc const * a = NULL, - cyclus::ExchangeTranslationContext - const * ctx = NULL) const { - cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), - tails_); - - double fissile_matl = cyclus::toolkit::FeedQty(m->quantity(), assays); - // double non_fissile_mult = 1.0 ; - double non_fissile_mult = cyclus::toolkit::NonFissileMultiplier(m); - return fissile_matl*non_fissile_mult; - } - - /// @returns true if Converter is a NatUConverter and feed and tails equal - virtual bool operator==(Converter& other) const { - NatUConverter* cast = dynamic_cast(&other); - return cast != NULL && - feed_ == cast->feed_ && - tails_ == cast->tails_; - } - - private: - double feed_, tails_; -}; - -/// @class EnrichmentFacility -/// -/// @section introduction Introduction -/// The EnrichmentFacility is a simple Agent to agent the enriching of natural -/// Uranium in a Cyclus simulation. It requests its input recipe (nominally -/// natural Uranium), and produces any amount of enriched Uranium, given the its -/// natural uranium inventory constraint and its SWU capacity constraint. -/// -/// @section requests Requests -/// The EnrichmentFacility will request from the cyclus::ResourceExchange a -/// cyclus::Material whose quantity is its remaining inventory capacity and whose -/// composition is that of its input recipe. -/// -/// @section acctrade Accepting Trades -/// The EnrichmentFacility adds any accepted trades to its inventory. -/// -/// @section bids Bids -/// The EnrichmentFacility will bid on any request for its output commodity. It -/// will bid either the request quantity, or the quanity associated with either -/// its SWU constraint or natural uranium constraint, whichever is lower. -/// -/// @section extrades Executing Trades -/// The EnrichmentFacility will execute trades for its output commodity in the -/// following manner: -/// #. Determine the trade's quantity and product assay -/// #. Determine the natural Uranium and SWU required to create that product -/// #. Remove the required quantity of natural Uranium from its inventory -/// #. Extract the appropriate composition of enriched Uranium -/// #. Send the enriched Uranium as the trade resource -/// -/// @section gotchas Gotchas -/// #. In its current form, the EnrichmentFacility can only accept -/// cyclus::Material having the composition of its input recipe. If a -/// cyclus::Material of a different composition is sent to it, an exception will -/// be thrown. -/// -/// #. During the trading phase, an exception will be thrown if either the -/// EnrichmentFacility's SWU or inventory constraint is breached. -/// -/// @section improvements Improvments -/// The primary improvement to the EnrichmentFacility would be to relax the -/// requirement that all input material have the in_recipe composition (i.e., -/// allow different base enrichments of Uranium). -/// -/// How would I go about doing so? I'd likely develop an EnrichmentBuffer-type -/// class that can be queried as to its SWU and natural Uranium capacity. -class EnrichmentFacility : public cyclus::Facility { - public: - // --- Module Members --- -/// Constructor for the EnrichmentFacility class -/// @param ctx the cyclus context for access to simulation-wide parameters - EnrichmentFacility(cyclus::Context* ctx); - -/// Destructor for the EnrichmentFacility class - virtual ~EnrichmentFacility(); - - #pragma cyclus - - #pragma cyclus note {"doc": "An enrichment facility that intakes a commodity " \ - "(usually natural uranium) and supplies a user-" \ - "specified enriched product based on SWU capacity", \ - "niche": "enrichment"} - -/// Print information about this agent - virtual std::string str(); - // --- - - // --- Facility Members --- - /// perform module-specific tasks when entering the simulation - virtual void Build(cyclus::Agent* parent); - // --- - - // --- Agent Members --- - /// Each facility is prompted to do its beginning-of-time-step - /// stuff at the tick of the timer. - - /// @param time is the time to perform the tick - virtual void Tick(); - - /// Each facility is prompted to its end-of-time-step - /// stuff on the tock of the timer. - - /// @param time is the time to perform the tock - virtual void Tock(); - - /// @brief The EnrichmentFacility request Materials of its given - /// commodity. - virtual std::set::Ptr> - GetMatlRequests(); - - /// @brief The EnrichmentFacility adjusts preferences for offers of - /// natural uranium it has received to maximize U-235 content - /// If any offers have zero U-235 content then they get a preference = 0 - virtual void AdjustMatlPrefs(cyclus::PrefMap::type& prefs); - - /// @brief The EnrichmentFacility place accepted trade Materials in their - /// Inventory - virtual void AcceptMatlTrades( - const std::vector< std::pair, - cyclus::Material::Ptr> >& responses); - - /// @brief Responds to each request for this facility's commodity. If a given - /// request is more than this facility's inventory or SWU capacity, it will - /// offer its minimum of its capacities. - virtual std::set::Ptr> - GetMatlBids(cyclus::CommodMap::type& - commod_requests); - - /// @brief respond to each trade with a material enriched to the appropriate - /// level given this facility's inventory - /// - /// @param trades all trades in which this trader is the supplier - /// @param responses a container to populate with responses to each trade - virtual void GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses); - // --- - - // --- EnrichmentFacility Members --- - /// @brief Determines if a particular material is a valid request to respond - /// to. Valid requests must contain U235 and U238 and must have a relative - /// U235-to-U238 ratio less than this facility's tails_assay(). - /// @return true if the above description is met by the material - bool ValidReq(const cyclus::Material::Ptr mat); - - inline void in_commodity(std::string in_com) { in_commod = in_com; } - - inline std::string in_commodity() const { return in_commod; } - - inline void out_commodity(std::string out_com) { - out_commod = out_com; - } - - inline std::string out_commodity() const { return out_commod; } - - inline void tails_commodity(std::string tails_com) { - tails_commod = tails_com; - } ///QQ - - inline std::string tails_commodity() const { return tails_commod; } ///QQ - - inline void InRecipe(std::string in_rec) { in_recipe = in_rec; } - - inline std::string InRecipe() const { return in_recipe; } - - inline void SetMaxInventorySize(double size) { - max_inv_size = size; - inventory.capacity(size); //QQ - } - - inline double MaxInventorySize() const { return inventory.capacity(); } - - inline double InventorySize() const { return inventory.quantity(); } - //QQ: TO BE DELETED - // inline void FeedAssay(double assay) { feed_assay = assay; } - - inline void TailsAssay(double assay) { tails_assay = assay; } - - inline double TailsAssay() const { return tails_assay; } - - inline void SwuCapacity(double capacity) { - swu_capacity = capacity; - current_swu_capacity = swu_capacity; - } - inline void MaxEnrich(double enrichment) { max_enrich = enrichment; } //QQ - - inline double SwuCapacity() const { return swu_capacity; } - - inline double CurrentSwuCapacity() const { return current_swu_capacity; } - - inline double MaxEnrich() const { return max_enrich; } ///QQ - - /// @brief this facility's initial conditions - inline void InitialReserves(double qty) { initial_reserves = qty; } - inline double InitialReserves() const { return initial_reserves; } - - inline const cyclus::toolkit::ResBuf& Tails() const { return tails; } - ///QQ It's not used for anything and can be deleted if we decide to make everything a state variable for testing - - private: - /// @brief adds a material into the natural uranium inventory - /// @throws if the material is not the same composition as the in_recipe - void AddMat_(cyclus::Material::Ptr mat); - - /// @brief generates a request for this facility given its current state. The - /// quantity of the material will be equal to the remaining inventory size. - cyclus::Material::Ptr Request_(); - - /// @brief Generates a material offer for a given request. The response - /// composition will be comprised only of U235 and U238 at their relative ratio - /// in the requested material. The response quantity will be the same as the - /// requested commodity. - /// - /// @param req the requested material being responded to - cyclus::Material::Ptr Offer_(cyclus::Material::Ptr req); - - cyclus::Material::Ptr Enrich_(cyclus::Material::Ptr mat, double qty); - - /// @brief calculates the feed assay based on the unenriched inventory - double FeedAssay(); - - /// @brief records and enrichment with the cyclus::Recorder - void RecordEnrichment_(double natural_u, double swu); - - #pragma cyclus var {"tooltip": "input commodity", \ - "doc": "commodity that the enrichment facility accepts", \ - "uitype": "incommodity"} - std::string in_commod; - #pragma cyclus var {"tooltip": "output commodity", \ - "doc": "commodity that the enrichment facility supplies", \ - "uitype": "outcommodity"} - std::string out_commod; - #pragma cyclus var {"tooltip": "input commodity recipe", \ - "doc": "recipe for enrichment facility's input commodity", \ - "uitype": "recipe"} - std::string in_recipe; - #pragma cyclus var {"tooltip": "tails commodity", \ - "doc": "tails commodity that the enrichment facility supplies", \ - "uitype": "outcommodity"} - std::string tails_commod; //QQ - #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ - "doc": "tails assay from the enrichment process"} - double tails_assay; - #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity (kgSWU/month)", \ - "doc": "separative work unit (SWU) capcity of " \ - "enrichment facility (kgSWU/month)"} - double swu_capacity; - #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size (kg)", \ - "doc": "maximum total inventory of natural uranium in " \ - "the enrichment facility (kg)"} - double max_inv_size; - /* - #pragma cyclus var {"default": 1.0, "tooltip": "maximum allowed enrichment fraction", \ - "doc": "maximum allowed weight fraction of U235 in product " \ - "in the enrichment facility", \ - "schema": ' "\\n"\n' \ - ' " \\n"\n' \ - ' " \\n"\n' \ - ' " \\n"\n'\ - ' " \\n"\n'\ - ' " \\n"\n'\ - ' " \\n"\n'\ - ' " \\n"\n'\ - ' " \\n"\n'\ - ' "\\n"\n'} - double max_enrich; - //QQ - */ - #pragma cyclus var {"default": 1.0, "tooltip": "maximum allowed enrichment fraction", \ - "doc": "maximum allowed weight fraction of U235 in product " \ - "in the enrichment facility"} - double max_enrich; - - #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves (kg)", \ - "doc": "amount of natural uranium stored at the " \ - "enrichment facility at the beginning of the " \ - "simulation (kg)"} - double initial_reserves; - #pragma cyclus var {'derived_init': 'current_swu_capacity = swu_capacity;'} - double current_swu_capacity; - - #pragma cyclus var {'capacity': 'max_inv_size'} - cyclus::toolkit::ResBuf inventory; // of natl u - #pragma cyclus var {} - cyclus::toolkit::ResBuf tails; // depleted u - - friend class EnrichmentFacilityTest; - // --- -}; - -} // namespace cycamore - -#endif // CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ diff --git a/src/.#enrichment_facility.h b/src/.#enrichment_facility.h deleted file mode 120000 index 4492a262da..0000000000 --- a/src/.#enrichment_facility.h +++ /dev/null @@ -1 +0,0 @@ -mbmcgarry@dragonfly.91293 \ No newline at end of file diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 7a3cd9346d..d4c1f890f3 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -200,9 +200,6 @@ class EnrichmentFacility : public cyclus::Facility { /// U235-to-U238 ratio less than this facility's tails_assay(). /// @return true if the above description is met by the material bool ValidReq(const cyclus::Material::Ptr mat); - - // Sort bids by u-235 content - bool SortBids (int i, int j) {return (i <= j );} inline void in_commodity(std::string in_com) { in_commod = in_com; } From 8a8f26b0719faafe71f18fa8761266617dc2be67 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Thu, 26 Feb 2015 15:49:57 -0600 Subject: [PATCH 130/314] fixed xml syntax, and everything compiles. Still some logic bugs though. --- src/enrichment_facility.cc | 131 +++++++++++++++---------------------- src/enrichment_facility.h | 23 ++++--- 2 files changed, 62 insertions(+), 92 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index fc79e17f06..057610bb4f 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -5,7 +5,7 @@ #include #include #include - +#include #include namespace cycamore { @@ -88,61 +88,70 @@ EnrichmentFacility::GetMatlRequests() { return ports; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Sort bids by U-235 content +bool SortBids( + cyclus::Bid* i, cyclus::Bid* j) { + + cyclus::Material::Ptr mat_i = i->offer(); + cyclus::Material::Ptr mat_j = j->offer(); + + cyclus::toolkit::MatQuery mq_i(mat_i); + cyclus::toolkit::MatQuery mq_j(mat_j); + + return ((mq_i.mass(922350000)/mq_i.qty()) <= (mq_j.mass(922350000)/mq_j.qty())); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Sort offers of input material to have higher preference for more // U-235 content void EnrichmentFacility::AdjustMatlPrefs( cyclus::PrefMap::type& prefs) { + using cyclus::Bid; using cyclus::Material; using cyclus::Request; cyclus::PrefMap::type::iterator reqit; - // PrefMap is map of requests and a map of bids and prefs. (, map) + // PrefMap is map of requests and a map of bids and prefs: map(, map) // Loop over all requests for (reqit = prefs.begin(); reqit != prefs.end(); ++reqit) { - // Request* req = reqit->first; - std::map* > u235qty_map ; - - // Make a map with U235 qty as key so Bids can be sorted by qty. - std::map*, double>::iterator bidit; - - for (bidit = reqit->second.begin(); bidit != reqit->second.end(); ++bidit) { - cyclus::Material::Ptr mat = bidit->first->offer(); - double u235qty = -1 ; - cyclus::CompMap cm = mat->comp()->atom(); - for (cyclus::CompMap::const_iterator it=cm.begin(); it !=cm.end(); ++it) { - if (pyne::nucname::anum(it->first) == 235){ - u235qty = it->second; - u235qty_map.insert ((* >(u235qty, bidit)) ; - break ; - } - } // each composition element - } // each Bid for the request + // std::map* , double> bids_map = reqit->second ; + + std::vector* > bids_vector; + std::map*, double>::iterator mit; + for (mit = reqit->second.begin(); mit != reqit->second.end(); ++mit) { + Bid* bid = mit->first; + bids_vector.push_back(bid) ; + } + + std::sort (bids_vector.begin(), bids_vector.end(), SortBids); - //THIS ISNT WORKING BECAUSE I CANT HAVE DUPLICATE KEYS. - // NEED TO MAKE A VECTOR AND USE THE ALGORITHM SORT FUNCTION INSTEAD. + // Assign preferences to the sorted vector + double n_bids = bids_vector.size() ; + + // std::vector* >::iterator bidit; + // for (bidit=bids_vector.begin(); bidit!=bids_vector.end(); ++bidit) { + for (int bidit=0 ; bidit < bids_vector.size(); bidit++) { + int new_pref = bidit ; - double n_bids = prefs->second.count() ; - int bidct = 0 ; - std::map*, double>::iterator qtyit; - //u235qty map is automatically sorted by U-235 content - for (qtyit = u235qty_map.begin();qtyit != u235qty_map.end(); ++qtyit) - { - bidct++ ; - bid = qtyit->second; - if (qtyit->first == 0) { - reqit->second->first.at(bid) = new_pref; - } - else { - double new_pref = (10/n_bids)*(bidct) ; - reqit->second->first.at(bid) = new_pref; + // If u-235 qty of smallest item is 0, set pref to zero. + // if (bidct == 0) { + cyclus::Material::Ptr mat = bids_vector[bidit]->offer(); + cyclus::toolkit::MatQuery mq(mat); + // new_pref = (mq_i.mass(922350000) == 0) ? 0 : 1 ; + // new_pref = (mq.mass(922350000) == 0) ? 0 : (bidit) ; + if (mq.mass(922350000) == 0) { + new_pref = 0; } - std::cout << "U235 = " << qtyit->first << " New pref is " << - reqit->second->first.at(bid) << std::endl; - } // each Bid again - + + (reqit->second)[bids_vector[bidit]] = new_pref; + + std::cout << "U235 = " << mq.mass(922350000) << " New pref is " << + (reqit->second)[bids_vector[bidit]] << std::endl; + + } // each bid } // each Material Request } @@ -170,7 +179,7 @@ EnrichmentFacility::GetMatlBids( using cyclus::Material; using cyclus::Request; - Std::set::Ptr> ports; + std::set::Ptr> ports; //QQ if (out_requests.count(tails_commod) > 0 && tails.quantity() > 0) { BidPortfolio::Ptr tails_port(new BidPortfolio()); //QQ @@ -445,45 +454,7 @@ double EnrichmentFacility::FeedAssay() { inventory.Push(fission_matl); return cyclus::toolkit::UraniumAssay(fission_matl); } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Sort bids by u-235 content -bool SortBids ( Bid* i, Bid* j) { - cyclus::Material::Ptr mat_i = i->first->offer(); - cyclus::Material::Ptr mat_j = j->first->offer(); - cyclus::CompMap cm_i = mat_i->comp()->atom(); - cyclus::CompMap cm_j = mat_j->comp()->atom(); - double u235_i ; - double u_235_j ; - - // CAN I USE THE COMP MAP FOR A DIRECT LOOKUP INSTEAD OF THIS LOOP? - - for (cyclus::CompMap::const_iterator it=cm_i.begin(); it !=cm_i.end(); ++it) { - if (pyne::nucname::anum(it->first) == 235){ - u235qty = it->second; - u235qty_map.insert ((* >(u235qty, bidit)) ; - break ; - - - - - return (i <= j ); - -} - - - for (bidit = reqit->second.begin(); bidit != reqit->second.end(); ++bidit) { - cyclus::Material::Ptr mat = bidit->first->offer(); - double u235qty = -1 ; - cyclus::CompMap cm = mat->comp()->atom(); - for (cyclus::CompMap::const_iterator it=cm.begin(); it !=cm.end(); ++it) { - if (pyne::nucname::anum(it->first) == 235){ - u235qty = it->second; - u235qty_map.insert ((* >(u235qty, bidit)) ; - break ; - } - - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - extern "C" cyclus::Agent* ConstructEnrichmentFacility(cyclus::Context* ctx) { return new EnrichmentFacility(ctx); diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index d4c1f890f3..759e907b7f 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -277,7 +277,7 @@ class EnrichmentFacility : public cyclus::Facility { /// @brief calculates the feed assay based on the unenriched inventory double FeedAssay(); - /// @brief records and enrichment with the cyclus::Recorder + /// @brief records and enrichment with the cyclus::Recorder void RecordEnrichment_(double natural_u, double swu); #pragma cyclus var {"tooltip": "input commodity", \ @@ -307,28 +307,27 @@ class EnrichmentFacility : public cyclus::Facility { "doc": "maximum total inventory of natural uranium in " \ "the enrichment facility (kg)"} double max_inv_size; - /* + #pragma cyclus var {"default": 1.0, "tooltip": "maximum allowed enrichment fraction", \ "doc": "maximum allowed weight fraction of U235 in product " \ "in the enrichment facility", \ "schema": ' "\\n"\n' \ - ' " \\n"\n' \ - ' " \\n"\n' \ - ' " \\n"\n'\ - ' " \\n"\n'\ - ' " \\n"\n'\ - ' " \\n"\n'\ - ' " \\n"\n'\ - ' " \\n"\n'\ + ' " \\n"\n' \ + ' " \\n"\n ' \ + ' " 0\\n"\n'\ + ' " 1\\n"\n'\ + ' " \\n"\n ' \ + ' " \\n"\n' \ ' "\\n"\n'} double max_enrich; //QQ - */ + + /* #pragma cyclus var {"default": 1.0, "tooltip": "maximum allowed enrichment fraction", \ "doc": "maximum allowed weight fraction of U235 in product " \ "in the enrichment facility"} double max_enrich; - + */ #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves (kg)", \ "doc": "amount of natural uranium stored at the " \ "enrichment facility at the beginning of the " \ From 2d7e12b433071c676ca592454ea201038ae38b70 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Fri, 27 Feb 2015 10:41:54 -0600 Subject: [PATCH 131/314] preference sorting works --- src/enrichment_facility.cc | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 057610bb4f..2f167f2960 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -99,7 +99,8 @@ bool SortBids( cyclus::toolkit::MatQuery mq_i(mat_i); cyclus::toolkit::MatQuery mq_j(mat_j); - return ((mq_i.mass(922350000)/mq_i.qty()) <= (mq_j.mass(922350000)/mq_j.qty())); + return ((mq_i.mass(922350000)/mq_i.qty()) <= + (mq_j.mass(922350000)/mq_j.qty())); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -113,11 +114,9 @@ void EnrichmentFacility::AdjustMatlPrefs( using cyclus::Request; cyclus::PrefMap::type::iterator reqit; - // PrefMap is map of requests and a map of bids and prefs: map(, map) // Loop over all requests for (reqit = prefs.begin(); reqit != prefs.end(); ++reqit) { - // std::map* , double> bids_map = reqit->second ; std::vector* > bids_vector; std::map*, double>::iterator mit; @@ -125,34 +124,26 @@ void EnrichmentFacility::AdjustMatlPrefs( Bid* bid = mit->first; bids_vector.push_back(bid) ; } - + std::sort (bids_vector.begin(), bids_vector.end(), SortBids); // Assign preferences to the sorted vector double n_bids = bids_vector.size() ; - // std::vector* >::iterator bidit; - // for (bidit=bids_vector.begin(); bidit!=bids_vector.end(); ++bidit) { for (int bidit=0 ; bidit < bids_vector.size(); bidit++) { - int new_pref = bidit ; + int new_pref = bidit+1 ; // If u-235 qty of smallest item is 0, set pref to zero. - // if (bidct == 0) { - cyclus::Material::Ptr mat = bids_vector[bidit]->offer(); + if (bidit == 0) { + cyclus::Material::Ptr mat = bids_vector[bidit]->offer(); cyclus::toolkit::MatQuery mq(mat); - // new_pref = (mq_i.mass(922350000) == 0) ? 0 : 1 ; - // new_pref = (mq.mass(922350000) == 0) ? 0 : (bidit) ; - if (mq.mass(922350000) == 0) { - new_pref = 0; - } - + new_pref = (mq.mass(922350000) == 0) ? -1 : (new_pref) ; + } + (reqit->second)[bids_vector[bidit]] = new_pref; - - std::cout << "U235 = " << mq.mass(922350000) << " New pref is " << - (reqit->second)[bids_vector[bidit]] << std::endl; - } // each bid } // each Material Request + std::cout << "end of request" << std::endl; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From bfc21b02d750633c1de0a34e6565ccd65432bd82 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Fri, 27 Feb 2015 16:53:51 -0600 Subject: [PATCH 132/314] removed NonFissileMultiplier function calls and replaced with multi_mass_frac. Fixed bug in preference-setting for zero mass. Started documentation updates. --- src/enrichment_facility.cc | 38 ++++++++++++++---------- src/enrichment_facility.h | 61 ++++++++++++++++++++++---------------- 2 files changed, 58 insertions(+), 41 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 2f167f2960..cecb96d798 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -102,7 +102,6 @@ bool SortBids( return ((mq_i.mass(922350000)/mq_i.qty()) <= (mq_j.mass(922350000)/mq_j.qty())); } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Sort offers of input material to have higher preference for more // U-235 content @@ -130,16 +129,21 @@ void EnrichmentFacility::AdjustMatlPrefs( // Assign preferences to the sorted vector double n_bids = bids_vector.size() ; + bool finite_mass = 0 ; for (int bidit=0 ; bidit < bids_vector.size(); bidit++) { int new_pref = bidit+1 ; // If u-235 qty of smallest item is 0, set pref to zero. - if (bidit == 0) { + if (!finite_mass) { cyclus::Material::Ptr mat = bids_vector[bidit]->offer(); cyclus::toolkit::MatQuery mq(mat); - new_pref = (mq.mass(922350000) == 0) ? -1 : (new_pref) ; + if (mq.mass(922350000) == 0) { + new_pref = -1; + } + else { + finite_mass = TRUE; + } } - (reqit->second)[bids_vector[bidit]] = new_pref; } // each bid } // each Material Request @@ -358,29 +362,33 @@ cyclus::Material::Ptr EnrichmentFacility::Enrich_( // get enrichment parameters Assays assays(FeedAssay(), UraniumAssay(mat), TailsAssay()); double swu_req = SwuRequired(qty, assays); - double fissile_u_req = FeedQty(qty, assays); + double natu_req = FeedQty(qty, assays); // Determine the composition of the natural uranium // (ie. fraction of non-fissile materials) Material::Ptr natu_matl=inventory.Pop(inventory.quantity()); inventory.Push(natu_matl); - - double non_fissile_mult = cyclus::toolkit::NonFissileMultiplier(natu_matl); - double natu_req = fissile_u_req*non_fissile_mult; + cyclus::toolkit::MatQuery mq(natu_matl); + std::set nucs ; + nucs.insert(922350000); + nucs.insert(922380000); + double natu_frac = mq.multi_mass_frac(nucs); + double feed_req = natu_req/natu_frac; + // pop amount from inventory and blob it into one material Material::Ptr r; try { // required so popping doesn't take out too much - if (cyclus::AlmostEq(natu_req, inventory.quantity())) { + if (cyclus::AlmostEq(feed_req, inventory.quantity())) { r = cyclus::toolkit::Squash(inventory.PopN(inventory.count())); } else { - r = inventory.Pop(natu_req); + r = inventory.Pop(feed_req); } } catch (cyclus::Error& e) { NatUConverter nc(FeedAssay(), tails_assay); std::stringstream ss; - ss << " tried to remove " << natu_req + ss << " tried to remove " << feed_req << " from its inventory of size " << inventory.quantity() << " and the conversion of the material into natu is " << nc.convert(mat); @@ -395,12 +403,12 @@ cyclus::Material::Ptr EnrichmentFacility::Enrich_( current_swu_capacity -= swu_req; - RecordEnrichment_(natu_req, swu_req); + RecordEnrichment_(feed_req, swu_req); LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " has performed an enrichment: "; LOG(cyclus::LEV_INFO5, "EnrFac") << " * Feed Qty: " - << natu_req; + << feed_req; LOG(cyclus::LEV_INFO5, "EnrFac") << " * Feed Assay: " << assays.Feed() * 100; LOG(cyclus::LEV_INFO5, "EnrFac") << " * Product Qty: " @@ -445,8 +453,8 @@ double EnrichmentFacility::FeedAssay() { inventory.Push(fission_matl); return cyclus::toolkit::UraniumAssay(fission_matl); } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - extern "C" cyclus::Agent* ConstructEnrichmentFacility(cyclus::Context* ctx) { return new EnrichmentFacility(ctx); } diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 759e907b7f..075d87f615 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -6,6 +6,7 @@ #include "cyclus.h" namespace cycamore { + /// @class SWUConverter /// /// @brief The SWUConverter is a simple Converter class for material to @@ -57,10 +58,14 @@ class NatUConverter : public cyclus::Converter { cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), tails_); - double fissile_matl = cyclus::toolkit::FeedQty(m->quantity(), assays); - // double non_fissile_mult = 1.0 ; - double non_fissile_mult = cyclus::toolkit::NonFissileMultiplier(m); - return fissile_matl*non_fissile_mult; + cyclus::toolkit::MatQuery mq(m); + std::set nucs ; + nucs.insert(922350000); + nucs.insert(922380000); + + double natu_frac = mq.multi_mass_frac(nucs); + double natu_req = cyclus::toolkit::FeedQty(m->quantity(), assays); + return natu_req/natu_frac; } /// @returns true if Converter is a NatUConverter and feed and tails equal @@ -75,6 +80,9 @@ class NatUConverter : public cyclus::Converter { double feed_, tails_; }; + +/// NEW DOC GOES HERE + /// @class EnrichmentFacility /// /// @section introduction Introduction @@ -85,8 +93,11 @@ class NatUConverter : public cyclus::Converter { /// /// @section requests Requests /// The EnrichmentFacility will request from the cyclus::ResourceExchange a -/// cyclus::Material whose quantity is its remaining inventory capacity and whose -/// composition is that of its input recipe. +/// cyclus::Material whose quantity is its remaining inventory capacity. +/// All material compositions with U-235 content < the EnrichmentFacility +/// output recipe will be accepted, with higher U-235 fraction preferred up +/// to the U-235 fraction of the output bids. Bids with U-235 fraction=0 +/// or greater than output bid are not accepted. /// /// @section acctrade Accepting Trades /// The EnrichmentFacility adds any accepted trades to its inventory. @@ -95,6 +106,7 @@ class NatUConverter : public cyclus::Converter { /// The EnrichmentFacility will bid on any request for its output commodity. It /// will bid either the request quantity, or the quanity associated with either /// its SWU constraint or natural uranium constraint, whichever is lower. +/// The EnrichmentFacility also offers its Tails as an additional output commodity. /// /// @section extrades Executing Trades /// The EnrichmentFacility will execute trades for its output commodity in the @@ -102,33 +114,30 @@ class NatUConverter : public cyclus::Converter { /// #. Determine the trade's quantity and product assay /// #. Determine the natural Uranium and SWU required to create that product /// #. Remove the required quantity of natural Uranium from its inventory +/// (this quantity is adjusted if it contains components other than U-235 +/// and U-238 so that the correct ratio of U-235/U-235+U-238 is provided) /// #. Extract the appropriate composition of enriched Uranium +/// #. Send all remaining material to the tails inventory /// #. Send the enriched Uranium as the trade resource /// -/// @section gotchas Gotchas -/// #. In its current form, the EnrichmentFacility can only accept -/// cyclus::Material having the composition of its input recipe. If a -/// cyclus::Material of a different composition is sent to it, an exception will -/// be thrown. -/// -/// #. During the trading phase, an exception will be thrown if either the -/// EnrichmentFacility's SWU or inventory constraint is breached. -/// -/// @section improvements Improvments -/// The primary improvement to the EnrichmentFacility would be to relax the -/// requirement that all input material have the in_recipe composition (i.e., -/// allow different base enrichments of Uranium). +/// #. During the trading phase, an exception will be thrown if either the +/// EnrichmentFacility's SWU or inventory constraint is breached. /// -/// How would I go about doing so? I'd likely develop an EnrichmentBuffer-type -/// class that can be queried as to its SWU and natural Uranium capacity. class EnrichmentFacility : public cyclus::Facility { +#pragma cyclus note { \ + "niche": "enrichment facility", \ + "doc": \ + "TODO:Copy documentation here, with " \ + "\n\n" \ + "to separate paragraphs." ,\ +} public: // --- Module Members --- -/// Constructor for the EnrichmentFacility class -/// @param ctx the cyclus context for access to simulation-wide parameters + /// Constructor for the EnrichmentFacility class + /// @param ctx the cyclus context for access to simulation-wide parameters EnrichmentFacility(cyclus::Context* ctx); -/// Destructor for the EnrichmentFacility class + /// Destructor for the EnrichmentFacility class virtual ~EnrichmentFacility(); #pragma cyclus @@ -138,7 +147,7 @@ class EnrichmentFacility : public cyclus::Facility { "specified enriched product based on SWU capacity", \ "niche": "enrichment"} -/// Print information about this agent + /// Print information about this agent virtual std::string str(); // --- @@ -167,7 +176,7 @@ class EnrichmentFacility : public cyclus::Facility { /// @brief The EnrichmentFacility adjusts preferences for offers of /// natural uranium it has received to maximize U-235 content - /// If any offers have zero U-235 content then they get a preference = 0 + /// Any offers that have zero U-235 content are not accepted virtual void AdjustMatlPrefs(cyclus::PrefMap::type& prefs); /// @brief The EnrichmentFacility place accepted trade Materials in their From 77d8c65a56a09bd3af7e1cb55882505d775de376 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 3 Mar 2015 12:07:11 -0600 Subject: [PATCH 133/314] documentation --- src/enrichment_facility.cc | 8 +- src/enrichment_facility.h | 156 ++++++++++++++++++++----------------- 2 files changed, 88 insertions(+), 76 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index cecb96d798..2523ca5c28 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -129,19 +129,19 @@ void EnrichmentFacility::AdjustMatlPrefs( // Assign preferences to the sorted vector double n_bids = bids_vector.size() ; - bool finite_mass = 0 ; + bool u235_mass = 0 ; for (int bidit=0 ; bidit < bids_vector.size(); bidit++) { int new_pref = bidit+1 ; - // If u-235 qty of smallest item is 0, set pref to zero. - if (!finite_mass) { + // For any bids with U-235 qty=0, set pref to zero. + if (!u235_mass) { cyclus::Material::Ptr mat = bids_vector[bidit]->offer(); cyclus::toolkit::MatQuery mq(mat); if (mq.mass(922350000) == 0) { new_pref = -1; } else { - finite_mass = TRUE; + u235_mass = TRUE; } } (reqit->second)[bids_vector[bidit]] = new_pref; diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 075d87f615..8b3bfa46ba 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -80,57 +80,73 @@ class NatUConverter : public cyclus::Converter { double feed_, tails_; }; +/// EnrichmentFacility is a simple Agent that enriches natural +/// uranium in a Cyclus simulation. It does not explicitly compute +/// the physical enrichment process, rather it calculates the SWU +/// required to convert an source uranium recipe (ie. natural uranium) +/// into a requested enriched recipe (ie. 4% enriched uranium), given +/// the natural uranium inventory constraint and its SWU capacity +/// constraint. + +/// Enrichment Facility requests an input commodity and associated recipe +/// whose quantity is its remaining inventory capacity. All facilities +/// trading the same input commodity (even with different recipes) will +/// offer materials for trade. The Enrichment Facility accepts any input +/// materials with enrichments less than its tails assay, as long as some +/// U235 is present, and preference increases with U235 content. If no +/// U235 is present in the offered material, the trade preference is set +/// to -1 and the material is not accepted. Any material components other +/// other than U235 and U238 are sent directly to the tails buffer. + +/// EnrichmentFacility will bid on any request for its output commodity +/// up to the maximum allowed enrichment (if not specified, default is 100%) +/// It bids on either the request quantity, or the maximum quanity allowed +/// by its SWU constraint or natural uranium inventory, whichever is lower. +/// If multiple output commodities with different enrichment levels are +/// requested and the facility does not have the SWU or quantity capacity +/// to meet all requests, the requests are fully, then partially filled +/// in unspecified but repeatable order. + +/// EnrichmentFacility also offers its tails as an output commodity with +/// no associated recipe. Bids for tails are constrained only by total +/// tails inventory. -/// NEW DOC GOES HERE - -/// @class EnrichmentFacility -/// -/// @section introduction Introduction -/// The EnrichmentFacility is a simple Agent to agent the enriching of natural -/// Uranium in a Cyclus simulation. It requests its input recipe (nominally -/// natural Uranium), and produces any amount of enriched Uranium, given the its -/// natural uranium inventory constraint and its SWU capacity constraint. -/// -/// @section requests Requests -/// The EnrichmentFacility will request from the cyclus::ResourceExchange a -/// cyclus::Material whose quantity is its remaining inventory capacity. -/// All material compositions with U-235 content < the EnrichmentFacility -/// output recipe will be accepted, with higher U-235 fraction preferred up -/// to the U-235 fraction of the output bids. Bids with U-235 fraction=0 -/// or greater than output bid are not accepted. -/// -/// @section acctrade Accepting Trades -/// The EnrichmentFacility adds any accepted trades to its inventory. -/// -/// @section bids Bids -/// The EnrichmentFacility will bid on any request for its output commodity. It -/// will bid either the request quantity, or the quanity associated with either -/// its SWU constraint or natural uranium constraint, whichever is lower. -/// The EnrichmentFacility also offers its Tails as an additional output commodity. -/// -/// @section extrades Executing Trades -/// The EnrichmentFacility will execute trades for its output commodity in the -/// following manner: -/// #. Determine the trade's quantity and product assay -/// #. Determine the natural Uranium and SWU required to create that product -/// #. Remove the required quantity of natural Uranium from its inventory -/// (this quantity is adjusted if it contains components other than U-235 -/// and U-238 so that the correct ratio of U-235/U-235+U-238 is provided) -/// #. Extract the appropriate composition of enriched Uranium -/// #. Send all remaining material to the tails inventory -/// #. Send the enriched Uranium as the trade resource -/// -/// #. During the trading phase, an exception will be thrown if either the -/// EnrichmentFacility's SWU or inventory constraint is breached. -/// class EnrichmentFacility : public cyclus::Facility { #pragma cyclus note { \ "niche": "enrichment facility", \ "doc": \ - "TODO:Copy documentation here, with " \ - "\n\n" \ - "to separate paragraphs." ,\ + "EnrichmentFacility is a simple Agent that enriches natural" \ + "uranium in a Cyclus simulation. It does not explicitly compute" \ + "the physical enrichment process, rather it calculates the SWU" \ + "required to convert an source uranium recipe (ie. natural uranium)" \ + "into a requested enriched recipe (ie. 4% enriched uranium), given" \ + "the natural uranium inventory constraint and its SWU capacity" \ + "constraint." \ + "\n\n"\ + "Enrichment Facility requests an input commodity and associated recipe" \ + "whose quantity is its remaining inventory capacity. All facilities" \ + "trading the same input commodity (even with different recipes) will" \ + "offer materials for trade. The Enrichment Facility accepts any input" \ + "materials with enrichments less than its tails assay, as long as some" \ + "U235 is present, and preference increases with U235 content. If no" \ + "U235 is present in the offered material, the trade preference is set" \ + "to -1 and the material is not accepted. Any material components other" \ + "other than U235 and U238 are sent directly to the tails buffer." \ + "\n\n"\ + "EnrichmentFacility will bid on any request for its output commodity" \ + "up to the maximum allowed enrichment (if not specified, default is 100%)" \ + "It bids on either the request quantity, or the maximum quanity allowed" \ + "by its SWU constraint or natural uranium inventory, whichever is lower." \ + "If multiple output commodities with different enrichment levels are" \ + "requested and the facility does not have the SWU or quantity capacity" \ + "to meet all requests, the requests are fully, then partially filled" \ + "in unspecified but repeatable order." \ + "\n\n"\ + "EnrichmentFacility also offers its tails as an output commodity with" \ + "no associated recipe. Bids for tails are constrained only by total" \ + "tails inventory.", \ } + public: // --- Module Members --- /// Constructor for the EnrichmentFacility class @@ -238,8 +254,6 @@ class EnrichmentFacility : public cyclus::Facility { inline double MaxInventorySize() const { return inventory.capacity(); } inline double InventorySize() const { return inventory.quantity(); } - //QQ: TO BE DELETED - // inline void FeedAssay(double assay) { feed_assay = assay; } inline void TailsAssay(double assay) { tails_assay = assay; } @@ -249,19 +263,22 @@ class EnrichmentFacility : public cyclus::Facility { swu_capacity = capacity; current_swu_capacity = swu_capacity; } - inline void MaxEnrich(double enrichment) { max_enrich = enrichment; } //QQ inline double SwuCapacity() const { return swu_capacity; } inline double CurrentSwuCapacity() const { return current_swu_capacity; } + inline void MaxEnrich(double enrichment) { max_enrich = enrichment; } //QQ + inline double MaxEnrich() const { return max_enrich; } ///QQ /// @brief this facility's initial conditions inline void InitialReserves(double qty) { initial_reserves = qty; } inline double InitialReserves() const { return initial_reserves; } - inline const cyclus::toolkit::ResBuf& Tails() const { return tails; } + inline const cyclus::toolkit::ResBuf& Tails() const { + return tails; + } ///QQ It's not used for anything and can be deleted if we decide to make everything a state variable for testing private: @@ -269,14 +286,14 @@ class EnrichmentFacility : public cyclus::Facility { /// @throws if the material is not the same composition as the in_recipe void AddMat_(cyclus::Material::Ptr mat); - /// @brief generates a request for this facility given its current state. The - /// quantity of the material will be equal to the remaining inventory size. + /// @brief generates a request for this facility given its current state. + /// Quantity of the material will be equal to remaining inventory size. cyclus::Material::Ptr Request_(); /// @brief Generates a material offer for a given request. The response - /// composition will be comprised only of U235 and U238 at their relative ratio - /// in the requested material. The response quantity will be the same as the - /// requested commodity. + /// composition will be comprised only of U235 and U238 at their relative + /// ratio in the requested material. The response quantity will be the + /// same as the requested commodity. /// /// @param req the requested material being responded to cyclus::Material::Ptr Offer_(cyclus::Material::Ptr req); @@ -298,28 +315,30 @@ class EnrichmentFacility : public cyclus::Facility { "uitype": "outcommodity"} std::string out_commod; #pragma cyclus var {"tooltip": "input commodity recipe", \ - "doc": "recipe for enrichment facility's input commodity", \ + "doc": "recipe for enrichment facility input commodity", \ "uitype": "recipe"} std::string in_recipe; #pragma cyclus var {"tooltip": "tails commodity", \ - "doc": "tails commodity that the enrichment facility supplies", \ + "doc": "tails commodity supplied by enrichment facility",\ "uitype": "outcommodity"} std::string tails_commod; //QQ #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ "doc": "tails assay from the enrichment process"} double tails_assay; - #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity (kgSWU/month)", \ - "doc": "separative work unit (SWU) capcity of " \ + #pragma cyclus var {"default": 1e299, \ + "tooltip": "SWU capacity (kgSWU/month)", \ + "doc": "separative work unit (SWU) capacity of " \ "enrichment facility (kgSWU/month)"} double swu_capacity; - #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size (kg)", \ + #pragma cyclus var {"default": 1e299, "tooltip": "max inventory size (kg)", \ "doc": "maximum total inventory of natural uranium in " \ - "the enrichment facility (kg)"} + "the enrichment facility (kg)"} double max_inv_size; - #pragma cyclus var {"default": 1.0, "tooltip": "maximum allowed enrichment fraction", \ - "doc": "maximum allowed weight fraction of U235 in product " \ - "in the enrichment facility", \ + #pragma cyclus var {"default": 1.0, \ + "tooltip": "maximum allowed enrichment fraction",\ + "doc": "maximum allowed weight fraction of U235 " \ + "in product ", \ "schema": ' "\\n"\n' \ ' " \\n"\n' \ ' " \\n"\n ' \ @@ -331,13 +350,7 @@ class EnrichmentFacility : public cyclus::Facility { double max_enrich; //QQ - /* - #pragma cyclus var {"default": 1.0, "tooltip": "maximum allowed enrichment fraction", \ - "doc": "maximum allowed weight fraction of U235 in product " \ - "in the enrichment facility"} - double max_enrich; - */ - #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves (kg)", \ + #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves (kg)",\ "doc": "amount of natural uranium stored at the " \ "enrichment facility at the beginning of the " \ "simulation (kg)"} @@ -346,12 +359,11 @@ class EnrichmentFacility : public cyclus::Facility { double current_swu_capacity; #pragma cyclus var {'capacity': 'max_inv_size'} - cyclus::toolkit::ResBuf inventory; // of natl u + cyclus::toolkit::ResBuf inventory; // natural u #pragma cyclus var {} cyclus::toolkit::ResBuf tails; // depleted u friend class EnrichmentFacilityTest; - // --- }; } // namespace cycamore From 81509cde9b864e492a165211308e1da278bd7246 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 3 Mar 2015 14:44:35 -0600 Subject: [PATCH 134/314] flag for preference ordering --- src/enrichment_facility.cc | 5 +++++ src/enrichment_facility.h | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 2523ca5c28..f8491d2782 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -17,6 +17,7 @@ EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) swu_capacity(0), max_enrich(0), ///QQ initial_reserves(0), + order_prefs(0), in_commod(""), in_recipe(""), out_commod(""), @@ -112,6 +113,10 @@ void EnrichmentFacility::AdjustMatlPrefs( using cyclus::Material; using cyclus::Request; + if (!order_prefs){ + return ; + } + cyclus::PrefMap::type::iterator reqit; // Loop over all requests diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 8b3bfa46ba..5fac860729 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -355,8 +355,16 @@ class EnrichmentFacility : public cyclus::Facility { "enrichment facility at the beginning of the " \ "simulation (kg)"} double initial_reserves; + #pragma cyclus var {"default": 1,\ + "userlevel": 10, \ + "tooltip": "order material requests by U235 content",\ + "doc": "turn on preference ordering for input material "\ + "so that EF chooses higher U235 content first"} + + bool order_prefs; #pragma cyclus var {'derived_init': 'current_swu_capacity = swu_capacity;'} double current_swu_capacity; + #pragma cyclus var {'capacity': 'max_inv_size'} cyclus::toolkit::ResBuf inventory; // natural u From 554ee5713fdd1bc36df5e1b4e41eb752c737bafa Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Wed, 4 Mar 2015 16:40:27 -0600 Subject: [PATCH 135/314] added tests for new features. Some old tests are still broken --- src/enrichment_facility.cc | 6 +- src/enrichment_facility_tests.cc | 309 +++++++++++++++++++++++++++++-- src/enrichment_facility_tests.h | 6 +- 3 files changed, 295 insertions(+), 26 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index f8491d2782..a455460a58 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -17,7 +17,7 @@ EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) swu_capacity(0), max_enrich(0), ///QQ initial_reserves(0), - order_prefs(0), + order_prefs(0), //QQ in_commod(""), in_recipe(""), out_commod(""), @@ -315,13 +315,9 @@ void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { cyclus::Warn("Non-uranium elements are " \ "sent directly to tails."); } - /// TODO: Add FAIL if non-235/238 quantities are too large - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " is initially holding " << inventory.quantity() << " total."; - - try { inventory.Push(mat); diff --git a/src/enrichment_facility_tests.cc b/src/enrichment_facility_tests.cc index 98f8bf4cb1..d71c7fef73 100644 --- a/src/enrichment_facility_tests.cc +++ b/src/enrichment_facility_tests.cc @@ -11,7 +11,257 @@ #include "enrichment_facility_tests.h" +using cyclus::QueryResult; +using cyclus::Cond; +using cyclus::CompMap; +using cyclus::toolkit::MatQuery; +using pyne::nucname::id; +using cyclus::Material; + namespace cycamore { + +Composition::Ptr c_nou235() { + cyclus::CompMap m; + m[922380000] = 1.0; + return Composition::CreateFromMass(m); +}; +Composition::Ptr c_natu1() { + cyclus::CompMap m; + m[922350000] = 0.007; + m[922380000] = 0.993; + return Composition::CreateFromMass(m); +}; +Composition::Ptr c_natu2() { + cyclus::CompMap m; + m[922350000] = 0.01; + m[922380000] = 0.99; + return Composition::CreateFromMass(m); +}; +Composition::Ptr c_leu() { + cyclus::CompMap m; + m[922350000] = 0.04; + m[922380000] = 0.96; + return Composition::CreateFromMass(m); +}; +Composition::Ptr c_heu() { + cyclus::CompMap m; + m[922350000] = 0.20; + m[922380000] = 0.80; + return Composition::CreateFromMass(m); +}; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, RequestEnrich) { + // this tests verifies that requests for material exceeding the maximum + // allowed enrichment are not fulfilled. + + std::string config = + " natu " + " natu1 " + " enr_u " + " tails " + " 0.003 " + " 0.20 " ; + + int simdur = 2; + cyclus::MockSim sim(cyclus::AgentSpec + (":cycamore:EnrichmentFacility"), config, simdur); + sim.AddRecipe("natu1", c_natu1()) ; + sim.AddRecipe("leu", c_leu()) ; + sim.AddRecipe("heu", c_heu()) ; + + sim.AddSource("natu") + .recipe("natu1") + .Finalize(); + sim.AddSink("enr_u") + .recipe("leu") + .Finalize(); + sim.AddSink("enr_u") + .recipe("heu") + .Finalize(); + + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==",std::string("enr_u"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + + // Should be only one transaction out of the EF, + // and it should be LEU + EXPECT_EQ(1.0, qr.rows.size()); + + Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); + CompMap got = m->comp()->mass(); + CompMap want = c_leu()->mass(); + cyclus::compmath::Normalize(&got); + cyclus::compmath::Normalize(&want); + + CompMap::iterator it; + for (it = want.begin(); it != want.end(); ++it) { + EXPECT_DOUBLE_EQ(it->second, got[it->first]) << + "nuclide qty off: " << pyne::nucname::name(it->first); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, TradeTails) { + // this tests whether tails are being traded. + + std::string config = + " natu " + " natu1 " + " enr_u " + " tails " + " 0.003 " ; + + //QQ - should tails buffer be available for trades on timestep 2? + int simdur = 3 ;// 1-source to EF, 2-EF process, 3-add to tails inventory + cyclus::MockSim sim(cyclus::AgentSpec + (":cycamore:EnrichmentFacility"), config, simdur); + sim.AddRecipe("natu1", c_natu1()) ; + sim.AddRecipe("leu", c_leu()) ; + + sim.AddSource("natu") + .recipe("natu1") + .Finalize(); + sim.AddSink("enr_u") + .recipe("leu") + .Finalize(); + sim.AddSink("tails") + .Finalize(); + + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==",std::string("tails"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + + // Should be exactly one tails transaction + EXPECT_EQ(1, qr.rows.size()); + +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, BidPrefs) { + // This tests that natu sources are preference-ordered by + // U235 content + + std::string config = + " natu " + " natu1 " + " enr_u " + " tails " + " 0.003 " + " 1.0 " ; + + int simdur = 1; + cyclus::MockSim sim(cyclus::AgentSpec + (":cycamore:EnrichmentFacility"), config, simdur); + sim.AddRecipe("natu1", c_natu1()) ; + sim.AddRecipe("natu2", c_natu2()) ; + + sim.AddSource("natu") + .recipe("natu1") + .capacity(1) + .Finalize(); + + sim.AddSource("natu") + .recipe("natu2") + .capacity(1) + .Finalize(); + + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==",std::string("natu"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + + // should trade only with #2 since it has higher U235 + EXPECT_EQ(1, qr.rows.size()); + + Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); + CompMap got = m->comp()->mass(); + CompMap want = c_natu2()->mass(); + cyclus::compmath::Normalize(&got); + cyclus::compmath::Normalize(&want); + + CompMap::iterator it; + for (it = want.begin(); it != want.end(); ++it) { + EXPECT_DOUBLE_EQ(it->second, got[it->first]) << + "nuclide qty off: " << pyne::nucname::name(it->first); + } + +} +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, NoBidPrefs) { + // This tests that preference-ordering for sources + // turns off correctly if flag is used + + std::string config = + " natu " + " natu1 " + " enr_u " + " tails " + " 0.003 " + " 2.0 " ; + " 0 " ; + + int simdur = 1; + cyclus::MockSim sim(cyclus::AgentSpec + (":cycamore:EnrichmentFacility"), config, simdur); + sim.AddRecipe("natu1", c_natu1()) ; + sim.AddRecipe("natu2", c_natu2()) ; + + sim.AddSource("natu") + .recipe("natu1") + .capacity(1) + .Finalize(); + + sim.AddSource("natu") + .recipe("natu2") + .capacity(1) + .Finalize(); + + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==",std::string("natu"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + + // should trade with both to meet its capacity limit + EXPECT_EQ(2, qr.rows.size()); + } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, ZeroU235) { + // Test that offers of natu with no u235 content are rejected + + std::string config = + " natu " + " natu1 " + " enr_u " + " tails " + " 0.003 " + " 1.0 " ; + + int simdur = 1; + cyclus::MockSim sim(cyclus::AgentSpec + (":cycamore:EnrichmentFacility"), config, simdur); + sim.AddRecipe("no_u235", c_nou235()) ; + sim.AddRecipe("natu1", c_natu1()) ; + + sim.AddSource("natu") + .recipe("no_u235") + .capacity(1) + .Finalize(); + + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==",std::string("natu"))); + // DB table should be empty since there are no transactions + EXPECT_THROW(sim.db().Query("Transactions", &conds), + std::exception); +} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentFacilityTest::SetUp() { @@ -34,6 +284,7 @@ void EnrichmentFacilityTest::InitParameters() { in_commod = "incommod"; out_commod = "outcommod"; + tails_commod = "tailscommod"; in_recipe = "recipe"; feed_assay = 0.0072; @@ -56,8 +307,9 @@ void EnrichmentFacilityTest::SetUpSource() { src_facility->InRecipe(in_recipe); src_facility->in_commodity(in_commod); src_facility->out_commodity(out_commod); + src_facility->tails_commodity(tails_commod); src_facility->TailsAssay(tails_assay); - // src_facility->FeedAssay(feed_assay); + src_facility->MaxEnrich(max_enrich); src_facility->SetMaxInventorySize(inv_size); src_facility->SwuCapacity(swu_capacity); src_facility->InitialReserves(reserves); @@ -106,11 +358,12 @@ TEST_F(EnrichmentFacilityTest, InitialState) { EXPECT_EQ(in_recipe, src_facility->InRecipe()); EXPECT_EQ(in_commod, src_facility->in_commodity()); EXPECT_EQ(out_commod, src_facility->out_commodity()); + EXPECT_EQ(tails_commod, src_facility->tails_commodity()); //QQ -fixed EXPECT_DOUBLE_EQ(tails_assay, src_facility->TailsAssay()); - // EXPECT_DOUBLE_EQ(feed_assay, src_facility->FeedAssay()); EXPECT_DOUBLE_EQ(inv_size, src_facility->MaxInventorySize()); EXPECT_DOUBLE_EQ(0.0, src_facility->InventorySize()); EXPECT_DOUBLE_EQ(swu_capacity, src_facility->SwuCapacity()); + EXPECT_DOUBLE_EQ(max_enrich, src_facility->MaxEnrich()); //QQ -fixed EXPECT_EQ(reserves, src_facility->InitialReserves()); } @@ -128,8 +381,10 @@ TEST_F(EnrichmentFacilityTest, DISABLED_XMLInit) { << " " << " " << " " << out_commod << "" + << " " << tails_commod << "" //QQ-fixed << " " << tails_assay << "" << " " << swu_capacity << "" + << " " << max_enrich << "" //QQ-fixed << " " << " " << " " << reserves << "" @@ -147,11 +402,12 @@ TEST_F(EnrichmentFacilityTest, DISABLED_XMLInit) { EXPECT_EQ(in_recipe, fac.InRecipe()); EXPECT_EQ(in_commod, fac.in_commodity()); EXPECT_EQ(out_commod, fac.out_commodity()); + EXPECT_EQ(tails_commod, fac.tails_commodity()); //QQ--fixed EXPECT_DOUBLE_EQ(tails_assay, fac.TailsAssay()); - // EXPECT_DOUBLE_EQ(feed_assay, fac.FeedAssay()); EXPECT_DOUBLE_EQ(inv_size, fac.MaxInventorySize()); EXPECT_DOUBLE_EQ(0.0, fac.InventorySize()); EXPECT_DOUBLE_EQ(swu_capacity, fac.SwuCapacity()); + EXPECT_DOUBLE_EQ(max_enrich, fac.MaxEnrich()); //QQ--fixed EXPECT_EQ(reserves, fac.InitialReserves()); } @@ -165,11 +421,13 @@ TEST_F(EnrichmentFacilityTest, Clone) { EXPECT_EQ(in_recipe, cloned_fac->InRecipe()); EXPECT_EQ(in_commod, cloned_fac->in_commodity()); EXPECT_EQ(out_commod, cloned_fac->out_commodity()); + EXPECT_EQ(tails_commod, cloned_fac->tails_commodity()); //QQ--fixed EXPECT_DOUBLE_EQ(tails_assay, cloned_fac->TailsAssay()); // EXPECT_DOUBLE_EQ(feed_assay, cloned_fac->FeedAssay()); EXPECT_DOUBLE_EQ(inv_size, cloned_fac->MaxInventorySize()); EXPECT_DOUBLE_EQ(0.0, cloned_fac->InventorySize()); EXPECT_DOUBLE_EQ(swu_capacity, cloned_fac->SwuCapacity()); + EXPECT_DOUBLE_EQ(max_enrich, cloned_fac->MaxEnrich()); //QQ-fixed EXPECT_EQ(reserves, cloned_fac->InitialReserves()); delete cloned_fac; @@ -177,10 +435,11 @@ TEST_F(EnrichmentFacilityTest, Clone) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TEST_F(EnrichmentFacilityTest, AddMat) { - EXPECT_THROW(DoAddMat(test_helpers::get_mat()), cyclus::ValueError); + //QQ - GetMat->AddMat_ is failing when pushing material to inventory. Why? Not set up? + // EXPECT_THROW(DoAddMat(test_helpers::get_mat()), cyclus::ValueError); EXPECT_THROW(DoAddMat(GetMat(inv_size + 1)), cyclus::Error); - EXPECT_NO_THROW(DoAddMat(GetMat(inv_size))); - EXPECT_THROW(DoAddMat(GetMat(1)), cyclus::Error); + EXPECT_NO_THROW(DoAddMat(GetMat(inv_size))); + // EXPECT_THROW(DoAddMat(GetMat(1)), cyclus::Error); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -207,7 +466,7 @@ TEST_F(EnrichmentFacilityTest, Request) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, Offer) { + TEST_F(EnrichmentFacilityTest, Offer) { using cyclus::CompMap; using cyclus::Composition; using cyclus::Material; @@ -389,19 +648,22 @@ TEST_F(EnrichmentFacilityTest, AddBids) { EXPECT_EQ(ports.size(), 1); BidPortfolio::Ptr port = *ports.begin(); - EXPECT_EQ(port->bidder(), src_facility); - EXPECT_EQ(port->bids().size(), nvalid); + //QQ src_facility failing b/c of GetMat->AddMat_ ? + // EXPECT_EQ(port->bidder(), src_facility); + + //QQ bids().size=0, but nvalid=4 -->src_facility isn't working? + // EXPECT_EQ(port->bids().size(), nvalid); const std::set< CapacityConstraint >& constrs = port->constraints(); - Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); - Converter::Ptr nc(new NatUConverter(feed_assay, tails_assay)); + Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); //QQ + Converter::Ptr nc(new NatUConverter(feed_assay, tails_assay)); //QQ CapacityConstraint swu(swu_capacity, sc); CapacityConstraint natu(current_size, nc); EXPECT_EQ(constrs.size(), 2); EXPECT_TRUE(*constrs.begin() == swu || *(++constrs.begin()) == swu); EXPECT_TRUE(*constrs.begin() == natu || *(++constrs.begin()) == natu); } - + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - boost::shared_ptr< cyclus::ExchangeContext > EnrichmentFacilityTest::GetContext(int nreqs, int nvalid) { @@ -418,8 +680,7 @@ EnrichmentFacilityTest::GetContext(int nreqs, int nvalid) { } for (int i = 0; i < nreqs - nvalid; i++) { ec->AddRequest( - // get_mat returns a material of only u235, which is not valid - Request::Create(get_mat(), trader, out_commod)); + Request::Create(get_mat(), trader, out_commod)); } return ec; } @@ -436,6 +697,7 @@ TEST_F(EnrichmentFacilityTest, BidConverters) { using cyclus::toolkit::UraniumAssay; using cyclus::toolkit::SwuRequired; using cyclus::toolkit::FeedQty; + using cyclus::toolkit::MatQuery; cyclus::Env::SetNucDataPath(); double qty = 5; // 5 kg @@ -447,13 +709,20 @@ TEST_F(EnrichmentFacilityTest, BidConverters) { Material::Ptr target = Material::CreateUntracked( qty, Composition::CreateFromMass(v)); + std::set nucs ; + nucs.insert(922350000); + nucs.insert(922380000); + + MatQuery mq(target) ; + double mass_frac = mq.multi_mass_frac(nucs); + SWUConverter swuc(feed_assay, tails_assay); NatUConverter natuc(feed_assay, tails_assay); Material::Ptr offer = DoOffer(target); EXPECT_NEAR(swuc.convert(target), swuc.convert(offer), 0.001); - EXPECT_NEAR(natuc.convert(target), natuc.convert(offer), 0.001); + EXPECT_NEAR(natuc.convert(target)*mass_frac, natuc.convert(offer), 0.001); //QQ fixed } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -536,6 +805,7 @@ TEST_F(EnrichmentFacilityTest, Response) { double qty = 5; // 5 kg double trade_qty = qty / 3; double product_assay = 0.05; // of 5 w/o enriched U + cyclus::CompMap v; v[922350000] = product_assay; v[922380000] = 1 - product_assay; @@ -546,10 +816,10 @@ TEST_F(EnrichmentFacilityTest, Response) { Assays assays(feed_assay, UraniumAssay(target), tails_assay); double swu_req = SwuRequired(qty, assays); double natu_req = FeedQty(qty, assays); - + src_facility->SetMaxInventorySize(natu_req * 4); // not capacitated by nat u src_facility->SwuCapacity(swu_req); // swu capacitated - + // Null response src_facility->GetMatlTrades(trades, responses); EXPECT_NO_THROW(); @@ -564,10 +834,10 @@ TEST_F(EnrichmentFacilityTest, Response) { Trade trade(req, bid, trade_qty); trades.push_back(trade); - // 1 trade, SWU < SWU cap + // 1 allowed trade, SWU < SWU cap ASSERT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_req); src_facility->GetMatlTrades(trades, responses); - ASSERT_EQ(responses.size(), 1); + ASSERT_EQ(responses.size(), 1); EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_req - SwuRequired(trade_qty, assays)); @@ -592,6 +862,7 @@ TEST_F(EnrichmentFacilityTest, Response) { EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_req); } + } // namespace cycamore // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/enrichment_facility_tests.h b/src/enrichment_facility_tests.h index c771bdd86d..b2c95ba19d 100644 --- a/src/enrichment_facility_tests.h +++ b/src/enrichment_facility_tests.h @@ -19,12 +19,14 @@ class EnrichmentFacilityTest : public ::testing::Test { protected: cyclus::TestContext tc_; EnrichmentFacility* src_facility; - std::string in_commod, out_commod, in_recipe; + std::string in_commod, out_commod, in_recipe, tails_commod; cyclus::Composition::Ptr recipe; TestFacility* trader; - double tails_assay, feed_assay, inv_size, commodity_price, swu_capacity; + double feed_assay, tails_assay, inv_size, commodity_price, swu_capacity, max_enrich; + bool order_prefs; + double reserves; virtual void SetUp(); From 96e78cadd0f654169fbf7612322b0bf223732363 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Thu, 5 Mar 2015 15:50:15 -0600 Subject: [PATCH 136/314] more test editing --- src/enrichment_facility.cc | 12 +- src/enrichment_facility.h | 1 - src/enrichment_facility_tests.cc | 218 +++---------------------------- 3 files changed, 26 insertions(+), 205 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index a455460a58..571426cc40 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -15,13 +15,9 @@ EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) : cyclus::Facility(ctx), tails_assay(0), swu_capacity(0), - max_enrich(0), ///QQ + max_enrich(1), ///QQ initial_reserves(0), - order_prefs(0), //QQ - in_commod(""), - in_recipe(""), - out_commod(""), - tails_commod(""){} ///QQ + order_prefs(true){} //QQ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EnrichmentFacility::~EnrichmentFacility() {} @@ -219,6 +215,10 @@ EnrichmentFacility::GetMatlBids( Material::Ptr offer = Offer_(req->target()); commod_port->AddBid(req, offer, this); } + else { + std::cout<< request_enrich << " , " << max_enrich << "\n" ; + } + } Converter::Ptr sc(new SWUConverter(FeedAssay(), tails_assay)); Converter::Ptr nc(new NatUConverter(FeedAssay(), tails_assay)); diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 5fac860729..da5f323ec9 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -219,7 +219,6 @@ class EnrichmentFacility : public cyclus::Facility { cyclus::Material::Ptr> >& responses); // --- - // --- EnrichmentFacility Members --- /// @brief Determines if a particular material is a valid request to respond /// to. Valid requests must contain U235 and U238 and must have a relative /// U235-to-U238 ratio less than this facility's tails_assay(). diff --git a/src/enrichment_facility_tests.cc b/src/enrichment_facility_tests.cc index d71c7fef73..44488eb175 100644 --- a/src/enrichment_facility_tests.cc +++ b/src/enrichment_facility_tests.cc @@ -353,95 +353,6 @@ EnrichmentFacilityTest::DoEnrich(cyclus::Material::Ptr mat, double qty) { return src_facility->Enrich_(mat, qty); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, InitialState) { - EXPECT_EQ(in_recipe, src_facility->InRecipe()); - EXPECT_EQ(in_commod, src_facility->in_commodity()); - EXPECT_EQ(out_commod, src_facility->out_commodity()); - EXPECT_EQ(tails_commod, src_facility->tails_commodity()); //QQ -fixed - EXPECT_DOUBLE_EQ(tails_assay, src_facility->TailsAssay()); - EXPECT_DOUBLE_EQ(inv_size, src_facility->MaxInventorySize()); - EXPECT_DOUBLE_EQ(0.0, src_facility->InventorySize()); - EXPECT_DOUBLE_EQ(swu_capacity, src_facility->SwuCapacity()); - EXPECT_DOUBLE_EQ(max_enrich, src_facility->MaxEnrich()); //QQ -fixed - EXPECT_EQ(reserves, src_facility->InitialReserves()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, DISABLED_XMLInit) { - std::stringstream ss; - ss << "" - << "fooname" - << "" - << "" - << " " - << " " << in_commod << "" - << " " << in_recipe << "" - << " " << inv_size << "" - << " " - << " " - << " " << out_commod << "" - << " " << tails_commod << "" //QQ-fixed - << " " << tails_assay << "" - << " " << swu_capacity << "" - << " " << max_enrich << "" //QQ-fixed - << " " - << " " - << " " << reserves << "" - << " " - << "" - << "" - << ""; - - cyclus::XMLParser p; - p.Init(ss); - cyclus::InfileTree engine(p); - cycamore::EnrichmentFacility fac(tc_.get()); - - // EXPECT_NO_THROW(fac.InitFrom(&engine);); - EXPECT_EQ(in_recipe, fac.InRecipe()); - EXPECT_EQ(in_commod, fac.in_commodity()); - EXPECT_EQ(out_commod, fac.out_commodity()); - EXPECT_EQ(tails_commod, fac.tails_commodity()); //QQ--fixed - EXPECT_DOUBLE_EQ(tails_assay, fac.TailsAssay()); - EXPECT_DOUBLE_EQ(inv_size, fac.MaxInventorySize()); - EXPECT_DOUBLE_EQ(0.0, fac.InventorySize()); - EXPECT_DOUBLE_EQ(swu_capacity, fac.SwuCapacity()); - EXPECT_DOUBLE_EQ(max_enrich, fac.MaxEnrich()); //QQ--fixed - EXPECT_EQ(reserves, fac.InitialReserves()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, Clone) { - cyclus::Context* ctx = tc_.get(); - - cycamore::EnrichmentFacility* cloned_fac = - dynamic_cast(src_facility->Clone()); - - EXPECT_EQ(in_recipe, cloned_fac->InRecipe()); - EXPECT_EQ(in_commod, cloned_fac->in_commodity()); - EXPECT_EQ(out_commod, cloned_fac->out_commodity()); - EXPECT_EQ(tails_commod, cloned_fac->tails_commodity()); //QQ--fixed - EXPECT_DOUBLE_EQ(tails_assay, cloned_fac->TailsAssay()); - // EXPECT_DOUBLE_EQ(feed_assay, cloned_fac->FeedAssay()); - EXPECT_DOUBLE_EQ(inv_size, cloned_fac->MaxInventorySize()); - EXPECT_DOUBLE_EQ(0.0, cloned_fac->InventorySize()); - EXPECT_DOUBLE_EQ(swu_capacity, cloned_fac->SwuCapacity()); - EXPECT_DOUBLE_EQ(max_enrich, cloned_fac->MaxEnrich()); //QQ-fixed - EXPECT_EQ(reserves, cloned_fac->InitialReserves()); - - delete cloned_fac; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, AddMat) { - //QQ - GetMat->AddMat_ is failing when pushing material to inventory. Why? Not set up? - // EXPECT_THROW(DoAddMat(test_helpers::get_mat()), cyclus::ValueError); - EXPECT_THROW(DoAddMat(GetMat(inv_size + 1)), cyclus::Error); - EXPECT_NO_THROW(DoAddMat(GetMat(inv_size))); - // EXPECT_THROW(DoAddMat(GetMat(1)), cyclus::Error); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TEST_F(EnrichmentFacilityTest, Request) { double req = inv_size; @@ -466,32 +377,7 @@ TEST_F(EnrichmentFacilityTest, Request) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TEST_F(EnrichmentFacilityTest, Offer) { - using cyclus::CompMap; - using cyclus::Composition; - using cyclus::Material; - using cyclus::toolkit::MatQuery; - - double qty = 4.5; - double u234 = 1.0; - double u235 = 1.0; - double u238 = 2.0; - cyclus::CompMap v; - v[94239] = u234; - v[922350000] = u235; - v[922380000] = u238; - Material::Ptr mat = - DoOffer(Material::CreateUntracked(qty, Composition::CreateFromAtom(v))); - - MatQuery q(mat); - - EXPECT_DOUBLE_EQ(q.atom_frac(94239), 0.0); - EXPECT_DOUBLE_EQ(q.atom_frac(922350000), u235 / (u235 + u238)); - EXPECT_DOUBLE_EQ(q.atom_frac(922380000), u238 / (u235 + u238)); - EXPECT_DOUBLE_EQ(mat->quantity(), qty); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// QQ Document, check that Fn is false when expected. TEST_F(EnrichmentFacilityTest, ValidReq) { using cyclus::CompMap; using cyclus::Composition; @@ -503,13 +389,13 @@ TEST_F(EnrichmentFacilityTest, ValidReq) { v1[922350000] = 1; Material::Ptr mat = Material::CreateUntracked(qty, Composition::CreateFromAtom(v1)); - EXPECT_TRUE(!src_facility->ValidReq(mat)); // u238 = 0 + EXPECT_FALSE(src_facility->ValidReq(mat)); // u238 = 0 cyclus::CompMap v2; v2[922350000] = tails_assay; v2[922380000] = 1 - tails_assay; mat = Material::CreateUntracked(qty, Composition::CreateFromAtom(v2)); - EXPECT_TRUE(!src_facility->ValidReq(mat)); // u235 / (u235 + u238) <= tails_assay + EXPECT_FALSE(src_facility->ValidReq(mat)); // u235 / (u235 + u238) <= tails_assay cyclus::CompMap v3; v3[922350000] = 1; @@ -518,20 +404,11 @@ TEST_F(EnrichmentFacilityTest, ValidReq) { EXPECT_TRUE(src_facility->ValidReq(mat)); // valid } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, EmptyRequests) { - using cyclus::Material; - using cyclus::RequestPortfolio; - - src_facility->SetMaxInventorySize(src_facility->InventorySize()); - std::set::Ptr> ports = - src_facility->GetMatlRequests(); - ports = src_facility->GetMatlRequests(); - EXPECT_TRUE(ports.empty()); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, AddRequests) { +// QQ Replace w/MockSim: generates requests with the correct amnt of material +// (requests to fill its inventory size - no more and no less) +// Generate case where source can generate more than inventory, amount matched is reasonable. + TEST_F(EnrichmentFacilityTest, AddRequests) { using cyclus::Request; using cyclus::RequestPortfolio; using cyclus::CapacityConstraint; @@ -559,68 +436,13 @@ TEST_F(EnrichmentFacilityTest, AddRequests) { EXPECT_EQ(constraints.size(), 0); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, Extract) { - using cyclus::Material; - cyclus::Env::SetNucDataPath(); - double qty = 1000; // 5 kg - Material::Ptr base = GetMat(qty); - double time = tc_.get()->time(); - // cyclus::Material::Create(src_facility, qty, - // tc_.get()->GetRecipe(in_recipe)); - Material::Ptr base2 = GetMat(qty); - base->Absorb(base2); - double product_assay = 0.05; // of 5 w/o enriched U - cyclus::CompMap v; - v[922350000] = product_assay; - v[922380000] = 1 - product_assay; - // target qty need not be = to request qty - Material::Ptr target = cyclus::Material::CreateUntracked( - 5, cyclus::Composition::CreateFromMass(v)); - Material::Ptr response = base->ExtractComp(6, target->comp()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, Accept) { - using cyclus::Bid; - using cyclus::Material; - using cyclus::Request; - using cyclus::Trade; - - // an enrichment facility gets two trades, each for 1/3 of its inv size - // note that comp != recipe is covered by AddMat tests - // note that qty >= inv capacity is covered by toolkit::ResourceBuff tests - - double qty = inv_size / 3; - std::vector< std::pair, - cyclus::Material::Ptr> > responses; - - Request* req1 = - Request::Create(DoRequest(), src_facility, in_commod); - Bid* bid1 = - Bid::Create(req1, GetMat(qty), trader); - - Request* req2 = - Request::Create(DoRequest(), src_facility, in_commod); - Bid* bid2 = Bid::Create(req2, GetMat(qty), trader); - - Trade trade1(req1, bid1, qty); - responses.push_back(std::make_pair(trade1, GetMat(qty))); - Trade trade2(req2, bid2, qty); - responses.push_back(std::make_pair(trade2, GetMat(qty))); - - EXPECT_DOUBLE_EQ(0.0, src_facility->InventorySize()); - src_facility->AcceptMatlTrades(responses); - EXPECT_DOUBLE_EQ(qty * 2, src_facility->InventorySize()); - - delete bid2; - delete bid1; - delete req2; - delete req1; -} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, AddBids) { +// Tests that SWU and invent. constraints are being properly applied. + // MockSim that is SWU constrained - check amnt of matl traded. + // Does traded amount meet SWU constraint? (1/2 qty of requested value) + // Cap constraint - requests too much - supplies only amt avail. + TEST_F(EnrichmentFacilityTest, AddBids) { using cyclus::Bid; using cyclus::BidPortfolio; using cyclus::CapacityConstraint; @@ -649,10 +471,10 @@ TEST_F(EnrichmentFacilityTest, AddBids) { BidPortfolio::Ptr port = *ports.begin(); //QQ src_facility failing b/c of GetMat->AddMat_ ? - // EXPECT_EQ(port->bidder(), src_facility); + EXPECT_EQ(port->bidder(), src_facility); //QQ bids().size=0, but nvalid=4 -->src_facility isn't working? - // EXPECT_EQ(port->bids().size(), nvalid); + EXPECT_EQ(port->bids().size(), nvalid); const std::set< CapacityConstraint >& constrs = port->constraints(); Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); //QQ @@ -686,7 +508,8 @@ EnrichmentFacilityTest::GetContext(int nreqs, int nvalid) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, BidConverters) { + // Add documentation to clarify + TEST_F(EnrichmentFacilityTest, ConstraintConverters) { // this test is designed to confirm that the bid response behavior matches the // converter behavior. using cyclus::CompMap; @@ -726,6 +549,7 @@ TEST_F(EnrichmentFacilityTest, BidConverters) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// QQ KEEP HERE TEST_F(EnrichmentFacilityTest, Enrich) { // this test asks the facility to enrich a material that results in an amount // of natural uranium required that is exactly its inventory level. that @@ -841,6 +665,7 @@ TEST_F(EnrichmentFacilityTest, Response) { EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_req - SwuRequired(trade_qty, assays)); + // KEEP ONLY THIS SET OF TESTS // 2 trades, SWU = SWU cap ASSERT_GT(src_facility->CurrentSwuCapacity() - 2 * swu_req / 3, -1 * cyclus::eps()); @@ -849,17 +674,14 @@ TEST_F(EnrichmentFacilityTest, Response) { EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); EXPECT_EQ(responses.size(), 2); EXPECT_TRUE(cyclus::AlmostEq(src_facility->CurrentSwuCapacity(), 0)); - + // END + // too much qty, capn! trade = Trade(req, bid, 1); // a small number trades.clear(); trades.push_back(trade); EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), cyclus::ValueError); - - // reset! - src_facility->Tick(); - EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_req); } From 02ec6d877b8a38054cdcf805de5f1a9439e7f827 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Fri, 6 Mar 2015 16:03:28 -0600 Subject: [PATCH 137/314] almost finished with tests --- src/enrichment_facility.cc | 17 +- src/enrichment_facility.h | 11 +- src/enrichment_facility_tests.cc | 302 +++++++++++++++---------------- 3 files changed, 159 insertions(+), 171 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 571426cc40..48b22355a1 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -17,6 +17,10 @@ EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) swu_capacity(0), max_enrich(1), ///QQ initial_reserves(0), + in_commod(""), + in_recipe(""), + out_commod(""), + tails_commod(""), order_prefs(true){} //QQ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -109,7 +113,7 @@ void EnrichmentFacility::AdjustMatlPrefs( using cyclus::Material; using cyclus::Request; - if (!order_prefs){ + if (order_prefs == false){ return ; } @@ -148,8 +152,7 @@ void EnrichmentFacility::AdjustMatlPrefs( (reqit->second)[bids_vector[bidit]] = new_pref; } // each bid } // each Material Request - std::cout << "end of request" << std::endl; -} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentFacility::AcceptMatlTrades( @@ -215,9 +218,6 @@ EnrichmentFacility::GetMatlBids( Material::Ptr offer = Offer_(req->target()); commod_port->AddBid(req, offer, this); } - else { - std::cout<< request_enrich << " , " << max_enrich << "\n" ; - } } Converter::Ptr sc(new SWUConverter(FeedAssay(), tails_assay)); @@ -449,7 +449,10 @@ void EnrichmentFacility::RecordEnrichment_(double natural_u, double swu) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - double EnrichmentFacility::FeedAssay() { using cyclus::Material; - + + if (inventory.empty()) { + return 0 ; + } cyclus::Material::Ptr fission_matl=inventory.Pop(inventory.quantity()); inventory.Push(fission_matl); return cyclus::toolkit::UraniumAssay(fission_matl); diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index da5f323ec9..ecb11c3b9e 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -158,9 +158,10 @@ class EnrichmentFacility : public cyclus::Facility { #pragma cyclus - #pragma cyclus note {"doc": "An enrichment facility that intakes a commodity " \ - "(usually natural uranium) and supplies a user-" \ - "specified enriched product based on SWU capacity", \ + #pragma cyclus note {"doc": "An enrichment facility that intakes a "\ + "commodity (usually natural uranium) and " \ + "supplies a user-specified enriched product "\ + "based on SWU capacity", \ "niche": "enrichment"} /// Print information about this agent @@ -304,8 +305,8 @@ class EnrichmentFacility : public cyclus::Facility { /// @brief records and enrichment with the cyclus::Recorder void RecordEnrichment_(double natural_u, double swu); - - #pragma cyclus var {"tooltip": "input commodity", \ + + #pragma cyclus var {"tooltip": "input commodity", \ "doc": "commodity that the enrichment facility accepts", \ "uitype": "incommodity"} std::string in_commod; diff --git a/src/enrichment_facility_tests.cc b/src/enrichment_facility_tests.cc index 44488eb175..005ad63319 100644 --- a/src/enrichment_facility_tests.cc +++ b/src/enrichment_facility_tests.cc @@ -50,10 +50,126 @@ Composition::Ptr c_heu() { return Composition::CreateFromMass(m); }; +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, RequestQty) { + // this tests verifies that requests for input material are fulfilled + // without providing any extra + + std::string config = + " natu " + " natu1 " + " enr_u " + " tails " + " 1.0 " + " 0.003 "; + + int simdur = 1; + cyclus::MockSim sim(cyclus::AgentSpec + (":cycamore:EnrichmentFacility"), config, simdur); + sim.AddRecipe("natu1", c_natu1()) ; + + sim.AddSource("natu") + .recipe("natu1") + .Finalize(); + + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==",std::string("natu"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); + + // Should be only one transaction into the EF, + // and it should be exactly 1kg of natu + EXPECT_EQ(1.0, qr.rows.size()); + EXPECT_NEAR(1.0, m->quantity(), 1e-10) << + "matched trade provides the wrong quantity of material"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, CheckSWUConstraint) { + // Tests that request for enrichment that exceeds the SWU constraint + // fulfilled only up to the available SWU. + // Also confirms that initial_reserves flag works. + // 388 SWU = 10kg 80% enriched HEU from 486kg feed matl + + std::string config = + " natu " + " natu1 " + " enr_u " + " tails " + " 0.003 " + " 1000 " + " 195 " ; + + int simdur = 1; + + cyclus::MockSim sim(cyclus::AgentSpec + (":cycamore:EnrichmentFacility"), config, simdur); + + sim.AddRecipe("natu1", c_natu1()) ; + sim.AddRecipe("heu", c_heu()) ; + + sim.AddSink("enr_u") + .recipe("heu") + .capacity(10) + .Finalize(); + + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==",std::string("enr_u"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); + + EXPECT_EQ(1.0, qr.rows.size()); + EXPECT_NEAR(5.0, m->quantity(), 0.1) << + "traded quantity exceeds SWU constraint"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(EnrichmentFacilityTest, CheckCapConstraint) { + // Tests that a request for more material than is available in + // inventory is partially filled with only the inventory quantity. + + std::string config = + " natu " + " natu1 " + " enr_u " + " tails " + " 0.003 " + " 243 " ; + + int simdur = 1; + + cyclus::MockSim sim(cyclus::AgentSpec + (":cycamore:EnrichmentFacility"), config, simdur); + + + sim.AddRecipe("natu1", c_natu1()) ; + sim.AddRecipe("heu", c_heu()) ; + + sim.AddSink("enr_u") + .recipe("heu") + .capacity(10) + .Finalize(); + + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("Commodity", "==",std::string("enr_u"))); + QueryResult qr = sim.db().Query("Transactions", &conds); + Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); + + EXPECT_EQ(1.0, qr.rows.size()); + EXPECT_NEAR(5.0, m->quantity(), 0.01) << + "traded quantity exceeds capacity constraint"; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TEST_F(EnrichmentFacilityTest, RequestEnrich) { - // this tests verifies that requests for material exceeding the maximum - // allowed enrichment are not fulfilled. + // this tests verifies that requests for output material exceeding + // the maximum allowed enrichment are not fulfilled. std::string config = " natu " @@ -75,6 +191,7 @@ TEST_F(EnrichmentFacilityTest, RequestEnrich) { .Finalize(); sim.AddSink("enr_u") .recipe("leu") + .capacity(1.0) .Finalize(); sim.AddSink("enr_u") .recipe("heu") @@ -85,12 +202,14 @@ TEST_F(EnrichmentFacilityTest, RequestEnrich) { std::vector conds; conds.push_back(Cond("Commodity", "==",std::string("enr_u"))); QueryResult qr = sim.db().Query("Transactions", &conds); - + Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); + // Should be only one transaction out of the EF, - // and it should be LEU + // and it should be 1kg of LEU EXPECT_EQ(1.0, qr.rows.size()); + EXPECT_NEAR(1.0, m->quantity(), 0.01) << + "Not providing the requested quantity" ; - Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); CompMap got = m->comp()->mass(); CompMap want = c_leu()->mass(); cyclus::compmath::Normalize(&got); @@ -192,7 +311,7 @@ TEST_F(EnrichmentFacilityTest, BidPrefs) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, NoBidPrefs) { + TEST_F(EnrichmentFacilityTest, NoBidPrefs) { // This tests that preference-ordering for sources // turns off correctly if flag is used @@ -202,7 +321,7 @@ TEST_F(EnrichmentFacilityTest, NoBidPrefs) { " enr_u " " tails " " 0.003 " - " 2.0 " ; + " 2.0 " " 0 " ; int simdur = 1; @@ -321,16 +440,6 @@ cyclus::Material::Ptr EnrichmentFacilityTest::GetMat(double qty) { tc_.get()->GetRecipe(in_recipe)); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacilityTest::GetReqMat(double qty, - double enr) { - cyclus::CompMap v; - v[922350000] = enr; - v[922380000] = 1 - enr; - return cyclus::Material::CreateUntracked( - qty, cyclus::Composition::CreateFromAtom(v)); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentFacilityTest::DoAddMat(cyclus::Material::Ptr mat) { src_facility->AddMat_(mat); @@ -355,6 +464,7 @@ EnrichmentFacilityTest::DoEnrich(cyclus::Material::Ptr mat, double qty) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TEST_F(EnrichmentFacilityTest, Request) { + // Tests that quantity in material request is accurate double req = inv_size; double add = 0; cyclus::Material::Ptr mat = DoRequest(); @@ -377,8 +487,8 @@ TEST_F(EnrichmentFacilityTest, Request) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// QQ Document, check that Fn is false when expected. TEST_F(EnrichmentFacilityTest, ValidReq) { + // Tests that material requests have U235/(U235+U238) > tails assay using cyclus::CompMap; using cyclus::Composition; using cyclus::Material; @@ -387,15 +497,16 @@ TEST_F(EnrichmentFacilityTest, ValidReq) { cyclus::CompMap v1; v1[922350000] = 1; - Material::Ptr mat = Material::CreateUntracked(qty, - Composition::CreateFromAtom(v1)); + Material::Ptr mat = Material::CreateUntracked + (qty,Composition::CreateFromAtom(v1)); EXPECT_FALSE(src_facility->ValidReq(mat)); // u238 = 0 cyclus::CompMap v2; v2[922350000] = tails_assay; v2[922380000] = 1 - tails_assay; mat = Material::CreateUntracked(qty, Composition::CreateFromAtom(v2)); - EXPECT_FALSE(src_facility->ValidReq(mat)); // u235 / (u235 + u238) <= tails_assay + // u235 / (u235 + u238) <= tails_assay + EXPECT_FALSE(src_facility->ValidReq(mat)); cyclus::CompMap v3; v3[922350000] = 1; @@ -405,113 +516,9 @@ TEST_F(EnrichmentFacilityTest, ValidReq) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// QQ Replace w/MockSim: generates requests with the correct amnt of material -// (requests to fill its inventory size - no more and no less) -// Generate case where source can generate more than inventory, amount matched is reasonable. - TEST_F(EnrichmentFacilityTest, AddRequests) { - using cyclus::Request; - using cyclus::RequestPortfolio; - using cyclus::CapacityConstraint; - using cyclus::Converter; - using cyclus::Material; - - // a request is made for the current available inventory amount - - std::set::Ptr> ports = - src_facility->GetMatlRequests(); - - ASSERT_EQ(ports.size(), 1); - ASSERT_EQ(ports.begin()->get()->qty(), inv_size); - - const std::vector*>& requests = - ports.begin()->get()->requests(); - ASSERT_EQ(requests.size(), 1); - - Request* req = *requests.begin(); - EXPECT_EQ(req->requester(), src_facility); - EXPECT_EQ(req->commodity(), in_commod); - - const std::set< CapacityConstraint >& constraints = - ports.begin()->get()->constraints(); - EXPECT_EQ(constraints.size(), 0); -} - - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Tests that SWU and invent. constraints are being properly applied. - // MockSim that is SWU constrained - check amnt of matl traded. - // Does traded amount meet SWU constraint? (1/2 qty of requested value) - // Cap constraint - requests too much - supplies only amt avail. - TEST_F(EnrichmentFacilityTest, AddBids) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::Converter; - using cyclus::ExchangeContext; - using cyclus::Material; - cyclus::Env::SetNucDataPath(); - // an enrichment facility bids on nreqs requests - // note that bid response is covered by Bid tests - // note that validity of requests is covered by ValidReq tests - int nreqs = 5; - int nvalid = 4; - - // set up inventory - double current_size = inv_size / 2; // test something other than max size - DoAddMat(GetMat(current_size)); - - boost::shared_ptr< cyclus::ExchangeContext > - ec = GetContext(nreqs, nvalid); - - std::set::Ptr> ports = - src_facility->GetMatlBids(ec.get()->commod_requests); - - ASSERT_TRUE(ports.size() > 0); - EXPECT_EQ(ports.size(), 1); - - BidPortfolio::Ptr port = *ports.begin(); - //QQ src_facility failing b/c of GetMat->AddMat_ ? - EXPECT_EQ(port->bidder(), src_facility); - - //QQ bids().size=0, but nvalid=4 -->src_facility isn't working? - EXPECT_EQ(port->bids().size(), nvalid); - - const std::set< CapacityConstraint >& constrs = port->constraints(); - Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); //QQ - Converter::Ptr nc(new NatUConverter(feed_assay, tails_assay)); //QQ - CapacityConstraint swu(swu_capacity, sc); - CapacityConstraint natu(current_size, nc); - EXPECT_EQ(constrs.size(), 2); - EXPECT_TRUE(*constrs.begin() == swu || *(++constrs.begin()) == swu); - EXPECT_TRUE(*constrs.begin() == natu || *(++constrs.begin()) == natu); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -boost::shared_ptr< cyclus::ExchangeContext > -EnrichmentFacilityTest::GetContext(int nreqs, int nvalid) { - using cyclus::ExchangeContext; - using cyclus::Material; - using cyclus::Request; - using test_helpers::get_mat; - - boost::shared_ptr< ExchangeContext > - ec(new ExchangeContext()); - for (int i = 0; i < nvalid; i++) { - ec->AddRequest( - Request::Create(GetReqMat(1.0, 0.05), trader, out_commod)); - } - for (int i = 0; i < nreqs - nvalid; i++) { - ec->AddRequest( - Request::Create(get_mat(), trader, out_commod)); - } - return ec; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Add documentation to clarify TEST_F(EnrichmentFacilityTest, ConstraintConverters) { - // this test is designed to confirm that the bid response behavior matches the - // converter behavior. + // Tests the SWU and NatU converters to make sure that amount of + // feed and SWU required are correct to fulfill the enrichment request. using cyclus::CompMap; using cyclus::Material; using cyclus::toolkit::MatQuery; @@ -549,7 +556,6 @@ EnrichmentFacilityTest::GetContext(int nreqs, int nvalid) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// QQ KEEP HERE TEST_F(EnrichmentFacilityTest, Enrich) { // this test asks the facility to enrich a material that results in an amount // of natural uranium required that is exactly its inventory level. that @@ -586,7 +592,6 @@ TEST_F(EnrichmentFacilityTest, Enrich) { Material::Ptr response; EXPECT_NO_THROW(response = DoEnrich(target, qty)); - EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_cap - swu_req); EXPECT_DOUBLE_EQ(src_facility->Tails().quantity(), tails_qty); MatQuery q(response); @@ -607,19 +612,16 @@ TEST_F(EnrichmentFacilityTest, Response) { // of in the Enrich tests). // // note that response quantity and quality need not be tested, because they - // are covered by the Enrich and Offer tests + // are covered by the Enrich and RequestEnrich tests using cyclus::Bid; using cyclus::CompMap; - using cyclus::Composition; using cyclus::Material; using cyclus::Request; using cyclus::Trade; - using cyclus::toolkit::MatQuery; - using cyclus::toolkit::Assays; - using cyclus::toolkit::FeedQty; + using cyclus::toolkit::Assays; + using cyclus::toolkit::FeedQty; using cyclus::toolkit::SwuRequired; using cyclus::toolkit::UraniumAssay; - using test_helpers::get_mat; // problem set up std::vector< cyclus::Trade > trades; @@ -644,46 +646,28 @@ TEST_F(EnrichmentFacilityTest, Response) { src_facility->SetMaxInventorySize(natu_req * 4); // not capacitated by nat u src_facility->SwuCapacity(swu_req); // swu capacitated - // Null response - src_facility->GetMatlTrades(trades, responses); - EXPECT_NO_THROW(); - EXPECT_EQ(responses.size(), 0); + + src_facility->GetMatlTrades(trades, responses); // set up state DoAddMat(GetMat(natu_req * 2)); + src_facility->GetMatlTrades(trades, responses); + Request* req = Request::Create(target, trader, out_commod); Bid* bid = Bid::Create(req, target, src_facility); Trade trade(req, bid, trade_qty); trades.push_back(trade); - // 1 allowed trade, SWU < SWU cap - ASSERT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_req); - src_facility->GetMatlTrades(trades, responses); - ASSERT_EQ(responses.size(), 1); - EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), - swu_req - SwuRequired(trade_qty, assays)); - - // KEEP ONLY THIS SET OF TESTS // 2 trades, SWU = SWU cap - ASSERT_GT(src_facility->CurrentSwuCapacity() - 2 * swu_req / 3, - -1 * cyclus::eps()); + ASSERT_GT(src_facility->SwuCapacity() - 2 * swu_req / 3, + -1 * cyclus::eps()); trades.push_back(trade); responses.clear(); EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); EXPECT_EQ(responses.size(), 2); - EXPECT_TRUE(cyclus::AlmostEq(src_facility->CurrentSwuCapacity(), 0)); - // END - - // too much qty, capn! - trade = Trade(req, bid, 1); // a small number - trades.clear(); - trades.push_back(trade); - EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), - cyclus::ValueError); } - } // namespace cycamore From 29ef02ce0eb662d0621e473a1279a7524df04da8 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 10 Mar 2015 11:40:28 -0500 Subject: [PATCH 138/314] style guide cleanup --- src/enrichment_facility.cc | 129 ++-- src/enrichment_facility.h | 209 ++--- src/enrichment_facility_tests.h | 2 +- .../fn_behavior/behavior_functions.cc | 7 - .../fn_behavior/behavior_functions.h | 17 - .../fn_behavior/enrichment_facility.cc | 357 --------- .../fn_behavior/enrichment_facility.h | 324 -------- src/meg_old_tests/fn_consider/CMakeLists.txt | 25 - .../fn_consider/enrichment_facility.cc | 392 ---------- .../fn_consider/enrichment_facility.h | 331 -------- .../fn_consider/enrichment_facility_tests.cc | 725 ------------------ .../fn_consider/enrichment_facility_tests.h | 51 -- 12 files changed, 174 insertions(+), 2395 deletions(-) delete mode 100644 src/meg_old_tests/fn_behavior/behavior_functions.cc delete mode 100644 src/meg_old_tests/fn_behavior/behavior_functions.h delete mode 100644 src/meg_old_tests/fn_behavior/enrichment_facility.cc delete mode 100644 src/meg_old_tests/fn_behavior/enrichment_facility.h delete mode 100644 src/meg_old_tests/fn_consider/CMakeLists.txt delete mode 100644 src/meg_old_tests/fn_consider/enrichment_facility.cc delete mode 100644 src/meg_old_tests/fn_consider/enrichment_facility.h delete mode 100644 src/meg_old_tests/fn_consider/enrichment_facility_tests.cc delete mode 100644 src/meg_old_tests/fn_consider/enrichment_facility_tests.h diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 48b22355a1..326c6dd9d1 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -15,13 +15,13 @@ EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) : cyclus::Facility(ctx), tails_assay(0), swu_capacity(0), - max_enrich(1), ///QQ + max_enrich(1), initial_reserves(0), in_commod(""), in_recipe(""), out_commod(""), tails_commod(""), - order_prefs(true){} //QQ + order_prefs(true){} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EnrichmentFacility::~EnrichmentFacility() {} @@ -36,7 +36,7 @@ std::string EnrichmentFacility::str() { << " * Feed assay: " << FeedAssay() << " * Input cyclus::Commodity: " << in_commodity() << " * Output cyclus::Commodity: " << out_commodity() - << " * Tails cyclus::Commodity: " << tails_commodity(); ///QQ + << " * Tails cyclus::Commodity: " << tails_commodity(); return ss.str(); } @@ -52,7 +52,7 @@ void EnrichmentFacility::Build(cyclus::Agent* parent) { } LOG(cyclus::LEV_DEBUG2, "EnrFac") << "EnrichmentFacility " - << " entering the simuluation: "; + << " entering the simuluation: "; LOG(cyclus::LEV_DEBUG2, "EnrFac") << str(); } @@ -71,7 +71,7 @@ void EnrichmentFacility::Tock() { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - std::set::Ptr> -EnrichmentFacility::GetMatlRequests() { + EnrichmentFacility::GetMatlRequests() { using cyclus::Material; using cyclus::RequestPortfolio; using cyclus::Request; @@ -92,7 +92,7 @@ EnrichmentFacility::GetMatlRequests() { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Sort bids by U-235 content bool SortBids( - cyclus::Bid* i, cyclus::Bid* j) { + cyclus::Bid* i, cyclus::Bid* j) { cyclus::Material::Ptr mat_i = i->offer(); cyclus::Material::Ptr mat_j = j->offer(); @@ -100,43 +100,41 @@ bool SortBids( cyclus::toolkit::MatQuery mq_i(mat_i); cyclus::toolkit::MatQuery mq_j(mat_j); - return ((mq_i.mass(922350000)/mq_i.qty()) <= - (mq_j.mass(922350000)/mq_j.qty())); + return ((mq_i.mass(922350000) / mq_i.qty()) <= + (mq_j.mass(922350000) / mq_j.qty())); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Sort offers of input material to have higher preference for more // U-235 content void EnrichmentFacility::AdjustMatlPrefs( - cyclus::PrefMap::type& prefs) { + cyclus::PrefMap::type& prefs) { using cyclus::Bid; using cyclus::Material; using cyclus::Request; - if (order_prefs == false){ - return ; + if (order_prefs == false) { + return; } cyclus::PrefMap::type::iterator reqit; // Loop over all requests for (reqit = prefs.begin(); reqit != prefs.end(); ++reqit) { - std::vector* > bids_vector; std::map*, double>::iterator mit; for (mit = reqit->second.begin(); mit != reqit->second.end(); ++mit) { Bid* bid = mit->first; - bids_vector.push_back(bid) ; + bids_vector.push_back(bid); } - std::sort (bids_vector.begin(), bids_vector.end(), SortBids); // Assign preferences to the sorted vector - double n_bids = bids_vector.size() ; + double n_bids = bids_vector.size(); + bool u235_mass = 0; - bool u235_mass = 0 ; - for (int bidit=0 ; bidit < bids_vector.size(); bidit++) { - int new_pref = bidit+1 ; + for (int bidit = 0 ; bidit < bids_vector.size(); bidit++) { + int new_pref = bidit + 1; // For any bids with U-235 qty=0, set pref to zero. if (!u235_mass) { @@ -146,18 +144,18 @@ void EnrichmentFacility::AdjustMatlPrefs( new_pref = -1; } else { - u235_mass = TRUE; + u235_mass = true; } } (reqit->second)[bids_vector[bidit]] = new_pref; } // each bid } // each Material Request +} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentFacility::AcceptMatlTrades( - const std::vector< std::pair, - cyclus::Material::Ptr> >& responses) { + const std::vector< std::pair, + cyclus::Material::Ptr> >& responses) { // see // http://stackoverflow.com/questions/5181183/boostshared-ptr-and-inheritance std::vector< std::pair, @@ -169,7 +167,7 @@ void EnrichmentFacility::AcceptMatlTrades( // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - std::set::Ptr> -EnrichmentFacility::GetMatlBids( + EnrichmentFacility::GetMatlBids( cyclus::CommodMap::type& out_requests){ using cyclus::Bid; using cyclus::BidPortfolio; @@ -179,46 +177,42 @@ EnrichmentFacility::GetMatlBids( using cyclus::Request; std::set::Ptr> ports; - //QQ - if (out_requests.count(tails_commod) > 0 && tails.quantity() > 0) { - BidPortfolio::Ptr tails_port(new BidPortfolio()); //QQ + + if ((out_requests.count(tails_commod) > 0) && (tails.quantity() > 0)) { + BidPortfolio::Ptr tails_port(new BidPortfolio()); std::vector*>& tails_requests = out_requests[tails_commod]; - std::vector*>::iterator it; for (it = tails_requests.begin(); it != tails_requests.end(); ++it) { Request* req = *it; tails_port->AddBid(req, tails.Peek(), this); } - //QQ // overbidding (bidding on every offer) // add an overall capacity constraint CapacityConstraint tails_constraint(tails.quantity()); tails_port->AddConstraint(tails_constraint); LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() - << " adding a tails capacity constraint of " + << " adding tails capacity constraint of " << tails.capacity(); - //QQ ports.insert(tails_port); } - if (out_requests.count(out_commod) > 0 && inventory.quantity() > 0) { + + if ((out_requests.count(out_commod) > 0) && (inventory.quantity() > 0)) { BidPortfolio::Ptr commod_port(new BidPortfolio()); std::vector*>& commod_requests = out_requests[out_commod]; - std::vector*>::iterator it; for (it = commod_requests.begin(); it != commod_requests.end(); ++it) { Request* req = *it; - // Do not offer a bid if the enrichment exceed max. QQ Material::Ptr mat = req->target(); double request_enrich = cyclus::toolkit::UraniumAssay(mat) ; + if (ValidReq(req->target()) && (request_enrich <= max_enrich)) { Material::Ptr offer = Offer_(req->target()); commod_port->AddBid(req, offer, this); } - } Converter::Ptr sc(new SWUConverter(FeedAssay(), tails_assay)); Converter::Ptr nc(new NatUConverter(FeedAssay(), tails_assay)); @@ -228,12 +222,11 @@ EnrichmentFacility::GetMatlBids( commod_port->AddConstraint(natu); LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() - << " adding a swu constraint of " - << swu.capacity(); + << " adding a swu constraint of " + << swu.capacity(); LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() - << " adding a natu constraint of " - << natu.capacity(); - + << " adding a natu constraint of " + << natu.capacity(); ports.insert(commod_port); } return ports; @@ -249,21 +242,22 @@ bool EnrichmentFacility::ValidReq(const cyclus::Material::Ptr mat) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentFacility::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses) { + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses) { + using cyclus::Material; using cyclus::Trade; std::vector< Trade >::const_iterator it; for (it = trades.begin(); it != trades.end(); ++it) { double qty = it->amt; - std::string commod_type = it->bid->request()->commodity() ; - Material::Ptr response ; + std::string commod_type = it->bid->request()->commodity(); + Material::Ptr response; - //QQ Figure out whether material is tails or enriched, + // Figure out whether material is tails or enriched, // if tails then make transfer of material - if (commod_type == tails_commod){ + if (commod_type == tails_commod) { LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " just received an order" << " for " << it->amt @@ -278,9 +272,10 @@ void EnrichmentFacility::GetMatlTrades( } responses.push_back(std::make_pair(*it, response)); } + if (cyclus::IsNegative(tails.quantity())) { std::stringstream ss; - ss << "is being asked to provide more than its current inventory." ; + ss << "is being asked to provide more than its current inventory."; throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); } if (cyclus::IsNegative(current_swu_capacity)) { @@ -296,10 +291,10 @@ void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { cyclus::CompMap cm = mat->comp()->atom(); bool extra_u = false; bool other_elem = false; - for (cyclus::CompMap::const_iterator it=cm.begin(); it !=cm.end(); ++it) { - if (pyne::nucname::znum(it->first) == 92){ + for (cyclus::CompMap::const_iterator it = cm.begin(); it != cm.end(); ++it) { + if (pyne::nucname::znum(it->first) == 92) { if (pyne::nucname::anum(it->first) != 235 && - pyne::nucname::anum(it->first) != 238 && it->second > 0){ + pyne::nucname::anum(it->first) != 238 && it->second > 0) { extra_u = true; } } @@ -307,12 +302,12 @@ void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { other_elem = true ; } } - if (extra_u){ - cyclus::Warn("More than 2 isotopes of U." \ + if (extra_u) { + cyclus::Warn ("More than 2 isotopes of U. " \ "Istopes other than U-235, U-238 are sent directly to tails."); } - if (other_elem){ - cyclus::Warn("Non-uranium elements are " \ + if (other_elem) { + cyclus::Warn ("Non-uranium elements are " \ "sent directly to tails."); } @@ -321,7 +316,8 @@ void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { try { inventory.Push(mat); - } catch (cyclus::Error& e) { + } + catch (cyclus::Error& e) { e.msg(Agent::InformErrorMsg(e.msg())); throw e; } @@ -336,10 +332,10 @@ void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { cyclus::Material::Ptr EnrichmentFacility::Request_() { double qty = std::max(0.0, MaxInventorySize() - InventorySize()); return cyclus::Material::CreateUntracked(qty, - context()->GetRecipe(in_recipe)); + context()->GetRecipe(in_recipe)); } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { cyclus::toolkit::MatQuery q(mat); cyclus::CompMap comp; @@ -348,10 +344,11 @@ cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { return cyclus::Material::CreateUntracked( mat->quantity(), cyclus::Composition::CreateFromAtom(comp)); } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - cyclus::Material::Ptr EnrichmentFacility::Enrich_( - cyclus::Material::Ptr mat, - double qty) { + cyclus::Material::Ptr mat, + double qty) { + using cyclus::Material; using cyclus::ResCast; using cyclus::toolkit::Assays; @@ -366,12 +363,12 @@ cyclus::Material::Ptr EnrichmentFacility::Enrich_( double natu_req = FeedQty(qty, assays); // Determine the composition of the natural uranium - // (ie. fraction of non-fissile materials) + // (ie. U-235+U-238/TotalMass) Material::Ptr natu_matl=inventory.Pop(inventory.quantity()); inventory.Push(natu_matl); cyclus::toolkit::MatQuery mq(natu_matl); - std::set nucs ; + std::set nucs; nucs.insert(922350000); nucs.insert(922380000); double natu_frac = mq.multi_mass_frac(nucs); @@ -451,16 +448,16 @@ double EnrichmentFacility::FeedAssay() { using cyclus::Material; if (inventory.empty()) { - return 0 ; + return 0; } - cyclus::Material::Ptr fission_matl=inventory.Pop(inventory.quantity()); + cyclus::Material::Ptr fission_matl = inventory.Pop(inventory.quantity()); inventory.Push(fission_matl); return cyclus::toolkit::UraniumAssay(fission_matl); } - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - extern "C" cyclus::Agent* ConstructEnrichmentFacility(cyclus::Context* ctx) { return new EnrichmentFacility(ctx); } - + } // namespace cycamore diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index ecb11c3b9e..5dd659bbce 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -1,6 +1,6 @@ #ifndef CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ #define CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ - +/* #include #include "cyclus.h" @@ -57,9 +57,8 @@ class NatUConverter : public cyclus::Converter { const * ctx = NULL) const { cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), tails_); - cyclus::toolkit::MatQuery mq(m); - std::set nucs ; + std::set nucs; nucs.insert(922350000); nucs.insert(922380000); @@ -69,7 +68,7 @@ class NatUConverter : public cyclus::Converter { } /// @returns true if Converter is a NatUConverter and feed and tails equal - virtual bool operator==(Converter& other) const { + virtual bool operator == (Converter& other) const { NatUConverter* cast = dynamic_cast(&other); return cast != NULL && feed_ == cast->feed_ && @@ -112,41 +111,40 @@ class NatUConverter : public cyclus::Converter { /// tails inventory. class EnrichmentFacility : public cyclus::Facility { -#pragma cyclus note { \ - "niche": "enrichment facility", \ - "doc": \ - "EnrichmentFacility is a simple Agent that enriches natural" \ - "uranium in a Cyclus simulation. It does not explicitly compute" \ - "the physical enrichment process, rather it calculates the SWU" \ - "required to convert an source uranium recipe (ie. natural uranium)" \ - "into a requested enriched recipe (ie. 4% enriched uranium), given" \ - "the natural uranium inventory constraint and its SWU capacity" \ - "constraint." \ - "\n\n"\ - "Enrichment Facility requests an input commodity and associated recipe" \ - "whose quantity is its remaining inventory capacity. All facilities" \ - "trading the same input commodity (even with different recipes) will" \ - "offer materials for trade. The Enrichment Facility accepts any input" \ - "materials with enrichments less than its tails assay, as long as some" \ - "U235 is present, and preference increases with U235 content. If no" \ - "U235 is present in the offered material, the trade preference is set" \ - "to -1 and the material is not accepted. Any material components other" \ - "other than U235 and U238 are sent directly to the tails buffer." \ - "\n\n"\ - "EnrichmentFacility will bid on any request for its output commodity" \ - "up to the maximum allowed enrichment (if not specified, default is 100%)" \ - "It bids on either the request quantity, or the maximum quanity allowed" \ - "by its SWU constraint or natural uranium inventory, whichever is lower." \ - "If multiple output commodities with different enrichment levels are" \ - "requested and the facility does not have the SWU or quantity capacity" \ - "to meet all requests, the requests are fully, then partially filled" \ - "in unspecified but repeatable order." \ - "\n\n"\ - "EnrichmentFacility also offers its tails as an output commodity with" \ - "no associated recipe. Bids for tails are constrained only by total" \ - "tails inventory.", \ +#pragma cyclus note { \ + "niche": "enrichment facility", \ + "doc": \ + "EnrichmentFacility is a simple Agent that enriches natural" \ + "uranium in a Cyclus simulation. It does not explicitly compute" \ + "the physical enrichment process, rather it calculates the SWU" \ + "required to convert an source uranium recipe (ie. natural uranium)" \ + "into a requested enriched recipe (ie. 4% enriched uranium), given" \ + "the natural uranium inventory constraint and its SWU capacity" \ + "constraint." \ + "\n\n" \ + "Enrichment Facility requests an input commodity and associated recipe" \ + "whose quantity is its remaining inventory capacity. All facilities" \ + "trading the same input commodity (even with different recipes) will" \ + "offer materials for trade. The Enrichment Facility accepts any input" \ + "materials with enrichments less than its tails assay, as long as some" \ + "U235 is present, and preference increases with U235 content. If no" \ + "U235 is present in the offered material, the trade preference is set" \ + "to -1 and the material is not accepted. Any material components other" \ + "other than U235 and U238 are sent directly to the tails buffer." \ + "\n\n" \ + "EnrichmentFacility will bid on any request for its output commodity" \ + "up to the maximum allowed enrichment (if not specified, default is 100%)" \ + "It bids on either the request quantity, or the maximum quanity allowed" \ + "by its SWU constraint or natural uranium inventory, whichever is lower." \ + "If multiple output commodities with different enrichment levels are" \ + "requested and the facility does not have the SWU or quantity capacity" \ + "to meet all requests, the requests are fully, then partially filled" \ + "in unspecified but repeatable order." \ + "\n\n" \ + "EnrichmentFacility also offers its tails as an output commodity with" \ + "no associated recipe. Bids for tails are constrained only by total" \ + "tails inventory.", \ } - public: // --- Module Members --- /// Constructor for the EnrichmentFacility class @@ -238,9 +236,9 @@ class EnrichmentFacility : public cyclus::Facility { inline void tails_commodity(std::string tails_com) { tails_commod = tails_com; - } ///QQ + } - inline std::string tails_commodity() const { return tails_commod; } ///QQ + inline std::string tails_commodity() const { return tails_commod; } inline void InRecipe(std::string in_rec) { in_recipe = in_rec; } @@ -248,7 +246,7 @@ class EnrichmentFacility : public cyclus::Facility { inline void SetMaxInventorySize(double size) { max_inv_size = size; - inventory.capacity(size); //QQ + inventory.capacity(size); } inline double MaxInventorySize() const { return inventory.capacity(); } @@ -268,9 +266,9 @@ class EnrichmentFacility : public cyclus::Facility { inline double CurrentSwuCapacity() const { return current_swu_capacity; } - inline void MaxEnrich(double enrichment) { max_enrich = enrichment; } //QQ + inline void MaxEnrich(double enrichment) { max_enrich = enrichment; } - inline double MaxEnrich() const { return max_enrich; } ///QQ + inline double MaxEnrich() const { return max_enrich; } /// @brief this facility's initial conditions inline void InitialReserves(double qty) { initial_reserves = qty; } @@ -279,8 +277,7 @@ class EnrichmentFacility : public cyclus::Facility { inline const cyclus::toolkit::ResBuf& Tails() const { return tails; } - ///QQ It's not used for anything and can be deleted if we decide to make everything a state variable for testing - + private: /// @brief adds a material into the natural uranium inventory /// @throws if the material is not the same composition as the in_recipe @@ -305,75 +302,89 @@ class EnrichmentFacility : public cyclus::Facility { /// @brief records and enrichment with the cyclus::Recorder void RecordEnrichment_(double natural_u, double swu); - - #pragma cyclus var {"tooltip": "input commodity", \ - "doc": "commodity that the enrichment facility accepts", \ - "uitype": "incommodity"} + + #pragma cyclus var { \ + "tooltip": "input commodity", \ + "doc": "commodity that the enrichment facility accepts", \ + "uitype": "incommodity" \ + } std::string in_commod; - #pragma cyclus var {"tooltip": "output commodity", \ - "doc": "commodity that the enrichment facility supplies", \ - "uitype": "outcommodity"} + #pragma cyclus var { \ + "tooltip": "output commodity", \ + "doc": "commodity that the enrichment facility supplies", \ + "uitype": "outcommodity" \ + } std::string out_commod; - #pragma cyclus var {"tooltip": "input commodity recipe", \ - "doc": "recipe for enrichment facility input commodity", \ - "uitype": "recipe"} + #pragma cyclus var { \ + "tooltip": "input commodity recipe", \ + "doc": "recipe for enrichment facility input commodity", \ + "uitype": "recipe" \ + } std::string in_recipe; - #pragma cyclus var {"tooltip": "tails commodity", \ - "doc": "tails commodity supplied by enrichment facility",\ - "uitype": "outcommodity"} - std::string tails_commod; //QQ - #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ - "doc": "tails assay from the enrichment process"} + #pragma cyclus var { \ + "tooltip": "tails commodity", \ + "doc": "tails commodity supplied by enrichment facility", \ + "uitype": "outcommodity" \ + } + std::string tails_commod; + #pragma cyclus var { \ + "default": 0.03, "tooltip": "tails assay", \ + "doc": "tails assay from the enrichment process" \ + } double tails_assay; - #pragma cyclus var {"default": 1e299, \ - "tooltip": "SWU capacity (kgSWU/month)", \ - "doc": "separative work unit (SWU) capacity of " \ - "enrichment facility (kgSWU/month)"} + #pragma cyclus var { \ + "default": 1e299, \ + "tooltip": "SWU capacity (kgSWU/month)", \ + "doc": "separative work unit (SWU) capacity of enrichment " \ + "facility (kgSWU/month) " \ + } double swu_capacity; - #pragma cyclus var {"default": 1e299, "tooltip": "max inventory size (kg)", \ - "doc": "maximum total inventory of natural uranium in " \ - "the enrichment facility (kg)"} + #pragma cyclus var { \ + "default": 1e299, "tooltip": "max inventory size (kg)", \ + "doc": "maximum total inventory of natural uranium in " \ + "the enrichment facility (kg)" \ + } double max_inv_size; - #pragma cyclus var {"default": 1.0, \ - "tooltip": "maximum allowed enrichment fraction",\ - "doc": "maximum allowed weight fraction of U235 " \ - "in product ", \ - "schema": ' "\\n"\n' \ - ' " \\n"\n' \ - ' " \\n"\n ' \ - ' " 0\\n"\n'\ - ' " 1\\n"\n'\ - ' " \\n"\n ' \ - ' " \\n"\n' \ - ' "\\n"\n'} + #pragma cyclus var { \ + "default": 1.0, \ + "tooltip": "maximum allowed enrichment fraction", \ + "doc": "maximum allowed weight fraction of U235 in product", \ + "schema": ' "\\n"\n' \ + ' " \\n"\n' \ + ' " \\n"\n ' \ + ' " 0\\n"\n' \ + ' " 1\\n"\n' \ + ' " \\n"\n ' \ + ' " \\n"\n' \ + ' "\\n"\n' \ + } double max_enrich; - //QQ - - #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves (kg)",\ - "doc": "amount of natural uranium stored at the " \ - "enrichment facility at the beginning of the " \ - "simulation (kg)"} + + #pragma cyclus var { \ + "default": 0, "tooltip": "initial uranium reserves (kg)", \ + "doc": "amount of natural uranium stored at the enrichment " \ + "facility at the beginning of the simulation (kg)" \ + } double initial_reserves; - #pragma cyclus var {"default": 1,\ - "userlevel": 10, \ - "tooltip": "order material requests by U235 content",\ - "doc": "turn on preference ordering for input material "\ - "so that EF chooses higher U235 content first"} - + #pragma cyclus var { \ + "default": 1, \ + "userlevel": 10, \ + "tooltip": "order material requests by U235 content", \ + "doc": "turn on preference ordering for input material " \ + "so that EF chooses higher U235 content first" \ + } bool order_prefs; - #pragma cyclus var {'derived_init': 'current_swu_capacity = swu_capacity;'} + #pragma cyclus var { 'derived_init': 'current_swu_capacity = swu_capacity;' } double current_swu_capacity; - - - #pragma cyclus var {'capacity': 'max_inv_size'} + #pragma cyclus var { 'capacity': 'max_inv_size' } cyclus::toolkit::ResBuf inventory; // natural u #pragma cyclus var {} cyclus::toolkit::ResBuf tails; // depleted u friend class EnrichmentFacilityTest; }; - + } // namespace cycamore - -#endif // CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ +*/ +#endif // CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ \ No newline at end of file diff --git a/src/enrichment_facility_tests.h b/src/enrichment_facility_tests.h index b2c95ba19d..109eb3a111 100644 --- a/src/enrichment_facility_tests.h +++ b/src/enrichment_facility_tests.h @@ -23,7 +23,7 @@ class EnrichmentFacilityTest : public ::testing::Test { cyclus::Composition::Ptr recipe; TestFacility* trader; - double feed_assay, tails_assay, inv_size, commodity_price, swu_capacity, max_enrich; + double feed_assay, tails_assay, inv_size, swu_capacity, max_enrich; bool order_prefs; diff --git a/src/meg_old_tests/fn_behavior/behavior_functions.cc b/src/meg_old_tests/fn_behavior/behavior_functions.cc deleted file mode 100644 index 6d319e4cf8..0000000000 --- a/src/meg_old_tests/fn_behavior/behavior_functions.cc +++ /dev/null @@ -1,7 +0,0 @@ - - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EveryXTimestep(int curr_time, int interval) { - return curr_time % interval != 0; -} -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/meg_old_tests/fn_behavior/behavior_functions.h b/src/meg_old_tests/fn_behavior/behavior_functions.h deleted file mode 100644 index f3be83c90a..0000000000 --- a/src/meg_old_tests/fn_behavior/behavior_functions.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CYCAMORE_SRC_BEHAVIOR_FUNCTIONS_H_ -#define CYCAMORE_SRC_BEHAVIOR_FUNCTIONS_H_ - - -bool EveryXTimestep(int curr_time, int interval); - - - - - - - - - - - -#endif // CYCAMORE_SRC_BEHAVIOR_FUNCTIONS_H_ diff --git a/src/meg_old_tests/fn_behavior/enrichment_facility.cc b/src/meg_old_tests/fn_behavior/enrichment_facility.cc deleted file mode 100644 index 38c3da6cb7..0000000000 --- a/src/meg_old_tests/fn_behavior/enrichment_facility.cc +++ /dev/null @@ -1,357 +0,0 @@ -// Implements the EnrichmentFacility class -#include "enrichment_facility.h" -#include "behavior_functions.h" - -#include -#include -#include -#include - -#include - -namespace cycamore { - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) - : cyclus::Facility(ctx), - tails_assay(0), - feed_assay(0), - swu_capacity(0), - social_behav(0), //*** - initial_reserves(0), - in_commod(""), - in_recipe(""), - out_commods() {} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -EnrichmentFacility::~EnrichmentFacility() {} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::string EnrichmentFacility::str() { - std::stringstream ss; - - std::string out_commod_msg = ""; - out_commod_msg += " * Output cyclus::Commodities: " ; - for (std::vector::iterator commod = out_commods.begin(); - commod != out_commods.end(); - commod++) { - out_commod_msg += (commod == out_commods.begin() ? "{" : ", "); - out_commod_msg += (*commod); - } - - ss << cyclus::Facility::str() - << " with enrichment facility parameters:" - << " * SWU capacity: " << SwuCapacity() - << " * Tails assay: " << TailsAssay() - << " * Feed assay: " << FeedAssay() - << " * Input cyclus::Commodity: " << in_commodity() - << out_commod_msg ; - return ss.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::Build(cyclus::Agent* parent) { - using cyclus::Material; - - Facility::Build(parent); - if (initial_reserves > 0) { - inventory.Push( - Material::Create( - this, initial_reserves, context()->GetRecipe(in_recipe))); - } - - LOG(cyclus::LEV_DEBUG2, "EnrFac") << "EnrichmentFacility " - << " entering the simuluation: "; - LOG(cyclus::LEV_DEBUG2, "EnrFac") << str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::Tick() { - LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is ticking {"; - LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; - current_swu_capacity = SwuCapacity(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::Tock() { - LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is tocking {"; - LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -EnrichmentFacility::GetMatlRequests() { - using cyclus::Material; - using cyclus::RequestPortfolio; - using cyclus::Request; - - std::set::Ptr> ports; - RequestPortfolio::Ptr port(new RequestPortfolio()); - Material::Ptr mat = Request_(); - double amt = mat->quantity(); - - if (amt > cyclus::eps()) { - port->AddRequest(mat, this, in_commod); - ports.insert(port); - } - - return ports; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::AcceptMatlTrades( - const std::vector< std::pair, - cyclus::Material::Ptr> >& responses) { - // see - // http://stackoverflow.com/questions/5181183/boostshared-ptr-and-inheritance - std::vector< std::pair, - cyclus::Material::Ptr> >::const_iterator it; - for (it = responses.begin(); it != responses.end(); ++it) { - AddMat_(it->second); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -EnrichmentFacility::GetMatlBids( - cyclus::CommodMap::type& commod_requests) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::Converter; - using cyclus::Material; - using cyclus::Request; - - std::set::Ptr> ports; - // *** Add to modify preferences for specific timesteps ***// - if (social_behav) { - int cur_time = context()->time(); - // only trade on every 5th timestep - int interval = 5 ; - if (EveryXTimestep(cur_time, interval)) { - return ports; - // if (cur_time % 5 != 0) { - // return ports; - } - } - if (inventory.quantity() <= 0) { - return ports; - } - - BidPortfolio::Ptr port(new BidPortfolio()); - - for (std::vector::iterator commod = out_commods.begin(); - commod != out_commods.end(); - ++commod) { - if (commod_requests.count(*commod) == 0) { - continue; - } - - std::vector*>& requests = - commod_requests[*commod]; - - std::vector*>::iterator it; - for (it = requests.begin(); it != requests.end(); ++it) { - Request* req = *it; - if (ValidReq(req->target())) { - Material::Ptr offer = Offer_(req->target()); - port->AddBid(req, offer, this); - } - } - } //for each out commod - - Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); - Converter::Ptr nc(new NatUConverter(feed_assay, tails_assay)); - CapacityConstraint swu(swu_capacity, sc); - CapacityConstraint natu(inventory.quantity(), nc); - port->AddConstraint(swu); - port->AddConstraint(natu); - - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() - << " adding a swu constraint of " - << swu.capacity(); - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() - << " adding a natu constraint of " - << natu.capacity(); - ports.insert(port); - - return ports; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EnrichmentFacility::ValidReq(const cyclus::Material::Ptr mat) { - cyclus::toolkit::MatQuery q(mat); - double u235 = q.atom_frac(922350000); - double u238 = q.atom_frac(922380000); - return (u238 > 0 && u235 / (u235 + u238) > TailsAssay()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses) { - using cyclus::Material; - using cyclus::Trade; - - std::vector< Trade >::const_iterator it; - for (it = trades.begin(); it != trades.end(); ++it) { - Material::Ptr mat = it->bid->offer(); - double qty = it->amt; - Material::Ptr response = Enrich_(mat, qty); - responses.push_back(std::make_pair(*it, response)); - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() - << " just received an order" - << " for " << it->amt - << " of " << it->bid->request()->commodity() ; - } - - if (cyclus::IsNegative(current_swu_capacity)) { - throw cyclus::ValueError( - "EnrFac " + prototype() - + " is being asked to provide more than its SWU capacity."); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { - if (mat->comp() != context()->GetRecipe(in_recipe)) { - throw cyclus::ValueError( - "EnrichmentFacility recipe and material composition not the same."); - } - - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " is initially holding " - << inventory.quantity() << " total."; - - try { - inventory.Push(mat); - } catch (cyclus::Error& e) { - e.msg(Agent::InformErrorMsg(e.msg())); - throw e; - } - - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " added " - << mat->quantity() << " of " << in_commod - << " to its inventory, which is holding " - << inventory.quantity() << " total."; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacility::Request_() { - double qty = std::max(0.0, MaxInventorySize() - InventorySize()); - return cyclus::Material::CreateUntracked(qty, - context()->GetRecipe(in_recipe)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { - cyclus::toolkit::MatQuery q(mat); - cyclus::CompMap comp; - comp[922350000] = q.atom_frac(922350000); - comp[922380000] = q.atom_frac(922380000); - return cyclus::Material::CreateUntracked( - mat->quantity(), cyclus::Composition::CreateFromAtom(comp)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacility::Enrich_( - cyclus::Material::Ptr mat, - double qty) { - using cyclus::Material; - using cyclus::ResCast; - using cyclus::toolkit::Assays; - using cyclus::toolkit::UraniumAssay; - using cyclus::toolkit::SwuRequired; - using cyclus::toolkit::FeedQty; - using cyclus::toolkit::TailsQty; - - // get enrichment parameters - Assays assays(FeedAssay(), UraniumAssay(mat), TailsAssay()); - double swu_req = SwuRequired(qty, assays); - double natu_req = FeedQty(qty, assays); - - // pop amount from inventory and blob it into one material - std::vector manifest; - try { - // required so popping doesn't take out too much - if (cyclus::AlmostEq(natu_req, inventory.quantity())) { - manifest = ResCast(inventory.PopN(inventory.count())); - } else { - manifest = ResCast(inventory.PopQty(natu_req)); - } - } catch (cyclus::Error& e) { - NatUConverter nc(feed_assay, tails_assay); - std::stringstream ss; - ss << " tried to remove " << natu_req - << " from its inventory of size " << inventory.quantity() - << " and the conversion of the material into natu is " - << nc.convert(mat); - throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); - } - Material::Ptr r = manifest[0]; - for (int i = 1; i < manifest.size(); ++i) { - r->Absorb(manifest[i]); - } - - // "enrich" it, but pull out the composition and quantity we require from the - // blob - cyclus::Composition::Ptr comp = mat->comp(); - Material::Ptr response = r->ExtractComp(qty, comp); - tails.Push(r); // add remainder to tails buffer - - current_swu_capacity -= swu_req; - - RecordEnrichment_(natu_req, swu_req); - - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << - " has performed an enrichment: "; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Feed Qty: " - << natu_req; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Feed Assay: " - << assays.Feed() * 100; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Product Qty: " - << qty; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Product Assay: " - << assays.Product() * 100; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Tails Qty: " - << TailsQty(qty, assays); - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Tails Assay: " - << assays.Tails() * 100; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * SWU: " - << swu_req; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Current SWU capacity: " - << CurrentSwuCapacity(); - - return response; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::RecordEnrichment_(double natural_u, double swu) { - using cyclus::Context; - using cyclus::Agent; - - LOG(cyclus::LEV_DEBUG1, "EnrFac") << prototype() - << " has enriched a material:"; - LOG(cyclus::LEV_DEBUG1, "EnrFac") << " * Amount: " << natural_u; - LOG(cyclus::LEV_DEBUG1, "EnrFac") << " * SWU: " << swu; - - Context* ctx = Agent::context(); - ctx->NewDatum("Enrichments") - ->AddVal("ID", id()) - ->AddVal("Time", ctx->time()) - ->AddVal("Natural_Uranium", natural_u) - ->AddVal("SWU", swu) - ->Record(); -} -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -/* - bool EnrichmentFacility::EveryXTimestep(int curr_time, int interval) { - return curr_time % interval != 0; -} -*/ -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern "C" cyclus::Agent* ConstructEnrichmentFacility(cyclus::Context* ctx) { - return new EnrichmentFacility(ctx); -} - -} // namespace cycamore diff --git a/src/meg_old_tests/fn_behavior/enrichment_facility.h b/src/meg_old_tests/fn_behavior/enrichment_facility.h deleted file mode 100644 index cee712c5c5..0000000000 --- a/src/meg_old_tests/fn_behavior/enrichment_facility.h +++ /dev/null @@ -1,324 +0,0 @@ -#ifndef CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ -#define CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ - -#include - -#include "cyclus.h" - -namespace cycamore { - -/// @class SWUConverter -/// -/// @brief The SWUConverter is a simple Converter class for material to -/// determine the amount of SWU required for their proposed enrichment -class SWUConverter : public cyclus::Converter { - public: - SWUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} - virtual ~SWUConverter() {} - - /// @brief provides a conversion for the SWU required - virtual double convert( - cyclus::Material::Ptr m, - cyclus::Arc const * a = NULL, - cyclus::ExchangeTranslationContext - const * ctx = NULL) const { - cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), - tails_); - return cyclus::toolkit::SwuRequired(m->quantity(), assays); - } - - /// @returns true if Converter is a SWUConverter and feed and tails equal - virtual bool operator==(Converter& other) const { - SWUConverter* cast = dynamic_cast(&other); - return cast != NULL && - feed_ == cast->feed_ && - tails_ == cast->tails_; - } - - private: - double feed_, tails_; -}; - -/// @class NatUConverter -/// -/// @brief The NatUConverter is a simple Converter class for material to -/// determine the amount of natural uranium required for their proposed -/// enrichment -class NatUConverter : public cyclus::Converter { - public: - NatUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} - virtual ~NatUConverter() {} - - /// @brief provides a conversion for the amount of natural Uranium required - virtual double convert( - cyclus::Material::Ptr m, - cyclus::Arc const * a = NULL, - cyclus::ExchangeTranslationContext - const * ctx = NULL) const { - cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), - tails_); - return cyclus::toolkit::FeedQty(m->quantity(), assays); - } - - /// @returns true if Converter is a NatUConverter and feed and tails equal - virtual bool operator==(Converter& other) const { - NatUConverter* cast = dynamic_cast(&other); - return cast != NULL && - feed_ == cast->feed_ && - tails_ == cast->tails_; - } - - private: - double feed_, tails_; -}; - -/// @class EnrichmentFacility -/// -/// @section introduction Introduction -/// The EnrichmentFacility is a simple Agent to agent the enriching of natural -/// Uranium in a Cyclus simulation. It requests its input recipe (nominally -/// natural Uranium), and produces any amount of enriched Uranium, given the its -/// natural uranium inventory constraint and its SWU capacity constraint. -/// -/// @section requests Requests -/// The EnrichmentFacility will request from the cyclus::ResourceExchange a -/// cyclus::Material whose quantity is its remaining inventory capacity and whose -/// composition is that of its input recipe. -/// -/// @section acctrade Accepting Trades -/// The EnrichmentFacility adds any accepted trades to its inventory. -/// -/// @section bids Bids -/// The EnrichmentFacility will bid on any request for its output commodities. It -/// will bid either the request quantity, or the quanity associated with either -/// its SWU constraint or natural uranium constraint, whichever is lower. -/// -/// @section extrades Executing Trades -/// The EnrichmentFacility will execute trades for its output commodities in the -/// following manner: -/// #. Determine the trade's quantity and product assay -/// #. Determine the natural Uranium and SWU requires to create that product -/// #. Remove the required quantity of natural Uranium from its inventory -/// #. Extract the appropriate composition of enriched Uranium -/// #. Send the enriched Uranium as the trade resource -/// -/// @section gotchas Gotchas -/// #. In its current form, the EnrichmentFacility can only accept -/// cyclus::Material having the composition of its input recipe. If a -/// cyclus::Material of a different composition is sent to it, an exception will -/// be thrown. -/// -/// #. During the trading phase, an exception will be thrown if either the -/// EnrichmentFacility's SWU or inventory constraint is breached. -/// -/// @section improvements Improvments -/// The primary improvement to the EnrichmentFacility would be to relax the -/// requirement that all input material have the in_recipe composition (i.e., -/// allow different base enrichments of Uranium). -/// -/// How would I go about doing so? I'd likely develop an EnrichmentBuffer-type -/// class that can be queried as to its SWU and natural Uranium capacity. -class EnrichmentFacility : public cyclus::Facility { - public: - // --- Module Members --- -/// Constructor for the EnrichmentFacility class -/// @param ctx the cyclus context for access to simulation-wide parameters - EnrichmentFacility(cyclus::Context* ctx); - -/// Destructor for the EnrichmentFacility class - virtual ~EnrichmentFacility(); - - #pragma cyclus - - #pragma cyclus note {"doc": "An enrichment facility that intakes a commodity " \ - "(usually natural uranium) and supplies a user-" \ - "specified enriched product based on SWU capacity", \ - "niche": "enrichment"} - -/// Print information about this agent - virtual std::string str(); - // --- - - // --- Facility Members --- - /// perform module-specific tasks when entering the simulation - virtual void Build(cyclus::Agent* parent); - // --- - - // --- Agent Members --- - /// Each facility is prompted to do its beginning-of-time-step - /// stuff at the tick of the timer. - - /// @param time is the time to perform the tick - virtual void Tick(); - - /// Each facility is prompted to its end-of-time-step - /// stuff on the tock of the timer. - - /// @param time is the time to perform the tock - virtual void Tock(); - - /// @brief The EnrichmentFacility request Materials of its given - /// commodity. - virtual std::set::Ptr> - GetMatlRequests(); - - /// @brief The EnrichmentFacility place accepted trade Materials in their - /// Inventory - virtual void AcceptMatlTrades( - const std::vector< std::pair, - cyclus::Material::Ptr> >& responses); - - /// @brief Responds to each request for this facility's commodity. If a given - /// request is more than this facility's inventory or SWU capacity, it will - /// offer its minimum of its capacities. - virtual std::set::Ptr> - GetMatlBids(cyclus::CommodMap::type& - commod_requests); - - /// @brief respond to each trade with a material enriched to the appropriate - /// level given this facility's inventory - /// - /// @param trades all trades in which this trader is the supplier - /// @param responses a container to populate with responses to each trade - virtual void GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses); - // --- - - // --- EnrichmentFacility Members --- - /// @brief Determines if a particular material is a valid request to respond - /// to. Valid requests must contain U235 and U238 and must have a relative - /// U235-to-U238 ratio less than this facility's tails_assay(). - /// @return true if the above description is met by the material - bool ValidReq(const cyclus::Material::Ptr mat); - - inline void in_commodity(std::string in_com) { in_commod = in_com; } - - inline std::string in_commodity() const { return in_commod; } - - inline void out_commodities(std::vector out_com) { - out_commods = out_com; - } - - inline const std::vector& - out_commodities() const { return out_commods; } - - inline void InRecipe(std::string in_rec) { in_recipe = in_rec; } - - inline std::string InRecipe() const { return in_recipe; } - - inline void SetMaxInventorySize(double size) { - max_inv_size = size; - inventory.set_capacity(size); - } - - inline double MaxInventorySize() const { return inventory.capacity(); } - - inline double InventorySize() const { return inventory.quantity(); } - - inline void FeedAssay(double assay) { feed_assay = assay; } - - inline double FeedAssay() const { return feed_assay; } - - inline void TailsAssay(double assay) { tails_assay = assay; } - - inline double TailsAssay() const { return tails_assay; } - - inline void SwuCapacity(double capacity) { - swu_capacity = capacity; - current_swu_capacity = swu_capacity; - } - inline double SwuCapacity() const { return swu_capacity; } - - inline double CurrentSwuCapacity() const { return current_swu_capacity; } - - /// @brief this facility's initial conditions - inline void InitialReserves(double qty) { initial_reserves = qty; } - inline double InitialReserves() const { return initial_reserves; } - - inline const cyclus::toolkit::ResourceBuff& Tails() const { return tails; } - - private: - /// @brief adds a material into the natural uranium inventory - /// @throws if the material is not the same composition as the in_recipe - void AddMat_(cyclus::Material::Ptr mat); - - /// @brief generates a request for this facility given its current state. The - /// quantity of the material will be equal to the remaining inventory size. - cyclus::Material::Ptr Request_(); - - /// @brief Generates a material offer for a given request. The response - /// composition will be comprised only of U235 and U238 at their relative ratio - /// in the requested material. The response quantity will be the same as the - /// requested commodity. - /// - /// @param req the requested material being responded to - cyclus::Material::Ptr Offer_(cyclus::Material::Ptr req); - - cyclus::Material::Ptr Enrich_(cyclus::Material::Ptr mat, double qty); - - /// @brief records and enrichment with the cyclus::Recorder - void RecordEnrichment_(double natural_u, double swu); - - // bool EveryXTimestep(int curr_time, int interval); - - #pragma cyclus var {"tooltip": "input commodity", \ - "doc": "commodity that the enrichment facility accepts", \ - "uitype": "incommodity"} - std::string in_commod; - - #pragma cyclus var {"tooltip": "output commodities", \ - "doc": "commodities that the enrichment facility supplies"} //, \ - // "uitype": ["oneormore", "outcommodity"]} - std::vector out_commods; - - #pragma cyclus var {"tooltip": "input commodity recipe", \ - "doc": "recipe for enrichment facility's input commodity", \ - "uitype": "recipe"} - std::string in_recipe; - - #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ - "doc": "tails assay from the enrichment process"} - double tails_assay; - #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity", \ - "doc": "separative work unit (SWU) capcity of " \ - "enrichment facility"} - double swu_capacity; - #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size", \ - "doc": "maximum inventory capacity of natural uranium in " \ - "the enrichment facility"} - double max_inv_size; - - #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves", \ - "doc": "amount of natural uranium stored at the " \ - "enrichment facility at the beginning of the " \ - "simulation"} - double initial_reserves; - //*** - #pragma cyclus var {"default": 0, "tooltip": "social behavior" , \ - "doc": "if set to 1 then enable social behavior " \ - "in trade decisions"} - bool social_behav; - //*** - #pragma cyclus var {'derived_init': 'current_swu_capacity = swu_capacity;'} - double current_swu_capacity; - #pragma cyclus var {\ - 'derived_init': "cyclus::Material::Ptr feed = "\ - "cyclus::Material::CreateUntracked(0, context()->GetRecipe(in_recipe)); "\ - "feed_assay = cyclus::toolkit::UraniumAssay(feed);", \ - "tooltip": "feed assay", \ - "doc": "feed assay for the enrichment process"} - double feed_assay; - #pragma cyclus var {'capacity': 'max_inv_size'} - cyclus::toolkit::ResourceBuff inventory; // of natl u - #pragma cyclus var {} - cyclus::toolkit::ResourceBuff tails; // depleted u - - friend class EnrichmentFacilityTest; - // --- -}; - -} // namespace cycamore - -#endif // CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ diff --git a/src/meg_old_tests/fn_consider/CMakeLists.txt b/src/meg_old_tests/fn_consider/CMakeLists.txt deleted file mode 100644 index c7ab466fb9..0000000000 --- a/src/meg_old_tests/fn_consider/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -# ------------------- Add all Concrete Agents ---------------------------- - -USE_CYCLUS("cycamore" "batch_reactor") - -USE_CYCLUS("cycamore" "enrichment_facility") - -#USE_CYCLUS("cycamore" "inpro_reactor") - -USE_CYCLUS("cycamore" "sink") - -USE_CYCLUS("cycamore" "source") - -USE_CYCLUS("cycamore" "deploy_inst") - -USE_CYCLUS("cycamore" "manager_inst") - -USE_CYCLUS("cycamore" "growth_region") - -INSTALL_CYCLUS_MODULE("cycamore" "" "NONE") - -SET(TestSource ${cycamore_TEST_CC} PARENT_SCOPE) - -# install header files -FILE(GLOB h_files "${CMAKE_CURRENT_SOURCE_DIR}/*.h") -INSTALL(FILES ${h_files} DESTINATION include/cycamore COMPONENT cycamore) diff --git a/src/meg_old_tests/fn_consider/enrichment_facility.cc b/src/meg_old_tests/fn_consider/enrichment_facility.cc deleted file mode 100644 index 344f44645f..0000000000 --- a/src/meg_old_tests/fn_consider/enrichment_facility.cc +++ /dev/null @@ -1,392 +0,0 @@ -// Implements the EnrichmentFacility class -#include "enrichment_facility.h" - -#include -#include -#include -#include - -#include - -namespace cycamore { - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) - : cyclus::Facility(ctx), - tails_assay(0), - feed_assay(0), - swu_capacity(0), - social_behav(0), //*** - initial_reserves(0), - in_commod(""), - in_recipe(""), - out_commods() {} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -EnrichmentFacility::~EnrichmentFacility() {} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::string EnrichmentFacility::str() { - std::stringstream ss; - - std::string out_commod_msg = ""; - out_commod_msg += " * Output cyclus::Commodities: " ; - for (std::vector::iterator commod = out_commods.begin(); - commod != out_commods.end(); - commod++) { - out_commod_msg += (commod == out_commods.begin() ? "{" : ", "); - out_commod_msg += (*commod); - } - - ss << cyclus::Facility::str() - << " with enrichment facility parameters:" - << " * SWU capacity: " << SwuCapacity() - << " * Tails assay: " << TailsAssay() - << " * Feed assay: " << FeedAssay() - << " * Input cyclus::Commodity: " << in_commodity() - << out_commod_msg ; - return ss.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::Build(cyclus::Agent* parent) { - using cyclus::Material; - - Facility::Build(parent); - if (initial_reserves > 0) { - inventory.Push( - Material::Create( - this, initial_reserves, context()->GetRecipe(in_recipe))); - } - - LOG(cyclus::LEV_DEBUG2, "EnrFac") << "EnrichmentFacility " - << " entering the simuluation: "; - LOG(cyclus::LEV_DEBUG2, "EnrFac") << str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::Tick() { - LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is ticking {"; - LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; - current_swu_capacity = SwuCapacity(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::Tock() { - LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is tocking {"; - LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -EnrichmentFacility::GetMatlRequests() { - using cyclus::Material; - using cyclus::RequestPortfolio; - using cyclus::Request; - - std::set::Ptr> ports; - RequestPortfolio::Ptr port(new RequestPortfolio()); - Material::Ptr mat = Request_(); - double amt = mat->quantity(); - - if (amt > cyclus::eps()) { - port->AddRequest(mat, this, in_commod); - ports.insert(port); - } - - return ports; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::AcceptMatlTrades( - const std::vector< std::pair, - cyclus::Material::Ptr> >& responses) { - // see - // http://stackoverflow.com/questions/5181183/boostshared-ptr-and-inheritance - std::vector< std::pair, - cyclus::Material::Ptr> >::const_iterator it; - for (it = responses.begin(); it != responses.end(); ++it) { - AddMat_(it->second); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -EnrichmentFacility::GetMatlBids( - cyclus::CommodMap::type& commod_requests) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::Converter; - using cyclus::Material; - using cyclus::Request; - - std::set::Ptr> all_ports; -/* - // returns empty portfolio for all bids at certain timesteps - if (social_behav) { - int cur_time = context()->time(); - // only trade on every 5th timestep - int interval = 5 ; - if (EveryXTimestep(cur_time, interval)) { - return ports; - // if (cur_time % 5 != 0) { - // return all_ports; - } - } -*/ - if (inventory.quantity() <= 0) { - return all_ports; - } - - BidPortfolio::Ptr port = ConsiderMatlRequests(commod_requests); - - Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); - Converter::Ptr nc(new NatUConverter(feed_assay, tails_assay)); - CapacityConstraint swu(swu_capacity, sc); - CapacityConstraint natu(inventory.quantity(), nc); - port->AddConstraint(swu); - port->AddConstraint(natu); - - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() - << " adding a swu constraint of " - << swu.capacity(); - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() - << " adding a natu constraint of " - << natu.capacity(); - all_ports.insert(port); - - return all_ports; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EnrichmentFacility::ValidReq(const cyclus::Material::Ptr mat) { - cyclus::toolkit::MatQuery q(mat); - double u235 = q.atom_frac(922350000); - double u238 = q.atom_frac(922380000); - return (u238 > 0 && u235 / (u235 + u238) > TailsAssay()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses) { - using cyclus::Material; - using cyclus::Trade; - - std::vector< Trade >::const_iterator it; - for (it = trades.begin(); it != trades.end(); ++it) { - Material::Ptr mat = it->bid->offer(); - double qty = it->amt; - Material::Ptr response = Enrich_(mat, qty); - responses.push_back(std::make_pair(*it, response)); - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() - << " just received an order" - << " for " << it->amt - << " of " << it->bid->request()->commodity() ; - } - - if (cyclus::IsNegative(current_swu_capacity)) { - throw cyclus::ValueError( - "EnrFac " + prototype() - + " is being asked to provide more than its SWU capacity."); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { - if (mat->comp() != context()->GetRecipe(in_recipe)) { - throw cyclus::ValueError( - "EnrichmentFacility recipe and material composition not the same."); - } - - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " is initially holding " - << inventory.quantity() << " total."; - - try { - inventory.Push(mat); - } catch (cyclus::Error& e) { - e.msg(Agent::InformErrorMsg(e.msg())); - throw e; - } - - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " added " - << mat->quantity() << " of " << in_commod - << " to its inventory, which is holding " - << inventory.quantity() << " total."; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacility::Request_() { - double qty = std::max(0.0, MaxInventorySize() - InventorySize()); - return cyclus::Material::CreateUntracked(qty, - context()->GetRecipe(in_recipe)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { - cyclus::toolkit::MatQuery q(mat); - cyclus::CompMap comp; - comp[922350000] = q.atom_frac(922350000); - comp[922380000] = q.atom_frac(922380000); - return cyclus::Material::CreateUntracked( - mat->quantity(), cyclus::Composition::CreateFromAtom(comp)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacility::Enrich_( - cyclus::Material::Ptr mat, - double qty) { - using cyclus::Material; - using cyclus::ResCast; - using cyclus::toolkit::Assays; - using cyclus::toolkit::UraniumAssay; - using cyclus::toolkit::SwuRequired; - using cyclus::toolkit::FeedQty; - using cyclus::toolkit::TailsQty; - - // get enrichment parameters - Assays assays(FeedAssay(), UraniumAssay(mat), TailsAssay()); - double swu_req = SwuRequired(qty, assays); - double natu_req = FeedQty(qty, assays); - - // pop amount from inventory and blob it into one material - std::vector manifest; - try { - // required so popping doesn't take out too much - if (cyclus::AlmostEq(natu_req, inventory.quantity())) { - manifest = ResCast(inventory.PopN(inventory.count())); - } else { - manifest = ResCast(inventory.PopQty(natu_req)); - } - } catch (cyclus::Error& e) { - NatUConverter nc(feed_assay, tails_assay); - std::stringstream ss; - ss << " tried to remove " << natu_req - << " from its inventory of size " << inventory.quantity() - << " and the conversion of the material into natu is " - << nc.convert(mat); - throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); - } - Material::Ptr r = manifest[0]; - for (int i = 1; i < manifest.size(); ++i) { - r->Absorb(manifest[i]); - } - - // "enrich" it, but pull out the composition and quantity we require from the - // blob - cyclus::Composition::Ptr comp = mat->comp(); - Material::Ptr response = r->ExtractComp(qty, comp); - tails.Push(r); // add remainder to tails buffer - - current_swu_capacity -= swu_req; - - RecordEnrichment_(natu_req, swu_req); - - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << - " has performed an enrichment: "; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Feed Qty: " - << natu_req; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Feed Assay: " - << assays.Feed() * 100; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Product Qty: " - << qty; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Product Assay: " - << assays.Product() * 100; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Tails Qty: " - << TailsQty(qty, assays); - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Tails Assay: " - << assays.Tails() * 100; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * SWU: " - << swu_req; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Current SWU capacity: " - << CurrentSwuCapacity(); - - return response; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::RecordEnrichment_(double natural_u, double swu) { - using cyclus::Context; - using cyclus::Agent; - - LOG(cyclus::LEV_DEBUG1, "EnrFac") << prototype() - << " has enriched a material:"; - LOG(cyclus::LEV_DEBUG1, "EnrFac") << " * Amount: " << natural_u; - LOG(cyclus::LEV_DEBUG1, "EnrFac") << " * SWU: " << swu; - - Context* ctx = Agent::context(); - ctx->NewDatum("Enrichments") - ->AddVal("ID", id()) - ->AddVal("Time", ctx->time()) - ->AddVal("Natural_Uranium", natural_u) - ->AddVal("SWU", swu) - ->Record(); -} -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EnrichmentFacility::EveryXTimestep(int curr_time, int interval) { - return curr_time % interval != 0; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Decide whether each individual bid will be responded to. -cyclus::BidPortfolio::Ptr -EnrichmentFacility::ConsiderMatlRequests( - cyclus::CommodMap::type& commod_requests) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::Material; - using cyclus::Request; - - // std::set::Ptr> ports; - - BidPortfolio::Ptr port(new BidPortfolio()); - - for (std::vector::iterator commod = out_commods.begin(); - commod != out_commods.end(); - ++commod) { - if (commod_requests.count(*commod) == 0) { - continue; - } - - std::vector*>& requests = - commod_requests[*commod]; - - std::vector*>::iterator it; - for (it = requests.begin(); it != requests.end(); ++it) { - Request* req = *it; - /* add check that request is desirable */ - Material::Ptr mat = Request_(); - double enrich_limit ; - /* if (social_behav) { - enrich_limit = 0.1 ; // do not trade to facilities that want HEU - } else { - enrich_limit = 1.0 ; - } - */ - enrich_limit = 0.1; - double request_enrich = cyclus::toolkit::UraniumAssay(mat) ; - int cur_time = context()->time(); - int interval = 5 ; // only trade on every 5th timestep - if (ValidReq(req->target())) { // This check is always done - if ((request_enrich <= enrich_limit) // LEU facility - || (EveryXTimestep(cur_time, interval))) // HEU every 5th time - { - Material::Ptr offer = Offer_(req->target()); - port->AddBid(req, offer, this); - } - } - } - } //for each out commod - - return port; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern "C" cyclus::Agent* ConstructEnrichmentFacility(cyclus::Context* ctx) { - return new EnrichmentFacility(ctx); -} - -} // namespace cycamore diff --git a/src/meg_old_tests/fn_consider/enrichment_facility.h b/src/meg_old_tests/fn_consider/enrichment_facility.h deleted file mode 100644 index 5832eb8fe4..0000000000 --- a/src/meg_old_tests/fn_consider/enrichment_facility.h +++ /dev/null @@ -1,331 +0,0 @@ -#ifndef CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ -#define CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ - -#include - -#include "cyclus.h" - -namespace cycamore { - -/// @class SWUConverter -/// -/// @brief The SWUConverter is a simple Converter class for material to -/// determine the amount of SWU required for their proposed enrichment -class SWUConverter : public cyclus::Converter { - public: - SWUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} - virtual ~SWUConverter() {} - - /// @brief provides a conversion for the SWU required - virtual double convert( - cyclus::Material::Ptr m, - cyclus::Arc const * a = NULL, - cyclus::ExchangeTranslationContext - const * ctx = NULL) const { - cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), - tails_); - return cyclus::toolkit::SwuRequired(m->quantity(), assays); - } - - /// @returns true if Converter is a SWUConverter and feed and tails equal - virtual bool operator==(Converter& other) const { - SWUConverter* cast = dynamic_cast(&other); - return cast != NULL && - feed_ == cast->feed_ && - tails_ == cast->tails_; - } - - private: - double feed_, tails_; -}; - -/// @class NatUConverter -/// -/// @brief The NatUConverter is a simple Converter class for material to -/// determine the amount of natural uranium required for their proposed -/// enrichment -class NatUConverter : public cyclus::Converter { - public: - NatUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} - virtual ~NatUConverter() {} - - /// @brief provides a conversion for the amount of natural Uranium required - virtual double convert( - cyclus::Material::Ptr m, - cyclus::Arc const * a = NULL, - cyclus::ExchangeTranslationContext - const * ctx = NULL) const { - cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), - tails_); - return cyclus::toolkit::FeedQty(m->quantity(), assays); - } - - /// @returns true if Converter is a NatUConverter and feed and tails equal - virtual bool operator==(Converter& other) const { - NatUConverter* cast = dynamic_cast(&other); - return cast != NULL && - feed_ == cast->feed_ && - tails_ == cast->tails_; - } - - private: - double feed_, tails_; -}; - -/// @class EnrichmentFacility -/// -/// @section introduction Introduction -/// The EnrichmentFacility is a simple Agent to agent the enriching of natural -/// Uranium in a Cyclus simulation. It requests its input recipe (nominally -/// natural Uranium), and produces any amount of enriched Uranium, given the its -/// natural uranium inventory constraint and its SWU capacity constraint. -/// -/// @section requests Requests -/// The EnrichmentFacility will request from the cyclus::ResourceExchange a -/// cyclus::Material whose quantity is its remaining inventory capacity and whose -/// composition is that of its input recipe. -/// -/// @section acctrade Accepting Trades -/// The EnrichmentFacility adds any accepted trades to its inventory. -/// -/// @section bids Bids -/// The EnrichmentFacility will bid on any request for its output commodities. It -/// will bid either the request quantity, or the quanity associated with either -/// its SWU constraint or natural uranium constraint, whichever is lower. -/// -/// @section extrades Executing Trades -/// The EnrichmentFacility will execute trades for its output commodities in the -/// following manner: -/// #. Determine the trade's quantity and product assay -/// #. Determine the natural Uranium and SWU requires to create that product -/// #. Remove the required quantity of natural Uranium from its inventory -/// #. Extract the appropriate composition of enriched Uranium -/// #. Send the enriched Uranium as the trade resource -/// -/// @section gotchas Gotchas -/// #. In its current form, the EnrichmentFacility can only accept -/// cyclus::Material having the composition of its input recipe. If a -/// cyclus::Material of a different composition is sent to it, an exception will -/// be thrown. -/// -/// #. During the trading phase, an exception will be thrown if either the -/// EnrichmentFacility's SWU or inventory constraint is breached. -/// -/// @section improvements Improvments -/// The primary improvement to the EnrichmentFacility would be to relax the -/// requirement that all input material have the in_recipe composition (i.e., -/// allow different base enrichments of Uranium). -/// -/// How would I go about doing so? I'd likely develop an EnrichmentBuffer-type -/// class that can be queried as to its SWU and natural Uranium capacity. -class EnrichmentFacility : public cyclus::Facility { - public: - // --- Module Members --- -/// Constructor for the EnrichmentFacility class -/// @param ctx the cyclus context for access to simulation-wide parameters - EnrichmentFacility(cyclus::Context* ctx); - -/// Destructor for the EnrichmentFacility class - virtual ~EnrichmentFacility(); - - #pragma cyclus - - #pragma cyclus note {"doc": "An enrichment facility that intakes a commodity " \ - "(usually natural uranium) and supplies a user-" \ - "specified enriched product based on SWU capacity", \ - "niche": "enrichment"} - -/// Print information about this agent - virtual std::string str(); - // --- - - // --- Facility Members --- - /// perform module-specific tasks when entering the simulation - virtual void Build(cyclus::Agent* parent); - // --- - - // --- Agent Members --- - /// Each facility is prompted to do its beginning-of-time-step - /// stuff at the tick of the timer. - - /// @param time is the time to perform the tick - virtual void Tick(); - - /// Each facility is prompted to its end-of-time-step - /// stuff on the tock of the timer. - - /// @param time is the time to perform the tock - virtual void Tock(); - - /// @brief The EnrichmentFacility request Materials of its given - /// commodity. - virtual std::set::Ptr> - GetMatlRequests(); - - /// @brief The EnrichmentFacility place accepted trade Materials in their - /// Inventory - virtual void AcceptMatlTrades( - const std::vector< std::pair, - cyclus::Material::Ptr> >& responses); - - /// @brief Responds to each request for this facility's commodity. If a given - /// request is more than this facility's inventory or SWU capacity, it will - /// offer its minimum of its capacities. - virtual std::set::Ptr> - GetMatlBids(cyclus::CommodMap::type& - commod_requests); - - /// @brief respond to each trade with a material enriched to the appropriate - /// level given this facility's inventory - /// - /// @param trades all trades in which this trader is the supplier - /// @param responses a container to populate with responses to each trade - virtual void GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses); - // --- - - // --- EnrichmentFacility Members --- - /// @brief Determines if a particular material is a valid request to respond - /// to. Valid requests must contain U235 and U238 and must have a relative - /// U235-to-U238 ratio less than this facility's tails_assay(). - /// @return true if the above description is met by the material - bool ValidReq(const cyclus::Material::Ptr mat); - - /// @brief Determines if a particular request will be responded to - /// based on user specification such as maximum allowed enrichment - /// or other behavior parameters. - virtual cyclus::BidPortfolio::Ptr - ConsiderMatlRequests(cyclus::CommodMap::type& - commod_requests); - - inline void in_commodity(std::string in_com) { in_commod = in_com; } - - inline std::string in_commodity() const { return in_commod; } - - inline void out_commodities(std::vector out_com) { - out_commods = out_com; - } - - inline const std::vector& - out_commodities() const { return out_commods; } - - inline void InRecipe(std::string in_rec) { in_recipe = in_rec; } - - inline std::string InRecipe() const { return in_recipe; } - - inline void SetMaxInventorySize(double size) { - max_inv_size = size; - inventory.set_capacity(size); - } - - inline double MaxInventorySize() const { return inventory.capacity(); } - - inline double InventorySize() const { return inventory.quantity(); } - - inline void FeedAssay(double assay) { feed_assay = assay; } - - inline double FeedAssay() const { return feed_assay; } - - inline void TailsAssay(double assay) { tails_assay = assay; } - - inline double TailsAssay() const { return tails_assay; } - - inline void SwuCapacity(double capacity) { - swu_capacity = capacity; - current_swu_capacity = swu_capacity; - } - inline double SwuCapacity() const { return swu_capacity; } - - inline double CurrentSwuCapacity() const { return current_swu_capacity; } - - /// @brief this facility's initial conditions - inline void InitialReserves(double qty) { initial_reserves = qty; } - inline double InitialReserves() const { return initial_reserves; } - - inline const cyclus::toolkit::ResourceBuff& Tails() const { return tails; } - - private: - /// @brief adds a material into the natural uranium inventory - /// @throws if the material is not the same composition as the in_recipe - void AddMat_(cyclus::Material::Ptr mat); - - /// @brief generates a request for this facility given its current state. The - /// quantity of the material will be equal to the remaining inventory size. - cyclus::Material::Ptr Request_(); - - /// @brief Generates a material offer for a given request. The response - /// composition will be comprised only of U235 and U238 at their relative ratio - /// in the requested material. The response quantity will be the same as the - /// requested commodity. - /// - /// @param req the requested material being responded to - cyclus::Material::Ptr Offer_(cyclus::Material::Ptr req); - - cyclus::Material::Ptr Enrich_(cyclus::Material::Ptr mat, double qty); - - /// @brief records and enrichment with the cyclus::Recorder - void RecordEnrichment_(double natural_u, double swu); - - bool EveryXTimestep(int curr_time, int interval); - - #pragma cyclus var {"tooltip": "input commodity", \ - "doc": "commodity that the enrichment facility accepts", \ - "uitype": "incommodity"} - std::string in_commod; - - #pragma cyclus var {"tooltip": "output commodities", \ - "doc": "commodities that the enrichment facility supplies"} //, \ - // "uitype": ["oneormore", "outcommodity"]} - std::vector out_commods; - - #pragma cyclus var {"tooltip": "input commodity recipe", \ - "doc": "recipe for enrichment facility's input commodity", \ - "uitype": "recipe"} - std::string in_recipe; - - #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ - "doc": "tails assay from the enrichment process"} - double tails_assay; - #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity", \ - "doc": "separative work unit (SWU) capcity of " \ - "enrichment facility"} - double swu_capacity; - #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size", \ - "doc": "maximum inventory capacity of natural uranium in " \ - "the enrichment facility"} - double max_inv_size; - - #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves", \ - "doc": "amount of natural uranium stored at the " \ - "enrichment facility at the beginning of the " \ - "simulation"} - double initial_reserves; - //*** - #pragma cyclus var {"default": 0, "tooltip": "social behavior" , \ - "doc": "if set to 1 then enable social behavior " \ - "in trade decisions"} - bool social_behav; - //*** - #pragma cyclus var {'derived_init': 'current_swu_capacity = swu_capacity;'} - double current_swu_capacity; - #pragma cyclus var {\ - 'derived_init': "cyclus::Material::Ptr feed = "\ - "cyclus::Material::CreateUntracked(0, context()->GetRecipe(in_recipe)); "\ - "feed_assay = cyclus::toolkit::UraniumAssay(feed);", \ - "tooltip": "feed assay", \ - "doc": "feed assay for the enrichment process"} - double feed_assay; - #pragma cyclus var {'capacity': 'max_inv_size'} - cyclus::toolkit::ResourceBuff inventory; // of natl u - #pragma cyclus var {} - cyclus::toolkit::ResourceBuff tails; // depleted u - - friend class EnrichmentFacilityTest; - // --- -}; - -} // namespace cycamore - -#endif // CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ diff --git a/src/meg_old_tests/fn_consider/enrichment_facility_tests.cc b/src/meg_old_tests/fn_consider/enrichment_facility_tests.cc deleted file mode 100644 index 0d66a62fcf..0000000000 --- a/src/meg_old_tests/fn_consider/enrichment_facility_tests.cc +++ /dev/null @@ -1,725 +0,0 @@ -#include - -#include - -#include "facility_tests.h" -#include "toolkit/mat_query.h" -#include "agent_tests.h" -#include "resource_helpers.h" -#include "infile_tree.h" -#include "env.h" - -#include "enrichment_facility_tests.h" - -namespace cycamore { - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacilityTest::SetUp() { - cyclus::Env::SetNucDataPath(); - cyclus::Context* ctx = tc_.get(); - src_facility = new EnrichmentFacility(ctx); - trader = tc_.trader(); - InitParameters(); - SetUpSource(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacilityTest::TearDown() { - delete src_facility; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacilityTest::InitParameters() { - cyclus::Context* ctx = tc_.get(); - - in_commod = "incommod"; - std::string x [2] = {"acommod", "bcommod"}; - out_commods = std::vector(x, x+2) ; - - in_recipe = "recipe"; - feed_assay = 0.0072; - - cyclus::CompMap v; - v[922350000] = feed_assay; - v[922380000] = 1 - feed_assay; - recipe = cyclus::Composition::CreateFromAtom(v); - ctx->AddRecipe(in_recipe, recipe); - - tails_assay = 0.002; - swu_capacity = 100; - inv_size = 5; - - reserves = 105.5; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacilityTest::SetUpSource() { - src_facility->InRecipe(in_recipe); - src_facility->in_commodity(in_commod); - src_facility->out_commodities(out_commods); - src_facility->TailsAssay(tails_assay); - src_facility->FeedAssay(feed_assay); - src_facility->SetMaxInventorySize(inv_size); - src_facility->SwuCapacity(swu_capacity); - src_facility->InitialReserves(reserves); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacilityTest::GetMat(double qty) { - return cyclus::Material::CreateUntracked(qty, - tc_.get()->GetRecipe(in_recipe)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacilityTest::GetReqMat(double qty, - double enr) { - cyclus::CompMap v; - v[922350000] = enr; - v[922380000] = 1 - enr; - return cyclus::Material::CreateUntracked( - qty, cyclus::Composition::CreateFromAtom(v)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacilityTest::DoAddMat(cyclus::Material::Ptr mat) { - src_facility->AddMat_(mat); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacilityTest::DoRequest() { - return src_facility->Request_(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr -EnrichmentFacilityTest::DoOffer(cyclus::Material::Ptr mat) { - return src_facility->Offer_(mat); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr -EnrichmentFacilityTest::DoEnrich(cyclus::Material::Ptr mat, double qty) { - return src_facility->Enrich_(mat, qty); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, InitialState) { - EXPECT_EQ(in_recipe, src_facility->InRecipe()); - EXPECT_EQ(in_commod, src_facility->in_commodity()); - // for (int i = 0 ; i < out_commods.size() ; ++i) { - // EXPECT_EQ(out_commods[i],src_facility->out_commodities()[i]) - // } - EXPECT_EQ(out_commods, src_facility->out_commodities()); - EXPECT_DOUBLE_EQ(tails_assay, src_facility->TailsAssay()); - EXPECT_DOUBLE_EQ(feed_assay, src_facility->FeedAssay()); - EXPECT_DOUBLE_EQ(inv_size, src_facility->MaxInventorySize()); - EXPECT_DOUBLE_EQ(0.0, src_facility->InventorySize()); - EXPECT_DOUBLE_EQ(swu_capacity, src_facility->SwuCapacity()); - EXPECT_EQ(reserves, src_facility->InitialReserves()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, DISABLED_XMLInit) { - std::stringstream ss; - - ss << "" - << "fooname" - << "" - << "" - << " " - << " " << in_commod << "" - << " " << in_recipe << "" - << " " << inv_size << "" - << " " - << " " - << " " - << " " << out_commods[0] << "" - << " " << out_commods[1] << "" - << " " - << " " << tails_assay << "" - << " " << swu_capacity << "" - << " " - << " " - << " " << reserves << "" - << " " - << "" - << "" - << ""; - - cyclus::XMLParser p; - p.Init(ss); - cyclus::InfileTree engine(p); - cycamore::EnrichmentFacility fac(tc_.get()); - - // EXPECT_NO_THROW(fac.InitFrom(&engine);); - EXPECT_EQ(in_recipe, fac.InRecipe()); - EXPECT_EQ(in_commod, fac.in_commodity()); - EXPECT_EQ(out_commods, fac.out_commodities()); - EXPECT_DOUBLE_EQ(tails_assay, fac.TailsAssay()); - EXPECT_DOUBLE_EQ(feed_assay, fac.FeedAssay()); - EXPECT_DOUBLE_EQ(inv_size, fac.MaxInventorySize()); - EXPECT_DOUBLE_EQ(0.0, fac.InventorySize()); - EXPECT_DOUBLE_EQ(swu_capacity, fac.SwuCapacity()); - EXPECT_EQ(reserves, fac.InitialReserves()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, Clone) { - cyclus::Context* ctx = tc_.get(); - - cycamore::EnrichmentFacility* cloned_fac = - dynamic_cast(src_facility->Clone()); - - EXPECT_EQ(in_recipe, cloned_fac->InRecipe()); - EXPECT_EQ(in_commod, cloned_fac->in_commodity()); - EXPECT_EQ(out_commods, cloned_fac->out_commodities()); - EXPECT_DOUBLE_EQ(tails_assay, cloned_fac->TailsAssay()); - EXPECT_DOUBLE_EQ(feed_assay, cloned_fac->FeedAssay()); - EXPECT_DOUBLE_EQ(inv_size, cloned_fac->MaxInventorySize()); - EXPECT_DOUBLE_EQ(0.0, cloned_fac->InventorySize()); - EXPECT_DOUBLE_EQ(swu_capacity, cloned_fac->SwuCapacity()); - EXPECT_EQ(reserves, cloned_fac->InitialReserves()); - - delete cloned_fac; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, AddMat) { - EXPECT_THROW(DoAddMat(test_helpers::get_mat()), cyclus::ValueError); - EXPECT_THROW(DoAddMat(GetMat(inv_size + 1)), cyclus::Error); - EXPECT_NO_THROW(DoAddMat(GetMat(inv_size))); - EXPECT_THROW(DoAddMat(GetMat(1)), cyclus::Error); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, Request) { - double req = inv_size; - double add = 0; - cyclus::Material::Ptr mat = DoRequest(); - EXPECT_DOUBLE_EQ(mat->quantity(), req); - EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(in_recipe)); - - add = 2 * inv_size / 3; - req -= add; - DoAddMat(GetMat(add)); - mat = DoRequest(); - EXPECT_DOUBLE_EQ(mat->quantity(), req); - EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(in_recipe)); - - add = inv_size / 3; - req = 0; - DoAddMat(GetMat(add)); - mat = DoRequest(); - EXPECT_DOUBLE_EQ(mat->quantity(), req); - EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(in_recipe)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, Offer) { - using cyclus::CompMap; - using cyclus::Composition; - using cyclus::Material; - using cyclus::toolkit::MatQuery; - - double qty = 4.5; - double u234 = 1.0; - double u235 = 1.0; - double u238 = 2.0; - cyclus::CompMap v; - v[94239] = u234; - v[922350000] = u235; - v[922380000] = u238; - Material::Ptr mat = - DoOffer(Material::CreateUntracked(qty, Composition::CreateFromAtom(v))); - - MatQuery q(mat); - - EXPECT_DOUBLE_EQ(q.atom_frac(94239), 0.0); - EXPECT_DOUBLE_EQ(q.atom_frac(922350000), u235 / (u235 + u238)); - EXPECT_DOUBLE_EQ(q.atom_frac(922380000), u238 / (u235 + u238)); - EXPECT_DOUBLE_EQ(mat->quantity(), qty); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, ValidReq) { - using cyclus::CompMap; - using cyclus::Composition; - using cyclus::Material; - - double qty = 4.5; // some magic number - - cyclus::CompMap v1; - v1[922350000] = 1; - Material::Ptr mat = Material::CreateUntracked(qty, - Composition::CreateFromAtom(v1)); - EXPECT_TRUE(!src_facility->ValidReq(mat)); // u238 = 0 - - cyclus::CompMap v2; - v2[922350000] = tails_assay; - v2[922380000] = 1 - tails_assay; - mat = Material::CreateUntracked(qty, Composition::CreateFromAtom(v2)); - EXPECT_TRUE(!src_facility->ValidReq(mat)); // u235 / (u235 + u238) <= tails_assay - - cyclus::CompMap v3; - v3[922350000] = 1; - v3[922380000] = 1; - mat = Material::CreateUntracked(qty, Composition::CreateFromAtom(v3)); - EXPECT_TRUE(src_facility->ValidReq(mat)); // valid -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, EmptyRequests) { - using cyclus::Material; - using cyclus::RequestPortfolio; - - src_facility->SetMaxInventorySize(src_facility->InventorySize()); - std::set::Ptr> ports = - src_facility->GetMatlRequests(); - ports = src_facility->GetMatlRequests(); - EXPECT_TRUE(ports.empty()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, AddRequests) { - using cyclus::Request; - using cyclus::RequestPortfolio; - using cyclus::CapacityConstraint; - using cyclus::Converter; - using cyclus::Material; - - // a request is made for the current available inventory amount - - std::set::Ptr> ports = - src_facility->GetMatlRequests(); - - ASSERT_EQ(ports.size(), 1); - ASSERT_EQ(ports.begin()->get()->qty(), inv_size); - - const std::vector*>& requests = - ports.begin()->get()->requests(); - ASSERT_EQ(requests.size(), 1); - - Request* req = *requests.begin(); - EXPECT_EQ(req->requester(), src_facility); - EXPECT_EQ(req->commodity(), in_commod); - - const std::set< CapacityConstraint >& constraints = - ports.begin()->get()->constraints(); - EXPECT_EQ(constraints.size(), 0); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, Extract) { - using cyclus::Material; - cyclus::Env::SetNucDataPath(); - double qty = 1000; // 5 kg - Material::Ptr base = GetMat(qty); - double time = tc_.get()->time(); - // cyclus::Material::Create(src_facility, qty, - // tc_.get()->GetRecipe(in_recipe)); - Material::Ptr base2 = GetMat(qty); - base->Absorb(base2); - double product_assay = 0.05; // of 5 w/o enriched U - cyclus::CompMap v; - v[922350000] = product_assay; - v[922380000] = 1 - product_assay; - // target qty need not be = to request qty - Material::Ptr target = cyclus::Material::CreateUntracked( - 5, cyclus::Composition::CreateFromMass(v)); - Material::Ptr response = base->ExtractComp(6, target->comp()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, Accept) { - using cyclus::Bid; - using cyclus::Material; - using cyclus::Request; - using cyclus::Trade; - - // an enrichment facility gets two trades, each for 1/3 of its inv size - // note that comp != recipe is covered by AddMat tests - // note that qty >= inv capacity is covered by toolkit::ResourceBuff tests - - double qty = inv_size / 3; - std::vector< std::pair, - cyclus::Material::Ptr> > responses; - - Request* req1 = - Request::Create(DoRequest(), src_facility, in_commod); - Bid* bid1 = - Bid::Create(req1, GetMat(qty), trader); - - Request* req2 = - Request::Create(DoRequest(), src_facility, in_commod); - Bid* bid2 = Bid::Create(req2, GetMat(qty), trader); - - Trade trade1(req1, bid1, qty); - responses.push_back(std::make_pair(trade1, GetMat(qty))); - Trade trade2(req2, bid2, qty); - responses.push_back(std::make_pair(trade2, GetMat(qty))); - - EXPECT_DOUBLE_EQ(0.0, src_facility->InventorySize()); - src_facility->AcceptMatlTrades(responses); - EXPECT_DOUBLE_EQ(qty * 2, src_facility->InventorySize()); - - delete bid2; - delete bid1; - delete req2; - delete req1; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, AddBids) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::Converter; - using cyclus::ExchangeContext; - using cyclus::Material; - cyclus::Env::SetNucDataPath(); - // an enrichment facility bids on nreqs requests - // note that bid response is covered by Bid tests - // note that validity of requests is covered by ValidReq tests - int nreqs = 5; - int nvalid = 4; - - // set up inventory - double current_size = inv_size / 2; // test something other than max size - DoAddMat(GetMat(current_size)); - - boost::shared_ptr< cyclus::ExchangeContext > - ec = GetContext(nreqs, nvalid); - - std::set::Ptr> ports = - src_facility->GetMatlBids(ec.get()->commod_requests); - - ASSERT_TRUE(ports.size() > 0); - EXPECT_EQ(ports.size(), 1); - - BidPortfolio::Ptr port = *ports.begin(); - EXPECT_EQ(port->bidder(), src_facility); - EXPECT_EQ(port->bids().size(), nvalid); - - const std::set< CapacityConstraint >& constrs = port->constraints(); - Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); - Converter::Ptr nc(new NatUConverter(feed_assay, tails_assay)); - CapacityConstraint swu(swu_capacity, sc); - CapacityConstraint natu(current_size, nc); - EXPECT_EQ(constrs.size(), 2); - EXPECT_TRUE(*constrs.begin() == swu || *(++constrs.begin()) == swu); - EXPECT_TRUE(*constrs.begin() == natu || *(++constrs.begin()) == natu); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -boost::shared_ptr< cyclus::ExchangeContext > -EnrichmentFacilityTest::GetContext(int nreqs, int nvalid) { - using cyclus::ExchangeContext; - using cyclus::Material; - using cyclus::Request; - using test_helpers::get_mat; - - boost::shared_ptr< ExchangeContext > - ec(new ExchangeContext()); - for (int i = 0; i < nvalid; i++) { - ec->AddRequest( - Request::Create(GetReqMat(1.0, 0.05), trader, out_commods[0])); - } - for (int i = 0; i < nreqs - nvalid; i++) { - ec->AddRequest( - // get_mat returns a material of only u235, which is not valid - Request::Create(get_mat(), trader, out_commods[0])); - } - return ec; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, BidConverters) { - // this test is designed to confirm that the bid response behavior matches the - // converter behavior. - using cyclus::CompMap; - using cyclus::Material; - using cyclus::toolkit::MatQuery; - using cyclus::Composition; - using cyclus::toolkit::Assays; - using cyclus::toolkit::UraniumAssay; - using cyclus::toolkit::SwuRequired; - using cyclus::toolkit::FeedQty; - cyclus::Env::SetNucDataPath(); - - double qty = 5; // 5 kg - double product_assay = 0.05; // of 5 w/o enriched U - CompMap v; - v[922350000] = product_assay; - v[922380000] = 1 - product_assay; - v[94239] = 0.5; // 94239 shouldn't be taken into account - Material::Ptr target = Material::CreateUntracked( - qty, Composition::CreateFromMass(v)); - - SWUConverter swuc(feed_assay, tails_assay); - NatUConverter natuc(feed_assay, tails_assay); - - Material::Ptr offer = DoOffer(target); - - EXPECT_NEAR(swuc.convert(target), swuc.convert(offer), 0.001); - EXPECT_NEAR(natuc.convert(target), natuc.convert(offer), 0.001); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, Enrich) { - // this test asks the facility to enrich a material that results in an amount - // of natural uranium required that is exactly its inventory level. that - // inventory will be comprised of two materials to test the manifest/absorb - // strategy employed in Enrich_. - using cyclus::CompMap; - using cyclus::Material; - using cyclus::toolkit::MatQuery; - using cyclus::Composition; - using cyclus::toolkit::Assays; - using cyclus::toolkit::UraniumAssay; - using cyclus::toolkit::SwuRequired; - using cyclus::toolkit::FeedQty; - - double qty = 5; // 5 kg - double product_assay = 0.05; // of 5 w/o enriched U - cyclus::CompMap v; - v[922350000] = product_assay; - v[922380000] = 1 - product_assay; - // target qty need not be = to request qty - Material::Ptr target = cyclus::Material::CreateUntracked( - qty + 10, cyclus::Composition::CreateFromMass(v)); - - Assays assays(feed_assay, UraniumAssay(target), tails_assay); - double swu_req = SwuRequired(qty, assays); - double natu_req = FeedQty(qty, assays); - double tails_qty = TailsQty(qty, assays); - - double swu_cap = swu_req * 5; - src_facility->SwuCapacity(swu_cap); - src_facility->SetMaxInventorySize(natu_req); - DoAddMat(GetMat(natu_req / 2)); - DoAddMat(GetMat(natu_req / 2)); - - Material::Ptr response; - EXPECT_NO_THROW(response = DoEnrich(target, qty)); - EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_cap - swu_req); - EXPECT_DOUBLE_EQ(src_facility->Tails().quantity(), tails_qty); - - MatQuery q(response); - EXPECT_EQ(response->quantity(), qty); - EXPECT_EQ(q.mass_frac(922350000), product_assay); - EXPECT_EQ(q.mass_frac(922380000), 1 - product_assay); - - // test too much natu request - DoAddMat(GetMat(natu_req - 1)); - EXPECT_THROW(response = DoEnrich(target, qty), cyclus::Error); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, Response) { - // this test asks the facility to respond to multiple requests for enriched - // uranium. two requests are provided, whose total equals the swu capacity of - // the facility while not exceeding its inventory capacity (that's taken care - // of in the Enrich tests). - // - // note that response quantity and quality need not be tested, because they - // are covered by the Enrich and Offer tests - using cyclus::Bid; - using cyclus::CompMap; - using cyclus::Composition; - using cyclus::Material; - using cyclus::Request; - using cyclus::Trade; - using cyclus::toolkit::MatQuery; - using cyclus::toolkit::Assays; - using cyclus::toolkit::FeedQty; - using cyclus::toolkit::SwuRequired; - using cyclus::toolkit::UraniumAssay; - using test_helpers::get_mat; - - // problem set up - std::vector< cyclus::Trade > trades; - std::vector, - cyclus::Material::Ptr> > responses; - - double qty = 5; // 5 kg - double trade_qty = qty / 3; - double product_assay = 0.05; // of 5 w/o enriched U - cyclus::CompMap v; - v[922350000] = product_assay; - v[922380000] = 1 - product_assay; - // target qty need not be = to request qty - Material::Ptr target = cyclus::Material::CreateUntracked( - qty + 10, cyclus::Composition::CreateFromMass(v)); - - Assays assays(feed_assay, UraniumAssay(target), tails_assay); - double swu_req = SwuRequired(qty, assays); - double natu_req = FeedQty(qty, assays); - - src_facility->SetMaxInventorySize(natu_req * 4); // not capacitated by nat u - src_facility->SwuCapacity(swu_req); // swu capacitated - - // Null response - src_facility->GetMatlTrades(trades, responses); - EXPECT_NO_THROW(); - EXPECT_EQ(responses.size(), 0); - - // set up state - DoAddMat(GetMat(natu_req * 2)); - - Request* req = - Request::Create(target, trader, out_commods[0]); - Bid* bid = Bid::Create(req, target, src_facility); - Trade trade(req, bid, trade_qty); - trades.push_back(trade); - - // 1 trade, SWU < SWU cap - ASSERT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_req); - src_facility->GetMatlTrades(trades, responses); - ASSERT_EQ(responses.size(), 1); - EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), - swu_req - SwuRequired(trade_qty, assays)); - - // 2 trades, SWU = SWU cap - ASSERT_GT(src_facility->CurrentSwuCapacity() - 2 * swu_req / 3, - -1 * cyclus::eps()); - trades.push_back(trade); - responses.clear(); - EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); - EXPECT_EQ(responses.size(), 2); - EXPECT_TRUE(cyclus::AlmostEq(src_facility->CurrentSwuCapacity(), 0)); - - // too much qty, capn! - trade = Trade(req, bid, 1); // a small number - trades.clear(); - trades.push_back(trade); - EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), - cyclus::ValueError); - - // reset! - src_facility->Tick(); - EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_req); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, TwoCommodResponse) { - // this test asks the facility to fufill multiple requests for different uranium - // enrichment levels. Two requests are provided, whose total is less than the swu capacity of - // the facility while not exceeding its inventory capacity - // - using cyclus::Bid; - using cyclus::CompMap; - using cyclus::Composition; - using cyclus::Material; - using cyclus::Request; - using cyclus::Trade; - using cyclus::toolkit::MatQuery; - using cyclus::toolkit::Assays; - using cyclus::toolkit::FeedQty; - using cyclus::toolkit::SwuRequired; - using cyclus::toolkit::UraniumAssay; - using test_helpers::get_mat; - - // problem set up - std::vector< cyclus::Trade > trades; - std::vector, - cyclus::Material::Ptr> > responses; - - double qty1 = 5; // 5 kg - double trade_qty1 = qty1; - double product_assay1 = 0.04; - double qty2 = 1; // 1 kg - double trade_qty2 = qty2; - double product_assay2 = 0.20; - - cyclus::CompMap v1; - v1[922350000] = product_assay1; - v1[922380000] = 1 - product_assay1; - // target qty need not be = to request qty - Material::Ptr target1 = cyclus::Material::CreateUntracked( - qty1 + 10, cyclus::Composition::CreateFromMass(v1)); - - cyclus::CompMap v2; - v2[922350000] = product_assay2; - v2[922380000] = 1 - product_assay2; - // target qty need not be = to request qty - Material::Ptr target2 = cyclus::Material::CreateUntracked( - qty2 + 10, cyclus::Composition::CreateFromMass(v2)); - - Assays assays1(feed_assay, UraniumAssay(target1), tails_assay); - Assays assays2(feed_assay, UraniumAssay(target2), tails_assay); - double swu_req = SwuRequired(qty1, assays1) + SwuRequired(qty2, assays2) ; - double natu_req = FeedQty(qty1, assays1)+FeedQty(qty2, assays2); - - src_facility->SetMaxInventorySize(natu_req * 4); // not capacitated by nat u - src_facility->SwuCapacity(swu_req); // swu capacitated - - // Null response - src_facility->GetMatlTrades(trades, responses); - EXPECT_NO_THROW(); - EXPECT_EQ(responses.size(), 0); - - // set up state - DoAddMat(GetMat(natu_req * 2)); - - Request* req1 = - Request::Create(target1, trader, out_commods[0]); - Bid* bid1 = Bid::Create(req1, target1, src_facility); - Trade trade1(req1, bid1, trade_qty1); - trades.push_back(trade1); - - Request* req2 = - Request::Create(target2, trader, out_commods[1]); - Bid* bid2 = Bid::Create(req2, target2, src_facility); - Trade trade2(req2, bid2, trade_qty2); - trades.push_back(trade2); - - // 2 trades, SWU = SWU cap - ASSERT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_req); - src_facility->GetMatlTrades(trades, responses); - ASSERT_EQ(responses.size(), 2); - - EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), - swu_req - SwuRequired(trade_qty1, assays1) - - SwuRequired(trade_qty2, assays2)); - - // 2 trades, 2 responses - - // trades.push_back(trade); - // responses.clear(); - // EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); - // EXPECT_EQ(responses.size(), 2); - // EXPECT_TRUE(cyclus::AlmostEq(src_facility->CurrentSwuCapacity(), 0)); - - // // too much qty, capn! - // trade = Trade(req, bid, 1); // a small number - // trades.clear(); - // trades.push_back(trade); - // EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), - // cyclus::ValueError); - - // reset! - src_facility->Tick(); - EXPECT_DOUBLE_EQ(src_facility->CurrentSwuCapacity(), swu_req); -} - -} // namespace cycamore - -// -// -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Agent* EnrichmentFacilityConstructor(cyclus::Context* ctx) { - return new cycamore::EnrichmentFacility(ctx); -} - -// required to get functionality in cyclus agent unit tests library -#ifndef CYCLUS_AGENT_TESTS_CONNECTED -int ConnectAgentTests(); -static int cyclus_agent_tests_connected = ConnectAgentTests(); -#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected -#endif // CYCLUS_AGENT_TESTS_CONNECTED - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -INSTANTIATE_TEST_CASE_P(EnrichmentFac, FacilityTests, - Values(&EnrichmentFacilityConstructor)); -INSTANTIATE_TEST_CASE_P(EnrichmentFac, AgentTests, - Values(&EnrichmentFacilityConstructor)); diff --git a/src/meg_old_tests/fn_consider/enrichment_facility_tests.h b/src/meg_old_tests/fn_consider/enrichment_facility_tests.h deleted file mode 100644 index 53ea956ebe..0000000000 --- a/src/meg_old_tests/fn_consider/enrichment_facility_tests.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef CYCAMORE_SRC_ENRICHMENT_FACILITY_TESTS_ -#define CYCAMORE_SRC_ENRICHMENT_FACILITY_TESTS_ - -#include - -#include - -#include "test_context.h" -#include "env.h" -#include "exchange_context.h" -#include "material.h" - -#include "enrichment_facility.h" - -namespace cycamore { - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -class EnrichmentFacilityTest : public ::testing::Test { - protected: - cyclus::TestContext tc_; - EnrichmentFacility* src_facility; - std::string in_commod, in_recipe; - std::vector out_commods ; - cyclus::Composition::Ptr recipe; - TestFacility* trader; - - double tails_assay, feed_assay, inv_size, commodity_price, swu_capacity; - - double reserves; - - virtual void SetUp(); - virtual void TearDown(); - void InitParameters(); - void SetUpSource(); - cyclus::Material::Ptr GetMat(double qty); - /// @param enr the enrichment percent, i.e. for 5 w/o, enr = 0.05 - cyclus::Material::Ptr GetReqMat(double qty, double enr); - void DoAddMat(cyclus::Material::Ptr mat); - cyclus::Material::Ptr DoRequest(); - cyclus::Material::Ptr DoBid(cyclus::Material::Ptr mat); - cyclus::Material::Ptr DoOffer(cyclus::Material::Ptr mat); - cyclus::Material::Ptr DoEnrich(cyclus::Material::Ptr mat, double qty); - /// @param nreqs the total number of requests - /// @param nvalid the number of requests that are valid - boost::shared_ptr< cyclus::ExchangeContext > - GetContext(int nreqs, int nvalid); -}; - -} // namespace cycamore - -#endif // CYCAMORE_SRC_ENRICHMENT_FACILITY_TESTS_ From 4a2c83d08f36c21314238c6e7e3d332a59e4d034 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 10 Mar 2015 12:01:29 -0500 Subject: [PATCH 139/314] more cleanup --- src/enrichment_facility.h | 7 +-- src/enrichment_facility_tests.cc | 76 ++++++++++++++++---------------- 2 files changed, 42 insertions(+), 41 deletions(-) diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 5dd659bbce..00acdb338c 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -1,6 +1,6 @@ #ifndef CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ #define CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ -/* + #include #include "cyclus.h" @@ -383,8 +383,9 @@ class EnrichmentFacility : public cyclus::Facility { cyclus::toolkit::ResBuf tails; // depleted u friend class EnrichmentFacilityTest; + // --- }; } // namespace cycamore -*/ -#endif // CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ \ No newline at end of file + +#endif // CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ diff --git a/src/enrichment_facility_tests.cc b/src/enrichment_facility_tests.cc index 005ad63319..d4746df2e0 100644 --- a/src/enrichment_facility_tests.cc +++ b/src/enrichment_facility_tests.cc @@ -66,7 +66,7 @@ TEST_F(EnrichmentFacilityTest, RequestQty) { int simdur = 1; cyclus::MockSim sim(cyclus::AgentSpec (":cycamore:EnrichmentFacility"), config, simdur); - sim.AddRecipe("natu1", c_natu1()) ; + sim.AddRecipe("natu1", c_natu1()); sim.AddSource("natu") .recipe("natu1") @@ -75,7 +75,7 @@ TEST_F(EnrichmentFacilityTest, RequestQty) { int id = sim.Run(); std::vector conds; - conds.push_back(Cond("Commodity", "==",std::string("natu"))); + conds.push_back(Cond("Commodity", "==", std::string("natu"))); QueryResult qr = sim.db().Query("Transactions", &conds); Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); @@ -100,15 +100,15 @@ TEST_F(EnrichmentFacilityTest, CheckSWUConstraint) { " tails " " 0.003 " " 1000 " - " 195 " ; + " 195 "; int simdur = 1; cyclus::MockSim sim(cyclus::AgentSpec (":cycamore:EnrichmentFacility"), config, simdur); - sim.AddRecipe("natu1", c_natu1()) ; - sim.AddRecipe("heu", c_heu()) ; + sim.AddRecipe("natu1", c_natu1()); + sim.AddRecipe("heu", c_heu()); sim.AddSink("enr_u") .recipe("heu") @@ -118,7 +118,7 @@ TEST_F(EnrichmentFacilityTest, CheckSWUConstraint) { int id = sim.Run(); std::vector conds; - conds.push_back(Cond("Commodity", "==",std::string("enr_u"))); + conds.push_back(Cond("Commodity", "==", std::string("enr_u"))); QueryResult qr = sim.db().Query("Transactions", &conds); Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); @@ -138,7 +138,7 @@ TEST_F(EnrichmentFacilityTest, CheckCapConstraint) { " enr_u " " tails " " 0.003 " - " 243 " ; + " 243 "; int simdur = 1; @@ -146,8 +146,8 @@ TEST_F(EnrichmentFacilityTest, CheckCapConstraint) { (":cycamore:EnrichmentFacility"), config, simdur); - sim.AddRecipe("natu1", c_natu1()) ; - sim.AddRecipe("heu", c_heu()) ; + sim.AddRecipe("natu1", c_natu1()); + sim.AddRecipe("heu", c_heu()); sim.AddSink("enr_u") .recipe("heu") @@ -157,7 +157,7 @@ TEST_F(EnrichmentFacilityTest, CheckCapConstraint) { int id = sim.Run(); std::vector conds; - conds.push_back(Cond("Commodity", "==",std::string("enr_u"))); + conds.push_back(Cond("Commodity", "==", std::string("enr_u"))); QueryResult qr = sim.db().Query("Transactions", &conds); Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); @@ -177,14 +177,14 @@ TEST_F(EnrichmentFacilityTest, RequestEnrich) { " enr_u " " tails " " 0.003 " - " 0.20 " ; + " 0.20 "; int simdur = 2; cyclus::MockSim sim(cyclus::AgentSpec (":cycamore:EnrichmentFacility"), config, simdur); - sim.AddRecipe("natu1", c_natu1()) ; - sim.AddRecipe("leu", c_leu()) ; - sim.AddRecipe("heu", c_heu()) ; + sim.AddRecipe("natu1", c_natu1()); + sim.AddRecipe("leu", c_leu()); + sim.AddRecipe("heu", c_heu()); sim.AddSource("natu") .recipe("natu1") @@ -200,7 +200,7 @@ TEST_F(EnrichmentFacilityTest, RequestEnrich) { int id = sim.Run(); std::vector conds; - conds.push_back(Cond("Commodity", "==",std::string("enr_u"))); + conds.push_back(Cond("Commodity", "==", std::string("enr_u"))); QueryResult qr = sim.db().Query("Transactions", &conds); Material::Ptr m = sim.GetMaterial(qr.GetVal("ResourceId")); @@ -231,14 +231,14 @@ TEST_F(EnrichmentFacilityTest, TradeTails) { " natu1 " " enr_u " " tails " - " 0.003 " ; + " 0.003 "; - //QQ - should tails buffer be available for trades on timestep 2? - int simdur = 3 ;// 1-source to EF, 2-EF process, 3-add to tails inventory + // 1-source to EF, 2-Enrich, add to tails, 3-tails avail. for trade + int simdur = 3; cyclus::MockSim sim(cyclus::AgentSpec (":cycamore:EnrichmentFacility"), config, simdur); - sim.AddRecipe("natu1", c_natu1()) ; - sim.AddRecipe("leu", c_leu()) ; + sim.AddRecipe("natu1", c_natu1()); + sim.AddRecipe("leu", c_leu()); sim.AddSource("natu") .recipe("natu1") @@ -252,7 +252,7 @@ TEST_F(EnrichmentFacilityTest, TradeTails) { int id = sim.Run(); std::vector conds; - conds.push_back(Cond("Commodity", "==",std::string("tails"))); + conds.push_back(Cond("Commodity", "==", std::string("tails"))); QueryResult qr = sim.db().Query("Transactions", &conds); // Should be exactly one tails transaction @@ -270,13 +270,13 @@ TEST_F(EnrichmentFacilityTest, BidPrefs) { " enr_u " " tails " " 0.003 " - " 1.0 " ; + " 1.0 "; int simdur = 1; cyclus::MockSim sim(cyclus::AgentSpec (":cycamore:EnrichmentFacility"), config, simdur); - sim.AddRecipe("natu1", c_natu1()) ; - sim.AddRecipe("natu2", c_natu2()) ; + sim.AddRecipe("natu1", c_natu1()); + sim.AddRecipe("natu2", c_natu2()); sim.AddSource("natu") .recipe("natu1") @@ -291,7 +291,7 @@ TEST_F(EnrichmentFacilityTest, BidPrefs) { int id = sim.Run(); std::vector conds; - conds.push_back(Cond("Commodity", "==",std::string("natu"))); + conds.push_back(Cond("Commodity", "==", std::string("natu"))); QueryResult qr = sim.db().Query("Transactions", &conds); // should trade only with #2 since it has higher U235 @@ -322,13 +322,13 @@ TEST_F(EnrichmentFacilityTest, BidPrefs) { " tails " " 0.003 " " 2.0 " - " 0 " ; + " 0 "; int simdur = 1; cyclus::MockSim sim(cyclus::AgentSpec (":cycamore:EnrichmentFacility"), config, simdur); - sim.AddRecipe("natu1", c_natu1()) ; - sim.AddRecipe("natu2", c_natu2()) ; + sim.AddRecipe("natu1", c_natu1()); + sim.AddRecipe("natu2", c_natu2()); sim.AddSource("natu") .recipe("natu1") @@ -343,7 +343,7 @@ TEST_F(EnrichmentFacilityTest, BidPrefs) { int id = sim.Run(); std::vector conds; - conds.push_back(Cond("Commodity", "==",std::string("natu"))); + conds.push_back(Cond("Commodity", "==", std::string("natu"))); QueryResult qr = sim.db().Query("Transactions", &conds); // should trade with both to meet its capacity limit @@ -360,13 +360,13 @@ TEST_F(EnrichmentFacilityTest, ZeroU235) { " enr_u " " tails " " 0.003 " - " 1.0 " ; + " 1.0 "; int simdur = 1; cyclus::MockSim sim(cyclus::AgentSpec (":cycamore:EnrichmentFacility"), config, simdur); - sim.AddRecipe("no_u235", c_nou235()) ; - sim.AddRecipe("natu1", c_natu1()) ; + sim.AddRecipe("no_u235", c_nou235()); + sim.AddRecipe("natu1", c_natu1()); sim.AddSource("natu") .recipe("no_u235") @@ -376,7 +376,7 @@ TEST_F(EnrichmentFacilityTest, ZeroU235) { int id = sim.Run(); std::vector conds; - conds.push_back(Cond("Commodity", "==",std::string("natu"))); + conds.push_back(Cond("Commodity", "==", std::string("natu"))); // DB table should be empty since there are no transactions EXPECT_THROW(sim.db().Query("Transactions", &conds), std::exception); @@ -539,11 +539,11 @@ TEST_F(EnrichmentFacilityTest, ValidReq) { Material::Ptr target = Material::CreateUntracked( qty, Composition::CreateFromMass(v)); - std::set nucs ; + std::set nucs; nucs.insert(922350000); nucs.insert(922380000); - MatQuery mq(target) ; + MatQuery mq(target); double mass_frac = mq.multi_mass_frac(nucs); SWUConverter swuc(feed_assay, tails_assay); @@ -552,7 +552,7 @@ TEST_F(EnrichmentFacilityTest, ValidReq) { Material::Ptr offer = DoOffer(target); EXPECT_NEAR(swuc.convert(target), swuc.convert(offer), 0.001); - EXPECT_NEAR(natuc.convert(target)*mass_frac, natuc.convert(offer), 0.001); //QQ fixed + EXPECT_NEAR(natuc.convert(target) * mass_frac, natuc.convert(offer), 0.001); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -570,7 +570,7 @@ TEST_F(EnrichmentFacilityTest, Enrich) { using cyclus::toolkit::SwuRequired; using cyclus::toolkit::FeedQty; - double qty = 5; // 5 kg + double qty = 5; // kg double product_assay = 0.05; // of 5 w/o enriched U cyclus::CompMap v; v[922350000] = product_assay; @@ -628,7 +628,7 @@ TEST_F(EnrichmentFacilityTest, Response) { std::vector, cyclus::Material::Ptr> > responses; - double qty = 5; // 5 kg + double qty = 5; // kg double trade_qty = qty / 3; double product_assay = 0.05; // of 5 w/o enriched U From b63f8330a1ec36a264ca1893c560420518fbfde9 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Tue, 10 Mar 2015 12:16:02 -0500 Subject: [PATCH 140/314] another cleanup --- src/enrichment_facility.cc.old | 320 --------------------------------- src/enrichment_facility.h.old | 313 -------------------------------- 2 files changed, 633 deletions(-) delete mode 100644 src/enrichment_facility.cc.old delete mode 100644 src/enrichment_facility.h.old diff --git a/src/enrichment_facility.cc.old b/src/enrichment_facility.cc.old deleted file mode 100644 index 87976a78ab..0000000000 --- a/src/enrichment_facility.cc.old +++ /dev/null @@ -1,320 +0,0 @@ -// Implements the EnrichmentFacility class -#include "enrichment_facility.h" - -#include -#include -#include -#include - -#include - -namespace cycamore { - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) - : cyclus::Facility(ctx), - tails_assay(0), - feed_assay(0), - swu_capacity(0), - initial_reserves(0), - in_commod(""), - in_recipe(""), - out_commod("") {} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -EnrichmentFacility::~EnrichmentFacility() {} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::string EnrichmentFacility::str() { - std::stringstream ss; - ss << cyclus::Facility::str() - << " with enrichment facility parameters:" - << " * SWU capacity: " << SwuCapacity() - << " * Tails assay: " << TailsAssay() - << " * Feed assay: " << FeedAssay() - << " * Input cyclus::Commodity: " << in_commodity() - << " * Output cyclus::Commodity: " << out_commodity(); - return ss.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::Build(cyclus::Agent* parent) { - using cyclus::Material; - - Facility::Build(parent); - if (initial_reserves > 0) { - inventory.Push( - Material::Create( - this, initial_reserves, context()->GetRecipe(in_recipe))); - } - - LOG(cyclus::LEV_DEBUG2, "EnrFac") << "EnrichmentFacility " - << " entering the simuluation: "; - LOG(cyclus::LEV_DEBUG2, "EnrFac") << str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::Tick() { - LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is ticking {"; - LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; - current_swu_capacity = SwuCapacity(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::Tock() { - LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is tocking {"; - LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -EnrichmentFacility::GetMatlRequests() { - using cyclus::Material; - using cyclus::RequestPortfolio; - using cyclus::Request; - - std::set::Ptr> ports; - RequestPortfolio::Ptr port(new RequestPortfolio()); - Material::Ptr mat = Request_(); - double amt = mat->quantity(); - - if (amt > cyclus::eps()) { - port->AddRequest(mat, this, in_commod); - ports.insert(port); - } - - return ports; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::AcceptMatlTrades( - const std::vector< std::pair, - cyclus::Material::Ptr> >& responses) { - // see - // http://stackoverflow.com/questions/5181183/boostshared-ptr-and-inheritance - std::vector< std::pair, - cyclus::Material::Ptr> >::const_iterator it; - for (it = responses.begin(); it != responses.end(); ++it) { - AddMat_(it->second); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -EnrichmentFacility::GetMatlBids( - cyclus::CommodMap::type& commod_requests) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::Converter; - using cyclus::Material; - using cyclus::Request; - - std::set::Ptr> ports; - - if (commod_requests.count(out_commod) > 0 && inventory.quantity() > 0) { - BidPortfolio::Ptr port(new BidPortfolio()); - - std::vector*>& requests = - commod_requests[out_commod]; - - std::vector*>::iterator it; - for (it = requests.begin(); it != requests.end(); ++it) { - Request* req = *it; - if (ValidReq(req->target())) { - Material::Ptr offer = Offer_(req->target()); - port->AddBid(req, offer, this); - } - } - - Converter::Ptr sc(new SWUConverter(feed_assay, tails_assay)); - Converter::Ptr nc(new NatUConverter(feed_assay, tails_assay)); - CapacityConstraint swu(swu_capacity, sc); - CapacityConstraint natu(inventory.quantity(), nc); - port->AddConstraint(swu); - port->AddConstraint(natu); - - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() - << " adding a swu constraint of " - << swu.capacity(); - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() - << " adding a natu constraint of " - << natu.capacity(); - - ports.insert(port); - } - return ports; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EnrichmentFacility::ValidReq(const cyclus::Material::Ptr mat) { - cyclus::toolkit::MatQuery q(mat); - double u235 = q.atom_frac(922350000); - double u238 = q.atom_frac(922380000); - return (u238 > 0 && u235 / (u235 + u238) > TailsAssay()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses) { - using cyclus::Material; - using cyclus::Trade; - - std::vector< Trade >::const_iterator it; - for (it = trades.begin(); it != trades.end(); ++it) { - Material::Ptr mat = it->bid->offer(); - double qty = it->amt; - Material::Ptr response = Enrich_(mat, qty); - responses.push_back(std::make_pair(*it, response)); - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() - << " just received an order" - << " for " << it->amt - << " of " << out_commod; - } - - if (cyclus::IsNegative(current_swu_capacity)) { - throw cyclus::ValueError( - "EnrFac " + prototype() - + " is being asked to provide more than its SWU capacity."); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { - if (mat->comp() != context()->GetRecipe(in_recipe)) { - throw cyclus::ValueError( - "EnrichmentFacility recipe and material composition not the same."); - } - - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " is initially holding " - << inventory.quantity() << " total."; - - try { - inventory.Push(mat); - } catch (cyclus::Error& e) { - e.msg(Agent::InformErrorMsg(e.msg())); - throw e; - } - - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " added " - << mat->quantity() << " of " << in_commod - << " to its inventory, which is holding " - << inventory.quantity() << " total."; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacility::Request_() { - double qty = std::max(0.0, MaxInventorySize() - InventorySize()); - return cyclus::Material::CreateUntracked(qty, - context()->GetRecipe(in_recipe)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { - cyclus::toolkit::MatQuery q(mat); - cyclus::CompMap comp; - comp[922350000] = q.atom_frac(922350000); - comp[922380000] = q.atom_frac(922380000); - return cyclus::Material::CreateUntracked( - mat->quantity(), cyclus::Composition::CreateFromAtom(comp)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacility::Enrich_( - cyclus::Material::Ptr mat, - double qty) { - using cyclus::Material; - using cyclus::ResCast; - using cyclus::toolkit::Assays; - using cyclus::toolkit::UraniumAssay; - using cyclus::toolkit::SwuRequired; - using cyclus::toolkit::FeedQty; - using cyclus::toolkit::TailsQty; - - // get enrichment parameters - Assays assays(FeedAssay(), UraniumAssay(mat), TailsAssay()); - double swu_req = SwuRequired(qty, assays); - double natu_req = FeedQty(qty, assays); - - // pop amount from inventory and blob it into one material - std::vector manifest; - try { - // required so popping doesn't take out too much - if (cyclus::AlmostEq(natu_req, inventory.quantity())) { - manifest = ResCast(inventory.PopN(inventory.count())); - } else { - manifest = ResCast(inventory.PopQty(natu_req)); - } - } catch (cyclus::Error& e) { - NatUConverter nc(feed_assay, tails_assay); - std::stringstream ss; - ss << " tried to remove " << natu_req - << " from its inventory of size " << inventory.quantity() - << " and the conversion of the material into natu is " - << nc.convert(mat); - throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); - } - Material::Ptr r = manifest[0]; - for (int i = 1; i < manifest.size(); ++i) { - r->Absorb(manifest[i]); - } - - // "enrich" it, but pull out the composition and quantity we require from the - // blob - cyclus::Composition::Ptr comp = mat->comp(); - Material::Ptr response = r->ExtractComp(qty, comp); - tails.Push(r); // add remainder to tails buffer - - current_swu_capacity -= swu_req; - - RecordEnrichment_(natu_req, swu_req); - - LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << - " has performed an enrichment: "; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Feed Qty: " - << natu_req; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Feed Assay: " - << assays.Feed() * 100; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Product Qty: " - << qty; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Product Assay: " - << assays.Product() * 100; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Tails Qty: " - << TailsQty(qty, assays); - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Tails Assay: " - << assays.Tails() * 100; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * SWU: " - << swu_req; - LOG(cyclus::LEV_INFO5, "EnrFac") << " * Current SWU capacity: " - << CurrentSwuCapacity(); - - return response; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::RecordEnrichment_(double natural_u, double swu) { - using cyclus::Context; - using cyclus::Agent; - - LOG(cyclus::LEV_DEBUG1, "EnrFac") << prototype() - << " has enriched a material:"; - LOG(cyclus::LEV_DEBUG1, "EnrFac") << " * Amount: " << natural_u; - LOG(cyclus::LEV_DEBUG1, "EnrFac") << " * SWU: " << swu; - - Context* ctx = Agent::context(); - ctx->NewDatum("Enrichments") - ->AddVal("ID", id()) - ->AddVal("Time", ctx->time()) - ->AddVal("Natural_Uranium", natural_u) - ->AddVal("SWU", swu) - ->Record(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern "C" cyclus::Agent* ConstructEnrichmentFacility(cyclus::Context* ctx) { - return new EnrichmentFacility(ctx); -} - -} // namespace cycamore diff --git a/src/enrichment_facility.h.old b/src/enrichment_facility.h.old deleted file mode 100644 index b0d1bb0eec..0000000000 --- a/src/enrichment_facility.h.old +++ /dev/null @@ -1,313 +0,0 @@ -#ifndef CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ -#define CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ - -#include - -#include "cyclus.h" - -namespace cycamore { - -/// @class SWUConverter -/// -/// @brief The SWUConverter is a simple Converter class for material to -/// determine the amount of SWU required for their proposed enrichment -class SWUConverter : public cyclus::Converter { - public: - SWUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} - virtual ~SWUConverter() {} - - /// @brief provides a conversion for the SWU required - virtual double convert( - cyclus::Material::Ptr m, - cyclus::Arc const * a = NULL, - cyclus::ExchangeTranslationContext - const * ctx = NULL) const { - cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), - tails_); - return cyclus::toolkit::SwuRequired(m->quantity(), assays); - } - - /// @returns true if Converter is a SWUConverter and feed and tails equal - virtual bool operator==(Converter& other) const { - SWUConverter* cast = dynamic_cast(&other); - return cast != NULL && - feed_ == cast->feed_ && - tails_ == cast->tails_; - } - - private: - double feed_, tails_; -}; - -/// @class NatUConverter -/// -/// @brief The NatUConverter is a simple Converter class for material to -/// determine the amount of natural uranium required for their proposed -/// enrichment -class NatUConverter : public cyclus::Converter { - public: - NatUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} - virtual ~NatUConverter() {} - - /// @brief provides a conversion for the amount of natural Uranium required - virtual double convert( - cyclus::Material::Ptr m, - cyclus::Arc const * a = NULL, - cyclus::ExchangeTranslationContext - const * ctx = NULL) const { - cyclus::toolkit::Assays assays(feed_, cyclus::toolkit::UraniumAssay(m), - tails_); - return cyclus::toolkit::FeedQty(m->quantity(), assays); - } - - /// @returns true if Converter is a NatUConverter and feed and tails equal - virtual bool operator==(Converter& other) const { - NatUConverter* cast = dynamic_cast(&other); - return cast != NULL && - feed_ == cast->feed_ && - tails_ == cast->tails_; - } - - private: - double feed_, tails_; -}; - -/// @class EnrichmentFacility -/// -/// @section introduction Introduction -/// The EnrichmentFacility is a simple Agent to agent the enriching of natural -/// Uranium in a Cyclus simulation. It requests its input recipe (nominally -/// natural Uranium), and produces any amount of enriched Uranium, given the its -/// natural uranium inventory constraint and its SWU capacity constraint. -/// -/// @section requests Requests -/// The EnrichmentFacility will request from the cyclus::ResourceExchange a -/// cyclus::Material whose quantity is its remaining inventory capacity and whose -/// composition is that of its input recipe. -/// -/// @section acctrade Accepting Trades -/// The EnrichmentFacility adds any accepted trades to its inventory. -/// -/// @section bids Bids -/// The EnrichmentFacility will bid on any request for its output commodity. It -/// will bid either the request quantity, or the quanity associated with either -/// its SWU constraint or natural uranium constraint, whichever is lower. -/// -/// @section extrades Executing Trades -/// The EnrichmentFacility will execute trades for its output commodity in the -/// following manner: -/// #. Determine the trade's quantity and product assay -/// #. Determine the natural Uranium and SWU requires to create that product -/// #. Remove the required quantity of natural Uranium from its inventory -/// #. Extract the appropriate composition of enriched Uranium -/// #. Send the enriched Uranium as the trade resource -/// -/// @section gotchas Gotchas -/// #. In its current form, the EnrichmentFacility can only accept -/// cyclus::Material having the composition of its input recipe. If a -/// cyclus::Material of a different composition is sent to it, an exception will -/// be thrown. -/// -/// #. During the trading phase, an exception will be thrown if either the -/// EnrichmentFacility's SWU or inventory constraint is breached. -/// -/// @section improvements Improvments -/// The primary improvement to the EnrichmentFacility would be to relax the -/// requirement that all input material have the in_recipe composition (i.e., -/// allow different base enrichments of Uranium). -/// -/// How would I go about doing so? I'd likely develop an EnrichmentBuffer-type -/// class that can be queried as to its SWU and natural Uranium capacity. -class EnrichmentFacility : public cyclus::Facility { - public: - // --- Module Members --- -/// Constructor for the EnrichmentFacility class -/// @param ctx the cyclus context for access to simulation-wide parameters - EnrichmentFacility(cyclus::Context* ctx); - -/// Destructor for the EnrichmentFacility class - virtual ~EnrichmentFacility(); - - #pragma cyclus - - #pragma cyclus note {"doc": "An enrichment facility that intakes a commodity " \ - "(usually natural uranium) and supplies a user-" \ - "specified enriched product based on SWU capacity", \ - "niche": "enrichment"} - -/// Print information about this agent - virtual std::string str(); - // --- - - // --- Facility Members --- - /// perform module-specific tasks when entering the simulation - virtual void Build(cyclus::Agent* parent); - // --- - - // --- Agent Members --- - /// Each facility is prompted to do its beginning-of-time-step - /// stuff at the tick of the timer. - - /// @param time is the time to perform the tick - virtual void Tick(); - - /// Each facility is prompted to its end-of-time-step - /// stuff on the tock of the timer. - - /// @param time is the time to perform the tock - virtual void Tock(); - - /// @brief The EnrichmentFacility request Materials of its given - /// commodity. - virtual std::set::Ptr> - GetMatlRequests(); - - /// @brief The EnrichmentFacility place accepted trade Materials in their - /// Inventory - virtual void AcceptMatlTrades( - const std::vector< std::pair, - cyclus::Material::Ptr> >& responses); - - /// @brief Responds to each request for this facility's commodity. If a given - /// request is more than this facility's inventory or SWU capacity, it will - /// offer its minimum of its capacities. - virtual std::set::Ptr> - GetMatlBids(cyclus::CommodMap::type& - commod_requests); - - /// @brief respond to each trade with a material enriched to the appropriate - /// level given this facility's inventory - /// - /// @param trades all trades in which this trader is the supplier - /// @param responses a container to populate with responses to each trade - virtual void GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses); - // --- - - // --- EnrichmentFacility Members --- - /// @brief Determines if a particular material is a valid request to respond - /// to. Valid requests must contain U235 and U238 and must have a relative - /// U235-to-U238 ratio less than this facility's tails_assay(). - /// @return true if the above description is met by the material - bool ValidReq(const cyclus::Material::Ptr mat); - - inline void in_commodity(std::string in_com) { in_commod = in_com; } - - inline std::string in_commodity() const { return in_commod; } - - inline void out_commodity(std::string out_com) { - out_commod = out_com; - } - - inline std::string out_commodity() const { return out_commod; } - - inline void InRecipe(std::string in_rec) { in_recipe = in_rec; } - - inline std::string InRecipe() const { return in_recipe; } - - inline void SetMaxInventorySize(double size) { - max_inv_size = size; - inventory.set_capacity(size); - } - - inline double MaxInventorySize() const { return inventory.capacity(); } - - inline double InventorySize() const { return inventory.quantity(); } - - inline void FeedAssay(double assay) { feed_assay = assay; } - - inline double FeedAssay() const { return feed_assay; } - - inline void TailsAssay(double assay) { tails_assay = assay; } - - inline double TailsAssay() const { return tails_assay; } - - inline void SwuCapacity(double capacity) { - swu_capacity = capacity; - current_swu_capacity = swu_capacity; - } - - inline double SwuCapacity() const { return swu_capacity; } - - inline double CurrentSwuCapacity() const { return current_swu_capacity; } - - /// @brief this facility's initial conditions - inline void InitialReserves(double qty) { initial_reserves = qty; } - inline double InitialReserves() const { return initial_reserves; } - - inline const cyclus::toolkit::ResourceBuff& Tails() const { return tails; } - - private: - /// @brief adds a material into the natural uranium inventory - /// @throws if the material is not the same composition as the in_recipe - void AddMat_(cyclus::Material::Ptr mat); - - /// @brief generates a request for this facility given its current state. The - /// quantity of the material will be equal to the remaining inventory size. - cyclus::Material::Ptr Request_(); - - /// @brief Generates a material offer for a given request. The response - /// composition will be comprised only of U235 and U238 at their relative ratio - /// in the requested material. The response quantity will be the same as the - /// requested commodity. - /// - /// @param req the requested material being responded to - cyclus::Material::Ptr Offer_(cyclus::Material::Ptr req); - - cyclus::Material::Ptr Enrich_(cyclus::Material::Ptr mat, double qty); - - /// @brief records and enrichment with the cyclus::Recorder - void RecordEnrichment_(double natural_u, double swu); - - #pragma cyclus var {"tooltip": "input commodity", \ - "doc": "commodity that the enrichment facility accepts", \ - "uitype": "incommodity"} - std::string in_commod; - #pragma cyclus var {"tooltip": "output commodity", \ - "doc": "commodity that the enrichment facility supplies", \ - "uitype": "outcommodity"} - std::string out_commod; - #pragma cyclus var {"tooltip": "input commodity recipe", \ - "doc": "recipe for enrichment facility's input commodity", \ - "uitype": "recipe"} - std::string in_recipe; - - #pragma cyclus var {"default": 0.03, "tooltip": "tails assay", \ - "doc": "tails assay from the enrichment process"} - double tails_assay; - #pragma cyclus var {"default": 1e299, "tooltip": "SWU capacity", \ - "doc": "separative work unit (SWU) capcity of " \ - "enrichment facility"} - double swu_capacity; - #pragma cyclus var {"default": 1e299, "tooltip": "maximum inventory size", \ - "doc": "maximum inventory capacity of natural uranium in " \ - "the enrichment facility"} - double max_inv_size; - #pragma cyclus var {"default": 0, "tooltip": "initial uranium reserves", \ - "doc": "amount of natural uranium stored at the " \ - "enrichment facility at the beginning of the " \ - "simulation"} - double initial_reserves; - #pragma cyclus var {'derived_init': 'current_swu_capacity = swu_capacity;'} - double current_swu_capacity; - #pragma cyclus var {\ - 'derived_init': "cyclus::Material::Ptr feed = "\ - "cyclus::Material::CreateUntracked(0, context()->GetRecipe(in_recipe)); "\ - "feed_assay = cyclus::toolkit::UraniumAssay(feed);", \ - "tooltip": "feed assay", \ - "doc": "feed assay for the enrichment process"} - double feed_assay; - #pragma cyclus var {'capacity': 'max_inv_size'} - cyclus::toolkit::ResourceBuff inventory; // of natl u - #pragma cyclus var {} - cyclus::toolkit::ResourceBuff tails; // depleted u - - friend class EnrichmentFacilityTest; - // --- -}; - -} // namespace cycamore - -#endif // CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ From d8bab1ebd2d70f00c437e21e314547779dc792ca Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Wed, 11 Mar 2015 10:52:49 -0500 Subject: [PATCH 141/314] changed multi_mass_frac to overloaded mass_frac and updated xml schema to match rwcarlsen's updates --- src/enrichment_facility.cc | 2 +- src/enrichment_facility.h | 30 +++++++++++++++--------------- src/enrichment_facility_tests.cc | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 326c6dd9d1..baa9db7014 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -371,7 +371,7 @@ cyclus::Material::Ptr EnrichmentFacility::Enrich_( std::set nucs; nucs.insert(922350000); nucs.insert(922380000); - double natu_frac = mq.multi_mass_frac(nucs); + double natu_frac = mq.mass_frac(nucs); double feed_req = natu_req/natu_frac; // pop amount from inventory and blob it into one material diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 00acdb338c..e7fc210fd5 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -62,7 +62,7 @@ class NatUConverter : public cyclus::Converter { nucs.insert(922350000); nucs.insert(922380000); - double natu_frac = mq.multi_mass_frac(nucs); + double natu_frac = mq.mass_frac(nucs); double natu_req = cyclus::toolkit::FeedQty(m->quantity(), assays); return natu_req/natu_frac; } @@ -345,23 +345,23 @@ class EnrichmentFacility : public cyclus::Facility { "the enrichment facility (kg)" \ } double max_inv_size; - + #pragma cyclus var { \ - "default": 1.0, \ - "tooltip": "maximum allowed enrichment fraction", \ - "doc": "maximum allowed weight fraction of U235 in product", \ - "schema": ' "\\n"\n' \ - ' " \\n"\n' \ - ' " \\n"\n ' \ - ' " 0\\n"\n' \ - ' " 1\\n"\n' \ - ' " \\n"\n ' \ - ' " \\n"\n' \ - ' "\\n"\n' \ + "default": 1.0, \ + "tooltip": "maximum allowed enrichment fraction", \ + "doc": "maximum allowed weight fraction of U235 in product",\ + "schema": '' \ + ' ' \ + ' ' \ + ' 0' \ + ' 1' \ + ' ' \ + ' ' \ + ' ' \ } double max_enrich; - - #pragma cyclus var { \ + + #pragma cyclus var { \ "default": 0, "tooltip": "initial uranium reserves (kg)", \ "doc": "amount of natural uranium stored at the enrichment " \ "facility at the beginning of the simulation (kg)" \ diff --git a/src/enrichment_facility_tests.cc b/src/enrichment_facility_tests.cc index d4746df2e0..a54a99edf5 100644 --- a/src/enrichment_facility_tests.cc +++ b/src/enrichment_facility_tests.cc @@ -544,7 +544,7 @@ TEST_F(EnrichmentFacilityTest, ValidReq) { nucs.insert(922380000); MatQuery mq(target); - double mass_frac = mq.multi_mass_frac(nucs); + double mass_frac = mq.mass_frac(nucs); SWUConverter swuc(feed_assay, tails_assay); NatUConverter natuc(feed_assay, tails_assay); From e450721db180f71aeebf2ef7390049e64f9cf494 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Mon, 30 Mar 2015 13:36:05 -0500 Subject: [PATCH 142/314] removed auto-generated run_inputs.py --- tests/run_inputs.py | 153 -------------------------------------------- 1 file changed, 153 deletions(-) delete mode 100644 tests/run_inputs.py diff --git a/tests/run_inputs.py b/tests/run_inputs.py deleted file mode 100644 index ceb45c2e9e..0000000000 --- a/tests/run_inputs.py +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/python - -import sys -import subprocess -from subprocess import Popen, PIPE, STDOUT -import os -import re - -def main(): - """This function finds input files, runs them, and prints a summary""" - flag = check_inputs() - input_path = "/Users/mbmcgarry/git/cycamore/../input" - cyclus_path = "/Users/mbmcgarry/.local/include/cyclus/../../bin/cyclus" - files, catalogs, catalognames = get_files(input_path) - copy_catalogs(catalogs,cyclus_path.strip("cyclus")) - summ = Summary() - for name in files : - file_to_test = TestFile(cyclus_path, name, flag) - file_to_test.run() - summ.add_to_summary(file_to_test) - clean_catalogs(cyclus_path.strip("cyclus"),catalognames) - summ.print_summary() - -def check_inputs(): - """This function checks the input arguments""" - if len(sys.argv) > 2: - print_usage() - sys.exit(1) - elif len(sys.argv) == 2: - if re.search("-v*",sys.argv[1]): - flag = sys.argv[1] - else : - print_usage() - sys.exit(1) - elif len(sys.argv) == 1 : - flag = "-v0" - return flag - -def print_usage() : - """This prints the proper way to treat the command line interface""" - print 'Usage: python run_inputs.py\n' + \ - 'Allowed Options : \n' + \ - '-v arg output log verbosity. \n' + \ - ' \ - Can be text: \n' + \ - ' \ - LEV_ERROR (least verbose, default), LEV_WARN,\n' + \ - ' \ - LEV_INFO1 (through 5), and LEV_DEBUG1 (through 5).\n' + \ - ' \ - Or an integer:\n'+ \ - ' \ - 0 (LEV_ERROR equiv) through 11 (LEV_DEBUG5 equiv)\n' - -def get_files(path): - """This function walks the 'path' tree and finds input files""" - catalogs=[] - catalognames=[] - inputs=[] - for root, dirs, files in os.walk(path, followlinks=True): - if '.git' in dirs: - dirs.remove('.git') - for name in files: - if re.search("\.xml",name) : - if re.search("recipebook",name) or \ - re.search("facilitycatalog",name): - catalogs.append(os.path.join(root,name)) - catalognames.append(name) - else : - inputs.append(os.path.join(root, name)) - else : - files.remove(name) - print "The catalogs to be moved are:" - print catalogs - print "The files to be tested are:" - print inputs - return inputs, catalogs, catalognames - -def copy_catalogs(catalogs,cyclus_path) : - """Copies files in the catalogs list to the cyclus executable directory""" - for cat in catalogs : - p = Popen("cp "+cat+" "+cyclus_path, - shell=True, stdout=PIPE, stderr=STDOUT) - -def clean_catalogs(cyclus_path, catalogs) : - """Removes previously copied catalogs from executable directory.""" - for cat in catalogs : - p = Popen("rm "+ os.path.join(cyclus_path,cat), - shell=True, stdout=PIPE, stderr=STDOUT) - -class Summary(): - """An object to hold the results of all the tests""" - def __init__(self): - self.passed = [] - self.failed = [] - - def add_to_summary(self, test_file) : - """Adds a test file to this summary object""" - if test_file.passed : - self.passed.append( test_file.infile ) - else : - self.failed.append( test_file.infile ) - - def print_summary(self) : - """Prints the summary""" - print "Input files passed = " + str(len(self.passed)) - print "Input files failed = " + str(len(self.failed)) - print "Failed input files : " - for test in self.failed : - print test - -class TestFile(): - """An object representing the inputxml file to test""" - def __init__(self, cyclus_path, file_path, flag): - self.infile = file_path - self.cyclus_path = cyclus_path - self.passed=True - self.flag = " "+flag+" " - - def run(self): - """Runs all of the input file tests""" - output = self.get_output() - if self.no_errors(output) : - self.passed = True - else : - self.passed = False - - def get_output(self): - """Returns the output from running the FileTest""" - try : - p = Popen(self.cyclus_path+" "+ self.infile + self.flag, - shell=True, stdout=PIPE, stderr=STDOUT) - io_tuple = p.communicate() - output = io_tuple[0] - except subprocess.CalledProcessError, e: - print(e) - return output - - def no_errors(self, output): - """returns true if there were no errors or segfaults running this TestFile""" - to_ret = True - print "Input file " + self.infile - if re.search("No such file or directory",output) : - print "Cyclus executable not found in path." - elif re.search("ERROR",output) or re.search("Segmentation fault",output): - to_ret = False - print " resulted in errors: " - print output - else : - print " passed. " - return to_ret - -if __name__ == '__main__' : main() From ca06a0b7b6bb45d17247e82a408780cd991a8c4a Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Mon, 30 Mar 2015 13:36:49 -0500 Subject: [PATCH 143/314] also ignore future generations --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 83fc28d783..835e504e75 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ suffix.h *.pyc rs.cred *.h5 +tests/run_inputs.py \ No newline at end of file From 782c6382c0fe561efbb6011e48153f31b0e9a0ca Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Wed, 1 Apr 2015 17:24:49 -0500 Subject: [PATCH 144/314] changed facility and state var names. Did not yet changed derived current_swu_capacity --- input/enrichment/1_src_enr_rxtr_sink.xml | 14 +- input/enrichment/linear_src_enr_rxtr_sink.xml | 14 +- input/enrichment/natu_capacitated.xml | 14 +- input/enrichment/swu_capacitated.xml | 14 +- input/physor/1_Enrichment_2_Reactor.xml | 14 +- src/enrichment_facility.cc | 72 ++++---- src/enrichment_facility.h | 111 ++++++------ src/enrichment_facility_tests.cc | 158 +++++++++--------- src/enrichment_facility_tests.h | 10 +- 9 files changed, 210 insertions(+), 211 deletions(-) diff --git a/input/enrichment/1_src_enr_rxtr_sink.xml b/input/enrichment/1_src_enr_rxtr_sink.xml index ba9ade40c4..a62dbe8d66 100644 --- a/input/enrichment/1_src_enr_rxtr_sink.xml +++ b/input/enrichment/1_src_enr_rxtr_sink.xml @@ -10,8 +10,8 @@ cycamoreSink cycamoreSource - cycamoreEnrichmentFacility cycamoreReactor + cycamoreEnrichment agentsNullRegion agentsNullInst @@ -30,14 +30,14 @@ Enrichment - - natl_u - enriched_u + + natl_u + enriched_u ef_tails - natl_u + natl_u 0.003 - 500 - + 500 + diff --git a/input/enrichment/linear_src_enr_rxtr_sink.xml b/input/enrichment/linear_src_enr_rxtr_sink.xml index fc0d29b720..6e40a8635f 100644 --- a/input/enrichment/linear_src_enr_rxtr_sink.xml +++ b/input/enrichment/linear_src_enr_rxtr_sink.xml @@ -10,8 +10,8 @@ cycamoreSink cycamoreSource - cycamoreEnrichmentFacility cycamoreReactor + cycamoreEnrichment cycamoreGrowthRegion cycamoreManagerInst @@ -30,14 +30,14 @@ Enrichment - - natl_u - natl_u - 1000 - enriched_u + + natl_u + natl_u + 1000 + enriched_u ef_tails 0.003 - + diff --git a/input/enrichment/natu_capacitated.xml b/input/enrichment/natu_capacitated.xml index 569dd84380..36c0b1dba8 100644 --- a/input/enrichment/natu_capacitated.xml +++ b/input/enrichment/natu_capacitated.xml @@ -10,8 +10,8 @@ cycamoreSink cycamoreSource - cycamoreEnrichmentFacility cycamoreReactor + cycamoreEnrichment cycamoreGrowthRegion cycamoreManagerInst @@ -30,14 +30,14 @@ Enrichment - - natl_u - natl_u - 100 - enriched_u + + natl_u + natl_u + 100 + enriched_u ef_tails 0.003 - + diff --git a/input/enrichment/swu_capacitated.xml b/input/enrichment/swu_capacitated.xml index 9124fee179..67cbec62a3 100644 --- a/input/enrichment/swu_capacitated.xml +++ b/input/enrichment/swu_capacitated.xml @@ -10,8 +10,8 @@ cycamoreSink cycamoreSource - cycamoreEnrichmentFacility cycamoreReactor + cycamoreEnrichment cycamoreGrowthRegion cycamoreManagerInst @@ -30,15 +30,15 @@ Enrichment - - natl_u - natl_u - 100 - enriched_u + + natl_u + natl_u + 100 + enriched_u ef_tails 0.003 30.0 - + diff --git a/input/physor/1_Enrichment_2_Reactor.xml b/input/physor/1_Enrichment_2_Reactor.xml index afbb26823f..dd0737fb69 100755 --- a/input/physor/1_Enrichment_2_Reactor.xml +++ b/input/physor/1_Enrichment_2_Reactor.xml @@ -8,7 +8,7 @@ - cycamore EnrichmentFacility + cycamore Enrichment cycamore Reactor agents NullRegion agents NullInst @@ -17,15 +17,15 @@ Enrichment - - natl_u - natl_u - enriched_u + + natl_u + natl_u + enriched_u ef_tails 0.003 10.01 - 1e5 - + 1e5 + diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index baa9db7014..c57e940285 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -1,4 +1,4 @@ -// Implements the EnrichmentFacility class +// Implements the Enrichment class #include "enrichment_facility.h" #include @@ -11,67 +11,67 @@ namespace cycamore { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -EnrichmentFacility::EnrichmentFacility(cyclus::Context* ctx) +Enrichment::Enrichment(cyclus::Context* ctx) : cyclus::Facility(ctx), tails_assay(0), swu_capacity(0), max_enrich(1), - initial_reserves(0), - in_commod(""), - in_recipe(""), - out_commod(""), + initial_feed(0), + feed(""), + feed_recipe(""), + product(""), tails_commod(""), order_prefs(true){} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -EnrichmentFacility::~EnrichmentFacility() {} +Enrichment::~Enrichment() {} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::string EnrichmentFacility::str() { +std::string Enrichment::str() { std::stringstream ss; ss << cyclus::Facility::str() << " with enrichment facility parameters:" << " * SWU capacity: " << SwuCapacity() << " * Tails assay: " << TailsAssay() << " * Feed assay: " << FeedAssay() - << " * Input cyclus::Commodity: " << in_commodity() - << " * Output cyclus::Commodity: " << out_commodity() + << " * Input cyclus::Commodity: " << feed_commod() + << " * Output cyclus::Commodity: " << product_commod() << " * Tails cyclus::Commodity: " << tails_commodity(); return ss.str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::Build(cyclus::Agent* parent) { +void Enrichment::Build(cyclus::Agent* parent) { using cyclus::Material; Facility::Build(parent); - if (initial_reserves > 0) { + if (initial_feed > 0) { inventory.Push( Material::Create( - this, initial_reserves, context()->GetRecipe(in_recipe))); + this, initial_feed, context()->GetRecipe(feed_recipe))); } - LOG(cyclus::LEV_DEBUG2, "EnrFac") << "EnrichmentFacility " + LOG(cyclus::LEV_DEBUG2, "EnrFac") << "Enrichment " << " entering the simuluation: "; LOG(cyclus::LEV_DEBUG2, "EnrFac") << str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::Tick() { +void Enrichment::Tick() { LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is ticking {"; LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; current_swu_capacity = SwuCapacity(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::Tock() { +void Enrichment::Tock() { LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is tocking {"; LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - std::set::Ptr> - EnrichmentFacility::GetMatlRequests() { + Enrichment::GetMatlRequests() { using cyclus::Material; using cyclus::RequestPortfolio; using cyclus::Request; @@ -82,7 +82,7 @@ std::set::Ptr> double amt = mat->quantity(); if (amt > cyclus::eps()) { - port->AddRequest(mat, this, in_commod); + port->AddRequest(mat, this, feed); ports.insert(port); } @@ -106,7 +106,7 @@ bool SortBids( // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Sort offers of input material to have higher preference for more // U-235 content -void EnrichmentFacility::AdjustMatlPrefs( +void Enrichment::AdjustMatlPrefs( cyclus::PrefMap::type& prefs) { using cyclus::Bid; @@ -153,7 +153,7 @@ void EnrichmentFacility::AdjustMatlPrefs( } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::AcceptMatlTrades( +void Enrichment::AcceptMatlTrades( const std::vector< std::pair, cyclus::Material::Ptr> >& responses) { // see @@ -167,7 +167,7 @@ void EnrichmentFacility::AcceptMatlTrades( // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - std::set::Ptr> - EnrichmentFacility::GetMatlBids( + Enrichment::GetMatlBids( cyclus::CommodMap::type& out_requests){ using cyclus::Bid; using cyclus::BidPortfolio; @@ -198,11 +198,11 @@ std::set::Ptr> ports.insert(tails_port); } - if ((out_requests.count(out_commod) > 0) && (inventory.quantity() > 0)) { + if ((out_requests.count(product) > 0) && (inventory.quantity() > 0)) { BidPortfolio::Ptr commod_port(new BidPortfolio()); std::vector*>& commod_requests = - out_requests[out_commod]; + out_requests[product]; std::vector*>::iterator it; for (it = commod_requests.begin(); it != commod_requests.end(); ++it) { Request* req = *it; @@ -233,7 +233,7 @@ std::set::Ptr> } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EnrichmentFacility::ValidReq(const cyclus::Material::Ptr mat) { +bool Enrichment::ValidReq(const cyclus::Material::Ptr mat) { cyclus::toolkit::MatQuery q(mat); double u235 = q.atom_frac(922350000); double u238 = q.atom_frac(922380000); @@ -241,7 +241,7 @@ bool EnrichmentFacility::ValidReq(const cyclus::Material::Ptr mat) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::GetMatlTrades( +void Enrichment::GetMatlTrades( const std::vector< cyclus::Trade >& trades, std::vector, cyclus::Material::Ptr> >& responses) { @@ -267,7 +267,7 @@ void EnrichmentFacility::GetMatlTrades( LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " just received an order" << " for " << it->amt - << " of " << out_commod; + << " of " << product; response = Enrich_(it->bid->offer(), qty); } responses.push_back(std::make_pair(*it, response)); @@ -286,7 +286,7 @@ void EnrichmentFacility::GetMatlTrades( } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { +void Enrichment::AddMat_(cyclus::Material::Ptr mat) { // Elements and isotopes other than U-235, U-238 are sent directly to tails cyclus::CompMap cm = mat->comp()->atom(); bool extra_u = false; @@ -323,20 +323,20 @@ void EnrichmentFacility::AddMat_(cyclus::Material::Ptr mat) { } LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " added " - << mat->quantity() << " of " << in_commod + << mat->quantity() << " of " << feed << " to its inventory, which is holding " << inventory.quantity() << " total."; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacility::Request_() { +cyclus::Material::Ptr Enrichment::Request_() { double qty = std::max(0.0, MaxInventorySize() - InventorySize()); return cyclus::Material::CreateUntracked(qty, - context()->GetRecipe(in_recipe)); + context()->GetRecipe(feed_recipe)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { +cyclus::Material::Ptr Enrichment::Offer_(cyclus::Material::Ptr mat) { cyclus::toolkit::MatQuery q(mat); cyclus::CompMap comp; comp[922350000] = q.atom_frac(922350000); @@ -345,7 +345,7 @@ cyclus::Material::Ptr EnrichmentFacility::Offer_(cyclus::Material::Ptr mat) { mat->quantity(), cyclus::Composition::CreateFromAtom(comp)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacility::Enrich_( +cyclus::Material::Ptr Enrichment::Enrich_( cyclus::Material::Ptr mat, double qty) { @@ -426,7 +426,7 @@ cyclus::Material::Ptr EnrichmentFacility::Enrich_( } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacility::RecordEnrichment_(double natural_u, double swu) { +void Enrichment::RecordEnrichment_(double natural_u, double swu) { using cyclus::Context; using cyclus::Agent; @@ -444,7 +444,7 @@ void EnrichmentFacility::RecordEnrichment_(double natural_u, double swu) { ->Record(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -double EnrichmentFacility::FeedAssay() { +double Enrichment::FeedAssay() { using cyclus::Material; if (inventory.empty()) { @@ -456,8 +456,8 @@ double EnrichmentFacility::FeedAssay() { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern "C" cyclus::Agent* ConstructEnrichmentFacility(cyclus::Context* ctx) { - return new EnrichmentFacility(ctx); +extern "C" cyclus::Agent* ConstructEnrichment(cyclus::Context* ctx) { + return new Enrichment(ctx); } } // namespace cycamore diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index e7fc210fd5..90e1bf8e46 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -1,5 +1,5 @@ -#ifndef CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ -#define CYCAMORE_SRC_ENRICHMENT_FACILITY_H_ +#ifndef CYCAMORE_SRC_ENRICHMENT_H_ +#define CYCAMORE_SRC_ENRICHMENT_H_ #include @@ -79,25 +79,25 @@ class NatUConverter : public cyclus::Converter { double feed_, tails_; }; -/// EnrichmentFacility is a simple Agent that enriches natural +/// The Enrichment facility is a simple Agent that enriches natural /// uranium in a Cyclus simulation. It does not explicitly compute /// the physical enrichment process, rather it calculates the SWU /// required to convert an source uranium recipe (ie. natural uranium) /// into a requested enriched recipe (ie. 4% enriched uranium), given /// the natural uranium inventory constraint and its SWU capacity /// constraint. - -/// Enrichment Facility requests an input commodity and associated recipe +/// +/// The Enrichment facility requests an input commodity and associated recipe /// whose quantity is its remaining inventory capacity. All facilities /// trading the same input commodity (even with different recipes) will -/// offer materials for trade. The Enrichment Facility accepts any input +/// offer materials for trade. The Enrichment facility accepts any input /// materials with enrichments less than its tails assay, as long as some /// U235 is present, and preference increases with U235 content. If no /// U235 is present in the offered material, the trade preference is set /// to -1 and the material is not accepted. Any material components other /// other than U235 and U238 are sent directly to the tails buffer. - -/// EnrichmentFacility will bid on any request for its output commodity +/// +/// The Enrichment facility will bid on any request for its output commodity /// up to the maximum allowed enrichment (if not specified, default is 100%) /// It bids on either the request quantity, or the maximum quanity allowed /// by its SWU constraint or natural uranium inventory, whichever is lower. @@ -105,16 +105,16 @@ class NatUConverter : public cyclus::Converter { /// requested and the facility does not have the SWU or quantity capacity /// to meet all requests, the requests are fully, then partially filled /// in unspecified but repeatable order. - -/// EnrichmentFacility also offers its tails as an output commodity with +/// +/// The Enrichment facility also offers its tails as an output commodity with /// no associated recipe. Bids for tails are constrained only by total /// tails inventory. -class EnrichmentFacility : public cyclus::Facility { +class Enrichment : public cyclus::Facility { #pragma cyclus note { \ "niche": "enrichment facility", \ "doc": \ - "EnrichmentFacility is a simple Agent that enriches natural" \ + "The Enrichment facilityis a simple Agent that enriches natural" \ "uranium in a Cyclus simulation. It does not explicitly compute" \ "the physical enrichment process, rather it calculates the SWU" \ "required to convert an source uranium recipe (ie. natural uranium)" \ @@ -122,17 +122,17 @@ class EnrichmentFacility : public cyclus::Facility { "the natural uranium inventory constraint and its SWU capacity" \ "constraint." \ "\n\n" \ - "Enrichment Facility requests an input commodity and associated recipe" \ + "The Enrichment facility requests an input commodity and associated recipe" \ "whose quantity is its remaining inventory capacity. All facilities" \ "trading the same input commodity (even with different recipes) will" \ - "offer materials for trade. The Enrichment Facility accepts any input" \ + "offer materials for trade. The Enrichment facility accepts any input" \ "materials with enrichments less than its tails assay, as long as some" \ "U235 is present, and preference increases with U235 content. If no" \ "U235 is present in the offered material, the trade preference is set" \ "to -1 and the material is not accepted. Any material components other" \ "other than U235 and U238 are sent directly to the tails buffer." \ "\n\n" \ - "EnrichmentFacility will bid on any request for its output commodity" \ + "The Enrichment facility will bid on any request for its output commodity" \ "up to the maximum allowed enrichment (if not specified, default is 100%)" \ "It bids on either the request quantity, or the maximum quanity allowed" \ "by its SWU constraint or natural uranium inventory, whichever is lower." \ @@ -141,18 +141,17 @@ class EnrichmentFacility : public cyclus::Facility { "to meet all requests, the requests are fully, then partially filled" \ "in unspecified but repeatable order." \ "\n\n" \ - "EnrichmentFacility also offers its tails as an output commodity with" \ - "no associated recipe. Bids for tails are constrained only by total" \ - "tails inventory.", \ + "Accumulated tails inventory is offered for trading as a specifiable " \ + "output commodity.", \ } public: // --- Module Members --- - /// Constructor for the EnrichmentFacility class + /// Constructor for the Enrichment class /// @param ctx the cyclus context for access to simulation-wide parameters - EnrichmentFacility(cyclus::Context* ctx); + Enrichment(cyclus::Context* ctx); - /// Destructor for the EnrichmentFacility class - virtual ~EnrichmentFacility(); + /// Destructor for the Enrichment class + virtual ~Enrichment(); #pragma cyclus @@ -184,17 +183,17 @@ class EnrichmentFacility : public cyclus::Facility { /// @param time is the time to perform the tock virtual void Tock(); - /// @brief The EnrichmentFacility request Materials of its given + /// @brief The Enrichment request Materials of its given /// commodity. virtual std::set::Ptr> GetMatlRequests(); - /// @brief The EnrichmentFacility adjusts preferences for offers of + /// @brief The Enrichment adjusts preferences for offers of /// natural uranium it has received to maximize U-235 content /// Any offers that have zero U-235 content are not accepted virtual void AdjustMatlPrefs(cyclus::PrefMap::type& prefs); - /// @brief The EnrichmentFacility place accepted trade Materials in their + /// @brief The Enrichment place accepted trade Materials in their /// Inventory virtual void AcceptMatlTrades( const std::vector< std::pair, @@ -224,15 +223,15 @@ class EnrichmentFacility : public cyclus::Facility { /// @return true if the above description is met by the material bool ValidReq(const cyclus::Material::Ptr mat); - inline void in_commodity(std::string in_com) { in_commod = in_com; } + inline void feed_commod(std::string in_com) { feed = in_com; } - inline std::string in_commodity() const { return in_commod; } + inline std::string feed_commod() const { return feed; } - inline void out_commodity(std::string out_com) { - out_commod = out_com; + inline void product_commod(std::string out_com) { + product = out_com; } - inline std::string out_commodity() const { return out_commod; } + inline std::string product_commod() const { return product; } inline void tails_commodity(std::string tails_com) { tails_commod = tails_com; @@ -240,12 +239,12 @@ class EnrichmentFacility : public cyclus::Facility { inline std::string tails_commodity() const { return tails_commod; } - inline void InRecipe(std::string in_rec) { in_recipe = in_rec; } + inline void InRecipe(std::string in_rec) { feed_recipe = in_rec; } - inline std::string InRecipe() const { return in_recipe; } + inline std::string InRecipe() const { return feed_recipe; } inline void SetMaxInventorySize(double size) { - max_inv_size = size; + max_feed_inventory = size; inventory.capacity(size); } @@ -271,8 +270,8 @@ class EnrichmentFacility : public cyclus::Facility { inline double MaxEnrich() const { return max_enrich; } /// @brief this facility's initial conditions - inline void InitialReserves(double qty) { initial_reserves = qty; } - inline double InitialReserves() const { return initial_reserves; } + inline void InitialFeed(double qty) { initial_feed = qty; } + inline double InitialFeed() const { return initial_feed; } inline const cyclus::toolkit::ResBuf& Tails() const { return tails; @@ -280,7 +279,7 @@ class EnrichmentFacility : public cyclus::Facility { private: /// @brief adds a material into the natural uranium inventory - /// @throws if the material is not the same composition as the in_recipe + /// @throws if the material is not the same composition as the feed_recipe void AddMat_(cyclus::Material::Ptr mat); /// @brief generates a request for this facility given its current state. @@ -303,24 +302,24 @@ class EnrichmentFacility : public cyclus::Facility { /// @brief records and enrichment with the cyclus::Recorder void RecordEnrichment_(double natural_u, double swu); - #pragma cyclus var { \ - "tooltip": "input commodity", \ - "doc": "commodity that the enrichment facility accepts", \ + #pragma cyclus var { \ + "tooltip": "feed", \ + "doc": "feed commodity that the enrichment facility accepts", \ "uitype": "incommodity" \ } - std::string in_commod; + std::string feed; #pragma cyclus var { \ - "tooltip": "output commodity", \ - "doc": "commodity that the enrichment facility supplies", \ + "tooltip": "product", \ + "doc": "product commodity that the enrichment facility generates", \ "uitype": "outcommodity" \ } - std::string out_commod; + std::string product; #pragma cyclus var { \ - "tooltip": "input commodity recipe", \ - "doc": "recipe for enrichment facility input commodity", \ + "tooltip": "feed recipe", \ + "doc": "recipe for enrichment facility feed commodity", \ "uitype": "recipe" \ } - std::string in_recipe; + std::string feed_recipe; #pragma cyclus var { \ "tooltip": "tails commodity", \ "doc": "tails commodity supplied by enrichment facility", \ @@ -329,22 +328,22 @@ class EnrichmentFacility : public cyclus::Facility { std::string tails_commod; #pragma cyclus var { \ "default": 0.03, "tooltip": "tails assay", \ - "doc": "tails assay from the enrichment process" \ + "doc": "tails assay from the enrichment process" \ } double tails_assay; #pragma cyclus var { \ - "default": 1e299, \ + "default": 1e299, \ "tooltip": "SWU capacity (kgSWU/month)", \ - "doc": "separative work unit (SWU) capacity of enrichment " \ - "facility (kgSWU/month) " \ + "doc": "separative work unit (SWU) capacity of enrichment " \ + "facility (kgSWU/month) " \ } double swu_capacity; #pragma cyclus var { \ - "default": 1e299, "tooltip": "max inventory size (kg)", \ + "default": 1e299, "tooltip": "max inventory of feed material (kg)", \ "doc": "maximum total inventory of natural uranium in " \ - "the enrichment facility (kg)" \ + "the enrichment facility (kg)" \ } - double max_inv_size; + double max_feed_inventory; #pragma cyclus var { \ "default": 1.0, \ @@ -366,7 +365,7 @@ class EnrichmentFacility : public cyclus::Facility { "doc": "amount of natural uranium stored at the enrichment " \ "facility at the beginning of the simulation (kg)" \ } - double initial_reserves; + double initial_feed; #pragma cyclus var { \ "default": 1, \ "userlevel": 10, \ @@ -377,12 +376,12 @@ class EnrichmentFacility : public cyclus::Facility { bool order_prefs; #pragma cyclus var { 'derived_init': 'current_swu_capacity = swu_capacity;' } double current_swu_capacity; - #pragma cyclus var { 'capacity': 'max_inv_size' } + #pragma cyclus var { 'capacity': 'max_feed_inventory' } cyclus::toolkit::ResBuf inventory; // natural u #pragma cyclus var {} cyclus::toolkit::ResBuf tails; // depleted u - friend class EnrichmentFacilityTest; + friend class EnrichmentTest; // --- }; diff --git a/src/enrichment_facility_tests.cc b/src/enrichment_facility_tests.cc index a54a99edf5..442e1b64b1 100644 --- a/src/enrichment_facility_tests.cc +++ b/src/enrichment_facility_tests.cc @@ -51,21 +51,21 @@ Composition::Ptr c_heu() { }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, RequestQty) { +TEST_F(EnrichmentTest, RequestQty) { // this tests verifies that requests for input material are fulfilled // without providing any extra std::string config = - " natu " - " natu1 " - " enr_u " + " natu " + " natu1 " + " enr_u " " tails " - " 1.0 " + " 1.0 " " 0.003 "; int simdur = 1; cyclus::MockSim sim(cyclus::AgentSpec - (":cycamore:EnrichmentFacility"), config, simdur); + (":cycamore:Enrichment"), config, simdur); sim.AddRecipe("natu1", c_natu1()); sim.AddSource("natu") @@ -87,25 +87,25 @@ TEST_F(EnrichmentFacilityTest, RequestQty) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, CheckSWUConstraint) { +TEST_F(EnrichmentTest, CheckSWUConstraint) { // Tests that request for enrichment that exceeds the SWU constraint // fulfilled only up to the available SWU. - // Also confirms that initial_reserves flag works. + // Also confirms that initial_feed flag works. // 388 SWU = 10kg 80% enriched HEU from 486kg feed matl std::string config = - " natu " - " natu1 " - " enr_u " + " natu " + " natu1 " + " enr_u " " tails " " 0.003 " - " 1000 " + " 1000 " " 195 "; int simdur = 1; cyclus::MockSim sim(cyclus::AgentSpec - (":cycamore:EnrichmentFacility"), config, simdur); + (":cycamore:Enrichment"), config, simdur); sim.AddRecipe("natu1", c_natu1()); sim.AddRecipe("heu", c_heu()); @@ -128,22 +128,22 @@ TEST_F(EnrichmentFacilityTest, CheckSWUConstraint) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, CheckCapConstraint) { +TEST_F(EnrichmentTest, CheckCapConstraint) { // Tests that a request for more material than is available in // inventory is partially filled with only the inventory quantity. std::string config = - " natu " - " natu1 " - " enr_u " + " natu " + " natu1 " + " enr_u " " tails " " 0.003 " - " 243 "; + " 243 "; int simdur = 1; cyclus::MockSim sim(cyclus::AgentSpec - (":cycamore:EnrichmentFacility"), config, simdur); + (":cycamore:Enrichment"), config, simdur); sim.AddRecipe("natu1", c_natu1()); @@ -167,21 +167,21 @@ TEST_F(EnrichmentFacilityTest, CheckCapConstraint) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, RequestEnrich) { +TEST_F(EnrichmentTest, RequestEnrich) { // this tests verifies that requests for output material exceeding // the maximum allowed enrichment are not fulfilled. std::string config = - " natu " - " natu1 " - " enr_u " + " natu " + " natu1 " + " enr_u " " tails " " 0.003 " " 0.20 "; int simdur = 2; cyclus::MockSim sim(cyclus::AgentSpec - (":cycamore:EnrichmentFacility"), config, simdur); + (":cycamore:Enrichment"), config, simdur); sim.AddRecipe("natu1", c_natu1()); sim.AddRecipe("leu", c_leu()); sim.AddRecipe("heu", c_heu()); @@ -223,20 +223,20 @@ TEST_F(EnrichmentFacilityTest, RequestEnrich) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, TradeTails) { +TEST_F(EnrichmentTest, TradeTails) { // this tests whether tails are being traded. std::string config = - " natu " - " natu1 " - " enr_u " + " natu " + " natu1 " + " enr_u " " tails " " 0.003 "; // 1-source to EF, 2-Enrich, add to tails, 3-tails avail. for trade int simdur = 3; cyclus::MockSim sim(cyclus::AgentSpec - (":cycamore:EnrichmentFacility"), config, simdur); + (":cycamore:Enrichment"), config, simdur); sim.AddRecipe("natu1", c_natu1()); sim.AddRecipe("leu", c_leu()); @@ -260,21 +260,21 @@ TEST_F(EnrichmentFacilityTest, TradeTails) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, BidPrefs) { +TEST_F(EnrichmentTest, BidPrefs) { // This tests that natu sources are preference-ordered by // U235 content std::string config = - " natu " - " natu1 " - " enr_u " + " natu " + " natu1 " + " enr_u " " tails " " 0.003 " - " 1.0 "; + " 1.0 "; int simdur = 1; cyclus::MockSim sim(cyclus::AgentSpec - (":cycamore:EnrichmentFacility"), config, simdur); + (":cycamore:Enrichment"), config, simdur); sim.AddRecipe("natu1", c_natu1()); sim.AddRecipe("natu2", c_natu2()); @@ -311,22 +311,22 @@ TEST_F(EnrichmentFacilityTest, BidPrefs) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TEST_F(EnrichmentFacilityTest, NoBidPrefs) { + TEST_F(EnrichmentTest, NoBidPrefs) { // This tests that preference-ordering for sources // turns off correctly if flag is used std::string config = - " natu " - " natu1 " - " enr_u " + " natu " + " natu1 " + " enr_u " " tails " " 0.003 " - " 2.0 " + " 2.0 " " 0 "; int simdur = 1; cyclus::MockSim sim(cyclus::AgentSpec - (":cycamore:EnrichmentFacility"), config, simdur); + (":cycamore:Enrichment"), config, simdur); sim.AddRecipe("natu1", c_natu1()); sim.AddRecipe("natu2", c_natu2()); @@ -351,20 +351,20 @@ TEST_F(EnrichmentFacilityTest, BidPrefs) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, ZeroU235) { +TEST_F(EnrichmentTest, ZeroU235) { // Test that offers of natu with no u235 content are rejected std::string config = - " natu " - " natu1 " - " enr_u " + " natu " + " natu1 " + " enr_u " " tails " " 0.003 " - " 1.0 "; + " 1.0 "; int simdur = 1; cyclus::MockSim sim(cyclus::AgentSpec - (":cycamore:EnrichmentFacility"), config, simdur); + (":cycamore:Enrichment"), config, simdur); sim.AddRecipe("no_u235", c_nou235()); sim.AddRecipe("natu1", c_natu1()); @@ -383,36 +383,36 @@ TEST_F(EnrichmentFacilityTest, ZeroU235) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacilityTest::SetUp() { +void EnrichmentTest::SetUp() { cyclus::Env::SetNucDataPath(); cyclus::Context* ctx = tc_.get(); - src_facility = new EnrichmentFacility(ctx); + src_facility = new Enrichment(ctx); trader = tc_.trader(); InitParameters(); SetUpSource(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacilityTest::TearDown() { +void EnrichmentTest::TearDown() { delete src_facility; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacilityTest::InitParameters() { +void EnrichmentTest::InitParameters() { cyclus::Context* ctx = tc_.get(); - in_commod = "incommod"; - out_commod = "outcommod"; + feed = "incommod"; + product = "outcommod"; tails_commod = "tailscommod"; - in_recipe = "recipe"; + feed_recipe = "recipe"; feed_assay = 0.0072; cyclus::CompMap v; v[922350000] = feed_assay; v[922380000] = 1 - feed_assay; recipe = cyclus::Composition::CreateFromAtom(v); - ctx->AddRecipe(in_recipe, recipe); + ctx->AddRecipe(feed_recipe, recipe); tails_assay = 0.002; swu_capacity = 100; @@ -422,72 +422,72 @@ void EnrichmentFacilityTest::InitParameters() { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacilityTest::SetUpSource() { - src_facility->InRecipe(in_recipe); - src_facility->in_commodity(in_commod); - src_facility->out_commodity(out_commod); +void EnrichmentTest::SetUpSource() { + src_facility->InRecipe(feed_recipe); + src_facility->feed_commod(feed); + src_facility->product_commod(product); src_facility->tails_commodity(tails_commod); src_facility->TailsAssay(tails_assay); src_facility->MaxEnrich(max_enrich); src_facility->SetMaxInventorySize(inv_size); src_facility->SwuCapacity(swu_capacity); - src_facility->InitialReserves(reserves); + src_facility->InitialFeed(reserves); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacilityTest::GetMat(double qty) { +cyclus::Material::Ptr EnrichmentTest::GetMat(double qty) { return cyclus::Material::CreateUntracked(qty, - tc_.get()->GetRecipe(in_recipe)); + tc_.get()->GetRecipe(feed_recipe)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EnrichmentFacilityTest::DoAddMat(cyclus::Material::Ptr mat) { +void EnrichmentTest::DoAddMat(cyclus::Material::Ptr mat) { src_facility->AddMat_(mat); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr EnrichmentFacilityTest::DoRequest() { +cyclus::Material::Ptr EnrichmentTest::DoRequest() { return src_facility->Request_(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - cyclus::Material::Ptr -EnrichmentFacilityTest::DoOffer(cyclus::Material::Ptr mat) { +EnrichmentTest::DoOffer(cyclus::Material::Ptr mat) { return src_facility->Offer_(mat); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - cyclus::Material::Ptr -EnrichmentFacilityTest::DoEnrich(cyclus::Material::Ptr mat, double qty) { +EnrichmentTest::DoEnrich(cyclus::Material::Ptr mat, double qty) { return src_facility->Enrich_(mat, qty); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, Request) { +TEST_F(EnrichmentTest, Request) { // Tests that quantity in material request is accurate double req = inv_size; double add = 0; cyclus::Material::Ptr mat = DoRequest(); EXPECT_DOUBLE_EQ(mat->quantity(), req); - EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(in_recipe)); + EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(feed_recipe)); add = 2 * inv_size / 3; req -= add; DoAddMat(GetMat(add)); mat = DoRequest(); EXPECT_DOUBLE_EQ(mat->quantity(), req); - EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(in_recipe)); + EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(feed_recipe)); add = inv_size / 3; req = 0; DoAddMat(GetMat(add)); mat = DoRequest(); EXPECT_DOUBLE_EQ(mat->quantity(), req); - EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(in_recipe)); + EXPECT_EQ(mat->comp(), tc_.get()->GetRecipe(feed_recipe)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, ValidReq) { +TEST_F(EnrichmentTest, ValidReq) { // Tests that material requests have U235/(U235+U238) > tails assay using cyclus::CompMap; using cyclus::Composition; @@ -516,7 +516,7 @@ TEST_F(EnrichmentFacilityTest, ValidReq) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TEST_F(EnrichmentFacilityTest, ConstraintConverters) { + TEST_F(EnrichmentTest, ConstraintConverters) { // Tests the SWU and NatU converters to make sure that amount of // feed and SWU required are correct to fulfill the enrichment request. using cyclus::CompMap; @@ -556,7 +556,7 @@ TEST_F(EnrichmentFacilityTest, ValidReq) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, Enrich) { +TEST_F(EnrichmentTest, Enrich) { // this test asks the facility to enrich a material that results in an amount // of natural uranium required that is exactly its inventory level. that // inventory will be comprised of two materials to test the manifest/absorb @@ -605,7 +605,7 @@ TEST_F(EnrichmentFacilityTest, Enrich) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(EnrichmentFacilityTest, Response) { +TEST_F(EnrichmentTest, Response) { // this test asks the facility to respond to multiple requests for enriched // uranium. two requests are provided, whose total equals the swu capacity of // the facility while not exceeding its inventory capacity (that's taken care @@ -655,7 +655,7 @@ TEST_F(EnrichmentFacilityTest, Response) { src_facility->GetMatlTrades(trades, responses); Request* req = - Request::Create(target, trader, out_commod); + Request::Create(target, trader, product); Bid* bid = Bid::Create(req, target, src_facility); Trade trade(req, bid, trade_qty); trades.push_back(trade); @@ -672,8 +672,8 @@ TEST_F(EnrichmentFacilityTest, Response) { } // namespace cycamore // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Agent* EnrichmentFacilityConstructor(cyclus::Context* ctx) { - return new cycamore::EnrichmentFacility(ctx); +cyclus::Agent* EnrichmentConstructor(cyclus::Context* ctx) { + return new cycamore::Enrichment(ctx); } // required to get functionality in cyclus agent unit tests library @@ -685,6 +685,6 @@ static int cyclus_agent_tests_connected = ConnectAgentTests(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INSTANTIATE_TEST_CASE_P(EnrichmentFac, FacilityTests, - Values(&EnrichmentFacilityConstructor)); + Values(&EnrichmentConstructor)); INSTANTIATE_TEST_CASE_P(EnrichmentFac, AgentTests, - Values(&EnrichmentFacilityConstructor)); + Values(&EnrichmentConstructor)); diff --git a/src/enrichment_facility_tests.h b/src/enrichment_facility_tests.h index 109eb3a111..efdaeb0a39 100644 --- a/src/enrichment_facility_tests.h +++ b/src/enrichment_facility_tests.h @@ -1,5 +1,5 @@ -#ifndef CYCAMORE_SRC_ENRICHMENT_FACILITY_TESTS_ -#define CYCAMORE_SRC_ENRICHMENT_FACILITY_TESTS_ +#ifndef CYCAMORE_SRC_ENRICHMENT_TESTS_ +#define CYCAMORE_SRC_ENRICHMENT_TESTS_ #include @@ -15,11 +15,11 @@ namespace cycamore { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -class EnrichmentFacilityTest : public ::testing::Test { +class EnrichmentTest : public ::testing::Test { protected: cyclus::TestContext tc_; - EnrichmentFacility* src_facility; - std::string in_commod, out_commod, in_recipe, tails_commod; + Enrichment* src_facility; + std::string feed, product, feed_recipe, tails_commod; cyclus::Composition::Ptr recipe; TestFacility* trader; From b87a61c6b96083f15d10912efde4c0dc3610f26e Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Thu, 2 Apr 2015 12:36:44 -0500 Subject: [PATCH 145/314] removed pragma for current_swu_capacity --- src/enrichment_facility.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 90e1bf8e46..c8670b8174 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -374,8 +374,9 @@ class Enrichment : public cyclus::Facility { "so that EF chooses higher U235 content first" \ } bool order_prefs; - #pragma cyclus var { 'derived_init': 'current_swu_capacity = swu_capacity;' } + double current_swu_capacity; + #pragma cyclus var { 'capacity': 'max_feed_inventory' } cyclus::toolkit::ResBuf inventory; // natural u #pragma cyclus var {} From 2f5834cb42e0945b73a32fecff6b3683f2afc954 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Wed, 8 Apr 2015 10:31:56 -0500 Subject: [PATCH 146/314] changed feed/product to feed_commod/product_commod --- input/enrichment/1_src_enr_rxtr_sink.xml | 4 +- input/enrichment/linear_src_enr_rxtr_sink.xml | 4 +- input/enrichment/natu_capacitated.xml | 4 +- input/enrichment/swu_capacitated.xml | 4 +- input/physor/1_Enrichment_2_Reactor.xml | 4 +- src/enrichment_facility.cc | 14 +++---- src/enrichment_facility.h | 20 ++++----- src/enrichment_facility_tests.cc | 42 +++++++++---------- src/enrichment_facility_tests.h | 2 +- 9 files changed, 49 insertions(+), 49 deletions(-) diff --git a/input/enrichment/1_src_enr_rxtr_sink.xml b/input/enrichment/1_src_enr_rxtr_sink.xml index a62dbe8d66..ea8b519a41 100644 --- a/input/enrichment/1_src_enr_rxtr_sink.xml +++ b/input/enrichment/1_src_enr_rxtr_sink.xml @@ -31,8 +31,8 @@ Enrichment - natl_u - enriched_u + natl_u + enriched_u ef_tails natl_u 0.003 diff --git a/input/enrichment/linear_src_enr_rxtr_sink.xml b/input/enrichment/linear_src_enr_rxtr_sink.xml index 6e40a8635f..c2daee9706 100644 --- a/input/enrichment/linear_src_enr_rxtr_sink.xml +++ b/input/enrichment/linear_src_enr_rxtr_sink.xml @@ -31,10 +31,10 @@ Enrichment - natl_u + natl_u natl_u 1000 - enriched_u + enriched_u ef_tails 0.003 diff --git a/input/enrichment/natu_capacitated.xml b/input/enrichment/natu_capacitated.xml index 36c0b1dba8..b9a74d8af4 100644 --- a/input/enrichment/natu_capacitated.xml +++ b/input/enrichment/natu_capacitated.xml @@ -31,10 +31,10 @@ Enrichment - natl_u + natl_u natl_u 100 - enriched_u + enriched_u ef_tails 0.003 diff --git a/input/enrichment/swu_capacitated.xml b/input/enrichment/swu_capacitated.xml index 67cbec62a3..15c6baac5f 100644 --- a/input/enrichment/swu_capacitated.xml +++ b/input/enrichment/swu_capacitated.xml @@ -31,10 +31,10 @@ Enrichment - natl_u + natl_u natl_u 100 - enriched_u + enriched_u ef_tails 0.003 30.0 diff --git a/input/physor/1_Enrichment_2_Reactor.xml b/input/physor/1_Enrichment_2_Reactor.xml index dd0737fb69..ddb27a2b8e 100755 --- a/input/physor/1_Enrichment_2_Reactor.xml +++ b/input/physor/1_Enrichment_2_Reactor.xml @@ -18,9 +18,9 @@ Enrichment - natl_u + natl_u natl_u - enriched_u + enriched_u ef_tails 0.003 10.01 diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index c57e940285..8f8b928ab7 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -17,9 +17,9 @@ Enrichment::Enrichment(cyclus::Context* ctx) swu_capacity(0), max_enrich(1), initial_feed(0), - feed(""), + feed_commod(""), feed_recipe(""), - product(""), + product_commod(""), tails_commod(""), order_prefs(true){} @@ -82,7 +82,7 @@ std::set::Ptr> double amt = mat->quantity(); if (amt > cyclus::eps()) { - port->AddRequest(mat, this, feed); + port->AddRequest(mat, this, feed_commod); ports.insert(port); } @@ -198,11 +198,11 @@ std::set::Ptr> ports.insert(tails_port); } - if ((out_requests.count(product) > 0) && (inventory.quantity() > 0)) { + if ((out_requests.count(product_commod) > 0) && (inventory.quantity() > 0)) { BidPortfolio::Ptr commod_port(new BidPortfolio()); std::vector*>& commod_requests = - out_requests[product]; + out_requests[product_commod]; std::vector*>::iterator it; for (it = commod_requests.begin(); it != commod_requests.end(); ++it) { Request* req = *it; @@ -267,7 +267,7 @@ void Enrichment::GetMatlTrades( LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " just received an order" << " for " << it->amt - << " of " << product; + << " of " << product_commod; response = Enrich_(it->bid->offer(), qty); } responses.push_back(std::make_pair(*it, response)); @@ -323,7 +323,7 @@ void Enrichment::AddMat_(cyclus::Material::Ptr mat) { } LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << " added " - << mat->quantity() << " of " << feed + << mat->quantity() << " of " << feed_commod << " to its inventory, which is holding " << inventory.quantity() << " total."; } diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index c8670b8174..d9aa973855 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -13,7 +13,7 @@ namespace cycamore { /// determine the amount of SWU required for their proposed enrichment class SWUConverter : public cyclus::Converter { public: - SWUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} + SWUConverter(double feed_commod, double tails) : feed_(feed_commod), tails_(tails) {} virtual ~SWUConverter() {} /// @brief provides a conversion for the SWU required @@ -46,7 +46,7 @@ class SWUConverter : public cyclus::Converter { /// enrichment class NatUConverter : public cyclus::Converter { public: - NatUConverter(double feed, double tails) : feed_(feed), tails_(tails) {} + NatUConverter(double feed_commod, double tails) : feed_(feed_commod), tails_(tails) {} virtual ~NatUConverter() {} /// @brief provides a conversion for the amount of natural Uranium required @@ -223,15 +223,15 @@ class Enrichment : public cyclus::Facility { /// @return true if the above description is met by the material bool ValidReq(const cyclus::Material::Ptr mat); - inline void feed_commod(std::string in_com) { feed = in_com; } + inline void feed_commod(std::string in_com) { feed_commod = in_com; } - inline std::string feed_commod() const { return feed; } + inline std::string feed_commod() const { return feed_commod; } inline void product_commod(std::string out_com) { - product = out_com; + product_commod = out_com; } - inline std::string product_commod() const { return product; } + inline std::string product_commod() const { return product_commod; } inline void tails_commodity(std::string tails_com) { tails_commod = tails_com; @@ -303,17 +303,17 @@ class Enrichment : public cyclus::Facility { void RecordEnrichment_(double natural_u, double swu); #pragma cyclus var { \ - "tooltip": "feed", \ + "tooltip": "feed commodity", \ "doc": "feed commodity that the enrichment facility accepts", \ "uitype": "incommodity" \ } - std::string feed; + std::string feed_commod; #pragma cyclus var { \ - "tooltip": "product", \ + "tooltip": "product commodity", \ "doc": "product commodity that the enrichment facility generates", \ "uitype": "outcommodity" \ } - std::string product; + std::string product_commod; #pragma cyclus var { \ "tooltip": "feed recipe", \ "doc": "recipe for enrichment facility feed commodity", \ diff --git a/src/enrichment_facility_tests.cc b/src/enrichment_facility_tests.cc index 442e1b64b1..1f70045a7f 100644 --- a/src/enrichment_facility_tests.cc +++ b/src/enrichment_facility_tests.cc @@ -56,9 +56,9 @@ TEST_F(EnrichmentTest, RequestQty) { // without providing any extra std::string config = - " natu " + " natu " " natu1 " - " enr_u " + " enr_u " " tails " " 1.0 " " 0.003 "; @@ -94,9 +94,9 @@ TEST_F(EnrichmentTest, CheckSWUConstraint) { // 388 SWU = 10kg 80% enriched HEU from 486kg feed matl std::string config = - " natu " + " natu " " natu1 " - " enr_u " + " enr_u " " tails " " 0.003 " " 1000 " @@ -133,9 +133,9 @@ TEST_F(EnrichmentTest, CheckCapConstraint) { // inventory is partially filled with only the inventory quantity. std::string config = - " natu " + " natu " " natu1 " - " enr_u " + " enr_u " " tails " " 0.003 " " 243 "; @@ -172,9 +172,9 @@ TEST_F(EnrichmentTest, RequestEnrich) { // the maximum allowed enrichment are not fulfilled. std::string config = - " natu " + " natu " " natu1 " - " enr_u " + " enr_u " " tails " " 0.003 " " 0.20 "; @@ -227,9 +227,9 @@ TEST_F(EnrichmentTest, TradeTails) { // this tests whether tails are being traded. std::string config = - " natu " + " natu " " natu1 " - " enr_u " + " enr_u " " tails " " 0.003 "; @@ -265,9 +265,9 @@ TEST_F(EnrichmentTest, BidPrefs) { // U235 content std::string config = - " natu " + " natu " " natu1 " - " enr_u " + " enr_u " " tails " " 0.003 " " 1.0 "; @@ -316,9 +316,9 @@ TEST_F(EnrichmentTest, BidPrefs) { // turns off correctly if flag is used std::string config = - " natu " + " natu " " natu1 " - " enr_u " + " enr_u " " tails " " 0.003 " " 2.0 " @@ -355,9 +355,9 @@ TEST_F(EnrichmentTest, ZeroU235) { // Test that offers of natu with no u235 content are rejected std::string config = - " natu " + " natu " " natu1 " - " enr_u " + " enr_u " " tails " " 0.003 " " 1.0 "; @@ -401,8 +401,8 @@ void EnrichmentTest::TearDown() { void EnrichmentTest::InitParameters() { cyclus::Context* ctx = tc_.get(); - feed = "incommod"; - product = "outcommod"; + feed_commod = "incommod"; + product_commod = "outcommod"; tails_commod = "tailscommod"; feed_recipe = "recipe"; @@ -424,8 +424,8 @@ void EnrichmentTest::InitParameters() { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentTest::SetUpSource() { src_facility->InRecipe(feed_recipe); - src_facility->feed_commod(feed); - src_facility->product_commod(product); + src_facility->feed_commod(feed_commod); + src_facility->product_commod(product_commod); src_facility->tails_commodity(tails_commod); src_facility->TailsAssay(tails_assay); src_facility->MaxEnrich(max_enrich); @@ -655,7 +655,7 @@ TEST_F(EnrichmentTest, Response) { src_facility->GetMatlTrades(trades, responses); Request* req = - Request::Create(target, trader, product); + Request::Create(target, trader, product_commod); Bid* bid = Bid::Create(req, target, src_facility); Trade trade(req, bid, trade_qty); trades.push_back(trade); diff --git a/src/enrichment_facility_tests.h b/src/enrichment_facility_tests.h index efdaeb0a39..91d5b826e5 100644 --- a/src/enrichment_facility_tests.h +++ b/src/enrichment_facility_tests.h @@ -19,7 +19,7 @@ class EnrichmentTest : public ::testing::Test { protected: cyclus::TestContext tc_; Enrichment* src_facility; - std::string feed, product, feed_recipe, tails_commod; + std::string feed_commod, product_commod, feed_recipe, tails_commod; cyclus::Composition::Ptr recipe; TestFacility* trader; From d623f556b25fe868ade8b5f44f8d549e9b8d789c Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Wed, 8 Apr 2015 11:34:36 -0500 Subject: [PATCH 147/314] formatting --- src/enrichment_facility.cc | 4 +--- src/enrichment_facility.h | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 8f8b928ab7..ab64bced12 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -90,7 +90,6 @@ std::set::Ptr> } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// Sort bids by U-235 content bool SortBids( cyclus::Bid* i, cyclus::Bid* j) { @@ -166,8 +165,7 @@ void Enrichment::AcceptMatlTrades( } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> - Enrichment::GetMatlBids( +std::set::Ptr> Enrichment::GetMatlBids( cyclus::CommodMap::type& out_requests){ using cyclus::Bid; using cyclus::BidPortfolio; diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index d9aa973855..5d6787d3ab 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -64,11 +64,11 @@ class NatUConverter : public cyclus::Converter { double natu_frac = mq.mass_frac(nucs); double natu_req = cyclus::toolkit::FeedQty(m->quantity(), assays); - return natu_req/natu_frac; + return natu_req / natu_frac; } /// @returns true if Converter is a NatUConverter and feed and tails equal - virtual bool operator == (Converter& other) const { + virtual bool operator==(Converter& other) const { NatUConverter* cast = dynamic_cast(&other); return cast != NULL && feed_ == cast->feed_ && From 66416c73b9c0e5886cda93ff4e1002823c28aa6d Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Wed, 8 Apr 2015 11:49:26 -0500 Subject: [PATCH 148/314] fixed errors due to new product_commod, feed_commod names --- src/enrichment_facility.cc | 4 ++-- src/enrichment_facility.h | 8 ++++---- src/enrichment_facility_tests.cc | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index ab64bced12..3d981fda43 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -34,8 +34,8 @@ std::string Enrichment::str() { << " * SWU capacity: " << SwuCapacity() << " * Tails assay: " << TailsAssay() << " * Feed assay: " << FeedAssay() - << " * Input cyclus::Commodity: " << feed_commod() - << " * Output cyclus::Commodity: " << product_commod() + << " * Input cyclus::Commodity: " << feed_commodity() + << " * Output cyclus::Commodity: " << product_commodity() << " * Tails cyclus::Commodity: " << tails_commodity(); return ss.str(); } diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 5d6787d3ab..a92260ac92 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -223,15 +223,15 @@ class Enrichment : public cyclus::Facility { /// @return true if the above description is met by the material bool ValidReq(const cyclus::Material::Ptr mat); - inline void feed_commod(std::string in_com) { feed_commod = in_com; } + inline void feed_commodity(std::string in_com) { feed_commod = in_com; } - inline std::string feed_commod() const { return feed_commod; } + inline std::string feed_commodity() const { return feed_commod; } - inline void product_commod(std::string out_com) { + inline void product_commodity(std::string out_com) { product_commod = out_com; } - inline std::string product_commod() const { return product_commod; } + inline std::string product_commodity() const { return product_commod; } inline void tails_commodity(std::string tails_com) { tails_commod = tails_com; diff --git a/src/enrichment_facility_tests.cc b/src/enrichment_facility_tests.cc index 1f70045a7f..04c8a0120d 100644 --- a/src/enrichment_facility_tests.cc +++ b/src/enrichment_facility_tests.cc @@ -424,8 +424,8 @@ void EnrichmentTest::InitParameters() { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentTest::SetUpSource() { src_facility->InRecipe(feed_recipe); - src_facility->feed_commod(feed_commod); - src_facility->product_commod(product_commod); + src_facility->feed_commodity(feed_commod); + src_facility->product_commodity(product_commod); src_facility->tails_commodity(tails_commod); src_facility->TailsAssay(tails_assay); src_facility->MaxEnrich(max_enrich); From b1c4c40ab127d707ce85147f6e26df55e51a12d9 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Wed, 8 Apr 2015 16:00:01 -0500 Subject: [PATCH 149/314] removed getters/setters for state vars --- src/enrichment_facility.cc | 16 +++++------ src/enrichment_facility.h | 48 ++++---------------------------- src/enrichment_facility_tests.cc | 25 ++++++++--------- 3 files changed, 26 insertions(+), 63 deletions(-) diff --git a/src/enrichment_facility.cc b/src/enrichment_facility.cc index 3d981fda43..ff0fded925 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment_facility.cc @@ -32,11 +32,11 @@ std::string Enrichment::str() { ss << cyclus::Facility::str() << " with enrichment facility parameters:" << " * SWU capacity: " << SwuCapacity() - << " * Tails assay: " << TailsAssay() + << " * Tails assay: " << tails_assay << " * Feed assay: " << FeedAssay() - << " * Input cyclus::Commodity: " << feed_commodity() - << " * Output cyclus::Commodity: " << product_commodity() - << " * Tails cyclus::Commodity: " << tails_commodity(); + << " * Input cyclus::Commodity: " << feed_commod + << " * Output cyclus::Commodity: " << product_commod + << " * Tails cyclus::Commodity: " << tails_commod; return ss.str(); } @@ -235,7 +235,7 @@ bool Enrichment::ValidReq(const cyclus::Material::Ptr mat) { cyclus::toolkit::MatQuery q(mat); double u235 = q.atom_frac(922350000); double u238 = q.atom_frac(922380000); - return (u238 > 0 && u235 / (u235 + u238) > TailsAssay()); + return (u238 > 0 && u235 / (u235 + u238) > tails_assay); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -328,7 +328,7 @@ void Enrichment::AddMat_(cyclus::Material::Ptr mat) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - cyclus::Material::Ptr Enrichment::Request_() { - double qty = std::max(0.0, MaxInventorySize() - InventorySize()); + double qty = std::max(0.0, inventory.capacity() - inventory.quantity()); return cyclus::Material::CreateUntracked(qty, context()->GetRecipe(feed_recipe)); } @@ -356,7 +356,7 @@ cyclus::Material::Ptr Enrichment::Enrich_( using cyclus::toolkit::TailsQty; // get enrichment parameters - Assays assays(FeedAssay(), UraniumAssay(mat), TailsAssay()); + Assays assays(FeedAssay(), UraniumAssay(mat), tails_assay); double swu_req = SwuRequired(qty, assays); double natu_req = FeedQty(qty, assays); @@ -418,7 +418,7 @@ cyclus::Material::Ptr Enrichment::Enrich_( LOG(cyclus::LEV_INFO5, "EnrFac") << " * SWU: " << swu_req; LOG(cyclus::LEV_INFO5, "EnrFac") << " * Current SWU capacity: " - << CurrentSwuCapacity(); + << current_swu_capacity; return response; } diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index a92260ac92..def89331e4 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -13,7 +13,8 @@ namespace cycamore { /// determine the amount of SWU required for their proposed enrichment class SWUConverter : public cyclus::Converter { public: - SWUConverter(double feed_commod, double tails) : feed_(feed_commod), tails_(tails) {} + SWUConverter(double feed_commod, double tails) : feed_(feed_commod), + tails_(tails) {} virtual ~SWUConverter() {} /// @brief provides a conversion for the SWU required @@ -46,7 +47,8 @@ class SWUConverter : public cyclus::Converter { /// enrichment class NatUConverter : public cyclus::Converter { public: - NatUConverter(double feed_commod, double tails) : feed_(feed_commod), tails_(tails) {} + NatUConverter(double feed_commod, double tails) : feed_(feed_commod), + tails_(tails) {} virtual ~NatUConverter() {} /// @brief provides a conversion for the amount of natural Uranium required @@ -222,40 +224,12 @@ class Enrichment : public cyclus::Facility { /// U235-to-U238 ratio less than this facility's tails_assay(). /// @return true if the above description is met by the material bool ValidReq(const cyclus::Material::Ptr mat); - - inline void feed_commodity(std::string in_com) { feed_commod = in_com; } - - inline std::string feed_commodity() const { return feed_commod; } - - inline void product_commodity(std::string out_com) { - product_commod = out_com; - } - - inline std::string product_commodity() const { return product_commod; } - - inline void tails_commodity(std::string tails_com) { - tails_commod = tails_com; - } - - inline std::string tails_commodity() const { return tails_commod; } - - inline void InRecipe(std::string in_rec) { feed_recipe = in_rec; } - - inline std::string InRecipe() const { return feed_recipe; } - inline void SetMaxInventorySize(double size) { + inline void SetMaxInventorySize(double size) { max_feed_inventory = size; inventory.capacity(size); } - - inline double MaxInventorySize() const { return inventory.capacity(); } - - inline double InventorySize() const { return inventory.quantity(); } - inline void TailsAssay(double assay) { tails_assay = assay; } - - inline double TailsAssay() const { return tails_assay; } - inline void SwuCapacity(double capacity) { swu_capacity = capacity; current_swu_capacity = swu_capacity; @@ -263,20 +237,10 @@ class Enrichment : public cyclus::Facility { inline double SwuCapacity() const { return swu_capacity; } - inline double CurrentSwuCapacity() const { return current_swu_capacity; } - - inline void MaxEnrich(double enrichment) { max_enrich = enrichment; } - - inline double MaxEnrich() const { return max_enrich; } - - /// @brief this facility's initial conditions - inline void InitialFeed(double qty) { initial_feed = qty; } - inline double InitialFeed() const { return initial_feed; } - inline const cyclus::toolkit::ResBuf& Tails() const { return tails; } - + private: /// @brief adds a material into the natural uranium inventory /// @throws if the material is not the same composition as the feed_recipe diff --git a/src/enrichment_facility_tests.cc b/src/enrichment_facility_tests.cc index 04c8a0120d..129c905cf7 100644 --- a/src/enrichment_facility_tests.cc +++ b/src/enrichment_facility_tests.cc @@ -415,7 +415,7 @@ void EnrichmentTest::InitParameters() { ctx->AddRecipe(feed_recipe, recipe); tails_assay = 0.002; - swu_capacity = 100; + swu_capacity = 100; //** inv_size = 5; reserves = 105.5; @@ -423,15 +423,15 @@ void EnrichmentTest::InitParameters() { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EnrichmentTest::SetUpSource() { - src_facility->InRecipe(feed_recipe); - src_facility->feed_commodity(feed_commod); - src_facility->product_commodity(product_commod); - src_facility->tails_commodity(tails_commod); - src_facility->TailsAssay(tails_assay); - src_facility->MaxEnrich(max_enrich); + src_facility->feed_recipe = feed_recipe; + src_facility->feed_commod = feed_commod; + src_facility->product_commod = product_commod; + src_facility->tails_commod = tails_commod; + src_facility->tails_assay = tails_assay; + src_facility->max_enrich = max_enrich; src_facility->SetMaxInventorySize(inv_size); src_facility->SwuCapacity(swu_capacity); - src_facility->InitialFeed(reserves); + src_facility->initial_feed = reserves; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -592,7 +592,7 @@ TEST_F(EnrichmentTest, Enrich) { Material::Ptr response; EXPECT_NO_THROW(response = DoEnrich(target, qty)); - EXPECT_DOUBLE_EQ(src_facility->Tails().quantity(), tails_qty); + EXPECT_DOUBLE_EQ(src_facility->Tails().quantity(), tails_qty); MatQuery q(response); EXPECT_EQ(response->quantity(), qty); @@ -643,12 +643,11 @@ TEST_F(EnrichmentTest, Response) { double swu_req = SwuRequired(qty, assays); double natu_req = FeedQty(qty, assays); - src_facility->SetMaxInventorySize(natu_req * 4); // not capacitated by nat u + src_facility->SetMaxInventorySize(natu_req * 4); // not capacitated by nat src_facility->SwuCapacity(swu_req); // swu capacitated - - src_facility->GetMatlTrades(trades, responses); - + src_facility->GetMatlTrades(trades, responses); + // set up state DoAddMat(GetMat(natu_req * 2)); From c173e1108d07b5cfa77627a1ff6ff52ad9bbc0b6 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Fri, 10 Apr 2015 10:06:13 -0500 Subject: [PATCH 150/314] fixed nosetests failure --- tests/test_regression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index 922fcdc26c..66e150929e 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -110,7 +110,7 @@ def setUp(self): super(TestPhysorEnrichment, self).setUp() tbl = self.agent_entry self.rx_id = self.find_ids(":cycamore:Reactor", tbl) - self.enr_id = self.find_ids(":cycamore:EnrichmentFacility", tbl) + self.enr_id = self.find_ids(":cycamore:Enrichment", tbl) def test_deploy(self): assert_equal(len(self.rx_id), 2) From 30eed2c6a0ec721890477a1f1cb1b03e65cc3239 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 15 Apr 2015 14:54:07 -0500 Subject: [PATCH 151/314] rm'd use of source and sink from agent lib in tests --- tests/input/dynamic_capacitated.xml | 10 +++++----- tests/test_regression.py | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/input/dynamic_capacitated.xml b/tests/input/dynamic_capacitated.xml index 8b9de23502..ccc69f1747 100644 --- a/tests/input/dynamic_capacitated.xml +++ b/tests/input/dynamic_capacitated.xml @@ -8,8 +8,8 @@ - agentsSink - agentsSource + cycamoreSink + cycamoreSource agentsNullRegion cycamoreDeployInst @@ -18,9 +18,9 @@ Source - commodity - commod_recipe - 1.0 + commodity + commod_recipe + 1.0 diff --git a/tests/test_regression.py b/tests/test_regression.py index 66e150929e..9c315b3a9f 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -263,8 +263,8 @@ def setUp(self): self.depl_time = self.to_ary(self.agent_entry, "EnterTime") self.exit_time = self.to_ary(self.agent_exit, "ExitTime") self.exit_ids = self.to_ary(self.agent_exit, "AgentId") - self.source_id = self.find_ids(":agents:Source", self.agent_entry) - self.sink_id = self.find_ids(":agents:Sink", self.agent_entry) + self.source_id = self.find_ids(":cycamore:Source", self.agent_entry) + self.sink_id = self.find_ids(":cycamore:Sink", self.agent_entry) # Check transactions self.sender_ids = self.to_ary(self.transactions, "SenderId") From 87e9c246e85281b62e49402d90de9f385065b827 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 21 Apr 2015 10:32:28 -0500 Subject: [PATCH 152/314] adding travis.yml --- .travis.yml | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..3becb17748 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,49 @@ +language: python +python: + # We don't actually use the Travis Python, but this keeps it organized. + - "2.7" + - "3.4" + +before_install: + - sudo apt-get update -qq + +install: + # You may want to periodically update this, although the conda update + # conda line below will keep everything up-to-date. We do this + # conditionally because it saves us some downloading if the version is + # the same. + - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then + wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh; + else + wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; + fi + - bash miniconda.sh -b -p $HOME/miniconda + - export PATH="$HOME/miniconda/bin:$PATH" + - hash -r + - conda config --set always_yes yes --set changeps1 no + - conda config --add channels pyne + - conda config --add channels cyclus + - conda config --add channels cycamore + - conda update -q conda + - conda install conda-build jinja2 setuptools binstar patchelf nose + # Useful for debugging any issues with conda + - conda info -a + + # download CI repo + - wget https://github.com/cyclus/ciclus/archive/master.zip -O ciclus.zip + - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe + + # Replace dep1 dep2 ... with your dependencies + #- conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION dep1 dep2 ... + #- source activate test-environment + - conda build --no-test conda-recipe + - conda install cycamore --use-local + +script: + - cycamore_unit_tests + - nosetests -w tests + #- cd tests + #- nosetests + #- ./travis-run-tests.sh + + From e23c820cfee4f2ebd9d286b3268d649b3df7884b Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 21 Apr 2015 13:39:20 -0500 Subject: [PATCH 153/314] rm cycamore as binstar user --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3becb17748..12755d392b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,8 @@ python: # We don't actually use the Travis Python, but this keeps it organized. - "2.7" - "3.4" - before_install: - sudo apt-get update -qq - install: # You may want to periodically update this, although the conda update # conda line below will keep everything up-to-date. We do this @@ -23,7 +21,6 @@ install: - conda config --set always_yes yes --set changeps1 no - conda config --add channels pyne - conda config --add channels cyclus - - conda config --add channels cycamore - conda update -q conda - conda install conda-build jinja2 setuptools binstar patchelf nose # Useful for debugging any issues with conda From 6884f7ef094b6e641b01ebff5f7512295f870cc8 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 21 Apr 2015 16:51:47 -0500 Subject: [PATCH 154/314] updating path and tables install --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 12755d392b..f8e2e5d435 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ install: - conda config --add channels pyne - conda config --add channels cyclus - conda update -q conda - - conda install conda-build jinja2 setuptools binstar patchelf nose + - conda install conda-build setuptools binstar patchelf nose # Useful for debugging any issues with conda - conda info -a @@ -37,6 +37,8 @@ install: - conda install cycamore --use-local script: + - export PATH="$HOME/miniconda/bin:$PATH" + - conda install tables - cycamore_unit_tests - nosetests -w tests #- cd tests From bf235f2452ec69876d899b71c5d42e18bbf1c6ce Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 21 Apr 2015 16:52:55 -0500 Subject: [PATCH 155/314] numpy install --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f8e2e5d435..061440d20b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,7 +38,7 @@ install: script: - export PATH="$HOME/miniconda/bin:$PATH" - - conda install tables + - conda install numpy tables - cycamore_unit_tests - nosetests -w tests #- cd tests From dc7526d28b0f2174b11c708f846b8630738737a9 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 22 Apr 2015 10:56:36 -0500 Subject: [PATCH 156/314] updating from cyclus yml --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 061440d20b..dc2c452196 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,6 +38,11 @@ install: script: - export PATH="$HOME/miniconda/bin:$PATH" + - export LD_LIBRARY_PATH="$HOME/miniconda/lib:$HOME/miniconda/envs/_build/lib:$LD_LIBRARY_PATH" + - ls -l $HOME/miniconda/lib + - ls -l $HOME/miniconda/envs/_build/lib + - ln -s $HOME/miniconda/lib/libhdf5.so.9 $HOME/miniconda/lib/libhdf5.so.8 + - ln -s $HOME/miniconda/lib/libhdf5_hl.so.9 $HOME/miniconda/lib/libhdf5_hl.so.8 - conda install numpy tables - cycamore_unit_tests - nosetests -w tests From b33517b121b342c72237dd034bda2e3eb15e9fd4 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 22 Apr 2015 17:48:36 -0500 Subject: [PATCH 157/314] matching cyclus --- .travis.yml | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index dc2c452196..0bdcac5064 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,32 +22,30 @@ install: - conda config --add channels pyne - conda config --add channels cyclus - conda update -q conda - - conda install conda-build setuptools binstar patchelf nose + - conda install conda-build jinja2 setuptools binstar patchelf nose # Useful for debugging any issues with conda - conda info -a # download CI repo - wget https://github.com/cyclus/ciclus/archive/master.zip -O ciclus.zip - - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe - - # Replace dep1 dep2 ... with your dependencies - #- conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION dep1 dep2 ... - #- source activate test-environment - - conda build --no-test conda-recipe - - conda install cycamore --use-local + - unzip -j ciclus.zip + + # build cyclus + - mv ciclus/cyclus conda-recipe-cyclus + - conda build --no-test conda-recipe-cyclus + - conda install --use-local cyclus=0.0 + + # build cycamore + - mv ciclus/cycamore conda-recipe-cycamore + - conda build --no-test conda-recipe-cycamore + - conda install --use-local cycamore=0.0 script: - export PATH="$HOME/miniconda/bin:$PATH" - - export LD_LIBRARY_PATH="$HOME/miniconda/lib:$HOME/miniconda/envs/_build/lib:$LD_LIBRARY_PATH" - - ls -l $HOME/miniconda/lib - - ls -l $HOME/miniconda/envs/_build/lib - - ln -s $HOME/miniconda/lib/libhdf5.so.9 $HOME/miniconda/lib/libhdf5.so.8 - - ln -s $HOME/miniconda/lib/libhdf5_hl.so.9 $HOME/miniconda/lib/libhdf5_hl.so.8 - - conda install numpy tables + - export LD_LIBRARY_PATH="$HOME/miniconda/lib:$LD_LIBRARY_PATH" + #- ls -l $HOME/miniconda/lib + #- ls -l $HOME/miniconda/envs/_build/lib - cycamore_unit_tests + - conda install numpy tables - nosetests -w tests - #- cd tests - #- nosetests - #- ./travis-run-tests.sh - From aa10d1bc5a0e43b52fe164aa89b4f69e67b176e7 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 22 Apr 2015 17:50:17 -0500 Subject: [PATCH 158/314] grabbing correct ciclus --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0bdcac5064..1d51093559 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,7 @@ install: - conda info -a # download CI repo - - wget https://github.com/cyclus/ciclus/archive/master.zip -O ciclus.zip + - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - unzip -j ciclus.zip # build cyclus From 5df1535be38c8870834ced308a3ca52f96a775ab Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 22 Apr 2015 18:13:53 -0500 Subject: [PATCH 159/314] mirroring cyclus unzip --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1d51093559..d6eb10b32b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,14 +28,15 @@ install: # download CI repo - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - - unzip -j ciclus.zip # build cyclus + - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe-cyclus - mv ciclus/cyclus conda-recipe-cyclus - conda build --no-test conda-recipe-cyclus - conda install --use-local cyclus=0.0 # build cycamore + - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe-cycamore - mv ciclus/cycamore conda-recipe-cycamore - conda build --no-test conda-recipe-cycamore - conda install --use-local cycamore=0.0 From c7c45cc38ee0f8459d016f92090b7a2b68e0d0f9 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 22 Apr 2015 18:23:41 -0500 Subject: [PATCH 160/314] rm mvs --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d6eb10b32b..09c1b2a1bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,13 +31,11 @@ install: # build cyclus - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe-cyclus - - mv ciclus/cyclus conda-recipe-cyclus - conda build --no-test conda-recipe-cyclus - conda install --use-local cyclus=0.0 # build cycamore - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe-cycamore - - mv ciclus/cycamore conda-recipe-cycamore - conda build --no-test conda-recipe-cycamore - conda install --use-local cycamore=0.0 From c8773ab838b053f39a11d685f490f17a3146457c Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 22 Apr 2015 18:34:34 -0500 Subject: [PATCH 161/314] maybe conda-recipe name matters --- .travis.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 09c1b2a1bf..9e414d829c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,13 +30,14 @@ install: - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip # build cyclus - - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe-cyclus - - conda build --no-test conda-recipe-cyclus + - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe + - conda build --no-test conda-recipe - conda install --use-local cyclus=0.0 + - mv conda-recipe conda-recipe-cyclus # build cycamore - - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe-cycamore - - conda build --no-test conda-recipe-cycamore + - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe + - conda build --no-test conda-recipe - conda install --use-local cycamore=0.0 script: From 5808f75a18b0bd2d20778d6c70a452522b994a23 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 08:55:28 -0500 Subject: [PATCH 162/314] trying now with sedding the right cyclus --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9e414d829c..08589b0985 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,12 +33,14 @@ install: - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe - conda build --no-test conda-recipe - conda install --use-local cyclus=0.0 - - mv conda-recipe conda-recipe-cyclus + - mv conda-recipe cyclus-recipe # build cycamore - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe + - sed -i "s/- cyclus/- cyclus=0.0/g" conda-recipe/meta.yaml - conda build --no-test conda-recipe - conda install --use-local cycamore=0.0 + - mv conda-recipe cycamore-recipe script: - export PATH="$HOME/miniconda/bin:$PATH" From 7054c3c7741e2e87d78bc63ee5e8ee819d46d1cd Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 09:02:51 -0500 Subject: [PATCH 163/314] trying some cyclus foo --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.travis.yml b/.travis.yml index 08589b0985..d2ca4ae79a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,10 +30,17 @@ install: - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip # build cyclus + - pwd=$PWD + - echo "pwd: $pwd" + - cd $HOME + - git clone git@github.com:gidden/cyclus + - cd cyclus + - git checkout origin/travis - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe - conda build --no-test conda-recipe - conda install --use-local cyclus=0.0 - mv conda-recipe cyclus-recipe + - cd $pwd # build cycamore - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe From 124d70ba03f1d2b1cdc7cb20d3f1d36bf29d2078 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 09:08:50 -0500 Subject: [PATCH 164/314] travis doesn't like colons --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d2ca4ae79a..b703ceb84a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ install: # build cyclus - pwd=$PWD - - echo "pwd: $pwd" + - echo "pwd $pwd" - cd $HOME - git clone git@github.com:gidden/cyclus - cd cyclus From c3d8d007ae4e282aee92ef93937ecb6acf9e0717 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 09:15:08 -0500 Subject: [PATCH 165/314] https for clone --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b703ceb84a..876463161d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,8 +32,8 @@ install: # build cyclus - pwd=$PWD - echo "pwd $pwd" - - cd $HOME - - git clone git@github.com:gidden/cyclus + - cd .. + - git clone https://github.com/gidden/cyclus - cd cyclus - git checkout origin/travis - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe From 053b47c8c8385e4a9b3cfdb1aee0555dc1f87763 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 09:23:52 -0500 Subject: [PATCH 166/314] need to rewget --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 876463161d..a31791ff27 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,9 +26,6 @@ install: # Useful for debugging any issues with conda - conda info -a - # download CI repo - - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - # build cyclus - pwd=$PWD - echo "pwd $pwd" @@ -36,6 +33,7 @@ install: - git clone https://github.com/gidden/cyclus - cd cyclus - git checkout origin/travis + - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe - conda build --no-test conda-recipe - conda install --use-local cyclus=0.0 @@ -43,6 +41,7 @@ install: - cd $pwd # build cycamore + - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe - sed -i "s/- cyclus/- cyclus=0.0/g" conda-recipe/meta.yaml - conda build --no-test conda-recipe From 3130135b2cd39e8ba8b32af47957a76e4d30b6dd Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 10:00:58 -0500 Subject: [PATCH 167/314] meta didn't like = ' --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a31791ff27..f3b5eb5e8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,7 +43,7 @@ install: # build cycamore - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe - - sed -i "s/- cyclus/- cyclus=0.0/g" conda-recipe/meta.yaml + - sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml - conda build --no-test conda-recipe - conda install --use-local cycamore=0.0 - mv conda-recipe cycamore-recipe From 317da972decd0d9dd60e850224422cd93a55214a Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 10:20:45 -0500 Subject: [PATCH 168/314] updating for travis-install.sh --- .travis-install.sh | 5 +++++ .travis.yml | 26 +++++++------------------- 2 files changed, 12 insertions(+), 19 deletions(-) create mode 100755 .travis-install.sh diff --git a/.travis-install.sh b/.travis-install.sh new file mode 100755 index 0000000000..0ab998f721 --- /dev/null +++ b/.travis-install.sh @@ -0,0 +1,5 @@ +wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip +unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe +sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml +conda build --no-test conda-recipe +conda install --use-local cycamore=0.0 \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index f3b5eb5e8b..6eecf5b8a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,27 +26,15 @@ install: # Useful for debugging any issues with conda - conda info -a - # build cyclus - - pwd=$PWD - - echo "pwd $pwd" - - cd .. - - git clone https://github.com/gidden/cyclus - - cd cyclus + # install cyclus + - git clone https://github.com/gidden/cyclus ../cyclus + - cd ../cyclus - git checkout origin/travis - - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe - - conda build --no-test conda-recipe - - conda install --use-local cyclus=0.0 - - mv conda-recipe cyclus-recipe - - cd $pwd + - ./.travis-install.sh + - cd ../cycamore - # build cycamore - - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe - - sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml - - conda build --no-test conda-recipe - - conda install --use-local cycamore=0.0 - - mv conda-recipe cycamore-recipe + # install cycamore + - ./.travis-install.sh script: - export PATH="$HOME/miniconda/bin:$PATH" From 9b7650f01b0a96aa900f11af982c6c3d1ec4be28 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 10:25:51 -0500 Subject: [PATCH 169/314] matching find hdf5.cmakes with cyclus --- cmake/FindHDF5.cmake | 382 ++++++++++++++++++++++--------------------- 1 file changed, 192 insertions(+), 190 deletions(-) diff --git a/cmake/FindHDF5.cmake b/cmake/FindHDF5.cmake index 1722a7ea41..5b7cadd022 100644 --- a/cmake/FindHDF5.cmake +++ b/cmake/FindHDF5.cmake @@ -26,7 +26,7 @@ # In addition to finding the includes and libraries required to compile an HDF5 # client application, this module also makes an effort to find tools that come # with the HDF5 distribution that may be useful for regression testing. -# +# # This module will define the following variables: # HDF5_INCLUDE_DIRS - Location of the hdf5 includes # HDF5_INCLUDE_DIR - Location of the hdf5 includes (deprecated) @@ -60,268 +60,270 @@ include(SelectLibraryConfigurations) include(FindPackageHandleStandardArgs) # List of the valid HDF5 components -set(HDF5_VALID_COMPONENTS +set( HDF5_VALID_COMPONENTS C CXX - ) +) # try to find the HDF5 wrapper compilers -find_program(HDF5_C_COMPILER_EXECUTABLE +find_program( HDF5_C_COMPILER_EXECUTABLE NAMES h5cc h5pcc HINTS ENV HDF5_ROOT PATH_SUFFIXES bin Bin - DOC "HDF5 Wrapper compiler. Used only to detect HDF5 compile flags.") -mark_as_advanced(HDF5_C_COMPILER_EXECUTABLE) + DOC "HDF5 Wrapper compiler. Used only to detect HDF5 compile flags." ) +mark_as_advanced( HDF5_C_COMPILER_EXECUTABLE ) -find_program(HDF5_CXX_COMPILER_EXECUTABLE +find_program( HDF5_CXX_COMPILER_EXECUTABLE NAMES h5c++ h5pc++ HINTS ENV HDF5_ROOT PATH_SUFFIXES bin Bin - DOC "HDF5 C++ Wrapper compiler. Used only to detect HDF5 compile flags.") -mark_as_advanced(HDF5_CXX_COMPILER_EXECUTABLE) + DOC "HDF5 C++ Wrapper compiler. Used only to detect HDF5 compile flags." ) +mark_as_advanced( HDF5_CXX_COMPILER_EXECUTABLE ) -find_program(HDF5_DIFF_EXECUTABLE +find_program( HDF5_DIFF_EXECUTABLE NAMES h5diff HINTS ENV HDF5_ROOT - PATH_SUFFIXES bin Bin - DOC "HDF5 file differencing tool.") -mark_as_advanced(HDF5_DIFF_EXECUTABLE) + PATH_SUFFIXES bin Bin + DOC "HDF5 file differencing tool." ) +mark_as_advanced( HDF5_DIFF_EXECUTABLE ) # Invoke the HDF5 wrapper compiler. The compiler return value is stored to the # return_value argument, the text output is stored to the output variable. -macro(_HDF5_invoke_compiler language output return_value) - if(HDF5_${language}_COMPILER_EXECUTABLE) - exec_program(${HDF5_${language}_COMPILER_EXECUTABLE} +macro( _HDF5_invoke_compiler language output return_value ) + if( HDF5_${language}_COMPILER_EXECUTABLE ) + exec_program( ${HDF5_${language}_COMPILER_EXECUTABLE} ARGS -show OUTPUT_VARIABLE ${output} RETURN_VALUE ${return_value} - ) - if(${${return_value}} EQUAL 0) + ) + if( ${${return_value}} EQUAL 0 ) # do nothing else() - message(STATUS - "Unable to determine HDF5 ${language} flags from HDF5 wrapper.") + message( STATUS + "Unable to determine HDF5 ${language} flags from HDF5 wrapper." ) endif() endif() endmacro() # Parse a compile line for definitions, includes, library paths, and libraries. -macro(_HDF5_parse_compile_line - compile_line_var - include_paths - definitions - library_paths - libraries) +macro( _HDF5_parse_compile_line + compile_line_var + include_paths + definitions + library_paths + libraries ) # Match the include paths - string(REGEX MATCHALL "-I([^\" ]+)" include_path_flags + string( REGEX MATCHALL "-I([^\" ]+)" include_path_flags "${${compile_line_var}}" - ) - foreach(IPATH ${include_path_flags}) - string(REGEX REPLACE "^-I" "" IPATH ${IPATH}) - string(REGEX REPLACE "//" "/" IPATH ${IPATH}) - list(APPEND ${include_paths} ${IPATH}) + ) + foreach( IPATH ${include_path_flags} ) + string( REGEX REPLACE "^-I" "" IPATH ${IPATH} ) + string( REGEX REPLACE "//" "/" IPATH ${IPATH} ) + list( APPEND ${include_paths} ${IPATH} ) endforeach() # Match the definitions - string(REGEX MATCHALL "-D[^ ]*" definition_flags "${${compile_line_var}}") - foreach(DEF ${definition_flags}) - list(APPEND ${definitions} ${DEF}) + string( REGEX MATCHALL "-D[^ ]*" definition_flags "${${compile_line_var}}" ) + foreach( DEF ${definition_flags} ) + list( APPEND ${definitions} ${DEF} ) endforeach() # Match the library paths - string(REGEX MATCHALL "-L([^\" ]+|\"[^\"]+\")" library_path_flags + string( REGEX MATCHALL "-L([^\" ]+|\"[^\"]+\")" library_path_flags "${${compile_line_var}}" - ) - - foreach(LPATH ${library_path_flags}) - string(REGEX REPLACE "^-L" "" LPATH ${LPATH}) - string(REGEX REPLACE "//" "/" LPATH ${LPATH}) - list(APPEND ${library_paths} ${LPATH}) + ) + + foreach( LPATH ${library_path_flags} ) + string( REGEX REPLACE "^-L" "" LPATH ${LPATH} ) + string( REGEX REPLACE "//" "/" LPATH ${LPATH} ) + list( APPEND ${library_paths} ${LPATH} ) endforeach() # now search for the library names specified in the compile line (match -l...) # match only -l's preceded by a space or comma # this is to exclude directory names like xxx-linux/ - string(REGEX MATCHALL "[, ]-l([^\", ]+)" library_name_flags - "${${compile_line_var}}") + string( REGEX MATCHALL "[, ]-l([^\", ]+)" library_name_flags + "${${compile_line_var}}" ) # strip the -l from all of the library flags and add to the search list - foreach(LIB ${library_name_flags}) - string(REGEX REPLACE "^[, ]-l" "" LIB ${LIB}) - list(APPEND ${libraries} ${LIB}) + foreach( LIB ${library_name_flags} ) + string( REGEX REPLACE "^[, ]-l" "" LIB ${LIB} ) + list( APPEND ${libraries} ${LIB} ) endforeach() endmacro() -if(HDF5_INCLUDE_DIRS AND HDF5_LIBRARIES) +if( HDF5_INCLUDE_DIRS AND HDF5_LIBRARIES ) # Do nothing: we already have HDF5_INCLUDE_PATH and HDF5_LIBRARIES in the # cache, it would be a shame to override them else() - _HDF5_invoke_compiler(C HDF5_C_COMPILE_LINE HDF5_C_RETURN_VALUE) - _HDF5_invoke_compiler(CXX HDF5_CXX_COMPILE_LINE HDF5_CXX_RETURN_VALUE) + _HDF5_invoke_compiler( C HDF5_C_COMPILE_LINE HDF5_C_RETURN_VALUE ) + _HDF5_invoke_compiler( CXX HDF5_CXX_COMPILE_LINE HDF5_CXX_RETURN_VALUE ) - if(NOT HDF5_FIND_COMPONENTS) - set(HDF5_LANGUAGE_BINDINGS "C") + if( NOT HDF5_FIND_COMPONENTS ) + set( HDF5_LANGUAGE_BINDINGS "C" ) else() # add the extra specified components, ensuring that they are valid. - foreach(component ${HDF5_FIND_COMPONENTS}) - list(FIND HDF5_VALID_COMPONENTS ${component} component_location) - if(${component_location} EQUAL -1) - message(FATAL_ERROR - "\"${component}\" is not a valid HDF5 component.") + foreach( component ${HDF5_FIND_COMPONENTS} ) + list( FIND HDF5_VALID_COMPONENTS ${component} component_location ) + if( ${component_location} EQUAL -1 ) + message( FATAL_ERROR + "\"${component}\" is not a valid HDF5 component." ) else() - list(APPEND HDF5_LANGUAGE_BINDINGS ${component}) + list( APPEND HDF5_LANGUAGE_BINDINGS ${component} ) endif() endforeach() endif() - + # seed the initial lists of libraries to find with items we know we need - set(HDF5_C_LIBRARY_NAMES_INIT hdf5_hl hdf5) - set(HDF5_CXX_LIBRARY_NAMES_INIT hdf5_cpp ${HDF5_C_LIBRARY_NAMES_INIT}) - - foreach(LANGUAGE ${HDF5_LANGUAGE_BINDINGS}) - if(HDF5_${LANGUAGE}_COMPILE_LINE) - _HDF5_parse_compile_line(HDF5_${LANGUAGE}_COMPILE_LINE - HDF5_${LANGUAGE}_INCLUDE_FLAGS - HDF5_${LANGUAGE}_DEFINITIONS - HDF5_${LANGUAGE}_LIBRARY_DIRS - HDF5_${LANGUAGE}_LIBRARY_NAMES + set( HDF5_C_LIBRARY_NAMES_INIT hdf5_hl hdf5 ) + set( HDF5_CXX_LIBRARY_NAMES_INIT hdf5_cpp ${HDF5_C_LIBRARY_NAMES_INIT} ) + + foreach( LANGUAGE ${HDF5_LANGUAGE_BINDINGS} ) + if( HDF5_${LANGUAGE}_COMPILE_LINE ) + _HDF5_parse_compile_line( HDF5_${LANGUAGE}_COMPILE_LINE + HDF5_${LANGUAGE}_INCLUDE_FLAGS + HDF5_${LANGUAGE}_DEFINITIONS + HDF5_${LANGUAGE}_LIBRARY_DIRS + HDF5_${LANGUAGE}_LIBRARY_NAMES ) + + # take a guess that the includes may be in the 'include' sibling directory + # of a library directory. + foreach( dir ${HDF5_${LANGUAGE}_LIBRARY_DIRS} ) + list( APPEND HDF5_${LANGUAGE}_INCLUDE_FLAGS ${dir}/../include ) + endforeach() + endif() - # take a guess that the includes may be in the 'include' sibling directory - # of a library directory. - foreach(dir ${HDF5_${LANGUAGE}_LIBRARY_DIRS}) - list(APPEND HDF5_${LANGUAGE}_INCLUDE_FLAGS ${dir}/../include) - endforeach() - endif() - - # set the definitions for the language bindings. - list(APPEND HDF5_DEFINITIONS ${HDF5_${LANGUAGE}_DEFINITIONS}) - - # find the HDF5 include directories - find_path(HDF5_${LANGUAGE}_INCLUDE_DIR hdf5.h - HINTS - ${HDF5_${LANGUAGE}_INCLUDE_FLAGS} - ENV - HDF5_ROOT - PATHS - $ENV{HOME}/.local/include - PATH_SUFFIXES - include - Include + # set the definitions for the language bindings. + list( APPEND HDF5_DEFINITIONS ${HDF5_${LANGUAGE}_DEFINITIONS} ) + + # find the HDF5 include directories + find_path( HDF5_${LANGUAGE}_INCLUDE_DIR hdf5.h + HINTS + ${HDF5_${LANGUAGE}_INCLUDE_FLAGS} + ENV + HDF5_ROOT + PATHS + $ENV{HOME}/.local/include + PATH_SUFFIXES + include + Include ) - mark_as_advanced(HDF5_${LANGUAGE}_INCLUDE_DIR) - list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${LANGUAGE}_INCLUDE_DIR}) - - set(HDF5_${LANGUAGE}_LIBRARY_NAMES - ${HDF5_${LANGUAGE}_LIBRARY_NAMES_INIT} - ${HDF5_${LANGUAGE}_LIBRARY_NAMES}) - - # find the HDF5 libraries - foreach(LIB ${HDF5_${LANGUAGE}_LIBRARY_NAMES}) - if(UNIX AND HDF5_USE_STATIC_LIBRARIES) - # According to bug 1643 on the CMake bug tracker, this is the - # preferred method for searching for a static library. - # See http://www.cmake.org/Bug/view.php?id=1643. We search - # first for the full static library name, but fall back to a - # generic search on the name if the static search fails. - set(THIS_LIBRARY_SEARCH_DEBUG lib${LIB}d.a ${LIB}d) - set(THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a ${LIB}) - else() - set(THIS_LIBRARY_SEARCH_DEBUG ${LIB}d) - set(THIS_LIBRARY_SEARCH_RELEASE ${LIB}) - endif() - find_library(HDF5_${LIB}_LIBRARY_DEBUG - NAMES ${THIS_LIBRARY_SEARCH_DEBUG} - HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} - ENV HDF5_ROOT - PATH_SUFFIXES lib Lib) - find_library(HDF5_${LIB}_LIBRARY_RELEASE - NAMES ${THIS_LIBRARY_SEARCH_RELEASE} - HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} - ENV HDF5_ROOT - PATH_SUFFIXES lib Lib) - select_library_configurations(HDF5_${LIB}) - # even though we adjusted the individual library names in - # select_library_configurations, we still need to distinguish - # between debug and release variants because HDF5_LIBRARIES will - # need to specify different lists for debug and optimized builds. - # We can't just use the HDF5_${LIB}_LIBRARY variable (which was set - # up by the selection macro above) because it may specify debug and - # optimized variants for a particular library, but a list of - # libraries is allowed to specify debug and optimized only once. - list(APPEND HDF5_${LANGUAGE}_LIBRARIES_DEBUG - ${HDF5_${LIB}_LIBRARY_DEBUG}) - list(APPEND HDF5_${LANGUAGE}_LIBRARIES_RELEASE - ${HDF5_${LIB}_LIBRARY_RELEASE}) + mark_as_advanced( HDF5_${LANGUAGE}_INCLUDE_DIR ) + list( APPEND HDF5_INCLUDE_DIRS ${HDF5_${LANGUAGE}_INCLUDE_DIR} ) + + set( HDF5_${LANGUAGE}_LIBRARY_NAMES + ${HDF5_${LANGUAGE}_LIBRARY_NAMES_INIT} + ${HDF5_${LANGUAGE}_LIBRARY_NAMES} ) + + # find the HDF5 libraries + foreach( LIB ${HDF5_${LANGUAGE}_LIBRARY_NAMES} ) + if( UNIX AND HDF5_USE_STATIC_LIBRARIES ) + # According to bug 1643 on the CMake bug tracker, this is the + # preferred method for searching for a static library. + # See http://www.cmake.org/Bug/view.php?id=1643. We search + # first for the full static library name, but fall back to a + # generic search on the name if the static search fails. + set( THIS_LIBRARY_SEARCH_DEBUG lib${LIB}d.a ${LIB}d ) + set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a ${LIB} ) + else() + set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d ) + set( THIS_LIBRARY_SEARCH_RELEASE ${LIB} ) + endif() + find_library( HDF5_${LIB}_LIBRARY_DEBUG + NAMES ${THIS_LIBRARY_SEARCH_DEBUG} + HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} + ENV HDF5_ROOT + PATH_SUFFIXES lib Lib ) + find_library( HDF5_${LIB}_LIBRARY_RELEASE + NAMES ${THIS_LIBRARY_SEARCH_RELEASE} + HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} + ENV HDF5_ROOT + PATH_SUFFIXES lib Lib ) + select_library_configurations( HDF5_${LIB} ) + # even though we adjusted the individual library names in + # select_library_configurations, we still need to distinguish + # between debug and release variants because HDF5_LIBRARIES will + # need to specify different lists for debug and optimized builds. + # We can't just use the HDF5_${LIB}_LIBRARY variable (which was set + # up by the selection macro above) because it may specify debug and + # optimized variants for a particular library, but a list of + # libraries is allowed to specify debug and optimized only once. + list( APPEND HDF5_${LANGUAGE}_LIBRARIES_DEBUG + ${HDF5_${LIB}_LIBRARY_DEBUG} ) + list( APPEND HDF5_${LANGUAGE}_LIBRARIES_RELEASE + ${HDF5_${LIB}_LIBRARY_RELEASE} ) + endforeach() + list( APPEND HDF5_LIBRARY_DIRS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} ) + + # Append the libraries for this language binding to the list of all + # required libraries. + list( APPEND HDF5_LIBRARIES_DEBUG + ${HDF5_${LANGUAGE}_LIBRARIES_DEBUG} ) + list( APPEND HDF5_LIBRARIES_RELEASE + ${HDF5_${LANGUAGE}_LIBRARIES_RELEASE} ) endforeach() - list(APPEND HDF5_LIBRARY_DIRS ${HDF5_${LANGUAGE}_LIBRARY_DIRS}) - - # Append the libraries for this language binding to the list of all - # required libraries. - list(APPEND HDF5_LIBRARIES_DEBUG - ${HDF5_${LANGUAGE}_LIBRARIES_DEBUG}) - list(APPEND HDF5_LIBRARIES_RELEASE - ${HDF5_${LANGUAGE}_LIBRARIES_RELEASE}) -endforeach() -# We may have picked up some duplicates in various lists during the above -# process for the language bindings (both the C and C++ bindings depend on -# libz for example). Remove the duplicates. -if(HDF5_INCLUDE_DIRS) - list(REMOVE_DUPLICATES HDF5_INCLUDE_DIRS) -endif() -if(HDF5_LIBRARIES_DEBUG) - list(REMOVE_DUPLICATES HDF5_LIBRARIES_DEBUG) -endif() -if(HDF5_LIBRARIES_RELEASE) - list(REMOVE_DUPLICATES HDF5_LIBRARIES_RELEASE) -endif() -if(HDF5_LIBRARY_DIRS) - list(REMOVE_DUPLICATES HDF5_LIBRARY_DIRS) -endif() + # We may have picked up some duplicates in various lists during the above + # process for the language bindings (both the C and C++ bindings depend on + # libz for example). Remove the duplicates. + if( HDF5_INCLUDE_DIRS ) + list( REMOVE_DUPLICATES HDF5_INCLUDE_DIRS ) + endif() + if( HDF5_LIBRARIES_DEBUG ) + list( REMOVE_DUPLICATES HDF5_LIBRARIES_DEBUG ) + endif() + if( HDF5_LIBRARIES_RELEASE ) + list( REMOVE_DUPLICATES HDF5_LIBRARIES_RELEASE ) + endif() + if( HDF5_LIBRARY_DIRS ) + list( REMOVE_DUPLICATES HDF5_LIBRARY_DIRS ) + endif() -# Construct the complete list of HDF5 libraries with debug and optimized -# variants when the generator supports them. -if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) - set(HDF5_LIBRARIES - debug ${HDF5_LIBRARIES_DEBUG} - optimized ${HDF5_LIBRARIES_RELEASE}) -else() - set(HDF5_LIBRARIES ${HDF5_LIBRARIES_RELEASE}) -endif() + # Construct the complete list of HDF5 libraries with debug and optimized + # variants when the generator supports them. + if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) + set( HDF5_LIBRARIES + debug ${HDF5_LIBRARIES_DEBUG} + optimized ${HDF5_LIBRARIES_RELEASE} ) + else() + set( HDF5_LIBRARIES ${HDF5_LIBRARIES_RELEASE} ) + endif() -# If the HDF5 include directory was found, open H5pubconf.h to determine if -# HDF5 was compiled with parallel IO support -set(HDF5_IS_PARALLEL FALSE) -foreach(_dir HDF5_INCLUDE_DIRS) - if(EXISTS "${_dir}/H5pubconf.h") - file(STRINGS "${_dir}/H5pubconf.h" - HDF5_HAVE_PARALLEL_DEFINE - REGEX "HAVE_PARALLEL 1") - if(HDF5_HAVE_PARALLEL_DEFINE) - set(HDF5_IS_PARALLEL TRUE) + # If the HDF5 include directory was found, open H5pubconf.h to determine if + # HDF5 was compiled with parallel IO support + set( HDF5_IS_PARALLEL FALSE ) + foreach( _dir HDF5_INCLUDE_DIRS ) + if( EXISTS "${_dir}/H5pubconf.h" ) + file( STRINGS "${_dir}/H5pubconf.h" + HDF5_HAVE_PARALLEL_DEFINE + REGEX "HAVE_PARALLEL 1" ) + if( HDF5_HAVE_PARALLEL_DEFINE ) + set( HDF5_IS_PARALLEL TRUE ) + endif() endif() - endif() -endforeach() -set(HDF5_IS_PARALLEL ${HDF5_IS_PARALLEL} CACHE BOOL - "HDF5 library compiled with parallel IO support") -mark_as_advanced(HDF5_IS_PARALLEL) + endforeach() + set( HDF5_IS_PARALLEL ${HDF5_IS_PARALLEL} CACHE BOOL + "HDF5 library compiled with parallel IO support" ) + mark_as_advanced( HDF5_IS_PARALLEL ) endif() -find_package_handle_standard_args(HDF5 DEFAULT_MSG - HDF5_LIBRARIES +find_package_handle_standard_args( HDF5 DEFAULT_MSG + HDF5_LIBRARIES HDF5_INCLUDE_DIRS - ) +) -mark_as_advanced( - HDF5_INCLUDE_DIRS - HDF5_LIBRARIES +mark_as_advanced( + HDF5_INCLUDE_DIRS + HDF5_LIBRARIES HDF5_DEFINTIONS HDF5_LIBRARY_DIRS HDF5_C_COMPILER_EXECUTABLE - HDF5_CXX_COMPILER_EXECUTABLE) + HDF5_CXX_COMPILER_EXECUTABLE ) # For backwards compatibility we set HDF5_INCLUDE_DIR to the value of # HDF5_INCLUDE_DIRS -set(HDF5_INCLUDE_DIR "${HDF5_INCLUDE_DIRS}") +set( HDF5_INCLUDE_DIR "${HDF5_INCLUDE_DIRS}" ) + + From cce530514540be30109a6f4542a2582d4d06d48d Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 10:27:41 -0500 Subject: [PATCH 170/314] tables->pytables --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6eecf5b8a2..5153f20149 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,6 +42,6 @@ script: #- ls -l $HOME/miniconda/lib #- ls -l $HOME/miniconda/envs/_build/lib - cycamore_unit_tests - - conda install numpy tables + - conda install numpy pytables - nosetests -w tests From 4f25661c7fe06f815000ea851fa0a9d127678335 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Tue, 17 Feb 2015 12:50:14 -0600 Subject: [PATCH 171/314] Squashing commits from cyclus/cycamore#301. This should fail on CI. --- src/CMakeLists.txt | 2 + src/foo.cc | 171 +++++++++++++++++++++++++++++++++++++ src/foo.h | 204 +++++++++++++++++++++++++++++++++++++++++++++ src/foo_tests.cc | 204 +++++++++++++++++++++++++++++++++++++++++++++ src/foo_tests.h | 34 ++++++++ 5 files changed, 615 insertions(+) create mode 100644 src/foo.cc create mode 100644 src/foo.h create mode 100644 src/foo_tests.cc create mode 100644 src/foo_tests.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5701534c73..0f0ef9eea2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,8 @@ USE_CYCLUS("cycamore" "sink") USE_CYCLUS("cycamore" "source") +USE_CYCLUS("cycamore" "foo") + USE_CYCLUS("cycamore" "deploy_inst") USE_CYCLUS("cycamore" "manager_inst") diff --git a/src/foo.cc b/src/foo.cc new file mode 100644 index 0000000000..9ad8ada201 --- /dev/null +++ b/src/foo.cc @@ -0,0 +1,171 @@ +#include "foo.h" + +#include +#include + +#include + +namespace cycamore { + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Foo::Foo(cyclus::Context* ctx) + : cyclus::Facility(ctx), + out_commod(""), + recipe_name(""), + capacity(std::numeric_limits::max()) {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Foo::~Foo() {} + +#pragma cyclus def clone cycamore::Foo + +#pragma cyclus def schema cycamore::Foo + +#pragma cyclus def annotations cycamore::Foo + +#pragma cyclus def infiletodb cycamore::Foo + +#pragma cyclus def snapshot cycamore::Foo + +#pragma cyclus def snapshotinv cycamore::Foo + +#pragma cyclus def initinv cycamore::Foo + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::InitFrom(Foo* m) { + #pragma cyclus impl initfromcopy cycamore::Foo + cyclus::toolkit::CommodityProducer::Copy(m); +} + +void Foo::InitFrom(cyclus::QueryableBackend* b) { + #pragma cyclus impl initfromdb cycamore::Foo + + commod_ = cyclus::toolkit::Commodity(out_commod); + cyclus::toolkit::CommodityProducer::Add(commod_); + cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); + cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); +} + +void Foo::EnterNotify() { + Facility::EnterNotify(); + commod_ = cyclus::toolkit::Commodity(out_commod); + cyclus::toolkit::CommodityProducer::Add(commod_); + cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); + cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::string Foo::str() { + std::stringstream ss; + std::string ans; + if (cyclus::toolkit::CommodityProducer:: + Produces(cyclus::toolkit::Commodity(out_commod))) { + ans = "yes"; + } else { + ans = "no"; + } + ss << cyclus::Facility::str() + << " supplies commodity '" + << out_commod << "' with recipe '" + << recipe_name << "' at a capacity of " + << capacity << " kg per time step " + << " commod producer members: " << " produces " + << out_commod << "?: " << ans + << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(commod_) + << " cost: " << cyclus::toolkit::CommodityProducer::Cost(commod_); + return ss.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::Tick() { + LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is ticking {"; + LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity + << " kg of " + << out_commod << "."; + LOG(cyclus::LEV_INFO3, "SrcFac") << "Stats: " << str(); + LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; + current_capacity = capacity; // reset capacity +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::Tock() { + LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is tocking {"; + LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr Foo::GetOffer( + const cyclus::Material::Ptr target) const { + using cyclus::Material; + double qty = std::min(target->quantity(), capacity); + return Material::CreateUntracked(qty, context()->GetRecipe(recipe_name)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::set::Ptr> +Foo::GetMatlBids( + cyclus::CommodMap::type& commod_requests) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::Material; + using cyclus::Request; + + std::set::Ptr> ports; + + if (commod_requests.count(out_commod) > 0) { + BidPortfolio::Ptr port(new BidPortfolio()); + + std::vector*>& requests = + commod_requests[out_commod]; + + std::vector*>::iterator it; + for (it = requests.begin(); it != requests.end(); ++it) { + Request* req = *it; + Material::Ptr offer = GetOffer(req->target()); + port->AddBid(req, offer, this); + } + + CapacityConstraint cc(capacity); + port->AddConstraint(cc); + ports.insert(port); + } + return ports; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses) { + using cyclus::Material; + using cyclus::Trade; + + double provided = 0; + std::vector< cyclus::Trade >::const_iterator it; + for (it = trades.begin(); it != trades.end(); ++it) { + double qty = it->amt; + current_capacity -= qty; + provided += qty; + // @TODO we need a policy on negatives.. + Material::Ptr response = Material::Create(this, qty, + context()->GetRecipe(recipe_name)); + responses.push_back(std::make_pair(*it, response)); + LOG(cyclus::LEV_INFO5, "SrcFac") << prototype() << " just received an order" + << " for " << qty + << " of " << out_commod; + } + if (cyclus::IsNegative(current_capacity)) { + std::stringstream ss; + ss << "is being asked to provide " << provided + << " but its capacity is " << capacity << "."; + throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +extern "C" cyclus::Agent* ConstructFoo(cyclus::Context* ctx) { + return new Foo(ctx); +} + +} // namespace cycamore diff --git a/src/foo.h b/src/foo.h new file mode 100644 index 0000000000..e35ab83d99 --- /dev/null +++ b/src/foo.h @@ -0,0 +1,204 @@ +#ifndef CYCAMORE_SRC_FOO_H_ +#define CYCAMORE_SRC_FOO_H_ + +#include +#include + +#include "cyclus.h" + +namespace cycamore { + +class Context; + +/// @class Foo +/// This cyclus::Facility provides a simple source of some capacity +/// (possibly infinite) of some commodity/Recipe. + +/// The Foo class inherits from the cyclus::Facility class and is +/// dynamically loaded by the Agent class when requested. + +/// @section introduction Introduction +/// The Foo is a facility type in Cyclus capable of providing +/// a finite or infinite.Supply of a particular material to the +/// simulation. A Foo generates material of a certain +/// composition and commodity type, then offers that material on the +/// appropriate market. Shipments of this material are executed when the +/// market issues an order that the offer has been matched with a +/// request. + +/// @section agentparams Agent Parameters +/// Foo behavior is comprehensively defined by the following +/// parameters: +/// - double capacity: The production capacity of the facility (units +/// vary, but typically kg/month). Capacity is infinite if a negative +/// value is provided. +/// - int startDate: The date on which the facility begins to operate +/// (months). +/// - int lifeTime: The length of time that the facility operates +/// (months). - std::string outCommod: the commodity that this facility +/// produces - double inventorysize: the maximum quantity of material to +/// be held in the inventory +/// - double commodprice: the price of the output material PER UNIT +/// - map outComp + +/// @section optionalparams Optional Parameters +/// Foo behavior may also be specified with the following +/// optional parameters which have default values listed here. +/// - double capacityFactor: The ratio of actual production capacity to +/// the rated production capacity. Default is 1 (actual/rated). +/// - double availFactor: The percent of time the facility operates at +/// its capacity factor. Default is 100%. +/// - double capitalCost: The cost of constructing and commissioning +/// this facility. Default is 0 ($). +/// - double opCost: The annual cost of operation and maintenance of +/// this facility. Default is 0 ( $/year). +/// - int constrTime: The number of months it takes to construct and +/// commission this facility. Default is 0 (months). +/// - int decomTime: The number of months it takes to deconstruct and +/// decommission this facility. Default is 0 (months). +/// - Inst* inst: The institution responsible for this facility. +/// - string name: A non-generic name for this facility. + +/// @section detailed Detailed Behavior +/// @subsection finite If Finite Capacity: +/// The Foo starts operation when the simulation reaches the +/// month specified as the startDate. It immediately begins to produce +/// material at the rate defined by its capacity. Each month the +/// Foo adds the amount it has produced to its inventory. It +/// then offers to the appropriate market exactly as much material as it +/// has in its inventory. If an offer is matched with a request, the +/// Foo executes that order by subtracting the quantity from +/// its inventory and sending that amount to the requesting facility. +/// When the simulation time equals the startDate plus the lifeTime, the +/// facility ceases to operate. +/// @subsection infinite If Infinite Capacity: +/// The Foo starts operation when the simulation reaches the +/// month specified as the startDate. Each month the Foo +/// offers an infinite amount of material to the appropriate market. If +/// there is a request for that material, the Foo executes +/// that order by sending that amount to the requesting facility. When +/// the simulation time equals the startDate plus the lifeTime, the +/// facility ceases to operate. + +/// @subsection question Question: +/// What is the best way to allow offers of an infinite amount of +/// material on a market? + +class Foo : public cyclus::Facility, + public cyclus::toolkit::CommodityProducer { + public: + // --- Module Members --- + /// Constructor for the Foo class + /// @param ctx the cyclus context for access to simulation-wide parameters + Foo(cyclus::Context* ctx); + + virtual ~Foo() + + #pragma cyclus decl + + #pragma cyclus note {"doc": "A source facility that provides a " \ + "commodity with a given capacity"} + + /// Print information about this agent + virtual std::string str(); + // --- + + // --- Agent Members --- + virtual void EnterNotify(); + + /// Each facility is prompted to do its beginning-of-time-step + /// stuff at the tick of the timer. + + /// @param time is the time to perform the tick + virtual void Tick(); + + /// Each facility is prompted to its end-of-time-step + /// stuff on the tock of the timer. + + /// @param time is the time to perform the tock + virtual void Tock(); + + /// @brief Responds to each request for this source facility's commodity. + /// If a given request is more than this facility's capacity, it will offer + /// its capacity. + virtual std::set::Ptr> + GetMatlBids(cyclus::CommodMap::type& + commod_requests); + + /// @brief respond to each trade with a material made from this facility's + /// recipe + /// + /// @param trades all trades in which this trader is the supplier + /// @param responses a container to populate with responses to each trade + virtual void GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses); + // --- + + // --- Foo Members --- + /// @brief creates a material object to offer to a requester + /// @param target the material target a request desires + cyclus::Material::Ptr GetOffer(const cyclus::Material::Ptr target) const; + + /// sets the output commodity name + /// @param name the commodity name + inline void commodity(std::string name) { out_commod = name; } + + /// @return the output commodity + inline std::string commodity() const { return out_commod; } + + /// sets the capacity of a material generated at any given time step + /// @param capacity the production capacity + inline void Capacity(double cap) { + capacity = cap; + current_capacity = capacity; + } + + /// @return the production capacity at any given time step + inline double Capacity() const { return capacity; } + + /// sets the name of the recipe to be produced + /// @param name the recipe name + inline void recipe(std::string name) { recipe_name = name; } + + /// @return the name of the output recipe + inline std::string recipe() const { return recipe_name; } + + /// @return the current timestep's capacity + inline double CurrentCapacity() const { return current_capacity; } + + private: + cyclus::toolkit::Commodity commod_; + + /// This facility has only one output commodity + #pragma cyclus var {"tooltip": "source output commodity", \ + "doc": "output commodity that the source facility " \ + "supplies", \ + "uitype": "outcommodity"} + std::string out_commod; + + /// Name of the recipe this facility uses. + #pragma cyclus var {"tooltip": "commodity recipe name", \ + "doc": "recipe name for source facility's commodity", \ + "uitype": "recipe"} + std::string recipe_name; + + /// The capacity is defined in terms of the number of units of the + /// recipe that can be provided each time step. A very large number + /// can be provided to represent infinte capacity. + #pragma cyclus var {"default": 1e299, "tooltip": "source capacity", \ + "doc": "amount of commodity that can be supplied " \ + "at each time step"} + double capacity; + + /// The capacity at the current time step + #pragma cyclus var {'derived_init': 'current_capacity = capacity;'} + double current_capacity; + + // --- +}; + +} // namespace cycamore + +#endif // CYCAMORE_SRC_FOO_H_ diff --git a/src/foo_tests.cc b/src/foo_tests.cc new file mode 100644 index 0000000000..0973e794d0 --- /dev/null +++ b/src/foo_tests.cc @@ -0,0 +1,204 @@ +#include "foo_tests.h" + +#include + +#include + +#include "cyc_limits.h" +#include "resource_helpers.h" +#include "test_context.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::SetUp() { + src_facility = new cycamore::Foo(tc.get()); + trader = tc.trader(); + InitParameters(); + SetUpFoo(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::TearDown() { + delete src_facility; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::InitParameters() { + commod = "commod"; + recipe_name = "recipe"; + capacity = 5; // some magic number.. + + recipe = cyclus::Composition::CreateFromAtom(cyclus::CompMap()); + tc.get()->AddRecipe(recipe_name, recipe); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::SetUpFoo() { + src_facility->commodity(commod); + src_facility->recipe(recipe_name); + src_facility->Capacity(capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, InitialState) { + EXPECT_EQ(src_facility->Capacity(), capacity); + EXPECT_EQ(src_facility->commodity(), commod); + EXPECT_EQ(src_facility->recipe(), recipe_name); + EXPECT_EQ(src_facility->CurrentCapacity(), capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Clone) { + cyclus::Context* ctx = tc.get(); + cycamore::Foo* cloned_fac = dynamic_cast + (src_facility->Clone()); + + EXPECT_EQ(src_facility->commodity(), cloned_fac->commodity()); + EXPECT_EQ(src_facility->Capacity(), cloned_fac->Capacity()); + EXPECT_EQ(src_facility->recipe(), cloned_fac->recipe()); + EXPECT_EQ(src_facility->Capacity(), cloned_fac->CurrentCapacity()); + + delete cloned_fac; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Print) { + EXPECT_NO_THROW(std::string s = src_facility->str()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, GetOffer) { + using cyclus::Material; + + double qty = capacity - 1; + Material::Ptr mat = cyclus::NewBlankMaterial(qty); + Material::Ptr obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), qty); + EXPECT_EQ(obs_mat->comp(), recipe); + + qty = capacity + 1; + mat = cyclus::NewBlankMaterial(qty); + obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), capacity); + EXPECT_EQ(obs_mat->comp(), recipe); + + qty = capacity; + mat = cyclus::NewBlankMaterial(qty); + obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), capacity); + EXPECT_EQ(obs_mat->comp(), recipe); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, AddBids) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::ExchangeContext; + using cyclus::Material; + + int nreqs = 5; + + boost::shared_ptr< cyclus::ExchangeContext > + ec = GetContext(nreqs, commod); + + std::set::Ptr> ports = + src_facility->GetMatlBids(ec.get()->commod_requests); + + ASSERT_TRUE(ports.size() > 0); + EXPECT_EQ(ports.size(), 1); + + BidPortfolio::Ptr port = *ports.begin(); + EXPECT_EQ(port->bidder(), src_facility); + EXPECT_EQ(port->bids().size(), nreqs); + + const std::set< CapacityConstraint >& constrs = port->constraints(); + ASSERT_TRUE(constrs.size() > 0); + EXPECT_EQ(constrs.size(), 1); + EXPECT_EQ(*constrs.begin(), CapacityConstraint(capacity)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Response) { + using cyclus::Bid; + using cyclus::Material; + using cyclus::Request; + using cyclus::Trade; + using test_helpers::get_mat; + + std::vector< cyclus::Trade > trades; + std::vector, + cyclus::Material::Ptr> > responses; + + // Null response + EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); + EXPECT_EQ(responses.size(), 0); + + double qty = capacity / 3; + Request* request = + Request::Create(get_mat(), trader, commod); + Bid* bid = + Bid::Create(request, get_mat(), src_facility); + + Trade trade(request, bid, qty); + trades.push_back(trade); + + // 1 trade + ASSERT_EQ(src_facility->CurrentCapacity(), capacity); + src_facility->GetMatlTrades(trades, responses); + EXPECT_EQ(responses.size(), 1); + EXPECT_EQ(responses[0].second->quantity(), qty); + EXPECT_EQ(responses[0].second->comp(), recipe); + + // 2 trades, total qty = capacity + ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity - qty); + ASSERT_GT(src_facility->CurrentCapacity() - 2 * qty, -1 * cyclus::eps()); + trades.push_back(trade); + responses.clear(); + EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); + EXPECT_EQ(responses.size(), 2); + ASSERT_TRUE(cyclus::AlmostEq(src_facility->CurrentCapacity(), 0)); + + // too much qty, capn! + EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), + cyclus::ValueError); + + // reset! + src_facility->Tick(); + ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity); + + delete request; + delete bid; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +boost::shared_ptr< cyclus::ExchangeContext > +FooTest::GetContext(int nreqs, std::string commod) { + using cyclus::Material; + using cyclus::Request; + using cyclus::ExchangeContext; + using test_helpers::get_mat; + + double qty = 3; + boost::shared_ptr< ExchangeContext > + ec(new ExchangeContext()); + for (int i = 0; i < nreqs; i++) { + ec->AddRequest(Request::Create(get_mat(), trader, commod)); + } + return ec; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Agent* FooConstructor(cyclus::Context* ctx) { + return new cycamore::Foo(ctx); +} + +// required to get functionality in cyclus agent unit tests library +#ifndef CYCLUS_AGENT_TESTS_CONNECTED +int ConnectAgentTests(); +static int cyclus_agent_tests_connected = ConnectAgentTests(); +#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected +#endif // CYCLUS_AGENT_TESTS_CONNECTED + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +INSTANTIATE_TEST_CASE_P(FooFac, FacilityTests, Values(&FooConstructor)); +INSTANTIATE_TEST_CASE_P(FooFac, AgentTests, Values(&FooConstructor)); diff --git a/src/foo_tests.h b/src/foo_tests.h new file mode 100644 index 0000000000..59888926b7 --- /dev/null +++ b/src/foo_tests.h @@ -0,0 +1,34 @@ +#ifndef CYCAMORE_SRC_FOO_TESTS_H_ +#define CYCAMORE_SRC_FOO_TESTS_H_ +#include "foo.h" + +#include + +#include + +#include "agent_tests.h" +#include "context.h" +#include "exchange_context.h" +#include "facility_tests.h" +#include "material.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +class FooTest : public ::testing::Test { + public: + cyclus::TestContext tc; + TestFacility* trader; + cycamore::Foo* src_facility; + std::string commod, recipe_name; + double capacity; + cyclus::Composition::Ptr recipe; + + virtual void SetUp(); + virtual void TearDown(); + void InitParameters(); + void SetUpFoo(); + + boost::shared_ptr< cyclus::ExchangeContext > + GetContext(int nreqs, std::string commodity); +}; + +#endif // CYCAMORE_SRC_FOO_TESTS_H_ From 3d7a9f497f816a2e8fc6ef5ef4c5bd6d6b4b4580 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 10:56:49 -0500 Subject: [PATCH 172/314] adding same hdf5 messages as cyclus --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4985e62e56..f2d1f2b451 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,6 +104,10 @@ IF(NOT CYCLUS_DOC_ONLY) FIND_PACKAGE(HDF5 REQUIRED) ADD_DEFINITIONS(${HDF5_DEFINITIONS}) set(LIBS ${LIBS} ${HDF5_LIBRARIES}) + MESSAGE("-- HDF5 Root: ${HDF5_ROOT}") + MESSAGE("-- HDF5 Include directory: ${HDF5_INCLUDE_DIR}") + MESSAGE("-- HDF5 Library directories: ${HDF5_LIBRARY_DIRS}") + MESSAGE("-- HDF5 Libraries: ${HDF5_LIBRARIES}") # find coin and link to it FIND_PACKAGE(COIN REQUIRED) From bbf0a815bd7e9f1436914a9ee4d8e0db1d2dbd92 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 11:07:56 -0500 Subject: [PATCH 173/314] matching cyclus findhdf --- cmake/FindHDF5.cmake | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/cmake/FindHDF5.cmake b/cmake/FindHDF5.cmake index 5b7cadd022..c7f7d73bee 100644 --- a/cmake/FindHDF5.cmake +++ b/cmake/FindHDF5.cmake @@ -20,8 +20,9 @@ # HDF5_USE_STATIC_LIBRARIES variable is set before the call to find_package. # # To provide the module with a hint about where to find your HDF5 installation, -# you can set the environment variable HDF5_ROOT. The Find module will then -# look in this path when searching for HDF5 executables, paths, and libraries. +# you can set the CMAKE variable -OR- environment variable HDF5_ROOT. The Find +# module will then look in this path when searching for HDF5 executables, paths, +# and libraries. # # In addition to finding the includes and libraries required to compile an HDF5 # client application, this module also makes an effort to find tools that come @@ -68,21 +69,21 @@ set( HDF5_VALID_COMPONENTS # try to find the HDF5 wrapper compilers find_program( HDF5_C_COMPILER_EXECUTABLE NAMES h5cc h5pcc - HINTS ENV HDF5_ROOT + HINTS "${HDF5_ROOT}" ENV HDF5_ROOT PATH_SUFFIXES bin Bin DOC "HDF5 Wrapper compiler. Used only to detect HDF5 compile flags." ) mark_as_advanced( HDF5_C_COMPILER_EXECUTABLE ) find_program( HDF5_CXX_COMPILER_EXECUTABLE NAMES h5c++ h5pc++ - HINTS ENV HDF5_ROOT + HINTS "${HDF5_ROOT}" ENV HDF5_ROOT PATH_SUFFIXES bin Bin DOC "HDF5 C++ Wrapper compiler. Used only to detect HDF5 compile flags." ) mark_as_advanced( HDF5_CXX_COMPILER_EXECUTABLE ) find_program( HDF5_DIFF_EXECUTABLE NAMES h5diff - HINTS ENV HDF5_ROOT + HINTS "${HDF5_ROOT}" ENV HDF5_ROOT PATH_SUFFIXES bin Bin DOC "HDF5 file differencing tool." ) mark_as_advanced( HDF5_DIFF_EXECUTABLE ) @@ -200,6 +201,7 @@ else() # find the HDF5 include directories find_path( HDF5_${LANGUAGE}_INCLUDE_DIR hdf5.h HINTS + "${HDF5_ROOT}" ${HDF5_${LANGUAGE}_INCLUDE_FLAGS} ENV HDF5_ROOT @@ -232,12 +234,12 @@ else() endif() find_library( HDF5_${LIB}_LIBRARY_DEBUG NAMES ${THIS_LIBRARY_SEARCH_DEBUG} - HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} + HINTS "${HDF5_ROOT}" ${HDF5_${LANGUAGE}_LIBRARY_DIRS} ENV HDF5_ROOT PATH_SUFFIXES lib Lib ) find_library( HDF5_${LIB}_LIBRARY_RELEASE NAMES ${THIS_LIBRARY_SEARCH_RELEASE} - HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} + HINTS "${HDF5_ROOT}" ${HDF5_${LANGUAGE}_LIBRARY_DIRS} ENV HDF5_ROOT PATH_SUFFIXES lib Lib ) select_library_configurations( HDF5_${LIB} ) From 08499af805a4d3edc6b3140869ef3c28f466fc84 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 11:19:12 -0500 Subject: [PATCH 174/314] early exit on failure --- .travis-install.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.travis-install.sh b/.travis-install.sh index 0ab998f721..46059223a9 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -2,4 +2,11 @@ wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml conda build --no-test conda-recipe -conda install --use-local cycamore=0.0 \ No newline at end of file + +if [[ $? != 0 ]]; then + exit $? + +conda install --use-local cycamore=0.0 + +if [[ $? != 0 ]]; then + exit $? From 690a9153ffddd6ecc145dbb9e46ba2813939b3a5 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 11:19:37 -0500 Subject: [PATCH 175/314] Revert "Squashing commits from cyclus/cycamore#301. This should fail on CI." This reverts commit 4f25661c7fe06f815000ea851fa0a9d127678335. --- src/CMakeLists.txt | 2 - src/foo.cc | 171 ------------------------------------- src/foo.h | 204 --------------------------------------------- src/foo_tests.cc | 204 --------------------------------------------- src/foo_tests.h | 34 -------- 5 files changed, 615 deletions(-) delete mode 100644 src/foo.cc delete mode 100644 src/foo.h delete mode 100644 src/foo_tests.cc delete mode 100644 src/foo_tests.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0f0ef9eea2..5701534c73 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,8 +10,6 @@ USE_CYCLUS("cycamore" "sink") USE_CYCLUS("cycamore" "source") -USE_CYCLUS("cycamore" "foo") - USE_CYCLUS("cycamore" "deploy_inst") USE_CYCLUS("cycamore" "manager_inst") diff --git a/src/foo.cc b/src/foo.cc deleted file mode 100644 index 9ad8ada201..0000000000 --- a/src/foo.cc +++ /dev/null @@ -1,171 +0,0 @@ -#include "foo.h" - -#include -#include - -#include - -namespace cycamore { - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Foo::Foo(cyclus::Context* ctx) - : cyclus::Facility(ctx), - out_commod(""), - recipe_name(""), - capacity(std::numeric_limits::max()) {} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Foo::~Foo() {} - -#pragma cyclus def clone cycamore::Foo - -#pragma cyclus def schema cycamore::Foo - -#pragma cyclus def annotations cycamore::Foo - -#pragma cyclus def infiletodb cycamore::Foo - -#pragma cyclus def snapshot cycamore::Foo - -#pragma cyclus def snapshotinv cycamore::Foo - -#pragma cyclus def initinv cycamore::Foo - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::InitFrom(Foo* m) { - #pragma cyclus impl initfromcopy cycamore::Foo - cyclus::toolkit::CommodityProducer::Copy(m); -} - -void Foo::InitFrom(cyclus::QueryableBackend* b) { - #pragma cyclus impl initfromdb cycamore::Foo - - commod_ = cyclus::toolkit::Commodity(out_commod); - cyclus::toolkit::CommodityProducer::Add(commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); - cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); -} - -void Foo::EnterNotify() { - Facility::EnterNotify(); - commod_ = cyclus::toolkit::Commodity(out_commod); - cyclus::toolkit::CommodityProducer::Add(commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); - cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::string Foo::str() { - std::stringstream ss; - std::string ans; - if (cyclus::toolkit::CommodityProducer:: - Produces(cyclus::toolkit::Commodity(out_commod))) { - ans = "yes"; - } else { - ans = "no"; - } - ss << cyclus::Facility::str() - << " supplies commodity '" - << out_commod << "' with recipe '" - << recipe_name << "' at a capacity of " - << capacity << " kg per time step " - << " commod producer members: " << " produces " - << out_commod << "?: " << ans - << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(commod_) - << " cost: " << cyclus::toolkit::CommodityProducer::Cost(commod_); - return ss.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::Tick() { - LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is ticking {"; - LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity - << " kg of " - << out_commod << "."; - LOG(cyclus::LEV_INFO3, "SrcFac") << "Stats: " << str(); - LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; - current_capacity = capacity; // reset capacity -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::Tock() { - LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is tocking {"; - LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr Foo::GetOffer( - const cyclus::Material::Ptr target) const { - using cyclus::Material; - double qty = std::min(target->quantity(), capacity); - return Material::CreateUntracked(qty, context()->GetRecipe(recipe_name)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -Foo::GetMatlBids( - cyclus::CommodMap::type& commod_requests) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::Material; - using cyclus::Request; - - std::set::Ptr> ports; - - if (commod_requests.count(out_commod) > 0) { - BidPortfolio::Ptr port(new BidPortfolio()); - - std::vector*>& requests = - commod_requests[out_commod]; - - std::vector*>::iterator it; - for (it = requests.begin(); it != requests.end(); ++it) { - Request* req = *it; - Material::Ptr offer = GetOffer(req->target()); - port->AddBid(req, offer, this); - } - - CapacityConstraint cc(capacity); - port->AddConstraint(cc); - ports.insert(port); - } - return ports; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses) { - using cyclus::Material; - using cyclus::Trade; - - double provided = 0; - std::vector< cyclus::Trade >::const_iterator it; - for (it = trades.begin(); it != trades.end(); ++it) { - double qty = it->amt; - current_capacity -= qty; - provided += qty; - // @TODO we need a policy on negatives.. - Material::Ptr response = Material::Create(this, qty, - context()->GetRecipe(recipe_name)); - responses.push_back(std::make_pair(*it, response)); - LOG(cyclus::LEV_INFO5, "SrcFac") << prototype() << " just received an order" - << " for " << qty - << " of " << out_commod; - } - if (cyclus::IsNegative(current_capacity)) { - std::stringstream ss; - ss << "is being asked to provide " << provided - << " but its capacity is " << capacity << "."; - throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern "C" cyclus::Agent* ConstructFoo(cyclus::Context* ctx) { - return new Foo(ctx); -} - -} // namespace cycamore diff --git a/src/foo.h b/src/foo.h deleted file mode 100644 index e35ab83d99..0000000000 --- a/src/foo.h +++ /dev/null @@ -1,204 +0,0 @@ -#ifndef CYCAMORE_SRC_FOO_H_ -#define CYCAMORE_SRC_FOO_H_ - -#include -#include - -#include "cyclus.h" - -namespace cycamore { - -class Context; - -/// @class Foo -/// This cyclus::Facility provides a simple source of some capacity -/// (possibly infinite) of some commodity/Recipe. - -/// The Foo class inherits from the cyclus::Facility class and is -/// dynamically loaded by the Agent class when requested. - -/// @section introduction Introduction -/// The Foo is a facility type in Cyclus capable of providing -/// a finite or infinite.Supply of a particular material to the -/// simulation. A Foo generates material of a certain -/// composition and commodity type, then offers that material on the -/// appropriate market. Shipments of this material are executed when the -/// market issues an order that the offer has been matched with a -/// request. - -/// @section agentparams Agent Parameters -/// Foo behavior is comprehensively defined by the following -/// parameters: -/// - double capacity: The production capacity of the facility (units -/// vary, but typically kg/month). Capacity is infinite if a negative -/// value is provided. -/// - int startDate: The date on which the facility begins to operate -/// (months). -/// - int lifeTime: The length of time that the facility operates -/// (months). - std::string outCommod: the commodity that this facility -/// produces - double inventorysize: the maximum quantity of material to -/// be held in the inventory -/// - double commodprice: the price of the output material PER UNIT -/// - map outComp - -/// @section optionalparams Optional Parameters -/// Foo behavior may also be specified with the following -/// optional parameters which have default values listed here. -/// - double capacityFactor: The ratio of actual production capacity to -/// the rated production capacity. Default is 1 (actual/rated). -/// - double availFactor: The percent of time the facility operates at -/// its capacity factor. Default is 100%. -/// - double capitalCost: The cost of constructing and commissioning -/// this facility. Default is 0 ($). -/// - double opCost: The annual cost of operation and maintenance of -/// this facility. Default is 0 ( $/year). -/// - int constrTime: The number of months it takes to construct and -/// commission this facility. Default is 0 (months). -/// - int decomTime: The number of months it takes to deconstruct and -/// decommission this facility. Default is 0 (months). -/// - Inst* inst: The institution responsible for this facility. -/// - string name: A non-generic name for this facility. - -/// @section detailed Detailed Behavior -/// @subsection finite If Finite Capacity: -/// The Foo starts operation when the simulation reaches the -/// month specified as the startDate. It immediately begins to produce -/// material at the rate defined by its capacity. Each month the -/// Foo adds the amount it has produced to its inventory. It -/// then offers to the appropriate market exactly as much material as it -/// has in its inventory. If an offer is matched with a request, the -/// Foo executes that order by subtracting the quantity from -/// its inventory and sending that amount to the requesting facility. -/// When the simulation time equals the startDate plus the lifeTime, the -/// facility ceases to operate. -/// @subsection infinite If Infinite Capacity: -/// The Foo starts operation when the simulation reaches the -/// month specified as the startDate. Each month the Foo -/// offers an infinite amount of material to the appropriate market. If -/// there is a request for that material, the Foo executes -/// that order by sending that amount to the requesting facility. When -/// the simulation time equals the startDate plus the lifeTime, the -/// facility ceases to operate. - -/// @subsection question Question: -/// What is the best way to allow offers of an infinite amount of -/// material on a market? - -class Foo : public cyclus::Facility, - public cyclus::toolkit::CommodityProducer { - public: - // --- Module Members --- - /// Constructor for the Foo class - /// @param ctx the cyclus context for access to simulation-wide parameters - Foo(cyclus::Context* ctx); - - virtual ~Foo() - - #pragma cyclus decl - - #pragma cyclus note {"doc": "A source facility that provides a " \ - "commodity with a given capacity"} - - /// Print information about this agent - virtual std::string str(); - // --- - - // --- Agent Members --- - virtual void EnterNotify(); - - /// Each facility is prompted to do its beginning-of-time-step - /// stuff at the tick of the timer. - - /// @param time is the time to perform the tick - virtual void Tick(); - - /// Each facility is prompted to its end-of-time-step - /// stuff on the tock of the timer. - - /// @param time is the time to perform the tock - virtual void Tock(); - - /// @brief Responds to each request for this source facility's commodity. - /// If a given request is more than this facility's capacity, it will offer - /// its capacity. - virtual std::set::Ptr> - GetMatlBids(cyclus::CommodMap::type& - commod_requests); - - /// @brief respond to each trade with a material made from this facility's - /// recipe - /// - /// @param trades all trades in which this trader is the supplier - /// @param responses a container to populate with responses to each trade - virtual void GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses); - // --- - - // --- Foo Members --- - /// @brief creates a material object to offer to a requester - /// @param target the material target a request desires - cyclus::Material::Ptr GetOffer(const cyclus::Material::Ptr target) const; - - /// sets the output commodity name - /// @param name the commodity name - inline void commodity(std::string name) { out_commod = name; } - - /// @return the output commodity - inline std::string commodity() const { return out_commod; } - - /// sets the capacity of a material generated at any given time step - /// @param capacity the production capacity - inline void Capacity(double cap) { - capacity = cap; - current_capacity = capacity; - } - - /// @return the production capacity at any given time step - inline double Capacity() const { return capacity; } - - /// sets the name of the recipe to be produced - /// @param name the recipe name - inline void recipe(std::string name) { recipe_name = name; } - - /// @return the name of the output recipe - inline std::string recipe() const { return recipe_name; } - - /// @return the current timestep's capacity - inline double CurrentCapacity() const { return current_capacity; } - - private: - cyclus::toolkit::Commodity commod_; - - /// This facility has only one output commodity - #pragma cyclus var {"tooltip": "source output commodity", \ - "doc": "output commodity that the source facility " \ - "supplies", \ - "uitype": "outcommodity"} - std::string out_commod; - - /// Name of the recipe this facility uses. - #pragma cyclus var {"tooltip": "commodity recipe name", \ - "doc": "recipe name for source facility's commodity", \ - "uitype": "recipe"} - std::string recipe_name; - - /// The capacity is defined in terms of the number of units of the - /// recipe that can be provided each time step. A very large number - /// can be provided to represent infinte capacity. - #pragma cyclus var {"default": 1e299, "tooltip": "source capacity", \ - "doc": "amount of commodity that can be supplied " \ - "at each time step"} - double capacity; - - /// The capacity at the current time step - #pragma cyclus var {'derived_init': 'current_capacity = capacity;'} - double current_capacity; - - // --- -}; - -} // namespace cycamore - -#endif // CYCAMORE_SRC_FOO_H_ diff --git a/src/foo_tests.cc b/src/foo_tests.cc deleted file mode 100644 index 0973e794d0..0000000000 --- a/src/foo_tests.cc +++ /dev/null @@ -1,204 +0,0 @@ -#include "foo_tests.h" - -#include - -#include - -#include "cyc_limits.h" -#include "resource_helpers.h" -#include "test_context.h" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::SetUp() { - src_facility = new cycamore::Foo(tc.get()); - trader = tc.trader(); - InitParameters(); - SetUpFoo(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::TearDown() { - delete src_facility; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::InitParameters() { - commod = "commod"; - recipe_name = "recipe"; - capacity = 5; // some magic number.. - - recipe = cyclus::Composition::CreateFromAtom(cyclus::CompMap()); - tc.get()->AddRecipe(recipe_name, recipe); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::SetUpFoo() { - src_facility->commodity(commod); - src_facility->recipe(recipe_name); - src_facility->Capacity(capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, InitialState) { - EXPECT_EQ(src_facility->Capacity(), capacity); - EXPECT_EQ(src_facility->commodity(), commod); - EXPECT_EQ(src_facility->recipe(), recipe_name); - EXPECT_EQ(src_facility->CurrentCapacity(), capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Clone) { - cyclus::Context* ctx = tc.get(); - cycamore::Foo* cloned_fac = dynamic_cast - (src_facility->Clone()); - - EXPECT_EQ(src_facility->commodity(), cloned_fac->commodity()); - EXPECT_EQ(src_facility->Capacity(), cloned_fac->Capacity()); - EXPECT_EQ(src_facility->recipe(), cloned_fac->recipe()); - EXPECT_EQ(src_facility->Capacity(), cloned_fac->CurrentCapacity()); - - delete cloned_fac; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Print) { - EXPECT_NO_THROW(std::string s = src_facility->str()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, GetOffer) { - using cyclus::Material; - - double qty = capacity - 1; - Material::Ptr mat = cyclus::NewBlankMaterial(qty); - Material::Ptr obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), qty); - EXPECT_EQ(obs_mat->comp(), recipe); - - qty = capacity + 1; - mat = cyclus::NewBlankMaterial(qty); - obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), capacity); - EXPECT_EQ(obs_mat->comp(), recipe); - - qty = capacity; - mat = cyclus::NewBlankMaterial(qty); - obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), capacity); - EXPECT_EQ(obs_mat->comp(), recipe); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, AddBids) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::ExchangeContext; - using cyclus::Material; - - int nreqs = 5; - - boost::shared_ptr< cyclus::ExchangeContext > - ec = GetContext(nreqs, commod); - - std::set::Ptr> ports = - src_facility->GetMatlBids(ec.get()->commod_requests); - - ASSERT_TRUE(ports.size() > 0); - EXPECT_EQ(ports.size(), 1); - - BidPortfolio::Ptr port = *ports.begin(); - EXPECT_EQ(port->bidder(), src_facility); - EXPECT_EQ(port->bids().size(), nreqs); - - const std::set< CapacityConstraint >& constrs = port->constraints(); - ASSERT_TRUE(constrs.size() > 0); - EXPECT_EQ(constrs.size(), 1); - EXPECT_EQ(*constrs.begin(), CapacityConstraint(capacity)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Response) { - using cyclus::Bid; - using cyclus::Material; - using cyclus::Request; - using cyclus::Trade; - using test_helpers::get_mat; - - std::vector< cyclus::Trade > trades; - std::vector, - cyclus::Material::Ptr> > responses; - - // Null response - EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); - EXPECT_EQ(responses.size(), 0); - - double qty = capacity / 3; - Request* request = - Request::Create(get_mat(), trader, commod); - Bid* bid = - Bid::Create(request, get_mat(), src_facility); - - Trade trade(request, bid, qty); - trades.push_back(trade); - - // 1 trade - ASSERT_EQ(src_facility->CurrentCapacity(), capacity); - src_facility->GetMatlTrades(trades, responses); - EXPECT_EQ(responses.size(), 1); - EXPECT_EQ(responses[0].second->quantity(), qty); - EXPECT_EQ(responses[0].second->comp(), recipe); - - // 2 trades, total qty = capacity - ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity - qty); - ASSERT_GT(src_facility->CurrentCapacity() - 2 * qty, -1 * cyclus::eps()); - trades.push_back(trade); - responses.clear(); - EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); - EXPECT_EQ(responses.size(), 2); - ASSERT_TRUE(cyclus::AlmostEq(src_facility->CurrentCapacity(), 0)); - - // too much qty, capn! - EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), - cyclus::ValueError); - - // reset! - src_facility->Tick(); - ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity); - - delete request; - delete bid; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -boost::shared_ptr< cyclus::ExchangeContext > -FooTest::GetContext(int nreqs, std::string commod) { - using cyclus::Material; - using cyclus::Request; - using cyclus::ExchangeContext; - using test_helpers::get_mat; - - double qty = 3; - boost::shared_ptr< ExchangeContext > - ec(new ExchangeContext()); - for (int i = 0; i < nreqs; i++) { - ec->AddRequest(Request::Create(get_mat(), trader, commod)); - } - return ec; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Agent* FooConstructor(cyclus::Context* ctx) { - return new cycamore::Foo(ctx); -} - -// required to get functionality in cyclus agent unit tests library -#ifndef CYCLUS_AGENT_TESTS_CONNECTED -int ConnectAgentTests(); -static int cyclus_agent_tests_connected = ConnectAgentTests(); -#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected -#endif // CYCLUS_AGENT_TESTS_CONNECTED - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -INSTANTIATE_TEST_CASE_P(FooFac, FacilityTests, Values(&FooConstructor)); -INSTANTIATE_TEST_CASE_P(FooFac, AgentTests, Values(&FooConstructor)); diff --git a/src/foo_tests.h b/src/foo_tests.h deleted file mode 100644 index 59888926b7..0000000000 --- a/src/foo_tests.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef CYCAMORE_SRC_FOO_TESTS_H_ -#define CYCAMORE_SRC_FOO_TESTS_H_ -#include "foo.h" - -#include - -#include - -#include "agent_tests.h" -#include "context.h" -#include "exchange_context.h" -#include "facility_tests.h" -#include "material.h" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -class FooTest : public ::testing::Test { - public: - cyclus::TestContext tc; - TestFacility* trader; - cycamore::Foo* src_facility; - std::string commod, recipe_name; - double capacity; - cyclus::Composition::Ptr recipe; - - virtual void SetUp(); - virtual void TearDown(); - void InitParameters(); - void SetUpFoo(); - - boost::shared_ptr< cyclus::ExchangeContext > - GetContext(int nreqs, std::string commodity); -}; - -#endif // CYCAMORE_SRC_FOO_TESTS_H_ From cdf4ab29ed9511ee7db06f9ecf3c7dd56f4fd3c5 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 11:38:35 -0500 Subject: [PATCH 176/314] explicit status var --- .travis-install.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis-install.sh b/.travis-install.sh index 46059223a9..40e99c99c5 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -3,10 +3,12 @@ unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml conda build --no-test conda-recipe -if [[ $? != 0 ]]; then - exit $? +status=$? +if [[ $status != 0 ]]; then + exit $status conda install --use-local cycamore=0.0 -if [[ $? != 0 ]]; then - exit $? +status=$? +if [[ $status != 0 ]]; then + exit $status From 9891a950edf4cfb428825aa75cb4feb43424ae37 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 12:09:19 -0500 Subject: [PATCH 177/314] fixed syntax errors added logging --- .travis-install.sh | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.travis-install.sh b/.travis-install.sh index 40e99c99c5..1e53559839 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -1,14 +1,26 @@ +#!/bin/bash + +# setup conda recipe wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml -conda build --no-test conda-recipe +# build +cmd="conda build --no-test conda-recipe" +echo "cmd: $cmd" +$cmd status=$? +echo "status: $status" if [[ $status != 0 ]]; then exit $status +fi -conda install --use-local cycamore=0.0 - +# install +cmd="conda install --use-local cycamore=0.0" +echo "cmd: $cmd" +$cmd status=$? +echo "status: $status" if [[ $status != 0 ]]; then exit $status +fi From 42fea0add138d2d30b182dae84f9468b85594aa7 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 12:45:13 -0500 Subject: [PATCH 178/314] should fail --- src/reactor_tests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactor_tests.cc b/src/reactor_tests.cc index 8c743e5cf4..7ba33e8cc0 100644 --- a/src/reactor_tests.cc +++ b/src/reactor_tests.cc @@ -131,7 +131,7 @@ TEST(ReactorTests, RefuelTimes) { QueryResult qr = sim.db().Query("Transactions", NULL); int cyclet = 4; - int refuelt = 3; + int refuelt = 2; int n_assem_want = simdur/(cyclet+refuelt)+1; // +1 for initial core EXPECT_EQ(n_assem_want, qr.rows.size()); } From ee2eab2d9766383352cca7bcac82a69db0c4b58b Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 12:45:21 -0500 Subject: [PATCH 179/314] Revert "should fail" This reverts commit 42fea0add138d2d30b182dae84f9468b85594aa7. --- src/reactor_tests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactor_tests.cc b/src/reactor_tests.cc index 7ba33e8cc0..8c743e5cf4 100644 --- a/src/reactor_tests.cc +++ b/src/reactor_tests.cc @@ -131,7 +131,7 @@ TEST(ReactorTests, RefuelTimes) { QueryResult qr = sim.db().Query("Transactions", NULL); int cyclet = 4; - int refuelt = 2; + int refuelt = 3; int n_assem_want = simdur/(cyclet+refuelt)+1; // +1 for initial core EXPECT_EQ(n_assem_want, qr.rows.size()); } From 3bb92b3be3c5ccf879bc11c9c50243ab1a206bf0 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Tue, 17 Feb 2015 12:50:14 -0600 Subject: [PATCH 180/314] Squashing commits from cyclus/cycamore#301. This should fail on CI. --- src/CMakeLists.txt | 2 + src/foo.cc | 171 +++++++++++++++++++++++++++++++++++++ src/foo.h | 204 +++++++++++++++++++++++++++++++++++++++++++++ src/foo_tests.cc | 204 +++++++++++++++++++++++++++++++++++++++++++++ src/foo_tests.h | 34 ++++++++ 5 files changed, 615 insertions(+) create mode 100644 src/foo.cc create mode 100644 src/foo.h create mode 100644 src/foo_tests.cc create mode 100644 src/foo_tests.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5701534c73..0f0ef9eea2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,8 @@ USE_CYCLUS("cycamore" "sink") USE_CYCLUS("cycamore" "source") +USE_CYCLUS("cycamore" "foo") + USE_CYCLUS("cycamore" "deploy_inst") USE_CYCLUS("cycamore" "manager_inst") diff --git a/src/foo.cc b/src/foo.cc new file mode 100644 index 0000000000..9ad8ada201 --- /dev/null +++ b/src/foo.cc @@ -0,0 +1,171 @@ +#include "foo.h" + +#include +#include + +#include + +namespace cycamore { + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Foo::Foo(cyclus::Context* ctx) + : cyclus::Facility(ctx), + out_commod(""), + recipe_name(""), + capacity(std::numeric_limits::max()) {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Foo::~Foo() {} + +#pragma cyclus def clone cycamore::Foo + +#pragma cyclus def schema cycamore::Foo + +#pragma cyclus def annotations cycamore::Foo + +#pragma cyclus def infiletodb cycamore::Foo + +#pragma cyclus def snapshot cycamore::Foo + +#pragma cyclus def snapshotinv cycamore::Foo + +#pragma cyclus def initinv cycamore::Foo + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::InitFrom(Foo* m) { + #pragma cyclus impl initfromcopy cycamore::Foo + cyclus::toolkit::CommodityProducer::Copy(m); +} + +void Foo::InitFrom(cyclus::QueryableBackend* b) { + #pragma cyclus impl initfromdb cycamore::Foo + + commod_ = cyclus::toolkit::Commodity(out_commod); + cyclus::toolkit::CommodityProducer::Add(commod_); + cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); + cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); +} + +void Foo::EnterNotify() { + Facility::EnterNotify(); + commod_ = cyclus::toolkit::Commodity(out_commod); + cyclus::toolkit::CommodityProducer::Add(commod_); + cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); + cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::string Foo::str() { + std::stringstream ss; + std::string ans; + if (cyclus::toolkit::CommodityProducer:: + Produces(cyclus::toolkit::Commodity(out_commod))) { + ans = "yes"; + } else { + ans = "no"; + } + ss << cyclus::Facility::str() + << " supplies commodity '" + << out_commod << "' with recipe '" + << recipe_name << "' at a capacity of " + << capacity << " kg per time step " + << " commod producer members: " << " produces " + << out_commod << "?: " << ans + << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(commod_) + << " cost: " << cyclus::toolkit::CommodityProducer::Cost(commod_); + return ss.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::Tick() { + LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is ticking {"; + LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity + << " kg of " + << out_commod << "."; + LOG(cyclus::LEV_INFO3, "SrcFac") << "Stats: " << str(); + LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; + current_capacity = capacity; // reset capacity +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::Tock() { + LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is tocking {"; + LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr Foo::GetOffer( + const cyclus::Material::Ptr target) const { + using cyclus::Material; + double qty = std::min(target->quantity(), capacity); + return Material::CreateUntracked(qty, context()->GetRecipe(recipe_name)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::set::Ptr> +Foo::GetMatlBids( + cyclus::CommodMap::type& commod_requests) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::Material; + using cyclus::Request; + + std::set::Ptr> ports; + + if (commod_requests.count(out_commod) > 0) { + BidPortfolio::Ptr port(new BidPortfolio()); + + std::vector*>& requests = + commod_requests[out_commod]; + + std::vector*>::iterator it; + for (it = requests.begin(); it != requests.end(); ++it) { + Request* req = *it; + Material::Ptr offer = GetOffer(req->target()); + port->AddBid(req, offer, this); + } + + CapacityConstraint cc(capacity); + port->AddConstraint(cc); + ports.insert(port); + } + return ports; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses) { + using cyclus::Material; + using cyclus::Trade; + + double provided = 0; + std::vector< cyclus::Trade >::const_iterator it; + for (it = trades.begin(); it != trades.end(); ++it) { + double qty = it->amt; + current_capacity -= qty; + provided += qty; + // @TODO we need a policy on negatives.. + Material::Ptr response = Material::Create(this, qty, + context()->GetRecipe(recipe_name)); + responses.push_back(std::make_pair(*it, response)); + LOG(cyclus::LEV_INFO5, "SrcFac") << prototype() << " just received an order" + << " for " << qty + << " of " << out_commod; + } + if (cyclus::IsNegative(current_capacity)) { + std::stringstream ss; + ss << "is being asked to provide " << provided + << " but its capacity is " << capacity << "."; + throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +extern "C" cyclus::Agent* ConstructFoo(cyclus::Context* ctx) { + return new Foo(ctx); +} + +} // namespace cycamore diff --git a/src/foo.h b/src/foo.h new file mode 100644 index 0000000000..e35ab83d99 --- /dev/null +++ b/src/foo.h @@ -0,0 +1,204 @@ +#ifndef CYCAMORE_SRC_FOO_H_ +#define CYCAMORE_SRC_FOO_H_ + +#include +#include + +#include "cyclus.h" + +namespace cycamore { + +class Context; + +/// @class Foo +/// This cyclus::Facility provides a simple source of some capacity +/// (possibly infinite) of some commodity/Recipe. + +/// The Foo class inherits from the cyclus::Facility class and is +/// dynamically loaded by the Agent class when requested. + +/// @section introduction Introduction +/// The Foo is a facility type in Cyclus capable of providing +/// a finite or infinite.Supply of a particular material to the +/// simulation. A Foo generates material of a certain +/// composition and commodity type, then offers that material on the +/// appropriate market. Shipments of this material are executed when the +/// market issues an order that the offer has been matched with a +/// request. + +/// @section agentparams Agent Parameters +/// Foo behavior is comprehensively defined by the following +/// parameters: +/// - double capacity: The production capacity of the facility (units +/// vary, but typically kg/month). Capacity is infinite if a negative +/// value is provided. +/// - int startDate: The date on which the facility begins to operate +/// (months). +/// - int lifeTime: The length of time that the facility operates +/// (months). - std::string outCommod: the commodity that this facility +/// produces - double inventorysize: the maximum quantity of material to +/// be held in the inventory +/// - double commodprice: the price of the output material PER UNIT +/// - map outComp + +/// @section optionalparams Optional Parameters +/// Foo behavior may also be specified with the following +/// optional parameters which have default values listed here. +/// - double capacityFactor: The ratio of actual production capacity to +/// the rated production capacity. Default is 1 (actual/rated). +/// - double availFactor: The percent of time the facility operates at +/// its capacity factor. Default is 100%. +/// - double capitalCost: The cost of constructing and commissioning +/// this facility. Default is 0 ($). +/// - double opCost: The annual cost of operation and maintenance of +/// this facility. Default is 0 ( $/year). +/// - int constrTime: The number of months it takes to construct and +/// commission this facility. Default is 0 (months). +/// - int decomTime: The number of months it takes to deconstruct and +/// decommission this facility. Default is 0 (months). +/// - Inst* inst: The institution responsible for this facility. +/// - string name: A non-generic name for this facility. + +/// @section detailed Detailed Behavior +/// @subsection finite If Finite Capacity: +/// The Foo starts operation when the simulation reaches the +/// month specified as the startDate. It immediately begins to produce +/// material at the rate defined by its capacity. Each month the +/// Foo adds the amount it has produced to its inventory. It +/// then offers to the appropriate market exactly as much material as it +/// has in its inventory. If an offer is matched with a request, the +/// Foo executes that order by subtracting the quantity from +/// its inventory and sending that amount to the requesting facility. +/// When the simulation time equals the startDate plus the lifeTime, the +/// facility ceases to operate. +/// @subsection infinite If Infinite Capacity: +/// The Foo starts operation when the simulation reaches the +/// month specified as the startDate. Each month the Foo +/// offers an infinite amount of material to the appropriate market. If +/// there is a request for that material, the Foo executes +/// that order by sending that amount to the requesting facility. When +/// the simulation time equals the startDate plus the lifeTime, the +/// facility ceases to operate. + +/// @subsection question Question: +/// What is the best way to allow offers of an infinite amount of +/// material on a market? + +class Foo : public cyclus::Facility, + public cyclus::toolkit::CommodityProducer { + public: + // --- Module Members --- + /// Constructor for the Foo class + /// @param ctx the cyclus context for access to simulation-wide parameters + Foo(cyclus::Context* ctx); + + virtual ~Foo() + + #pragma cyclus decl + + #pragma cyclus note {"doc": "A source facility that provides a " \ + "commodity with a given capacity"} + + /// Print information about this agent + virtual std::string str(); + // --- + + // --- Agent Members --- + virtual void EnterNotify(); + + /// Each facility is prompted to do its beginning-of-time-step + /// stuff at the tick of the timer. + + /// @param time is the time to perform the tick + virtual void Tick(); + + /// Each facility is prompted to its end-of-time-step + /// stuff on the tock of the timer. + + /// @param time is the time to perform the tock + virtual void Tock(); + + /// @brief Responds to each request for this source facility's commodity. + /// If a given request is more than this facility's capacity, it will offer + /// its capacity. + virtual std::set::Ptr> + GetMatlBids(cyclus::CommodMap::type& + commod_requests); + + /// @brief respond to each trade with a material made from this facility's + /// recipe + /// + /// @param trades all trades in which this trader is the supplier + /// @param responses a container to populate with responses to each trade + virtual void GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses); + // --- + + // --- Foo Members --- + /// @brief creates a material object to offer to a requester + /// @param target the material target a request desires + cyclus::Material::Ptr GetOffer(const cyclus::Material::Ptr target) const; + + /// sets the output commodity name + /// @param name the commodity name + inline void commodity(std::string name) { out_commod = name; } + + /// @return the output commodity + inline std::string commodity() const { return out_commod; } + + /// sets the capacity of a material generated at any given time step + /// @param capacity the production capacity + inline void Capacity(double cap) { + capacity = cap; + current_capacity = capacity; + } + + /// @return the production capacity at any given time step + inline double Capacity() const { return capacity; } + + /// sets the name of the recipe to be produced + /// @param name the recipe name + inline void recipe(std::string name) { recipe_name = name; } + + /// @return the name of the output recipe + inline std::string recipe() const { return recipe_name; } + + /// @return the current timestep's capacity + inline double CurrentCapacity() const { return current_capacity; } + + private: + cyclus::toolkit::Commodity commod_; + + /// This facility has only one output commodity + #pragma cyclus var {"tooltip": "source output commodity", \ + "doc": "output commodity that the source facility " \ + "supplies", \ + "uitype": "outcommodity"} + std::string out_commod; + + /// Name of the recipe this facility uses. + #pragma cyclus var {"tooltip": "commodity recipe name", \ + "doc": "recipe name for source facility's commodity", \ + "uitype": "recipe"} + std::string recipe_name; + + /// The capacity is defined in terms of the number of units of the + /// recipe that can be provided each time step. A very large number + /// can be provided to represent infinte capacity. + #pragma cyclus var {"default": 1e299, "tooltip": "source capacity", \ + "doc": "amount of commodity that can be supplied " \ + "at each time step"} + double capacity; + + /// The capacity at the current time step + #pragma cyclus var {'derived_init': 'current_capacity = capacity;'} + double current_capacity; + + // --- +}; + +} // namespace cycamore + +#endif // CYCAMORE_SRC_FOO_H_ diff --git a/src/foo_tests.cc b/src/foo_tests.cc new file mode 100644 index 0000000000..0973e794d0 --- /dev/null +++ b/src/foo_tests.cc @@ -0,0 +1,204 @@ +#include "foo_tests.h" + +#include + +#include + +#include "cyc_limits.h" +#include "resource_helpers.h" +#include "test_context.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::SetUp() { + src_facility = new cycamore::Foo(tc.get()); + trader = tc.trader(); + InitParameters(); + SetUpFoo(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::TearDown() { + delete src_facility; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::InitParameters() { + commod = "commod"; + recipe_name = "recipe"; + capacity = 5; // some magic number.. + + recipe = cyclus::Composition::CreateFromAtom(cyclus::CompMap()); + tc.get()->AddRecipe(recipe_name, recipe); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::SetUpFoo() { + src_facility->commodity(commod); + src_facility->recipe(recipe_name); + src_facility->Capacity(capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, InitialState) { + EXPECT_EQ(src_facility->Capacity(), capacity); + EXPECT_EQ(src_facility->commodity(), commod); + EXPECT_EQ(src_facility->recipe(), recipe_name); + EXPECT_EQ(src_facility->CurrentCapacity(), capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Clone) { + cyclus::Context* ctx = tc.get(); + cycamore::Foo* cloned_fac = dynamic_cast + (src_facility->Clone()); + + EXPECT_EQ(src_facility->commodity(), cloned_fac->commodity()); + EXPECT_EQ(src_facility->Capacity(), cloned_fac->Capacity()); + EXPECT_EQ(src_facility->recipe(), cloned_fac->recipe()); + EXPECT_EQ(src_facility->Capacity(), cloned_fac->CurrentCapacity()); + + delete cloned_fac; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Print) { + EXPECT_NO_THROW(std::string s = src_facility->str()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, GetOffer) { + using cyclus::Material; + + double qty = capacity - 1; + Material::Ptr mat = cyclus::NewBlankMaterial(qty); + Material::Ptr obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), qty); + EXPECT_EQ(obs_mat->comp(), recipe); + + qty = capacity + 1; + mat = cyclus::NewBlankMaterial(qty); + obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), capacity); + EXPECT_EQ(obs_mat->comp(), recipe); + + qty = capacity; + mat = cyclus::NewBlankMaterial(qty); + obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), capacity); + EXPECT_EQ(obs_mat->comp(), recipe); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, AddBids) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::ExchangeContext; + using cyclus::Material; + + int nreqs = 5; + + boost::shared_ptr< cyclus::ExchangeContext > + ec = GetContext(nreqs, commod); + + std::set::Ptr> ports = + src_facility->GetMatlBids(ec.get()->commod_requests); + + ASSERT_TRUE(ports.size() > 0); + EXPECT_EQ(ports.size(), 1); + + BidPortfolio::Ptr port = *ports.begin(); + EXPECT_EQ(port->bidder(), src_facility); + EXPECT_EQ(port->bids().size(), nreqs); + + const std::set< CapacityConstraint >& constrs = port->constraints(); + ASSERT_TRUE(constrs.size() > 0); + EXPECT_EQ(constrs.size(), 1); + EXPECT_EQ(*constrs.begin(), CapacityConstraint(capacity)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Response) { + using cyclus::Bid; + using cyclus::Material; + using cyclus::Request; + using cyclus::Trade; + using test_helpers::get_mat; + + std::vector< cyclus::Trade > trades; + std::vector, + cyclus::Material::Ptr> > responses; + + // Null response + EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); + EXPECT_EQ(responses.size(), 0); + + double qty = capacity / 3; + Request* request = + Request::Create(get_mat(), trader, commod); + Bid* bid = + Bid::Create(request, get_mat(), src_facility); + + Trade trade(request, bid, qty); + trades.push_back(trade); + + // 1 trade + ASSERT_EQ(src_facility->CurrentCapacity(), capacity); + src_facility->GetMatlTrades(trades, responses); + EXPECT_EQ(responses.size(), 1); + EXPECT_EQ(responses[0].second->quantity(), qty); + EXPECT_EQ(responses[0].second->comp(), recipe); + + // 2 trades, total qty = capacity + ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity - qty); + ASSERT_GT(src_facility->CurrentCapacity() - 2 * qty, -1 * cyclus::eps()); + trades.push_back(trade); + responses.clear(); + EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); + EXPECT_EQ(responses.size(), 2); + ASSERT_TRUE(cyclus::AlmostEq(src_facility->CurrentCapacity(), 0)); + + // too much qty, capn! + EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), + cyclus::ValueError); + + // reset! + src_facility->Tick(); + ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity); + + delete request; + delete bid; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +boost::shared_ptr< cyclus::ExchangeContext > +FooTest::GetContext(int nreqs, std::string commod) { + using cyclus::Material; + using cyclus::Request; + using cyclus::ExchangeContext; + using test_helpers::get_mat; + + double qty = 3; + boost::shared_ptr< ExchangeContext > + ec(new ExchangeContext()); + for (int i = 0; i < nreqs; i++) { + ec->AddRequest(Request::Create(get_mat(), trader, commod)); + } + return ec; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Agent* FooConstructor(cyclus::Context* ctx) { + return new cycamore::Foo(ctx); +} + +// required to get functionality in cyclus agent unit tests library +#ifndef CYCLUS_AGENT_TESTS_CONNECTED +int ConnectAgentTests(); +static int cyclus_agent_tests_connected = ConnectAgentTests(); +#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected +#endif // CYCLUS_AGENT_TESTS_CONNECTED + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +INSTANTIATE_TEST_CASE_P(FooFac, FacilityTests, Values(&FooConstructor)); +INSTANTIATE_TEST_CASE_P(FooFac, AgentTests, Values(&FooConstructor)); diff --git a/src/foo_tests.h b/src/foo_tests.h new file mode 100644 index 0000000000..59888926b7 --- /dev/null +++ b/src/foo_tests.h @@ -0,0 +1,34 @@ +#ifndef CYCAMORE_SRC_FOO_TESTS_H_ +#define CYCAMORE_SRC_FOO_TESTS_H_ +#include "foo.h" + +#include + +#include + +#include "agent_tests.h" +#include "context.h" +#include "exchange_context.h" +#include "facility_tests.h" +#include "material.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +class FooTest : public ::testing::Test { + public: + cyclus::TestContext tc; + TestFacility* trader; + cycamore::Foo* src_facility; + std::string commod, recipe_name; + double capacity; + cyclus::Composition::Ptr recipe; + + virtual void SetUp(); + virtual void TearDown(); + void InitParameters(); + void SetUpFoo(); + + boost::shared_ptr< cyclus::ExchangeContext > + GetContext(int nreqs, std::string commodity); +}; + +#endif // CYCAMORE_SRC_FOO_TESTS_H_ From 55df5eecde6c221b6fce8a3bc5b216e3b37184e2 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 12:46:05 -0500 Subject: [PATCH 181/314] Revert "Squashing commits from cyclus/cycamore#301. This should fail on CI." This reverts commit 3bb92b3be3c5ccf879bc11c9c50243ab1a206bf0. --- src/CMakeLists.txt | 2 - src/foo.cc | 171 ------------------------------------- src/foo.h | 204 --------------------------------------------- src/foo_tests.cc | 204 --------------------------------------------- src/foo_tests.h | 34 -------- 5 files changed, 615 deletions(-) delete mode 100644 src/foo.cc delete mode 100644 src/foo.h delete mode 100644 src/foo_tests.cc delete mode 100644 src/foo_tests.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0f0ef9eea2..5701534c73 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,8 +10,6 @@ USE_CYCLUS("cycamore" "sink") USE_CYCLUS("cycamore" "source") -USE_CYCLUS("cycamore" "foo") - USE_CYCLUS("cycamore" "deploy_inst") USE_CYCLUS("cycamore" "manager_inst") diff --git a/src/foo.cc b/src/foo.cc deleted file mode 100644 index 9ad8ada201..0000000000 --- a/src/foo.cc +++ /dev/null @@ -1,171 +0,0 @@ -#include "foo.h" - -#include -#include - -#include - -namespace cycamore { - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Foo::Foo(cyclus::Context* ctx) - : cyclus::Facility(ctx), - out_commod(""), - recipe_name(""), - capacity(std::numeric_limits::max()) {} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Foo::~Foo() {} - -#pragma cyclus def clone cycamore::Foo - -#pragma cyclus def schema cycamore::Foo - -#pragma cyclus def annotations cycamore::Foo - -#pragma cyclus def infiletodb cycamore::Foo - -#pragma cyclus def snapshot cycamore::Foo - -#pragma cyclus def snapshotinv cycamore::Foo - -#pragma cyclus def initinv cycamore::Foo - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::InitFrom(Foo* m) { - #pragma cyclus impl initfromcopy cycamore::Foo - cyclus::toolkit::CommodityProducer::Copy(m); -} - -void Foo::InitFrom(cyclus::QueryableBackend* b) { - #pragma cyclus impl initfromdb cycamore::Foo - - commod_ = cyclus::toolkit::Commodity(out_commod); - cyclus::toolkit::CommodityProducer::Add(commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); - cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); -} - -void Foo::EnterNotify() { - Facility::EnterNotify(); - commod_ = cyclus::toolkit::Commodity(out_commod); - cyclus::toolkit::CommodityProducer::Add(commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); - cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::string Foo::str() { - std::stringstream ss; - std::string ans; - if (cyclus::toolkit::CommodityProducer:: - Produces(cyclus::toolkit::Commodity(out_commod))) { - ans = "yes"; - } else { - ans = "no"; - } - ss << cyclus::Facility::str() - << " supplies commodity '" - << out_commod << "' with recipe '" - << recipe_name << "' at a capacity of " - << capacity << " kg per time step " - << " commod producer members: " << " produces " - << out_commod << "?: " << ans - << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(commod_) - << " cost: " << cyclus::toolkit::CommodityProducer::Cost(commod_); - return ss.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::Tick() { - LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is ticking {"; - LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity - << " kg of " - << out_commod << "."; - LOG(cyclus::LEV_INFO3, "SrcFac") << "Stats: " << str(); - LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; - current_capacity = capacity; // reset capacity -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::Tock() { - LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is tocking {"; - LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr Foo::GetOffer( - const cyclus::Material::Ptr target) const { - using cyclus::Material; - double qty = std::min(target->quantity(), capacity); - return Material::CreateUntracked(qty, context()->GetRecipe(recipe_name)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -Foo::GetMatlBids( - cyclus::CommodMap::type& commod_requests) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::Material; - using cyclus::Request; - - std::set::Ptr> ports; - - if (commod_requests.count(out_commod) > 0) { - BidPortfolio::Ptr port(new BidPortfolio()); - - std::vector*>& requests = - commod_requests[out_commod]; - - std::vector*>::iterator it; - for (it = requests.begin(); it != requests.end(); ++it) { - Request* req = *it; - Material::Ptr offer = GetOffer(req->target()); - port->AddBid(req, offer, this); - } - - CapacityConstraint cc(capacity); - port->AddConstraint(cc); - ports.insert(port); - } - return ports; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses) { - using cyclus::Material; - using cyclus::Trade; - - double provided = 0; - std::vector< cyclus::Trade >::const_iterator it; - for (it = trades.begin(); it != trades.end(); ++it) { - double qty = it->amt; - current_capacity -= qty; - provided += qty; - // @TODO we need a policy on negatives.. - Material::Ptr response = Material::Create(this, qty, - context()->GetRecipe(recipe_name)); - responses.push_back(std::make_pair(*it, response)); - LOG(cyclus::LEV_INFO5, "SrcFac") << prototype() << " just received an order" - << " for " << qty - << " of " << out_commod; - } - if (cyclus::IsNegative(current_capacity)) { - std::stringstream ss; - ss << "is being asked to provide " << provided - << " but its capacity is " << capacity << "."; - throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern "C" cyclus::Agent* ConstructFoo(cyclus::Context* ctx) { - return new Foo(ctx); -} - -} // namespace cycamore diff --git a/src/foo.h b/src/foo.h deleted file mode 100644 index e35ab83d99..0000000000 --- a/src/foo.h +++ /dev/null @@ -1,204 +0,0 @@ -#ifndef CYCAMORE_SRC_FOO_H_ -#define CYCAMORE_SRC_FOO_H_ - -#include -#include - -#include "cyclus.h" - -namespace cycamore { - -class Context; - -/// @class Foo -/// This cyclus::Facility provides a simple source of some capacity -/// (possibly infinite) of some commodity/Recipe. - -/// The Foo class inherits from the cyclus::Facility class and is -/// dynamically loaded by the Agent class when requested. - -/// @section introduction Introduction -/// The Foo is a facility type in Cyclus capable of providing -/// a finite or infinite.Supply of a particular material to the -/// simulation. A Foo generates material of a certain -/// composition and commodity type, then offers that material on the -/// appropriate market. Shipments of this material are executed when the -/// market issues an order that the offer has been matched with a -/// request. - -/// @section agentparams Agent Parameters -/// Foo behavior is comprehensively defined by the following -/// parameters: -/// - double capacity: The production capacity of the facility (units -/// vary, but typically kg/month). Capacity is infinite if a negative -/// value is provided. -/// - int startDate: The date on which the facility begins to operate -/// (months). -/// - int lifeTime: The length of time that the facility operates -/// (months). - std::string outCommod: the commodity that this facility -/// produces - double inventorysize: the maximum quantity of material to -/// be held in the inventory -/// - double commodprice: the price of the output material PER UNIT -/// - map outComp - -/// @section optionalparams Optional Parameters -/// Foo behavior may also be specified with the following -/// optional parameters which have default values listed here. -/// - double capacityFactor: The ratio of actual production capacity to -/// the rated production capacity. Default is 1 (actual/rated). -/// - double availFactor: The percent of time the facility operates at -/// its capacity factor. Default is 100%. -/// - double capitalCost: The cost of constructing and commissioning -/// this facility. Default is 0 ($). -/// - double opCost: The annual cost of operation and maintenance of -/// this facility. Default is 0 ( $/year). -/// - int constrTime: The number of months it takes to construct and -/// commission this facility. Default is 0 (months). -/// - int decomTime: The number of months it takes to deconstruct and -/// decommission this facility. Default is 0 (months). -/// - Inst* inst: The institution responsible for this facility. -/// - string name: A non-generic name for this facility. - -/// @section detailed Detailed Behavior -/// @subsection finite If Finite Capacity: -/// The Foo starts operation when the simulation reaches the -/// month specified as the startDate. It immediately begins to produce -/// material at the rate defined by its capacity. Each month the -/// Foo adds the amount it has produced to its inventory. It -/// then offers to the appropriate market exactly as much material as it -/// has in its inventory. If an offer is matched with a request, the -/// Foo executes that order by subtracting the quantity from -/// its inventory and sending that amount to the requesting facility. -/// When the simulation time equals the startDate plus the lifeTime, the -/// facility ceases to operate. -/// @subsection infinite If Infinite Capacity: -/// The Foo starts operation when the simulation reaches the -/// month specified as the startDate. Each month the Foo -/// offers an infinite amount of material to the appropriate market. If -/// there is a request for that material, the Foo executes -/// that order by sending that amount to the requesting facility. When -/// the simulation time equals the startDate plus the lifeTime, the -/// facility ceases to operate. - -/// @subsection question Question: -/// What is the best way to allow offers of an infinite amount of -/// material on a market? - -class Foo : public cyclus::Facility, - public cyclus::toolkit::CommodityProducer { - public: - // --- Module Members --- - /// Constructor for the Foo class - /// @param ctx the cyclus context for access to simulation-wide parameters - Foo(cyclus::Context* ctx); - - virtual ~Foo() - - #pragma cyclus decl - - #pragma cyclus note {"doc": "A source facility that provides a " \ - "commodity with a given capacity"} - - /// Print information about this agent - virtual std::string str(); - // --- - - // --- Agent Members --- - virtual void EnterNotify(); - - /// Each facility is prompted to do its beginning-of-time-step - /// stuff at the tick of the timer. - - /// @param time is the time to perform the tick - virtual void Tick(); - - /// Each facility is prompted to its end-of-time-step - /// stuff on the tock of the timer. - - /// @param time is the time to perform the tock - virtual void Tock(); - - /// @brief Responds to each request for this source facility's commodity. - /// If a given request is more than this facility's capacity, it will offer - /// its capacity. - virtual std::set::Ptr> - GetMatlBids(cyclus::CommodMap::type& - commod_requests); - - /// @brief respond to each trade with a material made from this facility's - /// recipe - /// - /// @param trades all trades in which this trader is the supplier - /// @param responses a container to populate with responses to each trade - virtual void GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses); - // --- - - // --- Foo Members --- - /// @brief creates a material object to offer to a requester - /// @param target the material target a request desires - cyclus::Material::Ptr GetOffer(const cyclus::Material::Ptr target) const; - - /// sets the output commodity name - /// @param name the commodity name - inline void commodity(std::string name) { out_commod = name; } - - /// @return the output commodity - inline std::string commodity() const { return out_commod; } - - /// sets the capacity of a material generated at any given time step - /// @param capacity the production capacity - inline void Capacity(double cap) { - capacity = cap; - current_capacity = capacity; - } - - /// @return the production capacity at any given time step - inline double Capacity() const { return capacity; } - - /// sets the name of the recipe to be produced - /// @param name the recipe name - inline void recipe(std::string name) { recipe_name = name; } - - /// @return the name of the output recipe - inline std::string recipe() const { return recipe_name; } - - /// @return the current timestep's capacity - inline double CurrentCapacity() const { return current_capacity; } - - private: - cyclus::toolkit::Commodity commod_; - - /// This facility has only one output commodity - #pragma cyclus var {"tooltip": "source output commodity", \ - "doc": "output commodity that the source facility " \ - "supplies", \ - "uitype": "outcommodity"} - std::string out_commod; - - /// Name of the recipe this facility uses. - #pragma cyclus var {"tooltip": "commodity recipe name", \ - "doc": "recipe name for source facility's commodity", \ - "uitype": "recipe"} - std::string recipe_name; - - /// The capacity is defined in terms of the number of units of the - /// recipe that can be provided each time step. A very large number - /// can be provided to represent infinte capacity. - #pragma cyclus var {"default": 1e299, "tooltip": "source capacity", \ - "doc": "amount of commodity that can be supplied " \ - "at each time step"} - double capacity; - - /// The capacity at the current time step - #pragma cyclus var {'derived_init': 'current_capacity = capacity;'} - double current_capacity; - - // --- -}; - -} // namespace cycamore - -#endif // CYCAMORE_SRC_FOO_H_ diff --git a/src/foo_tests.cc b/src/foo_tests.cc deleted file mode 100644 index 0973e794d0..0000000000 --- a/src/foo_tests.cc +++ /dev/null @@ -1,204 +0,0 @@ -#include "foo_tests.h" - -#include - -#include - -#include "cyc_limits.h" -#include "resource_helpers.h" -#include "test_context.h" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::SetUp() { - src_facility = new cycamore::Foo(tc.get()); - trader = tc.trader(); - InitParameters(); - SetUpFoo(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::TearDown() { - delete src_facility; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::InitParameters() { - commod = "commod"; - recipe_name = "recipe"; - capacity = 5; // some magic number.. - - recipe = cyclus::Composition::CreateFromAtom(cyclus::CompMap()); - tc.get()->AddRecipe(recipe_name, recipe); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::SetUpFoo() { - src_facility->commodity(commod); - src_facility->recipe(recipe_name); - src_facility->Capacity(capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, InitialState) { - EXPECT_EQ(src_facility->Capacity(), capacity); - EXPECT_EQ(src_facility->commodity(), commod); - EXPECT_EQ(src_facility->recipe(), recipe_name); - EXPECT_EQ(src_facility->CurrentCapacity(), capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Clone) { - cyclus::Context* ctx = tc.get(); - cycamore::Foo* cloned_fac = dynamic_cast - (src_facility->Clone()); - - EXPECT_EQ(src_facility->commodity(), cloned_fac->commodity()); - EXPECT_EQ(src_facility->Capacity(), cloned_fac->Capacity()); - EXPECT_EQ(src_facility->recipe(), cloned_fac->recipe()); - EXPECT_EQ(src_facility->Capacity(), cloned_fac->CurrentCapacity()); - - delete cloned_fac; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Print) { - EXPECT_NO_THROW(std::string s = src_facility->str()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, GetOffer) { - using cyclus::Material; - - double qty = capacity - 1; - Material::Ptr mat = cyclus::NewBlankMaterial(qty); - Material::Ptr obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), qty); - EXPECT_EQ(obs_mat->comp(), recipe); - - qty = capacity + 1; - mat = cyclus::NewBlankMaterial(qty); - obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), capacity); - EXPECT_EQ(obs_mat->comp(), recipe); - - qty = capacity; - mat = cyclus::NewBlankMaterial(qty); - obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), capacity); - EXPECT_EQ(obs_mat->comp(), recipe); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, AddBids) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::ExchangeContext; - using cyclus::Material; - - int nreqs = 5; - - boost::shared_ptr< cyclus::ExchangeContext > - ec = GetContext(nreqs, commod); - - std::set::Ptr> ports = - src_facility->GetMatlBids(ec.get()->commod_requests); - - ASSERT_TRUE(ports.size() > 0); - EXPECT_EQ(ports.size(), 1); - - BidPortfolio::Ptr port = *ports.begin(); - EXPECT_EQ(port->bidder(), src_facility); - EXPECT_EQ(port->bids().size(), nreqs); - - const std::set< CapacityConstraint >& constrs = port->constraints(); - ASSERT_TRUE(constrs.size() > 0); - EXPECT_EQ(constrs.size(), 1); - EXPECT_EQ(*constrs.begin(), CapacityConstraint(capacity)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Response) { - using cyclus::Bid; - using cyclus::Material; - using cyclus::Request; - using cyclus::Trade; - using test_helpers::get_mat; - - std::vector< cyclus::Trade > trades; - std::vector, - cyclus::Material::Ptr> > responses; - - // Null response - EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); - EXPECT_EQ(responses.size(), 0); - - double qty = capacity / 3; - Request* request = - Request::Create(get_mat(), trader, commod); - Bid* bid = - Bid::Create(request, get_mat(), src_facility); - - Trade trade(request, bid, qty); - trades.push_back(trade); - - // 1 trade - ASSERT_EQ(src_facility->CurrentCapacity(), capacity); - src_facility->GetMatlTrades(trades, responses); - EXPECT_EQ(responses.size(), 1); - EXPECT_EQ(responses[0].second->quantity(), qty); - EXPECT_EQ(responses[0].second->comp(), recipe); - - // 2 trades, total qty = capacity - ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity - qty); - ASSERT_GT(src_facility->CurrentCapacity() - 2 * qty, -1 * cyclus::eps()); - trades.push_back(trade); - responses.clear(); - EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); - EXPECT_EQ(responses.size(), 2); - ASSERT_TRUE(cyclus::AlmostEq(src_facility->CurrentCapacity(), 0)); - - // too much qty, capn! - EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), - cyclus::ValueError); - - // reset! - src_facility->Tick(); - ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity); - - delete request; - delete bid; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -boost::shared_ptr< cyclus::ExchangeContext > -FooTest::GetContext(int nreqs, std::string commod) { - using cyclus::Material; - using cyclus::Request; - using cyclus::ExchangeContext; - using test_helpers::get_mat; - - double qty = 3; - boost::shared_ptr< ExchangeContext > - ec(new ExchangeContext()); - for (int i = 0; i < nreqs; i++) { - ec->AddRequest(Request::Create(get_mat(), trader, commod)); - } - return ec; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Agent* FooConstructor(cyclus::Context* ctx) { - return new cycamore::Foo(ctx); -} - -// required to get functionality in cyclus agent unit tests library -#ifndef CYCLUS_AGENT_TESTS_CONNECTED -int ConnectAgentTests(); -static int cyclus_agent_tests_connected = ConnectAgentTests(); -#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected -#endif // CYCLUS_AGENT_TESTS_CONNECTED - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -INSTANTIATE_TEST_CASE_P(FooFac, FacilityTests, Values(&FooConstructor)); -INSTANTIATE_TEST_CASE_P(FooFac, AgentTests, Values(&FooConstructor)); diff --git a/src/foo_tests.h b/src/foo_tests.h deleted file mode 100644 index 59888926b7..0000000000 --- a/src/foo_tests.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef CYCAMORE_SRC_FOO_TESTS_H_ -#define CYCAMORE_SRC_FOO_TESTS_H_ -#include "foo.h" - -#include - -#include - -#include "agent_tests.h" -#include "context.h" -#include "exchange_context.h" -#include "facility_tests.h" -#include "material.h" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -class FooTest : public ::testing::Test { - public: - cyclus::TestContext tc; - TestFacility* trader; - cycamore::Foo* src_facility; - std::string commod, recipe_name; - double capacity; - cyclus::Composition::Ptr recipe; - - virtual void SetUp(); - virtual void TearDown(); - void InitParameters(); - void SetUpFoo(); - - boost::shared_ptr< cyclus::ExchangeContext > - GetContext(int nreqs, std::string commodity); -}; - -#endif // CYCAMORE_SRC_FOO_TESTS_H_ From 67f4a5cf616ec24843599d45934025e07c3e9174 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 14:18:47 -0500 Subject: [PATCH 182/314] adding commit msg indicator --- .travis-install.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis-install.sh b/.travis-install.sh index 1e53559839..1f9e8a8e15 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -1,5 +1,9 @@ #!/bin/bash +# log +msg=`git log --pretty=oneline -1` +echo "Building commit: $msg" + # setup conda recipe wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe From d7c653699506e3aa4229840db5b97f24bc73d4f4 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 14:30:44 -0500 Subject: [PATCH 183/314] adding failure with an explicit check --- .travis-install.sh | 2 + src/CMakeLists.txt | 2 + src/foo.cc | 171 +++++++++++++++++++++++++++++++++++++ src/foo.h | 204 +++++++++++++++++++++++++++++++++++++++++++++ src/foo_tests.cc | 204 +++++++++++++++++++++++++++++++++++++++++++++ src/foo_tests.h | 34 ++++++++ 6 files changed, 617 insertions(+) create mode 100644 src/foo.cc create mode 100644 src/foo.h create mode 100644 src/foo_tests.cc create mode 100644 src/foo_tests.h diff --git a/.travis-install.sh b/.travis-install.sh index 1f9e8a8e15..08a02557a1 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -10,6 +10,8 @@ unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml # build +"src/CMakeLists.txt:" +cat src/CMakeLists.txt cmd="conda build --no-test conda-recipe" echo "cmd: $cmd" $cmd diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5701534c73..0f0ef9eea2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,8 @@ USE_CYCLUS("cycamore" "sink") USE_CYCLUS("cycamore" "source") +USE_CYCLUS("cycamore" "foo") + USE_CYCLUS("cycamore" "deploy_inst") USE_CYCLUS("cycamore" "manager_inst") diff --git a/src/foo.cc b/src/foo.cc new file mode 100644 index 0000000000..9ad8ada201 --- /dev/null +++ b/src/foo.cc @@ -0,0 +1,171 @@ +#include "foo.h" + +#include +#include + +#include + +namespace cycamore { + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Foo::Foo(cyclus::Context* ctx) + : cyclus::Facility(ctx), + out_commod(""), + recipe_name(""), + capacity(std::numeric_limits::max()) {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Foo::~Foo() {} + +#pragma cyclus def clone cycamore::Foo + +#pragma cyclus def schema cycamore::Foo + +#pragma cyclus def annotations cycamore::Foo + +#pragma cyclus def infiletodb cycamore::Foo + +#pragma cyclus def snapshot cycamore::Foo + +#pragma cyclus def snapshotinv cycamore::Foo + +#pragma cyclus def initinv cycamore::Foo + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::InitFrom(Foo* m) { + #pragma cyclus impl initfromcopy cycamore::Foo + cyclus::toolkit::CommodityProducer::Copy(m); +} + +void Foo::InitFrom(cyclus::QueryableBackend* b) { + #pragma cyclus impl initfromdb cycamore::Foo + + commod_ = cyclus::toolkit::Commodity(out_commod); + cyclus::toolkit::CommodityProducer::Add(commod_); + cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); + cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); +} + +void Foo::EnterNotify() { + Facility::EnterNotify(); + commod_ = cyclus::toolkit::Commodity(out_commod); + cyclus::toolkit::CommodityProducer::Add(commod_); + cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); + cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::string Foo::str() { + std::stringstream ss; + std::string ans; + if (cyclus::toolkit::CommodityProducer:: + Produces(cyclus::toolkit::Commodity(out_commod))) { + ans = "yes"; + } else { + ans = "no"; + } + ss << cyclus::Facility::str() + << " supplies commodity '" + << out_commod << "' with recipe '" + << recipe_name << "' at a capacity of " + << capacity << " kg per time step " + << " commod producer members: " << " produces " + << out_commod << "?: " << ans + << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(commod_) + << " cost: " << cyclus::toolkit::CommodityProducer::Cost(commod_); + return ss.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::Tick() { + LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is ticking {"; + LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity + << " kg of " + << out_commod << "."; + LOG(cyclus::LEV_INFO3, "SrcFac") << "Stats: " << str(); + LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; + current_capacity = capacity; // reset capacity +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::Tock() { + LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is tocking {"; + LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr Foo::GetOffer( + const cyclus::Material::Ptr target) const { + using cyclus::Material; + double qty = std::min(target->quantity(), capacity); + return Material::CreateUntracked(qty, context()->GetRecipe(recipe_name)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::set::Ptr> +Foo::GetMatlBids( + cyclus::CommodMap::type& commod_requests) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::Material; + using cyclus::Request; + + std::set::Ptr> ports; + + if (commod_requests.count(out_commod) > 0) { + BidPortfolio::Ptr port(new BidPortfolio()); + + std::vector*>& requests = + commod_requests[out_commod]; + + std::vector*>::iterator it; + for (it = requests.begin(); it != requests.end(); ++it) { + Request* req = *it; + Material::Ptr offer = GetOffer(req->target()); + port->AddBid(req, offer, this); + } + + CapacityConstraint cc(capacity); + port->AddConstraint(cc); + ports.insert(port); + } + return ports; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses) { + using cyclus::Material; + using cyclus::Trade; + + double provided = 0; + std::vector< cyclus::Trade >::const_iterator it; + for (it = trades.begin(); it != trades.end(); ++it) { + double qty = it->amt; + current_capacity -= qty; + provided += qty; + // @TODO we need a policy on negatives.. + Material::Ptr response = Material::Create(this, qty, + context()->GetRecipe(recipe_name)); + responses.push_back(std::make_pair(*it, response)); + LOG(cyclus::LEV_INFO5, "SrcFac") << prototype() << " just received an order" + << " for " << qty + << " of " << out_commod; + } + if (cyclus::IsNegative(current_capacity)) { + std::stringstream ss; + ss << "is being asked to provide " << provided + << " but its capacity is " << capacity << "."; + throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +extern "C" cyclus::Agent* ConstructFoo(cyclus::Context* ctx) { + return new Foo(ctx); +} + +} // namespace cycamore diff --git a/src/foo.h b/src/foo.h new file mode 100644 index 0000000000..e35ab83d99 --- /dev/null +++ b/src/foo.h @@ -0,0 +1,204 @@ +#ifndef CYCAMORE_SRC_FOO_H_ +#define CYCAMORE_SRC_FOO_H_ + +#include +#include + +#include "cyclus.h" + +namespace cycamore { + +class Context; + +/// @class Foo +/// This cyclus::Facility provides a simple source of some capacity +/// (possibly infinite) of some commodity/Recipe. + +/// The Foo class inherits from the cyclus::Facility class and is +/// dynamically loaded by the Agent class when requested. + +/// @section introduction Introduction +/// The Foo is a facility type in Cyclus capable of providing +/// a finite or infinite.Supply of a particular material to the +/// simulation. A Foo generates material of a certain +/// composition and commodity type, then offers that material on the +/// appropriate market. Shipments of this material are executed when the +/// market issues an order that the offer has been matched with a +/// request. + +/// @section agentparams Agent Parameters +/// Foo behavior is comprehensively defined by the following +/// parameters: +/// - double capacity: The production capacity of the facility (units +/// vary, but typically kg/month). Capacity is infinite if a negative +/// value is provided. +/// - int startDate: The date on which the facility begins to operate +/// (months). +/// - int lifeTime: The length of time that the facility operates +/// (months). - std::string outCommod: the commodity that this facility +/// produces - double inventorysize: the maximum quantity of material to +/// be held in the inventory +/// - double commodprice: the price of the output material PER UNIT +/// - map outComp + +/// @section optionalparams Optional Parameters +/// Foo behavior may also be specified with the following +/// optional parameters which have default values listed here. +/// - double capacityFactor: The ratio of actual production capacity to +/// the rated production capacity. Default is 1 (actual/rated). +/// - double availFactor: The percent of time the facility operates at +/// its capacity factor. Default is 100%. +/// - double capitalCost: The cost of constructing and commissioning +/// this facility. Default is 0 ($). +/// - double opCost: The annual cost of operation and maintenance of +/// this facility. Default is 0 ( $/year). +/// - int constrTime: The number of months it takes to construct and +/// commission this facility. Default is 0 (months). +/// - int decomTime: The number of months it takes to deconstruct and +/// decommission this facility. Default is 0 (months). +/// - Inst* inst: The institution responsible for this facility. +/// - string name: A non-generic name for this facility. + +/// @section detailed Detailed Behavior +/// @subsection finite If Finite Capacity: +/// The Foo starts operation when the simulation reaches the +/// month specified as the startDate. It immediately begins to produce +/// material at the rate defined by its capacity. Each month the +/// Foo adds the amount it has produced to its inventory. It +/// then offers to the appropriate market exactly as much material as it +/// has in its inventory. If an offer is matched with a request, the +/// Foo executes that order by subtracting the quantity from +/// its inventory and sending that amount to the requesting facility. +/// When the simulation time equals the startDate plus the lifeTime, the +/// facility ceases to operate. +/// @subsection infinite If Infinite Capacity: +/// The Foo starts operation when the simulation reaches the +/// month specified as the startDate. Each month the Foo +/// offers an infinite amount of material to the appropriate market. If +/// there is a request for that material, the Foo executes +/// that order by sending that amount to the requesting facility. When +/// the simulation time equals the startDate plus the lifeTime, the +/// facility ceases to operate. + +/// @subsection question Question: +/// What is the best way to allow offers of an infinite amount of +/// material on a market? + +class Foo : public cyclus::Facility, + public cyclus::toolkit::CommodityProducer { + public: + // --- Module Members --- + /// Constructor for the Foo class + /// @param ctx the cyclus context for access to simulation-wide parameters + Foo(cyclus::Context* ctx); + + virtual ~Foo() + + #pragma cyclus decl + + #pragma cyclus note {"doc": "A source facility that provides a " \ + "commodity with a given capacity"} + + /// Print information about this agent + virtual std::string str(); + // --- + + // --- Agent Members --- + virtual void EnterNotify(); + + /// Each facility is prompted to do its beginning-of-time-step + /// stuff at the tick of the timer. + + /// @param time is the time to perform the tick + virtual void Tick(); + + /// Each facility is prompted to its end-of-time-step + /// stuff on the tock of the timer. + + /// @param time is the time to perform the tock + virtual void Tock(); + + /// @brief Responds to each request for this source facility's commodity. + /// If a given request is more than this facility's capacity, it will offer + /// its capacity. + virtual std::set::Ptr> + GetMatlBids(cyclus::CommodMap::type& + commod_requests); + + /// @brief respond to each trade with a material made from this facility's + /// recipe + /// + /// @param trades all trades in which this trader is the supplier + /// @param responses a container to populate with responses to each trade + virtual void GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses); + // --- + + // --- Foo Members --- + /// @brief creates a material object to offer to a requester + /// @param target the material target a request desires + cyclus::Material::Ptr GetOffer(const cyclus::Material::Ptr target) const; + + /// sets the output commodity name + /// @param name the commodity name + inline void commodity(std::string name) { out_commod = name; } + + /// @return the output commodity + inline std::string commodity() const { return out_commod; } + + /// sets the capacity of a material generated at any given time step + /// @param capacity the production capacity + inline void Capacity(double cap) { + capacity = cap; + current_capacity = capacity; + } + + /// @return the production capacity at any given time step + inline double Capacity() const { return capacity; } + + /// sets the name of the recipe to be produced + /// @param name the recipe name + inline void recipe(std::string name) { recipe_name = name; } + + /// @return the name of the output recipe + inline std::string recipe() const { return recipe_name; } + + /// @return the current timestep's capacity + inline double CurrentCapacity() const { return current_capacity; } + + private: + cyclus::toolkit::Commodity commod_; + + /// This facility has only one output commodity + #pragma cyclus var {"tooltip": "source output commodity", \ + "doc": "output commodity that the source facility " \ + "supplies", \ + "uitype": "outcommodity"} + std::string out_commod; + + /// Name of the recipe this facility uses. + #pragma cyclus var {"tooltip": "commodity recipe name", \ + "doc": "recipe name for source facility's commodity", \ + "uitype": "recipe"} + std::string recipe_name; + + /// The capacity is defined in terms of the number of units of the + /// recipe that can be provided each time step. A very large number + /// can be provided to represent infinte capacity. + #pragma cyclus var {"default": 1e299, "tooltip": "source capacity", \ + "doc": "amount of commodity that can be supplied " \ + "at each time step"} + double capacity; + + /// The capacity at the current time step + #pragma cyclus var {'derived_init': 'current_capacity = capacity;'} + double current_capacity; + + // --- +}; + +} // namespace cycamore + +#endif // CYCAMORE_SRC_FOO_H_ diff --git a/src/foo_tests.cc b/src/foo_tests.cc new file mode 100644 index 0000000000..0973e794d0 --- /dev/null +++ b/src/foo_tests.cc @@ -0,0 +1,204 @@ +#include "foo_tests.h" + +#include + +#include + +#include "cyc_limits.h" +#include "resource_helpers.h" +#include "test_context.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::SetUp() { + src_facility = new cycamore::Foo(tc.get()); + trader = tc.trader(); + InitParameters(); + SetUpFoo(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::TearDown() { + delete src_facility; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::InitParameters() { + commod = "commod"; + recipe_name = "recipe"; + capacity = 5; // some magic number.. + + recipe = cyclus::Composition::CreateFromAtom(cyclus::CompMap()); + tc.get()->AddRecipe(recipe_name, recipe); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::SetUpFoo() { + src_facility->commodity(commod); + src_facility->recipe(recipe_name); + src_facility->Capacity(capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, InitialState) { + EXPECT_EQ(src_facility->Capacity(), capacity); + EXPECT_EQ(src_facility->commodity(), commod); + EXPECT_EQ(src_facility->recipe(), recipe_name); + EXPECT_EQ(src_facility->CurrentCapacity(), capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Clone) { + cyclus::Context* ctx = tc.get(); + cycamore::Foo* cloned_fac = dynamic_cast + (src_facility->Clone()); + + EXPECT_EQ(src_facility->commodity(), cloned_fac->commodity()); + EXPECT_EQ(src_facility->Capacity(), cloned_fac->Capacity()); + EXPECT_EQ(src_facility->recipe(), cloned_fac->recipe()); + EXPECT_EQ(src_facility->Capacity(), cloned_fac->CurrentCapacity()); + + delete cloned_fac; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Print) { + EXPECT_NO_THROW(std::string s = src_facility->str()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, GetOffer) { + using cyclus::Material; + + double qty = capacity - 1; + Material::Ptr mat = cyclus::NewBlankMaterial(qty); + Material::Ptr obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), qty); + EXPECT_EQ(obs_mat->comp(), recipe); + + qty = capacity + 1; + mat = cyclus::NewBlankMaterial(qty); + obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), capacity); + EXPECT_EQ(obs_mat->comp(), recipe); + + qty = capacity; + mat = cyclus::NewBlankMaterial(qty); + obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), capacity); + EXPECT_EQ(obs_mat->comp(), recipe); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, AddBids) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::ExchangeContext; + using cyclus::Material; + + int nreqs = 5; + + boost::shared_ptr< cyclus::ExchangeContext > + ec = GetContext(nreqs, commod); + + std::set::Ptr> ports = + src_facility->GetMatlBids(ec.get()->commod_requests); + + ASSERT_TRUE(ports.size() > 0); + EXPECT_EQ(ports.size(), 1); + + BidPortfolio::Ptr port = *ports.begin(); + EXPECT_EQ(port->bidder(), src_facility); + EXPECT_EQ(port->bids().size(), nreqs); + + const std::set< CapacityConstraint >& constrs = port->constraints(); + ASSERT_TRUE(constrs.size() > 0); + EXPECT_EQ(constrs.size(), 1); + EXPECT_EQ(*constrs.begin(), CapacityConstraint(capacity)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Response) { + using cyclus::Bid; + using cyclus::Material; + using cyclus::Request; + using cyclus::Trade; + using test_helpers::get_mat; + + std::vector< cyclus::Trade > trades; + std::vector, + cyclus::Material::Ptr> > responses; + + // Null response + EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); + EXPECT_EQ(responses.size(), 0); + + double qty = capacity / 3; + Request* request = + Request::Create(get_mat(), trader, commod); + Bid* bid = + Bid::Create(request, get_mat(), src_facility); + + Trade trade(request, bid, qty); + trades.push_back(trade); + + // 1 trade + ASSERT_EQ(src_facility->CurrentCapacity(), capacity); + src_facility->GetMatlTrades(trades, responses); + EXPECT_EQ(responses.size(), 1); + EXPECT_EQ(responses[0].second->quantity(), qty); + EXPECT_EQ(responses[0].second->comp(), recipe); + + // 2 trades, total qty = capacity + ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity - qty); + ASSERT_GT(src_facility->CurrentCapacity() - 2 * qty, -1 * cyclus::eps()); + trades.push_back(trade); + responses.clear(); + EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); + EXPECT_EQ(responses.size(), 2); + ASSERT_TRUE(cyclus::AlmostEq(src_facility->CurrentCapacity(), 0)); + + // too much qty, capn! + EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), + cyclus::ValueError); + + // reset! + src_facility->Tick(); + ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity); + + delete request; + delete bid; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +boost::shared_ptr< cyclus::ExchangeContext > +FooTest::GetContext(int nreqs, std::string commod) { + using cyclus::Material; + using cyclus::Request; + using cyclus::ExchangeContext; + using test_helpers::get_mat; + + double qty = 3; + boost::shared_ptr< ExchangeContext > + ec(new ExchangeContext()); + for (int i = 0; i < nreqs; i++) { + ec->AddRequest(Request::Create(get_mat(), trader, commod)); + } + return ec; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Agent* FooConstructor(cyclus::Context* ctx) { + return new cycamore::Foo(ctx); +} + +// required to get functionality in cyclus agent unit tests library +#ifndef CYCLUS_AGENT_TESTS_CONNECTED +int ConnectAgentTests(); +static int cyclus_agent_tests_connected = ConnectAgentTests(); +#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected +#endif // CYCLUS_AGENT_TESTS_CONNECTED + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +INSTANTIATE_TEST_CASE_P(FooFac, FacilityTests, Values(&FooConstructor)); +INSTANTIATE_TEST_CASE_P(FooFac, AgentTests, Values(&FooConstructor)); diff --git a/src/foo_tests.h b/src/foo_tests.h new file mode 100644 index 0000000000..59888926b7 --- /dev/null +++ b/src/foo_tests.h @@ -0,0 +1,34 @@ +#ifndef CYCAMORE_SRC_FOO_TESTS_H_ +#define CYCAMORE_SRC_FOO_TESTS_H_ +#include "foo.h" + +#include + +#include + +#include "agent_tests.h" +#include "context.h" +#include "exchange_context.h" +#include "facility_tests.h" +#include "material.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +class FooTest : public ::testing::Test { + public: + cyclus::TestContext tc; + TestFacility* trader; + cycamore::Foo* src_facility; + std::string commod, recipe_name; + double capacity; + cyclus::Composition::Ptr recipe; + + virtual void SetUp(); + virtual void TearDown(); + void InitParameters(); + void SetUpFoo(); + + boost::shared_ptr< cyclus::ExchangeContext > + GetContext(int nreqs, std::string commodity); +}; + +#endif // CYCAMORE_SRC_FOO_TESTS_H_ From 44a88042f3eeb9c10bef3409caa3313ac4b21b89 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 14:53:53 -0500 Subject: [PATCH 184/314] Revert "adding failure with an explicit check" This reverts commit d7c653699506e3aa4229840db5b97f24bc73d4f4. --- .travis-install.sh | 2 - src/CMakeLists.txt | 2 - src/foo.cc | 171 ------------------------------------- src/foo.h | 204 --------------------------------------------- src/foo_tests.cc | 204 --------------------------------------------- src/foo_tests.h | 34 -------- 6 files changed, 617 deletions(-) delete mode 100644 src/foo.cc delete mode 100644 src/foo.h delete mode 100644 src/foo_tests.cc delete mode 100644 src/foo_tests.h diff --git a/.travis-install.sh b/.travis-install.sh index 08a02557a1..1f9e8a8e15 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -10,8 +10,6 @@ unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml # build -"src/CMakeLists.txt:" -cat src/CMakeLists.txt cmd="conda build --no-test conda-recipe" echo "cmd: $cmd" $cmd diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0f0ef9eea2..5701534c73 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,8 +10,6 @@ USE_CYCLUS("cycamore" "sink") USE_CYCLUS("cycamore" "source") -USE_CYCLUS("cycamore" "foo") - USE_CYCLUS("cycamore" "deploy_inst") USE_CYCLUS("cycamore" "manager_inst") diff --git a/src/foo.cc b/src/foo.cc deleted file mode 100644 index 9ad8ada201..0000000000 --- a/src/foo.cc +++ /dev/null @@ -1,171 +0,0 @@ -#include "foo.h" - -#include -#include - -#include - -namespace cycamore { - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Foo::Foo(cyclus::Context* ctx) - : cyclus::Facility(ctx), - out_commod(""), - recipe_name(""), - capacity(std::numeric_limits::max()) {} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Foo::~Foo() {} - -#pragma cyclus def clone cycamore::Foo - -#pragma cyclus def schema cycamore::Foo - -#pragma cyclus def annotations cycamore::Foo - -#pragma cyclus def infiletodb cycamore::Foo - -#pragma cyclus def snapshot cycamore::Foo - -#pragma cyclus def snapshotinv cycamore::Foo - -#pragma cyclus def initinv cycamore::Foo - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::InitFrom(Foo* m) { - #pragma cyclus impl initfromcopy cycamore::Foo - cyclus::toolkit::CommodityProducer::Copy(m); -} - -void Foo::InitFrom(cyclus::QueryableBackend* b) { - #pragma cyclus impl initfromdb cycamore::Foo - - commod_ = cyclus::toolkit::Commodity(out_commod); - cyclus::toolkit::CommodityProducer::Add(commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); - cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); -} - -void Foo::EnterNotify() { - Facility::EnterNotify(); - commod_ = cyclus::toolkit::Commodity(out_commod); - cyclus::toolkit::CommodityProducer::Add(commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); - cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::string Foo::str() { - std::stringstream ss; - std::string ans; - if (cyclus::toolkit::CommodityProducer:: - Produces(cyclus::toolkit::Commodity(out_commod))) { - ans = "yes"; - } else { - ans = "no"; - } - ss << cyclus::Facility::str() - << " supplies commodity '" - << out_commod << "' with recipe '" - << recipe_name << "' at a capacity of " - << capacity << " kg per time step " - << " commod producer members: " << " produces " - << out_commod << "?: " << ans - << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(commod_) - << " cost: " << cyclus::toolkit::CommodityProducer::Cost(commod_); - return ss.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::Tick() { - LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is ticking {"; - LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity - << " kg of " - << out_commod << "."; - LOG(cyclus::LEV_INFO3, "SrcFac") << "Stats: " << str(); - LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; - current_capacity = capacity; // reset capacity -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::Tock() { - LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is tocking {"; - LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr Foo::GetOffer( - const cyclus::Material::Ptr target) const { - using cyclus::Material; - double qty = std::min(target->quantity(), capacity); - return Material::CreateUntracked(qty, context()->GetRecipe(recipe_name)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -Foo::GetMatlBids( - cyclus::CommodMap::type& commod_requests) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::Material; - using cyclus::Request; - - std::set::Ptr> ports; - - if (commod_requests.count(out_commod) > 0) { - BidPortfolio::Ptr port(new BidPortfolio()); - - std::vector*>& requests = - commod_requests[out_commod]; - - std::vector*>::iterator it; - for (it = requests.begin(); it != requests.end(); ++it) { - Request* req = *it; - Material::Ptr offer = GetOffer(req->target()); - port->AddBid(req, offer, this); - } - - CapacityConstraint cc(capacity); - port->AddConstraint(cc); - ports.insert(port); - } - return ports; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses) { - using cyclus::Material; - using cyclus::Trade; - - double provided = 0; - std::vector< cyclus::Trade >::const_iterator it; - for (it = trades.begin(); it != trades.end(); ++it) { - double qty = it->amt; - current_capacity -= qty; - provided += qty; - // @TODO we need a policy on negatives.. - Material::Ptr response = Material::Create(this, qty, - context()->GetRecipe(recipe_name)); - responses.push_back(std::make_pair(*it, response)); - LOG(cyclus::LEV_INFO5, "SrcFac") << prototype() << " just received an order" - << " for " << qty - << " of " << out_commod; - } - if (cyclus::IsNegative(current_capacity)) { - std::stringstream ss; - ss << "is being asked to provide " << provided - << " but its capacity is " << capacity << "."; - throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern "C" cyclus::Agent* ConstructFoo(cyclus::Context* ctx) { - return new Foo(ctx); -} - -} // namespace cycamore diff --git a/src/foo.h b/src/foo.h deleted file mode 100644 index e35ab83d99..0000000000 --- a/src/foo.h +++ /dev/null @@ -1,204 +0,0 @@ -#ifndef CYCAMORE_SRC_FOO_H_ -#define CYCAMORE_SRC_FOO_H_ - -#include -#include - -#include "cyclus.h" - -namespace cycamore { - -class Context; - -/// @class Foo -/// This cyclus::Facility provides a simple source of some capacity -/// (possibly infinite) of some commodity/Recipe. - -/// The Foo class inherits from the cyclus::Facility class and is -/// dynamically loaded by the Agent class when requested. - -/// @section introduction Introduction -/// The Foo is a facility type in Cyclus capable of providing -/// a finite or infinite.Supply of a particular material to the -/// simulation. A Foo generates material of a certain -/// composition and commodity type, then offers that material on the -/// appropriate market. Shipments of this material are executed when the -/// market issues an order that the offer has been matched with a -/// request. - -/// @section agentparams Agent Parameters -/// Foo behavior is comprehensively defined by the following -/// parameters: -/// - double capacity: The production capacity of the facility (units -/// vary, but typically kg/month). Capacity is infinite if a negative -/// value is provided. -/// - int startDate: The date on which the facility begins to operate -/// (months). -/// - int lifeTime: The length of time that the facility operates -/// (months). - std::string outCommod: the commodity that this facility -/// produces - double inventorysize: the maximum quantity of material to -/// be held in the inventory -/// - double commodprice: the price of the output material PER UNIT -/// - map outComp - -/// @section optionalparams Optional Parameters -/// Foo behavior may also be specified with the following -/// optional parameters which have default values listed here. -/// - double capacityFactor: The ratio of actual production capacity to -/// the rated production capacity. Default is 1 (actual/rated). -/// - double availFactor: The percent of time the facility operates at -/// its capacity factor. Default is 100%. -/// - double capitalCost: The cost of constructing and commissioning -/// this facility. Default is 0 ($). -/// - double opCost: The annual cost of operation and maintenance of -/// this facility. Default is 0 ( $/year). -/// - int constrTime: The number of months it takes to construct and -/// commission this facility. Default is 0 (months). -/// - int decomTime: The number of months it takes to deconstruct and -/// decommission this facility. Default is 0 (months). -/// - Inst* inst: The institution responsible for this facility. -/// - string name: A non-generic name for this facility. - -/// @section detailed Detailed Behavior -/// @subsection finite If Finite Capacity: -/// The Foo starts operation when the simulation reaches the -/// month specified as the startDate. It immediately begins to produce -/// material at the rate defined by its capacity. Each month the -/// Foo adds the amount it has produced to its inventory. It -/// then offers to the appropriate market exactly as much material as it -/// has in its inventory. If an offer is matched with a request, the -/// Foo executes that order by subtracting the quantity from -/// its inventory and sending that amount to the requesting facility. -/// When the simulation time equals the startDate plus the lifeTime, the -/// facility ceases to operate. -/// @subsection infinite If Infinite Capacity: -/// The Foo starts operation when the simulation reaches the -/// month specified as the startDate. Each month the Foo -/// offers an infinite amount of material to the appropriate market. If -/// there is a request for that material, the Foo executes -/// that order by sending that amount to the requesting facility. When -/// the simulation time equals the startDate plus the lifeTime, the -/// facility ceases to operate. - -/// @subsection question Question: -/// What is the best way to allow offers of an infinite amount of -/// material on a market? - -class Foo : public cyclus::Facility, - public cyclus::toolkit::CommodityProducer { - public: - // --- Module Members --- - /// Constructor for the Foo class - /// @param ctx the cyclus context for access to simulation-wide parameters - Foo(cyclus::Context* ctx); - - virtual ~Foo() - - #pragma cyclus decl - - #pragma cyclus note {"doc": "A source facility that provides a " \ - "commodity with a given capacity"} - - /// Print information about this agent - virtual std::string str(); - // --- - - // --- Agent Members --- - virtual void EnterNotify(); - - /// Each facility is prompted to do its beginning-of-time-step - /// stuff at the tick of the timer. - - /// @param time is the time to perform the tick - virtual void Tick(); - - /// Each facility is prompted to its end-of-time-step - /// stuff on the tock of the timer. - - /// @param time is the time to perform the tock - virtual void Tock(); - - /// @brief Responds to each request for this source facility's commodity. - /// If a given request is more than this facility's capacity, it will offer - /// its capacity. - virtual std::set::Ptr> - GetMatlBids(cyclus::CommodMap::type& - commod_requests); - - /// @brief respond to each trade with a material made from this facility's - /// recipe - /// - /// @param trades all trades in which this trader is the supplier - /// @param responses a container to populate with responses to each trade - virtual void GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses); - // --- - - // --- Foo Members --- - /// @brief creates a material object to offer to a requester - /// @param target the material target a request desires - cyclus::Material::Ptr GetOffer(const cyclus::Material::Ptr target) const; - - /// sets the output commodity name - /// @param name the commodity name - inline void commodity(std::string name) { out_commod = name; } - - /// @return the output commodity - inline std::string commodity() const { return out_commod; } - - /// sets the capacity of a material generated at any given time step - /// @param capacity the production capacity - inline void Capacity(double cap) { - capacity = cap; - current_capacity = capacity; - } - - /// @return the production capacity at any given time step - inline double Capacity() const { return capacity; } - - /// sets the name of the recipe to be produced - /// @param name the recipe name - inline void recipe(std::string name) { recipe_name = name; } - - /// @return the name of the output recipe - inline std::string recipe() const { return recipe_name; } - - /// @return the current timestep's capacity - inline double CurrentCapacity() const { return current_capacity; } - - private: - cyclus::toolkit::Commodity commod_; - - /// This facility has only one output commodity - #pragma cyclus var {"tooltip": "source output commodity", \ - "doc": "output commodity that the source facility " \ - "supplies", \ - "uitype": "outcommodity"} - std::string out_commod; - - /// Name of the recipe this facility uses. - #pragma cyclus var {"tooltip": "commodity recipe name", \ - "doc": "recipe name for source facility's commodity", \ - "uitype": "recipe"} - std::string recipe_name; - - /// The capacity is defined in terms of the number of units of the - /// recipe that can be provided each time step. A very large number - /// can be provided to represent infinte capacity. - #pragma cyclus var {"default": 1e299, "tooltip": "source capacity", \ - "doc": "amount of commodity that can be supplied " \ - "at each time step"} - double capacity; - - /// The capacity at the current time step - #pragma cyclus var {'derived_init': 'current_capacity = capacity;'} - double current_capacity; - - // --- -}; - -} // namespace cycamore - -#endif // CYCAMORE_SRC_FOO_H_ diff --git a/src/foo_tests.cc b/src/foo_tests.cc deleted file mode 100644 index 0973e794d0..0000000000 --- a/src/foo_tests.cc +++ /dev/null @@ -1,204 +0,0 @@ -#include "foo_tests.h" - -#include - -#include - -#include "cyc_limits.h" -#include "resource_helpers.h" -#include "test_context.h" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::SetUp() { - src_facility = new cycamore::Foo(tc.get()); - trader = tc.trader(); - InitParameters(); - SetUpFoo(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::TearDown() { - delete src_facility; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::InitParameters() { - commod = "commod"; - recipe_name = "recipe"; - capacity = 5; // some magic number.. - - recipe = cyclus::Composition::CreateFromAtom(cyclus::CompMap()); - tc.get()->AddRecipe(recipe_name, recipe); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::SetUpFoo() { - src_facility->commodity(commod); - src_facility->recipe(recipe_name); - src_facility->Capacity(capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, InitialState) { - EXPECT_EQ(src_facility->Capacity(), capacity); - EXPECT_EQ(src_facility->commodity(), commod); - EXPECT_EQ(src_facility->recipe(), recipe_name); - EXPECT_EQ(src_facility->CurrentCapacity(), capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Clone) { - cyclus::Context* ctx = tc.get(); - cycamore::Foo* cloned_fac = dynamic_cast - (src_facility->Clone()); - - EXPECT_EQ(src_facility->commodity(), cloned_fac->commodity()); - EXPECT_EQ(src_facility->Capacity(), cloned_fac->Capacity()); - EXPECT_EQ(src_facility->recipe(), cloned_fac->recipe()); - EXPECT_EQ(src_facility->Capacity(), cloned_fac->CurrentCapacity()); - - delete cloned_fac; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Print) { - EXPECT_NO_THROW(std::string s = src_facility->str()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, GetOffer) { - using cyclus::Material; - - double qty = capacity - 1; - Material::Ptr mat = cyclus::NewBlankMaterial(qty); - Material::Ptr obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), qty); - EXPECT_EQ(obs_mat->comp(), recipe); - - qty = capacity + 1; - mat = cyclus::NewBlankMaterial(qty); - obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), capacity); - EXPECT_EQ(obs_mat->comp(), recipe); - - qty = capacity; - mat = cyclus::NewBlankMaterial(qty); - obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), capacity); - EXPECT_EQ(obs_mat->comp(), recipe); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, AddBids) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::ExchangeContext; - using cyclus::Material; - - int nreqs = 5; - - boost::shared_ptr< cyclus::ExchangeContext > - ec = GetContext(nreqs, commod); - - std::set::Ptr> ports = - src_facility->GetMatlBids(ec.get()->commod_requests); - - ASSERT_TRUE(ports.size() > 0); - EXPECT_EQ(ports.size(), 1); - - BidPortfolio::Ptr port = *ports.begin(); - EXPECT_EQ(port->bidder(), src_facility); - EXPECT_EQ(port->bids().size(), nreqs); - - const std::set< CapacityConstraint >& constrs = port->constraints(); - ASSERT_TRUE(constrs.size() > 0); - EXPECT_EQ(constrs.size(), 1); - EXPECT_EQ(*constrs.begin(), CapacityConstraint(capacity)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Response) { - using cyclus::Bid; - using cyclus::Material; - using cyclus::Request; - using cyclus::Trade; - using test_helpers::get_mat; - - std::vector< cyclus::Trade > trades; - std::vector, - cyclus::Material::Ptr> > responses; - - // Null response - EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); - EXPECT_EQ(responses.size(), 0); - - double qty = capacity / 3; - Request* request = - Request::Create(get_mat(), trader, commod); - Bid* bid = - Bid::Create(request, get_mat(), src_facility); - - Trade trade(request, bid, qty); - trades.push_back(trade); - - // 1 trade - ASSERT_EQ(src_facility->CurrentCapacity(), capacity); - src_facility->GetMatlTrades(trades, responses); - EXPECT_EQ(responses.size(), 1); - EXPECT_EQ(responses[0].second->quantity(), qty); - EXPECT_EQ(responses[0].second->comp(), recipe); - - // 2 trades, total qty = capacity - ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity - qty); - ASSERT_GT(src_facility->CurrentCapacity() - 2 * qty, -1 * cyclus::eps()); - trades.push_back(trade); - responses.clear(); - EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); - EXPECT_EQ(responses.size(), 2); - ASSERT_TRUE(cyclus::AlmostEq(src_facility->CurrentCapacity(), 0)); - - // too much qty, capn! - EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), - cyclus::ValueError); - - // reset! - src_facility->Tick(); - ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity); - - delete request; - delete bid; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -boost::shared_ptr< cyclus::ExchangeContext > -FooTest::GetContext(int nreqs, std::string commod) { - using cyclus::Material; - using cyclus::Request; - using cyclus::ExchangeContext; - using test_helpers::get_mat; - - double qty = 3; - boost::shared_ptr< ExchangeContext > - ec(new ExchangeContext()); - for (int i = 0; i < nreqs; i++) { - ec->AddRequest(Request::Create(get_mat(), trader, commod)); - } - return ec; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Agent* FooConstructor(cyclus::Context* ctx) { - return new cycamore::Foo(ctx); -} - -// required to get functionality in cyclus agent unit tests library -#ifndef CYCLUS_AGENT_TESTS_CONNECTED -int ConnectAgentTests(); -static int cyclus_agent_tests_connected = ConnectAgentTests(); -#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected -#endif // CYCLUS_AGENT_TESTS_CONNECTED - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -INSTANTIATE_TEST_CASE_P(FooFac, FacilityTests, Values(&FooConstructor)); -INSTANTIATE_TEST_CASE_P(FooFac, AgentTests, Values(&FooConstructor)); diff --git a/src/foo_tests.h b/src/foo_tests.h deleted file mode 100644 index 59888926b7..0000000000 --- a/src/foo_tests.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef CYCAMORE_SRC_FOO_TESTS_H_ -#define CYCAMORE_SRC_FOO_TESTS_H_ -#include "foo.h" - -#include - -#include - -#include "agent_tests.h" -#include "context.h" -#include "exchange_context.h" -#include "facility_tests.h" -#include "material.h" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -class FooTest : public ::testing::Test { - public: - cyclus::TestContext tc; - TestFacility* trader; - cycamore::Foo* src_facility; - std::string commod, recipe_name; - double capacity; - cyclus::Composition::Ptr recipe; - - virtual void SetUp(); - virtual void TearDown(); - void InitParameters(); - void SetUpFoo(); - - boost::shared_ptr< cyclus::ExchangeContext > - GetContext(int nreqs, std::string commodity); -}; - -#endif // CYCAMORE_SRC_FOO_TESTS_H_ From 8e904cdf8ddedbb16a18f6aa6487df6e33734ee7 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 14:55:17 -0500 Subject: [PATCH 185/314] this should fail unit tests --- src/source_tests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source_tests.cc b/src/source_tests.cc index eea1d9c38d..556623a82f 100644 --- a/src/source_tests.cc +++ b/src/source_tests.cc @@ -107,7 +107,7 @@ TEST_F(SourceTest, Response) { // 1 trade src_facility->GetMatlTrades(trades, responses); EXPECT_EQ(responses.size(), 1); - EXPECT_EQ(responses[0].second->quantity(), qty); + EXPECT_EQ(responses[0].second->quantity(), qty + 1); EXPECT_EQ(responses[0].second->comp(), recipe); // 2 trades, total qty = capacity From 4139b4e0aa9eae39f63d85751b70f4502d6d96de Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 25 Mar 2015 12:15:39 -0500 Subject: [PATCH 186/314] skeleton of separations facility --- src/CMakeLists.txt | 2 + src/separations.cc | 198 +++++++++++++++++++++++++++++++++++++++++++++ src/separations.h | 82 +++++++++++++++++++ 3 files changed, 282 insertions(+) create mode 100644 src/separations.cc create mode 100644 src/separations.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5701534c73..6a29fcff22 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,8 @@ USE_CYCLUS("cycamore" "fuel_fab") USE_CYCLUS("cycamore" "enrichment_facility") +USE_CYCLUS("cycamore" "separations") + USE_CYCLUS("cycamore" "sink") USE_CYCLUS("cycamore" "source") diff --git a/src/separations.cc b/src/separations.cc new file mode 100644 index 0000000000..dc013e9bb2 --- /dev/null +++ b/src/separations.cc @@ -0,0 +1,198 @@ +#include "separations.h" + +using cyclus::Material; +using cyclus::Composition; +using cyclus::toolkit::ResBuf; +using cyclus::toolkit::MatVec; +using cyclus::KeyError; +using cyclus::ValueError; +using cyclus::Request; + +namespace cycamore { + +Separations::Separations(cyclus::Context* ctx) + : cyclus::Facility(ctx) { + cyclus::Warn("the Separations archetype " + "is experimental"); +} + +cyclus::Inventories Separations::SnapshotInv() { + cyclus::Inventories invs; + + invs["leftover"] = leftover.PopNRes(leftover.count()); + leftover.Push(invs["leftover"]); + invs["feed"] = feed.PopNRes(feed.count()); + feed.Push(invs["feed"]); + + std::map >::iterator it; + for (it = streambufs.begin(); it != streambufs.end(); ++it) { + invs[it->first] = it->second.PopNRes(it->second.count()); + it->second.Push(invs[it->first]); + } + + return invs; +} +void Separations::InitInv(cyclus::Inventories& inv) { + leftover.Push(inv["leftover"]); + feed.Push(inv["feed"]); + + cyclus::Inventories::iterator it; + for (it = inv.begin(); it != inv.end(); ++it) { + streambufs[it->first].Push(it->second); + } +} + +typedef std::map > > StreamSet; +typedef std::pair > Stream; + +void Separations::EnterNotify() { + cyclus::Facility::EnterNotify(); + StreamSet::iterator it; + for (it = streams_.begin(); it != streams_.end(); ++it) { + std::string name = it->first; + Stream stream = it->second; + double cap = stream.first; + if (cap >= 0) { + streambufs[name].capacity(cap); + } + } +} + +void Separations::Tick() { +} + +std::set::Ptr> +Separations::GetMatlRequests() { + //using cyclus::RequestPortfolio; + + //std::set::Ptr> ports; + //Material::Ptr m; + + //int n_assem_order = n_assem_core - core.count() + // + n_assem_fresh - fresh.count(); + //if (n_assem_order == 0) { + // return ports; + //} + + //for (int i = 0; i < n_assem_order; i++) { + // RequestPortfolio::Ptr port(new RequestPortfolio()); + // std::vector*> mreqs; + // for (int j = 0; j < fuel_incommods.size(); j++) { + // std::string commod = fuel_incommods[j]; + // double pref = fuel_prefs[j]; + // Composition::Ptr recipe = context()->GetRecipe(fuel_inrecipes[j]); + // m = Material::CreateUntracked(assem_size, recipe); + // Request* r = port->AddRequest(m, this, commod, pref, true); + // mreqs.push_back(r); + // } + // port->AddMutualReqs(mreqs); + // ports.insert(port); + //} + + //return ports; +} + +void Separations::GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + Material::Ptr> >& responses) { + //using cyclus::Trade; + + //std::map mats = PopSpent(); + //std::vector< cyclus::Trade >::const_iterator it; + //for (int i = 0; i < trades.size(); i++) { + // std::string commod = trades[i].request->commodity(); + // Material::Ptr m = mats[commod].back(); + // mats[commod].pop_back(); + // responses.push_back(std::make_pair(trades[i], m)); + // res_indexes.erase(m->obj_id()); + //} + //PushSpent(mats); // return leftovers back to spent buffer +} + +void Separations::AcceptMatlTrades( + const std::vector< std::pair, + Material::Ptr> >& responses) { + + //std::vector< std::pair, + // cyclus::Material::Ptr> >::const_iterator trade; + + //std::stringstream ss; + //int nload = std::min((int)responses.size(), n_assem_core - core.count()); + //if (nload > 0) { + // ss << nload << " assemblies"; + // Record("LOAD", ss.str()); + //} + + //for (trade = responses.begin(); trade != responses.end(); ++trade) { + // std::string commod = trade->first.request->commodity(); + // Material::Ptr m = trade->second; + // index_res(m, commod); + + // if (core.count() < n_assem_core) { + // core.Push(m); + // } else { + // fresh.Push(m); + // } + //} +} + +std::set::Ptr> +Separations::GetMatlBids(cyclus::CommodMap::type& + commod_requests) { + //using cyclus::BidPortfolio; + + //std::set::Ptr> ports; + + //bool gotmats = false; + //std::map all_mats; + //for (int i = 0; i < fuel_outcommods.size(); i++) { + // std::string commod = fuel_outcommods[i]; + // std::vector*>& reqs = commod_requests[commod]; + // if (reqs.size() == 0) { + // continue; + // } else if (!gotmats) { + // all_mats = PeekSpent(); + // } + + // MatVec mats = all_mats[commod]; + // if (mats.size() == 0) { + // continue; + // } + + // BidPortfolio::Ptr port(new BidPortfolio()); + + // for (int j = 0; j < reqs.size(); j++) { + // Request* req = reqs[j]; + // double tot_bid = 0; + // for (int k = 0; k < mats.size(); k++) { + // Material::Ptr m = mats[k]; + // tot_bid += m->quantity(); + // port->AddBid(req, m, this, true); + // if (tot_bid >= req->target()->quantity()) { + // break; + // } + // } + // } + + // double tot_qty = 0; + // for (int j = 0; j < mats.size(); j++) { + // tot_qty += mats[j]->quantity(); + // } + // cyclus::CapacityConstraint cc(tot_qty); + // port->AddConstraint(cc); + // ports.insert(port); + //} + + //return ports; +} + +void Separations::Tock() { +} + +extern "C" cyclus::Agent* ConstructSeparations(cyclus::Context* ctx) { + return new Separations(ctx); +} + +} // namespace cycamore + diff --git a/src/separations.h b/src/separations.h new file mode 100644 index 0000000000..772399f4f0 --- /dev/null +++ b/src/separations.h @@ -0,0 +1,82 @@ +#ifndef CYCAMORE_SRC_SEPARATIONS_H_ +#define CYCAMORE_SRC_SEPARATIONS_H_ + +#include "cyclus.h" + +namespace cycamore { + +class Separations : public cyclus::Facility { + public: + Separations(cyclus::Context* ctx); + virtual ~Separations(){}; + + virtual void Tick(); + virtual void Tock(); + virtual void EnterNotify(); + + virtual void AcceptMatlTrades(const std::vector, cyclus::Material::Ptr> >& responses); + + virtual std::set::Ptr> + GetMatlRequests(); + + virtual std::set::Ptr> GetMatlBids( + cyclus::CommodMap::type& commod_requests); + + virtual void GetMatlTrades( + const std::vector >& trades, + std::vector, + cyclus::Material::Ptr> >& responses); + + #pragma cyclus clone + #pragma cyclus initfromcopy + #pragma cyclus infiletodb + #pragma cyclus initfromdb + #pragma cyclus schema + #pragma cyclus annotations + #pragma cyclus snapshot + + virtual cyclus::Inventories SnapshotInv(); + virtual void InitInv(cyclus::Inventories& inv); + + // the following pragmas are ommitted and generated manually to handle a + // vector of resource buffers: + // #pragma cyclus snapshotinv + // #pragma cyclus initinv + + private: + #pragma cyclus var { \ + "alias": ["streams", "name", ["info", "cap", ["efficiencies", "comp", "eff"]]], \ + "uitype": ["oneormore", "string", ["pair", "double", ["oneormore", "nuclide", "double"]]], \ + "doc": "Output streams for separations. Each stream must have a unique name," \ + " a max buffer capacity in kg (neg values indicate infinite size), and a set of component efficiencies." \ + " 'comp' is a component to be separated into this stream (e.g. U, Pu, etc.) and 'eff' is the mass fraction of that component that is separated from the feed into this output stream.", \ + } + std::map > > streams_; + + #pragma cyclus var { \ + "doc" : "", \ + } + double feedbuf_size; + + #pragma cyclus var { \ + "capacity" : "feedbuf_size", \ + } + cyclus::toolkit::ResBuf feed; + + #pragma cyclus var { \ + "doc" : "", \ + } + double leftoverbuf_size; + + #pragma cyclus var { \ + "capacity" : "leftoverbuf_size", \ + } + cyclus::toolkit::ResBuf leftover; + + std::map > streambufs; + }; + +} // namespace cycamore + +#endif // CYCAMORE_SRC_SEPARATIONS_H_ From ec75c3348d1592ea79daf0b5f0857f603d37c673 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 26 Mar 2015 15:49:17 -0500 Subject: [PATCH 187/314] implement separations calculation and add a test --- src/separations.cc | 73 ++++++++++++++++++++++++++++++++++++---- src/separations.h | 10 +++++- src/separations_tests.cc | 47 ++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 8 deletions(-) create mode 100644 src/separations_tests.cc diff --git a/src/separations.cc b/src/separations.cc index dc013e9bb2..a844212aa8 100644 --- a/src/separations.cc +++ b/src/separations.cc @@ -7,6 +7,7 @@ using cyclus::toolkit::MatVec; using cyclus::KeyError; using cyclus::ValueError; using cyclus::Request; +using cyclus::CompMap; namespace cycamore { @@ -32,6 +33,7 @@ cyclus::Inventories Separations::SnapshotInv() { return invs; } + void Separations::InitInv(cyclus::Inventories& inv) { leftover.Push(inv["leftover"]); feed.Push(inv["feed"]); @@ -42,8 +44,8 @@ void Separations::InitInv(cyclus::Inventories& inv) { } } -typedef std::map > > StreamSet; typedef std::pair > Stream; +typedef std::map StreamSet; void Separations::EnterNotify() { cyclus::Facility::EnterNotify(); @@ -59,13 +61,70 @@ void Separations::EnterNotify() { } void Separations::Tick() { + Material::Ptr mat = feed.Pop(std::min(throughput, feed.quantity())); + + StreamSet::iterator it; + double maxfrac = 1; + std::map stagedsep; + for (it = streams_.begin(); it != streams_.end(); ++it) { + Stream info = it->second; + std::string name = it->first; + stagedsep[name] = SepMaterial(info.second, mat); + double frac = streambufs[name].space() / stagedsep[name]->quantity(); + if (frac < maxfrac) { + maxfrac = frac; + } + } + + std::map::iterator itf; + for (itf = stagedsep.begin(); itf != stagedsep.end(); ++it) { + std::string name = itf->first; + Material::Ptr m = itf->second; + streambufs[name].Push(mat->ExtractComp(m->quantity() * maxfrac, m->comp())); + } + + // push back any leftover onto feed stocks + if (maxfrac < 1) { + feed.Push(mat); + } } +// Note that this returns an untracked material that should just be used for +// its composition and qty - not in any real inventories, etc. +Material::Ptr SepMaterial(std::map effs, Material::Ptr mat) { + CompMap cm = mat->comp()->mass(); + cyclus::compmath::Normalize(&cm, mat->quantity()); + double tot_qty = 0; + CompMap sepcomp; + + CompMap::iterator it; + for (it = cm.begin(); it != cm.end(); ++it) { + int nuc = it->first; + int elem = (nuc / 10000000) * 10000000; + double eff = 0; + if (effs.count(nuc) > 0) { + eff = effs[nuc]; + } else if (effs.count(elem) > 0) { + eff = effs[elem]; + } else { + continue; + } + + double qty = it->second; + double sepqty = qty * eff; + sepcomp[nuc] = sepqty; + tot_qty += sepqty; + } + + Composition::Ptr c = Composition::CreateFromMass(sepcomp); + return Material::CreateUntracked(tot_qty, c); +}; + std::set::Ptr> Separations::GetMatlRequests() { - //using cyclus::RequestPortfolio; + using cyclus::RequestPortfolio; - //std::set::Ptr> ports; + std::set::Ptr> ports; //Material::Ptr m; //int n_assem_order = n_assem_core - core.count() @@ -89,7 +148,7 @@ Separations::GetMatlRequests() { // ports.insert(port); //} - //return ports; + return ports; } void Separations::GetMatlTrades( @@ -140,9 +199,9 @@ void Separations::AcceptMatlTrades( std::set::Ptr> Separations::GetMatlBids(cyclus::CommodMap::type& commod_requests) { - //using cyclus::BidPortfolio; + using cyclus::BidPortfolio; - //std::set::Ptr> ports; + std::set::Ptr> ports; //bool gotmats = false; //std::map all_mats; @@ -184,7 +243,7 @@ Separations::GetMatlBids(cyclus::CommodMap::type& // ports.insert(port); //} - //return ports; + return ports; } void Separations::Tock() { diff --git a/src/separations.h b/src/separations.h index 772399f4f0..cb59216958 100644 --- a/src/separations.h +++ b/src/separations.h @@ -5,6 +5,8 @@ namespace cycamore { +cyclus::Material::Ptr SepMaterial(std::map effs, cyclus::Material::Ptr mat); + class Separations : public cyclus::Facility { public: Separations(cyclus::Context* ctx); @@ -54,6 +56,12 @@ class Separations : public cyclus::Facility { } std::map > > streams_; + #pragma cyclus var { \ + "doc" : "Maximum quantity of feed material that can be processed per time step.", \ + "units": "kg", \ + } + double throughput; + #pragma cyclus var { \ "doc" : "", \ } @@ -75,7 +83,7 @@ class Separations : public cyclus::Facility { cyclus::toolkit::ResBuf leftover; std::map > streambufs; - }; +}; } // namespace cycamore diff --git a/src/separations_tests.cc b/src/separations_tests.cc new file mode 100644 index 0000000000..39f7308d8a --- /dev/null +++ b/src/separations_tests.cc @@ -0,0 +1,47 @@ +#include "separations.h" + +#include +#include +#include "cyclus.h" + +using pyne::nucname::id; +using cyclus::Composition; +using cyclus::CompMap; +using cyclus::Material; +using cyclus::QueryResult; +using cyclus::Cond; +using cyclus::toolkit::MatQuery; + +namespace cycamore { + +TEST(SeparationsTests, SepMaterial) { + CompMap comp; + comp[id("U235")] = 10; + comp[id("U238")] = 90; + comp[id("Pu239")] = 1; + comp[id("Pu240")] = 2; + comp[id("Am241")] = 3; + comp[id("Am242")] = 2.8; + double qty = 100; + Composition::Ptr c = Composition::CreateFromMass(comp); + Material::Ptr mat = Material::CreateUntracked(qty, c); + + std::map effs; + effs[id("U")] = .7; + effs[id("Pu")] = .4; + effs[id("Am241")] = .4; + + Material::Ptr sep = SepMaterial(effs, mat); + MatQuery mqorig(mat); + MatQuery mqsep(sep); + + EXPECT_DOUBLE_EQ(effs[id("U")] * mqorig.mass("U235"), mqsep.mass("U235")); + EXPECT_DOUBLE_EQ(effs[id("U")] * mqorig.mass("U238"), mqsep.mass("U238")); + EXPECT_DOUBLE_EQ(effs[id("Pu")] * mqorig.mass("Pu239"), mqsep.mass("Pu239")); + EXPECT_DOUBLE_EQ(effs[id("Pu")] * mqorig.mass("Pu240"), mqsep.mass("Pu240")); + EXPECT_DOUBLE_EQ(effs[id("Am241")] * mqorig.mass("Am241"), mqsep.mass("Am241")); + EXPECT_DOUBLE_EQ(0, mqsep.mass("Am242")); +} + +} // namespace cycamore + From a6a67dd2eec8e24d003e468c6420b5bd5cdb597c Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 30 Mar 2015 11:15:26 -0500 Subject: [PATCH 188/314] implement resource exchange for separations --- src/separations.cc | 218 +++++++++++++++++++++++++-------------------- src/separations.h | 54 ++++++++--- 2 files changed, 162 insertions(+), 110 deletions(-) diff --git a/src/separations.cc b/src/separations.cc index a844212aa8..f73979d150 100644 --- a/src/separations.cc +++ b/src/separations.cc @@ -58,10 +58,17 @@ void Separations::EnterNotify() { streambufs[name].capacity(cap); } } + + if (feed_commod_prefs.size() == 0) { + for (int i = 0; i < feed_commods.size(); i++) { + feed_commod_prefs.push_back(0); + } + } } void Separations::Tick() { Material::Ptr mat = feed.Pop(std::min(throughput, feed.quantity())); + double orig_qty = mat->quantity(); StreamSet::iterator it; double maxfrac = 1; @@ -83,9 +90,18 @@ void Separations::Tick() { streambufs[name].Push(mat->ExtractComp(m->quantity() * maxfrac, m->comp())); } - // push back any leftover onto feed stocks - if (maxfrac < 1) { - feed.Push(mat); + if (maxfrac == 1) { + if (mat->quantity() > 0) { + // unspecified separations fractions go to leftovers + leftover.Push(mat); + } + } else { // maxfrac is < 1 + // push back any leftover feed due to separated stream inv size constraints + feed.Push(mat->Extract((1 - maxfrac) * orig_qty)) + if (mat->quantity() > 0) { + // unspecified separations fractions go to leftovers + leftover.Push(mat); + } } } @@ -123,30 +139,27 @@ Material::Ptr SepMaterial(std::map effs, Material::Ptr mat) { std::set::Ptr> Separations::GetMatlRequests() { using cyclus::RequestPortfolio; - std::set::Ptr> ports; - //Material::Ptr m; - - //int n_assem_order = n_assem_core - core.count() - // + n_assem_fresh - fresh.count(); - //if (n_assem_order == 0) { - // return ports; - //} - - //for (int i = 0; i < n_assem_order; i++) { - // RequestPortfolio::Ptr port(new RequestPortfolio()); - // std::vector*> mreqs; - // for (int j = 0; j < fuel_incommods.size(); j++) { - // std::string commod = fuel_incommods[j]; - // double pref = fuel_prefs[j]; - // Composition::Ptr recipe = context()->GetRecipe(fuel_inrecipes[j]); - // m = Material::CreateUntracked(assem_size, recipe); - // Request* r = port->AddRequest(m, this, commod, pref, true); - // mreqs.push_back(r); - // } - // port->AddMutualReqs(mreqs); - // ports.insert(port); - //} + bool exclusive = false; + + if (feed.space() > cyclus::eps()) { + RequestPortfolio::Ptr port(new RequestPortfolio()); + + Material::Ptr m = cyclus::NewBlankMaterial(feed.space()); + if (!feed_recipe.empty()) { + Composition::Ptr c = context()->GetRecipe(feed_recipe); + m = Material::CreateUntracked(feed.space(), c); + } + + std::vector*> reqs; + for (int i = 0; i < feed_commods.size(); i++) { + std::string commod = feed_commods[i]; + double pref = feed_commod_prefs[i]; + reqs.push_back(port->AddRequest(m, this, commod, pref, exclusive)); + } + port->AddMutualReqs(reqs); + ports.insert(port); + } return ports; } @@ -155,45 +168,33 @@ void Separations::GetMatlTrades( const std::vector< cyclus::Trade >& trades, std::vector, Material::Ptr> >& responses) { - //using cyclus::Trade; - - //std::map mats = PopSpent(); - //std::vector< cyclus::Trade >::const_iterator it; - //for (int i = 0; i < trades.size(); i++) { - // std::string commod = trades[i].request->commodity(); - // Material::Ptr m = mats[commod].back(); - // mats[commod].pop_back(); - // responses.push_back(std::make_pair(trades[i], m)); - // res_indexes.erase(m->obj_id()); - //} - //PushSpent(mats); // return leftovers back to spent buffer + using cyclus::Trade; + + std::vector< cyclus::Trade >::const_iterator it; + for (int i = 0; i < trades.size(); i++) { + std::string commod = trades[i].request->commodity(); + if (commod == leftover_commod) { + Material::Ptr m = leftover.Pop(trades[i].amt); + responses.push_back(std::make_pair(trades[i], m)); + } else if (streambufs.count(commod) > 0) { + Material::Ptr m = streambufs[commod].Pop(trades[i].amt); + responses.push_back(std::make_pair(trades[i], m)); + } else { + throw ValueError("invalid commodity " + commod + " on trade matched to prototype " + prototype()); + } + } } void Separations::AcceptMatlTrades( const std::vector< std::pair, Material::Ptr> >& responses) { - //std::vector< std::pair, - // cyclus::Material::Ptr> >::const_iterator trade; - - //std::stringstream ss; - //int nload = std::min((int)responses.size(), n_assem_core - core.count()); - //if (nload > 0) { - // ss << nload << " assemblies"; - // Record("LOAD", ss.str()); - //} - - //for (trade = responses.begin(); trade != responses.end(); ++trade) { - // std::string commod = trade->first.request->commodity(); - // Material::Ptr m = trade->second; - // index_res(m, commod); - - // if (core.count() < n_assem_core) { - // core.Push(m); - // } else { - // fresh.Push(m); - // } - //} + std::vector< std::pair, + cyclus::Material::Ptr> >::const_iterator trade; + + for (trade = responses.begin(); trade != responses.end(); ++trade) { + feed.Push(trade->second); + } } std::set::Ptr> @@ -203,45 +204,66 @@ Separations::GetMatlBids(cyclus::CommodMap::type& std::set::Ptr> ports; - //bool gotmats = false; - //std::map all_mats; - //for (int i = 0; i < fuel_outcommods.size(); i++) { - // std::string commod = fuel_outcommods[i]; - // std::vector*>& reqs = commod_requests[commod]; - // if (reqs.size() == 0) { - // continue; - // } else if (!gotmats) { - // all_mats = PeekSpent(); - // } - - // MatVec mats = all_mats[commod]; - // if (mats.size() == 0) { - // continue; - // } - - // BidPortfolio::Ptr port(new BidPortfolio()); - - // for (int j = 0; j < reqs.size(); j++) { - // Request* req = reqs[j]; - // double tot_bid = 0; - // for (int k = 0; k < mats.size(); k++) { - // Material::Ptr m = mats[k]; - // tot_bid += m->quantity(); - // port->AddBid(req, m, this, true); - // if (tot_bid >= req->target()->quantity()) { - // break; - // } - // } - // } - - // double tot_qty = 0; - // for (int j = 0; j < mats.size(); j++) { - // tot_qty += mats[j]->quantity(); - // } - // cyclus::CapacityConstraint cc(tot_qty); - // port->AddConstraint(cc); - // ports.insert(port); - //} + // bid streams + std::map >::iterator it; + for (it = streambufs.begin(); it != streambufs.end(); ++it) { + std::string commod = it->first; + std::vector*>& reqs = commod_requests[commod]; + if (reqs.size() == 0) { + continue; + } else if (streambufs[commod].count() == 0) { + continue; + } + + double tot_qty = streambufs[commod].quantity(); + MatVec mats = streambufs[commod].PopN(streambufs[commod].count()); + streambufs[commod].Push(mats); + + BidPortfolio::Ptr port(new BidPortfolio()); + + for (int j = 0; j < reqs.size(); j++) { + Request* req = reqs[j]; + double tot_bid = 0; + for (int k = 0; k < mats.size(); k++) { + Material::Ptr m = mats[k]; + tot_bid += m->quantity(); + port->AddBid(req, m, this, true); + if (tot_bid >= req->target()->quantity()) { + break; + } + } + } + + cyclus::CapacityConstraint cc(tot_qty); + port->AddConstraint(cc); + ports.insert(port); + } + + // bid leftovers + std::vector*>& reqs = commod_requests[leftover_commod]; + if (reqs.size() > 0 && leftover.quantity() > cyclus::eps()) { + MatVec mats = leftover.PopN(leftover.count()); + leftover.Push(mats); + + BidPortfolio::Ptr port(new BidPortfolio()); + + for (int j = 0; j < reqs.size(); j++) { + Request* req = reqs[j]; + double tot_bid = 0; + for (int k = 0; k < mats.size(); k++) { + Material::Ptr m = mats[k]; + tot_bid += m->quantity(); + port->AddBid(req, m, this, true); + if (tot_bid >= req->target()->quantity()) { + break; + } + } + } + + cyclus::CapacityConstraint cc(leftover.quantity()); + port->AddConstraint(cc); + ports.insert(port); + } return ports; } diff --git a/src/separations.h b/src/separations.h index cb59216958..b81a8024c8 100644 --- a/src/separations.h +++ b/src/separations.h @@ -38,30 +38,42 @@ class Separations : public cyclus::Facility { #pragma cyclus annotations #pragma cyclus snapshot - virtual cyclus::Inventories SnapshotInv(); - virtual void InitInv(cyclus::Inventories& inv); - // the following pragmas are ommitted and generated manually to handle a // vector of resource buffers: // #pragma cyclus snapshotinv // #pragma cyclus initinv - private: - #pragma cyclus var { \ - "alias": ["streams", "name", ["info", "cap", ["efficiencies", "comp", "eff"]]], \ - "uitype": ["oneormore", "string", ["pair", "double", ["oneormore", "nuclide", "double"]]], \ - "doc": "Output streams for separations. Each stream must have a unique name," \ - " a max buffer capacity in kg (neg values indicate infinite size), and a set of component efficiencies." \ - " 'comp' is a component to be separated into this stream (e.g. U, Pu, etc.) and 'eff' is the mass fraction of that component that is separated from the feed into this output stream.", \ - } - std::map > > streams_; + virtual cyclus::Inventories SnapshotInv(); + virtual void InitInv(cyclus::Inventories& inv); + private: #pragma cyclus var { \ "doc" : "Maximum quantity of feed material that can be processed per time step.", \ "units": "kg", \ } double throughput; + #pragma cyclus var { \ + "doc": "Ordered list of commodities on which to request feed material to separate.", \ + "uitype": ["oneormore", "incommodity"], \ + } + std::vector feed_commods; + + #pragma cyclus var { \ + "default": [], \ + "doc": "Feed commodity request preferences for each of the given feed commodities (same order)." \ + " If unspecified, default is to use zero for all preferences.", \ + } + std::vector feed_commod_prefs; + + #pragma cyclus var { \ + "doc": "Name for recipe to be used in feed requests." \ + " Empty string results in use of an empty dummy recipe.", \ + "uitype": "recipe", \ + "default": "", \ + } + std::string feed_recipe; + #pragma cyclus var { \ "doc" : "", \ } @@ -74,14 +86,32 @@ class Separations : public cyclus::Facility { #pragma cyclus var { \ "doc" : "", \ + "default": 1e299, \ } double leftoverbuf_size; + #pragma cyclus var { \ + "doc": "Commodity on which to trade the leftover separated material stream." \ + " This MUST NOT be the same as any commodity used to define the other separations streams.", \ + "uitype": "outcommodity", \ + "default": "default-waste-stream", \ + } + std::string leftover_commod; + #pragma cyclus var { \ "capacity" : "leftoverbuf_size", \ } cyclus::toolkit::ResBuf leftover; + #pragma cyclus var { \ + "alias": ["streams", "name", ["info", "cap", ["efficiencies", "comp", "eff"]]], \ + "uitype": ["oneormore", "commod", ["pair", "double", ["oneormore", "nuclide", "double"]]], \ + "doc": "Output streams for separations. Each stream must have a unique name identifying the commodity on which its material is traded," \ + " a max buffer capacity in kg (neg values indicate infinite size), and a set of component efficiencies." \ + " 'comp' is a component to be separated into this stream (e.g. U, Pu, etc.) and 'eff' is the mass fraction of that component that is separated from the feed into this output stream.", \ + } + std::map > > streams_; + std::map > streambufs; }; From 24a05ffb7357737c9893f468cd6d2e02fb2c744d Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 30 Mar 2015 11:32:57 -0500 Subject: [PATCH 189/314] minor adjustments to schema and compile fixes. --- src/separations.cc | 2 +- src/separations.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/separations.cc b/src/separations.cc index f73979d150..b9d4ddfcd5 100644 --- a/src/separations.cc +++ b/src/separations.cc @@ -97,7 +97,7 @@ void Separations::Tick() { } } else { // maxfrac is < 1 // push back any leftover feed due to separated stream inv size constraints - feed.Push(mat->Extract((1 - maxfrac) * orig_qty)) + feed.Push(mat->ExtractQty((1 - maxfrac) * orig_qty)); if (mat->quantity() > 0) { // unspecified separations fractions go to leftovers leftover.Push(mat); diff --git a/src/separations.h b/src/separations.h index b81a8024c8..1302e987b4 100644 --- a/src/separations.h +++ b/src/separations.h @@ -104,8 +104,8 @@ class Separations : public cyclus::Facility { cyclus::toolkit::ResBuf leftover; #pragma cyclus var { \ - "alias": ["streams", "name", ["info", "cap", ["efficiencies", "comp", "eff"]]], \ - "uitype": ["oneormore", "commod", ["pair", "double", ["oneormore", "nuclide", "double"]]], \ + "alias": ["streams", "commod", ["info", "buf_size", ["efficiencies", "comp", "eff"]]], \ + "uitype": ["oneormore", "outcommodity", ["pair", "double", ["oneormore", "nuclide", "double"]]], \ "doc": "Output streams for separations. Each stream must have a unique name identifying the commodity on which its material is traded," \ " a max buffer capacity in kg (neg values indicate infinite size), and a set of component efficiencies." \ " 'comp' is a component to be separated into this stream (e.g. U, Pu, etc.) and 'eff' is the mass fraction of that component that is separated from the feed into this output stream.", \ From 64b0722dcbc391f2d1be9e297971d2a02f0171d9 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 30 Mar 2015 11:48:12 -0500 Subject: [PATCH 190/314] DELETE-ME - add sample input file --- recycle.xml | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 recycle.xml diff --git a/recycle.xml b/recycle.xml new file mode 100644 index 0000000000..ba494f5c38 --- /dev/null +++ b/recycle.xml @@ -0,0 +1,194 @@ + + + + flat + + 500 + 1 + 2000 + + + + agentsSource + cycamore EnrichmentFacility + cycamore Reactor + cycamore FuelFab + rwcSeparator + + + + enrichment + + + natl_u + natl_u + uox + 0.003 + 1e9 + 1e100 + + + + + + separations + + + + sepfiss + + 1e100 + + U .99 + Pu .98 + + + + + waste + 60000 + 1e100 + spent_uox + 2.0 + + + + + + fuelfab + + + depleted_u + depleted_u + 110000 + + sep_stream + 11000 + + thermal + mox + 22000 + + + + + + reactor + + + fresh_uox fresh_mox + spent_uox spent_mox + uox mox + spent_uox waste + 1.0 2.0 + + 9 + 1 + 11000 + 200 + 70 + + + + + + depleted_src + + + depleted_u + depleted_u + 1e10 + + + + + + r1 + reactor + + + + depleted1 + depleted_src + + + + fab1 + fuelfab + + + + sep1 + separations + + + + enrich1 + enrichment + + + + fresh_uox + mass + 9223500000.04 + 9223800000.96 + + + + depleted_u + mass + 9223500000.003 + 9223800000.997 + + + + fresh_mox + mass + 9223500000.0027381 + 9223800000.9099619 + 942380000 0.001746 + 942390000 0.045396 + 942400000 0.020952 + 942410000 0.013095 + 942420000 0.005238 + + + + spent_mox + mass + 9223500000.0017381 + 9223800000.90 + 942380000 0.001746 + 942390000 0.0134 + 942400000 0.020952 + 942410000 0.013095 + 942420000 0.005238 + + + + spent_uox + mass + 922350000 156.729 + 922360000 102.103 + 922380000 18280.324 + 932370000 13.656 + 942380000 5.043 + 942390000 106.343 + 942400000 41.357 + 942410000 36.477 + 942420000 15.387 + 952410000 1.234 + 952430000 3.607 + 962440000 0.431 + 962450000 1.263 + + + + natl_u + mass + 922350000 0.711 + 922380000 99.289 + + + + From 30b878e4dd2f06ce58ad718add3e4cf4d8435687 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 30 Mar 2015 16:41:25 -0500 Subject: [PATCH 191/314] fix separations bugs --- recycle.xml | 32 ++++++++++++++++++++++++-------- src/separations.cc | 28 ++++++++++++++++++---------- src/separations.h | 2 +- 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/recycle.xml b/recycle.xml index ba494f5c38..756b2943f0 100644 --- a/recycle.xml +++ b/recycle.xml @@ -3,17 +3,18 @@ flat - 500 + 1000 1 2000 - agentsSource + cycamoreSource + cycamoreSink cycamore EnrichmentFacility cycamore Reactor cycamore FuelFab - rwcSeparator + cycamore Separations @@ -35,11 +36,11 @@ - sepfiss + sep_stream 1e100 - U .99 + U 0 Pu .98 @@ -85,23 +86,38 @@ 9 1 11000 - 200 - 70 + 7 + 2 + + repo + + + waste + 1e10 + + + + depleted_src - depleted_u + depleted_u depleted_u 1e10 + + repo1 + repo + + r1 reactor diff --git a/src/separations.cc b/src/separations.cc index b9d4ddfcd5..a3db0a931f 100644 --- a/src/separations.cc +++ b/src/separations.cc @@ -20,10 +20,13 @@ Separations::Separations(cyclus::Context* ctx) cyclus::Inventories Separations::SnapshotInv() { cyclus::Inventories invs; - invs["leftover"] = leftover.PopNRes(leftover.count()); - leftover.Push(invs["leftover"]); - invs["feed"] = feed.PopNRes(feed.count()); - feed.Push(invs["feed"]); + // these inventory names are intentionally convoluted so as to not clash + // with the user-specified stream commods that are used as the separations + // streams inventory names. + invs["leftover-inv-name"] = leftover.PopNRes(leftover.count()); + leftover.Push(invs["leftover-inv-name"]); + invs["feed-inv-name"] = feed.PopNRes(feed.count()); + feed.Push(invs["feed-inv-name"]); std::map >::iterator it; for (it = streambufs.begin(); it != streambufs.end(); ++it) { @@ -35,8 +38,8 @@ cyclus::Inventories Separations::SnapshotInv() { } void Separations::InitInv(cyclus::Inventories& inv) { - leftover.Push(inv["leftover"]); - feed.Push(inv["feed"]); + leftover.Push(inv["leftover-inv-name"]); + feed.Push(inv["feed-inv-name"]); cyclus::Inventories::iterator it; for (it = inv.begin(); it != inv.end(); ++it) { @@ -67,6 +70,10 @@ void Separations::EnterNotify() { } void Separations::Tick() { + if (feed.count() == 0) { + return; + } + Material::Ptr mat = feed.Pop(std::min(throughput, feed.quantity())); double orig_qty = mat->quantity(); @@ -84,7 +91,7 @@ void Separations::Tick() { } std::map::iterator itf; - for (itf = stagedsep.begin(); itf != stagedsep.end(); ++it) { + for (itf = stagedsep.begin(); itf != stagedsep.end(); ++itf) { std::string name = itf->first; Material::Ptr m = itf->second; streambufs[name].Push(mat->ExtractComp(m->quantity() * maxfrac, m->comp())); @@ -202,6 +209,7 @@ Separations::GetMatlBids(cyclus::CommodMap::type& commod_requests) { using cyclus::BidPortfolio; + bool exclusive = false; std::set::Ptr> ports; // bid streams @@ -215,7 +223,6 @@ Separations::GetMatlBids(cyclus::CommodMap::type& continue; } - double tot_qty = streambufs[commod].quantity(); MatVec mats = streambufs[commod].PopN(streambufs[commod].count()); streambufs[commod].Push(mats); @@ -227,13 +234,14 @@ Separations::GetMatlBids(cyclus::CommodMap::type& for (int k = 0; k < mats.size(); k++) { Material::Ptr m = mats[k]; tot_bid += m->quantity(); - port->AddBid(req, m, this, true); + port->AddBid(req, m, this, exclusive); if (tot_bid >= req->target()->quantity()) { break; } } } + double tot_qty = streambufs[commod].quantity(); cyclus::CapacityConstraint cc(tot_qty); port->AddConstraint(cc); ports.insert(port); @@ -253,7 +261,7 @@ Separations::GetMatlBids(cyclus::CommodMap::type& for (int k = 0; k < mats.size(); k++) { Material::Ptr m = mats[k]; tot_bid += m->quantity(); - port->AddBid(req, m, this, true); + port->AddBid(req, m, this, exclusive); if (tot_bid >= req->target()->quantity()) { break; } diff --git a/src/separations.h b/src/separations.h index 1302e987b4..fc23e40bc8 100644 --- a/src/separations.h +++ b/src/separations.h @@ -108,7 +108,7 @@ class Separations : public cyclus::Facility { "uitype": ["oneormore", "outcommodity", ["pair", "double", ["oneormore", "nuclide", "double"]]], \ "doc": "Output streams for separations. Each stream must have a unique name identifying the commodity on which its material is traded," \ " a max buffer capacity in kg (neg values indicate infinite size), and a set of component efficiencies." \ - " 'comp' is a component to be separated into this stream (e.g. U, Pu, etc.) and 'eff' is the mass fraction of that component that is separated from the feed into this output stream.", \ + " 'comp' is a component to be separated into the stream (e.g. U, Pu, etc.) and 'eff' is the mass fraction of the component that is separated from the feed into this output stream.", \ } std::map > > streams_; From 419ce7e7d9bf6d957195a4507aa851f091e54a5d Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 2 Apr 2015 14:30:03 -0500 Subject: [PATCH 192/314] more robust constraint guarding. --- src/separations.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/separations.cc b/src/separations.cc index a3db0a931f..5938fadba5 100644 --- a/src/separations.cc +++ b/src/separations.cc @@ -219,7 +219,7 @@ Separations::GetMatlBids(cyclus::CommodMap::type& std::vector*>& reqs = commod_requests[commod]; if (reqs.size() == 0) { continue; - } else if (streambufs[commod].count() == 0) { + } else if (streambufs[commod].quantity() < cyclus::eps()) { continue; } @@ -249,7 +249,7 @@ Separations::GetMatlBids(cyclus::CommodMap::type& // bid leftovers std::vector*>& reqs = commod_requests[leftover_commod]; - if (reqs.size() > 0 && leftover.quantity() > cyclus::eps()) { + if (reqs.size() > 0 && leftover.quantity() >= cyclus::eps()) { MatVec mats = leftover.PopN(leftover.count()); leftover.Push(mats); From 3b553ef5f148b2bb4cca992a7a1c2b3e4a10dd0b Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 8 Apr 2015 09:16:59 -0500 Subject: [PATCH 193/314] clang-format --- src/separations.cc | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/separations.cc b/src/separations.cc index 5938fadba5..dcd8eca193 100644 --- a/src/separations.cc +++ b/src/separations.cc @@ -11,10 +11,10 @@ using cyclus::CompMap; namespace cycamore { -Separations::Separations(cyclus::Context* ctx) - : cyclus::Facility(ctx) { - cyclus::Warn("the Separations archetype " - "is experimental"); +Separations::Separations(cyclus::Context* ctx) : cyclus::Facility(ctx) { + cyclus::Warn( + "the Separations archetype " + "is experimental"); } cyclus::Inventories Separations::SnapshotInv() { @@ -102,7 +102,7 @@ void Separations::Tick() { // unspecified separations fractions go to leftovers leftover.Push(mat); } - } else { // maxfrac is < 1 + } else { // maxfrac is < 1 // push back any leftover feed due to separated stream inv size constraints feed.Push(mat->ExtractQty((1 - maxfrac) * orig_qty)); if (mat->quantity() > 0) { @@ -132,7 +132,7 @@ Material::Ptr SepMaterial(std::map effs, Material::Ptr mat) { } else { continue; } - + double qty = it->second; double sepqty = qty * eff; sepcomp[nuc] = sepqty; @@ -172,12 +172,12 @@ Separations::GetMatlRequests() { } void Separations::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - Material::Ptr> >& responses) { + const std::vector >& trades, + std::vector, Material::Ptr> >& + responses) { using cyclus::Trade; - std::vector< cyclus::Trade >::const_iterator it; + std::vector >::const_iterator it; for (int i = 0; i < trades.size(); i++) { std::string commod = trades[i].request->commodity(); if (commod == leftover_commod) { @@ -187,26 +187,24 @@ void Separations::GetMatlTrades( Material::Ptr m = streambufs[commod].Pop(trades[i].amt); responses.push_back(std::make_pair(trades[i], m)); } else { - throw ValueError("invalid commodity " + commod + " on trade matched to prototype " + prototype()); + throw ValueError("invalid commodity " + commod + + " on trade matched to prototype " + prototype()); } } } -void Separations::AcceptMatlTrades( - const std::vector< std::pair, - Material::Ptr> >& responses) { - - std::vector< std::pair, - cyclus::Material::Ptr> >::const_iterator trade; +void Separations::AcceptMatlTrades(const std::vector< + std::pair, Material::Ptr> >& responses) { + std::vector, + cyclus::Material::Ptr> >::const_iterator trade; for (trade = responses.begin(); trade != responses.end(); ++trade) { feed.Push(trade->second); } } -std::set::Ptr> -Separations::GetMatlBids(cyclus::CommodMap::type& - commod_requests) { +std::set::Ptr> Separations::GetMatlBids( + cyclus::CommodMap::type& commod_requests) { using cyclus::BidPortfolio; bool exclusive = false; @@ -276,12 +274,10 @@ Separations::GetMatlBids(cyclus::CommodMap::type& return ports; } -void Separations::Tock() { -} +void Separations::Tock() {} extern "C" cyclus::Agent* ConstructSeparations(cyclus::Context* ctx) { return new Separations(ctx); } -} // namespace cycamore - +} // namespace cycamore From db4aeeb23d407a570f63bcd8cb54be8feff87ded Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 8 Apr 2015 09:32:25 -0500 Subject: [PATCH 194/314] some better docs --- src/separations.h | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/separations.h b/src/separations.h index fc23e40bc8..5cbb876aa0 100644 --- a/src/separations.h +++ b/src/separations.h @@ -37,9 +37,9 @@ class Separations : public cyclus::Facility { #pragma cyclus schema #pragma cyclus annotations #pragma cyclus snapshot - - // the following pragmas are ommitted and generated manually to handle a - // vector of resource buffers: + // the following pragmas are ommitted and the functions are generated + // manually in order to handle the vector of resource buffers: + // // #pragma cyclus snapshotinv // #pragma cyclus initinv @@ -75,7 +75,8 @@ class Separations : public cyclus::Facility { std::string feed_recipe; #pragma cyclus var { \ - "doc" : "", \ + "doc" : "Amount of feed material to keep on hand.", \ + "units" : "kg", \ } double feedbuf_size; @@ -85,7 +86,9 @@ class Separations : public cyclus::Facility { cyclus::toolkit::ResBuf feed; #pragma cyclus var { \ - "doc" : "", \ + "doc" : "Maximum amount of leftover separated material (not included in" \ + " any other stream) that can be stored." \ + " If full, the facility halts operation until space becomes available.", \ "default": 1e299, \ } double leftoverbuf_size; @@ -106,12 +109,19 @@ class Separations : public cyclus::Facility { #pragma cyclus var { \ "alias": ["streams", "commod", ["info", "buf_size", ["efficiencies", "comp", "eff"]]], \ "uitype": ["oneormore", "outcommodity", ["pair", "double", ["oneormore", "nuclide", "double"]]], \ - "doc": "Output streams for separations. Each stream must have a unique name identifying the commodity on which its material is traded," \ - " a max buffer capacity in kg (neg values indicate infinite size), and a set of component efficiencies." \ - " 'comp' is a component to be separated into the stream (e.g. U, Pu, etc.) and 'eff' is the mass fraction of the component that is separated from the feed into this output stream.", \ + "doc": "Output streams for separations." \ + " Each stream must have a unique name identifying the commodity on which its material is traded," \ + " a max buffer capacity in kg (neg values indicate infinite size)," \ + " and a set of component efficiencies." \ + " 'comp' is a component to be separated into the stream" \ + " (e.g. U, Pu, etc.) and 'eff' is the mass fraction of the component" \ + " that is separated from the feed into this output stream." \ + " If any stream buffer is full, the facility halts operation until space becomes available.", \ } std::map > > streams_; + // custom SnapshotInv and InitInv and EnterNotify are used to persist this + // state var. std::map > streambufs; }; From d8244157f83c7f98857ddfee8bec417fe220a319 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 8 Apr 2015 16:56:00 -0500 Subject: [PATCH 195/314] clean up recycle.xml --- recycle.xml | 122 +++++++++++++++++++++------------------------------- 1 file changed, 48 insertions(+), 74 deletions(-) diff --git a/recycle.xml b/recycle.xml index 756b2943f0..653364d703 100644 --- a/recycle.xml +++ b/recycle.xml @@ -1,5 +1,3 @@ - - flat @@ -9,8 +7,8 @@ - cycamoreSource - cycamoreSink + cycamore Source + cycamore Sink cycamore EnrichmentFacility cycamore Reactor cycamore FuelFab @@ -47,7 +45,7 @@ waste - 60000 + 66000.001 1e100 spent_uox 2.0 @@ -83,8 +81,8 @@ spent_uox waste 1.0 2.0 - 9 - 1 + 16 + 2 11000 7 2 @@ -113,98 +111,74 @@ - - repo1 - repo - - - - r1 - reactor - - - - depleted1 - depleted_src - - - - fab1 - fuelfab - + repo1 repo + r1 reactor + depleted1 depleted_src + fab1 fuelfab + sep1 separations + enrich1 enrichment - - sep1 - separations - - - - enrich1 - enrichment - + + natl_u + mass + U235 0.711 + U238 99.289 + fresh_uox mass - 9223500000.04 - 9223800000.96 + U2350.04 + U2380.96 depleted_u mass - 9223500000.003 - 9223800000.997 + U2350.003 + U2380.997 fresh_mox mass - 9223500000.0027381 - 9223800000.9099619 - 942380000 0.001746 - 942390000 0.045396 - 942400000 0.020952 - 942410000 0.013095 - 942420000 0.005238 + U235 0.0027381 + U238 0.9099619 + Pu238 0.001746 + Pu239 0.045396 + Pu240 0.020952 + Pu241 0.013095 + Pu242 0.005238 spent_mox mass - 9223500000.0017381 - 9223800000.90 - 942380000 0.001746 - 942390000 0.0134 - 942400000 0.020952 - 942410000 0.013095 - 942420000 0.005238 + U235 0.0017381 + U238 0.90 + Pu238 0.001746 + Pu239 0.0134 + Pu240 0.020952 + Pu241 0.013095 + Pu242 0.005238 spent_uox mass - 922350000 156.729 - 922360000 102.103 - 922380000 18280.324 - 932370000 13.656 - 942380000 5.043 - 942390000 106.343 - 942400000 41.357 - 942410000 36.477 - 942420000 15.387 - 952410000 1.234 - 952430000 3.607 - 962440000 0.431 - 962450000 1.263 + U235 156.729 + U236 102.103 + U238 18280.324 + Np237 13.656 + Pu238 5.043 + Pu239 106.343 + Pu240 41.357 + Pu241 36.477 + Pu242 15.387 + Am241 1.234 + Am243 3.607 + Cm244 0.431 + Cm245 1.263 - - natl_u - mass - 922350000 0.711 - 922380000 99.289 - - - From a88f11a53fb70cc641eef5e58967dc529862bb15 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 9 Apr 2015 14:44:53 -0500 Subject: [PATCH 196/314] better doc comment and space after commas --- src/separations.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/separations.h b/src/separations.h index 5cbb876aa0..8843800b19 100644 --- a/src/separations.h +++ b/src/separations.h @@ -54,7 +54,8 @@ class Separations : public cyclus::Facility { double throughput; #pragma cyclus var { \ - "doc": "Ordered list of commodities on which to request feed material to separate.", \ + "doc": "Ordered list of commodities on which to request feed material to separate." \ + " Order only matters for matching up with feed commodity preferences if specified.", \ "uitype": ["oneormore", "incommodity"], \ } std::vector feed_commods; @@ -118,7 +119,7 @@ class Separations : public cyclus::Facility { " that is separated from the feed into this output stream." \ " If any stream buffer is full, the facility halts operation until space becomes available.", \ } - std::map > > streams_; + std::map > > streams_; // custom SnapshotInv and InitInv and EnterNotify are used to persist this // state var. From ab16bdb9cee5661e2525369329bec5213dcdcccd Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 10 Apr 2015 13:32:17 -0500 Subject: [PATCH 197/314] fix separations when feed has none of a stream's components --- src/separations.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/separations.cc b/src/separations.cc index dcd8eca193..a7e7cbf3bd 100644 --- a/src/separations.cc +++ b/src/separations.cc @@ -94,7 +94,9 @@ void Separations::Tick() { for (itf = stagedsep.begin(); itf != stagedsep.end(); ++itf) { std::string name = itf->first; Material::Ptr m = itf->second; - streambufs[name].Push(mat->ExtractComp(m->quantity() * maxfrac, m->comp())); + if (m->quantity() > 0) { + streambufs[name].Push(mat->ExtractComp(m->quantity() * maxfrac, m->comp())); + } } if (maxfrac == 1) { From 58b966ca750698a736005e08132148a2c8560533 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 16 Apr 2015 14:02:35 -0500 Subject: [PATCH 198/314] make separations more robust against floating point issues --- src/separations.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/separations.cc b/src/separations.cc index a7e7cbf3bd..128979bc3c 100644 --- a/src/separations.cc +++ b/src/separations.cc @@ -183,10 +183,12 @@ void Separations::GetMatlTrades( for (int i = 0; i < trades.size(); i++) { std::string commod = trades[i].request->commodity(); if (commod == leftover_commod) { - Material::Ptr m = leftover.Pop(trades[i].amt); + double amt = std::min(leftover.quantity(), trades[i].amt); + Material::Ptr m = leftover.Pop(amt); responses.push_back(std::make_pair(trades[i], m)); } else if (streambufs.count(commod) > 0) { - Material::Ptr m = streambufs[commod].Pop(trades[i].amt); + double amt = std::min(streambufs[commod].quantity(), trades[i].amt); + Material::Ptr m = streambufs[commod].Pop(amt); responses.push_back(std::make_pair(trades[i], m)); } else { throw ValueError("invalid commodity " + commod + From f282f4fee4695210d98b775a1332e1db8eeca695 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 23 Apr 2015 13:43:35 -0500 Subject: [PATCH 199/314] more docs and some formatting fixes --- src/separations.cc | 3 ++- src/separations.h | 63 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/separations.cc b/src/separations.cc index 128979bc3c..a81e26e211 100644 --- a/src/separations.cc +++ b/src/separations.cc @@ -95,7 +95,8 @@ void Separations::Tick() { std::string name = itf->first; Material::Ptr m = itf->second; if (m->quantity() > 0) { - streambufs[name].Push(mat->ExtractComp(m->quantity() * maxfrac, m->comp())); + streambufs[name].Push( + mat->ExtractComp(m->quantity() * maxfrac, m->comp())); } } diff --git a/src/separations.h b/src/separations.h index 8843800b19..da118ad6d4 100644 --- a/src/separations.h +++ b/src/separations.h @@ -5,9 +5,57 @@ namespace cycamore { -cyclus::Material::Ptr SepMaterial(std::map effs, cyclus::Material::Ptr mat); - +/// SepMaterial returns a material object that represents the composition and +/// quantity resulting from the separation of material from mat using the given +/// mass-based efficiencies. Each key in effs represents a nuclide or element +/// (canonical PyNE form), and each value is the corresponding mass-based +/// separations efficiency for that nuclide or element. Note that this returns +/// an untracked material that should only be used for its composition and qty +/// - not in any real inventories, etc. +cyclus::Material::Ptr SepMaterial(std::map effs, + cyclus::Material::Ptr mat); + +/// Separations processes feed material into one or more streams containing +/// specific elements and/or nuclides. It uses mass-based efficiencies. +/// +/// User defined separations streams are specified as groups of +/// component-efficiency pairs where 'component' means either a particular +/// element or a particular nuclide. Each component's paired efficiency +/// represents the mass fraction of that component in the feed that is +/// separated into that stream. The efficiencies of a particular component +/// across all streams must sum up to less than or equal to one. If less than +/// one, the remainining material is sent to a waste inventory and +/// (potentially) traded away from there. +/// +/// The facility receives material into a feed inventory that it processes with +/// a specified throughput each time step. Each output stream has a +/// corresponding output inventory size/limit. If the facility is unable to +/// reduce its stocks by trading and hits this limit for any of its output +/// streams, further processing/separations of feed material will halt until +/// room is again available in the output streams. class Separations : public cyclus::Facility { +#pragma cyclus note { \ + "doc": \ + "Separations processes feed material into one or more streams containing" \ + " specific elements and/or nuclides. It uses mass-based efficiencies." \ + "\n\n" \ + "User defined separations streams are specified as groups of" \ + " component-efficiency pairs where 'component' means either a particular" \ + " element or a particular nuclide. Each component's paired efficiency" \ + " represents the mass fraction of that component in the feed that is" \ + " separated into that stream. The efficiencies of a particular component" \ + " across all streams must sum up to less than or equal to one. If less than" \ + " one, the remainining material is sent to a waste inventory and" \ + " (potentially) traded away from there." \ + "\n\n" \ + "The facility receives material into a feed inventory that it processes with" \ + " a specified throughput each time step. Each output stream has a" \ + " corresponding output inventory size/limit. If the facility is unable to" \ + " reduce its stocks by trading and hits this limit for any of its output" \ + " streams, further processing/separations of feed material will halt until" \ + " room is again available in the output streams." \ + "", \ +} public: Separations(cyclus::Context* ctx); virtual ~Separations(){}; @@ -37,7 +85,7 @@ class Separations : public cyclus::Facility { #pragma cyclus schema #pragma cyclus annotations #pragma cyclus snapshot - // the following pragmas are ommitted and the functions are generated + // the following pragmas are ommitted and the functions are written // manually in order to handle the vector of resource buffers: // // #pragma cyclus snapshotinv @@ -69,14 +117,14 @@ class Separations : public cyclus::Facility { #pragma cyclus var { \ "doc": "Name for recipe to be used in feed requests." \ - " Empty string results in use of an empty dummy recipe.", \ + " Empty string results in use of a dummy recipe.", \ "uitype": "recipe", \ "default": "", \ } std::string feed_recipe; #pragma cyclus var { \ - "doc" : "Amount of feed material to keep on hand.", \ + "doc" : "Maximum amount of feed material to keep on hand.", \ "units" : "kg", \ } double feedbuf_size; @@ -91,6 +139,7 @@ class Separations : public cyclus::Facility { " any other stream) that can be stored." \ " If full, the facility halts operation until space becomes available.", \ "default": 1e299, \ + "units": "kg", \ } double leftoverbuf_size; @@ -117,7 +166,9 @@ class Separations : public cyclus::Facility { " 'comp' is a component to be separated into the stream" \ " (e.g. U, Pu, etc.) and 'eff' is the mass fraction of the component" \ " that is separated from the feed into this output stream." \ - " If any stream buffer is full, the facility halts operation until space becomes available.", \ + " If any stream buffer is full, the facility halts operation until space becomes available." \ + " The sum total of all component efficiencies across streams must be less than or equal to 1" \ + " (e.g. sum of U efficiencies for all streams must be <= 1).", \ } std::map > > streams_; From 907cda7c8310069e9b628f024f3c85f81c9eb954 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 23 Apr 2015 14:12:01 -0500 Subject: [PATCH 200/314] adding a test --- src/separations_tests.cc | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/separations_tests.cc b/src/separations_tests.cc index 39f7308d8a..0fb1b42c60 100644 --- a/src/separations_tests.cc +++ b/src/separations_tests.cc @@ -43,5 +43,48 @@ TEST(SeparationsTests, SepMaterial) { EXPECT_DOUBLE_EQ(0, mqsep.mass("Am242")); } +TEST(SeparationsTests, SepMixElemAndNuclide) { + std::string config = + "" + " stream1" + " " + " -1" + " " + " U 0.6" + " Pu239 .7" + " " + " " + "" + "" + "waste" + "100" + "100" + " feed " + ; + + CompMap m; + m[id("u235")] = 0.08; + m[id("u238")] = 0.9; + m[id("Pu239")] = .01; + m[id("Pu240")] = .01; + Composition::Ptr c = Composition::CreateFromMass(m); + + int simdur = 2; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Separations"), config, simdur); + sim.AddSource("feed").recipe("recipe1").Finalize(); + sim.AddSink("stream1").capacity(100).Finalize(); + sim.AddRecipe("recipe1", c); + int id = sim.Run(); + + std::vector conds; + conds.push_back(Cond("SenderId", "==", id)); + int resid = sim.db().Query("Transactions", &conds).GetVal("ResourceId"); + MatQuery mq (sim.GetMaterial(resid)); + EXPECT_DOUBLE_EQ(m[922350000]*0.6*100, mq.mass("U235")); + EXPECT_DOUBLE_EQ(m[922380000]*0.6*100, mq.mass("U238")); + EXPECT_DOUBLE_EQ(m[942390000]*0.7*100, mq.mass("Pu239")); + EXPECT_DOUBLE_EQ(0, mq.mass("Pu240")); +} + } // namespace cycamore From 2a4ce31b6f50ec1f59ba91b3533d9fe1ff8d8ade Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 23 Apr 2015 15:04:24 -0500 Subject: [PATCH 201/314] update example recycle input file --- recycle.xml => input/recycle.xml | 41 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 21 deletions(-) rename recycle.xml => input/recycle.xml (86%) diff --git a/recycle.xml b/input/recycle.xml similarity index 86% rename from recycle.xml rename to input/recycle.xml index 653364d703..bb2073291b 100644 --- a/recycle.xml +++ b/input/recycle.xml @@ -1,7 +1,7 @@ flat - 1000 + 600 1 2000 @@ -9,7 +9,7 @@ cycamore Source cycamore Sink - cycamore EnrichmentFacility + cycamore Enrichment cycamore Reactor cycamore FuelFab cycamore Separations @@ -18,14 +18,14 @@ enrichment - - natl_u - natl_u - uox + + natl_u + natl_u + uox 0.003 - 1e9 + 1e100 1e100 - + @@ -38,15 +38,14 @@ 1e100 - U 0 - Pu .98 + Pu .99 waste - 66000.001 - 1e100 + 30001 + 30001 spent_uox 2.0 @@ -59,14 +58,14 @@ depleted_u depleted_u - 110000 + 30001 sep_stream - 11000 + 15000 thermal mox - 22000 + 30001 @@ -81,11 +80,11 @@ spent_uox waste 1.0 2.0 - 16 + 17 2 - 11000 - 7 - 2 + 30000 + 3 + 1 @@ -95,7 +94,7 @@ waste - 1e10 + 1e100 @@ -106,7 +105,7 @@ depleted_u depleted_u - 1e10 + 1e100 From 713a9d409c54583e14f75df472d8e50216d9d22f Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 15:04:56 -0500 Subject: [PATCH 202/314] Revert "this should fail unit tests" This reverts commit 8e904cdf8ddedbb16a18f6aa6487df6e33734ee7. --- src/source_tests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source_tests.cc b/src/source_tests.cc index 556623a82f..eea1d9c38d 100644 --- a/src/source_tests.cc +++ b/src/source_tests.cc @@ -107,7 +107,7 @@ TEST_F(SourceTest, Response) { // 1 trade src_facility->GetMatlTrades(trades, responses); EXPECT_EQ(responses.size(), 1); - EXPECT_EQ(responses[0].second->quantity(), qty + 1); + EXPECT_EQ(responses[0].second->quantity(), qty); EXPECT_EQ(responses[0].second->comp(), recipe); // 2 trades, total qty = capacity From 08305ef9ba6fbea2b72743c32301561d1a46dd29 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 23 Apr 2015 15:12:11 -0500 Subject: [PATCH 203/314] fix up recycle.xml --- input/recycle.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/input/recycle.xml b/input/recycle.xml index bb2073291b..406994c642 100644 --- a/input/recycle.xml +++ b/input/recycle.xml @@ -23,8 +23,9 @@ natl_u uox 0.003 + waste 1e100 - 1e100 + 1e100 @@ -103,9 +104,8 @@ depleted_src - depleted_u - depleted_u - 1e100 + depleted_u + depleted_u From 1d3457a29e9f423c3b524b5d495897c7350cf458 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 15:32:58 -0500 Subject: [PATCH 204/314] Addressing @scopatz's comments --- .travis-install.sh | 10 ++++------ .travis.yml | 2 -- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/.travis-install.sh b/.travis-install.sh index 1f9e8a8e15..c6a2e10c90 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -x + # log msg=`git log --pretty=oneline -1` echo "Building commit: $msg" @@ -10,9 +12,7 @@ unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml # build -cmd="conda build --no-test conda-recipe" -echo "cmd: $cmd" -$cmd +conda build --no-test conda-recipe status=$? echo "status: $status" if [[ $status != 0 ]]; then @@ -20,9 +20,7 @@ if [[ $status != 0 ]]; then fi # install -cmd="conda install --use-local cycamore=0.0" -echo "cmd: $cmd" -$cmd +conda install --use-local cycamore=0.0 status=$? echo "status: $status" if [[ $status != 0 ]]; then diff --git a/.travis.yml b/.travis.yml index 5153f20149..54cdd1f8ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,8 +39,6 @@ install: script: - export PATH="$HOME/miniconda/bin:$PATH" - export LD_LIBRARY_PATH="$HOME/miniconda/lib:$LD_LIBRARY_PATH" - #- ls -l $HOME/miniconda/lib - #- ls -l $HOME/miniconda/envs/_build/lib - cycamore_unit_tests - conda install numpy pytables - nosetests -w tests From 2b9d07d7f18dc9bb1060233a016256007982fc1a Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 15:38:05 -0500 Subject: [PATCH 205/314] set -e --- .travis-install.sh | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/.travis-install.sh b/.travis-install.sh index c6a2e10c90..f4cf6adae1 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -1,6 +1,7 @@ #!/bin/bash -set -x +set -x # print cmds +set -e # exit as soon as an error occurs # log msg=`git log --pretty=oneline -1` @@ -13,16 +14,6 @@ sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml # build conda build --no-test conda-recipe -status=$? -echo "status: $status" -if [[ $status != 0 ]]; then - exit $status -fi # install conda install --use-local cycamore=0.0 -status=$? -echo "status: $status" -if [[ $status != 0 ]]; then - exit $status -fi From 91bdb3ae84d6c0cb06cd17ad698cbf65b64a9a68 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 15:04:32 -0500 Subject: [PATCH 206/314] removed testing-specific repo and branch info --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 54cdd1f8ad..6a126fed6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,9 +27,8 @@ install: - conda info -a # install cyclus - - git clone https://github.com/gidden/cyclus ../cyclus + - git clone https://github.com/cyclus/cyclus ../cyclus - cd ../cyclus - - git checkout origin/travis - ./.travis-install.sh - cd ../cycamore From 3158b7c935e51fa3696e3af49a4fadb92f810144 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 15:35:05 -0500 Subject: [PATCH 207/314] updating ciclus pull --- .travis-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis-install.sh b/.travis-install.sh index f4cf6adae1..0ec08d2ea3 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -8,7 +8,7 @@ msg=`git log --pretty=oneline -1` echo "Building commit: $msg" # setup conda recipe -wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip +wget https://github.com/cyclus/ciclus/archive/master.zip -O ciclus.zip unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml From e11a12eef8595087610aabd0cd89ae4616a4be1b Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 23 Apr 2015 16:37:24 -0500 Subject: [PATCH 208/314] added regression test for recycle --- .gitignore | 3 +- tests/test_regression.py | 90 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 835e504e75..ad488f2da1 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ suffix.h *.pyc rs.cred *.h5 -tests/run_inputs.py \ No newline at end of file +*.dat +tests/run_inputs.py diff --git a/tests/test_regression.py b/tests/test_regression.py index 9c315b3a9f..449f7d9cd9 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -375,3 +375,93 @@ def test_deployment(self): assert_equal(depl_time[np.where(agent_ids == source1_id[0])], 2) assert_equal(depl_time[np.where(agent_ids == source1_id[1])], 3) +class TestRecycle(TestRegression): + """This class tests the input/recycle.xml file. + """ + def __init__(self, *args, **kwargs): + super(TestRecycle, self).__init__(*args, **kwargs) + + # this test requires separations which isn't supported by hdf5 + # so we force sqlite: + base, _ = os.path.splitext(self.outf) + self.ext = '.sqlite' + self.outf = base + self.ext + self.inf = "../input/recycle.xml" + self.sql = """ + SELECT t.time as time,SUM(c.massfrac*r.quantity) as qty FROM transactions as t + JOIN resources as r ON t.resourceid=r.resourceid AND r.simid=t.simid + JOIN agententry as send ON t.senderid=send.agentid AND send.simid=t.simid + JOIN agententry as recv ON t.receiverid=recv.agentid AND recv.simid=t.simid + JOIN compositions as c ON c.qualid=r.qualid AND c.simid=r.simid + WHERE send.prototype=? AND recv.prototype=? AND c.nucid=? + GROUP BY t.time;""" + + def do_compare(self, fromfac, tofac, nuclide, exp_invs): + conn = sqlite3.connect(self.outf) + c = conn.cursor() + eps = 1e-10 + simdur = len(exp_invs) + + invs = [0.0] * simdur + for i, row in enumerate(c.execute(self.sql, (fromfac, tofac, nuclide))): + t = row[0] + invs[t] = row[1] + + expfname = 'exp_recycle_{0}-{1}-{2}.dat'.format(fromfac, tofac, nuclide) + with open(expfname, 'w') as f: + for t, val in enumerate(exp_invs): + f.write('{0} {1}\n'.format(t, val)) + obsfname = 'obs_recycle_{0}-{1}-{2}.dat'.format(fromfac, tofac, nuclide) + with open(obsfname, 'w') as f: + for t, val in enumerate(invs): + f.write('{0} {1}\n'.format(t, val)) + + i = 0 + for exp, obs in zip(invs, exp_invs): + i += 1 + self.assertAlmostEquals(exp, obs, msg='mismatch at t={0}'.format(i)) + + os.remove(expfname) + os.remove(obsfname) + + def test_pu239_sep_repo(self): + simdur = 600 + exp = [0.0] * simdur + exp[18] = 1.700222672 + exp[37] = 1.700222672 + exp[56] = 1.700222672 + exp[75] = 1.700222672 + exp[94] = 1.700222672 + exp[113] = 1.700222672 + exp[132] = 1.700222672 + exp[151] = 1.700222672 + exp[170] = 1.700222672 + exp[189] = 1.700222672 + exp[208] = 1.700222672 + exp[227] = 1.700222672 + exp[246] = 1.700222672 + exp[284] = 1.700222672 + exp[303] = 1.700222672 + exp[322] = 1.700222672 + exp[341] = 1.700222672 + exp[360] = 1.700222672 + exp[379] = 1.700222672 + exp[398] = 1.700222672 + exp[417] = 1.700222672 + exp[436] = 1.700222672 + exp[474] = 1.700222672 + exp[493] = 1.700222672 + exp[512] = 1.700222672 + exp[531] = 1.700222672 + exp[550] = 1.700222672 + exp[569] = 1.700222672 + exp[588] = 1.700222672 + self.do_compare('separations', 'repo', 942390000, exp) + + def test_pu239_reactor_repo(self): + simdur = 600 + exp = [0.0] * simdur + exp[264] = 420.42772559790944 + exp[454] = 420.42772559790944 + self.do_compare('reactor', 'repo', 942390000, exp) + From ab36e381de17cb7b8a9bb5c5c6692d84a732d199 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 21 Apr 2015 10:32:28 -0500 Subject: [PATCH 209/314] adding travis.yml --- .travis.yml | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..3becb17748 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,49 @@ +language: python +python: + # We don't actually use the Travis Python, but this keeps it organized. + - "2.7" + - "3.4" + +before_install: + - sudo apt-get update -qq + +install: + # You may want to periodically update this, although the conda update + # conda line below will keep everything up-to-date. We do this + # conditionally because it saves us some downloading if the version is + # the same. + - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then + wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh; + else + wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; + fi + - bash miniconda.sh -b -p $HOME/miniconda + - export PATH="$HOME/miniconda/bin:$PATH" + - hash -r + - conda config --set always_yes yes --set changeps1 no + - conda config --add channels pyne + - conda config --add channels cyclus + - conda config --add channels cycamore + - conda update -q conda + - conda install conda-build jinja2 setuptools binstar patchelf nose + # Useful for debugging any issues with conda + - conda info -a + + # download CI repo + - wget https://github.com/cyclus/ciclus/archive/master.zip -O ciclus.zip + - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe + + # Replace dep1 dep2 ... with your dependencies + #- conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION dep1 dep2 ... + #- source activate test-environment + - conda build --no-test conda-recipe + - conda install cycamore --use-local + +script: + - cycamore_unit_tests + - nosetests -w tests + #- cd tests + #- nosetests + #- ./travis-run-tests.sh + + From 40d4eb90a5d72e6fe9d56aa8dd127ef72cbd88ad Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 21 Apr 2015 13:39:20 -0500 Subject: [PATCH 210/314] rm cycamore as binstar user --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3becb17748..12755d392b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,8 @@ python: # We don't actually use the Travis Python, but this keeps it organized. - "2.7" - "3.4" - before_install: - sudo apt-get update -qq - install: # You may want to periodically update this, although the conda update # conda line below will keep everything up-to-date. We do this @@ -23,7 +21,6 @@ install: - conda config --set always_yes yes --set changeps1 no - conda config --add channels pyne - conda config --add channels cyclus - - conda config --add channels cycamore - conda update -q conda - conda install conda-build jinja2 setuptools binstar patchelf nose # Useful for debugging any issues with conda From 6d7cead8c0709ddde74f5f0484f9be18d6367834 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 21 Apr 2015 16:51:47 -0500 Subject: [PATCH 211/314] updating path and tables install --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 12755d392b..f8e2e5d435 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ install: - conda config --add channels pyne - conda config --add channels cyclus - conda update -q conda - - conda install conda-build jinja2 setuptools binstar patchelf nose + - conda install conda-build setuptools binstar patchelf nose # Useful for debugging any issues with conda - conda info -a @@ -37,6 +37,8 @@ install: - conda install cycamore --use-local script: + - export PATH="$HOME/miniconda/bin:$PATH" + - conda install tables - cycamore_unit_tests - nosetests -w tests #- cd tests From e98ddb668eac212aebe002389d62df66199e2d1a Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 21 Apr 2015 16:52:55 -0500 Subject: [PATCH 212/314] numpy install --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f8e2e5d435..061440d20b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,7 +38,7 @@ install: script: - export PATH="$HOME/miniconda/bin:$PATH" - - conda install tables + - conda install numpy tables - cycamore_unit_tests - nosetests -w tests #- cd tests From b368f7414437de87fe4c0b176ebaa167b9990204 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 22 Apr 2015 10:56:36 -0500 Subject: [PATCH 213/314] updating from cyclus yml --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 061440d20b..dc2c452196 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,6 +38,11 @@ install: script: - export PATH="$HOME/miniconda/bin:$PATH" + - export LD_LIBRARY_PATH="$HOME/miniconda/lib:$HOME/miniconda/envs/_build/lib:$LD_LIBRARY_PATH" + - ls -l $HOME/miniconda/lib + - ls -l $HOME/miniconda/envs/_build/lib + - ln -s $HOME/miniconda/lib/libhdf5.so.9 $HOME/miniconda/lib/libhdf5.so.8 + - ln -s $HOME/miniconda/lib/libhdf5_hl.so.9 $HOME/miniconda/lib/libhdf5_hl.so.8 - conda install numpy tables - cycamore_unit_tests - nosetests -w tests From de669a0896d92e7d2aaa92b9c4c05a0501557d94 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 22 Apr 2015 17:48:36 -0500 Subject: [PATCH 214/314] matching cyclus --- .travis.yml | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index dc2c452196..0bdcac5064 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,32 +22,30 @@ install: - conda config --add channels pyne - conda config --add channels cyclus - conda update -q conda - - conda install conda-build setuptools binstar patchelf nose + - conda install conda-build jinja2 setuptools binstar patchelf nose # Useful for debugging any issues with conda - conda info -a # download CI repo - wget https://github.com/cyclus/ciclus/archive/master.zip -O ciclus.zip - - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe - - # Replace dep1 dep2 ... with your dependencies - #- conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION dep1 dep2 ... - #- source activate test-environment - - conda build --no-test conda-recipe - - conda install cycamore --use-local + - unzip -j ciclus.zip + + # build cyclus + - mv ciclus/cyclus conda-recipe-cyclus + - conda build --no-test conda-recipe-cyclus + - conda install --use-local cyclus=0.0 + + # build cycamore + - mv ciclus/cycamore conda-recipe-cycamore + - conda build --no-test conda-recipe-cycamore + - conda install --use-local cycamore=0.0 script: - export PATH="$HOME/miniconda/bin:$PATH" - - export LD_LIBRARY_PATH="$HOME/miniconda/lib:$HOME/miniconda/envs/_build/lib:$LD_LIBRARY_PATH" - - ls -l $HOME/miniconda/lib - - ls -l $HOME/miniconda/envs/_build/lib - - ln -s $HOME/miniconda/lib/libhdf5.so.9 $HOME/miniconda/lib/libhdf5.so.8 - - ln -s $HOME/miniconda/lib/libhdf5_hl.so.9 $HOME/miniconda/lib/libhdf5_hl.so.8 - - conda install numpy tables + - export LD_LIBRARY_PATH="$HOME/miniconda/lib:$LD_LIBRARY_PATH" + #- ls -l $HOME/miniconda/lib + #- ls -l $HOME/miniconda/envs/_build/lib - cycamore_unit_tests + - conda install numpy tables - nosetests -w tests - #- cd tests - #- nosetests - #- ./travis-run-tests.sh - From 66c27450a61e0445edb5b65c93dc72a083d26481 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 22 Apr 2015 17:50:17 -0500 Subject: [PATCH 215/314] grabbing correct ciclus --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0bdcac5064..1d51093559 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,7 @@ install: - conda info -a # download CI repo - - wget https://github.com/cyclus/ciclus/archive/master.zip -O ciclus.zip + - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - unzip -j ciclus.zip # build cyclus From 8bf8e9164e66e583fb8a0bd737cb35aefdfd2ac6 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 22 Apr 2015 18:13:53 -0500 Subject: [PATCH 216/314] mirroring cyclus unzip --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1d51093559..d6eb10b32b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,14 +28,15 @@ install: # download CI repo - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - - unzip -j ciclus.zip # build cyclus + - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe-cyclus - mv ciclus/cyclus conda-recipe-cyclus - conda build --no-test conda-recipe-cyclus - conda install --use-local cyclus=0.0 # build cycamore + - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe-cycamore - mv ciclus/cycamore conda-recipe-cycamore - conda build --no-test conda-recipe-cycamore - conda install --use-local cycamore=0.0 From 1816731e95996d49006299503b1a9b53273a6fc8 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 22 Apr 2015 18:23:41 -0500 Subject: [PATCH 217/314] rm mvs --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d6eb10b32b..09c1b2a1bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,13 +31,11 @@ install: # build cyclus - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe-cyclus - - mv ciclus/cyclus conda-recipe-cyclus - conda build --no-test conda-recipe-cyclus - conda install --use-local cyclus=0.0 # build cycamore - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe-cycamore - - mv ciclus/cycamore conda-recipe-cycamore - conda build --no-test conda-recipe-cycamore - conda install --use-local cycamore=0.0 From 0c703195fc9a8dbf8618671617ef44c4f76ab157 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 22 Apr 2015 18:34:34 -0500 Subject: [PATCH 218/314] maybe conda-recipe name matters --- .travis.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 09c1b2a1bf..9e414d829c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,13 +30,14 @@ install: - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip # build cyclus - - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe-cyclus - - conda build --no-test conda-recipe-cyclus + - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe + - conda build --no-test conda-recipe - conda install --use-local cyclus=0.0 + - mv conda-recipe conda-recipe-cyclus # build cycamore - - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe-cycamore - - conda build --no-test conda-recipe-cycamore + - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe + - conda build --no-test conda-recipe - conda install --use-local cycamore=0.0 script: From eaadc31959e0b3183147de002f31eed39c15b47d Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 08:55:28 -0500 Subject: [PATCH 219/314] trying now with sedding the right cyclus --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9e414d829c..08589b0985 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,12 +33,14 @@ install: - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe - conda build --no-test conda-recipe - conda install --use-local cyclus=0.0 - - mv conda-recipe conda-recipe-cyclus + - mv conda-recipe cyclus-recipe # build cycamore - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe + - sed -i "s/- cyclus/- cyclus=0.0/g" conda-recipe/meta.yaml - conda build --no-test conda-recipe - conda install --use-local cycamore=0.0 + - mv conda-recipe cycamore-recipe script: - export PATH="$HOME/miniconda/bin:$PATH" From 16f31aa5aa5e58d3fada8a4c4c7125a89ad8d719 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 09:02:51 -0500 Subject: [PATCH 220/314] trying some cyclus foo --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.travis.yml b/.travis.yml index 08589b0985..d2ca4ae79a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,10 +30,17 @@ install: - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip # build cyclus + - pwd=$PWD + - echo "pwd: $pwd" + - cd $HOME + - git clone git@github.com:gidden/cyclus + - cd cyclus + - git checkout origin/travis - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe - conda build --no-test conda-recipe - conda install --use-local cyclus=0.0 - mv conda-recipe cyclus-recipe + - cd $pwd # build cycamore - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe From 2e4f2edc336cb9aa26dd68592d1863a7cb4deeae Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 09:08:50 -0500 Subject: [PATCH 221/314] travis doesn't like colons --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d2ca4ae79a..b703ceb84a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ install: # build cyclus - pwd=$PWD - - echo "pwd: $pwd" + - echo "pwd $pwd" - cd $HOME - git clone git@github.com:gidden/cyclus - cd cyclus From 629f2b71889a43c5737d4f75326d7229ad579e80 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 09:15:08 -0500 Subject: [PATCH 222/314] https for clone --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b703ceb84a..876463161d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,8 +32,8 @@ install: # build cyclus - pwd=$PWD - echo "pwd $pwd" - - cd $HOME - - git clone git@github.com:gidden/cyclus + - cd .. + - git clone https://github.com/gidden/cyclus - cd cyclus - git checkout origin/travis - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe From 80abe1a35e16184746ec65749ec01dc06127c94e Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 09:23:52 -0500 Subject: [PATCH 223/314] need to rewget --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 876463161d..a31791ff27 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,9 +26,6 @@ install: # Useful for debugging any issues with conda - conda info -a - # download CI repo - - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - # build cyclus - pwd=$PWD - echo "pwd $pwd" @@ -36,6 +33,7 @@ install: - git clone https://github.com/gidden/cyclus - cd cyclus - git checkout origin/travis + - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe - conda build --no-test conda-recipe - conda install --use-local cyclus=0.0 @@ -43,6 +41,7 @@ install: - cd $pwd # build cycamore + - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe - sed -i "s/- cyclus/- cyclus=0.0/g" conda-recipe/meta.yaml - conda build --no-test conda-recipe From a4335a564bdcf81a82134f2058f16a4c4114c71a Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 10:00:58 -0500 Subject: [PATCH 224/314] meta didn't like = ' --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a31791ff27..f3b5eb5e8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,7 +43,7 @@ install: # build cycamore - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe - - sed -i "s/- cyclus/- cyclus=0.0/g" conda-recipe/meta.yaml + - sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml - conda build --no-test conda-recipe - conda install --use-local cycamore=0.0 - mv conda-recipe cycamore-recipe From 1a52935f772abccd4a76ed289cb6f4daddd7a458 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 10:20:45 -0500 Subject: [PATCH 225/314] updating for travis-install.sh --- .travis-install.sh | 5 +++++ .travis.yml | 26 +++++++------------------- 2 files changed, 12 insertions(+), 19 deletions(-) create mode 100755 .travis-install.sh diff --git a/.travis-install.sh b/.travis-install.sh new file mode 100755 index 0000000000..0ab998f721 --- /dev/null +++ b/.travis-install.sh @@ -0,0 +1,5 @@ +wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip +unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe +sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml +conda build --no-test conda-recipe +conda install --use-local cycamore=0.0 \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index f3b5eb5e8b..6eecf5b8a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,27 +26,15 @@ install: # Useful for debugging any issues with conda - conda info -a - # build cyclus - - pwd=$PWD - - echo "pwd $pwd" - - cd .. - - git clone https://github.com/gidden/cyclus - - cd cyclus + # install cyclus + - git clone https://github.com/gidden/cyclus ../cyclus + - cd ../cyclus - git checkout origin/travis - - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - - unzip -j ciclus.zip "*/cyclus/*" -d conda-recipe - - conda build --no-test conda-recipe - - conda install --use-local cyclus=0.0 - - mv conda-recipe cyclus-recipe - - cd $pwd + - ./.travis-install.sh + - cd ../cycamore - # build cycamore - - wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip - - unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe - - sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml - - conda build --no-test conda-recipe - - conda install --use-local cycamore=0.0 - - mv conda-recipe cycamore-recipe + # install cycamore + - ./.travis-install.sh script: - export PATH="$HOME/miniconda/bin:$PATH" From bf85c705e9bc5dccff3f270df846cbb1b092feb0 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 10:25:51 -0500 Subject: [PATCH 226/314] matching find hdf5.cmakes with cyclus --- cmake/FindHDF5.cmake | 382 ++++++++++++++++++++++--------------------- 1 file changed, 192 insertions(+), 190 deletions(-) diff --git a/cmake/FindHDF5.cmake b/cmake/FindHDF5.cmake index 1722a7ea41..5b7cadd022 100644 --- a/cmake/FindHDF5.cmake +++ b/cmake/FindHDF5.cmake @@ -26,7 +26,7 @@ # In addition to finding the includes and libraries required to compile an HDF5 # client application, this module also makes an effort to find tools that come # with the HDF5 distribution that may be useful for regression testing. -# +# # This module will define the following variables: # HDF5_INCLUDE_DIRS - Location of the hdf5 includes # HDF5_INCLUDE_DIR - Location of the hdf5 includes (deprecated) @@ -60,268 +60,270 @@ include(SelectLibraryConfigurations) include(FindPackageHandleStandardArgs) # List of the valid HDF5 components -set(HDF5_VALID_COMPONENTS +set( HDF5_VALID_COMPONENTS C CXX - ) +) # try to find the HDF5 wrapper compilers -find_program(HDF5_C_COMPILER_EXECUTABLE +find_program( HDF5_C_COMPILER_EXECUTABLE NAMES h5cc h5pcc HINTS ENV HDF5_ROOT PATH_SUFFIXES bin Bin - DOC "HDF5 Wrapper compiler. Used only to detect HDF5 compile flags.") -mark_as_advanced(HDF5_C_COMPILER_EXECUTABLE) + DOC "HDF5 Wrapper compiler. Used only to detect HDF5 compile flags." ) +mark_as_advanced( HDF5_C_COMPILER_EXECUTABLE ) -find_program(HDF5_CXX_COMPILER_EXECUTABLE +find_program( HDF5_CXX_COMPILER_EXECUTABLE NAMES h5c++ h5pc++ HINTS ENV HDF5_ROOT PATH_SUFFIXES bin Bin - DOC "HDF5 C++ Wrapper compiler. Used only to detect HDF5 compile flags.") -mark_as_advanced(HDF5_CXX_COMPILER_EXECUTABLE) + DOC "HDF5 C++ Wrapper compiler. Used only to detect HDF5 compile flags." ) +mark_as_advanced( HDF5_CXX_COMPILER_EXECUTABLE ) -find_program(HDF5_DIFF_EXECUTABLE +find_program( HDF5_DIFF_EXECUTABLE NAMES h5diff HINTS ENV HDF5_ROOT - PATH_SUFFIXES bin Bin - DOC "HDF5 file differencing tool.") -mark_as_advanced(HDF5_DIFF_EXECUTABLE) + PATH_SUFFIXES bin Bin + DOC "HDF5 file differencing tool." ) +mark_as_advanced( HDF5_DIFF_EXECUTABLE ) # Invoke the HDF5 wrapper compiler. The compiler return value is stored to the # return_value argument, the text output is stored to the output variable. -macro(_HDF5_invoke_compiler language output return_value) - if(HDF5_${language}_COMPILER_EXECUTABLE) - exec_program(${HDF5_${language}_COMPILER_EXECUTABLE} +macro( _HDF5_invoke_compiler language output return_value ) + if( HDF5_${language}_COMPILER_EXECUTABLE ) + exec_program( ${HDF5_${language}_COMPILER_EXECUTABLE} ARGS -show OUTPUT_VARIABLE ${output} RETURN_VALUE ${return_value} - ) - if(${${return_value}} EQUAL 0) + ) + if( ${${return_value}} EQUAL 0 ) # do nothing else() - message(STATUS - "Unable to determine HDF5 ${language} flags from HDF5 wrapper.") + message( STATUS + "Unable to determine HDF5 ${language} flags from HDF5 wrapper." ) endif() endif() endmacro() # Parse a compile line for definitions, includes, library paths, and libraries. -macro(_HDF5_parse_compile_line - compile_line_var - include_paths - definitions - library_paths - libraries) +macro( _HDF5_parse_compile_line + compile_line_var + include_paths + definitions + library_paths + libraries ) # Match the include paths - string(REGEX MATCHALL "-I([^\" ]+)" include_path_flags + string( REGEX MATCHALL "-I([^\" ]+)" include_path_flags "${${compile_line_var}}" - ) - foreach(IPATH ${include_path_flags}) - string(REGEX REPLACE "^-I" "" IPATH ${IPATH}) - string(REGEX REPLACE "//" "/" IPATH ${IPATH}) - list(APPEND ${include_paths} ${IPATH}) + ) + foreach( IPATH ${include_path_flags} ) + string( REGEX REPLACE "^-I" "" IPATH ${IPATH} ) + string( REGEX REPLACE "//" "/" IPATH ${IPATH} ) + list( APPEND ${include_paths} ${IPATH} ) endforeach() # Match the definitions - string(REGEX MATCHALL "-D[^ ]*" definition_flags "${${compile_line_var}}") - foreach(DEF ${definition_flags}) - list(APPEND ${definitions} ${DEF}) + string( REGEX MATCHALL "-D[^ ]*" definition_flags "${${compile_line_var}}" ) + foreach( DEF ${definition_flags} ) + list( APPEND ${definitions} ${DEF} ) endforeach() # Match the library paths - string(REGEX MATCHALL "-L([^\" ]+|\"[^\"]+\")" library_path_flags + string( REGEX MATCHALL "-L([^\" ]+|\"[^\"]+\")" library_path_flags "${${compile_line_var}}" - ) - - foreach(LPATH ${library_path_flags}) - string(REGEX REPLACE "^-L" "" LPATH ${LPATH}) - string(REGEX REPLACE "//" "/" LPATH ${LPATH}) - list(APPEND ${library_paths} ${LPATH}) + ) + + foreach( LPATH ${library_path_flags} ) + string( REGEX REPLACE "^-L" "" LPATH ${LPATH} ) + string( REGEX REPLACE "//" "/" LPATH ${LPATH} ) + list( APPEND ${library_paths} ${LPATH} ) endforeach() # now search for the library names specified in the compile line (match -l...) # match only -l's preceded by a space or comma # this is to exclude directory names like xxx-linux/ - string(REGEX MATCHALL "[, ]-l([^\", ]+)" library_name_flags - "${${compile_line_var}}") + string( REGEX MATCHALL "[, ]-l([^\", ]+)" library_name_flags + "${${compile_line_var}}" ) # strip the -l from all of the library flags and add to the search list - foreach(LIB ${library_name_flags}) - string(REGEX REPLACE "^[, ]-l" "" LIB ${LIB}) - list(APPEND ${libraries} ${LIB}) + foreach( LIB ${library_name_flags} ) + string( REGEX REPLACE "^[, ]-l" "" LIB ${LIB} ) + list( APPEND ${libraries} ${LIB} ) endforeach() endmacro() -if(HDF5_INCLUDE_DIRS AND HDF5_LIBRARIES) +if( HDF5_INCLUDE_DIRS AND HDF5_LIBRARIES ) # Do nothing: we already have HDF5_INCLUDE_PATH and HDF5_LIBRARIES in the # cache, it would be a shame to override them else() - _HDF5_invoke_compiler(C HDF5_C_COMPILE_LINE HDF5_C_RETURN_VALUE) - _HDF5_invoke_compiler(CXX HDF5_CXX_COMPILE_LINE HDF5_CXX_RETURN_VALUE) + _HDF5_invoke_compiler( C HDF5_C_COMPILE_LINE HDF5_C_RETURN_VALUE ) + _HDF5_invoke_compiler( CXX HDF5_CXX_COMPILE_LINE HDF5_CXX_RETURN_VALUE ) - if(NOT HDF5_FIND_COMPONENTS) - set(HDF5_LANGUAGE_BINDINGS "C") + if( NOT HDF5_FIND_COMPONENTS ) + set( HDF5_LANGUAGE_BINDINGS "C" ) else() # add the extra specified components, ensuring that they are valid. - foreach(component ${HDF5_FIND_COMPONENTS}) - list(FIND HDF5_VALID_COMPONENTS ${component} component_location) - if(${component_location} EQUAL -1) - message(FATAL_ERROR - "\"${component}\" is not a valid HDF5 component.") + foreach( component ${HDF5_FIND_COMPONENTS} ) + list( FIND HDF5_VALID_COMPONENTS ${component} component_location ) + if( ${component_location} EQUAL -1 ) + message( FATAL_ERROR + "\"${component}\" is not a valid HDF5 component." ) else() - list(APPEND HDF5_LANGUAGE_BINDINGS ${component}) + list( APPEND HDF5_LANGUAGE_BINDINGS ${component} ) endif() endforeach() endif() - + # seed the initial lists of libraries to find with items we know we need - set(HDF5_C_LIBRARY_NAMES_INIT hdf5_hl hdf5) - set(HDF5_CXX_LIBRARY_NAMES_INIT hdf5_cpp ${HDF5_C_LIBRARY_NAMES_INIT}) - - foreach(LANGUAGE ${HDF5_LANGUAGE_BINDINGS}) - if(HDF5_${LANGUAGE}_COMPILE_LINE) - _HDF5_parse_compile_line(HDF5_${LANGUAGE}_COMPILE_LINE - HDF5_${LANGUAGE}_INCLUDE_FLAGS - HDF5_${LANGUAGE}_DEFINITIONS - HDF5_${LANGUAGE}_LIBRARY_DIRS - HDF5_${LANGUAGE}_LIBRARY_NAMES + set( HDF5_C_LIBRARY_NAMES_INIT hdf5_hl hdf5 ) + set( HDF5_CXX_LIBRARY_NAMES_INIT hdf5_cpp ${HDF5_C_LIBRARY_NAMES_INIT} ) + + foreach( LANGUAGE ${HDF5_LANGUAGE_BINDINGS} ) + if( HDF5_${LANGUAGE}_COMPILE_LINE ) + _HDF5_parse_compile_line( HDF5_${LANGUAGE}_COMPILE_LINE + HDF5_${LANGUAGE}_INCLUDE_FLAGS + HDF5_${LANGUAGE}_DEFINITIONS + HDF5_${LANGUAGE}_LIBRARY_DIRS + HDF5_${LANGUAGE}_LIBRARY_NAMES ) + + # take a guess that the includes may be in the 'include' sibling directory + # of a library directory. + foreach( dir ${HDF5_${LANGUAGE}_LIBRARY_DIRS} ) + list( APPEND HDF5_${LANGUAGE}_INCLUDE_FLAGS ${dir}/../include ) + endforeach() + endif() - # take a guess that the includes may be in the 'include' sibling directory - # of a library directory. - foreach(dir ${HDF5_${LANGUAGE}_LIBRARY_DIRS}) - list(APPEND HDF5_${LANGUAGE}_INCLUDE_FLAGS ${dir}/../include) - endforeach() - endif() - - # set the definitions for the language bindings. - list(APPEND HDF5_DEFINITIONS ${HDF5_${LANGUAGE}_DEFINITIONS}) - - # find the HDF5 include directories - find_path(HDF5_${LANGUAGE}_INCLUDE_DIR hdf5.h - HINTS - ${HDF5_${LANGUAGE}_INCLUDE_FLAGS} - ENV - HDF5_ROOT - PATHS - $ENV{HOME}/.local/include - PATH_SUFFIXES - include - Include + # set the definitions for the language bindings. + list( APPEND HDF5_DEFINITIONS ${HDF5_${LANGUAGE}_DEFINITIONS} ) + + # find the HDF5 include directories + find_path( HDF5_${LANGUAGE}_INCLUDE_DIR hdf5.h + HINTS + ${HDF5_${LANGUAGE}_INCLUDE_FLAGS} + ENV + HDF5_ROOT + PATHS + $ENV{HOME}/.local/include + PATH_SUFFIXES + include + Include ) - mark_as_advanced(HDF5_${LANGUAGE}_INCLUDE_DIR) - list(APPEND HDF5_INCLUDE_DIRS ${HDF5_${LANGUAGE}_INCLUDE_DIR}) - - set(HDF5_${LANGUAGE}_LIBRARY_NAMES - ${HDF5_${LANGUAGE}_LIBRARY_NAMES_INIT} - ${HDF5_${LANGUAGE}_LIBRARY_NAMES}) - - # find the HDF5 libraries - foreach(LIB ${HDF5_${LANGUAGE}_LIBRARY_NAMES}) - if(UNIX AND HDF5_USE_STATIC_LIBRARIES) - # According to bug 1643 on the CMake bug tracker, this is the - # preferred method for searching for a static library. - # See http://www.cmake.org/Bug/view.php?id=1643. We search - # first for the full static library name, but fall back to a - # generic search on the name if the static search fails. - set(THIS_LIBRARY_SEARCH_DEBUG lib${LIB}d.a ${LIB}d) - set(THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a ${LIB}) - else() - set(THIS_LIBRARY_SEARCH_DEBUG ${LIB}d) - set(THIS_LIBRARY_SEARCH_RELEASE ${LIB}) - endif() - find_library(HDF5_${LIB}_LIBRARY_DEBUG - NAMES ${THIS_LIBRARY_SEARCH_DEBUG} - HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} - ENV HDF5_ROOT - PATH_SUFFIXES lib Lib) - find_library(HDF5_${LIB}_LIBRARY_RELEASE - NAMES ${THIS_LIBRARY_SEARCH_RELEASE} - HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} - ENV HDF5_ROOT - PATH_SUFFIXES lib Lib) - select_library_configurations(HDF5_${LIB}) - # even though we adjusted the individual library names in - # select_library_configurations, we still need to distinguish - # between debug and release variants because HDF5_LIBRARIES will - # need to specify different lists for debug and optimized builds. - # We can't just use the HDF5_${LIB}_LIBRARY variable (which was set - # up by the selection macro above) because it may specify debug and - # optimized variants for a particular library, but a list of - # libraries is allowed to specify debug and optimized only once. - list(APPEND HDF5_${LANGUAGE}_LIBRARIES_DEBUG - ${HDF5_${LIB}_LIBRARY_DEBUG}) - list(APPEND HDF5_${LANGUAGE}_LIBRARIES_RELEASE - ${HDF5_${LIB}_LIBRARY_RELEASE}) + mark_as_advanced( HDF5_${LANGUAGE}_INCLUDE_DIR ) + list( APPEND HDF5_INCLUDE_DIRS ${HDF5_${LANGUAGE}_INCLUDE_DIR} ) + + set( HDF5_${LANGUAGE}_LIBRARY_NAMES + ${HDF5_${LANGUAGE}_LIBRARY_NAMES_INIT} + ${HDF5_${LANGUAGE}_LIBRARY_NAMES} ) + + # find the HDF5 libraries + foreach( LIB ${HDF5_${LANGUAGE}_LIBRARY_NAMES} ) + if( UNIX AND HDF5_USE_STATIC_LIBRARIES ) + # According to bug 1643 on the CMake bug tracker, this is the + # preferred method for searching for a static library. + # See http://www.cmake.org/Bug/view.php?id=1643. We search + # first for the full static library name, but fall back to a + # generic search on the name if the static search fails. + set( THIS_LIBRARY_SEARCH_DEBUG lib${LIB}d.a ${LIB}d ) + set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a ${LIB} ) + else() + set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d ) + set( THIS_LIBRARY_SEARCH_RELEASE ${LIB} ) + endif() + find_library( HDF5_${LIB}_LIBRARY_DEBUG + NAMES ${THIS_LIBRARY_SEARCH_DEBUG} + HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} + ENV HDF5_ROOT + PATH_SUFFIXES lib Lib ) + find_library( HDF5_${LIB}_LIBRARY_RELEASE + NAMES ${THIS_LIBRARY_SEARCH_RELEASE} + HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} + ENV HDF5_ROOT + PATH_SUFFIXES lib Lib ) + select_library_configurations( HDF5_${LIB} ) + # even though we adjusted the individual library names in + # select_library_configurations, we still need to distinguish + # between debug and release variants because HDF5_LIBRARIES will + # need to specify different lists for debug and optimized builds. + # We can't just use the HDF5_${LIB}_LIBRARY variable (which was set + # up by the selection macro above) because it may specify debug and + # optimized variants for a particular library, but a list of + # libraries is allowed to specify debug and optimized only once. + list( APPEND HDF5_${LANGUAGE}_LIBRARIES_DEBUG + ${HDF5_${LIB}_LIBRARY_DEBUG} ) + list( APPEND HDF5_${LANGUAGE}_LIBRARIES_RELEASE + ${HDF5_${LIB}_LIBRARY_RELEASE} ) + endforeach() + list( APPEND HDF5_LIBRARY_DIRS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} ) + + # Append the libraries for this language binding to the list of all + # required libraries. + list( APPEND HDF5_LIBRARIES_DEBUG + ${HDF5_${LANGUAGE}_LIBRARIES_DEBUG} ) + list( APPEND HDF5_LIBRARIES_RELEASE + ${HDF5_${LANGUAGE}_LIBRARIES_RELEASE} ) endforeach() - list(APPEND HDF5_LIBRARY_DIRS ${HDF5_${LANGUAGE}_LIBRARY_DIRS}) - - # Append the libraries for this language binding to the list of all - # required libraries. - list(APPEND HDF5_LIBRARIES_DEBUG - ${HDF5_${LANGUAGE}_LIBRARIES_DEBUG}) - list(APPEND HDF5_LIBRARIES_RELEASE - ${HDF5_${LANGUAGE}_LIBRARIES_RELEASE}) -endforeach() -# We may have picked up some duplicates in various lists during the above -# process for the language bindings (both the C and C++ bindings depend on -# libz for example). Remove the duplicates. -if(HDF5_INCLUDE_DIRS) - list(REMOVE_DUPLICATES HDF5_INCLUDE_DIRS) -endif() -if(HDF5_LIBRARIES_DEBUG) - list(REMOVE_DUPLICATES HDF5_LIBRARIES_DEBUG) -endif() -if(HDF5_LIBRARIES_RELEASE) - list(REMOVE_DUPLICATES HDF5_LIBRARIES_RELEASE) -endif() -if(HDF5_LIBRARY_DIRS) - list(REMOVE_DUPLICATES HDF5_LIBRARY_DIRS) -endif() + # We may have picked up some duplicates in various lists during the above + # process for the language bindings (both the C and C++ bindings depend on + # libz for example). Remove the duplicates. + if( HDF5_INCLUDE_DIRS ) + list( REMOVE_DUPLICATES HDF5_INCLUDE_DIRS ) + endif() + if( HDF5_LIBRARIES_DEBUG ) + list( REMOVE_DUPLICATES HDF5_LIBRARIES_DEBUG ) + endif() + if( HDF5_LIBRARIES_RELEASE ) + list( REMOVE_DUPLICATES HDF5_LIBRARIES_RELEASE ) + endif() + if( HDF5_LIBRARY_DIRS ) + list( REMOVE_DUPLICATES HDF5_LIBRARY_DIRS ) + endif() -# Construct the complete list of HDF5 libraries with debug and optimized -# variants when the generator supports them. -if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) - set(HDF5_LIBRARIES - debug ${HDF5_LIBRARIES_DEBUG} - optimized ${HDF5_LIBRARIES_RELEASE}) -else() - set(HDF5_LIBRARIES ${HDF5_LIBRARIES_RELEASE}) -endif() + # Construct the complete list of HDF5 libraries with debug and optimized + # variants when the generator supports them. + if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) + set( HDF5_LIBRARIES + debug ${HDF5_LIBRARIES_DEBUG} + optimized ${HDF5_LIBRARIES_RELEASE} ) + else() + set( HDF5_LIBRARIES ${HDF5_LIBRARIES_RELEASE} ) + endif() -# If the HDF5 include directory was found, open H5pubconf.h to determine if -# HDF5 was compiled with parallel IO support -set(HDF5_IS_PARALLEL FALSE) -foreach(_dir HDF5_INCLUDE_DIRS) - if(EXISTS "${_dir}/H5pubconf.h") - file(STRINGS "${_dir}/H5pubconf.h" - HDF5_HAVE_PARALLEL_DEFINE - REGEX "HAVE_PARALLEL 1") - if(HDF5_HAVE_PARALLEL_DEFINE) - set(HDF5_IS_PARALLEL TRUE) + # If the HDF5 include directory was found, open H5pubconf.h to determine if + # HDF5 was compiled with parallel IO support + set( HDF5_IS_PARALLEL FALSE ) + foreach( _dir HDF5_INCLUDE_DIRS ) + if( EXISTS "${_dir}/H5pubconf.h" ) + file( STRINGS "${_dir}/H5pubconf.h" + HDF5_HAVE_PARALLEL_DEFINE + REGEX "HAVE_PARALLEL 1" ) + if( HDF5_HAVE_PARALLEL_DEFINE ) + set( HDF5_IS_PARALLEL TRUE ) + endif() endif() - endif() -endforeach() -set(HDF5_IS_PARALLEL ${HDF5_IS_PARALLEL} CACHE BOOL - "HDF5 library compiled with parallel IO support") -mark_as_advanced(HDF5_IS_PARALLEL) + endforeach() + set( HDF5_IS_PARALLEL ${HDF5_IS_PARALLEL} CACHE BOOL + "HDF5 library compiled with parallel IO support" ) + mark_as_advanced( HDF5_IS_PARALLEL ) endif() -find_package_handle_standard_args(HDF5 DEFAULT_MSG - HDF5_LIBRARIES +find_package_handle_standard_args( HDF5 DEFAULT_MSG + HDF5_LIBRARIES HDF5_INCLUDE_DIRS - ) +) -mark_as_advanced( - HDF5_INCLUDE_DIRS - HDF5_LIBRARIES +mark_as_advanced( + HDF5_INCLUDE_DIRS + HDF5_LIBRARIES HDF5_DEFINTIONS HDF5_LIBRARY_DIRS HDF5_C_COMPILER_EXECUTABLE - HDF5_CXX_COMPILER_EXECUTABLE) + HDF5_CXX_COMPILER_EXECUTABLE ) # For backwards compatibility we set HDF5_INCLUDE_DIR to the value of # HDF5_INCLUDE_DIRS -set(HDF5_INCLUDE_DIR "${HDF5_INCLUDE_DIRS}") +set( HDF5_INCLUDE_DIR "${HDF5_INCLUDE_DIRS}" ) + + From c8f8511e03225ad7a5f57ad339cba3767f1ca34a Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 10:27:41 -0500 Subject: [PATCH 227/314] tables->pytables --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6eecf5b8a2..5153f20149 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,6 +42,6 @@ script: #- ls -l $HOME/miniconda/lib #- ls -l $HOME/miniconda/envs/_build/lib - cycamore_unit_tests - - conda install numpy tables + - conda install numpy pytables - nosetests -w tests From 863ed175d38c45bf01468b1ab176c9d434539f2c Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Tue, 17 Feb 2015 12:50:14 -0600 Subject: [PATCH 228/314] Squashing commits from cyclus/cycamore#301. This should fail on CI. --- src/CMakeLists.txt | 2 + src/foo.cc | 171 +++++++++++++++++++++++++++++++++++++ src/foo.h | 204 +++++++++++++++++++++++++++++++++++++++++++++ src/foo_tests.cc | 204 +++++++++++++++++++++++++++++++++++++++++++++ src/foo_tests.h | 34 ++++++++ 5 files changed, 615 insertions(+) create mode 100644 src/foo.cc create mode 100644 src/foo.h create mode 100644 src/foo_tests.cc create mode 100644 src/foo_tests.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6a29fcff22..29e907624e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,8 @@ USE_CYCLUS("cycamore" "sink") USE_CYCLUS("cycamore" "source") +USE_CYCLUS("cycamore" "foo") + USE_CYCLUS("cycamore" "deploy_inst") USE_CYCLUS("cycamore" "manager_inst") diff --git a/src/foo.cc b/src/foo.cc new file mode 100644 index 0000000000..9ad8ada201 --- /dev/null +++ b/src/foo.cc @@ -0,0 +1,171 @@ +#include "foo.h" + +#include +#include + +#include + +namespace cycamore { + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Foo::Foo(cyclus::Context* ctx) + : cyclus::Facility(ctx), + out_commod(""), + recipe_name(""), + capacity(std::numeric_limits::max()) {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Foo::~Foo() {} + +#pragma cyclus def clone cycamore::Foo + +#pragma cyclus def schema cycamore::Foo + +#pragma cyclus def annotations cycamore::Foo + +#pragma cyclus def infiletodb cycamore::Foo + +#pragma cyclus def snapshot cycamore::Foo + +#pragma cyclus def snapshotinv cycamore::Foo + +#pragma cyclus def initinv cycamore::Foo + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::InitFrom(Foo* m) { + #pragma cyclus impl initfromcopy cycamore::Foo + cyclus::toolkit::CommodityProducer::Copy(m); +} + +void Foo::InitFrom(cyclus::QueryableBackend* b) { + #pragma cyclus impl initfromdb cycamore::Foo + + commod_ = cyclus::toolkit::Commodity(out_commod); + cyclus::toolkit::CommodityProducer::Add(commod_); + cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); + cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); +} + +void Foo::EnterNotify() { + Facility::EnterNotify(); + commod_ = cyclus::toolkit::Commodity(out_commod); + cyclus::toolkit::CommodityProducer::Add(commod_); + cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); + cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::string Foo::str() { + std::stringstream ss; + std::string ans; + if (cyclus::toolkit::CommodityProducer:: + Produces(cyclus::toolkit::Commodity(out_commod))) { + ans = "yes"; + } else { + ans = "no"; + } + ss << cyclus::Facility::str() + << " supplies commodity '" + << out_commod << "' with recipe '" + << recipe_name << "' at a capacity of " + << capacity << " kg per time step " + << " commod producer members: " << " produces " + << out_commod << "?: " << ans + << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(commod_) + << " cost: " << cyclus::toolkit::CommodityProducer::Cost(commod_); + return ss.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::Tick() { + LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is ticking {"; + LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity + << " kg of " + << out_commod << "."; + LOG(cyclus::LEV_INFO3, "SrcFac") << "Stats: " << str(); + LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; + current_capacity = capacity; // reset capacity +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::Tock() { + LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is tocking {"; + LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr Foo::GetOffer( + const cyclus::Material::Ptr target) const { + using cyclus::Material; + double qty = std::min(target->quantity(), capacity); + return Material::CreateUntracked(qty, context()->GetRecipe(recipe_name)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::set::Ptr> +Foo::GetMatlBids( + cyclus::CommodMap::type& commod_requests) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::Material; + using cyclus::Request; + + std::set::Ptr> ports; + + if (commod_requests.count(out_commod) > 0) { + BidPortfolio::Ptr port(new BidPortfolio()); + + std::vector*>& requests = + commod_requests[out_commod]; + + std::vector*>::iterator it; + for (it = requests.begin(); it != requests.end(); ++it) { + Request* req = *it; + Material::Ptr offer = GetOffer(req->target()); + port->AddBid(req, offer, this); + } + + CapacityConstraint cc(capacity); + port->AddConstraint(cc); + ports.insert(port); + } + return ports; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses) { + using cyclus::Material; + using cyclus::Trade; + + double provided = 0; + std::vector< cyclus::Trade >::const_iterator it; + for (it = trades.begin(); it != trades.end(); ++it) { + double qty = it->amt; + current_capacity -= qty; + provided += qty; + // @TODO we need a policy on negatives.. + Material::Ptr response = Material::Create(this, qty, + context()->GetRecipe(recipe_name)); + responses.push_back(std::make_pair(*it, response)); + LOG(cyclus::LEV_INFO5, "SrcFac") << prototype() << " just received an order" + << " for " << qty + << " of " << out_commod; + } + if (cyclus::IsNegative(current_capacity)) { + std::stringstream ss; + ss << "is being asked to provide " << provided + << " but its capacity is " << capacity << "."; + throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +extern "C" cyclus::Agent* ConstructFoo(cyclus::Context* ctx) { + return new Foo(ctx); +} + +} // namespace cycamore diff --git a/src/foo.h b/src/foo.h new file mode 100644 index 0000000000..e35ab83d99 --- /dev/null +++ b/src/foo.h @@ -0,0 +1,204 @@ +#ifndef CYCAMORE_SRC_FOO_H_ +#define CYCAMORE_SRC_FOO_H_ + +#include +#include + +#include "cyclus.h" + +namespace cycamore { + +class Context; + +/// @class Foo +/// This cyclus::Facility provides a simple source of some capacity +/// (possibly infinite) of some commodity/Recipe. + +/// The Foo class inherits from the cyclus::Facility class and is +/// dynamically loaded by the Agent class when requested. + +/// @section introduction Introduction +/// The Foo is a facility type in Cyclus capable of providing +/// a finite or infinite.Supply of a particular material to the +/// simulation. A Foo generates material of a certain +/// composition and commodity type, then offers that material on the +/// appropriate market. Shipments of this material are executed when the +/// market issues an order that the offer has been matched with a +/// request. + +/// @section agentparams Agent Parameters +/// Foo behavior is comprehensively defined by the following +/// parameters: +/// - double capacity: The production capacity of the facility (units +/// vary, but typically kg/month). Capacity is infinite if a negative +/// value is provided. +/// - int startDate: The date on which the facility begins to operate +/// (months). +/// - int lifeTime: The length of time that the facility operates +/// (months). - std::string outCommod: the commodity that this facility +/// produces - double inventorysize: the maximum quantity of material to +/// be held in the inventory +/// - double commodprice: the price of the output material PER UNIT +/// - map outComp + +/// @section optionalparams Optional Parameters +/// Foo behavior may also be specified with the following +/// optional parameters which have default values listed here. +/// - double capacityFactor: The ratio of actual production capacity to +/// the rated production capacity. Default is 1 (actual/rated). +/// - double availFactor: The percent of time the facility operates at +/// its capacity factor. Default is 100%. +/// - double capitalCost: The cost of constructing and commissioning +/// this facility. Default is 0 ($). +/// - double opCost: The annual cost of operation and maintenance of +/// this facility. Default is 0 ( $/year). +/// - int constrTime: The number of months it takes to construct and +/// commission this facility. Default is 0 (months). +/// - int decomTime: The number of months it takes to deconstruct and +/// decommission this facility. Default is 0 (months). +/// - Inst* inst: The institution responsible for this facility. +/// - string name: A non-generic name for this facility. + +/// @section detailed Detailed Behavior +/// @subsection finite If Finite Capacity: +/// The Foo starts operation when the simulation reaches the +/// month specified as the startDate. It immediately begins to produce +/// material at the rate defined by its capacity. Each month the +/// Foo adds the amount it has produced to its inventory. It +/// then offers to the appropriate market exactly as much material as it +/// has in its inventory. If an offer is matched with a request, the +/// Foo executes that order by subtracting the quantity from +/// its inventory and sending that amount to the requesting facility. +/// When the simulation time equals the startDate plus the lifeTime, the +/// facility ceases to operate. +/// @subsection infinite If Infinite Capacity: +/// The Foo starts operation when the simulation reaches the +/// month specified as the startDate. Each month the Foo +/// offers an infinite amount of material to the appropriate market. If +/// there is a request for that material, the Foo executes +/// that order by sending that amount to the requesting facility. When +/// the simulation time equals the startDate plus the lifeTime, the +/// facility ceases to operate. + +/// @subsection question Question: +/// What is the best way to allow offers of an infinite amount of +/// material on a market? + +class Foo : public cyclus::Facility, + public cyclus::toolkit::CommodityProducer { + public: + // --- Module Members --- + /// Constructor for the Foo class + /// @param ctx the cyclus context for access to simulation-wide parameters + Foo(cyclus::Context* ctx); + + virtual ~Foo() + + #pragma cyclus decl + + #pragma cyclus note {"doc": "A source facility that provides a " \ + "commodity with a given capacity"} + + /// Print information about this agent + virtual std::string str(); + // --- + + // --- Agent Members --- + virtual void EnterNotify(); + + /// Each facility is prompted to do its beginning-of-time-step + /// stuff at the tick of the timer. + + /// @param time is the time to perform the tick + virtual void Tick(); + + /// Each facility is prompted to its end-of-time-step + /// stuff on the tock of the timer. + + /// @param time is the time to perform the tock + virtual void Tock(); + + /// @brief Responds to each request for this source facility's commodity. + /// If a given request is more than this facility's capacity, it will offer + /// its capacity. + virtual std::set::Ptr> + GetMatlBids(cyclus::CommodMap::type& + commod_requests); + + /// @brief respond to each trade with a material made from this facility's + /// recipe + /// + /// @param trades all trades in which this trader is the supplier + /// @param responses a container to populate with responses to each trade + virtual void GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses); + // --- + + // --- Foo Members --- + /// @brief creates a material object to offer to a requester + /// @param target the material target a request desires + cyclus::Material::Ptr GetOffer(const cyclus::Material::Ptr target) const; + + /// sets the output commodity name + /// @param name the commodity name + inline void commodity(std::string name) { out_commod = name; } + + /// @return the output commodity + inline std::string commodity() const { return out_commod; } + + /// sets the capacity of a material generated at any given time step + /// @param capacity the production capacity + inline void Capacity(double cap) { + capacity = cap; + current_capacity = capacity; + } + + /// @return the production capacity at any given time step + inline double Capacity() const { return capacity; } + + /// sets the name of the recipe to be produced + /// @param name the recipe name + inline void recipe(std::string name) { recipe_name = name; } + + /// @return the name of the output recipe + inline std::string recipe() const { return recipe_name; } + + /// @return the current timestep's capacity + inline double CurrentCapacity() const { return current_capacity; } + + private: + cyclus::toolkit::Commodity commod_; + + /// This facility has only one output commodity + #pragma cyclus var {"tooltip": "source output commodity", \ + "doc": "output commodity that the source facility " \ + "supplies", \ + "uitype": "outcommodity"} + std::string out_commod; + + /// Name of the recipe this facility uses. + #pragma cyclus var {"tooltip": "commodity recipe name", \ + "doc": "recipe name for source facility's commodity", \ + "uitype": "recipe"} + std::string recipe_name; + + /// The capacity is defined in terms of the number of units of the + /// recipe that can be provided each time step. A very large number + /// can be provided to represent infinte capacity. + #pragma cyclus var {"default": 1e299, "tooltip": "source capacity", \ + "doc": "amount of commodity that can be supplied " \ + "at each time step"} + double capacity; + + /// The capacity at the current time step + #pragma cyclus var {'derived_init': 'current_capacity = capacity;'} + double current_capacity; + + // --- +}; + +} // namespace cycamore + +#endif // CYCAMORE_SRC_FOO_H_ diff --git a/src/foo_tests.cc b/src/foo_tests.cc new file mode 100644 index 0000000000..0973e794d0 --- /dev/null +++ b/src/foo_tests.cc @@ -0,0 +1,204 @@ +#include "foo_tests.h" + +#include + +#include + +#include "cyc_limits.h" +#include "resource_helpers.h" +#include "test_context.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::SetUp() { + src_facility = new cycamore::Foo(tc.get()); + trader = tc.trader(); + InitParameters(); + SetUpFoo(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::TearDown() { + delete src_facility; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::InitParameters() { + commod = "commod"; + recipe_name = "recipe"; + capacity = 5; // some magic number.. + + recipe = cyclus::Composition::CreateFromAtom(cyclus::CompMap()); + tc.get()->AddRecipe(recipe_name, recipe); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::SetUpFoo() { + src_facility->commodity(commod); + src_facility->recipe(recipe_name); + src_facility->Capacity(capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, InitialState) { + EXPECT_EQ(src_facility->Capacity(), capacity); + EXPECT_EQ(src_facility->commodity(), commod); + EXPECT_EQ(src_facility->recipe(), recipe_name); + EXPECT_EQ(src_facility->CurrentCapacity(), capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Clone) { + cyclus::Context* ctx = tc.get(); + cycamore::Foo* cloned_fac = dynamic_cast + (src_facility->Clone()); + + EXPECT_EQ(src_facility->commodity(), cloned_fac->commodity()); + EXPECT_EQ(src_facility->Capacity(), cloned_fac->Capacity()); + EXPECT_EQ(src_facility->recipe(), cloned_fac->recipe()); + EXPECT_EQ(src_facility->Capacity(), cloned_fac->CurrentCapacity()); + + delete cloned_fac; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Print) { + EXPECT_NO_THROW(std::string s = src_facility->str()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, GetOffer) { + using cyclus::Material; + + double qty = capacity - 1; + Material::Ptr mat = cyclus::NewBlankMaterial(qty); + Material::Ptr obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), qty); + EXPECT_EQ(obs_mat->comp(), recipe); + + qty = capacity + 1; + mat = cyclus::NewBlankMaterial(qty); + obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), capacity); + EXPECT_EQ(obs_mat->comp(), recipe); + + qty = capacity; + mat = cyclus::NewBlankMaterial(qty); + obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), capacity); + EXPECT_EQ(obs_mat->comp(), recipe); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, AddBids) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::ExchangeContext; + using cyclus::Material; + + int nreqs = 5; + + boost::shared_ptr< cyclus::ExchangeContext > + ec = GetContext(nreqs, commod); + + std::set::Ptr> ports = + src_facility->GetMatlBids(ec.get()->commod_requests); + + ASSERT_TRUE(ports.size() > 0); + EXPECT_EQ(ports.size(), 1); + + BidPortfolio::Ptr port = *ports.begin(); + EXPECT_EQ(port->bidder(), src_facility); + EXPECT_EQ(port->bids().size(), nreqs); + + const std::set< CapacityConstraint >& constrs = port->constraints(); + ASSERT_TRUE(constrs.size() > 0); + EXPECT_EQ(constrs.size(), 1); + EXPECT_EQ(*constrs.begin(), CapacityConstraint(capacity)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Response) { + using cyclus::Bid; + using cyclus::Material; + using cyclus::Request; + using cyclus::Trade; + using test_helpers::get_mat; + + std::vector< cyclus::Trade > trades; + std::vector, + cyclus::Material::Ptr> > responses; + + // Null response + EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); + EXPECT_EQ(responses.size(), 0); + + double qty = capacity / 3; + Request* request = + Request::Create(get_mat(), trader, commod); + Bid* bid = + Bid::Create(request, get_mat(), src_facility); + + Trade trade(request, bid, qty); + trades.push_back(trade); + + // 1 trade + ASSERT_EQ(src_facility->CurrentCapacity(), capacity); + src_facility->GetMatlTrades(trades, responses); + EXPECT_EQ(responses.size(), 1); + EXPECT_EQ(responses[0].second->quantity(), qty); + EXPECT_EQ(responses[0].second->comp(), recipe); + + // 2 trades, total qty = capacity + ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity - qty); + ASSERT_GT(src_facility->CurrentCapacity() - 2 * qty, -1 * cyclus::eps()); + trades.push_back(trade); + responses.clear(); + EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); + EXPECT_EQ(responses.size(), 2); + ASSERT_TRUE(cyclus::AlmostEq(src_facility->CurrentCapacity(), 0)); + + // too much qty, capn! + EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), + cyclus::ValueError); + + // reset! + src_facility->Tick(); + ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity); + + delete request; + delete bid; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +boost::shared_ptr< cyclus::ExchangeContext > +FooTest::GetContext(int nreqs, std::string commod) { + using cyclus::Material; + using cyclus::Request; + using cyclus::ExchangeContext; + using test_helpers::get_mat; + + double qty = 3; + boost::shared_ptr< ExchangeContext > + ec(new ExchangeContext()); + for (int i = 0; i < nreqs; i++) { + ec->AddRequest(Request::Create(get_mat(), trader, commod)); + } + return ec; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Agent* FooConstructor(cyclus::Context* ctx) { + return new cycamore::Foo(ctx); +} + +// required to get functionality in cyclus agent unit tests library +#ifndef CYCLUS_AGENT_TESTS_CONNECTED +int ConnectAgentTests(); +static int cyclus_agent_tests_connected = ConnectAgentTests(); +#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected +#endif // CYCLUS_AGENT_TESTS_CONNECTED + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +INSTANTIATE_TEST_CASE_P(FooFac, FacilityTests, Values(&FooConstructor)); +INSTANTIATE_TEST_CASE_P(FooFac, AgentTests, Values(&FooConstructor)); diff --git a/src/foo_tests.h b/src/foo_tests.h new file mode 100644 index 0000000000..59888926b7 --- /dev/null +++ b/src/foo_tests.h @@ -0,0 +1,34 @@ +#ifndef CYCAMORE_SRC_FOO_TESTS_H_ +#define CYCAMORE_SRC_FOO_TESTS_H_ +#include "foo.h" + +#include + +#include + +#include "agent_tests.h" +#include "context.h" +#include "exchange_context.h" +#include "facility_tests.h" +#include "material.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +class FooTest : public ::testing::Test { + public: + cyclus::TestContext tc; + TestFacility* trader; + cycamore::Foo* src_facility; + std::string commod, recipe_name; + double capacity; + cyclus::Composition::Ptr recipe; + + virtual void SetUp(); + virtual void TearDown(); + void InitParameters(); + void SetUpFoo(); + + boost::shared_ptr< cyclus::ExchangeContext > + GetContext(int nreqs, std::string commodity); +}; + +#endif // CYCAMORE_SRC_FOO_TESTS_H_ From 163b667017150772b37d51dbc4107d942be1259c Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 10:56:49 -0500 Subject: [PATCH 229/314] adding same hdf5 messages as cyclus --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4985e62e56..f2d1f2b451 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,6 +104,10 @@ IF(NOT CYCLUS_DOC_ONLY) FIND_PACKAGE(HDF5 REQUIRED) ADD_DEFINITIONS(${HDF5_DEFINITIONS}) set(LIBS ${LIBS} ${HDF5_LIBRARIES}) + MESSAGE("-- HDF5 Root: ${HDF5_ROOT}") + MESSAGE("-- HDF5 Include directory: ${HDF5_INCLUDE_DIR}") + MESSAGE("-- HDF5 Library directories: ${HDF5_LIBRARY_DIRS}") + MESSAGE("-- HDF5 Libraries: ${HDF5_LIBRARIES}") # find coin and link to it FIND_PACKAGE(COIN REQUIRED) From 0135e3778d39de7ccbeab1717428643062b40860 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 11:07:56 -0500 Subject: [PATCH 230/314] matching cyclus findhdf --- cmake/FindHDF5.cmake | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/cmake/FindHDF5.cmake b/cmake/FindHDF5.cmake index 5b7cadd022..c7f7d73bee 100644 --- a/cmake/FindHDF5.cmake +++ b/cmake/FindHDF5.cmake @@ -20,8 +20,9 @@ # HDF5_USE_STATIC_LIBRARIES variable is set before the call to find_package. # # To provide the module with a hint about where to find your HDF5 installation, -# you can set the environment variable HDF5_ROOT. The Find module will then -# look in this path when searching for HDF5 executables, paths, and libraries. +# you can set the CMAKE variable -OR- environment variable HDF5_ROOT. The Find +# module will then look in this path when searching for HDF5 executables, paths, +# and libraries. # # In addition to finding the includes and libraries required to compile an HDF5 # client application, this module also makes an effort to find tools that come @@ -68,21 +69,21 @@ set( HDF5_VALID_COMPONENTS # try to find the HDF5 wrapper compilers find_program( HDF5_C_COMPILER_EXECUTABLE NAMES h5cc h5pcc - HINTS ENV HDF5_ROOT + HINTS "${HDF5_ROOT}" ENV HDF5_ROOT PATH_SUFFIXES bin Bin DOC "HDF5 Wrapper compiler. Used only to detect HDF5 compile flags." ) mark_as_advanced( HDF5_C_COMPILER_EXECUTABLE ) find_program( HDF5_CXX_COMPILER_EXECUTABLE NAMES h5c++ h5pc++ - HINTS ENV HDF5_ROOT + HINTS "${HDF5_ROOT}" ENV HDF5_ROOT PATH_SUFFIXES bin Bin DOC "HDF5 C++ Wrapper compiler. Used only to detect HDF5 compile flags." ) mark_as_advanced( HDF5_CXX_COMPILER_EXECUTABLE ) find_program( HDF5_DIFF_EXECUTABLE NAMES h5diff - HINTS ENV HDF5_ROOT + HINTS "${HDF5_ROOT}" ENV HDF5_ROOT PATH_SUFFIXES bin Bin DOC "HDF5 file differencing tool." ) mark_as_advanced( HDF5_DIFF_EXECUTABLE ) @@ -200,6 +201,7 @@ else() # find the HDF5 include directories find_path( HDF5_${LANGUAGE}_INCLUDE_DIR hdf5.h HINTS + "${HDF5_ROOT}" ${HDF5_${LANGUAGE}_INCLUDE_FLAGS} ENV HDF5_ROOT @@ -232,12 +234,12 @@ else() endif() find_library( HDF5_${LIB}_LIBRARY_DEBUG NAMES ${THIS_LIBRARY_SEARCH_DEBUG} - HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} + HINTS "${HDF5_ROOT}" ${HDF5_${LANGUAGE}_LIBRARY_DIRS} ENV HDF5_ROOT PATH_SUFFIXES lib Lib ) find_library( HDF5_${LIB}_LIBRARY_RELEASE NAMES ${THIS_LIBRARY_SEARCH_RELEASE} - HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} + HINTS "${HDF5_ROOT}" ${HDF5_${LANGUAGE}_LIBRARY_DIRS} ENV HDF5_ROOT PATH_SUFFIXES lib Lib ) select_library_configurations( HDF5_${LIB} ) From efc22ae7bd3ea5c6452c5d0ad66419a5c309f30c Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 11:19:12 -0500 Subject: [PATCH 231/314] early exit on failure --- .travis-install.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.travis-install.sh b/.travis-install.sh index 0ab998f721..46059223a9 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -2,4 +2,11 @@ wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml conda build --no-test conda-recipe -conda install --use-local cycamore=0.0 \ No newline at end of file + +if [[ $? != 0 ]]; then + exit $? + +conda install --use-local cycamore=0.0 + +if [[ $? != 0 ]]; then + exit $? From 7d8fce0f30ecb9a6dfc75f7cb633a40a90526cf5 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 11:19:37 -0500 Subject: [PATCH 232/314] Revert "Squashing commits from cyclus/cycamore#301. This should fail on CI." This reverts commit 4f25661c7fe06f815000ea851fa0a9d127678335. --- src/CMakeLists.txt | 2 - src/foo.cc | 171 ------------------------------------- src/foo.h | 204 --------------------------------------------- src/foo_tests.cc | 204 --------------------------------------------- src/foo_tests.h | 34 -------- 5 files changed, 615 deletions(-) delete mode 100644 src/foo.cc delete mode 100644 src/foo.h delete mode 100644 src/foo_tests.cc delete mode 100644 src/foo_tests.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 29e907624e..6a29fcff22 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,8 +12,6 @@ USE_CYCLUS("cycamore" "sink") USE_CYCLUS("cycamore" "source") -USE_CYCLUS("cycamore" "foo") - USE_CYCLUS("cycamore" "deploy_inst") USE_CYCLUS("cycamore" "manager_inst") diff --git a/src/foo.cc b/src/foo.cc deleted file mode 100644 index 9ad8ada201..0000000000 --- a/src/foo.cc +++ /dev/null @@ -1,171 +0,0 @@ -#include "foo.h" - -#include -#include - -#include - -namespace cycamore { - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Foo::Foo(cyclus::Context* ctx) - : cyclus::Facility(ctx), - out_commod(""), - recipe_name(""), - capacity(std::numeric_limits::max()) {} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Foo::~Foo() {} - -#pragma cyclus def clone cycamore::Foo - -#pragma cyclus def schema cycamore::Foo - -#pragma cyclus def annotations cycamore::Foo - -#pragma cyclus def infiletodb cycamore::Foo - -#pragma cyclus def snapshot cycamore::Foo - -#pragma cyclus def snapshotinv cycamore::Foo - -#pragma cyclus def initinv cycamore::Foo - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::InitFrom(Foo* m) { - #pragma cyclus impl initfromcopy cycamore::Foo - cyclus::toolkit::CommodityProducer::Copy(m); -} - -void Foo::InitFrom(cyclus::QueryableBackend* b) { - #pragma cyclus impl initfromdb cycamore::Foo - - commod_ = cyclus::toolkit::Commodity(out_commod); - cyclus::toolkit::CommodityProducer::Add(commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); - cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); -} - -void Foo::EnterNotify() { - Facility::EnterNotify(); - commod_ = cyclus::toolkit::Commodity(out_commod); - cyclus::toolkit::CommodityProducer::Add(commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); - cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::string Foo::str() { - std::stringstream ss; - std::string ans; - if (cyclus::toolkit::CommodityProducer:: - Produces(cyclus::toolkit::Commodity(out_commod))) { - ans = "yes"; - } else { - ans = "no"; - } - ss << cyclus::Facility::str() - << " supplies commodity '" - << out_commod << "' with recipe '" - << recipe_name << "' at a capacity of " - << capacity << " kg per time step " - << " commod producer members: " << " produces " - << out_commod << "?: " << ans - << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(commod_) - << " cost: " << cyclus::toolkit::CommodityProducer::Cost(commod_); - return ss.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::Tick() { - LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is ticking {"; - LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity - << " kg of " - << out_commod << "."; - LOG(cyclus::LEV_INFO3, "SrcFac") << "Stats: " << str(); - LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; - current_capacity = capacity; // reset capacity -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::Tock() { - LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is tocking {"; - LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr Foo::GetOffer( - const cyclus::Material::Ptr target) const { - using cyclus::Material; - double qty = std::min(target->quantity(), capacity); - return Material::CreateUntracked(qty, context()->GetRecipe(recipe_name)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -Foo::GetMatlBids( - cyclus::CommodMap::type& commod_requests) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::Material; - using cyclus::Request; - - std::set::Ptr> ports; - - if (commod_requests.count(out_commod) > 0) { - BidPortfolio::Ptr port(new BidPortfolio()); - - std::vector*>& requests = - commod_requests[out_commod]; - - std::vector*>::iterator it; - for (it = requests.begin(); it != requests.end(); ++it) { - Request* req = *it; - Material::Ptr offer = GetOffer(req->target()); - port->AddBid(req, offer, this); - } - - CapacityConstraint cc(capacity); - port->AddConstraint(cc); - ports.insert(port); - } - return ports; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses) { - using cyclus::Material; - using cyclus::Trade; - - double provided = 0; - std::vector< cyclus::Trade >::const_iterator it; - for (it = trades.begin(); it != trades.end(); ++it) { - double qty = it->amt; - current_capacity -= qty; - provided += qty; - // @TODO we need a policy on negatives.. - Material::Ptr response = Material::Create(this, qty, - context()->GetRecipe(recipe_name)); - responses.push_back(std::make_pair(*it, response)); - LOG(cyclus::LEV_INFO5, "SrcFac") << prototype() << " just received an order" - << " for " << qty - << " of " << out_commod; - } - if (cyclus::IsNegative(current_capacity)) { - std::stringstream ss; - ss << "is being asked to provide " << provided - << " but its capacity is " << capacity << "."; - throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern "C" cyclus::Agent* ConstructFoo(cyclus::Context* ctx) { - return new Foo(ctx); -} - -} // namespace cycamore diff --git a/src/foo.h b/src/foo.h deleted file mode 100644 index e35ab83d99..0000000000 --- a/src/foo.h +++ /dev/null @@ -1,204 +0,0 @@ -#ifndef CYCAMORE_SRC_FOO_H_ -#define CYCAMORE_SRC_FOO_H_ - -#include -#include - -#include "cyclus.h" - -namespace cycamore { - -class Context; - -/// @class Foo -/// This cyclus::Facility provides a simple source of some capacity -/// (possibly infinite) of some commodity/Recipe. - -/// The Foo class inherits from the cyclus::Facility class and is -/// dynamically loaded by the Agent class when requested. - -/// @section introduction Introduction -/// The Foo is a facility type in Cyclus capable of providing -/// a finite or infinite.Supply of a particular material to the -/// simulation. A Foo generates material of a certain -/// composition and commodity type, then offers that material on the -/// appropriate market. Shipments of this material are executed when the -/// market issues an order that the offer has been matched with a -/// request. - -/// @section agentparams Agent Parameters -/// Foo behavior is comprehensively defined by the following -/// parameters: -/// - double capacity: The production capacity of the facility (units -/// vary, but typically kg/month). Capacity is infinite if a negative -/// value is provided. -/// - int startDate: The date on which the facility begins to operate -/// (months). -/// - int lifeTime: The length of time that the facility operates -/// (months). - std::string outCommod: the commodity that this facility -/// produces - double inventorysize: the maximum quantity of material to -/// be held in the inventory -/// - double commodprice: the price of the output material PER UNIT -/// - map outComp - -/// @section optionalparams Optional Parameters -/// Foo behavior may also be specified with the following -/// optional parameters which have default values listed here. -/// - double capacityFactor: The ratio of actual production capacity to -/// the rated production capacity. Default is 1 (actual/rated). -/// - double availFactor: The percent of time the facility operates at -/// its capacity factor. Default is 100%. -/// - double capitalCost: The cost of constructing and commissioning -/// this facility. Default is 0 ($). -/// - double opCost: The annual cost of operation and maintenance of -/// this facility. Default is 0 ( $/year). -/// - int constrTime: The number of months it takes to construct and -/// commission this facility. Default is 0 (months). -/// - int decomTime: The number of months it takes to deconstruct and -/// decommission this facility. Default is 0 (months). -/// - Inst* inst: The institution responsible for this facility. -/// - string name: A non-generic name for this facility. - -/// @section detailed Detailed Behavior -/// @subsection finite If Finite Capacity: -/// The Foo starts operation when the simulation reaches the -/// month specified as the startDate. It immediately begins to produce -/// material at the rate defined by its capacity. Each month the -/// Foo adds the amount it has produced to its inventory. It -/// then offers to the appropriate market exactly as much material as it -/// has in its inventory. If an offer is matched with a request, the -/// Foo executes that order by subtracting the quantity from -/// its inventory and sending that amount to the requesting facility. -/// When the simulation time equals the startDate plus the lifeTime, the -/// facility ceases to operate. -/// @subsection infinite If Infinite Capacity: -/// The Foo starts operation when the simulation reaches the -/// month specified as the startDate. Each month the Foo -/// offers an infinite amount of material to the appropriate market. If -/// there is a request for that material, the Foo executes -/// that order by sending that amount to the requesting facility. When -/// the simulation time equals the startDate plus the lifeTime, the -/// facility ceases to operate. - -/// @subsection question Question: -/// What is the best way to allow offers of an infinite amount of -/// material on a market? - -class Foo : public cyclus::Facility, - public cyclus::toolkit::CommodityProducer { - public: - // --- Module Members --- - /// Constructor for the Foo class - /// @param ctx the cyclus context for access to simulation-wide parameters - Foo(cyclus::Context* ctx); - - virtual ~Foo() - - #pragma cyclus decl - - #pragma cyclus note {"doc": "A source facility that provides a " \ - "commodity with a given capacity"} - - /// Print information about this agent - virtual std::string str(); - // --- - - // --- Agent Members --- - virtual void EnterNotify(); - - /// Each facility is prompted to do its beginning-of-time-step - /// stuff at the tick of the timer. - - /// @param time is the time to perform the tick - virtual void Tick(); - - /// Each facility is prompted to its end-of-time-step - /// stuff on the tock of the timer. - - /// @param time is the time to perform the tock - virtual void Tock(); - - /// @brief Responds to each request for this source facility's commodity. - /// If a given request is more than this facility's capacity, it will offer - /// its capacity. - virtual std::set::Ptr> - GetMatlBids(cyclus::CommodMap::type& - commod_requests); - - /// @brief respond to each trade with a material made from this facility's - /// recipe - /// - /// @param trades all trades in which this trader is the supplier - /// @param responses a container to populate with responses to each trade - virtual void GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses); - // --- - - // --- Foo Members --- - /// @brief creates a material object to offer to a requester - /// @param target the material target a request desires - cyclus::Material::Ptr GetOffer(const cyclus::Material::Ptr target) const; - - /// sets the output commodity name - /// @param name the commodity name - inline void commodity(std::string name) { out_commod = name; } - - /// @return the output commodity - inline std::string commodity() const { return out_commod; } - - /// sets the capacity of a material generated at any given time step - /// @param capacity the production capacity - inline void Capacity(double cap) { - capacity = cap; - current_capacity = capacity; - } - - /// @return the production capacity at any given time step - inline double Capacity() const { return capacity; } - - /// sets the name of the recipe to be produced - /// @param name the recipe name - inline void recipe(std::string name) { recipe_name = name; } - - /// @return the name of the output recipe - inline std::string recipe() const { return recipe_name; } - - /// @return the current timestep's capacity - inline double CurrentCapacity() const { return current_capacity; } - - private: - cyclus::toolkit::Commodity commod_; - - /// This facility has only one output commodity - #pragma cyclus var {"tooltip": "source output commodity", \ - "doc": "output commodity that the source facility " \ - "supplies", \ - "uitype": "outcommodity"} - std::string out_commod; - - /// Name of the recipe this facility uses. - #pragma cyclus var {"tooltip": "commodity recipe name", \ - "doc": "recipe name for source facility's commodity", \ - "uitype": "recipe"} - std::string recipe_name; - - /// The capacity is defined in terms of the number of units of the - /// recipe that can be provided each time step. A very large number - /// can be provided to represent infinte capacity. - #pragma cyclus var {"default": 1e299, "tooltip": "source capacity", \ - "doc": "amount of commodity that can be supplied " \ - "at each time step"} - double capacity; - - /// The capacity at the current time step - #pragma cyclus var {'derived_init': 'current_capacity = capacity;'} - double current_capacity; - - // --- -}; - -} // namespace cycamore - -#endif // CYCAMORE_SRC_FOO_H_ diff --git a/src/foo_tests.cc b/src/foo_tests.cc deleted file mode 100644 index 0973e794d0..0000000000 --- a/src/foo_tests.cc +++ /dev/null @@ -1,204 +0,0 @@ -#include "foo_tests.h" - -#include - -#include - -#include "cyc_limits.h" -#include "resource_helpers.h" -#include "test_context.h" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::SetUp() { - src_facility = new cycamore::Foo(tc.get()); - trader = tc.trader(); - InitParameters(); - SetUpFoo(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::TearDown() { - delete src_facility; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::InitParameters() { - commod = "commod"; - recipe_name = "recipe"; - capacity = 5; // some magic number.. - - recipe = cyclus::Composition::CreateFromAtom(cyclus::CompMap()); - tc.get()->AddRecipe(recipe_name, recipe); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::SetUpFoo() { - src_facility->commodity(commod); - src_facility->recipe(recipe_name); - src_facility->Capacity(capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, InitialState) { - EXPECT_EQ(src_facility->Capacity(), capacity); - EXPECT_EQ(src_facility->commodity(), commod); - EXPECT_EQ(src_facility->recipe(), recipe_name); - EXPECT_EQ(src_facility->CurrentCapacity(), capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Clone) { - cyclus::Context* ctx = tc.get(); - cycamore::Foo* cloned_fac = dynamic_cast - (src_facility->Clone()); - - EXPECT_EQ(src_facility->commodity(), cloned_fac->commodity()); - EXPECT_EQ(src_facility->Capacity(), cloned_fac->Capacity()); - EXPECT_EQ(src_facility->recipe(), cloned_fac->recipe()); - EXPECT_EQ(src_facility->Capacity(), cloned_fac->CurrentCapacity()); - - delete cloned_fac; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Print) { - EXPECT_NO_THROW(std::string s = src_facility->str()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, GetOffer) { - using cyclus::Material; - - double qty = capacity - 1; - Material::Ptr mat = cyclus::NewBlankMaterial(qty); - Material::Ptr obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), qty); - EXPECT_EQ(obs_mat->comp(), recipe); - - qty = capacity + 1; - mat = cyclus::NewBlankMaterial(qty); - obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), capacity); - EXPECT_EQ(obs_mat->comp(), recipe); - - qty = capacity; - mat = cyclus::NewBlankMaterial(qty); - obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), capacity); - EXPECT_EQ(obs_mat->comp(), recipe); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, AddBids) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::ExchangeContext; - using cyclus::Material; - - int nreqs = 5; - - boost::shared_ptr< cyclus::ExchangeContext > - ec = GetContext(nreqs, commod); - - std::set::Ptr> ports = - src_facility->GetMatlBids(ec.get()->commod_requests); - - ASSERT_TRUE(ports.size() > 0); - EXPECT_EQ(ports.size(), 1); - - BidPortfolio::Ptr port = *ports.begin(); - EXPECT_EQ(port->bidder(), src_facility); - EXPECT_EQ(port->bids().size(), nreqs); - - const std::set< CapacityConstraint >& constrs = port->constraints(); - ASSERT_TRUE(constrs.size() > 0); - EXPECT_EQ(constrs.size(), 1); - EXPECT_EQ(*constrs.begin(), CapacityConstraint(capacity)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Response) { - using cyclus::Bid; - using cyclus::Material; - using cyclus::Request; - using cyclus::Trade; - using test_helpers::get_mat; - - std::vector< cyclus::Trade > trades; - std::vector, - cyclus::Material::Ptr> > responses; - - // Null response - EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); - EXPECT_EQ(responses.size(), 0); - - double qty = capacity / 3; - Request* request = - Request::Create(get_mat(), trader, commod); - Bid* bid = - Bid::Create(request, get_mat(), src_facility); - - Trade trade(request, bid, qty); - trades.push_back(trade); - - // 1 trade - ASSERT_EQ(src_facility->CurrentCapacity(), capacity); - src_facility->GetMatlTrades(trades, responses); - EXPECT_EQ(responses.size(), 1); - EXPECT_EQ(responses[0].second->quantity(), qty); - EXPECT_EQ(responses[0].second->comp(), recipe); - - // 2 trades, total qty = capacity - ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity - qty); - ASSERT_GT(src_facility->CurrentCapacity() - 2 * qty, -1 * cyclus::eps()); - trades.push_back(trade); - responses.clear(); - EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); - EXPECT_EQ(responses.size(), 2); - ASSERT_TRUE(cyclus::AlmostEq(src_facility->CurrentCapacity(), 0)); - - // too much qty, capn! - EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), - cyclus::ValueError); - - // reset! - src_facility->Tick(); - ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity); - - delete request; - delete bid; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -boost::shared_ptr< cyclus::ExchangeContext > -FooTest::GetContext(int nreqs, std::string commod) { - using cyclus::Material; - using cyclus::Request; - using cyclus::ExchangeContext; - using test_helpers::get_mat; - - double qty = 3; - boost::shared_ptr< ExchangeContext > - ec(new ExchangeContext()); - for (int i = 0; i < nreqs; i++) { - ec->AddRequest(Request::Create(get_mat(), trader, commod)); - } - return ec; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Agent* FooConstructor(cyclus::Context* ctx) { - return new cycamore::Foo(ctx); -} - -// required to get functionality in cyclus agent unit tests library -#ifndef CYCLUS_AGENT_TESTS_CONNECTED -int ConnectAgentTests(); -static int cyclus_agent_tests_connected = ConnectAgentTests(); -#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected -#endif // CYCLUS_AGENT_TESTS_CONNECTED - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -INSTANTIATE_TEST_CASE_P(FooFac, FacilityTests, Values(&FooConstructor)); -INSTANTIATE_TEST_CASE_P(FooFac, AgentTests, Values(&FooConstructor)); diff --git a/src/foo_tests.h b/src/foo_tests.h deleted file mode 100644 index 59888926b7..0000000000 --- a/src/foo_tests.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef CYCAMORE_SRC_FOO_TESTS_H_ -#define CYCAMORE_SRC_FOO_TESTS_H_ -#include "foo.h" - -#include - -#include - -#include "agent_tests.h" -#include "context.h" -#include "exchange_context.h" -#include "facility_tests.h" -#include "material.h" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -class FooTest : public ::testing::Test { - public: - cyclus::TestContext tc; - TestFacility* trader; - cycamore::Foo* src_facility; - std::string commod, recipe_name; - double capacity; - cyclus::Composition::Ptr recipe; - - virtual void SetUp(); - virtual void TearDown(); - void InitParameters(); - void SetUpFoo(); - - boost::shared_ptr< cyclus::ExchangeContext > - GetContext(int nreqs, std::string commodity); -}; - -#endif // CYCAMORE_SRC_FOO_TESTS_H_ From 5d23df9c078a76f1c8974ba83119930cea73ecaa Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 11:38:35 -0500 Subject: [PATCH 233/314] explicit status var --- .travis-install.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis-install.sh b/.travis-install.sh index 46059223a9..40e99c99c5 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -3,10 +3,12 @@ unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml conda build --no-test conda-recipe -if [[ $? != 0 ]]; then - exit $? +status=$? +if [[ $status != 0 ]]; then + exit $status conda install --use-local cycamore=0.0 -if [[ $? != 0 ]]; then - exit $? +status=$? +if [[ $status != 0 ]]; then + exit $status From b6331f85393a7b28a07426748dc2d2286b917acd Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 12:09:19 -0500 Subject: [PATCH 234/314] fixed syntax errors added logging --- .travis-install.sh | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.travis-install.sh b/.travis-install.sh index 40e99c99c5..1e53559839 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -1,14 +1,26 @@ +#!/bin/bash + +# setup conda recipe wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml -conda build --no-test conda-recipe +# build +cmd="conda build --no-test conda-recipe" +echo "cmd: $cmd" +$cmd status=$? +echo "status: $status" if [[ $status != 0 ]]; then exit $status +fi -conda install --use-local cycamore=0.0 - +# install +cmd="conda install --use-local cycamore=0.0" +echo "cmd: $cmd" +$cmd status=$? +echo "status: $status" if [[ $status != 0 ]]; then exit $status +fi From bb75eeb82f380107adfe9e8d3321e1dff7c84ce4 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 12:45:13 -0500 Subject: [PATCH 235/314] should fail --- src/reactor_tests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactor_tests.cc b/src/reactor_tests.cc index 8c743e5cf4..7ba33e8cc0 100644 --- a/src/reactor_tests.cc +++ b/src/reactor_tests.cc @@ -131,7 +131,7 @@ TEST(ReactorTests, RefuelTimes) { QueryResult qr = sim.db().Query("Transactions", NULL); int cyclet = 4; - int refuelt = 3; + int refuelt = 2; int n_assem_want = simdur/(cyclet+refuelt)+1; // +1 for initial core EXPECT_EQ(n_assem_want, qr.rows.size()); } From e28cc54ba3c2a387509f5b8961129e6591f35829 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 12:45:21 -0500 Subject: [PATCH 236/314] Revert "should fail" This reverts commit 42fea0add138d2d30b182dae84f9468b85594aa7. --- src/reactor_tests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactor_tests.cc b/src/reactor_tests.cc index 7ba33e8cc0..8c743e5cf4 100644 --- a/src/reactor_tests.cc +++ b/src/reactor_tests.cc @@ -131,7 +131,7 @@ TEST(ReactorTests, RefuelTimes) { QueryResult qr = sim.db().Query("Transactions", NULL); int cyclet = 4; - int refuelt = 2; + int refuelt = 3; int n_assem_want = simdur/(cyclet+refuelt)+1; // +1 for initial core EXPECT_EQ(n_assem_want, qr.rows.size()); } From daf399a8ed521c9d1f031bcb1264ed085567ec62 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Tue, 17 Feb 2015 12:50:14 -0600 Subject: [PATCH 237/314] Squashing commits from cyclus/cycamore#301. This should fail on CI. --- src/CMakeLists.txt | 2 + src/foo.cc | 171 +++++++++++++++++++++++++++++++++++++ src/foo.h | 204 +++++++++++++++++++++++++++++++++++++++++++++ src/foo_tests.cc | 204 +++++++++++++++++++++++++++++++++++++++++++++ src/foo_tests.h | 34 ++++++++ 5 files changed, 615 insertions(+) create mode 100644 src/foo.cc create mode 100644 src/foo.h create mode 100644 src/foo_tests.cc create mode 100644 src/foo_tests.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6a29fcff22..29e907624e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,8 @@ USE_CYCLUS("cycamore" "sink") USE_CYCLUS("cycamore" "source") +USE_CYCLUS("cycamore" "foo") + USE_CYCLUS("cycamore" "deploy_inst") USE_CYCLUS("cycamore" "manager_inst") diff --git a/src/foo.cc b/src/foo.cc new file mode 100644 index 0000000000..9ad8ada201 --- /dev/null +++ b/src/foo.cc @@ -0,0 +1,171 @@ +#include "foo.h" + +#include +#include + +#include + +namespace cycamore { + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Foo::Foo(cyclus::Context* ctx) + : cyclus::Facility(ctx), + out_commod(""), + recipe_name(""), + capacity(std::numeric_limits::max()) {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Foo::~Foo() {} + +#pragma cyclus def clone cycamore::Foo + +#pragma cyclus def schema cycamore::Foo + +#pragma cyclus def annotations cycamore::Foo + +#pragma cyclus def infiletodb cycamore::Foo + +#pragma cyclus def snapshot cycamore::Foo + +#pragma cyclus def snapshotinv cycamore::Foo + +#pragma cyclus def initinv cycamore::Foo + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::InitFrom(Foo* m) { + #pragma cyclus impl initfromcopy cycamore::Foo + cyclus::toolkit::CommodityProducer::Copy(m); +} + +void Foo::InitFrom(cyclus::QueryableBackend* b) { + #pragma cyclus impl initfromdb cycamore::Foo + + commod_ = cyclus::toolkit::Commodity(out_commod); + cyclus::toolkit::CommodityProducer::Add(commod_); + cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); + cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); +} + +void Foo::EnterNotify() { + Facility::EnterNotify(); + commod_ = cyclus::toolkit::Commodity(out_commod); + cyclus::toolkit::CommodityProducer::Add(commod_); + cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); + cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::string Foo::str() { + std::stringstream ss; + std::string ans; + if (cyclus::toolkit::CommodityProducer:: + Produces(cyclus::toolkit::Commodity(out_commod))) { + ans = "yes"; + } else { + ans = "no"; + } + ss << cyclus::Facility::str() + << " supplies commodity '" + << out_commod << "' with recipe '" + << recipe_name << "' at a capacity of " + << capacity << " kg per time step " + << " commod producer members: " << " produces " + << out_commod << "?: " << ans + << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(commod_) + << " cost: " << cyclus::toolkit::CommodityProducer::Cost(commod_); + return ss.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::Tick() { + LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is ticking {"; + LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity + << " kg of " + << out_commod << "."; + LOG(cyclus::LEV_INFO3, "SrcFac") << "Stats: " << str(); + LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; + current_capacity = capacity; // reset capacity +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::Tock() { + LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is tocking {"; + LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr Foo::GetOffer( + const cyclus::Material::Ptr target) const { + using cyclus::Material; + double qty = std::min(target->quantity(), capacity); + return Material::CreateUntracked(qty, context()->GetRecipe(recipe_name)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::set::Ptr> +Foo::GetMatlBids( + cyclus::CommodMap::type& commod_requests) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::Material; + using cyclus::Request; + + std::set::Ptr> ports; + + if (commod_requests.count(out_commod) > 0) { + BidPortfolio::Ptr port(new BidPortfolio()); + + std::vector*>& requests = + commod_requests[out_commod]; + + std::vector*>::iterator it; + for (it = requests.begin(); it != requests.end(); ++it) { + Request* req = *it; + Material::Ptr offer = GetOffer(req->target()); + port->AddBid(req, offer, this); + } + + CapacityConstraint cc(capacity); + port->AddConstraint(cc); + ports.insert(port); + } + return ports; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses) { + using cyclus::Material; + using cyclus::Trade; + + double provided = 0; + std::vector< cyclus::Trade >::const_iterator it; + for (it = trades.begin(); it != trades.end(); ++it) { + double qty = it->amt; + current_capacity -= qty; + provided += qty; + // @TODO we need a policy on negatives.. + Material::Ptr response = Material::Create(this, qty, + context()->GetRecipe(recipe_name)); + responses.push_back(std::make_pair(*it, response)); + LOG(cyclus::LEV_INFO5, "SrcFac") << prototype() << " just received an order" + << " for " << qty + << " of " << out_commod; + } + if (cyclus::IsNegative(current_capacity)) { + std::stringstream ss; + ss << "is being asked to provide " << provided + << " but its capacity is " << capacity << "."; + throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +extern "C" cyclus::Agent* ConstructFoo(cyclus::Context* ctx) { + return new Foo(ctx); +} + +} // namespace cycamore diff --git a/src/foo.h b/src/foo.h new file mode 100644 index 0000000000..e35ab83d99 --- /dev/null +++ b/src/foo.h @@ -0,0 +1,204 @@ +#ifndef CYCAMORE_SRC_FOO_H_ +#define CYCAMORE_SRC_FOO_H_ + +#include +#include + +#include "cyclus.h" + +namespace cycamore { + +class Context; + +/// @class Foo +/// This cyclus::Facility provides a simple source of some capacity +/// (possibly infinite) of some commodity/Recipe. + +/// The Foo class inherits from the cyclus::Facility class and is +/// dynamically loaded by the Agent class when requested. + +/// @section introduction Introduction +/// The Foo is a facility type in Cyclus capable of providing +/// a finite or infinite.Supply of a particular material to the +/// simulation. A Foo generates material of a certain +/// composition and commodity type, then offers that material on the +/// appropriate market. Shipments of this material are executed when the +/// market issues an order that the offer has been matched with a +/// request. + +/// @section agentparams Agent Parameters +/// Foo behavior is comprehensively defined by the following +/// parameters: +/// - double capacity: The production capacity of the facility (units +/// vary, but typically kg/month). Capacity is infinite if a negative +/// value is provided. +/// - int startDate: The date on which the facility begins to operate +/// (months). +/// - int lifeTime: The length of time that the facility operates +/// (months). - std::string outCommod: the commodity that this facility +/// produces - double inventorysize: the maximum quantity of material to +/// be held in the inventory +/// - double commodprice: the price of the output material PER UNIT +/// - map outComp + +/// @section optionalparams Optional Parameters +/// Foo behavior may also be specified with the following +/// optional parameters which have default values listed here. +/// - double capacityFactor: The ratio of actual production capacity to +/// the rated production capacity. Default is 1 (actual/rated). +/// - double availFactor: The percent of time the facility operates at +/// its capacity factor. Default is 100%. +/// - double capitalCost: The cost of constructing and commissioning +/// this facility. Default is 0 ($). +/// - double opCost: The annual cost of operation and maintenance of +/// this facility. Default is 0 ( $/year). +/// - int constrTime: The number of months it takes to construct and +/// commission this facility. Default is 0 (months). +/// - int decomTime: The number of months it takes to deconstruct and +/// decommission this facility. Default is 0 (months). +/// - Inst* inst: The institution responsible for this facility. +/// - string name: A non-generic name for this facility. + +/// @section detailed Detailed Behavior +/// @subsection finite If Finite Capacity: +/// The Foo starts operation when the simulation reaches the +/// month specified as the startDate. It immediately begins to produce +/// material at the rate defined by its capacity. Each month the +/// Foo adds the amount it has produced to its inventory. It +/// then offers to the appropriate market exactly as much material as it +/// has in its inventory. If an offer is matched with a request, the +/// Foo executes that order by subtracting the quantity from +/// its inventory and sending that amount to the requesting facility. +/// When the simulation time equals the startDate plus the lifeTime, the +/// facility ceases to operate. +/// @subsection infinite If Infinite Capacity: +/// The Foo starts operation when the simulation reaches the +/// month specified as the startDate. Each month the Foo +/// offers an infinite amount of material to the appropriate market. If +/// there is a request for that material, the Foo executes +/// that order by sending that amount to the requesting facility. When +/// the simulation time equals the startDate plus the lifeTime, the +/// facility ceases to operate. + +/// @subsection question Question: +/// What is the best way to allow offers of an infinite amount of +/// material on a market? + +class Foo : public cyclus::Facility, + public cyclus::toolkit::CommodityProducer { + public: + // --- Module Members --- + /// Constructor for the Foo class + /// @param ctx the cyclus context for access to simulation-wide parameters + Foo(cyclus::Context* ctx); + + virtual ~Foo() + + #pragma cyclus decl + + #pragma cyclus note {"doc": "A source facility that provides a " \ + "commodity with a given capacity"} + + /// Print information about this agent + virtual std::string str(); + // --- + + // --- Agent Members --- + virtual void EnterNotify(); + + /// Each facility is prompted to do its beginning-of-time-step + /// stuff at the tick of the timer. + + /// @param time is the time to perform the tick + virtual void Tick(); + + /// Each facility is prompted to its end-of-time-step + /// stuff on the tock of the timer. + + /// @param time is the time to perform the tock + virtual void Tock(); + + /// @brief Responds to each request for this source facility's commodity. + /// If a given request is more than this facility's capacity, it will offer + /// its capacity. + virtual std::set::Ptr> + GetMatlBids(cyclus::CommodMap::type& + commod_requests); + + /// @brief respond to each trade with a material made from this facility's + /// recipe + /// + /// @param trades all trades in which this trader is the supplier + /// @param responses a container to populate with responses to each trade + virtual void GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses); + // --- + + // --- Foo Members --- + /// @brief creates a material object to offer to a requester + /// @param target the material target a request desires + cyclus::Material::Ptr GetOffer(const cyclus::Material::Ptr target) const; + + /// sets the output commodity name + /// @param name the commodity name + inline void commodity(std::string name) { out_commod = name; } + + /// @return the output commodity + inline std::string commodity() const { return out_commod; } + + /// sets the capacity of a material generated at any given time step + /// @param capacity the production capacity + inline void Capacity(double cap) { + capacity = cap; + current_capacity = capacity; + } + + /// @return the production capacity at any given time step + inline double Capacity() const { return capacity; } + + /// sets the name of the recipe to be produced + /// @param name the recipe name + inline void recipe(std::string name) { recipe_name = name; } + + /// @return the name of the output recipe + inline std::string recipe() const { return recipe_name; } + + /// @return the current timestep's capacity + inline double CurrentCapacity() const { return current_capacity; } + + private: + cyclus::toolkit::Commodity commod_; + + /// This facility has only one output commodity + #pragma cyclus var {"tooltip": "source output commodity", \ + "doc": "output commodity that the source facility " \ + "supplies", \ + "uitype": "outcommodity"} + std::string out_commod; + + /// Name of the recipe this facility uses. + #pragma cyclus var {"tooltip": "commodity recipe name", \ + "doc": "recipe name for source facility's commodity", \ + "uitype": "recipe"} + std::string recipe_name; + + /// The capacity is defined in terms of the number of units of the + /// recipe that can be provided each time step. A very large number + /// can be provided to represent infinte capacity. + #pragma cyclus var {"default": 1e299, "tooltip": "source capacity", \ + "doc": "amount of commodity that can be supplied " \ + "at each time step"} + double capacity; + + /// The capacity at the current time step + #pragma cyclus var {'derived_init': 'current_capacity = capacity;'} + double current_capacity; + + // --- +}; + +} // namespace cycamore + +#endif // CYCAMORE_SRC_FOO_H_ diff --git a/src/foo_tests.cc b/src/foo_tests.cc new file mode 100644 index 0000000000..0973e794d0 --- /dev/null +++ b/src/foo_tests.cc @@ -0,0 +1,204 @@ +#include "foo_tests.h" + +#include + +#include + +#include "cyc_limits.h" +#include "resource_helpers.h" +#include "test_context.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::SetUp() { + src_facility = new cycamore::Foo(tc.get()); + trader = tc.trader(); + InitParameters(); + SetUpFoo(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::TearDown() { + delete src_facility; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::InitParameters() { + commod = "commod"; + recipe_name = "recipe"; + capacity = 5; // some magic number.. + + recipe = cyclus::Composition::CreateFromAtom(cyclus::CompMap()); + tc.get()->AddRecipe(recipe_name, recipe); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::SetUpFoo() { + src_facility->commodity(commod); + src_facility->recipe(recipe_name); + src_facility->Capacity(capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, InitialState) { + EXPECT_EQ(src_facility->Capacity(), capacity); + EXPECT_EQ(src_facility->commodity(), commod); + EXPECT_EQ(src_facility->recipe(), recipe_name); + EXPECT_EQ(src_facility->CurrentCapacity(), capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Clone) { + cyclus::Context* ctx = tc.get(); + cycamore::Foo* cloned_fac = dynamic_cast + (src_facility->Clone()); + + EXPECT_EQ(src_facility->commodity(), cloned_fac->commodity()); + EXPECT_EQ(src_facility->Capacity(), cloned_fac->Capacity()); + EXPECT_EQ(src_facility->recipe(), cloned_fac->recipe()); + EXPECT_EQ(src_facility->Capacity(), cloned_fac->CurrentCapacity()); + + delete cloned_fac; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Print) { + EXPECT_NO_THROW(std::string s = src_facility->str()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, GetOffer) { + using cyclus::Material; + + double qty = capacity - 1; + Material::Ptr mat = cyclus::NewBlankMaterial(qty); + Material::Ptr obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), qty); + EXPECT_EQ(obs_mat->comp(), recipe); + + qty = capacity + 1; + mat = cyclus::NewBlankMaterial(qty); + obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), capacity); + EXPECT_EQ(obs_mat->comp(), recipe); + + qty = capacity; + mat = cyclus::NewBlankMaterial(qty); + obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), capacity); + EXPECT_EQ(obs_mat->comp(), recipe); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, AddBids) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::ExchangeContext; + using cyclus::Material; + + int nreqs = 5; + + boost::shared_ptr< cyclus::ExchangeContext > + ec = GetContext(nreqs, commod); + + std::set::Ptr> ports = + src_facility->GetMatlBids(ec.get()->commod_requests); + + ASSERT_TRUE(ports.size() > 0); + EXPECT_EQ(ports.size(), 1); + + BidPortfolio::Ptr port = *ports.begin(); + EXPECT_EQ(port->bidder(), src_facility); + EXPECT_EQ(port->bids().size(), nreqs); + + const std::set< CapacityConstraint >& constrs = port->constraints(); + ASSERT_TRUE(constrs.size() > 0); + EXPECT_EQ(constrs.size(), 1); + EXPECT_EQ(*constrs.begin(), CapacityConstraint(capacity)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Response) { + using cyclus::Bid; + using cyclus::Material; + using cyclus::Request; + using cyclus::Trade; + using test_helpers::get_mat; + + std::vector< cyclus::Trade > trades; + std::vector, + cyclus::Material::Ptr> > responses; + + // Null response + EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); + EXPECT_EQ(responses.size(), 0); + + double qty = capacity / 3; + Request* request = + Request::Create(get_mat(), trader, commod); + Bid* bid = + Bid::Create(request, get_mat(), src_facility); + + Trade trade(request, bid, qty); + trades.push_back(trade); + + // 1 trade + ASSERT_EQ(src_facility->CurrentCapacity(), capacity); + src_facility->GetMatlTrades(trades, responses); + EXPECT_EQ(responses.size(), 1); + EXPECT_EQ(responses[0].second->quantity(), qty); + EXPECT_EQ(responses[0].second->comp(), recipe); + + // 2 trades, total qty = capacity + ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity - qty); + ASSERT_GT(src_facility->CurrentCapacity() - 2 * qty, -1 * cyclus::eps()); + trades.push_back(trade); + responses.clear(); + EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); + EXPECT_EQ(responses.size(), 2); + ASSERT_TRUE(cyclus::AlmostEq(src_facility->CurrentCapacity(), 0)); + + // too much qty, capn! + EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), + cyclus::ValueError); + + // reset! + src_facility->Tick(); + ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity); + + delete request; + delete bid; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +boost::shared_ptr< cyclus::ExchangeContext > +FooTest::GetContext(int nreqs, std::string commod) { + using cyclus::Material; + using cyclus::Request; + using cyclus::ExchangeContext; + using test_helpers::get_mat; + + double qty = 3; + boost::shared_ptr< ExchangeContext > + ec(new ExchangeContext()); + for (int i = 0; i < nreqs; i++) { + ec->AddRequest(Request::Create(get_mat(), trader, commod)); + } + return ec; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Agent* FooConstructor(cyclus::Context* ctx) { + return new cycamore::Foo(ctx); +} + +// required to get functionality in cyclus agent unit tests library +#ifndef CYCLUS_AGENT_TESTS_CONNECTED +int ConnectAgentTests(); +static int cyclus_agent_tests_connected = ConnectAgentTests(); +#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected +#endif // CYCLUS_AGENT_TESTS_CONNECTED + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +INSTANTIATE_TEST_CASE_P(FooFac, FacilityTests, Values(&FooConstructor)); +INSTANTIATE_TEST_CASE_P(FooFac, AgentTests, Values(&FooConstructor)); diff --git a/src/foo_tests.h b/src/foo_tests.h new file mode 100644 index 0000000000..59888926b7 --- /dev/null +++ b/src/foo_tests.h @@ -0,0 +1,34 @@ +#ifndef CYCAMORE_SRC_FOO_TESTS_H_ +#define CYCAMORE_SRC_FOO_TESTS_H_ +#include "foo.h" + +#include + +#include + +#include "agent_tests.h" +#include "context.h" +#include "exchange_context.h" +#include "facility_tests.h" +#include "material.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +class FooTest : public ::testing::Test { + public: + cyclus::TestContext tc; + TestFacility* trader; + cycamore::Foo* src_facility; + std::string commod, recipe_name; + double capacity; + cyclus::Composition::Ptr recipe; + + virtual void SetUp(); + virtual void TearDown(); + void InitParameters(); + void SetUpFoo(); + + boost::shared_ptr< cyclus::ExchangeContext > + GetContext(int nreqs, std::string commodity); +}; + +#endif // CYCAMORE_SRC_FOO_TESTS_H_ From df2a0c4c36666f77dbcb40bb13701a75defef15f Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 12:46:05 -0500 Subject: [PATCH 238/314] Revert "Squashing commits from cyclus/cycamore#301. This should fail on CI." This reverts commit 3bb92b3be3c5ccf879bc11c9c50243ab1a206bf0. --- src/CMakeLists.txt | 2 - src/foo.cc | 171 ------------------------------------- src/foo.h | 204 --------------------------------------------- src/foo_tests.cc | 204 --------------------------------------------- src/foo_tests.h | 34 -------- 5 files changed, 615 deletions(-) delete mode 100644 src/foo.cc delete mode 100644 src/foo.h delete mode 100644 src/foo_tests.cc delete mode 100644 src/foo_tests.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 29e907624e..6a29fcff22 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,8 +12,6 @@ USE_CYCLUS("cycamore" "sink") USE_CYCLUS("cycamore" "source") -USE_CYCLUS("cycamore" "foo") - USE_CYCLUS("cycamore" "deploy_inst") USE_CYCLUS("cycamore" "manager_inst") diff --git a/src/foo.cc b/src/foo.cc deleted file mode 100644 index 9ad8ada201..0000000000 --- a/src/foo.cc +++ /dev/null @@ -1,171 +0,0 @@ -#include "foo.h" - -#include -#include - -#include - -namespace cycamore { - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Foo::Foo(cyclus::Context* ctx) - : cyclus::Facility(ctx), - out_commod(""), - recipe_name(""), - capacity(std::numeric_limits::max()) {} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Foo::~Foo() {} - -#pragma cyclus def clone cycamore::Foo - -#pragma cyclus def schema cycamore::Foo - -#pragma cyclus def annotations cycamore::Foo - -#pragma cyclus def infiletodb cycamore::Foo - -#pragma cyclus def snapshot cycamore::Foo - -#pragma cyclus def snapshotinv cycamore::Foo - -#pragma cyclus def initinv cycamore::Foo - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::InitFrom(Foo* m) { - #pragma cyclus impl initfromcopy cycamore::Foo - cyclus::toolkit::CommodityProducer::Copy(m); -} - -void Foo::InitFrom(cyclus::QueryableBackend* b) { - #pragma cyclus impl initfromdb cycamore::Foo - - commod_ = cyclus::toolkit::Commodity(out_commod); - cyclus::toolkit::CommodityProducer::Add(commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); - cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); -} - -void Foo::EnterNotify() { - Facility::EnterNotify(); - commod_ = cyclus::toolkit::Commodity(out_commod); - cyclus::toolkit::CommodityProducer::Add(commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); - cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::string Foo::str() { - std::stringstream ss; - std::string ans; - if (cyclus::toolkit::CommodityProducer:: - Produces(cyclus::toolkit::Commodity(out_commod))) { - ans = "yes"; - } else { - ans = "no"; - } - ss << cyclus::Facility::str() - << " supplies commodity '" - << out_commod << "' with recipe '" - << recipe_name << "' at a capacity of " - << capacity << " kg per time step " - << " commod producer members: " << " produces " - << out_commod << "?: " << ans - << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(commod_) - << " cost: " << cyclus::toolkit::CommodityProducer::Cost(commod_); - return ss.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::Tick() { - LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is ticking {"; - LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity - << " kg of " - << out_commod << "."; - LOG(cyclus::LEV_INFO3, "SrcFac") << "Stats: " << str(); - LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; - current_capacity = capacity; // reset capacity -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::Tock() { - LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is tocking {"; - LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr Foo::GetOffer( - const cyclus::Material::Ptr target) const { - using cyclus::Material; - double qty = std::min(target->quantity(), capacity); - return Material::CreateUntracked(qty, context()->GetRecipe(recipe_name)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -Foo::GetMatlBids( - cyclus::CommodMap::type& commod_requests) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::Material; - using cyclus::Request; - - std::set::Ptr> ports; - - if (commod_requests.count(out_commod) > 0) { - BidPortfolio::Ptr port(new BidPortfolio()); - - std::vector*>& requests = - commod_requests[out_commod]; - - std::vector*>::iterator it; - for (it = requests.begin(); it != requests.end(); ++it) { - Request* req = *it; - Material::Ptr offer = GetOffer(req->target()); - port->AddBid(req, offer, this); - } - - CapacityConstraint cc(capacity); - port->AddConstraint(cc); - ports.insert(port); - } - return ports; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses) { - using cyclus::Material; - using cyclus::Trade; - - double provided = 0; - std::vector< cyclus::Trade >::const_iterator it; - for (it = trades.begin(); it != trades.end(); ++it) { - double qty = it->amt; - current_capacity -= qty; - provided += qty; - // @TODO we need a policy on negatives.. - Material::Ptr response = Material::Create(this, qty, - context()->GetRecipe(recipe_name)); - responses.push_back(std::make_pair(*it, response)); - LOG(cyclus::LEV_INFO5, "SrcFac") << prototype() << " just received an order" - << " for " << qty - << " of " << out_commod; - } - if (cyclus::IsNegative(current_capacity)) { - std::stringstream ss; - ss << "is being asked to provide " << provided - << " but its capacity is " << capacity << "."; - throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern "C" cyclus::Agent* ConstructFoo(cyclus::Context* ctx) { - return new Foo(ctx); -} - -} // namespace cycamore diff --git a/src/foo.h b/src/foo.h deleted file mode 100644 index e35ab83d99..0000000000 --- a/src/foo.h +++ /dev/null @@ -1,204 +0,0 @@ -#ifndef CYCAMORE_SRC_FOO_H_ -#define CYCAMORE_SRC_FOO_H_ - -#include -#include - -#include "cyclus.h" - -namespace cycamore { - -class Context; - -/// @class Foo -/// This cyclus::Facility provides a simple source of some capacity -/// (possibly infinite) of some commodity/Recipe. - -/// The Foo class inherits from the cyclus::Facility class and is -/// dynamically loaded by the Agent class when requested. - -/// @section introduction Introduction -/// The Foo is a facility type in Cyclus capable of providing -/// a finite or infinite.Supply of a particular material to the -/// simulation. A Foo generates material of a certain -/// composition and commodity type, then offers that material on the -/// appropriate market. Shipments of this material are executed when the -/// market issues an order that the offer has been matched with a -/// request. - -/// @section agentparams Agent Parameters -/// Foo behavior is comprehensively defined by the following -/// parameters: -/// - double capacity: The production capacity of the facility (units -/// vary, but typically kg/month). Capacity is infinite if a negative -/// value is provided. -/// - int startDate: The date on which the facility begins to operate -/// (months). -/// - int lifeTime: The length of time that the facility operates -/// (months). - std::string outCommod: the commodity that this facility -/// produces - double inventorysize: the maximum quantity of material to -/// be held in the inventory -/// - double commodprice: the price of the output material PER UNIT -/// - map outComp - -/// @section optionalparams Optional Parameters -/// Foo behavior may also be specified with the following -/// optional parameters which have default values listed here. -/// - double capacityFactor: The ratio of actual production capacity to -/// the rated production capacity. Default is 1 (actual/rated). -/// - double availFactor: The percent of time the facility operates at -/// its capacity factor. Default is 100%. -/// - double capitalCost: The cost of constructing and commissioning -/// this facility. Default is 0 ($). -/// - double opCost: The annual cost of operation and maintenance of -/// this facility. Default is 0 ( $/year). -/// - int constrTime: The number of months it takes to construct and -/// commission this facility. Default is 0 (months). -/// - int decomTime: The number of months it takes to deconstruct and -/// decommission this facility. Default is 0 (months). -/// - Inst* inst: The institution responsible for this facility. -/// - string name: A non-generic name for this facility. - -/// @section detailed Detailed Behavior -/// @subsection finite If Finite Capacity: -/// The Foo starts operation when the simulation reaches the -/// month specified as the startDate. It immediately begins to produce -/// material at the rate defined by its capacity. Each month the -/// Foo adds the amount it has produced to its inventory. It -/// then offers to the appropriate market exactly as much material as it -/// has in its inventory. If an offer is matched with a request, the -/// Foo executes that order by subtracting the quantity from -/// its inventory and sending that amount to the requesting facility. -/// When the simulation time equals the startDate plus the lifeTime, the -/// facility ceases to operate. -/// @subsection infinite If Infinite Capacity: -/// The Foo starts operation when the simulation reaches the -/// month specified as the startDate. Each month the Foo -/// offers an infinite amount of material to the appropriate market. If -/// there is a request for that material, the Foo executes -/// that order by sending that amount to the requesting facility. When -/// the simulation time equals the startDate plus the lifeTime, the -/// facility ceases to operate. - -/// @subsection question Question: -/// What is the best way to allow offers of an infinite amount of -/// material on a market? - -class Foo : public cyclus::Facility, - public cyclus::toolkit::CommodityProducer { - public: - // --- Module Members --- - /// Constructor for the Foo class - /// @param ctx the cyclus context for access to simulation-wide parameters - Foo(cyclus::Context* ctx); - - virtual ~Foo() - - #pragma cyclus decl - - #pragma cyclus note {"doc": "A source facility that provides a " \ - "commodity with a given capacity"} - - /// Print information about this agent - virtual std::string str(); - // --- - - // --- Agent Members --- - virtual void EnterNotify(); - - /// Each facility is prompted to do its beginning-of-time-step - /// stuff at the tick of the timer. - - /// @param time is the time to perform the tick - virtual void Tick(); - - /// Each facility is prompted to its end-of-time-step - /// stuff on the tock of the timer. - - /// @param time is the time to perform the tock - virtual void Tock(); - - /// @brief Responds to each request for this source facility's commodity. - /// If a given request is more than this facility's capacity, it will offer - /// its capacity. - virtual std::set::Ptr> - GetMatlBids(cyclus::CommodMap::type& - commod_requests); - - /// @brief respond to each trade with a material made from this facility's - /// recipe - /// - /// @param trades all trades in which this trader is the supplier - /// @param responses a container to populate with responses to each trade - virtual void GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses); - // --- - - // --- Foo Members --- - /// @brief creates a material object to offer to a requester - /// @param target the material target a request desires - cyclus::Material::Ptr GetOffer(const cyclus::Material::Ptr target) const; - - /// sets the output commodity name - /// @param name the commodity name - inline void commodity(std::string name) { out_commod = name; } - - /// @return the output commodity - inline std::string commodity() const { return out_commod; } - - /// sets the capacity of a material generated at any given time step - /// @param capacity the production capacity - inline void Capacity(double cap) { - capacity = cap; - current_capacity = capacity; - } - - /// @return the production capacity at any given time step - inline double Capacity() const { return capacity; } - - /// sets the name of the recipe to be produced - /// @param name the recipe name - inline void recipe(std::string name) { recipe_name = name; } - - /// @return the name of the output recipe - inline std::string recipe() const { return recipe_name; } - - /// @return the current timestep's capacity - inline double CurrentCapacity() const { return current_capacity; } - - private: - cyclus::toolkit::Commodity commod_; - - /// This facility has only one output commodity - #pragma cyclus var {"tooltip": "source output commodity", \ - "doc": "output commodity that the source facility " \ - "supplies", \ - "uitype": "outcommodity"} - std::string out_commod; - - /// Name of the recipe this facility uses. - #pragma cyclus var {"tooltip": "commodity recipe name", \ - "doc": "recipe name for source facility's commodity", \ - "uitype": "recipe"} - std::string recipe_name; - - /// The capacity is defined in terms of the number of units of the - /// recipe that can be provided each time step. A very large number - /// can be provided to represent infinte capacity. - #pragma cyclus var {"default": 1e299, "tooltip": "source capacity", \ - "doc": "amount of commodity that can be supplied " \ - "at each time step"} - double capacity; - - /// The capacity at the current time step - #pragma cyclus var {'derived_init': 'current_capacity = capacity;'} - double current_capacity; - - // --- -}; - -} // namespace cycamore - -#endif // CYCAMORE_SRC_FOO_H_ diff --git a/src/foo_tests.cc b/src/foo_tests.cc deleted file mode 100644 index 0973e794d0..0000000000 --- a/src/foo_tests.cc +++ /dev/null @@ -1,204 +0,0 @@ -#include "foo_tests.h" - -#include - -#include - -#include "cyc_limits.h" -#include "resource_helpers.h" -#include "test_context.h" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::SetUp() { - src_facility = new cycamore::Foo(tc.get()); - trader = tc.trader(); - InitParameters(); - SetUpFoo(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::TearDown() { - delete src_facility; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::InitParameters() { - commod = "commod"; - recipe_name = "recipe"; - capacity = 5; // some magic number.. - - recipe = cyclus::Composition::CreateFromAtom(cyclus::CompMap()); - tc.get()->AddRecipe(recipe_name, recipe); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::SetUpFoo() { - src_facility->commodity(commod); - src_facility->recipe(recipe_name); - src_facility->Capacity(capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, InitialState) { - EXPECT_EQ(src_facility->Capacity(), capacity); - EXPECT_EQ(src_facility->commodity(), commod); - EXPECT_EQ(src_facility->recipe(), recipe_name); - EXPECT_EQ(src_facility->CurrentCapacity(), capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Clone) { - cyclus::Context* ctx = tc.get(); - cycamore::Foo* cloned_fac = dynamic_cast - (src_facility->Clone()); - - EXPECT_EQ(src_facility->commodity(), cloned_fac->commodity()); - EXPECT_EQ(src_facility->Capacity(), cloned_fac->Capacity()); - EXPECT_EQ(src_facility->recipe(), cloned_fac->recipe()); - EXPECT_EQ(src_facility->Capacity(), cloned_fac->CurrentCapacity()); - - delete cloned_fac; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Print) { - EXPECT_NO_THROW(std::string s = src_facility->str()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, GetOffer) { - using cyclus::Material; - - double qty = capacity - 1; - Material::Ptr mat = cyclus::NewBlankMaterial(qty); - Material::Ptr obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), qty); - EXPECT_EQ(obs_mat->comp(), recipe); - - qty = capacity + 1; - mat = cyclus::NewBlankMaterial(qty); - obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), capacity); - EXPECT_EQ(obs_mat->comp(), recipe); - - qty = capacity; - mat = cyclus::NewBlankMaterial(qty); - obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), capacity); - EXPECT_EQ(obs_mat->comp(), recipe); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, AddBids) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::ExchangeContext; - using cyclus::Material; - - int nreqs = 5; - - boost::shared_ptr< cyclus::ExchangeContext > - ec = GetContext(nreqs, commod); - - std::set::Ptr> ports = - src_facility->GetMatlBids(ec.get()->commod_requests); - - ASSERT_TRUE(ports.size() > 0); - EXPECT_EQ(ports.size(), 1); - - BidPortfolio::Ptr port = *ports.begin(); - EXPECT_EQ(port->bidder(), src_facility); - EXPECT_EQ(port->bids().size(), nreqs); - - const std::set< CapacityConstraint >& constrs = port->constraints(); - ASSERT_TRUE(constrs.size() > 0); - EXPECT_EQ(constrs.size(), 1); - EXPECT_EQ(*constrs.begin(), CapacityConstraint(capacity)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Response) { - using cyclus::Bid; - using cyclus::Material; - using cyclus::Request; - using cyclus::Trade; - using test_helpers::get_mat; - - std::vector< cyclus::Trade > trades; - std::vector, - cyclus::Material::Ptr> > responses; - - // Null response - EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); - EXPECT_EQ(responses.size(), 0); - - double qty = capacity / 3; - Request* request = - Request::Create(get_mat(), trader, commod); - Bid* bid = - Bid::Create(request, get_mat(), src_facility); - - Trade trade(request, bid, qty); - trades.push_back(trade); - - // 1 trade - ASSERT_EQ(src_facility->CurrentCapacity(), capacity); - src_facility->GetMatlTrades(trades, responses); - EXPECT_EQ(responses.size(), 1); - EXPECT_EQ(responses[0].second->quantity(), qty); - EXPECT_EQ(responses[0].second->comp(), recipe); - - // 2 trades, total qty = capacity - ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity - qty); - ASSERT_GT(src_facility->CurrentCapacity() - 2 * qty, -1 * cyclus::eps()); - trades.push_back(trade); - responses.clear(); - EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); - EXPECT_EQ(responses.size(), 2); - ASSERT_TRUE(cyclus::AlmostEq(src_facility->CurrentCapacity(), 0)); - - // too much qty, capn! - EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), - cyclus::ValueError); - - // reset! - src_facility->Tick(); - ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity); - - delete request; - delete bid; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -boost::shared_ptr< cyclus::ExchangeContext > -FooTest::GetContext(int nreqs, std::string commod) { - using cyclus::Material; - using cyclus::Request; - using cyclus::ExchangeContext; - using test_helpers::get_mat; - - double qty = 3; - boost::shared_ptr< ExchangeContext > - ec(new ExchangeContext()); - for (int i = 0; i < nreqs; i++) { - ec->AddRequest(Request::Create(get_mat(), trader, commod)); - } - return ec; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Agent* FooConstructor(cyclus::Context* ctx) { - return new cycamore::Foo(ctx); -} - -// required to get functionality in cyclus agent unit tests library -#ifndef CYCLUS_AGENT_TESTS_CONNECTED -int ConnectAgentTests(); -static int cyclus_agent_tests_connected = ConnectAgentTests(); -#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected -#endif // CYCLUS_AGENT_TESTS_CONNECTED - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -INSTANTIATE_TEST_CASE_P(FooFac, FacilityTests, Values(&FooConstructor)); -INSTANTIATE_TEST_CASE_P(FooFac, AgentTests, Values(&FooConstructor)); diff --git a/src/foo_tests.h b/src/foo_tests.h deleted file mode 100644 index 59888926b7..0000000000 --- a/src/foo_tests.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef CYCAMORE_SRC_FOO_TESTS_H_ -#define CYCAMORE_SRC_FOO_TESTS_H_ -#include "foo.h" - -#include - -#include - -#include "agent_tests.h" -#include "context.h" -#include "exchange_context.h" -#include "facility_tests.h" -#include "material.h" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -class FooTest : public ::testing::Test { - public: - cyclus::TestContext tc; - TestFacility* trader; - cycamore::Foo* src_facility; - std::string commod, recipe_name; - double capacity; - cyclus::Composition::Ptr recipe; - - virtual void SetUp(); - virtual void TearDown(); - void InitParameters(); - void SetUpFoo(); - - boost::shared_ptr< cyclus::ExchangeContext > - GetContext(int nreqs, std::string commodity); -}; - -#endif // CYCAMORE_SRC_FOO_TESTS_H_ From 7d6bb197cca7eaf62449a847b333a26ef97fd32a Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 14:18:47 -0500 Subject: [PATCH 239/314] adding commit msg indicator --- .travis-install.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis-install.sh b/.travis-install.sh index 1e53559839..1f9e8a8e15 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -1,5 +1,9 @@ #!/bin/bash +# log +msg=`git log --pretty=oneline -1` +echo "Building commit: $msg" + # setup conda recipe wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe From 858077e2a6a84f494cbab9a47c969c33dade99e4 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 14:30:44 -0500 Subject: [PATCH 240/314] adding failure with an explicit check --- .travis-install.sh | 2 + src/CMakeLists.txt | 2 + src/foo.cc | 171 +++++++++++++++++++++++++++++++++++++ src/foo.h | 204 +++++++++++++++++++++++++++++++++++++++++++++ src/foo_tests.cc | 204 +++++++++++++++++++++++++++++++++++++++++++++ src/foo_tests.h | 34 ++++++++ 6 files changed, 617 insertions(+) create mode 100644 src/foo.cc create mode 100644 src/foo.h create mode 100644 src/foo_tests.cc create mode 100644 src/foo_tests.h diff --git a/.travis-install.sh b/.travis-install.sh index 1f9e8a8e15..08a02557a1 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -10,6 +10,8 @@ unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml # build +"src/CMakeLists.txt:" +cat src/CMakeLists.txt cmd="conda build --no-test conda-recipe" echo "cmd: $cmd" $cmd diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6a29fcff22..29e907624e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,8 @@ USE_CYCLUS("cycamore" "sink") USE_CYCLUS("cycamore" "source") +USE_CYCLUS("cycamore" "foo") + USE_CYCLUS("cycamore" "deploy_inst") USE_CYCLUS("cycamore" "manager_inst") diff --git a/src/foo.cc b/src/foo.cc new file mode 100644 index 0000000000..9ad8ada201 --- /dev/null +++ b/src/foo.cc @@ -0,0 +1,171 @@ +#include "foo.h" + +#include +#include + +#include + +namespace cycamore { + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Foo::Foo(cyclus::Context* ctx) + : cyclus::Facility(ctx), + out_commod(""), + recipe_name(""), + capacity(std::numeric_limits::max()) {} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Foo::~Foo() {} + +#pragma cyclus def clone cycamore::Foo + +#pragma cyclus def schema cycamore::Foo + +#pragma cyclus def annotations cycamore::Foo + +#pragma cyclus def infiletodb cycamore::Foo + +#pragma cyclus def snapshot cycamore::Foo + +#pragma cyclus def snapshotinv cycamore::Foo + +#pragma cyclus def initinv cycamore::Foo + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::InitFrom(Foo* m) { + #pragma cyclus impl initfromcopy cycamore::Foo + cyclus::toolkit::CommodityProducer::Copy(m); +} + +void Foo::InitFrom(cyclus::QueryableBackend* b) { + #pragma cyclus impl initfromdb cycamore::Foo + + commod_ = cyclus::toolkit::Commodity(out_commod); + cyclus::toolkit::CommodityProducer::Add(commod_); + cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); + cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); +} + +void Foo::EnterNotify() { + Facility::EnterNotify(); + commod_ = cyclus::toolkit::Commodity(out_commod); + cyclus::toolkit::CommodityProducer::Add(commod_); + cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); + cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::string Foo::str() { + std::stringstream ss; + std::string ans; + if (cyclus::toolkit::CommodityProducer:: + Produces(cyclus::toolkit::Commodity(out_commod))) { + ans = "yes"; + } else { + ans = "no"; + } + ss << cyclus::Facility::str() + << " supplies commodity '" + << out_commod << "' with recipe '" + << recipe_name << "' at a capacity of " + << capacity << " kg per time step " + << " commod producer members: " << " produces " + << out_commod << "?: " << ans + << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(commod_) + << " cost: " << cyclus::toolkit::CommodityProducer::Cost(commod_); + return ss.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::Tick() { + LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is ticking {"; + LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity + << " kg of " + << out_commod << "."; + LOG(cyclus::LEV_INFO3, "SrcFac") << "Stats: " << str(); + LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; + current_capacity = capacity; // reset capacity +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::Tock() { + LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is tocking {"; + LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Material::Ptr Foo::GetOffer( + const cyclus::Material::Ptr target) const { + using cyclus::Material; + double qty = std::min(target->quantity(), capacity); + return Material::CreateUntracked(qty, context()->GetRecipe(recipe_name)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +std::set::Ptr> +Foo::GetMatlBids( + cyclus::CommodMap::type& commod_requests) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::Material; + using cyclus::Request; + + std::set::Ptr> ports; + + if (commod_requests.count(out_commod) > 0) { + BidPortfolio::Ptr port(new BidPortfolio()); + + std::vector*>& requests = + commod_requests[out_commod]; + + std::vector*>::iterator it; + for (it = requests.begin(); it != requests.end(); ++it) { + Request* req = *it; + Material::Ptr offer = GetOffer(req->target()); + port->AddBid(req, offer, this); + } + + CapacityConstraint cc(capacity); + port->AddConstraint(cc); + ports.insert(port); + } + return ports; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void Foo::GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses) { + using cyclus::Material; + using cyclus::Trade; + + double provided = 0; + std::vector< cyclus::Trade >::const_iterator it; + for (it = trades.begin(); it != trades.end(); ++it) { + double qty = it->amt; + current_capacity -= qty; + provided += qty; + // @TODO we need a policy on negatives.. + Material::Ptr response = Material::Create(this, qty, + context()->GetRecipe(recipe_name)); + responses.push_back(std::make_pair(*it, response)); + LOG(cyclus::LEV_INFO5, "SrcFac") << prototype() << " just received an order" + << " for " << qty + << " of " << out_commod; + } + if (cyclus::IsNegative(current_capacity)) { + std::stringstream ss; + ss << "is being asked to provide " << provided + << " but its capacity is " << capacity << "."; + throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +extern "C" cyclus::Agent* ConstructFoo(cyclus::Context* ctx) { + return new Foo(ctx); +} + +} // namespace cycamore diff --git a/src/foo.h b/src/foo.h new file mode 100644 index 0000000000..e35ab83d99 --- /dev/null +++ b/src/foo.h @@ -0,0 +1,204 @@ +#ifndef CYCAMORE_SRC_FOO_H_ +#define CYCAMORE_SRC_FOO_H_ + +#include +#include + +#include "cyclus.h" + +namespace cycamore { + +class Context; + +/// @class Foo +/// This cyclus::Facility provides a simple source of some capacity +/// (possibly infinite) of some commodity/Recipe. + +/// The Foo class inherits from the cyclus::Facility class and is +/// dynamically loaded by the Agent class when requested. + +/// @section introduction Introduction +/// The Foo is a facility type in Cyclus capable of providing +/// a finite or infinite.Supply of a particular material to the +/// simulation. A Foo generates material of a certain +/// composition and commodity type, then offers that material on the +/// appropriate market. Shipments of this material are executed when the +/// market issues an order that the offer has been matched with a +/// request. + +/// @section agentparams Agent Parameters +/// Foo behavior is comprehensively defined by the following +/// parameters: +/// - double capacity: The production capacity of the facility (units +/// vary, but typically kg/month). Capacity is infinite if a negative +/// value is provided. +/// - int startDate: The date on which the facility begins to operate +/// (months). +/// - int lifeTime: The length of time that the facility operates +/// (months). - std::string outCommod: the commodity that this facility +/// produces - double inventorysize: the maximum quantity of material to +/// be held in the inventory +/// - double commodprice: the price of the output material PER UNIT +/// - map outComp + +/// @section optionalparams Optional Parameters +/// Foo behavior may also be specified with the following +/// optional parameters which have default values listed here. +/// - double capacityFactor: The ratio of actual production capacity to +/// the rated production capacity. Default is 1 (actual/rated). +/// - double availFactor: The percent of time the facility operates at +/// its capacity factor. Default is 100%. +/// - double capitalCost: The cost of constructing and commissioning +/// this facility. Default is 0 ($). +/// - double opCost: The annual cost of operation and maintenance of +/// this facility. Default is 0 ( $/year). +/// - int constrTime: The number of months it takes to construct and +/// commission this facility. Default is 0 (months). +/// - int decomTime: The number of months it takes to deconstruct and +/// decommission this facility. Default is 0 (months). +/// - Inst* inst: The institution responsible for this facility. +/// - string name: A non-generic name for this facility. + +/// @section detailed Detailed Behavior +/// @subsection finite If Finite Capacity: +/// The Foo starts operation when the simulation reaches the +/// month specified as the startDate. It immediately begins to produce +/// material at the rate defined by its capacity. Each month the +/// Foo adds the amount it has produced to its inventory. It +/// then offers to the appropriate market exactly as much material as it +/// has in its inventory. If an offer is matched with a request, the +/// Foo executes that order by subtracting the quantity from +/// its inventory and sending that amount to the requesting facility. +/// When the simulation time equals the startDate plus the lifeTime, the +/// facility ceases to operate. +/// @subsection infinite If Infinite Capacity: +/// The Foo starts operation when the simulation reaches the +/// month specified as the startDate. Each month the Foo +/// offers an infinite amount of material to the appropriate market. If +/// there is a request for that material, the Foo executes +/// that order by sending that amount to the requesting facility. When +/// the simulation time equals the startDate plus the lifeTime, the +/// facility ceases to operate. + +/// @subsection question Question: +/// What is the best way to allow offers of an infinite amount of +/// material on a market? + +class Foo : public cyclus::Facility, + public cyclus::toolkit::CommodityProducer { + public: + // --- Module Members --- + /// Constructor for the Foo class + /// @param ctx the cyclus context for access to simulation-wide parameters + Foo(cyclus::Context* ctx); + + virtual ~Foo() + + #pragma cyclus decl + + #pragma cyclus note {"doc": "A source facility that provides a " \ + "commodity with a given capacity"} + + /// Print information about this agent + virtual std::string str(); + // --- + + // --- Agent Members --- + virtual void EnterNotify(); + + /// Each facility is prompted to do its beginning-of-time-step + /// stuff at the tick of the timer. + + /// @param time is the time to perform the tick + virtual void Tick(); + + /// Each facility is prompted to its end-of-time-step + /// stuff on the tock of the timer. + + /// @param time is the time to perform the tock + virtual void Tock(); + + /// @brief Responds to each request for this source facility's commodity. + /// If a given request is more than this facility's capacity, it will offer + /// its capacity. + virtual std::set::Ptr> + GetMatlBids(cyclus::CommodMap::type& + commod_requests); + + /// @brief respond to each trade with a material made from this facility's + /// recipe + /// + /// @param trades all trades in which this trader is the supplier + /// @param responses a container to populate with responses to each trade + virtual void GetMatlTrades( + const std::vector< cyclus::Trade >& trades, + std::vector, + cyclus::Material::Ptr> >& responses); + // --- + + // --- Foo Members --- + /// @brief creates a material object to offer to a requester + /// @param target the material target a request desires + cyclus::Material::Ptr GetOffer(const cyclus::Material::Ptr target) const; + + /// sets the output commodity name + /// @param name the commodity name + inline void commodity(std::string name) { out_commod = name; } + + /// @return the output commodity + inline std::string commodity() const { return out_commod; } + + /// sets the capacity of a material generated at any given time step + /// @param capacity the production capacity + inline void Capacity(double cap) { + capacity = cap; + current_capacity = capacity; + } + + /// @return the production capacity at any given time step + inline double Capacity() const { return capacity; } + + /// sets the name of the recipe to be produced + /// @param name the recipe name + inline void recipe(std::string name) { recipe_name = name; } + + /// @return the name of the output recipe + inline std::string recipe() const { return recipe_name; } + + /// @return the current timestep's capacity + inline double CurrentCapacity() const { return current_capacity; } + + private: + cyclus::toolkit::Commodity commod_; + + /// This facility has only one output commodity + #pragma cyclus var {"tooltip": "source output commodity", \ + "doc": "output commodity that the source facility " \ + "supplies", \ + "uitype": "outcommodity"} + std::string out_commod; + + /// Name of the recipe this facility uses. + #pragma cyclus var {"tooltip": "commodity recipe name", \ + "doc": "recipe name for source facility's commodity", \ + "uitype": "recipe"} + std::string recipe_name; + + /// The capacity is defined in terms of the number of units of the + /// recipe that can be provided each time step. A very large number + /// can be provided to represent infinte capacity. + #pragma cyclus var {"default": 1e299, "tooltip": "source capacity", \ + "doc": "amount of commodity that can be supplied " \ + "at each time step"} + double capacity; + + /// The capacity at the current time step + #pragma cyclus var {'derived_init': 'current_capacity = capacity;'} + double current_capacity; + + // --- +}; + +} // namespace cycamore + +#endif // CYCAMORE_SRC_FOO_H_ diff --git a/src/foo_tests.cc b/src/foo_tests.cc new file mode 100644 index 0000000000..0973e794d0 --- /dev/null +++ b/src/foo_tests.cc @@ -0,0 +1,204 @@ +#include "foo_tests.h" + +#include + +#include + +#include "cyc_limits.h" +#include "resource_helpers.h" +#include "test_context.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::SetUp() { + src_facility = new cycamore::Foo(tc.get()); + trader = tc.trader(); + InitParameters(); + SetUpFoo(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::TearDown() { + delete src_facility; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::InitParameters() { + commod = "commod"; + recipe_name = "recipe"; + capacity = 5; // some magic number.. + + recipe = cyclus::Composition::CreateFromAtom(cyclus::CompMap()); + tc.get()->AddRecipe(recipe_name, recipe); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void FooTest::SetUpFoo() { + src_facility->commodity(commod); + src_facility->recipe(recipe_name); + src_facility->Capacity(capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, InitialState) { + EXPECT_EQ(src_facility->Capacity(), capacity); + EXPECT_EQ(src_facility->commodity(), commod); + EXPECT_EQ(src_facility->recipe(), recipe_name); + EXPECT_EQ(src_facility->CurrentCapacity(), capacity); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Clone) { + cyclus::Context* ctx = tc.get(); + cycamore::Foo* cloned_fac = dynamic_cast + (src_facility->Clone()); + + EXPECT_EQ(src_facility->commodity(), cloned_fac->commodity()); + EXPECT_EQ(src_facility->Capacity(), cloned_fac->Capacity()); + EXPECT_EQ(src_facility->recipe(), cloned_fac->recipe()); + EXPECT_EQ(src_facility->Capacity(), cloned_fac->CurrentCapacity()); + + delete cloned_fac; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Print) { + EXPECT_NO_THROW(std::string s = src_facility->str()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, GetOffer) { + using cyclus::Material; + + double qty = capacity - 1; + Material::Ptr mat = cyclus::NewBlankMaterial(qty); + Material::Ptr obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), qty); + EXPECT_EQ(obs_mat->comp(), recipe); + + qty = capacity + 1; + mat = cyclus::NewBlankMaterial(qty); + obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), capacity); + EXPECT_EQ(obs_mat->comp(), recipe); + + qty = capacity; + mat = cyclus::NewBlankMaterial(qty); + obs_mat = src_facility->GetOffer(mat); + EXPECT_EQ(obs_mat->quantity(), capacity); + EXPECT_EQ(obs_mat->comp(), recipe); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, AddBids) { + using cyclus::Bid; + using cyclus::BidPortfolio; + using cyclus::CapacityConstraint; + using cyclus::ExchangeContext; + using cyclus::Material; + + int nreqs = 5; + + boost::shared_ptr< cyclus::ExchangeContext > + ec = GetContext(nreqs, commod); + + std::set::Ptr> ports = + src_facility->GetMatlBids(ec.get()->commod_requests); + + ASSERT_TRUE(ports.size() > 0); + EXPECT_EQ(ports.size(), 1); + + BidPortfolio::Ptr port = *ports.begin(); + EXPECT_EQ(port->bidder(), src_facility); + EXPECT_EQ(port->bids().size(), nreqs); + + const std::set< CapacityConstraint >& constrs = port->constraints(); + ASSERT_TRUE(constrs.size() > 0); + EXPECT_EQ(constrs.size(), 1); + EXPECT_EQ(*constrs.begin(), CapacityConstraint(capacity)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST_F(FooTest, Response) { + using cyclus::Bid; + using cyclus::Material; + using cyclus::Request; + using cyclus::Trade; + using test_helpers::get_mat; + + std::vector< cyclus::Trade > trades; + std::vector, + cyclus::Material::Ptr> > responses; + + // Null response + EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); + EXPECT_EQ(responses.size(), 0); + + double qty = capacity / 3; + Request* request = + Request::Create(get_mat(), trader, commod); + Bid* bid = + Bid::Create(request, get_mat(), src_facility); + + Trade trade(request, bid, qty); + trades.push_back(trade); + + // 1 trade + ASSERT_EQ(src_facility->CurrentCapacity(), capacity); + src_facility->GetMatlTrades(trades, responses); + EXPECT_EQ(responses.size(), 1); + EXPECT_EQ(responses[0].second->quantity(), qty); + EXPECT_EQ(responses[0].second->comp(), recipe); + + // 2 trades, total qty = capacity + ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity - qty); + ASSERT_GT(src_facility->CurrentCapacity() - 2 * qty, -1 * cyclus::eps()); + trades.push_back(trade); + responses.clear(); + EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); + EXPECT_EQ(responses.size(), 2); + ASSERT_TRUE(cyclus::AlmostEq(src_facility->CurrentCapacity(), 0)); + + // too much qty, capn! + EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), + cyclus::ValueError); + + // reset! + src_facility->Tick(); + ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity); + + delete request; + delete bid; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +boost::shared_ptr< cyclus::ExchangeContext > +FooTest::GetContext(int nreqs, std::string commod) { + using cyclus::Material; + using cyclus::Request; + using cyclus::ExchangeContext; + using test_helpers::get_mat; + + double qty = 3; + boost::shared_ptr< ExchangeContext > + ec(new ExchangeContext()); + for (int i = 0; i < nreqs; i++) { + ec->AddRequest(Request::Create(get_mat(), trader, commod)); + } + return ec; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cyclus::Agent* FooConstructor(cyclus::Context* ctx) { + return new cycamore::Foo(ctx); +} + +// required to get functionality in cyclus agent unit tests library +#ifndef CYCLUS_AGENT_TESTS_CONNECTED +int ConnectAgentTests(); +static int cyclus_agent_tests_connected = ConnectAgentTests(); +#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected +#endif // CYCLUS_AGENT_TESTS_CONNECTED + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +INSTANTIATE_TEST_CASE_P(FooFac, FacilityTests, Values(&FooConstructor)); +INSTANTIATE_TEST_CASE_P(FooFac, AgentTests, Values(&FooConstructor)); diff --git a/src/foo_tests.h b/src/foo_tests.h new file mode 100644 index 0000000000..59888926b7 --- /dev/null +++ b/src/foo_tests.h @@ -0,0 +1,34 @@ +#ifndef CYCAMORE_SRC_FOO_TESTS_H_ +#define CYCAMORE_SRC_FOO_TESTS_H_ +#include "foo.h" + +#include + +#include + +#include "agent_tests.h" +#include "context.h" +#include "exchange_context.h" +#include "facility_tests.h" +#include "material.h" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +class FooTest : public ::testing::Test { + public: + cyclus::TestContext tc; + TestFacility* trader; + cycamore::Foo* src_facility; + std::string commod, recipe_name; + double capacity; + cyclus::Composition::Ptr recipe; + + virtual void SetUp(); + virtual void TearDown(); + void InitParameters(); + void SetUpFoo(); + + boost::shared_ptr< cyclus::ExchangeContext > + GetContext(int nreqs, std::string commodity); +}; + +#endif // CYCAMORE_SRC_FOO_TESTS_H_ From 3797bf5dbc1f1d827b4c48ef2b5650b5a16e54f2 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 14:53:53 -0500 Subject: [PATCH 241/314] Revert "adding failure with an explicit check" This reverts commit d7c653699506e3aa4229840db5b97f24bc73d4f4. --- .travis-install.sh | 2 - src/CMakeLists.txt | 2 - src/foo.cc | 171 ------------------------------------- src/foo.h | 204 --------------------------------------------- src/foo_tests.cc | 204 --------------------------------------------- src/foo_tests.h | 34 -------- 6 files changed, 617 deletions(-) delete mode 100644 src/foo.cc delete mode 100644 src/foo.h delete mode 100644 src/foo_tests.cc delete mode 100644 src/foo_tests.h diff --git a/.travis-install.sh b/.travis-install.sh index 08a02557a1..1f9e8a8e15 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -10,8 +10,6 @@ unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml # build -"src/CMakeLists.txt:" -cat src/CMakeLists.txt cmd="conda build --no-test conda-recipe" echo "cmd: $cmd" $cmd diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 29e907624e..6a29fcff22 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,8 +12,6 @@ USE_CYCLUS("cycamore" "sink") USE_CYCLUS("cycamore" "source") -USE_CYCLUS("cycamore" "foo") - USE_CYCLUS("cycamore" "deploy_inst") USE_CYCLUS("cycamore" "manager_inst") diff --git a/src/foo.cc b/src/foo.cc deleted file mode 100644 index 9ad8ada201..0000000000 --- a/src/foo.cc +++ /dev/null @@ -1,171 +0,0 @@ -#include "foo.h" - -#include -#include - -#include - -namespace cycamore { - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Foo::Foo(cyclus::Context* ctx) - : cyclus::Facility(ctx), - out_commod(""), - recipe_name(""), - capacity(std::numeric_limits::max()) {} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Foo::~Foo() {} - -#pragma cyclus def clone cycamore::Foo - -#pragma cyclus def schema cycamore::Foo - -#pragma cyclus def annotations cycamore::Foo - -#pragma cyclus def infiletodb cycamore::Foo - -#pragma cyclus def snapshot cycamore::Foo - -#pragma cyclus def snapshotinv cycamore::Foo - -#pragma cyclus def initinv cycamore::Foo - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::InitFrom(Foo* m) { - #pragma cyclus impl initfromcopy cycamore::Foo - cyclus::toolkit::CommodityProducer::Copy(m); -} - -void Foo::InitFrom(cyclus::QueryableBackend* b) { - #pragma cyclus impl initfromdb cycamore::Foo - - commod_ = cyclus::toolkit::Commodity(out_commod); - cyclus::toolkit::CommodityProducer::Add(commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); - cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); -} - -void Foo::EnterNotify() { - Facility::EnterNotify(); - commod_ = cyclus::toolkit::Commodity(out_commod); - cyclus::toolkit::CommodityProducer::Add(commod_); - cyclus::toolkit::CommodityProducer::SetCapacity(commod_, capacity); - cyclus::toolkit::CommodityProducer::SetCost(commod_, capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::string Foo::str() { - std::stringstream ss; - std::string ans; - if (cyclus::toolkit::CommodityProducer:: - Produces(cyclus::toolkit::Commodity(out_commod))) { - ans = "yes"; - } else { - ans = "no"; - } - ss << cyclus::Facility::str() - << " supplies commodity '" - << out_commod << "' with recipe '" - << recipe_name << "' at a capacity of " - << capacity << " kg per time step " - << " commod producer members: " << " produces " - << out_commod << "?: " << ans - << " capacity: " << cyclus::toolkit::CommodityProducer::Capacity(commod_) - << " cost: " << cyclus::toolkit::CommodityProducer::Cost(commod_); - return ss.str(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::Tick() { - LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is ticking {"; - LOG(cyclus::LEV_INFO4, "SrcFac") << "will offer " << capacity - << " kg of " - << out_commod << "."; - LOG(cyclus::LEV_INFO3, "SrcFac") << "Stats: " << str(); - LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; - current_capacity = capacity; // reset capacity -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::Tock() { - LOG(cyclus::LEV_INFO3, "SrcFac") << prototype() << " is tocking {"; - LOG(cyclus::LEV_INFO3, "SrcFac") << "}"; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Material::Ptr Foo::GetOffer( - const cyclus::Material::Ptr target) const { - using cyclus::Material; - double qty = std::min(target->quantity(), capacity); - return Material::CreateUntracked(qty, context()->GetRecipe(recipe_name)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::set::Ptr> -Foo::GetMatlBids( - cyclus::CommodMap::type& commod_requests) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::Material; - using cyclus::Request; - - std::set::Ptr> ports; - - if (commod_requests.count(out_commod) > 0) { - BidPortfolio::Ptr port(new BidPortfolio()); - - std::vector*>& requests = - commod_requests[out_commod]; - - std::vector*>::iterator it; - for (it = requests.begin(); it != requests.end(); ++it) { - Request* req = *it; - Material::Ptr offer = GetOffer(req->target()); - port->AddBid(req, offer, this); - } - - CapacityConstraint cc(capacity); - port->AddConstraint(cc); - ports.insert(port); - } - return ports; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Foo::GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses) { - using cyclus::Material; - using cyclus::Trade; - - double provided = 0; - std::vector< cyclus::Trade >::const_iterator it; - for (it = trades.begin(); it != trades.end(); ++it) { - double qty = it->amt; - current_capacity -= qty; - provided += qty; - // @TODO we need a policy on negatives.. - Material::Ptr response = Material::Create(this, qty, - context()->GetRecipe(recipe_name)); - responses.push_back(std::make_pair(*it, response)); - LOG(cyclus::LEV_INFO5, "SrcFac") << prototype() << " just received an order" - << " for " << qty - << " of " << out_commod; - } - if (cyclus::IsNegative(current_capacity)) { - std::stringstream ss; - ss << "is being asked to provide " << provided - << " but its capacity is " << capacity << "."; - throw cyclus::ValueError(Agent::InformErrorMsg(ss.str())); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -extern "C" cyclus::Agent* ConstructFoo(cyclus::Context* ctx) { - return new Foo(ctx); -} - -} // namespace cycamore diff --git a/src/foo.h b/src/foo.h deleted file mode 100644 index e35ab83d99..0000000000 --- a/src/foo.h +++ /dev/null @@ -1,204 +0,0 @@ -#ifndef CYCAMORE_SRC_FOO_H_ -#define CYCAMORE_SRC_FOO_H_ - -#include -#include - -#include "cyclus.h" - -namespace cycamore { - -class Context; - -/// @class Foo -/// This cyclus::Facility provides a simple source of some capacity -/// (possibly infinite) of some commodity/Recipe. - -/// The Foo class inherits from the cyclus::Facility class and is -/// dynamically loaded by the Agent class when requested. - -/// @section introduction Introduction -/// The Foo is a facility type in Cyclus capable of providing -/// a finite or infinite.Supply of a particular material to the -/// simulation. A Foo generates material of a certain -/// composition and commodity type, then offers that material on the -/// appropriate market. Shipments of this material are executed when the -/// market issues an order that the offer has been matched with a -/// request. - -/// @section agentparams Agent Parameters -/// Foo behavior is comprehensively defined by the following -/// parameters: -/// - double capacity: The production capacity of the facility (units -/// vary, but typically kg/month). Capacity is infinite if a negative -/// value is provided. -/// - int startDate: The date on which the facility begins to operate -/// (months). -/// - int lifeTime: The length of time that the facility operates -/// (months). - std::string outCommod: the commodity that this facility -/// produces - double inventorysize: the maximum quantity of material to -/// be held in the inventory -/// - double commodprice: the price of the output material PER UNIT -/// - map outComp - -/// @section optionalparams Optional Parameters -/// Foo behavior may also be specified with the following -/// optional parameters which have default values listed here. -/// - double capacityFactor: The ratio of actual production capacity to -/// the rated production capacity. Default is 1 (actual/rated). -/// - double availFactor: The percent of time the facility operates at -/// its capacity factor. Default is 100%. -/// - double capitalCost: The cost of constructing and commissioning -/// this facility. Default is 0 ($). -/// - double opCost: The annual cost of operation and maintenance of -/// this facility. Default is 0 ( $/year). -/// - int constrTime: The number of months it takes to construct and -/// commission this facility. Default is 0 (months). -/// - int decomTime: The number of months it takes to deconstruct and -/// decommission this facility. Default is 0 (months). -/// - Inst* inst: The institution responsible for this facility. -/// - string name: A non-generic name for this facility. - -/// @section detailed Detailed Behavior -/// @subsection finite If Finite Capacity: -/// The Foo starts operation when the simulation reaches the -/// month specified as the startDate. It immediately begins to produce -/// material at the rate defined by its capacity. Each month the -/// Foo adds the amount it has produced to its inventory. It -/// then offers to the appropriate market exactly as much material as it -/// has in its inventory. If an offer is matched with a request, the -/// Foo executes that order by subtracting the quantity from -/// its inventory and sending that amount to the requesting facility. -/// When the simulation time equals the startDate plus the lifeTime, the -/// facility ceases to operate. -/// @subsection infinite If Infinite Capacity: -/// The Foo starts operation when the simulation reaches the -/// month specified as the startDate. Each month the Foo -/// offers an infinite amount of material to the appropriate market. If -/// there is a request for that material, the Foo executes -/// that order by sending that amount to the requesting facility. When -/// the simulation time equals the startDate plus the lifeTime, the -/// facility ceases to operate. - -/// @subsection question Question: -/// What is the best way to allow offers of an infinite amount of -/// material on a market? - -class Foo : public cyclus::Facility, - public cyclus::toolkit::CommodityProducer { - public: - // --- Module Members --- - /// Constructor for the Foo class - /// @param ctx the cyclus context for access to simulation-wide parameters - Foo(cyclus::Context* ctx); - - virtual ~Foo() - - #pragma cyclus decl - - #pragma cyclus note {"doc": "A source facility that provides a " \ - "commodity with a given capacity"} - - /// Print information about this agent - virtual std::string str(); - // --- - - // --- Agent Members --- - virtual void EnterNotify(); - - /// Each facility is prompted to do its beginning-of-time-step - /// stuff at the tick of the timer. - - /// @param time is the time to perform the tick - virtual void Tick(); - - /// Each facility is prompted to its end-of-time-step - /// stuff on the tock of the timer. - - /// @param time is the time to perform the tock - virtual void Tock(); - - /// @brief Responds to each request for this source facility's commodity. - /// If a given request is more than this facility's capacity, it will offer - /// its capacity. - virtual std::set::Ptr> - GetMatlBids(cyclus::CommodMap::type& - commod_requests); - - /// @brief respond to each trade with a material made from this facility's - /// recipe - /// - /// @param trades all trades in which this trader is the supplier - /// @param responses a container to populate with responses to each trade - virtual void GetMatlTrades( - const std::vector< cyclus::Trade >& trades, - std::vector, - cyclus::Material::Ptr> >& responses); - // --- - - // --- Foo Members --- - /// @brief creates a material object to offer to a requester - /// @param target the material target a request desires - cyclus::Material::Ptr GetOffer(const cyclus::Material::Ptr target) const; - - /// sets the output commodity name - /// @param name the commodity name - inline void commodity(std::string name) { out_commod = name; } - - /// @return the output commodity - inline std::string commodity() const { return out_commod; } - - /// sets the capacity of a material generated at any given time step - /// @param capacity the production capacity - inline void Capacity(double cap) { - capacity = cap; - current_capacity = capacity; - } - - /// @return the production capacity at any given time step - inline double Capacity() const { return capacity; } - - /// sets the name of the recipe to be produced - /// @param name the recipe name - inline void recipe(std::string name) { recipe_name = name; } - - /// @return the name of the output recipe - inline std::string recipe() const { return recipe_name; } - - /// @return the current timestep's capacity - inline double CurrentCapacity() const { return current_capacity; } - - private: - cyclus::toolkit::Commodity commod_; - - /// This facility has only one output commodity - #pragma cyclus var {"tooltip": "source output commodity", \ - "doc": "output commodity that the source facility " \ - "supplies", \ - "uitype": "outcommodity"} - std::string out_commod; - - /// Name of the recipe this facility uses. - #pragma cyclus var {"tooltip": "commodity recipe name", \ - "doc": "recipe name for source facility's commodity", \ - "uitype": "recipe"} - std::string recipe_name; - - /// The capacity is defined in terms of the number of units of the - /// recipe that can be provided each time step. A very large number - /// can be provided to represent infinte capacity. - #pragma cyclus var {"default": 1e299, "tooltip": "source capacity", \ - "doc": "amount of commodity that can be supplied " \ - "at each time step"} - double capacity; - - /// The capacity at the current time step - #pragma cyclus var {'derived_init': 'current_capacity = capacity;'} - double current_capacity; - - // --- -}; - -} // namespace cycamore - -#endif // CYCAMORE_SRC_FOO_H_ diff --git a/src/foo_tests.cc b/src/foo_tests.cc deleted file mode 100644 index 0973e794d0..0000000000 --- a/src/foo_tests.cc +++ /dev/null @@ -1,204 +0,0 @@ -#include "foo_tests.h" - -#include - -#include - -#include "cyc_limits.h" -#include "resource_helpers.h" -#include "test_context.h" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::SetUp() { - src_facility = new cycamore::Foo(tc.get()); - trader = tc.trader(); - InitParameters(); - SetUpFoo(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::TearDown() { - delete src_facility; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::InitParameters() { - commod = "commod"; - recipe_name = "recipe"; - capacity = 5; // some magic number.. - - recipe = cyclus::Composition::CreateFromAtom(cyclus::CompMap()); - tc.get()->AddRecipe(recipe_name, recipe); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void FooTest::SetUpFoo() { - src_facility->commodity(commod); - src_facility->recipe(recipe_name); - src_facility->Capacity(capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, InitialState) { - EXPECT_EQ(src_facility->Capacity(), capacity); - EXPECT_EQ(src_facility->commodity(), commod); - EXPECT_EQ(src_facility->recipe(), recipe_name); - EXPECT_EQ(src_facility->CurrentCapacity(), capacity); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Clone) { - cyclus::Context* ctx = tc.get(); - cycamore::Foo* cloned_fac = dynamic_cast - (src_facility->Clone()); - - EXPECT_EQ(src_facility->commodity(), cloned_fac->commodity()); - EXPECT_EQ(src_facility->Capacity(), cloned_fac->Capacity()); - EXPECT_EQ(src_facility->recipe(), cloned_fac->recipe()); - EXPECT_EQ(src_facility->Capacity(), cloned_fac->CurrentCapacity()); - - delete cloned_fac; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Print) { - EXPECT_NO_THROW(std::string s = src_facility->str()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, GetOffer) { - using cyclus::Material; - - double qty = capacity - 1; - Material::Ptr mat = cyclus::NewBlankMaterial(qty); - Material::Ptr obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), qty); - EXPECT_EQ(obs_mat->comp(), recipe); - - qty = capacity + 1; - mat = cyclus::NewBlankMaterial(qty); - obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), capacity); - EXPECT_EQ(obs_mat->comp(), recipe); - - qty = capacity; - mat = cyclus::NewBlankMaterial(qty); - obs_mat = src_facility->GetOffer(mat); - EXPECT_EQ(obs_mat->quantity(), capacity); - EXPECT_EQ(obs_mat->comp(), recipe); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, AddBids) { - using cyclus::Bid; - using cyclus::BidPortfolio; - using cyclus::CapacityConstraint; - using cyclus::ExchangeContext; - using cyclus::Material; - - int nreqs = 5; - - boost::shared_ptr< cyclus::ExchangeContext > - ec = GetContext(nreqs, commod); - - std::set::Ptr> ports = - src_facility->GetMatlBids(ec.get()->commod_requests); - - ASSERT_TRUE(ports.size() > 0); - EXPECT_EQ(ports.size(), 1); - - BidPortfolio::Ptr port = *ports.begin(); - EXPECT_EQ(port->bidder(), src_facility); - EXPECT_EQ(port->bids().size(), nreqs); - - const std::set< CapacityConstraint >& constrs = port->constraints(); - ASSERT_TRUE(constrs.size() > 0); - EXPECT_EQ(constrs.size(), 1); - EXPECT_EQ(*constrs.begin(), CapacityConstraint(capacity)); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TEST_F(FooTest, Response) { - using cyclus::Bid; - using cyclus::Material; - using cyclus::Request; - using cyclus::Trade; - using test_helpers::get_mat; - - std::vector< cyclus::Trade > trades; - std::vector, - cyclus::Material::Ptr> > responses; - - // Null response - EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); - EXPECT_EQ(responses.size(), 0); - - double qty = capacity / 3; - Request* request = - Request::Create(get_mat(), trader, commod); - Bid* bid = - Bid::Create(request, get_mat(), src_facility); - - Trade trade(request, bid, qty); - trades.push_back(trade); - - // 1 trade - ASSERT_EQ(src_facility->CurrentCapacity(), capacity); - src_facility->GetMatlTrades(trades, responses); - EXPECT_EQ(responses.size(), 1); - EXPECT_EQ(responses[0].second->quantity(), qty); - EXPECT_EQ(responses[0].second->comp(), recipe); - - // 2 trades, total qty = capacity - ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity - qty); - ASSERT_GT(src_facility->CurrentCapacity() - 2 * qty, -1 * cyclus::eps()); - trades.push_back(trade); - responses.clear(); - EXPECT_NO_THROW(src_facility->GetMatlTrades(trades, responses)); - EXPECT_EQ(responses.size(), 2); - ASSERT_TRUE(cyclus::AlmostEq(src_facility->CurrentCapacity(), 0)); - - // too much qty, capn! - EXPECT_THROW(src_facility->GetMatlTrades(trades, responses), - cyclus::ValueError); - - // reset! - src_facility->Tick(); - ASSERT_DOUBLE_EQ(src_facility->CurrentCapacity(), capacity); - - delete request; - delete bid; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -boost::shared_ptr< cyclus::ExchangeContext > -FooTest::GetContext(int nreqs, std::string commod) { - using cyclus::Material; - using cyclus::Request; - using cyclus::ExchangeContext; - using test_helpers::get_mat; - - double qty = 3; - boost::shared_ptr< ExchangeContext > - ec(new ExchangeContext()); - for (int i = 0; i < nreqs; i++) { - ec->AddRequest(Request::Create(get_mat(), trader, commod)); - } - return ec; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -cyclus::Agent* FooConstructor(cyclus::Context* ctx) { - return new cycamore::Foo(ctx); -} - -// required to get functionality in cyclus agent unit tests library -#ifndef CYCLUS_AGENT_TESTS_CONNECTED -int ConnectAgentTests(); -static int cyclus_agent_tests_connected = ConnectAgentTests(); -#define CYCLUS_AGENT_TESTS_CONNECTED cyclus_agent_tests_connected -#endif // CYCLUS_AGENT_TESTS_CONNECTED - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -INSTANTIATE_TEST_CASE_P(FooFac, FacilityTests, Values(&FooConstructor)); -INSTANTIATE_TEST_CASE_P(FooFac, AgentTests, Values(&FooConstructor)); diff --git a/src/foo_tests.h b/src/foo_tests.h deleted file mode 100644 index 59888926b7..0000000000 --- a/src/foo_tests.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef CYCAMORE_SRC_FOO_TESTS_H_ -#define CYCAMORE_SRC_FOO_TESTS_H_ -#include "foo.h" - -#include - -#include - -#include "agent_tests.h" -#include "context.h" -#include "exchange_context.h" -#include "facility_tests.h" -#include "material.h" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -class FooTest : public ::testing::Test { - public: - cyclus::TestContext tc; - TestFacility* trader; - cycamore::Foo* src_facility; - std::string commod, recipe_name; - double capacity; - cyclus::Composition::Ptr recipe; - - virtual void SetUp(); - virtual void TearDown(); - void InitParameters(); - void SetUpFoo(); - - boost::shared_ptr< cyclus::ExchangeContext > - GetContext(int nreqs, std::string commodity); -}; - -#endif // CYCAMORE_SRC_FOO_TESTS_H_ From 35aa9551ccef55900132ddd75d86648ce809468e Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 14:55:17 -0500 Subject: [PATCH 242/314] this should fail unit tests --- src/source_tests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source_tests.cc b/src/source_tests.cc index eea1d9c38d..556623a82f 100644 --- a/src/source_tests.cc +++ b/src/source_tests.cc @@ -107,7 +107,7 @@ TEST_F(SourceTest, Response) { // 1 trade src_facility->GetMatlTrades(trades, responses); EXPECT_EQ(responses.size(), 1); - EXPECT_EQ(responses[0].second->quantity(), qty); + EXPECT_EQ(responses[0].second->quantity(), qty + 1); EXPECT_EQ(responses[0].second->comp(), recipe); // 2 trades, total qty = capacity From facd65eff6f6d6bb106624aa3c4e9f1a9c86772c Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 15:04:56 -0500 Subject: [PATCH 243/314] Revert "this should fail unit tests" This reverts commit 8e904cdf8ddedbb16a18f6aa6487df6e33734ee7. --- src/source_tests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source_tests.cc b/src/source_tests.cc index 556623a82f..eea1d9c38d 100644 --- a/src/source_tests.cc +++ b/src/source_tests.cc @@ -107,7 +107,7 @@ TEST_F(SourceTest, Response) { // 1 trade src_facility->GetMatlTrades(trades, responses); EXPECT_EQ(responses.size(), 1); - EXPECT_EQ(responses[0].second->quantity(), qty + 1); + EXPECT_EQ(responses[0].second->quantity(), qty); EXPECT_EQ(responses[0].second->comp(), recipe); // 2 trades, total qty = capacity From 67172274292248624f70f838fbadca1d1b218f4b Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 15:32:58 -0500 Subject: [PATCH 244/314] Addressing @scopatz's comments --- .travis-install.sh | 10 ++++------ .travis.yml | 2 -- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/.travis-install.sh b/.travis-install.sh index 1f9e8a8e15..c6a2e10c90 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -x + # log msg=`git log --pretty=oneline -1` echo "Building commit: $msg" @@ -10,9 +12,7 @@ unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml # build -cmd="conda build --no-test conda-recipe" -echo "cmd: $cmd" -$cmd +conda build --no-test conda-recipe status=$? echo "status: $status" if [[ $status != 0 ]]; then @@ -20,9 +20,7 @@ if [[ $status != 0 ]]; then fi # install -cmd="conda install --use-local cycamore=0.0" -echo "cmd: $cmd" -$cmd +conda install --use-local cycamore=0.0 status=$? echo "status: $status" if [[ $status != 0 ]]; then diff --git a/.travis.yml b/.travis.yml index 5153f20149..54cdd1f8ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,8 +39,6 @@ install: script: - export PATH="$HOME/miniconda/bin:$PATH" - export LD_LIBRARY_PATH="$HOME/miniconda/lib:$LD_LIBRARY_PATH" - #- ls -l $HOME/miniconda/lib - #- ls -l $HOME/miniconda/envs/_build/lib - cycamore_unit_tests - conda install numpy pytables - nosetests -w tests From 09edea328a09e1d6e7131620437f18787d65a16a Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 15:38:05 -0500 Subject: [PATCH 245/314] set -e --- .travis-install.sh | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/.travis-install.sh b/.travis-install.sh index c6a2e10c90..f4cf6adae1 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -1,6 +1,7 @@ #!/bin/bash -set -x +set -x # print cmds +set -e # exit as soon as an error occurs # log msg=`git log --pretty=oneline -1` @@ -13,16 +14,6 @@ sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml # build conda build --no-test conda-recipe -status=$? -echo "status: $status" -if [[ $status != 0 ]]; then - exit $status -fi # install conda install --use-local cycamore=0.0 -status=$? -echo "status: $status" -if [[ $status != 0 ]]; then - exit $status -fi From 59f3c6d882f536f5b881358072dfd65f6e3c3cf2 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 15:04:32 -0500 Subject: [PATCH 246/314] removed testing-specific repo and branch info --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 54cdd1f8ad..6a126fed6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,9 +27,8 @@ install: - conda info -a # install cyclus - - git clone https://github.com/gidden/cyclus ../cyclus + - git clone https://github.com/cyclus/cyclus ../cyclus - cd ../cyclus - - git checkout origin/travis - ./.travis-install.sh - cd ../cycamore From 321d900077d1195536959120658ea44b24b7dbbd Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 23 Apr 2015 15:35:05 -0500 Subject: [PATCH 247/314] updating ciclus pull --- .travis-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis-install.sh b/.travis-install.sh index f4cf6adae1..0ec08d2ea3 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -8,7 +8,7 @@ msg=`git log --pretty=oneline -1` echo "Building commit: $msg" # setup conda recipe -wget https://github.com/gidden/ciclus/archive/travis.zip -O ciclus.zip +wget https://github.com/cyclus/ciclus/archive/master.zip -O ciclus.zip unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml From b1a429cf08b203c52576c602c59a3382af646bd3 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Fri, 24 Apr 2015 15:20:08 -0500 Subject: [PATCH 248/314] bad non-flat schema --- input/recycle.xml | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/input/recycle.xml b/input/recycle.xml index 406994c642..1167ad498f 100644 --- a/input/recycle.xml +++ b/input/recycle.xml @@ -1,5 +1,4 @@ - flat 600 1 @@ -110,12 +109,40 @@ - repo1 repo - r1 reactor - depleted1 depleted_src - fab1 fuelfab - sep1 separations - enrich1 enrichment + + SingleRegion + + + SingleInstitution + + + repo + 1 + + + reactor + 1 + + + depleted_src + 1 + + + fuelfab + 1 + + + separations + 1 + + + enrichment + 1 + + + + + natl_u From 741fbfd3045d36711f4595156fd3e75709b38e6e Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Fri, 24 Apr 2015 18:43:38 -0500 Subject: [PATCH 249/314] using non-flat schema --- input/recycle.xml | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/input/recycle.xml b/input/recycle.xml index 1167ad498f..278662a345 100644 --- a/input/recycle.xml +++ b/input/recycle.xml @@ -6,6 +6,8 @@ + agents NullInst + agents NullRegion cycamore Source cycamore Sink cycamore Enrichment @@ -14,7 +16,7 @@ cycamore Separations - + enrichment @@ -27,9 +29,9 @@ 1e100 - + - + separations @@ -50,9 +52,9 @@ 2.0 - + - + fuelfab @@ -68,9 +70,9 @@ 30001 - + - + reactor @@ -87,9 +89,9 @@ 1 - + - + repo @@ -97,9 +99,9 @@ 1e100 - + - + depleted_src @@ -107,7 +109,7 @@ depleted_u - + SingleRegion From c9d1c42d4926a2d469153ab3855f82589d411424 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Sat, 25 Apr 2015 10:04:34 -0500 Subject: [PATCH 250/314] fixes input file for new source schema --- input/growth/source_sink_linear.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/input/growth/source_sink_linear.xml b/input/growth/source_sink_linear.xml index b9708be956..61afe79539 100644 --- a/input/growth/source_sink_linear.xml +++ b/input/growth/source_sink_linear.xml @@ -18,9 +18,9 @@ Source1 - commodity - commod_recipe - 1.1 + commodity + commod_recipe + 1.1 @@ -29,9 +29,9 @@ Source2 - commodity - commod_recipe - 2 + commodity + commod_recipe + 2 From b2b6e5198da219dbea660e984c77b4dd50f68bf8 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 9 Apr 2015 15:24:11 -0500 Subject: [PATCH 251/314] add run_inputs to tests --- tests/CMakeLists.txt | 2 +- tests/run_inputs.py.in | 74 +++++++++++++++++++++------------------- tests/test_run_inputs.py | 13 +++++++ 3 files changed, 53 insertions(+), 36 deletions(-) create mode 100644 tests/test_run_inputs.py diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 934ff21b51..2ec825551b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,7 +10,7 @@ SET(cyclus_path ${CYCLUS_ROOT_DIR}/bin) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/run_inputs.py.in ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/run_inputs.py @ONLY) -SET(input_path ${PROJECT_SOURCE_DIR}/../input) +SET(input_path ${PROJECT_SOURCE_DIR}/input) SET(cyclus_path ${CYCLUS_ROOT_DIR}/bin) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/run_inputs.py.in ${CMAKE_CURRENT_SOURCE_DIR}/run_inputs.py @ONLY) diff --git a/tests/run_inputs.py.in b/tests/run_inputs.py.in index b6aae68bf1..49be1fe64c 100644 --- a/tests/run_inputs.py.in +++ b/tests/run_inputs.py.in @@ -5,12 +5,11 @@ import subprocess from subprocess import Popen, PIPE, STDOUT import os import re - -def main(): - """This function finds input files, runs them, and prints a summary""" - flag = check_inputs() - input_path = "@input_path@" - cyclus_path = "@cyclus_path@/cyclus" + +cyclus_path = "@cyclus_path@/cyclus" +input_path = "@input_path@" + +def main_body(flag): files, catalogs, catalognames = get_files(input_path) copy_catalogs(catalogs,cyclus_path.strip("cyclus")) summ = Summary() @@ -20,7 +19,12 @@ def main(): summ.add_to_summary(file_to_test) clean_catalogs(cyclus_path.strip("cyclus"),catalognames) summ.print_summary() - + +def main(): + """This function finds input files, runs them, and prints a summary""" + flag = check_inputs() + main_body(flag) + def check_inputs(): """This function checks the input arguments""" if len(sys.argv) > 2: @@ -38,19 +42,19 @@ def check_inputs(): def print_usage() : """This prints the proper way to treat the command line interface""" - print 'Usage: python run_inputs.py\n' + \ - 'Allowed Options : \n' + \ - '-v arg output log verbosity. \n' + \ - ' \ - Can be text: \n' + \ - ' \ - LEV_ERROR (least verbose, default), LEV_WARN,\n' + \ - ' \ - LEV_INFO1 (through 5), and LEV_DEBUG1 (through 5).\n' + \ - ' \ - Or an integer:\n'+ \ - ' \ - 0 (LEV_ERROR equiv) through 11 (LEV_DEBUG5 equiv)\n' + print(""" Usage: python run_inputs.py\n + Allowed Options : \n + -v arg output log verbosity. \n + + Can be text: \n + + LEV_ERROR (least verbose, default), LEV_WARN,\n + + LEV_INFO1 (through 5), and LEV_DEBUG1 (through 5).\n + + Or an integer:\n + + 0 (LEV_ERROR equiv) through 11 (LEV_DEBUG5 equiv)\n""") def get_files(path): """This function walks the 'path' tree and finds input files""" @@ -70,10 +74,10 @@ def get_files(path): inputs.append(os.path.join(root, name)) else : files.remove(name) - print "The catalogs to be moved are:" - print catalogs - print "The files to be tested are:" - print inputs + print("The catalogs to be moved are:") + print(catalogs) + print("The files to be tested are:") + print(inputs) return inputs, catalogs, catalognames def copy_catalogs(catalogs,cyclus_path) : @@ -103,11 +107,11 @@ class Summary(): def print_summary(self) : """Prints the summary""" - print "Input files passed = " + str(len(self.passed)) - print "Input files failed = " + str(len(self.failed)) - print "Failed input files : " + print("Input files passed = " + str(len(self.passed))) + print("Input files failed = " + str(len(self.failed))) + print("Failed input files : ") for test in self.failed : - print test + print(test) class TestFile(): """An object representing the inputxml file to test""" @@ -132,22 +136,22 @@ class TestFile(): shell=True, stdout=PIPE, stderr=STDOUT) io_tuple = p.communicate() output = io_tuple[0] - except subprocess.CalledProcessError, e: + except subprocess.CalledProcessError as e: print(e) - return output + return str(output) def no_errors(self, output): """returns true if there were no errors or segfaults running this TestFile""" to_ret = True - print "Input file " + self.infile + print("Input file " + self.infile) if re.search("No such file or directory",output) : - print "Cyclus executable not found in path." + print("Cyclus executable not found in path.") elif re.search("ERROR",output) or re.search("Segmentation fault",output): to_ret = False - print " resulted in errors: " - print output + print(" resulted in errors: ") + print(output) else : - print " passed. " + print(" passed. ") return to_ret if __name__ == '__main__' : main() diff --git a/tests/test_run_inputs.py b/tests/test_run_inputs.py new file mode 100644 index 0000000000..48abcd16c3 --- /dev/null +++ b/tests/test_run_inputs.py @@ -0,0 +1,13 @@ +import os +import subprocess + +from nose.tools import assert_true + +import run_inputs as ri + +def test_inputs(): + files, _, _ = ri.get_files(ri.input_path) + for f in files: + testf = ri.TestFile(ri.cyclus_path, f, "-v0") + testf.run() + yield assert_true, testf.passed From 66a31d46004bee090933a4977b89b3684d21ef75 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 28 Apr 2015 16:14:31 -0500 Subject: [PATCH 252/314] moving conda files to this repo --- .travis-install.sh | 8 +++----- conda/build.sh | 38 ++++++++++++++++++++++++++++++++++++++ conda/meta.yaml | 29 +++++++++++++++++++++++++++++ conda/post-link.sh | 17 +++++++++++++++++ conda/pre-link.sh | 6 ++++++ 5 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 conda/build.sh create mode 100644 conda/meta.yaml create mode 100644 conda/post-link.sh create mode 100644 conda/pre-link.sh diff --git a/.travis-install.sh b/.travis-install.sh index 0ec08d2ea3..c59a20f171 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -7,13 +7,11 @@ set -e # exit as soon as an error occurs msg=`git log --pretty=oneline -1` echo "Building commit: $msg" -# setup conda recipe -wget https://github.com/cyclus/ciclus/archive/master.zip -O ciclus.zip -unzip -j ciclus.zip "*/cycamore/*" -d conda-recipe -sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml +# setup conda recipe to use develop cyclus +sed -i "s/- cyclus/- cyclus 0.0/g" conda/meta.yaml # build -conda build --no-test conda-recipe +conda build --no-test conda # install conda install --use-local cycamore=0.0 diff --git a/conda/build.sh b/conda/build.sh new file mode 100644 index 0000000000..86da896a41 --- /dev/null +++ b/conda/build.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +mkdir build +cd build +export LD_LIBRARY_PATH=$PREFIX/lib/ +export CMAKE_LIBRARY_PATH=$PREFIX/lib/ +export PATH=$PREFIX/bin:$PATH +export MACOSX_DEPLOYMENT_TARGET= + +$PREFIX/bin/cyclus --version + +if [[ `uname` == 'Linux' ]]; then + cmake .. \ + -DCMAKE_INSTALL_PREFIX=$PREFIX \ + -DCYCLUS_ROOT_DIR=$PREFIX \ + -DHDF5_ROOT=$PREFIX \ + -DBOOST_ROOT=$PREFIX \ + -DBOOST_LIBRARYDIR=$PREFIX/lib \ + -DBoost_NO_SYSTEM_PATHS=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DLAPACK_LIBRARIES=$PREFIX/lib/liblapack.so \ + -DBLAS_LIBRARIES=$PREFIX/lib/libblas.so +else + export DYLD_FALLBACK_LIBRARY_PATH=$PREFIX/lib/cyclus:$PREFIX/lib + cmake .. \ + -DCMAKE_INSTALL_PREFIX=$PREFIX \ + -DCYCLUS_ROOT_DIR=$PREFIX \ + -DHDF5_ROOT=$PREFIX \ + -DCOIN_ROOT_DIR=$PREFIX \ + -DBOOST_ROOT=$PREFIX \ + -DLAPACK_LIBRARIES=$PREFIX/lib/liblapack.dylib \ + -DBLAS_LIBRARIES=$PREFIX/lib/libblas.dylib +fi + +make +make install + +echo DONE diff --git a/conda/meta.yaml b/conda/meta.yaml new file mode 100644 index 0000000000..95f525c964 --- /dev/null +++ b/conda/meta.yaml @@ -0,0 +1,29 @@ +package: + name: cycamore + version: 0.0 + +# Only use fn and url for polyphemus compatability +source: + fn: cycamore-src.tar.gz # ["TRAVIS" not in environ] + url: https://github.com/cyclus/cycamore/archive/develop.tar.gz # ["TRAVIS" not in environ] + path: .. # ["TRAVIS" in environ] + +requirements: + build: + - cyclus + - cmake + - python + run: + - cyclus + +test: + requires: + - nose + - pytables + +build: + string: nightly + +about: + home: Cyclus + license: BSD 3 Clause diff --git a/conda/post-link.sh b/conda/post-link.sh new file mode 100644 index 0000000000..d8ee67f829 --- /dev/null +++ b/conda/post-link.sh @@ -0,0 +1,17 @@ + +echo "post-link.sh, PREFIX: $PREFIX" + +mv $PREFIX/bin/cycamore_unit_tests $PREFIX/bin/cycamore_unit_tests_base +echo " +#!/bin/bash +export LD_LIBRARY_PATH=$PREFIX/lib:$PREFIX/lib/cyclus + export DYLD_FALLBACK_LIBRARY_PATH=$PREFIX/lib/cyclus +export CYCLUS_NUC_DATA=$PREFIX/share/cyclus/cyclus_nuc_data.h5 +export CYCLUS_PATH=$PREFIX/lib/cyclus +export CYCLUS_RNG_SCHEMA=$PREFIX/share/cyclus/cyclus.rng.in +export DYLD_LIBRARY_PATH= +$PREFIX/bin/cycamore_unit_tests_base \$* + +" > $PREFIX/bin/cycamore_unit_tests +chmod 755 $PREFIX/bin/cycamore_unit_tests + diff --git a/conda/pre-link.sh b/conda/pre-link.sh new file mode 100644 index 0000000000..9a188008e3 --- /dev/null +++ b/conda/pre-link.sh @@ -0,0 +1,6 @@ + +echo "pre-link.sh, PREFIX: $PREFIX" + +export LD_LIBRARY_PATH=$PREFIX/lib/:$LD_LIBRARY_PATH +export CMAKE_LIBRARY_PATH=$PREFIX/lib/:$CMAKE_LIBRARY_PATH + From 291b625f279b12e0aa9230ee550e7ab4d2cce054 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 28 Apr 2015 16:18:35 -0500 Subject: [PATCH 253/314] conda->conda-recipe --- .travis-install.sh | 4 ++-- {conda => conda-recipe}/build.sh | 0 {conda => conda-recipe}/meta.yaml | 0 {conda => conda-recipe}/post-link.sh | 0 {conda => conda-recipe}/pre-link.sh | 0 5 files changed, 2 insertions(+), 2 deletions(-) rename {conda => conda-recipe}/build.sh (100%) rename {conda => conda-recipe}/meta.yaml (100%) rename {conda => conda-recipe}/post-link.sh (100%) rename {conda => conda-recipe}/pre-link.sh (100%) diff --git a/.travis-install.sh b/.travis-install.sh index c59a20f171..cc8aff563f 100755 --- a/.travis-install.sh +++ b/.travis-install.sh @@ -8,10 +8,10 @@ msg=`git log --pretty=oneline -1` echo "Building commit: $msg" # setup conda recipe to use develop cyclus -sed -i "s/- cyclus/- cyclus 0.0/g" conda/meta.yaml +sed -i "s/- cyclus/- cyclus 0.0/g" conda-recipe/meta.yaml # build -conda build --no-test conda +conda build --no-test conda-recipe # install conda install --use-local cycamore=0.0 diff --git a/conda/build.sh b/conda-recipe/build.sh similarity index 100% rename from conda/build.sh rename to conda-recipe/build.sh diff --git a/conda/meta.yaml b/conda-recipe/meta.yaml similarity index 100% rename from conda/meta.yaml rename to conda-recipe/meta.yaml diff --git a/conda/post-link.sh b/conda-recipe/post-link.sh similarity index 100% rename from conda/post-link.sh rename to conda-recipe/post-link.sh diff --git a/conda/pre-link.sh b/conda-recipe/pre-link.sh similarity index 100% rename from conda/pre-link.sh rename to conda-recipe/pre-link.sh From ef5e019dc869b674b54b8e8a59cfb827f1f1c388 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 28 Apr 2015 17:12:14 -0500 Subject: [PATCH 254/314] we don't build nightlies --- conda-recipe/meta.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 95f525c964..cc2e038463 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -21,9 +21,6 @@ test: - nose - pytables -build: - string: nightly - about: home: Cyclus license: BSD 3 Clause From 6697fb482f893e4f15ad40bc8d14ac110fc52da0 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 29 Apr 2015 09:08:13 -0500 Subject: [PATCH 255/314] we *do* build nightlies --- conda-recipe/meta.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index cc2e038463..95f525c964 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -21,6 +21,9 @@ test: - nose - pytables +build: + string: nightly + about: home: Cyclus license: BSD 3 Clause From 1ba4b71c16f369ee0bf36280049d6c72de79d04a Mon Sep 17 00:00:00 2001 From: Anthony Scopatz Date: Thu, 30 Apr 2015 16:55:56 -0500 Subject: [PATCH 256/314] updates for nested and interleaved schema --- .gitignore | 1 + input/recycle.xml | 16 +++++++++------- src/separations_tests.cc | 20 +++++++++++--------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index ad488f2da1..f6f454de46 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ rs.cred *.h5 *.dat tests/run_inputs.py +cyclus.sqlite \ No newline at end of file diff --git a/input/recycle.xml b/input/recycle.xml index 278662a345..4eda32322e 100644 --- a/input/recycle.xml +++ b/input/recycle.xml @@ -36,13 +36,15 @@ - sep_stream - - 1e100 - - Pu .99 - - + + sep_stream + + 1e100 + + Pu .99 + + + waste diff --git a/src/separations_tests.cc b/src/separations_tests.cc index 0fb1b42c60..0b1eb62588 100644 --- a/src/separations_tests.cc +++ b/src/separations_tests.cc @@ -44,16 +44,18 @@ TEST(SeparationsTests, SepMaterial) { } TEST(SeparationsTests, SepMixElemAndNuclide) { - std::string config = + std::string config = "" - " stream1" - " " - " -1" - " " - " U 0.6" - " Pu239 .7" - " " - " " + " " + " stream1" + " " + " -1" + " " + " U 0.6" + " Pu239 .7" + " " + " " + " " "" "" "waste" From d4dd024a0f6c0edb2bce8d55571c17b1e4593630 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Fri, 1 May 2015 10:10:19 -0500 Subject: [PATCH 257/314] kill extra space --- conda-recipe/post-link.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conda-recipe/post-link.sh b/conda-recipe/post-link.sh index d8ee67f829..ed30d81a2b 100644 --- a/conda-recipe/post-link.sh +++ b/conda-recipe/post-link.sh @@ -5,7 +5,7 @@ mv $PREFIX/bin/cycamore_unit_tests $PREFIX/bin/cycamore_unit_tests_base echo " #!/bin/bash export LD_LIBRARY_PATH=$PREFIX/lib:$PREFIX/lib/cyclus - export DYLD_FALLBACK_LIBRARY_PATH=$PREFIX/lib/cyclus +export DYLD_FALLBACK_LIBRARY_PATH=$PREFIX/lib/cyclus export CYCLUS_NUC_DATA=$PREFIX/share/cyclus/cyclus_nuc_data.h5 export CYCLUS_PATH=$PREFIX/lib/cyclus export CYCLUS_RNG_SCHEMA=$PREFIX/share/cyclus/cyclus.rng.in From 7f8ee19f14adb69713ef0789f260f6dbb920faf8 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 4 May 2015 14:47:57 -0500 Subject: [PATCH 258/314] fix fuel fab buffer composition assumption bug --- src/fuel_fab.cc | 57 +++++++++++++++++++++++++++++++++++++------ src/fuel_fab_tests.cc | 46 ++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 8 deletions(-) diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index 90456aed2f..381126a974 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -225,7 +225,20 @@ void FuelFab::AcceptMatlTrades(const std::vector< throw cyclus::ValueError("cycamore::FuelFab was overmatched on requests"); } } + req_inventories_.clear(); + + // IMPORTANT - each buffer needs to be a single homogenous composition or + // the inventory mixing constraints for bids don't work + if (fill.count() > 1) { + fill.Push(cyclus::toolkit::Squash(fill.PopN(fill.count()))); + } + if (fiss.count() > 1) { + fiss.Push(cyclus::toolkit::Squash(fiss.PopN(fiss.count()))); + } + if (topup.count() > 1) { + topup.Push(cyclus::toolkit::Squash(topup.PopN(topup.count()))); + } } std::set::Ptr> FuelFab::GetMatlBids( @@ -339,9 +352,10 @@ void FuelFab::GetMatlTrades( responses) { using cyclus::Trade; + // guard against cases where a buffer is empty - this is okay because some trades + // may not need that particular buffer. double w_fill = 0; - if (fill.count() > - 0) { // it's possible to only need fissile inventory for a trade + if (fill.count() > 0) { w_fill = CosiWeight(fill.Peek()->comp(), spectrum); } double w_topup = 0; @@ -357,6 +371,7 @@ void FuelFab::GetMatlTrades( double tot = 0; for (int i = 0; i < trades.size(); i++) { Material::Ptr tgt = trades[i].request->target(); + double w_tgt = CosiWeight(tgt->comp(), spectrum); double qty = trades[i].amt; double wfiss = w_fiss; @@ -371,10 +386,18 @@ void FuelFab::GetMatlTrades( if (fiss.count() == 0) { // use straight filler to satisfy this request - responses.push_back(std::make_pair(trades[i], fill.Pop(qty))); + double fillqty = qty; + if (std::abs(fillqty - fill.quantity()) < cyclus::eps()) { + fillqty = std::min(fill.quantity(), qty); + } + responses.push_back(std::make_pair(trades[i], fill.Pop(fillqty))); } else if (fill.count() == 0 && ValidWeights(w_fill, w_tgt, w_fiss)) { // use straight fissile to satisfy this request - responses.push_back(std::make_pair(trades[i], fiss.Pop(qty))); + double fissqty = qty; + if (std::abs(fissqty - fiss.quantity()) < cyclus::eps()) { + fissqty = std::min(fiss.quantity(), qty); + } + responses.push_back(std::make_pair(trades[i], fiss.Pop(fissqty))); } else if (ValidWeights(w_fill, w_tgt, w_fiss)) { double fiss_frac = HighFrac(w_fill, w_tgt, w_fiss); double fill_frac = LowFrac(w_fill, w_tgt, w_fiss); @@ -383,10 +406,19 @@ void FuelFab::GetMatlTrades( fill_frac = AtomToMassFrac(fill_frac, fill.Peek()->comp(), fiss.Peek()->comp()); - Material::Ptr m = fiss.Pop(fiss_frac * qty); + double fissqty = fiss_frac*qty; + if (std::abs(fissqty - fiss.quantity()) < cyclus::eps()) { + fissqty = std::min(fiss.quantity(), fiss_frac*qty); + } + double fillqty = fill_frac*qty; + if (std::abs(fillqty - fill.quantity()) < cyclus::eps()) { + fillqty = std::min(fill.quantity(), fill_frac*qty); + } + + Material::Ptr m = fiss.Pop(fissqty); // this if block prevents zero qty ResBuf pop exceptions if (fill_frac > 0) { - m->Absorb(fill.Pop(fill_frac * qty)); + m->Absorb(fill.Pop(fillqty)); } responses.push_back(std::make_pair(trades[i], m)); } else { @@ -397,10 +429,19 @@ void FuelFab::GetMatlTrades( fiss_frac = AtomToMassFrac(fiss_frac, fiss.Peek()->comp(), topup.Peek()->comp()); - Material::Ptr m = fiss.Pop(fiss_frac * qty); + double fissqty = fiss_frac*qty; + if (std::abs(fissqty - fiss.quantity()) < cyclus::eps()) { + fissqty = std::min(fiss.quantity(), fiss_frac*qty); + } + double topupqty = topup_frac*qty; + if (std::abs(topupqty - topup.quantity()) < cyclus::eps()) { + topupqty = std::min(topup.quantity(), topup_frac*qty); + } + + Material::Ptr m = fiss.Pop(fissqty); // this if block prevents zero qty ResBuf pop exceptions if (topup_frac > 0) { - m->Absorb(topup.Pop(topup_frac * qty)); + m->Absorb(topup.Pop(topupqty)); } responses.push_back(std::make_pair(trades[i], m)); } diff --git a/src/fuel_fab_tests.cc b/src/fuel_fab_tests.cc index a72dcaff00..dfa0ab0baf 100644 --- a/src/fuel_fab_tests.cc +++ b/src/fuel_fab_tests.cc @@ -837,6 +837,52 @@ TEST(FuelFabTests, SwapTopup_FissConstrained) { EXPECT_NEAR(max_provide, m->quantity(), 1e-10) << "matched trade uses more fiss than available"; } +// Before this test and a fix, the fuel fab (partially) assumed each entire material +// buffer had the same composition as the material on top of the buffer when +// calculating stream mixing ratios for material to supply. This problem was +// compounded by the fact that material weights are computed on an atom basis +// and mixing is done on a mass basis - corresponding conversions resulted in +// the fab being matched for more than it could actually supply - due to +// thinking it had an inventory of higher quality material than was actually +// the case. This test makes sure that doesn't happen again. +TEST(FuelFabTests, HomogenousBuffers) { + std::string config = + "natu" + "natu" + "40" + "" + " stream1 " + "4" + "spentuox" + "" + "out" + "thermal" + "1e10" + ; + + CompMap m; + m[id("u235")] = 7; + m[id("u238")] = 86; + // the zr90 is important to force the atom-mass basis conversion to push the + // dre to overmatch in the direction we want. + m[id("zr90")] = 7; + Composition::Ptr c = Composition::CreateFromMass(m); + + int simdur = 5; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:FuelFab"), config, simdur); + sim.AddSource("stream1").start(0).lifetime(1).capacity(.01).recipe("special").Finalize(); + sim.AddSource("stream1").start(1).lifetime(1).capacity(3.98).recipe("natu").Finalize(); + sim.AddSource("natu").lifetime(1).Finalize(); + sim.AddSink("out").start(2).capacity(4).lifetime(1).recipe("uox").Finalize(); + sim.AddSink("out").start(2).capacity(4).lifetime(1).recipe("uox").Finalize(); + sim.AddRecipe("uox", c_uox()); + sim.AddRecipe("spentuox", c_pustream()); + sim.AddRecipe("natu", c_natu()); + sim.AddRecipe("special", c); + ASSERT_NO_THROW(sim.Run()); +} + } // namespace fuelfabtests } // namespace cycamore + From 260104b054e9a7bbd082f9087bec8f5be2e74137 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 5 May 2015 12:46:02 -0500 Subject: [PATCH 259/314] niche for fuel fab and separations --- src/fuel_fab.h | 1 + src/separations.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/fuel_fab.h b/src/fuel_fab.h index 1b96b48a71..8fc3ea3a7f 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -54,6 +54,7 @@ namespace cycamore { /// @endcode class FuelFab : public cyclus::Facility { #pragma cyclus note { \ +"niche": "fabrication", \ "doc": \ "FuelFab takes in 2 streams of material and mixes them in ratios in order to" \ " supply material that matches some neutronics properties of reqeusted" \ diff --git a/src/separations.h b/src/separations.h index da118ad6d4..f0cee6a025 100644 --- a/src/separations.h +++ b/src/separations.h @@ -35,6 +35,7 @@ cyclus::Material::Ptr SepMaterial(std::map effs, /// room is again available in the output streams. class Separations : public cyclus::Facility { #pragma cyclus note { \ + "niche": "separations", \ "doc": \ "Separations processes feed material into one or more streams containing" \ " specific elements and/or nuclides. It uses mass-based efficiencies." \ From 831e953bf26bc85abfc513383dc6e2631772431e Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Tue, 5 May 2015 21:09:17 -0500 Subject: [PATCH 260/314] Fix uitype typo --- src/deploy_inst.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deploy_inst.h b/src/deploy_inst.h index 7e06002df4..44db5e377e 100644 --- a/src/deploy_inst.h +++ b/src/deploy_inst.h @@ -43,7 +43,7 @@ class DeployInst : public cyclus::Institution { protected: #pragma cyclus var { \ "doc": "Ordered list of prototypes to build.", \ - "uitype": ("onormore", "prototype"), \ + "uitype": ("oneormore", "prototype"), \ } std::vector prototypes; From fc5791d10069dbffd95bd7c0feb82d0649b262b0 Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Tue, 5 May 2015 23:08:23 -0500 Subject: [PATCH 261/314] Fix spent fuel commodity uitype --- src/reactor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactor.h b/src/reactor.h index eb64663777..1e7f962a7c 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -227,7 +227,7 @@ class Reactor : public cyclus::Facility, } std::vector fuel_outrecipes; #pragma cyclus var { \ - "uitype": ["oneormore", "incommodity"], \ + "uitype": ["oneormore", "outcommodity"], \ "doc": "Output commodities on which to offer spent fuel originally received as each particular " \ " input commodity (same order)." \ } From 7f3b319c9e8ea407f412ca4eb8438040ebec6529 Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Tue, 5 May 2015 21:36:08 -0500 Subject: [PATCH 262/314] Add uilabels to deploy institution --- src/deploy_inst.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/deploy_inst.h b/src/deploy_inst.h index 44db5e377e..f31f2e227a 100644 --- a/src/deploy_inst.h +++ b/src/deploy_inst.h @@ -43,27 +43,31 @@ class DeployInst : public cyclus::Institution { protected: #pragma cyclus var { \ "doc": "Ordered list of prototypes to build.", \ - "uitype": ("oneormore", "prototype"), \ + "uitype": ("onormore", "prototype"), \ + "uilabel": "Prototypes to deploy", \ } std::vector prototypes; #pragma cyclus var { \ - "doc": "Time step on which to build agents given in prototypes (same order).", \ + "doc": "Time step on which to deploy agents given in prototype list (same order).", \ + "uilabel": "Deployment times", \ } std::vector build_times; #pragma cyclus var { \ - "doc": "Number of each prototype in prototypes var to build (same order).", \ + "doc": "Number of each prototype given in prototype list that should be deployed (same order).", \ + "uilabel": "Number to deploy", \ } std::vector n_build; #pragma cyclus var { \ - "doc": "Lifetimes for each prototype in protos (same order)." \ + "doc": "Lifetimes for each prototype in prototype list (same order)." \ " These lifetimes override the lifetimes in the original prototype definition." \ " If unspecified, lifetimes from the original prototype definitions are used." \ " Although a new prototype is created in the Prototypes table for each lifetime with the suffix '_life_[lifetime]'," \ " all deployed agents themselves will have the same original prototype name (and so will the Agents tables).", \ "default": [], \ + "uilabel": "Lifetimes" } std::vector lifetimes; }; From 7775b34e31845593aca8458ce763962ea44897f6 Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Tue, 5 May 2015 21:36:18 -0500 Subject: [PATCH 263/314] Add uilabels to enrichment facility --- src/enrichment_facility.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index def89331e4..3e3fed752e 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -269,43 +269,50 @@ class Enrichment : public cyclus::Facility { #pragma cyclus var { \ "tooltip": "feed commodity", \ "doc": "feed commodity that the enrichment facility accepts", \ + "uilabel": "Feed Commodity", \ "uitype": "incommodity" \ } std::string feed_commod; #pragma cyclus var { \ "tooltip": "product commodity", \ "doc": "product commodity that the enrichment facility generates", \ + "uilabel": "Product Commodity", \ "uitype": "outcommodity" \ } std::string product_commod; #pragma cyclus var { \ "tooltip": "feed recipe", \ "doc": "recipe for enrichment facility feed commodity", \ + "uilabel": "Feed Recipe", \ "uitype": "recipe" \ } std::string feed_recipe; #pragma cyclus var { \ "tooltip": "tails commodity", \ "doc": "tails commodity supplied by enrichment facility", \ + "uilabel": "Tails Commodity", \ "uitype": "outcommodity" \ } std::string tails_commod; #pragma cyclus var { \ "default": 0.03, "tooltip": "tails assay", \ - "doc": "tails assay from the enrichment process" \ + "uilabel": "Tails Assay", \ + "doc": "tails assay from the enrichment process", \ } double tails_assay; #pragma cyclus var { \ "default": 1e299, \ "tooltip": "SWU capacity (kgSWU/month)", \ + "uilabel": "SWU Capacity", \ "doc": "separative work unit (SWU) capacity of enrichment " \ - "facility (kgSWU/month) " \ + "facility (kgSWU/month) " \ } double swu_capacity; #pragma cyclus var { \ "default": 1e299, "tooltip": "max inventory of feed material (kg)", \ + "uilabel": "Maximum Feed Inventory", \ "doc": "maximum total inventory of natural uranium in " \ - "the enrichment facility (kg)" \ + "the enrichment facility (kg)" \ } double max_feed_inventory; @@ -313,6 +320,7 @@ class Enrichment : public cyclus::Facility { "default": 1.0, \ "tooltip": "maximum allowed enrichment fraction", \ "doc": "maximum allowed weight fraction of U235 in product",\ + "uilabel": "Maximum Allowed Enrichment", \ "schema": '' \ ' ' \ ' ' \ @@ -326,6 +334,7 @@ class Enrichment : public cyclus::Facility { #pragma cyclus var { \ "default": 0, "tooltip": "initial uranium reserves (kg)", \ + "uilabel": "Initial Feed Inventory", \ "doc": "amount of natural uranium stored at the enrichment " \ "facility at the beginning of the simulation (kg)" \ } @@ -334,6 +343,7 @@ class Enrichment : public cyclus::Facility { "default": 1, \ "userlevel": 10, \ "tooltip": "order material requests by U235 content", \ + "uilabel": "Prefer feed with higher U235 content", \ "doc": "turn on preference ordering for input material " \ "so that EF chooses higher U235 content first" \ } From e18aefdf57ad0844ea18e458c9e3c6aa39617f42 Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Tue, 5 May 2015 21:48:15 -0500 Subject: [PATCH 264/314] Add uilabels to fuel_fab facility --- src/fuel_fab.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/fuel_fab.h b/src/fuel_fab.h index 8fc3ea3a7f..7e43d9b5b1 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -129,21 +129,25 @@ class FuelFab : public cyclus::Facility { private: #pragma cyclus var { \ "doc": "Commodity on which to request material for filler stream.", \ + "uilabel": "Filler Stream Commodity", \ "uitype": "incommodity", \ } std::string fill_commod; #pragma cyclus var { \ "doc": "Name of recipe to be used in filler material stream requests.", \ + "uilabel": "Filler Stream Recipe", \ "uitype": "recipe", \ } std::string fill_recipe; #pragma cyclus var { \ "doc": "Filler material stream request preference.", \ + "uilabel": "Filler Stream Preference", \ "default": 0, \ } double fill_pref; #pragma cyclus var { \ "doc": "Size of filler material stream inventory.", \ + "uilabel": "Filler Stream Inventory Capacity", \ "units": "kg", \ } double fill_size; @@ -152,11 +156,13 @@ class FuelFab : public cyclus::Facility { #pragma cyclus var { \ "doc": "Ordered list of commodities on which to requesting fissile stream material.", \ + "uilabel": "Fissile Stream Commodities", \ "uitype": ["oneormore", "incommodity"], \ } std::vector fiss_commods; #pragma cyclus var { \ "default": [], \ + "uilabel":, "Fissile Stream Preferences", \ "doc": "Fissile stream commodity request preferences for each of the given fissile commodities (same order)." \ " If unspecified, default is to use zero for all preferences.", \ } @@ -165,11 +171,13 @@ class FuelFab : public cyclus::Facility { "doc": "Name for recipe to be used in fissile stream requests." \ " Empty string results in use of an empty dummy recipe.", \ "uitype": "recipe", \ + "uilabel": "Fissile Stream Recipes", \ "default": "", \ } std::string fiss_recipe; #pragma cyclus var { \ "doc": "Size of fissile material stream inventory.", \ + "uilabel": "Fissile Stream Inventory Capacity", \ "units": "kg", \ } double fiss_size; @@ -179,6 +187,7 @@ class FuelFab : public cyclus::Facility { #pragma cyclus var { \ "doc": "Commodity on which to request material for top-up stream." \ " This MUST be set if 'topup_size > 0'.", \ + "uilabel": "Top-up Stream Commodity", \ "default": "", \ "uitype": "incommodity", \ } @@ -186,17 +195,20 @@ class FuelFab : public cyclus::Facility { #pragma cyclus var { \ "doc": "Name of recipe to be used in top-up material stream requests." \ " This MUST be set if 'topup_size > 0'.", \ + "uilabel": "Top-up Stream Recipe", \ "uitype": "recipe", \ "default": "", \ } std::string topup_recipe; #pragma cyclus var { \ "doc": "Top-up material stream request preference.", \ + "uilabel": "Top-up Stream Preference", \ "default": 0, \ } double topup_pref; #pragma cyclus var { \ "doc": "Size of top-up material stream inventory.", \ + "uilabel": "Top-up Stream Inventory Capacity", \ "units": "kg", \ "default": 0, \ } @@ -205,6 +217,7 @@ class FuelFab : public cyclus::Facility { cyclus::toolkit::ResBuf topup; #pragma cyclus var { \ + "uilabel": "Spectrum type", \ "doc": "The type of cross-sections to use for composition property calculation." \ " Use 'fission_spectrum_ave' for fast reactor compositions or 'thermal' for thermal reactors.", \ } @@ -212,12 +225,14 @@ class FuelFab : public cyclus::Facility { #pragma cyclus var { \ "doc": "Commodity on which to offer/supply mixed fuel material.", \ + "uilabel": "Output Commodity", \ "uitype": "outcommodity", \ } std::string outcommod; #pragma cyclus var { \ "doc": "Maximum number of kg of fuel material that can be supplied per time step.", \ + "uilabel": "Maximum Throughput", \ "units": "kg", \ } double throughput; From 4d96aba481cd96b9671c908cb85b1395ab6389ef Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Tue, 5 May 2015 21:48:38 -0500 Subject: [PATCH 265/314] Make fuel_fab 'spectrum' variable 'categorical' --- src/fuel_fab.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fuel_fab.h b/src/fuel_fab.h index 7e43d9b5b1..ff18b42e38 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -218,6 +218,7 @@ class FuelFab : public cyclus::Facility { #pragma cyclus var { \ "uilabel": "Spectrum type", \ + "categorical": ['fission_spectrum_ave','thermal'], \ "doc": "The type of cross-sections to use for composition property calculation." \ " Use 'fission_spectrum_ave' for fast reactor compositions or 'thermal' for thermal reactors.", \ } From fa5ba7072b4483314634ea81813e6788c550c95f Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Tue, 5 May 2015 22:21:00 -0500 Subject: [PATCH 266/314] fix type in trailing backslash --- src/deploy_inst.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deploy_inst.h b/src/deploy_inst.h index f31f2e227a..b3d0114291 100644 --- a/src/deploy_inst.h +++ b/src/deploy_inst.h @@ -67,7 +67,7 @@ class DeployInst : public cyclus::Institution { " Although a new prototype is created in the Prototypes table for each lifetime with the suffix '_life_[lifetime]'," \ " all deployed agents themselves will have the same original prototype name (and so will the Agents tables).", \ "default": [], \ - "uilabel": "Lifetimes" + "uilabel": "Lifetimes" \ } std::vector lifetimes; }; From 9e8549ee45a1c5554280ea4199910d64ac22e366 Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Tue, 5 May 2015 22:47:54 -0500 Subject: [PATCH 267/314] Add uilabels to growth region --- src/growth_region.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/growth_region.h b/src/growth_region.h index 87526c349c..cdcdff06cc 100644 --- a/src/growth_region.h +++ b/src/growth_region.h @@ -74,20 +74,24 @@ class GrowthRegion : public cyclus::Region { #pragma cyclus var {"tooltip": "commodity in demand", \ "doc": "name of the commodity experiencing a " \ "growth in demand", \ + "uilabel": "Growth Commodity", \ "uitype": "commodity"} std::string commodity_name; #pragma cyclus var {"tooltip": "demand type", \ + "uilabel": "Demand Growth Function Form", \ "doc": "mathematical description of demand growth " \ "(i.e., linear, exponential, piecewise)"} std::vector demand_types; #pragma cyclus var {"tooltip": "demand parameters", \ + "uilabel": "Demand Growth Function Parameters", \ "doc": "parameters that define the behavior of the " \ "demand type function"} std::vector demand_params; #pragma cyclus var {"tooltip": "demand times", \ + "uilabel": "Demand Growth Piecewise Function Times", \ "doc": "vector describing the length of times " \ "regarding the piecewise demand type"} std::vector demand_times; From 29af453c3b2256eb1cac0d757d6d008eceedc9da Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Tue, 5 May 2015 23:07:27 -0500 Subject: [PATCH 268/314] Add uilabels to Manager Inst --- src/manager_inst.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/manager_inst.h b/src/manager_inst.h index 3b1142b854..5cea34467e 100644 --- a/src/manager_inst.h +++ b/src/manager_inst.h @@ -49,6 +49,7 @@ class ManagerInst #pragma cyclus var {"tooltip": "facility prototypes", \ "doc": "a facility to be managed by the institution", \ + "uilabel": "Prototype List", \ "uitype": ["none", "prototype"]} std::vector prototypes; }; From 154bd4330eec8b9c34bec0834280cdf07eb24eb8 Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Tue, 5 May 2015 23:18:36 -0500 Subject: [PATCH 269/314] Add uilabels to reactor --- src/reactor.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/reactor.h b/src/reactor.h index 1e7f962a7c..b78edc9f39 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -151,18 +151,21 @@ class Reactor : public cyclus::Facility, #pragma cyclus var { \ "default": 0, \ "doc": "Amount of electrical power the facility produces when operating normally.", \ + "uilabel": "Nominal Reactor Power", \ "units": "MWe", \ } double power_cap; #pragma cyclus var { \ "default": "power", \ + "uilabel": "Power Commodity Name", \ "doc": "The name of the 'power' commodity used in conjunction with a deployment curve.", \ } std::string power_name; //////////// inventory and core params //////////// #pragma cyclus var { \ + "uilabel": "Number of Assemblies per Batch", \ "doc": "Number of assemblies that constitute a single batch." \ "This is the number of assemblies discharged from the core fully burned each cycle." \ "Batch size is equivalent to ``n_assem_batch / n_assem_core``.", \ @@ -170,20 +173,26 @@ class Reactor : public cyclus::Facility, int n_assem_batch; #pragma cyclus var { \ "doc": "Mass (kg) of a single assembly.", \ + "uilabels": "Assembly Mass", \ "units": "kg", \ } double assem_size; #pragma cyclus var { \ + "uilabel": "Number of Assemblies in Core", \ "doc": "Number of assemblies that constitute a full core.", \ } int n_assem_core; #pragma cyclus var { \ "default": 1000000000, \ + "uilabel": "Maximum Spent Fuel Inventory", \ + "units": "assemblies", \ "doc": "Number of spent fuel assemblies that can be stored on-site before reactor operation stalls.", \ } int n_assem_spent; #pragma cyclus var { \ "default": 0, \ + "uilabel": "Minimum Fresh Fuel Inventory", \ + "units": "assemblies", \ "doc": "Number of fresh fuel assemblies to keep on-hand if possible.", \ } int n_assem_fresh; @@ -191,12 +200,14 @@ class Reactor : public cyclus::Facility, ///////// cycle params /////////// #pragma cyclus var { \ "doc": "The duration of a full operational cycle (excluding refueling time) in time steps.", \ + "uilabel": "Cycle Length", \ "units": "time steps", \ } int cycle_time; #pragma cyclus var { \ "doc": "The duration of a full refueling period - the minimum time between" \ " a cycle end and the start of the next cycle.", \ + "uilabel": "Refueling Outage Length", \ "units": "time steps", \ } int refuel_time; @@ -204,6 +215,7 @@ class Reactor : public cyclus::Facility, "default": 0, \ "doc": "Number of time steps since the start of the last cycle." \ " Only set this if you know what you are doing", \ + "uilabel": "Time Since Start of Last Cycle", \ "units": "time steps", \ } int cycle_step; @@ -211,16 +223,19 @@ class Reactor : public cyclus::Facility, /////// fuel specifications ///////// #pragma cyclus var { \ "uitype": ["oneormore", "incommodity"], \ + "uilabels": "Fresh Fuel Commodity List", \ "doc": "Ordered list of input commodities on which to requesting fuel.", \ } std::vector fuel_incommods; #pragma cyclus var { \ "uitype": ["oneormore", "recipe"], \ + "uilabel": "Fresh Fuel Recipes", \ "doc": "Fresh fuel recipes to request for each of the given fuel input commodities (same order).", \ } std::vector fuel_inrecipes; #pragma cyclus var { \ "uitype": ["oneormore", "recipe"], \ + "uilabel": "Spent Fuel Recipes", \ "doc": "Spent fuel recipes corresponding to the given fuel input commodities (same order)." \ " Fuel received via a particular input commodity is transmuted to the recipe specified" \ " here after being burned during a cycle.", \ @@ -228,12 +243,14 @@ class Reactor : public cyclus::Facility, std::vector fuel_outrecipes; #pragma cyclus var { \ "uitype": ["oneormore", "outcommodity"], \ + "uilabel": "Spent Fuel Commodity List", \ "doc": "Output commodities on which to offer spent fuel originally received as each particular " \ " input commodity (same order)." \ } std::vector fuel_outcommods; #pragma cyclus var { \ "default": [], \ + "uilabels": "Fresh Fuel Preferences", \ "doc": "The preference for each type of fresh fuel requested corresponding to each input" \ " commodity (same order). If no preferences are specified, zero is" \ " used for all fuel requests (default).", \ @@ -252,6 +269,7 @@ class Reactor : public cyclus::Facility, /////////// preference changes /////////// #pragma cyclus var { \ "default": [], \ + "uilabel": "Time to Change Fresh Fuel Preference", \ "doc": "A time step on which to change the request preference for a " \ "particular fresh fuel type.", \ } @@ -260,11 +278,13 @@ class Reactor : public cyclus::Facility, "default": [], \ "doc": "The input commodity for a particular fuel preference change." \ " Same order as and direct correspondence to the specified preference change times.", \ + "uilabel": "Commodity for Changed Fresh Fuel Preference", \ "uitype": ["oneormore", "incommodity"], \ } std::vector pref_change_commods; #pragma cyclus var { \ "default": [], \ + "uilabel", "Changed Fresh Fuel Preference", \ "doc": "The new/changed request preference for a particular fresh fuel." \ " Same order as and direct correspondence to the specified preference change times.", \ } @@ -273,11 +293,13 @@ class Reactor : public cyclus::Facility, ///////////// recipe changes /////////// #pragma cyclus var { \ "default": [], \ + "uilabel": "Time to Change Fresh/Spent Fuel Recipe", \ "doc": "A time step on which to change the input-output recipe pair for a requested fresh fuel.", \ } std::vector recipe_change_times; #pragma cyclus var { \ "default": [], \ + "uilabel": "Commodity for Changed Fresh/Spent Fuel Recipe", \ "doc": "The input commodity indicating fresh fuel for which recipes will be changed." \ " Same order as and direct correspondence to the specified recipe change times.", \ "uitype": ["oneormore", "incommodity"], \ @@ -285,6 +307,7 @@ class Reactor : public cyclus::Facility, std::vector recipe_change_commods; #pragma cyclus var { \ "default": [], \ + "uilabel": "New Recipe for Fresh Fuel", \ "doc": "The new input recipe to use for this recipe change." \ " Same order as and direct correspondence to the specified recipe change times.", \ "uitype": ["oneormore", "recipe"], \ @@ -292,6 +315,7 @@ class Reactor : public cyclus::Facility, std::vector recipe_change_in; #pragma cyclus var { \ "default": [], \ + "uilabel": "New Recipe for Spent Fuel", \ "doc": "The new output recipe to use for this recipe change." \ " Same order as and direct correspondence to the specified recipe change times.", \ "uitype": ["oneormore", "recipe"], \ From 46654a4d900da97fa2337b9ac7bf99ee78128a49 Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Tue, 5 May 2015 23:37:35 -0500 Subject: [PATCH 270/314] Add uilabels to separations --- src/separations.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/separations.h b/src/separations.h index f0cee6a025..6621f9c13f 100644 --- a/src/separations.h +++ b/src/separations.h @@ -98,6 +98,7 @@ class Separations : public cyclus::Facility { private: #pragma cyclus var { \ "doc" : "Maximum quantity of feed material that can be processed per time step.", \ + "uilabel": "Maximum Separations Throughput", \ "units": "kg", \ } double throughput; @@ -105,12 +106,14 @@ class Separations : public cyclus::Facility { #pragma cyclus var { \ "doc": "Ordered list of commodities on which to request feed material to separate." \ " Order only matters for matching up with feed commodity preferences if specified.", \ + "uilabel": "List of Feed Commodities", \ "uitype": ["oneormore", "incommodity"], \ } std::vector feed_commods; #pragma cyclus var { \ "default": [], \ + "uilabel": "Feed Commodity Preferences", \ "doc": "Feed commodity request preferences for each of the given feed commodities (same order)." \ " If unspecified, default is to use zero for all preferences.", \ } @@ -119,6 +122,7 @@ class Separations : public cyclus::Facility { #pragma cyclus var { \ "doc": "Name for recipe to be used in feed requests." \ " Empty string results in use of a dummy recipe.", \ + "uilabel": "Feed Commodity Recipes", \ "uitype": "recipe", \ "default": "", \ } @@ -126,6 +130,7 @@ class Separations : public cyclus::Facility { #pragma cyclus var { \ "doc" : "Maximum amount of feed material to keep on hand.", \ + "uilabel": "Maximum Feed Inventories", \ "units" : "kg", \ } double feedbuf_size; @@ -139,6 +144,7 @@ class Separations : public cyclus::Facility { "doc" : "Maximum amount of leftover separated material (not included in" \ " any other stream) that can be stored." \ " If full, the facility halts operation until space becomes available.", \ + "uilabel": "Maximum Leftover Inventory", \ "default": 1e299, \ "units": "kg", \ } @@ -148,6 +154,7 @@ class Separations : public cyclus::Facility { "doc": "Commodity on which to trade the leftover separated material stream." \ " This MUST NOT be the same as any commodity used to define the other separations streams.", \ "uitype": "outcommodity", \ + "uilabel": "Leftover Commodity", \ "default": "default-waste-stream", \ } std::string leftover_commod; @@ -160,6 +167,7 @@ class Separations : public cyclus::Facility { #pragma cyclus var { \ "alias": ["streams", "commod", ["info", "buf_size", ["efficiencies", "comp", "eff"]]], \ "uitype": ["oneormore", "outcommodity", ["pair", "double", ["oneormore", "nuclide", "double"]]], \ + "uilabel": "Separations Streams and Efficiencies", \ "doc": "Output streams for separations." \ " Each stream must have a unique name identifying the commodity on which its material is traded," \ " a max buffer capacity in kg (neg values indicate infinite size)," \ From 730cbf75056404c5186d5fb368b8bedf6f416cf7 Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Tue, 5 May 2015 23:40:48 -0500 Subject: [PATCH 271/314] Add uilabels to sink --- src/sink.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sink.h b/src/sink.h index f7389ffc59..d33a404716 100644 --- a/src/sink.h +++ b/src/sink.h @@ -166,11 +166,13 @@ class Sink : public cyclus::Facility { /// all facilities must have at least one input commodity #pragma cyclus var {"tooltip": "input commodities", \ "doc": "commodities that the sink facility accepts", \ + "uilabel": "List of Input Commodities", \ "uitype": ["oneormore", "incommodity"]} std::vector in_commods; /// monthly acceptance capacity #pragma cyclus var {"default": 1e299, "tooltip": "sink capacity", \ + "uilabel": "Maximum Throughput", \ "doc": "capacity the sink facility can " \ "accept at each time step"} double capacity; @@ -178,12 +180,14 @@ class Sink : public cyclus::Facility { #pragma cyclus var {"default": "", "tooltip": "requested composition", \ "doc": "name of recipe to use for material requests, where " \ "the default (empty string) is to accept everything", \ + "uilabel": "Input Recipe", \ "uitype": "recipe"} std::string recipe_name; /// max inventory size #pragma cyclus var {"default": 1e299, \ "tooltip": "sink maximum inventory size", \ + "uilabel": "Maximum Inventory", \ "doc": "total maximum inventory size of sink facility"} double max_inv_size; From cb3e16f50dd537456b2b4c83ad4fba9cf43970fa Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Wed, 6 May 2015 00:05:31 -0500 Subject: [PATCH 272/314] Add uilabels to source --- src/source.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/source.h b/src/source.h index 90cd9857c0..7a7d74b07c 100644 --- a/src/source.h +++ b/src/source.h @@ -71,6 +71,7 @@ class Source : public cyclus::Facility, #pragma cyclus var { \ "tooltip": "source output commodity", \ "doc": "Output commodity on which the source offers material.", \ + "uilabel": "Output Commodity", \ "uitype": "outcommodity", \ } std::string outcommod; @@ -79,6 +80,7 @@ class Source : public cyclus::Facility, "tooltip": "name of material recipe to provide", \ "doc": "Name of composition recipe that this source provides regardless of requested composition." \ " If empty, source creates and provides whatever compositions are requested.", \ + "uilabel": "Output Recipe", \ "default": "", \ "uitype": "recipe", \ } @@ -88,6 +90,7 @@ class Source : public cyclus::Facility, "default": 1e299, \ "tooltip": "per time step throughput", \ "units": "kg/(time step)", \ + "uilabel": "Maximum Throughput", \ "doc": "amount of commodity that can be supplied at each time step", \ } double throughput; @@ -97,6 +100,7 @@ class Source : public cyclus::Facility, " Every trade decreases this value by the supplied material quantity'." \ " When it reaches zero, the source cannot provide any more material.", \ "default": 1e299, \ + "uilabel": "Initial Inventory", \ "units": "kg", \ } double inventory_size; From 036efa07978ce35d85985fc1f7b47b7c0153afcb Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Wed, 6 May 2015 00:08:36 -0500 Subject: [PATCH 273/314] Fix type in fuel fab --- src/fuel_fab.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fuel_fab.h b/src/fuel_fab.h index ff18b42e38..0161498b21 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -162,7 +162,7 @@ class FuelFab : public cyclus::Facility { std::vector fiss_commods; #pragma cyclus var { \ "default": [], \ - "uilabel":, "Fissile Stream Preferences", \ + "uilabel": "Fissile Stream Preferences", \ "doc": "Fissile stream commodity request preferences for each of the given fissile commodities (same order)." \ " If unspecified, default is to use zero for all preferences.", \ } From 99201c189325fddf92f795427b2b1854afea8276 Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Wed, 6 May 2015 10:05:09 -0500 Subject: [PATCH 274/314] Fix more typos --- src/reactor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactor.h b/src/reactor.h index b78edc9f39..bc1cda80ad 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -284,7 +284,7 @@ class Reactor : public cyclus::Facility, std::vector pref_change_commods; #pragma cyclus var { \ "default": [], \ - "uilabel", "Changed Fresh Fuel Preference", \ + "uilabel":, "Changed Fresh Fuel Preference", \ "doc": "The new/changed request preference for a particular fresh fuel." \ " Same order as and direct correspondence to the specified preference change times.", \ } From dee3f4dbf6eafd2030846e176de331c7f7204e61 Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Wed, 6 May 2015 10:13:14 -0500 Subject: [PATCH 275/314] Add internal flags to 2 reactor variables --- src/reactor.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/reactor.h b/src/reactor.h index bc1cda80ad..907337faab 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -324,12 +324,16 @@ class Reactor : public cyclus::Facility, // should be hidden in ui (internal only). True if fuel has already been // discharged this cycle. - #pragma cyclus var {"default": 0, "doc": "This should NEVER be set manually."} +#pragma cyclus var {"default": 0, "doc": "This should NEVER be set manually.", \ + "internal": True \ + } bool discharged; // This variable should be hidden/unavailable in ui. Maps resource object // id's to the index for the incommod through which they were received. - #pragma cyclus var {"default": {}, "doc": "This should NEVER be set manually."} +#pragma cyclus var {"default": {}, "doc": "This should NEVER be set manually.", \ + "internal": True \ + } std::map res_indexes; }; From 004acf380dc36cb204d6eb04d6da2905756d52ff Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Wed, 6 May 2015 10:16:12 -0500 Subject: [PATCH 276/314] fix whitespace mistakes --- src/reactor.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/reactor.h b/src/reactor.h index 907337faab..af08d8f26e 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -324,15 +324,15 @@ class Reactor : public cyclus::Facility, // should be hidden in ui (internal only). True if fuel has already been // discharged this cycle. -#pragma cyclus var {"default": 0, "doc": "This should NEVER be set manually.", \ - "internal": True \ + #pragma cyclus var {"default": 0, "doc": "This should NEVER be set manually.", \ + "internal": True \ } bool discharged; // This variable should be hidden/unavailable in ui. Maps resource object // id's to the index for the incommod through which they were received. -#pragma cyclus var {"default": {}, "doc": "This should NEVER be set manually.", \ - "internal": True \ + #pragma cyclus var {"default": {}, "doc": "This should NEVER be set manually.", \ + "internal": True \ } std::map res_indexes; }; From 3b1cfd1ff1b0aafc09b07298f38643d65b1176bb Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Wed, 6 May 2015 12:52:10 -0500 Subject: [PATCH 277/314] remove uitype commodity from GrowthRegion. --- src/growth_region.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/growth_region.h b/src/growth_region.h index cdcdff06cc..07584633a9 100644 --- a/src/growth_region.h +++ b/src/growth_region.h @@ -75,7 +75,7 @@ class GrowthRegion : public cyclus::Region { "doc": "name of the commodity experiencing a " \ "growth in demand", \ "uilabel": "Growth Commodity", \ - "uitype": "commodity"} + } std::string commodity_name; #pragma cyclus var {"tooltip": "demand type", \ From 3805791c53d8bd42290cb60fe1a57beced4ca142 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 6 May 2015 14:13:32 -0500 Subject: [PATCH 278/314] sink docs match source docs, fixes #344 --- src/sink.h | 89 +++++------------------------------------------------- 1 file changed, 8 insertions(+), 81 deletions(-) diff --git a/src/sink.h b/src/sink.h index f7389ffc59..5de7f6e5ff 100644 --- a/src/sink.h +++ b/src/sink.h @@ -12,98 +12,27 @@ namespace cycamore { class Context; -/// @class Sink -/// This cyclus::Facility requests a finite amount of its input commodity. -/// It offers nothing. -/// -/// The Sink class inherits from the cyclus::Facility class and is -/// dynamically loaded by the Agent class when requested. -/// -/// @section intro Introduction -/// The Sink is a facility type in *Cyclus* capable of accepting -/// a finite or infinite quantity of some commodity produced in the -/// simulation. A Sink requests an amount of that commodity from -/// the appropriate market. It then receives that commodity when the -/// market issues an order that the request has been matched with a -/// corresponding offer. -/// @section agentparams Agent Parameters -/// Sink behavior is comprehensively defined by the following -/// parameters: -/// - double capacity: The acceptance capacity of the facility (units -/// vary, but typically kg/month). Capacity is infinite if a positive -/// value is provided. -/// - int startDate: The date on which the facility begins to operate -/// (months). - int lifeTime: The length of time that the facility -/// operates (months). - std::string inCommod: The commodity type this -/// facility accepts. -/// @section optionalparams Optional Parameters -/// Sink behavior may also be specified with the following -/// optional parameters which have default values listed here. -/// - double capacityFactor: The ratio of actual acceptance capacity to -/// the rated acceptance capacity. Default is 1 (actual/rated). -/// - double AvailFactor: The percent of time the facility operates at -/// its capacity factor. Default is 100%. -/// - double capitalCost: The cost of constructing and commissioning this -/// facility. Default is 0 ($). -/// - double opCost: The annual cost of operation and maintenance of this -/// facility. Default is 0 ($/year). -/// - int constrTime: The number of months it takes to construct and -/// commission this facility. Default is 0 (months). -/// - int decomTime: The number of months it takes to deconstruct and -/// decommission this facility. Default is 0 (months). -/// - Inst* inst: The institution responsible for this facility. -/// - string name: A non-generic name for this facility. -/// -/// @section detailed Detailed Behavior -/// @subsection finite If Finite Capacity: -/// The Sink starts operation when the simulation reaches the -/// month specified as the startDate. It immediately begins to request -/// the inCommod commodity type at the rate defined by the Sink -/// capacity. If a request is matched with an offer from another -/// facility, the Sink executes that order by adding that -/// quantity to its stocks. When the simulation time equals the startDate -/// plus the lifeTime, the facility ceases to operate. -/// -/// @subsection infinite If Infinite Capacity: -/// The Sink starts operation when the simulation reaches the -/// month specified as the startDate. Each month the Sink -/// requests an infinite amount of the inCommod commodity from the -/// appropriate market. If there is a corresponding offer for that -/// commodity type from another facility, the Sink executes that -/// order by adding that quantity to its stocks. When the simulation time -/// equals the startDate plus the lifeTime, the facility ceases to -/// operate. -/// @subsection question Question: -/// What is the best way to allow requests of an infinite amount of -/// material on a market? +/// This facility acts as a sink of materials and products with a fixed +/// throughput (per time step) capacity and a lifetime capacity defined by a +/// total inventory size. The inventory size and throughput capacity both +/// default to infinite. If a recipe is provided, it will request material with +/// that recipe. Requests are made for any number of specified commodities. class Sink : public cyclus::Facility { public: - // --- Module Members --- - /// Constructor for the Sink class. - /// @param ctx the cyclus context for access to simulation-wide parameters + Sink(cyclus::Context* ctx); - /// Destructor for the Sink class. virtual ~Sink(); - #pragma cyclus decl - #pragma cyclus note {"doc": "A sink facility that accepts specified " \ "amounts of commodities from other agents"} - /// A verbose printer for the Sink Facility. - virtual std::string str(); - // --- + #pragma cyclus decl - // --- Agent Members --- - /// The Sink can handle the Tick. + virtual std::string str(); - /// @param time the current simulation time. virtual void Tick(); - /// The Sink can handle the Tock. - - /// @param time the current simulation time. virtual void Tock(); /// @brief SinkFacilities request Materials of their given commodity. Note @@ -126,9 +55,7 @@ class Sink : public cyclus::Facility { virtual void AcceptGenRsrcTrades( const std::vector< std::pair, cyclus::Product::Ptr> >& responses); - // --- - // --- Sink Members --- /// add a commodity to the set of input commodities /// @param name the commodity name inline void AddCommodity(std::string name) { in_commods.push_back(name); } From 61b856dbf9255f489f48128792cda7f0476ea190 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Wed, 6 May 2015 14:31:02 -0500 Subject: [PATCH 279/314] Enrichment Facility docs were not rendering due to a duplicate pragma cyclus note. --- src/enrichment_facility.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index def89331e4..5e149e9960 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -157,12 +157,6 @@ class Enrichment : public cyclus::Facility { #pragma cyclus - #pragma cyclus note {"doc": "An enrichment facility that intakes a "\ - "commodity (usually natural uranium) and " \ - "supplies a user-specified enriched product "\ - "based on SWU capacity", \ - "niche": "enrichment"} - /// Print information about this agent virtual std::string str(); // --- From 7a53842fbb667aa5f0e079e574f0ffb745745124 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 6 May 2015 14:56:02 -0500 Subject: [PATCH 280/314] cyclus note --- src/sink.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/sink.h b/src/sink.h index 5de7f6e5ff..2219e5c055 100644 --- a/src/sink.h +++ b/src/sink.h @@ -24,8 +24,15 @@ class Sink : public cyclus::Facility { virtual ~Sink(); - #pragma cyclus note {"doc": "A sink facility that accepts specified " \ - "amounts of commodities from other agents"} + #pragma cyclus note { \ + "doc": \ + " A sink facility that accepts materials and products with a fixed\n"\ + " throughput (per time step) capacity and a lifetime capacity defined by\n"\ + " a total inventory size. The inventory size and throughput capacity\n"\ + " both default to infinite. If a recipe is provided, it will request\n"\ + " material with that recipe. Requests are made for any number of\n"\ + " specified commodities.\n" \ + } #pragma cyclus decl From 827dc10c244d82f95a380835edf45ee02bfab851 Mon Sep 17 00:00:00 2001 From: Meghan McGarry Date: Wed, 6 May 2015 16:28:17 -0500 Subject: [PATCH 281/314] A few more typos in the EF docstring --- src/enrichment_facility.h | 46 +++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/enrichment_facility.h b/src/enrichment_facility.h index 5e149e9960..3b68e837f6 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment_facility.h @@ -116,31 +116,31 @@ class Enrichment : public cyclus::Facility { #pragma cyclus note { \ "niche": "enrichment facility", \ "doc": \ - "The Enrichment facilityis a simple Agent that enriches natural" \ - "uranium in a Cyclus simulation. It does not explicitly compute" \ - "the physical enrichment process, rather it calculates the SWU" \ - "required to convert an source uranium recipe (ie. natural uranium)" \ - "into a requested enriched recipe (ie. 4% enriched uranium), given" \ - "the natural uranium inventory constraint and its SWU capacity" \ - "constraint." \ + "The Enrichment facility is a simple agent that enriches natural " \ + "uranium in a Cyclus simulation. It does not explicitly compute " \ + "the physical enrichment process, rather it calculates the SWU " \ + "required to convert an source uranium recipe (i.e. natural uranium) " \ + "into a requested enriched recipe (i.e. 4% enriched uranium), given " \ + "the natural uranium inventory constraint and its SWU capacity " \ + "constraint." \ "\n\n" \ - "The Enrichment facility requests an input commodity and associated recipe" \ - "whose quantity is its remaining inventory capacity. All facilities" \ - "trading the same input commodity (even with different recipes) will" \ - "offer materials for trade. The Enrichment facility accepts any input" \ - "materials with enrichments less than its tails assay, as long as some" \ - "U235 is present, and preference increases with U235 content. If no" \ - "U235 is present in the offered material, the trade preference is set" \ - "to -1 and the material is not accepted. Any material components other" \ - "other than U235 and U238 are sent directly to the tails buffer." \ + "The Enrichment facility requests an input commodity and associated " \ + "recipe whose quantity is its remaining inventory capacity. All " \ + "facilities trading the same input commodity (even with different " \ + "recipes) will offer materials for trade. The Enrichment facility " \ + "accepts any input materials with enrichments less than its tails assay, "\ + "as long as some U235 is present, and preference increases with U235 " \ + "content. If no U235 is present in the offered material, the trade " \ + "preference is set to -1 and the material is not accepted. Any material " \ + "components other than U235 and U238 are sent directly to the tails buffer."\ "\n\n" \ - "The Enrichment facility will bid on any request for its output commodity" \ - "up to the maximum allowed enrichment (if not specified, default is 100%)" \ - "It bids on either the request quantity, or the maximum quanity allowed" \ - "by its SWU constraint or natural uranium inventory, whichever is lower." \ - "If multiple output commodities with different enrichment levels are" \ - "requested and the facility does not have the SWU or quantity capacity" \ - "to meet all requests, the requests are fully, then partially filled" \ + "The Enrichment facility will bid on any request for its output commodity "\ + "up to the maximum allowed enrichment (if not specified, default is 100%) "\ + "It bids on either the request quantity, or the maximum quanity allowed " \ + "by its SWU constraint or natural uranium inventory, whichever is lower. " \ + "If multiple output commodities with different enrichment levels are " \ + "requested and the facility does not have the SWU or quantity capacity " \ + "to meet all requests, the requests are fully, then partially filled " \ "in unspecified but repeatable order." \ "\n\n" \ "Accumulated tails inventory is offered for trading as a specifiable " \ From 587c1a8621a64a8ec9e848918224740589f6b94f Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 7 May 2015 09:11:42 -0500 Subject: [PATCH 282/314] fix duplicate prototype entries in db --- src/deploy_inst.cc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/deploy_inst.cc b/src/deploy_inst.cc index 0c66e698db..a5dccf381c 100644 --- a/src/deploy_inst.cc +++ b/src/deploy_inst.cc @@ -18,11 +18,17 @@ void DeployInst::Build(cyclus::Agent* parent) { if (lifetimes.size() == prototypes.size()) { cyclus::Agent* a = context()->CreateAgent(proto); - a->lifetime(lifetimes[i]); + if (a->lifetime() != lifetimes[i]) { + a->lifetime(lifetimes[i]); - ss << "_life_" << lifetimes[i]; - proto = ss.str(); - context()->AddPrototype(proto, a); + if (lifetimes[i] == -1) { + ss << "_life_forever"; + } else { + ss << "_life_" << lifetimes[i]; + } + proto = ss.str(); + context()->AddPrototype(proto, a); + } } int t = build_times[i]; From 92d5d6436a7b77cbb3a1794aabdea9ae79daaeb5 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 7 May 2015 11:12:54 -0500 Subject: [PATCH 283/314] added test and improved the fix --- src/deploy_inst.cc | 6 +++++- src/deploy_inst_tests.cc | 30 +++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/deploy_inst.cc b/src/deploy_inst.cc index a5dccf381c..3abd2b87ac 100644 --- a/src/deploy_inst.cc +++ b/src/deploy_inst.cc @@ -10,6 +10,7 @@ DeployInst::~DeployInst() {} void DeployInst::Build(cyclus::Agent* parent) { cyclus::Institution::Build(parent); BuildSched::iterator it; + std::set protos; for (int i = 0; i < prototypes.size(); i++) { std::string proto = prototypes[i]; @@ -27,7 +28,10 @@ void DeployInst::Build(cyclus::Agent* parent) { ss << "_life_" << lifetimes[i]; } proto = ss.str(); - context()->AddPrototype(proto, a); + if (protos.count(proto) == 0) { + protos.insert(proto); + context()->AddPrototype(proto, a); + } } } diff --git a/src/deploy_inst_tests.cc b/src/deploy_inst_tests.cc index 9d1657966e..49c870eae8 100644 --- a/src/deploy_inst_tests.cc +++ b/src/deploy_inst_tests.cc @@ -109,7 +109,35 @@ TEST(DeployInstTests, FiniteLifetimes) { EXPECT_EQ(8, stmt->GetInt(0)); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TEST(DeployInstTests, NoDupProtos) { + std::string config = + " foobar foobar foobar " + " 1 1 2 " + " 1 7 3 " + " 1 1 -1 " + ; + + int simdur = 5; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:DeployInst"), config, simdur); + sim.DummyProto("foobar"); + int id = sim.Run(); + + // don't duplicate same prototypes with same custom lifetime + cyclus::SqlStatement::Ptr stmt = sim.db().db().Prepare( + "SELECT COUNT(*) FROM Prototypes WHERE Prototype = 'foobar_life_1';" + ); + stmt->Step(); + EXPECT_EQ(1, stmt->GetInt(0)); + + // don't duplicate custom lifetimes that are identical to original prototype + // lifetime. + stmt = sim.db().db().Prepare( + "SELECT COUNT(*) FROM Prototypes WHERE Prototype = 'foobar';" + ); + stmt->Step(); + EXPECT_EQ(1, stmt->GetInt(0)); +} + // required to get functionality in cyclus agent unit tests library cyclus::Agent* DeployInstitutionConstructor(cyclus::Context* ctx) { return new cycamore::DeployInst(ctx); From 8b53f139f6d843744ffab1bb34d8b84f878beb27 Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Thu, 7 May 2015 11:15:55 -0500 Subject: [PATCH 284/314] refixing typo --- src/deploy_inst.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deploy_inst.h b/src/deploy_inst.h index b3d0114291..87b86da8f7 100644 --- a/src/deploy_inst.h +++ b/src/deploy_inst.h @@ -43,7 +43,7 @@ class DeployInst : public cyclus::Institution { protected: #pragma cyclus var { \ "doc": "Ordered list of prototypes to build.", \ - "uitype": ("onormore", "prototype"), \ + "uitype": ("oneormore", "prototype"), \ "uilabel": "Prototypes to deploy", \ } std::vector prototypes; From d825230a19a43c1fe65e6b49f0e68ab90bbf54ed Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Thu, 7 May 2015 11:24:51 -0500 Subject: [PATCH 285/314] outage length -> outage duration --- src/reactor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactor.h b/src/reactor.h index af08d8f26e..b623913a00 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -207,7 +207,7 @@ class Reactor : public cyclus::Facility, #pragma cyclus var { \ "doc": "The duration of a full refueling period - the minimum time between" \ " a cycle end and the start of the next cycle.", \ - "uilabel": "Refueling Outage Length", \ + "uilabel": "Refueling Outage Duration", \ "units": "time steps", \ } int refuel_time; From 9f998e9b353c8fa78e408a16f115ba1865a829cd Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Thu, 7 May 2015 11:44:15 -0500 Subject: [PATCH 286/314] some tweaks suggested by @mbmcgarry --- src/reactor.h | 8 ++++---- src/separations.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/reactor.h b/src/reactor.h index b623913a00..bc451660a0 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -223,19 +223,19 @@ class Reactor : public cyclus::Facility, /////// fuel specifications ///////// #pragma cyclus var { \ "uitype": ["oneormore", "incommodity"], \ - "uilabels": "Fresh Fuel Commodity List", \ + "uilabel": "Fresh Fuel Commodity List", \ "doc": "Ordered list of input commodities on which to requesting fuel.", \ } std::vector fuel_incommods; #pragma cyclus var { \ "uitype": ["oneormore", "recipe"], \ - "uilabel": "Fresh Fuel Recipes", \ + "uilabel": "Fresh Fuel Recipe List", \ "doc": "Fresh fuel recipes to request for each of the given fuel input commodities (same order).", \ } std::vector fuel_inrecipes; #pragma cyclus var { \ "uitype": ["oneormore", "recipe"], \ - "uilabel": "Spent Fuel Recipes", \ + "uilabel": "Spent Fuel Recipe List", \ "doc": "Spent fuel recipes corresponding to the given fuel input commodities (same order)." \ " Fuel received via a particular input commodity is transmuted to the recipe specified" \ " here after being burned during a cycle.", \ @@ -250,7 +250,7 @@ class Reactor : public cyclus::Facility, std::vector fuel_outcommods; #pragma cyclus var { \ "default": [], \ - "uilabels": "Fresh Fuel Preferences", \ + "uilabel": "Fresh Fuel Preference List", \ "doc": "The preference for each type of fresh fuel requested corresponding to each input" \ " commodity (same order). If no preferences are specified, zero is" \ " used for all fuel requests (default).", \ diff --git a/src/separations.h b/src/separations.h index 6621f9c13f..809f7b212b 100644 --- a/src/separations.h +++ b/src/separations.h @@ -106,14 +106,14 @@ class Separations : public cyclus::Facility { #pragma cyclus var { \ "doc": "Ordered list of commodities on which to request feed material to separate." \ " Order only matters for matching up with feed commodity preferences if specified.", \ - "uilabel": "List of Feed Commodities", \ + "uilabel": "Feed Commodity List", \ "uitype": ["oneormore", "incommodity"], \ } std::vector feed_commods; #pragma cyclus var { \ "default": [], \ - "uilabel": "Feed Commodity Preferences", \ + "uilabel": "Feed Commodity Preference List", \ "doc": "Feed commodity request preferences for each of the given feed commodities (same order)." \ " If unspecified, default is to use zero for all preferences.", \ } @@ -122,7 +122,7 @@ class Separations : public cyclus::Facility { #pragma cyclus var { \ "doc": "Name for recipe to be used in feed requests." \ " Empty string results in use of a dummy recipe.", \ - "uilabel": "Feed Commodity Recipes", \ + "uilabel": "Feed Commodity Recipe List", \ "uitype": "recipe", \ "default": "", \ } @@ -130,7 +130,7 @@ class Separations : public cyclus::Facility { #pragma cyclus var { \ "doc" : "Maximum amount of feed material to keep on hand.", \ - "uilabel": "Maximum Feed Inventories", \ + "uilabel": "Maximum Feed Inventory", \ "units" : "kg", \ } double feedbuf_size; From 9d3ed0b2c92accf9df2c126b0bde7096274be6d4 Mon Sep 17 00:00:00 2001 From: "Paul P.H. Wilson" Date: Thu, 7 May 2015 21:39:08 -0500 Subject: [PATCH 287/314] More rebase failures corrected. --- src/reactor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactor.h b/src/reactor.h index bc451660a0..8d9cfcecf4 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -284,7 +284,7 @@ class Reactor : public cyclus::Facility, std::vector pref_change_commods; #pragma cyclus var { \ "default": [], \ - "uilabel":, "Changed Fresh Fuel Preference", \ + "uilabel": "Changed Fresh Fuel Preference", \ "doc": "The new/changed request preference for a particular fresh fuel." \ " Same order as and direct correspondence to the specified preference change times.", \ } From 9e1a10753bd3ad173f1198e8265aa3d3a2c9834e Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Tue, 12 May 2015 10:05:07 -0500 Subject: [PATCH 288/314] Add swu and feed time series to enrichment facility and rename enrichment_facility.* -> enrichment.* --- src/CMakeLists.txt | 2 +- src/{enrichment_facility.cc => enrichment.cc} | 14 +++++++++----- src/{enrichment_facility.h => enrichment.h} | 5 +++++ ...hment_facility_tests.cc => enrichment_tests.cc} | 0 ...ichment_facility_tests.h => enrichment_tests.h} | 0 5 files changed, 15 insertions(+), 6 deletions(-) rename src/{enrichment_facility.cc => enrichment.cc} (97%) rename src/{enrichment_facility.h => enrichment.h} (98%) rename src/{enrichment_facility_tests.cc => enrichment_tests.cc} (100%) rename src/{enrichment_facility_tests.h => enrichment_tests.h} (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6a29fcff22..37dea6319c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,7 +4,7 @@ USE_CYCLUS("cycamore" "reactor") USE_CYCLUS("cycamore" "fuel_fab") -USE_CYCLUS("cycamore" "enrichment_facility") +USE_CYCLUS("cycamore" "enrichment") USE_CYCLUS("cycamore" "separations") diff --git a/src/enrichment_facility.cc b/src/enrichment.cc similarity index 97% rename from src/enrichment_facility.cc rename to src/enrichment.cc index ff0fded925..439d76422c 100644 --- a/src/enrichment_facility.cc +++ b/src/enrichment.cc @@ -58,15 +58,14 @@ void Enrichment::Build(cyclus::Agent* parent) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Enrichment::Tick() { - LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is ticking {"; - LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; current_swu_capacity = SwuCapacity(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Enrichment::Tock() { - LOG(cyclus::LEV_INFO3, "EnrFac") << prototype() << " is tocking {"; - LOG(cyclus::LEV_INFO3, "EnrFac") << "}"; + using cyclus::toolkit::RecordTimeSeries; + RecordTimeSeries(this, intra_timestep_swu_); + RecordTimeSeries(this, intra_timestep_feed_); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -247,6 +246,9 @@ void Enrichment::GetMatlTrades( using cyclus::Material; using cyclus::Trade; + intra_timestep_swu_ = 0; + intra_timestep_feed_ = 0; + std::vector< Trade >::const_iterator it; for (it = trades.begin(); it != trades.end(); ++it) { double qty = it->amt; @@ -270,7 +272,7 @@ void Enrichment::GetMatlTrades( } responses.push_back(std::make_pair(*it, response)); } - + if (cyclus::IsNegative(tails.quantity())) { std::stringstream ss; ss << "is being asked to provide more than its current inventory."; @@ -399,6 +401,8 @@ cyclus::Material::Ptr Enrichment::Enrich_( current_swu_capacity -= swu_req; + intra_timestep_swu_ += swu_req; + intra_timestep_feed_ += feed_req; RecordEnrichment_(feed_req, swu_req); LOG(cyclus::LEV_INFO5, "EnrFac") << prototype() << diff --git a/src/enrichment_facility.h b/src/enrichment.h similarity index 98% rename from src/enrichment_facility.h rename to src/enrichment.h index 7f6e72c376..277ed3a495 100644 --- a/src/enrichment_facility.h +++ b/src/enrichment.h @@ -349,6 +349,11 @@ class Enrichment : public cyclus::Facility { cyclus::toolkit::ResBuf inventory; // natural u #pragma cyclus var {} cyclus::toolkit::ResBuf tails; // depleted u + + // used to total intra-timestep swu and natu usage for meeting requests - + // these help enable time series generation. + double intra_timestep_swu_; + double intra_timestep_feed_; friend class EnrichmentTest; // --- diff --git a/src/enrichment_facility_tests.cc b/src/enrichment_tests.cc similarity index 100% rename from src/enrichment_facility_tests.cc rename to src/enrichment_tests.cc diff --git a/src/enrichment_facility_tests.h b/src/enrichment_tests.h similarity index 100% rename from src/enrichment_facility_tests.h rename to src/enrichment_tests.h From 27f013ed59916623e60e6add1f72436bdc492e57 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 13 May 2015 09:01:58 -0500 Subject: [PATCH 289/314] fix source facility note annotation --- src/source.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/source.h b/src/source.h index 7a7d74b07c..fdc5d27008 100644 --- a/src/source.h +++ b/src/source.h @@ -30,14 +30,15 @@ class Source : public cyclus::Facility, #pragma cyclus note { \ "doc": "This facility acts as a source of material with a fixed throughput (per\n" \ - " time step) capacity and a lifetime capacity defined by a total inventory\n" \ - " size. It offers its material as a single commodity. If a composition\n" \ - " recipe is specified, it provides that single material composition to\n" \ - " requesters. If unspecified, the source provides materials with the exact\n" \ - " requested compositions. The inventory size and throughput both default to\n" \ - " infinite. Supplies material results in corresponding decrease in\n" \ - " inventory, and when the inventory size reaches zero, the source can provide\n" \ - " no more material.\n" \ + "time step) capacity and a lifetime capacity defined by a total inventory\n" \ + "size. It offers its material as a single commodity. If a composition\n" \ + "recipe is specified, it provides that single material composition to\n" \ + "requesters. If unspecified, the source provides materials with the exact\n" \ + "requested compositions. The inventory size and throughput both default to\n" \ + "infinite. Supplies material results in corresponding decrease in\n" \ + "inventory, and when the inventory size reaches zero, the source can provide\n" \ + "no more material.\n" \ + "", \ } #pragma cyclus def clone From 10d4e4074e6506bb6ddcba77bc0a2783516dcf8f Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Wed, 13 May 2015 11:38:27 -0500 Subject: [PATCH 290/314] fix build errors --- src/cycamore.h | 4 ++-- src/enrichment.cc | 2 +- src/enrichment_tests.cc | 2 +- src/enrichment_tests.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cycamore.h b/src/cycamore.h index 7f1efdc5fa..fbc9f5e0e3 100644 --- a/src/cycamore.h +++ b/src/cycamore.h @@ -6,8 +6,8 @@ #include "batch_reactor.h" #include "batch_reactor_tests.h" #include "deploy_inst.h" -#include "enrichment_facility.h" -#include "enrichment_facility_tests.h" +#include "enrichment.h" +#include "enrichment_tests.h" #include "growth_region.h" #include "growth_region_tests.h" #include "inpro_reactor.h" diff --git a/src/enrichment.cc b/src/enrichment.cc index 439d76422c..39ed64373f 100644 --- a/src/enrichment.cc +++ b/src/enrichment.cc @@ -1,5 +1,5 @@ // Implements the Enrichment class -#include "enrichment_facility.h" +#include "enrichment.h" #include #include diff --git a/src/enrichment_tests.cc b/src/enrichment_tests.cc index 129c905cf7..ac84221b33 100644 --- a/src/enrichment_tests.cc +++ b/src/enrichment_tests.cc @@ -9,7 +9,7 @@ #include "infile_tree.h" #include "env.h" -#include "enrichment_facility_tests.h" +#include "enrichment_tests.h" using cyclus::QueryResult; using cyclus::Cond; diff --git a/src/enrichment_tests.h b/src/enrichment_tests.h index 91d5b826e5..4811392480 100644 --- a/src/enrichment_tests.h +++ b/src/enrichment_tests.h @@ -10,7 +10,7 @@ #include "exchange_context.h" #include "material.h" -#include "enrichment_facility.h" +#include "enrichment.h" namespace cycamore { From 663ef71c4d2d7fce1560dd62ec2c38b5f99cb55e Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 13 May 2015 16:10:44 -0500 Subject: [PATCH 291/314] deprecate sink's use of resource buffer --- src/sink.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sink.h b/src/sink.h index 3cd405906e..7c07609d9b 100644 --- a/src/sink.h +++ b/src/sink.h @@ -71,7 +71,7 @@ class Sink : public cyclus::Facility { /// @param size the storage size inline void SetMaxInventorySize(double size) { max_inv_size = size; - inventory.set_capacity(size); + inventory.capacity(size); } /// @return the maximum inventory storage size @@ -127,7 +127,7 @@ class Sink : public cyclus::Facility { /// this facility holds material in storage. #pragma cyclus var {'capacity': 'max_inv_size'} - cyclus::toolkit::ResourceBuff inventory; + cyclus::toolkit::ResBuf inventory; }; } // namespace cycamore From 0336b70dc287539bdc7aede4ea2ddd24e6990319 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Fri, 15 May 2015 13:22:37 -0500 Subject: [PATCH 292/314] don't need a build method, everything is covered by enternotify --- src/growth_region.cc | 7 ------- src/growth_region.h | 24 +++++++++++------------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/growth_region.cc b/src/growth_region.cc index 4f09f8c8d6..44ac081db5 100644 --- a/src/growth_region.cc +++ b/src/growth_region.cc @@ -27,13 +27,6 @@ void GrowthRegion::AddCommodityDemand(cyclus::toolkit::Commodity commod) { sdmanager_.RegisterCommodity(commod, pff.GetFunctionPtr()); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void GrowthRegion::Build(cyclus::Agent* parent) { - cyclus::Region::Build(parent); - commod_ = cyclus::toolkit::Commodity(commodity_name); - AddCommodityDemand(commod_); -} - void GrowthRegion::EnterNotify() { cyclus::Region::EnterNotify(); std::set::iterator it; diff --git a/src/growth_region.h b/src/growth_region.h index 07584633a9..72eb6f0886 100644 --- a/src/growth_region.h +++ b/src/growth_region.h @@ -47,9 +47,6 @@ class GrowthRegion : public cyclus::Region { /// facilities be built void AddCommodityDemand(cyclus::toolkit::Commodity commod); - /// perform module-specific tasks when entering the simulation - virtual void Build(cyclus::Agent* parent); - /// On each tick, the GrowthRegion queries its supply demand manager /// to determine if there exists some demand. If demand for a /// commodity exists, then the correct build order for that demand @@ -69,16 +66,17 @@ class GrowthRegion : public cyclus::Region { inline cyclus::toolkit::SupplyDemandManager* sdmanager() { return &sdmanager_; } - + protected: - #pragma cyclus var {"tooltip": "commodity in demand", \ - "doc": "name of the commodity experiencing a " \ - "growth in demand", \ - "uilabel": "Growth Commodity", \ - } + #pragma cyclus var {"tooltip": "commodity in demand", \ + "doc": "name of the commodity experiencing a " \ + "growth in demand", \ + "uilabel": "Growth Commodity", \ + } std::string commodity_name; - - #pragma cyclus var {"tooltip": "demand type", \ + + + #pragma cyclus var {"tooltip": "demand type", \ "uilabel": "Demand Growth Function Form", \ "doc": "mathematical description of demand growth " \ "(i.e., linear, exponential, piecewise)"} @@ -96,14 +94,14 @@ class GrowthRegion : public cyclus::Region { "regarding the piecewise demand type"} std::vector demand_times; - cyclus::toolkit::Commodity commod_; - /// manager for building things cyclus::toolkit::BuildingManager buildmanager_; /// manager for Supply and demand cyclus::toolkit::SupplyDemandManager sdmanager_; + cyclus::toolkit::Commodity commod_; + /// register a child void Register_(cyclus::Agent* agent); From 85653a2d0ab291fd363d805bef1def120538ef22 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Fri, 15 May 2015 13:23:50 -0500 Subject: [PATCH 293/314] kill comment lines --- src/growth_region.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/growth_region.cc b/src/growth_region.cc index 44ac081db5..03ed976899 100644 --- a/src/growth_region.cc +++ b/src/growth_region.cc @@ -3,15 +3,12 @@ namespace cycamore { -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GrowthRegion::GrowthRegion(cyclus::Context* ctx) : cyclus::Region(ctx) { cyclus::Warn("the GrowthRegion is experimental."); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GrowthRegion::~GrowthRegion() {} -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void GrowthRegion::AddCommodityDemand(cyclus::toolkit::Commodity commod) { // instantiate demand function cyclus::toolkit::PiecewiseFunctionFactory pff; @@ -85,7 +82,6 @@ void GrowthRegion::Unregister_(cyclus::Agent* agent) { buildmanager_.Unregister(b_cast); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void GrowthRegion::Tick() { int time = context()->time(); double demand = sdmanager_.Demand(commod_, time); @@ -106,7 +102,6 @@ void GrowthRegion::Tick() { cyclus::Region::Tick(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void GrowthRegion::OrderBuilds(cyclus::toolkit::Commodity& commodity, double unmetdemand) { using std::vector; @@ -138,7 +133,6 @@ void GrowthRegion::OrderBuilds(cyclus::toolkit::Commodity& commodity, } } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - extern "C" cyclus::Agent* ConstructGrowthRegion(cyclus::Context* ctx) { return new GrowthRegion(ctx); } From 5ac353269ad741b178e78b3a2b49534a7aace718 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Fri, 15 May 2015 13:43:40 -0500 Subject: [PATCH 294/314] also don't need build notify, only enter notify --- src/growth_region.cc | 4 ---- src/growth_region.h | 3 --- 2 files changed, 7 deletions(-) diff --git a/src/growth_region.cc b/src/growth_region.cc index 03ed976899..87546c55ff 100644 --- a/src/growth_region.cc +++ b/src/growth_region.cc @@ -38,10 +38,6 @@ void GrowthRegion::EnterNotify() { AddCommodityDemand(commod_); } -void GrowthRegion::BuildNotify(Agent* a) { - Register_(a); -} - void GrowthRegion::DecomNotify(Agent* a) { Unregister_(a); } diff --git a/src/growth_region.h b/src/growth_region.h index 72eb6f0886..57b5bea022 100644 --- a/src/growth_region.h +++ b/src/growth_region.h @@ -57,9 +57,6 @@ class GrowthRegion : public cyclus::Region { /// enter the simulation and register any children present virtual void EnterNotify(); - /// register a new child - virtual void BuildNotify(Agent* m); - /// unregister a child virtual void DecomNotify(Agent* m); From b91003e8bdf46957af85f54600f102242a0495eb Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Fri, 15 May 2015 17:28:04 -0500 Subject: [PATCH 295/314] new growth region structure complete --- src/growth_region.cc | 110 ++++++++++++++++++++++++----------------- src/growth_region.h | 52 +++++++------------ tests/input/growth.xml | 24 +++++---- 3 files changed, 98 insertions(+), 88 deletions(-) diff --git a/src/growth_region.cc b/src/growth_region.cc index 87546c55ff..7550d32efa 100644 --- a/src/growth_region.cc +++ b/src/growth_region.cc @@ -9,33 +9,43 @@ GrowthRegion::GrowthRegion(cyclus::Context* ctx) : cyclus::Region(ctx) { GrowthRegion::~GrowthRegion() {} -void GrowthRegion::AddCommodityDemand(cyclus::toolkit::Commodity commod) { - // instantiate demand function +void GrowthRegion::AddCommodityDemand_(std::string commod, + Demand& demand) { + + cyclus::toolkit::PiecewiseFunctionFactory pff; - int ndemands = demand_types.size(); - for (int i = 0; i < ndemands; i++) { - cyclus::toolkit::BasicFunctionFactory bff; - bool continuous = (i != 0); // the first entry is not continuous - pff.AddFunction(bff.GetFunctionPtr(demand_types[i], demand_params[i]), - demand_times[i], continuous); + cyclus::toolkit::BasicFunctionFactory bff; + bool continuous = false; + int time; + std::string type, params; + Demand::const_iterator it; + for (it = demand.begin(); it != demand.end(); it++) { + time = it->first; + type = it->second.first; + params = it->second.second; + pff.AddFunction(bff.GetFunctionPtr(type, params), time, continuous); + continuous = true; // only the first entry is not continuous } - // register the commodity anddemand - sdmanager_.RegisterCommodity(commod, pff.GetFunctionPtr()); + // register the commodity and demand + cyclus::toolkit::Commodity c(commod); + sdmanager_.RegisterCommodity(c, pff.GetFunctionPtr()); } void GrowthRegion::EnterNotify() { cyclus::Region::EnterNotify(); - std::set::iterator it; - for (it = cyclus::Agent::children().begin(); - it != cyclus::Agent::children().end(); - ++it) { - Agent* a = *it; + std::set::iterator ait; + for (ait = cyclus::Agent::children().begin(); + ait != cyclus::Agent::children().end(); + ++ait) { + Agent* a = *ait; Register_(a); } - commod_ = cyclus::toolkit::Commodity(commodity_name); - AddCommodityDemand(commod_); + std::map::iterator it; + for (it = commodity_demand.begin(); it != commodity_demand.end(); ++it) { + AddCommodityDemand_(it->first, it->second); + } } void GrowthRegion::DecomNotify(Agent* a) { @@ -79,21 +89,27 @@ void GrowthRegion::Unregister_(cyclus::Agent* agent) { } void GrowthRegion::Tick() { + double demand, supply, unmetdemand; + cyclus::toolkit::Commodity commod; int time = context()->time(); - double demand = sdmanager_.Demand(commod_, time); - double supply = sdmanager_.Supply(commod_); - double unmetdemand = demand - supply; - - LOG(cyclus::LEV_INFO3, "greg") << "GrowthRegion: " << prototype() - << " at time: " << time - << " has the following values regaring " - << " commodity: " << commod_.name(); - LOG(cyclus::LEV_INFO3, "greg") << " *demand = " << demand; - LOG(cyclus::LEV_INFO3, "greg") << " *supply = " << supply; - LOG(cyclus::LEV_INFO3, "greg") << " * unmetdemand = " << unmetdemand; - - if (unmetdemand > 0) { - OrderBuilds(commod_, unmetdemand); + std::map::iterator it; + for (it = commodity_demand.begin(); it != commodity_demand.end(); ++it) { + commod = cyclus::toolkit::Commodity(it->first); + demand = sdmanager_.Demand(commod, time); + supply = sdmanager_.Supply(commod); + unmetdemand = demand - supply; + + LOG(cyclus::LEV_INFO3, "greg") << "GrowthRegion: " << prototype() + << " at time: " << time + << " has the following values regaring " + << " commodity: " << commod.name(); + LOG(cyclus::LEV_INFO3, "greg") << " *demand = " << demand; + LOG(cyclus::LEV_INFO3, "greg") << " *supply = " << supply; + LOG(cyclus::LEV_INFO3, "greg") << " * unmetdemand = " << unmetdemand; + + if (unmetdemand > 0) { + OrderBuilds(commod, unmetdemand); + } } cyclus::Region::Tick(); } @@ -104,25 +120,31 @@ void GrowthRegion::OrderBuilds(cyclus::toolkit::Commodity& commodity, vector orders = buildmanager_.MakeBuildDecision(commodity, unmetdemand); - LOG(cyclus::LEV_INFO3, "greg") << "The build orders have been determined. " - << orders.size() - << " different type(s) of prototypes will be built."; + LOG(cyclus::LEV_INFO3, "greg") + << "The build orders have been determined. " + << orders.size() + << " different type(s) of prototypes will be built."; + cyclus::toolkit::BuildOrder* order; + cyclus::Institution* instcast; + cyclus::Agent* agentcast; for (int i = 0; i < orders.size(); i++) { - cyclus::toolkit::BuildOrder order = orders.at(i); - cyclus::Institution* instcast = dynamic_cast(order.builder); - cyclus::Agent* agentcast = dynamic_cast(order.producer); + order = &orders.at(i); + instcast = dynamic_cast(order->builder); + agentcast = dynamic_cast(order->producer); if (!instcast || !agentcast) { - throw cyclus::CastError("growth_region.has tried to incorrectly cast an already known entity."); + throw cyclus::CastError("growth_region has tried to incorrectly " + "cast an already known entity."); } - LOG(cyclus::LEV_INFO3, "greg") << "A build order for " << order.number - << " prototype(s) of type " - << dynamic_cast(agentcast)->prototype() - << " from builder " << instcast->prototype() - << " is being placed."; + LOG(cyclus::LEV_INFO3, "greg") + << "A build order for " << order->number + << " prototype(s) of type " + << dynamic_cast(agentcast)->prototype() + << " from builder " << instcast->prototype() + << " is being placed."; - for (int j = 0; j < order.number; j++) { + for (int j = 0; j < order->number; j++) { LOG(cyclus::LEV_DEBUG2, "greg") << "Ordering build number: " << j + 1; context()->SchedBuild(instcast, agentcast->prototype()); } diff --git a/src/growth_region.h b/src/growth_region.h index 57b5bea022..dd7fa9814b 100644 --- a/src/growth_region.h +++ b/src/growth_region.h @@ -1,12 +1,12 @@ #ifndef CYCAMORE_SRC_GROWTH_REGION_H_ #define CYCAMORE_SRC_GROWTH_REGION_H_ -#include +#include +#include #include #include "cyclus.h" - // forward declarations namespace cycamore { class GrowthRegion; @@ -16,6 +16,11 @@ class GrowthRegion; #include "growth_region_tests.h" namespace cycamore { + +/// A container of (time, (demand type, demand parameters)) +typedef std::vector< + std::pair > > Demand; + /// This region determines if there is a need to meet a certain /// capacity (as defined via input) at each time step. If there is /// such a need, the region will determine how many of each facility @@ -43,10 +48,6 @@ class GrowthRegion : public cyclus::Region { #pragma cyclus note {"doc": "A region that governs a scenario in which " \ "there is growth in demand for a commodity. "} - /// add a demand for a commodity on which this region request that - /// facilities be built - void AddCommodityDemand(cyclus::toolkit::Commodity commod); - /// On each tick, the GrowthRegion queries its supply demand manager /// to determine if there exists some demand. If demand for a /// commodity exists, then the correct build order for that demand @@ -64,40 +65,19 @@ class GrowthRegion : public cyclus::Region { return &sdmanager_; } - protected: - #pragma cyclus var {"tooltip": "commodity in demand", \ - "doc": "name of the commodity experiencing a " \ - "growth in demand", \ - "uilabel": "Growth Commodity", \ - } - std::string commodity_name; - - - #pragma cyclus var {"tooltip": "demand type", \ - "uilabel": "Demand Growth Function Form", \ - "doc": "mathematical description of demand growth " \ - "(i.e., linear, exponential, piecewise)"} - std::vector demand_types; - - #pragma cyclus var {"tooltip": "demand parameters", \ - "uilabel": "Demand Growth Function Parameters", \ - "doc": "parameters that define the behavior of the " \ - "demand type function"} - std::vector demand_params; - - #pragma cyclus var {"tooltip": "demand times", \ - "uilabel": "Demand Growth Piecewise Function Times", \ - "doc": "vector describing the length of times " \ - "regarding the piecewise demand type"} - std::vector demand_times; + protected: + #pragma cyclus var { \ + "alias": ["growth", "commod", \ + ["piecewise_function", \ + ["piece", "start", ["function", "type", "params"]]]], \ + } + std::map > > > commodity_demand; // must match Demand typedef /// manager for building things cyclus::toolkit::BuildingManager buildmanager_; /// manager for Supply and demand cyclus::toolkit::SupplyDemandManager sdmanager_; - - cyclus::toolkit::Commodity commod_; /// register a child void Register_(cyclus::Agent* agent); @@ -105,6 +85,10 @@ class GrowthRegion : public cyclus::Region { /// unregister a child void Unregister_(cyclus::Agent* agent); + /// add a demand for a commodity on which this region request that + /// facilities be built + void AddCommodityDemand_(std::string commod, Demand& demand); + /// orders builds given a commodity and an unmet demand for production /// capacity of that commodity /// @param commodity the commodity being demanded diff --git a/tests/input/growth.xml b/tests/input/growth.xml index 0c38c4c946..e7ce233d07 100644 --- a/tests/input/growth.xml +++ b/tests/input/growth.xml @@ -63,16 +63,20 @@ SingleRegion - commodity - - linear - - - 1 2 - - - 0 - + + + commodity + + + 0 + + linear + 1 2 + + + + + From ec7f7645aee5d05f9c4ae079156da86a8685074b Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Fri, 15 May 2015 17:28:19 -0500 Subject: [PATCH 296/314] have to now run tests in sqlite because hdf5 does not have complex container support --- tests/test_regression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index 449f7d9cd9..0a254763b7 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -23,7 +23,7 @@ class TestRegression(TestCase): """ def __init__(self, *args, **kwargs): super(TestRegression, self).__init__(*args, **kwargs) - self.ext = '.h5' if platform.system() == 'Linux' else '.sqlite' + self.ext = '.sqlite' self.outf = str(uuid.uuid4()) + self.ext self.inf = None From a1b262df0e85656a33605fb82705f1fe886698ea Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Fri, 15 May 2015 17:33:31 -0500 Subject: [PATCH 297/314] no implementation for OrderBuild --- src/growth_region.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/growth_region.h b/src/growth_region.h index dd7fa9814b..3d0af9bfa3 100644 --- a/src/growth_region.h +++ b/src/growth_region.h @@ -94,11 +94,6 @@ class GrowthRegion : public cyclus::Region { /// @param commodity the commodity being demanded /// @param unmetdemand the unmet demand void OrderBuilds(cyclus::toolkit::Commodity& commodity, double unmetdemand); - - /// orders builder to build a prototype - /// @param builder the agent that can build buildee - /// @param prototype the agent to be built - void OrderBuild(cyclus::Agent* builder, cyclus::Agent* prototype); }; } // namespace cycamore From 13b59232673166aa1a9893ad2c1edcb63b810cc8 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 18 May 2015 12:11:01 -0500 Subject: [PATCH 298/314] much better docs for growth region --- src/growth_region.h | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/growth_region.h b/src/growth_region.h index 3d0af9bfa3..42523334f1 100644 --- a/src/growth_region.h +++ b/src/growth_region.h @@ -70,9 +70,36 @@ class GrowthRegion : public cyclus::Region { "alias": ["growth", "commod", \ ["piecewise_function", \ ["piece", "start", ["function", "type", "params"]]]], \ + "uitype": ["oneormore", "string", \ + ["oneormore", \ + ["pair", "int", ["pair", "string", "string"]]]], \ + "uilabel": "Growth Demand Curves", \ + "doc": "Nameplate capacity demand functions." \ + "\n\n" \ + "Each demand type must be for a commodity for which capacity can be built "\ + "(e.g., 'power' from cycamore::Reactors). Any archetype that implements the "\ + "cyclus::toolkit::CommodityProducer interface can interact with the "\ + "GrowthRegion in the manner." \ + "\n\n" \ + "Demand functions are defined as piecewise functions. Each piece must "\ + "be provided a starting time and function description. Each function "\ + "description is comprised of a function type and associated parameters. "\ + "\n\n" \ + " * Start times are inclusive. For a start time :math:`t_0`, the demand "\ + "function is evaluated on :math:`[t_0, \infty)`." \ + "\n\n" \ + " * Supported function types are based on the "\ + "`cyclus::toolkit::BasicFunctionFactory "\ + "types `_. " \ + "\n\n" \ + " * The type name is the lower-case name of the function (e.g., " \ + "'linear', 'exponential', etc.)." \ + "\n\n" \ + " * The parameters associated with each function type can be found on their " \ + "respective documentation pages.", \ } std::map > > > commodity_demand; // must match Demand typedef - + /// manager for building things cyclus::toolkit::BuildingManager buildmanager_; From 64311fb1e6cb140c25c15149b95a4436a870c14c Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 18 May 2015 12:38:48 -0500 Subject: [PATCH 299/314] updating manager inst docs --- src/manager_inst.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/manager_inst.h b/src/manager_inst.h index 5cea34467e..c89715dac8 100644 --- a/src/manager_inst.h +++ b/src/manager_inst.h @@ -47,10 +47,14 @@ class ManagerInst /// unregister a child void Unregister_(cyclus::Agent* agent); - #pragma cyclus var {"tooltip": "facility prototypes", \ - "doc": "a facility to be managed by the institution", \ - "uilabel": "Prototype List", \ - "uitype": ["none", "prototype"]} + #pragma cyclus var { \ + "tooltip": "producer facility prototypes", \ + "uilabel": "Producer Prototype List", \ + "uitype": ["none", "prototype"], \ + "doc": "A set of facility prototypes that this institution can build. " \ + "All prototypes in this list must be based on an archetype that " \ + "implements the cyclus::toolkit::CommodityProducer interface", \ + } std::vector prototypes; }; From 4964d597b5e22b6a6f6472f2a71eb4906d487847 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Mon, 18 May 2015 15:36:09 -0500 Subject: [PATCH 300/314] added logging and a test for multiple demands --- src/growth_region.cc | 2 ++ tests/input/growth.xml | 33 +++++++++++++++++++++++++++++---- tests/test_regression.py | 16 ++++++++++++---- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/growth_region.cc b/src/growth_region.cc index 7550d32efa..4401eb5080 100644 --- a/src/growth_region.cc +++ b/src/growth_region.cc @@ -44,6 +44,8 @@ void GrowthRegion::EnterNotify() { std::map::iterator it; for (it = commodity_demand.begin(); it != commodity_demand.end(); ++it) { + LOG(cyclus::LEV_INFO3, "greg") << "Adding demand for commodity " + << it->first; AddCommodityDemand_(it->first, it->second); } } diff --git a/tests/input/growth.xml b/tests/input/growth.xml index e7ce233d07..7bc3fd874b 100644 --- a/tests/input/growth.xml +++ b/tests/input/growth.xml @@ -30,7 +30,7 @@ Source1 - commodity + commodity1 commod_recipe 1.1 @@ -41,19 +41,31 @@ Source2 - commodity + commodity1 commod_recipe 2 + + Source3 + + + commodity2 + commod_recipe + 1 + + + + Sink - commodity + commodity1 + commodity2 @@ -65,7 +77,7 @@ - commodity + commodity1 0 @@ -76,6 +88,18 @@ + + commodity2 + + + 1 + + linear + 0 3 + + + + @@ -93,6 +117,7 @@ Sink Source1 Source2 + Source3 diff --git a/tests/test_regression.py b/tests/test_regression.py index 0a254763b7..3f1cd08a2f 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -353,6 +353,9 @@ class TestGrowth(TestRegression): Sources are allowed in the ManagerInst, with capacities of 2 and 1.1, respectively. At t=1, a 2-capacity Source is expected to be built, and at t=2 and t=3, 1-capacity Sources are expected to be built. + + A linear growth demand (y = 0x + 3) for a second comodity is provided at t=2 + to test the demand for multiple commodities. """ def __init__(self, *args, **kwargs): super(TestGrowth, self).__init__(*args, **kwargs) @@ -361,19 +364,24 @@ def __init__(self, *args, **kwargs): def test_deployment(self): agent_ids = self.to_ary(self.agent_entry, "AgentId") proto = self.to_ary(self.agent_entry, "Prototype") - depl_time = self.to_ary(self.agent_entry, "EnterTime") + enter_time = self.to_ary(self.agent_entry, "EnterTime") source1_id = self.find_ids("Source1", self.agent_entry, spec_col="Prototype") source2_id = self.find_ids("Source2", self.agent_entry, spec_col="Prototype") + source3_id = self.find_ids("Source3", self.agent_entry, + spec_col="Prototype") assert_equal(len(source2_id), 1) assert_equal(len(source1_id), 2) + assert_equal(len(source3_id), 3) - assert_equal(depl_time[np.where(agent_ids == source2_id[0])], 1) - assert_equal(depl_time[np.where(agent_ids == source1_id[0])], 2) - assert_equal(depl_time[np.where(agent_ids == source1_id[1])], 3) + assert_equal(enter_time[np.where(agent_ids == source2_id[0])], 1) + assert_equal(enter_time[np.where(agent_ids == source1_id[0])], 2) + assert_equal(enter_time[np.where(agent_ids == source1_id[1])], 3) + for x in source3_id: + yield assert_equal, enter_time[np.where(agent_ids == x)], 2 class TestRecycle(TestRegression): """This class tests the input/recycle.xml file. From 6e6aedbeae5531791abf38c2f0baab1f8d353b6a Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 19 May 2015 12:07:59 -0500 Subject: [PATCH 301/314] adding failed input test to run_inputs --- tests/test_run_inputs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_run_inputs.py b/tests/test_run_inputs.py index 48abcd16c3..3957557648 100644 --- a/tests/test_run_inputs.py +++ b/tests/test_run_inputs.py @@ -10,4 +10,4 @@ def test_inputs(): for f in files: testf = ri.TestFile(ri.cyclus_path, f, "-v0") testf.run() - yield assert_true, testf.passed + yield assert_true, testf.passed, "Failed running {}".format(f) From 84b69e6cabf59b37e8f06e6c4cd4d2862cae1bde Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 19 May 2015 12:08:07 -0500 Subject: [PATCH 302/314] updating all growth region input files --- input/enrichment/linear_src_enr_rxtr_sink.xml | 24 +++++++++++-------- input/enrichment/natu_capacitated.xml | 24 +++++++++++-------- input/enrichment/swu_capacitated.xml | 24 +++++++++++-------- input/growth/source_sink_linear.xml | 24 +++++++++++-------- 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/input/enrichment/linear_src_enr_rxtr_sink.xml b/input/enrichment/linear_src_enr_rxtr_sink.xml index c2daee9706..1b9a720ce4 100644 --- a/input/enrichment/linear_src_enr_rxtr_sink.xml +++ b/input/enrichment/linear_src_enr_rxtr_sink.xml @@ -78,16 +78,20 @@ SingleRegion - power - - linear - - - 10 0 - - - 1 - + + + power + + + 1 + + linear + 10 0 + + + + + diff --git a/input/enrichment/natu_capacitated.xml b/input/enrichment/natu_capacitated.xml index b9a74d8af4..3d94d88b20 100644 --- a/input/enrichment/natu_capacitated.xml +++ b/input/enrichment/natu_capacitated.xml @@ -78,16 +78,20 @@ SingleRegion - power - - linear - - - 10 0 - - - 1 - + + + power + + + 1 + + linear + 10 0 + + + + + diff --git a/input/enrichment/swu_capacitated.xml b/input/enrichment/swu_capacitated.xml index 15c6baac5f..06d961d877 100644 --- a/input/enrichment/swu_capacitated.xml +++ b/input/enrichment/swu_capacitated.xml @@ -79,16 +79,20 @@ SingleRegion - power - - linear - - - 10 0 - - - 1 - + + + power + + + 1 + + linear + 10 0 + + + + + diff --git a/input/growth/source_sink_linear.xml b/input/growth/source_sink_linear.xml index 61afe79539..79752cc09f 100644 --- a/input/growth/source_sink_linear.xml +++ b/input/growth/source_sink_linear.xml @@ -51,16 +51,20 @@ SingleRegion - commodity - - linear - - - 1 2 - - - 0 - + + + commodity1 + + + 0 + + linear + 1 2 + + + + + From 54f6ea81146b886856ee2eedebc55af7fcb7aa28 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Tue, 19 May 2015 15:04:46 -0500 Subject: [PATCH 303/314] typos/spacing --- src/growth_region.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/growth_region.cc b/src/growth_region.cc index 4401eb5080..6fbd41f0e3 100644 --- a/src/growth_region.cc +++ b/src/growth_region.cc @@ -103,11 +103,11 @@ void GrowthRegion::Tick() { LOG(cyclus::LEV_INFO3, "greg") << "GrowthRegion: " << prototype() << " at time: " << time - << " has the following values regaring " + << " has the following values regarding " << " commodity: " << commod.name(); - LOG(cyclus::LEV_INFO3, "greg") << " *demand = " << demand; - LOG(cyclus::LEV_INFO3, "greg") << " *supply = " << supply; - LOG(cyclus::LEV_INFO3, "greg") << " * unmetdemand = " << unmetdemand; + LOG(cyclus::LEV_INFO3, "greg") << " * demand = " << demand; + LOG(cyclus::LEV_INFO3, "greg") << " * supply = " << supply; + LOG(cyclus::LEV_INFO3, "greg") << " * unmet demand = " << unmetdemand; if (unmetdemand > 0) { OrderBuilds(commod, unmetdemand); From 93fc724c99a34ec0213269dfb12ebcb53d8c750f Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Wed, 20 May 2015 00:01:12 -0500 Subject: [PATCH 304/314] typo --- tests/test_regression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_regression.py b/tests/test_regression.py index 3f1cd08a2f..e8ab2e10a1 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -354,7 +354,7 @@ class TestGrowth(TestRegression): respectively. At t=1, a 2-capacity Source is expected to be built, and at t=2 and t=3, 1-capacity Sources are expected to be built. - A linear growth demand (y = 0x + 3) for a second comodity is provided at t=2 + A linear growth demand (y = 0x + 3) for a second commodity is provided at t=2 to test the demand for multiple commodities. """ def __init__(self, *args, **kwargs): From 3eceef25eb2c3ab8ff584bd71d73e82d217842cf Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 21 May 2015 09:28:00 -0500 Subject: [PATCH 305/314] fab now supports multiple fill commods with non-uniform prefs --- input/recycle.xml | 2 +- src/fuel_fab.cc | 33 ++++++++++++++++++++++++++++----- src/fuel_fab.h | 19 ++++++++++--------- src/fuel_fab_tests.cc | 32 ++++++++++++++++---------------- 4 files changed, 55 insertions(+), 31 deletions(-) diff --git a/input/recycle.xml b/input/recycle.xml index 4eda32322e..5917ef6d31 100644 --- a/input/recycle.xml +++ b/input/recycle.xml @@ -60,7 +60,7 @@ fuelfab - depleted_u + depleted_u depleted_u 30001 diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index 381126a974..37d8104db5 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -1,4 +1,5 @@ #include "fuel_fab.h" +#include using cyclus::Material; using cyclus::Composition; @@ -131,10 +132,26 @@ FuelFab::FuelFab(cyclus::Context* ctx) void FuelFab::EnterNotify() { cyclus::Facility::EnterNotify(); - if (fiss_commod_prefs.size() == 0) { + if (fiss_commod_prefs.empty()) { for (int i = 0; i < fiss_commods.size(); i++) { - fiss_commod_prefs.push_back(0); + fiss_commod_prefs.push_back(1); } + } else if (fiss_commod_prefs.size() != fiss_commods.size()) { + std::stringstream ss; + ss << "prototype '" << prototype() << "' has " << fiss_commod_prefs.size() + << " fiss_commod_prefs vals, expected " << fiss_commods.size(); + throw cyclus::ValidationError(ss.str()); + } + + if (fill_commod_prefs.empty()) { + for (int i = 0; i < fill_commods.size(); i++) { + fill_commod_prefs.push_back(1); + } + } else if (fill_commod_prefs.size() != fill_commods.size()) { + std::stringstream ss; + ss << "prototype '" << prototype() << "' has " << fill_commod_prefs.size() + << " fill_commod_prefs vals, expected " << fill_commods.size(); + throw cyclus::ValidationError(ss.str()); } } @@ -173,9 +190,15 @@ std::set::Ptr> FuelFab::GetMatlRequests() { Composition::Ptr c = context()->GetRecipe(fill_recipe); m = Material::CreateUntracked(fill.space(), c); } - cyclus::Request* r = - port->AddRequest(m, this, fill_commod, fill_pref, exclusive); - req_inventories_[r] = "fill"; + + std::vector*> reqs; + for (int i = 0; i < fill_commods.size(); i++) { + std::string commod = fill_commods[i]; + double pref = fill_commod_prefs[i]; + reqs.push_back(port->AddRequest(m, this, commod, pref, exclusive)); + req_inventories_[reqs.back()] = "fill"; + } + port->AddMutualReqs(reqs); ports.insert(port); } diff --git a/src/fuel_fab.h b/src/fuel_fab.h index 0161498b21..5facb27cff 100644 --- a/src/fuel_fab.h +++ b/src/fuel_fab.h @@ -128,11 +128,11 @@ class FuelFab : public cyclus::Facility { private: #pragma cyclus var { \ - "doc": "Commodity on which to request material for filler stream.", \ - "uilabel": "Filler Stream Commodity", \ - "uitype": "incommodity", \ + "doc": "Ordered list of commodities on which to requesting filler stream material.", \ + "uilabel": "Filler Stream Commodities", \ + "uitype": ["oneormore", "incommodity"], \ } - std::string fill_commod; + std::vector fill_commods; #pragma cyclus var { \ "doc": "Name of recipe to be used in filler material stream requests.", \ "uilabel": "Filler Stream Recipe", \ @@ -140,11 +140,12 @@ class FuelFab : public cyclus::Facility { } std::string fill_recipe; #pragma cyclus var { \ - "doc": "Filler material stream request preference.", \ - "uilabel": "Filler Stream Preference", \ - "default": 0, \ + "default": [], \ + "uilabel": "Filler Stream Preferences", \ + "doc": "Filler stream commodity request preferences for each of the given filler commodities (same order)." \ + " If unspecified, default is to use 1.0 for all preferences.", \ } - double fill_pref; + std::vector fill_commod_prefs; #pragma cyclus var { \ "doc": "Size of filler material stream inventory.", \ "uilabel": "Filler Stream Inventory Capacity", \ @@ -164,7 +165,7 @@ class FuelFab : public cyclus::Facility { "default": [], \ "uilabel": "Fissile Stream Preferences", \ "doc": "Fissile stream commodity request preferences for each of the given fissile commodities (same order)." \ - " If unspecified, default is to use zero for all preferences.", \ + " If unspecified, default is to use 1.0 for all preferences.", \ } std::vector fiss_commod_prefs; #pragma cyclus var { \ diff --git a/src/fuel_fab_tests.cc b/src/fuel_fab_tests.cc index dfa0ab0baf..96751ef138 100644 --- a/src/fuel_fab_tests.cc +++ b/src/fuel_fab_tests.cc @@ -182,7 +182,7 @@ TEST(FuelFabTests, ValidWeights) { // request (and receive) a specific recipe for fissile stream correctly. TEST(FuelFabTests, FissRecipe) { std::string config = - "dummy" + " dummy " "natu" "1" "" @@ -217,7 +217,7 @@ TEST(FuelFabTests, FissRecipe) { // fissile material inventory. TEST(FuelFabTests, MultipleFissStreams) { std::string config = - "dummy" + " dummy " "natu" "1" "" @@ -258,7 +258,7 @@ TEST(FuelFabTests, MultipleFissStreams) { // fissile stream preferences can be specified. TEST(FuelFabTests, FissStreamPrefs) { std::string config = - "dummy" + " dummy " "natu" "1" "" @@ -299,7 +299,7 @@ TEST(FuelFabTests, FissStreamPrefs) { // zero throughput must not result in a zero capacity constraint excception. TEST(FuelFabTests, ZeroThroughput) { std::string config = - "natu" + " natu " "natu" "3.9" "" @@ -332,7 +332,7 @@ TEST(FuelFabTests, ZeroThroughput) { // enforced after they are full. TEST(FuelFabTests, FillAllInventories) { std::string config = - "natu" + " natu " "natu" "3.9" "" @@ -382,7 +382,7 @@ TEST(FuelFabTests, FillAllInventories) { // inventory quantity. TEST(FuelFabTests, ProvideStraightFiss_WithZeroFill) { std::string config = - "nothing" + " nothing " "natu" "100" "" @@ -412,7 +412,7 @@ TEST(FuelFabTests, ProvideStraightFiss_WithZeroFill) { TEST(FuelFabTests, ProvideStraightFill_ZeroFiss) { std::string config = - "anything" + " anything " "natu" "100" "" @@ -444,7 +444,7 @@ TEST(FuelFabTests, ProvideStraightFill_ZeroFiss) { // requests and with ample material inventory. TEST(FuelFabTests, ThroughputLimit) { std::string config = - "anything" + " anything " "natu" "100" "" @@ -490,7 +490,7 @@ TEST(FuelFabTests, ThroughputLimit) { // supplied fuel has proper equivalence weights as requested. TEST(FuelFabTests, CorrectMixing) { std::string config = - "natu" + " natu " "natu" "100" "" @@ -540,7 +540,7 @@ TEST(FuelFabTests, CorrectMixing) { // fissile. TEST(FuelFabTests, FillConstrained) { std::string config = - "natu" + " natu " "natu" "1" "" @@ -585,7 +585,7 @@ TEST(FuelFabTests, FillConstrained) { // plenty of filler. TEST(FuelFabTests, FissConstrained) { std::string config = - "natu" + " natu " "natu" "10000" "" @@ -629,7 +629,7 @@ TEST(FuelFabTests, FissConstrained) { // swap to topup inventory because fissile has too low reactivity. TEST(FuelFabTests, SwapTopup) { std::string config = - "natu" + " natu " "natu" "10000" "" @@ -679,7 +679,7 @@ TEST(FuelFabTests, SwapTopup) { TEST(FuelFabTests, SwapTopup_ZeroFill) { std::string config = - "natu" + " natu " "natu" "0" "" @@ -734,7 +734,7 @@ TEST(FuelFabTests, SwapTopup_ZeroFill) { // fiss). TEST(FuelFabTests, SwapTopup_TopupConstrained) { std::string config = - "natu" + " natu " "natu" "10000" "" @@ -788,7 +788,7 @@ TEST(FuelFabTests, SwapTopup_TopupConstrained) { // small fiss inventory. TEST(FuelFabTests, SwapTopup_FissConstrained) { std::string config = - "natu" + " natu " "natu" "0" "" @@ -847,7 +847,7 @@ TEST(FuelFabTests, SwapTopup_FissConstrained) { // the case. This test makes sure that doesn't happen again. TEST(FuelFabTests, HomogenousBuffers) { std::string config = - "natu" + " natu " "natu" "40" "" From ed7fb3c4b3c152c114bea52c25438cd7b8e17622 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 21 May 2015 10:01:50 -0500 Subject: [PATCH 306/314] Pu241 nu = Pu239 for now --- src/fuel_fab.cc | 9 ++++++ src/fuel_fab_tests.cc | 4 +-- tests/test_regression.py | 63 ++++++++++++++++++++-------------------- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index 37d8104db5..709ca29194 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -497,6 +497,7 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { double nu_u233 = 2.5; double nu_u235 = 2.43; double nu_u238 = 0; + double nu_pu241 = nu_pu239; static std::map absorb_xs; static std::map fiss_xs; @@ -523,6 +524,8 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { nu = nu_u233; } else if (nuc == 942390000) { nu = nu_pu239; + } else if (nuc == 942410000) { + nu = nu_pu241; } double fiss = 0; @@ -551,6 +554,7 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { double nu_u233 = 2.63; double nu_u235 = 2.58; double nu_u238 = 0; + double nu_pu241 = nu_pu239; static std::map absorb_xs; static std::map fiss_xs; @@ -581,6 +585,8 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { nu = nu_u233; } else if (nuc == 942390000) { nu = nu_pu239; + } else if (nuc == 942410000) { + nu = nu_pu241; } double fiss = 0; @@ -609,6 +615,7 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { double nu_u233 = 2.63; double nu_u235 = 2.58; double nu_u238 = 0; + double nu_pu241 = nu_pu239; double fiss_u238 = simple_xs(922380000, "fission", spectrum); double absorb_u238 = simple_xs(922380000, "absorption", spectrum); @@ -629,6 +636,8 @@ double CosiWeight(cyclus::Composition::Ptr c, const std::string& spectrum) { nu = nu_u233; } else if (nuc == 942390000) { nu = nu_pu239; + } else if (nuc == 942410000) { + nu = nu_pu241; } double fiss = 0; diff --git a/src/fuel_fab_tests.cc b/src/fuel_fab_tests.cc index 96751ef138..810783c846 100644 --- a/src/fuel_fab_tests.cc +++ b/src/fuel_fab_tests.cc @@ -528,12 +528,12 @@ TEST(FuelFabTests, CorrectMixing) { conds[0] = Cond("Commodity", "==", std::string("natu")); qr = sim.db().Query("Transactions", &conds); m = sim.GetMaterial(qr.GetVal("ResourceId")); - EXPECT_NEAR(9.73958936, m->quantity(), 1e-6) << "mixed wrong amount of Nat. U stream"; + EXPECT_NEAR(9.7463873197, m->quantity(), 1e-6) << "mixed wrong amount of Nat. U stream"; conds[0] = Cond("Commodity", "==", std::string("pustream")); qr = sim.db().Query("Transactions", &conds); m = sim.GetMaterial(qr.GetVal("ResourceId")); - EXPECT_NEAR(0.2604106, m->quantity(), 1e-6) << "mixed wrong amount of Pu stream"; + EXPECT_NEAR(0.25361268029, m->quantity(), 1e-6) << "mixed wrong amount of Pu stream"; } // fuel is requested requiring more filler than is available with plenty of diff --git a/tests/test_regression.py b/tests/test_regression.py index 449f7d9cd9..f8d40701f1 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -427,41 +427,42 @@ def do_compare(self, fromfac, tofac, nuclide, exp_invs): def test_pu239_sep_repo(self): simdur = 600 exp = [0.0] * simdur - exp[18] = 1.700222672 - exp[37] = 1.700222672 - exp[56] = 1.700222672 - exp[75] = 1.700222672 - exp[94] = 1.700222672 - exp[113] = 1.700222672 - exp[132] = 1.700222672 - exp[151] = 1.700222672 - exp[170] = 1.700222672 - exp[189] = 1.700222672 - exp[208] = 1.700222672 - exp[227] = 1.700222672 - exp[246] = 1.700222672 - exp[284] = 1.700222672 - exp[303] = 1.700222672 - exp[322] = 1.700222672 - exp[341] = 1.700222672 - exp[360] = 1.700222672 - exp[379] = 1.700222672 - exp[398] = 1.700222672 - exp[417] = 1.700222672 - exp[436] = 1.700222672 - exp[474] = 1.700222672 - exp[493] = 1.700222672 - exp[512] = 1.700222672 - exp[531] = 1.700222672 - exp[550] = 1.700222672 - exp[569] = 1.700222672 - exp[588] = 1.700222672 + exp[18] = 1.70022267 + exp[37] = 1.70022267 + exp[56] = 1.70022267 + exp[75] = 1.70022267 + exp[94] = 1.70022267 + exp[113] = 1.70022267 + exp[132] = 1.70022267 + exp[151] = 1.70022267 + exp[170] = 1.70022267 + exp[189] = 1.70022267 + exp[208] = 1.70022267 + exp[246] = 1.70022267 + exp[265] = 1.70022267 + exp[284] = 1.70022267 + exp[303] = 1.70022267 + exp[322] = 1.70022267 + exp[341] = 1.70022267 + exp[360] = 1.70022267 + exp[379] = 1.70022267 + exp[417] = 1.70022267 + exp[436] = 1.70022267 + exp[455] = 1.70022267 + exp[474] = 1.70022267 + exp[493] = 1.70022267 + exp[512] = 1.70022267 + exp[531] = 1.70022267 + exp[569] = 1.70022267 + exp[588] = 1.70022267 + self.do_compare('separations', 'repo', 942390000, exp) def test_pu239_reactor_repo(self): simdur = 600 exp = [0.0] * simdur - exp[264] = 420.42772559790944 - exp[454] = 420.42772559790944 + exp[226] = 420.42772559790944 + exp[397] = 420.42772559790944 + exp[549] = 420.42772559790944 self.do_compare('reactor', 'repo', 942390000, exp) From effd7a2dfe9f3350caddd69665a5c61f3fe67575 Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 21 May 2015 10:15:51 -0500 Subject: [PATCH 307/314] adding exp warning to fuelfab --- src/fuel_fab.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fuel_fab.cc b/src/fuel_fab.cc index 381126a974..15244c5f75 100644 --- a/src/fuel_fab.cc +++ b/src/fuel_fab.cc @@ -126,7 +126,11 @@ class TopupConverter : public cyclus::Converter { }; FuelFab::FuelFab(cyclus::Context* ctx) - : cyclus::Facility(ctx), fill_size(0), fiss_size(0), throughput(0) {} + : cyclus::Facility(ctx), fill_size(0), fiss_size(0), throughput(0) { + cyclus::Warn( + "the FuelFab archetype " + "is experimental"); +} void FuelFab::EnterNotify() { cyclus::Facility::EnterNotify(); From 343dce6ae3f17e829b18d3368cc0983b3ed1688c Mon Sep 17 00:00:00 2001 From: Matthew Gidden Date: Thu, 21 May 2015 13:23:38 -0500 Subject: [PATCH 308/314] none->oneormore --- src/manager_inst.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manager_inst.h b/src/manager_inst.h index c89715dac8..3e1d294a79 100644 --- a/src/manager_inst.h +++ b/src/manager_inst.h @@ -50,7 +50,7 @@ class ManagerInst #pragma cyclus var { \ "tooltip": "producer facility prototypes", \ "uilabel": "Producer Prototype List", \ - "uitype": ["none", "prototype"], \ + "uitype": ["oneormore", "prototype"], \ "doc": "A set of facility prototypes that this institution can build. " \ "All prototypes in this list must be based on an archetype that " \ "implements the cyclus::toolkit::CommodityProducer interface", \ From 44855d792bb8244aee5e88632723c9376a9d8a8d Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Fri, 10 Apr 2015 12:01:24 -0500 Subject: [PATCH 309/314] Handle reactor retirement better: * discharge all fuel fuel from core at end of life (and transmute it). * if nearing end of life, only order up to enough fresh fuel to reach end of life. * block decommissioning until all fuel has been removed from core and traded away out of spent inventory. --- src/reactor.cc | 56 +++++++++++++++++++++++++++++++++++++++++--------- src/reactor.h | 5 +++++ 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index 26b82a644b..ccb5675667 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -57,7 +57,7 @@ void Reactor::InitFrom(cyclus::QueryableBackend* b) { void Reactor::EnterNotify() { cyclus::Facility::EnterNotify(); - + // If the user ommitted fuel_prefs, we set it to zeros for each fuel // type. Without this segfaults could occur - yuck. if (fuel_prefs.size() == 0) { @@ -98,6 +98,10 @@ void Reactor::EnterNotify() { } } +bool Reactor::CheckDecommissionCondition() { + return core.count() == 0 && spent.count() == 0; +} + void Reactor::Tick() { // The following code must go in the Tick so they fire on the time step // following the cycle_step update - allowing for the all reactor events to @@ -105,10 +109,23 @@ void Reactor::Tick() { // they // can't go at the beginnin of the Tock is so that resource exchange has a // chance to occur after the discharge on this same time step. + + if (retired()) { + Record("RETIRED", ""); + while (core.count() > 0) { + Transmute(); + if (!Discharge()) { + break; + } + } + return; + } + if (cycle_step == cycle_time) { Transmute(); Record("CYCLE_END", ""); } + if (cycle_step >= cycle_time && !discharged) { discharged = Discharge(); } @@ -158,10 +175,25 @@ std::set::Ptr> Reactor::GetMatlRequests() { std::set::Ptr> ports; Material::Ptr m; - int n_assem_order = - n_assem_core - core.count() + n_assem_fresh - fresh.count(); + // second min expression reduces assembles to amount needed until + // retirement if it is near. + int n_assem_order = n_assem_core - core.count() + n_assem_fresh - fresh.count(); + + if (exit_time() != -1) { + int tleft = exit_time() - context()->time(); + int tleftcycle = cycle_time + refuel_time - cycle_step; + double ncyclesleft = (double)(tleft - tleftcycle) / (double)(cycle_time + refuel_time); + if ((int)ncyclesleft < ncyclesleft) { + ncyclesleft = ((int)ncyclesleft) + 1; + } + int nneed = std::max(0.0, ncyclesleft * n_assem_batch - n_assem_fresh); + n_assem_order = std::min(n_assem_order, nneed); + } + if (n_assem_order == 0) { return ports; + } else if (retired()) { + return ports; } for (int i = 0; i < n_assem_order; i++) { @@ -275,6 +307,10 @@ std::set::Ptr> Reactor::GetMatlBids( } void Reactor::Tock() { + if (retired()) { + return; + } + if (cycle_step >= cycle_time + refuel_time && core.count() == n_assem_core) { discharged = false; cycle_step = 0; @@ -299,11 +335,12 @@ void Reactor::Tock() { } void Reactor::Transmute() { - // safe to assume full core. - MatVec old = core.PopN(n_assem_batch); - MatVec tail = core.PopN(core.count()); + MatVec old = core.PopN(std::min(n_assem_batch, core.count())); core.Push(old); - core.Push(tail); + if (core.count() > old.size()) { + // rotate untransmuted mats back to back of buffer + core.Push(core.PopN(core.count() - old.size())); + } std::stringstream ss; ss << old.size() << " assemblies"; @@ -326,13 +363,12 @@ std::map Reactor::PeekSpent() { } bool Reactor::Discharge() { - if (n_assem_spent - spent.count() < n_assem_batch) { + int npop = std::min(n_assem_batch, core.count()); + if (n_assem_spent - spent.count() < npop) { Record("DISCHARGE", "failed"); return false; // not enough room in spent buffer } - int npop = std::min(n_assem_batch, core.count()); - std::stringstream ss; ss << npop << " assemblies"; Record("DISCHARGE", ss.str()); diff --git a/src/reactor.h b/src/reactor.h index 8d9cfcecf4..b90122160b 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -93,6 +93,7 @@ class Reactor : public cyclus::Facility, virtual void Tick(); virtual void Tock(); virtual void EnterNotify(); + virtual bool CheckDecommissionCondition(); virtual void AcceptMatlTrades(const std::vector, cyclus::Material::Ptr> >& responses); @@ -117,6 +118,10 @@ class Reactor : public cyclus::Facility, std::string fuel_outrecipe(cyclus::Material::Ptr m); double fuel_pref(cyclus::Material::Ptr m); + bool retired() { + return exit_time() != -1 && context()->time() >= exit_time(); + } + /// Store fuel info index for the given resource received on incommod. void index_res(cyclus::Resource::Ptr m, std::string incommod); From 4a845dd6b91b8561e52202fc7690072d414d651f Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Mon, 13 Apr 2015 14:42:46 -0500 Subject: [PATCH 310/314] only transmute half of discharged core at retirement --- src/reactor.cc | 18 +++++++++++------- src/reactor.h | 24 +++++++++++++++++++++++- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index ccb5675667..845174ce59 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -112,8 +112,11 @@ void Reactor::Tick() { if (retired()) { Record("RETIRED", ""); + + if (context()->time() == exit_time()) { // only need to transmute once + Transmute(ceil(static_cast(n_assem_core) / 2.0)); + } while (core.count() > 0) { - Transmute(); if (!Discharge()) { break; } @@ -182,10 +185,9 @@ std::set::Ptr> Reactor::GetMatlRequests() { if (exit_time() != -1) { int tleft = exit_time() - context()->time(); int tleftcycle = cycle_time + refuel_time - cycle_step; - double ncyclesleft = (double)(tleft - tleftcycle) / (double)(cycle_time + refuel_time); - if ((int)ncyclesleft < ncyclesleft) { - ncyclesleft = ((int)ncyclesleft) + 1; - } + double ncyclesleft = static_cast(tleft - tleftcycle) / + static_cast(cycle_time + refuel_time); + ncyclesleft = ceil(ncyclesleft); int nneed = std::max(0.0, ncyclesleft * n_assem_batch - n_assem_fresh); n_assem_order = std::min(n_assem_order, nneed); } @@ -334,8 +336,10 @@ void Reactor::Tock() { } } -void Reactor::Transmute() { - MatVec old = core.PopN(std::min(n_assem_batch, core.count())); +void Reactor::Transmute() { Transmute(n_assem_batch); } + +void Reactor::Transmute(int n_assem) { + MatVec old = core.PopN(std::min(n_assem, core.count())); core.Push(old); if (core.count() > old.size()) { // rotate untransmuted mats back to back of buffer diff --git a/src/reactor.h b/src/reactor.h index b90122160b..5dd22f1079 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -42,6 +42,15 @@ namespace cycamore { /// becomes full, the reactor will halt operation at the end of the next cycle /// until there is more room. Each time step, the reactor will try to trade /// away as much of its spent fuel inventory as possible. +/// +/// When the reactor reaches the end of its lifetime, it will discharge all +/// material from its core and trade away all its spent fuel as quickly as +/// possible. Full decommissioning will be delayed until all spent fuel is +/// gone. If the reactor has a full core when it is decommissioned (i.e. is +/// mid-cycle) when the reactor is decommissioned, half (rounded up to nearest +/// int) of its assemblies are transmuted to their respective burnt +/// compositions. + class Reactor : public cyclus::Facility, public cyclus::toolkit::CommodityProducer { #pragma cyclus note { \ @@ -83,7 +92,16 @@ class Reactor : public cyclus::Facility, " operational cycle before the next begins. If the spent fuel inventory" \ " becomes full, the reactor will halt operation at the end of the next cycle" \ " until there is more room. Each time step, the reactor will try to trade" \ - " away as much of its spent fuel inventory as possible.", \ + " away as much of its spent fuel inventory as possible." \ + "\n\n" \ + "When the reactor reaches the end of its lifetime, it will discharge all" \ + " material from its core and trade away all its spent fuel as quickly as" \ + " possible. Full decommissioning will be delayed until all spent fuel is" \ + " gone. If the reactor has a full core when it is decommissioned (i.e. is" \ + " mid-cycle) when the reactor is decommissioned, half (rounded up to nearest" \ + " int) of its assemblies are transmuted to their respective burnt" \ + " compositions." \ + "", \ } public: @@ -136,6 +154,10 @@ class Reactor : public cyclus::Facility, /// fully burnt state as defined by its outrecipe. void Transmute(); + /// Transmute the specified number of assemblies in the core to their + /// fully burnt state as defined by their outrecipe. + void Transmute(int n_assem); + /// Records a reactor event to the output db with the given name and note val. void Record(std::string name, std::string val); From e2b75d64cc9e5171a56bffdc44c9c2483b5a089f Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 16 Apr 2015 13:33:33 -0500 Subject: [PATCH 311/314] fix bug where non-unique fuel outcommods on a reactor resulted in duplicate bid portfolios and over-matching --- src/reactor.cc | 13 ++++++++++--- src/reactor.h | 3 +++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index 845174ce59..8c6f0ecdd3 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -223,7 +223,6 @@ void Reactor::GetMatlTrades( using cyclus::Trade; std::map mats = PopSpent(); - std::vector >::const_iterator it; for (int i = 0; i < trades.size(); i++) { std::string commod = trades[i].request->commodity(); Material::Ptr m = mats[commod].back(); @@ -267,8 +266,16 @@ std::set::Ptr> Reactor::GetMatlBids( bool gotmats = false; std::map all_mats; - for (int i = 0; i < fuel_outcommods.size(); i++) { - std::string commod = fuel_outcommods[i]; + + if (uniq_outcommods_.empty()) { + for (int i = 0; i < fuel_outcommods.size(); i++) { + uniq_outcommods_.insert(fuel_outcommods[i]); + } + } + + std::set::iterator it; + for (it = uniq_outcommods_.begin(); it != uniq_outcommods_.end(); ++it) { + std::string commod = *it; std::vector*>& reqs = commod_requests[commod]; if (reqs.size() == 0) { continue; diff --git a/src/reactor.h b/src/reactor.h index 5dd22f1079..a6aa645dbf 100644 --- a/src/reactor.h +++ b/src/reactor.h @@ -362,6 +362,9 @@ class Reactor : public cyclus::Facility, "internal": True \ } std::map res_indexes; + + // populated lazily and no need to persist. + std::set uniq_outcommods_; }; } // namespace cycamore From 85fe5dd0789fdea0ec2a0306ef87400e4d107e06 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 21 May 2015 15:51:18 -0500 Subject: [PATCH 312/314] add tests and fix bugs --- src/reactor.cc | 13 ++++++++++++- src/reactor_tests.cc | 46 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/reactor.cc b/src/reactor.cc index 8c6f0ecdd3..1d46ddc31d 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -109,6 +109,9 @@ void Reactor::Tick() { // they // can't go at the beginnin of the Tock is so that resource exchange has a // chance to occur after the discharge on this same time step. + std::cout << context()->time() << ": " << "fresh.count=" << fresh.count() << "\n"; + std::cout << " core.count=" << core.count() << "\n"; + std::cout << " spent.count=" << spent.count() << "\n"; if (retired()) { Record("RETIRED", ""); @@ -121,6 +124,12 @@ void Reactor::Tick() { break; } } + // in case a cycle lands exactly on our last time step, we will need to + // burn a batch from fresh inventory on this time step. When retired, + // this batch also needs to be discharged to spent fuel inventory. + while (fresh.count() > 0 && spent.space() >= assem_size) { + spent.Push(fresh.Pop()); + } return; } @@ -183,7 +192,9 @@ std::set::Ptr> Reactor::GetMatlRequests() { int n_assem_order = n_assem_core - core.count() + n_assem_fresh - fresh.count(); if (exit_time() != -1) { - int tleft = exit_time() - context()->time(); + // the +1 accounts for the fact that the reactor is alive and gets to + // operate during its exit_time time step. + int tleft = exit_time() - context()->time() + 1; int tleftcycle = cycle_time + refuel_time - cycle_step; double ncyclesleft = static_cast(tleft - tleftcycle) / static_cast(cycle_time + refuel_time); diff --git a/src/reactor_tests.cc b/src/reactor_tests.cc index 8c743e5cf4..d67d14d897 100644 --- a/src/reactor_tests.cc +++ b/src/reactor_tests.cc @@ -461,6 +461,52 @@ TEST(ReactorTests, RecipeChange) { EXPECT_TRUE(0 < mq.mass(id("H1"))); } +TEST(ReactorTests, Retire) { + std::string config = + " lwr_fresh " + " lwr_spent " + " enriched_u " + " waste " + "" + " 7 " + " 0 " + " 300 " + " 1 " + " 3 " + " 1 " + ""; + + int dur = 50; + int life = 36; + cyclus::MockSim sim(cyclus::AgentSpec(":cycamore:Reactor"), config, dur, life); + sim.AddSource("enriched_u").Finalize(); + sim.AddSink("waste").Finalize(); + sim.AddRecipe("lwr_fresh", c_uox()); + sim.AddRecipe("lwr_spent", c_spentuox()); + int id = sim.Run(); + + int ncore = 3; + int nbatch = 1; + + // reactor should stop requesting new fresh fuel as it approaches retirement + int nassem_recv = + static_cast(ceil(static_cast(life) / 7.0)) * nbatch + + (ncore - nbatch); + + std::vector conds; + conds.push_back(Cond("ReceiverId", "==", id)); + QueryResult qr = sim.db().Query("Transactions", &conds); + EXPECT_EQ(nassem_recv, qr.rows.size()) + << "failed to stop ordering near retirement"; + + // reactor should discharge all fuel before/by retirement + conds.clear(); + conds.push_back(Cond("SenderId", "==", id)); + qr = sim.db().Query("Transactions", &conds); + EXPECT_EQ(nassem_recv, qr.rows.size()) + << "failed to discharge all material by retirement time"; +} + } // namespace reactortests } // namespace cycamore From 74dac3d9f49918b138ce53da40cd4ab8b7aee379 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 21 May 2015 15:59:59 -0500 Subject: [PATCH 313/314] remove debug cout --- src/reactor.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index 1d46ddc31d..b6bf1e9c78 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -109,9 +109,6 @@ void Reactor::Tick() { // they // can't go at the beginnin of the Tock is so that resource exchange has a // chance to occur after the discharge on this same time step. - std::cout << context()->time() << ": " << "fresh.count=" << fresh.count() << "\n"; - std::cout << " core.count=" << core.count() << "\n"; - std::cout << " spent.count=" << spent.count() << "\n"; if (retired()) { Record("RETIRED", ""); From 67607b970ee2c3f6f5d8e537289093eabe75c794 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Thu, 21 May 2015 16:12:48 -0500 Subject: [PATCH 314/314] fix var name style --- src/reactor.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/reactor.cc b/src/reactor.cc index b6bf1e9c78..e8d30ecb4d 100644 --- a/src/reactor.cc +++ b/src/reactor.cc @@ -191,13 +191,13 @@ std::set::Ptr> Reactor::GetMatlRequests() { if (exit_time() != -1) { // the +1 accounts for the fact that the reactor is alive and gets to // operate during its exit_time time step. - int tleft = exit_time() - context()->time() + 1; - int tleftcycle = cycle_time + refuel_time - cycle_step; - double ncyclesleft = static_cast(tleft - tleftcycle) / + int t_left = exit_time() - context()->time() + 1; + int t_left_cycle = cycle_time + refuel_time - cycle_step; + double n_cycles_left = static_cast(t_left - t_left_cycle) / static_cast(cycle_time + refuel_time); - ncyclesleft = ceil(ncyclesleft); - int nneed = std::max(0.0, ncyclesleft * n_assem_batch - n_assem_fresh); - n_assem_order = std::min(n_assem_order, nneed); + n_cycles_left = ceil(n_cycles_left); + int n_need = std::max(0.0, n_cycles_left * n_assem_batch - n_assem_fresh); + n_assem_order = std::min(n_assem_order, n_need); } if (n_assem_order == 0) {