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 #pragma cyclus note { \
58 "niche": "reactor", \
59 "doc": \
60  "Reactor is a simple, general reactor based on static compositional" \
61  " transformations to model fuel burnup. The user specifies a set of input" \
62  " fuels and corresponding burnt compositions that fuel is transformed to when" \
63  " it is discharged from the core. No incremental transmutation takes place." \
64  " Rather, at the end of an operational cycle, the batch being discharged from" \
65  " the core is instantaneously transmuted from its original fresh fuel" \
66  " composition into its spent fuel form." \
67  "\n\n" \
68  "Each fuel is identified by a specific input commodity and has an associated" \
69  " input recipe (nuclide composition), output recipe, output commidity, and" \
70  " preference. The preference identifies which input fuels are preferred when" \
71  " requesting. Changes in these preferences can be specified as a function of" \
72  " time using the pref_change variables. Changes in the input-output recipe" \
73  " compositions can also be specified as a function of time using the" \
74  " recipe_change variables." \
75  "\n\n" \
76  "The reactor treats fuel as individual assemblies that are never split," \
77  " combined or otherwise treated in any non-discrete way. Fuel is requested" \
78  " in full-or-nothing assembly sized quanta. If real-world assembly modeling" \
79  " is unnecessary, parameters can be adjusted (e.g. n_assem_core, assem_size," \
80  " n_assem_batch). At the end of every cycle, a full batch is discharged from" \
81  " the core consisting of n_assem_batch assemblies of assem_size kg. The" \
82  " reactor also has a specifiable refueling time period following the end of" \
83  " each cycle at the end of which it will resume operation on the next cycle" \
84  " *if* it has enough fuel for a full core; otherwise it waits until it has" \
85  " enough fresh fuel assemblies." \
86  "\n\n" \
87  "In addition to its core, the reactor has an on-hand fresh fuel inventory" \
88  " and a spent fuel inventory whose capacities are specified by n_assem_fresh" \
89  " and n_assem_spent respectively. Each time step the reactor will attempt to" \
90  " acquire enough fresh fuel to fill its fresh fuel inventory (and its core if" \
91  " the core isn't currently full). If the fresh fuel inventory has zero" \
92  " capacity, fuel will be ordered just-in-time after the end of each" \
93  " operational cycle before the next begins. If the spent fuel inventory" \
94  " becomes full, the reactor will halt operation at the end of the next cycle" \
95  " until there is more room. Each time step, the reactor will try to trade" \
96  " away as much of its spent fuel inventory as possible." \
97  "\n\n" \
98  "When the reactor reaches the end of its lifetime, it will discharge all" \
99  " material from its core and trade away all its spent fuel as quickly as" \
100  " possible. Full decommissioning will be delayed until all spent fuel is" \
101  " gone. If the reactor has a full core when it is decommissioned (i.e. is" \
102  " mid-cycle) when the reactor is decommissioned, half (rounded up to nearest" \
103  " int) of its assemblies are transmuted to their respective burnt" \
104  " compositions." \
105  "", \
106 }
107 
108  public:
109  Reactor(cyclus::Context* ctx);
110  virtual ~Reactor(){};
111 
112  virtual std::string version() { return CYCAMORE_VERSION; }
113 
114  virtual void Tick();
115  virtual void Tock();
116  virtual void EnterNotify();
117  virtual bool CheckDecommissionCondition();
118 
119  virtual void AcceptMatlTrades(const std::vector<std::pair<
120  cyclus::Trade<cyclus::Material>, cyclus::Material::Ptr> >& responses);
121 
122  virtual std::set<cyclus::RequestPortfolio<cyclus::Material>::Ptr>
123  GetMatlRequests();
124 
125  virtual std::set<cyclus::BidPortfolio<cyclus::Material>::Ptr> GetMatlBids(
126  cyclus::CommodMap<cyclus::Material>::type& commod_requests);
127 
128  virtual void GetMatlTrades(
129  const std::vector<cyclus::Trade<cyclus::Material> >& trades,
130  std::vector<std::pair<cyclus::Trade<cyclus::Material>,
131  cyclus::Material::Ptr> >& responses);
132 
133  #pragma cyclus decl
134 
135  private:
136  std::string fuel_incommod(cyclus::Material::Ptr m);
137  std::string fuel_outcommod(cyclus::Material::Ptr m);
138  std::string fuel_inrecipe(cyclus::Material::Ptr m);
139  std::string fuel_outrecipe(cyclus::Material::Ptr m);
140  double fuel_pref(cyclus::Material::Ptr m);
141 
142  bool retired() {
143  return exit_time() != -1 && context()->time() >= exit_time();
144  }
145 
147  void index_res(cyclus::Resource::Ptr m, std::string incommod);
148 
151  bool Discharge();
152 
154  void Load();
155 
158  void Transmute();
159 
162  void Transmute(int n_assem);
163 
165  void Record(std::string name, std::string val);
166 
169  void PushSpent(std::map<std::string, cyclus::toolkit::MatVec> leftover);
170 
173  std::map<std::string, cyclus::toolkit::MatVec> PopSpent();
174 
177  std::map<std::string, cyclus::toolkit::MatVec> PeekSpent();
178 
180  #pragma cyclus var { \
181  "uitype": ["oneormore", "incommodity"], \
182  "uilabel": "Fresh Fuel Commodity List", \
183  "doc": "Ordered list of input commodities on which to requesting fuel.", \
184  }
185  std::vector<std::string> fuel_incommods;
186  #pragma cyclus var { \
187  "uitype": ["oneormore", "recipe"], \
188  "uilabel": "Fresh Fuel Recipe List", \
189  "doc": "Fresh fuel recipes to request for each of the given fuel input " \
190  "commodities (same order).", \
191  }
192  std::vector<std::string> fuel_inrecipes;
193 
194  #pragma cyclus var { \
195  "default": [], \
196  "uilabel": "Fresh Fuel Preference List", \
197  "doc": "The preference for each type of fresh fuel requested corresponding"\
198  " to each input commodity (same order). If no preferences are " \
199  "specified, 1.0 is used for all fuel " \
200  "requests (default).", \
201  }
202  std::vector<double> fuel_prefs;
203  #pragma cyclus var { \
204  "uitype": ["oneormore", "outcommodity"], \
205  "uilabel": "Spent Fuel Commodity List", \
206  "doc": "Output commodities on which to offer spent fuel originally " \
207  "received as each particular input commodity (same order)." \
208  }
209  std::vector<std::string> fuel_outcommods;
210  #pragma cyclus var { \
211  "uitype": ["oneormore", "recipe"], \
212  "uilabel": "Spent Fuel Recipe List", \
213  "doc": "Spent fuel recipes corresponding to the given fuel input " \
214  "commodities (same order)." \
215  " Fuel received via a particular input commodity is transmuted to " \
216  "the recipe specified here after being burned during a cycle.", \
217  }
218  std::vector<std::string> fuel_outrecipes;
219 
221  #pragma cyclus var { \
222  "default": [], \
223  "uilabel": "Time to Change Fresh/Spent Fuel Recipe", \
224  "doc": "A time step on which to change the input-output recipe pair for " \
225  "a requested fresh fuel.", \
226  }
227  std::vector<int> recipe_change_times;
228  #pragma cyclus var { \
229  "default": [], \
230  "uilabel": "Commodity for Changed Fresh/Spent Fuel Recipe", \
231  "doc": "The input commodity indicating fresh fuel for which recipes will " \
232  "be changed. Same order as and direct correspondence to the " \
233  "specified recipe change times.", \
234  "uitype": ["oneormore", "incommodity"], \
235  }
236  std::vector<std::string> recipe_change_commods;
237  #pragma cyclus var { \
238  "default": [], \
239  "uilabel": "New Recipe for Fresh Fuel", \
240  "doc": "The new input recipe to use for this recipe change." \
241  " Same order as and direct correspondence to the specified recipe " \
242  "change times.", \
243  "uitype": ["oneormore", "recipe"], \
244  }
245  std::vector<std::string> recipe_change_in;
246  #pragma cyclus var { \
247  "default": [], \
248  "uilabel": "New Recipe for Spent Fuel", \
249  "doc": "The new output recipe to use for this recipe change." \
250  " Same order as and direct correspondence to the specified recipe " \
251  "change times.", \
252  "uitype": ["oneormore", "recipe"], \
253  }
254  std::vector<std::string> recipe_change_out;
255 
257  #pragma cyclus var { \
258  "doc": "Mass (kg) of a single assembly.", \
259  "uilabel": "Assembly Mass", \
260  "units": "kg", \
261  }
262  double assem_size;
263 
264  #pragma cyclus var { \
265  "uilabel": "Number of Assemblies per Batch", \
266  "doc": "Number of assemblies that constitute a single batch. " \
267  "This is the number of assemblies discharged from the core fully " \
268  "burned each cycle." \
269  "Batch size is equivalent to ``n_assem_batch / n_assem_core``.", \
270  }
271  int n_assem_batch;
272  #pragma cyclus var { \
273  "uilabel": "Number of Assemblies in Core", \
274  "doc": "Number of assemblies that constitute a full core.", \
275  }
276  int n_assem_core;
277  #pragma cyclus var { \
278  "default": 0, \
279  "uilabel": "Minimum Fresh Fuel Inventory", \
280  "units": "assemblies", \
281  "doc": "Number of fresh fuel assemblies to keep on-hand if possible.", \
282  }
283  int n_assem_fresh;
284  #pragma cyclus var { \
285  "default": 1000000000, \
286  "uilabel": "Maximum Spent Fuel Inventory", \
287  "units": "assemblies", \
288  "doc": "Number of spent fuel assemblies that can be stored on-site before" \
289  " reactor operation stalls.", \
290  }
291  int n_assem_spent;
292 
294  #pragma cyclus var { \
295  "doc": "The duration of a full operational cycle (excluding refueling " \
296  "time) in time steps.", \
297  "uilabel": "Cycle Length", \
298  "units": "time steps", \
299  }
300  int cycle_time;
301  #pragma cyclus var { \
302  "doc": "The duration of a full refueling period - the minimum time between"\
303  " the end of a cycle and the start of the next cycle.", \
304  "uilabel": "Refueling Outage Duration", \
305  "units": "time steps", \
306  }
307  int refuel_time;
308  #pragma cyclus var { \
309  "default": 0, \
310  "doc": "Number of time steps since the start of the last cycle." \
311  " Only set this if you know what you are doing", \
312  "uilabel": "Time Since Start of Last Cycle", \
313  "units": "time steps", \
314  }
315  int cycle_step;
316 
318  #pragma cyclus var { \
319  "default": 0, \
320  "doc": "Amount of electrical power the facility produces when operating " \
321  "normally.", \
322  "uilabel": "Nominal Reactor Power", \
323  "units": "MWe", \
324  }
325  double power_cap;
326 
327  #pragma cyclus var { \
328  "default": "power", \
329  "uilabel": "Power Commodity Name", \
330  "doc": "The name of the 'power' commodity used in conjunction with a " \
331  "deployment curve.", \
332  }
334 
336  #pragma cyclus var { \
337  "default": [], \
338  "uilabel": "Time to Change Fresh Fuel Preference", \
339  "doc": "A time step on which to change the request preference for a " \
340  "particular fresh fuel type.", \
341  }
342  std::vector<int> pref_change_times;
343  #pragma cyclus var { \
344  "default": [], \
345  "doc": "The input commodity for a particular fuel preference change. " \
346  "Same order as and direct correspondence to the specified " \
347  "preference change times.", \
348  "uilabel": "Commodity for Changed Fresh Fuel Preference", \
349  "uitype": ["oneormore", "incommodity"], \
350  }
351  std::vector<std::string> pref_change_commods;
352  #pragma cyclus var { \
353  "default": [], \
354  "uilabel": "Changed Fresh Fuel Preference", \
355  "doc": "The new/changed request preference for a particular fresh fuel." \
356  " Same order as and direct correspondence to the specified " \
357  "preference change times.", \
358  }
359  std::vector<double> pref_change_values;
360 
361  // Resource inventories - these must be defined AFTER/BELOW the member vars
362  // referenced (e.g. n_batch_fresh, assem_size, etc.).
363  #pragma cyclus var {"capacity": "n_assem_fresh * assem_size"}
364  cyclus::toolkit::ResBuf<cyclus::Material> fresh;
365  #pragma cyclus var {"capacity": "n_assem_core * assem_size"}
366  cyclus::toolkit::ResBuf<cyclus::Material> core;
367  #pragma cyclus var {"capacity": "n_assem_spent * assem_size"}
368  cyclus::toolkit::ResBuf<cyclus::Material> spent;
369 
370 
371  // should be hidden in ui (internal only). True if fuel has already been
372  // discharged this cycle.
373  #pragma cyclus var {"default": 0, "doc": "This should NEVER be set manually",\
374  "internal": True \
375  }
376  bool discharged;
377 
378  // This variable should be hidden/unavailable in ui. Maps resource object
379  // id's to the index for the incommod through which they were received.
380  #pragma cyclus var {"default": {}, "doc": "This should NEVER be set manually", \
381  "internal": True \
382  }
383  std::map<int, int> res_indexes;
384 
385  // populated lazily and no need to persist.
386  std::set<std::string> uniq_outcommods_;
387 };
388 
389 } // namespace cycamore
390 
391 #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)
void Load()
Top up core inventory as much as possible.
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()
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:110
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
virtual std::string version()
Definition: src/reactor.h:112