Adding Buffers and Policies from the Toolkit¶
In this lesson, we will:
Add ResBufs to track material inventories
Add Policies to manage the trading of material
Add inventory management logic
Change our log information to show the info about the inventories
Add a notion of total storage capacity
Overview¶
Cyclus has a growing Toolkit of standard patterns that can be used by archetype developers. There are many advantages to using the Toolkit patterns rather than developing similar functionality yourself, typical of most code reuse situations:
robustness - Toolkit patterns have been subjected to the Cyclus QA process
time savings - It will take less time to learn how to use a Toolkit than it takes to develop your own
improvements - You can benefit immediately from any improvements in the performance of the Toolkit pattern
Code reuse is a critical best practice in all software development.
One of the Toolkit patterns is a ResBuf
, providing a way to track an
inventory of Resource
objects. There are also MatlBuyPolicy
and
MatlSellPolicy
for managing the trading of Material
objects.
Add State Variables, Buffers, and Policies¶
All state variable additions should be included in src/storage.h
below the
other state variables added previously.
A
ResBuf
is available as a data type for another state variable, so we simply have to add the following:
/// this facility holds material in storage.
#pragma cyclus var {}
cyclus::toolkit::ResBuf<cyclus::Material> inventory;
This creates a state variable named inventory
that is based on the
cyclus::toolkit::ResBuf
class. We’ll explain how buffers and policies
work in just a moment. A ResBuf object has special handling by the
preprocessor, so it will not appear in the schema and therefore will not
appear in the Cycic UI either.
Next, add two additional buffers
/// a buffer for incoming material
#pragma cyclus var {}
cyclus::toolkit::ResBuf<cyclus::Material> input;
/// a buffer for outgoing material
#pragma cyclus var {}
cyclus::toolkit::ResBuf<cyclus::Material> output;
Now add the policies. Policies do not require any special handling, and thus do not need a pragma
/// a policy for requesting material
cyclus::toolkit::MatlBuyPolicy buy_policy;
/// a policy for sending material
cyclus::toolkit::MatlSellPolicy sell_policy;
There needs to be a mechansim for keeping track of when materials enter the inventory. In order to utilize Cyclus’ sophisticated restart capability, we must choose a data structure that is compatible with at least one of the Cyclus output databases (see Database Types). Given that requirement, an appropriate data structure is a list. Accordingly, add the following
/// list for material entry times, providing a default lets this variable be
/// optional in an input file
#pragma cyclus var { \
"default": [] \
}
std::list<int> entry_times;
This requires another header file, so at the top of the storage.h file, after
#include <string>
, add another include
#include <list>
Finally, check that everything works by installing and testing
$ ./install.py
$ Storage_unit_tests
You can also confirm that everything still works with running the simulation:
$ cyclus -v 3 input/storage.xml
:
.CL:CC CC _Q _Q _Q_Q _Q _Q _Q
CC;CCCCCCCC:C; /_\) /_\)/_/\\) /_\) /_\) /_\)
CCCCCCCCCCCCCl __O|/O___O|/O_OO|/O__O|/O__O|/O____________O|/O__
CCCCCCf iCCCLCC /////////////////////////////////////////////////
iCCCt ;;;;;. CCCC
CCCC ;;;;;;;;;. CClL. c
CCCC ,;; ;;: CCCC ; : CCCCi
CCC ;; ;; CC ;;: CCC` `C;
lCCC ;; CCCC ;;;: :CC .;;. C; ; : ; :;;
CCCC ;. CCCC ;;;, CC ; ; Ci ; : ; : ;
iCC :; CC ;;;, ;C ; CC ; : ; .
CCCi ;; CCC ;;;. .C ; tf ; : ; ;.
CCC ;; CCC ;;;;;;; fC : lC ; : ; ;:
iCf ;; CC :;;: tC ; CC ; : ; ;
fCCC :; LCCf ;;;: LC :. ,: C ; ; ; ; ;
CCCC ;; CCCC ;;;: CCi `;;` CC. ;;;; :;.;. ; ,;
CCl ;; CC ;;;; CCC CCL
tCCC ;; ;; CCCL ;;; tCCCCC.
CCCC ;; :;; CCCCf ; ,L
lCCC ;;;;;; CCCL
CCCCCC :;; fCCCCC
. CCCC CCCC .
.CCCCCCCCCCCCCi
iCCCCCLCf
. C. ,
:
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
INFO1(core ):Simulation set to run from start=0 to end=10
INFO1(core ):Beginning simulation
INFO1(tutori):Hello
INFO1(tutori):World!
INFO1(tutori):Hello
INFO1(tutori):World!
INFO1(tutori):Hello
INFO1(tutori):World!
INFO1(tutori):Hello
INFO1(tutori):World!
INFO1(tutori):Hello
INFO1(tutori):World!
INFO1(tutori):Hello
INFO1(tutori):World!
INFO1(tutori):Hello
INFO1(tutori):World!
INFO1(tutori):Hello
INFO1(tutori):World!
INFO1(tutori):Hello
INFO1(tutori):World!
INFO1(tutori):Hello
INFO1(tutori):World!
Status: Cyclus run successful!
Output location: cyclus.sqlite
Simulation ID: 9f15b93c-9ab2-49bb-a14f-fef872e64ce8
Add Implementation Logic¶
The goal of a storage facility is to ask for material up to some limit, store it for an amount of time, and then send it on to any interested parties. This can be implemented in Cyclus by utilizing the Toolkit objects stated above. The buy and sell policies will automatically fill and empty the input and output buffers, respectively. A concept of material flow through the facility is shown below.
Connect Buffers and Policies¶
In order for policies to be utilized, they must be connected to their respective
buffers. The storage facility would like them always connected; accordingly,
that operation should happen at the time when the facility enters a
simulation. The kernel will let agents know that they are entering a simulation
via the EnterNotify()
function.
Add the following to src/storage.h
before the Tick()
function
/// set up policies and buffers
virtual void EnterNotify();
And add the following to src/storage.cc
before the Tick()
function
void Storage::EnterNotify() {
cyclus::Facility::EnterNotify(); // call base function first
buy_policy.Init(this, &input, std::string("input"), throughput).Set(incommod).Start();
sell_policy.Init(this, &output, std::string("output"), throughput).Set(outcommod).Start();
}
Buffer Transfer Logic¶
The job of the Storage
archetype developer is to determine and implement
the logic related to transfering material between the input and output buffers
and the middle inventory buffer. Two rules govern buffer transfer logic
in this model:
All material in the input buffer is transferred to the inventory buffer
Material in the inventory buffer that has been stored for long enough is transferred to the output buffer
Because the input buffer transfer should occur after the DRE, it must happen
in the Tock()
method. Similarly, because the output buffer transfer should
occur before the DRE, it must happen in the Tick()
method. For each
transfer, care must be taken to update the entry_times
list appropriately.
The input buffer transfer requires the following operation for each object in the buffer:
Pop the object from the input buffer
Push the object to the inventory buffer
Push the current time to the
entry_times
In order to implement this, replace the current Tock()
implementation in
src/storage.cc
with
void Storage::Tock() {
int t = context()->time();
while (!input.empty()) {
inventory.Push(input.Pop());
entry_times.push_back(t);
}
}
The output buffer transfer requires the following operation so long as the condition in 1. is met:
Check whether enough time has passed since the time at the front of
entry_times
and the inventory is not empty. If so:Pop an object from the inventory buffer
Push that object to the output buffer
Pop a time from the
entry_times
In order to implement this, replace the current Tick()
implementation in
src/storage.cc
with
void Storage::Tick() {
int finished_storing = context()->time() - storage_time;
while (!inventory.empty() && entry_times.front() <= finished_storing) {
output.Push(inventory.Pop());
entry_times.pop_front();
}
}
Build and Test¶
Same as it ever was
$ ./install.py
$ Storage_unit_tests
Add Some Logging¶
Now that all of the required logic is there, it would be nice to know some information about what is happening to a facility during a simulation. This is accomplished in Cyclus through Logging, which is implemented as a stream operation.
Information about the current inventory can be added by updating the Tock()
function (after any pushing/popping) with
LOG(cyclus::LEV_INFO2, "Storage") << "The total inventory at time "
<< t << " is "
<< inventory.quantity() + output.quantity()
<< " kg.";
After updating the function should look something like
void Storage::Tock() {
int t = context()->time();
while (!input.empty()) {
inventory.Push(input.Pop());
entry_times.push_back(t);
}
LOG(cyclus::LEV_INFO2, "Storage") << "The total inventory at time "
<< t << " is "
<< inventory.quantity() + output.quantity()
<< " kg.";
}
Notice that this uses the built in quantity()
method of a ResBuf
object and that both the inventory
and output
buffers are queried. While
the implementation logic requires multiple buffers, the model assumes the
facility acts as a single cohesive unit.
You can also add information about the quantity of material that will be
requested and offered. Since this information is important to know before the
DRE, it goes in the Tick()
LOG(cyclus::LEV_INFO2, "Storage") << "Quantity to be requested: " << buy_policy.TotalQty() << " kg.";
LOG(cyclus::LEV_INFO2, "Storage") << "Quantity to be offered: " << sell_policy.Limit() << " kg.";
After updating the function should look something like
void Storage::Tick() {
int finished_storing = context()->time() - storage_time;
while (!inventory.empty() && entry_times.front() <= finished_storing) {
output.Push(inventory.Pop());
entry_times.pop_front();
}
LOG(cyclus::LEV_INFO2, "Storage") << "Quantity to be requested: " << buy_policy.TotalQty() << " kg.";
LOG(cyclus::LEV_INFO2, "Storage") << "Quantity to be offered: " << sell_policy.Limit() << " kg.";
}
To see the logging output, build and rerun the simulation
Note
Increase the verbosity from 2
to 3
.
$ ./install.py
$ cyclus -v 3 input/storage.xml
:
.CL:CC CC _Q _Q _Q_Q _Q _Q _Q
CC;CCCCCCCC:C; /_\) /_\)/_/\\) /_\) /_\) /_\)
CCCCCCCCCCCCCl __O|/O___O|/O_OO|/O__O|/O__O|/O____________O|/O__
CCCCCCf iCCCLCC /////////////////////////////////////////////////
iCCCt ;;;;;. CCCC
CCCC ;;;;;;;;;. CClL. c
CCCC ,;; ;;: CCCC ; : CCCCi
CCC ;; ;; CC ;;: CCC` `C;
lCCC ;; CCCC ;;;: :CC .;;. C; ; : ; :;;
CCCC ;. CCCC ;;;, CC ; ; Ci ; : ; : ;
iCC :; CC ;;;, ;C ; CC ; : ; .
CCCi ;; CCC ;;;. .C ; tf ; : ; ;.
CCC ;; CCC ;;;;;;; fC : lC ; : ; ;:
iCf ;; CC :;;: tC ; CC ; : ; ;
fCCC :; LCCf ;;;: LC :. ,: C ; ; ; ; ;
CCCC ;; CCCC ;;;: CCi `;;` CC. ;;;; :;.;. ; ,;
CCl ;; CC ;;;; CCC CCL
tCCC ;; ;; CCCL ;;; tCCCCC.
CCCC ;; :;; CCCCf ; ,L
lCCC ;;;;;; CCCL
CCCCCC :;; fCCCCC
. CCCC CCCC .
.CCCCCCCCCCCCCi
iCCCCCLCf
. C. ,
:
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
INFO1(core ):Simulation set to run from start=0 to end=10
INFO1(core ):Beginning simulation
INFO1(core ):Current time: 0
INFO2(core ): Beginning Tick for time: 0
INFO2(Storag): Quantity to be requested: 10 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 0
INFO2(core ): Beginning Tock for time: 0
INFO2(Storag): The total inventory at time 0 is 0 kg of material.
INFO1(core ):Current time: 1
INFO2(core ): Beginning Tick for time: 1
INFO2(Storag): Quantity to be requested: 10 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 1
INFO2(core ): Beginning Tock for time: 1
INFO2(Storag): The total inventory at time 1 is 0 kg of material.
INFO1(core ):Current time: 2
INFO2(core ): Beginning Tick for time: 2
INFO2(Storag): Quantity to be requested: 10 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 2
INFO2(core ): Beginning Tock for time: 2
INFO2(Storag): The total inventory at time 2 is 0 kg of material.
INFO1(core ):Current time: 3
INFO2(core ): Beginning Tick for time: 3
INFO2(Storag): Quantity to be requested: 10 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 3
INFO2(core ): Beginning Tock for time: 3
INFO2(Storag): The total inventory at time 3 is 0 kg of material.
INFO1(core ):Current time: 4
INFO2(core ): Beginning Tick for time: 4
INFO2(Storag): Quantity to be requested: 10 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 4
INFO2(core ): Beginning Tock for time: 4
INFO2(Storag): The total inventory at time 4 is 0 kg of material.
INFO1(core ):Current time: 5
INFO2(core ): Beginning Tick for time: 5
INFO2(Storag): Quantity to be requested: 10 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 5
INFO2(core ): Beginning Tock for time: 5
INFO2(Storag): The total inventory at time 5 is 0 kg of material.
INFO1(core ):Current time: 6
INFO2(core ): Beginning Tick for time: 6
INFO2(Storag): Quantity to be requested: 10 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 6
INFO2(core ): Beginning Tock for time: 6
INFO2(Storag): The total inventory at time 6 is 0 kg of material.
INFO1(core ):Current time: 7
INFO2(core ): Beginning Tick for time: 7
INFO2(Storag): Quantity to be requested: 10 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 7
INFO2(core ): Beginning Tock for time: 7
INFO2(Storag): The total inventory at time 7 is 0 kg of material.
INFO1(core ):Current time: 8
INFO2(core ): Beginning Tick for time: 8
INFO2(Storag): Quantity to be requested: 10 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 8
INFO2(core ): Beginning Tock for time: 8
INFO2(Storag): The total inventory at time 8 is 0 kg of material.
INFO1(core ):Current time: 9
INFO2(core ): Beginning Tick for time: 9
INFO2(Storag): Quantity to be requested: 10 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 9
INFO2(core ): Beginning Tock for time: 9
INFO2(Storag): The total inventory at time 9 is 0 kg of material.
Status: Cyclus run successful!
Output location: cyclus.sqlite
Simulation ID: 747f6c86-fce8-49be-8c57-8bb38e11761a
Add a State Variable to Define Storage Capcity¶
A natural extension for the current storage facility implementation is to have a
maximum storage capacity. To do so, first add a capacity state variable to
storage.h . If you still want the input file to work, you have to provide a
default
key in the pragma data structure. A sufficiently large value will
do.
#pragma cyclus var { \
'doc': 'Maximum storage capacity (including all material in the facility)', \
'tooltip': 'Maximum storage capacity', \
'units': 'kg', \
'default': 1e200, \
'uilabel': 'Maximum Storage Capacity' \
}
double capacity;
The required implementation is nontrivial. The goal of adding a capacity
member is to guarantee that the amount of material in the facility never exceeds
a certain value. The only way for material to enter the facility is through the
input
ResBuff via the buy_policy
. The MatlBuyPolicy
sets a maximum
buy amount based on both its throughput
and the capacity
of the
connected ResBuf
. Accordingly, you can update the input
buffer’s
capacity before the DRE occurs to achieve this behavior.
To do so, add the following line to the end of the Tick()
function (in the
implementation file), which updates capacity of the input
through the
ResBuf
capacity()
API
// only allow requests up to the storage capacity
input.capacity(capacity - inventory.quantity() - output.quantity());
So the full Tick()
function now looks like
void Storage::Tick() {
int finished_storing = context()->time() - storage_time;
while (!inventory.empty() && entry_times.front() <= finished_storing) {
output.Push(inventory.Pop());
entry_times.pop_front();
}
// only allow requests up to the storage capacity
input.capacity(capacity - inventory.quantity() - output.quantity());
LOG(cyclus::LEV_INFO2, "Storage") << "Quantity to be requested: " << buy_policy.TotalQty() << " kg.";
LOG(cyclus::LEV_INFO2, "Storage") << "Quantity to be offered: " << sell_policy.Limit() << " kg.";
}
Build and Test¶
Same as it ever was
$ ./install.py
$ Storage_unit_tests
Update Input File and Run¶
You can test that your new capacity capability works by adding the following to
the end of the config
block for Storage
(before the close tag
</Storage>) in input/storage.xml
<capacity>8</capacity>
Note that this capacity is smaller than the throughput! What do you think you will see in the output logs?
Try it out (don’t forget to delete the old sqlite file first):
$ rm cyclus.sqlite
$ cyclus -v 3 input/storage.xml
:
.CL:CC CC _Q _Q _Q_Q _Q _Q _Q
CC;CCCCCCCC:C; /_\) /_\)/_/\\) /_\) /_\) /_\)
CCCCCCCCCCCCCl __O|/O___O|/O_OO|/O__O|/O__O|/O____________O|/O__
CCCCCCf iCCCLCC /////////////////////////////////////////////////
iCCCt ;;;;;. CCCC
CCCC ;;;;;;;;;. CClL. c
CCCC ,;; ;;: CCCC ; : CCCCi
CCC ;; ;; CC ;;: CCC` `C;
lCCC ;; CCCC ;;;: :CC .;;. C; ; : ; :;;
CCCC ;. CCCC ;;;, CC ; ; Ci ; : ; : ;
iCC :; CC ;;;, ;C ; CC ; : ; .
CCCi ;; CCC ;;;. .C ; tf ; : ; ;.
CCC ;; CCC ;;;;;;; fC : lC ; : ; ;:
iCf ;; CC :;;: tC ; CC ; : ; ;
fCCC :; LCCf ;;;: LC :. ,: C ; ; ; ; ;
CCCC ;; CCCC ;;;: CCi `;;` CC. ;;;; :;.;. ; ,;
CCl ;; CC ;;;; CCC CCL
tCCC ;; ;; CCCL ;;; tCCCCC.
CCCC ;; :;; CCCCf ; ,L
lCCC ;;;;;; CCCL
CCCCCC :;; fCCCCC
. CCCC CCCC .
.CCCCCCCCCCCCCi
iCCCCCLCf
. C. ,
:
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: ResBuf is experimental and its API may be subject to change
Experimental Warning: MatlBuyPolicy is experimental and its API may be subject to change
Experimental Warning: MatlSellPolicy is experimental and its API may be subject to change
INFO1(core ):Simulation set to run from start=0 to end=10
INFO1(core ):Beginning simulation
INFO1(core ):Current time: 0
INFO2(core ): Beginning Tick for time: 0
INFO2(Storag): Quantity to be requested: 8 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 0
INFO2(core ): Beginning Tock for time: 0
INFO2(Storag): The total inventory at time 0 is 0 kg of material.
INFO1(core ):Current time: 1
INFO2(core ): Beginning Tick for time: 1
INFO2(Storag): Quantity to be requested: 8 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 1
INFO2(core ): Beginning Tock for time: 1
INFO2(Storag): The total inventory at time 1 is 0 kg of material.
INFO1(core ):Current time: 2
INFO2(core ): Beginning Tick for time: 2
INFO2(Storag): Quantity to be requested: 8 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 2
INFO2(core ): Beginning Tock for time: 2
INFO2(Storag): The total inventory at time 2 is 0 kg of material.
INFO1(core ):Current time: 3
INFO2(core ): Beginning Tick for time: 3
INFO2(Storag): Quantity to be requested: 8 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 3
INFO2(core ): Beginning Tock for time: 3
INFO2(Storag): The total inventory at time 3 is 0 kg of material.
INFO1(core ):Current time: 4
INFO2(core ): Beginning Tick for time: 4
INFO2(Storag): Quantity to be requested: 8 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 4
INFO2(core ): Beginning Tock for time: 4
INFO2(Storag): The total inventory at time 4 is 0 kg of material.
INFO1(core ):Current time: 5
INFO2(core ): Beginning Tick for time: 5
INFO2(Storag): Quantity to be requested: 8 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 5
INFO2(core ): Beginning Tock for time: 5
INFO2(Storag): The total inventory at time 5 is 0 kg of material.
INFO1(core ):Current time: 6
INFO2(core ): Beginning Tick for time: 6
INFO2(Storag): Quantity to be requested: 8 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 6
INFO2(core ): Beginning Tock for time: 6
INFO2(Storag): The total inventory at time 6 is 0 kg of material.
INFO1(core ):Current time: 7
INFO2(core ): Beginning Tick for time: 7
INFO2(Storag): Quantity to be requested: 8 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 7
INFO2(core ): Beginning Tock for time: 7
INFO2(Storag): The total inventory at time 7 is 0 kg of material.
INFO1(core ):Current time: 8
INFO2(core ): Beginning Tick for time: 8
INFO2(Storag): Quantity to be requested: 8 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 8
INFO2(core ): Beginning Tock for time: 8
INFO2(Storag): The total inventory at time 8 is 0 kg of material.
INFO1(core ):Current time: 9
INFO2(core ): Beginning Tick for time: 9
INFO2(Storag): Quantity to be requested: 8 kg.
INFO2(Storag): Quantity to be offered: 0 kg.
INFO2(core ): Beginning DRE for time: 9
INFO2(core ): Beginning Tock for time: 9
INFO2(Storag): The total inventory at time 9 is 0 kg of material.
Status: Cyclus run successful!
Output location: cyclus.sqlite
Simulation ID: 1ce98e9b-bd89-402b-8bd6-c8266e293dba