CYCAMORE
src/reactor.h
Go to the documentation of this file.
1 #ifndef CYCAMORE_SRC_REACTOR_H_
2 #define CYCAMORE_SRC_REACTOR_H_
3 
4 #include "cyclus.h"
5 #include "cycamore_version.h"
6 
7 namespace cycamore {
8 
54 
55 class Reactor : public cyclus::Facility,
56  public cyclus::toolkit::CommodityProducer,
57  public cyclus::toolkit::Position {
58 #pragma cyclus note { \
59 "niche": "reactor", \
60 "doc": \
61  "Reactor is a simple, general reactor based on static compositional" \
62  " transformations to model fuel burnup. The user specifies a set of input" \
63  " fuels and corresponding burnt compositions that fuel is transformed to when" \
64  " it is discharged from the core. No incremental transmutation takes place." \
65  " Rather, at the end of an operational cycle, the batch being discharged from" \
66  " the core is instantaneously transmuted from its original fresh fuel" \
67  " composition into its spent fuel form." \
68  "\n\n" \
69  "Each fuel is identified by a specific input commodity and has an associated" \
70  " input recipe (nuclide composition), output recipe, output commidity, and" \
71  " preference. The preference identifies which input fuels are preferred when" \
72  " requesting. Changes in these preferences can be specified as a function of" \
73  " time using the pref_change variables. Changes in the input-output recipe" \
74  " compositions can also be specified as a function of time using the" \
75  " recipe_change variables." \
76  "\n\n" \
77  "The reactor treats fuel as individual assemblies that are never split," \
78  " combined or otherwise treated in any non-discrete way. Fuel is requested" \
79  " in full-or-nothing assembly sized quanta. If real-world assembly modeling" \
80  " is unnecessary, parameters can be adjusted (e.g. n_assem_core, assem_size," \
81  " n_assem_batch). At the end of every cycle, a full batch is discharged from" \
82  " the core consisting of n_assem_batch assemblies of assem_size kg. The" \
83  " reactor also has a specifiable refueling time period following the end of" \
84  " each cycle at the end of which it will resume operation on the next cycle" \
85  " *if* it has enough fuel for a full core; otherwise it waits until it has" \
86  " enough fresh fuel assemblies." \
87  "\n\n" \
88  "In addition to its core, the reactor has an on-hand fresh fuel inventory" \
89  " and a spent fuel inventory whose capacities are specified by n_assem_fresh" \
90  " and n_assem_spent respectively. Each time step the reactor will attempt to" \
91  " acquire enough fresh fuel to fill its fresh fuel inventory (and its core if" \
92  " the core isn't currently full). If the fresh fuel inventory has zero" \
93  " capacity, fuel will be ordered just-in-time after the end of each" \
94  " operational cycle before the next begins. If the spent fuel inventory" \
95  " becomes full, the reactor will halt operation at the end of the next cycle" \
96  " until there is more room. Each time step, the reactor will try to trade" \
97  " away as much of its spent fuel inventory as possible." \
98  "\n\n" \
99  "When the reactor reaches the end of its lifetime, it will discharge all" \
100  " material from its core and trade away all its spent fuel as quickly as" \
101  " possible. Full decommissioning will be delayed until all spent fuel is" \
102  " gone. If the reactor has a full core when it is decommissioned (i.e. is" \
103  " mid-cycle) when the reactor is decommissioned, half (rounded up to nearest" \
104  " int) of its assemblies are transmuted to their respective burnt" \
105  " compositions." \
106  "", \
107 }
108 
109  public:
110  Reactor(cyclus::Context* ctx);
111  virtual ~Reactor(){};
112 
113  virtual std::string version() { return CYCAMORE_VERSION; }
114 
115  virtual void Tick();
116  virtual void Tock();
117  virtual void EnterNotify();
118  virtual bool CheckDecommissionCondition();
119 
120  virtual void AcceptMatlTrades(const std::vector<std::pair<
121  cyclus::Trade<cyclus::Material>, cyclus::Material::Ptr> >& responses);
122 
123  virtual std::set<cyclus::RequestPortfolio<cyclus::Material>::Ptr>
124  GetMatlRequests();
125 
126  virtual std::set<cyclus::BidPortfolio<cyclus::Material>::Ptr> GetMatlBids(
127  cyclus::CommodMap<cyclus::Material>::type& commod_requests);
128 
129  virtual void GetMatlTrades(
130  const std::vector<cyclus::Trade<cyclus::Material> >& trades,
131  std::vector<std::pair<cyclus::Trade<cyclus::Material>,
132  cyclus::Material::Ptr> >& responses);
133 
134  #pragma cyclus decl
135 
136  private:
137  std::string fuel_incommod(cyclus::Material::Ptr m);
138  std::string fuel_outcommod(cyclus::Material::Ptr m);
139  std::string fuel_inrecipe(cyclus::Material::Ptr m);
140  std::string fuel_outrecipe(cyclus::Material::Ptr m);
141  double fuel_pref(cyclus::Material::Ptr m);
142 
143  bool retired() {
144  return exit_time() != -1 && context()->time() > exit_time();
145  }
146 
148  void index_res(cyclus::Resource::Ptr m, std::string incommod);
149 
152  bool Discharge();
153 
155  void Load();
156 
159  void Transmute();
160 
162  void RecordSideProduct(bool produce);
163 
166  void Transmute(int n_assem);
167 
169  void Record(std::string name, std::string val);
170 
173  void PushSpent(std::map<std::string, cyclus::toolkit::MatVec> leftover);
174 
177  std::map<std::string, cyclus::toolkit::MatVec> PopSpent();
178 
181  std::map<std::string, cyclus::toolkit::MatVec> PeekSpent();
182 
184  #pragma cyclus var { \
185  "uitype": ["oneormore", "incommodity"], \
186  "uilabel": "Fresh Fuel Commodity List", \
187  "doc": "Ordered list of input commodities on which to requesting fuel.", \
188  }
189  std::vector<std::string> fuel_incommods;
190  #pragma cyclus var { \
191  "uitype": ["oneormore", "inrecipe"], \
192  "uilabel": "Fresh Fuel Recipe List", \
193  "doc": "Fresh fuel recipes to request for each of the given fuel input " \
194  "commodities (same order).", \
195  }
196  std::vector<std::string> fuel_inrecipes;
197 
198  #pragma cyclus var { \
199  "default": [], \
200  "uilabel": "Fresh Fuel Preference List", \
201  "doc": "The preference for each type of fresh fuel requested corresponding"\
202  " to each input commodity (same order). If no preferences are " \
203  "specified, 1.0 is used for all fuel " \
204  "requests (default).", \
205  }
206  std::vector<double> fuel_prefs;
207  #pragma cyclus var { \
208  "uitype": ["oneormore", "outcommodity"], \
209  "uilabel": "Spent Fuel Commodity List", \
210  "doc": "Output commodities on which to offer spent fuel originally " \
211  "received as each particular input commodity (same order)." \
212  }
213  std::vector<std::string> fuel_outcommods;
214  #pragma cyclus var { \
215  "uitype": ["oneormore", "outrecipe"], \
216  "uilabel": "Spent Fuel Recipe List", \
217  "doc": "Spent fuel recipes corresponding to the given fuel input " \
218  "commodities (same order)." \
219  " Fuel received via a particular input commodity is transmuted to " \
220  "the recipe specified here after being burned during a cycle.", \
221  }
222  std::vector<std::string> fuel_outrecipes;
223 
225  #pragma cyclus var { \
226  "default": [], \
227  "uilabel": "Time to Change Fresh/Spent Fuel Recipe", \
228  "doc": "A time step on which to change the input-output recipe pair for " \
229  "a requested fresh fuel.", \
230  }
231  std::vector<int> recipe_change_times;
232  #pragma cyclus var { \
233  "default": [], \
234  "uilabel": "Commodity for Changed Fresh/Spent Fuel Recipe", \
235  "doc": "The input commodity indicating fresh fuel for which recipes will " \
236  "be changed. Same order as and direct correspondence to the " \
237  "specified recipe change times.", \
238  "uitype": ["oneormore", "incommodity"], \
239  }
240  std::vector<std::string> recipe_change_commods;
241  #pragma cyclus var { \
242  "default": [], \
243  "uilabel": "New Recipe for Fresh Fuel", \
244  "doc": "The new input recipe to use for this recipe change." \
245  " Same order as and direct correspondence to the specified recipe " \
246  "change times.", \
247  "uitype": ["oneormore", "inrecipe"], \
248  }
249  std::vector<std::string> recipe_change_in;
250  #pragma cyclus var { \
251  "default": [], \
252  "uilabel": "New Recipe for Spent Fuel", \
253  "doc": "The new output recipe to use for this recipe change." \
254  " Same order as and direct correspondence to the specified recipe " \
255  "change times.", \
256  "uitype": ["oneormore", "outrecipe"], \
257  }
258  std::vector<std::string> recipe_change_out;
259 
261  #pragma cyclus var { \
262  "doc": "Mass (kg) of a single assembly.", \
263  "uilabel": "Assembly Mass", \
264  "uitype": "range", \
265  "range": [1.0, 1e5], \
266  "units": "kg", \
267  }
268  double assem_size;
269 
270  #pragma cyclus var { \
271  "uilabel": "Number of Assemblies per Batch", \
272  "doc": "Number of assemblies that constitute a single batch. " \
273  "This is the number of assemblies discharged from the core fully " \
274  "burned each cycle." \
275  "Batch size is equivalent to ``n_assem_batch / n_assem_core``.", \
276  }
277  int n_assem_batch;
278  #pragma cyclus var { \
279  "default": 3, \
280  "uilabel": "Number of Assemblies in Core", \
281  "uitype": "range", \
282  "range": [1,3], \
283  "doc": "Number of assemblies that constitute a full core.", \
284  }
285  int n_assem_core;
286  #pragma cyclus var { \
287  "default": 0, \
288  "uilabel": "Minimum Fresh Fuel Inventory", \
289  "uitype": "range", \
290  "range": [0,3], \
291  "units": "assemblies", \
292  "doc": "Number of fresh fuel assemblies to keep on-hand if possible.", \
293  }
294  int n_assem_fresh;
295  #pragma cyclus var { \
296  "default": 1000000000, \
297  "uilabel": "Maximum Spent Fuel Inventory", \
298  "uitype": "range", \
299  "range": [0, 1000000000], \
300  "units": "assemblies", \
301  "doc": "Number of spent fuel assemblies that can be stored on-site before" \
302  " reactor operation stalls.", \
303  }
304  int n_assem_spent;
305 
307  #pragma cyclus var { \
308  "default": 18, \
309  "doc": "The duration of a full operational cycle (excluding refueling " \
310  "time) in time steps.", \
311  "uilabel": "Cycle Length", \
312  "units": "time steps", \
313  }
314  int cycle_time;
315  #pragma cyclus var { \
316  "default": 1, \
317  "doc": "The duration of a full refueling period - the minimum time between"\
318  " the end of a cycle and the start of the next cycle.", \
319  "uilabel": "Refueling Outage Duration", \
320  "units": "time steps", \
321  }
322  int refuel_time;
323  #pragma cyclus var { \
324  "default": 0, \
325  "doc": "Number of time steps since the start of the last cycle." \
326  " Only set this if you know what you are doing", \
327  "uilabel": "Time Since Start of Last Cycle", \
328  "units": "time steps", \
329  }
330  int cycle_step;
331 
333  #pragma cyclus var { \
334  "default": 0, \
335  "doc": "Amount of electrical power the facility produces when operating " \
336  "normally.", \
337  "uilabel": "Nominal Reactor Power", \
338  "uitype": "range", \
339  "range": [0.0, 2000.00], \
340  "units": "MWe", \
341  }
342  double power_cap;
343 
344  #pragma cyclus var { \
345  "default": "power", \
346  "uilabel": "Power Commodity Name", \
347  "doc": "The name of the 'power' commodity used in conjunction with a " \
348  "deployment curve.", \
349  }
351 
353 
354  #pragma cyclus var { \
355  "uilabel": "Side Product from Reactor Plant", \
356  "default": [], \
357  "doc": "Ordered vector of side product the reactor produces with power", \
358  }
359  std::vector<std::string> side_products;
360 
361  #pragma cyclus var { \
362  "uilabel": "Quantity of Side Product from Reactor Plant", \
363  "default": [], \
364  "doc": "Ordered vector of the quantity of side product the reactor produces with power", \
365  }
366  std::vector<double> side_product_quantity;
367 
368  #pragma cyclus var {"default": 1,\
369  "internal": True,\
370  "doc": "True if reactor is a hybrid system (produces side products)", \
371  }
372  bool hybrid_;
373 
374 
376  #pragma cyclus var {"default": 0, \
377  "uilabel": "Boolean for transmutation behavior upon decommissioning.", \
378  "doc": "If true, the archetype transmutes all assemblies upon decommissioning " \
379  "If false, the archetype only transmutes half.", \
380  }
381  bool decom_transmute_all;
382 
383 
385  #pragma cyclus var { \
386  "default": [], \
387  "uilabel": "Time to Change Fresh Fuel Preference", \
388  "doc": "A time step on which to change the request preference for a " \
389  "particular fresh fuel type.", \
390  }
391  std::vector<int> pref_change_times;
392  #pragma cyclus var { \
393  "default": [], \
394  "doc": "The input commodity for a particular fuel preference change. " \
395  "Same order as and direct correspondence to the specified " \
396  "preference change times.", \
397  "uilabel": "Commodity for Changed Fresh Fuel Preference", \
398  "uitype": ["oneormore", "incommodity"], \
399  }
400  std::vector<std::string> pref_change_commods;
401  #pragma cyclus var { \
402  "default": [], \
403  "uilabel": "Changed Fresh Fuel Preference", \
404  "doc": "The new/changed request preference for a particular fresh fuel." \
405  " Same order as and direct correspondence to the specified " \
406  "preference change times.", \
407  }
408  std::vector<double> pref_change_values;
409 
410  // Resource inventories - these must be defined AFTER/BELOW the member vars
411  // referenced (e.g. n_batch_fresh, assem_size, etc.).
412  #pragma cyclus var {"capacity": "n_assem_fresh * assem_size"}
413  cyclus::toolkit::ResBuf<cyclus::Material> fresh;
414  #pragma cyclus var {"capacity": "n_assem_core * assem_size"}
415  cyclus::toolkit::ResBuf<cyclus::Material> core;
416  #pragma cyclus var {"capacity": "n_assem_spent * assem_size"}
417  cyclus::toolkit::ResBuf<cyclus::Material> spent;
418 
419 
420  // should be hidden in ui (internal only). True if fuel has already been
421  // discharged this cycle.
422  #pragma cyclus var {"default": 0, "doc": "This should NEVER be set manually",\
423  "internal": True \
424  }
425  bool discharged;
426 
427  // This variable should be hidden/unavailable in ui. Maps resource object
428  // id's to the index for the incommod through which they were received.
429  #pragma cyclus var {"default": {}, "doc": "This should NEVER be set manually", \
430  "internal": True \
431  }
432  std::map<int, int> res_indexes;
433 
434  // populated lazily and no need to persist.
435  std::set<std::string> uniq_outcommods_;
436 
437  #pragma cyclus var { \
438  "default": 0.0, \
439  "uilabel": "Geographical latitude in degrees as a double", \
440  "doc": "Latitude of the agent's geographical position. The value should " \
441  "be expressed in degrees as a double." \
442  }
443  double latitude;
444 
445  #pragma cyclus var { \
446  "default": 0.0, \
447  "uilabel": "Geographical longitude in degrees as a double", \
448  "doc": "Longitude of the agent's geographical position. The value should " \
449  "be expressed in degrees as a double." \
450  }
451  double longitude;
452 
453  cyclus::toolkit::Position coordinates;
454 
456  void RecordPosition();
457 };
458 
459 } // namespace cycamore
460 
461 #endif // CYCAMORE_SRC_REACTOR_H_
std::set< std::string > uniq_outcommods_
double fuel_pref(cyclus::Material::Ptr m)
std::map< std::string, cyclus::toolkit::MatVec > PeekSpent()
Returns all spent assemblies indexed by outcommod without removing them from the spent fuel buffer...
std::vector< std::string > recipe_change_out
std::map< std::string, cyclus::toolkit::MatVec > PopSpent()
Returns all spent assemblies indexed by outcommod - removing them from the spent fuel buffer...
std::string fuel_outrecipe(cyclus::Material::Ptr m)
std::vector< std::string > fuel_outrecipes
void Transmute()
Transmute the batch that is about to be discharged from the core to its fully burnt state as defined ...
std::vector< std::string > recipe_change_in
std::vector< double > pref_change_values
Reactor(cyclus::Context *ctx)
std::vector< std::string > side_products
void Load()
Top up core inventory as much as possible.
cyclus::toolkit::Position coordinates
bool Discharge()
Discharge a batch from the core if there is room in the spent fuel inventory.
std::vector< std::string > fuel_incommods
std::map< int, int > res_indexes
void PushSpent(std::map< std::string, cyclus::toolkit::MatVec > leftover)
Complement of PopSpent - must be called with all materials passed that were not traded away to other ...
std::vector< std::string > fuel_inrecipes
std::vector< int > recipe_change_times
cycamore::GrowthRegion string
std::vector< double > fuel_prefs
cyclus::toolkit::ResBuf< cyclus::Material > fresh
virtual std::set< cyclus::RequestPortfolio< cyclus::Material >::Ptr > GetMatlRequests()
std::vector< double > side_product_quantity
virtual std::set< cyclus::BidPortfolio< cyclus::Material >::Ptr > GetMatlBids(cyclus::CommodMap< cyclus::Material >::type &commod_requests)
std::string fuel_inrecipe(cyclus::Material::Ptr m)
virtual void GetMatlTrades(const std::vector< cyclus::Trade< cyclus::Material > > &trades, std::vector< std::pair< cyclus::Trade< cyclus::Material >, cyclus::Material::Ptr > > &responses)
cyclus::toolkit::ResBuf< cyclus::Material > core
std::vector< std::string > pref_change_commods
cyclus::toolkit::ResBuf< cyclus::Material > spent
std::string fuel_outcommod(cyclus::Material::Ptr m)
virtual ~Reactor()
Definition: src/reactor.h:111
std::vector< int > pref_change_times
void Record(std::string name, std::string val)
Records a reactor event to the output db with the given name and note val.
virtual void AcceptMatlTrades(const std::vector< std::pair< cyclus::Trade< cyclus::Material >, cyclus::Material::Ptr > > &responses)
std::vector< std::string > recipe_change_commods
std::string fuel_incommod(cyclus::Material::Ptr m)
void index_res(cyclus::Resource::Ptr m, std::string incommod)
Store fuel info index for the given resource received on incommod.
std::vector< std::string > fuel_outcommods
void RecordPosition()
Records an agent&#39;s latitude and longitude to the output db.
virtual std::string version()
Definition: src/reactor.h:113
void RecordSideProduct(bool produce)
Records production of side products from the reactor.