Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cad_geometry_example #29

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from 20 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions doc/content/bib/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,45 @@ @article{gall2024verification
year={2024},
publisher={ANS PBNC Conference}
}

@article{novak2022_cardinal,
author = {A.J. Novak and D. Andrs and P. Shriwise and J. Fang and H. Yuan and D. Shaver and E. Merzari and P.K. Romano and R.C. Martineau},
title = {{Coupled {Monte} {Carlo} and Thermal-Fluid Modeling of High Temperature Gas Reactors Using {Cardinal}}},
journal = {Annals of Nuclear Energy},
year = 2022,
volume = 177,
pages = {109310},
DOI = {10.1016/j.anucene.2022.109310},
url = {https://www.sciencedirect.com/science/article/pii/S0306454922003450}
}

@article{giudicelli2024moose,
title = {3.0 - {MOOSE}: Enabling massively parallel multiphysics simulations},
author = {Guillaume Giudicelli and Alexander Lindsay and Logan Harbour and Casey Icenhour and
Mengnan Li and Joshua E. Hansel and Peter German and Patrick Behne and Oana Marin and
Roy H. Stogner and Jason M. Miller and Daniel Schwen and Yaqi Wang and Lynn Munday and
Sebastian Schunert and Benjamin W. Spencer and Dewen Yushu and Antonio Recuero and
Zachary M. Prince and Max Nezdyur and Tianchen Hu and Yinbin Miao and
Yeon Sang Jung and Christopher Matthews and April Novak and Brandon Langley and
Timothy Truster and Nuno Nobre and Brian Alger and David Andr{\v{s}} and
Fande Kong and Robert Carlsen and Andrew E. Slaughter and John W. Peterson and
Derek Gaston and Cody Permann},
year = {2024},
journal = {{SoftwareX}},
volume = {26},
pages = {101690},
issn = {2352-7110},
doi = {https://doi.org/10.1016/j.softx.2024.101690},
url = {https://www.sciencedirect.com/science/article/pii/S235271102400061X},
keywords = {Framework, Finite-element, Finite-volume, Parallel, Multiphysics, Multiscale},
}

@Article{openmc,
author = {P.K. Romano and N.E. Horelik and B.R. Herman and A.G. Nelson and B. Forget and K. Smith},
title = {{OpenMC: A State-of-the-Art {Monte} {Carlo} Code for Research and Development}},
journal = {Annals of Nuclear Energy},
year = 2015,
volume = 82,
pages = {90--97},
DOI = {10.1016/j.anucene.2014.07.048}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# CAD-based Geometry Workflow for Multiphysics Fusion Problems Using OpenMC and MOOSE

This demonstration describes a workflow for modeling fusion problems in OpenMC and MOOSE using a computer aided design (CAD)-based geometry workflow.
It is based on the work published in [!cite](Eltawila2024PBNC).

In this example, you'll learn how to:

- Couple OpenMC [!cite](openmc) and MOOSE [!cite](giudicelli2024moose) using Cardinal for fixed source Monte Carlo calculations.
- Use Cardinal [!cite](novak2022_cardinal) to tally values of interest such as tritium production and heating which would be used in MOOSE to solve for the temperature distribution

!media figures/transfers.png
id=transfers
caption=OpenMC and MOOSE Coupling
style=width:60%;margin-left:auto;margin-right:auto

An extremely simplified tokamak was modeled in CAD and was considered for this example. The meshed geometry was prepared using direct accelerated geometry Monte Carlo (DAGMC) for particle transport, and a volumetric mesh was also prepared to be used in MOOSE’s finite element solver and to tally OpenMC results for heat source distribution and tritium production. Cardinal was used to run OpenMC Monte Carlo particle transport within MOOSE framework. The data transfer system transfered heat source and temperature distribution between OpenMC and MOOSE as shown in Figure 1, with coupling between neutron transport and heat conduction achieved via Picard iteration.
meltawila marked this conversation as resolved.
Show resolved Hide resolved

## Generating the meshes

The CAD model was first developed in FUSION360 and was imported into Cubit to assign blocks, materials, and side sets and generate the mesh (Figure 2). A corresponding DAGMC surface mesh (Figure 3) was exported directly from the meshed geometry in Cubit (by loading the volumetric meshed geometry in Cubit and exporting a DAGMC surface mesh).
meltawila marked this conversation as resolved.
Show resolved Hide resolved

In this example, `tmesh_1.e` (Figure 2) is the finite element mesh used in MOOSE on which the heat conduction physics is solved. `tmesh_1.h5m` (Figure 3) is the DAGMC surface mesh used for particle transport in OpenMC (which bounds the surfaces between different materials). Cardinal also allows for mesh tallying for tallying OpenMC results directly on the mesh overlayed on the OpenMC geometry which `tmesh_1.e` (Figure 2) could be used for as well as an unstructered volume mesh. This could be used by changing the tally type and adding a mesh template (`tally_type = mesh`, `mesh_template = tmesh_1.e`) in Cardinal input under Problem.
meltawila marked this conversation as resolved.
Show resolved Hide resolved

 

!row! style=display:inline-flex;
!col! small=12 medium=4 large=3

!media figures/mesh_1.png style=width:130%;display:block;
id=volumetric_mesh caption=Volumetric mesh
meltawila marked this conversation as resolved.
Show resolved Hide resolved

!col-end!

!col! small=12 medium=4 large=3

!media figures/d1.png style=width:130%;display:block;
id=dagmc caption=DAGMC mesh
meltawila marked this conversation as resolved.
Show resolved Hide resolved

!col-end!
!row-end!

## OpenMC

!listing /test/tests/cad_geometry_example/model.py language=python
meltawila marked this conversation as resolved.
Show resolved Hide resolved

## Cardinal

!listing /test/tests/cad_geometry_example/openmc.i
meltawila marked this conversation as resolved.
Show resolved Hide resolved

## MOOSE Heat transfer
meltawila marked this conversation as resolved.
Show resolved Hide resolved

!listing /test/tests/cad_geometry_example/solid.i
meltawila marked this conversation as resolved.
Show resolved Hide resolved

## Execution

To run the coupled calculation:

```
mpiexec -np 2 cardinal-opt -i solid.i --n-threads=2
meltawila marked this conversation as resolved.
Show resolved Hide resolved
```

This will run both MOOSE and OpenMC with 2 MPI processes and 2 OpenMP threads per rank. To run the simulation faster, you can increase the parallel processes/threads, or simply decrease the number of particles used in OpenMC. When the simulation has completed, you will have created a number of different output files:
meltawila marked this conversation as resolved.
Show resolved Hide resolved

- `solid_out.e`, an Exodus output with the solid mesh and solution
meltawila marked this conversation as resolved.
Show resolved Hide resolved
- `solid_out_openmc0.e`, an Exodus output with the OpenMC solution and the data that was ultimately transferred in/out of OpenMC

## Results

 

meltawila marked this conversation as resolved.
Show resolved Hide resolved
!row! style=display:inline-flex;
!col! small=12 medium=4 large=3

!media figures/Temps.png style=width:130%;display:block;
id=temps caption=Temperature distribution
meltawila marked this conversation as resolved.
Show resolved Hide resolved

!col-end!

!col! small=12 medium=4 large=3

!media figures/tritium_production.png style=width:130%;display:block;
id=h3production caption=Tritium production rate density
meltawila marked this conversation as resolved.
Show resolved Hide resolved

!col-end!
!row-end!

 

!table id=results caption=Results summary
| Parameter | Value |
meltawila marked this conversation as resolved.
Show resolved Hide resolved
| :- | :- |
| Armor Max. Temp. (K) | 1062.4 |
| First Wall Max. Temp. (K) | 1057.6 |
| Breeder Max. Temp. (K) | 987.4 |
| Heat Source (W) | 2.44 × 10^5^ ± 3 × 10^3^ |
| Tritium Production (atoms/s) | 4.70 × 10^13^ ± 8 × 10^11^ |

 
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions doc/content/verification_validation_examples/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,5 @@ FENIX is under active development and does not currently have any benchmarking c

# List of example cases

!alert construction title=Under development - no example cases are available yet
FENIX is under active development and does not currently have any example cases available to users.
[CAD-based geometry workflow example](cad_geometry_model/cad_model.md)
meltawila marked this conversation as resolved.
Show resolved Hide resolved

100 changes: 100 additions & 0 deletions test/tests/cad_geometry_example/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import openmc
import math

mat1 = openmc.Material(name="mat1")
mat1.set_density('g/cc', 19.30)
mat1.add_element('W', 1.0)

eurofer = openmc.Material(name="eurofer")
eurofer.add_element('Fe', 0.011 , 'wo')
eurofer.add_element('Al', 0.002 , 'wo')
eurofer.add_element('As', 0.0002 , 'wo')
eurofer.add_element('B', 0.0012 , 'wo')
eurofer.add_element('C', 0.0005 , 'wo')
eurofer.add_element('Co', 0.0005 , 'wo')
eurofer.add_element('Cr', 0.0005 , 'wo')
eurofer.add_element('Cu', 0.00005 , 'wo')
eurofer.add_element('Mn', 0.00005 , 'wo')
eurofer.add_element('Mo', 0.0001 , 'wo')
eurofer.add_element('N', 0.0001 , 'wo')
eurofer.add_element('Nb', 0.00005 , 'wo')
eurofer.add_element('Ni', 0.0003 , 'wo')
eurofer.add_element('O', 0.00005 , 'wo')
eurofer.add_element('P', 0.004 , 'wo')
eurofer.add_element('S', 0.0001 , 'wo')
eurofer.add_element('Sb', 0.09 , 'wo')
eurofer.add_element('Sn', 0.0001 , 'wo')
eurofer.add_element('Si', 0.0011 , 'wo')
eurofer.add_element('Ta', 0.00002 , 'wo')
eurofer.add_element('Ti', 0.0005 , 'wo')
eurofer.add_element('V', 0 , 'wo')
eurofer.add_element('W', 0.0001 , 'wo')
eurofer.add_element('Zr', 0.88698 , 'wo')
eurofer.set_density("g/cm3", 7.798)

Helium = openmc.Material(name="Helium")
Helium.add_element('He', 1.0)
Helium.set_density("kg/m3", 0.166)

mat2 = openmc.Material.mix_materials([eurofer, Helium], [0.65, 0.35], 'ao')

beryllium = openmc.Material(name="beryllium")
beryllium.add_element('Be', 1.0)
beryllium.set_density("g/cm3", 1.85)

Li4SiO4 = openmc.Material(name="Li4SiO4")
Li4SiO4.add_element('Li', 4.0)
Li4SiO4.add_element('Si', 1.0)
Li4SiO4.add_element('O', 4.0)
Li4SiO4.set_density("g/cm3", 2.39)

mat3 = openmc.Material.mix_materials([eurofer, beryllium, Li4SiO4, Helium], [0.1, 0.37, 0.15, 0.38], 'ao')

mats = openmc.Materials([mat1, eurofer, Helium, mat2, beryllium, Li4SiO4, mat3])
mats.export_to_xml()

pz = openmc.Plot()
pz.basis = 'yz'
pz.origin = (0.0, 0.0, 0.0)
pz.width = (200.0, 200.0)
pz.pixels = (500, 500)
pz.color_by = 'material'

px = openmc.Plot()
px.basis = 'xy'
px.origin = (0.0, 0.0, 0.0)
px.width = (200, 200)
px.pixels = (500, 500)
px.color_by = 'material'

plots = openmc.Plots([pz,px])
plots.export_to_xml()

settings = openmc.Settings()
settings.dagmc = True
settings.batches = 100
settings.particles = 10000000
settings.run_mode = "fixed source"

settings.temperature = {'default': 800.0,
'method': 'interpolation',
'range': (294.0, 3000.0),
'tolerance': 1000.0}

source = openmc.Source()

r = openmc.stats.PowerLaw(55, 65, 1.0)
phi = openmc.stats.Uniform(0.0, 2*math.pi)
z = openmc.stats.Discrete([0,], [1.0,])
spatial_dist = openmc.stats.CylindricalIndependent(r, phi, z)

source.angle = openmc.stats.Isotropic()
source.energy = openmc.stats.Discrete([14.08e6], [1.0])
source.space=spatial_dist
settings.source = source
settings.export_to_xml()

dagmc_univ = openmc.DAGMCUniverse(filename='torus7v2t2.h5m')

geometry = openmc.Geometry(root=dagmc_univ)
geometry.export_to_xml()
83 changes: 83 additions & 0 deletions test/tests/cad_geometry_example/openmc.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
[Mesh]
[file]
type = FileMeshGenerator
file = tmesh_1.e
[]
[]

[AuxVariables]
[cell_temperature]
family = MONOMIAL
order = CONSTANT
[]
[]

[AuxKernels]
[cell_temperature]
type = CellTemperatureAux
variable = cell_temperature
[]
[]

[Problem]
type = OpenMCCellAverageProblem
tally_type = cell
tally_name = 'heat_source H3'
lowest_cell_level = 0
temperature_blocks = '1 2 3'
check_tally_sum = false
source_strength = 1e18 # Particles/sec.
meltawila marked this conversation as resolved.
Show resolved Hide resolved
volume_calculation = vol
tally_score = 'heating_local H3_production'
tally_trigger = 'rel_err none'
tally_trigger_threshold = '0.1 0.1'
verbose = true
max_batches = 10
batch_interval = 5
particles = 5000
output = unrelaxed_tally_std_dev
skinner = moab
[]

[UserObjects]
[vol]
type = OpenMCVolumeCalculation
n_samples = 5000
[]
[moab]
type = MoabSkinner
temperature_min = 800
temperature_max = 1100
n_temperature_bins = 100
temperature = temp
build_graveyard = true
[]
[]

[Postprocessors]
[heat_source]
type = ElementIntegralVariablePostprocessor
variable = heat_source
[]
[tritium_production]
type = ElementIntegralVariablePostprocessor
variable = H3
[]
[tritium_RelativeError]
type = TallyRelativeError
tally_score = h3_production
[]
[heat_source_RelativeError]
type = TallyRelativeError
tally_score = heating_local
[]
[]

[Executioner]
type = Transient
[]

[Outputs]
exodus = true
csv = true
[]
Loading