LCOV - code coverage report
Current view: top level - include/base - OpenMCCellAverageProblem.h (source / functions) Hit Total Coverage
Test: neams-th-coe/cardinal: faa471 Lines: 33 33 100.0 %
Date: 2026-08-05 13:00:46 Functions: 18 18 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14