diff --git a/.github/workflows/run-unit-tests.yml b/.github/workflows/run-unit-tests.yml
new file mode 100644
index 0000000..350b758
--- /dev/null
+++ b/.github/workflows/run-unit-tests.yml
@@ -0,0 +1,58 @@
+name: MOOSE Tests
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+
+ steps:
+
+ - name: Install Apptainer
+ uses: eWaterCycle/setup-apptainer@v2
+ with:
+ apptainer-version: 1.3.6
+
+ - name: Restore Apptainer library
+ run: |
+ apptainer remote add --no-login SylabsCloud cloud.sycloud.io
+ apptainer remote use SylabsCloud
+
+
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ path: Fizzy
+
+ - name: Pull Apptainer image
+ run: |
+ apptainer pull library://billellis.07/fizzy/fizzy_cont_202112
+
+ - name: Build application
+ run: |
+ apptainer cache clean --force
+ df -h
+ apptainer overlay create --size 1024 overlay.img
+ apptainer exec \
+ --bind ${{ github.workspace }}:/workspace \
+ --overlay overlay.img \
+ fizzy_cont_202112_latest.sif \
+ bash -c "
+ . /opt/intel/oneapi/setvars.sh &&
+ cd /workspace/Fizzy/unit &&
+ make -j$(nproc)
+ "
+
+ - name: Run tests
+ run: |
+ apptainer exec \
+ --bind ${{ github.workspace }}:/workspace \
+ fizzy_cont_202112_latest.sif \
+ bash -c "
+ cd /workspace/Fizzy/unit &&
+ ./fizzy-unit-opt -j$(nproc)
+ "
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..37f64e3
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "FizzyCompiledSource"]
+ path = FizzyCompiledSource
+ url = https://github.com/TheBEllis/FizzyCompiledSource
diff --git a/FizzyCompiledSource b/FizzyCompiledSource
new file mode 160000
index 0000000..e2633a9
--- /dev/null
+++ b/FizzyCompiledSource
@@ -0,0 +1 @@
+Subproject commit e2633a93d717b54691574fa9e49c78285f145f6c
diff --git a/Makefile b/Makefile
index d15b0c9..7f99a75 100644
--- a/Makefile
+++ b/Makefile
@@ -86,9 +86,9 @@ export LDFLAGS := $(libmesh_LDFLAGS)
export LIBS := $(libmesh_LIBS)
FISPACT_DIR ?= ${MOOSE_DIR}/../FISPACT/ubuntu/20.10
+FISPACT_DIR ?= ${MOOSE_DIR}
FISPACT_INCLUDES ?= -I ${FISPACT_DIR}/include/c -I ${FISPACT_DIR}/include/cpp
-FISPACT_LIB_DIR ?= ${FISPACT_DIR}/lib/
-# FISPACT_LIB ?=
+FISPACT_LIB_DIR ?= ${FISPACT_DIR}/lib/linux
PUGIXML_DIR ?= $(MOOSE_DIR)/../pugixml/
PUGIXML_INCLUDES ?= -I $(PUGIXML_DIR)/src/
@@ -96,8 +96,13 @@ PUGIXML_LIB_DIR ?= ${PUGIXML_DIR}/build/
HDF5_DIR ?= /usr/lib/x86_64-linux-gnu/hdf5/openmpi/lib/
-ADDITIONAL_LIBS := -L$(FISPACT_LIB_DIR) -ljsonfortran -lmonitor -lfispact -lfispactapi -lfmt -L$(PUGIXML_LIB_DIR) -lpugixml -L$(HDF5_DIR) -lhdf5 -lhdf5_cpp
-ADDITIONAL_LIBS += $(CC_LINKER_SLFLAG)$(FISPACT_LIB_DIR)
+ADDITIONAL_LIBS := -L$(FISPACT_LIB_DIR) -ljsonfortran -lmonitor -lfispact -lfispactapi -L$(PUGIXML_LIB_DIR) -lpugixml -L$(HDF5_DIR) -lhdf5 -lspdlog
+# ADDITIONAL_LIBS += $(CC_LINKER_SLFLAG)$(FISPACT_LIB_DIR)
ADDITIONAL_CPPFLAGS += $(FISPACT_INCLUDES) ${PUGIXML_INCLUDES}
+FIZZY_EXTERNAL_FLAGS = ${ADDITIONAL_LIBS} ${ADDITIONAL_CPPFLAGS}
+
+$(app_LIB): EXTERNAL_FLAGS := $(FIZZY_EXTERNAL_FLAGS)
+$(app_test_LIB): EXTERNAL_FLAGS := $(FIZZY_EXTERNAL_FLAGS)
+$(app_EXEC): EXTERNAL_FLAGS := $(FIZZY_EXTERNAL_FLAGS)
diff --git a/README.md b/README.md
index 1d82523..396f78c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,69 @@
-Fizzy
-=====
+# Fizzy
+
+Fizzy is a MOOSE application wrapping the nuclear inventory, source term and multi-physics code, FISPACT-II.
+
+## Dependencies
+- [FISPACT-II](https://www.ukaea.org/service/fispact/)(5.0+) binaries.
+- A working [MOOSE](https://mooseframework.inl.gov/) build.
+ - Being a MOOSE based application, Fizzy also has the same [minimum requirements](https://mooseframework.inl.gov/sqa/minimum_requirements.html) as MOOSE.
+- PugiXML
+ - PugiXML can be installed easily from most package managers
+ - `sudo apt install libpugixml`
+
+## Obtaining Fizzy
+
+To obtain Fizzy, simply clone this repository.
+
+```language=bash
+git clone https://github.com/TheBEllis/Fizzy.git
+cd Fizzy
+```
+
+## Install
+
+> [!WARNING]
+> Fizzy has only been tested on Ubuntu 24.04 (so far). Other Linux distros, MacOS and Windows have not been tested. If users trying to run Fizzy on these platforms
+experience issues with installation and/or running, please report the issue on Fizzy's [github issues](https://github.com/TheBEllis/Fizzy/issues) page.
+
+To install Fizzy, users must specify the directory containg their FISPACT-II binaries. This can be done using the environment variable `FISPACT_DIR`. The exact directory will differe depending on the version of FISPACT-II being used.
+
+Users must also make sure that the relevent FISPACT-II libraries are present in their `LD_LIBRARY_PATH`.
+
+#### For FISPACT-II V5.1
+
+```language=bash
+export FISPACT_DIR=/path/to/FISPACT/api/
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:path/to/FISPACT/api/lib/linux
+```
+
+#### For FISPACT-II V5.0
+
+```language=bash
+export FISPACT_DIR=/path/to/FISPACT/ubuntu/20.10
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:path/to/FISPACT/ubuntu/20.10/lib
+```
+
+> [!IMPORTANT]
+> The exact directories that need to be set may differ depending on users directory structure. By setting `FISPACT_DIR`, Fizzy will automatically look for FISPACT libraries and includes at `${FISPACT_DIR}/lib/linux` and `${FISPACT_DIR}/includes/cpp`. Users can manually set the locations of libraries and includes by settings the environment variables `FISPACT_LIB_DIR` and `FISPACT_INCLUDE_DIR`.
+
+The final step is to run `make` in the Fizzy root directory. After a successful install, an executable called `Fizzy-opt` should be found in the application root directory.
+
+```language=bash
+cd /path/to/Fizzy
+make -j 4
+```
+
+## Building docs
+Due to Fizzy currently being private, the only way to access documentation is by building it locally. Users can do this by running.
+
+```
+cd /path/to/Fizzy/doc
+./moosedocs.py build --destination ./build_folder
+```
+
+This will populate the specified `build_folder` with html files. To access the documentation after building, `cd` into the build folder and open `index.html` from your chosen web browser.
+
+## References
+
-Fork "Fizzy" to create a new MOOSE-based application.
-For more information see: [https://mooseframework.inl.gov/getting_started/new_users.html#create-an-app](https://mooseframework.inl.gov/getting_started/new_users.html#create-an-app)
diff --git a/doc/config.yml b/doc/config.yml
index cf01956..cff4c24 100644
--- a/doc/config.yml
+++ b/doc/config.yml
@@ -3,18 +3,80 @@ Content:
root_dir: ${ROOT_DIR}/doc/content
moose:
root_dir: ${MOOSE_DIR}/framework/doc/content
+ fluid_properties:
+ root_dir: ${MOOSE_DIR}/modules/fluid_properties/doc/content
+ heat_transfer:
+ root_dir: ${MOOSE_DIR}/modules/heat_transfer/doc/content
+ navier_stokes:
+ root_dir: ${MOOSE_DIR}/modules/navier_stokes/doc/content
+ ray_tracing:
+ root_dir: ${MOOSE_DIR}/modules/ray_tracing/doc/content
+ reactor:
+ root_dir: ${MOOSE_DIR}/modules/reactor/doc/content
+ solid_mechanics:
+ root_dir: ${MOOSE_DIR}/modules/solid_mechanics/doc/content
+ solid_properties:
+ root_dir: ${MOOSE_DIR}/modules/solid_properties/doc/content
+ stochastic_tools:
+ root_dir: ${MOOSE_DIR}/modules/stochastic_tools/doc/content
+ subchannel:
+ root_dir: ${MOOSE_DIR}/modules/subchannel/doc/content
+ thermal_hydraulics:
+ root_dir: ${MOOSE_DIR}/modules/thermal_hydraulics/doc/content
+ modules:
+ root_dir: ${MOOSE_DIR}/modules/doc/content
content:
- - js/*
- - css/*
- - contrib/**
- - media/**
+ - help/development/VSCode.md
+ - help/development/analyze_jacobian.md
+ - help/finite_element_concepts/nodal_patch_recovery.md
+ - application_development/performance_benchmarking.md
+ - application_usage/restart_recover.md
+ - application_usage/command_line_usage.md
+ python:
+ root_dir: ${MOOSE_DIR}/python/doc/content
+ content:
+ - python/mms.md
+ - python/MooseDocs/**
+ - python/moosesqa/index.md
+ - python/source/moosetree/Node.md
+ - python/testers/**
+ - python/CSVDiff.md
+ - python/TestHarness.md
+
Renderer:
type: MooseDocs.base.MaterializeRenderer
+
Extensions:
MooseDocs.extensions.navigation:
name: Fizzy
+ repo: https://github.com/TheBEllis/Fizzy
+ menu:
+ Getting Started:
+ Installation: start.md
+ Documentation:
+ Tutorials: /tutorials/index.md
+ Input Syntax: /source/index.md
+
+ MooseDocs.extensions.common:
+ shortcuts:
+ !include ${MOOSE_DIR}/framework/doc/globals.yml
+
MooseDocs.extensions.appsyntax:
executable: ${ROOT_DIR}
- remove: !include ${MOOSE_DIR}/framework/doc/remove.yml
- includes:
- - include
+ app_name: Fizzy
+ # remove:
+ # framework: !include ${MOOSE_DIR}/framework/doc/remove.yml
+ # unregister:
+ # framework: !include ${MOOSE_DIR}/framework/doc/unregister.yml
+
+ MooseDocs.extensions.acronym:
+ acronyms: !include ${MOOSE_DIR}/framework/doc/acronyms.yml
+
+ MooseDocs.extensions.template:
+ active: True
+
+globals:
+ type: MooseDocs.extensions.common
+ shortcuts:
+
+
diff --git a/doc/content/index.md b/doc/content/index.md
index 5d0f0d9..d76b165 100644
--- a/doc/content/index.md
+++ b/doc/content/index.md
@@ -1,3 +1,11 @@
!config navigation breadcrumbs=False scrollspy=False
-# FizzyApp
+# Fizzy class=center style=font-weight:200;font-size:400%
+
+!style halign=center fontsize=120%
+Enabling FISPACT-II solves on unstructured meshes
+
+Fizzy utilises [FISPACT-II](https://www.ukaea.org/service/fispact/) APIs to enable easier usage of the nuclear inventory and source term code on unstructured meshes.
+
+It is primarily designed for use when the user has tallied neutron transport results on an unstructured mesh.
+
diff --git a/doc/content/media/FizzyDocsFlow.drawio b/doc/content/media/FizzyDocsFlow.drawio
new file mode 100644
index 0000000..9913486
--- /dev/null
+++ b/doc/content/media/FizzyDocsFlow.drawio
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/content/media/FizzyDocsFlow.png b/doc/content/media/FizzyDocsFlow.png
new file mode 100644
index 0000000..dceffe9
Binary files /dev/null and b/doc/content/media/FizzyDocsFlow.png differ
diff --git a/doc/content/media/FizzyFlow.png b/doc/content/media/FizzyFlow.png
new file mode 100644
index 0000000..82e7290
Binary files /dev/null and b/doc/content/media/FizzyFlow.png differ
diff --git a/doc/content/media/FizzyFlowNoneutrons.png b/doc/content/media/FizzyFlowNoneutrons.png
new file mode 100644
index 0000000..cb745dd
Binary files /dev/null and b/doc/content/media/FizzyFlowNoneutrons.png differ
diff --git a/doc/content/media/Nb93.mp4 b/doc/content/media/Nb93.mp4
new file mode 100644
index 0000000..4c0b644
Binary files /dev/null and b/doc/content/media/Nb93.mp4 differ
diff --git a/doc/content/source/actions/AddPhotonSpectraVectorPPAllBlocks.md b/doc/content/source/actions/AddPhotonSpectraVectorPPAllBlocks.md
new file mode 100644
index 0000000..b393bed
--- /dev/null
+++ b/doc/content/source/actions/AddPhotonSpectraVectorPPAllBlocks.md
@@ -0,0 +1,21 @@
+# AddPhotonSpectraVectorPPAllBlocks
+
+!alert construction title=Undocumented Action Class
+The AddPhotonSpectraVectorPPAllBlocks has not been documented. The content listed below should be used as a starting point for
+documenting the class, which includes the typical automatic documentation associated with an Action;
+however, what is contained is ultimately determined by what is necessary to make the documentation
+clear for users.
+
+!syntax description /VectorPostprocessors/PhotonEmissionAllBlocks/AddPhotonSpectraVectorPPAllBlocks
+
+## Overview
+
+!! Replace these lines with information regarding the AddPhotonSpectraVectorPPAllBlocks action.
+
+## Example Input File Syntax
+
+!! Describe and include an example of how to use the AddPhotonSpectraVectorPPAllBlocks action.
+
+!syntax description /VectorPostprocessors/PhotonEmissionAllBlocks/AddPhotonSpectraVectorPPAllBlocks
+
+!syntax parameters /VectorPostprocessors/PhotonEmissionAllBlocks/AddPhotonSpectraVectorPPAllBlocks
diff --git a/doc/content/source/auxkernels/FispactElementKernel.md b/doc/content/source/auxkernels/FispactElementKernel.md
new file mode 100644
index 0000000..27e003a
--- /dev/null
+++ b/doc/content/source/auxkernels/FispactElementKernel.md
@@ -0,0 +1,23 @@
+# FispactElementKernel
+
+!alert construction title=Undocumented Class
+The FispactElementKernel has not been documented. The content listed below should be used as a starting point for
+documenting the class, which includes the typical automatic documentation associated with a
+MooseObject; however, what is contained is ultimately determined by what is necessary to make the
+documentation clear for users.
+
+!syntax description /AuxVariables/AuxKernel/FispactElementKernel
+
+## Overview
+
+!! Replace these lines with information regarding the FispactElementKernel object.
+
+## Example Input File Syntax
+
+!! Describe and include an example of how to use the FispactElementKernel object.
+
+!syntax parameters /AuxVariables/AuxKernel/FispactElementKernel
+
+!syntax inputs /AuxVariables/AuxKernel/FispactElementKernel
+
+!syntax children /AuxVariables/AuxKernel/FispactElementKernel
diff --git a/doc/content/source/auxkernels/FispactNuclideKernel.md b/doc/content/source/auxkernels/FispactNuclideKernel.md
new file mode 100644
index 0000000..6a4958e
--- /dev/null
+++ b/doc/content/source/auxkernels/FispactNuclideKernel.md
@@ -0,0 +1,23 @@
+# FispactNuclideKernel
+
+!alert construction title=Undocumented Class
+The FispactNuclideKernel has not been documented. The content listed below should be used as a starting point for
+documenting the class, which includes the typical automatic documentation associated with a
+MooseObject; however, what is contained is ultimately determined by what is necessary to make the
+documentation clear for users.
+
+!syntax description /AuxVariables/AuxKernel/FispactNuclideKernel
+
+## Overview
+
+!! Replace these lines with information regarding the FispactNuclideKernel object.
+
+## Example Input File Syntax
+
+!! Describe and include an example of how to use the FispactNuclideKernel object.
+
+!syntax parameters /AuxVariables/AuxKernel/FispactNuclideKernel
+
+!syntax inputs /AuxVariables/AuxKernel/FispactNuclideKernel
+
+!syntax children /AuxVariables/AuxKernel/FispactNuclideKernel
diff --git a/doc/content/source/index.md b/doc/content/source/index.md
new file mode 100644
index 0000000..f2c5f29
--- /dev/null
+++ b/doc/content/source/index.md
@@ -0,0 +1,4 @@
+!config navigation collapsible-sections=[None, 'open', 'open', 'open', 'open', 'open']
+
+!content location=source
+
diff --git a/doc/content/source/postprocessors/ElementPhotonEmission.md b/doc/content/source/postprocessors/ElementPhotonEmission.md
new file mode 100644
index 0000000..85cb907
--- /dev/null
+++ b/doc/content/source/postprocessors/ElementPhotonEmission.md
@@ -0,0 +1,23 @@
+# ElementPhotonEmission
+
+!alert construction title=Undocumented Class
+The ElementPhotonEmission has not been documented. The content listed below should be used as a starting point for
+documenting the class, which includes the typical automatic documentation associated with a
+MooseObject; however, what is contained is ultimately determined by what is necessary to make the
+documentation clear for users.
+
+!syntax description /UserObjects/ElementPhotonEmission
+
+## Overview
+
+!! Replace these lines with information regarding the ElementPhotonEmission object.
+
+## Example Input File Syntax
+
+!! Describe and include an example of how to use the ElementPhotonEmission object.
+
+!syntax parameters /UserObjects/ElementPhotonEmission
+
+!syntax inputs /UserObjects/ElementPhotonEmission
+
+!syntax children /UserObjects/ElementPhotonEmission
diff --git a/doc/content/source/postprocessors/NuclideMetric.md b/doc/content/source/postprocessors/NuclideMetric.md
new file mode 100644
index 0000000..fbaedc5
--- /dev/null
+++ b/doc/content/source/postprocessors/NuclideMetric.md
@@ -0,0 +1,23 @@
+# NuclideMetric
+
+!alert construction title=Undocumented Class
+The NuclideMetric has not been documented. The content listed below should be used as a starting point for
+documenting the class, which includes the typical automatic documentation associated with a
+MooseObject; however, what is contained is ultimately determined by what is necessary to make the
+documentation clear for users.
+
+!syntax description /UserObjects/NuclideMetric
+
+## Overview
+
+!! Replace these lines with information regarding the NuclideMetric object.
+
+## Example Input File Syntax
+
+!! Describe and include an example of how to use the NuclideMetric object.
+
+!syntax parameters /UserObjects/NuclideMetric
+
+!syntax inputs /UserObjects/NuclideMetric
+
+!syntax children /UserObjects/NuclideMetric
diff --git a/doc/content/source/postprocessors/SubdomainPhotonEmission.md b/doc/content/source/postprocessors/SubdomainPhotonEmission.md
new file mode 100644
index 0000000..271b1ca
--- /dev/null
+++ b/doc/content/source/postprocessors/SubdomainPhotonEmission.md
@@ -0,0 +1,23 @@
+# SubdomainPhotonEmission
+
+!alert construction title=Undocumented Class
+The SubdomainPhotonEmission has not been documented. The content listed below should be used as a starting point for
+documenting the class, which includes the typical automatic documentation associated with a
+MooseObject; however, what is contained is ultimately determined by what is necessary to make the
+documentation clear for users.
+
+!syntax description /UserObjects/SubdomainPhotonEmission
+
+## Overview
+
+!! Replace these lines with information regarding the SubdomainPhotonEmission object.
+
+## Example Input File Syntax
+
+!! Describe and include an example of how to use the SubdomainPhotonEmission object.
+
+!syntax parameters /UserObjects/SubdomainPhotonEmission
+
+!syntax inputs /UserObjects/SubdomainPhotonEmission
+
+!syntax children /UserObjects/SubdomainPhotonEmission
diff --git a/doc/content/source/problems/FispactProblem.md b/doc/content/source/problems/FispactProblem.md
new file mode 100644
index 0000000..d76f734
--- /dev/null
+++ b/doc/content/source/problems/FispactProblem.md
@@ -0,0 +1,53 @@
+# FispactProblem
+
+!alert construction title=Undocumented Class
+The FispactProblem has not been documented. The content listed below should be used as a starting point for
+documenting the class, which includes the typical automatic documentation associated with a
+MooseObject; however, what is contained is ultimately determined by what is necessary to make the
+documentation clear for users.
+
+!syntax description /Problem/FispactProblem
+
+## Overview
+
+The FispactProblem does most of the heavy lifiting for interfacing FISPACT-II's API with MOOSE's existing framework.
+
+## Example Input File Syntax
+
+!listing /tutorials/tutorial_1/input.i
+ id=simple-input
+ caption=A simple Fizzy input file.
+
+## Logic Flow
+
+[Figure 1](#fizzyflow) shows the logic within the +externalSolve+ method. The logic here is fairly simple. Each MPI rank loops over its local elements, and reads in the flux spectra corresponding to the current element from a given results file. Using user provided material properties and the read in flux, FISPACT-II input data is set, and then a calculation is run.
+
+!media media/FizzyDocsFlow.png
+ id=fizzyflow
+ style=width:100%;float:centre
+ prefix=Figure
+ caption=Logic flow in Fizzy externalSolve method
+
+ Given these flux spectra often have on the order of 1000 energy bins, they can be a real memory hog. By reading in the flux spectra corresponding to the current loop iteration within the scope of the loop, we reduce maximum memory utilisation. Only one flux spectra is ever in scope for each MPI rank.
+
+Another potential memory hoarder is the nuclear inventory data generated by FISPACT-II. FISPACT-II provides users various quantities relating to all of the nuclides within the nuclear inventory. Once again we keep the output inventory data within the scope of the main solve loop, so that only one output object existson any one MPI rank at any time. However, we may want to do further operations on some of these nuclear inventory statistics later in the simulation, for example within an AuxKernel. Therefore, we need a system to extract requested inventory metrics for later retrieval, before the output data goes out of scope. For this we use the [Inventory Management system](#invmanage).
+
+## Inventory Management id=invmanage
+
+FISPACT-II produces a wealth of inventory data. Therefore it is infeasible to keep all data on all nuclides from every element in memory, especially when a high fidelity mesh is being used. To get around this, we only keep the data requested from other objects in the simulation. To manage these requests, we have implemented the [FispactInventoryManager](source/userobjects/FispactInventoryManager.md) object. This object stores the quantities requested by AuxKernels/PostProcessors, and extracts them from the FISPACT output objects.
+
+## Time Stepping
+
+### Steady
+
+For [Steady](source/executioners/Steady.md) simulations, the user can choose which time in the provided FispactSchedule they would like to use as their output, using the +output_inventory_time+ parameter. By default, values from the last entry in the irradiation schedule will be used in the output.
+
+### Transient
+
+The way FISPACT-II handles timestepping and the way MOOSE handles timestepping are, in short, not immediately compatible. FISPACT-II calculates nuclear inventories for all times defined in the irradiation [schedule](source/userobjects/FispactSchedule.md) in one API call. MOOSE on the other hand expects to run the +externalSolve+ method once every timestep. To get around this, we do all of the FISPACT calculations on the first MOOSE timestep i.e. the first time +externalSolve()+ is called. Data for all timesteps is then extracted from the output object.Later MOOSE timesteps query the stored data, but do not actually do any solving.
+
+!syntax parameters /Problem/FispactProblem
+
+!syntax inputs /Problem/FispactProblem
+
+!! !syntax children /Problem/FispactProblem
diff --git a/doc/content/source/userobjects/FispactInventoryManager.md b/doc/content/source/userobjects/FispactInventoryManager.md
new file mode 100644
index 0000000..1fa5bd9
--- /dev/null
+++ b/doc/content/source/userobjects/FispactInventoryManager.md
@@ -0,0 +1,26 @@
+# FispactInventoryManager
+
+!alert construction title=Undocumented Class
+The FispactInventoryManager has not been documented. The content listed below should be used as a starting point for
+documenting the class, which includes the typical automatic documentation associated with a
+MooseObject; however, what is contained is ultimately determined by what is necessary to make the
+documentation clear for users.
+
+!syntax description /UserObjects/FispactInventoryManager
+
+## Overview
+
+
+
+
+!! Replace these lines with information regarding the FispactInventoryManager object.
+
+## Example Input File Syntax
+
+!! Describe and include an example of how to use the FispactInventoryManager object.
+
+!syntax parameters /UserObjects/FispactInventoryManager
+
+!syntax inputs /UserObjects/FispactInventoryManager
+
+!syntax children /UserObjects/FispactInventoryManager
diff --git a/doc/content/source/userobjects/FispactMaterial.md b/doc/content/source/userobjects/FispactMaterial.md
new file mode 100644
index 0000000..41dbd92
--- /dev/null
+++ b/doc/content/source/userobjects/FispactMaterial.md
@@ -0,0 +1,23 @@
+# FispactMaterial
+
+!alert construction title=Undocumented Class
+The FispactMaterial has not been documented. The content listed below should be used as a starting point for
+documenting the class, which includes the typical automatic documentation associated with a
+MooseObject; however, what is contained is ultimately determined by what is necessary to make the
+documentation clear for users.
+
+!syntax description /UserObjects/FispactMaterial
+
+## Overview
+
+!! Replace these lines with information regarding the FispactMaterial object.
+
+## Example Input File Syntax
+
+!! Describe and include an example of how to use the FispactMaterial object.
+
+!syntax parameters /UserObjects/FispactMaterial
+
+!syntax inputs /UserObjects/FispactMaterial
+
+!syntax children /UserObjects/FispactMaterial
diff --git a/doc/content/source/userobjects/FispactNuclearDataPaths.md b/doc/content/source/userobjects/FispactNuclearDataPaths.md
new file mode 100644
index 0000000..676a3b9
--- /dev/null
+++ b/doc/content/source/userobjects/FispactNuclearDataPaths.md
@@ -0,0 +1,23 @@
+# FispactNuclearDataPaths
+
+!alert construction title=Undocumented Class
+The FispactNuclearDataPaths has not been documented. The content listed below should be used as a starting point for
+documenting the class, which includes the typical automatic documentation associated with a
+MooseObject; however, what is contained is ultimately determined by what is necessary to make the
+documentation clear for users.
+
+!syntax description /UserObjects/FispactNuclearDataPaths
+
+## Overview
+
+!! Replace these lines with information regarding the FispactNuclearDataPaths object.
+
+## Example Input File Syntax
+
+!! Describe and include an example of how to use the FispactNuclearDataPaths object.
+
+!syntax parameters /UserObjects/FispactNuclearDataPaths
+
+!syntax inputs /UserObjects/FispactNuclearDataPaths
+
+!syntax children /UserObjects/FispactNuclearDataPaths
diff --git a/doc/content/source/userobjects/FispactSchedule.md b/doc/content/source/userobjects/FispactSchedule.md
new file mode 100644
index 0000000..f3c393b
--- /dev/null
+++ b/doc/content/source/userobjects/FispactSchedule.md
@@ -0,0 +1,23 @@
+# FispactSchedule
+
+!alert construction title=Undocumented Class
+The FispactSchedule has not been documented. The content listed below should be used as a starting point for
+documenting the class, which includes the typical automatic documentation associated with a
+MooseObject; however, what is contained is ultimately determined by what is necessary to make the
+documentation clear for users.
+
+!syntax description /UserObjects/FispactSchedule
+
+## Overview
+
+!! Replace these lines with information regarding the FispactSchedule object.
+
+## Example Input File Syntax
+
+!! Describe and include an example of how to use the FispactSchedule object.
+
+!syntax parameters /UserObjects/FispactSchedule
+
+!syntax inputs /UserObjects/FispactSchedule
+
+!syntax children /UserObjects/FispactSchedule
diff --git a/doc/content/source/userobjects/OpenMCFluxInput.md b/doc/content/source/userobjects/OpenMCFluxInput.md
new file mode 100644
index 0000000..1b9500e
--- /dev/null
+++ b/doc/content/source/userobjects/OpenMCFluxInput.md
@@ -0,0 +1,23 @@
+# OpenMCFluxInput
+
+!alert construction title=Undocumented Class
+The OpenMCFluxInput has not been documented. The content listed below should be used as a starting point for
+documenting the class, which includes the typical automatic documentation associated with a
+MooseObject; however, what is contained is ultimately determined by what is necessary to make the
+documentation clear for users.
+
+!syntax description /UserObjects/OpenMCFluxInput
+
+## Overview
+
+!! Replace these lines with information regarding the OpenMCFluxInput object.
+
+## Example Input File Syntax
+
+!! Describe and include an example of how to use the OpenMCFluxInput object.
+
+!syntax parameters /UserObjects/OpenMCFluxInput
+
+!syntax inputs /UserObjects/OpenMCFluxInput
+
+!syntax children /UserObjects/OpenMCFluxInput
diff --git a/doc/content/source/vectorpostprocessors/SubdomainPhotonEmissionSpectraPostprocessor.md b/doc/content/source/vectorpostprocessors/SubdomainPhotonEmissionSpectraPostprocessor.md
new file mode 100644
index 0000000..543eb2c
--- /dev/null
+++ b/doc/content/source/vectorpostprocessors/SubdomainPhotonEmissionSpectraPostprocessor.md
@@ -0,0 +1,23 @@
+# SubdomainPhotonEmissionSpectraPostprocessor
+
+!alert construction title=Undocumented Class
+The SubdomainPhotonEmissionSpectraPostprocessor has not been documented. The content listed below should be used as a starting point for
+documenting the class, which includes the typical automatic documentation associated with a
+MooseObject; however, what is contained is ultimately determined by what is necessary to make the
+documentation clear for users.
+
+!syntax description /VectorPostprocessors/SubdomainPhotonEmissionSpectraPostprocessor
+
+## Overview
+
+!! Replace these lines with information regarding the SubdomainPhotonEmissionSpectraPostprocessor object.
+
+## Example Input File Syntax
+
+!! Describe and include an example of how to use the SubdomainPhotonEmissionSpectraPostprocessor object.
+
+!syntax parameters /VectorPostprocessors/SubdomainPhotonEmissionSpectraPostprocessor
+
+!syntax inputs /VectorPostprocessors/SubdomainPhotonEmissionSpectraPostprocessor
+
+!syntax children /VectorPostprocessors/SubdomainPhotonEmissionSpectraPostprocessor
diff --git a/doc/content/start.md b/doc/content/start.md
new file mode 100644
index 0000000..1882b17
--- /dev/null
+++ b/doc/content/start.md
@@ -0,0 +1,106 @@
+# Installation
+
+## Prerequisites
+
+- A working +MOOSE+ build Currently Fizzy has not been tested using MOOSE's conda environment, only MOOSE builds from source. Being a MOOSE based app, Fizzy shared MOOSE's [minimum requirements](http://mooseframework.inl.gov/sqa/minimum_requirements.html)
+- Access to FISPACT-II binaries (5.0+)
+
+ - FISPACT-II licenses can be purchase from [this](https://www.ukaea.org/service/fispact/) link.
+
+- [PugiXML](https://pugixml.org/) (1.14+)
+
+ - PugiXML can be easily installed from most package managers.
+
+ ```
+ sudo apt install libpugixml-dev
+ ```
+
+- [BOOST](https://www.boost.org/doc/user-guide/getting-started.html) Libraries
+ - This application makes use of `boost::interprocess`. Most users should be able to install BOOST libraries via their package manager. For Debian/Ubuntu users, this would look like:
+
+ ```
+ sudo apt install sudo apt install libboost-all-dev
+ ```
+
+- [spdlog](https://github.com/gabime/spdlog) Libraries
+ - FISPACT-II's internal monitoring depends on libspdlog being available on the system
+
+ ```
+ sudo apt install libspdlog-dev
+ ```
+
+!alert! note title=Recommended
+> To use all of Fizzy's capabilities, users will also need a valid [Cardinal](https://cardinal.cels.anl.gov/) installation. Instructions on how to install Cardinal can be found [here](https://cardinal.cels.anl.gov/start.html).
+> Using Fizzy and Cardinal together, users can perform particle transport using a source term generated by Fizzy. This may be used to perform shutdown dose rate calculations, for example.
+!alert-end!
+
+[Tutorial 4](/) demonstrates how Fizzy and Cardinal can be used together.
+
+## Access
+
+To access Fizzy, clone the repository and cd into the directory
+
+```language=bash
+git clone https://github.com/TheBEllis/Fizzy.git
+cd Fizzy
+```
+
+## Installing
+
+!alert warning
+Fizzy has only been tested on Ubuntu 24.04 (so far). Other Linux distros, MacOS and Windows have not been tested. If users trying to run Fizzy on these platforms
+experience issues with installation and/or running, please report the issue on Fizzy's [github issues](https://github.com/TheBEllis/Fizzy/issues) page.
+
+To install Fizzy, users must specify the directory of their FISPACT-II binaries by setting the environment variable `FISPACT_DIR`. The exact directory will differ depending on the version of FISPACT-II the user has available.
+
+Users must also make sure that the relevent FISPACT-II libraries are present in their `LD_LIBRARY_PATH`.
+
+
+#### FISPACT-II V5.1
+
+```language=bash
+export FISPACT_DIR=/path/to/FISPACT/api/
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:path/to/FISPACT/api/lib/linux
+```
+
+#### FISPACT-II V5.0
+
+```language=bash
+export FISPACT_DIR=/path/to/FISPACT/ubuntu/20.10
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:path/to/FISPACT/ubuntu/20.10/lib
+```
+
+!alert warning
+The exact directories that need to be set may differ depending on users directory structure. By setting `FISPACT_DIR`, Fizzy will automatically look for FISPACT libraries and includes at `${FISPACT_DIR}/lib/linux` and `${FISPACT_DIR}/includes/cpp`. Users can manually set the locations of libraries and includes by settings the environment variables `FISPACT_LIB_DIR` and `FISPACT_INCLUDE_DIR`.
+
+The final step is to run `make` in the Fizzy root directory. After a successful install, an executable called `Fizzy-opt` should be found in the application root directory.
+
+```language=bash
+make -j 4
+```
+
+## Verifying installation.
+
+To verify Fizzy has been installed correctly, users can run example problems found in `/Fizzy/tutorials`. However, to run these tutorials, users need access to a suitable nuclear data set. The FISPACT-II nuclear data repository can be found [here](https://git.oecd-nea.org/fispact/nuclear_data/). The tutorials all make use of ENDFB80 nuclear data, so it is recommended that first time users download this nuclear data set.
+
+By default the `base_path` parameter in Tutorial 1's input file points to `/Projects/FispactNuclearData`. Users must change this directory to the directory on their local machine containing the downloaded nuclear data in their local filesystem.
+
+!listing /tutorials/tutorial_1/input.i
+ block=UserObjects/endf_nuclear_data
+ id=nd-block
+ caption=The user defined +Nuclear Data+
+
+Then they are ready to run the input file.
+
+```language=bash
+./Fizzy-opt -i tutorials/tutorial_1/input.i
+```
+
+
+## Tutorials
+
+Click the link to access Fizzy tutorials that take you through the available functionality.
+
+!content pagination use_title=True
+ next=tutorials/index.md
+
diff --git a/doc/content/tutorials/index.md b/doc/content/tutorials/index.md
new file mode 100644
index 0000000..3347f32
--- /dev/null
+++ b/doc/content/tutorials/index.md
@@ -0,0 +1,20 @@
+# Tutorials
+
+Fizzy is designed to work similarly to other MOOSE applications, in terms of its interoperability with other MOOSE applications. Any quantity that can be mapped to an auxiliary variable can be used within the existing MOOSE [Transfers](Transfers/index.md) system to communicate it's values with other MOOSE apps.
+
+
+## Tutorial 1: Just FISPACT
+
+[Tutorial 1](tutorials/tutorial_1/index.md) will take you through how to set up a simple Fizzy application. This tutorial details the bare essentials of a Fizzy input file
+
+## Tutorial 2: Adding AuxVariables, AuxKernels and Postprocessors
+
+[Tutorial 2](tutorials/tutorial_2/index.md) will take you through how to add AuxVariables and AuxKernels to an input file in order to capture nuclear inventory quantities.
+
+## Tutorial 3: Transient Simulations
+
+[Tutorial 3](tutorials/tutorial_3/index.md) will take you through how to set up a transient Fizzy application, allowing the user to visualise how the inventory develops over time.
+
+## Tutorial 4: Coupling with Cardinal/OpenMC
+
+[Tutorial 4](tutorials/tutorial_4/index.md) will take you through how to set up a Fizzy application that couples to Cardinal/OpenMC to perform dose rate analysis.
diff --git a/doc/content/tutorials/tutorial_1/index.md b/doc/content/tutorials/tutorial_1/index.md
new file mode 100644
index 0000000..0d499d8
--- /dev/null
+++ b/doc/content/tutorials/tutorial_1/index.md
@@ -0,0 +1,100 @@
+# Fizzy tutorial 1: Just FISPACT
+
+This tutorial will focus on getting a base level input file prepared for a FISPACT solve using Fizzy.
+
+There are +6 necessary components+ to a Fizzy input file,
+
+1. [#mesh-section]
+2. [#problem-section]
+3. [#schedule]
+4. [#input-flux]
+5. [#materials]
+6. [#nd]
+7. [#exec]
+
+## The Mesh id=mesh-section
+
+!listing /tutorials/tutorial_1/input.i
+ block=Mesh
+ id=mesh-block
+ caption=The +Mesh+ block
+
+A Fizzy input file defines the mesh just like a standard [MOOSE](https://mooseframework.inl.gov/syntax/Mesh/) input file. There are no special requirements for a mesh using exclusively Fizzy, however restrictions do exist when coupling with [Cardinal], these are discussed in latter [tutorials](tutorials/tutorial_2/index.md).
+
+## The Problem id=problem-section
+
+!listing /tutorials/tutorial_1/input.i
+ block=Problem
+ id=problem-block
+ caption=User defined +irradiation schedule+"
+
+
+The problem block represents the first significant departure from a standard MOOSE input. Here, a problem of type [FispactProblem](source/problems/FispactProblem.md) must be used. The required parameters are listed in [Table 1](#fp-params).
+
+!table id=fp-params caption=Necessary input parameters for a FispactProblem
+| Parameter | Description |
+| - | - |
+| +molar_mass_data+ | Path to an HDF5 file containing molar mass data for relevant nuclides. |
+| +fispact_schedule_uo+ | The name of the fispact schedule UserObject the user whishes to use in this simulation. |
+| +fispact_nuclear_data_uo+ | The name of the fispact nuclear data UserObject the user whishes to use in this simulation. |
+| +fispact_input_flux_uo+ | The name of the UserObject defining the input flux. |
+| +output_inventory_time+ | If this is a Steady simulation, this parameter determines which FISPACT-II inventory step is used for output. |
+
+
+## Irradiation Schedule id=schedule
+
+!listing /tutorials/tutorial_1/input.i
+ block=UserObjects/Schedule
+ id=schedule-block
+ caption=The +irradiation schedule+ block
+
+This block defines the irradiation schedule of your simulation.
+
+| Parameter | Description |
+| - | - |
+| +times+ | The times in seconds used for the irradiation schedule. |
+| +flux_amplitude+ | Energy integrated projectile flux values in particles per second per cm^2 |
+
+## Input Flux id=input-flux
+
+!listing /tutorials/tutorial_1/input.i
+ block=UserObjects/InputFlux
+ id=input-flux-block
+ caption=The +input-flux+ block
+
+!alert warning
+Currently only OpenMC statepoint files are supported as inputs.
+
+This block defines the input flux spectra for your FISPACT-II simulation. Here we are using mesh tallied flux spectra from an OpenMC simulation. The provided results data file must be compatible with the input mesh, i.e. it must have the correct dimensions.
+
+## FISPACT material definitions id=materials
+
+!listing /tutorials/tutorial_1/input.i
+ block=UserObjects/steel
+ id=materials-block
+ caption=A FISPACT material definition
+
+This block defines the materials in the simulation. Each block within the mesh must have +one and only one+ FispactMaterial assigned to it. Users can define materials by explicitly stating the concentrations of each isotope, or by defining elements, and letting FISPACT automatically decide the abundancies of each isotope.
+
+## Nuclear Data id=nd
+
+!listing /tutorials/tutorial_1/input.i
+ block=UserObjects/endf_nuclear_data
+ id=nd-block
+ caption=The user defined +Nuclear Data+
+
+Here the user sets the necessary paths to their chosen nuclear data set. The [FispactNuclearData](source/userobjects/FispactNuclearDataPaths.md) UserObject will check whether the paths handed to it are valid, but currently it cannot check the validity of the nuclear data itself.
+
+FISPACT-II uses multi-group cross sections. The input flux spectra are required to be binned into the same energy groups as the passed in nuclear data. If the user passes in flux spectra binned into different energy groups, a conversion is automatically performed. The FispactProblem block has a parameter **conversion_type**, which can be set to either ENERGY or LETHARGY depending on how the user would like the energy groups to be converted.
+
+## Executioner id=exec
+
+!listing /tutorials/tutorial_1/input.i
+ block=Executioner
+ id=executioner-block
+ caption=The +Executioner+ block
+
+For [Steady](source/executioners/Steady.md) simulations, the executioner block looks just like a standard MOOSE input file.
+
+!content pagination use_title=True
+ next=tutorials/tutorial_2/index.md
diff --git a/doc/content/tutorials/tutorial_2/index.md b/doc/content/tutorials/tutorial_2/index.md
new file mode 100644
index 0000000..4c58618
--- /dev/null
+++ b/doc/content/tutorials/tutorial_2/index.md
@@ -0,0 +1,57 @@
+# Fizzy tutorial 2: Adding AuxVariables, AuxKernels, and PostProcessors
+
+In this tutorial, the input file from [Tutorial 1](tutorials/tutorial_1/index.md) will be developed to add AuxVariables, AuxKernels and PostProcessors to help extract data from the calculated nuclear inventories.
+
+1. [#auxvars]
+2. [#postprocessors]
+3. [#outputs]
+
+## Adding AuxVars and AuxKernels id=auxvars
+
+!listing /tutorials/tutorial_2/input.i
+ block=AuxVariables
+ id=aux-block
+
+Firstly, we add AuxVariables into the input file. Anyone who has used MOOSE before will be familiar with this syntax. We just define a block called `AuxVariables`, which lets MOOSE know we wish to define AuxVariables here. Then we define sub-blocks that represent our actual variables. Variables used in Fizzy AuxKernels must be CONSTANT order MONOMIALS.
+
+
+!listing /tutorials/tutorial_2/input.i
+ block=AuxKernels
+ id=auxkern-block
+
+Secondly, we add AuxKernel blocks, to which we assign AuxVariables. Here we add two slightly different AuxKernels, a [FispactNuclideKernel](source/auxkernels/FispactNuclideKernel.md), and a [FispactElementKernel](source/auxkernels/FispactElementKernel.md).
+
+The FispactNuclideKernel is used for extracting metrics regarding particular nuclides from the nuclear inventory. In this example, we extract the number of Niobium-93 atoms. Because we are using AuxVariables, this value will be evaluated for each element.
+
+The FispactElementKernel is used for getting quantities representitive of the entire nuclear inventory, not just individual nuclides. Here we are modelling the total number of atoms in the entire inventory.
+
+To get a list of possible values of the `metric`, parameter, see the individual documentation pages for both [FispactNuclideKernel](source/auxkernels/FispactNuclideKernel.md), and [FispactElementKernel](source/auxkernels/FispactElementKernel.md).
+
+
+## Adding PostProcessors id=postprocessors
+
+!listing /tutorials/tutorial_2/input.i
+ block=Postprocessors
+ id=post-block
+
+To calculate scalar quantities over the entire domain, or subsections of the domain, users can use PostProcessors.
+
+This example includes two postprocessors. Firstly, there is an [ElementPhotonEmission](ElementPhotonEmission.md) PostProcessor. This will return the total gamma emission rate summed over the elements defined by the element_ids parameter. If the user wishes to obtain the total gamma emission rate over a subdomain, they can use the [SubdomainPhotonEmission](SubdomainPhotonEmission.md) PostProcessor.
+
+A [NuclideMetric](NuclideMetric.md) is included to track domain wide metrics from particular nuclides. In this example, the nuclide_contribution postprocessor outputs the total slab dose rate contributed by Cr51.
+
+!alert warning
+When providing nuclide names to AuxKernels or PostProcessors, make sure they are formatted correctly, using the correct case.
+
+## Output id=outputs
+
+!listing /tutorials/tutorial_2/input.i
+ block=Outputs
+ id=outputs-block
+ caption=The +Outputas+ block
+
+Now that some variables exist on the mesh, we may want to visualise the results.To do this we will need to add an exodus output block, or in this case, use the syntactical shortcut for one.
+
+!content pagination use_title=True
+ previous=tutorials/tutorial_1/index.md
+ next=tutorials/tutorial_3/index.md
diff --git a/doc/content/tutorials/tutorial_3/index.md b/doc/content/tutorials/tutorial_3/index.md
new file mode 100644
index 0000000..1620df1
--- /dev/null
+++ b/doc/content/tutorials/tutorial_3/index.md
@@ -0,0 +1,38 @@
+# Fizzy tutorial 3: Transient Simulations
+
+In this tutorial, the input file from [Tutorial 2](tutorials/tutorial_2/index.md) will be developed into a transient simulation, allowing users to visualise how tracked inventory metrics develop over time.
+
+1. [#times]
+2. [#exec]
+
+## Getting Times from the FispactSchedule
+
+!listing /tutorials/tutorial_3/input.i
+ block=Times
+ id=times-block
+
+To run a transient simulation, we need to get our timesteps. FISPACT is different from standard MOOSE, in that the timestepping system is not dynamic. The user sets the times they would like to be solved for in the irradiation schedule, and then FISPACT solves for those times. We need a way of turning the times defined in the schedule into something that can be passed into MOOSE's Transient executioner. For this we use the [FispactScheduleTimes](FispactScheduleTimes.md) object. The only parameter we pass to this is the name of our previously defined FispactSchedule UserObject.
+
+## Adding PostProcessors id=postprocessors
+
+!listing /tutorials/tutorial_3/input.i
+ block=Executioner
+ id=exec-block
+
+To perform a transient solve firstly we must set our executioner type to Transient. Then we must use use a [TimeSequenceFromTimes](TimeSequenceFromTimes.md) timestepper, and pass in our previously defined FizzyTimes.
+
+
+## Output id=output
+
+Now that the simulation is transient, we can visualise the number of Nb93 atoms over time.
+
+!media media/Nb93.mp4
+ id=Nb93
+ style=width:50%;margin-left:auto;margin-right:auto;
+ prefix=Figure
+ caption=Evolution of Nb93 atom count over time.
+ loop=true
+
+!content pagination use_title=True
+ previous=tutorials/tutorial_2/index.md
+ next=tutorials/tutorial_4/index.md
diff --git a/doc/content/tutorials/tutorial_4/index.md b/doc/content/tutorials/tutorial_4/index.md
new file mode 100644
index 0000000..511dbc3
--- /dev/null
+++ b/doc/content/tutorials/tutorial_4/index.md
@@ -0,0 +1,94 @@
+# Fizzy tutorial 4: Distributed Sampling with Cardinal
+
+In this tutorial, we will set up a MOOSE multiapp using Cardinal, to perform a photon transport solve. The source of the transport solve will be defined by the photon emission spectra calculated by FISPACT-II. The source will also be distributed over MPI ranks, so that different MPI ranks are responsible for sampling from subsections of the domain.
+
+## Prerequisites
+
+1. An MPI compatible MOOSE build
+2. A valid Cardinal installation w/ OpenMC & DAGMC
+3. A build of FizzyCompiledSource
+
+The next section will explain how to install the latter. For instructions on how to install Cardinal, please visit Cardinal's own [installation instructions](https://cardinal.cels.anl.gov/start.html).
+
+## Background
+
+!media media/FizzyFlowNoneutrons.png
+ id=fizzyflow
+ style=width:50%;margin-left:auto;margin-right:auto;
+ prefix=Figure
+ caption=Flow of data in a Fizzy & Cardinal multiapp.
+
+Figure 1 shows the flow of data used when performing distributed sampling with Fizzy. To perform distributed sampling, a custom OpenMC source is used, defined in FizzyCompiledSource. FizzyCompiledSource derived from OpenMC's [CompiledSource](https://docs.openmc.org/en/stable/pythonapi/generated/openmc.CompiledSource.html) functionality, which allows a source term to be defined by a compiled library. We utilise the CompiledSource functionality in order to have granular control over the weighting of sampled particles. This is necessary to perform distributed sampling, as the source terms for different MPI ranks may be of different strengths.
+
+Once Fizzy has completed its solve, the calculated photon emission spectra need to be communicated directly to the CompiledSource. There is not currently a way to do this using MOOSE's Transfers system. Therefore, we utilise an interprocess memory segment to store the photon emission spectra calculated by Fizzy, which we can then read into the CompiledSource at run time.
+
+## Installing FizzyCompiledSource
+
+FizzyCompiledSource is included as a submodule of Fizzy. To build it, first initialise the submodules in the repository.
+
+```language=bash
+git submodule git submodule update --init
+```
+
+Then change directory into FizzyCompiledSource from the main Fizzy directory, and create a build folder.
+
+```language=bash
+cd Fizzy
+cd FizzyCompiledSource
+mkdir build && cd build
+```
+
+Run CMake from the build folder, specifying the directory of your Cardinal build.
+
+```language=bash
+cmake -DCARDINAL_DIR=/path/to/cardinal ../
+make -j
+```
+
+The built library can be found in the build folder at libCompiledSource.so.
+
+## OpenMC inputs id=openmc_inputs
+
+Within the OpenMC Python API, users can set parameters for their OpenMC run. This tutorial won't go over the fundamentals of setting up an OpenMC solve, or installing the OpenMC python module, but for more information, the OpenMC team have extensively documented the Python API, as well as all other parts of [OpenMC](https://docs.openmc.org/en/stable/pythonapi/index.html).
+
+To make use of distributed sampling, users must set the library they compiled in the previous step as their desired source in OpenMC. Below is an example OpenMC python file that shows users how to set the source, and that can be used a base for their own simulations.
+
+!listing /tutorials/tutorial_4/openmc_photon.py
+
+## Fizzy Inputs
+
+To prepare the Fizzy input for communicating with Cardinal/OpenMC, the com_photon_flux parameter must be set to True. This prompts Fizzy to put the necessary photon emission rate data into an interprocess memory segment.
+
+!listing /tutorials/tutorial_4/input.i
+ block=Problem
+ id=newblocks
+
+The other requisite addition to the Fizzy input file in the MultiApps block, within which we define a Cardinal multi-app that runs after Fizzy's solve is completed.
+
+!listing /tutorials/tutorial_4/input.i
+ block=MultiApps
+ id=multiapps
+
+The next additions are not required for the simulation to run, but might still be useful. Here we define a variable transfer from Cardinal to OpenMC. The tallies photon flux on each element will be transferred to the Auxiliary Variable photon_flux in Fizzy.
+
+!listing /tutorials/tutorial_4/input.i
+ block=AuxVariables Transfers
+ id=newblocks
+
+## Cardinal Inputs
+
+Listing 5 shows the example Cardinal input file. This input defines the mesh we wish to tally on, quantities we wish to tally, and the OpenMC xml files we wish to use as input.
+
+
+!alert warning
+The mesh used in Fizzy and Cardinal must be the same for distributed sampling to work.
+
+
+!listing /tutorials/tutorial_4/photons_input.i
+ id=cardinal
+
+!alert warning
+To make use of distributed sampling, OpenMC must be aware of the mesh used in the Fizzy calculation. For OpenMC to be aware of the mesh, at least one mesh tally must exist on the mesh.
+
+!content pagination use_title=True
+ previous=tutorials/tutorial_3/index.md
diff --git a/doc/globals.yml b/doc/globals.yml
new file mode 100644
index 0000000..8781ad4
--- /dev/null
+++ b/doc/globals.yml
@@ -0,0 +1 @@
+Cardinal: inal.cels.anl.gov
diff --git a/doc/sqa_reports.yml b/doc/sqa_reports.yml
index b81f567..44b7d77 100644
--- a/doc/sqa_reports.yml
+++ b/doc/sqa_reports.yml
@@ -1,5 +1,5 @@
Applications:
- fizzy:
+ Fizzy:
app_types:
- FizzyApp
content_directory: ${ROOT_DIR}/doc/content
diff --git a/geometry/cube.e b/geometry/cube.e
new file mode 100644
index 0000000..5f40eb5
Binary files /dev/null and b/geometry/cube.e differ
diff --git a/geometry/cube_dag.h5m b/geometry/cube_dag.h5m
new file mode 100644
index 0000000..e18deee
Binary files /dev/null and b/geometry/cube_dag.h5m differ
diff --git a/include/actions/AddInventoryManager.h b/include/actions/AddInventoryManager.h
new file mode 100644
index 0000000..bdf6f5c
--- /dev/null
+++ b/include/actions/AddInventoryManager.h
@@ -0,0 +1,12 @@
+#pragma once
+#include "Action.h"
+#include "InputParameters.h"
+
+class AddInventoryManager : public Action {
+public:
+ static InputParameters validParams();
+
+ AddInventoryManager(const InputParameters ¶ms);
+
+ virtual void act() override;
+};
diff --git a/include/actions/AddPhotonSpectraVectorPPAllBlocks.h b/include/actions/AddPhotonSpectraVectorPPAllBlocks.h
new file mode 100644
index 0000000..e5c1f40
--- /dev/null
+++ b/include/actions/AddPhotonSpectraVectorPPAllBlocks.h
@@ -0,0 +1,12 @@
+#pragma once
+#include "Action.h"
+#include "InputParameters.h"
+
+class AddPhotonSpectraVectorPPAllBlocks : public Action {
+public:
+ static InputParameters validParams();
+
+ AddPhotonSpectraVectorPPAllBlocks(const InputParameters ¶ms);
+
+ virtual void act() override;
+};
diff --git a/include/auxkernels/FispactAuxKernel.h b/include/auxkernels/FispactAuxKernel.h
new file mode 100644
index 0000000..25367c7
--- /dev/null
+++ b/include/auxkernels/FispactAuxKernel.h
@@ -0,0 +1,25 @@
+#pragma once
+#include "AuxKernel.h"
+#include "FispactInventoryManager.h"
+#include "FizzyEnums.h"
+
+class FispactAuxKernel : public AuxKernel {
+
+public:
+ static InputParameters validParams() {
+ InputParameters params = AuxKernel::validParams();
+ return params;
+ }
+
+ FispactAuxKernel(const InputParameters ¶ms) : AuxKernel(params) {
+ if (mooseVariableBase()->feType() != libMesh::FEType(CONSTANT, MONOMIAL))
+ paramError("variable", "Must be of type CONSTANT MONOMIAL");
+ }
+
+protected:
+ virtual Real computeValue() override = 0;
+
+ const FispactInventoryManager &getInventoryManager() {
+ return getUserObject("InvManager");
+ }
+};
diff --git a/include/auxkernels/FispactElementKernel.h b/include/auxkernels/FispactElementKernel.h
new file mode 100644
index 0000000..da04924
--- /dev/null
+++ b/include/auxkernels/FispactElementKernel.h
@@ -0,0 +1,18 @@
+#include "FispactAuxKernel.h"
+#include "FizzyEnums.h"
+#include "InputParameters.h"
+
+class FispactElementKernel : public FispactAuxKernel {
+
+public:
+ static InputParameters validParams();
+
+ FispactElementKernel(const InputParameters ¶ms);
+
+protected:
+ virtual Real computeValue() override;
+
+ std::string _nuclide;
+
+ inventory_outputs::InventoryOutputsEnum _metric;
+};
diff --git a/include/auxkernels/FispactNuclideKernel.h b/include/auxkernels/FispactNuclideKernel.h
new file mode 100644
index 0000000..bdbe8f4
--- /dev/null
+++ b/include/auxkernels/FispactNuclideKernel.h
@@ -0,0 +1,17 @@
+#include "FispactAuxKernel.h"
+#include "InputParameters.h"
+
+class FispactNuclideKernel : public FispactAuxKernel {
+
+public:
+ static InputParameters validParams();
+
+ FispactNuclideKernel(const InputParameters ¶ms);
+
+protected:
+ virtual Real computeValue() override;
+
+ std::string _nuclide;
+
+ nuclide_quantities::NuclideQuantitiesEnum _metric;
+};
diff --git a/include/base/FizzyApp.h b/include/base/FizzyApp.h
index b9ed312..9138f91 100644
--- a/include/base/FizzyApp.h
+++ b/include/base/FizzyApp.h
@@ -11,8 +11,7 @@
#include "MooseApp.h"
-class FizzyApp : public MooseApp
-{
+class FizzyApp : public MooseApp {
public:
static InputParameters validParams();
@@ -20,5 +19,7 @@ class FizzyApp : public MooseApp
virtual ~FizzyApp();
static void registerApps();
- static void registerAll(Factory & f, ActionFactory & af, Syntax & s);
+ static void registerAll(Factory &f, ActionFactory &af, Syntax &s);
+ static void associateSyntaxInner(Syntax &syntax,
+ ActionFactory &action_factory);
};
diff --git a/include/base/FizzyEnums.h b/include/base/FizzyEnums.h
new file mode 100644
index 0000000..d7d53b6
--- /dev/null
+++ b/include/base/FizzyEnums.h
@@ -0,0 +1,46 @@
+#pragma once
+
+#include "MooseEnum.h"
+#include "MultiMooseEnum.h"
+
+MooseEnum getInventoryMetricsEnum();
+MooseEnum getNuclideMetricsEnum();
+
+namespace inventory_outputs {
+
+enum InventoryOutputsEnum {
+ INVENTORY_IRRAD_TIME,
+ INVENTORY_COOL_TIME,
+ INVENTORY_TOTAL_ACTIVITY,
+ INVENTORY_ALPHA_ACTIVITY,
+ INVENTORY_BETA_ACTIVITY,
+ INVENTORY_GAMMA_ACTIVITY,
+ INVENTORY_TOTAL_HEAT,
+ INVENTORY_ALPHA_HEAT,
+ INVENTORY_BETA_HEAT,
+ INVENTORY_GAMMA_HEAT,
+ INVENTORY_TOTAL_MASS,
+ INVENTORY_TOTAL_ATOMS,
+ INVENTORY_INGESTION,
+ INVENTORY_INHALATION,
+ INVENTORY_FLUX_AMP,
+ INVENTORY_DOSE_RATE
+};
+};
+
+namespace nuclide_quantities {
+
+enum NuclideQuantitiesEnum {
+ ATOMS,
+ GRAMS,
+ ACTIVITY,
+ ALPHA_ACTIVITY,
+ BETA_ACTIVITY,
+ GAMMA_ACTIVITY,
+ TOTAL_HEAT,
+ ALPHA_HEAT,
+ BETA_HEAT,
+ GAMMA_HEAT,
+ DOSE
+};
+};
diff --git a/include/fispact/adapter/FispactContext.h b/include/fispact/adapter/FispactContext.h
new file mode 100644
index 0000000..982cc7c
--- /dev/null
+++ b/include/fispact/adapter/FispactContext.h
@@ -0,0 +1,478 @@
+#pragma once
+#include "FispactContextBase.h"
+
+#include
+#include
+#include
+/// Fispact includes
+#include "FizzyEnums.h"
+#include "fispactcompute.hpp"
+#include "fispactelementaldata.hpp"
+#include "fispactgroupconvert.hpp"
+#include "fispactgroupstructures.hpp"
+#include "fispactinputdata.hpp"
+#include "fispactmonitor.hpp"
+#include "fispactnucleardata.hpp"
+#include "fispactoutputdata.hpp"
+#include "fispactoutputdataapi.h"
+#include "fispactutil.hpp"
+
+inline int
+convertFispactEnum(inventory_outputs::InventoryOutputsEnum output_enum) {
+ switch (output_enum) {
+ case (inventory_outputs::INVENTORY_IRRAD_TIME):
+ return FISPACT_OUTPUT_DATA_INVENTORY_IRRAD_TIME;
+ case (inventory_outputs::INVENTORY_COOL_TIME):
+ return FISPACT_OUTPUT_DATA_INVENTORY_COOL_TIME;
+ case (inventory_outputs::INVENTORY_TOTAL_ACTIVITY):
+ return FISPACT_OUTPUT_DATA_INVENTORY_TOTAL_ACTIVITY;
+ case (inventory_outputs::INVENTORY_ALPHA_ACTIVITY):
+ return FISPACT_OUTPUT_DATA_INVENTORY_ALPHA_ACTIVITY;
+ case (inventory_outputs::INVENTORY_BETA_ACTIVITY):
+ return FISPACT_OUTPUT_DATA_INVENTORY_BETA_ACTIVITY;
+ case (inventory_outputs::INVENTORY_GAMMA_ACTIVITY):
+ return FISPACT_OUTPUT_DATA_INVENTORY_GAMMA_ACTIVITY;
+ case (inventory_outputs::INVENTORY_TOTAL_HEAT):
+ return FISPACT_OUTPUT_DATA_INVENTORY_TOTAL_HEAT;
+ case (inventory_outputs::INVENTORY_ALPHA_HEAT):
+ return FISPACT_OUTPUT_DATA_INVENTORY_ALPHA_HEAT;
+ case (inventory_outputs::INVENTORY_BETA_HEAT):
+ return FISPACT_OUTPUT_DATA_INVENTORY_BETA_HEAT;
+ case (inventory_outputs::INVENTORY_GAMMA_HEAT):
+ return FISPACT_OUTPUT_DATA_INVENTORY_GAMMA_HEAT;
+ case (inventory_outputs::INVENTORY_TOTAL_MASS):
+ return FISPACT_OUTPUT_DATA_INVENTORY_TOTAL_MASS;
+ case (inventory_outputs::INVENTORY_TOTAL_ATOMS):
+ return FISPACT_OUTPUT_DATA_INVENTORY_TOTAL_ATOMS;
+ case (inventory_outputs::INVENTORY_FLUX_AMP):
+ return FISPACT_OUTPUT_DATA_INVENTORY_FLUX_AMP;
+ default:
+ return -1;
+ }
+}
+
+class FispactOutputNuclideData : public FispactOutputNuclideDataBase {
+public:
+ explicit FispactOutputNuclideData(fispact::OutputNuclideData &nuclide_data)
+ : _nuclide_data(std::move(nuclide_data)) {}
+
+ virtual ~FispactOutputNuclideData() = default;
+
+ virtual std::string getElement() const { return _nuclide_data.getElement(); }
+
+ virtual std::string getState() const { return _nuclide_data.getState(); }
+
+ virtual int getIsotope() const { return _nuclide_data.getIsotope(); }
+
+ virtual int getZAI() const { return _nuclide_data.getZAI(); }
+
+ virtual double getHalfLife() const { return _nuclide_data.getHalfLife(); }
+ // The number of atoms
+ virtual double getAtoms() const { return _nuclide_data.getAtoms(); }
+ // The grams (g)
+ virtual double getGrams() const { return _nuclide_data.getGrams(); }
+ // The activity (Bq)
+ virtual double getActivity() const { return _nuclide_data.getActivity(); }
+ // The alpha fraction of the activity (Bq)
+ virtual double getAlphaActivity() const {
+ return _nuclide_data.getAlphaActivity();
+ }
+ // The beta fraction of the activity (Bq)
+ virtual double getBetaActivity() const {
+ return _nuclide_data.getBetaActivity();
+ }
+ // The gamma fraction of the activity (Bq)
+ virtual double getGammaActivity() const {
+ return _nuclide_data.getGammaActivity();
+ }
+ // The total heat (kW)
+ virtual double getTotalHeat() const { return _nuclide_data.getTotalHeat(); }
+ // The alpha heat (kW)
+ virtual double getAlphaHeat() const { return _nuclide_data.getAlphaHeat(); }
+ // The beta heat (kW)
+ virtual double getBetaHeat() const { return _nuclide_data.getBetaHeat(); }
+ // The gamma heat (kW)
+ virtual double getGammaHeat() const { return _nuclide_data.getGammaHeat(); }
+ // The dose rate (Sv/hr)
+ virtual double getDoseRate() const { return _nuclide_data.getDoseRate(); }
+ // The ingestion (Sv)
+ virtual double getIngestion() const { return _nuclide_data.getIngestion(); }
+ // The inhalation (Sv)
+ virtual double getInhalation() const { return _nuclide_data.getInhalation(); }
+
+ // virtual double
+ // getQuantity(nuclide_quantities::NuclideQuantitiesEnum quantity) const {
+ // switch (quantity) {
+ // case (nuclide_quantities::ATOMS):
+ // return getAtoms();
+ // case (nuclide_quantities::GRAMS):
+ // return getGrams();
+ // case (nuclide_quantities::ACTIVITY):
+ // return getActivity();
+ // case (nuclide_quantities::ALPHA_ACTIVITY):
+ // return getAlphaActivity();
+ // case (nuclide_quantities::BETA_ACTIVITY):
+ // return getBetaActivity();
+ // case (nuclide_quantities::GAMMA_ACTIVITY):
+ // return getGammaActivity();
+ // case (nuclide_quantities::TOTAL_HEAT):
+ // return getTotalHeat();
+ // case (nuclide_quantities::ALPHA_HEAT):
+ // return getAlphaHeat();
+ // case (nuclide_quantities::BETA_HEAT):
+ // return getBetaHeat();
+ // case (nuclide_quantities::GAMMA_HEAT):
+ // return getGammaHeat();
+ // case (nuclide_quantities::DOSE):
+ // return getDoseRate();
+ // default:
+ // throw std::invalid_argument(
+ // "Invalid quantity requested from FISPACT nuclide inventory");
+ // }
+ // }
+
+private:
+ fispact::OutputNuclideData _nuclide_data;
+};
+
+// IFispactInputData
+class IFispactInputData : public IFispactInputDataBase {
+
+public:
+ IFispactInputData(fispact::FispactMonitor &monitor)
+ : IFispactInputDataBase(), _monitor(monitor), _input(_monitor) {}
+
+ virtual void setFlux(const std::vector &flux_energy_groups,
+ const std::vector &flux) {
+ _input.setFlux(flux_energy_groups, flux);
+ }
+
+ virtual void setFluxWallLoading(double wall_loading) {
+ _input.setFluxWallLoading(wall_loading);
+ }
+
+ virtual void setFluxName(std::string flux_name) {
+ _input.setFluxName(flux_name);
+ }
+
+ virtual void setExcludeXrays(bool enable) { _input.setExcludeXrays(enable); }
+
+ virtual void setDensity(double density) { _input.setDensity(density); }
+
+ virtual void setMassTotal(double total_mass) {
+ _input.setMassTotal(total_mass);
+ }
+
+ virtual void setMass(const std::vector &atomicnumbers,
+ const std::vector &percentages) {
+ _input.setMass(atomicnumbers, percentages);
+ }
+
+ virtual void setFuel(const std::vector &zais,
+ const std::vector &values) {
+ _input.setFuel(zais, values);
+ }
+
+ virtual void setSchedule(const std::vector &deltatime,
+ const std::vector &fluxamp) {
+ _input.setSchedule(deltatime, fluxamp);
+ }
+
+ virtual std::pair, std::vector> getSchedule() {
+ return _input.getSchedule();
+ }
+
+ virtual void setAtomsThreshold(double threshold) {
+ _input.setAtomsThreshold(threshold);
+ }
+
+ virtual void setSolverTolerance(double rtol, double atol) {
+ _input.setSolverTolerance(rtol, atol);
+ }
+
+ fispact::InputData &getInput() { return _input; };
+
+private:
+ fispact::FispactMonitor &_monitor;
+ fispact::InputData _input;
+};
+//~IFispactInputData
+
+// IFispactOutputData
+class IFispactOutputData : public IFispactOutputDataBase {
+
+public:
+ IFispactOutputData(fispact::FispactMonitor &monitor)
+ : IFispactOutputDataBase(), _monitor(monitor), _output(_monitor) {}
+
+ virtual std::vector getGammaSpectrumBins(int inv_index) {
+ return _output.getGammaSpectrumBins(inv_index);
+ };
+
+ virtual std::vector getGammaSpectrumBoundaries(int inv_index) {
+ return _output.getGammaSpectrumBoundaries(inv_index);
+ };
+
+ virtual std::vector>
+ getInventoryNuclides(int inventory_index) {
+
+ std::vector fispact_nuclide_data =
+ _output.getInventoryNuclides(inventory_index);
+
+ std::vector> nuclide_data;
+ nuclide_data.reserve(fispact_nuclide_data.size());
+
+ for (fispact::OutputNuclideData &nuclide : fispact_nuclide_data) {
+ nuclide_data.push_back(
+ std::make_unique(nuclide));
+ }
+ return nuclide_data;
+ }
+
+ fispact::OutputData &getOutput() { return _output; };
+
+ virtual std::pair, std::vector>
+ getSortedInventory(int inv_index,
+ inventory_outputs::InventoryOutputsEnum key) const {
+
+ return _output.getSortedInventory(inv_index, convertFispactEnum(key));
+ }
+
+ virtual double
+ getInventoryValue(int inv_index,
+ inventory_outputs::InventoryOutputsEnum key) {
+
+ if (key != inventory_outputs::INVENTORY_DOSE_RATE) {
+ return _output.getInventoryValue(inv_index, convertFispactEnum(key));
+ }
+ return _output.getInventoryDoseRate(inv_index).getDose();
+ }
+
+ virtual int findInventoryIndex(int inv_index, int zai) {
+ return _output.findInventoryIndex(inv_index, zai);
+ }
+
+ virtual bool findInventoryExists(int inv_index, int zai) {
+ return _output.findInventoryExists(inv_index, zai);
+ }
+
+private:
+ fispact::FispactMonitor &_monitor;
+ fispact::OutputData _output;
+};
+//~IFispactOutputData
+
+class IFispactUtils : public IFispactUtilsBase {
+
+public:
+ IFispactUtils(fispact::FispactMonitor &monitor)
+ : IFispactUtilsBase(), _monitor(monitor) {
+
+ _neutron_energy_groups_map[709] = fispact::groups::G709();
+ _neutron_energy_groups_map[1102] = fispact::groups::G1102();
+
+ _photon_energy_groups_map[22] = {0.0, 1.0e4, 1.0e5, 2.0e5, 4.0e5, 1.0e6,
+ 1.5e6, 2.0e6, 2.5e6, 3.0e6, 3.5e6, 4.0e6,
+ 4.5e6, 5.0e6, 5.5e6, 6.0e6, 6.5e6, 7.0e6,
+ 7.5e6, 8.0e6, 1.0e7, 1.2e7, 1.4e7};
+ _photon_energy_groups_map[24] = {
+ 1.000e-11, 1.000e+4, 2.000e+4, 5.000e+4, 1.000e+5, 2.000e+5, 3.000e+5,
+ 4.000e+5, 6.000e+5, 8.000e+5, 1.000e+6, 1.220e+6, 1.440e+6, 1.660e+6,
+ 2.000e+6, 2.500e+6, 3.000e+6, 4.000e+6, 5.000e+6, 6.500e+6, 8.000e+6,
+ 1.000e+7, 1.200e+7, 1.400e+7, 2.000e+7};
+ }
+
+ virtual int GetZai(std::string nuclidename) {
+ return fispact::util::GetZai(_monitor, nuclidename);
+ }
+
+ virtual std::string getNuclideName(int zai) {
+ return fispact::util::GetNuclideName(_monitor, zai);
+ }
+
+ virtual int GetAtomicNumberFromElementName(std::string elementname) {
+ return fispact::util::GetAtomicNumberFromElementName(_monitor, elementname);
+ }
+
+ virtual std::vector getNeutronEnergyBounds(size_t n_bins) {
+ return _neutron_energy_groups_map[n_bins];
+ }
+
+ virtual std::vector getPhotonEnergyBounds(size_t n_bins) {
+ return _photon_energy_groups_map[n_bins];
+ }
+
+ virtual std::vector
+ GroupConvertByEnergy(const std::vector &inbounds,
+ const std::vector &invals,
+ const std::vector &outbounds) {
+ return fispact::groupconvert::GroupConvertByEnergy(_monitor, inbounds,
+ invals, outbounds);
+ }
+
+ virtual std::vector
+ GroupConvertByLethargy(const std::vector &inbounds,
+ const std::vector &invals,
+ const std::vector &outbounds) {
+ return fispact::groupconvert::GroupConvertByLethargy(_monitor, inbounds,
+ invals, outbounds);
+ }
+
+private:
+ fispact::FispactMonitor &_monitor;
+ std::unordered_map> _neutron_energy_groups_map;
+ std::unordered_map> _photon_energy_groups_map;
+};
+
+class FispactContext : public FispactContextBase {
+public:
+ FispactContext() : FispactContextBase(), _monitor("log_name"), _nd(_monitor) {
+
+ _i_input_data = std::make_unique(_monitor);
+ _i_output_data = std::make_unique(_monitor);
+ _i_utils = std::make_unique(_monitor);
+ }
+
+ virtual void globalInitialise() { fispact::GlobalInitialise(_monitor); }
+
+ virtual void globalFinalise() { fispact::GlobalFinalise(_monitor); }
+
+ virtual void process() {
+ auto *real_input = dynamic_cast(_i_input_data.get());
+ auto *real_output =
+ dynamic_cast(_i_output_data.get());
+ fispact::InputData &input = real_input->getInput();
+ fispact::OutputData &output = real_output->getOutput();
+ fispact::Process(input, _nd, output, _monitor, process_callback);
+ }
+
+ virtual size_t getNuclearDataCrossSections() {
+ return _nd.getReactionXS(0, 0).size();
+ }
+ virtual void setNuclearData(
+ std::unordered_map nuclear_data_paths) {
+
+ fispact::io::NuclearDataReader nd_reader(_monitor);
+
+ for (auto &[data, path] : nuclear_data_paths) {
+ if (data == "ND_IND_NUC_KEY") {
+ nd_reader.setPath(FISPACT_ND_IND_NUC_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_HAZARDS_KEY") {
+ nd_reader.setPath(FISPACT_ND_HAZARDS_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_ABSORP_KEY") {
+
+ nd_reader.setPath(FISPACT_ND_ABSORP_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_CLEAR_KEY") {
+
+ nd_reader.setPath(FISPACT_ND_CLEAR_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_A2DATA_KEY") {
+ nd_reader.setPath(FISPACT_ND_A2DATA_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_ENBINS_KEY") {
+ nd_reader.setPath(FISPACT_ND_ENBINS_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_DECAY_KEY") {
+ nd_reader.setPath(FISPACT_ND_DECAY_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_DK_ENDF_KEY") {
+ nd_reader.setPath(FISPACT_ND_DK_ENDF_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_PROB_TAB_KEY") {
+ nd_reader.setPath(FISPACT_ND_PROB_TAB_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_ASSCFY_KEY") {
+ nd_reader.setPath(FISPACT_ND_ASSCFY_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_FISSYLD_KEY") {
+ nd_reader.setPath(FISPACT_ND_FISSYLD_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_FY_ENDF_KEY") {
+ nd_reader.setPath(FISPACT_ND_FY_ENDF_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_SF_ENDF_KEY") {
+ nd_reader.setPath(FISPACT_ND_SF_ENDF_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_SP_ENDF_KEY") {
+ nd_reader.setPath(FISPACT_ND_SP_ENDF_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_XS_EXTRA_KEY") {
+ nd_reader.setPath(FISPACT_ND_XS_EXTRA_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_CROSSEC_KEY") {
+ nd_reader.setPath(FISPACT_ND_CROSSEC_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_CROSSUNC_KEY") {
+ nd_reader.setPath(FISPACT_ND_CROSSUNC_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_XS_ENDF_KEY") {
+ nd_reader.setPath(FISPACT_ND_XS_ENDF_KEY, path);
+ continue;
+ }
+
+ if (data == "ND_XS_ENDFB_KEY") {
+ nd_reader.setUseXSBinary(true);
+ nd_reader.setPath(FISPACT_ND_XS_ENDFB_KEY, path);
+ continue;
+ }
+ }
+ // Load the nuclear data
+ nd_reader.load(_nd, load_callback);
+ }
+
+ static void load_callback(std::string key, std::string path, int i, int t) {
+ std::cout << "\33[2K\r" << key << ": " << path << " [" << i << "/" << t
+ << "]" << std::flush;
+ }
+
+ /**
+ *
+ *
+ *
+ */
+ static void process_callback(std::string process_name, int i, int t) {
+ std::cout << "\33[2K\r [" << i << "/" << t << "] " << process_name
+ << std::flush;
+ }
+
+private:
+ fispact::FispactMonitor _monitor;
+ fispact::NuclearData _nd;
+};
diff --git a/include/fispact/factory/FispactFactory.h b/include/fispact/factory/FispactFactory.h
new file mode 100644
index 0000000..03171d6
--- /dev/null
+++ b/include/fispact/factory/FispactFactory.h
@@ -0,0 +1,5 @@
+#pragma once
+#include "FispactContextBase.h"
+#include
+
+std::unique_ptr createFispactContext();
diff --git a/include/fispact/interface/FispactContextBase.h b/include/fispact/interface/FispactContextBase.h
new file mode 100644
index 0000000..9b61865
--- /dev/null
+++ b/include/fispact/interface/FispactContextBase.h
@@ -0,0 +1,178 @@
+#pragma once
+#include "FizzyEnums.h"
+#include
+#include
+#include
+
+class FispactOutputNuclideDataBase {
+public:
+ virtual ~FispactOutputNuclideDataBase() = default;
+
+ virtual std::string getElement() const = 0;
+
+ virtual std::string getState() const = 0;
+
+ virtual int getIsotope() const = 0;
+
+ virtual int getZAI() const = 0;
+
+ // The half life (s)
+ virtual double getHalfLife() const = 0;
+ // The number of atoms
+ virtual double getAtoms() const = 0;
+ // The grams (g)
+ virtual double getGrams() const = 0;
+ // The activity (Bq)
+ virtual double getActivity() const = 0;
+ // The alpha fraction of the activity (Bq)
+ virtual double getAlphaActivity() const = 0;
+ // The beta fraction of the activity (Bq)
+ virtual double getBetaActivity() const = 0;
+ // The gamma fraction of the activity (Bq)
+ virtual double getGammaActivity() const = 0;
+ // The total heat (kW)
+ virtual double getTotalHeat() const = 0;
+ // The alpha heat (kW)
+ virtual double getAlphaHeat() const = 0;
+ // The beta heat (kW)
+ virtual double getBetaHeat() const = 0;
+ // The gamma heat (kW)
+ virtual double getGammaHeat() const = 0;
+ // The dose rate (Sv/hr)
+ virtual double getDoseRate() const = 0;
+ // The ingestion (Sv)
+ virtual double getIngestion() const = 0;
+ // The inhalation (Sv)
+ virtual double getInhalation() const = 0;
+
+ virtual double
+ getQuantity(nuclide_quantities::NuclideQuantitiesEnum quantity) const {
+
+ switch (quantity) {
+ case (nuclide_quantities::ATOMS):
+ return getAtoms();
+ case (nuclide_quantities::GRAMS):
+ return getGrams();
+ case (nuclide_quantities::ACTIVITY):
+ return getActivity();
+ case (nuclide_quantities::ALPHA_ACTIVITY):
+ return getAlphaActivity();
+ case (nuclide_quantities::BETA_ACTIVITY):
+ return getBetaActivity();
+ case (nuclide_quantities::GAMMA_ACTIVITY):
+ return getGammaActivity();
+ case (nuclide_quantities::TOTAL_HEAT):
+ return getTotalHeat();
+ case (nuclide_quantities::ALPHA_HEAT):
+ return getAlphaHeat();
+ case (nuclide_quantities::BETA_HEAT):
+ return getBetaHeat();
+ case (nuclide_quantities::GAMMA_HEAT):
+ return getGammaHeat();
+ case (nuclide_quantities::DOSE):
+ return getDoseRate();
+ default:
+ throw std::invalid_argument(
+ "Invalid quantity requested from FISPACT nuclide inventory");
+ }
+ }
+
+private:
+};
+
+class IFispactInputDataBase {
+public:
+ virtual void setFlux(const std::vector &flux_energy_groups,
+ const std::vector &flux) = 0;
+
+ virtual void setFluxWallLoading(double wall_loading) = 0;
+
+ virtual void setExcludeXrays(bool enable) = 0;
+
+ virtual void setFluxName(std::string flux_name) = 0;
+
+ virtual void setDensity(double density) = 0;
+
+ virtual void setMassTotal(double total_mass) = 0;
+
+ virtual void setMass(const std::vector &atomicnumbers,
+ const std::vector &percentages) = 0;
+
+ virtual void setFuel(const std::vector &zais,
+ const std::vector &values) = 0;
+
+ virtual void setSchedule(const std::vector &deltatime,
+ const std::vector &fluxamp) = 0;
+
+ virtual std::pair, std::vector> getSchedule() = 0;
+
+ virtual void setAtomsThreshold(double threshold) = 0;
+
+ virtual void setSolverTolerance(double rtol, double atol) = 0;
+};
+
+class IFispactOutputDataBase {
+public:
+ virtual std::vector getGammaSpectrumBins(int inv_index) = 0;
+
+ virtual std::vector getGammaSpectrumBoundaries(int inv_index) = 0;
+
+ virtual std::vector>
+ getInventoryNuclides(int inventory_index) = 0;
+
+ virtual std::pair, std::vector>
+ getSortedInventory(int inv_index,
+ inventory_outputs::InventoryOutputsEnum key) const = 0;
+
+ virtual double
+ getInventoryValue(int inv_index,
+ inventory_outputs::InventoryOutputsEnum key) = 0;
+
+ virtual int findInventoryIndex(int inv_index, int zai) = 0;
+
+ virtual bool findInventoryExists(int inv_index, int zai) = 0;
+};
+
+class IFispactUtilsBase {
+public:
+ virtual int GetZai(std::string nuclidename) = 0;
+
+ virtual std::string getNuclideName(int zai) = 0;
+
+ virtual int GetAtomicNumberFromElementName(std::string elementname) = 0;
+
+ virtual std::vector getNeutronEnergyBounds(size_t n_groups) = 0;
+
+ virtual std::vector getPhotonEnergyBounds(size_t n_groups) = 0;
+
+ virtual std::vector
+ GroupConvertByEnergy(const std::vector &inbounds,
+ const std::vector &invals,
+ const std::vector &outbounds) = 0;
+
+ virtual std::vector
+ GroupConvertByLethargy(const std::vector &inbounds,
+ const std::vector &invals,
+ const std::vector &outbounds) = 0;
+};
+
+class FispactContextBase {
+public:
+ virtual void globalInitialise() = 0;
+ virtual void globalFinalise() = 0;
+ virtual void process() = 0;
+ // virtual void hasFatal() = 0;
+
+ virtual void setNuclearData(
+ std::unordered_map nuclear_data_paths) = 0;
+
+ virtual size_t getNuclearDataCrossSections() = 0;
+ virtual IFispactInputDataBase &getInput() { return *_i_input_data; }
+ virtual IFispactOutputDataBase &getOutput() { return *_i_output_data; }
+ virtual IFispactUtilsBase &getUtils() { return *_i_utils; }
+
+protected:
+ std::unique_ptr _i_input_data;
+ std::unique_ptr _i_output_data;
+ std::unique_ptr _i_utils;
+};
diff --git a/include/postprocessors/ElementPhotonEmission.h b/include/postprocessors/ElementPhotonEmission.h
new file mode 100644
index 0000000..e64ed3d
--- /dev/null
+++ b/include/postprocessors/ElementPhotonEmission.h
@@ -0,0 +1,20 @@
+#pragma once
+#include "FispactPostprocessor.h"
+
+class ElementPhotonEmission : public FispactPostprocessor {
+
+public:
+ static InputParameters validParams();
+
+ ElementPhotonEmission(const InputParameters ¶ms);
+
+ virtual void initialize();
+ virtual void execute();
+ virtual void finalize();
+
+ virtual PostprocessorValue getValue() const;
+
+ std::vector _element_ids;
+
+ Real _sum;
+};
diff --git a/include/postprocessors/FispactElementPostprocessor.h b/include/postprocessors/FispactElementPostprocessor.h
new file mode 100644
index 0000000..bf26144
--- /dev/null
+++ b/include/postprocessors/FispactElementPostprocessor.h
@@ -0,0 +1,30 @@
+#pragma once
+#include "ElementPostprocessor.h"
+#include "InputParameters.h"
+#include "UserObject.h"
+
+// Forward dec
+class FispactProblem;
+
+class FispactElementPostprocessor : public ElementPostprocessor {
+
+public:
+ static InputParameters validParams() {
+ InputParameters params = ElementPostprocessor::validParams();
+ return params;
+ };
+
+ FispactElementPostprocessor(const InputParameters ¶ms);
+
+ virtual void initialize() = 0;
+ virtual void execute() = 0;
+ virtual void finalize() = 0;
+ virtual void threadJoin(const UserObject &y) = 0;
+
+ virtual PostprocessorValue getValue() const = 0;
+
+ FispactProblem &getFispactProblem();
+
+protected:
+ FispactProblem &_fispact_problem;
+};
diff --git a/include/postprocessors/FispactInventoryMetric.h b/include/postprocessors/FispactInventoryMetric.h
new file mode 100644
index 0000000..32d7c91
--- /dev/null
+++ b/include/postprocessors/FispactInventoryMetric.h
@@ -0,0 +1,31 @@
+#pragma once
+#include "FispactElementPostprocessor.h"
+#include "FizzyEnums.h"
+#include "UserObject.h"
+
+class FispactInventoryMetric : public FispactElementPostprocessor {
+
+public:
+ static InputParameters validParams();
+
+ FispactInventoryMetric(const InputParameters ¶ms);
+
+ virtual void initialize();
+ virtual void execute();
+ virtual void finalize();
+
+ virtual void threadJoin(const UserObject &y);
+
+ virtual PostprocessorValue getValue() const;
+
+ Real _sum;
+
+ inventory_outputs::InventoryOutputsEnum _metric;
+
+ /**
+ * Because sieverts is a specific quantity, if we want the total dose rate of
+ * a set of elements spanning multiple materials, we need to track the
+ * total_mass
+ */
+ double _total_mass;
+};
diff --git a/include/postprocessors/FispactNuclideMetric.h b/include/postprocessors/FispactNuclideMetric.h
new file mode 100644
index 0000000..ac0d4e7
--- /dev/null
+++ b/include/postprocessors/FispactNuclideMetric.h
@@ -0,0 +1,33 @@
+#pragma once
+#include "FispactElementPostprocessor.h"
+#include "FizzyEnums.h"
+#include "UserObject.h"
+
+class FispactNuclideMetric : public FispactElementPostprocessor {
+
+public:
+ static InputParameters validParams();
+
+ FispactNuclideMetric(const InputParameters ¶ms);
+
+ virtual void initialize();
+ virtual void execute();
+ virtual void finalize();
+
+ virtual void threadJoin(const UserObject &y);
+
+ virtual PostprocessorValue getValue() const;
+
+ Real _sum;
+
+ std::vector _nuclides;
+
+ nuclide_quantities::NuclideQuantitiesEnum _metric;
+
+ /**
+ * Because sieverts is a specific quantity, if we want the total dose rate of
+ * a set of elements spanning multiple materials, we need to track the
+ * total_mass
+ */
+ double _total_mass;
+};
diff --git a/include/postprocessors/FispactPostprocessor.h b/include/postprocessors/FispactPostprocessor.h
new file mode 100644
index 0000000..66b9bea
--- /dev/null
+++ b/include/postprocessors/FispactPostprocessor.h
@@ -0,0 +1,28 @@
+#pragma once
+#include "GeneralPostprocessor.h"
+#include "InputParameters.h"
+
+// Forward dec
+class FispactProblem;
+
+class FispactPostprocessor : public GeneralPostprocessor {
+
+public:
+ static InputParameters validParams() {
+ InputParameters params = GeneralPostprocessor::validParams();
+ return params;
+ };
+
+ FispactPostprocessor(const InputParameters ¶ms);
+
+ virtual void initialize() = 0;
+ virtual void execute() = 0;
+ virtual void finalize() = 0;
+
+ virtual PostprocessorValue getValue() const = 0;
+
+ FispactProblem &getFispactProblem();
+
+protected:
+ FispactProblem &_fispact_problem;
+};
diff --git a/include/postprocessors/SubdomainPhotonEmission.h b/include/postprocessors/SubdomainPhotonEmission.h
new file mode 100644
index 0000000..1e11aa7
--- /dev/null
+++ b/include/postprocessors/SubdomainPhotonEmission.h
@@ -0,0 +1,20 @@
+#pragma once
+#include "BlockRestrictable.h"
+#include "FispactPostprocessor.h"
+
+class SubdomainPhotonEmission : public FispactPostprocessor,
+ public BlockRestrictable {
+
+public:
+ static InputParameters validParams();
+
+ SubdomainPhotonEmission(const InputParameters ¶ms);
+
+ virtual void initialize();
+ virtual void execute();
+ virtual void finalize();
+
+ virtual PostprocessorValue getValue() const;
+
+ Real _sum;
+};
diff --git a/include/problems/FispactProblem.h b/include/problems/FispactProblem.h
index 124da28..ca3b75a 100644
--- a/include/problems/FispactProblem.h
+++ b/include/problems/FispactProblem.h
@@ -1,74 +1,163 @@
#pragma once
+
#include "ExternalProblem.h"
-#include "fispactcompute.hpp"
-#include "fispactelementaldata.hpp"
-#include "fispactgroupconvert.hpp"
-#include "fispactgroupstructures.hpp"
-#include "fispactinputdata.hpp"
-#include "fispactnucleardata.hpp"
-#include "fispactoutputdata.hpp"
-#include "fispactutil.hpp"
-#include
+#include "FispactContextBase.h"
+#include "FispactFactory.h"
+#include "FispactFluxInput.h"
+#include "FispactMaterial.h"
+#include "FispactNuclearDataPaths.h"
+#include "FispactSchedule.h"
+#include "PhotonSpectra.h"
+
+// Include for interprocess communication data structure
+#include "HDF5Utils.h"
+#include "PhotonSharingData.h"
+#include
#include
+#include
+#include
-// Use fp as short for fispact
-namespace fp = fispact;
+#ifdef LIBMESH_HAVE_BOOST
+namespace bi = boost::interprocess;
+#endif
class FispactProblem : public ExternalProblem {
- /// Struct to store Material definitions
- struct MaterialDefinition {
- std::string _mat_name;
- std::vector> _mat_atomic_composition;
- double _mat_density;
- };
public:
- // Constructor for FispactProblem
FispactProblem(const InputParameters ¶ms);
+ ~FispactProblem();
+
static InputParameters validParams();
- // virtual void initialSetup() override;
+ virtual void initialSetup() override;
+
virtual void externalSolve() override;
virtual void syncSolutions(ExternalProblem::Direction direction) override;
virtual bool converged(unsigned int) override { return true; }
-private:
- static void load_callback(std::string key, std::string path, int i, int t) {
- std::cout << "\33[2K\r" << key << ": " << path << " [" << i << "/" << t
- << "]" << std::flush;
+ void timestepSetup() override;
+
+ /**
+ *
+ * Calculates the total strength of one elements photon source term
+ * @param[in] element a ptr to the libmesh element whose strength we are
+ * calculating
+ * @param[in] element_flux the vector representing the energy binned photon
+ * flux for the relevent mesh element
+ * @return the total strength of the photon source term for this element
+ *
+ */
+ double calculateElementStrength(const std::vector element_flux);
+ /**
+ *
+ */
+ bool isFlux(const std::vector &flux) const;
+
+ ///
+ const FispactMaterial &getElementMaterial(const dof_id_type &elem_id);
+
+ void setPhotonBins(const std::vector &photon_bins);
+
+ /**
+ * Converts FISPACT gamma spectra outputs from MeV s^-1 to cm^-3 s^-1
+ * @param[in] photon_energy_spectra_ev Photon energy spectra as output by
+ * FISPACT
+ * @param[out] photon_energy_spectra_per_cc_s Photon energy spectra in
+ * photons/cc-s
+ */
+ void
+ convertGammaEvToCount(const std::vector &photon_energy_spectra_ev,
+ std::vector &photon_energy_spectra_per_cc_s);
+
+ std::unordered_map &getLocalElemIndexMap() {
+ return _local_elem_index;
}
- static void process_callback(std::string process_name, int i, int t) {
- std::cout << "\33[2K\r [" << i << "/" << t << "] " << process_name
- << std::flush;
+ PhotonSpectra *getPhotonSpectra() const {
+ return _photon_energy_spectra.get();
}
- void setNuclearData(std::string nd_base_path);
+ const FispactSchedule &getSchedule() const {
+ if (hasUserObject(_fp_schedule_uo_name)) {
+ return getUserObject(_fp_schedule_uo_name);
+ }
+ mooseError("FispactSchedule UserObject has not been instantiated.");
+ }
- /// Read a neutron flux spectra from a hdf5 file
- std::vector readNeutronFluxFromHDF5(const std::string &filename);
+ size_t getFispactInventoryIndexFromTime();
- /// Write output photon flux to HDF5
- void writePhotonFluxToHDF5(const std::string &filename,
- fp::OutputData &fispact_output);
+ const double getOutputInventoryTime() const { return _output_inventory_time; }
- void writePhotonFluxBins(hid_t file_id, fp::OutputData &fispact_output);
+ const std::unordered_map &getMolarMassMap() {
+ return _molar_mass_map;
+ }
- void setFispactInputData(fp::FispactMonitor &monitor, fp::InputData &input,
- MaterialDefinition &material,
- std::vector &neutron_flux,
- const std::vector &bins, double volume);
+ const double avogadroNumber() const;
- /// Generate a log file name for the fispact logs
- std::string fispactLogName();
+ const FispactContextBase *getFpContext() const { return _fp_ctxt.get(); }
+
+ /**
+ * Load in molar mass data from HDF5 file set using input params
+ */
+ void loadMolarMasses();
- // Initialise FISPACT monitor object
- void initFispactMonitor(std::string);
+ void callFispactFactory();
- void readNeutronFluxFromHDF5(std::string filename, std::string tally_dir);
+ /**
+ * Set the nuclear data for FISPACT
+ * @param[in] nd_base_path The directory containing the various nuclear data
+ * resources required for fispact
+ *
+ */
+ void setNuclearData();
+ /**
+ * Method to write calculated photon flux to a HDF5 file, primarily for
+ * debugging purposes.
+ * @param[in] filename the name of the resulting HDF5 file containing the
+ * photon flux
+ *
+ */
+ void writePhotonFlux(const std::string &filename,
+ const std::vector &inventory_times);
+
+ /**
+ * Method used within @ref writePhotonFlux to write the photon energy bins
+ * used by FISPACT to the same HDF5 file
+ * @param[in] file_id the HDF5 file identifier for the file we are writing to
+ * @param[in] photon_bins a vector of doubles containing the photon energy
+ * bins used
+ * @param[in] parallel indicates whether or not to use the parallel HDF5
+ * driver
+ */
+ void writePhotonFluxBins(const hid_t &file_id, const bool parallel);
+
+ /**
+ *
+ * Method used to set input parameters for a FISPACT activation calculation
+ * @param[in] monitor the FISPACT monitor object required by all FISPACT
+ * methods
+ * @param[in] material the material definition for the FISPACT calculation
+ * @param[in] neutron_flux the energy binned neutron flux
+ * @param[in] bins the energy bin boundaries for neutron flux
+ * @param[in] volume the volume in m^3 for the mesh element this FISPACT
+ * calculation corresponds to
+ * @param[out] input the now correctly setup FISPACT input object
+ */
+ void setFispactInputData(const FispactMaterial &material,
+ const std::vector &neutron_flux,
+ const double &volume,
+ IFispactInputDataBase &input) const;
+
+ /// Generate a log file name for the fispact logs
+ std::string fispactLogName();
+
+ /**
+ *
+ *
+ */
void read_material_xml_data();
/**
@@ -77,74 +166,208 @@ class FispactProblem : public ExternalProblem {
* start as opposed to running into a subdomain lacking a material half way
* through the solve.
*/
- void checkMaterialsExist();
+ void checkMaterialsExist() const;
/**
* Retrieve Fispact radiation schedule from FispactSchedule UserObject
*/
- void setFispactSchedule(fp::InputData &input);
+ void setFispactSchedule(IFispactInputDataBase &input, const double &volume,
+ const double &neutron_flux_sum) const;
- void convertGammaEvToCount(fp::InputData &input,
- const std::vector &photon_spectra,
- const std::vector &photon_flux_bins,
- std::vector &photons_per_cc_per_s);
+ /**
+ *
+ */
+ void insertElementStrength(const int inv_index, const libMesh::Elem *element,
+ const std::vector element_flux);
- void printInventoryByHeat(fp::OutputData &output, int timestep_index,
- std::ostream &stream = std::cout);
+ /**
+ *
+ */
+ void calculateLocalDomainStrength();
- void printInventoryByMass(fp::OutputData &output, int timestep_index,
- std::ostream &stream);
+ /**
+ *
+ */
+ void getTotalDomainStrength();
- void printInvData(fp::OutputData &output, std::ostream &stream);
+ /**
+ *
+ */
+ void resolveFispactUserObjects();
- double extractHalflifeFromNuc(fp::NuclearData &nuclear_data, int zai);
+ /**
+ * Check if neutron group structure is consistent between the passed in flux
+ * data and the read in nuclear data
+ */
+ void checkForEnergyGroupConsistency();
- bool isFlux(int elem_id);
+ /**
+ *
+ */
+ std::vector &getNeutronBins() {
+ if (_flux_energy_groups.empty()) {
+ mooseError("_flux_energy_groups not set, so could not be gotten");
+ }
+ return _flux_energy_groups;
+ }
- /// FISPACT monitor
- fp::FispactMonitor _fp_monitor;
+ /**
+ * Return a vector populated with the number of atoms of each isotope in a
+ * given material
+ */
+ std::vector getMaterialAtoms(const FispactMaterial &material);
- /// FISPACT nuclear data
- fp::NuclearData _fp_nuclear_data;
+ /**
+ * Method to calculate the number of atoms in a given mass of substance
+ */
+ double getNumAtoms(const double &mass, const double &molar_mass,
+ const double &avogadro) const;
+
+ /**
+ *
+ */
+ std::vector &getPhotonBins() {
+ if (_photon_bins.empty()) {
+ mooseError("_photon_bins not set, so could not be gotten");
+ }
+ return _photon_bins;
+ }
+
+ size_t photonEnergySpectraIdx(size_t inv_idx, dof_id_type elem_id) {
+ return ((inv_idx * (_mesh.nActiveLocalElem() * _n_photon_bins)) +
+ (_local_elem_index[elem_id] * _n_photon_bins));
+ }
+
+ /**
+ *
+ */
+ int calculateMemorySize();
+
+ void convertFluxEnergyGroups(std::vector &flux,
+ const std::vector &input_energy_groups);
+ /**
+ * Method to generate name of the interprocess memory segment generated by
+ * this MPI rank
+ * @param[out] ipc_name Reference to the string we want to populate
+ */
+ const std::string generateInterprocessName();
+
+protected:
+ /// -- Interprocess bits --
+#ifdef LIBMESH_HAVE_BOOST
+ bi::managed_shared_memory _segment;
+
+ PhotonSharingData *_photon_sharing_instance;
+#endif
+
+ std::unique_ptr _fp_ctxt;
/// FISPACT neutron flux
std::unordered_map> _neutron_fluxes;
- // FISPACT Photon fluxes
- std::unordered_map> _photon_fluxes;
+ /// FISPACT Photon fluxes
+ /// Indexed by time major, element id minor
+ // std::vector _photon_energy_spectra;
- /// hdf5 filename for neutron flux
- std::string _neutron_flux_filename;
+ std::unique_ptr _photon_energy_spectra;
- /// path to neutron flux array in hdf5 file
- std::string _neutron_flux_hdf5_path;
+ /// Vector to store all local element strengths over all inventory times
+ /// Indexed by time major, element id minor
+ std::vector _element_strengths;
/// hdf5 filename for photon flux
std::string _photon_flux_filename;
- ///
bool _materials_from_xml;
- /// Boolean to determine whether a rank is still running FISPACT calculations
- bool _calculating = true;
-
/// Filename of xml file to read materials from
std::string _materials_xml_file;
- /// Mappings from material name to material definitions
- std::unordered_map _mat_definitions;
-
- MaterialDefinition &getElementMaterial(int &elem_id);
+ ///
+ // const size_t _input_neutron_bin_structure;
- std::string _neutron_bin_type;
+ ///
+ std::vector _flux_energy_groups;
- std::vector _neutron_bins;
+ ///
+ // std::vector _input_neutron_bins;
+ ///
std::vector _photon_bins;
- int _num_neutron_bins;
+ ///
+ // uint64_t _n_input_neutron_bins;
+
+ ///
+ uint64_t _n_photon_bins;
+
+ /// Number of FISPACT inventories
+ const size_t *_n_inventories;
+
+ /// Number of FISPACT solution inventories(ignoring initial conditions)
+ const size_t *_n_solution_inventories;
+
+ double _output_inventory_time;
+
+ ///
+ UserObjectName _fp_schedule_uo_name;
+
+ ///
+ UserObjectName _fp_flux_uo_name = NULL;
+
+ /// Fispact nuclear data path
+ UserObjectName _fp_nuclear_data_uo_name;
+
+ FispactSchedule *_fp_schedule_uo = nullptr;
+
+ FispactNuclearDataPaths *_fp_nuclear_data_uo;
+
+ FispactFluxInput *_fp_flux_input_uo = nullptr;
+
+ std::vector _fp_fispact_materials;
+
+ /// Vector to store local domain strength over all inventory times
+ std::vector _local_domain_strength;
+
+ /// Vector to store local domain strength over all inventory times
+ std::vector _total_domain_strength;
+
+ ///
+ bool _write_photon_flux;
+
+ ///
+ bool _comm_photon_flux;
+
+ ///
+ bool _solved;
+
+ ///
+
+ ///
+ bool _convert_energy_groups = false;
+
+ bool _uniform;
+
+ /// name given to the interprocess memory segment generated by this rank
+ const std::string _interprocess_segment_name;
+
+ const std::string &_molar_mass_data_filename;
+
+ /// Map from element ZAI to molar mass (g/mol)
+ std::unordered_map _molar_mass_map;
+
+ /// Map from global element id to "local element id"
+ std::unordered_map _local_elem_index;
- std::string _schedule_uo_name;
+ /// Absolute tolerance for FISPACT solver
+ double _atol;
+ /// Relative tolerance for FISPACT solver
+ double _rtol;
- void setNeutronBins();
+ // std::unordered_map> _neutron_group_map = {
+ // {100, fp::groups::G100()},
+ // {709, fp::groups::G709()},
+ // {1102, fp::groups::G1102()}};
+ //
+ bool _exclude_xrays;
};
diff --git a/include/times/FispactScheduleTimes.h b/include/times/FispactScheduleTimes.h
new file mode 100644
index 0000000..e48c3eb
--- /dev/null
+++ b/include/times/FispactScheduleTimes.h
@@ -0,0 +1,21 @@
+#pragma once
+// Moose includes
+#include "FispactSchedule.h"
+#include "Times.h"
+
+/**
+ * Simple times from an input parameter
+ */
+class FispactScheduleTimes : public Times {
+public:
+ static InputParameters validParams();
+ FispactScheduleTimes(const InputParameters ¶meters);
+ virtual ~FispactScheduleTimes() = default;
+
+protected:
+ virtual void initialize() override {}
+
+ const FispactSchedule &_schedule;
+
+ std::vector _fispact_times;
+};
diff --git a/include/userobjects/FISPACTMaterial.h b/include/userobjects/FISPACTMaterial.h
deleted file mode 100644
index e774ba9..0000000
--- a/include/userobjects/FISPACTMaterial.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-#include "GeneralUserObject.h"
-
-class FISPACTMaterial : public GeneralUserObject
-{
-public:
- static InputParameters validParams();
-
- FISPACTMaterial(const InputParameters & params);
-
- virtual void initialize() {}
- virtual void finalize() {}
- virtual void execute() {}
-
-protected:
-
- // Nuclide names
- std::vector _nuclides;
-
- // List of nuclide proportions corresponding to each nuclide in the nuclide list
- std::vector _nuclide_proportion;
-
- // Density of the fispact material
- double _density;
-};
diff --git a/include/userobjects/FispactFluxInput.h b/include/userobjects/FispactFluxInput.h
new file mode 100644
index 0000000..3da9f1f
--- /dev/null
+++ b/include/userobjects/FispactFluxInput.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include "GeneralUserObject.h"
+#include "InputParameters.h"
+#include "UserObject.h"
+#include "libmesh/id_types.h"
+
+class FispactFluxInput : public GeneralUserObject {
+
+public:
+ static InputParameters validParams() {
+
+ InputParameters params = GeneralUserObject::validParams();
+
+ params.addRequiredParam("wall_loading", "");
+
+ return params;
+ }
+
+ FispactFluxInput(const InputParameters ¶meters)
+ : GeneralUserObject(parameters),
+ _wall_loading(getParam("wall_loading")) {}
+
+ virtual void initialize() {}
+ virtual void finalize() {}
+ virtual void execute() {}
+
+ virtual std::vector getElemFlux(dof_id_type elem_id) = 0;
+
+ virtual const std::vector &getFluxEnergyGroups() {
+ return _flux_energy_groups;
+ };
+
+ const size_t &getNumEnergyGroups() { return _n_bins; };
+
+ const double &getWallLoading() { return _wall_loading; };
+
+protected:
+ std::vector _flux_energy_groups;
+
+ size_t _n_bins;
+
+ double _wall_loading;
+};
diff --git a/include/userobjects/FispactInventoryManager.h b/include/userobjects/FispactInventoryManager.h
new file mode 100644
index 0000000..53c0351
--- /dev/null
+++ b/include/userobjects/FispactInventoryManager.h
@@ -0,0 +1,228 @@
+#pragma once
+
+#include "FispactContextBase.h"
+#include "FispactUserObject.h"
+#include "FizzyEnums.h"
+#include "InputParameters.h"
+#include "UserObject.h"
+#include "libmesh/id_types.h"
+#include
+#include
+
+class FispactInventoryManager : public FispactUserObject {
+public:
+ /// Forward declaration
+ class ElementInventory;
+
+ static InputParameters validParams();
+
+ FispactInventoryManager(const InputParameters ¶meters);
+
+ virtual void initialize() {}
+ virtual void finalize() {}
+ virtual void execute() {}
+
+ void registerNuclideMetricRequest(
+ const std::string &nuclide,
+ const nuclide_quantities::NuclideQuantitiesEnum metric,
+ const std::set &blocks);
+
+ void registerElementMetricRequest(
+ const inventory_outputs::InventoryOutputsEnum metric,
+ const std::set &blocks);
+
+ void extractInventoryData(FispactContextBase &fp_context, size_t elem_id);
+
+ double
+ getNuclideMetric(libMesh::dof_id_type elem_id, std::string &nuclide,
+ int inv_index,
+ nuclide_quantities::NuclideQuantitiesEnum metric) const;
+
+ double getElementMetric(libMesh::dof_id_type elem_id, int inv_index,
+ inventory_outputs::InventoryOutputsEnum metric) const;
+
+ void initialiseNuclearInventory();
+
+ ElementInventory &getElementInventory(size_t elem_id);
+
+ const ElementInventory &getElementInventory(size_t elem_id) const;
+
+protected:
+ /// Mapping from nuclide names to a vector containing the quantities to be
+ /// stored for that nuclide
+
+ std::unordered_map _nuclide_ids;
+
+ std::unordered_map _nuclide_names;
+
+ std::vector _element_inventories;
+
+ size_t _n_fispact_inventories;
+
+ size_t _max_nuclide_id = 0;
+
+public:
+ class NuclideInventory {
+ public:
+ NuclideInventory(
+ const std::string &nuclide_name, size_t n_inventories,
+ const std::vector
+ &quantities)
+ : _nuclide_name(nuclide_name), _n_inventories(n_inventories) {
+ for (auto &quantity : quantities) {
+ _metric_data[quantity] = std::vector(n_inventories, 0.0);
+ }
+
+ _n_metrics = _metric_data.size();
+ };
+
+ void addQuantity(nuclide_quantities::NuclideQuantitiesEnum quantity) {
+ // _quantities.push_back(quantity);
+ // _data.resize(_quantities.size() * _n_inventories);
+ _metric_data[quantity] = std::vector(_n_inventories, 0.0);
+ }
+
+ std::vector getQuantities() {
+ std::vector quantities;
+
+ for (auto &[quantity, value] : _metric_data) {
+ quantities.push_back(quantity);
+ }
+ return quantities;
+ }
+
+ double &getQuantity(nuclide_quantities::NuclideQuantitiesEnum quantity,
+ size_t inv_index) {
+
+ return _metric_data.at(quantity)[inv_index];
+
+ // return _data[(_quantities.size() * inv_index) +
+ // findQuantity(quantity)];
+ }
+
+ const double &
+ getQuantity(nuclide_quantities::NuclideQuantitiesEnum quantity,
+ size_t inv_index) const {
+
+ return _metric_data.at(quantity)[inv_index];
+ // return _data[(_quantities.size() * inv_index) +
+ // findQuantity(quantity)];
+ }
+
+ void setQuantity(nuclide_quantities::NuclideQuantitiesEnum quantity,
+ size_t inv_index, const double &value) {
+
+ _metric_data.at(quantity)[inv_index] = value;
+ // _data[(_quantities.size() * inv_index) + findQuantity(quantity)] =
+ // value;
+ }
+
+ size_t
+ findQuantity(nuclide_quantities::NuclideQuantitiesEnum quantity) const {
+ for (int i = 0; i < _quantities.size(); i++) {
+ if (quantity == _quantities[i]) {
+ return i;
+ }
+ }
+ throw std::runtime_error(
+ "Searching for nuclide quantity that is not stored.");
+ }
+
+ // double &operator()(size_t inv_index,
+ // nuclide_quantities::NuclideQuantitiesEnum quantity) {
+ // size_t quantity_id = findQuantity(quantity);
+ // return _data[(inv_index * _n_metrics) + quantity_id];
+ // }
+
+ protected:
+ std::string _nuclide_name;
+ size_t _n_inventories;
+ size_t _n_metrics;
+
+ std::vector _quantities;
+ std::vector _data;
+
+ std::unordered_map>
+ _metric_data;
+ };
+
+ ///
+ class ElementInventory {
+ public:
+ ElementInventory(size_t elem_id) : _elem_id(elem_id) {}
+
+ void registerNuclideMetricRequest(
+ const std::string &name, const size_t id, const size_t n_inventories,
+ const nuclide_quantities::NuclideQuantitiesEnum metric) {
+
+ if (std::find(_nuclides.begin(), _nuclides.end(), id) ==
+ _nuclides.end()) {
+
+ _nuclides.push_back(id);
+ _nuclide_data.emplace_back(
+ name, n_inventories,
+ std::vector(metric));
+ _nuclide_data.back().addQuantity(metric);
+ } else {
+ getNuclide(id).addQuantity(metric);
+ }
+ }
+
+ void registerElementMetricRequest(
+ const size_t n_inventories,
+ const inventory_outputs::InventoryOutputsEnum metric) {
+
+ _inventory_metrics[metric] = std::vector(n_inventories, 0.0);
+ }
+
+ bool has_nuclide(size_t nuclide_id) const {
+ if (find_nuclide(nuclide_id == -1)) {
+ return false;
+ }
+ return true;
+ }
+
+ int find_nuclide(size_t nuclide_id) const {
+ for (size_t i = 0; i < _nuclides.size(); ++i)
+ if (_nuclides[i] == nuclide_id)
+ return i;
+ return -1;
+ }
+
+ NuclideInventory &getNuclide(size_t n) {
+ return _nuclide_data[find_nuclide(n)];
+ }
+
+ const NuclideInventory &getNuclide(size_t n) const {
+ return _nuclide_data[find_nuclide(n)];
+ }
+
+ size_t getElemID() { return _elem_id; }
+
+ std::vector &getNuclides() { return _nuclides; }
+
+ std::unordered_map> &
+ getInventoryMetricMap() {
+ return _inventory_metrics;
+ }
+
+ const double
+ getElementMetric(inventory_outputs::InventoryOutputsEnum metric,
+ int inv_index) const {
+ return _inventory_metrics.at(metric)[inv_index];
+ }
+
+ protected:
+ std::vector _nuclide_data;
+ std::vector _nuclides;
+ libMesh::dof_id_type _elem_id;
+
+ size_t _n_element_metrics;
+
+ std::unordered_map>
+ _inventory_metrics;
+ };
+};
diff --git a/include/userobjects/FispactMaterial.h b/include/userobjects/FispactMaterial.h
new file mode 100644
index 0000000..1701609
--- /dev/null
+++ b/include/userobjects/FispactMaterial.h
@@ -0,0 +1,70 @@
+#pragma once
+
+#include "BlockRestrictable.h"
+#include "FispactUserObject.h"
+#include
+
+class FispactMaterial : public FispactUserObject, public BlockRestrictable {
+public:
+ static InputParameters validParams();
+
+ FispactMaterial(const InputParameters ¶ms);
+
+ virtual void initialize() {}
+ virtual void finalize() {}
+ virtual void execute() {}
+
+ FispactProblem &getFispactProblem() const;
+
+ /**
+ * Return a vector of Z or Zai numbers, depending on whether we are using
+ * setMass or setFuel, corresponding to the nuclides in _nuclides.
+ */
+ // std::vector getZsorZais(const fispact::FispactMonitor &monitor) const;
+
+ /*
+ * Getter for _nuclides
+ */
+ const std::vector getNuclides() const;
+
+ /*
+ * Getter for _nuclide_fraction
+ */
+ const std::vector getNuclideFractions() const;
+
+ const std::unordered_map &getNuclideFractionMap() const {
+ return _nuclide_fraction_map;
+ }
+ /*
+ * Getter for _nuclide_fraction
+ */
+ const double &getDensity() const { return _density; }
+
+ /*
+ * Getter for _material_type
+ */
+ const std::string &getMaterialType() const { return _material_type; }
+
+ double getAverageMolarMass(const std::vector &nuclide_names,
+ const std::vector &nuclide_fractions,
+ const std::string &fraction_type) const;
+
+ void
+ convertFromAtomToMassFraction(const std::vector &nuclide_names,
+ std::vector &nuclide_fractions,
+ const double average_molar_mass);
+
+protected:
+ //
+ std::unordered_map _nuclide_fraction_map;
+
+ const std::unordered_map &_molar_mass_map;
+
+ // Density of the fispact material
+ double _density;
+
+ //
+ const std::string _material_type;
+
+ const double _avogadro;
+};
diff --git a/include/userobjects/FispactNuclearDataPaths.h b/include/userobjects/FispactNuclearDataPaths.h
new file mode 100644
index 0000000..4030683
--- /dev/null
+++ b/include/userobjects/FispactNuclearDataPaths.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "GeneralUserObject.h"
+#include
+
+class FispactNuclearDataPaths : public GeneralUserObject {
+public:
+ static InputParameters validParams();
+
+ FispactNuclearDataPaths(const InputParameters ¶ms);
+
+ virtual void initialize() {}
+ virtual void finalize() {}
+ virtual void execute() {}
+
+ void loadNuclearDataPaths();
+
+ std::unordered_map &getNuclearDataPathMap();
+
+protected:
+ /// Nuclear data strings
+ const std::string _base_path;
+ std::unordered_map _datatype_to_path_map;
+};
diff --git a/include/userobjects/FispactSchedule.h b/include/userobjects/FispactSchedule.h
index bdfbc69..ffa9d90 100644
--- a/include/userobjects/FispactSchedule.h
+++ b/include/userobjects/FispactSchedule.h
@@ -12,13 +12,26 @@ class FispactSchedule : public GeneralUserObject {
virtual void finalize() {}
virtual void execute() {}
- const std::vector &getFluxSchedule();
- const std::vector &getTimes();
+ const std::vector &getFluxAmplitude() const;
+ std::vector getFluxAmplitude();
+ const std::vector &getTimes() const;
+ const std::vector &getCumulativeTimes() const;
+ const size_t &getNumInventories() const;
+ const size_t &getNumSolutionInventories() const;
protected:
/// Vector of flux amplitudes
- const std::vector _flux_schedule;
+ const std::vector _flux_amplitude;
/// List of times corresponding to the list of flux amplitudes on or off
const std::vector _times;
+
+ /// Cumulative version of _times
+ std::vector _cumulative_times;
+
+ /// Total number of solution inventories (ignoring initial)
+ const size_t _n_solution_inventories;
+
+ /// Total number of FISPACT inventories including initial inventory
+ const size_t _n_inventories;
};
diff --git a/include/userobjects/FispactUserObject.h b/include/userobjects/FispactUserObject.h
new file mode 100644
index 0000000..687cd6e
--- /dev/null
+++ b/include/userobjects/FispactUserObject.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "GeneralUserObject.h"
+#include
+
+class FispactProblem;
+
+class FispactUserObject : public GeneralUserObject {
+public:
+ static InputParameters validParams() {
+ InputParameters params = GeneralUserObject::validParams();
+ return params;
+ };
+
+ FispactUserObject(const InputParameters ¶ms);
+
+ virtual void initialize() {};
+ virtual void finalize() {};
+ virtual void execute() {};
+
+ FispactProblem &getFispactProblem() const { return _fispact_problem; }
+
+protected:
+ FispactProblem &_fispact_problem;
+};
diff --git a/include/userobjects/OpenMCFluxInput.h b/include/userobjects/OpenMCFluxInput.h
new file mode 100644
index 0000000..a4cd7c3
--- /dev/null
+++ b/include/userobjects/OpenMCFluxInput.h
@@ -0,0 +1,24 @@
+#include "FispactFluxInput.h"
+#include "InputParameters.h"
+#include "libMeshReducedNamespace.h"
+#include "libmesh/id_types.h"
+
+class OpenMCFluxInput : public FispactFluxInput {
+
+public:
+ static InputParameters validParams();
+
+ OpenMCFluxInput(const InputParameters ¶ms);
+
+ virtual std::vector getElemFlux(dof_id_type elem_id);
+
+ void readEnergyFilterBins();
+ void readNumEnergyBins();
+
+protected:
+ size_t _flux_tally_id;
+
+ size_t _energy_filter_id;
+
+ std::string _statepoint_filename;
+};
diff --git a/include/utils/EnergyGroups.h b/include/utils/EnergyGroups.h
new file mode 100644
index 0000000..a110f00
--- /dev/null
+++ b/include/utils/EnergyGroups.h
@@ -0,0 +1,364 @@
+#include
+#include
+#include
+
+namespace utils {
+namespace energy_groups {
+
+inline std::unordered_map> gamma_groups = {
+ {24, {1.000e-11, 1.000e+4, 2.000e+4, 5.000e+4, 1.000e+5, 2.000e+5, 3.000e+5,
+ 4.000e+5, 6.000e+5, 8.000e+5, 1.000e+6, 1.220e+6, 1.440e+6, 1.660e+6,
+ 2.000e+6, 2.500e+6, 3.000e+6, 4.000e+6, 5.000e+6, 6.500e+6, 8.000e+6,
+ 1.000e+7, 1.200e+7, 1.400e+7, 2.000e+7}},
+ {22, {0.0, 1.0e4, 1.0e5, 2.0e5, 4.0e5, 1.0e6, 1.5e6, 2.0e6,
+ 2.5e6, 3.0e6, 3.5e6, 4.0e6, 4.5e6, 5.0e6, 5.5e6, 6.0e6,
+ 6.5e6, 7.0e6, 7.5e6, 8.0e6, 1.0e7, 1.2e7, 1.4e7}}};
+
+inline std::unordered_map> neutron_groups = {
+ {1102,
+ {1.000000E-05, 1.047129E-05, 1.096478E-05, 1.148154E-05, 1.202264E-05,
+ 1.258925E-05, 1.318257E-05, 1.380384E-05, 1.445440E-05, 1.513561E-05,
+ 1.584893E-05, 1.659587E-05, 1.737801E-05, 1.819701E-05, 1.905461E-05,
+ 1.995262E-05, 2.089296E-05, 2.187762E-05, 2.290868E-05, 2.398833E-05,
+ 2.511886E-05, 2.630268E-05, 2.754229E-05, 2.884032E-05, 3.019952E-05,
+ 3.162278E-05, 3.311311E-05, 3.467369E-05, 3.630781E-05, 3.801894E-05,
+ 3.981072E-05, 4.168694E-05, 4.365158E-05, 4.570882E-05, 4.786301E-05,
+ 5.011872E-05, 5.248075E-05, 5.495409E-05, 5.754399E-05, 6.025596E-05,
+ 6.309573E-05, 6.606934E-05, 6.918310E-05, 7.244360E-05, 7.585776E-05,
+ 7.943282E-05, 8.317638E-05, 8.709636E-05, 9.120108E-05, 9.549926E-05,
+ 1.000000E-04, 1.047129E-04, 1.096478E-04, 1.148154E-04, 1.202264E-04,
+ 1.258925E-04, 1.318257E-04, 1.380384E-04, 1.445440E-04, 1.513561E-04,
+ 1.584893E-04, 1.659587E-04, 1.737801E-04, 1.819701E-04, 1.905461E-04,
+ 1.995262E-04, 2.089296E-04, 2.187762E-04, 2.290868E-04, 2.398833E-04,
+ 2.511886E-04, 2.630268E-04, 2.754229E-04, 2.884032E-04, 3.019952E-04,
+ 3.162278E-04, 3.311311E-04, 3.467369E-04, 3.630781E-04, 3.801894E-04,
+ 3.981072E-04, 4.168694E-04, 4.365158E-04, 4.570882E-04, 4.786301E-04,
+ 5.011872E-04, 5.248075E-04, 5.495409E-04, 5.754399E-04, 6.025596E-04,
+ 6.309573E-04, 6.606934E-04, 6.918310E-04, 7.244360E-04, 7.585776E-04,
+ 7.943282E-04, 8.317638E-04, 8.709636E-04, 9.120108E-04, 9.549926E-04,
+ 1.000000E-03, 1.047129E-03, 1.096478E-03, 1.148154E-03, 1.202264E-03,
+ 1.258925E-03, 1.318257E-03, 1.380384E-03, 1.445440E-03, 1.513561E-03,
+ 1.584893E-03, 1.659587E-03, 1.737801E-03, 1.819701E-03, 1.905461E-03,
+ 1.995262E-03, 2.089296E-03, 2.187762E-03, 2.290868E-03, 2.398833E-03,
+ 2.511886E-03, 2.630268E-03, 2.754229E-03, 2.884032E-03, 3.019952E-03,
+ 3.162278E-03, 3.311311E-03, 3.467369E-03, 3.630781E-03, 3.801894E-03,
+ 3.981072E-03, 4.168694E-03, 4.365158E-03, 4.570882E-03, 4.786301E-03,
+ 5.011872E-03, 5.248075E-03, 5.495409E-03, 5.754399E-03, 6.025596E-03,
+ 6.309573E-03, 6.606934E-03, 6.918310E-03, 7.244360E-03, 7.585776E-03,
+ 7.943282E-03, 8.317638E-03, 8.709636E-03, 9.120108E-03, 9.549926E-03,
+ 1.000000E-02, 1.047129E-02, 1.096478E-02, 1.148154E-02, 1.202264E-02,
+ 1.258925E-02, 1.318257E-02, 1.380384E-02, 1.445440E-02, 1.513561E-02,
+ 1.584893E-02, 1.659587E-02, 1.737801E-02, 1.819701E-02, 1.905461E-02,
+ 1.995262E-02, 2.089296E-02, 2.187762E-02, 2.290868E-02, 2.398833E-02,
+ 2.511886E-02, 2.630268E-02, 2.754229E-02, 2.884032E-02, 3.019952E-02,
+ 3.162278E-02, 3.311311E-02, 3.467369E-02, 3.630781E-02, 3.801894E-02,
+ 3.981072E-02, 4.168694E-02, 4.365158E-02, 4.570882E-02, 4.786301E-02,
+ 5.011872E-02, 5.248075E-02, 5.495409E-02, 5.754399E-02, 6.025596E-02,
+ 6.309573E-02, 6.606934E-02, 6.918310E-02, 7.244360E-02, 7.585776E-02,
+ 7.943282E-02, 8.317638E-02, 8.709636E-02, 9.120108E-02, 9.549926E-02,
+ 1.000000E-01, 1.047129E-01, 1.096478E-01, 1.148154E-01, 1.202264E-01,
+ 1.258925E-01, 1.318257E-01, 1.380384E-01, 1.445440E-01, 1.513561E-01,
+ 1.584893E-01, 1.659587E-01, 1.737801E-01, 1.819701E-01, 1.905461E-01,
+ 1.995262E-01, 2.089296E-01, 2.187762E-01, 2.290868E-01, 2.398833E-01,
+ 2.511886E-01, 2.630268E-01, 2.754229E-01, 2.884032E-01, 3.019952E-01,
+ 3.162278E-01, 3.311311E-01, 3.467369E-01, 3.630781E-01, 3.801894E-01,
+ 3.981072E-01, 4.168694E-01, 4.365158E-01, 4.570882E-01, 4.786301E-01,
+ 5.011872E-01, 5.248075E-01, 5.500000E-01, 5.750000E-01, 6.000000E-01,
+ 6.250000E-01, 6.500000E-01, 6.750000E-01, 7.000000E-01, 7.250000E-01,
+ 7.500000E-01, 7.750000E-01, 8.000000E-01, 8.250000E-01, 8.500000E-01,
+ 8.750000E-01, 9.000000E-01, 9.250000E-01, 9.500000E-01, 9.750000E-01,
+ 1.000000E+00, 1.025000E+00, 1.050000E+00, 1.075000E+00, 1.100000E+00,
+ 1.125000E+00, 1.150000E+00, 1.175000E+00, 1.200000E+00, 1.225000E+00,
+ 1.250000E+00, 1.275000E+00, 1.300000E+00, 1.325000E+00, 1.350000E+00,
+ 1.375000E+00, 1.400000E+00, 1.425000E+00, 1.450000E+00, 1.475000E+00,
+ 1.500000E+00, 1.525000E+00, 1.550000E+00, 1.575000E+00, 1.600000E+00,
+ 1.625000E+00, 1.650000E+00, 1.675000E+00, 1.700000E+00, 1.725000E+00,
+ 1.750000E+00, 1.775000E+00, 1.800000E+00, 1.825000E+00, 1.850000E+00,
+ 1.875000E+00, 1.900000E+00, 1.925000E+00, 1.950000E+00, 1.975000E+00,
+ 2.000000E+00, 2.025000E+00, 2.050000E+00, 2.075000E+00, 2.100000E+00,
+ 2.125000E+00, 2.150000E+00, 2.175000E+00, 2.200000E+00, 2.225000E+00,
+ 2.250000E+00, 2.275000E+00, 2.300000E+00, 2.325000E+00, 2.350000E+00,
+ 2.375000E+00, 2.400000E+00, 2.425000E+00, 2.450000E+00, 2.475000E+00,
+ 2.500000E+00, 2.525000E+00, 2.550000E+00, 2.575000E+00, 2.600000E+00,
+ 2.625000E+00, 2.650000E+00, 2.675000E+00, 2.700000E+00, 2.725000E+00,
+ 2.750000E+00, 2.775000E+00, 2.800000E+00, 2.825000E+00, 2.850000E+00,
+ 2.875000E+00, 2.900000E+00, 2.925000E+00, 2.950000E+00, 2.975000E+00,
+ 3.000000E+00, 3.025000E+00, 3.050000E+00, 3.075000E+00, 3.100000E+00,
+ 3.125000E+00, 3.150000E+00, 3.175000E+00, 3.200000E+00, 3.225000E+00,
+ 3.250000E+00, 3.275000E+00, 3.300000E+00, 3.325000E+00, 3.350000E+00,
+ 3.375000E+00, 3.400000E+00, 3.425000E+00, 3.450000E+00, 3.475000E+00,
+ 3.500000E+00, 3.525000E+00, 3.550000E+00, 3.575000E+00, 3.600000E+00,
+ 3.625000E+00, 3.650000E+00, 3.675000E+00, 3.700000E+00, 3.725000E+00,
+ 3.750000E+00, 3.775000E+00, 3.800000E+00, 3.825000E+00, 3.850000E+00,
+ 3.875000E+00, 3.900000E+00, 3.925000E+00, 3.950000E+00, 3.975000E+00,
+ 4.000000E+00, 4.025000E+00, 4.050000E+00, 4.075000E+00, 4.100000E+00,
+ 4.125000E+00, 4.150000E+00, 4.175000E+00, 4.200000E+00, 4.225000E+00,
+ 4.250000E+00, 4.275000E+00, 4.300000E+00, 4.325000E+00, 4.350000E+00,
+ 4.375000E+00, 4.400000E+00, 4.425000E+00, 4.450000E+00, 4.475000E+00,
+ 4.500000E+00, 4.525000E+00, 4.550000E+00, 4.575000E+00, 4.600000E+00,
+ 4.625000E+00, 4.650000E+00, 4.675000E+00, 4.700000E+00, 4.725000E+00,
+ 4.750000E+00, 4.775000E+00, 4.800000E+00, 4.825000E+00, 4.850000E+00,
+ 4.875000E+00, 4.900000E+00, 4.925000E+00, 4.950000E+00, 4.975000E+00,
+ 5.000000E+00, 5.025000E+00, 5.050000E+00, 5.075000E+00, 5.100000E+00,
+ 5.125000E+00, 5.150000E+00, 5.175000E+00, 5.200000E+00, 5.225000E+00,
+ 5.250000E+00, 5.275000E+00, 5.300000E+00, 5.325000E+00, 5.350000E+00,
+ 5.375000E+00, 5.400000E+00, 5.425000E+00, 5.450000E+00, 5.475000E+00,
+ 5.500000E+00, 5.525000E+00, 5.550000E+00, 5.575000E+00, 5.600000E+00,
+ 5.625000E+00, 5.650000E+00, 5.675000E+00, 5.700000E+00, 5.725000E+00,
+ 5.750000E+00, 5.775000E+00, 5.800000E+00, 5.825000E+00, 5.850000E+00,
+ 5.875000E+00, 5.900000E+00, 5.925000E+00, 5.950000E+00, 5.975000E+00,
+ 6.000000E+00, 6.025000E+00, 6.050000E+00, 6.075000E+00, 6.100000E+00,
+ 6.125000E+00, 6.150000E+00, 6.175000E+00, 6.200000E+00, 6.225000E+00,
+ 6.250000E+00, 6.275000E+00, 6.300000E+00, 6.325000E+00, 6.350000E+00,
+ 6.375000E+00, 6.400000E+00, 6.425000E+00, 6.450000E+00, 6.475000E+00,
+ 6.500000E+00, 6.525000E+00, 6.550000E+00, 6.575000E+00, 6.600000E+00,
+ 6.625000E+00, 6.650000E+00, 6.675000E+00, 6.700000E+00, 6.725000E+00,
+ 6.750000E+00, 6.775000E+00, 6.800000E+00, 6.825000E+00, 6.850000E+00,
+ 6.875000E+00, 6.900000E+00, 6.925000E+00, 6.950000E+00, 6.975000E+00,
+ 7.000000E+00, 7.025000E+00, 7.050000E+00, 7.075000E+00, 7.100000E+00,
+ 7.125000E+00, 7.150000E+00, 7.175000E+00, 7.200000E+00, 7.225000E+00,
+ 7.250000E+00, 7.275000E+00, 7.300000E+00, 7.325000E+00, 7.350000E+00,
+ 7.375000E+00, 7.400000E+00, 7.425000E+00, 7.450000E+00, 7.475000E+00,
+ 7.500000E+00, 7.525000E+00, 7.550000E+00, 7.575000E+00, 7.600000E+00,
+ 7.625000E+00, 7.650000E+00, 7.675000E+00, 7.700000E+00, 7.725000E+00,
+ 7.750000E+00, 7.775000E+00, 7.800000E+00, 7.825000E+00, 7.850000E+00,
+ 7.875000E+00, 7.900000E+00, 7.925000E+00, 7.950000E+00, 7.975000E+00,
+ 8.000000E+00, 8.025000E+00, 8.050000E+00, 8.075000E+00, 8.100000E+00,
+ 8.125000E+00, 8.150000E+00, 8.175000E+00, 8.200000E+00, 8.225000E+00,
+ 8.250000E+00, 8.275000E+00, 8.300000E+00, 8.325000E+00, 8.350000E+00,
+ 8.375000E+00, 8.400000E+00, 8.425000E+00, 8.450000E+00, 8.475000E+00,
+ 8.500000E+00, 8.525000E+00, 8.550000E+00, 8.575000E+00, 8.600000E+00,
+ 8.625000E+00, 8.650000E+00, 8.675000E+00, 8.700000E+00, 8.725000E+00,
+ 8.750000E+00, 8.775000E+00, 8.800000E+00, 8.825000E+00, 8.850000E+00,
+ 8.875000E+00, 8.900000E+00, 8.925000E+00, 8.950000E+00, 8.975000E+00,
+ 9.000000E+00, 9.025000E+00, 9.050000E+00, 9.075000E+00, 9.100000E+00,
+ 9.125000E+00, 9.150000E+00, 9.175000E+00, 9.200000E+00, 9.225000E+00,
+ 9.250000E+00, 9.275000E+00, 9.300000E+00, 9.325000E+00, 9.350000E+00,
+ 9.375000E+00, 9.400000E+00, 9.425000E+00, 9.450000E+00, 9.475000E+00,
+ 9.500000E+00, 9.525000E+00, 9.550000E+00, 9.575000E+00, 9.600000E+00,
+ 9.625000E+00, 9.650000E+00, 9.675000E+00, 9.700000E+00, 9.725000E+00,
+ 9.750000E+00, 9.775000E+00, 9.800000E+00, 9.825000E+00, 9.850000E+00,
+ 9.875000E+00, 9.900000E+00, 9.925000E+00, 9.950000E+00, 9.975000E+00,
+ 1.000000E+01, 1.047129E+01, 1.096478E+01, 1.148154E+01, 1.202264E+01,
+ 1.258925E+01, 1.318257E+01, 1.380384E+01, 1.445440E+01, 1.513561E+01,
+ 1.584893E+01, 1.659587E+01, 1.737801E+01, 1.819701E+01, 1.905461E+01,
+ 1.995262E+01, 2.089296E+01, 2.187762E+01, 2.290868E+01, 2.398833E+01,
+ 2.511886E+01, 2.630268E+01, 2.754229E+01, 2.884032E+01, 3.019952E+01,
+ 3.162278E+01, 3.311311E+01, 3.467369E+01, 3.630781E+01, 3.801894E+01,
+ 3.981072E+01, 4.168694E+01, 4.365158E+01, 4.570882E+01, 4.786301E+01,
+ 5.011872E+01, 5.248075E+01, 5.495409E+01, 5.754399E+01, 6.025596E+01,
+ 6.309573E+01, 6.606934E+01, 6.918310E+01, 7.244360E+01, 7.585776E+01,
+ 7.943282E+01, 8.317638E+01, 8.709636E+01, 9.120108E+01, 9.549926E+01,
+ 1.000000E+02, 1.047129E+02, 1.096478E+02, 1.148154E+02, 1.202264E+02,
+ 1.258925E+02, 1.318257E+02, 1.380384E+02, 1.445440E+02, 1.513561E+02,
+ 1.584893E+02, 1.659587E+02, 1.737801E+02, 1.819701E+02, 1.905461E+02,
+ 1.995262E+02, 2.089296E+02, 2.187762E+02, 2.290868E+02, 2.398833E+02,
+ 2.511886E+02, 2.630268E+02, 2.754229E+02, 2.884032E+02, 3.019952E+02,
+ 3.162278E+02, 3.311311E+02, 3.467369E+02, 3.630781E+02, 3.801894E+02,
+ 3.981072E+02, 4.168694E+02, 4.365158E+02, 4.570882E+02, 4.786301E+02,
+ 5.011872E+02, 5.248075E+02, 5.495409E+02, 5.754399E+02, 6.025596E+02,
+ 6.309573E+02, 6.606934E+02, 6.918310E+02, 7.244360E+02, 7.585776E+02,
+ 7.943282E+02, 8.317638E+02, 8.709636E+02, 9.120108E+02, 9.549926E+02,
+ 1.000000E+03, 1.047129E+03, 1.096478E+03, 1.148154E+03, 1.202264E+03,
+ 1.258925E+03, 1.318257E+03, 1.380384E+03, 1.445440E+03, 1.513561E+03,
+ 1.584893E+03, 1.659587E+03, 1.737801E+03, 1.819701E+03, 1.905461E+03,
+ 1.995262E+03, 2.089296E+03, 2.187762E+03, 2.290868E+03, 2.398833E+03,
+ 2.511886E+03, 2.630268E+03, 2.754229E+03, 2.884032E+03, 3.019952E+03,
+ 3.162278E+03, 3.311311E+03, 3.467369E+03, 3.630781E+03, 3.801894E+03,
+ 3.981072E+03, 4.168694E+03, 4.365158E+03, 4.570882E+03, 4.786301E+03,
+ 5.011872E+03, 5.248075E+03, 5.495409E+03, 5.754399E+03, 6.025596E+03,
+ 6.309573E+03, 6.606934E+03, 6.918310E+03, 7.244360E+03, 7.585776E+03,
+ 7.943282E+03, 8.317638E+03, 8.709636E+03, 9.120108E+03, 9.549926E+03,
+ 1.000000E+04, 1.047129E+04, 1.096478E+04, 1.148154E+04, 1.202264E+04,
+ 1.258925E+04, 1.318257E+04, 1.380384E+04, 1.445440E+04, 1.513561E+04,
+ 1.584893E+04, 1.659587E+04, 1.737801E+04, 1.819701E+04, 1.905461E+04,
+ 1.995262E+04, 2.089296E+04, 2.187762E+04, 2.290868E+04, 2.398833E+04,
+ 2.511886E+04, 2.630268E+04, 2.754229E+04, 2.884032E+04, 3.019952E+04,
+ 3.162278E+04, 3.311311E+04, 3.467369E+04, 3.630781E+04, 3.801894E+04,
+ 3.981072E+04, 4.168694E+04, 4.365158E+04, 4.570882E+04, 4.786301E+04,
+ 5.011872E+04, 5.248075E+04, 5.495409E+04, 5.754399E+04, 6.025596E+04,
+ 6.309573E+04, 6.606934E+04, 6.918310E+04, 7.244360E+04, 7.585776E+04,
+ 7.943282E+04, 8.317638E+04, 8.709636E+04, 9.120108E+04, 9.549926E+04,
+ 1.000000E+05, 1.047129E+05, 1.096478E+05, 1.148154E+05, 1.202264E+05,
+ 1.258925E+05, 1.318257E+05, 1.380384E+05, 1.445440E+05, 1.513561E+05,
+ 1.584893E+05, 1.659587E+05, 1.737801E+05, 1.819701E+05, 1.905461E+05,
+ 1.995262E+05, 2.089296E+05, 2.187762E+05, 2.290868E+05, 2.398833E+05,
+ 2.511886E+05, 2.630268E+05, 2.754229E+05, 2.884032E+05, 3.019952E+05,
+ 3.162278E+05, 3.311311E+05, 3.467369E+05, 3.630781E+05, 3.801894E+05,
+ 3.981072E+05, 4.168694E+05, 4.365158E+05, 4.570882E+05, 4.786301E+05,
+ 5.011872E+05, 5.248075E+05, 5.495409E+05, 5.754399E+05, 6.025596E+05,
+ 6.309573E+05, 6.606934E+05, 6.918310E+05, 7.244360E+05, 7.585776E+05,
+ 7.943282E+05, 8.317638E+05, 8.709636E+05, 9.120108E+05, 9.549926E+05,
+ 1.000000E+06, 1.047129E+06, 1.096478E+06, 1.148154E+06, 1.202264E+06,
+ 1.258925E+06, 1.318257E+06, 1.380384E+06, 1.445440E+06, 1.513561E+06,
+ 1.584893E+06, 1.659587E+06, 1.737801E+06, 1.819701E+06, 1.905461E+06,
+ 1.995262E+06, 2.089296E+06, 2.187762E+06, 2.290868E+06, 2.398833E+06,
+ 2.511886E+06, 2.630268E+06, 2.754229E+06, 2.884032E+06, 3.019952E+06,
+ 3.162278E+06, 3.311311E+06, 3.467369E+06, 3.630781E+06, 3.801894E+06,
+ 3.981072E+06, 4.168694E+06, 4.365158E+06, 4.570882E+06, 4.786301E+06,
+ 5.000000E+06, 5.200000E+06, 5.400000E+06, 5.600000E+06, 5.800000E+06,
+ 6.000000E+06, 6.200000E+06, 6.400000E+06, 6.600000E+06, 6.800000E+06,
+ 7.000000E+06, 7.200000E+06, 7.400000E+06, 7.600000E+06, 7.800000E+06,
+ 8.000000E+06, 8.200000E+06, 8.400000E+06, 8.600000E+06, 8.800000E+06,
+ 9.000000E+06, 9.200000E+06, 9.400000E+06, 9.600000E+06, 9.800000E+06,
+ 1.000000E+07, 1.020000E+07, 1.040000E+07, 1.060000E+07, 1.080000E+07,
+ 1.100000E+07, 1.120000E+07, 1.140000E+07, 1.160000E+07, 1.180000E+07,
+ 1.200000E+07, 1.220000E+07, 1.240000E+07, 1.260000E+07, 1.280000E+07,
+ 1.300000E+07, 1.320000E+07, 1.340000E+07, 1.360000E+07, 1.380000E+07,
+ 1.400000E+07, 1.420000E+07, 1.440000E+07, 1.460000E+07, 1.480000E+07,
+ 1.500000E+07, 1.520000E+07, 1.540000E+07, 1.560000E+07, 1.580000E+07,
+ 1.600000E+07, 1.620000E+07, 1.640000E+07, 1.660000E+07, 1.680000E+07,
+ 1.700000E+07, 1.720000E+07, 1.740000E+07, 1.760000E+07, 1.780000E+07,
+ 1.800000E+07, 1.820000E+07, 1.840000E+07, 1.860000E+07, 1.880000E+07,
+ 1.900000E+07, 1.920000E+07, 1.940000E+07, 1.960000E+07, 1.980000E+07,
+ 2.000000E+07, 2.020000E+07, 2.040000E+07, 2.060000E+07, 2.080000E+07,
+ 2.100000E+07, 2.120000E+07, 2.140000E+07, 2.160000E+07, 2.180000E+07,
+ 2.200000E+07, 2.220000E+07, 2.240000E+07, 2.260000E+07, 2.280000E+07,
+ 2.300000E+07, 2.320000E+07, 2.340000E+07, 2.360000E+07, 2.380000E+07,
+ 2.400000E+07, 2.420000E+07, 2.440000E+07, 2.460000E+07, 2.480000E+07,
+ 2.500000E+07, 2.520000E+07, 2.540000E+07, 2.560000E+07, 2.580000E+07,
+ 2.600000E+07, 2.620000E+07, 2.640000E+07, 2.660000E+07, 2.680000E+07,
+ 2.700000E+07, 2.720000E+07, 2.740000E+07, 2.760000E+07, 2.780000E+07,
+ 2.800000E+07, 2.820000E+07, 2.840000E+07, 2.860000E+07, 2.880000E+07,
+ 2.900000E+07, 2.920000E+07, 2.940000E+07, 2.960000E+07, 2.980000E+07,
+ 3.000000E+07, 3.019952E+07, 3.162278E+07, 3.311311E+07, 3.467369E+07,
+ 3.630781E+07, 3.801894E+07, 3.981072E+07, 4.168694E+07, 4.365158E+07,
+ 4.570882E+07, 4.786301E+07, 5.011872E+07, 5.248075E+07, 5.495409E+07,
+ 5.754399E+07, 6.025596E+07, 6.309573E+07, 6.606934E+07, 6.918310E+07,
+ 7.244360E+07, 7.585776E+07, 7.943282E+07, 8.317638E+07, 8.709636E+07,
+ 9.120108E+07, 9.549926E+07, 1.000000E+08, 1.047129E+08, 1.096478E+08,
+ 1.148154E+08, 1.202264E+08, 1.258925E+08, 1.318257E+08, 1.380384E+08,
+ 1.445440E+08, 1.513561E+08, 1.584893E+08, 1.659587E+08, 1.737801E+08,
+ 1.819701E+08, 1.905461E+08, 1.995262E+08, 2.089296E+08, 2.187762E+08,
+ 2.290868E+08, 2.398833E+08, 2.511886E+08, 2.630268E+08, 2.754229E+08,
+ 2.884032E+08, 3.019952E+08, 3.162278E+08, 3.311311E+08, 3.467369E+08,
+ 3.630781E+08, 3.801894E+08, 3.981072E+08, 4.168694E+08, 4.365158E+08,
+ 4.570882E+08, 4.786301E+08, 5.011872E+08, 5.248075E+08, 5.495409E+08,
+ 5.754399E+08, 6.025596E+08, 6.309573E+08, 6.606934E+08, 6.918310E+08,
+ 7.244360E+08, 7.585776E+08, 7.943282E+08, 8.317638E+08, 8.709636E+08,
+ 9.120108E+08, 9.549926E+08, 1.000000E+09}},
+
+ {709, {1.0000E-5, 1.0471E-5, 1.0965E-5, 1.1482E-5, 1.2023E-5, 1.2589E-5,
+ 1.3183E-5, 1.3804E-5, 1.4454E-5, 1.5136E-5, 1.5849E-5, 1.6596E-5,
+ 1.7378E-5, 1.8197E-5, 1.9055E-5, 1.9953E-5, 2.0893E-5, 2.1878E-5,
+ 2.2909E-5, 2.3988E-5, 2.5119E-5, 2.6303E-5, 2.7542E-5, 2.8840E-5,
+ 3.0200E-5, 3.1623E-5, 3.3113E-5, 3.4674E-5, 3.6308E-5, 3.8019E-5,
+ 3.9811E-5, 4.1687E-5, 4.3652E-5, 4.5709E-5, 4.7863E-5, 5.0119E-5,
+ 5.2481E-5, 5.4954E-5, 5.7544E-5, 6.0256E-5, 6.3096E-5, 6.6069E-5,
+ 6.9183E-5, 7.2444E-5, 7.5858E-5, 7.9433E-5, 8.3176E-5, 8.7096E-5,
+ 9.1201E-5, 9.5499E-5, 1.0000E-4, 1.0471E-4, 1.0965E-4, 1.1482E-4,
+ 1.2023E-4, 1.2589E-4, 1.3183E-4, 1.3804E-4, 1.4454E-4, 1.5136E-4,
+ 1.5849E-4, 1.6596E-4, 1.7378E-4, 1.8197E-4, 1.9055E-4, 1.9953E-4,
+ 2.0893E-4, 2.1878E-4, 2.2909E-4, 2.3988E-4, 2.5119E-4, 2.6303E-4,
+ 2.7542E-4, 2.8840E-4, 3.0200E-4, 3.1623E-4, 3.3113E-4, 3.4674E-4,
+ 3.6308E-4, 3.8019E-4, 3.9811E-4, 4.1687E-4, 4.3652E-4, 4.5709E-4,
+ 4.7863E-4, 5.0119E-4, 5.2481E-4, 5.4954E-4, 5.7544E-4, 6.0256E-4,
+ 6.3096E-4, 6.6069E-4, 6.9183E-4, 7.2444E-4, 7.5858E-4, 7.9433E-4,
+ 8.3176E-4, 8.7096E-4, 9.1201E-4, 9.5499E-4, 1.0000E-3, 1.0471E-3,
+ 1.0965E-3, 1.1482E-3, 1.2023E-3, 1.2589E-3, 1.3183E-3, 1.3804E-3,
+ 1.4454E-3, 1.5136E-3, 1.5849E-3, 1.6596E-3, 1.7378E-3, 1.8197E-3,
+ 1.9055E-3, 1.9953E-3, 2.0893E-3, 2.1878E-3, 2.2909E-3, 2.3988E-3,
+ 2.5119E-3, 2.6303E-3, 2.7542E-3, 2.8840E-3, 3.0200E-3, 3.1623E-3,
+ 3.3113E-3, 3.4674E-3, 3.6308E-3, 3.8019E-3, 3.9811E-3, 4.1687E-3,
+ 4.3652E-3, 4.5709E-3, 4.7863E-3, 5.0119E-3, 5.2481E-3, 5.4954E-3,
+ 5.7544E-3, 6.0256E-3, 6.3096E-3, 6.6069E-3, 6.9183E-3, 7.2444E-3,
+ 7.5858E-3, 7.9433E-3, 8.3176E-3, 8.7096E-3, 9.1201E-3, 9.5499E-3,
+ 1.0000E-2, 1.0471E-2, 1.0965E-2, 1.1482E-2, 1.2023E-2, 1.2589E-2,
+ 1.3183E-2, 1.3804E-2, 1.4454E-2, 1.5136E-2, 1.5849E-2, 1.6596E-2,
+ 1.7378E-2, 1.8197E-2, 1.9055E-2, 1.9953E-2, 2.0893E-2, 2.1878E-2,
+ 2.2909E-2, 2.3988E-2, 2.5119E-2, 2.6303E-2, 2.7542E-2, 2.8840E-2,
+ 3.0200E-2, 3.1623E-2, 3.3113E-2, 3.4674E-2, 3.6308E-2, 3.8019E-2,
+ 3.9811E-2, 4.1687E-2, 4.3652E-2, 4.5709E-2, 4.7863E-2, 5.0119E-2,
+ 5.2481E-2, 5.4954E-2, 5.7544E-2, 6.0256E-2, 6.3096E-2, 6.6069E-2,
+ 6.9183E-2, 7.2444E-2, 7.5858E-2, 7.9433E-2, 8.3176E-2, 8.7096E-2,
+ 9.1201E-2, 9.5499E-2, 1.0000E-1, 1.0471E-1, 1.0965E-1, 1.1482E-1,
+ 1.2023E-1, 1.2589E-1, 1.3183E-1, 1.3804E-1, 1.4454E-1, 1.5136E-1,
+ 1.5849E-1, 1.6596E-1, 1.7378E-1, 1.8197E-1, 1.9055E-1, 1.9953E-1,
+ 2.0893E-1, 2.1878E-1, 2.2909E-1, 2.3988E-1, 2.5119E-1, 2.6303E-1,
+ 2.7542E-1, 2.8840E-1, 3.0200E-1, 3.1623E-1, 3.3113E-1, 3.4674E-1,
+ 3.6308E-1, 3.8019E-1, 3.9811E-1, 4.1687E-1, 4.3652E-1, 4.5709E-1,
+ 4.7863E-1, 5.0119E-1, 5.2481E-1, 5.4954E-1, 5.7544E-1, 6.0256E-1,
+ 6.3096E-1, 6.6069E-1, 6.9183E-1, 7.2444E-1, 7.5858E-1, 7.9433E-1,
+ 8.3176E-1, 8.7096E-1, 9.1201E-1, 9.5499E-1, 1.0000E+0, 1.0471E+0,
+ 1.0965E+0, 1.1482E+0, 1.2023E+0, 1.2589E+0, 1.3183E+0, 1.3804E+0,
+ 1.4454E+0, 1.5136E+0, 1.5849E+0, 1.6596E+0, 1.7378E+0, 1.8197E+0,
+ 1.9055E+0, 1.9953E+0, 2.0893E+0, 2.1878E+0, 2.2909E+0, 2.3988E+0,
+ 2.5119E+0, 2.6303E+0, 2.7542E+0, 2.8840E+0, 3.0200E+0, 3.1623E+0,
+ 3.3113E+0, 3.4674E+0, 3.6308E+0, 3.8019E+0, 3.9811E+0, 4.1687E+0,
+ 4.3652E+0, 4.5709E+0, 4.7863E+0, 5.0119E+0, 5.2481E+0, 5.4954E+0,
+ 5.7544E+0, 6.0256E+0, 6.3096E+0, 6.6069E+0, 6.9183E+0, 7.2444E+0,
+ 7.5858E+0, 7.9433E+0, 8.3176E+0, 8.7096E+0, 9.1201E+0, 9.5499E+0,
+ 1.0000E+1, 1.0471E+1, 1.0965E+1, 1.1482E+1, 1.2023E+1, 1.2589E+1,
+ 1.3183E+1, 1.3804E+1, 1.4454E+1, 1.5136E+1, 1.5849E+1, 1.6596E+1,
+ 1.7378E+1, 1.8197E+1, 1.9055E+1, 1.9953E+1, 2.0893E+1, 2.1878E+1,
+ 2.2909E+1, 2.3988E+1, 2.5119E+1, 2.6303E+1, 2.7542E+1, 2.8840E+1,
+ 3.0200E+1, 3.1623E+1, 3.3113E+1, 3.4674E+1, 3.6308E+1, 3.8019E+1,
+ 3.9811E+1, 4.1687E+1, 4.3652E+1, 4.5709E+1, 4.7863E+1, 5.0119E+1,
+ 5.2481E+1, 5.4954E+1, 5.7544E+1, 6.0256E+1, 6.3096E+1, 6.6069E+1,
+ 6.9183E+1, 7.2444E+1, 7.5858E+1, 7.9433E+1, 8.3176E+1, 8.7096E+1,
+ 9.1201E+1, 9.5499E+1, 1.0000E+2, 1.0471E+2, 1.0965E+2, 1.1482E+2,
+ 1.2023E+2, 1.2589E+2, 1.3183E+2, 1.3804E+2, 1.4454E+2, 1.5136E+2,
+ 1.5849E+2, 1.6596E+2, 1.7378E+2, 1.8197E+2, 1.9055E+2, 1.9953E+2,
+ 2.0893E+2, 2.1878E+2, 2.2909E+2, 2.3988E+2, 2.5119E+2, 2.6303E+2,
+ 2.7542E+2, 2.8840E+2, 3.0200E+2, 3.1623E+2, 3.3113E+2, 3.4674E+2,
+ 3.6308E+2, 3.8019E+2, 3.9811E+2, 4.1687E+2, 4.3652E+2, 4.5709E+2,
+ 4.7863E+2, 5.0119E+2, 5.2481E+2, 5.4954E+2, 5.7544E+2, 6.0256E+2,
+ 6.3096E+2, 6.6069E+2, 6.9183E+2, 7.2444E+2, 7.5858E+2, 7.9433E+2,
+ 8.3176E+2, 8.7096E+2, 9.1201E+2, 9.5499E+2, 1.0000E+3, 1.0471E+3,
+ 1.0965E+3, 1.1482E+3, 1.2023E+3, 1.2589E+3, 1.3183E+3, 1.3804E+3,
+ 1.4454E+3, 1.5136E+3, 1.5849E+3, 1.6596E+3, 1.7378E+3, 1.8197E+3,
+ 1.9055E+3, 1.9953E+3, 2.0893E+3, 2.1878E+3, 2.2909E+3, 2.3988E+3,
+ 2.5119E+3, 2.6303E+3, 2.7542E+3, 2.8840E+3, 3.0200E+3, 3.1623E+3,
+ 3.3113E+3, 3.4674E+3, 3.6308E+3, 3.8019E+3, 3.9811E+3, 4.1687E+3,
+ 4.3652E+3, 4.5709E+3, 4.7863E+3, 5.0119E+3, 5.2481E+3, 5.4954E+3,
+ 5.7544E+3, 6.0256E+3, 6.3096E+3, 6.6069E+3, 6.9183E+3, 7.2444E+3,
+ 7.5858E+3, 7.9433E+3, 8.3176E+3, 8.7096E+3, 9.1201E+3, 9.5499E+3,
+ 1.0000E+4, 1.0471E+4, 1.0965E+4, 1.1482E+4, 1.2023E+4, 1.2589E+4,
+ 1.3183E+4, 1.3804E+4, 1.4454E+4, 1.5136E+4, 1.5849E+4, 1.6596E+4,
+ 1.7378E+4, 1.8197E+4, 1.9055E+4, 1.9953E+4, 2.0893E+4, 2.1878E+4,
+ 2.2909E+4, 2.3988E+4, 2.5119E+4, 2.6303E+4, 2.7542E+4, 2.8840E+4,
+ 3.0200E+4, 3.1623E+4, 3.3113E+4, 3.4674E+4, 3.6308E+4, 3.8019E+4,
+ 3.9811E+4, 4.1687E+4, 4.3652E+4, 4.5709E+4, 4.7863E+4, 5.0119E+4,
+ 5.2481E+4, 5.4954E+4, 5.7544E+4, 6.0256E+4, 6.3096E+4, 6.6069E+4,
+ 6.9183E+4, 7.2444E+4, 7.5858E+4, 7.9433E+4, 8.3176E+4, 8.7096E+4,
+ 9.1201E+4, 9.5499E+4, 1.0000E+5, 1.0471E+5, 1.0965E+5, 1.1482E+5,
+ 1.2023E+5, 1.2589E+5, 1.3183E+5, 1.3804E+5, 1.4454E+5, 1.5136E+5,
+ 1.5849E+5, 1.6596E+5, 1.7378E+5, 1.8197E+5, 1.9055E+5, 1.9953E+5,
+ 2.0893E+5, 2.1878E+5, 2.2909E+5, 2.3988E+5, 2.5119E+5, 2.6303E+5,
+ 2.7542E+5, 2.8840E+5, 3.0200E+5, 3.1623E+5, 3.3113E+5, 3.4674E+5,
+ 3.6308E+5, 3.8019E+5, 3.9811E+5, 4.1687E+5, 4.3652E+5, 4.5709E+5,
+ 4.7863E+5, 5.0119E+5, 5.2481E+5, 5.4954E+5, 5.7544E+5, 6.0256E+5,
+ 6.3096E+5, 6.6069E+5, 6.9183E+5, 7.2444E+5, 7.5858E+5, 7.9433E+5,
+ 8.3176E+5, 8.7096E+5, 9.1201E+5, 9.5499E+5, 1.0000E+6, 1.0471E+6,
+ 1.0965E+6, 1.1482E+6, 1.2023E+6, 1.2589E+6, 1.3183E+6, 1.3804E+6,
+ 1.4454E+6, 1.5136E+6, 1.5849E+6, 1.6596E+6, 1.7378E+6, 1.8197E+6,
+ 1.9055E+6, 1.9953E+6, 2.0893E+6, 2.1878E+6, 2.2909E+6, 2.3988E+6,
+ 2.5119E+6, 2.6303E+6, 2.7542E+6, 2.8840E+6, 3.0200E+6, 3.1623E+6,
+ 3.3113E+6, 3.4674E+6, 3.6308E+6, 3.8019E+6, 3.9811E+6, 4.1687E+6,
+ 4.3652E+6, 4.5709E+6, 4.7863E+6, 5.0119E+6, 5.2481E+6, 5.4954E+6,
+ 5.7544E+6, 6.0256E+6, 6.3096E+6, 6.6069E+6, 6.9183E+6, 7.2444E+6,
+ 7.5858E+6, 7.9433E+6, 8.3176E+6, 8.7096E+6, 9.1201E+6, 9.5499E+6,
+ 1.0000E+7, 1.0200E+7, 1.0400E+7, 1.0600E+7, 1.0800E+7, 1.1000E+7,
+ 1.1200E+7, 1.1400E+7, 1.1600E+7, 1.1800E+7, 1.2000E+7, 1.2200E+7,
+ 1.2400E+7, 1.2600E+7, 1.2800E+7, 1.3000E+7, 1.3200E+7, 1.3400E+7,
+ 1.3600E+7, 1.3800E+7, 1.4000E+7, 1.4200E+7, 1.4400E+7, 1.4600E+7,
+ 1.4800E+7, 1.5000E+7, 1.5200E+7, 1.5400E+7, 1.5600E+7, 1.5800E+7,
+ 1.6000E+7, 1.6200E+7, 1.6400E+7, 1.6600E+7, 1.6800E+7, 1.7000E+7,
+ 1.7200E+7, 1.7400E+7, 1.7600E+7, 1.7800E+7, 1.8000E+7, 1.8200E+7,
+ 1.8400E+7, 1.8600E+7, 1.8800E+7, 1.9000E+7, 1.9200E+7, 1.9400E+7,
+ 1.9600E+7, 1.9800E+7, 2.0000E+7, 2.1000E+7, 2.2000E+7, 2.3000E+7,
+ 2.4000E+7, 2.5000E+7, 2.6000E+7, 2.7000E+7, 2.8000E+7, 2.9000E+7,
+ 3.0000E+7, 3.2000E+7, 3.4000E+7, 3.6000E+7, 3.8000E+7, 4.0000E+7,
+ 4.2000E+7, 4.4000E+7, 4.6000E+7, 4.8000E+7, 5.0000E+7, 5.2000E+7,
+ 5.4000E+7, 5.6000E+7, 5.8000E+7, 6.0000E+7, 6.5000E+7, 7.0000E+7,
+ 7.5000E+7, 8.0000E+7, 9.0000E+7, 1.0000E+8, 1.1000E+8, 1.2000E+8,
+ 1.3000E+8, 1.4000E+8, 1.5000E+8, 1.6000E+8, 1.8000E+8, 2.0000E+8,
+ 2.4000E+8, 2.8000E+8, 3.2000E+8, 3.6000E+8, 4.0000E+8, 4.4000E+8,
+ 4.8000E+8, 5.2000E+8, 5.6000E+8, 6.0000E+8, 6.4000E+8, 6.8000E+8,
+ 7.2000E+8, 7.6000E+8, 8.0000E+8, 8.4000E+8, 8.8000E+8, 9.2000E+8,
+ 9.6000E+8, 1.0000E+9}}};
+
+}; // namespace energy_groups
+}; // namespace utils
+//
+//
diff --git a/include/utils/HDF5Utils.h b/include/utils/HDF5Utils.h
new file mode 100644
index 0000000..e3c74eb
--- /dev/null
+++ b/include/utils/HDF5Utils.h
@@ -0,0 +1,98 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "MooseError.h"
+
+#include "hdf5.h"
+#include "hdf5_hl.h"
+
+namespace hdf5_utils {
+
+/*
+ *Check an attribute exists for a given object, using the object id and the
+ *name of the attribute
+ *
+ *
+ **/
+bool attribute_exists(hid_t obj_id, const char *name);
+/***/
+bool object_exists(hid_t object_id, const char *name);
+
+/*
+ * Get the shape of an object
+ *
+ *
+ **/
+void get_shape(hid_t obj_id, hsize_t *dims);
+
+std::string object_name(hid_t obj_id);
+/***/
+void ensure_exists(hid_t obj_id, const char *name, bool attribute = false);
+
+/***/
+hid_t file_open(const char *filename, char mode, bool parallel,
+ const MPI_Comm &comm);
+
+/***/
+void file_close(hid_t file_id);
+
+/***/
+
+hid_t open_dataset(hid_t group_id, const char *name);
+
+void close_dataset(hid_t dataset_id);
+
+hid_t open_group(hid_t group_id, const char *name);
+
+hid_t open_group(hid_t group_id, const std::string &name);
+
+void close_group(hid_t group_id);
+
+void read_dataset_lowlevel(hid_t obj_id, const char *name, hid_t mem_type_id,
+ hid_t mem_space_id, void *buffer, bool parallel,
+ bool indep = true, hid_t file_space_id = H5S_ALL);
+
+void write_dataset_lowlevel(hid_t obj_id, const char *name, int ndim,
+ const hsize_t *dims, hid_t mem_type_id,
+ void *buffer, bool parallel, bool indep = true,
+ hid_t file_space_id = H5S_ALL);
+
+void read_double(hid_t obj_id, const char *name, double *buffer, bool parallel,
+ bool indep = true);
+
+void read_int(hid_t obj_id, const char *name, int *buffer, bool parallel,
+ bool indep = true);
+
+void read_string(hid_t obj_id, const char *name,
+ std::vector &buffer, int slen, bool parallel,
+ bool indep = true);
+
+bool using_mpio_device(hid_t obj_id);
+
+void read_double_hyperslab(hid_t group_id, const char *name, hsize_t rank,
+ hsize_t dims[], hsize_t start[], hsize_t count[],
+ double *results, bool parallel = true,
+ bool indep = true);
+
+void write_double_hyperslab(hid_t obj_id, const char *name, hsize_t ndim,
+ hsize_t dims[3], hsize_t start[], hsize_t count[],
+ double *results, bool parallel = true,
+ bool indep = true);
+} // namespace hdf5_utils
diff --git a/include/utils/PhotonSharingData.h b/include/utils/PhotonSharingData.h
new file mode 100644
index 0000000..6996b9f
--- /dev/null
+++ b/include/utils/PhotonSharingData.h
@@ -0,0 +1,150 @@
+#ifndef PHOTON_SHARING_DATA_H
+#define PHOTON_SHARING_DATA_H
+
+#include "boost/interprocess/containers/map.hpp"
+#include "boost/interprocess/containers/vector.hpp"
+#include "boost/interprocess/managed_shared_memory.hpp"
+#include "boost/interprocess/shared_memory_object.hpp"
+
+#include
+#include
+#include