├── .github └── workflows │ ├── ci_with_docker_build.yml │ ├── ci_with_install.yml │ └── docker_publish.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── environment.yml ├── example_01_single_volume_cell_tally ├── 1_create_cad_and_convert_to_dagmc.py ├── 2_run_neutronics_simulation.py ├── README.md └── run_all.sh ├── example_02_multi_volume_cell_tally ├── 1_create_cad_and_convert_to_dagmc.py ├── 2_run_neutronics_simulation.py ├── README.md └── run_all.sh ├── example_04_multi_volume_regular_mesh_tally ├── 1_create_cad_and_convert_to_dagmc.py ├── 2_run_neutronics_simulation.py ├── 3_post_process_and_plot.py └── run_all.sh └── example_05_3D_unstructured_mesh_tally ├── 1_create_cad_and_convert_to_dagmc.py ├── 2_run_neutronics_simulation.py ├── README.md └── run_all.sh /.github/workflows/ci_with_docker_build.yml: -------------------------------------------------------------------------------- 1 | 2 | # Builds a dockerimage and then runs tests from within the docker enviroment 3 | 4 | name: CI with docker build 5 | on: 6 | pull_request: 7 | branches: 8 | - main # this takes around 90 mins to build the image, hence limiting to occational PRs 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Checkout repository 16 | uses: actions/checkout@v2 17 | 18 | - name: Build and test with Docker 19 | run: | 20 | docker build -t fusion-neutronics-workflow --build-arg cq_version=2.1 --build-arg compile_cores=2 . 21 | 22 | docker run --rm fusion-neutronics-workflow /bin/bash -c "cd examples/example_01_single_volume_cell_tally && bash run_all.sh" 23 | docker run --rm fusion-neutronics-workflow /bin/bash -c "cd examples/example_02_multi_volume_cell_tally && bash run_all.sh" 24 | docker run --rm fusion-neutronics-workflow /bin/bash -c "cd examples/example_04_multi_volume_regular_mesh_tally && bash run_all.sh" 25 | 26 | # commented out as cubit learn license is currently not working 27 | # docker run --rm fusion-neutronics-workflow /bin/bash -c "cd examples/example_05_3D_unstructured_mesh_tally && bash run_all.sh" 28 | -------------------------------------------------------------------------------- /.github/workflows/ci_with_install.yml: -------------------------------------------------------------------------------- 1 | 2 | # This CI will lauch a Docker image that contains all the dependencies required 3 | # within that image the pytest test suite is run 4 | 5 | name: CI with install 6 | 7 | on: 8 | pull_request: 9 | branches: 10 | - develop 11 | - main 12 | 13 | jobs: 14 | testing: 15 | runs-on: ubuntu-latest 16 | container: 17 | image: ghcr.io/fusion-energy/fusion-neutronics-workflow 18 | steps: 19 | - name: Checkout repository 20 | uses: actions/checkout@v2 21 | 22 | - name: run example_01_single_volume_cell_tally 23 | run: | 24 | cd example_01_single_volume_cell_tally 25 | python 1_create_cad_and_convert_to_dagmc.py 26 | python 2_run_neutronics_simulation.py 27 | 28 | - name: run example_02_multi_volume_cell_tally 29 | run: | 30 | cd example_02_multi_volume_cell_tally 31 | python 1_create_cad_and_convert_to_dagmc.py 32 | python 2_run_neutronics_simulation.py 33 | 34 | - name: run example_04_multi_volume_regular_mesh_tally 35 | run: | 36 | cd example_04_multi_volume_regular_mesh_tally 37 | python 1_create_cad_and_convert_to_dagmc.py 38 | python 2_run_neutronics_simulation.py 39 | 40 | # commented out as cubit learn license is not currently working 41 | # - name: run example_05_3D_unstructured_mesh_tally 42 | # run: | 43 | # cd example_05_3D_unstructured_mesh_tally 44 | # python 1_create_cad_and_convert_to_dagmc.py 45 | # mbconvert stage_2_output/unstructured_mesh.cub stage_2_output/unstructured_mesh.h5m 46 | # python 2_run_neutronics_simulation.py 47 | -------------------------------------------------------------------------------- /.github/workflows/docker_publish.yml: -------------------------------------------------------------------------------- 1 | 2 | # This yml file will trigger a Github Action on release creation. 3 | # This Action will build and upload a Docker image to GHCR 4 | # https://github.com/marketplace/actions/publish-docker 5 | 6 | name: docker-publish-release 7 | 8 | on: 9 | workflow_dispatch: 10 | release: 11 | types: [created] 12 | 13 | jobs: 14 | build_and_push_docker_images: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@v2 19 | 20 | - name: Set up QEMU 21 | uses: docker/setup-qemu-action@v1 22 | 23 | - name: Set up Docker Buildx 24 | uses: docker/setup-buildx-action@v1 25 | 26 | - name: Login to GitHub Container Registry 27 | uses: docker/login-action@v1 28 | with: 29 | registry: ghcr.io 30 | username: ${{ github.repository_owner }} 31 | password: ${{ secrets.GITHUB_TOKEN }} 32 | 33 | - name: Cache Docker layers 34 | uses: actions/cache@v2 35 | with: 36 | path: /tmp/.buildx-cache 37 | key: ${{ runner.os }}-single-buildx-${{ github.sha }} 38 | restore-keys: | 39 | ${{ runner.os }}-single-buildx 40 | 41 | - name: Build and push the Docker image 42 | uses: docker/build-push-action@v2 43 | with: 44 | push: true 45 | tags: ghcr.io/fusion-energy/fusion-neutronics-workflow:embree 46 | build-args: | 47 | include_avx=false 48 | build_double_down=ON 49 | cq_version=2.1 50 | compile_cores=2 51 | cache-from: type=local,src=/tmp/.buildx-cache 52 | cache-to: type=local,dest=/tmp/.buildx-cache-new 53 | 54 | # Temp fix 55 | # https://github.com/docker/build-push-action/issues/252 56 | # https://github.com/moby/buildkit/issues/1896 57 | - name: Move cache 58 | run: | 59 | rm -rf /tmp/.buildx-cache 60 | mv /tmp/.buildx-cache-new /tmp/.buildx-cache 61 | 62 | - name: Build and push the Docker image 63 | uses: docker/build-push-action@v2 64 | with: 65 | push: true 66 | tags: ghcr.io/fusion-energy/fusion-neutronics-workflow:embree-avx 67 | build-args: | 68 | include_avx=true 69 | build_double_down=ON 70 | cq_version=2.1 71 | compile_cores=2 72 | 73 | - name: Build and push the Docker image 74 | uses: docker/build-push-action@v2 75 | with: 76 | push: true 77 | tags: ghcr.io/fusion-energy/fusion-neutronics-workflow 78 | build-args: | 79 | include_avx=true 80 | build_double_down=OFF 81 | cq_version=2.1 82 | compile_cores=2 83 | 84 | upload_workflow_output_files_to_release: 85 | needs: build_and_push_docker_images 86 | runs-on: ubuntu-latest 87 | 88 | name: 'create_files' 89 | 90 | container: 91 | image: ghcr.io/fusion-energy/fusion-neutronics-workflow 92 | 93 | steps: 94 | - uses: actions/checkout@v2 95 | 96 | # the examples also appear on the docker image but they are in the 97 | # /examples subfolder so there is no overlap with these examples 98 | - name: run example_01_single_volume_cell_tally 99 | run: | 100 | cd example_01_single_volume_cell_tally 101 | python 1_create_cad_and_convert_to_dagmc.py 102 | python 2_run_neutronics_simulation.py 103 | 104 | - name: run example_02_multi_volume_cell_tally 105 | run: | 106 | cd example_02_multi_volume_cell_tally 107 | python 1_create_cad_and_convert_to_dagmc.py 108 | python 2_run_neutronics_simulation.py 109 | 110 | - name: run example_04_multi_volume_regular_mesh_tally 111 | run: | 112 | cd example_04_multi_volume_regular_mesh_tally 113 | python 1_create_cad_and_convert_to_dagmc.py 114 | python 2_run_neutronics_simulation.py 115 | python 3_post_process_and_plot.py 116 | 117 | # - name: run example_05_3D_unstructured_mesh_tally 118 | # run: | 119 | # cd example_05_3D_unstructured_mesh_tally 120 | # python 1_create_cad_and_convert_to_dagmc.py 121 | # mbconvert stage_2_output/unstructured_mesh.cub stage_2_output/unstructured_mesh.h5m 122 | # python 2_run_neutronics_simulation.py 123 | 124 | - name: compress files 125 | run: | 126 | apt-get -y update 127 | apt-get -y install zip 128 | zip -r output_files_produced.zip example_* 129 | 130 | - name: Upload artifact for CI 131 | uses: actions/upload-artifact@v2 132 | with: 133 | name: output_files_produced.zip 134 | path: output_files_produced.zip 135 | if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn` 136 | 137 | - name: Upload files into the release 138 | uses: svenstaro/upload-release-action@v2 139 | with: 140 | overwrite: true 141 | tag: ${{ github.ref }} 142 | file: output_files_produced.zip 143 | asset_name: output_files_produced.zip 144 | repo_token: ${{ secrets.GITHUB_TOKEN }} 145 | 146 | 147 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | 131 | # Cubit log files 132 | *.log 133 | *.jou 134 | 135 | *.xml 136 | *.h5 137 | *.out 138 | *.json 139 | *.h5m 140 | *.stp 141 | *.cub 142 | *.stl 143 | *.png 144 | *.vtk 145 | *.zip 146 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # This Dockerfile creates an enviroment / dependancies needed to run the 2 | # fusion-neutronics-workflow. 3 | 4 | # This Dockerfile can be build locally or a prebuild image can be downloaded 5 | 6 | # To download the prebuild image 7 | # docker pull ghcr.io/fusion-energy/fusion-neutronics-workflow 8 | # docker pull ghcr.io/fusion-energy/fusion-neutronics-workflow:embree 9 | # docker pull ghcr.io/fusion-energy/fusion-neutronics-workflow:embree-avx 10 | 11 | # To build this Dockerfile into a docker image: 12 | # docker build -t fusion-neutronics-workflow . 13 | 14 | 15 | # To build this Dockerfile with different options --build-arg can be used 16 | # --build-arg compile_cores=1 17 | # int 18 | # number of cores to compile codes with 19 | # --build-arg build_double_down=OFF 20 | # ON OFF 21 | # controls if DAGMC is built with double down (ON) or not (OFF). Note that if double down is OFF then Embree is not included 22 | # --build-arg include_avx=true 23 | # true false 24 | # controls if the Embree is built to use AVX instruction set (true) or not (false). AVX is not supported by all CPUs 25 | 26 | # example builds 27 | # simplest quickest build that does not contain the speed benefits of double down 28 | # docker build -t fusion-neutronics-workflow --build-arg compile_cores=7 --build-arg build_double_down=OFF . 29 | # medium level build that contain some of the speed benefits of double down 30 | # docker build -t fusion-neutronics-workflow:embree-avx --build-arg compile_cores=7 --build-arg build_double_down=ON --build-arg include_avx=false . 31 | # performance level build that contain all of the speed benefits of double down 32 | # docker build -t fusion-neutronics-workflow:embree --build-arg compile_cores=7 --build-arg build_double_down=ON --build-arg include_avx=true . 33 | 34 | # base image contains nuclear data 35 | FROM continuumio/miniconda3:4.10.3 36 | 37 | ARG compile_cores=1 38 | ARG include_avx=true 39 | ARG build_double_down=OFF 40 | 41 | 42 | ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 \ 43 | PATH=/opt/openmc/bin:$PATH \ 44 | LD_LIBRARY_PATH=/opt/openmc/lib:$LD_LIBRARY_PATH \ 45 | CC=/usr/bin/mpicc CXX=/usr/bin/mpicxx \ 46 | DEBIAN_FRONTEND=noninteractive 47 | 48 | RUN apt-get --allow-releaseinfo-change update 49 | RUN apt-get update -y && \ 50 | apt-get upgrade -y 51 | 52 | RUN apt-get install -y libgl1-mesa-glx \ 53 | libgl1-mesa-dev \ 54 | libglu1-mesa-dev \ 55 | freeglut3-dev \ 56 | libosmesa6 \ 57 | libosmesa6-dev \ 58 | libgles2-mesa-dev \ 59 | curl && \ 60 | apt-get clean 61 | 62 | # solves OSError: libXft.so.2: cannot open shared object file: No such file or directory 63 | RUN apt-get install -y libxft2 64 | 65 | # upgrading numpy version 66 | # RUN pip install "numpy>=1.21.4,<1.30" cython 67 | RUN pip install cython 68 | RUN conda install -c anaconda numpy==1.21.2 69 | 70 | # Installing CadQuery add on 71 | RUN pip install jupyter-cadquery==3.0.0 72 | 73 | # Install neutronics dependencies from Debian package manager 74 | RUN apt-get install -y \ 75 | wget \ 76 | git \ 77 | gfortran \ 78 | g++ \ 79 | cmake \ 80 | mpich \ 81 | libmpich-dev \ 82 | libhdf5-serial-dev \ 83 | libhdf5-mpich-dev \ 84 | imagemagick 85 | 86 | 87 | # install addition packages required for MOAB 88 | RUN apt-get --yes install libeigen3-dev && \ 89 | apt-get --yes install libblas-dev && \ 90 | apt-get --yes install liblapack-dev && \ 91 | apt-get --yes install libnetcdf-dev && \ 92 | apt-get --yes install libtbb-dev && \ 93 | apt-get --yes install libglfw3-dev 94 | 95 | 96 | # Clone and install Embree 97 | # embree from conda is not supported yet 98 | # conda install -c conda-forge embree >> version: 2.17.7 99 | # requested version "3.6.1" 100 | # added following two lines to allow use on AMD CPUs see discussion 101 | # https://openmc.discourse.group/t/dagmc-geometry-open-mc-aborted-unexpectedly/1369/24?u=pshriwise 102 | RUN if [ "$build_double_down" = "ON" ] ; \ 103 | then git clone --shallow-submodules --single-branch --branch v3.12.2 --depth 1 https://github.com/embree/embree.git ; \ 104 | cd embree ; \ 105 | mkdir build ; \ 106 | cd build ; \ 107 | if [ "$include_avx" = "false" ] ; \ 108 | then cmake .. -DCMAKE_INSTALL_PREFIX=.. \ 109 | -DEMBREE_ISPC_SUPPORT=OFF \ 110 | -DEMBREE_MAX_ISA=NONE \ 111 | -DEMBREE_ISA_SSE42=ON ; \ 112 | fi ; \ 113 | if [ "$include_avx" = "true" ] ; \ 114 | then cmake .. -DCMAKE_INSTALL_PREFIX=.. \ 115 | -DEMBREE_ISPC_SUPPORT=OFF ; \ 116 | fi ; \ 117 | make -j"$compile_cores" ; \ 118 | make -j"$compile_cores" install ; \ 119 | fi 120 | 121 | # Clone and install MOAB 122 | RUN mkdir MOAB && \ 123 | cd MOAB && \ 124 | mkdir build && \ 125 | git clone --shallow-submodules --single-branch --branch 5.3.1 --depth 1 https://bitbucket.org/fathomteam/moab.git && \ 126 | cd build && \ 127 | cmake ../moab -DENABLE_HDF5=ON \ 128 | -DENABLE_NETCDF=ON \ 129 | -DENABLE_FORTRAN=OFF \ 130 | -DENABLE_BLASLAPACK=OFF \ 131 | -DBUILD_SHARED_LIBS=OFF \ 132 | -DCMAKE_INSTALL_PREFIX=/MOAB && \ 133 | make -j"$compile_cores" && \ 134 | make -j"$compile_cores" install && \ 135 | rm -rf * && \ 136 | cmake ../moab -DENABLE_HDF5=ON \ 137 | -DENABLE_PYMOAB=ON \ 138 | -DENABLE_FORTRAN=OFF \ 139 | -DBUILD_SHARED_LIBS=ON \ 140 | -DENABLE_BLASLAPACK=OFF \ 141 | -DCMAKE_INSTALL_PREFIX=/MOAB && \ 142 | make -j"$compile_cores" && \ 143 | make -j"$compile_cores" install && \ 144 | cd pymoab && \ 145 | bash install.sh && \ 146 | python setup.py install 147 | 148 | 149 | # Clone and install Double-Down 150 | RUN if [ "$build_double_down" = "ON" ] ; \ 151 | then git clone --shallow-submodules --single-branch --branch v1.0.0 --depth 1 https://github.com/pshriwise/double-down.git && \ 152 | cd double-down ; \ 153 | mkdir build ; \ 154 | cd build ; \ 155 | cmake .. -DMOAB_DIR=/MOAB \ 156 | -DCMAKE_INSTALL_PREFIX=.. \ 157 | -DEMBREE_DIR=/embree ; \ 158 | make -j"$compile_cores" ; \ 159 | make -j"$compile_cores" install ; \ 160 | fi 161 | 162 | 163 | # Clone and install DAGMC 164 | RUN mkdir DAGMC && \ 165 | cd DAGMC && \ 166 | git clone --single-branch --branch v3.2.2 --depth 1 https://github.com/svalinn/DAGMC.git && \ 167 | mkdir build && \ 168 | cd build && \ 169 | cmake ../DAGMC -DBUILD_TALLY=ON \ 170 | -DMOAB_DIR=/MOAB \ 171 | -DDOUBLE_DOWN=${build_double_down} \ 172 | -DBUILD_STATIC_EXE=OFF \ 173 | -DBUILD_STATIC_LIBS=OFF \ 174 | -DCMAKE_INSTALL_PREFIX=/DAGMC/ \ 175 | -DDOUBLE_DOWN_DIR=/double-down && \ 176 | make -j"$compile_cores" install && \ 177 | rm -rf /DAGMC/DAGMC /DAGMC/build 178 | 179 | # Clone OpenMC and install OpenMC with DAGMC 180 | RUN cd /opt && \ 181 | git clone --single-branch --branch v0.13.0 --depth 1 https://github.com/openmc-dev/openmc.git && \ 182 | cd openmc && \ 183 | cd /opt/openmc && \ 184 | mkdir build && \ 185 | cd build && \ 186 | cmake -Doptimize=on \ 187 | -Ddagmc=ON \ 188 | -DDAGMC_DIR=/DAGMC/ \ 189 | -DHDF5_PREFER_PARALLEL=on .. && \ 190 | make -j"$compile_cores" && \ 191 | make -j"$compile_cores" install && \ 192 | cd .. && \ 193 | pip install -e .[test] 194 | 195 | COPY environment.yml . 196 | RUN conda env update -f environment.yml 197 | 198 | # downloads nuclear data from zip file an uncompress 199 | # RUN download_nndc 200 | 201 | # this is an optional way to install python packages and nuclear data (quick as it does not overwrite existing h5 files) 202 | RUN openmc_data_downloader -d nuclear_data -e all -i H3 -l ENDFB-7.1-NNDC TENDL-2019 -p neutron photon --no-overwrite 203 | 204 | # setting enviromental varibles 205 | ENV OPENMC_CROSS_SECTIONS=/nuclear_data/cross_sections.xml 206 | # ENV OPENMC_CROSS_SECTIONS=/nndc-b7.1-hdf5/endfb71_hdf5/cross_sections.xml 207 | ENV PATH="/MOAB/build/bin:${PATH}" 208 | ENV PATH="/DAGMC/bin:${PATH}" 209 | 210 | RUN mkdir /home/fusion-neutronics-workflow 211 | EXPOSE 8888 212 | WORKDIR /home/fusion-neutronics-workflow 213 | 214 | # subfolder used to avoid overlapping with the testing of examples in GH actions 215 | RUN mkdir examples 216 | COPY example_01_single_volume_cell_tally examples/example_01_single_volume_cell_tally/ 217 | COPY example_02_multi_volume_cell_tally examples/example_02_multi_volume_cell_tally/ 218 | COPY example_04_multi_volume_regular_mesh_tally examples/example_04_multi_volume_regular_mesh_tally/ 219 | COPY example_05_3D_unstructured_mesh_tally examples/example_05_3D_unstructured_mesh_tally/ 220 | 221 | 222 | #this sets the port, gcr looks for this varible 223 | ENV PORT 8888 224 | 225 | # could switch to --ip='*' 226 | # CMD ["jupyter", "notebook", "--notebook-dir=/tasks", "--port=8888", "--no-browser", "--ip=0.0.0.0", "--allow-root"] 227 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Fusion Energy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![CI with docker build](https://github.com/fusion-energy/fusion_neutronics_workflow/actions/workflows/ci_with_docker_build.yml/badge.svg)](https://github.com/fusion-energy/fusion_neutronics_workflow/actions/workflows/ci_with_docker_build.yml) 2 | 3 | [![CI with install](https://github.com/fusion-energy/fusion_neutronics_workflow/actions/workflows/ci_with_install.yml/badge.svg)](https://github.com/fusion-energy/fusion_neutronics_workflow/actions/workflows/ci_with_install.yml) 4 | 5 | [![docker-publish-release](https://github.com/fusion-energy/fusion_neutronics_workflow/actions/workflows/docker_publish.yml/badge.svg?event=release)](https://github.com/fusion-energy/fusion_neutronics_workflow/actions/workflows/docker_publish.yml) 6 | 7 | 8 | # Fusion Neutronics Workflow 9 | 10 | ![fusion neutronics workflow](https://user-images.githubusercontent.com/8583900/150701623-29fbf50b-0203-4818-b318-2f3a996e1db7.png) 11 | 12 | Diagram showing the connectivity of software packages that make up the Fusion 13 | Neutronics Workflow. Software that the user interacts with directly are shown 14 | in blue. 15 | 16 | This repository contains a containerized neutronics workflow for carrying out 17 | standard neutronics simulations in a repeatable manner. 18 | 19 | There are workflows for producing standard neutronics simulations such as dose 20 | maps, DPA tallies, neutron/photon spectra, 3D VTK visualizations and the aim is 21 | to provide working examples for mainstream fusion neutronics analysis. 22 | Contributions are welcome. 23 | 24 | This repository combines the several packages to create neutronics workflow 25 | that is: 26 | 27 | - Automated - the entire workflow can be run automatically. Care has been taken 28 | to code out all manual processes so that the neutronics analysis can be 29 | performed in an API manner. As a result it is therefore possible to drive 30 | the workflow with machine learning, optimization or parameter space 31 | sampling methods. 32 | - Scalable - by using efficient interfaces (Embree, Double Down) and 33 | accelerated geometry (DAGMC) together with scalable Monte Carlo transport 34 | (OpenMC) the resulting workflow scales well with computational power. 35 | - Deployable - By integrating open source software preferentially and ensuring 36 | compatibility with containerization the combined workflow is straight 37 | forward to deploy. Instances have been run everywhere from cloud computing 38 | to local compute. 39 | - Modular - individual packages created as part of the workflow are all 40 | available to install via PyPi pip installers or Conda installs. This allows 41 | separate components of the workflow to be easily installed as well as the 42 | workflow asa whole. All interfaces are exposed and there is no vendor lock 43 | in for any aspect. 44 | - Documented - documentation of installation procedures, use cases, examples, 45 | tutorials and even demonstration videos are all available. 46 | 47 | # Dockerfile 48 | 49 | ## Quick start 50 | 51 | The Dockerfile can build locally or a prebuilt one can be downloaded with 52 | ```bash 53 | docker pull ghcr.io/fusion-energy/fusion-neutronics-workflow 54 | ``` 55 | 56 | The docker image can then be run with 57 | ```bash 58 | docker run -it ghcr.io/fusion-energy/fusion-neutronics-workflow 59 | ``` 60 | 61 | ## Sharing files 62 | 63 | To map a local folder to the docker container a volume mount can be used. 64 | The following example mounts the local folder that the command is being run from with the ```/home/fusion-neutronics-workflow/examples``` that is inside the docker 65 | images 66 | ```bash 67 | docker run -it -v $PWD:/home/fusion-neutronics-workflow/examples ghcr.io/fusion-energy/fusion-neutronics-workflow 68 | ``` 69 | 70 | ## Performance builds 71 | 72 | There are additional higher performance docker images available if your CPU 73 | supports vectorization instructions available Embree. 74 | 75 | Download a prebuilt docker image with Embree and Double Down enabled 76 | ```bash 77 | docker pull ghcr.io/fusion-energy/fusion-neutronics-workflow:embree 78 | ``` 79 | 80 | Download a prebuilt docker image with Embree compiled with AVX instruction set and Double Down enabled 81 | ```bash 82 | docker pull ghcr.io/fusion-energy/fusion-neutronics-workflow:embree-avx 83 | ``` 84 | 85 | 86 | # Software Packages included 87 | 88 | Links to the packages that are utilized by the fusion-neutronics-workflow 89 | 90 | * Open source projects created and maintained 91 | 92 | * [Paramak](https://github.com/fusion-energy/paramak) - 93 | automated production of fusion reactor CAD models (stp and stl files) from 94 | parameters. 95 | 96 | * [stl_to_h5m](https://github.com/fusion-energy/stl_to_h5m) automated 97 | conversion of STL files to h5m files compatible with DAGMC enabled 98 | particle transport codes. 99 | 100 | * [openmc_dagmc_wrapper](https://github.com/fusion-energy/openmc-dagmc-wrapper) 101 | allows one to quickly utilise the h5m geometry files in a range of 102 | standard OpenMC based neutronics simulations. 103 | 104 | * [neutronics-material-maker](https://github.com/fusion-energy/neutronics_material_maker) 105 | Create and customise materials from an internal database or from your own 106 | recipe, export to a wide range of neutronics codes. 107 | 108 | * [openmc_tally_unit_converter](https://github.com/openmc-data-storage/openmc_tally_unit_converter) converts the units of common tally such as 109 | heating, DPA, effective dose into user specified units. 110 | 111 | * [openmc_data_downloader](https://github.com/openmc-data-storage/openmc_data_downloader) performs on the fly downloading of nuclear data needed for OpenMC neutronics simulations. 112 | 113 | * [openmc_data](https://github.com/openmc-data-storage/openmc_data) downloading and processing of nuclear data needed for OpenMC neutronics simulations. 114 | 115 | * [openmc-plasma-source](https://github.com/fusion-energy/openmc-plasma-source/) 116 | Creates a plasma source as an openmc.source object from input parameters that describe the plasma 117 | 118 | * [spectrum_plotter](https://github.com/fusion-energy/spectrum_plotter) 119 | A Python package for creating publication quality plots for neutron / photon / particle spectrum 120 | 121 | * [openmc_mesh_tally_to_vtk](https://github.com/fusion-energy/openmc_mesh_tally_to_vtk) 122 | A Python package for converting OpenMC mesh tallies to VTK files and optionally converting the units 123 | 124 | * [regular_mesh_plotter](https://github.com/fusion-energy/regular_mesh_plotter) 125 | A Python package for plotting regular mesh tally results from neutronics simulations. 126 | 127 | * [dagmc_geometry_slice_plotter](https://github.com/fusion-energy/dagmc_geometry_slice_plotter) A minimal Python package that produces slice plots through h5m DAGMC geometry files 128 | 129 | * [dagmc_bounding_box](https://github.com/fusion-energy/dagmc_bounding_box) 130 | Finds the bounding box and related properties of a DAGMC geometry 131 | 132 | * [remove_dagmc_tags](https://github.com/svalinn/remove_dagmc_tags) A python package and command line tool for removing DAGMC tags such as graveyard and vacuum 133 | 134 | * [dagmc_h5m_file_inspector](https://github.com/fusion-energy/dagmc_h5m_file_inspector) 135 | Extracts information from DAGMC h5m files including volumes number, material tags 136 | 137 | * [brep_to_h5m](https://github.com/fusion-energy/brep_to_h5m) Converts Brep CAD geometry files to h5m geometry files compatible with DAGMC simulations 138 | 139 | * [brep_part_finder](https://github.com/fusion-energy/brep_part_finder) A Python package to identify the part ID number in Brep format CAD files 140 | 141 | * Open source projects that are utilized and contributed to 142 | 143 | * [OpenMC](https://github.com/openmc-dev/openmc) The OpenMC project, a 144 | Monte Carlo particle transport code based on modern methods. 145 | 146 | * [DAGMC](https://github.com/svalinn/DAGMC) Direct Accelerated Geometry 147 | Monte Carlo Toolkit 148 | 149 | * [SphinxCadQuery](https://github.com/CadQuery/sphinxcadquery) An extension to visualize CadQuery 3D files in your Sphinx documentation 150 | 151 | 152 | * Open source projects utilized in the software stack 153 | 154 | * [MOAB and pymoab](https://github.com/svalinn/Cubit-plugin/) the 155 | Mesh-Oriented datABase MOAB is a component for representing and evaluating 156 | mesh data. 157 | 158 | * [CadQuery](https://github.com/cadquery/cadquery) A python parametric CAD 159 | scripting framework based on OCCT 160 | 161 | * [Double-Down](https://github.com/pshriwise/double-down) A double precision 162 | interface to Embree via the Mesh Oriented dAtaBase (MOAB). 163 | 164 | * [Embree](https://github.com/embree/embree) high-performance ray tracing 165 | kernels 166 | 167 | * [Gmsh](https://gitlab.onelab.info/gmsh/gmsh) A three-dimensional finite 168 | element mesh generator with built-in pre- and post-processing facilities 169 | 170 | * Scipy, Numpy, Plotly, Pint and other standard scientific Python packages 171 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: base 2 | channels: 3 | - fusion-energy 4 | - cadquery 5 | - conda-forge 6 | dependencies: 7 | - paramak>=0.8.1 8 | - pip 9 | - pip: 10 | - openmc-dagmc-wrapper 11 | - openmc-plasma-source 12 | - openmc_tally_unit_converter 13 | - spectrum_plotter 14 | - regular_mesh_plotter 15 | - openmc_data_downloader 16 | - openmc_data 17 | -------------------------------------------------------------------------------- /example_01_single_volume_cell_tally/1_create_cad_and_convert_to_dagmc.py: -------------------------------------------------------------------------------- 1 | # This minimal example makes a 3D volume and exports the shape to a stp file 2 | # A surrounding volume called a graveyard is needed for neutronics simulations 3 | 4 | import paramak 5 | import os 6 | 7 | my_shape = paramak.ExtrudeStraightShape( 8 | name='my_material', 9 | points=[(400, 100), (400, 200), (600, 200), (600, 100)], 10 | distance=180, 11 | ) 12 | 13 | my_shape.export_dagmc_h5m('dagmc.h5m') 14 | 15 | # this converts the neutronics geometry h5m file into a vtk file for 16 | # visualisation in Paraview or Visit 17 | os.system('mbconvert dagmc.h5m dagmc.vtk') 18 | -------------------------------------------------------------------------------- /example_01_single_volume_cell_tally/2_run_neutronics_simulation.py: -------------------------------------------------------------------------------- 1 | # makes use of the previously created neutronics geometry (h5m file) and assigns 2 | # actual materials to the material tags. Sets simulation intensity and specifies 3 | # the neutronics results to record (know as tallies). 4 | 5 | import openmc 6 | import openmc_dagmc_wrapper as odw 7 | import openmc_plasma_source as ops 8 | import openmc_tally_unit_converter as otuc 9 | from spectrum_plotter import plot_spectrum_from_tally 10 | 11 | 12 | # defines a simple DT neutron point source 13 | my_source = ops.FusionPointSource(coordinate=(0, 0, 0), temperature=20000.0, fuel="DT") 14 | 15 | # set the geometry file to use 16 | geometry = odw.Geometry( 17 | h5m_filename="dagmc.h5m", 18 | ) 19 | 20 | # sets the material to use 21 | materials = odw.Materials( 22 | h5m_filename="dagmc.h5m", correspondence_dict={"my_material": "eurofer"} 23 | ) 24 | 25 | # creates a cell tally for neutron flux 26 | tally1 = odw.CellTally( 27 | tally_type="neutron_flux", target="my_material", materials=materials 28 | ) 29 | 30 | # creates a cell tally for neutron spectra 31 | tally2 = odw.CellTally( 32 | tally_type="neutron_spectra", target="my_material", materials=materials 33 | ) 34 | 35 | tallies = openmc.Tallies([tally1, tally2]) 36 | 37 | settings = odw.FusionSettings() 38 | settings.batches = 1 39 | settings.particles = 50000 40 | 41 | # assigns a ring source of DT energy neutrons to the source using the 42 | # openmc_plasma_source package 43 | settings.source = ops.FusionRingSource(fuel="DT", radius=350) 44 | 45 | 46 | my_model = openmc.Model( 47 | materials=materials, geometry=geometry, settings=settings, tallies=tallies 48 | ) 49 | 50 | # starts the simulation 51 | statepoint_file = my_model.run() 52 | 53 | # loads up the statepoint file with simulation results 54 | statepoint = openmc.StatePoint(filepath=statepoint_file) 55 | 56 | # gets the first tally using its name 57 | my_tally_1 = statepoint.get_tally(name="my_material_neutron_flux") 58 | 59 | # gets number of neutron for a 1.3 mega joule shot 60 | source_strength = otuc.find_source_strength(fusion_energy_per_second_or_per_pulse=1.3e6) 61 | 62 | # converts the flux units of the tally 63 | result = otuc.process_tally( 64 | source_strength=source_strength, 65 | tally=my_tally_1, 66 | required_units="centimeter / second", 67 | ) 68 | 69 | print(f"flux per second = {result}", end="\n\n") 70 | 71 | # gets the second tally using its name 72 | my_tally_2 = statepoint.get_tally(name="my_material_neutron_spectra") 73 | 74 | # returns the tally converted to MeV, scaled and normalisation for source strength 75 | result = otuc.process_spectra_tally( 76 | tally=my_tally_2, 77 | required_units="centimeter / second", 78 | required_energy_units="MeV", 79 | source_strength=source_strength, 80 | ) 81 | 82 | # creates a matplotlib figure of the tally 83 | spectrum_plot = plot_spectrum_from_tally( 84 | spectrum={"neutron spectra tally": my_tally_2}, 85 | x_label="Energy [MeV]", 86 | y_label="Flux [n/cm^2s]", 87 | x_scale="log", 88 | y_scale="log", 89 | title="neutron spectra tally", 90 | filename="my_spectrum_plot.png", 91 | ) 92 | 93 | print("image saved as my_spectrum_plot.png") 94 | -------------------------------------------------------------------------------- /example_01_single_volume_cell_tally/README.md: -------------------------------------------------------------------------------- 1 | This is a minimal example that creates a single volume CAD file in stp file 2 | format, then converts the file to a DAGMC neutronics model, then runs an OpenMC 3 | simulation to get a cell tally. 4 | 5 | Run the files in this order 6 | 7 | ```bash 8 | python 1_create_cad_and_convert_to_dagmc.py 9 | python 2_run_neutronics_simulation.py 10 | ``` 11 | -------------------------------------------------------------------------------- /example_01_single_volume_cell_tally/run_all.sh: -------------------------------------------------------------------------------- 1 | python 1_create_cad_and_convert_to_dagmc.py 2 | python 2_run_neutronics_simulation.py -------------------------------------------------------------------------------- /example_02_multi_volume_cell_tally/1_create_cad_and_convert_to_dagmc.py: -------------------------------------------------------------------------------- 1 | 2 | # This minimal example makes a 3D volume and exports the shape to a stp file 3 | # A surrounding volume called a graveyard is needed for neutronics simulations 4 | 5 | import paramak 6 | import os 7 | 8 | my_reactor = paramak.BallReactor( 9 | inner_bore_radial_thickness=1, 10 | inboard_tf_leg_radial_thickness=30, 11 | center_column_shield_radial_thickness=60, 12 | divertor_radial_thickness=50, 13 | inner_plasma_gap_radial_thickness=30, 14 | plasma_gap_vertical_thickness=30, 15 | plasma_radial_thickness=300, 16 | outer_plasma_gap_radial_thickness=30, 17 | firstwall_radial_thickness=3, 18 | blanket_radial_thickness=100, 19 | blanket_rear_wall_radial_thickness=3, 20 | elongation=2.75, 21 | triangularity=0.5, 22 | number_of_tf_coils=16, 23 | rotation_angle=180 24 | ) 25 | 26 | # exports the reactor shapes as a DAGMC h5m file which can be used as 27 | # neutronics geometry by OpenMC 28 | my_reactor.export_dagmc_h5m('dagmc.h5m') 29 | 30 | # this converts the neutronics geometry h5m file into a vtk file for 31 | # visualisation in Paraview or Visit 32 | os.system('mbconvert dagmc.h5m dagmc.vtk') 33 | -------------------------------------------------------------------------------- /example_02_multi_volume_cell_tally/2_run_neutronics_simulation.py: -------------------------------------------------------------------------------- 1 | # makes use of the previously created neutronics geometry (h5m file) and assigns 2 | # actual materials to the material tags. Sets simulation intensity and specifies 3 | # the neutronics results to record (know as tallies). 4 | 5 | import openmc 6 | import openmc_dagmc_wrapper as odw 7 | import openmc_plasma_source as ops 8 | import openmc_tally_unit_converter as otuc 9 | 10 | # makes an OpenMC geometry object from the dagmc file 11 | geometry = odw.Geometry( 12 | h5m_filename="dagmc.h5m", 13 | reflective_angles=(0, 180) 14 | ) 15 | 16 | 17 | # this links the material tags in the dagmc h5m file with materials. 18 | # these materials are input as strings so they will be looked up in the 19 | # neutronics material maker package 20 | materials = odw.Materials( 21 | h5m_filename=geometry.h5m_filename, 22 | correspondence_dict={ 23 | "plasma": "DT_plasma", 24 | "inboard_tf_coils": "copper", 25 | "center_column_shield": "tungsten", 26 | "firstwall": "tungsten", 27 | "blanket": "Li4SiO4", 28 | "blanket_rear_wall": "eurofer", 29 | "divertor_upper": "tungsten", 30 | "divertor_lower": "tungsten", 31 | } 32 | ) 33 | 34 | tally1 = odw.CellTally(tally_type="TBR", target="blanket", materials=materials) 35 | 36 | # creates a dose tally for neutrons with the required EnergyFunctionFilter, 37 | # ParticleFilter, MaterialFilter etc 38 | tally2 = odw.CellTally( 39 | tally_type="neutron_effective_dose", target="firstwall", materials=materials 40 | ) 41 | 42 | tallies = openmc.Tallies([tally1, tally2]) 43 | 44 | settings = odw.FusionSettings() 45 | settings.batches = 2 46 | settings.particles = 100 47 | # assigns a ring source of DT energy neutrons to the source using the 48 | # openmc_plasma_source package 49 | settings.source = ops.FusionRingSource(fuel="DT", radius=350) 50 | 51 | 52 | my_model = openmc.Model( 53 | materials=materials, geometry=geometry, settings=settings, tallies=tallies 54 | ) 55 | statepoint_file = my_model.run() 56 | 57 | statepoint = openmc.StatePoint(statepoint_file) 58 | 59 | # gets the second tally using its name 60 | my_tally_1 = statepoint.get_tally(name="blanket_TBR") 61 | 62 | # no unit coversion is needed for the TBR (tritium breeding ratio) tally 63 | print(f'TBR is {my_tally_1}') 64 | 65 | 66 | my_tally_2 = statepoint.get_tally(name="firstwall_neutron_effective_dose") 67 | 68 | # returns the tally with normalisation for source strength 69 | result = otuc.process_dose_tally( 70 | source_strength=1.3e6, 71 | tally=my_tally_2, 72 | required_units="Sv / second", 73 | volume= 100 # in the future this volume of the component will be found automatically 74 | ) 75 | print(f"effective dose = {result}", end="\n\n") 76 | -------------------------------------------------------------------------------- /example_02_multi_volume_cell_tally/README.md: -------------------------------------------------------------------------------- 1 | This is a minimal example that creates a multi volume CAD file in stp file 2 | format, then converts the file to a DAGMC neutronics model, then runs an OpenMC 3 | simulation to get a cell tally. 4 | 5 | Run the files in this order 6 | 7 | ```bash 8 | python 1_create_cad_and_convert_to_dagmc.py 9 | python 2_run_neutronics_simulation.py 10 | ``` 11 | -------------------------------------------------------------------------------- /example_02_multi_volume_cell_tally/run_all.sh: -------------------------------------------------------------------------------- 1 | python 1_create_cad_and_convert_to_dagmc.py 2 | python 2_run_neutronics_simulation.py -------------------------------------------------------------------------------- /example_04_multi_volume_regular_mesh_tally/1_create_cad_and_convert_to_dagmc.py: -------------------------------------------------------------------------------- 1 | 2 | # This minimal example makes a 3D volume and exports the shape to a stp file 3 | # A surrounding volume called a graveyard is needed for neutronics simulations 4 | 5 | import paramak 6 | import os 7 | 8 | 9 | my_reactor = paramak.BallReactor( 10 | inner_bore_radial_thickness=1, 11 | inboard_tf_leg_radial_thickness=30, 12 | center_column_shield_radial_thickness=60, 13 | divertor_radial_thickness=50, 14 | inner_plasma_gap_radial_thickness=30, 15 | plasma_radial_thickness=300, 16 | outer_plasma_gap_radial_thickness=30, 17 | plasma_gap_vertical_thickness=30, 18 | firstwall_radial_thickness=3, 19 | blanket_radial_thickness=100, 20 | blanket_rear_wall_radial_thickness=3, 21 | elongation=2.75, 22 | triangularity=0.5, 23 | number_of_tf_coils=16, 24 | rotation_angle=180 25 | ) 26 | 27 | # exports the reactor shapes as a DAGMC h5m file which can be used as 28 | # neutronics geometry by OpenMC 29 | my_reactor.export_dagmc_h5m('dagmc.h5m', exclude=['plasma']) 30 | 31 | # this converts the neutronics geometry h5m file into a vtk file for 32 | # visualisation in Paraview or Visit 33 | os.system('mbconvert dagmc.h5m dagmc.vtk') 34 | -------------------------------------------------------------------------------- /example_04_multi_volume_regular_mesh_tally/2_run_neutronics_simulation.py: -------------------------------------------------------------------------------- 1 | # makes use of the previously created neutronics geometry (h5m file) and assigns 2 | # actual materials to the material tags. Sets simulation intensity and specifies 3 | # the neutronics results to record (know as tallies). 4 | 5 | import openmc 6 | import openmc_dagmc_wrapper as odw 7 | import openmc_plasma_source as ops 8 | 9 | 10 | geometry = odw.Geometry(h5m_filename='dagmc.h5m') 11 | 12 | # this links the material tags in the dagmc h5m file with materials. 13 | # these materials are input as strings so they will be looked up in the 14 | # neutronics material maker package 15 | material_tag_to_material_dict = { 16 | "inboard_tf_coils": "copper", 17 | "center_column_shield": "tungsten", 18 | "firstwall": "tungsten", 19 | "blanket": "Li4SiO4", 20 | "blanket_rear_wall": "eurofer", 21 | "divertor_upper": "tungsten", 22 | "divertor_lower": "tungsten", 23 | } 24 | 25 | materials = odw.Materials( 26 | h5m_filename=geometry.h5m_filename, 27 | correspondence_dict=material_tag_to_material_dict, 28 | ) 29 | 30 | # uncomment if you don't have nuclear data already and it will be downloaded 31 | # import openmc_data_downloader as odd 32 | # odd.just_in_time_library_generator( 33 | # libraries=['ENDFB-7.1-NNDC', 'TENDL-2019'], 34 | # materials=materials 35 | # ) 36 | 37 | # gets the corners of the geometry for use later 38 | bounding_box = geometry.corners() 39 | 40 | tally1 = odw.MeshTally3D( 41 | mesh_resolution=(100, 100, 100), 42 | bounding_box=bounding_box, 43 | tally_type="(n,Xa)", 44 | ) 45 | 46 | tally2 = odw.MeshTally2D(tally_type="(n,Xa)", plane="xy", bounding_box=bounding_box) 47 | 48 | tally3 = odw.MeshTally2D(tally_type="(n,Xa)", plane="xz", bounding_box=bounding_box) 49 | 50 | tallies = openmc.Tallies([tally1, tally2, tally3]) 51 | 52 | settings = odw.FusionSettings() 53 | settings.batches = 4 54 | settings.particles = 10000 55 | # assigns a ring source of DT energy neutrons to the source using the 56 | # openmc_plasma_source package 57 | settings.source = ops.FusionRingSource(fuel="DT", radius=350, angles=(0, 3.14)) 58 | 59 | 60 | my_model = openmc.Model( 61 | materials=materials, geometry=geometry, settings=settings, tallies=tallies 62 | ) 63 | 64 | # starts the simulation 65 | statepoint_file = my_model.run() 66 | 67 | print(f'neutronics results are saved in {statepoint_file}') 68 | -------------------------------------------------------------------------------- /example_04_multi_volume_regular_mesh_tally/3_post_process_and_plot.py: -------------------------------------------------------------------------------- 1 | import openmc_tally_unit_converter as otuc 2 | import openmc 3 | from regular_mesh_plotter import plot_regular_mesh_tally_with_geometry 4 | 5 | # can be used to scale the color scale 6 | from matplotlib.colors import LogNorm 7 | 8 | statepoint_file = "statepoint.4.h5" 9 | 10 | # loads up the statepoint file with simulation results 11 | statepoint = openmc.StatePoint(filepath=statepoint_file) 12 | 13 | # gets the first tally using its name 14 | my_tally_xy = statepoint.get_tally(name="(n,Xa)_on_2D_mesh_xy") 15 | my_tally_xz = statepoint.get_tally(name="(n,Xa)_on_2D_mesh_xz") 16 | 17 | # gets number of neutron for a 1.3 mega joule shot 18 | source_strength = otuc.find_source_strength(fusion_energy_per_second_or_per_pulse=1.3e6) 19 | 20 | 21 | plot = plot_regular_mesh_tally_with_geometry( 22 | tally=my_tally_xy, 23 | dagmc_file_or_trimesh_object="dagmc.h5m", 24 | plane_origin=None, 25 | plane_normal=[0, 0, 1], 26 | scale=LogNorm(), 27 | rotate_mesh=180, 28 | vmin=None, 29 | label="(n,Xa) per pulse", 30 | filename="mesh_tally_xy.png", 31 | ) 32 | 33 | # plot.show() 34 | 35 | plot = plot_regular_mesh_tally_with_geometry( 36 | tally=my_tally_xz, 37 | dagmc_file_or_trimesh_object="dagmc.h5m", 38 | plane_origin=[0,0.1,0], # moves the slice 1mm into the 180 degree model to ensure geometry is sliced 39 | plane_normal=[0, 1, 0], 40 | rotate_geometry=90, 41 | scale=LogNorm(), 42 | vmin=None, 43 | label="(n,Xa)", 44 | filename="my_tally_xz.png", 45 | ) 46 | 47 | # plot.show() 48 | -------------------------------------------------------------------------------- /example_04_multi_volume_regular_mesh_tally/run_all.sh: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rm *.jou *.json *.out *.xml *.exo *.h5m *.vtk *.log *.h5 5 | rm -rf stage_1_output/ 6 | rm -rf stage_2_output/ 7 | 8 | python 1_create_cad_and_convert_to_dagmc.py 9 | 10 | # needed to prevent hdf5 conflict if using cad-to-h5m 11 | # export HDF5_DISABLE_VERSION_CHECK=1 12 | 13 | python 2_run_neutronics_simulation.py 14 | 15 | python 3_post_process_and_plot.py 16 | -------------------------------------------------------------------------------- /example_05_3D_unstructured_mesh_tally/1_create_cad_and_convert_to_dagmc.py: -------------------------------------------------------------------------------- 1 | 2 | # This minimal example makes a 3D volume and exports the shape to a stp file 3 | # A surrounding volume called a graveyard is needed for neutronics simulations 4 | 5 | import paramak 6 | from cad_to_h5m import cad_to_h5m 7 | 8 | my_shape = paramak.ExtrudeStraightShape( 9 | points=[ 10 | (200, 10), 11 | (200, 20), 12 | (250, 20), 13 | (250, 10) 14 | ], 15 | distance = 5, 16 | ) 17 | 18 | my_shape.export_stp('steel.stp') 19 | 20 | # This script converts the CAD stp files generated into h5m files that can be 21 | # used in DAGMC enabled codes. h5m files created in this way are imprinted, 22 | # merged, faceted and ready for use in OpenMC. One of the key aspects of this 23 | # is the assignment of materials to the volumes present in the CAD files. 24 | 25 | cad_to_h5m( 26 | files_with_tags=[ 27 | { 28 | 'cad_filename':'steel.stp', 29 | 'material_tag':'mat1', 30 | 'tet_mesh': 'size 10', 31 | }, 32 | ], 33 | make_watertight=False, 34 | h5m_filename='dagmc.h5m', 35 | cubit_path='/opt/Coreform-Cubit-2021.5/bin/', 36 | cubit_filename='unstructured_mesh.cub' 37 | ) 38 | -------------------------------------------------------------------------------- /example_05_3D_unstructured_mesh_tally/2_run_neutronics_simulation.py: -------------------------------------------------------------------------------- 1 | # makes use of the previously created neutronics geometry (h5m file) and assigns 2 | # actual materials to the material tags. Sets simulation intensity and specifies 3 | # the neutronics results to record (know as tallies). 4 | 5 | import openmc 6 | import openmc_dagmc_wrapper as odw 7 | import openmc_plasma_source as ops 8 | 9 | # defines a simple DT neutron point source 10 | my_source = ops.FusionPointSource( 11 | coordinate = (0,0,0), 12 | temperature = 20000., 13 | fuel='DT' 14 | ) 15 | 16 | geometry = odw.Geometry( 17 | h5m_filename='dagmc.h5m', 18 | ) 19 | 20 | materials = odw.Materials( 21 | h5m_filename='dagmc.h5m', 22 | correspondence_dict={"mat1": "eurofer"} 23 | ) 24 | 25 | tally1 = odw.TetMeshTally( 26 | tally_type="neutron_fast_flux", 27 | filename='unstructured_mesh.h5m', 28 | ) 29 | 30 | 31 | tallies = openmc.Tallies([tally1]) 32 | 33 | settings = odw.FusionSettings() 34 | settings.batches = 5 35 | settings.particles = 1000 36 | # assigns a point source of DT energy neutrons to the source using the 37 | # openmc_plasma_source package 38 | settings.source = ops.FusionPointSource(fuel="DT") 39 | 40 | 41 | my_model = openmc.Model( 42 | materials=materials, geometry=geometry, settings=settings, tallies=tallies 43 | ) 44 | statepoint_file = my_model.run() 45 | 46 | odw.process_results(statepoint_file, fusion_power=1e9) 47 | -------------------------------------------------------------------------------- /example_05_3D_unstructured_mesh_tally/README.md: -------------------------------------------------------------------------------- 1 | # WORK IN PROGRESS. NOT READY FOR USE AT THE MOMENT 2 | 3 | This is a minimal example that creates a single volume CAD file in stp file 4 | format, then converts the file to a DAGMC neutronics model and creates a tet 5 | mesh of the volume, then runs an OpenMC simulation to get a unstrucuted mesh tally. 6 | 7 | Run the files in this order 8 | 9 | ```bash 10 | python 1_create_cad_and_convert_to_dagmc.py 11 | mbconvert unstructured_mesh.cub unstructured_mesh.h5m 12 | python 2_run_neutronics_simulation.py 13 | ``` 14 | -------------------------------------------------------------------------------- /example_05_3D_unstructured_mesh_tally/run_all.sh: -------------------------------------------------------------------------------- 1 | # needed to prevent hdf5 conflict 2 | export HDF5_DISABLE_VERSION_CHECK=1 3 | 4 | python 1_create_cad_and_convert_to_dagmc.py 5 | 6 | mbconvert unstructured_mesh.cub unstructured_mesh.h5m 7 | 8 | python 2_run_neutronics_simulation.py 9 | --------------------------------------------------------------------------------