diff --git a/.gitignore b/.gitignore index 0dd8647de..6ff5ad95c 100644 --- a/.gitignore +++ b/.gitignore @@ -240,6 +240,7 @@ mesh_info.i *.msh *.nek5000 *.json* +*.gz cardinal.yaml unit/cardinal-unit.yaml *.step diff --git a/doc/content/news.md b/doc/content/news.md index 3ec845c88..e349bbf87 100644 --- a/doc/content/news.md +++ b/doc/content/news.md @@ -5,6 +5,7 @@ significant changes to report. ### 2024 +- [July 2024](news/july2024.md) - [March 2024](news/march2024.md) ### 2023 diff --git a/doc/content/news/july2024.md b/doc/content/news/july2024.md new file mode 100644 index 000000000..0437bc76d --- /dev/null +++ b/doc/content/news/july2024.md @@ -0,0 +1,22 @@ +# July 2022 News + +- A new [tally system](/actions/AddTallyAction.md) and an accompanying input syntax + block have been added to Cardinal +- The tally parameters found in [OpenMCCellAverageProblem](/problems/OpenMCCellAverageProblem.md) + have been deprecated in favor of this new tally system. + + - Existing input files written with the previous tally syntax will no longer run + +The main advantages of the new tally system is the ability to add multiple tallies with different +spatial binning schemes for different scores. As an example, you can add a [CellTally](/tallies/CellTally.md) +with a heating score and a [MeshTally](/tallies/MeshTally.md) with a flux score: + +!listing actions/multi_tally_example.i + block=Problem + +Other advantages include: + +- Being able to specify tally triggers on a per-tally basis; +- The option to apply block restrictions to different [CellTally](/tallies/CellTally.md) + scores; +- Additional flexibility when it comes to adding new tally filters in the future. diff --git a/doc/content/source/actions/AddTallyAction.md b/doc/content/source/actions/AddTallyAction.md new file mode 100644 index 000000000..4e980fbc0 --- /dev/null +++ b/doc/content/source/actions/AddTallyAction.md @@ -0,0 +1,36 @@ +# AddTallyAction + +!alert note +`AddTallyAction` can only add tallies to problems which contain a [OpenMCCellAverageProblem](OpenMCCellAverageProblem.md) +in the `[Problem]` block. Otherwise, attempting to add a tally will result in an error. + +## Overview + +The `AddTallyAction` action is responsible for adding local tallies to a simulation through the +`[Tallies]` block in a Cardinal input file. + +For all requested tallies other than unstructured mesh tallies, a single tally object is added +per sub-block in `[Tallies]`. When an unstructured mesh tally is requested `N` tally objects +will be added, where `N` is the number of positions in `mesh_translations` / the number of positions +in the file named `mesh_translations_file`. These translated mesh tallies store their scores in the +same auxvariable(s), and the tally scores are normalized by the sum over all bins in the associated +[OpenMCCellAverageProblem](OpenMCCellAverageProblem.md). `mesh_translations` and +`mesh_translations_file` are only applicable to [MeshTally](MeshTally.md) objects. + +## Example Input File Syntax + +An example where multiple unstructured mesh tallies are added can be found below. `AddTallyAction`adds +three mesh tallies, where each tally has one of the positions listed in the file named `mesh_translations_file`. + +!listing /tutorials/pebbles/openmc_um.i + block=Problem + +An example of adding non-translated tallies can be found below, where both a [CellTally](CellTally.md) +and [MeshTally](MeshTally.md) are added to the problem. + +!listing /multi_tally_example.i + block=Problem + +!syntax list /Problem/Tallies actions=false subsystems=false heading=Available Tally Objects + +!syntax parameters /Problem/Tallies/AddTallyAction diff --git a/doc/content/source/actions/multi_tally_example.i b/doc/content/source/actions/multi_tally_example.i new file mode 100644 index 000000000..02aac1b5c --- /dev/null +++ b/doc/content/source/actions/multi_tally_example.i @@ -0,0 +1,43 @@ +[Mesh] + [sphere] + type = FileMeshGenerator + file = mesh_in.e + [] +[] + +[Problem] + type = OpenMCCellAverageProblem + particles = 10000 + inactive_batches = 100 + batches = 1000 + initial_properties = xml + verbose = true + cell_level = 0 + + normalize_by_global_tally = true + check_tally_sum = true + + power = 100.0 + + source_rate_normalization = 'heating_local' + + [Tallies] + [Mesh_Tally] + type = MeshTally + score = 'flux' + [] + [Cell_Tally] + type = CellTally + score = 'heating_local' + [] + [] +[] + +[Executioner] + type = Steady +[] + +[Outputs] + execute_on = final + exodus = true +[] diff --git a/doc/content/source/problems/OpenMCCellAverageProblem.md b/doc/content/source/problems/OpenMCCellAverageProblem.md index f02b720f7..25fc3146c 100644 --- a/doc/content/source/problems/OpenMCCellAverageProblem.md +++ b/doc/content/source/problems/OpenMCCellAverageProblem.md @@ -7,7 +7,7 @@ The data flow contains two major steps: - Temperature and/or density field data on the [MooseMesh](https://mooseframework.inl.gov/source/mesh/MooseMesh.html) are volume-averaged and applied to the corresponding OpenMC cells. - Tallies are mapped from OpenMC into `CONSTANT MONOMIAL` fields on the - [MooseMesh](https://mooseframework.inl.gov/source/mesh/MooseMesh.html). + [MooseMesh](https://mooseframework.inl.gov/source/mesh/MooseMesh.html) through the [tally system](AddTallyAction.md). The smallest possible input file to run OpenMC is shown below. This page describes this syntax, plus more advanced settings. @@ -24,7 +24,7 @@ to communicate OpenMC's solution with MOOSE. These variables will be viewable in the MOOSE output files (e.g., via Paraview). Depending on the user settings, the following `CONSTANT MONOMIAL` variables will be added: -- Variable(s) representing the OpenMC tally(s) +- Variable(s) representing the OpenMC tally(s) added by the `[Tallies]` block - Variable(s) representing the temperature to read into OpenMC. Temperature will be read from the mesh subdomains indicated by `temperature_blocks`. - Variable(s) representing the density to read into OpenMC. Density will be read @@ -34,8 +34,9 @@ Depending on the user settings, the following `CONSTANT MONOMIAL` variables will !alert tip These variables have default names, but you can also control their names using the -`temperature_variables`, `density_variables`, and `tally_name` parameters. If you want -to see the names, run with `verbose = true` and tables will print out on initialization +`temperature_variables`, and `density_variables` parameters. The names of the tally variables +can be customized with the `tally_name` parameter in each [tally object](AddTallyAction.md). +If you want to see the names, run with `verbose = true` and tables will print out on initialization with this information. !alert note @@ -59,8 +60,13 @@ a variable named `nek_temp` in the `helium` block (and so on for density). density_variables = 'rho_water; rho_helium' density_blocks = 'water; helium' - tally_score = 'heating flux' - tally_name = 'power openmc_flux' + [Tallies] + [cell_tally] + type = CellTally + score = 'heating flux' + name = 'power openmc_flux' + [] + [] [] ``` @@ -114,7 +120,13 @@ on defaults; we would set our `[Problem]` block as: type = OpenMCCellAverageProblem density_blocks = 'water helium' temperature_blocks = 'fuel cladding water helium' - tally_score = 'heating flux' + + [Tallies] + [cell_tally] + type = CellTally + score = 'heating flux' + [] + [] [] ``` @@ -284,20 +296,20 @@ regions where there are no cells at that level. ## Adding Tallies -This class automatically creates tallies with scores specified by the user. There -are two spatial options, controlled by `tally_type`: +This class takes the tally objects initialized by the `[Tallies]` block and use them to construct +tally auxvariables. At the moment there are two options for discretizing tallies spatially in Cardinal: -1. cell tallies -2. libMesh unstructured mesh tallies +1. cell tallies ([CellTally](CellTally.md)) +2. libMesh unstructured mesh tallies ([MeshTally](MeshTally.md)) -The tally is normalized according to the specified `power` or `source_strength` -(depending on whether you are running a $k$-eigenvalue or fixed-source problem). By default, -the normalization is done against a global tally added over the entire -OpenMC domain. By setting `normalize_by_global_tally` to false, however, the tally is instead -normalized by the sum of the tally itself. +If no tallies are specified by the `[Tallies]` block, this class adds no tally auxvariables. Each is normalized +according to the specified `power` or `source_strength` (depending on whether you are running a +$k$-eigenvalue or fixed-source problem). By default, the normalization is done against a global +tally added over the entire OpenMC domain. By setting `normalize_by_global_tally` to false, however, +the tally is instead normalized by the sum of the tally itself. -You can customize the type of score that OpenMC uses for its tally with the -`tally_score` parameter. Options include: +You can customize the type of score that Cardinal uses to normalize tallies to `power` with the `source_rate_normalization` +parameter. Options include: - `heating`: total nuclear heating - `heating_local`: same as the `heating` score, except that energy from secondary photons @@ -310,12 +322,12 @@ You can customize the type of score that OpenMC uses for its tally with the released is a function of the incident energy by linking to optional fission energy release data. - `fission_q_recoverable`: same as the `kappa_fission` score, except that the score depends on the incident energy by linking to optional fission energy release data -- `damage_energy`: damage energy production For more information on the specific meanings of these various scores, -please consult the [OpenMC tally documentation](https://docs.openmc.org/en/stable/usersguide/tallies.html). [tally_units] compares the units from OpenMC -and the units of the AuxVariables created by Cardinal. Note that for all area or -volume units in [tally_units], that those units match whatever unit is used in the `[Mesh]`. +please consult the [OpenMC tally documentation](https://docs.openmc.org/en/stable/usersguide/tallies.html). All +of the tallies added are normalized with the same `source_rate_normalization` score when running in eigenvalue mode. +[tally_units] compares the units from OpenMC and the units of the AuxVariables created for all tally scores supported +by Cardinal. Note that for all area or volume units in [tally_units], that those units match whatever unit is used in the `[Mesh]`. !table id=tally_units caption=Tally units from OpenMC and the conversion in Cardinal. | Tally score | OpenMC Units | Cardinal Units | @@ -366,38 +378,6 @@ already are exactly the same volume, then no special thought is needed for the t normalization, and the value will be exactly consistent with the interpretation used in OpenMC. -#### Cell Tallies - -With cell tallies, `tally_blocks` specifies which blocks -in the `[Mesh]` should be tallied. Then, any OpenMC cells that map to those blocks -are added to a cell tally, with one bin for each unique cell ID/instance combination. - -#### Unstructured Mesh Tallies - id=um - -There are two options with unstructured mesh tallies: - -- Do nothing, in which case OpenMC will tally on the `[Mesh]` -- Specify a `mesh_template`, which provides a path to a mesh file - -For the `mesh_template` option, it is possible -to translate the same mesh to multiple locations in the OpenMC geometry -(while only taking up the memory needed to store a single mesh) using -the `mesh_translations` or `mesh_translations_file` parameters. This is a useful feature for -geometries that consist of many repeated geometry units, such as pebble bed and pin fuel -systems. - -!alert note -At present, unstructured mesh tallies are copied directly to the `[Mesh]` (without -doing any type of nearest-node lookup). -Suppose the mesh template consists of a mesh for a pincell with $N$ elements -that you have translated to 3 different locations, giving a total of $3N$ tally -bins. Because a direct copy is used to transfer the mesh tally results to the `[Mesh]`, -the first $3N$ elements in the `[Mesh]` must exactly match the $3N$ elements in -the mesh tally (except for a possible mesh scaling, as described in [#scaling]). -This equivalence is required for the direct copy to be accurate - otherwise, the -mesh tally results would be transferred to incorrect regions of space. - ## Other Features While this class mainly facilitates data transfers to and from OpenMC, a number of @@ -512,11 +492,9 @@ once reaching certain criteria in $k$ and/or the tally uncertainties, including: - $k$ relative error - tally relative error -Set the `k_trigger` parameter to activate a trigger based on $k$, and set -`tally_trigger` to activate a trigger based on the tally created -automatically as part of the wrapping setup. Then, the desired convergence -threshold is specified with the `k_trigger_threshold` and `tally_trigger_threshold` -parameters, respectively. Both $k$ and tally triggers can be used simultaneously. +Setting `k_trigger` enables triggers based on $k$, and setting `k_trigger_threshold` sets the required convergence criteria. +Individual tally triggers can be set in the `tally_trigger` and `tally_trigger_threshold` parameters of the tally classes +([CellTally](CellTally.md) and [MeshTally](MeshTally.md)). Both $k$ and multiple tally triggers can be used simultaneously. #### Controlling the OpenMC Settings @@ -531,13 +509,6 @@ settings directly from the Cardinal input file: For all of the above, a setting in the Cardinal input file will override any settings in the OpenMC XML files. -#### Outputting the OpenMC Solution - -Certain aspects of the OpenMC solution can be output as auxiliary variables to the mesh: - -- `unrelaxed_tally`: unrelaxed tally; this will append `_raw` to the tally name and output to the mesh mirror -- `unrelaxed_tally_std_dev`: unrelaxed tally standard deviation; this will append `_std_dev` to the tally and output to the mesh mirror - #### Volume Calculations It can be helpful for debugging problem setup to compare actual OpenMC cell volumes against diff --git a/doc/content/source/problems/smallest_openmc_input.i b/doc/content/source/problems/smallest_openmc_input.i index 55837686e..e84690e4d 100644 --- a/doc/content/source/problems/smallest_openmc_input.i +++ b/doc/content/source/problems/smallest_openmc_input.i @@ -10,9 +10,14 @@ temperature_blocks = '1 2 3' density_blocks = '3' - tally_type = cell - tally_blocks = '1' cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/doc/content/source/tallies/CellTally.md b/doc/content/source/tallies/CellTally.md new file mode 100644 index 000000000..c1e288d34 --- /dev/null +++ b/doc/content/source/tallies/CellTally.md @@ -0,0 +1,33 @@ +# CellTally + +!alert note +`CellTally` can only be added to problems when the input files contains a [OpenMCCellAverageProblem](OpenMCCellAverageProblem.md) +in the `[Problem]` block. Otherwise, attempting to add this tally will result in an error. + +## Description + +The `CellTally` class wraps an OpenMC tally with a distributed cell filter to enable data transfer +from CSG cells to a [MooseMesh](https://mooseframework.inl.gov/source/mesh/MooseMesh.html) mirror +of the OpenMC geometry. The cell to element mapping established by the [OpenMCCellAverageProblem](OpenMCCellAverageProblem.md) +is used to facilitate this data transfer to the mesh mirror. When using a `CellTally`, `tally_blocks` +specifies which blocks in the `[Mesh]` should be tallied. Then, any OpenMC cells that map to those +blocks are added to a cell tally, with one bin for each unique cell ID/instance combination. +`check_equal_mapped_tally_volumes` is used to confirm whether each cell in the `CellTally` has the +same mapped volume on the `MooseMesh` (to a tolerance specified in `equal_tally_volume_abs_tol`). + +!include scores_triggers.md + +## Example Input File Syntax + +As an example, this `CellTally` scores `kappa_fission` (the default tally score) on block `0` and stores +the result in a variable named `heat_source`. This corresponds to tallying the heating for three different +fuel pebbles. + +!listing /tutorials/pebbles/openmc.i + block=Problem + +!syntax parameters /Problem/Tallies/CellTally + +!syntax inputs /Problem/Tallies/CellTally + +!syntax children /Problem/Tallies/CellTally diff --git a/doc/content/source/tallies/MeshTally.md b/doc/content/source/tallies/MeshTally.md new file mode 100644 index 000000000..078d41c98 --- /dev/null +++ b/doc/content/source/tallies/MeshTally.md @@ -0,0 +1,56 @@ +# MeshTally + id=um + +!alert note +`MeshTally` can only be added to problems when the input files contains a [OpenMCCellAverageProblem](OpenMCCellAverageProblem.md) +in the `[Problem]` block. Otherwise, attempting to add this tally will result in an error. + +## Description + +The `MeshTally` class wraps an OpenMC tally with an unstructured libMesh filter to directly enable tallying on an unstructured mesh. +There are two options when using a `MeshTally`: + +- Do nothing, in which case OpenMC will tally on the `[Mesh]` +- Specify a `mesh_template`, which provides a path to a mesh file + +For the `mesh_template` option, it is possible +to translate the same mesh to multiple locations in the OpenMC geometry +(while only taking up the memory needed to store a single mesh) using +the `mesh_translations` or `mesh_translations_file` parameters provided by +the [tallies block](AddTallyAction.md). This is a useful feature for +geometries that consist of many repeated geometry units, such as pebble bed and pin fuel +systems. + +!alert note +At present, unstructured mesh tallies are copied directly to the `[Mesh]` (without +doing any type of nearest-node lookup). +Suppose the mesh template consists of a mesh for a pincell with $N$ elements +that you have translated to 3 different locations, giving a total of $3N$ tally +bins. Because a direct copy is used to transfer the mesh tally results to the `[Mesh]`, +the first $3N$ elements in the `[Mesh]` must exactly match the $3N$ elements in +the mesh tally (except for a possible mesh scaling, as described in [OpenMCCellAverageProblem.md#scaling]). +This equivalence is required for the direct copy to be accurate - otherwise, the +mesh tally results would be transferred to incorrect regions of space. + +!include scores_triggers.md + +!alert note +At present time, libMesh unstructured mesh tallies only support `collision` and `analog` estimators. Attempting to set `estimator` +to `tracklength` will result in a warning; the `MeshTally` will then manually reset the estimator to `collision` to prevent OpenMC from +throwing an error. + +## Example Input File Syntax + +As an example, this `MeshTally` scores `kappa_fission` (the default tally score) on the unstructured mesh +found in `mesh_in.e` and stores it in a variable called `heat_source`. The `[Tallies]` block adds three +`MeshTally` classes, each one located at a different point specified in `mesh_translations` which corresponds +to the centroid of a fuel pebble. + +!listing /tutorials/pebbles/openmc_um.i + block=Problem + +!syntax parameters /Problem/Tallies/MeshTally + +!syntax inputs /Problem/Tallies/MeshTally + +!syntax children /Problem/Tallies/MeshTally diff --git a/doc/content/source/tallies/scores_triggers.md b/doc/content/source/tallies/scores_triggers.md new file mode 100644 index 000000000..af9bf0ab4 --- /dev/null +++ b/doc/content/source/tallies/scores_triggers.md @@ -0,0 +1,33 @@ +Cardinal supports several tally scores which can be specified in the `score` parameter when adding +a tally. Options include: + +- `heating`: total nuclear heating +- `heating_local`: same as the `heating` score, except that energy from secondary photons + is deposited locally +- `kappa_fission`: recoverable energy from fission, including prompt sources (fission fragments, + prompt neutrons, prompt gammas) and delayed sources (delayed neutrons, + delayed gammas, delayed betas). Neutrino energy is neglected. The energy from photons + is assumed to deposit locally. +- `fission_q_prompt`: the prompt components of the `kappa_fission` score, except that the energy + released is a function of the incident energy by linking to optional fission energy release data. +- `fission_q_recoverable`: same as the `kappa_fission` score, except that the score depends + on the incident energy by linking to optional fission energy release data +- `damage_energy`: damage energy production +- `flux`: particle scalar flux +- `H3_production`: tritium production reaction rate + +For more information on the specific meanings of these various scores, +please consult the [OpenMC tally documentation](https://docs.openmc.org/en/stable/usersguide/tallies.html). The names of +the tally auxvariables added by the [OpenMCCellAverageProblem](OpenMCCellAverageProblem.md) can be modified by specifying a name +for each score in `name`. + +This tally is capable of controlling OpenMC execution through the use of +[tally triggers](https://docs.openmc.org/en/latest/pythonapi/generated/openmc.Trigger.html?highlight=trigger). Tallies currently +support active batch termination through a relative error indicator, which can be enabled by setting `trigger` to `rel_err` +for each score in the tally. Scores which do not need to control active batch termination can have a value of `none` set. If enabled, +an appropriate relative error must be set for each score in `trigger_threshold`. + +Certain aspects of tally results can be output as auxiliary variables to the mesh: + +- `unrelaxed_tally`: unrelaxed tally; this will append `_raw` to the tally name and output to the mesh mirror +- `unrelaxed_tally_std_dev`: unrelaxed tally standard deviation; this will append `_std_dev` to the tally and output to the mesh mirror diff --git a/doc/content/tutorials/dagmc.md b/doc/content/tutorials/dagmc.md index 8f4843fe0..90cfd86d1 100644 --- a/doc/content/tutorials/dagmc.md +++ b/doc/content/tutorials/dagmc.md @@ -172,10 +172,10 @@ in other tutorials. end=AuxVariables Next, the [Problem](https://mooseframework.inl.gov/syntax/Problem/index.html) -block describes all objects necessary for the actual physics solve. To replace -MOOSE finite element calculations with OpenMC particle transport calculations, -the [OpenMCCellAverageProblem](/problems/OpenMCCellAverageProblem.md) class -is used. +and [Tallies](/actions/AddTallyAction.md) blocks describe all objects necessary +for the actual neutronics solve. To replace MOOSE finite element calculations +with OpenMC particle transport calculations, the +[OpenMCCellAverageProblem](/problems/OpenMCCellAverageProblem.md) class is used. !listing /tutorials/dagmc/openmc.i block=Problem @@ -190,10 +190,9 @@ will automatically map from MOOSE elements to OpenMC cells, and store which MOOS are providing temperature feedback. Then when temperature is sent into OpenMC, that mapping is used to compute a volume-average temperature to apply to each OpenMC cell. -This example uses mesh tallies, as indicated by the -`tally_type`. -[OpenMCCellAverageProblem](/problems/OpenMCCellAverageProblem.md) will then -automatically add the necessary tallies. +This example uses mesh tallies, as indicated by the [MeshTally](/tallies/MeshTally.md) +in the `[Tallies]` block. [OpenMCCellAverageProblem](/problems/OpenMCCellAverageProblem.md) +will then automatically add the OpenMC mesh tally using the information provided. Finally, we specify the level in the geometry on which the cells exist. Because we don't have any lattices or filled universes in our OpenMC model, the cell level is zero. diff --git a/doc/content/tutorials/gas_compact.md b/doc/content/tutorials/gas_compact.md index c5b01d31f..59ca7e0a1 100644 --- a/doc/content/tutorials/gas_compact.md +++ b/doc/content/tutorials/gas_compact.md @@ -272,8 +272,8 @@ mapped to the OpenMC cells. start=AuxVariables end=ICs -The `[Problem]` block is then used to specify settings for the OpenMC wrapping. We define a total power -of 30 kW and indicate that we'd like to add tallies to the fuel compacts. The cell +The `[Problem]` and `[Tallies]` blocks are then used to specify settings for the OpenMC wrapping. We define a total power +of 30 kW and add a [CellTally](/tallies/CellTally.md) to the fuel compacts. The cell tally setup in Cardinal will then automatically add a tally for each unique cell ID+instance combination. By setting `temperature_blocks` to all blocks, OpenMC will then receive temperature from MOOSE for the entire domain (because the mesh mirror consists of these @@ -288,7 +288,7 @@ we specify a `scaling` of 100, i.e. a multiplicative factor to apply to the Other features we use include an output of the fission tally standard deviation in units of W/m$^3$ to the `[Mesh]` by setting the `output` parameter. This is used to obtain the standard deviation of the heat source distribution from OpenMC in the same -units as the heat source. We also leverage a helper utility in Cardinal by setting +units as the heat source. We also leverage a helper utility in [CellTally](/tallies/CellTally.md) by setting `check_equal_mapped_tally_volumes` to `true`. This parameter will throw an error if the tallied OpenMC cells map to different volumes in the MOOSE domain. Because we know *a priori* that the equal-volume OpenMC tally cells *should* all map to equal volumes, this will diff --git a/doc/content/tutorials/msfr.md b/doc/content/tutorials/msfr.md index 4a3aed847..7c1343bfe 100644 --- a/doc/content/tutorials/msfr.md +++ b/doc/content/tutorials/msfr.md @@ -189,15 +189,15 @@ will display the OpenMC cell temperatures and densities (after volume-averaging start=AuxVariables end=Problem -Next, the `Problem` block defines all the parameters related to coupling +Next, the `[Problem]` and `[Tallies]` blocks define all the parameters related to coupling OpenMC to MOOSE. We will send temperature and density to OpenMC, and extract -power using a mesh tally. We set a number of relaxation settings to use +power using a [MeshTally](/tallies/MeshTally.md). We set a number of relaxation settings to use Dufek-Gudowski relaxation, which will progressively ramp the number of particles used in the simulation (starting at 5000) so that we selectively apply computational effort only after the thermal-fluid physics are reasonably well converged. Finally, we will be "skinning" the geometry on-the-fly by providing the `skinner` user object (of type -[MoabSkinner](https://cardinal.cels.anl.gov/source/userobjects/MoabSkinner.html). +[MoabSkinner](https://cardinal.cels.anl.gov/source/userobjects/MoabSkinner.html)). !listing tutorials/msfr/openmc.i block=Problem diff --git a/doc/content/tutorials/openmc_fluid.md b/doc/content/tutorials/openmc_fluid.md index 7da0f4300..34c8b2241 100644 --- a/doc/content/tutorials/openmc_fluid.md +++ b/doc/content/tutorials/openmc_fluid.md @@ -445,10 +445,10 @@ conduction module and to [!ac](THM) occur, these initial conditions will be pass start=ICs end=FluidProperties -The `[Problem]` block is then used to specify settings for the OpenMC wrapping. We +The `[Problem]` and `[Tallies]` blocks are then used to specify settings for the OpenMC wrapping. We define the total power for normalization, indicate that blocks 1, 2, and 4 are solid -(graphite, compacts, and poison) while block 101 is fluid. We automatically add -tallies to block 2, the fuel compacts. Because OpenMC solves in units of centimeters, +(graphite, compacts, and poison) while block 101 is fluid. We add a [CellTally](/tallies/CellTally.md) +to block 2, the fuel compacts. Because OpenMC solves in units of centimeters, we specify a `scaling` of 100, i.e. a multiplicative factor to apply to the `[Mesh]` to get into OpenMC's centimeter units. @@ -459,7 +459,7 @@ Other features we use include an output of the fission tally standard deviation in units of W/m$^3$ to the `[Mesh]` by setting `output = 'unrelaxed_tally_std_dev'`. This is used to obtain uncertainty estimates of the heat source distribution from OpenMC in the same units as the heat source. We also leverage a helper utility -in Cardinal by setting `check_equal_mapped_tally_volumes = true`. This parameter will +in [CellTally](/tallies/CellTally.md) by setting `check_equal_mapped_tally_volumes = true`. This parameter will throw an error if the tallied OpenMC cells map to different volumes in the MOOSE domain. Because we know *a priori* that the equal-volume OpenMC tally cells *should* all map to equal volumes, this will help ensure that the volumes used for heat source normalization diff --git a/doc/content/tutorials/pincell1.md b/doc/content/tutorials/pincell1.md index 27f737ff2..321343646 100644 --- a/doc/content/tutorials/pincell1.md +++ b/doc/content/tutorials/pincell1.md @@ -332,14 +332,25 @@ in other tutorials. end=AuxVariables Next, the [Problem](https://mooseframework.inl.gov/syntax/Problem/index.html) -block describes all objects necessary for the actual physics solve. To replace -MOOSE finite element calculations with OpenMC particle transport calculations, -the [OpenMCCellAverageProblem](/problems/OpenMCCellAverageProblem.md) class -is used. +and [Tallies](/actions/AddTallyAction.md) blocks describe all objects necessary for the +actual neutronics solve. To replace MOOSE finite element calculations +with OpenMC particle transport calculations, the +[OpenMCCellAverageProblem](/problems/OpenMCCellAverageProblem.md) class is used. !listing /tutorials/lwr_solid/openmc.i block=Problem +For this example, we first start by specifying that we wish to add a +[CellTally](/tallies/CellTally.md) in `[Tallies]`. The `blocks` are +then used to indicate which OpenMC cells to add tallies to +(as inferred from the mapping of MOOSE elements to OpenMC cells). If not specified, +we add tallies to all OpenMC cells. But for this problem, we already know that the +cladding doesn't have any fissile material, so we can save some effort with the +tallies by skipping tallies in those regions by setting +`blocks` to blocks 2 and 3. +[OpenMCCellAverageProblem](/problems/OpenMCCellAverageProblem.md) will then +take the information provided in the `[Tallies]` block and add the necessary OpenMC tally. + For this example, we specify the total fission power by which to normalize OpenMC's tally results (because OpenMC's tally results are in units of eV/source particle). Next, we indicate which blocks in the `[Mesh]` should be considered for @@ -348,20 +359,7 @@ Here, we specify temperature feedback for the pellet (blocks 2 and 3) and the cl (block 1). During the initialization, [OpenMCCellAverageProblem](/problems/OpenMCCellAverageProblem.md) will automatically map from MOOSE elements to OpenMC cells, and store which MOOSE elements are providing feedback. Then when temperature is sent into OpenMC, that mapping is used to compute -a volume-average temperature to apply to each OpenMC cell. - -This example uses cell tallies, as indicated by -`tally_type`. -The `tally_blocks` are -then used to indicate which OpenMC cells to add tallies to -(as inferred from the mapping of MOOSE elements to OpenMC cells). If not specified, -we add tallies to all OpenMC cells. But for this problem, we already know that the -cladding doesn't have any fissile material, so we can save some effort with the -tallies by skipping tallies in those regions by setting -`tally_blocks` to blocks 2 and 3. -[OpenMCCellAverageProblem](/problems/OpenMCCellAverageProblem.md) will then -automatically add the necessary tallies. -We specify the level in the geometry on which the cells +a volume-average temperature to apply to each OpenMC cell. We specify the level in the geometry on which the cells exist. Because we don't have any lattices or filled universes in our OpenMC model, the cell level is zero. @@ -379,7 +377,7 @@ how Cardinal volume-averages temperature over the mesh, we add a !listing /tutorials/lwr_solid/openmc.i start=AuxVariables - end=Problem + end=Tallies Next, we specify an executioner and output settings. Even though OpenMC technically performs a criticality calculation (with no time dependence), we use the transient @@ -593,12 +591,10 @@ point to a different input file. !listing /tutorials/lwr_solid/solid_um.i block=MultiApps -Then, in `openmc_um.i`, we make small modifications to the settings for the -[OpenMCCellAverageProblem](/problems/OpenMCCellAverageProblem.md). We indicate that -`tally_type` -is set to `mesh`. By default, OpenMC will then just tally directly on the MOOSE -`[Mesh]` (though we could have specified a different mesh by providing a -`mesh_template` file name). +Then, in `openmc_um.i`, we change the [CellTally](/tallies/CellTally.md) +to a [MeshTally](/tallies/MeshTally.md). By default, OpenMC will then just +tally directly on the MOOSE `[Mesh]` (though we could have specified a +different mesh by providing a`mesh_template` file name). !listing /tutorials/lwr_solid/openmc_um.i block=Problem diff --git a/doc/content/tutorials/pincell_multiphysics.md b/doc/content/tutorials/pincell_multiphysics.md index 60d8fdfff..6684f873f 100644 --- a/doc/content/tutorials/pincell_multiphysics.md +++ b/doc/content/tutorials/pincell_multiphysics.md @@ -245,11 +245,11 @@ saturation temperature). start=AuxVariables end=ICs -Next, the `Problem` block defines all the parameters related to coupling +Next, the `[Problem]` and `[Tallies]` blocks define all the parameters related to coupling OpenMC to MOOSE. We will send temperature to OpenMC from blocks 2 and 3 (which represent the solid regions) and we will send temperature and density -to OpenMC from block 1 (which represents the fluid region). We will have -Cardinal automatically set up cell tallies. +to OpenMC from block 1 (which represents the fluid region). We add a +[CellTally](/tallies/CellTally.md) to tally the heat source in the fuel. For this problem, the temperature that gets mapped into OpenMC is sourced from two different applications, which we can customize using the diff --git a/doc/content/tutorials/tokamak.md b/doc/content/tutorials/tokamak.md index 3d88ad278..27bb5465d 100644 --- a/doc/content/tutorials/tokamak.md +++ b/doc/content/tutorials/tokamak.md @@ -180,10 +180,8 @@ will automatically map from MOOSE elements to OpenMC cells, and store which MOOS are providing temperature feedback. Then when temperature is sent into OpenMC, that mapping is used to compute a volume-average temperature to apply to each OpenMC cell. -This example uses mesh tallies, as indicated by the -`tally_type`. -[OpenMCCellAverageProblem](/problems/OpenMCCellAverageProblem.md) will then -automatically add the necessary tallies. In this example, we will tally on +This example uses mesh tallies, as indicated by the [MeshTally](tallies/MeshTally.md) +in the [Tallies](actions/AddTallyAction.md) block. In this example, we will tally on the same mesh given in the `[Mesh]` block. Finally, we specify the level in the geometry on which the cells exist. Because we don't have any lattices or filled universes in our OpenMC model, diff --git a/doc/content/tutorials/triso.md b/doc/content/tutorials/triso.md index 99dceb9cb..dc7e01c3b 100644 --- a/doc/content/tutorials/triso.md +++ b/doc/content/tutorials/triso.md @@ -179,9 +179,9 @@ as they map to the `[Mesh]`. start=AuxVariables end=Problem -The `[Problem]` -block is then used to specify the OpenMC wrapping. We define a total power of -1500 W, and indicate that we'd like to add tallies on block 0, which corresponds to the pebbles. +The `[Problem]` and `[Tallies]` +blocks are then used to specify the OpenMC wrapping. We define a total power of +1500 W, and indicate that we'd like to add a [CellTally](/tallies/CellTally.md) on block 0, which corresponds to the pebbles. The cell tally setup in Cardinal will then automatically add a tally for each unique cell ID+instance combination. Because the repeated pebble cells we'd like to tally @@ -287,7 +287,7 @@ application. To do this, we increase `nr` to add more radial discretization. block=Mesh For the OpenMC wrapping, the only changes required are -that we set the type of tally to `mesh`, provide a mesh template with the mesh, and specify the +that we change the added tally to a [MeshTally](/tallies/MeshTally.md), provide a mesh template with the mesh, and specify the translations to apply to replicate the mesh at the desired end positions in OpenMC's domain. For the mesh tally, let's create a mesh for a single pebble using MOOSE's mesh generators. We simply need to run the `mesh.i` file in `--mesh-only` mode: @@ -299,7 +299,7 @@ cardinal-opt -i mesh.i --mesh-only ``` which will create a mesh file named `mesh_in.e`. We then list that mesh as the -`mesh_template` in the `[Problem]` block. +`mesh_template` in the `[Tallies]` block. !listing /tutorials/pebbles/openmc_um.i block=Problem diff --git a/doc/content/tutorials/triso_multiphysics.md b/doc/content/tutorials/triso_multiphysics.md index 192c60895..0f1dff0ff 100644 --- a/doc/content/tutorials/triso_multiphysics.md +++ b/doc/content/tutorials/triso_multiphysics.md @@ -368,10 +368,10 @@ from the inlet to outlet fluid temperatures. start=ICs end=Problem -The wrapping of OpenMC is specified in the `[Problem]` block. Here, we -indicate that we will provide both temperature and density feedback to OpenMC. In order to -visualize the tally standard deviation, we output the fission tally standard -deviation using the `output` parameter. The heat source from OpenMC will be relaxed +The wrapping of OpenMC is specified in the `[Problem]` block and the addition of tallies is done +in the `[Tallies]` block. Here, we indicate that we will provide both temperature and density +feedback to OpenMC. In order to visualize the tally standard deviation, we output the fission +tally standard deviation using the `output` parameter. The heat source from OpenMC will be relaxed using Robbins-Monro relaxation. By default, OpenMC will try to read temperature from the `temp` variable. However, in diff --git a/include/actions/AddTallyAction.h b/include/actions/AddTallyAction.h new file mode 100644 index 000000000..fe8c2aef1 --- /dev/null +++ b/include/actions/AddTallyAction.h @@ -0,0 +1,64 @@ +/********************************************************************/ +/* SOFTWARE COPYRIGHT NOTIFICATION */ +/* Cardinal */ +/* */ +/* (c) 2021 UChicago Argonne, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by UChicago Argonne, LLC */ +/* Under Contract No. DE-AC02-06CH11357 */ +/* With the U. S. Department of Energy */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See LICENSE for full restrictions */ +/********************************************************************/ + +#pragma once + +#include "MooseObjectAction.h" + +/// This action adds tallies for use in simulations that couple OpenMC. +class AddTallyAction : public MooseObjectAction +{ +public: + static InputParameters validParams(); + + AddTallyAction(const InputParameters & parameters); + + virtual void act() override; + +protected: + /** + * This function adds a a tally which may be an offset into an array + * of translations with index instance. Used for translated mesh tallies + * that all use the same base mesh for the spatial filter. + * @param instance the index of the tally into the translation array + * @param translation the translation vector at instance + */ + void addMeshTally(unsigned int instance = 0, const Point & translation = Point(0.0, 0.0, 0.0)); + + /** + * This function adds a a tally which may be an offset into an array + * of translations with index instance. Used for translated mesh tallies + * that all use the same base mesh for the spatial filter. + */ + void addTally(); + + /** + * Fill the mesh translations to be applied to an unstructured mesh tally; if no + * translations are explicitly given, a translation of (0.0, 0.0, 0.0) is assumed. + */ + void fillMeshTranslations(); + + /** + * Read the mesh translations from file data + * @param[in] data data from file + */ + void readMeshTranslations(const std::vector> & data); + + /// The number of mesh translations. + std::vector _mesh_translations; +}; diff --git a/include/base/OpenMCCellAverageProblem.h b/include/base/OpenMCCellAverageProblem.h index ea809c5a6..8e9f243fb 100644 --- a/include/base/OpenMCCellAverageProblem.h +++ b/include/base/OpenMCCellAverageProblem.h @@ -22,6 +22,9 @@ #include "SymmetryPointGenerator.h" #include "OpenMCVolumeCalculation.h" +/// Tally includes. +#include "TallyBase.h" + #include "openmc/tallies/filter_mesh.h" #ifdef ENABLE_DAGMC @@ -117,7 +120,20 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase * Get the mapping of cells to MOOSE elements * @return mapping of cells to MOOSE elements */ - virtual const std::map> cellToElem() const { return _cell_to_elem; } + virtual const std::map> & cellToElem() const + { + return _cell_to_elem; + } + + /** + * Get the MOOSE subdomains associated with an OpenMC cell + * @param info the cell info + * @return MOOSE subdomains associated with an OpenMC cell + */ + virtual std::unordered_set getCellToElementSub(const cellInfo & info) + { + return _cell_to_elem_subdomain.at(info); + } /** * Whether transformations are applied to the [Mesh] points when mapping to OpenMC @@ -129,7 +145,7 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase * Get all the scores added to the tally * @return scores */ - virtual const std::vector & getTallyScores() const { return _tally_score; } + virtual const std::vector & getTallyScores() const { return _all_tally_scores; } /** * Apply transformations to point @@ -252,7 +268,7 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase * Get the local tally * @return local tally */ - const std::vector & getLocalTally() const { return _local_tally; } + const std::vector> & getLocalTally() const { return _local_tallies; } /** * Get the temperature of a cell; for cells not filled with materials, this will return @@ -270,9 +286,35 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase /// Reconstruct the DAGMC geometry after skinning void reloadDAGMC(); + /** + * Add a Tally object using the new tally system. TODO: rename to addTally once + * OpenMCCellAverageProblem and OpenMCProblemBase are refactored. + * @param[in] type the new tally type + * @param[in] name the name of the new tally + * @param[in] moose_object_pars the input parameters of the new tally + */ + void addTallyObject(const std::string & type, + const std::string & name, + InputParameters & moose_object_pars); + + /** + * Multiplier on the normalized tally results; for fixed source runs, + * we multiply the tally (which has units of eV/source) + * by the source strength and the eV to joule conversion, while for k-eigenvalue runs, we + * multiply the normalized tally (which is unitless and has an integral + * value of 1.0) by the power. + * @param[in] global_score tally score + */ + Real tallyMultiplier(unsigned int global_score) const; + + int fixedPointIteration() const { return _fixed_point_iteration; } + /// Constant flag to indicate that a cell/element was unmapped static constexpr int32_t UNMAPPED{-1}; + /// Spatial dimension of the Monte Carlo problem + static constexpr int DIMENSION{3}; + protected: /** * Get the cell level in OpenMC to use for coupling @@ -353,53 +395,13 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase */ Point transformPointToOpenMC(const Point & pt) const; - /** - * Read from an OpenMC cell tally and write into an elemental aux variable - * @param[in] var_num variable name to write - * @param[in] tally tally values to write - * @param[in] score tally score - * @return sum of the tally - */ - Real getCellTally(const unsigned int & var_num, - const std::vector> & tally, - const unsigned int & score); - - /** - * Read from an OpenMC mesh tally and write into an elemental aux variable - * @param[in] var_num variable name to write - * @param[in] tally tally values to write - * @param[in] score tally score - * @return sum of the tally - */ - Real getMeshTally(const unsigned int & var_num, - const std::vector> & tally, - const unsigned int & score); - - /** - * Extract the tally from OpenMC and then apply to the corresponding MOOSE elements. - * @param[in] var_num variable name to write - * @param[in] tally tally values to write - * @param[in] score tally score - * @return sum sum of the tally - */ - Real getTally(const unsigned int & var_num, - const std::vector> & tally, - const unsigned int & score); - /** * Check that the tally normalization gives a total tally sum of 1.0 (when normalized * against the total tally value). * @param[in] sum sum of the tally * @param[in] score tally score */ - void checkNormalization(const Real & sum, const unsigned int & score) const; - - /** - * Get the mesh filter(s) for tallies automatically constructed by Cardinal. - * Multiple mesh filters are only created if the mesh template feature is used. - * @return mesh filters - */ - std::vector meshFilter(); + void checkNormalization(const Real & sum, unsigned int global_score) const; /** * For geometries with fine-scale details (e.g. TRISO), Cardinal's default settings can @@ -527,21 +529,6 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase template void checkEmptyVector(const std::vector & vector, const std::string & name) const; - /** - * Read the mesh translations from file data - * @param[in] data data from file - */ - void readMeshTranslations(const std::vector> & data); - - /** - * Check the setup of the mesh template and translations. Because a simple copy transfer - * is used to write a mesh tally onto the [Mesh], we require that the - * meshes are identical - both in terms of the element ordering and the actual dimensions of - * each element. This function performs as many checks as possible to ensure that the meshes - * are indeed identical. - */ - void checkMeshTemplateAndTranslations() const; - /// Loop over the elements in the MOOSE mesh and store the type of feedback applied by each. void storeElementPhase(); @@ -562,10 +549,13 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase * change dramatically with iteration. But because relaxation is itself a numerical approximation, * this is still inconsequential at the end of the day as long as your problem has converged * the relaxed tally to the raw (unrelaxed) tally. - * @param[in] t tally index within local tally - * @param[in] score score + * @param[in] global_score the global index of the tally score + * @param[in] local_score the local index of the tally score + * @param[in] local_tally the tally to relax and normalize */ - void relaxAndNormalizeTally(const int & t, const unsigned int & score); + void relaxAndNormalizeTally(unsigned int global_score, + unsigned int local_score, + std::shared_ptr local_tally); /** * Loop over all the OpenMC cells and count the number of MOOSE elements to which the cell @@ -576,22 +566,9 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase /// This function is used to ensure that each OpenMC cell only maps to a single phase void checkCellMappedPhase(); - /** - * Loop over all the OpenMC cells and find those for which we should add tallies. - * @return cells to which we should add tallies - */ - std::vector getTallyCells() const; - /// Loop over all the OpenMC cells and get the element subdomain IDs that map to each cell void getCellMappedSubdomains(); - /** - * Loop over all the OpenMC cells and determine if a cell maps to more than one subdomain - * that also has different tally settings (i.e. we would not know whether to add or not to - * add tallies to the cell). - */ - void checkCellMappedSubdomains(); - /** * Loop over all the OpenMC cells and compute the volume of the MOOSE elements that each * cell maps to @@ -604,6 +581,13 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase /// Populate maps of MOOSE elements to OpenMC cells void mapElemsToCells(); + /** + * A function which validates local tallies. This is done to ensure that at least one of the + * tallies contains a heating score when running in eigenvalue mode. This must be done outside + * of the constructor as tallies are added from an external system. + */ + void validateLocalTallies(); + /// Add OpenMC tallies to facilitate the coupling void initializeTallies(); @@ -645,40 +629,12 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase */ void sendDensityToOpenMC() const; - /** - * Multiplier on the normalized tally results; for fixed source runs, - * we multiply the tally (which has units of eV/source) - * by the source strength and the eV to joule conversion, while for k-eigenvalue runs, we - * multiply the normalized tally (which is unitless and has an integral - * value of 1.0) by the power. - * @param[in] score tally score - */ - Real tallyMultiplier(const unsigned int & score) const; - /** * Factor by which to normalize a tally - * @param[in] score tally score + * @param[in] global_score global index for the tally score * @return value to divide tally sum by for normalization */ - Real tallyNormalization(const unsigned int & score) const; - - /** - * Normalize the local tally by either the global tally, or the sum - * of the local tally. For fixed source simulations, do nothing because the - * tally result is not re-normalized to any integral quantity. - * @param[in] tally_result value of tally result - * @param[in] score tally score - * @return normalized tally - */ - template - T normalizeLocalTally(const T & tally_result, const unsigned int & score) const; - - /** - * Add local tally - * @param[in] score score type - * @param[in] filters tally filters - */ - void addLocalTally(const std::vector & score, std::vector & filters); + Real tallyNormalization(unsigned int global_score) const; /** * Check the sum of the tallies against the global tally @@ -686,12 +642,6 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase */ void checkTallySum(const unsigned int & score) const; - /** - * Fill the mesh translations to be applied to each unstructured mesh; if no - * translations are explicitly given, a translation of (0.0, 0.0, 0.0) is assumed. - */ - void fillMeshTranslations(); - /** * Check if a mapped location is in the outer universe of a lattice * @param[in] level lattice level @@ -743,14 +693,6 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase /// Type of relaxation to apply to the OpenMC tallies const relaxation::RelaxationEnum _relaxation; - /** - * Type of trigger to apply to OpenMC tallies to indicate when - * the simulation is complete. These can be used to on-the-fly adjust the number - * of active batches in order to reach some desired criteria (which is specified - * by this parameter). - */ - const MultiMooseEnum * _tally_trigger; - /** * Type of trigger to apply to k eigenvalue to indicate when * the simulation is complete. These can be used to on-the-fly adjust the number @@ -816,22 +758,6 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase */ const bool _check_tally_sum; - /** - * Whether to check that the [Mesh] volume each cell tally maps to is identical. - * This is a useful helper function for OpenMC models where each cell tally has the - * same volume (often the case for many reactor geometries). If the OpenMC model - * cell tallies all are of the same spatial size, it's still possible that they - * can map to different volumes in the MOOSE mesh if the MOOSE elements don't line - * up with the edges of the OpenMC cells. Different volumes then can distort the - * volume normalization that we do to convert the fission power to a volumetric - * power (in a perfect world, we would actually divide OpenMC's tallies by the - * results of a stochastic volume calculation in OpenMC, but that is too expensive). - */ - const bool & _check_equal_mapped_tally_volumes; - - /// Absolute tolerance for checking equal tally mapped volumes - const Real & _equal_tally_volume_abs_tol; - /// Constant relaxation factor const Real & _relaxation_factor; @@ -904,8 +830,11 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase */ const bool _specified_temperature_feedback; + /// Whether any cell tallies exist. + bool _has_cell_tallies = false; + /// Whether any spatial mapping from OpenMC's cells to the mesh is needed - const bool _needs_to_map_cells; + bool _needs_to_map_cells; /** * Whether a global tally is required for the sake of normalization and/or checking @@ -913,14 +842,27 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase */ const bool _needs_global_tally; - /// Tally estimator for the tallies created by Cardinal - openmc::TallyEstimator _tally_estimator; + /// A vector of the tally objects created by the [Tallies] block. + std::vector> _local_tallies; + + /// A list of all of the scores contained by the local tallies added in the [Tallies] block. + std::vector _all_tally_scores; + + /** + * The [Tallies] block allows tallies with different scores, and so we can't assume they have the + * same indices in each tally's arrays. This variable map between the name of each score and it's + * index in each local tally. + */ + std::vector> _local_tally_score_map; - /// OpenMC tally score(s) to write into the 'tally_name' auxiliary variable(s) - std::vector _tally_score; + /// A vector of auxvariable ids added by the [Tallies] block. + std::vector> _tally_var_ids; - /// Auxiliary variable name(s) for the OpenMC tally(s) - std::vector _tally_name; + /// A vector of external (output-based) auxvariable ids added by the [Tallies] block. + std::vector>> _tally_ext_var_ids; + + /// Whether the problem contains a cell tally or not. + bool _contains_cell_tally = false; /// Blocks in MOOSE mesh that provide density feedback std::vector _density_blocks; @@ -928,9 +870,6 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase /// Blocks in MOOSE mesh that provide temperature feedback std::vector _temp_blocks; - /// Blocks for which to add (cell) tallies - std::unordered_set _tally_blocks; - /// Blocks for which the cell fills are identical std::unordered_set _identical_cell_fill_blocks; @@ -997,9 +936,6 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase */ std::map _cell_to_point; - /// Whether a cell index, instance pair should be added to the tally filter - std::map _cell_has_tally; - /** * Volume associated with the mapped element space for each OpenMC cell; the unit * for this volume is whatever is used in the [Mesh] block @@ -1027,21 +963,17 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase /// Number of material-type cells contained within a cell std::map _cell_to_n_contained; - /// Global tally - openmc::Tally * _global_tally{nullptr}; - /** - * Local tallies; multiple tallies will only exist when - * translating multiple unstructured meshes throughout the geometry. Each tally - * may have multiple scores which are simultaneously tracked. + * Global tallies. We add one per tally added in the [Tallies] block to + * enable global noramlization. */ - std::vector _local_tally; + std::vector _global_tallies; - /// OpenMC unstructured mesh instance for use of mesh tallies - const openmc::LibMesh * _mesh_template; + /// Global tally scores corresponding to '_global_tallies'. + std::vector> _global_tally_scores; - /// Tally variable(s) - std::vector _tally_var; + /// Global tally estimators corresponding to '_global_tallies'. + std::vector _global_tally_estimators; /// Sum value of the global tally(s), across all bins std::vector _global_sum_tally; @@ -1052,17 +984,6 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase /// Mean value of the local tally(s), across all bins; only used for fixed source mode std::vector _local_mean_tally; - /** - * Mesh template file to use for creating mesh tallies in OpenMC; currently, this mesh - * must be identical to the mesh used in the [Mesh] block because a simple copy transfer - * is used to extract the tallies and put on the application's mesh in preparation for - * a transfer to another MOOSE app. If not set, this indicates that tallying will be - * performed directly on the [Mesh]. - * TODO: allow the mesh to not be identical, both in terms of using different units - * and more general differences like not having a particular phase present - */ - const std::string * _mesh_template_filename = nullptr; - /// Whether the present transfer is the first transfer static bool _first_transfer; @@ -1075,53 +996,9 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase /// Dummy particle to reduce number of allocations of particles for cell lookup routines openmc::Particle _particle; - /** - * Translations to apply to the mesh template, in the event that the mesh should be - * repeated throughout the geometry. For instance, in pincell type geometries, you can - * use this feature to repeat the same cylinder mesh multiple times throughout the domain. - */ - std::vector _mesh_translations; - - /// OpenMC mesh filters for unstructured mesh tallies - std::vector _mesh_filters; - - /// OpenMC solution fields to output to the mesh mirror - const MultiMooseEnum * _outputs = nullptr; - - /// Suffixes to apply to 'tally_name' in order to name the fields in the 'output' - std::vector _output_name; - - /// Numeric identifiers for the external variables (for each score) - std::vector> _external_vars; - - /// Spatial dimension of the Monte Carlo problem - static constexpr int DIMENSION{3}; - /// Number of particles simulated in the first iteration unsigned int _n_particles_1; - /// Thresholds to use for accepting tallies when using triggers - std::vector _tally_trigger_threshold; - - /** - * Current fixed point iteration tally result; for instance, when using constant - * relaxation, the tally is updated as: - * q(n+1) = (1-a) * q(n) + a * PHI(q(n), s) - * where q(n+1) is _current_tally, a is the relaxation factor, q(n) - * is _previous_tally, and PHI is the most-recently-computed tally result - * (the _current_raw_tally). - */ - std::vector>> _current_tally; - - /// Previous fixed point iteration tally result (after relaxation) - std::vector>> _previous_tally; - - /// Current "raw" tally output from Monte Carlo solution - std::vector>> _current_raw_tally; - - /// Current "raw" tally standard deviation - std::vector>> _current_raw_tally_std_dev; - /// Mapping from temperature variable name to the subdomains on which to read it from std::map> _temp_vars_to_blocks; @@ -1146,17 +1023,8 @@ class OpenMCCellAverageProblem : public OpenMCProblemBase /// Number of none elements in each mapped OpenMC cell (global) std::map _n_none; - /// Index in OpenMC tallies corresponding to the global tally added by Cardinal - unsigned int _global_tally_index; - - /// Index in OpenMC tallies corresponding to the first local tally added by Cardinal - unsigned int _local_tally_index; - - /// Index in OpenMC tally filters corresponding to the first filter added by Cardinal - unsigned int _filter_index; - - /// Index in OpenMC meshes corresponding to the mesh tally (if used) - unsigned int _mesh_index; + /// Index in OpenMC tallies corresponding to the first global tally added by Cardinal + unsigned int _global_tally_index = 0; /// Index in tally_score pointing to the score used for normalizing flux tallies in eigenvalue mode unsigned int _source_rate_index; diff --git a/include/base/OpenMCProblemBase.h b/include/base/OpenMCProblemBase.h index b0213a4b8..682a39a54 100644 --- a/include/base/OpenMCProblemBase.h +++ b/include/base/OpenMCProblemBase.h @@ -83,19 +83,18 @@ class OpenMCProblemBase : public CardinalProblem, public PostprocessorInterface */ unsigned int addExternalVariable(const std::string & name, const std::vector * block = nullptr); - /** - * Create an openmc::LibMesh mesh - * @param[in] filename file name to construct the mesh from; if nullptr, uses [Mesh] - * @return OpenMC libMesh mesh - */ - std::unique_ptr tallyMesh(const std::string * filename = nullptr) const; - /** * Get the scaling value applied to the [Mesh] to convert to OpenMC's centimeters units * @return scaling value */ const Real & scaling() const { return _scaling; } + /** + * Whether the problem has user defined scaling or not. + * @return whether the user has set the problem scaling or not + */ + bool hasScaling() const { return _specified_scaling; } + /** * Convert from a MOOSE-type enum into a valid OpenMC tally score string * @param[in] score MOOSE-type enum string @@ -135,6 +134,13 @@ class OpenMCProblemBase : public CardinalProblem, public PostprocessorInterface */ openmc::TallyEstimator tallyEstimator(tally::TallyEstimatorEnum estimator) const; + /** + * Convert a tally estimator to a string (for output purposes). + * @param[in] estimator OpenMC tally estimator enum + * @return a string form of the OpenMC tally estimator enum + */ + std::string estimatorToString(openmc::TallyEstimator estimator) const; + /// Run a k-eigenvalue OpenMC simulation void externalSolve() override; @@ -184,13 +190,6 @@ class OpenMCProblemBase : public CardinalProblem, public PostprocessorInterface */ bool cellIsVoid(const cellInfo & cell_info) const; - /** - * Get the cell instance filter corresponding to provided cells - * @param[in] tally_cells cells to add to the filter - * @return cell instance filter - */ - openmc::Filter * cellInstanceFilter(const std::vector & tally_cells) const; - /** * Whether this cell has zero instances * @param[in] cell_info cell info @@ -347,16 +346,6 @@ class OpenMCProblemBase : public CardinalProblem, public PostprocessorInterface /// Set the tally nuclides for any tallies being modified via MOOSE void sendTallyNuclidesToOpenMC(); - /** - * Add tally - * @param[in] score score type - * @param[in] filters tally filters - * @param[in] estimator estimator - * @return tally, which has been added to OpenMC, but may want to still be queried from Cardinal - */ - openmc::Tally * addTally(const std::vector & score, - std::vector & filters, const openmc::TallyEstimator & estimator); - /** * Set an auxiliary elemental variable to a specified value * @param[in] var_num variable number @@ -380,9 +369,6 @@ class OpenMCProblemBase : public CardinalProblem, public PostprocessorInterface /// Whether to print diagnostic information about model setup and the transfers const bool & _verbose; - /// Type of tally to apply to extract score from OpenMC - const tally::TallyTypeEnum _tally_type; - /// Power by which to normalize the OpenMC results, for k-eigenvalue mode const Real * _power; diff --git a/include/tallies/CellTally.h b/include/tallies/CellTally.h new file mode 100644 index 000000000..41331d1c6 --- /dev/null +++ b/include/tallies/CellTally.h @@ -0,0 +1,93 @@ +/********************************************************************/ +/* SOFTWARE COPYRIGHT NOTIFICATION */ +/* Cardinal */ +/* */ +/* (c) 2021 UChicago Argonne, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by UChicago Argonne, LLC */ +/* Under Contract No. DE-AC02-06CH11357 */ +/* With the U. S. Department of Energy */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See LICENSE for full restrictions */ +/********************************************************************/ + +#pragma once + +#include "TallyBase.h" +#include "OpenMCCellAverageProblem.h" + +#include "openmc/tallies/filter_cell.h" + +class CellTally : public TallyBase +{ +public: + static InputParameters validParams(); + + CellTally(const InputParameters & parameters); + + /** + * A function to generate the cell filter needed by this object. + * @return a pair where the first entry is the filter index in the global filter array and the + * second entry is an OpenMC distributed cell filter + */ + virtual std::pair spatialFilter() override; + + /** + * A function which stores the results of this tally into the created + * auxvariables. + * @param[in] var_numbers variables which the tally will store results in + * @param[in] local_score index into the tally's local array of scores which represents the + * current score being stored + * @param[in] global_score index into the global array of tally results which represents the + * current score being stored + * @param[in] output_type the output type + */ + virtual Real storeResults(const std::vector & var_numbers, + unsigned int local_score, + unsigned int global_score, + const std::string & output_type) override; + +protected: + /** + * Loop over all the OpenMC cells and determine if a cell maps to more than one subdomain + * that also has different tally settings (i.e. we would not know whether to add or not to + * add tallies to the cell). + */ + void checkCellMappedSubdomains(); + + /** + * Loop over all the OpenMC cells and find those for which we should add tallies. + * @return cells to which we should add tallies + */ + std::vector getTallyCells() const; + + /// Blocks for which to add cell tallies. + std::unordered_set _tally_blocks; + + /// Whether a cell index, instance pair should be added to the tally filter + std::map _cell_has_tally; + + /// OpenMC mesh filter for this unstructured mesh tally. + openmc::CellInstanceFilter * _cell_filter; + + /** + * Whether to check that the [Mesh] volume each cell tally maps to is identical. + * This is a useful helper function for OpenMC models where each cell tally has the + * same volume (often the case for many reactor geometries). If the OpenMC model + * cell tallies all are of the same spatial size, it's still possible that they + * can map to different volumes in the MOOSE mesh if the MOOSE elements don't line + * up with the edges of the OpenMC cells. Different volumes then can distort the + * volume normalization that we do to convert the fission power to a volumetric + * power (in a perfect world, we would actually divide OpenMC's tallies by the + * results of a stochastic volume calculation in OpenMC, but that is too expensive). + */ + const bool & _check_equal_mapped_tally_volumes; + + /// Absolute tolerance for checking equal tally mapped volumes + const Real & _equal_tally_volume_abs_tol; +}; diff --git a/include/tallies/MeshTally.h b/include/tallies/MeshTally.h new file mode 100644 index 000000000..bd55ec46d --- /dev/null +++ b/include/tallies/MeshTally.h @@ -0,0 +1,93 @@ +/********************************************************************/ +/* SOFTWARE COPYRIGHT NOTIFICATION */ +/* Cardinal */ +/* */ +/* (c) 2021 UChicago Argonne, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by UChicago Argonne, LLC */ +/* Under Contract No. DE-AC02-06CH11357 */ +/* With the U. S. Department of Energy */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See LICENSE for full restrictions */ +/********************************************************************/ + +#pragma once + +#include "TallyBase.h" +#include "OpenMCCellAverageProblem.h" + +#include "openmc/tallies/filter_mesh.h" + +class MeshTally : public TallyBase +{ +public: + static InputParameters validParams(); + + MeshTally(const InputParameters & parameters); + + /** + * A function to generate the cell filter needed by this object. + * @return a pair where the first entry is the filter index in the global filter array and the + * second entry is an OpenMC unstructured mesh filter + */ + virtual std::pair spatialFilter() override; + + /// A function to reset the tally. MeshTally overrides this function to delete the OpenMC mesh. + virtual void resetTally() override; + + /** + * A function which stores the results of this tally into the created + * auxvariables. + * @param[in] var_numbers variables which the tally will store results in + * @param[in] local_score index into the tally's local array of scores which represents the + * current score being stored + * @param[in] global_score index into the global array of tally results which represents the + * current score being stored + * @param[in] output_type the output type + */ + virtual Real storeResults(const std::vector & var_numbers, + unsigned int local_score, + unsigned int global_score, + const std::string & output_type) override; + +protected: + /** + * Check the setup of the mesh template and translations. Because a simple copy transfer + * is used to write a mesh tally onto the [Mesh], we require that the + * meshes are identical - both in terms of the element ordering and the actual dimensions of + * each element. This function performs as many checks as possible to ensure that the meshes + * are indeed identical. + */ + void checkMeshTemplateAndTranslations() const; + + /** + * Mesh template file to use for creating mesh tallies in OpenMC; currently, this mesh + * must be identical to the mesh used in the [Mesh] block because a simple copy transfer + * is used to extract the tallies and put on the application's mesh in preparation for + * a transfer to another MOOSE app. If not set, this indicates that tallying will be + * performed directly on the [Mesh]. + * TODO: allow the mesh to not be identical, both in terms of using different units + * and more general differences like not having a particular phase present + */ + const std::string * _mesh_template_filename = nullptr; + + /// The translation to apply to the mesh template. + Point _mesh_translation; + + /// The index into an array of mesh translations. + unsigned int _instance; + + /// The index of the mesh added by this tally. + unsigned int _mesh_index; + + /// OpenMC mesh filter for this unstructured mesh tally. + openmc::MeshFilter * _mesh_filter; + + /// OpenMC unstructured mesh instance for use with mesh tallies + const openmc::LibMesh * _mesh_template; +}; diff --git a/include/tallies/TallyBase.h b/include/tallies/TallyBase.h new file mode 100644 index 000000000..b06ed7cb0 --- /dev/null +++ b/include/tallies/TallyBase.h @@ -0,0 +1,268 @@ +/********************************************************************/ +/* SOFTWARE COPYRIGHT NOTIFICATION */ +/* Cardinal */ +/* */ +/* (c) 2021 UChicago Argonne, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by UChicago Argonne, LLC */ +/* Under Contract No. DE-AC02-06CH11357 */ +/* With the U. S. Department of Energy */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See LICENSE for full restrictions */ +/********************************************************************/ + +#pragma once + +#include "MooseObject.h" +#include "CardinalEnums.h" + +#include "openmc/tallies/tally.h" +#include "xtensor/xview.hpp" + +/// Forward declarations. +class OpenMCCellAverageProblem; +class MooseMesh; +class AuxiliarySystem; + +class TallyBase : public MooseObject +{ +public: + static InputParameters validParams(); + + TallyBase(const InputParameters & parameters); + + /** + * A function which the derivied tally must override to create the OpenMC spatial filter + * the object maps to. + * @return a pair where the first entry is the filter index in the global filter array and the + * second entry is the OpenMC filter + */ + virtual std::pair spatialFilter() = 0; + + /** + * A function to initialize the tally object. Override with care. + */ + virtual void initializeTally(); + + /** + * A function to reset the tally object. Override with care. + */ + virtual void resetTally(); + + /** + * A function which stores the results of this tally into the created + * auxvariables. This must be implemented by a derived class. + * @param[in] var_numbers variables which the tally will store results in + * @param[in] local_score index into the tally's local array of scores which represents the + * current score being stored + * @param[in] global_score index into the global array of tally results which represents the + * current score being stored + * @param[in] output_type the output type + */ + virtual Real storeResults(const std::vector & var_numbers, + unsigned int local_score, + unsigned int global_score, + const std::string & output_type) = 0; + + /** + * Add a score to this tally. + * @param[in] score score to add + */ + void addScore(const std::string & score); + + /** + * A function which computes and stores the sum and mean of the tally across all bins for a + * particular score. + */ + void computeSumAndMean(); + + /** + * Relax the tally and normalize it according to some normalization factor 'norm'. This tends to + * either be the sum of the over all bins OR a global tally over the entire problem. + * + * NOTE: This function relaxes the tally _distribution_, and not the actual magnitude of the sum. + * That is, we relax the shape distribution and then multiply it by the power + * (for k-eigenvalue) or source strength (for fixed source) of the current step before + * applying it to MOOSE. If the magnitude of the power or source strength is constant in time, + * there is zero error in this. But if the magnitude of the tally varies in time, we are basically + * relaxing the distribution of the tally, but then multiplying it by the _current_ mean tally + * magnitude. + * + * There will be very small errors in these approximations unless the power/source strength + * change dramatically with iteration. But because relaxation is itself a numerical approximation, + * this is still inconsequential at the end of the day as long as your problem has converged + * the relaxed tally to the raw (unrelaxed) tally. + * @param[in] local_score the local index of the current score to normalize + * @param[in] alpha the relaxation factor + * @param[in] norm the normalization factor + */ + void relaxAndNormalizeTally(unsigned int local_score, const Real & alpha, const Real & norm); + + /** + * Get the OpenMC tally that this object wraps. + * @return the OpenMC tally object + */ + const openmc::Tally * getWrappedTally() const; + + /** + * Get the list of scores this tally uses. + * @return list of scores this tally uses + */ + const std::vector & getScores() const { return _tally_score; } + + /** + * Gets the auxvariable names for use in creating and storing tally results. + * This allows for the splitting of tally results into energy bins, angular bins, etc. + * + * @return vector of variable names to be associated with this tally + */ + const std::vector & getAuxVarNames() const { return _tally_name; } + + /** + * Gets the output names to append to the end of the '_tally_name' when adding tally auxvariables + * for additional outputs. + * @return additional tally outputs + */ + const std::vector & getOutputs() const { return _output_name; } + + /** + * Get the estimator used in this tally. + * @return the tally estimator + */ + openmc::TallyEstimator getTallyEstimator() const { return _estimator; } + + /** + * Get the mean for a score summed over all bins. + * @param[in] local_score the index representing a tally score + * @return mean for a score summed over all bins. + */ + const Real & getMean(unsigned int local_score) const { return _local_mean_tally[local_score]; } + + /** + * Get the sum for a score summed over all bins. + * @param[in] local_score the index representing a tally score + * @return sum for a score summed over all bins. + */ + const Real & getSum(unsigned int local_score) const { return _local_sum_tally[local_score]; } + + /** + * Check to see if this tally uses a trigger or not. + * @return whether this tally uses a trigger or not + */ + bool hasTrigger() const { return _tally_trigger != nullptr; } + + /** + * Check to see if this tally adds additional output variables or not. + * @return whether this tally adds additional output variables or not + */ + bool hasOutputs() const { return _has_outputs; } + + /** + * Check to see if the user has requested special names for the tallies. + * @return whether this tally names stored values something other than '_tally_score' + */ + bool renamesTallyVars() const { return _renames_tally_vars; } + +protected: + /** + * Set an auxiliary elemental variable to a specified value + * @param[in] var_num variable number + * @param[in] elem_ids element IDs to set + * @param[in] value value to set + */ + void fillElementalAuxVariable(const unsigned int & var_num, + const std::vector & elem_ids, + const Real & value); + + /** + * Applies triggers to a tally. This is often the local tally wrapped by this object. + * @param[in] tally the tally to apply triggers to + */ + void applyTriggersToLocalTally(openmc::Tally * tally); + + /// The OpenMCCellAverageProblem using the tally system. + OpenMCCellAverageProblem & _openmc_problem; + + /// The MooseMesh. + MooseMesh & _mesh; + + /// The aux system. + AuxiliarySystem & _aux; + + /// The OpenMC estimator to use with this tally. + openmc::TallyEstimator _estimator; + + /// OpenMC tally score(s) to use with this tally. + std::vector _tally_score; + + /// Auxiliary variable name(s) for this tally. + std::vector _tally_name; + + /// The OpenMC tally object this class wraps. + openmc::Tally * _local_tally = nullptr; + + /// The index of the OpenMC tally this object wraps. + unsigned int _local_tally_index; + + /// The index of the first filter added by this tally. + unsigned int _filter_index; + + /// Sum value of this tally across all bins. Indexed by score. + std::vector _local_sum_tally; + + /** + * Mean value of this tally across all bins; only used for fixed source mode. + * Indexed by score. + */ + std::vector _local_mean_tally; + + /** + * Type of trigger to apply to OpenMC tallies to indicate when + * the simulation is complete. These can be used to on-the-fly adjust the number + * of active batches in order to reach some desired criteria (which is specified + * by this parameter). + */ + const MultiMooseEnum * _tally_trigger; + + /** + * Thresholds to use for accepting this tally when using triggers. Indexed by + * score. + */ + std::vector _tally_trigger_threshold; + + /** + * Current fixed point iteration tally result; for instance, when using constant + * relaxation, the tally is updated as: + * q(n+1) = (1-a) * q(n) + a * PHI(q(n), s) + * where q(n+1) is _current_tally, a is the relaxation factor, q(n) + * is _previous_tally, and PHI is the most-recently-computed tally result + * (the _current_raw_tally). + */ + std::vector> _current_tally; + + /// Previous fixed point iteration tally result (after relaxation) + std::vector> _previous_tally; + + /// Current "raw" tally output from Monte Carlo solution + std::vector> _current_raw_tally; + + /// Current "raw" tally standard deviation + std::vector> _current_raw_tally_std_dev; + + /// Whether this tally stores results in variables names something other than '_tally_score'. + const bool _renames_tally_vars; + + /// Whether this tally has additional outputs or not. + const bool _has_outputs; + + /// Suffixes to apply to 'tally_name' in order to name the fields in the 'output'. + std::vector _output_name; + + /// Tolerance for setting zero tally + static constexpr Real ZERO_TALLY_THRESHOLD = 1e-12; +}; diff --git a/src/actions/AddTallyAction.C b/src/actions/AddTallyAction.C new file mode 100644 index 000000000..c5f4579ec --- /dev/null +++ b/src/actions/AddTallyAction.C @@ -0,0 +1,159 @@ +/********************************************************************/ +/* SOFTWARE COPYRIGHT NOTIFICATION */ +/* Cardinal */ +/* */ +/* (c) 2021 UChicago Argonne, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by UChicago Argonne, LLC */ +/* Under Contract No. DE-AC02-06CH11357 */ +/* With the U. S. Department of Energy */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See LICENSE for full restrictions */ +/********************************************************************/ + +#ifdef ENABLE_OPENMC_COUPLING +#include "AddTallyAction.h" + +#include "OpenMCCellAverageProblem.h" +#include "DelimitedFileReader.h" + +registerMooseAction("CardinalApp", AddTallyAction, "add_tallies"); + +InputParameters +AddTallyAction::validParams() +{ + auto params = MooseObjectAction::validParams(); + params.addClassDescription("Adds tally(s) for use in simulations containing an " + "OpenMCCellAverageProblem."); + /** + * These params are used to add multiple mesh tallies that use the same mesh but are + * translated through the domain. + */ + params.addParam>( + "mesh_translations", + "Coordinates to which each mesh template should be " + "translated, if multiple unstructured meshes " + "are desired. Units must match those used to define the [Mesh]."); + params.addParam>( + "mesh_translations_file", + "File providing the coordinates to which each mesh " + "template should be translated, if multiple " + "unstructured meshes are desired. Units must match those used to define the [Mesh]"); + + return params; +} + +AddTallyAction::AddTallyAction(const InputParameters & parameters) : MooseObjectAction(parameters) +{ + if (_type == "MeshTally") + { + if (isParamValid("mesh_translations") && isParamValid("mesh_translations_file")) + mooseError("Both 'mesh_translations' and 'mesh_translations_file' cannot be specified"); + + fillMeshTranslations(); + } + else + { + if (isParamValid("mesh_translations") || isParamValid("mesh_translations_file")) + mooseError("Mesh translations only apply to mesh-based tallies. 'mesh_translations' / " + "'mesh_translations_file' cannot be specified"); + } +} + +void +AddTallyAction::act() +{ + if (_current_task == "add_tallies") + { + if (_type == "MeshTally") + for (unsigned int i = 0; i < _mesh_translations.size(); ++i) + addMeshTally(i, _mesh_translations[i]); + else + addTally(); + } +} + +void +AddTallyAction::addMeshTally(unsigned int instance, const Point & translation) +{ + auto openmc_problem = dynamic_cast(_problem.get()); + + if (!openmc_problem) + mooseError("The simulation must use an OpenMCCellAverageProblem when using the tally system!"); + + std::string obj_name = _name; + if (_mesh_translations.size() > 1) + { + obj_name += "_" + Moose::stringify(instance); + _moose_object_pars.set("instance") = instance; + _moose_object_pars.set("mesh_translation") = translation * openmc_problem->scaling(); + } + + _moose_object_pars.set("_openmc_problem") = openmc_problem; + openmc_problem->addTallyObject(_type, obj_name, _moose_object_pars); +} + +void +AddTallyAction::addTally() +{ + auto openmc_problem = dynamic_cast(_problem.get()); + + if (!openmc_problem) + mooseError("The simulation must use an OpenMCCellAverageProblem when using the tally system!"); + + _moose_object_pars.set("_openmc_problem") = openmc_problem; + openmc_problem->addTallyObject(_type, _name, _moose_object_pars); +} + +void +AddTallyAction::fillMeshTranslations() +{ + if (isParamValid("mesh_translations")) + { + _mesh_translations = getParam>("mesh_translations"); + if (_mesh_translations.empty()) + mooseError("mesh_translations cannot be empty!"); + } + else if (isParamValid("mesh_translations_file")) + { + std::vector mesh_translations_file = + getParam>("mesh_translations_file"); + if (mesh_translations_file.empty()) + mooseError("mesh_translations_file cannot be empty!"); + + for (const auto & f : mesh_translations_file) + { + MooseUtils::DelimitedFileReader file(f, &_communicator); + file.setFormatFlag(MooseUtils::DelimitedFileReader::FormatFlag::ROWS); + file.read(); + + const std::vector> & data = file.getData(); + readMeshTranslations(data); + } + } + else + _mesh_translations = {Point(0.0, 0.0, 0.0)}; +} + +void +AddTallyAction::readMeshTranslations(const std::vector> & data) +{ + for (const auto & d : data) + { + if (d.size() != OpenMCCellAverageProblem::DIMENSION) + paramError("mesh_translations_file", + "All entries in 'mesh_translations_file' " + "must contain exactly ", + OpenMCCellAverageProblem::DIMENSION, + " coordinates."); + + // OpenMCCellAverageProblem::DIMENSION will always be 3 + _mesh_translations.push_back(Point(d[0], d[1], d[2])); + } +} +#endif diff --git a/src/base/CardinalApp.C b/src/base/CardinalApp.C index b88bbd455..c8b58643a 100644 --- a/src/base/CardinalApp.C +++ b/src/base/CardinalApp.C @@ -176,6 +176,15 @@ CardinalApp::associateSyntaxInner(Syntax & syntax, ActionFactory & /* action_fac registerSyntax("VolumetricHeatSourceICAction", "Cardinal/ICs/VolumetricHeatSource"); registerSyntax("BulkEnergyConservationICAction", "Cardinal/ICs/BulkEnergyConservation"); +// Add the [Tallies] block +#ifdef ENABLE_OPENMC_COUPLING + registerSyntaxTask("AddTallyAction", "Problem/Tallies/*", "add_tallies"); + registerMooseObjectTask("add_tallies", Tally, false); + addTaskDependency("add_tallies", "init_displaced_problem"); + // Can only add external auxvars after the tallies have been added. + addTaskDependency("add_external_aux_variables", "add_tallies"); +#endif + registerTask("add_heat_source_ic", false /* is required */); addTaskDependency("add_heat_source_ic", "add_ic"); diff --git a/src/base/OpenMCCellAverageProblem.C b/src/base/OpenMCCellAverageProblem.C index 35e6337fb..7e4be109b 100644 --- a/src/base/OpenMCCellAverageProblem.C +++ b/src/base/OpenMCCellAverageProblem.C @@ -20,6 +20,8 @@ #include "OpenMCCellAverageProblem.h" #include "DelimitedFileReader.h" +#include "TallyBase.h" +#include "AddTallyAction.h" #include "openmc/constants.h" #include "openmc/cross_sections.h" @@ -52,8 +54,6 @@ OpenMCCellAverageProblem::validParams() "Whether to automatically output the mapping from OpenMC cells to the " "[Mesh], usually for diagnostic purposes"); - params.addParam>( - "tally_blocks", "Subdomains for which to add tallies in OpenMC; only used with cell tallies"); params.addParam("check_tally_sum", "Whether to check consistency between the local tallies " "with a global tally sum"); @@ -90,12 +90,6 @@ OpenMCCellAverageProblem::validParams() "during the simulation, the mapping from OpenMC's cells to the mesh must be re-evaluated after " "each OpenMC run."); - params.addParam( - "tally_estimator", getTallyEstimatorEnum(), "Type of tally estimator to use in OpenMC"); - - params.addParam( - "tally_score", getTallyScoreEnum(), "Score(s) to use in the OpenMC tallies. If not specified, defaults to 'kappa_fission'"); - MooseEnum scores_heat( "heating heating_local kappa_fission fission_q_prompt fission_q_recoverable"); params.addParam( @@ -106,34 +100,6 @@ OpenMCCellAverageProblem::validParams() "eigenvalue mode. In other words, the " "source/sec is computed as (power divided by the global value of this tally)"); - params.addParam>( - "tally_name", "Auxiliary variable name(s) to use for OpenMC tallies. " - "If not specified, defaults to the names of the scores"); - params.addParam("mesh_template", - "Mesh tally template for OpenMC when using mesh tallies; " - "at present, this mesh must exactly match the mesh used in the " - "[Mesh] block because a one-to-one copy " - "is used to get OpenMC's tally results on the [Mesh]."); - params.addParam>( - "mesh_translations", - "Coordinates to which each mesh template should be " - "translated, if multiple unstructured meshes " - "are desired. Units must match those used to define the [Mesh]."); - params.addParam>( - "mesh_translations_file", - "File providing the coordinates to which each mesh " - "template should be translated, if multiple " - "unstructured meshes are desired. Units must match those used to define the [Mesh]"); - - MultiMooseEnum tally_trigger("rel_err none"); - params.addParam( - "tally_trigger", - tally_trigger, - "Trigger criterion to determine when OpenMC simulation is complete " - "based on tallies. If multiple scores are specified in 'tally_score, " - "this same trigger is applied to all scores."); - params.addRangeCheckedParam>( - "tally_trigger_threshold", "tally_trigger_threshold > 0", "Threshold for the tally trigger"); params.addParam( "k_trigger", getTallyTriggerEnum(), @@ -164,16 +130,6 @@ OpenMCCellAverageProblem::validParams() "Blocks corresponding to each of the 'density_variables'. If not specified, " "there will be no density feedback to OpenMC."); - params.addParam( - "check_equal_mapped_tally_volumes", - false, - "Whether to check if the tallied cells map to regions in the mesh of equal volume. " - "This can be helpful to ensure that the volume normalization of OpenMC's tallies doesn't " - "introduce any unintentional distortion just because the mapped volumes are different. " - "You should only set this to true if your OpenMC tally cells are all the same volume!"); - params.addRangeCheckedParam("equal_tally_volume_abs_tol", 1e-8, "equal_tally_volume_abs_tol > 0", - "Absolute tolerance for comparing tally volumes"); - params.addParam("cell_level", "Coordinate level in OpenMC (across the entire geometry) to use " "for identifying cells"); @@ -197,16 +153,6 @@ OpenMCCellAverageProblem::validParams() "Whether to check that your model does indeed have identical cell fills, allowing " "you to set 'identical_cell_fills' to speed up initialization"); - MultiMooseEnum openmc_outputs("unrelaxed_tally_std_dev unrelaxed_tally"); - params.addParam("output", - openmc_outputs, - "UNRELAXED field(s) to output from OpenMC for each tally score. " - "unrelaxed_tally_std_dev will write the standard deviation of " - "each tally into auxiliary variables " - "named *_std_dev. Unrelaxed_tally will write the raw unrelaxed " - "tally into auxiliary variables " - "named *_raw (replace * with 'tally_name')."); - params.addParam("relaxation", getRelaxationEnum(), "Type of relaxation to apply to the OpenMC solution"); @@ -241,8 +187,6 @@ OpenMCCellAverageProblem::OpenMCCellAverageProblem(const InputParameters & param _initial_condition( getParam("initial_properties").getEnum()), _relaxation(getParam("relaxation").getEnum()), - _tally_trigger(isParamValid("tally_trigger") ? &getParam("tally_trigger") - : nullptr), _k_trigger(getParam("k_trigger").getEnum()), _export_properties(getParam("export_properties")), _normalize_by_global(_run_mode == openmc::RunMode::FIXED_SOURCE @@ -253,8 +197,6 @@ OpenMCCellAverageProblem::OpenMCCellAverageProblem(const InputParameters & param isParamValid("check_tally_sum") ? getParam("check_tally_sum") : (_run_mode == openmc::RunMode::FIXED_SOURCE ? true : _normalize_by_global)), - _check_equal_mapped_tally_volumes(getParam("check_equal_mapped_tally_volumes")), - _equal_tally_volume_abs_tol(getParam("equal_tally_volume_abs_tol")), _relaxation_factor(getParam("relaxation_factor")), _has_identical_cell_fills(params.isParamSetByUser("identical_cell_fills")), _check_identical_cell_fills(getParam("check_identical_cell_fills")), @@ -262,12 +204,18 @@ OpenMCCellAverageProblem::OpenMCCellAverageProblem(const InputParameters & param _map_density_by_cell(getParam("map_density_by_cell")), _specified_density_feedback(params.isParamSetByUser("density_blocks")), _specified_temperature_feedback(params.isParamSetByUser("temperature_blocks")), - _needs_to_map_cells(_specified_density_feedback || _specified_temperature_feedback || - params.isParamSetByUser("tally_blocks")), + _needs_to_map_cells(_specified_density_feedback || _specified_temperature_feedback), _needs_global_tally(_check_tally_sum || _normalize_by_global), _volume_calc(nullptr), _symmetry(nullptr) { + // Look through the list of AddTallyActions to see if we have a CellTally. If so, we need to map + // cells. + const auto & actions = getMooseApp().actionWarehouse().getActions(); + for (const auto & act : actions) + _has_cell_tallies = act->getMooseObjectType() == "CellTally" || _has_cell_tallies; + _needs_to_map_cells = _needs_to_map_cells || _has_cell_tallies; + if (!_needs_to_map_cells) checkUnusedParam(params, "output_cell_mapping", @@ -300,162 +248,12 @@ OpenMCCellAverageProblem::OpenMCCellAverageProblem(const InputParameters & param "possible to apply relaxation to the OpenMC tallies because you might end up trying to add vectors " "of different length (and possibly spatial mapping)."); - if (_tally_type == tally::none) - { - std::vector ps = {"tally_blocks", - "check_tally_sum", - "normalize_by_global_tally", - "assume_separate_tallies", - "tally_estimator", - "tally_score", - "source_rate_normalization", - "tally_name", - "mesh_template", - "mesh_translations", - "mesh_translations_file", - "tally_trigger", - "tally_trigger_threshold", - "check_equal_mapped_tally_volumes", - "equval_tally_volume_abs_tol", - "output"}; - for (const auto & s : ps) - checkUnusedParam(params, s, "'tally_type = none'"); - } - if (_run_mode == openmc::RunMode::FIXED_SOURCE) checkUnusedParam(params, "normalize_by_global_tally", "running OpenMC in fixed source mode"); if (_run_mode != openmc::RunMode::EIGENVALUE && _k_trigger != trigger::none) mooseError("Cannot specify a 'k_trigger' for OpenMC runs that are not eigenvalue mode!"); - if (isParamValid("tally_score")) - { - const auto & scores = getParam("tally_score"); - for (const auto & score : scores) - _tally_score.push_back(enumToTallyScore(score)); - } - else - _tally_score = {"kappa-fission"}; - - bool heating = - std::find(_tally_score.begin(), _tally_score.end(), "heating") != _tally_score.end(); - - if (isParamValid("tally_estimator")) - { - auto estimator = getParam("tally_estimator").getEnum(); - - // not all tallies can use tracklength estimators - if (estimator == tally::tracklength) - { - if (_tally_type == tally::mesh) - mooseError("Tracklength estimators are currently incompatible with mesh tallies!"); - - if (openmc::settings::photon_transport && heating) - mooseError("Tracklength estimators are currently incompatible with photon transport and " - "heating scores! For more information: https://tinyurl.com/3wre3kwt"); - } - - _tally_estimator = tallyEstimator(estimator); - } - else - { - // set a default of tracklength, and use mandatory collision for mesh tallies and photon heating - _tally_estimator = openmc::TallyEstimator::TRACKLENGTH; - if (_tally_type == tally::mesh) - _tally_estimator = openmc::TallyEstimator::COLLISION; - if (heating && openmc::settings::photon_transport) - _tally_estimator = openmc::TallyEstimator::COLLISION; - } - - if (heating && !openmc::settings::photon_transport) - mooseWarning( - "When using the 'heating' score with photon transport disabled, energy deposition\n" - "from photons is neglected unless you specifically ran NJOY to produce MT=301 with\n" - "photon energy deposited locally (not true for any pre-packaged OpenMC data libraries\n" - "on openmc.org).\n\n" - "If you did NOT specifically run NJOY yourself with this customization, we recommend\n" - "using the 'heating_local' score instead, which will capture photon energy deposition.\n" - "Otherwise, you will underpredict the true energy deposition."); - - // need some special treatment for non-heating scores, in eigenvalue mode - bool has_non_heating_score = false; - for (const auto & t : _tally_score) - if (!isHeatingScore(t)) - has_non_heating_score = true; - - if (has_non_heating_score && _run_mode == openmc::RunMode::EIGENVALUE) - { - std::string non_heating_scores; - for (const auto & e : _tally_score) - { - if (!isHeatingScore(e)) - { - std::string l = e; - std::replace(l.begin(), l.end(), '-', '_'); - non_heating_scores += "" + l + ", "; - } - } - - if (non_heating_scores.length() > 0) - non_heating_scores.erase(non_heating_scores.length() - 2); - - checkRequiredParam(params, "source_rate_normalization", "using a non-heating tally (" + - non_heating_scores + ") in eigenvalue mode"); - const auto & norm = getParam("source_rate_normalization"); - - // If the score is already in tally_score, no need to do anything special. - // Otherwise, we need to add that score. - std::string n = enumToTallyScore(norm); - auto it = std::find(_tally_score.begin(), _tally_score.end(), n); - if (it != _tally_score.end()) - _source_rate_index = it - _tally_score.begin(); - else - { - _tally_score.push_back(n); - _source_rate_index = _tally_score.size() - 1; - - if (isParamValid("tally_name")) - mooseError("When specifying 'tally_name', the score indicated in " - "'source_rate_normalization' must be\n" - "listed in 'tally_score' so that we know what you want to name that score (", - norm, - ")"); - } - } - else - checkUnusedParam(params, "source_rate_normalization", "either running in fixed-source mode, or all tallies have units of eV/src"); - - if (isParamValid("tally_name")) - _tally_name = getParam>("tally_name"); - else - { - for (auto score : _tally_score) - { - std::replace(score.begin(), score.end(), '-', '_'); - _tally_name.push_back(score); - } - } - - if (_tally_name.size() != _tally_score.size()) - mooseError("'tally_name' must be the same length as 'tally_score'!"); - - if (has_non_heating_score && _run_mode == openmc::RunMode::EIGENVALUE) - { - // later, we populate the tally results in a loop. We will rely on the normalization - // tally being listed before the non-heating tally, so we swap entries so that the normalization - // tally is first - std::iter_swap(_tally_score.begin(), _tally_score.begin() + _source_rate_index); - std::iter_swap(_tally_name.begin(), _tally_name.begin() + _source_rate_index); - } - - _source_rate_index = 0; - checkDuplicateEntries(_tally_name, "tally_name"); - checkDuplicateEntries(_tally_score, "tally_score"); - - if (_tally_type == tally::mesh) - if (_mesh.getMesh().allow_renumbering() && !_mesh.getMesh().is_replicated()) - mooseError("Mesh tallies currently require 'allow_renumbering = false' to be set in the [Mesh]!"); - if (_assume_separate_tallies && _needs_global_tally) paramError("assume_separate_tallies", "Cannot assume separate tallies when either of 'check_tally_sum' or" @@ -516,9 +314,6 @@ OpenMCCellAverageProblem::OpenMCCellAverageProblem(const InputParameters & param _n_particles_1 = nParticles(); - // set the parameters needed for tally triggers - getTallyTriggerParameters(params); - if (_relaxation != relaxation::constant) checkUnusedParam(params, "relaxation_factor", "not using constant relaxation"); @@ -537,77 +332,6 @@ OpenMCCellAverageProblem::OpenMCCellAverageProblem(const InputParameters & param "Entries in 'identical_cell_fills' cannot be contained in 'density_blocks'; the\n" "identical fill universe optimization is not yet implemented for density feedback."); - switch (_tally_type) - { - case tally::none: - { - break; - } - case tally::cell: - { - checkRequiredParam(params, "tally_blocks", "using cell tallies"); - checkUnusedParam(params, {"mesh_template", "mesh_translations", "mesh_translations_file"}, - "using cell tallies"); - - readBlockParameters("tally_blocks", _tally_blocks); - - // If not specified, add tallies to all MOOSE blocks - if (!isParamValid("tally_blocks")) - for (const auto & s : _mesh.meshSubdomains()) - _tally_blocks.insert(s); - - break; - } - case tally::mesh: - { - checkUnusedParam(params, "tally_blocks", "using mesh tallies"); - - if (isParamValid("mesh_template")) - { - _mesh_template_filename = &getParam("mesh_template"); - - if (isParamValid("mesh_translations") && isParamValid("mesh_translations_file")) - mooseError("Both 'mesh_translations' and 'mesh_translations_file' cannot be specified"); - } - else - { - if (std::abs(_scaling - 1.0) > 1e-6) - mooseError("Directly tallying on the [Mesh] is only supported for 'scaling' of unity. " - "Instead, please make a file containing your tally mesh and set it with " - "'mesh_template'. You can generate a mesh file corresponding to the [Mesh] " - "by running:\n\ncardinal-opt -i " + - _app.getFileName() + " --mesh-only"); - - // for distributed meshes, each rank only owns a portion of the mesh information, but - // OpenMC wants the entire mesh to be available on every rank. We might be able to add - // this feature in the future, but will need to investigate - if (!_mesh.getMesh().is_replicated()) - mooseError("Directly tallying on the [Mesh] block by OpenMC is not yet supported " - "for distributed meshes!"); - - // if user does not provide a 'mesh_template', just use the [Mesh] block, which means these - // other parameters are ignored. To simplify logic elsewhere in the code, we throw an error - if (isParamValid("mesh_translations")) - mooseError("When reading the tally mesh from the [Mesh] block, the 'mesh_translations' " - "cannot be specified!"); - - if (isParamValid("mesh_translations_file")) - mooseError("When reading the tally mesh from the [Mesh] block, the 'mesh_translations_file' " - "cannot be specified!"); - } - - if (_check_equal_mapped_tally_volumes) - mooseWarning( - "The 'check_equal_mapped_tally_volumes' parameter is unused when using mesh tallies!"); - - fillMeshTranslations(); - - break; - } - default: - mooseError("Unhandled TallyTypeEnum in OpenMCCellAverageProblem!"); - } - if (_needs_to_map_cells) { if (isParamValid("cell_level") == isParamValid("lowest_cell_level")) @@ -641,24 +365,6 @@ OpenMCCellAverageProblem::OpenMCCellAverageProblem(const InputParameters & param "lowest_cell_level", "'temperature_blocks', 'density_blocks', and 'tally_blocks' are empty"); } - - if (isParamValid("output")) - { - _outputs = &getParam("output"); - - // names of output are appended to ends of 'tally_name' - for (const auto & o : *_outputs) - { - std::string name = o; - - if (o == "UNRELAXED_TALLY_STD_DEV") - _output_name.push_back("std_dev"); - else if (o == "UNRELAXED_TALLY") - _output_name.push_back("raw"); - else - mooseError("Unhandled OutputEnum in OpenMCCellAverageProblem!"); - } - } } void @@ -751,6 +457,9 @@ OpenMCCellAverageProblem::initialSetup() mooseError("The 'symmetry_mapper' user object has to be of type SymmetryPointGenerator!"); } + // Get triggers. + getTallyTriggerParameters(_pars); + setupProblem(); #ifdef ENABLE_DAGMC @@ -869,39 +578,13 @@ OpenMCCellAverageProblem::setupProblem() subdomainsToMaterials(); initializeTallies(); - - checkMeshTemplateAndTranslations(); } void OpenMCCellAverageProblem::getTallyTriggerParameters(const InputParameters & parameters) { - if (isParamValid("tally_trigger") != isParamValid("tally_trigger_threshold")) - mooseError("You must either specify none or both of 'tally_trigger' and " - "'tally_trigger_threshold'. You have specified only one."); - - bool has_tally_trigger = false; - if (_tally_trigger) - { - _tally_trigger_threshold = getParam>("tally_trigger_threshold"); - - if (_tally_trigger->size() != _tally_score.size()) - mooseError("'tally_trigger' (size " + std::to_string(_tally_trigger->size()) + - ") must have the same length as 'tally_score' (size " + - std::to_string(_tally_score.size()) + ")"); - - if (_tally_trigger_threshold.size() != _tally_score.size()) - mooseError("'tally_trigger_threshold' (size " + - std::to_string(_tally_trigger_threshold.size()) + - ") must have the same length as 'tally_score' (size " + - std::to_string(_tally_score.size()) + ")"); - - for (unsigned int s = 0; s < _tally_trigger->size(); ++s) - if ((*_tally_trigger)[s] != "none") - has_tally_trigger = true; - } - // parameters needed for k triggers + bool has_tally_trigger = false; if (_k_trigger != trigger::none) { checkRequiredParam(parameters, "k_trigger_threshold", "using a k trigger"); @@ -911,6 +594,10 @@ OpenMCCellAverageProblem::getTallyTriggerParameters(const InputParameters & para else checkUnusedParam(parameters, "k_trigger_threshold", "not using a k trigger"); + // Check to see if any of the local tallies have triggers. + for (const auto & local_tally : _local_tallies) + has_tally_trigger = has_tally_trigger || local_tally->hasTrigger(); + if (has_tally_trigger) // at least one trigger { openmc::settings::trigger_on = true; @@ -945,128 +632,6 @@ OpenMCCellAverageProblem::checkEmptyVector(const std::vector & vector, mooseError(name + " cannot be empty!"); } -void -OpenMCCellAverageProblem::fillMeshTranslations() -{ - if (isParamValid("mesh_translations")) - { - _mesh_translations = getParam>("mesh_translations"); - checkEmptyVector(_mesh_translations, "mesh_translations"); - } - else if (isParamValid("mesh_translations_file")) - { - std::vector mesh_translations_file = - getParam>("mesh_translations_file"); - checkEmptyVector(mesh_translations_file, "mesh_translations_file"); - - for (const auto & f : mesh_translations_file) - { - MooseUtils::DelimitedFileReader file(f, &_communicator); - file.setFormatFlag(MooseUtils::DelimitedFileReader::FormatFlag::ROWS); - file.read(); - - const std::vector> & data = file.getData(); - readMeshTranslations(data); - } - } - else - _mesh_translations = {Point(0.0, 0.0, 0.0)}; - - // convert to appropriate units - for (auto & m : _mesh_translations) - m *= _scaling; -} - -void -OpenMCCellAverageProblem::checkMeshTemplateAndTranslations() const -{ - // we can do some rudimentary checking on the mesh template by comparing the centroid - // coordinates compared to centroids in the [Mesh] (because right now, we just doing a simple - // copy transfer that necessitates the meshes to have the same elements in the same order). In - // other words, you might have two meshes that represent the same geometry, the element ordering - // could be different. - unsigned int offset = 0; - for (unsigned int i = 0; i < _mesh_filters.size(); ++i) - { - const auto & filter = _mesh_filters[i]; - - for (int e = 0; e < filter->n_bins(); ++e) - { - auto elem_ptr = _mesh.queryElemPtr(offset + e); - - // if element is not on this part of the distributed mesh, skip it - if (!elem_ptr) - continue; - - const auto pt = _mesh_template->centroid(e); - Point centroid_template = {pt[0], pt[1], pt[2]}; - - // The translation applied in OpenMC isn't actually registered in the mesh itself; - // it is always added on to the point, so we need to do the same here - centroid_template += _mesh_translations[i]; - - // because the mesh template and [Mesh] may be in different units, we need - // to adjust the [Mesh] by the scaling factor before doing a comparison. - Point centroid_mesh = elem_ptr->vertex_average() * _scaling; - - // if the centroids are the same except for a factor of 'scaling', then we can - // guess that the mesh_template is probably not in units of centimeters - if (_specified_scaling) - { - // if scaling was applied correctly, then each calculation of 'scaling' here should equal 1. - // Otherwise, if they're all the same, then 'scaling_x' is probably the factor by which the - // mesh_template needs to be multiplied, so we can print a helpful error message - bool incorrect_scaling = true; - for (unsigned int j = 0; j < DIMENSION; ++j) - { - Real scaling = centroid_mesh(j) / centroid_template(j); - incorrect_scaling = incorrect_scaling && !MooseUtils::absoluteFuzzyEqual(scaling, 1.0); - } - - if (incorrect_scaling) - mooseError("The centroids of the 'mesh_template' differ from the " - "centroids of the [Mesh] by a factor of " + - Moose::stringify(centroid_mesh(0) / centroid_template(0)) + - ".\nDid you forget that the 'mesh_template' must be in " - "the same units as the [Mesh]?"); - } - - // check if centroids are the same - bool different_centroids = false; - for (unsigned int j = 0; j < DIMENSION; ++j) - different_centroids = different_centroids || !MooseUtils::absoluteFuzzyEqual( - centroid_mesh(j), centroid_template(j)); - - if (different_centroids) - mooseError( - "Centroid for element " + Moose::stringify(offset + e) + " in the [Mesh] (cm): " + - printPoint(centroid_mesh) + "\ndoes not match centroid for element " + - Moose::stringify(e) + " in 'mesh_template' " + Moose::stringify(i) + - " (cm): " + printPoint(centroid_template) + - "!\n\nThe copy transfer requires that the [Mesh] and 'mesh_template' be identical."); - } - - offset += filter->n_bins(); - } -} - -void -OpenMCCellAverageProblem::readMeshTranslations(const std::vector> & data) -{ - for (const auto & d : data) - { - if (d.size() != DIMENSION) - paramError("mesh_translations_file", - "All entries in 'mesh_translations_file' " - "must contain exactly ", - DIMENSION, - " coordinates."); - - // DIMENSION will always be 3 - _mesh_translations.push_back(Point(d[0], d[1], d[2])); - } -} - void OpenMCCellAverageProblem::readBlockParameters(const std::string name, std::unordered_set & blocks) @@ -1424,7 +989,7 @@ OpenMCCellAverageProblem::printAuxVariableIO() return; if (!(_specified_density_feedback || _specified_temperature_feedback || - _tally_type != tally::none)) + _local_tallies.size() > 0)) return; _console << "\n ===================> AUXVARIABLES FOR OPENMC I/O <===================\n" @@ -1457,14 +1022,29 @@ OpenMCCellAverageProblem::printAuxVariableIO() _console << std::endl; } - if (_tally_type != tally::none) + if (_local_tallies.size() > 0) { + _console << " Tally Name: Cardinal tally object name" << std::endl; _console << " Tally Score: OpenMC tally score" << std::endl; _console << " AuxVariable: variable where this score is written\n" << std::endl; - VariadicTable tallies({"Tally Score", "AuxVariable"}); - for (unsigned int i = 0; i < _tally_name.size(); ++i) - tallies.addRow(_tally_score[i], _tally_name[i]); + VariadicTable tallies( + {"Tally Name", "Tally Score", "AuxVariable"}); + for (unsigned int i = 0; i < _local_tallies.size(); ++i) + { + const auto & scores = _local_tallies[i]->getScores(); + const auto & names = _local_tallies[i]->getAuxVarNames(); + for (unsigned int j = 0; j < scores.size(); ++j) + { + if (names.size() == 0) + continue; + + if (j == 0) + tallies.addRow(_local_tallies[i]->name(), scores[j], names[j]); + else + tallies.addRow("", scores[j], names[j]); + } + } tallies.print(_console); } @@ -1612,51 +1192,6 @@ OpenMCCellAverageProblem::subdomainsToMaterials() } } -void -OpenMCCellAverageProblem::checkCellMappedSubdomains() -{ - // If the OpenMC cell maps to multiple subdomains that _also_ have different - // tally settings, we need to error because we are unsure of whether to add tallies or not; - // both of these need to be true to error - for (const auto & c : _cell_to_elem) - { - bool at_least_one_in_tallies = false; - bool at_least_one_not_in_tallies = false; - int block_in_tallies, block_not_in_tallies; - - auto cell_info = c.first; - for (const auto & s : _cell_to_elem_subdomain[cell_info]) - { - if (!at_least_one_in_tallies) - { - at_least_one_in_tallies = _tally_blocks.count(s) != 0; - block_in_tallies = s; - } - - if (!at_least_one_not_in_tallies) - { - at_least_one_not_in_tallies = _tally_blocks.count(s) == 0; - block_not_in_tallies = s; - } - - // can cut the search early if we've already hit multiple tally settings - if (at_least_one_in_tallies && at_least_one_not_in_tallies) - break; - } - - if (at_least_one_in_tallies && at_least_one_not_in_tallies) - mooseError("cell " + printCell(cell_info) + - " maps to blocks with different tally settings!\n" - "Block " + - Moose::stringify(block_in_tallies) + - " is in 'tally_blocks', but " - "block " + - Moose::stringify(block_not_in_tallies) + " is not."); - - _cell_has_tally[cell_info] = at_least_one_in_tallies; - } -} - void OpenMCCellAverageProblem::getMaterialFills() { @@ -1790,7 +1325,7 @@ OpenMCCellAverageProblem::initializeElementToCellMapping() // Get the element subdomains within each cell getCellMappedSubdomains(); - if (_cell_to_elem.size() == 0 && _tally_type == tally::cell) + if (_cell_to_elem.size() == 0 && _has_cell_tallies) mooseError("Did not find any overlap between MOOSE elements and OpenMC cells for " "the specified blocks!"); @@ -1851,10 +1386,6 @@ OpenMCCellAverageProblem::initializeElementToCellMapping() // Check that each cell maps to a single phase checkCellMappedPhase(); - - // Check that each cell maps to subdomain IDs that all have the same tally setting - if (_tally_type == tally::cell) - checkCellMappedSubdomains(); } void @@ -2138,7 +1669,7 @@ OpenMCCellAverageProblem::mapElemsToCells() // the type of couling) auto phase = elemFeedback(elem); - bool requires_mapping = phase != coupling::none || _tally_blocks.count(id); + bool requires_mapping = phase != coupling::none || _contains_cell_tally; // get the level in the OpenMC model to fetch mapped cell information. For // uncoupled regions, we know we will be successful in finding a cell (because @@ -2269,162 +1800,24 @@ OpenMCCellAverageProblem::getPointInCell() } } -std::vector -OpenMCCellAverageProblem::getTallyCells() const -{ - bool is_first_tally_cell = true; - cellInfo first_tally_cell; - Real mapped_tally_volume; - - std::vector tally_cells; - - for (const auto & c : _cell_to_elem) - { - auto cell_info = c.first; - - if (_cell_has_tally.at(cell_info)) - { - tally_cells.push_back(cell_info); - - if (is_first_tally_cell) - { - is_first_tally_cell = false; - first_tally_cell = cell_info; - mapped_tally_volume = _cell_to_elem_volume.at(cell_info); - } - - if (_check_equal_mapped_tally_volumes) - { - Real diff = std::abs(mapped_tally_volume - _cell_to_elem_volume.at(cell_info)); - bool absolute_diff = diff > _equal_tally_volume_abs_tol; - bool relative_diff = diff / mapped_tally_volume > 1e-3; - if (absolute_diff && relative_diff) - { - std::stringstream msg; - msg << "Detected un-equal mapped tally volumes!\n cell " << printCell(first_tally_cell) - << " maps to a volume of " - << Moose::stringify(_cell_to_elem_volume.at(first_tally_cell)) << " (cm3)\n cell " - << printCell(cell_info) << " maps to a volume of " - << Moose::stringify(_cell_to_elem_volume.at(cell_info)) - << " (cm3).\n\n" - "If the tallied cells in your OpenMC model are of identical volumes, this means " - "that you can get\n" - "distortion of the volumetric tally output. For instance, suppose you have " - "two equal-size OpenMC\n" - "cells which have the same volume - but each OpenMC cell maps to a MOOSE region " - "of different volume\n" - "just due to the nature of the centroid mapping scheme. Even if those two tallies " - "do actually have the\n" - "same value, the volumetric tally will be different because you'll be " - "dividing each tally by a\n" - "different mapped MOOSE volume.\n\n"; - - if (_symmetry) - msg << "NOTE: You have imposed symmetry, which means that you'll hit this error if any " - "of your tally\n" - "cells are cut by symmetry planes. If your tally cells would otherwise be the " - "same volume if NOT\n" - "imposing symmetry, or if your tally cells are not the same volume regardless, " - "you need to set\n" - "'check_equal_mapped_tally_volumes = false'."; - else - msg << "We recommend re-creating the mesh mirror to have an equal volume mapping of " - "MOOSE elements to each\n" - "OpenMC cell. Or, you can disable this check by setting " - "'check_equal_mapped_tally_volumes = false'."; - - mooseError(msg.str()); - } - } - } - } - - return tally_cells; -} - -void -OpenMCCellAverageProblem::addLocalTally(const std::vector & score, std::vector & filters) -{ - auto tally = addTally(score, filters, _tally_estimator); - _local_tally.push_back(tally); -} - -std::vector -OpenMCCellAverageProblem::meshFilter() -{ - std::unique_ptr tally_mesh = tallyMesh(_mesh_template_filename); - - _mesh_template = tally_mesh.get(); - _mesh_index = openmc::model::meshes.size(); - openmc::model::meshes.push_back(std::move(tally_mesh)); - - std::vector mesh_filters; - - for (unsigned int i = 0; i < _mesh_translations.size(); ++i) - { - const auto & translation = _mesh_translations[i]; - auto meshFilter = dynamic_cast(openmc::Filter::create("mesh")); - meshFilter->set_mesh(_mesh_index); - meshFilter->set_translation({translation(0), translation(1), translation(2)}); - mesh_filters.push_back(meshFilter); - } - - return mesh_filters; -} - void OpenMCCellAverageProblem::resetTallies() { - if (_tally_type == tally::none) + if (_local_tallies.size() == 0 && !_needs_global_tally) return; - // We create the global tally, and THEN the local tally. So we need to delete in - // reverse order + // We initialize tallies by forward iterating this vector. We need to delete them in reverse. + for (int i = _local_tallies.size() - 1; i >= 0; --i) + _local_tallies[i]->resetTally(); - auto idx = openmc::model::tallies.begin() + _local_tally_index; - switch (_tally_type) + // erase global tallies + if (_needs_global_tally) { - case tally::cell: + for (int i = _global_tally_index + _global_tally_scores.size() - 1; i >= 0; --i) { - // erase tally + auto idx = openmc::model::tallies.begin() + _global_tally_index + i; openmc::model::tallies.erase(idx); - - // erase filter - auto fidx = openmc::model::tally_filters.begin() + _filter_index; - openmc::model::tally_filters.erase(fidx); - break; } - case tally::mesh: - { - // erase tallies - for (int i = _mesh_translations.size() + _local_tally_index - 1; i >= _local_tally_index; --i) - { - auto midx = openmc::model::tallies.begin() + i; - openmc::model::tallies.erase(midx); - } - - // erase filters - int fi = _filter_index; // to get signed int for loop to work - for (int i = _mesh_translations.size() + fi - 1; i >= fi; i--) - { - auto fidx = openmc::model::tally_filters.begin() + i; - openmc::model::tally_filters.erase(fidx); - } - - // erase mesh - auto midx = openmc::model::meshes.begin() + _mesh_index; - openmc::model::meshes.erase(midx); - break; - } - default: - mooseError("Unhandled TallyTypeEnum in OpenMCCellAverageProblem!"); - } - - if (_needs_global_tally) - { - // erase tally - auto idx = openmc::model::tallies.begin() + _global_tally_index; - openmc::model::tallies.erase(idx); } } @@ -2434,105 +1827,30 @@ OpenMCCellAverageProblem::initializeTallies() // add trigger information for k, if present openmc::settings::keff_trigger.metric = triggerMetric(_k_trigger); - if (_tally_type == tally::none) + if (_local_tallies.size() == 0 && !_needs_global_tally) return; // create the global tally for normalization; we make sure to use the // same estimator as the local tally if (_needs_global_tally) { - _global_tally = openmc::Tally::create(); - _global_tally->set_scores(_tally_score); - _global_tally->estimator_ = _tally_estimator; - - _global_tally_index = openmc::model::tallies.size() - 1; - _global_sum_tally.resize(_tally_score.size()); - } - - _local_tally.clear(); + _global_tally_index = openmc::model::tallies.size(); - _local_sum_tally.resize(_tally_score.size()); - _local_mean_tally.resize(_tally_score.size()); - _current_tally.resize(_tally_score.size()); - _current_raw_tally.resize(_tally_score.size()); - _current_raw_tally_std_dev.resize(_tally_score.size()); - _previous_tally.resize(_tally_score.size()); - - // we have not added the local tally yet, so we do not have the "-1" here. This needs - // to be before the switch-case statement, because we may add > 1 mesh tally - _local_tally_index = openmc::model::tallies.size(); - _filter_index = openmc::model::tally_filters.size(); - - // create the local tally - switch (_tally_type) - { - case tally::cell: + _global_tallies.clear(); + for (unsigned int i = 0; i < _global_tally_scores.size(); ++i) { - auto tally_cells = getTallyCells(); - _console << "Adding cell tallies to blocks " + Moose::stringify(_tally_blocks) + " for " + - Moose::stringify(tally_cells.size()) + " cells... "; - - for (unsigned int i = 0; i < _tally_score.size(); ++i) - { - _current_tally[i].resize(1); - _current_raw_tally[i].resize(1); - _current_raw_tally_std_dev[i].resize(1); - _previous_tally[i].resize(1); - } - - std::vector filter = {cellInstanceFilter(tally_cells)}; - addLocalTally(_tally_score, filter); - - _console << "done" << std::endl; - - break; + _global_tallies.push_back(openmc::Tally::create()); + _global_tallies[i]->set_scores(_global_tally_scores[i]); + _global_tallies[i]->estimator_ = _global_tally_estimators[i]; } - case tally::mesh: - { - int n_translations = _mesh_translations.size(); - - std::string name = _mesh_template_filename ? *_mesh_template_filename : "the [Mesh]"; - std::string tally = n_translations > 1 ? "tallies" : "tally"; - _console << "\nAdding " << n_translations << " mesh " << tally << " based on " + name - << "... "; - for (unsigned int i = 0; i < _tally_score.size(); ++i) - { - _current_tally[i].resize(n_translations); - _current_raw_tally[i].resize(n_translations); - _current_raw_tally_std_dev[i].resize(n_translations); - _previous_tally[i].resize(n_translations); - } - - _mesh_filters.clear(); - const auto & filters = meshFilter(); - for (const auto & m : filters) - _mesh_filters.push_back(dynamic_cast(m)); - - for (unsigned int i = 0; i < _mesh_translations.size(); ++i) - { - std::vector filter = {filters[i]}; - addLocalTally(_tally_score, filter); - } - - _console << "done" << std::endl; - - break; - } - default: - mooseError("Unhandled TallyTypeEnum in OpenMCCellAverageProblem!"); + _global_sum_tally.clear(); + _global_sum_tally.resize(_all_tally_scores.size(), 0.0); } - if (_assume_separate_tallies) - openmc::settings::assume_separate = true; - - if (_tally_trigger) - for (auto & t : _local_tally) - for (int score = 0; score < _tally_score.size(); ++score) - t->triggers_.push_back({triggerMetric((*_tally_trigger)[score]), - _tally_trigger_threshold[score], - false, - score}); + // Initialize all of the [Tallies]. + for (auto & local_tally : _local_tallies) + local_tally->initializeTally(); } void @@ -2598,20 +1916,47 @@ OpenMCCellAverageProblem::findCell(const Point & point) void OpenMCCellAverageProblem::addExternalVariables() { - if (_tally_type != tally::none) + // We need to validate tallies here to we can add scores that may be missing. + validateLocalTallies(); + + // Add all of the auxvariables in which the [Tallies] block will store results. + unsigned int previous_valid_name_index = 0; + for (unsigned int i = 0; i < _local_tallies.size(); ++i) { - _external_vars.resize(_tally_score.size()); - for (unsigned int score = 0; score < _tally_score.size(); ++score) + _tally_var_ids.emplace_back(); + + // We use this to check if a sequence of added tallies corresponds to a single translated mesh. + // If the number of names reported in getAuxVarNames is zero, the tally must store it's results + // in the variables added by the first mesh tally in the sequence. + bool is_instanced = _local_tallies[i]->getAuxVarNames().size() == 0; + previous_valid_name_index = !is_instanced ? i : previous_valid_name_index; + + const auto & names = _local_tallies[previous_valid_name_index]->getAuxVarNames(); + + _tally_ext_var_ids.emplace_back(); + if (_local_tallies[i]->hasOutputs()) + _tally_ext_var_ids[i].resize(_local_tallies[i]->getOutputs().size()); + + for (unsigned int j = 0; j < names.size(); ++j) { - auto name = _tally_name[score]; - _tally_var.push_back(addExternalVariable(name) /* all blocks */); + if (is_instanced) + _tally_var_ids[i].push_back( + _tally_var_ids[previous_valid_name_index][j]); // Use variables from first in sequence. + else + _tally_var_ids[i].push_back(addExternalVariable(names[j])); - if (_outputs) + if (_local_tallies[i]->hasOutputs()) { - for (std::size_t i = 0; i < _outputs->size(); ++i) + const auto & outs = _local_tallies[i]->getOutputs(); + for (std::size_t k = 0; k < outs.size(); ++k) { - std::string n = name + "_" + _output_name[i]; - _external_vars[score].push_back(addExternalVariable(n) /* all blocks */); + std::string n = names[j] + "_" + outs[k]; + if (is_instanced) + _tally_ext_var_ids[i][k].push_back( + _tally_ext_var_ids[previous_valid_name_index][k] + [j]); // Use variables from first in sequence. + else + _tally_ext_var_ids[i][k].push_back(addExternalVariable(n)); } } } @@ -2858,21 +2203,21 @@ OpenMCCellAverageProblem::sendDensityToOpenMC() const } Real -OpenMCCellAverageProblem::tallyMultiplier(const unsigned int & score) const +OpenMCCellAverageProblem::tallyMultiplier(unsigned int global_score) const { - if (!isHeatingScore(_tally_score[score])) + if (!isHeatingScore(_all_tally_scores[global_score])) { // we need to get an effective source rate (particles / second) in order to // normalize the tally - Real source = _local_mean_tally[score]; + Real source = _local_mean_tally[global_score]; if (_run_mode == openmc::RunMode::EIGENVALUE) source *= *_power / EV_TO_JOULE / _local_mean_tally[_source_rate_index]; else source *= *_source_strength; - if (_tally_score[score] == "flux") + if (_all_tally_scores[global_score] == "flux") return source / _scaling; - else if (_tally_score[score] == "H3-production") + else if (_all_tally_scores[global_score] == "H3-production") return source; else mooseError("Unhandled tally score enum!"); @@ -2883,65 +2228,31 @@ OpenMCCellAverageProblem::tallyMultiplier(const unsigned int & score) const if (_run_mode == openmc::RunMode::EIGENVALUE) return *_power; else - return *_source_strength * EV_TO_JOULE * _local_mean_tally[score]; + return *_source_strength * EV_TO_JOULE * _local_mean_tally[global_score]; } } Real -OpenMCCellAverageProblem::tallyNormalization(const unsigned int & score) const +OpenMCCellAverageProblem::tallyNormalization(unsigned int global_score) const { - return _normalize_by_global ? _global_sum_tally[score] : _local_sum_tally[score]; -} - -template -T -OpenMCCellAverageProblem::normalizeLocalTally(const T & tally_result, const unsigned int & score) const -{ - Real comparison = tallyNormalization(score); - - if (std::abs(comparison) < ZERO_TALLY_THRESHOLD) - { - // If the value over the whole domain is zero, then the values in the individual bins must be zero. - // We need to avoid divide-by-zero - return tally_result * 0.0; - } - else - return tally_result / comparison; + return _normalize_by_global ? _global_sum_tally[global_score] : _local_sum_tally[global_score]; } void -OpenMCCellAverageProblem::relaxAndNormalizeTally(const int & t, const unsigned int & score) +OpenMCCellAverageProblem::relaxAndNormalizeTally(unsigned int global_score, + unsigned int local_score, + std::shared_ptr local_tally) { - auto & current = _current_tally[score][t]; - auto & previous = _previous_tally[score][t]; - auto & current_raw = _current_raw_tally[score][t]; - auto & current_raw_std_dev = _current_raw_tally_std_dev[score][t]; + Real comparison = tallyNormalization(global_score); - auto & tally = _local_tally.at(t); - auto mean_tally = tallySum(tally, score); - current_raw = normalizeLocalTally(mean_tally, score); - - auto sum_sq = - xt::view(tally->results_, xt::all(), score, static_cast(openmc::TallyResult::SUM_SQ)); - auto rel_err = relativeError(mean_tally, sum_sq, tally->n_realizations_); - current_raw_std_dev = rel_err * current_raw; - - // if OpenMC has only run one time, or we don't have relaxation at all, - // then we don't have a "previous" with which to relax, so we just copy the mean tally in and - // return - if (_fixed_point_iteration == 0 || _relaxation == relaxation::none) - { - current = current_raw; - previous = current_raw; - return; - } - - // save the current tally (from the previous iteration) into the previous one - std::copy(current.cbegin(), current.cend(), previous.begin()); - - double alpha; + Real alpha; switch (_relaxation) { + case relaxation::none: + { + alpha = 1.0; + break; + } case relaxation::constant: { alpha = _relaxation_factor; @@ -2961,8 +2272,7 @@ OpenMCCellAverageProblem::relaxAndNormalizeTally(const int & t, const unsigned i mooseError("Unhandled RelaxationEnum in OpenMCCellAverageProblem!"); } - auto relaxed_tally = (1.0 - alpha) * previous + alpha * current_raw; - std::copy(relaxed_tally.cbegin(), relaxed_tally.cend(), current.begin()); + local_tally->relaxAndNormalizeTally(local_score, alpha, comparison); } void @@ -2974,95 +2284,13 @@ OpenMCCellAverageProblem::dufekGudowskiParticleUpdate() openmc::settings::n_particles = n; } -Real -OpenMCCellAverageProblem::getTally(const unsigned int & var_num, - const std::vector> & tally, - const unsigned int & score) -{ - switch (_tally_type) - { - case tally::cell: - return getCellTally(var_num, tally, score); - case tally::mesh: - return getMeshTally(var_num, tally, score); - default: - mooseError("Unhandled TallyTypeEnum in OpenMCCellAverageProblem!"); - } -} - void -OpenMCCellAverageProblem::checkNormalization(const Real & sum, const unsigned int & score) const +OpenMCCellAverageProblem::checkNormalization(const Real & sum, unsigned int global_score) const { - if (tallyNormalization(score) > ZERO_TALLY_THRESHOLD) + if (tallyNormalization(global_score) > ZERO_TALLY_THRESHOLD) if (_check_tally_sum && std::abs(sum - 1.0) > 1e-6) - mooseError("Tally normalization process failed for " + _tally_score[score] + " score! Total fraction of " + - Moose::stringify(sum) + " does not match 1.0!"); -} - -Real -OpenMCCellAverageProblem::getCellTally(const unsigned int & var_num, - const std::vector> & tally, - const unsigned int & score) -{ - Real total = 0.0; - - int i = 0; - for (const auto & c : _cell_to_elem) - { - auto cell_info = c.first; - - // if this cell doesn't have any tallies, skip it - if (!_cell_has_tally[cell_info]) - continue; - - Real local = tally[0](i++); - - // divide each tally value by the volume that it corresponds to in MOOSE - // because we will apply it as a volumetric tally - Real volumetric_power = local * tallyMultiplier(score) / _cell_to_elem_volume[cell_info]; - total += local; - - fillElementalAuxVariable(var_num, c.second, volumetric_power); - } - - return total; -} - -Real -OpenMCCellAverageProblem::getMeshTally(const unsigned int & var_num, - const std::vector> & tally, - const unsigned int & score) -{ - Real total = 0.0; - - // TODO: this requires that the mesh exactly correspond to the mesh templates; - // for cases where they don't match, we'll need to do a nearest-node transfer or something - - unsigned int offset = 0; - for (unsigned int i = 0; i < _mesh_filters.size(); ++i) - { - const auto * filter = _mesh_filters[i]; - - for (decltype(filter->n_bins()) e = 0; e < filter->n_bins(); ++e) - { - Real power_fraction = tally[i](e); - - // divide each tally by the volume that it corresponds to in MOOSE - // because we will apply it as a volumetric tally (per unit volume). - // Because we require that the mesh template has units of cm based on the - // mesh constructors in OpenMC, we need to adjust the division - Real volumetric_power = - power_fraction * tallyMultiplier(score) / _mesh_template->volume(e) * _scaling * _scaling * _scaling; - total += power_fraction; - - std::vector elem_ids = {offset + e}; - fillElementalAuxVariable(var_num, elem_ids, volumetric_power); - } - - offset += filter->n_bins(); - } - - return total; + mooseError("Tally normalization process failed for " + _all_tally_scores[global_score] + + " score! Total fraction of " + Moose::stringify(sum) + " does not match 1.0!"); } void @@ -3188,56 +2416,93 @@ OpenMCCellAverageProblem::syncSolutions(ExternalProblem::Direction direction) } case ExternalProblem::Direction::FROM_EXTERNAL_APP: { - if (_tally_type == tally::none) - break; - _console << "Extracting OpenMC tallies..."; - for (unsigned int score = 0; score < _tally_score.size(); ++score) - { - // get the total tallies for normalization - if (_global_tally) - _global_sum_tally[score] = tallySumAcrossBins({_global_tally}, score); + if (_local_tallies.size() == 0 && _global_tallies.size() == 0) + break; - _local_sum_tally[score] = tallySumAcrossBins(_local_tally, score); - _local_mean_tally[score] = tallyMeanAcrossBins(_local_tally, score); + // Get the total tallies for normalization + if (_global_tallies.size() > 0) + { + for (unsigned int global_score = 0; global_score < _all_tally_scores.size(); ++global_score) + { + for (unsigned int i = 0; i < _global_tallies.size(); ++i) + { + auto loc = std::find(_global_tally_scores[i].begin(), + _global_tally_scores[i].end(), + _all_tally_scores[global_score]); + if (loc == _global_tally_scores[i].end()) + continue; + + auto index = loc - _global_tally_scores[i].begin(); + _global_sum_tally[global_score] = tallySumAcrossBins({_global_tallies[i]}, index); + } + } + } - if (_check_tally_sum) - checkTallySum(score); + // Loop over all of the tallies and calculate their sums and averages. + for (auto & local_tally : _local_tallies) + local_tally->computeSumAndMean(); - // Populate the current relaxed and unrelaxed tallies. After this, the _current_tally - // holds the relaxed tally and _current_raw_tally has the current unrelaxed tally. If - // no relaxation is used, _current_tally and _current_raw_tally are the same. - switch (_tally_type) + // Accumulate the sums and means for every score. + _local_sum_tally.clear(); + _local_sum_tally.resize(_all_tally_scores.size(), 0.0); + _local_mean_tally.clear(); + _local_mean_tally.resize(_all_tally_scores.size(), 0.0); + for (unsigned int i = 0; i < _local_tallies.size(); ++i) + { + for (unsigned int global_score = 0; global_score < _all_tally_scores.size(); ++global_score) { - case tally::cell: - relaxAndNormalizeTally(0, score); - break; - case tally::mesh: - for (unsigned int i = 0; i < _mesh_filters.size(); ++i) - relaxAndNormalizeTally(i, score); - break; - default: - mooseError("Unhandled TallyTypeEnum in OpenMCCellAverageProblem!"); + const auto & tally_name = _all_tally_scores[global_score]; + if (_local_tally_score_map[i].count(tally_name) == + 0) // If the local tally doesn't have this score, skip it. + continue; + + auto local_score = _local_tally_score_map[i].at(_all_tally_scores[global_score]); + _local_sum_tally[global_score] += _local_tallies[i]->getSum(local_score); + _local_mean_tally[global_score] += _local_tallies[i]->getMean(local_score); } + } - auto sum = getTally(_tally_var[score], _current_tally[score], score); - checkNormalization(sum, score); + if (_check_tally_sum) + for (unsigned int global_score = 0; global_score < _all_tally_scores.size(); ++global_score) + checkTallySum(global_score); - if (_outputs) + // Loop over the tallies to relax and normalize their results score by score. Then, store the + // results. + std::vector sums; + sums.resize(_all_tally_scores.size(), 0.0); + for (unsigned int i = 0; i < _local_tallies.size(); ++i) + { + for (unsigned int global_score = 0; global_score < _all_tally_scores.size(); ++global_score) { - for (std::size_t i = 0; i < _outputs->size(); ++i) - { - std::string out = (*_outputs)[i]; + const auto & tally_name = _all_tally_scores[global_score]; + if (_local_tally_score_map[i].count(tally_name) == + 0) // If the local tally doesn't have this score, skip it. + continue; + + auto local_score = _local_tally_score_map[i].at(tally_name); + relaxAndNormalizeTally(global_score, local_score, _local_tallies[i]); - if (out == "unrelaxed_tally_std_dev") - getTally(_external_vars[score][i], _current_raw_tally_std_dev[score], score); - if (out == "unrelaxed_tally") - getTally(_external_vars[score][i], _current_raw_tally[score], score); + // Store the tally results. + sums[global_score] += _local_tallies[i]->storeResults( + _tally_var_ids[i], local_score, global_score, "relaxed"); + + // Store additional tally outputs. + if (_local_tallies[i]->hasOutputs()) + { + const auto & outs = _local_tallies[i]->getOutputs(); + for (unsigned int j = 0; j < outs.size(); ++j) + _local_tallies[i]->storeResults( + _tally_ext_var_ids[i][j], local_score, global_score, outs[j]); } } } + // Check the normalization. + for (unsigned int global_score = 0; global_score < _all_tally_scores.size(); ++global_score) + checkNormalization(sums[global_score], global_score); + _console << " done" << std::endl; break; @@ -3257,18 +2522,15 @@ OpenMCCellAverageProblem::checkTallySum(const unsigned int & score) const if (std::abs(_global_sum_tally[score] - _local_sum_tally[score]) / _global_sum_tally[score] > 1e-6) { std::stringstream msg; - msg << _tally_score[score] << " tallies do not match the global " << _tally_score[score] << " tally:\n" + msg << _all_tally_scores[score] << " tallies do not match the global " + << _all_tally_scores[score] << " tally:\n" << " Global value: " << Moose::stringify(_global_sum_tally[score]) << "\n Tally sum: " << Moose::stringify(_local_sum_tally[score]) << "\n Difference: " << _global_sum_tally[score] - _local_sum_tally[score] - << "\n\nThis means that the tallies created by Cardinal are missing some hits over the domain.\n" + << "\n\nThis means that the tallies created by Cardinal are missing some hits over the " + "domain.\n" << "You can turn off this check by setting 'check_tally_sum' to false."; - if (_tally_type == tally::mesh) - msg << "\n\nOr, if your mesh tally doesn't perfectly align with cell boundaries, you could be\n" - "missing a portion of the scores. To normalize by the total tally (and evade this error),\n" - "you can set 'normalize_by_global_tally' to false."; - mooseError(msg.str()); } } @@ -3396,6 +2658,139 @@ OpenMCCellAverageProblem::reloadDAGMC() #endif } +void +OpenMCCellAverageProblem::addTallyObject(const std::string & type, + const std::string & name, + InputParameters & moose_object_pars) +{ + auto tally = addObject(type, name, moose_object_pars, false)[0]; + _local_tallies.push_back(tally); + _local_tally_score_map.emplace_back(); + + const auto & tally_scores = tally->getScores(); + for (unsigned int i = 0; i < tally_scores.size(); ++i) + { + _local_tally_score_map.back()[tally_scores[i]] = i; + + // Add the local tally's score to the list of scores if we don't have it yet. + if (std::find(_all_tally_scores.begin(), _all_tally_scores.end(), tally_scores[i]) == + _all_tally_scores.end()) + _all_tally_scores.push_back(tally_scores[i]); + } + + _contains_cell_tally = type == "CellTally" ? true : _contains_cell_tally; + + // Add the associated global tally if required. + if (_needs_global_tally && tally->getAuxVarNames().size() > 0) + { + _global_tally_scores.push_back(tally_scores); + _global_tally_estimators.push_back(tally->getTallyEstimator()); + } +} + +void +OpenMCCellAverageProblem::validateLocalTallies() +{ + // We can skip this check if we don't have tallies. + if (_local_tallies.size() == 0) + return; + + /** + * Check to make sure local tallies don't share scores (unless they're distributed mesh tallies). + * This prevents normalization issues as we sum the values of all of the scores over all of the + * tally bins. + * TODO: we might be able to loosen this restriction later if there's a good way to + * account for bin overlap. + */ + std::vector tallies_per_score; + tallies_per_score.resize(_all_tally_scores.size(), 0); + for (unsigned int i = 0; i < _local_tallies.size(); ++i) + { + for (unsigned int global_score = 0; global_score < _all_tally_scores.size(); ++global_score) + { + bool has_score = _local_tally_score_map[i].count(_all_tally_scores[global_score]) == 1; + // The second check is required to avoid multi counting translated mesh tallies. + if (has_score && _local_tallies[i]->getAuxVarNames().size() > 0) + tallies_per_score[global_score]++; + } + } + + for (unsigned int global_score = 0; global_score < _all_tally_scores.size(); ++global_score) + { + if (tallies_per_score[global_score] > 1) + { + mooseError("You have added " + Moose::stringify(tallies_per_score[global_score]) + + " tallies which score " + _all_tally_scores[global_score] + + "!\nCardinal does not support multiple tallies with the same" + " scores as these tallies may have overlapping bins, preventing normalization."); + } + } + + // need some special treatment for non-heating scores, in eigenvalue mode + bool has_non_heating_score = false; + for (const auto & t : _all_tally_scores) + if (!isHeatingScore(t)) + has_non_heating_score = true; + + if (has_non_heating_score && _run_mode == openmc::RunMode::EIGENVALUE) + { + std::string non_heating_scores; + for (const auto & e : _all_tally_scores) + { + if (!isHeatingScore(e)) + { + std::string l = e; + std::replace(l.begin(), l.end(), '-', '_'); + non_heating_scores += "" + l + ", "; + } + } + + if (non_heating_scores.length() > 0) + non_heating_scores.erase(non_heating_scores.length() - 2); + + checkRequiredParam(_pars, + "source_rate_normalization", + "using a non-heating tally (" + non_heating_scores + ") in eigenvalue mode"); + const auto & norm = getParam("source_rate_normalization"); + + // If the score is already in tally_score, no need to do anything special. + std::string n = enumToTallyScore(norm); + auto it = std::find(_all_tally_scores.begin(), _all_tally_scores.end(), n); + if (it != _all_tally_scores.end()) + _source_rate_index = it - _all_tally_scores.begin(); + else if (it == _all_tally_scores.end() && _local_tallies.size() == 1) + { + if (_local_tallies[0]->renamesTallyVars()) + mooseError("When specifying 'name', the score indicated in " + "'source_rate_normalization' must be\n" + "listed in 'score' so that we know what you want to name that score (", + norm, + ")"); + + // We can add the requested normalization score if and only if a single tally was added by + // [Tallies]. + _all_tally_scores.push_back(n); + _local_tallies[0]->addScore(n); + _local_tally_score_map[0][n] = _local_tallies[0]->getScores().size() - 1; + _global_tally_scores[0].push_back(n); + _source_rate_index = _all_tally_scores.size() - 1; + } + else + { + // Otherwise, we error and let the user know that they need to add the score. + mooseError("The local tallies added in the [Tallies] block do not contain the requested " + "heating score " + + n + + ". You must either add this score in one of the tallies or choose a different " + "heating score."); + } + } + else if (isParamValid("source_rate_normalization")) + mooseWarning( + "When either running in fixed-source mode, or all tallies have units of eV/src, the " + "'source_rate_normalization' parameter is unused!"); +} + void OpenMCCellAverageProblem::updateMaterials() { diff --git a/src/base/OpenMCProblemBase.C b/src/base/OpenMCProblemBase.C index 92387a850..6965019df 100644 --- a/src/base/OpenMCProblemBase.C +++ b/src/base/OpenMCProblemBase.C @@ -20,6 +20,7 @@ #include "OpenMCProblemBase.h" #include "CardinalAppTypes.h" +#include "AddTallyAction.h" InputParameters OpenMCProblemBase::validParams() @@ -31,8 +32,7 @@ OpenMCProblemBase::validParams() "source_strength", "Neutrons/second to normalize the OpenMC tallies; only used for fixed source mode"); params.addParam("verbose", false, "Whether to print diagnostic information"); - params.addRequiredParam( - "tally_type", getTallyTypeEnum(), "Type of tally to use in OpenMC"); + params.addParam("tally_type", getTallyTypeEnum(), "Type of tally to use in OpenMC"); params.addRangeCheckedParam( "scaling", @@ -77,7 +77,6 @@ OpenMCProblemBase::OpenMCProblemBase(const InputParameters & params) : CardinalProblem(params), PostprocessorInterface(this), _verbose(getParam("verbose")), - _tally_type(getParam("tally_type").getEnum()), _reuse_source(getParam("reuse_source")), _specified_scaling(params.isParamSetByUser("scaling")), _scaling(getParam("scaling")), @@ -85,6 +84,10 @@ OpenMCProblemBase::OpenMCProblemBase(const InputParameters & params) _fixed_point_iteration(-1), _total_n_particles(0) { + if (isParamValid("tally_type")) + mooseError("The tally system used by OpenMCProblemBase derived classes has been deprecated. " + "Please add tallies with the [Tallies] block instead."); + int argc = 1; char openmc[] = "openmc"; char * argv[1] = {openmc}; @@ -103,30 +106,32 @@ OpenMCProblemBase::OpenMCProblemBase(const InputParameters & params) // ensure that unsupported run modes are not used, while also checking for // necessary/unused input parameters for the valid run modes _run_mode = openmc::settings::run_mode; + const auto & tally_actions = getMooseApp().actionWarehouse().getActions(); switch (_run_mode) { case openmc::RunMode::EIGENVALUE: { - if (_tally_type != tally::none) + // Jumping through hoops to see if we're going to add tallies down the line. + if (tally_actions.size() > 0) { checkRequiredParam(params, "power", "running in k-eigenvalue mode"); _power = &getPostprocessorValue("power"); } else - checkUnusedParam(params, "power", "'tally_type = none'"); + checkUnusedParam(params, "power", "no tallies have been added"); checkUnusedParam(params, "source_strength", "running in k-eigenvalue mode"); break; } case openmc::RunMode::FIXED_SOURCE: { - if (_tally_type != tally::none) + if (tally_actions.size() > 0) { checkRequiredParam(params, "source_strength", "running in fixed source mode"); _source_strength = &getPostprocessorValue("source_strength"); } else - checkUnusedParam(params, "source_strength", "'tally_type = none'"); + checkUnusedParam(params, "source_strength", "no tallies have been added"); checkUnusedParam(params, "inactive_batches", "running in fixed source mode"); checkUnusedParam(params, "reuse_source", "running in fixed source mode"); @@ -600,6 +605,22 @@ OpenMCProblemBase::tallyEstimator(tally::TallyEstimatorEnum estimator) const } } +std::string +OpenMCProblemBase::estimatorToString(openmc::TallyEstimator estimator) const +{ + switch (estimator) + { + case openmc::TallyEstimator::TRACKLENGTH: + return "tracklength"; + case openmc::TallyEstimator::COLLISION: + return "collision"; + case openmc::TallyEstimator::ANALOG: + return "analog"; + default: + mooseError("Unhandled TallyEstimatorEnum!"); + } +} + openmc::TriggerMetric OpenMCProblemBase::triggerMetric(std::string trigger) const { @@ -633,32 +654,6 @@ OpenMCProblemBase::triggerMetric(trigger::TallyTriggerTypeEnum trigger) const } } -openmc::Filter * -OpenMCProblemBase::cellInstanceFilter(const std::vector & tally_cells) const -{ - auto cell_filter = - dynamic_cast(openmc::Filter::create("cellinstance")); - - std::vector cells; - for (const auto & c : tally_cells) - cells.push_back( - {gsl::narrow_cast(c.first), gsl::narrow_cast(c.second)}); - - cell_filter->set_cell_instances(cells); - return cell_filter; -} - -openmc::Tally * -OpenMCProblemBase::addTally(const std::vector & score, - std::vector & filters, const openmc::TallyEstimator & estimator) -{ - auto tally = openmc::Tally::create(); - tally->set_scores(score); - tally->estimator_ = estimator; - tally->set_filters(filters); - return tally; -} - bool OpenMCProblemBase::cellIsVoid(const cellInfo & cell_info) const { @@ -687,21 +682,6 @@ OpenMCProblemBase::geometryType(bool & has_csg_universe, bool & has_dag_universe } } -std::unique_ptr -OpenMCProblemBase::tallyMesh(const std::string * filename) const -{ - std::unique_ptr mesh; - if (!filename) - mesh = std::make_unique(_mesh.getMesh(), _scaling); - else - mesh = std::make_unique(*filename, _scaling); - - // by setting the ID to -1, OpenMC will automatically detect the next available ID - mesh->set_id(-1); - mesh->output_ = false; - return mesh; -} - long unsigned int OpenMCProblemBase::numCells() const { diff --git a/src/postprocessors/TallyRelativeError.C b/src/postprocessors/TallyRelativeError.C index 2e73fd373..95ac43395 100644 --- a/src/postprocessors/TallyRelativeError.C +++ b/src/postprocessors/TallyRelativeError.C @@ -84,7 +84,7 @@ TallyRelativeError::TallyRelativeError(const InputParameters & parameters) Real TallyRelativeError::getValue() const { - const auto & tally = _openmc_problem->getLocalTally(); + const auto & tallies = _openmc_problem->getLocalTally(); Real post_processor_value; @@ -104,8 +104,9 @@ TallyRelativeError::getValue() const } unsigned int num_values = 0; - for (const auto & t : tally) + for (const auto & tally : tallies) { + const auto t = tally->getWrappedTally(); auto sum = xt::view(t->results_, xt::all(), _tally_index, static_cast(openmc::TallyResult::SUM)); auto sum_sq = xt::view(t->results_, xt::all(), _tally_index, static_cast(openmc::TallyResult::SUM_SQ)); diff --git a/src/tallies/CellTally.C b/src/tallies/CellTally.C new file mode 100644 index 000000000..d6144658e --- /dev/null +++ b/src/tallies/CellTally.C @@ -0,0 +1,297 @@ +/********************************************************************/ +/* SOFTWARE COPYRIGHT NOTIFICATION */ +/* Cardinal */ +/* */ +/* (c) 2021 UChicago Argonne, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by UChicago Argonne, LLC */ +/* Under Contract No. DE-AC02-06CH11357 */ +/* With the U. S. Department of Energy */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See LICENSE for full restrictions */ +/********************************************************************/ + +#ifdef ENABLE_OPENMC_COUPLING +#include "CellTally.h" + +registerMooseObject("CardinalApp", CellTally); + +InputParameters +CellTally::validParams() +{ + auto params = TallyBase::validParams(); + params.addClassDescription("A class which implements distributed cell tallies."); + params.addParam>( + "blocks", + "Subdomains for which to add tallies in OpenMC. If not provided, cell " + "tallies will be applied over the entire mesh."); + params.addParam( + "check_equal_mapped_tally_volumes", + false, + "Whether to check if the tallied cells map to regions in the mesh of equal volume. " + "This can be helpful to ensure that the volume normalization of OpenMC's tallies doesn't " + "introduce any unintentional distortion just because the mapped volumes are different. " + "You should only set this to true if your OpenMC tally cells are all the same volume!"); + params.addRangeCheckedParam("equal_tally_volume_abs_tol", + 1e-8, + "equal_tally_volume_abs_tol > 0", + "Absolute tolerance for comparing tally volumes"); + + return params; +} + +CellTally::CellTally(const InputParameters & parameters) + : TallyBase(parameters), + _check_equal_mapped_tally_volumes(getParam("check_equal_mapped_tally_volumes")), + _equal_tally_volume_abs_tol(getParam("equal_tally_volume_abs_tol")) +{ + if (isParamValid("blocks")) + { + auto block_names = getParam>("blocks"); + if (block_names.empty()) + mooseError("Subdomain names must be provided if using 'blocks'!"); + + auto block_ids = _mesh.getSubdomainIDs(block_names); + std::copy( + block_ids.begin(), block_ids.end(), std::inserter(_tally_blocks, _tally_blocks.end())); + + // Check to make sure all of the blocks are in the mesh. + const auto & subdomains = _mesh.meshSubdomains(); + for (std::size_t b = 0; b < block_names.size(); ++b) + if (subdomains.find(block_ids[b]) == subdomains.end()) + mooseError("Block '" + block_names[b] + "' specified in 'blocks' not found in mesh!"); + } + else + { + // Tally over all mesh blocks if no blocks are provided. + for (const auto & s : _mesh.meshSubdomains()) + _tally_blocks.insert(s); + } +} + +std::pair +CellTally::spatialFilter() +{ + // Check to make sure we can map tallies to the mesh subdomains requested in tally_blocks. + checkCellMappedSubdomains(); + + if (_openmc_problem.cellToElem().size() == 0) + mooseError("Did not find any overlap between MOOSE elements and OpenMC cells for " + "the specified blocks!"); + + auto tally_cells = getTallyCells(); + std::vector cells; + for (const auto & c : tally_cells) + cells.push_back( + {gsl::narrow_cast(c.first), gsl::narrow_cast(c.second)}); + + _cell_filter = dynamic_cast(openmc::Filter::create("cellinstance")); + _cell_filter->set_cell_instances(cells); + + return std::make_pair(openmc::model::tally_filters.size(), _cell_filter); +} + +Real +CellTally::storeResults(const std::vector & var_numbers, + unsigned int local_score, + unsigned int global_score, + const std::string & output_type) +{ + Real total = 0.0; + + if (output_type == "relaxed") + { + int i = 0; + for (const auto & c : _openmc_problem.cellToElem()) + { + auto cell_info = c.first; + + // if this cell doesn't have any tallies, skip it + if (!_cell_has_tally[cell_info]) + continue; + + Real local = _current_tally[local_score](i++); + + // divide each tally value by the volume that it corresponds to in MOOSE + // because we will apply it as a volumetric tally + Real volumetric_power = local * _openmc_problem.tallyMultiplier(global_score) / + _openmc_problem.cellMappedVolume(cell_info); + total += local; + + fillElementalAuxVariable(var_numbers[local_score], c.second, volumetric_power); + } + } + else if (output_type == "std_dev") + { + int i = 0; + for (const auto & c : _openmc_problem.cellToElem()) + { + auto cell_info = c.first; + + // if this cell doesn't have any tallies, skip it + if (!_cell_has_tally[cell_info]) + continue; + + Real local = _current_raw_tally_std_dev[local_score](i++); + + // divide each tally value by the volume that it corresponds to in MOOSE + // because we will apply it as a volumetric tally + Real volumetric_power = local * _openmc_problem.tallyMultiplier(global_score) / + _openmc_problem.cellMappedVolume(cell_info); + + fillElementalAuxVariable(var_numbers[local_score], c.second, volumetric_power); + } + } + else if (output_type == "raw") + { + int i = 0; + for (const auto & c : _openmc_problem.cellToElem()) + { + auto cell_info = c.first; + + // if this cell doesn't have any tallies, skip it + if (!_cell_has_tally[cell_info]) + continue; + + Real local = _current_raw_tally[local_score](i++); + + // divide each tally value by the volume that it corresponds to in MOOSE + // because we will apply it as a volumetric tally + Real volumetric_power = local * _openmc_problem.tallyMultiplier(global_score) / + _openmc_problem.cellMappedVolume(cell_info); + + fillElementalAuxVariable(var_numbers[local_score], c.second, volumetric_power); + } + } + else + mooseError("Unknown external output " + output_type); + + return total; +} + +void +CellTally::checkCellMappedSubdomains() +{ + _cell_has_tally.clear(); + + // If the OpenMC cell maps to multiple subdomains that _also_ have different + // tally settings, we need to error because we are unsure of whether to add tallies or not; + // both of these need to be true to error + for (const auto & c : _openmc_problem.cellToElem()) + { + bool at_least_one_in_tallies = false; + bool at_least_one_not_in_tallies = false; + int block_in_tallies, block_not_in_tallies; + + auto cell_info = c.first; + auto cell_subdomains = _openmc_problem.getCellToElementSub(cell_info); + for (const auto & s : cell_subdomains) + { + if (!at_least_one_in_tallies) + { + at_least_one_in_tallies = _tally_blocks.count(s) != 0; + block_in_tallies = s; + } + + if (!at_least_one_not_in_tallies) + { + at_least_one_not_in_tallies = _tally_blocks.count(s) == 0; + block_not_in_tallies = s; + } + + // can cut the search early if we've already hit multiple tally settings + if (at_least_one_in_tallies && at_least_one_not_in_tallies) + break; + } + + if (at_least_one_in_tallies && at_least_one_not_in_tallies) + mooseError("cell " + _openmc_problem.printCell(cell_info) + + " maps to blocks with different tally settings!\n" + "Block " + + Moose::stringify(block_in_tallies) + + " is in 'blocks', but " + "block " + + Moose::stringify(block_not_in_tallies) + " is not."); + + _cell_has_tally[cell_info] = at_least_one_in_tallies; + } +} + +std::vector +CellTally::getTallyCells() const +{ + bool is_first_tally_cell = true; + OpenMCCellAverageProblem::cellInfo first_tally_cell; + Real mapped_tally_volume; + + std::vector tally_cells; + + for (const auto & c : _openmc_problem.cellToElem()) + { + auto cell_info = c.first; + + if (_cell_has_tally.at(cell_info)) + { + tally_cells.push_back(cell_info); + + if (is_first_tally_cell) + { + is_first_tally_cell = false; + first_tally_cell = cell_info; + mapped_tally_volume = _openmc_problem.cellMappedVolume(first_tally_cell); + } + + if (_check_equal_mapped_tally_volumes) + { + Real diff = std::abs(mapped_tally_volume - _openmc_problem.cellMappedVolume(cell_info)); + bool absolute_diff = diff > _equal_tally_volume_abs_tol; + bool relative_diff = diff / mapped_tally_volume > 1e-3; + if (absolute_diff && relative_diff) + { + std::stringstream msg; + msg << "Detected un-equal mapped tally volumes!\n cell " + << _openmc_problem.printCell(first_tally_cell) << " maps to a volume of " + << Moose::stringify(_openmc_problem.cellMappedVolume(first_tally_cell)) + << " (cm3)\n cell " << _openmc_problem.printCell(cell_info) << " maps to a volume of " + << Moose::stringify(_openmc_problem.cellMappedVolume(cell_info)) + << " (cm3).\n\n" + "If the tallied cells in your OpenMC model are of identical volumes, this means " + "that you can get\n" + "distortion of the volumetric tally output. For instance, suppose you have " + "two equal-size OpenMC\n" + "cells which have the same volume - but each OpenMC cell maps to a MOOSE region " + "of different volume\n" + "just due to the nature of the centroid mapping scheme. Even if those two tallies " + "do actually have the\n" + "same value, the volumetric tally will be different because you'll be " + "dividing each tally by a\n" + "different mapped MOOSE volume.\n\n"; + + if (_openmc_problem.hasPointTransformations()) + msg << "NOTE: You have imposed symmetry, which means that you'll hit this error if any " + "of your tally\n" + "cells are cut by symmetry planes. If your tally cells would otherwise be the " + "same volume if NOT\n" + "imposing symmetry, or if your tally cells are not the same volume regardless, " + "you need to set\n" + "'check_equal_mapped_tally_volumes = false'."; + else + msg << "We recommend re-creating the mesh mirror to have an equal volume mapping of " + "MOOSE elements to each\n" + "OpenMC cell. Or, you can disable this check by setting " + "'check_equal_mapped_tally_volumes = false'."; + + mooseError(msg.str()); + } + } + } + } + + return tally_cells; +} +#endif diff --git a/src/tallies/MeshTally.C b/src/tallies/MeshTally.C new file mode 100644 index 000000000..102ceec8b --- /dev/null +++ b/src/tallies/MeshTally.C @@ -0,0 +1,270 @@ +/********************************************************************/ +/* SOFTWARE COPYRIGHT NOTIFICATION */ +/* Cardinal */ +/* */ +/* (c) 2021 UChicago Argonne, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by UChicago Argonne, LLC */ +/* Under Contract No. DE-AC02-06CH11357 */ +/* With the U. S. Department of Energy */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See LICENSE for full restrictions */ +/********************************************************************/ + +#ifdef ENABLE_OPENMC_COUPLING +#include "MeshTally.h" + +registerMooseObject("CardinalApp", MeshTally); + +InputParameters +MeshTally::validParams() +{ + auto params = TallyBase::validParams(); + params.addClassDescription("A class which implements unstructured mesh tallies."); + params.addParam("mesh_template", + "Mesh tally template for OpenMC when using mesh tallies; " + "at present, this mesh must exactly match the mesh used in the " + "[Mesh] block because a one-to-one copy " + "is used to get OpenMC's tally results on the [Mesh]."); + params.addParam("mesh_translation", + "Coordinate to which this mesh should be " + "translated. Units must match those used to define the [Mesh]."); + + // The index of this tally into an array of mesh translations. Defaults to zero. + params.addPrivateParam("instance", 0); + + return params; +} + +MeshTally::MeshTally(const InputParameters & parameters) + : TallyBase(parameters), + _mesh_translation(isParamValid("mesh_translation") ? getParam("mesh_translation") + : Point(0.0, 0.0, 0.0)), + _instance(getParam("instance")) +{ + // Error check the estimators. + if (isParamValid("estimator")) + { + if (_estimator == openmc::TallyEstimator::TRACKLENGTH) + mooseError("Tracklength estimators are currently incompatible with mesh tallies!"); + } + else + _estimator = openmc::TallyEstimator::COLLISION; + + // Error check the mesh template. + if (_mesh.getMesh().allow_renumbering() && !_mesh.getMesh().is_replicated()) + mooseError( + "Mesh tallies currently require 'allow_renumbering = false' to be set in the [Mesh]!"); + + if (isParamValid("mesh_template")) + _mesh_template_filename = &getParam("mesh_template"); + else + { + if (std::abs(_openmc_problem.scaling() - 1.0) > 1e-6) + mooseError("Directly tallying on the [Mesh] is only supported for 'scaling' of unity. " + "Instead, please make a file containing your tally mesh and set it with " + "'mesh_template'. You can generate a mesh file corresponding to the [Mesh] " + "by running:\n\ncardinal-opt -i " + + _app.getFileName() + " --mesh-only"); + + // for distributed meshes, each rank only owns a portion of the mesh information, but + // OpenMC wants the entire mesh to be available on every rank. We might be able to add + // this feature in the future, but will need to investigate + if (!_mesh.getMesh().is_replicated()) + mooseError("Directly tallying on the [Mesh] block by OpenMC is not yet supported " + "for distributed meshes!"); + + if (isParamValid("mesh_translation")) + mooseError("The mesh filter cannot be translated if directly tallying on the mesh " + "provided in the [Mesh] block!"); + } + + /** + * If the instance isn't zero this variable is a translated mesh tally. It will accumulate it's + * scores in a different set of variables (the auxvars which are added by the first tally in a + * sequence of mesh tallies), and so it doesn't need to create any auxvars. + */ + if (_instance != 0) + _tally_name = std::vector(); +} + +std::pair +MeshTally::spatialFilter() +{ + // Create the OpenMC mesh which will be tallied on. + std::unique_ptr tally_mesh; + if (!_mesh_template_filename) + tally_mesh = std::make_unique(_mesh.getMesh(), _openmc_problem.scaling()); + else + tally_mesh = + std::make_unique(*_mesh_template_filename, _openmc_problem.scaling()); + + // by setting the ID to -1, OpenMC will automatically detect the next available ID + tally_mesh->set_id(-1); + tally_mesh->output_ = false; + _mesh_template = tally_mesh.get(); + + // Create the mesh filter itself. + _mesh_index = openmc::model::meshes.size(); + openmc::model::meshes.push_back(std::move(tally_mesh)); + + _mesh_filter = dynamic_cast(openmc::Filter::create("mesh")); + _mesh_filter->set_mesh(_mesh_index); + _mesh_filter->set_translation({_mesh_translation(0), _mesh_translation(1), _mesh_translation(2)}); + + // Validate the mesh filters to make sure we can run a copy transfer to the [Mesh]. + checkMeshTemplateAndTranslations(); + + return std::make_pair(openmc::model::tally_filters.size(), _mesh_filter); +} + +void +MeshTally::resetTally() +{ + TallyBase::resetTally(); + + // Erase the OpenMC mesh. + openmc::model::meshes.erase(openmc::model::meshes.begin() + _mesh_index); +} + +Real +MeshTally::storeResults(const std::vector & var_numbers, + unsigned int local_score, + unsigned int global_score, + const std::string & output_type) +{ + Real total = 0.0; + + unsigned int offset = _instance * _mesh_filter->n_bins(); + if (output_type == "relaxed") + { + for (decltype(_mesh_filter->n_bins()) e = 0; e < _mesh_filter->n_bins(); ++e) + { + Real power_fraction = _current_tally[local_score](e); + + // divide each tally by the volume that it corresponds to in MOOSE + // because we will apply it as a volumetric tally (per unit volume). + // Because we require that the mesh template has units of cm based on the + // mesh constructors in OpenMC, we need to adjust the division + Real volumetric_power = power_fraction * _openmc_problem.tallyMultiplier(global_score) / + _mesh_template->volume(e) * _openmc_problem.scaling() * + _openmc_problem.scaling() * _openmc_problem.scaling(); + total += power_fraction; + + std::vector elem_ids = {offset + e}; + fillElementalAuxVariable(var_numbers[local_score], elem_ids, volumetric_power); + } + } + else if (output_type == "std_dev") + { + for (decltype(_mesh_filter->n_bins()) e = 0; e < _mesh_filter->n_bins(); ++e) + { + Real power_fraction = _current_raw_tally_std_dev[local_score](e); + + // divide each tally by the volume that it corresponds to in MOOSE + // because we will apply it as a volumetric tally (per unit volume). + // Because we require that the mesh template has units of cm based on the + // mesh constructors in OpenMC, we need to adjust the division + Real volumetric_power = power_fraction * _openmc_problem.tallyMultiplier(global_score) / + _mesh_template->volume(e) * _openmc_problem.scaling() * + _openmc_problem.scaling() * _openmc_problem.scaling(); + + std::vector elem_ids = {offset + e}; + fillElementalAuxVariable(var_numbers[local_score], elem_ids, volumetric_power); + } + } + else if (output_type == "raw") + { + for (decltype(_mesh_filter->n_bins()) e = 0; e < _mesh_filter->n_bins(); ++e) + { + Real power_fraction = _current_raw_tally[local_score](e); + + // divide each tally by the volume that it corresponds to in MOOSE + // because we will apply it as a volumetric tally (per unit volume). + // Because we require that the mesh template has units of cm based on the + // mesh constructors in OpenMC, we need to adjust the division + Real volumetric_power = power_fraction * _openmc_problem.tallyMultiplier(global_score) / + _mesh_template->volume(e) * _openmc_problem.scaling() * + _openmc_problem.scaling() * _openmc_problem.scaling(); + + std::vector elem_ids = {offset + e}; + fillElementalAuxVariable(var_numbers[local_score], elem_ids, volumetric_power); + } + } + else + mooseError("Unknown external output " + output_type); + + return total; +} + +void +MeshTally::checkMeshTemplateAndTranslations() const +{ + // we can do some rudimentary checking on the mesh template by comparing the centroid + // coordinates compared to centroids in the [Mesh] (because right now, we just doing a simple + // copy transfer that necessitates the meshes to have the same elements in the same order). In + // other words, you might have two meshes that represent the same geometry, the element ordering + // could be different. + unsigned int offset = _instance * _mesh_filter->n_bins(); + for (int e = 0; e < _mesh_filter->n_bins(); ++e) + { + auto elem_ptr = _mesh.queryElemPtr(offset + e); + + // if element is not on this part of the distributed mesh, skip it + if (!elem_ptr) + continue; + + const auto pt = _mesh_template->centroid(e); + Point centroid_template = {pt[0], pt[1], pt[2]}; + + // The translation applied in OpenMC isn't actually registered in the mesh itself; + // it is always added on to the point, so we need to do the same here + centroid_template += _mesh_translation; + + // because the mesh template and [Mesh] may be in different units, we need + // to adjust the [Mesh] by the scaling factor before doing a comparison. + Point centroid_mesh = elem_ptr->vertex_average() * _openmc_problem.scaling(); + + // if the centroids are the same except for a factor of 'scaling', then we can + // guess that the mesh_template is probably not in units of centimeters + if (_openmc_problem.hasScaling()) + { + // if scaling was applied correctly, then each calculation of 'scaling' here should equal 1. + // Otherwise, if they're all the same, then 'scaling_x' is probably the factor by which the + // mesh_template needs to be multiplied, so we can print a helpful error message + bool incorrect_scaling = true; + for (unsigned int j = 0; j < OpenMCCellAverageProblem::DIMENSION; ++j) + { + Real scaling = centroid_mesh(j) / centroid_template(j); + incorrect_scaling = incorrect_scaling && !MooseUtils::absoluteFuzzyEqual(scaling, 1.0); + } + + if (incorrect_scaling) + mooseError("The centroids of the 'mesh_template' differ from the " + "centroids of the [Mesh] by a factor of " + + Moose::stringify(centroid_mesh(0) / centroid_template(0)) + + ".\nDid you forget that the 'mesh_template' must be in " + "the same units as the [Mesh]?"); + } + + // check if centroids are the same + bool different_centroids = false; + for (unsigned int j = 0; j < OpenMCCellAverageProblem::DIMENSION; ++j) + different_centroids = different_centroids || + !MooseUtils::absoluteFuzzyEqual(centroid_mesh(j), centroid_template(j)); + + if (different_centroids) + mooseError( + "Centroid for element " + Moose::stringify(offset + e) + " in the [Mesh] (cm): " + + _openmc_problem.printPoint(centroid_mesh) + "\ndoes not match centroid for element " + + Moose::stringify(e) + " in the 'mesh_template' with instance " + + Moose::stringify(_instance) + " (cm): " + _openmc_problem.printPoint(centroid_template) + + "!\n\nThe copy transfer requires that the [Mesh] and 'mesh_template' be identical."); + } +} +#endif diff --git a/src/tallies/TallyBase.C b/src/tallies/TallyBase.C new file mode 100644 index 000000000..298aaeaed --- /dev/null +++ b/src/tallies/TallyBase.C @@ -0,0 +1,335 @@ +/********************************************************************/ +/* SOFTWARE COPYRIGHT NOTIFICATION */ +/* Cardinal */ +/* */ +/* (c) 2021 UChicago Argonne, LLC */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Prepared by UChicago Argonne, LLC */ +/* Under Contract No. DE-AC02-06CH11357 */ +/* With the U. S. Department of Energy */ +/* */ +/* Prepared by Battelle Energy Alliance, LLC */ +/* Under Contract No. DE-AC07-05ID14517 */ +/* With the U. S. Department of Energy */ +/* */ +/* See LICENSE for full restrictions */ +/********************************************************************/ + +#ifdef ENABLE_OPENMC_COUPLING +#include "TallyBase.h" + +#include "OpenMCCellAverageProblem.h" +#include "AuxiliarySystem.h" + +#include "openmc/settings.h" + +InputParameters +TallyBase::validParams() +{ + auto params = MooseObject::validParams(); + params.addParam( + "score", + getTallyScoreEnum(), + "Score(s) to use in the OpenMC tallies. If not specified, defaults to 'kappa_fission'"); + params.addParam( + "estimator", getTallyEstimatorEnum(), "Type of tally estimator to use in OpenMC"); + params.addParam>( + "name", + "Auxiliary variable name(s) to use for OpenMC tallies. " + "If not specified, defaults to the names of the scores"); + + MultiMooseEnum tally_trigger("rel_err none"); + params.addParam( + "trigger", + tally_trigger, + "Trigger criterion to determine when OpenMC simulation is complete " + "based on tallies. If multiple scores are specified in 'score, " + "this same trigger is applied to all scores."); + params.addRangeCheckedParam>( + "trigger_threshold", "trigger_threshold > 0", "Threshold for the tally trigger"); + + MultiMooseEnum openmc_outputs("unrelaxed_tally_std_dev unrelaxed_tally"); + params.addParam("output", + openmc_outputs, + "UNRELAXED field(s) to output from OpenMC for each tally score. " + "unrelaxed_tally_std_dev will write the standard deviation of " + "each tally into auxiliary variables " + "named *_std_dev. Unrelaxed_tally will write the raw unrelaxed " + "tally into auxiliary variables " + "named *_raw (replace * with 'name')."); + + params.addPrivateParam("_openmc_problem"); + + params.registerBase("Tally"); + params.registerSystemAttributeName("Tally"); + + return params; +} + +TallyBase::TallyBase(const InputParameters & parameters) + : MooseObject(parameters), + _openmc_problem(*getParam("_openmc_problem")), + _mesh(_openmc_problem.mesh()), + _aux(_openmc_problem.getAuxiliarySystem()), + _tally_trigger(isParamValid("trigger") ? &getParam("trigger") : nullptr), + _renames_tally_vars(isParamValid("name")), + _has_outputs(isParamValid("output")) +{ + if (isParamValid("score")) + { + const auto & scores = getParam("score"); + for (const auto & score : scores) + _tally_score.push_back(_openmc_problem.enumToTallyScore(score)); + } + else + _tally_score = {"kappa-fission"}; + + bool heating = + std::find(_tally_score.begin(), _tally_score.end(), "heating") != _tally_score.end(); + + if (isParamValid("estimator")) + { + auto estimator = getParam("estimator").getEnum(); + + // Photon heating tallies cannot use tracklength estimators. + if (estimator == tally::tracklength && openmc::settings::photon_transport && heating) + mooseError("Tracklength estimators are currently incompatible with photon transport and " + "heating scores! For more information: https://tinyurl.com/3wre3kwt"); + + _estimator = _openmc_problem.tallyEstimator(estimator); + } + else + { + /** + * Set a default of tracklength for all tallies other then heating tallies in photon transport. + * This behavior must be overridden in derived tallies that implement mesh filters. + */ + _estimator = openmc::TallyEstimator::TRACKLENGTH; + if (heating && openmc::settings::photon_transport) + _estimator = openmc::TallyEstimator::COLLISION; + } + + if (heating && !openmc::settings::photon_transport) + mooseWarning( + "When using the 'heating' score with photon transport disabled, energy deposition\n" + "from photons is neglected unless you specifically ran NJOY to produce MT=301 with\n" + "photon energy deposited locally (not true for any pre-packaged OpenMC data libraries\n" + "on openmc.org).\n\n" + "If you did NOT specifically run NJOY yourself with this customization, we recommend\n" + "using the 'heating_local' score instead, which will capture photon energy deposition.\n" + "Otherwise, you will underpredict the true energy deposition."); + + if (isParamValid("trigger") != isParamValid("trigger_threshold")) + mooseError("You must either specify none or both of 'trigger' and " + "'trigger_threshold'. You have specified only one."); + + bool has_tally_trigger = false; + if (_tally_trigger) + { + _tally_trigger_threshold = getParam>("trigger_threshold"); + + if (_tally_trigger->size() != _tally_score.size()) + mooseError("'trigger' (size " + std::to_string(_tally_trigger->size()) + + ") must have the same length as 'score' (size " + + std::to_string(_tally_score.size()) + ")"); + + if (_tally_trigger_threshold.size() != _tally_score.size()) + mooseError("'trigger_threshold' (size " + std::to_string(_tally_trigger_threshold.size()) + + ") must have the same length as 'score' (size " + + std::to_string(_tally_score.size()) + ")"); + + for (unsigned int s = 0; s < _tally_trigger->size(); ++s) + if ((*_tally_trigger)[s] != "none") + has_tally_trigger = true; + } + + if (isParamValid("name")) + _tally_name = getParam>("name"); + else + { + for (auto score : _tally_score) + { + std::replace(score.begin(), score.end(), '-', '_'); + _tally_name.push_back(score); + } + } + + if (_has_outputs) + { + // names of output are appended to ends of 'name' + for (const auto & o : getParam("output")) + { + std::string name = o; + + if (o == "UNRELAXED_TALLY_STD_DEV") + _output_name.push_back("std_dev"); + else if (o == "UNRELAXED_TALLY") + _output_name.push_back("raw"); + else + mooseError("Unhandled OutputEnum in OpenMCCellAverageProblem!"); + } + } + + if (_tally_name.size() != _tally_score.size()) + mooseError("'name' must be the same length as 'score'!"); + + _openmc_problem.checkDuplicateEntries(_tally_name, "name"); + _openmc_problem.checkDuplicateEntries(_tally_score, "score"); + + _local_sum_tally.resize(_tally_score.size(), 0.0); + _local_mean_tally.resize(_tally_score.size(), 0.0); + + _current_tally.resize(_tally_score.size()); + _current_raw_tally.resize(_tally_score.size()); + _current_raw_tally_std_dev.resize(_tally_score.size()); + _previous_tally.resize(_tally_score.size()); +} + +void +TallyBase::initializeTally() +{ + // Clear cached results. + _local_sum_tally.clear(); + _local_sum_tally.resize(_tally_score.size(), 0.0); + _local_mean_tally.clear(); + _local_mean_tally.resize(_tally_score.size(), 0.0); + + _current_tally.resize(_tally_score.size()); + _current_raw_tally.resize(_tally_score.size()); + _current_raw_tally_std_dev.resize(_tally_score.size()); + _previous_tally.resize(_tally_score.size()); + + auto [index, spatial_filter] = spatialFilter(); + _filter_index = index; + + // TODO: Append to this to add other filters + std::vector filters = {spatial_filter}; + + // Create the tally, assign the required filters and apply the triggers. + _local_tally_index = openmc::model::tallies.size(); + _local_tally = openmc::Tally::create(); + _local_tally->set_scores(_tally_score); + _local_tally->estimator_ = _estimator; + _local_tally->set_filters(filters); + applyTriggersToLocalTally(_local_tally); +} + +void +TallyBase::resetTally() +{ + // Erase the tally. + openmc::model::tallies.erase(openmc::model::tallies.begin() + _local_tally_index); + + // Erase the filter(s). + openmc::model::tally_filters.erase(openmc::model::tally_filters.begin() + _filter_index); +} + +void +TallyBase::addScore(const std::string & score) +{ + _tally_score.push_back(score); + + std::string s = score; + std::replace(s.begin(), s.end(), '-', '_'); + _tally_name.push_back(s); + + _local_sum_tally.resize(_tally_score.size(), 0.0); + _local_mean_tally.resize(_tally_score.size(), 0.0); + + _current_tally.resize(_tally_score.size()); + _current_raw_tally.resize(_tally_score.size()); + _current_raw_tally_std_dev.resize(_tally_score.size()); + _previous_tally.resize(_tally_score.size()); +} + +void +TallyBase::computeSumAndMean() +{ + for (unsigned int score = 0; score < _tally_score.size(); ++score) + { + _local_sum_tally[score] = _openmc_problem.tallySumAcrossBins({_local_tally}, score); + _local_mean_tally[score] = _openmc_problem.tallyMeanAcrossBins({_local_tally}, score); + } +} + +void +TallyBase::relaxAndNormalizeTally(unsigned int local_score, const Real & alpha, const Real & norm) +{ + auto & current = _current_tally[local_score]; + auto & previous = _previous_tally[local_score]; + auto & current_raw = _current_raw_tally[local_score]; + auto & current_raw_std_dev = _current_raw_tally_std_dev[local_score]; + + auto mean_tally = _openmc_problem.tallySum(_local_tally, local_score); + /** + * If the value over the whole domain is zero, then the values in the individual bins must be + * zero. We need to avoid divide-by-zeros. + */ + current_raw = std::abs(norm) < ZERO_TALLY_THRESHOLD + ? static_cast>(mean_tally * 0.0) + : static_cast>(mean_tally / norm); + + auto sum_sq = xt::view(_local_tally->results_, + xt::all(), + local_score, + static_cast(openmc::TallyResult::SUM_SQ)); + auto rel_err = _openmc_problem.relativeError(mean_tally, sum_sq, _local_tally->n_realizations_); + current_raw_std_dev = rel_err * current_raw; + + if (_openmc_problem.fixedPointIteration() == 0 || alpha == 1.0) + { + current = current_raw; + previous = current_raw; + return; + } + + // Save the current tally (from the previous iteration) into the previous one. + std::copy(current.cbegin(), current.cend(), previous.begin()); + + // Relax the tallies by alpha. TODO: skip relaxation when alpha is one. + auto relaxed_tally = (1.0 - alpha) * previous + alpha * current_raw; + std::copy(relaxed_tally.cbegin(), relaxed_tally.cend(), current.begin()); +} + +const openmc::Tally * +TallyBase::getWrappedTally() const +{ + if (!_local_tally) + mooseError("This tally has not been initialized!"); + + return _local_tally; +} + +void +TallyBase::fillElementalAuxVariable(const unsigned int & var_num, + const std::vector & elem_ids, + const Real & value) +{ + auto & solution = _aux.solution(); + auto sys_number = _aux.number(); + + // loop over all the elements and set the specified variable to the specified value + for (const auto & e : elem_ids) + { + auto elem_ptr = _mesh.queryElemPtr(e); + + if (!_openmc_problem.isLocalElem(elem_ptr)) + continue; + + auto dof_idx = elem_ptr->dof_number(sys_number, var_num, 0); + solution.set(dof_idx, value); + } +} + +void +TallyBase::applyTriggersToLocalTally(openmc::Tally * tally) +{ + if (_tally_trigger) + for (int score = 0; score < _tally_score.size(); ++score) + tally->triggers_.push_back({_openmc_problem.triggerMetric((*_tally_trigger)[score]), + _tally_trigger_threshold[score], + false, + score}); +} +#endif diff --git a/test/tests/controls/openmc_nuclide_densities/error.i b/test/tests/controls/openmc_nuclide_densities/error.i index fffc7148b..c894d6366 100644 --- a/test/tests/controls/openmc_nuclide_densities/error.i +++ b/test/tests/controls/openmc_nuclide_densities/error.i @@ -17,12 +17,17 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '0' temperature_blocks = '0' cell_level = 0 power = 100.0 + + [Tallies] + [Cell] + type = CellTally + blocks = 0 + [] + [] [] [UserObjects] diff --git a/test/tests/controls/openmc_nuclide_densities/openmc.i b/test/tests/controls/openmc_nuclide_densities/openmc.i index 80b01db07..999322687 100644 --- a/test/tests/controls/openmc_nuclide_densities/openmc.i +++ b/test/tests/controls/openmc_nuclide_densities/openmc.i @@ -17,11 +17,16 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '0' cell_level = 0 power = 100.0 + + [Tallies] + [Cell] + type = CellTally + blocks = 0 + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/cell_tallies/csg_step_1/openmc.i b/test/tests/neutronics/dagmc/cell_tallies/csg_step_1/openmc.i index 1acf37dcf..fa926844d 100644 --- a/test/tests/neutronics/dagmc/cell_tallies/csg_step_1/openmc.i +++ b/test/tests/neutronics/dagmc/cell_tallies/csg_step_1/openmc.i @@ -37,12 +37,17 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '1 2' temperature_blocks = '1 2' cell_level = 0 power = 100.0 + + [Tallies] + [Cell] + type = CellTally + blocks = '1 2' + [] + [] [] [Postprocessors] diff --git a/test/tests/neutronics/dagmc/cell_tallies/csg_step_2/openmc.i b/test/tests/neutronics/dagmc/cell_tallies/csg_step_2/openmc.i index f3e274276..0997a9b24 100644 --- a/test/tests/neutronics/dagmc/cell_tallies/csg_step_2/openmc.i +++ b/test/tests/neutronics/dagmc/cell_tallies/csg_step_2/openmc.i @@ -43,11 +43,16 @@ dT = 50.0 [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '1 2' temperature_blocks = '1 2' cell_level = 0 power = 100.0 + + [Tallies] + [Cell] + type = CellTally + blocks = '1 2' + [] + [] [] [Postprocessors] diff --git a/test/tests/neutronics/dagmc/cell_tallies/null_density.i b/test/tests/neutronics/dagmc/cell_tallies/null_density.i index 2de6c372f..ef6d98cfe 100644 --- a/test/tests/neutronics/dagmc/cell_tallies/null_density.i +++ b/test/tests/neutronics/dagmc/cell_tallies/null_density.i @@ -52,14 +52,19 @@ dT = 50.0 [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '1 2' temperature_blocks = '1 2' density_blocks = '1 2' cell_level = 0 power = 100.0 skinner = moab + + [Tallies] + [Cell] + type = CellTally + blocks = '1 2' + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/cell_tallies/one_bin.i b/test/tests/neutronics/dagmc/cell_tallies/one_bin.i index d6a24cdc7..60c74b372 100644 --- a/test/tests/neutronics/dagmc/cell_tallies/one_bin.i +++ b/test/tests/neutronics/dagmc/cell_tallies/one_bin.i @@ -30,13 +30,18 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '1 2' temperature_blocks = '1 2' cell_level = 0 power = 100.0 skinner = moab + + [Tallies] + [Cell] + type = CellTally + blocks = '1 2' + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/cell_tallies/openmc.i b/test/tests/neutronics/dagmc/cell_tallies/openmc.i index 272b92061..bf9896bac 100644 --- a/test/tests/neutronics/dagmc/cell_tallies/openmc.i +++ b/test/tests/neutronics/dagmc/cell_tallies/openmc.i @@ -44,13 +44,18 @@ dT = 50.0 [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '1 2' temperature_blocks = '1 2' cell_level = 0 power = 100.0 skinner = moab + + [Tallies] + [Cell] + type = CellTally + blocks = '1 2' + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/cell_tallies/with_scaling.i b/test/tests/neutronics/dagmc/cell_tallies/with_scaling.i index db270c418..9d171bb35 100644 --- a/test/tests/neutronics/dagmc/cell_tallies/with_scaling.i +++ b/test/tests/neutronics/dagmc/cell_tallies/with_scaling.i @@ -40,8 +40,6 @@ scale = 100.0 [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '1 2' scaling = ${scale} temperature_blocks = '1 2' @@ -49,6 +47,13 @@ scale = 100.0 power = 16.0 skinner = moab + + [Tallies] + [Cell] + type = CellTally + blocks = '1 2' + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/density_skin/csg_step_2/openmc.i b/test/tests/neutronics/dagmc/density_skin/csg_step_2/openmc.i index 140d6dc2a..6c5dcf0c2 100644 --- a/test/tests/neutronics/dagmc/density_skin/csg_step_2/openmc.i +++ b/test/tests/neutronics/dagmc/density_skin/csg_step_2/openmc.i @@ -67,12 +67,17 @@ dT = 50.0 [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '1 2' temperature_blocks = '1 2' density_blocks = '1 2' cell_level = 0 power = 100.0 + + [Tallies] + [Mesh] + type = CellTally + blocks = '1 2' + [] + [] [] [Postprocessors] diff --git a/test/tests/neutronics/dagmc/density_skin/disjoint_bins.i b/test/tests/neutronics/dagmc/density_skin/disjoint_bins.i index 05cce1f33..9a06c691e 100644 --- a/test/tests/neutronics/dagmc/density_skin/disjoint_bins.i +++ b/test/tests/neutronics/dagmc/density_skin/disjoint_bins.i @@ -37,8 +37,6 @@ dT = 50.0 [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '1 2' temperature_blocks = '1 2' density_blocks = '1 2' @@ -46,6 +44,13 @@ dT = 50.0 power = 100.0 skinner = moab + + [Tallies] + [Mesh] + type = CellTally + blocks = '1 2' + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/density_skin/only_solid.i b/test/tests/neutronics/dagmc/density_skin/only_solid.i index db6ee4ea7..916b86974 100644 --- a/test/tests/neutronics/dagmc/density_skin/only_solid.i +++ b/test/tests/neutronics/dagmc/density_skin/only_solid.i @@ -15,13 +15,18 @@ type = OpenMCCellAverageProblem verbose = true initial_properties = xml - tally_type = cell - tally_blocks = '1 2' temperature_blocks = '1 2' cell_level = 0 power = 100.0 skinner = moab + + [Tallies] + [Mesh] + type = CellTally + blocks = '1 2' + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/density_skin/openmc.i b/test/tests/neutronics/dagmc/density_skin/openmc.i index 66f236a90..d8f180217 100644 --- a/test/tests/neutronics/dagmc/density_skin/openmc.i +++ b/test/tests/neutronics/dagmc/density_skin/openmc.i @@ -60,14 +60,19 @@ drho = 50.0 [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '1 2' temperature_blocks = '1 2' density_blocks = '1 2' power = 100.0 skinner = moab cell_level = 0 + + [Tallies] + [Mesh] + type = CellTally + blocks = '1 2' + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/incompatible_geom/has_csg/openmc.i b/test/tests/neutronics/dagmc/incompatible_geom/has_csg/openmc.i index 85616f4ca..968ad218b 100644 --- a/test/tests/neutronics/dagmc/incompatible_geom/has_csg/openmc.i +++ b/test/tests/neutronics/dagmc/incompatible_geom/has_csg/openmc.i @@ -9,12 +9,16 @@ type = OpenMCCellAverageProblem initial_properties = xml power = 100.0 - tally_type = mesh cell_level = 0 temperature_blocks = '1 2' - mesh_template = ../../mesh_tallies/slab.e - skinner = moab + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = ../../mesh_tallies/slab.e + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/incompatible_geom/mismatch/openmc.i b/test/tests/neutronics/dagmc/incompatible_geom/mismatch/openmc.i index 566cc99e0..edb08ae00 100644 --- a/test/tests/neutronics/dagmc/incompatible_geom/mismatch/openmc.i +++ b/test/tests/neutronics/dagmc/incompatible_geom/mismatch/openmc.i @@ -16,8 +16,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = mesh - mesh_template = ../../mesh_tallies/slab.e temperature_blocks = '1' cell_level = 0 @@ -25,6 +23,13 @@ initial_properties = xml skinner = moab + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = ../../mesh_tallies/slab.e + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/mesh_tallies/csg_step_1/openmc.i b/test/tests/neutronics/dagmc/mesh_tallies/csg_step_1/openmc.i index 72eb9e44d..7dc8d249e 100644 --- a/test/tests/neutronics/dagmc/mesh_tallies/csg_step_1/openmc.i +++ b/test/tests/neutronics/dagmc/mesh_tallies/csg_step_1/openmc.i @@ -37,12 +37,17 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = mesh - mesh_template = ../slab.e temperature_blocks = '1 2' cell_level = 0 power = 100.0 + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = ../slab.e + [] + [] [] [Postprocessors] diff --git a/test/tests/neutronics/dagmc/mesh_tallies/csg_step_2/openmc.i b/test/tests/neutronics/dagmc/mesh_tallies/csg_step_2/openmc.i index ff87b8a0b..a01070cee 100644 --- a/test/tests/neutronics/dagmc/mesh_tallies/csg_step_2/openmc.i +++ b/test/tests/neutronics/dagmc/mesh_tallies/csg_step_2/openmc.i @@ -43,12 +43,17 @@ dT = 50.0 [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = mesh - mesh_template = ../slab.e temperature_blocks = '1 2' cell_level = 0 power = 100.0 + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = ../slab.e + [] + [] [] [Postprocessors] diff --git a/test/tests/neutronics/dagmc/mesh_tallies/direct_tally.i b/test/tests/neutronics/dagmc/mesh_tallies/direct_tally.i index f83b3a13d..c132ce669 100644 --- a/test/tests/neutronics/dagmc/mesh_tallies/direct_tally.i +++ b/test/tests/neutronics/dagmc/mesh_tallies/direct_tally.i @@ -45,13 +45,18 @@ dT = 50.0 [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = mesh temperature_blocks = '1 2' cell_level = 0 power = 100.0 skinner = moab + + [Tallies] + [Mesh] + type = MeshTally + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/mesh_tallies/disjoint_bins.i b/test/tests/neutronics/dagmc/mesh_tallies/disjoint_bins.i index 06e65954c..947b328ae 100644 --- a/test/tests/neutronics/dagmc/mesh_tallies/disjoint_bins.i +++ b/test/tests/neutronics/dagmc/mesh_tallies/disjoint_bins.i @@ -31,14 +31,19 @@ dT = 50.0 [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = mesh - mesh_template = slab.e temperature_blocks = '1 2' cell_level = 0 power = 100.0 skinner = moab + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = slab.e + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/mesh_tallies/one_bin.i b/test/tests/neutronics/dagmc/mesh_tallies/one_bin.i index afca15fb1..ecbd8bb3c 100644 --- a/test/tests/neutronics/dagmc/mesh_tallies/one_bin.i +++ b/test/tests/neutronics/dagmc/mesh_tallies/one_bin.i @@ -29,14 +29,19 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = mesh - mesh_template = slab.e temperature_blocks = '1 2' cell_level = 0 power = 100.0 skinner = moab + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = slab.e + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/mesh_tallies/openmc.i b/test/tests/neutronics/dagmc/mesh_tallies/openmc.i index e64a2bb69..425c0eee3 100644 --- a/test/tests/neutronics/dagmc/mesh_tallies/openmc.i +++ b/test/tests/neutronics/dagmc/mesh_tallies/openmc.i @@ -44,14 +44,19 @@ dT = 50.0 [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = mesh - mesh_template = slab.e temperature_blocks = '1 2' cell_level = 0 power = 100.0 skinner = moab + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = slab.e + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/mesh_tallies/with_scaling.i b/test/tests/neutronics/dagmc/mesh_tallies/with_scaling.i index 2dc0df2fe..43a6fc4da 100644 --- a/test/tests/neutronics/dagmc/mesh_tallies/with_scaling.i +++ b/test/tests/neutronics/dagmc/mesh_tallies/with_scaling.i @@ -40,8 +40,6 @@ scale = 100.0 [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = mesh - mesh_template = scale_in.e scaling = ${scale} temperature_blocks = '1 2' @@ -49,6 +47,13 @@ scale = 100.0 power = 16.0 skinner = moab + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = scale_in.e + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/missing_graveyard.i b/test/tests/neutronics/dagmc/missing_graveyard.i index 7a6e7db6b..48505ab40 100644 --- a/test/tests/neutronics/dagmc/missing_graveyard.i +++ b/test/tests/neutronics/dagmc/missing_graveyard.i @@ -10,11 +10,16 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = mesh cell_level = 0 temperature_blocks = '1' power = 1000.0 skinner = moab + + [Tallies] + [Mesh] + type = MeshTally + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/no_symmetry.i b/test/tests/neutronics/dagmc/no_symmetry.i index ac92e82b7..15ea9dcaf 100644 --- a/test/tests/neutronics/dagmc/no_symmetry.i +++ b/test/tests/neutronics/dagmc/no_symmetry.i @@ -10,13 +10,18 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = mesh - mesh_template = ../meshes/tet_cube.e cell_level = 0 temperature_blocks = '1' power = 1000.0 skinner = moab symmetry_mapper = sym + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = ../meshes/tet_cube.e + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/properties.i b/test/tests/neutronics/dagmc/properties.i index e91152f03..17925d123 100644 --- a/test/tests/neutronics/dagmc/properties.i +++ b/test/tests/neutronics/dagmc/properties.i @@ -8,14 +8,19 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = cell cell_level = 0 - tally_blocks = '1' temperature_blocks = '1' power = 1000.0 skinner = moab initial_properties = hdf5 + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/dagmc/wrong_uo.i b/test/tests/neutronics/dagmc/wrong_uo.i index f956938ad..e9dadfc95 100644 --- a/test/tests/neutronics/dagmc/wrong_uo.i +++ b/test/tests/neutronics/dagmc/wrong_uo.i @@ -8,12 +8,17 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = cell cell_level = 0 - tally_blocks = '1' temperature_blocks = '1' power = 1000.0 skinner = moab + + [Tallies] + [Mesh] + type = CellTally + blocks = '1' + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/density/openmc.i b/test/tests/neutronics/density/openmc.i index 00749652f..ea9ad86e5 100644 --- a/test/tests/neutronics/density/openmc.i +++ b/test/tests/neutronics/density/openmc.i @@ -94,7 +94,6 @@ rho0 = 1000.0 [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = none density_blocks = '2 1' temperature_blocks = '200 1' cell_level = 0 diff --git a/test/tests/neutronics/feedback/different_units/openmc.i b/test/tests/neutronics/feedback/different_units/openmc.i index b54d7c83d..b5e1f21f4 100644 --- a/test/tests/neutronics/feedback/different_units/openmc.i +++ b/test/tests/neutronics/feedback/different_units/openmc.i @@ -45,10 +45,14 @@ cell_level = 0 - tally_blocks = '1' - tally_type = cell - scaling = 100.0 + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/different_units/openmc_cm.i b/test/tests/neutronics/feedback/different_units/openmc_cm.i index 41ebbc1cf..cc7e526c9 100644 --- a/test/tests/neutronics/feedback/different_units/openmc_cm.i +++ b/test/tests/neutronics/feedback/different_units/openmc_cm.i @@ -45,9 +45,13 @@ cell_level = 0 - tally_type = cell - tally_blocks = '1' - tally_name = 'heat_source' + [Tallies] + [Cell] + type = CellTally + blocks = '1' + name = 'heat_source' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/interchangeable/no_data_flow.i b/test/tests/neutronics/feedback/interchangeable/no_data_flow.i index 92a5c19fe..159a3dc5d 100644 --- a/test/tests/neutronics/feedback/interchangeable/no_data_flow.i +++ b/test/tests/neutronics/feedback/interchangeable/no_data_flow.i @@ -83,8 +83,6 @@ active = '' [Problem] type = OpenMCCellAverageProblem verbose = true - - tally_type = none [] [Postprocessors] diff --git a/test/tests/neutronics/feedback/interchangeable/no_tally.i b/test/tests/neutronics/feedback/interchangeable/no_tally.i new file mode 100644 index 000000000..90a6226d2 --- /dev/null +++ b/test/tests/neutronics/feedback/interchangeable/no_tally.i @@ -0,0 +1,149 @@ +[Mesh] + [3d] + type = GeneratedMeshGenerator + dim = 3 + nx = 4 + ny = 4 + nz = 2 + xmin = -12.5 + xmax = 87.5 + ymin = -12.5 + ymax = 37.5 + zmin = -12.5 + zmax = 12.5 + [] + [upper_block] + type = ParsedSubdomainMeshGenerator + input = 3d + combinatorial_geometry = 'y > 12.5' + block_id = 1 + [] +[] + +[AuxVariables] + [cell_temperature] + family = MONOMIAL + order = CONSTANT + [] + [material_id] + family = MONOMIAL + order = CONSTANT + [] + [cell_density] + family = MONOMIAL + order = CONSTANT + [] +[] + +[AuxKernels] + [cell_temperature] + type = CellTemperatureAux + variable = cell_temperature + [] + [material_id] + type = CellMaterialIDAux + variable = material_id + [] + [cell_density] + type = CellDensityAux + variable = cell_density + [] +[] + +[ICs] +active = '' + [temp] + type = ConstantIC + variable = temp + value = 300.0 + [] + [density] + type = ConstantIC + variable = density + value = 15.0e3 + [] +[] + +[Problem] + type = OpenMCCellAverageProblem + verbose = true + + cell_level = 0 + + power = 1.0 +[] + +[Postprocessors] + [k] + type = KEigenvalue + [] + [power_0] + type = ElementIntegralVariablePostprocessor + variable = kappa_fission + block = '0' + [] + [power_1] + type = ElementIntegralVariablePostprocessor + variable = kappa_fission + block = '1' + [] + [id_0] + type = ElementAverageValue + variable = cell_id + block = '0' + [] + [id_1] + type = ElementAverageValue + variable = cell_id + block = '1' + [] + [instance_0] + type = ElementAverageValue + variable = cell_instance + block = '0' + [] + [instance_1] + type = ElementAverageValue + variable = cell_instance + block = '1' + [] + [temp_0] + type = ElementAverageValue + variable = cell_temperature + block = '0' + [] + [temp_1] + type = ElementAverageValue + variable = cell_temperature + block = '1' + [] + [rho_0] + type = ElementAverageValue + variable = cell_density + block = '0' + [] + [rho_1] + type = ElementAverageValue + variable = cell_density + block = '1' + [] + [mat_0] + type = ElementAverageValue + variable = material_id + block = '0' + [] + [mat_1] + type = ElementAverageValue + variable = material_id + block = '1' + [] +[] + +[Executioner] + type = Transient + num_steps = 1 +[] + +[Outputs] + csv = true +[] diff --git a/test/tests/neutronics/feedback/interchangeable/openmc.i b/test/tests/neutronics/feedback/interchangeable/openmc.i index 40c56910b..f431b385c 100644 --- a/test/tests/neutronics/feedback/interchangeable/openmc.i +++ b/test/tests/neutronics/feedback/interchangeable/openmc.i @@ -68,11 +68,16 @@ active = '' type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '0 1' cell_level = 0 power = 1.0 + + [Tallies] + [Cell] + type = CellTally + blocks = '0 1' + [] + [] [] [Postprocessors] diff --git a/test/tests/neutronics/feedback/interchangeable/tests b/test/tests/neutronics/feedback/interchangeable/tests index f58a55b83..80d811df7 100644 --- a/test/tests/neutronics/feedback/interchangeable/tests +++ b/test/tests/neutronics/feedback/interchangeable/tests @@ -36,8 +36,8 @@ [] [T_feedback_no_tally] type = CSVDiff - input = openmc.i - cli_args = 'Problem/temperature_blocks="0 1" ICs/active="temp" Outputs/file_base=T_no_tally Problem/tally_type=none Postprocessors/inactive="power_0 power_1"' + input = no_tally.i + cli_args = 'Problem/temperature_blocks="0 1" ICs/active="temp" Outputs/file_base=T_no_tally Postprocessors/inactive="power_0 power_1"' csvdiff = T_no_tally.csv requirement = 'The system shall allow OpenMC tallies to be extracted on cell blocks which also have temperature feedback.' 'The tallies were compared against separate standalone OpenMC runs.' @@ -45,8 +45,8 @@ [] [rho_feedback_no_tally] type = CSVDiff - input = openmc.i - cli_args = 'Problem/density_blocks="0 1" Problem/temperature_blocks="0 1" ICs/active="density temp" ICs/temp/value=500.0 Outputs/file_base=rho_no_tally Problem/tally_type=none Postprocessors/inactive="power_0 power_1"' + input = no_tally.i + cli_args = 'Problem/density_blocks="0 1" Problem/temperature_blocks="0 1" ICs/active="density temp" ICs/temp/value=500.0 Outputs/file_base=rho_no_tally Postprocessors/inactive="power_0 power_1"' csvdiff = rho_no_tally.csv requirement = 'The system shall allow OpenMC tallies to be extracted on cell blocks which also have temperature/density feedback.' 'The tallies were compared against separate standalone OpenMC runs.' diff --git a/test/tests/neutronics/feedback/lattice/non_material_fluid.i b/test/tests/neutronics/feedback/lattice/non_material_fluid.i index c63efa753..c3f4b5795 100644 --- a/test/tests/neutronics/feedback/lattice/non_material_fluid.i +++ b/test/tests/neutronics/feedback/lattice/non_material_fluid.i @@ -13,8 +13,12 @@ cell_level = 0 - tally_type = mesh - mesh_template = ../../meshes/pincell.e + [Tallies] + [Mesh] + type = MeshTally + mesh_template = ../../meshes/pincell.e + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/lattice/openmc.i b/test/tests/neutronics/feedback/lattice/openmc.i index 65e4f7493..4df3ba3e2 100644 --- a/test/tests/neutronics/feedback/lattice/openmc.i +++ b/test/tests/neutronics/feedback/lattice/openmc.i @@ -45,9 +45,13 @@ cell_level = 1 - tally_type = cell - tally_blocks = '1' - tally_name = heat_source + [Tallies] + [Cell] + type = CellTally + blocks = '1' + name = heat_source + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/lattice/openmc_scores.i b/test/tests/neutronics/feedback/lattice/openmc_scores.i index df456599c..fd68d80ef 100644 --- a/test/tests/neutronics/feedback/lattice/openmc_scores.i +++ b/test/tests/neutronics/feedback/lattice/openmc_scores.i @@ -12,13 +12,18 @@ cell_level = 1 - tally_type = cell - tally_blocks = '1 2 3' check_tally_sum = false - tally_score = heating - tally_name = heat_source initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '1 2 3' + score = heating + name = heat_source + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/lattice/tests b/test/tests/neutronics/feedback/lattice/tests index 32dbab85b..ee2fdd446 100644 --- a/test/tests/neutronics/feedback/lattice/tests +++ b/test/tests/neutronics/feedback/lattice/tests @@ -41,7 +41,7 @@ type = CSVDiff input = openmc_scores.i csvdiff = heating_local_out.csv - cli_args = 'Problem/tally_score=heating_local Outputs/file_base=heating_local_out' + cli_args = 'Problem/Tallies/Cell/score=heating_local Outputs/file_base=heating_local_out' requirement = "The system shall allow the user to specify a 'heating-local' score in the OpenMC tally." required_objects = 'OpenMCCellAverageProblem' [] @@ -49,7 +49,7 @@ type = CSVDiff input = openmc_scores.i csvdiff = damage_energy_out.csv - cli_args = 'Problem/tally_score=damage_energy Outputs/file_base=damage_energy_out' + cli_args = 'Problem/Tallies/Cell/score=damage_energy Outputs/file_base=damage_energy_out' requirement = "The system shall allow the user to specify a 'damage-energy' score in the OpenMC tally." required_objects = 'OpenMCCellAverageProblem' [] @@ -57,7 +57,7 @@ type = CSVDiff input = openmc_scores.i csvdiff = fission_q_prompt_out.csv - cli_args = 'Problem/tally_score=fission_q_prompt Outputs/file_base=fission_q_prompt_out' + cli_args = 'Problem/Tallies/Cell/score=fission_q_prompt Outputs/file_base=fission_q_prompt_out' requirement = "The system shall allow the user to specify a 'fission-q-prompt' score in the OpenMC tally." required_objects = 'OpenMCCellAverageProblem' [] @@ -65,7 +65,7 @@ type = CSVDiff input = openmc_scores.i csvdiff = fission_q_recoverable_out.csv - cli_args = 'Problem/tally_score=fission_q_recoverable Outputs/file_base=fission_q_recoverable_out' + cli_args = 'Problem/Tallies/Cell/score=fission_q_recoverable Outputs/file_base=fission_q_recoverable_out' requirement = "The system shall allow the user to specify a 'fission-q-recoverable' score in the OpenMC tally." required_objects = 'OpenMCCellAverageProblem' [] diff --git a/test/tests/neutronics/feedback/materials/openmc.i b/test/tests/neutronics/feedback/materials/openmc.i index be3e43b37..827501c62 100644 --- a/test/tests/neutronics/feedback/materials/openmc.i +++ b/test/tests/neutronics/feedback/materials/openmc.i @@ -59,10 +59,14 @@ cell_level = 0 - tally_type = cell - tally_blocks = '1' - map_density_by_cell = false + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Postprocessors] diff --git a/test/tests/neutronics/feedback/multi_component_density/multi/multi_vars.i b/test/tests/neutronics/feedback/multi_component_density/multi/multi_vars.i index 560a3532d..e5f4e0797 100644 --- a/test/tests/neutronics/feedback/multi_component_density/multi/multi_vars.i +++ b/test/tests/neutronics/feedback/multi_component_density/multi/multi_vars.i @@ -91,8 +91,6 @@ density_variables = 'density1; density2; density3' density_blocks = '0; 1; 50' temperature_blocks = '0 1 50' - - tally_type = none [] [Postprocessors] diff --git a/test/tests/neutronics/feedback/multi_component_density/multi/multi_vars_alt.i b/test/tests/neutronics/feedback/multi_component_density/multi/multi_vars_alt.i index e99665b53..c0b1ada5d 100644 --- a/test/tests/neutronics/feedback/multi_component_density/multi/multi_vars_alt.i +++ b/test/tests/neutronics/feedback/multi_component_density/multi/multi_vars_alt.i @@ -91,8 +91,6 @@ density_variables = 'density1; density2' density_blocks = '0; 1 50' temperature_blocks = '0 1 50' - - tally_type = none [] [Postprocessors] diff --git a/test/tests/neutronics/feedback/multi_component_density/multi/openmc.i b/test/tests/neutronics/feedback/multi_component_density/multi/openmc.i index 9139be9fc..b95ee70f7 100644 --- a/test/tests/neutronics/feedback/multi_component_density/multi/openmc.i +++ b/test/tests/neutronics/feedback/multi_component_density/multi/openmc.i @@ -57,8 +57,6 @@ density_variables = 'density1 ; density2' density_blocks = '0; 1' temperature_blocks = '0 1' - - tally_type = none [] [Postprocessors] diff --git a/test/tests/neutronics/feedback/multi_component_density/openmc.i b/test/tests/neutronics/feedback/multi_component_density/openmc.i index fd75dab9a..991fcba5f 100644 --- a/test/tests/neutronics/feedback/multi_component_density/openmc.i +++ b/test/tests/neutronics/feedback/multi_component_density/openmc.i @@ -8,14 +8,19 @@ [Problem] type = OpenMCCellAverageProblem power = 500.0 - tally_blocks = '1' - tally_type = cell cell_level = 1 verbose = true density_variables = 'density1' density_blocks = '1; 2 3' temperature_blocks = '1 2 3' + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/multi_component_density/openmc_incorrect_length.i b/test/tests/neutronics/feedback/multi_component_density/openmc_incorrect_length.i index 82a6a9808..eda757397 100644 --- a/test/tests/neutronics/feedback/multi_component_density/openmc_incorrect_length.i +++ b/test/tests/neutronics/feedback/multi_component_density/openmc_incorrect_length.i @@ -21,13 +21,17 @@ [Problem] type = OpenMCCellAverageProblem power = 500.0 - tally_blocks = '1' - tally_type = cell - cell_level = 1 density_variables = 'density1; density2' density_blocks = '1' temperature_blocks = '1' + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/multi_component_temp/multi_vars.i b/test/tests/neutronics/feedback/multi_component_temp/multi_vars.i index 8528f9801..8863881b2 100644 --- a/test/tests/neutronics/feedback/multi_component_temp/multi_vars.i +++ b/test/tests/neutronics/feedback/multi_component_temp/multi_vars.i @@ -72,13 +72,18 @@ [Problem] type = OpenMCCellAverageProblem power = 500.0 - tally_blocks = '1 3 2 10' - tally_type = cell cell_level = 0 verbose = true temperature_variables = 'solid_temp; fluid_temp; other_temp' temperature_blocks = '1 3; 2; 10' + + [Tallies] + [Cell] + type = CellTally + blocks = '1 3 2 10' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/multi_component_temp/openmc.i b/test/tests/neutronics/feedback/multi_component_temp/openmc.i index 98fd66e93..a1c61443b 100644 --- a/test/tests/neutronics/feedback/multi_component_temp/openmc.i +++ b/test/tests/neutronics/feedback/multi_component_temp/openmc.i @@ -33,13 +33,18 @@ [Problem] type = OpenMCCellAverageProblem power = 500.0 - tally_blocks = '1' - tally_type = cell cell_level = 1 verbose = true temperature_variables = 'solid_temp; fluid_temp' temperature_blocks = '1 3; 2' + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/multi_component_temp/openmc_incorrect_length.i b/test/tests/neutronics/feedback/multi_component_temp/openmc_incorrect_length.i index e77625805..106299498 100644 --- a/test/tests/neutronics/feedback/multi_component_temp/openmc_incorrect_length.i +++ b/test/tests/neutronics/feedback/multi_component_temp/openmc_incorrect_length.i @@ -21,12 +21,17 @@ [Problem] type = OpenMCCellAverageProblem power = 500.0 - tally_blocks = '1' - tally_type = cell cell_level = 1 temperature_variables = 'solid_temp; fluid_temp' temperature_blocks = '1' + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/multiple_levels/openmc.i b/test/tests/neutronics/feedback/multiple_levels/openmc.i index 1377c71f4..1b5e81186 100644 --- a/test/tests/neutronics/feedback/multiple_levels/openmc.i +++ b/test/tests/neutronics/feedback/multiple_levels/openmc.i @@ -54,9 +54,14 @@ temperature_blocks = '1 3 5' lowest_cell_level = 1 - tally_blocks = '1' verbose = true - tally_type = cell + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/single_level/openmc.i b/test/tests/neutronics/feedback/single_level/openmc.i index 052d899ec..facd1f6e5 100644 --- a/test/tests/neutronics/feedback/single_level/openmc.i +++ b/test/tests/neutronics/feedback/single_level/openmc.i @@ -40,10 +40,15 @@ power = 500.0 temperature_blocks = '1 2 3' density_blocks = '2' - tally_blocks = '1' verbose = true - tally_type = cell cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/temperature/one_one/openmc.i b/test/tests/neutronics/feedback/temperature/one_one/openmc.i index 39e1d8c10..a39ac3fae 100644 --- a/test/tests/neutronics/feedback/temperature/one_one/openmc.i +++ b/test/tests/neutronics/feedback/temperature/one_one/openmc.i @@ -23,7 +23,6 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = none temperature_blocks = '0' cell_level = 0 [] diff --git a/test/tests/neutronics/feedback/temperature/one_two/openmc.i b/test/tests/neutronics/feedback/temperature/one_two/openmc.i index 92bd14731..7f2700a60 100644 --- a/test/tests/neutronics/feedback/temperature/one_two/openmc.i +++ b/test/tests/neutronics/feedback/temperature/one_two/openmc.i @@ -44,7 +44,6 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = none temperature_blocks = '0' cell_level = 0 [] diff --git a/test/tests/neutronics/feedback/temperature/two_one/openmc.i b/test/tests/neutronics/feedback/temperature/two_one/openmc.i index fe7c0a6f4..7e09cb26a 100644 --- a/test/tests/neutronics/feedback/temperature/two_one/openmc.i +++ b/test/tests/neutronics/feedback/temperature/two_one/openmc.i @@ -54,8 +54,6 @@ verbose = true power = 100.0 - tally_type = none - temperature_blocks = '0 3' cell_level = 0 [] diff --git a/test/tests/neutronics/feedback/temperature/two_one/openmc_default.i b/test/tests/neutronics/feedback/temperature/two_one/openmc_default.i index 724bc9d58..9977995e0 100644 --- a/test/tests/neutronics/feedback/temperature/two_one/openmc_default.i +++ b/test/tests/neutronics/feedback/temperature/two_one/openmc_default.i @@ -52,7 +52,6 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = none cell_level = 0 temperature_blocks = '3 0' [] diff --git a/test/tests/neutronics/feedback/temperature/two_one/openmc_multi_temp.i b/test/tests/neutronics/feedback/temperature/two_one/openmc_multi_temp.i index d503e7b3c..e2f0fbb0b 100644 --- a/test/tests/neutronics/feedback/temperature/two_one/openmc_multi_temp.i +++ b/test/tests/neutronics/feedback/temperature/two_one/openmc_multi_temp.i @@ -57,7 +57,6 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = none cell_level = 0 temperature_variables = 'temp_left; temp_right' temperature_blocks = '3; 0' diff --git a/test/tests/neutronics/feedback/triso/cache/openmc.i b/test/tests/neutronics/feedback/triso/cache/openmc.i index 5923127df..6079a255c 100644 --- a/test/tests/neutronics/feedback/triso/cache/openmc.i +++ b/test/tests/neutronics/feedback/triso/cache/openmc.i @@ -40,14 +40,18 @@ h = 1.0 [Problem] type = OpenMCCellAverageProblem - - tally_score = heating_local power = 100.0 scaling = 100.0 temperature_blocks = '0 100' - tally_blocks = '0 100' - tally_type = cell lowest_cell_level = 1 + + [Tallies] + [Cell] + type = CellTally + blocks = '0 100' + score = heating_local + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/triso/different_fill_univs/openmc.i b/test/tests/neutronics/feedback/triso/different_fill_univs/openmc.i index 0627f0afa..d417a1208 100644 --- a/test/tests/neutronics/feedback/triso/different_fill_univs/openmc.i +++ b/test/tests/neutronics/feedback/triso/different_fill_univs/openmc.i @@ -8,7 +8,6 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - check_equal_mapped_tally_volumes = true # this input should error because the universes filling the tally cells # dont match identically @@ -18,9 +17,15 @@ power = 100.0 scaling = 100.0 temperature_blocks = '1 2' - tally_blocks = '2' - tally_type = cell cell_level = 1 + + [Tallies] + [Cell] + type = CellTally + blocks = '2' + check_equal_mapped_tally_volumes = true + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/triso/missing_triso_fill/openmc.i b/test/tests/neutronics/feedback/triso/missing_triso_fill/openmc.i index 7ec6662fc..5e5701319 100644 --- a/test/tests/neutronics/feedback/triso/missing_triso_fill/openmc.i +++ b/test/tests/neutronics/feedback/triso/missing_triso_fill/openmc.i @@ -17,8 +17,6 @@ power = 2000.0 scaling = 100.0 temperature_blocks = '2 5' - tally_blocks = '2' - tally_type = cell cell_level = 1 # This input should error because the offset we compute for shifting cell instances @@ -26,6 +24,13 @@ # TRISO universes from the tally setup identical_cell_fills = '2' check_identical_cell_fills = true + + [Tallies] + [Cell] + type = CellTally + blocks = '2' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/feedback/triso/openmc.i b/test/tests/neutronics/feedback/triso/openmc.i index e3cde72c7..cb22ef77d 100644 --- a/test/tests/neutronics/feedback/triso/openmc.i +++ b/test/tests/neutronics/feedback/triso/openmc.i @@ -37,16 +37,21 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - check_equal_mapped_tally_volumes = true identical_cell_fills = '2' check_identical_cell_fills = true power = 100.0 scaling = 100.0 temperature_blocks = '1 2' - tally_blocks = '2' - tally_type = cell cell_level = 1 + + [Tallies] + [Cell] + type = CellTally + blocks = '2' + check_equal_mapped_tally_volumes = true + [] + [] [] diff --git a/test/tests/neutronics/feedback/universes/fill_in_flat/openmc.i b/test/tests/neutronics/feedback/universes/fill_in_flat/openmc.i index ab73e795b..5c162d271 100644 --- a/test/tests/neutronics/feedback/universes/fill_in_flat/openmc.i +++ b/test/tests/neutronics/feedback/universes/fill_in_flat/openmc.i @@ -27,7 +27,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = none verbose = true temperature_blocks = '0' cell_level = 0 diff --git a/test/tests/neutronics/feedback/universes/lattice_in_flat/openmc.i b/test/tests/neutronics/feedback/universes/lattice_in_flat/openmc.i index e6a7186ff..5f2a30864 100644 --- a/test/tests/neutronics/feedback/universes/lattice_in_flat/openmc.i +++ b/test/tests/neutronics/feedback/universes/lattice_in_flat/openmc.i @@ -13,7 +13,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = none temperature_blocks = '0' cell_level = 0 [] diff --git a/test/tests/neutronics/feedback/unmapped_moose/openmc.i b/test/tests/neutronics/feedback/unmapped_moose/openmc.i index 9fde7fd55..b231403e5 100644 --- a/test/tests/neutronics/feedback/unmapped_moose/openmc.i +++ b/test/tests/neutronics/feedback/unmapped_moose/openmc.i @@ -48,10 +48,15 @@ power = 500.0 temperature_blocks = '1 2 3' density_blocks = '2' - tally_blocks = '1' verbose = true - tally_type = cell cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/fixed_source/flux.i b/test/tests/neutronics/fixed_source/flux.i index 42bbe48b9..7eb6d6f19 100644 --- a/test/tests/neutronics/fixed_source/flux.i +++ b/test/tests/neutronics/fixed_source/flux.i @@ -36,12 +36,16 @@ source_strength = 1e12 temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100 200' cell_level = 0 - tally_type = cell initial_properties = xml - tally_score = flux + [Tallies] + [Cell] + type = CellTally + score = flux + blocks = '100 200' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/fixed_source/overlap_all.i b/test/tests/neutronics/fixed_source/overlap_all.i index 7491105c0..4bff18bcb 100644 --- a/test/tests/neutronics/fixed_source/overlap_all.i +++ b/test/tests/neutronics/fixed_source/overlap_all.i @@ -36,10 +36,15 @@ source_strength = 1e12 temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100 200' cell_level = 0 - tally_type = cell initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '100 200' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/fixed_source/overlap_solid.i b/test/tests/neutronics/fixed_source/overlap_solid.i index 224fa3a9e..283f067db 100644 --- a/test/tests/neutronics/fixed_source/overlap_solid.i +++ b/test/tests/neutronics/fixed_source/overlap_solid.i @@ -35,14 +35,19 @@ verbose = true source_strength = 1e12 temperature_blocks = '100' - tally_blocks = '100' cell_level = 0 - tally_type = cell initial_properties = xml # we are omitting the fluid regions from feedback (which have some fissile material), # so we need to explicitly skip the tally check check_tally_sum = false + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/flux/flux.i b/test/tests/neutronics/flux/flux.i index 4030bd4f2..2598fc2ae 100644 --- a/test/tests/neutronics/flux/flux.i +++ b/test/tests/neutronics/flux/flux.i @@ -36,13 +36,18 @@ power = 1e4 temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100 200' cell_level = 0 - tally_type = cell initial_properties = xml - tally_score = 'heating flux' source_rate_normalization = 'heating' + + [Tallies] + [Cell] + type = CellTally + score = 'heating flux' + blocks = '100 200' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/flux/missing_norm.i b/test/tests/neutronics/flux/missing_norm.i index 04144daa3..75cc07d1e 100644 --- a/test/tests/neutronics/flux/missing_norm.i +++ b/test/tests/neutronics/flux/missing_norm.i @@ -22,12 +22,17 @@ verbose = true power = 1e4 temperature_blocks = '100' - tally_blocks = '100' + cell_level = 0 - tally_type = cell initial_properties = xml - tally_score = 'heating flux H3_production' + [Tallies] + [Cell] + type = CellTally + score = 'heating flux H3_production' + blocks = '100' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/flux/tests b/test/tests/neutronics/flux/tests index d9178817a..7210090fd 100644 --- a/test/tests/neutronics/flux/tests +++ b/test/tests/neutronics/flux/tests @@ -9,7 +9,7 @@ [flip_order] type = CSVDiff input = flux.i - cli_args = 'Problem/tally_score="flux heating"' + cli_args = 'Problem/Tallies/Cell/score="flux heating"' csvdiff = flux_out.csv requirement = "The system shall correctly normalize flux tallies for eigenvalue simulations when listed in an arbitrary order." required_objects = 'OpenMCCellAverageProblem' @@ -17,7 +17,7 @@ [flip_order_and_name] type = CSVDiff input = flux.i - cli_args = 'Problem/tally_score="flux heating" Problem/tally_name="flux0 heating0" Postprocessors/flux_pebble1/variable=flux0 Postprocessors/flux_pebble2/variable=flux0 Postprocessors/flux_pebble3/variable=flux0 Postprocessors/flux_fluid/variable=flux0 Problem/source_rate_normalization="heating"' + cli_args = 'Problem/Tallies/Cell/score="flux heating" Problem/Tallies/Cell/name="flux0 heating0" Postprocessors/flux_pebble1/variable=flux0 Postprocessors/flux_pebble2/variable=flux0 Postprocessors/flux_pebble3/variable=flux0 Postprocessors/flux_fluid/variable=flux0 Problem/source_rate_normalization="heating"' csvdiff = flux_out.csv requirement = "The system shall correctly normalize flux tallies for eigenvalue simulations when listed in an arbitrary order and with user-defined names." required_objects = 'OpenMCCellAverageProblem' @@ -25,7 +25,7 @@ [not_already_added] type = CSVDiff input = flux.i - cli_args = 'Problem/tally_score="flux" Problem/source_rate_normalization=heating' + cli_args = 'Problem/Tallies/Cell/score="flux" Problem/source_rate_normalization=heating' csvdiff = flux_out.csv requirement = "The system shall correctly normalize flux tallies for eigenvalue simulations when the source rate normalization tally is not already added." required_objects = 'OpenMCCellAverageProblem' @@ -33,9 +33,9 @@ [missing_name] type = RunException input = flux.i - cli_args = 'Problem/tally_score="flux" Problem/tally_name="f"' - expect_err = "When specifying 'tally_name', the score indicated in 'source_rate_normalization' must be\n" - "listed in 'tally_score' so that we know what you want to name that score \(heating\)" + cli_args = 'Problem/Tallies/Cell/score="flux" Problem/Tallies/Cell/name="f"' + expect_err = "When specifying 'name', the score indicated in 'source_rate_normalization' must be\n" + "listed in 'score' so that we know what you want to name that score \(heating\)" requirement = "The system shall error if the user tries to name only a partial set of the total tally scores." required_objects = 'OpenMCCellAverageProblem' [] diff --git a/test/tests/neutronics/heat_source/cell_volumes.i b/test/tests/neutronics/heat_source/cell_volumes.i index ee13a58fd..4baf0a753 100644 --- a/test/tests/neutronics/heat_source/cell_volumes.i +++ b/test/tests/neutronics/heat_source/cell_volumes.i @@ -55,12 +55,17 @@ power = 100.0 temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100 200' - tally_type = cell initial_properties = xml verbose = true cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + blocks = '100 200' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/heat_source/custom_name.i b/test/tests/neutronics/heat_source/custom_name.i index dc699b93f..4a74d2f0c 100644 --- a/test/tests/neutronics/heat_source/custom_name.i +++ b/test/tests/neutronics/heat_source/custom_name.i @@ -35,24 +35,28 @@ power = 100.0 temperature_blocks = '100 200' density_blocks = '200' - tally_type = cell - - # This input has fissile material in the fluid phase, so we will get a warning - # that we are neglecting some of the global kappa-fission distribution; so here - # the power is the total power of the OpenMC problem, and only a fraction of this - # will be computed in the solid pebbles - tally_blocks = '100' initial_properties = xml # We are skipping some feedback with fissile regions, so we need to turn off the check check_tally_sum = false - # Use a custom tally name - tally_name = "volumetric_power" - verbose = true cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + # Use a custom tally name + name = "volumetric_power" + + # This input has fissile material in the fluid phase, so we will get a warning + # that we are neglecting some of the global kappa-fission distribution; so here + # the power is the total power of the OpenMC problem, and only a fraction of this + # will be computed in the solid pebbles + blocks = '100' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/heat_source/default_tally_blocks.i b/test/tests/neutronics/heat_source/default_tally_blocks.i index 983f11501..6fc91ac1d 100644 --- a/test/tests/neutronics/heat_source/default_tally_blocks.i +++ b/test/tests/neutronics/heat_source/default_tally_blocks.i @@ -37,11 +37,16 @@ density_blocks = '200' verbose = true cell_level = 0 - tally_type = cell - tally_name = heat_source - tally_blocks = '100 200' initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + name = heat_source + blocks = '100 200' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/heat_source/distrib_cell/solid.i b/test/tests/neutronics/heat_source/distrib_cell/solid.i index b3817be44..8f74b3a15 100644 --- a/test/tests/neutronics/heat_source/distrib_cell/solid.i +++ b/test/tests/neutronics/heat_source/distrib_cell/solid.i @@ -35,16 +35,20 @@ power = 100.0 temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100 200' - tally_name = heat_source - tally_type = cell - # This turns off the density and temperature update on the first syncSolutions; # this uses whatever temperature and densities are set in OpenMCs XML files for first step initial_properties = xml verbose = true cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + name = heat_source + blocks = '100 200' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/heat_source/from_postprocessor.i b/test/tests/neutronics/heat_source/from_postprocessor.i index 152a06285..742ccca80 100644 --- a/test/tests/neutronics/heat_source/from_postprocessor.i +++ b/test/tests/neutronics/heat_source/from_postprocessor.i @@ -42,13 +42,18 @@ power = p temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100 200' verbose = true cell_level = 0 - tally_type = cell - tally_name = heat_source initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '100 200' + name = heat_source + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/heat_source/multi_tally.i b/test/tests/neutronics/heat_source/multi_tally.i index bfc2acbdc..166e0a0be 100644 --- a/test/tests/neutronics/heat_source/multi_tally.i +++ b/test/tests/neutronics/heat_source/multi_tally.i @@ -35,14 +35,18 @@ power = 100.0 temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100 200' verbose = true cell_level = 0 - tally_type = cell - - tally_score = 'kappa_fission heating' initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + score = 'kappa_fission heating' + blocks = '100 200' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/heat_source/multi_tally_mesh.i b/test/tests/neutronics/heat_source/multi_tally_mesh.i index f3aae9240..5d84ea545 100644 --- a/test/tests/neutronics/heat_source/multi_tally_mesh.i +++ b/test/tests/neutronics/heat_source/multi_tally_mesh.i @@ -27,16 +27,20 @@ verbose = true cell_level = 0 - tally_type = mesh - mesh_template = ../meshes/sphere.e - mesh_translations = '0 0 0 - 0 0 4 - 0 0 8' check_tally_sum = false - tally_score = 'kappa_fission heating' - initial_properties = xml + + [Tallies] + [Mesh] + type = MeshTally + score = 'kappa_fission heating' + mesh_template = ../meshes/sphere.e + mesh_translations = '0 0 0 + 0 0 4 + 0 0 8' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/heat_source/multi_tally_overlap_solid.i b/test/tests/neutronics/heat_source/multi_tally_overlap_solid.i index 0bcc5a8aa..1a4fb82fa 100644 --- a/test/tests/neutronics/heat_source/multi_tally_overlap_solid.i +++ b/test/tests/neutronics/heat_source/multi_tally_overlap_solid.i @@ -35,16 +35,20 @@ power = 100.0 temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100' verbose = true cell_level = 0 - tally_type = cell normalize_by_global_tally = false check_tally_sum = false - tally_score = 'kappa_fission heating' - initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + score = 'kappa_fission heating' + blocks = '100' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/heat_source/overlap_all.i b/test/tests/neutronics/heat_source/overlap_all.i index 7d7e63753..e1f6252c6 100644 --- a/test/tests/neutronics/heat_source/overlap_all.i +++ b/test/tests/neutronics/heat_source/overlap_all.i @@ -35,13 +35,18 @@ power = 100.0 temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100 200' verbose = true cell_level = 0 - tally_type = cell - tally_name = heat_source initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '100 200' + name = heat_source + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/heat_source/overlap_fluid.i b/test/tests/neutronics/heat_source/overlap_fluid.i index b1bd85b13..f32c7d31f 100644 --- a/test/tests/neutronics/heat_source/overlap_fluid.i +++ b/test/tests/neutronics/heat_source/overlap_fluid.i @@ -35,14 +35,6 @@ power = 100.0 temperature_blocks = '100 200' density_blocks = '200' - tally_type = cell - tally_name = heat_source - - # This input has fissile material in the solid phase, so we will get a warning - # that we are neglecting some of the global kappa-fission distribution; so here - # the power is the total power of the OpenMC problem, and only a fraction of this - # will be computed in the fluid - tally_blocks = '200' initial_properties = xml @@ -51,6 +43,19 @@ verbose = true cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + name = heat_source + + # This input has fissile material in the solid phase, so we will get a warning + # that we are neglecting some of the global kappa-fission distribution; so here + # the power is the total power of the OpenMC problem, and only a fraction of this + # will be computed in the fluid + blocks = '200' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/heat_source/overlap_solid.i b/test/tests/neutronics/heat_source/overlap_solid.i index 136359c23..fe8c5714f 100644 --- a/test/tests/neutronics/heat_source/overlap_solid.i +++ b/test/tests/neutronics/heat_source/overlap_solid.i @@ -35,14 +35,6 @@ power = 100.0 temperature_blocks = '100 200' density_blocks = '200' - tally_type = cell - tally_name = heat_source - - # This input has fissile material in the fluid phase, so we will get a warning - # that we are neglecting some of the global kappa-fission distribution; so here - # the power is the total power of the OpenMC problem, and only a fraction of this - # will be computed in the solid pebbles - tally_blocks = '100' initial_properties = xml @@ -51,6 +43,19 @@ verbose = true cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + name = heat_source + + # This input has fissile material in the fluid phase, so we will get a warning + # that we are neglecting some of the global kappa-fission distribution; so here + # the power is the total power of the OpenMC problem, and only a fraction of this + # will be computed in the solid pebbles + blocks = '100' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/heat_source/partial_overlap_moose_union.i b/test/tests/neutronics/heat_source/partial_overlap_moose_union.i index addb6823e..51ca5781f 100644 --- a/test/tests/neutronics/heat_source/partial_overlap_moose_union.i +++ b/test/tests/neutronics/heat_source/partial_overlap_moose_union.i @@ -40,13 +40,18 @@ power = 100.0 temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100 200' - tally_type = cell - tally_name = heat_source initial_properties = xml verbose = true cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + name = heat_source + blocks = '100 200' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/heat_source/partial_overlap_openmc_union.i b/test/tests/neutronics/heat_source/partial_overlap_openmc_union.i index 318849a6c..ef086ce7d 100644 --- a/test/tests/neutronics/heat_source/partial_overlap_openmc_union.i +++ b/test/tests/neutronics/heat_source/partial_overlap_openmc_union.i @@ -38,9 +38,6 @@ power = 100.0 temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100 200' - tally_type = cell - tally_name = heat_source initial_properties = xml @@ -49,6 +46,14 @@ verbose = true cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + name = heat_source + blocks = '100 200' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/mesh_tally/different_units.i b/test/tests/neutronics/mesh_tally/different_units.i index 28458d8b2..379c40e68 100644 --- a/test/tests/neutronics/mesh_tally/different_units.i +++ b/test/tests/neutronics/mesh_tally/different_units.i @@ -19,14 +19,19 @@ verbose = true cell_level = 0 - tally_type = mesh power = 100.0 # the [Mesh] is in units of meters, so the mesh_template must also be in units of meters scaling = 100.0 - mesh_template = '../meshes/sphere_in_m.e' normalize_by_global_tally = false + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = '../meshes/sphere_in_m.e' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/mesh_tally/different_units_and_translations.i b/test/tests/neutronics/mesh_tally/different_units_and_translations.i index 0206db249..d7c67ab0a 100644 --- a/test/tests/neutronics/mesh_tally/different_units_and_translations.i +++ b/test/tests/neutronics/mesh_tally/different_units_and_translations.i @@ -43,15 +43,19 @@ cell_level = 0 normalize_by_global_tally = false - tally_type = mesh - # Because the [Mesh] is in units of meters, the mesh translations and mesh template # must also be in units of meters scaling = 100.0 - mesh_translations_file = pebble_centers_in_m.txt - mesh_template = '../meshes/sphere_in_m.e' power = 100.0 + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = '../meshes/sphere_in_m.e' + mesh_translations_file = pebble_centers_in_m.txt + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/mesh_tally/fission_tally_std_dev.i b/test/tests/neutronics/mesh_tally/fission_tally_std_dev.i index a8f506100..636b718c0 100644 --- a/test/tests/neutronics/mesh_tally/fission_tally_std_dev.i +++ b/test/tests/neutronics/mesh_tally/fission_tally_std_dev.i @@ -20,12 +20,16 @@ cell_level = 0 normalize_by_global_tally = true - tally_type = mesh - mesh_template = '../meshes/sphere.e' power = 100.0 check_tally_sum = false - output = 'unrelaxed_tally_std_dev' + [Tallies] + [Mesh] + type = MeshTally + mesh_template = '../meshes/sphere.e' + output = 'unrelaxed_tally_std_dev' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/mesh_tally/multiple_meshes.i b/test/tests/neutronics/mesh_tally/multiple_meshes.i index 2ca003a31..d57d5adc5 100644 --- a/test/tests/neutronics/mesh_tally/multiple_meshes.i +++ b/test/tests/neutronics/mesh_tally/multiple_meshes.i @@ -42,11 +42,16 @@ verbose = true cell_level = 0 normalize_by_global_tally = false - mesh_translations_file = pebble_centers.txt - tally_type = mesh - mesh_template = '../meshes/sphere.e' power = 100.0 + + [Tallies] + [Mesh] + type = MeshTally + mesh_translations_file = pebble_centers.txt + mesh_template = '../meshes/sphere.e' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/mesh_tally/multiple_meshes_global.i b/test/tests/neutronics/mesh_tally/multiple_meshes_global.i index 8615eea61..56d056047 100644 --- a/test/tests/neutronics/mesh_tally/multiple_meshes_global.i +++ b/test/tests/neutronics/mesh_tally/multiple_meshes_global.i @@ -44,14 +44,19 @@ verbose = true cell_level = 0 normalize_by_global_tally = true - mesh_translations = '0 0 0 - 0 0 4 - 0 0 8' - tally_type = mesh - mesh_template = '../meshes/sphere.e' power = 100.0 check_tally_sum = false + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = '../meshes/sphere.e' + mesh_translations = '0 0 0 + 0 0 4 + 0 0 8' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/mesh_tally/no_coupling.i b/test/tests/neutronics/mesh_tally/no_coupling.i index 41a1c6e23..158073861 100644 --- a/test/tests/neutronics/mesh_tally/no_coupling.i +++ b/test/tests/neutronics/mesh_tally/no_coupling.i @@ -10,9 +10,14 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = mesh check_tally_sum = false power = 100.0 + + [Tallies] + [Mesh] + type = MeshTally + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/mesh_tally/one_mesh.i b/test/tests/neutronics/mesh_tally/one_mesh.i index b237befc1..5507032a8 100644 --- a/test/tests/neutronics/mesh_tally/one_mesh.i +++ b/test/tests/neutronics/mesh_tally/one_mesh.i @@ -20,9 +20,14 @@ cell_level = 0 normalize_by_global_tally = false - tally_type = mesh - mesh_template = '../meshes/sphere.e' power = 100.0 + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = '../meshes/sphere.e' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/mesh_tally/one_mesh_global.i b/test/tests/neutronics/mesh_tally/one_mesh_global.i index b6387d9df..d91c8bf52 100644 --- a/test/tests/neutronics/mesh_tally/one_mesh_global.i +++ b/test/tests/neutronics/mesh_tally/one_mesh_global.i @@ -20,10 +20,15 @@ cell_level = 0 normalize_by_global_tally = true - tally_type = mesh - mesh_template = '../meshes/sphere.e' power = 100.0 check_tally_sum = false + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = '../meshes/sphere.e' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/mesh_tally/one_mesh_no_input_file.i b/test/tests/neutronics/mesh_tally/one_mesh_no_input_file.i index 70b13d172..a97ac9bf5 100644 --- a/test/tests/neutronics/mesh_tally/one_mesh_no_input_file.i +++ b/test/tests/neutronics/mesh_tally/one_mesh_no_input_file.i @@ -20,8 +20,13 @@ cell_level = 0 normalize_by_global_tally = false - tally_type = mesh power = 100.0 + + [Tallies] + [Mesh] + type = MeshTally + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/openmc_xml/openmc.i b/test/tests/neutronics/openmc_xml/openmc.i index bcf2750c3..27f3d8529 100644 --- a/test/tests/neutronics/openmc_xml/openmc.i +++ b/test/tests/neutronics/openmc_xml/openmc.i @@ -7,7 +7,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = none [] [Executioner] diff --git a/test/tests/neutronics/openmc_xml/skip_statepoint.i b/test/tests/neutronics/openmc_xml/skip_statepoint.i index 27f537ec6..5d4b78f75 100644 --- a/test/tests/neutronics/openmc_xml/skip_statepoint.i +++ b/test/tests/neutronics/openmc_xml/skip_statepoint.i @@ -8,7 +8,6 @@ [Problem] type = OpenMCCellAverageProblem power = 100.0 - tally_type = none inactive_batches = 3 batches = 8 diff --git a/test/tests/neutronics/photon/openmc.i b/test/tests/neutronics/photon/openmc.i index 01a2082b7..cb76fe2ca 100644 --- a/test/tests/neutronics/photon/openmc.i +++ b/test/tests/neutronics/photon/openmc.i @@ -8,10 +8,15 @@ power = 500.0 cell_level = 1 - tally_type = cell - tally_blocks = '1' - tally_score = 'heating' - tally_estimator = tracklength + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + score = 'heating' + estimator = tracklength + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/relaxation/cell_tallies/dufek_gudowski.i b/test/tests/neutronics/relaxation/cell_tallies/dufek_gudowski.i index 726e90ada..11b201900 100644 --- a/test/tests/neutronics/relaxation/cell_tallies/dufek_gudowski.i +++ b/test/tests/neutronics/relaxation/cell_tallies/dufek_gudowski.i @@ -38,13 +38,18 @@ verbose = true power = 100.0 temperature_blocks = '0' - tally_blocks = '0' - tally_type = cell cell_level = 1 scaling = 100.0 relaxation = dufek_gudowski first_iteration_particles = 1000 + + [Tallies] + [Cell] + type = CellTally + blocks = '0' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/relaxation/cell_tallies/multi_tally.i b/test/tests/neutronics/relaxation/cell_tallies/multi_tally.i index 462b7cce1..1dde8e165 100644 --- a/test/tests/neutronics/relaxation/cell_tallies/multi_tally.i +++ b/test/tests/neutronics/relaxation/cell_tallies/multi_tally.i @@ -37,8 +37,6 @@ verbose = true power = 1500.0 temperature_blocks = '0' - tally_blocks = '0' - tally_type = cell cell_level = 1 scaling = 100.0 @@ -46,8 +44,14 @@ # wont match check_tally_sum = false - tally_score = 'kappa_fission heating' - tally_name = 'heat_source heating' + [Tallies] + [Cell] + type = CellTally + score = 'kappa_fission heating' + name = 'heat_source heating' + blocks = '0' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/relaxation/cell_tallies/openmc.i b/test/tests/neutronics/relaxation/cell_tallies/openmc.i index 92f5c2c66..bc2527cff 100644 --- a/test/tests/neutronics/relaxation/cell_tallies/openmc.i +++ b/test/tests/neutronics/relaxation/cell_tallies/openmc.i @@ -38,12 +38,17 @@ verbose = true power = 100.0 temperature_blocks = '0' - tally_blocks = '0' - tally_type = cell cell_level = 1 scaling = 100.0 volume_calculation = vol + + [Tallies] + [Cell] + type = CellTally + blocks = '0' + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/relaxation/cell_tallies/openmc_nonaligned.i b/test/tests/neutronics/relaxation/cell_tallies/openmc_nonaligned.i index e0db812a2..8107e9cd2 100644 --- a/test/tests/neutronics/relaxation/cell_tallies/openmc_nonaligned.i +++ b/test/tests/neutronics/relaxation/cell_tallies/openmc_nonaligned.i @@ -37,14 +37,19 @@ verbose = true power = 1500.0 temperature_blocks = '0' - tally_blocks = '0' - tally_type = cell cell_level = 1 scaling = 100.0 # our problem is missing overlap for fissile regions, so our local and global tallies # wont match check_tally_sum = false + + [Tallies] + [Cell] + type = CellTally + blocks = '0' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/relaxation/cell_tallies/output_fission_tally.i b/test/tests/neutronics/relaxation/cell_tallies/output_fission_tally.i index cd3cc8d3e..406b277a0 100644 --- a/test/tests/neutronics/relaxation/cell_tallies/output_fission_tally.i +++ b/test/tests/neutronics/relaxation/cell_tallies/output_fission_tally.i @@ -38,13 +38,18 @@ verbose = true power = 1500.0 temperature_blocks = '0' - tally_blocks = '0' - tally_type = cell cell_level = 1 scaling = 100.0 - output = 'unrelaxed_tally' relaxation = constant + + [Tallies] + [Cell] + type = CellTally + blocks = '0' + output = 'unrelaxed_tally' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/relaxation/mesh_tallies/openmc.i b/test/tests/neutronics/relaxation/mesh_tallies/openmc.i index 98c25a9f9..dbae3aa35 100644 --- a/test/tests/neutronics/relaxation/mesh_tallies/openmc.i +++ b/test/tests/neutronics/relaxation/mesh_tallies/openmc.i @@ -40,15 +40,21 @@ verbose = true power = 1500.0 temperature_blocks = '0' - tally_type = mesh - mesh_template = ../../meshes/sphere_in_m.e - mesh_translations = '0.0 0.0 0.02 - 0.0 0.0 0.06 - 0.0 0.0 0.10' + cell_level = 1 scaling = 100.0 check_tally_sum = false + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = ../../meshes/sphere_in_m.e + mesh_translations = '0.0 0.0 0.02 + 0.0 0.0 0.06 + 0.0 0.0 0.10' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/relaxation/mesh_tallies/output_fission_tally.i b/test/tests/neutronics/relaxation/mesh_tallies/output_fission_tally.i index 680cd880b..2fabc7a11 100644 --- a/test/tests/neutronics/relaxation/mesh_tallies/output_fission_tally.i +++ b/test/tests/neutronics/relaxation/mesh_tallies/output_fission_tally.i @@ -40,18 +40,24 @@ verbose = true power = 1500.0 temperature_blocks = '0' - tally_type = mesh - mesh_template = ../../meshes/sphere_in_m.e - mesh_translations = '0.0 0.0 0.02 - 0.0 0.0 0.06 - 0.0 0.0 0.10' + cell_level = 1 scaling = 100.0 - output = 'unrelaxed_tally' relaxation = constant check_tally_sum = false + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = ../../meshes/sphere_in_m.e + mesh_translations = '0.0 0.0 0.02 + 0.0 0.0 0.06 + 0.0 0.0 0.10' + output = 'unrelaxed_tally' + [] + [] [] diff --git a/test/tests/neutronics/solid/openmc_missing_pebble.i b/test/tests/neutronics/solid/openmc_missing_pebble.i index e01e5b68e..dbfe0e7ec 100644 --- a/test/tests/neutronics/solid/openmc_missing_pebble.i +++ b/test/tests/neutronics/solid/openmc_missing_pebble.i @@ -20,10 +20,15 @@ [Problem] type = OpenMCCellAverageProblem power = 10.0 - tally_type = cell - tally_blocks = '1' cell_level = 0 temperature_blocks = '1' + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/solid/openmc_zero.i b/test/tests/neutronics/solid/openmc_zero.i index 97fddb985..2cda463af 100644 --- a/test/tests/neutronics/solid/openmc_zero.i +++ b/test/tests/neutronics/solid/openmc_zero.i @@ -22,11 +22,16 @@ [Problem] type = OpenMCCellAverageProblem power = 0.0 - tally_type = cell - tally_blocks = '1' - tally_name = heat_source cell_level = 0 temperature_blocks = '1' + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + name = heat_source + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/source/openmc.i b/test/tests/neutronics/source/openmc.i index 5a4e48f17..618525e82 100644 --- a/test/tests/neutronics/source/openmc.i +++ b/test/tests/neutronics/source/openmc.i @@ -17,10 +17,15 @@ type = OpenMCCellAverageProblem power = ${fparse 3000e6 / 273 / (17 * 17)} temperature_blocks = '1 2 3' - tally_blocks = '2 3' - tally_type = cell cell_level = 0 reuse_source = true + + [Tallies] + [Cell] + type = CellTally + blocks = '2 3' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/symmetry/openmc.i b/test/tests/neutronics/symmetry/openmc.i index 2e25e0fe0..239ba5c2f 100644 --- a/test/tests/neutronics/symmetry/openmc.i +++ b/test/tests/neutronics/symmetry/openmc.i @@ -56,11 +56,16 @@ height = 6.343 # height of the full core (m) scaling = 100.0 temperature_blocks = '1 2 101' density_blocks = '101' - tally_blocks = '2' - tally_type = cell cell_level = 1 symmetry_mapper = sym + + [Tallies] + [Cell] + type = CellTally + blocks = '2' + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/symmetry/rotational/openmc.i b/test/tests/neutronics/symmetry/rotational/openmc.i index e383b2c67..844b9a04a 100644 --- a/test/tests/neutronics/symmetry/rotational/openmc.i +++ b/test/tests/neutronics/symmetry/rotational/openmc.i @@ -49,18 +49,22 @@ [] [] - [Problem] type = OpenMCCellAverageProblem power = 1000.0 scaling = 100.0 temperature_blocks = '1 2 200' - tally_blocks = '2' - tally_type = cell cell_level = 1 symmetry_mapper = sym + + [Tallies] + [Cell] + type = CellTally + blocks = '2' + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/symmetry/triso/openmc.i b/test/tests/neutronics/symmetry/triso/openmc.i index 17146bd0a..b77bc1d73 100644 --- a/test/tests/neutronics/symmetry/triso/openmc.i +++ b/test/tests/neutronics/symmetry/triso/openmc.i @@ -53,16 +53,21 @@ type = OpenMCCellAverageProblem identical_cell_fills = 'compacts' check_identical_cell_fills = true - check_equal_mapped_tally_volumes = true power = 1000.0 scaling = 100.0 temperature_blocks = 'graphite compacts' - tally_blocks = 'compacts' - tally_type = cell cell_level = 1 symmetry_mapper = sym + + [Tallies] + [Cell] + type = CellTally + blocks = 'compacts' + check_equal_mapped_tally_volumes = true + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/symmetry/wrong_uo.i b/test/tests/neutronics/symmetry/wrong_uo.i index 23696ea50..a3daef8d0 100644 --- a/test/tests/neutronics/symmetry/wrong_uo.i +++ b/test/tests/neutronics/symmetry/wrong_uo.i @@ -17,11 +17,16 @@ height = 6.343 # height of the full core (m) power = 1000.0 scaling = 100.0 temperature_blocks = '1 2' - tally_type = mesh - mesh_template = solid_mesh_in.e cell_level = 1 symmetry_mapper = sym + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = solid_mesh_in.e + [] + [] [] [UserObjects] diff --git a/test/tests/neutronics/tallies/tritium/openmc.i b/test/tests/neutronics/tallies/tritium/openmc.i index a2f0b7f9d..6900befce 100644 --- a/test/tests/neutronics/tallies/tritium/openmc.i +++ b/test/tests/neutronics/tallies/tritium/openmc.i @@ -37,12 +37,17 @@ temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100 200' cell_level = 0 - tally_type = cell - tally_score = 'H3_production' initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + score = 'H3_production' + blocks = '100 200' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/tally_system/geometry.xml b/test/tests/neutronics/tally_system/geometry.xml new file mode 100644 index 000000000..3f4dc24e7 --- /dev/null +++ b/test/tests/neutronics/tally_system/geometry.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/test/tests/neutronics/tally_system/gold/multi_cell_out.csv b/test/tests/neutronics/tally_system/gold/multi_cell_out.csv new file mode 100644 index 000000000..49789d15c --- /dev/null +++ b/test/tests/neutronics/tally_system/gold/multi_cell_out.csv @@ -0,0 +1,3 @@ +time,Pebble_1_Flux,Pebble_1_Heat,Pebble_1_Vol,Pebble_2_Flux,Pebble_2_Heat,Pebble_2_Vol,Pebble_3_Flux,Pebble_3_Heat,Pebble_3_Vol +0,0,0,0,0,0,0,0,0,0 +1,2.5979298893453e+15,91.245617807911,13.221284052406,2.6097931587198e+15,235.4335644497,13.221284052406,2.5898024811709e+15,398.08854558273,13.221284052406 diff --git a/test/tests/neutronics/tally_system/gold/multi_cell_relax_out.csv b/test/tests/neutronics/tally_system/gold/multi_cell_relax_out.csv new file mode 100644 index 000000000..6c7c556c2 --- /dev/null +++ b/test/tests/neutronics/tally_system/gold/multi_cell_relax_out.csv @@ -0,0 +1,5 @@ +time,Pebble_1_Flux,Pebble_1_Heat,Pebble_2_Flux,Pebble_2_Heat,Pebble_3_Flux,Pebble_3_Heat +0,0,0,0,0,0,0 +1,2.5979298893453e+15,91.245617807911,2.6097931587198e+15,235.4335644497,2.5898024811709e+15,398.08854558273 +2,2.6211953903931e+15,89.85973248815,2.6514947009223e+15,234.97367680664,2.6472391598482e+15,400.22363745689 +3,2.6426708276117e+15,90.971815759453,2.6743796175397e+15,234.55898064185,2.6733965120498e+15,399.41159064178 diff --git a/test/tests/neutronics/tally_system/gold/multi_cell_triggers_out.csv b/test/tests/neutronics/tally_system/gold/multi_cell_triggers_out.csv new file mode 100644 index 000000000..7bb28dc9a --- /dev/null +++ b/test/tests/neutronics/tally_system/gold/multi_cell_triggers_out.csv @@ -0,0 +1,3 @@ +time,Pebble_1_Flux,Pebble_1_Heat,Pebble_2_Flux,Pebble_2_Heat,Pebble_3_Flux,Pebble_3_Heat +0,0,0,0,0,0,0 +1,2.5778179546668e+15,90.233612668561,2.5808328002502e+15,234.88201212936,2.5845054971767e+15,400.04578418294 diff --git a/test/tests/neutronics/tally_system/gold/multi_diff_out.e b/test/tests/neutronics/tally_system/gold/multi_diff_out.e new file mode 100644 index 000000000..bf39c6c85 Binary files /dev/null and b/test/tests/neutronics/tally_system/gold/multi_diff_out.e differ diff --git a/test/tests/neutronics/tally_system/gold/multi_diff_outputs.e b/test/tests/neutronics/tally_system/gold/multi_diff_outputs.e new file mode 100644 index 000000000..5cb503743 Binary files /dev/null and b/test/tests/neutronics/tally_system/gold/multi_diff_outputs.e differ diff --git a/test/tests/neutronics/tally_system/gold/multi_estimator_out.csv b/test/tests/neutronics/tally_system/gold/multi_estimator_out.csv new file mode 100644 index 000000000..39bd7106f --- /dev/null +++ b/test/tests/neutronics/tally_system/gold/multi_estimator_out.csv @@ -0,0 +1,3 @@ +time,Pebble_1_Flux,Pebble_1_Heat,Pebble_2_Flux,Pebble_2_Heat,Pebble_3_Flux,Pebble_3_Heat +0,0,0,0,0,0,0 +1,2.5841366193817e+15,91.245617807911,2.6175692882477e+15,235.4335644497,2.5980906706876e+15,398.08854558273 diff --git a/test/tests/neutronics/tally_system/gold/multi_mesh_out.e b/test/tests/neutronics/tally_system/gold/multi_mesh_out.e new file mode 100644 index 000000000..51f5d186f Binary files /dev/null and b/test/tests/neutronics/tally_system/gold/multi_mesh_out.e differ diff --git a/test/tests/neutronics/tally_system/gold/multi_mesh_relax_out.e b/test/tests/neutronics/tally_system/gold/multi_mesh_relax_out.e new file mode 100644 index 000000000..51842daf3 Binary files /dev/null and b/test/tests/neutronics/tally_system/gold/multi_mesh_relax_out.e differ diff --git a/test/tests/neutronics/tally_system/gold/multi_mesh_triggers_out.e b/test/tests/neutronics/tally_system/gold/multi_mesh_triggers_out.e new file mode 100644 index 000000000..fa2508653 Binary files /dev/null and b/test/tests/neutronics/tally_system/gold/multi_mesh_triggers_out.e differ diff --git a/test/tests/neutronics/tally_system/materials.xml b/test/tests/neutronics/tally_system/materials.xml new file mode 100644 index 000000000..54d5c6a86 --- /dev/null +++ b/test/tests/neutronics/tally_system/materials.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/tests/neutronics/tally_system/multi_cell.i b/test/tests/neutronics/tally_system/multi_cell.i new file mode 100644 index 000000000..ff0a7c614 --- /dev/null +++ b/test/tests/neutronics/tally_system/multi_cell.i @@ -0,0 +1,128 @@ +[Mesh] + [sphere] + type = FileMeshGenerator + file = ../meshes/sphere.e + [] + [solid] + type = CombinerGenerator + inputs = sphere + positions = '0 0 0 + 0 0 4 + 0 0 8' + [] + [solid_ids] + type = SubdomainIDGenerator + input = solid + subdomain_id = '100' + [] + [fluid] + type = FileMeshGenerator + file = ../heat_source/stoplight.exo + [] + [fluid_ids] + type = SubdomainIDGenerator + input = fluid + subdomain_id = '200' + [] + [combine] + type = CombinerGenerator + inputs = 'solid_ids fluid_ids' + [] +[] + +[AuxVariables] + [cell_volume] + family = MONOMIAL + order = CONSTANT + [] +[] + +[AuxKernels] + [cell_volume] + type = CellVolumeAux + variable = cell_volume + volume_type = mapped + [] +[] + +[Problem] + type = OpenMCCellAverageProblem + verbose = true + power = 1e4 + temperature_blocks = '100' + cell_level = 0 + initial_properties = xml + + source_rate_normalization = 'kappa_fission' + + [Tallies] + [Cell_1] + type = CellTally + score = kappa_fission + blocks = '100 200' + [] + [Cell_2] + type = CellTally + score = flux + blocks = '100 200' + [] + [] +[] + +[Postprocessors] + [Pebble_1_Vol] + type = PointValue + point = '0 0 0' + variable = cell_volume + [] + [Pebble_2_Vol] + type = PointValue + point = '0 0 4' + variable = cell_volume + [] + [Pebble_3_Vol] + type = PointValue + point = '0 0 8' + variable = cell_volume + [] + + [Pebble_1_Heat] + type = PointValue + point = '0 0 0' + variable = kappa_fission + [] + [Pebble_2_Heat] + type = PointValue + point = '0 0 4' + variable = kappa_fission + [] + [Pebble_3_Heat] + type = PointValue + point = '0 0 8' + variable = kappa_fission + [] + + [Pebble_1_Flux] + type = PointValue + point = '0 0 0' + variable = flux + [] + [Pebble_2_Flux] + type = PointValue + point = '0 0 4' + variable = flux + [] + [Pebble_3_Flux] + type = PointValue + point = '0 0 8' + variable = flux + [] +[] + +[Executioner] + type = Steady +[] + +[Outputs] + csv = true +[] diff --git a/test/tests/neutronics/tally_system/multi_cell_relax.i b/test/tests/neutronics/tally_system/multi_cell_relax.i new file mode 100644 index 000000000..0f05a554f --- /dev/null +++ b/test/tests/neutronics/tally_system/multi_cell_relax.i @@ -0,0 +1,116 @@ +[Mesh] + [sphere] + type = FileMeshGenerator + file = ../meshes/sphere.e + [] + [solid] + type = CombinerGenerator + inputs = sphere + positions = '0 0 0 + 0 0 4 + 0 0 8' + [] + [solid_ids] + type = SubdomainIDGenerator + input = solid + subdomain_id = '100' + [] + [fluid] + type = FileMeshGenerator + file = ../heat_source/stoplight.exo + [] + [fluid_ids] + type = SubdomainIDGenerator + input = fluid + subdomain_id = '200' + [] + [combine] + type = CombinerGenerator + inputs = 'solid_ids fluid_ids' + [] +[] + +[AuxKernels] + [temp] + type = FunctionAux + variable = temp + function = axial + execute_on = initial + [] +[] + +[Functions] + [axial] + type = ParsedFunction + expression = '500 + z / 0.10 * 100' + [] +[] + +[Problem] + type = OpenMCCellAverageProblem + verbose = true + power = 1e4 + temperature_blocks = '100' + cell_level = 0 + initial_properties = xml + + source_rate_normalization = 'kappa_fission' + + relaxation = constant + relaxation_factor = 0.5 + + [Tallies] + [Cell_1] + type = CellTally + score = kappa_fission + blocks = '100 200' + [] + [Cell_2] + type = CellTally + score = flux + blocks = '100 200' + [] + [] +[] + +[Postprocessors] + [Pebble_1_Heat] + type = PointValue + point = '0 0 0' + variable = kappa_fission + [] + [Pebble_2_Heat] + type = PointValue + point = '0 0 4' + variable = kappa_fission + [] + [Pebble_3_Heat] + type = PointValue + point = '0 0 8' + variable = kappa_fission + [] + [Pebble_1_Flux] + type = PointValue + point = '0 0 0' + variable = flux + [] + [Pebble_2_Flux] + type = PointValue + point = '0 0 4' + variable = flux + [] + [Pebble_3_Flux] + type = PointValue + point = '0 0 8' + variable = flux + [] +[] + +[Executioner] + type = Transient + num_steps = 3 +[] + +[Outputs] + csv = true +[] diff --git a/test/tests/neutronics/tally_system/multi_cell_triggers.i b/test/tests/neutronics/tally_system/multi_cell_triggers.i new file mode 100644 index 000000000..2428ed237 --- /dev/null +++ b/test/tests/neutronics/tally_system/multi_cell_triggers.i @@ -0,0 +1,102 @@ +[Mesh] + [sphere] + type = FileMeshGenerator + file = ../meshes/sphere.e + [] + [solid] + type = CombinerGenerator + inputs = sphere + positions = '0 0 0 + 0 0 4 + 0 0 8' + [] + [solid_ids] + type = SubdomainIDGenerator + input = solid + subdomain_id = '100' + [] + [fluid] + type = FileMeshGenerator + file = ../heat_source/stoplight.exo + [] + [fluid_ids] + type = SubdomainIDGenerator + input = fluid + subdomain_id = '200' + [] + [combine] + type = CombinerGenerator + inputs = 'solid_ids fluid_ids' + [] +[] + +[Problem] + type = OpenMCCellAverageProblem + verbose = true + power = 1e4 + temperature_blocks = '100' + cell_level = 0 + initial_properties = xml + + source_rate_normalization = 'kappa_fission' + + max_batches = 200 + + [Tallies] + [Cell_1] + type = CellTally + score = kappa_fission + blocks = '100 200' + trigger = rel_err + trigger_threshold = 1e-2 + [] + [Cell_2] + type = CellTally + score = flux + blocks = '100 200' + trigger = rel_err + trigger_threshold = 1e-2 + [] + [] +[] + +[Postprocessors] + [Pebble_1_Heat] + type = PointValue + point = '0 0 0' + variable = kappa_fission + [] + [Pebble_2_Heat] + type = PointValue + point = '0 0 4' + variable = kappa_fission + [] + [Pebble_3_Heat] + type = PointValue + point = '0 0 8' + variable = kappa_fission + [] + [Pebble_1_Flux] + type = PointValue + point = '0 0 0' + variable = flux + [] + [Pebble_2_Flux] + type = PointValue + point = '0 0 4' + variable = flux + [] + [Pebble_3_Flux] + type = PointValue + point = '0 0 8' + variable = flux + [] +[] + +[Executioner] + type = Steady +[] + +[Outputs] + csv = true +[] diff --git a/test/tests/neutronics/tally_system/multi_diff.i b/test/tests/neutronics/tally_system/multi_diff.i new file mode 100644 index 000000000..ce3f215d7 --- /dev/null +++ b/test/tests/neutronics/tally_system/multi_diff.i @@ -0,0 +1,57 @@ +[Mesh] + [sphere] + type = FileMeshGenerator + file = ../meshes/sphere.e + [] + [solid] + type = CombinerGenerator + inputs = sphere + positions = '0 0 0' + [] + [solid_ids] + type = SubdomainIDGenerator + input = solid + subdomain_id = '100' + [] + + allow_renumbering = false +[] + +[Problem] + type = OpenMCCellAverageProblem + verbose = true + power = 1e4 + temperature_blocks = '100' + cell_level = 0 + initial_properties = xml + + # The global tally check is disabled because we have a loosely fitting unstructured mesh tally. + normalize_by_global_tally = false + + source_rate_normalization = 'kappa_fission' + + # Missing some hits in the model (only tallying a single pebble instead of 3) + check_tally_sum = false + + [Tallies] + [Cell] + type = CellTally + score = 'kappa_fission' + blocks = '100' + [] + [Mesh] + type = MeshTally + score = 'flux' + mesh_translations = '0 0 0' + mesh_template = ../meshes/sphere.e + [] + [] +[] + +[Executioner] + type = Steady +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/neutronics/tally_system/multi_estimator.i b/test/tests/neutronics/tally_system/multi_estimator.i new file mode 100644 index 000000000..79936b708 --- /dev/null +++ b/test/tests/neutronics/tally_system/multi_estimator.i @@ -0,0 +1,98 @@ +[Mesh] + [sphere] + type = FileMeshGenerator + file = ../meshes/sphere.e + [] + [solid] + type = CombinerGenerator + inputs = sphere + positions = '0 0 0 + 0 0 4 + 0 0 8' + [] + [solid_ids] + type = SubdomainIDGenerator + input = solid + subdomain_id = '100' + [] + [fluid] + type = FileMeshGenerator + file = ../heat_source/stoplight.exo + [] + [fluid_ids] + type = SubdomainIDGenerator + input = fluid + subdomain_id = '200' + [] + [combine] + type = CombinerGenerator + inputs = 'solid_ids fluid_ids' + [] +[] + +[Problem] + type = OpenMCCellAverageProblem + verbose = true + power = 1e4 + temperature_blocks = '100' + cell_level = 0 + initial_properties = xml + + source_rate_normalization = 'kappa_fission' + + [Tallies] + [Cell_1] + type = CellTally + score = kappa_fission + blocks = '100 200' + estimator = tracklength + [] + [Cell_2] + type = CellTally + score = flux + blocks = '100 200' + estimator = collision + [] + [] +[] + +[Postprocessors] + [Pebble_1_Heat] + type = PointValue + point = '0 0 0' + variable = kappa_fission + [] + [Pebble_2_Heat] + type = PointValue + point = '0 0 4' + variable = kappa_fission + [] + [Pebble_3_Heat] + type = PointValue + point = '0 0 8' + variable = kappa_fission + [] + [Pebble_1_Flux] + type = PointValue + point = '0 0 0' + variable = flux + [] + [Pebble_2_Flux] + type = PointValue + point = '0 0 4' + variable = flux + [] + [Pebble_3_Flux] + type = PointValue + point = '0 0 8' + variable = flux + [] +[] + +[Executioner] + type = Steady +[] + +[Outputs] + csv = true +[] diff --git a/test/tests/neutronics/tally_system/multi_mesh.i b/test/tests/neutronics/tally_system/multi_mesh.i new file mode 100644 index 000000000..ea8e39444 --- /dev/null +++ b/test/tests/neutronics/tally_system/multi_mesh.i @@ -0,0 +1,61 @@ +[Mesh] + [sphere] + type = FileMeshGenerator + file = ../meshes/sphere.e + [] + [solid] + type = CombinerGenerator + inputs = sphere + positions = '0 0 0 + 0 0 4 + 0 0 8' + [] + [solid_ids] + type = SubdomainIDGenerator + input = solid + subdomain_id = '100' + [] + + allow_renumbering = false +[] + +[Problem] + type = OpenMCCellAverageProblem + verbose = true + power = 1e4 + temperature_blocks = '100' + cell_level = 0 + initial_properties = xml + + source_rate_normalization = 'kappa_fission' + + # The global tally check is disabled because we have a loosely fitting unstructured mesh tally. + normalize_by_global_tally = false + + [Tallies] + [Mesh_1] + type = MeshTally + score = kappa_fission + mesh_translations = '0 0 0 + 0 0 4 + 0 0 8' + mesh_template = ../meshes/sphere.e + [] + [Mesh_2] + type = MeshTally + score = flux + mesh_translations = '0 0 0 + 0 0 4 + 0 0 8' + mesh_template = ../meshes/sphere.e + [] + [] +[] + +[Executioner] + type = Steady +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/neutronics/tally_system/multi_mesh_relax.i b/test/tests/neutronics/tally_system/multi_mesh_relax.i new file mode 100644 index 000000000..51bc66194 --- /dev/null +++ b/test/tests/neutronics/tally_system/multi_mesh_relax.i @@ -0,0 +1,75 @@ +[Mesh] + [sphere] + type = FileMeshGenerator + file = ../meshes/sphere.e + [] + [solid] + type = CombinerGenerator + inputs = sphere + positions = '0 0 0' + [] + [solid_ids] + type = SubdomainIDGenerator + input = solid + subdomain_id = '100' + [] + + allow_renumbering = false +[] + +[AuxKernels] + [temp] + type = FunctionAux + variable = temp + function = axial + execute_on = initial + [] +[] + +[Functions] + [axial] + type = ParsedFunction + expression = '500 + z / 0.10 * 100' + [] +[] + +[Problem] + type = OpenMCCellAverageProblem + verbose = true + power = 1e4 + temperature_blocks = '100' + cell_level = 0 + initial_properties = xml + + source_rate_normalization = 'kappa_fission' + + relaxation = constant + relaxation_factor = 0.5 + + # The global tally check is disabled because we have a loosely fitting unstructured mesh tally. + normalize_by_global_tally = false + + [Tallies] + [Mesh_1] + type = MeshTally + score = kappa_fission + mesh_translations = '0 0 0' + mesh_template = ../meshes/sphere.e + [] + [Mesh_2] + type = MeshTally + score = flux + mesh_translations = '0 0 0' + mesh_template = ../meshes/sphere.e + [] + [] +[] + +[Executioner] + type = Transient + num_steps = 3 +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/neutronics/tally_system/multi_mesh_triggers.i b/test/tests/neutronics/tally_system/multi_mesh_triggers.i new file mode 100644 index 000000000..7d4873503 --- /dev/null +++ b/test/tests/neutronics/tally_system/multi_mesh_triggers.i @@ -0,0 +1,62 @@ +[Mesh] + [sphere] + type = FileMeshGenerator + file = ../meshes/sphere.e + [] + [solid] + type = CombinerGenerator + inputs = sphere + positions = '0 0 0' + [] + [solid_ids] + type = SubdomainIDGenerator + input = solid + subdomain_id = '100' + [] + + allow_renumbering = false +[] + +[Problem] + type = OpenMCCellAverageProblem + verbose = true + power = 1e4 + temperature_blocks = '100' + cell_level = 0 + initial_properties = xml + + source_rate_normalization = 'kappa_fission' + + # The global tally check is disabled because we have a loosely fitting unstructured mesh tally. + normalize_by_global_tally = false + + particles = 100 + max_batches = 200 + + [Tallies] + [Mesh_1] + type = MeshTally + score = kappa_fission + trigger = rel_err + trigger_threshold = 5e-1 + mesh_translations = '0 0 0' + mesh_template = ../meshes/sphere.e + [] + [Mesh_2] + type = MeshTally + score = flux + trigger = rel_err + trigger_threshold = 5e-1 + mesh_translations = '0 0 0' + mesh_template = ../meshes/sphere.e + [] + [] +[] + +[Executioner] + type = Steady +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/neutronics/tally_system/settings.xml b/test/tests/neutronics/tally_system/settings.xml new file mode 100644 index 000000000..2206cb140 --- /dev/null +++ b/test/tests/neutronics/tally_system/settings.xml @@ -0,0 +1,16 @@ + + + eigenvalue + 100 + 10 + 50 + + + -5.0 -5.0 0 5.0 5.0 12.0 + + + 600.0 + nearest + false + 294.0 1600.0 + diff --git a/test/tests/neutronics/tally_system/tests b/test/tests/neutronics/tally_system/tests new file mode 100644 index 000000000..04a2f8710 --- /dev/null +++ b/test/tests/neutronics/tally_system/tests @@ -0,0 +1,89 @@ +[Tests] + [multi_global_estimator] + type = CSVDiff + input = multi_estimator.i + csvdiff = multi_estimator_out.csv + requirement = "The system shall correctly normalize local tallies with different estimators using multiple global tallies." + required_objects = 'OpenMCCellAverageProblem' + [] + [multiple_tallies_cell] + type = CSVDiff + input = multi_cell.i + csvdiff = multi_cell_out.csv + requirement = "The system shall correctly apply and normalize two different CellTally objects with different scores. " + "The gold file was generated using an input that had a single CellTally with multiple scores." + required_objects = 'OpenMCCellAverageProblem' + [] + [multiple_tallies_mesh] + type = Exodiff + input = multi_mesh.i + exodiff = multi_mesh_out.e + requirement = "The system shall correctly apply and normalize two different MeshTally objects with different scores. " + "The gold file was generated using an input that had a single MeshTally with multiple scores." + required_objects = 'OpenMCCellAverageProblem' + [] + [multiple_tallies_cell_triggers] + type = CSVDiff + input = multi_cell_triggers.i + csvdiff = multi_cell_triggers_out.csv + requirement = "The system shall correctly apply and normalize two different CellTally objects with different scores and triggers. " + "The gold file was generated using an input that had a single CellTally with multiple scores and triggers." + required_objects = 'OpenMCCellAverageProblem' + [] + [multiple_tallies_mesh_triggers] + type = Exodiff + input = multi_mesh_triggers.i + exodiff = multi_mesh_triggers_out.e + requirement = "The system shall correctly apply and normalize two different MeshTally objects with different scores and triggers. " + "The gold file was generated using an input that had a single MeshTally with multiple scores and triggers." + required_objects = 'OpenMCCellAverageProblem' + [] + [multiple_tallies_cell_relax] + type = CSVDiff + input = multi_cell_relax.i + csvdiff = multi_cell_relax_out.csv + requirement = "The system shall correctly apply and normalize two different CellTally objects with different scores when using relaxation. " + "The gold file was generated using an input that had a single CellTally with multiple scores when using relaxation." + required_objects = 'OpenMCCellAverageProblem' + [] + [multiple_tallies_mesh_relax] + type = Exodiff + input = multi_mesh_relax.i + exodiff = multi_mesh_relax_out.e + requirement = "The system shall correctly apply and normalize two different MeshTally objects with different scores when using relaxation. " + "The gold file was generated using an input that had a single MeshTally with multiple scores when using relaxation." + required_objects = 'OpenMCCellAverageProblem' + [] + [duplicate_scores] + type = RunException + input = multi_cell.i + cli_args = 'Problem/Tallies/Cell_2/score="flux kappa_fission"' + expect_err = "You have added 2 tallies which score kappa-fission!" + requirement = "The system shall error if the user provides multiple tallies with overlapping scores." + required_objects = 'OpenMCCellAverageProblem' + [] + [multi_no_norm] + type = RunException + input = multi_cell.i + cli_args = 'Problem/Tallies/Cell_1/score="heating"' + expect_err = "The local tallies added in the \[Tallies\] block do not contain the requested heating score" + requirement = "The system shall error if more than one tally is provided and the requested heating score is in " + "none of the tallies." + required_objects = 'OpenMCCellAverageProblem' + [] + [multiple_different_tallies] + type = Exodiff + input = multi_diff.i + exodiff = multi_diff_out.e + requirement = "The system shall allow calculations with multiple different tallies." + required_objects = 'OpenMCCellAverageProblem' + [] + [multiple_different_outputs] + type = Exodiff + input = multi_diff.i + exodiff = multi_diff_outputs.e + cli_args = 'Problem/Tallies/Cell/output="unrelaxed_tally_std_dev unrelaxed_tally" Problem/Tallies/Mesh/output="unrelaxed_tally_std_dev" Outputs/file_base=multi_diff_outputs' + requirement = "The system shall allow calculations with multiple different tally outputs." + required_objects = 'OpenMCCellAverageProblem' + [] +[] diff --git a/test/tests/neutronics/triggers/k_std_dev.i b/test/tests/neutronics/triggers/k_std_dev.i index 564ca64f0..a6d0bd275 100644 --- a/test/tests/neutronics/triggers/k_std_dev.i +++ b/test/tests/neutronics/triggers/k_std_dev.i @@ -19,7 +19,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = none k_trigger = std_dev k_trigger_threshold = 1.2e-2 diff --git a/test/tests/neutronics/triggers/mesh_tally_rel_err.i b/test/tests/neutronics/triggers/mesh_tally_rel_err.i index cbc89e0cf..20b53a697 100644 --- a/test/tests/neutronics/triggers/mesh_tally_rel_err.i +++ b/test/tests/neutronics/triggers/mesh_tally_rel_err.i @@ -23,17 +23,22 @@ type = OpenMCCellAverageProblem verbose = true power = 100.0 - tally_type = mesh - mesh_template = '../meshes/sphere.e' - mesh_translations = '0 0 0 - 0 0 4 - 0 0 8' normalize_by_global_tally = false - tally_trigger = rel_err - tally_trigger_threshold = 5e-1 particles = 1000 max_batches = 200 + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = '../meshes/sphere.e' + mesh_translations = '0 0 0 + 0 0 4 + 0 0 8' + trigger = rel_err + trigger_threshold = 5e-1 + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/triggers/multi_rel_err.i b/test/tests/neutronics/triggers/multi_rel_err.i index 4aaabd5db..b189cd82b 100644 --- a/test/tests/neutronics/triggers/multi_rel_err.i +++ b/test/tests/neutronics/triggers/multi_rel_err.i @@ -22,15 +22,20 @@ power = 100.0 batches = 20 cell_level = 0 - tally_type = cell - tally_blocks = '100' normalize_by_global_tally = false - tally_score = 'damage_energy kappa_fission' - - tally_trigger = 'rel_err rel_err' - tally_trigger_threshold = '2e-2 2e-2' max_batches = 200 + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + score = 'damage_energy kappa_fission' + + trigger = 'rel_err rel_err' + trigger_threshold = '2e-2 2e-2' + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/triggers/tally_rel_err.i b/test/tests/neutronics/triggers/tally_rel_err.i index e72e975b0..50027e84e 100644 --- a/test/tests/neutronics/triggers/tally_rel_err.i +++ b/test/tests/neutronics/triggers/tally_rel_err.i @@ -21,13 +21,19 @@ type = OpenMCCellAverageProblem power = 100.0 cell_level = 0 - tally_type = cell - tally_blocks = '100' + normalize_by_global_tally = false - tally_trigger = rel_err - tally_trigger_threshold = 2e-2 max_batches = 200 + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + trigger = rel_err + trigger_threshold = 2e-2 + [] + [] [] [Executioner] diff --git a/test/tests/neutronics/triggers/tests b/test/tests/neutronics/triggers/tests index 9c899cc39..d08a3b3c9 100644 --- a/test/tests/neutronics/triggers/tests +++ b/test/tests/neutronics/triggers/tests @@ -45,7 +45,7 @@ [tally_rel_err_collision] type = CSVDiff input = tally_rel_err.i - cli_args = "Outputs/file_base=collision_out Problem/tally_estimator=collision" + cli_args = "Outputs/file_base=collision_out Problem/Tallies/Cell/estimator=collision" csvdiff = collision_out.csv requirement = "The system shall allow the user to customize the tally estimator for cell tallies" required_objects = 'OpenMCCellAverageProblem' @@ -69,24 +69,24 @@ [length_trigger] type = RunException input = multi_rel_err.i - cli_args = 'Problem/tally_trigger="rel_err"' + cli_args = 'Problem/Tallies/Cell/trigger="rel_err"' requirement = "The system shall enforce correct trigger length" - expect_err = "'tally_trigger' \(size 1\) must have the same length as 'tally_score' \(size 2\)" + expect_err = "'trigger' \(size 1\) must have the same length as 'score' \(size 2\)" required_objects = 'OpenMCCellAverageProblem' [] [length_threshold] type = RunException input = multi_rel_err.i - cli_args = 'Problem/tally_trigger_threshold="1e-2"' + cli_args = 'Problem/Tallies/Cell/trigger_threshold="1e-2"' requirement = "The system shall enforce correct trigger threshold length" - expect_err = "'tally_trigger_threshold' \(size 1\) must have the same length as 'tally_score' \(size 2\)" + expect_err = "'trigger_threshold' \(size 1\) must have the same length as 'score' \(size 2\)" required_objects = 'OpenMCCellAverageProblem' [] [multi_diff_rel_err] type = CSVDiff input = multi_rel_err.i csvdiff = diff_out.csv - cli_args = 'Outputs/file_base=diff_out Problem/tally_trigger_threshold="1e-2 5e-2"' + cli_args = 'Outputs/file_base=diff_out Problem/Tallies/Cell/trigger_threshold="1e-2 5e-2"' requirement = "The system shall correctly terminate the OpenMC simulation once reaching a desired " "tally relative error when applying a different trigger to multiple scores." required_objects = 'OpenMCCellAverageProblem' @@ -95,7 +95,7 @@ type = CSVDiff input = multi_rel_err.i csvdiff = diffb_out.csv - cli_args = 'Outputs/file_base=diffb_out Problem/tally_trigger_threshold="5e-2 1e-2"' + cli_args = 'Outputs/file_base=diffb_out Problem/Tallies/Cell/trigger_threshold="5e-2 1e-2"' requirement = "The system shall correctly terminate the OpenMC simulation once reaching a desired " "tally relative error when applying a different trigger to multiple scores." required_objects = 'OpenMCCellAverageProblem' diff --git a/test/tests/openmc_errors/adaptivity/fixed_mesh.i b/test/tests/openmc_errors/adaptivity/fixed_mesh.i index 6b1e80368..3f22fbea7 100644 --- a/test/tests/openmc_errors/adaptivity/fixed_mesh.i +++ b/test/tests/openmc_errors/adaptivity/fixed_mesh.i @@ -20,10 +20,15 @@ type = OpenMCCellAverageProblem power = 70.0 temperature_blocks = '100' - tally_blocks = '100' - tally_type = cell cell_level = 0 fixed_mesh = true + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/block_mappings/absent_solid_block.i b/test/tests/openmc_errors/block_mappings/absent_solid_block.i index 8559fafb2..701a82a9f 100644 --- a/test/tests/openmc_errors/block_mappings/absent_solid_block.i +++ b/test/tests/openmc_errors/block_mappings/absent_solid_block.i @@ -39,8 +39,6 @@ power = 70.0 temperature_blocks = '500' cell_level = 0 - - tally_type = none [] [Executioner] diff --git a/test/tests/openmc_errors/block_mappings/multiple_phases.i b/test/tests/openmc_errors/block_mappings/multiple_phases.i index 81078e949..278226707 100644 --- a/test/tests/openmc_errors/block_mappings/multiple_phases.i +++ b/test/tests/openmc_errors/block_mappings/multiple_phases.i @@ -42,10 +42,15 @@ power = 70.0 temperature_blocks = '100 200' density_blocks = '200' - tally_type = cell - tally_blocks = '100' cell_level = 0 initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/block_mappings/multiple_tally_settings.i b/test/tests/openmc_errors/block_mappings/multiple_tally_settings.i index b8960cdf4..cdb736bcc 100644 --- a/test/tests/openmc_errors/block_mappings/multiple_tally_settings.i +++ b/test/tests/openmc_errors/block_mappings/multiple_tally_settings.i @@ -40,10 +40,15 @@ type = OpenMCCellAverageProblem power = 70.0 temperature_blocks = '100 200' - tally_type = cell - tally_blocks = '100' cell_level = 0 initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/block_mappings/no_overlap.i b/test/tests/openmc_errors/block_mappings/no_overlap.i index 145495e2f..ae936dedf 100644 --- a/test/tests/openmc_errors/block_mappings/no_overlap.i +++ b/test/tests/openmc_errors/block_mappings/no_overlap.i @@ -13,9 +13,14 @@ [Problem] type = OpenMCCellAverageProblem power = 70.0 - tally_type = cell - tally_blocks = '1' cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/block_mappings/nonexistent_block.i b/test/tests/openmc_errors/block_mappings/nonexistent_block.i index 8721573be..6feb40993 100644 --- a/test/tests/openmc_errors/block_mappings/nonexistent_block.i +++ b/test/tests/openmc_errors/block_mappings/nonexistent_block.i @@ -33,9 +33,14 @@ [Problem] type = OpenMCCellAverageProblem power = 70.0 - tally_type = cell - tally_blocks = '100 200 who' cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + blocks = '100 200 who' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/block_mappings/skipping_moose_feedback.i b/test/tests/openmc_errors/block_mappings/skipping_moose_feedback.i index 140a4e377..f49e37790 100644 --- a/test/tests/openmc_errors/block_mappings/skipping_moose_feedback.i +++ b/test/tests/openmc_errors/block_mappings/skipping_moose_feedback.i @@ -46,10 +46,15 @@ power = 70.0 temperature_blocks = '100 200' density_blocks = '200' - tally_type = cell - tally_blocks = '100' cell_level = 0 initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/block_mappings/tests b/test/tests/openmc_errors/block_mappings/tests index a91afa31e..edf23521d 100644 --- a/test/tests/openmc_errors/block_mappings/tests +++ b/test/tests/openmc_errors/block_mappings/tests @@ -2,7 +2,7 @@ [nonexistent_block] type = RunException input = nonexistent_block.i - expect_err = "Block 'who' specified in 'tally_blocks' not found in mesh!" + expect_err = "Block 'who' specified in 'blocks' not found in mesh!" requirement = "The system shall error if the user specifies a block for coupling that does not exist." required_objects = 'OpenMCCellAverageProblem' [] @@ -43,7 +43,7 @@ [multiple_tally_settings] type = RunException input = multiple_tally_settings.i - expect_err = "cell id 4, instance 0 \(of 1\) maps to blocks with different tally settings!\nBlock 100 is in 'tally_blocks', but block 200 is not." + expect_err = "cell id 4, instance 0 \(of 1\) maps to blocks with different tally settings!\nBlock 100 is in 'blocks', but block 200 is not." requirement = "The system shall error if one OpenMC cell maps to multiple subdomains that don't all have the same tally setting" required_objects = 'OpenMCCellAverageProblem' [] diff --git a/test/tests/openmc_errors/block_mappings/unequal_volumes.i b/test/tests/openmc_errors/block_mappings/unequal_volumes.i index f56c1007d..cac563ad1 100644 --- a/test/tests/openmc_errors/block_mappings/unequal_volumes.i +++ b/test/tests/openmc_errors/block_mappings/unequal_volumes.i @@ -32,10 +32,15 @@ power = 70.0 temperature_blocks = '100' verbose = true - tally_type = cell - tally_blocks = '100' cell_level = 0 - check_equal_mapped_tally_volumes = true + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + check_equal_mapped_tally_volumes = true + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/cell_instances/insufficient_materials/fluid.i b/test/tests/openmc_errors/cell_instances/insufficient_materials/fluid.i index 7667b992c..c73036968 100644 --- a/test/tests/openmc_errors/cell_instances/insufficient_materials/fluid.i +++ b/test/tests/openmc_errors/cell_instances/insufficient_materials/fluid.i @@ -8,10 +8,15 @@ power = 500.0 temperature_blocks = '1 2 3' density_blocks = '2' - tally_type = cell - tally_blocks = '1' verbose = true cell_level = 1 + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/cell_instances/insufficient_materials/solid.i b/test/tests/openmc_errors/cell_instances/insufficient_materials/solid.i index d33604962..691988702 100644 --- a/test/tests/openmc_errors/cell_instances/insufficient_materials/solid.i +++ b/test/tests/openmc_errors/cell_instances/insufficient_materials/solid.i @@ -7,14 +7,19 @@ type = OpenMCCellAverageProblem power = 500.0 temperature_blocks = '2' - tally_type = cell - tally_blocks = '2' cell_level = 1 verbose = true check_tally_sum = false initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '2' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/cell_instances/lattice_outer/temp.i b/test/tests/openmc_errors/cell_instances/lattice_outer/temp.i index c0d3e4472..cb67b681c 100644 --- a/test/tests/openmc_errors/cell_instances/lattice_outer/temp.i +++ b/test/tests/openmc_errors/cell_instances/lattice_outer/temp.i @@ -23,7 +23,6 @@ [Problem] type = OpenMCCellAverageProblem power = 1.0 - tally_type = none temperature_blocks = 0 cell_level = 1 [] diff --git a/test/tests/openmc_errors/densities/void_density.i b/test/tests/openmc_errors/densities/void_density.i index 0ad871b6b..ba43abf64 100644 --- a/test/tests/openmc_errors/densities/void_density.i +++ b/test/tests/openmc_errors/densities/void_density.i @@ -37,11 +37,16 @@ power = 10.0 temperature_blocks = '1' density_blocks = '1' - tally_type = cell - tally_blocks = '1' verbose = true cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/densities/zero_density.i b/test/tests/openmc_errors/densities/zero_density.i index 8741ce710..959342e4f 100644 --- a/test/tests/openmc_errors/densities/zero_density.i +++ b/test/tests/openmc_errors/densities/zero_density.i @@ -38,10 +38,15 @@ power = 100.0 temperature_blocks = '0' density_blocks = '0' - tally_type = cell - tally_blocks = '0' verbose = true cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + blocks = '0' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/fixed_source/k.i b/test/tests/openmc_errors/fixed_source/k.i index 615701497..6c7f8b945 100644 --- a/test/tests/openmc_errors/fixed_source/k.i +++ b/test/tests/openmc_errors/fixed_source/k.i @@ -7,7 +7,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = none source_strength = 1e6 [] diff --git a/test/tests/openmc_errors/fixed_source/k_trigger.i b/test/tests/openmc_errors/fixed_source/k_trigger.i index acef9213b..68f4db55b 100644 --- a/test/tests/openmc_errors/fixed_source/k_trigger.i +++ b/test/tests/openmc_errors/fixed_source/k_trigger.i @@ -7,7 +7,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = none k_trigger = std_dev k_trigger_threshold = 1e-4 diff --git a/test/tests/openmc_errors/incorrect_aux_setup/incorrect_var_type.i b/test/tests/openmc_errors/incorrect_aux_setup/incorrect_var_type.i index 1112a2b21..06d8062ce 100644 --- a/test/tests/openmc_errors/incorrect_aux_setup/incorrect_var_type.i +++ b/test/tests/openmc_errors/incorrect_aux_setup/incorrect_var_type.i @@ -34,10 +34,15 @@ type = OpenMCCellAverageProblem power = 70.0 temperature_blocks = '100' - tally_type = cell - tally_blocks = '100' cell_level = 0 initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/input_params/invalid_batches.i b/test/tests/openmc_errors/input_params/invalid_batches.i index b4d43af1a..9aa58d468 100644 --- a/test/tests/openmc_errors/input_params/invalid_batches.i +++ b/test/tests/openmc_errors/input_params/invalid_batches.i @@ -7,7 +7,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = none batches = 8 [] diff --git a/test/tests/openmc_errors/input_params/invalid_max_batches.i b/test/tests/openmc_errors/input_params/invalid_max_batches.i index 87a31a5f2..5f5560fd6 100644 --- a/test/tests/openmc_errors/input_params/invalid_max_batches.i +++ b/test/tests/openmc_errors/input_params/invalid_max_batches.i @@ -7,7 +7,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = none # there are only 10 inactive batches, so we should error max_batches = 8 diff --git a/test/tests/openmc_errors/input_params/levels.i b/test/tests/openmc_errors/input_params/levels.i index dd206ac9f..903c90525 100644 --- a/test/tests/openmc_errors/input_params/levels.i +++ b/test/tests/openmc_errors/input_params/levels.i @@ -10,7 +10,6 @@ temperature_blocks = '1' cell_level = 0 lowest_cell_level = 0 - tally_type = none [] [Executioner] diff --git a/test/tests/openmc_errors/input_params/missing_properties.i b/test/tests/openmc_errors/input_params/missing_properties.i index 4f283dba0..945cd678c 100644 --- a/test/tests/openmc_errors/input_params/missing_properties.i +++ b/test/tests/openmc_errors/input_params/missing_properties.i @@ -9,7 +9,6 @@ type = OpenMCCellAverageProblem temperature_blocks = '1' cell_level = 0 - tally_type = none initial_properties = hdf5 [] diff --git a/test/tests/openmc_errors/input_params/no_dag.i b/test/tests/openmc_errors/input_params/no_dag.i index 1c8d7f70b..434f13472 100644 --- a/test/tests/openmc_errors/input_params/no_dag.i +++ b/test/tests/openmc_errors/input_params/no_dag.i @@ -9,7 +9,6 @@ type = OpenMCCellAverageProblem temperature_blocks = '1' cell_level = 0 - tally_type = none skinner = moab [] diff --git a/test/tests/openmc_errors/level/phase_too_high/fluid_too_high.i b/test/tests/openmc_errors/level/phase_too_high/fluid_too_high.i index 09f01c2e3..569510404 100644 --- a/test/tests/openmc_errors/level/phase_too_high/fluid_too_high.i +++ b/test/tests/openmc_errors/level/phase_too_high/fluid_too_high.i @@ -36,8 +36,6 @@ power = 70.0 temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100 200' - tally_type = cell verbose = true # skip the data transfer of temperature into OpenMC for the first time step @@ -47,6 +45,13 @@ # For this setup, the fluid cells only exist on coordinate level 0, even though # the highest coordinate level across the entire problem is 1 cell_level = 1 + + [Tallies] + [Cell] + type = CellTally + blocks = '100 200' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/level/total_too_high/level_too_high.i b/test/tests/openmc_errors/level/total_too_high/level_too_high.i index 16dea2542..9a41aaeaa 100644 --- a/test/tests/openmc_errors/level/total_too_high/level_too_high.i +++ b/test/tests/openmc_errors/level/total_too_high/level_too_high.i @@ -22,8 +22,6 @@ type = OpenMCCellAverageProblem power = 70.0 temperature_blocks = '100' - tally_blocks = '100' - tally_type = cell verbose = true # skip the data transfer of temperature into OpenMC for the first time step @@ -31,6 +29,13 @@ initial_properties = xml cell_level = 1 + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/material_mappings/materials.i b/test/tests/openmc_errors/material_mappings/materials.i index 9a450625d..27ac4ef7b 100644 --- a/test/tests/openmc_errors/material_mappings/materials.i +++ b/test/tests/openmc_errors/material_mappings/materials.i @@ -38,10 +38,15 @@ power = 70.0 temperature_blocks = '100 200' density_blocks = '200' - tally_type = cell - tally_blocks = '100' cell_level = 0 initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/mesh_tally/incorrect_file.i b/test/tests/openmc_errors/mesh_tally/incorrect_file.i index 156d9f7db..8fe560b2e 100644 --- a/test/tests/openmc_errors/mesh_tally/incorrect_file.i +++ b/test/tests/openmc_errors/mesh_tally/incorrect_file.i @@ -19,12 +19,16 @@ verbose = true cell_level = 0 - tally_type = mesh power = 100.0 check_tally_sum = false - # make the mistake of clearly using a totally different mesh - mesh_template = '../../neutronics/meshes/pincell.e' + [Tallies] + [Mesh] + type = MeshTally + # make the mistake of clearly using a totally different mesh + mesh_template = '../../neutronics/meshes/pincell.e' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/mesh_tally/incorrect_order.i b/test/tests/openmc_errors/mesh_tally/incorrect_order.i index 253abed58..62d8a4e10 100644 --- a/test/tests/openmc_errors/mesh_tally/incorrect_order.i +++ b/test/tests/openmc_errors/mesh_tally/incorrect_order.i @@ -26,17 +26,21 @@ verbose = true cell_level = 0 - tally_type = mesh - mesh_template = '../../neutronics/meshes/sphere.e' power = 100.0 check_tally_sum = false - # Make the mistake of listing the mesh template translations in a different order than - # was used to create the [Mesh]. This should catch that the mesh template does not - # exactly match the [Mesh] - mesh_translations = '0 0 0 - 0 0 8 - 0 0 4' + [Tallies] + [Mesh] + type = MeshTally + mesh_template = '../../neutronics/meshes/sphere.e' + # Make the mistake of listing the mesh template translations in a different order than + # was used to create the [Mesh]. This should catch that the mesh template does not + # exactly match the [Mesh] + mesh_translations = '0 0 0 + 0 0 8 + 0 0 4' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/mesh_tally/incorrect_scaling.i b/test/tests/openmc_errors/mesh_tally/incorrect_scaling.i index f5be3ffb6..09da93786 100644 --- a/test/tests/openmc_errors/mesh_tally/incorrect_scaling.i +++ b/test/tests/openmc_errors/mesh_tally/incorrect_scaling.i @@ -19,15 +19,19 @@ verbose = true cell_level = 0 - tally_type = mesh power = 100.0 check_tally_sum = false scaling = 100.0 normalize_by_global_tally = false - # We incorrectly provide a mesh in units of centimeters - mesh_template = '../../neutronics/meshes/sphere.e' + [Tallies] + [Mesh] + type = MeshTally + # We incorrectly provide a mesh in units of centimeters + mesh_template = '../../neutronics/meshes/sphere.e' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/mesh_tally/tests b/test/tests/openmc_errors/mesh_tally/tests index 7b06d78d8..ec6597856 100644 --- a/test/tests/openmc_errors/mesh_tally/tests +++ b/test/tests/openmc_errors/mesh_tally/tests @@ -12,7 +12,7 @@ type = RunException input = incorrect_order.i expect_err = "Centroid for element 256 in the \[Mesh\] \(cm\): \(0.896826, 0.189852, 4.60886\)\n" - "does not match centroid for element 0 in 'mesh_template' 1 \(cm\): \(0.896826, 0.189852, 8.60886\)!\n\n" + "does not match centroid for element 0 in the 'mesh_template' with instance 1 \(cm\): \(0.896826, 0.189852, 8.60886\)!\n\n" "The copy transfer requires that the \[Mesh\] and 'mesh_template' be identical." requirement = "The system shall error if the mesh template does not exactly match the [Mesh], such as when " "the order of mesh translations does not match the order of inputs in a CombinerGenerator." @@ -22,7 +22,7 @@ type = RunException input = incorrect_file.i expect_err = "Centroid for element 0 in the \[Mesh\] \(cm\): \(0.896826, 0.189852, 0.608855\)\n" - "does not match centroid for element 0 in 'mesh_template' 0 \(cm\): \(-0.0251736, -0.0667374, 0.0847458\)!\n\n" + "does not match centroid for element 0 in the 'mesh_template' with instance 0 \(cm\): \(-0.0251736, -0.0667374, 0.0847458\)!\n\n" "The copy transfer requires that the \[Mesh\] and 'mesh_template' be identical." requirement = "The system shall error if the mesh template does not exactly match the [Mesh], such as when " "a totally different mesh is used (pincell versus pebbles)." @@ -31,7 +31,7 @@ [invalid_estimator] type = RunException input = incorrect_file.i - cli_args = 'Problem/mesh_template=../../neutronics/meshes/sphere.e Problem/tally_estimator=tracklength' + cli_args = 'Problem/Tallies/Mesh/mesh_template=../../neutronics/meshes/sphere.e Problem/Tallies/Mesh/estimator=tracklength' expect_err = "Tracklength estimators are currently incompatible with mesh tallies!" requirement = "The system shall error if a tracklength estimator is attempted with unstructured mesh tallies, " "since this capability is not supported in libMesh." diff --git a/test/tests/openmc_errors/mesh_translations/invalid_row.i b/test/tests/openmc_errors/mesh_translations/invalid_row.i index 3cef566d7..36f75492c 100644 --- a/test/tests/openmc_errors/mesh_translations/invalid_row.i +++ b/test/tests/openmc_errors/mesh_translations/invalid_row.i @@ -16,11 +16,15 @@ [Problem] type = OpenMCCellAverageProblem - mesh_translations_file = pebble_centers.txt - - tally_type = mesh - mesh_template = '../neutronics/meshes/sphere.e' power = 100.0 + + [Tallies] + [Mesh] + type = MeshTally + mesh_template = '../neutronics/meshes/sphere.e' + mesh_translations_file = pebble_centers.txt + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/mode/particle/particle.i b/test/tests/openmc_errors/mode/particle/particle.i index 480dd3b9c..10dcfe011 100644 --- a/test/tests/openmc_errors/mode/particle/particle.i +++ b/test/tests/openmc_errors/mode/particle/particle.i @@ -7,7 +7,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = none [] [Executioner] diff --git a/test/tests/openmc_errors/mode/plot/plot.i b/test/tests/openmc_errors/mode/plot/plot.i index 480dd3b9c..10dcfe011 100644 --- a/test/tests/openmc_errors/mode/plot/plot.i +++ b/test/tests/openmc_errors/mode/plot/plot.i @@ -7,7 +7,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = none [] [Executioner] diff --git a/test/tests/openmc_errors/mode/volume/volume.i b/test/tests/openmc_errors/mode/volume/volume.i index 480dd3b9c..10dcfe011 100644 --- a/test/tests/openmc_errors/mode/volume/volume.i +++ b/test/tests/openmc_errors/mode/volume/volume.i @@ -7,7 +7,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = none [] [Executioner] diff --git a/test/tests/openmc_errors/no_range/openmc.i b/test/tests/openmc_errors/no_range/openmc.i index f5a33be00..3fd4e5595 100644 --- a/test/tests/openmc_errors/no_range/openmc.i +++ b/test/tests/openmc_errors/no_range/openmc.i @@ -14,7 +14,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = none [] [Executioner] diff --git a/test/tests/openmc_errors/tallies/length.i b/test/tests/openmc_errors/tallies/length.i index 51b88afba..51efca0ab 100644 --- a/test/tests/openmc_errors/tallies/length.i +++ b/test/tests/openmc_errors/tallies/length.i @@ -8,9 +8,14 @@ [Problem] type = OpenMCCellAverageProblem power = 100.0 - tally_type = cell - tally_blocks = '1' cell_level = 0 + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/tallies/separate_tallies.i b/test/tests/openmc_errors/tallies/separate_tallies.i index dfc6aac36..a877897ad 100644 --- a/test/tests/openmc_errors/tallies/separate_tallies.i +++ b/test/tests/openmc_errors/tallies/separate_tallies.i @@ -15,11 +15,16 @@ [Problem] type = OpenMCCellAverageProblem power = 100.0 - tally_type = cell - tally_blocks = '1' cell_level = 0 assume_separate_tallies = true + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/openmc_errors/tallies/tests b/test/tests/openmc_errors/tallies/tests index 481755abf..3da8f1255 100644 --- a/test/tests/openmc_errors/tallies/tests +++ b/test/tests/openmc_errors/tallies/tests @@ -9,33 +9,33 @@ [invalid_length] type = RunException input = length.i - cli_args = 'Problem/tally_score="damage_energy kappa_fission" Problem/tally_name="heat_source"' - expect_err = "'tally_name' must be the same length as 'tally_score'!" - requirement = "The system shall error if tally_name and tally_score are not the same length." + cli_args = 'Problem/Tallies/Cell/score="damage_energy kappa_fission" Problem/Tallies/Cell/name="heat_source"' + expect_err = "'name' must be the same length as 'score'!" + requirement = "The system shall error if name and score are not the same length." required_objects = 'OpenMCCellAverageProblem' [] [missing_threshold] type = RunException input = length.i - cli_args = 'Problem/tally_trigger="rel_err"' - expect_err = "You must either specify none or both of 'tally_trigger' and 'tally_trigger_threshold'. You have specified only one." - requirement = "The system shall error if tally_trigger and tally_trigger_threshold are not simultaneously specified" + cli_args = 'Problem/Tallies/Cell/trigger="rel_err"' + expect_err = "You must either specify none or both of 'trigger' and 'trigger_threshold'. You have specified only one." + requirement = "The system shall error if trigger and trigger_threshold are not simultaneously specified" required_objects = 'OpenMCCellAverageProblem' [] [duplicate_name] type = RunException input = length.i - cli_args = 'Problem/tally_score="damage_energy kappa_fission" Problem/tally_name="heat_source heat_source"' - expect_err = "Entries cannot be repeated in 'tally_name'!" - requirement = "The system shall error if tally_name has duplicate entries." + cli_args = 'Problem/Tallies/Cell/score="damage_energy kappa_fission" Problem/Tallies/Cell/name="heat_source heat_source"' + expect_err = "Entries cannot be repeated in 'name'!" + requirement = "The system shall error if name has duplicate entries." required_objects = 'OpenMCCellAverageProblem' [] [duplicate_score] type = RunException input = length.i - cli_args = 'Problem/tally_score="damage_energy damage_energy" Problem/tally_name="heat1 heat2"' - expect_err = "Entries cannot be repeated in 'tally_score'!" - requirement = "The system shall error if tally_score has duplicate entries." + cli_args = 'Problem/Tallies/Cell/score="damage_energy damage_energy" Problem/Tallies/Cell/name="heat1 heat2"' + expect_err = "Entries cannot be repeated in 'score'!" + requirement = "The system shall error if score has duplicate entries." required_objects = 'OpenMCCellAverageProblem' [] [] diff --git a/test/tests/openmc_errors/xs_temperatures/openmc.i b/test/tests/openmc_errors/xs_temperatures/openmc.i index 1839f879b..7839b07eb 100644 --- a/test/tests/openmc_errors/xs_temperatures/openmc.i +++ b/test/tests/openmc_errors/xs_temperatures/openmc.i @@ -23,7 +23,6 @@ [Problem] type = OpenMCCellAverageProblem temperature_blocks = '0' - tally_type = none verbose = true cell_level = 0 [] diff --git a/test/tests/openmc_errors/zero_tally/openmc.i b/test/tests/openmc_errors/zero_tally/openmc.i index 5901ec5f5..1b5bf7119 100644 --- a/test/tests/openmc_errors/zero_tally/openmc.i +++ b/test/tests/openmc_errors/zero_tally/openmc.i @@ -15,10 +15,15 @@ [Problem] type = OpenMCCellAverageProblem power = 100.0 - tally_blocks = '1' cell_level = 0 - tally_type = cell source_strength = 1e6 + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + [] + [] [] [Executioner] diff --git a/test/tests/postprocessors/coupled_cells/openmc.i b/test/tests/postprocessors/coupled_cells/openmc.i index 749a6dbd7..6ca0c080f 100644 --- a/test/tests/postprocessors/coupled_cells/openmc.i +++ b/test/tests/postprocessors/coupled_cells/openmc.i @@ -36,7 +36,6 @@ density_blocks = '200' verbose = true cell_level = 0 - tally_type = none initial_properties = xml [] diff --git a/test/tests/postprocessors/eigenvalue/openmc.i b/test/tests/postprocessors/eigenvalue/openmc.i index 51f82b421..d9e0a7df0 100644 --- a/test/tests/postprocessors/eigenvalue/openmc.i +++ b/test/tests/postprocessors/eigenvalue/openmc.i @@ -21,12 +21,17 @@ type = OpenMCCellAverageProblem power = 100.0 temperature_blocks = '100' - tally_blocks = '100' cell_level = 0 - tally_type = cell check_tally_sum = false initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + [] + [] [] [Executioner] diff --git a/test/tests/postprocessors/fission_tally_relative_error/multi.i b/test/tests/postprocessors/fission_tally_relative_error/multi.i index f737e9bba..ca3f75eb9 100644 --- a/test/tests/postprocessors/fission_tally_relative_error/multi.i +++ b/test/tests/postprocessors/fission_tally_relative_error/multi.i @@ -21,17 +21,21 @@ type = OpenMCCellAverageProblem power = 100.0 temperature_blocks = '100' - tally_blocks = '100' cell_level = 0 - tally_type = cell check_tally_sum = false - tally_score = 'heating kappa_fission' + initial_properties = xml - # this outputs the fission tally standard deviation in space - output = 'unrelaxed_tally_std_dev' + [Tallies] + [Cell] + type = CellTally + blocks = '100' + score = 'heating kappa_fission' - initial_properties = xml + # this outputs the fission tally standard deviation in space + output = 'unrelaxed_tally_std_dev' + [] + [] [] [Executioner] diff --git a/test/tests/postprocessors/fission_tally_relative_error/openmc.i b/test/tests/postprocessors/fission_tally_relative_error/openmc.i index 5a4f070d8..661e48452 100644 --- a/test/tests/postprocessors/fission_tally_relative_error/openmc.i +++ b/test/tests/postprocessors/fission_tally_relative_error/openmc.i @@ -21,15 +21,20 @@ type = OpenMCCellAverageProblem power = 100.0 temperature_blocks = '100' - tally_blocks = '100' cell_level = 0 - tally_type = cell check_tally_sum = false - # this outputs the fission tally standard deviation in space - output = 'unrelaxed_tally_std_dev' - initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + + # this outputs the fission tally standard deviation in space + output = 'unrelaxed_tally_std_dev' + [] + [] [] [Executioner] diff --git a/test/tests/postprocessors/fission_tally_relative_error/ratio.i b/test/tests/postprocessors/fission_tally_relative_error/ratio.i index 036e44802..c53f72d85 100644 --- a/test/tests/postprocessors/fission_tally_relative_error/ratio.i +++ b/test/tests/postprocessors/fission_tally_relative_error/ratio.i @@ -15,14 +15,19 @@ [Problem] type = OpenMCCellAverageProblem power = 100.0 - tally_blocks = '1' cell_level = 0 - tally_type = cell check_tally_sum = false - tally_score = 'heating kappa_fission' - output = 'unrelaxed_tally_std_dev' initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + score = 'heating kappa_fission' + output = 'unrelaxed_tally_std_dev' + [] + [] [] # the ratio of the std_dev variable and the output tally should give diff --git a/test/tests/postprocessors/fission_tally_relative_error/tests b/test/tests/postprocessors/fission_tally_relative_error/tests index 15e684649..cab7da960 100644 --- a/test/tests/postprocessors/fission_tally_relative_error/tests +++ b/test/tests/postprocessors/fission_tally_relative_error/tests @@ -33,7 +33,7 @@ [plural_scores] type = RunException input = openmc.i - cli_args = 'Postprocessors/max_rel_err/tally_score="kappa_fission heating" Problem/tally_score="kappa_fission heating"' + cli_args = 'Postprocessors/max_rel_err/tally_score="kappa_fission heating" Problem/Tallies/Cell/score="kappa_fission heating"' # This test has very few particles, and OpenMC will error if there aren't enough source particles # in the fission bank on a process max_parallel = 8 diff --git a/test/tests/postprocessors/openmc_particles/openmc.i b/test/tests/postprocessors/openmc_particles/openmc.i index b9b5ed3f2..140b21dcd 100644 --- a/test/tests/postprocessors/openmc_particles/openmc.i +++ b/test/tests/postprocessors/openmc_particles/openmc.i @@ -17,14 +17,19 @@ verbose = true power = 100.0 temperature_blocks = '100' - tally_blocks = '100' - tally_type = cell cell_level = 1 scaling = 100.0 relaxation = dufek_gudowski first_iteration_particles = 500 initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + [] + [] [] [Executioner] diff --git a/test/tests/symmetry/reflection.i b/test/tests/symmetry/reflection.i index 2f48120ce..85630f9b3 100644 --- a/test/tests/symmetry/reflection.i +++ b/test/tests/symmetry/reflection.i @@ -47,7 +47,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = none symmetry_mapper = sym [] diff --git a/test/tests/symmetry/rotation.i b/test/tests/symmetry/rotation.i index 3c75c2532..093c66030 100644 --- a/test/tests/symmetry/rotation.i +++ b/test/tests/symmetry/rotation.i @@ -48,7 +48,6 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = none symmetry_mapper = sym [] diff --git a/test/tests/userobjects/openmc_nuclide_densities/no_change.i b/test/tests/userobjects/openmc_nuclide_densities/no_change.i index 37ec90470..c7603390d 100644 --- a/test/tests/userobjects/openmc_nuclide_densities/no_change.i +++ b/test/tests/userobjects/openmc_nuclide_densities/no_change.i @@ -25,12 +25,17 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '0' temperature_blocks = '0' cell_level = 0 power = 100.0 + + [Tallies] + [Cell] + type = CellTally + blocks = '0' + [] + [] [] [UserObjects] diff --git a/test/tests/userobjects/openmc_nuclide_densities/only_density.i b/test/tests/userobjects/openmc_nuclide_densities/only_density.i index c1c063ae6..bfc98722e 100644 --- a/test/tests/userobjects/openmc_nuclide_densities/only_density.i +++ b/test/tests/userobjects/openmc_nuclide_densities/only_density.i @@ -25,12 +25,17 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '0' temperature_blocks = '0' cell_level = 0 power = 100.0 + + [Tallies] + [Cell] + type = CellTally + blocks = '0' + [] + [] [] [UserObjects] diff --git a/test/tests/userobjects/openmc_nuclide_densities/openmc.i b/test/tests/userobjects/openmc_nuclide_densities/openmc.i index ae2ab9e6a..14ae453b9 100644 --- a/test/tests/userobjects/openmc_nuclide_densities/openmc.i +++ b/test/tests/userobjects/openmc_nuclide_densities/openmc.i @@ -25,14 +25,19 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '0' temperature_blocks = '0' cell_level = 0 power = 100.0 initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '0' + [] + [] [] [UserObjects] diff --git a/test/tests/userobjects/openmc_nuclide_densities/tests b/test/tests/userobjects/openmc_nuclide_densities/tests index 5f1bf439d..26f96a8ca 100644 --- a/test/tests/userobjects/openmc_nuclide_densities/tests +++ b/test/tests/userobjects/openmc_nuclide_densities/tests @@ -1,7 +1,7 @@ [Tests] [wrong_problem] type = RunException - input = openmc.i + input = wrong_problem.i cli_args = 'Problem/type=FEProblem Variables/u/order=FIRST Kernels/d/type=Diffusion Kernels/d/variable=u' expect_err = 'This user object can only be used with wrapped OpenMC cases!' requirement = 'The system shall error if a userobject is not used with a compatible problem class.' diff --git a/test/tests/userobjects/openmc_nuclide_densities/thermal_density.i b/test/tests/userobjects/openmc_nuclide_densities/thermal_density.i index ffd40e45c..983745703 100644 --- a/test/tests/userobjects/openmc_nuclide_densities/thermal_density.i +++ b/test/tests/userobjects/openmc_nuclide_densities/thermal_density.i @@ -30,13 +30,18 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = cell - tally_blocks = '0' temperature_blocks = '0' density_blocks = '0' cell_level = 0 power = 100.0 + + [Tallies] + [Cell] + type = CellTally + blocks = '0' + [] + [] [] [UserObjects] diff --git a/test/tests/userobjects/openmc_nuclide_densities/wrong_problem.i b/test/tests/userobjects/openmc_nuclide_densities/wrong_problem.i new file mode 100644 index 000000000..c092a13dc --- /dev/null +++ b/test/tests/userobjects/openmc_nuclide_densities/wrong_problem.i @@ -0,0 +1,63 @@ +[Mesh] + [g] + type = GeneratedMeshGenerator + dim = 3 + nx = 8 + ny = 8 + nz = 8 + xmin = -12.5 + xmax = 87.5 + ymin = -12.5 + ymax = 37.5 + zmin = -12.5 + zmax = 12.5 + [] +[] + +[Variables] + [u] + order = FIRST + [] +[] + +[Kernels] + [d] + type = Diffusion + variable = u + [] +[] + +[ICs] + [temp] + type = ConstantIC + variable = temp + value = 500.0 + [] +[] + +[Problem] + type = FEProblem +[] + +[UserObjects] + [mat1] + type = OpenMCNuclideDensities + material_id = 1 + names = 'U235 U238' + densities = '0.01 0.02' + [] +[] + +[Postprocessors] + [k] + type = KEigenvalue + [] +[] + +[Executioner] + type = Steady +[] + +[Outputs] + csv = true +[] diff --git a/test/tests/userobjects/openmc_tally_nuclides/openmc.i b/test/tests/userobjects/openmc_tally_nuclides/openmc.i index bae814973..4d92b5db3 100644 --- a/test/tests/userobjects/openmc_tally_nuclides/openmc.i +++ b/test/tests/userobjects/openmc_tally_nuclides/openmc.i @@ -16,13 +16,18 @@ [Problem] type = OpenMCCellAverageProblem - tally_type = cell - tally_blocks = '0' cell_level = 0 power = 100.0 check_tally_sum = false + + [Tallies] + [Cell] + type = CellTally + blocks = '0' + [] + [] [] [UserObjects] diff --git a/test/tests/userobjects/openmc_tally_nuclides/tests b/test/tests/userobjects/openmc_tally_nuclides/tests index 43a64b904..89c84f2b2 100644 --- a/test/tests/userobjects/openmc_tally_nuclides/tests +++ b/test/tests/userobjects/openmc_tally_nuclides/tests @@ -1,7 +1,7 @@ [Tests] [wrong_problem] type = RunException - input = openmc.i + input = wrong_problem.i cli_args = 'Problem/type=FEProblem Variables/u/order=FIRST Kernels/d/type=Diffusion Kernels/d/variable=u' expect_err = 'This user object can only be used with wrapped OpenMC cases!' requirement = 'The system shall error if a userobject is not used with a compatible problem class.' diff --git a/test/tests/userobjects/openmc_tally_nuclides/wrong_problem.i b/test/tests/userobjects/openmc_tally_nuclides/wrong_problem.i new file mode 100644 index 000000000..57859a218 --- /dev/null +++ b/test/tests/userobjects/openmc_tally_nuclides/wrong_problem.i @@ -0,0 +1,61 @@ +[Mesh] + [g] + type = GeneratedMeshGenerator + dim = 3 + nx = 8 + ny = 8 + nz = 8 + xmin = -12.5 + xmax = 87.5 + ymin = -12.5 + ymax = 37.5 + zmin = -12.5 + zmax = 12.5 + [] +[] + +[Variables] + [u] + order = FIRST + [] +[] + +[Kernels] + [d] + type = Diffusion + variable = u + [] +[] + +[Problem] + type = FEProblem +[] + +[UserObjects] + [tally1] + type = OpenMCTallyNuclides + tally_id = 2 + names = 'U238' + [] +[] + +[Postprocessors] + [power_1] + type = PointValue + variable = kappa_fission + point = '0.0 -12.0 0.0' + [] + [power_2] + type = PointValue + variable = kappa_fission + point = '0.0 37.0 0.0' + [] +[] + +[Executioner] + type = Steady +[] + +[Outputs] + csv = true +[] diff --git a/test/tests/userobjects/volume_calculation/instances/openmc.i b/test/tests/userobjects/volume_calculation/instances/openmc.i index 06a57e4de..b7911e998 100644 --- a/test/tests/userobjects/volume_calculation/instances/openmc.i +++ b/test/tests/userobjects/volume_calculation/instances/openmc.i @@ -23,14 +23,19 @@ power = 500.0 temperature_blocks = '1 2 3' density_blocks = '2' - tally_blocks = '1' - tally_name = heat_source verbose = true - tally_type = cell cell_level = 1 volume_calculation = vol initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '1' + name = heat_source + [] + [] [] [UserObjects] diff --git a/test/tests/userobjects/volume_calculation/no_vol.i b/test/tests/userobjects/volume_calculation/no_vol.i index 8ffb3df42..639f26573 100644 --- a/test/tests/userobjects/volume_calculation/no_vol.i +++ b/test/tests/userobjects/volume_calculation/no_vol.i @@ -36,13 +36,18 @@ type = OpenMCCellAverageProblem power = 100.0 temperature_blocks = '100' - tally_blocks = '100' cell_level = 0 - tally_type = cell - tally_name = heat_source check_tally_sum = false initial_properties = xml + + [Tallies] + [Cell] + type = CellTally + blocks = '100' + name = heat_source + [] + [] [] [Executioner] diff --git a/test/tests/userobjects/volume_calculation/openmc.i b/test/tests/userobjects/volume_calculation/openmc.i index dc73d38bd..15d045baa 100644 --- a/test/tests/userobjects/volume_calculation/openmc.i +++ b/test/tests/userobjects/volume_calculation/openmc.i @@ -50,14 +50,19 @@ power = 100.0 temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100 200' verbose = true cell_level = 0 - tally_type = cell - tally_name = heat_source initial_properties = xml volume_calculation = vol + + [Tallies] + [Cell] + type = CellTally + blocks = '100 200' + name = heat_source + [] + [] [] [UserObjects] diff --git a/test/tests/userobjects/volume_calculation/scaling.i b/test/tests/userobjects/volume_calculation/scaling.i index fe3c7a8f2..5d4baaca1 100644 --- a/test/tests/userobjects/volume_calculation/scaling.i +++ b/test/tests/userobjects/volume_calculation/scaling.i @@ -56,15 +56,20 @@ power = 100.0 temperature_blocks = '100 200' density_blocks = '200' - tally_blocks = '100 200' verbose = true scaling = 100.0 cell_level = 0 - tally_type = cell - tally_name = heat_source initial_properties = xml volume_calculation = vol + + [Tallies] + [Cell] + type = CellTally + blocks = '100 200' + name = heat_source + [] + [] [] [Executioner] diff --git a/test/tests/userobjects/volume_calculation/user_bb.i b/test/tests/userobjects/volume_calculation/user_bb.i index 30f8e607c..75af63c70 100644 --- a/test/tests/userobjects/volume_calculation/user_bb.i +++ b/test/tests/userobjects/volume_calculation/user_bb.i @@ -35,7 +35,6 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = none cell_level = 0 temperature_blocks = '100' diff --git a/tutorials/dagmc/openmc.i b/tutorials/dagmc/openmc.i index 7e82c7833..04ca4100e 100644 --- a/tutorials/dagmc/openmc.i +++ b/tutorials/dagmc/openmc.i @@ -24,9 +24,6 @@ [Problem] type = OpenMCCellAverageProblem verbose = true - tally_type = mesh - mesh_template = mesh_in.e - tally_name = heat_source cell_level = 0 temperature_blocks = '2 3' check_tally_sum = false @@ -34,6 +31,14 @@ power = 1000.0 volume_calculation = vol + + [Tallies] + [heat_source] + type = MeshTally + mesh_template = mesh_in.e + name = heat_source + [] + [] [] [UserObjects] diff --git a/tutorials/gas_assembly/openmc.i b/tutorials/gas_assembly/openmc.i index 01e1b9c61..d0cc7e726 100644 --- a/tutorials/gas_assembly/openmc.i +++ b/tutorials/gas_assembly/openmc.i @@ -146,16 +146,11 @@ num_layers_for_THM = 50 # number of elements in the THM model; for the conv [Problem] type = OpenMCCellAverageProblem - output = 'unrelaxed_tally_std_dev' - check_equal_mapped_tally_volumes = true identical_cell_fills = '2' power = ${fparse power / n_bundles} scaling = 100.0 - tally_blocks = '2' - tally_type = cell - tally_name = heat_source cell_level = 1 relaxation = constant @@ -175,6 +170,16 @@ num_layers_for_THM = 50 # number of elements in the THM model; for the conv temperature_variables = 'solid_temp; thm_temp' temperature_blocks = '1 2 4; 101' density_blocks = '101' + + [Tallies] + [heat_source] + type = CellTally + blocks = '2' + name = heat_source + check_equal_mapped_tally_volumes = true + output = 'unrelaxed_tally_std_dev' + [] + [] [] [MultiApps] diff --git a/tutorials/gas_compact/openmc.i b/tutorials/gas_compact/openmc.i index 52ff1b7e4..4d45d140e 100644 --- a/tutorials/gas_compact/openmc.i +++ b/tutorials/gas_compact/openmc.i @@ -42,16 +42,22 @@ mdot = 0.011 # fluid mass flowrate (kg/s) [Problem] type = OpenMCCellAverageProblem - output = 'unrelaxed_tally_std_dev' - check_equal_mapped_tally_volumes = true power = ${power} scaling = 100.0 temperature_blocks = 'graphite compacts compacts_trimmer_tri' - tally_blocks = 'compacts compacts_trimmer_tri' - tally_type = cell - tally_name = heat_source + cell_level = 1 + + [Tallies] + [heat_source] + type = CellTally + name = heat_source + blocks = 'compacts compacts_trimmer_tri' + check_equal_mapped_tally_volumes = true + output = 'unrelaxed_tally_std_dev' + [] + [] [] [MultiApps] diff --git a/tutorials/gas_compact_multiphysics/openmc_nek.i b/tutorials/gas_compact_multiphysics/openmc_nek.i index ce1a4d5d5..ca7fc7302 100644 --- a/tutorials/gas_compact_multiphysics/openmc_nek.i +++ b/tutorials/gas_compact_multiphysics/openmc_nek.i @@ -85,15 +85,10 @@ N = 1000 [Problem] type = OpenMCCellAverageProblem - output = 'unrelaxed_tally_std_dev' - check_equal_mapped_tally_volumes = true power = ${unit_cell_power} scaling = 100.0 density_blocks = ${density_blocks} - tally_blocks = ${fuel_blocks} - tally_type = cell - tally_name = heat_source cell_level = 1 relaxation = robbins_monro @@ -103,11 +98,24 @@ N = 1000 k_trigger = std_dev k_trigger_threshold = 7.5e-4 - tally_trigger = rel_err - tally_trigger_threshold = 1e-2 batches = 40 max_batches = 100 batch_interval = 5 + + [Tallies] + [heat_source] + type = CellTally + blocks = ${fuel_blocks} + name = heat_source + + check_equal_mapped_tally_volumes = true + + trigger = rel_err + trigger_threshold = 1e-2 + + output = 'unrelaxed_tally_std_dev' + [] + [] [] [Executioner] diff --git a/tutorials/gas_compact_multiphysics/openmc_thm.i b/tutorials/gas_compact_multiphysics/openmc_thm.i index cb8c44264..778ebe392 100644 --- a/tutorials/gas_compact_multiphysics/openmc_thm.i +++ b/tutorials/gas_compact_multiphysics/openmc_thm.i @@ -94,15 +94,10 @@ unit_cell_power = ${fparse power / (n_bundles * n_coolant_channels_per_block) * [Problem] type = OpenMCCellAverageProblem - output = 'unrelaxed_tally_std_dev' - check_equal_mapped_tally_volumes = true power = ${unit_cell_power} scaling = 100.0 density_blocks = ${density_blocks} - tally_blocks = ${fuel_blocks} - tally_type = cell - tally_name = heat_source cell_level = 1 relaxation = robbins_monro @@ -112,11 +107,24 @@ unit_cell_power = ${fparse power / (n_bundles * n_coolant_channels_per_block) * k_trigger = std_dev k_trigger_threshold = 7.5e-4 - tally_trigger = rel_err - tally_trigger_threshold = 1e-2 batches = 40 max_batches = 100 batch_interval = 5 + + [Tallies] + [heat_source] + type = CellTally + blocks = ${fuel_blocks} + name = heat_source + + check_equal_mapped_tally_volumes = true + + trigger = rel_err + trigger_threshold = 1e-2 + + output = 'unrelaxed_tally_std_dev' + [] + [] [] [Executioner] diff --git a/tutorials/gas_compact_multiphysics/tests b/tutorials/gas_compact_multiphysics/tests index b6da861f2..4275d40b3 100644 --- a/tutorials/gas_compact_multiphysics/tests +++ b/tutorials/gas_compact_multiphysics/tests @@ -16,7 +16,7 @@ input = common_input.i prereq = gen_mesh mesh_mode = 'replicated' # MultiAppGeometricInterpolationTransfer not supported - cli_args = 'openmc_thm.i Problem/particles=200 Executioner/num_steps=2 Problem/inactive_batches=10 Problem/batches=20 Problem/tally_trigger=none Problem/k_trigger=none Outputs/csv/file_base=openmc_thm_test_out Problem/identical_cell_fills="compacts compacts_trimmer_tri"' + cli_args = 'openmc_thm.i Problem/particles=200 Executioner/num_steps=2 Problem/inactive_batches=10 Problem/batches=20 Problem/Tallies/heat_source/trigger=none Problem/k_trigger=none Outputs/csv/file_base=openmc_thm_test_out Problem/identical_cell_fills="compacts compacts_trimmer_tri"' min_parallel = 2 requirement = 'The system shall solve for coupled OpenMC, heat conduction, and THM fluid flow for a TRISO compact.' required_objects = 'OpenMCCellAverageProblem' @@ -27,7 +27,7 @@ prereq = gen_mesh min_parallel = 2 mesh_mode = 'replicated' # MultiAppGeometricInterpolationTransfer not supported - cli_args = "openmc_nek.i Problem/particles=200 Executioner/num_steps=1 Problem/inactive_batches=10 Problem/batches=20 Problem/tally_trigger=none Problem/k_trigger=none Outputs/csv/file_base=openmc_nek_test_out Problem/identical_cell_fills='compacts compacts_trimmer_tri' bison:MultiApps/active='' bison:Transfers/active='' Problem/initial_properties=xml" + cli_args = "openmc_nek.i Problem/particles=200 Executioner/num_steps=1 Problem/inactive_batches=10 Problem/batches=20 Problem/Tallies/heat_source/trigger=none Problem/k_trigger=none Outputs/csv/file_base=openmc_nek_test_out Problem/identical_cell_fills='compacts compacts_trimmer_tri' bison:MultiApps/active='' bison:Transfers/active='' Problem/initial_properties=xml" requirement = 'The system shall solve for coupled OpenMC and heat conduction for a TRISO compact.' required_objects = 'OpenMCCellAverageProblem' [] diff --git a/tutorials/lwr_solid/openmc.i b/tutorials/lwr_solid/openmc.i index 0d1bab84a..f682694b9 100644 --- a/tutorials/lwr_solid/openmc.i +++ b/tutorials/lwr_solid/openmc.i @@ -24,12 +24,17 @@ verbose = true power = ${fparse 3000e6 / 273 / (17 * 17)} temperature_blocks = '1 2 3' - tally_blocks = '2 3' - tally_type = cell - tally_name = heat_source cell_level = 0 volume_calculation = vol + + [Tallies] + [heat_source] + type = CellTally + blocks = '2 3' + name = heat_source + [] + [] [] [UserObjects] diff --git a/tutorials/lwr_solid/openmc_um.i b/tutorials/lwr_solid/openmc_um.i index 76470440e..924563510 100644 --- a/tutorials/lwr_solid/openmc_um.i +++ b/tutorials/lwr_solid/openmc_um.i @@ -26,14 +26,19 @@ verbose = true power = ${fparse 3000e6 / 273 / (17 * 17)} temperature_blocks = '1 2 3' - tally_type = mesh - tally_name = heat_source normalize_by_global_tally = false cell_level = 0 particles = 20000 inactive_batches = 500 batches = 10000 + + [Tallies] + [heat_source] + type = MeshTally + name = heat_source + [] + [] [] [Executioner] diff --git a/tutorials/msfr/openmc.i b/tutorials/msfr/openmc.i index 2c6dda587..98d0fc78e 100644 --- a/tutorials/msfr/openmc.i +++ b/tutorials/msfr/openmc.i @@ -49,15 +49,12 @@ [Problem] type = OpenMCCellAverageProblem - output = unrelaxed_tally_std_dev verbose = true # this will start each Picard iteration from the fission source from the previous one reuse_source = true scaling = 100.0 - tally_type = mesh - mesh_template = msr.e density_blocks = '1' temperature_blocks = '1' @@ -69,6 +66,14 @@ first_iteration_particles = 5000 skinner = moab + + [Tallies] + [heat_source] + type = MeshTally + mesh_template = msr.e + output = unrelaxed_tally_std_dev + [] + [] [] nb = 15.0 diff --git a/tutorials/pebbles/openmc.i b/tutorials/pebbles/openmc.i index c682c648e..b3f20ab3c 100644 --- a/tutorials/pebbles/openmc.i +++ b/tutorials/pebbles/openmc.i @@ -32,11 +32,16 @@ verbose = true power = 1500.0 temperature_blocks = '0' - tally_blocks = '0' - tally_type = cell - tally_name = heat_source cell_level = 1 scaling = 100.0 + + [Tallies] + [heat_source] + type = CellTally + blocks = '0' + name = heat_source + [] + [] [] [Executioner] diff --git a/tutorials/pebbles/openmc_um.i b/tutorials/pebbles/openmc_um.i index 4d8b3308b..b044816c8 100644 --- a/tutorials/pebbles/openmc_um.i +++ b/tutorials/pebbles/openmc_um.i @@ -34,15 +34,20 @@ verbose = true power = 1500.0 temperature_blocks = '0' - tally_type = mesh - tally_name = heat_source - mesh_template = mesh_in.e - mesh_translations = '0 0 0.02 - 0 0 0.06 - 0 0 0.10' normalize_by_global_tally = false cell_level = 1 scaling = 100.0 + + [Tallies] + [heat_source] + type = MeshTally + mesh_translations = '0 0 0.02 + 0 0 0.06 + 0 0 0.10' + mesh_template = mesh_in.e + name = heat_source + [] + [] [] [Executioner] diff --git a/tutorials/pincell_multiphysics/openmc.i b/tutorials/pincell_multiphysics/openmc.i index a92613094..be28d5730 100644 --- a/tutorials/pincell_multiphysics/openmc.i +++ b/tutorials/pincell_multiphysics/openmc.i @@ -104,15 +104,10 @@ dT = ${fparse power / mdot / Cp} [Problem] type = OpenMCCellAverageProblem - output = 'unrelaxed_tally_std_dev' - check_equal_mapped_tally_volumes = true power = ${power} scaling = 100.0 density_blocks = '1' - tally_blocks = '2' - tally_type = cell - tally_name = heat_source cell_level = 0 # This automatically creates these variables and will read from the non-default choice of 'temp' @@ -128,10 +123,23 @@ dT = ${fparse power / mdot / Cp} batches = 30 k_trigger = std_dev k_trigger_threshold = 7.5e-4 - tally_trigger = rel_err - tally_trigger_threshold = 2e-2 batch_interval = 50 max_batches = 1000 + + [Tallies] + [heat_source] + type = CellTally + blocks = '2' + name = heat_source + + check_equal_mapped_tally_volumes = true + + trigger = rel_err + trigger_threshold = 2e-2 + + output = 'unrelaxed_tally_std_dev' + [] + [] [] [MultiApps] diff --git a/tutorials/tokamak/openmc.i b/tutorials/tokamak/openmc.i index 7db4954bd..2a15cbb6a 100644 --- a/tutorials/tokamak/openmc.i +++ b/tutorials/tokamak/openmc.i @@ -21,12 +21,8 @@ [Problem] type = OpenMCCellAverageProblem - output = unrelaxed_tally_std_dev scaling = 100.0 - tally_type = mesh - mesh_template = tokamak.e - tally_score = 'heating_local H3_production' source_strength = 2e18 cell_level = 0 @@ -38,6 +34,15 @@ relaxation = dufek_gudowski skinner = moab + + [Tallies] + [tokamak] + type = MeshTally + mesh_template = tokamak.e + score = 'heating_local H3_production' + output = unrelaxed_tally_std_dev + [] + [] [] [UserObjects]