Line data Source code
1 : /********************************************************************/
2 : /* SOFTWARE COPYRIGHT NOTIFICATION */
3 : /* Cardinal */
4 : /* */
5 : /* (c) 2021 UChicago Argonne, LLC */
6 : /* ALL RIGHTS RESERVED */
7 : /* */
8 : /* Prepared by UChicago Argonne, LLC */
9 : /* Under Contract No. DE-AC02-06CH11357 */
10 : /* With the U. S. Department of Energy */
11 : /* */
12 : /* Prepared by Battelle Energy Alliance, LLC */
13 : /* Under Contract No. DE-AC07-05ID14517 */
14 : /* With the U. S. Department of Energy */
15 : /* */
16 : /* See LICENSE for full restrictions */
17 : /********************************************************************/
18 :
19 : #pragma once
20 :
21 : #include "OpenMCProblemBase.h"
22 : #include "SymmetryPointGenerator.h"
23 :
24 : /// Tally/filter includes.
25 : #include "TallyBase.h"
26 : #include "FilterBase.h"
27 :
28 : #ifdef ENABLE_DAGMC
29 : #include "MoabSkinner.h"
30 : #include "DagMC.hpp"
31 : #endif
32 :
33 : /// Forward declarations to avoid cyclic dependencies.
34 : class OpenMCVolumeCalculation;
35 :
36 : /**
37 : * Mapping of OpenMC to a collection of MOOSE elements, with temperature and/or
38 : * density feedback. The mappind is established authomatically by looping over
39 : * all the MOOSE elements and finding the OpenMC cell at each element's centroid.
40 : *
41 : * All feedback into OpenMC is performed via element averages. The
42 : * 'temperature_blocks' parameter is used to indicate which MOOSE blocks should
43 : * provide temperature feedback, while the 'density_blocks' parameter is used to
44 : * indicate which MOOSE blocks should provide density feedback. Tallies are
45 : * automatically added to OpenMC using either cell or mesh tallies.
46 : *
47 : * Each OpenMC cell shall not have ambiguous data transfers. That is, a cell
48 : * should map to a set of elements that are ALL/NONE providing temperature
49 : * feedback, ALL/NONE providing density feedback, ALL/NONE providing cell
50 : * tallies, and ALL/NONE being uncoupled altogether.
51 : *
52 : * TODO: If this is too restrictive in the future, we could implement some type
53 : * of weighted averaging process. Also, if a cell maps to a phase and an
54 : * unmapped region, perhaps we want to allow that.
55 : *
56 : * Other considerations you should be aware of:
57 : * - The density being transferred into OpenMC from MOOSE is in units of kg/m3; this
58 : * is the unit employed by the MOOSE fluid properties module.
59 : * - The temperature being transferred into OpenMC from MOOSE is in units of K; this
60 : * is the unit employed by the MOOSE fluid and solid properties modules.
61 : * - If your geometry is highly fine-scale (such as TRISOs), you might be able to get a
62 : * huge speedup in your runtime if you (i) build your OpenMC model by repeating the same
63 : * TRISO universe in each of your repeatable-units (e.g. pebbles, compacts, plates)
64 : * AND (ii) leverage the 'identical_cell_fills' option.
65 : */
66 : class OpenMCCellAverageProblem : public OpenMCProblemBase
67 : {
68 : public:
69 : OpenMCCellAverageProblem(const InputParameters & params);
70 : static InputParameters validParams();
71 :
72 : virtual void initialSetup() override;
73 : virtual void externalSolve() override;
74 : virtual void syncSolutions(ExternalProblem::Direction direction) override;
75 2324 : virtual bool converged(unsigned int) override { return true; }
76 :
77 : /**
78 : * Read a 2d vector of subdomain names, and check that there are no duplications
79 : * and that all provided values exist on the mesh.
80 : * @param[in] name string name for the 2d vector parameter
81 : * @param[out] names subdomain names
82 : * @param[out] flattened_ids flattened 1d vector of subdomain IDs
83 : */
84 : void read2DBlockParameters(const std::string name,
85 : std::vector<std::vector<SubdomainName>> & names,
86 : std::vector<SubdomainID> & flattened_ids);
87 :
88 : /**
89 : * Check that the specified blocks are in the mesh
90 : * @param[in] name name for throwing an error
91 : * @param[in] ids block IDs to check
92 : * @param[in] names block subdomain names for throwing an error
93 : */
94 : void checkBlocksInMesh(const std::string name,
95 : const std::vector<SubdomainID> & ids,
96 : const std::vector<SubdomainName> & names) const;
97 :
98 : /// Initialize the mapping of OpenMC to the MooseMesh and perform additional setup actions
99 : void setupProblem();
100 :
101 : /**
102 : * Add the tally variable(s) (to receive OpenMC tally values), temperature variable(s)
103 : * (to write into OpenMC cells), and density variable(s) (to write into OpenMC materials)
104 : */
105 : virtual void addExternalVariables() override;
106 :
107 : /**
108 : * Get the cell volume from a stochastic calculation
109 : * @param[in] cell_info cell index, instance pair
110 : * @return stochastically-computed OpenMC cell volume
111 : */
112 : virtual Real cellVolume(const cellInfo & cell_info) const;
113 :
114 : /**
115 : * Reference to stochastic volume calculation
116 : * @return reference to stochastic volume calculation
117 : */
118 609314 : virtual const OpenMCVolumeCalculation * volumeCalculation() const { return _volume_calc; }
119 :
120 : /**
121 : * Get the mapping of cells to MOOSE elements
122 : * @return mapping of cells to MOOSE elements
123 : */
124 9297 : virtual const std::map<cellInfo, std::vector<unsigned int>> & cellToElem() const
125 : {
126 9297 : return _cell_to_elem;
127 : }
128 :
129 : /**
130 : * Get the MOOSE subdomains associated with an OpenMC cell
131 : * @param info the cell info
132 : * @return MOOSE subdomains associated with an OpenMC cell
133 : */
134 74930 : virtual std::unordered_set<SubdomainID> getCellToElementSub(const cellInfo & info)
135 : {
136 74930 : return _cell_to_elem_subdomain.at(info);
137 : }
138 :
139 : /**
140 : * Whether transformations are applied to the [Mesh] points when mapping to OpenMC
141 : * @return whether transformations are applied
142 : */
143 8748938 : virtual bool hasPointTransformations() const { return _symmetry != nullptr; }
144 :
145 : /**
146 : * Get all the scores added to the tally
147 : * @return scores
148 : */
149 336 : virtual const std::vector<std::string> & getTallyScores() const { return _all_tally_scores; }
150 :
151 : /**
152 : * Check to see if this problem contains a specific tally score.
153 : * @param[in] score the tally score
154 : * @return whether this problem contains the tally score in a tally object
155 : */
156 322 : bool hasScore(const std::string & score)
157 : {
158 322 : return std::find(_all_tally_scores.begin(), _all_tally_scores.end(), score) !=
159 322 : _all_tally_scores.end();
160 : }
161 :
162 : /**
163 : * Fetch the tally that contains the requested score.
164 : * @param[in] score the tally score
165 : * @return a vector of Cardinal tally objects containing the scores
166 : */
167 : std::vector<const TallyBase *> getTalliesByScore(const std::string & score);
168 :
169 : /**
170 : * Get the variable(s) associated with an OpenMC tally score.
171 : * @param[in] score the OpenMC score
172 : * @param[in] tid the thread ID associated with the current MOOSE object
173 : * @param[in] output the output variable (relative error, standard deviation, etc.) to fetch
174 : * @param[in] skip_func_exp whether functional expansion filter bins should be skipped or not when
175 : * fetching variable values
176 : * @return a vector of variable values associated with score
177 : */
178 : std::vector<const MooseVariableFE<Real> *> getTallyScoreVariables(const std::string & score,
179 : THREAD_ID tid,
180 : const std::string & output = "",
181 : bool skip_func_exp = false);
182 :
183 : /**
184 : * Get the variable value(s) associated with an OpenMC tally score.
185 : * @param[in] score the OpenMC score
186 : * @param[in] tid the thread ID associated with the current MOOSE object
187 : * @param[in] output the output variable (relative error, standard deviation, etc.) to fetch
188 : * @param[in] skip_func_exp whether functional expansion filter bins should be skipped or not when
189 : * fetching variable values
190 : * @return a vector of variable values associated with score
191 : */
192 : std::vector<const VariableValue *> getTallyScoreVariableValues(const std::string & score,
193 : THREAD_ID tid,
194 : const std::string & output = "",
195 : bool skip_func_exp = false);
196 :
197 : /**
198 : * Get the variable value(s) associated with an OpenMC tally score.
199 : * @param[in] score the OpenMC score
200 : * @param[in] tid the thread ID associated with the current MOOSE object
201 : * @param[in] output the output variable (relative error, standard deviation, etc.) to fetch
202 : * @param[in] skip_func_exp whether functional expansion filter bins should be skipped or not when
203 : * fetching variable values
204 : * @return a vector of variable values associated with score
205 : */
206 : std::vector<const VariableValue *>
207 : getTallyScoreNeighborVariableValues(const std::string & score,
208 : THREAD_ID tid,
209 : const std::string & output = "",
210 : bool skip_func_exp = false);
211 :
212 : /**
213 : * Whether a tally contains a specified output or not.
214 : * @param[in] score the tally score to check
215 : * @param[in] output the additional output (unrelaxed standard deviation, relative error, or
216 : * tally)
217 : * @return whether an added tally has the output or not
218 : */
219 : bool hasOutput(const std::string & score, const std::string & output) const;
220 :
221 : /**
222 : * Apply transformations to point
223 : * @param[in] pt point
224 : * @return transformed point
225 : */
226 8699784 : virtual Point transformPoint(const Point & pt) const
227 : {
228 8699784 : return this->hasPointTransformations() ? _symmetry->transformPoint(pt) : pt;
229 : }
230 :
231 : /**
232 : * This class uses elem->volume() in order to normalize the tally values. However,
233 : * elem->volume() is expensive, so whenever MOOSE does integration, they set
234 : * _current_elem_volume to the volume as set by the sum of the quadrature weights.
235 : * The quadrature rule that MOOSE provides when you only have CONSTANT MONOMIALS is
236 : * insufficient for exactly integrating the element Jacobian mapping type (which
237 : * is FIRST LAGRANGE for a first order element), so you get an error relative to
238 : * the libmesh volume computation.
239 : *
240 : * So, we need to make sure that a minimum order quadrature rule is used
241 : * so that the total tally as computed by an
242 : * ElementIntegralVariablePostprocessor actually matches the specified total
243 : * (for low quadrature orders, there can be an error up to about 5% or so in total
244 : * power). This override simply forces the volume quadrature order to be 2 or higher
245 : * when using Gauss (default), monomial, or Gauss-Lobatto quadrature.
246 : *
247 : * For other quadrature rules, the approximations made in elem->volume() are never
248 : * going to match the volume integrations in MOOSE (unless the quadrature order is
249 : * very very high). For these orders, we print an error message informing the user
250 : * that they should switch to a different order.
251 : */
252 : virtual void createQRules(QuadratureType type,
253 : Order order,
254 : Order volume_order,
255 : Order face_order,
256 : SubdomainID block,
257 : bool allow_negative_weights = true) override;
258 :
259 : /**
260 : * Type definition for cells contained within a parent cell; the first value
261 : * is the cell index, while the second is the set of cell instances
262 : */
263 : typedef std::unordered_map<int32_t, std::vector<int32_t>> containedCells;
264 :
265 : /**
266 : * Get the cell index from the element ID; will return UNMAPPED for unmapped elements
267 : * @param[in] elem_id element ID
268 : * @return cell index
269 : */
270 : int32_t elemToCellIndex(const int & elem_id) const { return elemToCellInfo(elem_id).first; }
271 :
272 : /**
273 : * Get the cell ID from the element ID. Note that this function requires that the elem_id
274 : * maps to an OpenMC cell, or else an error will be raised from OpenMC in cellID.
275 : * @param[in] elem_id element ID
276 : * @return cell ID
277 : */
278 70808000 : int32_t elemToCellID(const int & elem_id) const { return cellID(elemToCellIndex(elem_id)); }
279 :
280 : /**
281 : * Get the cell instance from the element ID; will return UNMAPPED for unmapped elements
282 : * @param[in] elem_id element ID
283 : * @return cell instance
284 : */
285 : int32_t elemToCellInstance(const int & elem_id) const { return elemToCellInfo(elem_id).second; }
286 :
287 : /**
288 : * Get the cell index, instance pair from element ID; if the element doesn't map to an OpenMC
289 : * cell, the index and instance are both set to UNMAPPED
290 : * @param[in] elem_id element ID
291 : * @return cell index, instance pair
292 : */
293 90784160 : cellInfo elemToCellInfo(const int & elem_id) const { return _elem_to_cell[elem_id]; }
294 :
295 : /**
296 : * Get the cell material index based on index, instance pair. Note that this function requires
297 : * a valid instance, index pair for cellInfo - you cannot pass in an unmapped cell, i.e.
298 : * (UNMAPPED, UNMAPPED)
299 : * @param[in] cell_info cell index, instance pair
300 : * @return material index
301 : */
302 : int32_t cellToMaterialIndex(const cellInfo & cell_info) const
303 : {
304 2844928 : return _cell_to_material.at(cell_info);
305 : }
306 :
307 : /**
308 : * Get the fields coupled for each cell; because we require that each cell maps to a consistent
309 : * set, we simply look up the coupled fields of the first element that this cell maps to. Note
310 : * that this function requires a valid instance, index pair for cellInfo - you cannot pass in an
311 : * unmapped cell, i.e. (UNMAPPED, UNMAPPED)
312 : * @param[in] cell_info cell index, instance pair
313 : * @return coupling fields
314 : */
315 : coupling::CouplingFields cellFeedback(const cellInfo & cell_info) const;
316 :
317 : /**
318 : * Whether a cell has density feedback
319 : * @param[in] cell_info cell index,instance pair
320 : * @return if cell has density feedback
321 : */
322 6959397 : bool hasDensityFeedback(const cellInfo & cell_info) const
323 : {
324 : std::vector<coupling::CouplingFields> phase = {coupling::density,
325 6959397 : coupling::density_and_temperature};
326 6959397 : return std::find(phase.begin(), phase.end(), cellFeedback(cell_info)) != phase.end();
327 6959397 : }
328 :
329 : /**
330 : * Whether a cell has temperature feedback
331 : * @param[in] cell_info cell index,instance pair
332 : * @return if cell has temperature feedback
333 : */
334 8114046 : bool hasTemperatureFeedback(const cellInfo & cell_info) const
335 : {
336 : std::vector<coupling::CouplingFields> phase = {coupling::temperature,
337 8114046 : coupling::density_and_temperature};
338 8114046 : return std::find(phase.begin(), phase.end(), cellFeedback(cell_info)) != phase.end();
339 8114046 : }
340 :
341 : /**
342 : * Checks if the [Problem/Filters] block contains a specific filter.
343 : * @param[in] filter_name the MOOSE object name of the filter
344 : * @return whether the problem contains the specified filter
345 : */
346 : bool hasFilter(const std::string & filter_name) const { return _filters.count(filter_name) > 0; }
347 :
348 : /**
349 : * Get a filter added by the [Problem/Filters] block by it's MOOSE object name.
350 : * @param[in] filter_name the MOOSE object name of the filter
351 : * @return the filter object
352 : */
353 : std::shared_ptr<FilterBase> & getFilter(const std::string & filter_name)
354 : {
355 1130 : return _filters.at(filter_name);
356 : }
357 :
358 : /**
359 : * Get the local tally
360 : * @return local tally
361 : */
362 : const std::vector<std::shared_ptr<TallyBase>> & getLocalTally() const { return _local_tallies; }
363 :
364 : /**
365 : * Get the temperature of a cell; for cells not filled with materials, this will return
366 : * the temperature of the first material-type cell
367 : * @param[in] cell_info cell index, instance pair
368 : */
369 : double cellTemperature(const cellInfo & cell_info) const;
370 :
371 : /**
372 : * Get the volume that each OpenMC cell mapped to
373 : * @param[in] cell_info cell index, instance pair
374 : */
375 : double cellMappedVolume(const cellInfo & cell_info) const;
376 :
377 : /// Reconstruct the DAGMC geometry after skinning
378 : void reloadDAGMC();
379 :
380 : /**
381 : * Add a Filter object using the filter system.
382 : * @param[in] type the new tally type
383 : * @param[in] name the name of the new tally
384 : * @param[in] moose_object_pars the input parameters of the new tally
385 : */
386 : void addFilter(const std::string & type,
387 : const std::string & name,
388 : InputParameters & moose_object_pars);
389 :
390 : /**
391 : * Add a Tally object using the tally system.
392 : * @param[in] type the new tally type
393 : * @param[in] name the name of the new tally
394 : * @param[in] moose_object_pars the input parameters of the new tally
395 : */
396 : void
397 : addTally(const std::string & type, const std::string & name, InputParameters & moose_object_pars);
398 :
399 : /**
400 : * Multiplier on the normalized tally results; for fixed source runs,
401 : * we multiply the tally (which has units of eV/source)
402 : * by the source strength and the eV to joule conversion, while for k-eigenvalue runs, we
403 : * multiply the normalized tally (which is unitless and has an integral
404 : * value of 1.0) by the power.
405 : * @param[in] global_score tally score
406 : */
407 : Real tallyMultiplier(unsigned int global_score) const;
408 :
409 : /**
410 : * Check whether a vector extracted with getParam is empty
411 : * @param[in] vector vector
412 : * @param[in] name name to use for printing error if empty
413 : */
414 : template <typename T>
415 4600 : void checkEmptyVector(const std::vector<T> & vector, const std::string & name) const
416 : {
417 4484 : if (vector.empty())
418 8 : mooseError(name + " cannot be empty!");
419 4592 : }
420 :
421 3606 : int fixedPointIteration() const { return _fixed_point_iteration; }
422 :
423 : /**
424 : * Checks if the problem uses adaptivity or not.
425 : * @return if the problem uses adaptivity.
426 : */
427 2567 : bool hasAdaptivity() const { return _has_adaptivity; }
428 :
429 : /// Constant flag to indicate that a cell/element was unmapped
430 : static constexpr int32_t UNMAPPED{-1};
431 :
432 : /// Spatial dimension of the Monte Carlo problem
433 : static constexpr int DIMENSION{3};
434 :
435 : /// Get a modifyable non-const reference to the Moose mesh
436 : virtual MooseMesh & getMooseMesh();
437 :
438 : /// Get a modifyable const reference to the Moose mesh
439 : virtual const MooseMesh & getMooseMesh() const;
440 :
441 : /**
442 : * Whether a moving mesh is used
443 : * @return whether the [Mesh] is moving
444 : */
445 : const bool & useDisplaced() const { return _use_displaced; }
446 :
447 : protected:
448 : /**
449 : * Get the cell level in OpenMC to use for coupling
450 : * @param[in] c point
451 : * @return cell level
452 : */
453 : unsigned int getCellLevel(const Point & c) const;
454 :
455 : /**
456 : * Read the names of the MOOSE variables used for sending feedback into OpenMC
457 : * @param[in] param feedback term to read
458 : * @param[in] default_name default name to use for MOOSE variables holding this field
459 : * @param[out] vars_to_specified_blocks map from MOOSE variable names to the blocks on which they
460 : * are defined
461 : * @param[out] specified_blocks user-specified blocks for feedback
462 : */
463 : void
464 : readBlockVariables(const std::string & param,
465 : const std::string & default_name,
466 : std::map<std::string, std::vector<SubdomainName>> & vars_to_specified_blocks,
467 : std::vector<SubdomainID> & specified_blocks);
468 :
469 : /**
470 : * Whether this cell has an identical fill
471 : * @param[in] cell_info cell index, instance pair
472 : * @return whether this cell has an identical fill
473 : */
474 : bool cellHasIdenticalFill(const cellInfo & cell_info) const;
475 :
476 : /**
477 : * When using the 'identical_cell_fills' feature, this is used to determine the
478 : * contained material cells in each parent cell by applying a uniform shift
479 : * @param[in] cell_info cell index, instance pair
480 : * @return material cells contained within the given cell
481 : */
482 : containedCells shiftCellInstances(const cellInfo & cell_info) const;
483 :
484 : /**
485 : * Whether this cell overlaps with ANY value in the given subdomain set
486 : * @param[in] cell_info cell index, instance pair
487 : * @param[in] id subdomain IDs
488 : * @return whether the cell overlaps with the subdomain
489 : */
490 : bool cellMapsToSubdomain(const cellInfo & cell_info,
491 : const std::unordered_set<SubdomainID> & id) const;
492 :
493 : /**
494 : * Get the first material cell contained in the given cell
495 : * @param[in] cell_info cell index, instance pair
496 : * @return material cell index, instance pair
497 : */
498 : cellInfo firstContainedMaterialCell(const cellInfo & cell_info) const;
499 :
500 : /**
501 : * Get all of the material cells contained within this cell
502 : * @param[in] cell_info cell index, instance pair
503 : * @return all material cells contained in the given cell
504 : */
505 : containedCells containedMaterialCells(const cellInfo & cell_info) const;
506 :
507 : /**
508 : * Delete the OpenMC DAGMC geometry and re-generate the CSG geometry data structures in-place.
509 : */
510 : void updateOpenMCGeometry();
511 :
512 : /**
513 : * Get a list of each material in the problem, sorted by subdomain. This function also checks
514 : * that there is just one OpenMC material in each subdomain, necessary for the DAGMC skinning.
515 : * @return material in each subdomain
516 : */
517 : std::vector<std::string> getMaterialInEachSubdomain() const;
518 :
519 : /**
520 : * Apply transformations and scale point from MOOSE into the OpenMC domain
521 : * @param[in] pt point
522 : * @return transformed point
523 : */
524 : Point transformPointToOpenMC(const Point & pt) const;
525 :
526 : /**
527 : * Check that the tally normalization gives a total tally sum of 1.0 (when normalized
528 : * against the total tally value).
529 : * @param[in] sum sum of the tally
530 : * @param[in] score tally score
531 : */
532 : void checkNormalization(const Real & sum, unsigned int global_score) const;
533 :
534 : /**
535 : * For geometries with fine-scale details (e.g. TRISO), Cardinal's default settings can
536 : * take a very long time to initialize the problem (but we can't change those defaults
537 : * because they are not 100% applicable all the time). So, we print out a message to
538 : * the user to point them in the right direction if their initialization is taking a
539 : * long time.
540 : * @param[in] start time to use for evaluating whether we've exceeded our limit for printing the
541 : * message
542 : */
543 : void
544 : printTrisoHelp(const std::chrono::time_point<std::chrono::high_resolution_clock> & start) const;
545 :
546 : /**
547 : * Print to the console the names of the auxvariables used for I/O with OpenMC.
548 : * We only print these tables once, upon initialization, because this data does
549 : * not change if re-initializing the spatial mapping for moving-mesh problems,
550 : * adaptive refinement, skinning, etc.
551 : */
552 : void printAuxVariableIO();
553 :
554 : /**
555 : * Get all the material indices within the set of cells
556 : * @param[in] contained_cells set of cells
557 : * @return contained materials
558 : */
559 : std::vector<int32_t> materialsInCells(const containedCells & contained_cells) const;
560 :
561 : /// Loop over the mapped cells, and build a map between subdomains to OpenMC materials
562 : void subdomainsToMaterials();
563 :
564 : /**
565 : * Get a set of all subdomains that have at least 1 element coupled to an OpenMC cell
566 : * @return subdomains with at least 1 element coupled to OpenMC
567 : */
568 : std::set<SubdomainID> coupledSubdomains() const;
569 :
570 : /**
571 : * Gather a vector of values to be summed for each cell
572 : * @param[in] local local values to be summed for the cells
573 : * @param[out] global global mapping of the summed values to the cells
574 : */
575 : template <typename T>
576 : void gatherCellSum(std::vector<T> & local, std::map<cellInfo, T> & global) const;
577 :
578 : /**
579 : * Gather a vector of values to be pushed back to for each cell
580 : * @param[in] local local values to be pushed back for the cells
581 : * @param[in] n_local number of local values contributed to each cell
582 : * @param[out] global global mapping of the pushed back values to the cells
583 : */
584 : template <typename T>
585 : void gatherCellVector(std::vector<T> & local, std::vector<unsigned int> & n_local, std::map<cellInfo, std::vector<T>> & global);
586 :
587 : /**
588 : * Get the feedback which this element provides to OpenMC
589 : * @param[in] elem
590 : * @return coupling phase
591 : */
592 : coupling::CouplingFields elemFeedback(const Elem * elem) const;
593 :
594 : /**
595 : * Read the parameters needed for triggers
596 : * @param[in] params input parameters
597 : */
598 : void getTallyTriggerParameters(const InputParameters & params);
599 :
600 : /**
601 : * Read the block parameters based on user settings
602 : * @param[in] name name of input parameter representing a vector of subdomain names
603 : * @param[in] blocks list of block ids to write
604 : */
605 : void readBlockParameters(const std::string name, std::unordered_set<SubdomainID> & blocks);
606 :
607 : /**
608 : * Cache the material cells contained within each coupling cell;
609 : * depending on user settings, this may attempt to take shortcuts
610 : * by assuming each cell has the same fills
611 : */
612 : void cacheContainedCells();
613 :
614 : /**
615 : * Fill the cached contained cells data structure for a given cell
616 : * @param[in] cell_info cell index, instance pair
617 : * @param[in] hint location hint used to accelerate the search
618 : * @param[out] map contained cell map
619 : */
620 : void setContainedCells(const cellInfo & cell_info,
621 : const Point & hint,
622 : std::map<cellInfo, containedCells> & map);
623 :
624 : /**
625 : * Check that the structure of the contained material cells for two cell matches;
626 : * i.e. this checks that the keys are the same and that the *number* of instances
627 : * of each filling material cell match.
628 : * @param[in] cell_info cell index, instance pair
629 : * @param[in] reference map we want to check against
630 : * @param[in] compare map we want to check
631 : */
632 : void checkContainedCellsStructure(const cellInfo & cell_info,
633 : containedCells & reference,
634 : containedCells & compare) const;
635 :
636 : /**
637 : * Set a minimum order for a volume quadrature rule
638 : * @param[in] volume_order order of the volume quadrature rule
639 : * @param[in] type string type of quadrature rule for printing a console message
640 : */
641 : void setMinimumVolumeQRules(Order & volume_order, const std::string & type);
642 :
643 : /// For keeping the output neat when using verbose
644 : std::string printNewline() const
645 : {
646 : if (_verbose)
647 : return "\n";
648 : else
649 : return "";
650 : }
651 :
652 : /// Loop over the elements in the MOOSE mesh and store the type of feedback applied by each.
653 : void storeElementPhase();
654 :
655 : /**
656 : * Relax the tally and normalize it according to some "global" tally. If you set
657 : * 'normalize_by_global_tally = true', you will be normalizing by a tally over the ENTIRE
658 : * OpenMC geometry. Otherwise, you normalize only by the sum of the tally bins themselves.
659 : *
660 : * NOTE: This function relaxes the tally _distribution_, and not the actual magnitude of the sum.
661 : * That is, we relax the shape distribution and then multiply it by the power
662 : * (for k-eigenvalue) or source strength (for fixed source) of the current step before
663 : * applying it to MOOSE. If the magnitude of the power or source strength is constant in time,
664 : * there is zero error in this. But if the magnitude of the tally varies in time, we are basically
665 : * relaxing the distribution of the tally, but then multiplying it by the _current_ mean tally
666 : * magnitude.
667 : *
668 : * There will be very small errors in these approximations unless the power/source strength
669 : * change dramatically with iteration. But because relaxation is itself a numerical approximation,
670 : * this is still inconsequential at the end of the day as long as your problem has converged
671 : * the relaxed tally to the raw (unrelaxed) tally.
672 : * @param[in] global_score the global index of the tally score
673 : * @param[in] local_score the local index of the tally score
674 : * @param[in] local_tally the tally to relax and normalize
675 : */
676 : void relaxAndNormalizeTally(unsigned int global_score,
677 : unsigned int local_score,
678 : std::shared_ptr<TallyBase> local_tally);
679 :
680 : /**
681 : * Loop over all the OpenMC cells and count the number of MOOSE elements to which the cell
682 : * is mapped based on phase.
683 : */
684 : void getCellMappedPhase();
685 :
686 : /// This function is used to ensure that each OpenMC cell only maps to a single phase
687 : void checkCellMappedPhase();
688 :
689 : /// Loop over all the OpenMC cells and get the element subdomain IDs that map to each cell
690 : void getCellMappedSubdomains();
691 :
692 : /**
693 : * Loop over all the OpenMC cells and compute the volume of the MOOSE elements that each
694 : * cell maps to
695 : */
696 : void computeCellMappedVolumes();
697 :
698 : /// Set up the mapping from MOOSE elements to OpenMC cells
699 : void initializeElementToCellMapping();
700 :
701 : /// Populate maps of MOOSE elements to OpenMC cells
702 : void mapElemsToCells();
703 :
704 : /**
705 : * A function which validates local tallies. This is done to ensure that at least one of the
706 : * tallies contains a heating score when running in eigenvalue mode. This must be done outside
707 : * of the constructor as tallies are added from an external system.
708 : */
709 : void validateLocalTallies();
710 :
711 : /// Add OpenMC tallies to facilitate the coupling
712 : void initializeTallies();
713 :
714 : /**
715 : * Reset any tallies previously added by Cardinal, by deleting them from OpenMC.
716 : * Also delete any mesh filters and meshes added to OpenMC for mesh filters.
717 : */
718 : void resetTallies();
719 :
720 : /// Find the material filling each cell which receives density feedback
721 : void getMaterialFills();
722 :
723 : /**
724 : * Get one point inside each cell, for accelerating the particle search routine.
725 : * This function will get the centroid of the first global element in the lowest
726 : * rank in the cell.
727 : */
728 : void getPointInCell();
729 :
730 : /**
731 : * Compute the product of volume with a field across ranks and sum into a global map
732 : * @param[in] var_num variable to weight with volume, mapped by subdomain ID
733 : * @param[in] phase phases to compute the operation for
734 : * @return volume-weighted field for each cell, in a global sense
735 : */
736 : std::map<cellInfo, Real> computeVolumeWeightedCellInput(
737 : const std::map<SubdomainID, std::pair<unsigned int, std::string>> & var_num,
738 : const std::vector<coupling::CouplingFields> * phase) const;
739 :
740 : /**
741 : * Send temperature from MOOSE to OpenMC by computing a volume average
742 : * and applying a single temperature per OpenMC cell
743 : */
744 : void sendTemperatureToOpenMC() const;
745 :
746 : /**
747 : * Send density from MOOSE to OpenMC by computing a volume average
748 : * and applying a single density per OpenMC cell.
749 : */
750 : void sendDensityToOpenMC() const;
751 :
752 : /**
753 : * Factor by which to normalize a tally
754 : * @param[in] global_score global index for the tally score
755 : * @return value to divide tally sum by for normalization
756 : */
757 : Real tallyNormalization(unsigned int global_score) const;
758 :
759 : /**
760 : * Check the sum of the tallies against the global tally
761 : * @param[in] score tally score
762 : */
763 : void checkTallySum(const unsigned int & score) const;
764 :
765 : /**
766 : * Check if a mapped location is in the outer universe of a lattice
767 : * @param[in] level lattice level
768 : * @return whether the location is in the outer universe
769 : */
770 : void latticeOuterCheck(const Point & c, int level) const;
771 :
772 : /**
773 : * Report an error for a mapped location in an outer universe of a lattice
774 : * @param[in] c Mapped location
775 : * @param[in] level level of the mapped cell
776 : */
777 : void latticeOuterError(const Point & c, int level) const;
778 :
779 : /**
780 : * Find the OpenMC cell at a given point in space
781 : * @param[in] point point
782 : * @return whether OpenMC reported an error
783 : */
784 : bool findCell(const Point & point);
785 :
786 : /**
787 : * Checks that the contained material cells exactly match between a reference obtained
788 : * by calling openmc::Cell::get_contained_cells for each cell and a shortcut
789 : * approach that assumes all identical cells (which aren't simply just material fills)
790 : * has exactly the same contained material cells.
791 : * @param[in] reference reference map to compare against
792 : * @param[in] compare shortcut map to compare
793 : */
794 : void compareContainedCells(std::map<cellInfo, containedCells> & reference,
795 : std::map<cellInfo, containedCells> & compare) const;
796 :
797 : NumericVector<Number> & _serialized_solution;
798 :
799 : /**
800 : * Return all IDs of all Cardinal-mapped Tallies
801 : * @return all Cardinal-mapped Tally IDs
802 : */
803 : virtual std::vector<int32_t> getMappedTallyIDs() const override;
804 :
805 : /**
806 : * Whether to automatically compute the mapping of OpenMC cell IDs and
807 : * instances to the [Mesh].
808 : */
809 : const bool & _output_cell_mapping;
810 :
811 : /**
812 : * Where to get the initial OpenMC temperatures and densities from;
813 : * can be either hdf5 (from a properties.h5 file), xml (whatever is already
814 : * set in the XML files), or moose (meaning whatever ICs are set on the 'temperature_variables'
815 : * and 'density_variables'
816 : */
817 : const coupling::OpenMCInitialCondition _initial_condition;
818 :
819 : /// Type of relaxation to apply to the OpenMC tallies
820 : const relaxation::RelaxationEnum _relaxation;
821 :
822 : /**
823 : * Type of trigger to apply to k eigenvalue to indicate when
824 : * the simulation is complete. These can be used to on-the-fly adjust the number
825 : * of active batches in order to reach some desired criteria (which is specified
826 : * by this parameter).
827 : */
828 : const trigger::TallyTriggerTypeEnum _k_trigger;
829 :
830 : /**
831 : * Coordinate level in the OpenMC domain to use for mapping cells to mesh.
832 : * When using 'lowest_cell_level', this parameter indicates that the lowest
833 : * cell level is used, up until _cell_level.
834 : */
835 : unsigned int _cell_level;
836 :
837 : /**
838 : * Whether OpenMC properties (temperature and density) should be exported
839 : * after being updated in syncSolutions.
840 : */
841 : const bool & _export_properties;
842 :
843 : /**
844 : * How to normalize the OpenMC tally into units of W/volume. If 'true',
845 : * normalization is performed by dividing each local tally against a problem-global
846 : * tally. The advantage of this approach is that some non-zero tally regions of the
847 : * OpenMC domain can be excluded from multiphysics feedback (without us having to guess
848 : * what the power of the *included* part of the domain is). This can let us do
849 : * "zooming" type calculations, where perhaps we only want to send T/H feedback to
850 : * one bundle in a full core.
851 : *
852 : * If 'false', normalization is performed by dividing each local tally by the sum
853 : * of the local tally itself. The advantage of this approach becomes evident when
854 : * using mesh tallies. If a mesh tally does not perfectly align with an OpenMC cell -
855 : * for instance, a first-order sphere mesh will not perfectly match the volume of a
856 : * TRISO pebble - then not all of the power actually produced in the pebble is
857 : * tallies on the mesh approximation to that pebble. Therefore, if you set a core
858 : * power of 1 MW and you normalized based on a global tally, you'd always
859 : * miss some of that power when sending to MOOSE. So, in this case, it is better to
860 : * normalize against the local tally itself so that the correct power is preserved.
861 : */
862 : const bool _normalize_by_global;
863 :
864 : /// Whether or not the problem uses a skinner to regenerate the OpenMC geometry.
865 : const bool _using_skinner;
866 :
867 : /**
868 : * When the mesh changes during the simulation (either from adaptive mesh refinement
869 : * or deformation), the mapping from OpenMC cells to the [Mesh] must be re-established
870 : * after each OpenMC run.
871 : */
872 : bool _need_to_reinit_coupling;
873 :
874 : /**
875 : * Whether to check the tallies against the global tally;
876 : * if set to true, and the tallies added for the 'tally_blocks' do not
877 : * sum to the global tally, an error is thrown. If you are
878 : * only performing multiphysics feedback for, say, a single assembly in a
879 : * full-core OpenMC model, you must set this check to false, because there
880 : * are known fission sources outside the domain of interest.
881 : *
882 : * If not specified, then this is set to 'true' if normalizing by a global
883 : * tally, and to 'false' if normalizing by the local tally (because when we choose
884 : * to normalize by the local tally, we're probably using mesh tallies). But you can
885 : * of course still set a value for this parameter to override the default.
886 : */
887 : const bool _check_tally_sum;
888 :
889 : /// Constant relaxation factor
890 : const Real & _relaxation_factor;
891 :
892 : /**
893 : * If known a priori by the user, whether the tally cells (which are not simply material
894 : * fills) have EXACTLY the same contained material cells. This is a big optimization for
895 : * TRISO problems in setting up homogenized temperature/density feedback to OpenMC.
896 : *
897 : * The concept can best be explained with a pebble bed reactor.
898 : * If every pebble is filled with an identical TRISO universe, then the material fills
899 : * in each pebble are identical to one another except for a constant offset. This idea
900 : * can be used to then skip all but the first two openmc::Cell::get_contained_cells
901 : * calls (which are required in order to figure out the pattern by which pebble N is
902 : * incremented relative to pebble 1).
903 : *
904 : * When using this parameter, we HIGHLY recommend setting 'check_identical_cell_fills =
905 : * true' the first time you run your model. This will figure out the material cell fills using a
906 : * method that calls openmc::Cell::get_contained_cells for every tally cell, i.e. without assuming
907 : * anything about repeated structure in your OpenMC model. Setting 'identical_cell_fills'
908 : * without also setting 'check_identical_cell_fills = true' may result in SILENT
909 : * errors!!! So it is essential to be sure you've removed any error sources before you turn the
910 : * error check off to actually leverage the speedup.
911 : *
912 : * Note: for any tally cells that are just filled with a material, we use the approach
913 : * where openmc::Cell::get_contained_cells is called in full.
914 : *
915 : * This optimization will not work (and 'check_identical_cell_fills = true' *will*
916 : * catch these) for:
917 : * - any situation where tallied, non-material-fill pebbles have different fills
918 : * (such as if you have different TRISO lattices in each pebble)
919 : * - any situation where there is a "gap" in the incrementing of the material fill
920 : * instances (such as if pebble 89 does not map to 'tally_blocks', then the instance
921 : * shift for pebble 90 relative to pebble 1 is 89, when it should have been 90).
922 : */
923 : const bool _has_identical_cell_fills;
924 :
925 : /**
926 : * Whether we should rigorously check that each tally cell has identical fills;
927 : * this is SLOW for large TRISO problems, but is essential to ensure the accuracy of
928 : * 'identical_cell_fills'. Please set 'check_identical_cell_fills' to 'true' at least
929 : * once before running production cases to be sure the optimization can be applied.
930 : */
931 : const bool & _check_identical_cell_fills;
932 :
933 : /**
934 : * Whether it can be assumed that all of the tallies (both those set by the user
935 : * in the XML file, as well as those created automatically by Cardinal) are
936 : * spatially separate. This means that once a particle scores to one tally bin, it wouldn't
937 : * score to ANY other tally bins. This can dramatically increase tracking rates
938 : * for problems with many tallies.
939 : */
940 : const bool & _assume_separate_tallies;
941 :
942 : /**
943 : * Whether to map density according to each individual OpenMC cell (in which case an
944 : * error is thrown if you don't have a unique material in each cell) or by material.
945 : */
946 : bool _map_density_by_cell;
947 :
948 : /**
949 : * Whether the problem has density feedback blocks specified; note that this is NOT necessarily
950 : * indicative that the mapping was successful in finding any cells corresponding to those blocks
951 : */
952 : const bool _specified_density_feedback;
953 :
954 : /**
955 : * Whether the problem has temperature feedback blocks specified; note that this is NOT
956 : * necessarily indicative that the mapping was successful in finding any cells corresponding to
957 : * those blocks
958 : */
959 : const bool _specified_temperature_feedback;
960 :
961 : /// Whether any cell tallies exist.
962 : bool _has_cell_tallies = false;
963 :
964 : /// Whether any spatial mapping from OpenMC's cells to the mesh is needed
965 : bool _needs_to_map_cells;
966 :
967 : /**
968 : * Whether a global tally is required for the sake of normalization and/or checking
969 : * the tally sum
970 : */
971 : const bool _needs_global_tally;
972 :
973 : /**
974 : * A map of the filter objects created by the [Problem/Filters] block. The key for each filter is
975 : * it's corresponding MOOSE name to allow tallies to look up filters.
976 : */
977 : std::map<std::string, std::shared_ptr<FilterBase>> _filters;
978 :
979 : /// A vector of the tally objects created by the [Problem/Tallies] block.
980 : std::vector<std::shared_ptr<TallyBase>> _local_tallies;
981 :
982 : /// A list of all of the scores contained by the local tallies added in the [Tallies] block.
983 : std::vector<std::string> _all_tally_scores;
984 :
985 : /**
986 : * The [Tallies] block allows tallies with different scores, and so we can't assume they have the
987 : * same indices in each tally's arrays. This variable map between the name of each score and it's
988 : * index in each local tally.
989 : */
990 : std::vector<std::map<std::string, int>> _local_tally_score_map;
991 :
992 : /// A vector of auxvariable ids added by the [Tallies] block.
993 : std::vector<std::vector<unsigned int>> _tally_var_ids;
994 :
995 : /// A vector of external (output-based) auxvariable ids added by the [Tallies] block.
996 : std::vector<std::vector<std::vector<unsigned int>>> _tally_ext_var_ids;
997 :
998 : /// Blocks in MOOSE mesh that provide density feedback
999 : std::vector<SubdomainID> _density_blocks;
1000 :
1001 : /// Blocks in MOOSE mesh that provide temperature feedback
1002 : std::vector<SubdomainID> _temp_blocks;
1003 :
1004 : /// Blocks for which the cell fills are identical
1005 : std::unordered_set<SubdomainID> _identical_cell_fill_blocks;
1006 :
1007 : /// Mapping of MOOSE elements to the OpenMC cell they map to (if any)
1008 : std::vector<cellInfo> _elem_to_cell{};
1009 :
1010 : /// Phase of each cell
1011 : std::map<cellInfo, coupling::CouplingFields> _cell_phase;
1012 :
1013 : /// Number of elements in the MOOSE mesh that exclusively provide density feedback
1014 : int _n_moose_density_elems;
1015 :
1016 : /// Number of elements in the MOOSE mesh that exclusively provide temperature feedback
1017 : int _n_moose_temp_elems;
1018 :
1019 : /// Number of elements in the MOOSE mesh which provide temperature+density feedback
1020 : int _n_moose_temp_density_elems;
1021 :
1022 : /// Number of no-coupling elements in the MOOSE mesh
1023 : int _n_moose_none_elems;
1024 :
1025 : /**
1026 : * Number of MOOSE elements that exclusively provide temperature feedback,
1027 : * and which successfully mapped to OpenMC cells
1028 : */
1029 : int _n_mapped_temp_elems;
1030 :
1031 : /**
1032 : * Number of MOOSE elements that exclusively provide density feedback,
1033 : * and which successfully mapped to OpenMC cells
1034 : */
1035 : int _n_mapped_density_elems;
1036 :
1037 : /**
1038 : * Number of MOOSE elements that provide temperature+density feedback,
1039 : * and which successfully mapped to OpenMC cells
1040 : */
1041 : int _n_mapped_temp_density_elems;
1042 :
1043 : /// Number of no-coupling elements mapped to OpenMC cells
1044 : int _n_mapped_none_elems;
1045 :
1046 : /// Total volume of uncoupled MOOSE mesh elements
1047 : Real _uncoupled_volume;
1048 :
1049 : /// Whether non-material cells are mapped
1050 : bool _material_cells_only{true};
1051 :
1052 : /// Mapping of OpenMC cell indices to a vector of MOOSE element IDs
1053 : std::map<cellInfo, std::vector<unsigned int>> _cell_to_elem;
1054 :
1055 : /// Mapping of OpenMC cell indices to a vector of MOOSE element IDs, on each local rank
1056 : std::map<cellInfo, std::vector<unsigned int>> _local_cell_to_elem;
1057 :
1058 : /// Mapping of OpenMC cell indices to the subdomain IDs each maps to
1059 : std::map<cellInfo, std::unordered_set<SubdomainID>> _cell_to_elem_subdomain;
1060 :
1061 : /// Mapping of elem subdomains to materials
1062 : std::map<SubdomainID, std::set<int32_t>> _subdomain_to_material;
1063 :
1064 : /**
1065 : * A point inside the cell, taken simply as the centroid of the first global
1066 : * element inside the cell. This is stored to accelerate the particle search.
1067 : */
1068 : std::map<cellInfo, Point> _cell_to_point;
1069 :
1070 : /**
1071 : * Volume associated with the mapped element space for each OpenMC cell; the unit
1072 : * for this volume is whatever is used in the [Mesh] block
1073 : */
1074 : std::map<cellInfo, Real> _cell_to_elem_volume;
1075 :
1076 : /**
1077 : * Volume associated with the actual OpenMC cell, computed by an optional
1078 : * OpenMCVolumeCalculation user object
1079 : */
1080 : std::map<cellInfo, Real> _cell_volume;
1081 :
1082 : /**
1083 : * Material filling each cell to receive density feedback. We enforce that these
1084 : * cells are filled with a material (cannot be filled with a lattice or universe).
1085 : */
1086 : std::map<cellInfo, int32_t> _cell_to_material;
1087 :
1088 : /**
1089 : * Material-type cells contained within a cell; this is only populated if a cell
1090 : * is NOT indicated as having an identical fill
1091 : */
1092 : std::map<cellInfo, containedCells> _cell_to_contained_material_cells;
1093 :
1094 : /// Number of material-type cells contained within a cell
1095 : std::map<cellInfo, int32_t> _cell_to_n_contained;
1096 :
1097 : /**
1098 : * Global tallies. We add one per tally added in the [Tallies] block to
1099 : * enable global noramlization.
1100 : */
1101 : std::vector<openmc::Tally *> _global_tallies;
1102 :
1103 : /// Global tally scores corresponding to '_global_tallies'.
1104 : std::vector<std::vector<std::string>> _global_tally_scores;
1105 :
1106 : /// Global tally estimators corresponding to '_global_tallies'.
1107 : std::vector<openmc::TallyEstimator> _global_tally_estimators;
1108 :
1109 : /// Sum value of the global tally(s), across all bins
1110 : std::vector<Real> _global_sum_tally;
1111 :
1112 : /// Sum value of the local tally(s), across all bins
1113 : std::vector<Real> _local_sum_tally;
1114 :
1115 : /// Mean value of the local tally(s), across all bins; only used for fixed source mode
1116 : std::vector<Real> _local_mean_tally;
1117 :
1118 : /// Whether the present transfer is the first transfer
1119 : static bool _first_transfer;
1120 :
1121 : /// Whether the diagnostic tables on initialization have already been printed
1122 : static bool _printed_initial;
1123 :
1124 : /// Whether a warning has already been printed about very long setup times (for TRISOs)
1125 : static bool _printed_triso_warning;
1126 :
1127 : /// Dummy particle to reduce number of allocations of particles for cell lookup routines
1128 : openmc::Particle _particle;
1129 :
1130 : /// Number of particles simulated in the first iteration
1131 : unsigned int _n_particles_1;
1132 :
1133 : /// Mapping from temperature variable name to the subdomains on which to read it from
1134 : std::map<std::string, std::vector<SubdomainName>> _temp_vars_to_blocks;
1135 :
1136 : /// Mapping from density variable name to the subdomains on which to read it from
1137 : std::map<std::string, std::vector<SubdomainName>> _density_vars_to_blocks;
1138 :
1139 : /// Optional volume calculation for cells which map to MOOSE
1140 : OpenMCVolumeCalculation * _volume_calc;
1141 :
1142 : /// Userobject that maps from a partial-symmetry OpenMC model to a whole-domain [Mesh]
1143 : const SymmetryPointGenerator * _symmetry;
1144 :
1145 : /// Number of temperature-only feedback elements in each mapped OpenMC cell (global)
1146 : std::map<cellInfo, int> _n_temp;
1147 :
1148 : /// Number of density-only feedback elements in each mapped OpenMC cell (global)
1149 : std::map<cellInfo, int> _n_rho;
1150 :
1151 : /// Number of temperature+density feedback elements in each mapped OpenMC cell (global)
1152 : std::map<cellInfo, int> _n_temp_rho;
1153 :
1154 : /// Number of none elements in each mapped OpenMC cell (global)
1155 : std::map<cellInfo, int> _n_none;
1156 :
1157 : /// Index in OpenMC tallies corresponding to the first global tally added by Cardinal
1158 : unsigned int _global_tally_index = 0;
1159 :
1160 : /// Index in tally_score pointing to the score used for normalizing flux tallies in eigenvalue mode
1161 : unsigned int _source_rate_index;
1162 :
1163 : #ifdef ENABLE_DAGMC
1164 : /// Optional skinner to re-generate the OpenMC geometry on-the-fly for DAGMC models
1165 : MoabSkinner * _skinner = nullptr;
1166 :
1167 : /// Pointer to DAGMC
1168 : std::shared_ptr<moab::DagMC> _dagmc = nullptr;
1169 : #endif
1170 :
1171 : /// Total number of unique OpenMC cell IDs + instances combinations
1172 : long unsigned int _n_openmc_cells;
1173 :
1174 : /// ID of the OpenMC universe corresponding to the DAGMC universe
1175 : int32_t _dagmc_universe_id;
1176 :
1177 : /// Whether the DAGMC universe is the root universe or not.
1178 : bool _dagmc_root_universe = true;
1179 :
1180 : /// ID of the OpenMC cell corresponding to the cell which uses the DAGMC universe as a fill.
1181 : int32_t _cell_using_dagmc_universe_id;
1182 :
1183 : /// The number of OpenMC surfaces before skinning occurs. This is required to properly reinitialize
1184 : /// the CSG geometry contained in the OpenMC model.
1185 : const int32_t _initial_num_openmc_surfaces;
1186 :
1187 : /// Conversion rate from eV to Joule
1188 : static constexpr Real EV_TO_JOULE = 1.6022e-19;
1189 :
1190 : /// Tolerance for setting zero tally
1191 : static constexpr Real ZERO_TALLY_THRESHOLD = 1e-12;
1192 :
1193 : private:
1194 : /**
1195 : * Update the number of particles according to the Dufek-Gudowski relaxation scheme
1196 : */
1197 : void dufekGudowskiParticleUpdate();
1198 :
1199 : /// Flattened cell IDs collected after parallel communication
1200 : std::vector<int32_t> _flattened_ids;
1201 :
1202 : /// Flattened cell instancess collected after parallel communication
1203 : std::vector<int32_t> _flattened_instances;
1204 :
1205 : /// Offsets for each cell instance in an identically-repeated universe
1206 : containedCells _instance_offsets;
1207 :
1208 : /// Offset for each cell relative to the first identical-fill cell
1209 : std::map<cellInfo, int32_t> _n_offset;
1210 :
1211 : /// First identical-fill cell
1212 : cellInfo _first_identical_cell;
1213 :
1214 : /// Materials in the first identical-fill cell
1215 : std::vector<int32_t> _first_identical_cell_materials;
1216 :
1217 : /// Whether OpenMCCellAverageProblem should use the displaced mesh
1218 : bool _use_displaced;
1219 :
1220 : /// Mapping from subdomain IDs to which aux variable to read temperature (K) from
1221 : std::map<SubdomainID, std::pair<unsigned int, std::string>> _subdomain_to_temp_vars;
1222 :
1223 : /// Mapping from subdomain IDs to which aux variable to read density (kg/m3) from
1224 : std::map<SubdomainID, std::pair<unsigned int, std::string>> _subdomain_to_density_vars;
1225 : };
|