diff --git a/.circleci/config.yml b/.circleci/config.yml index a26b529..9bba8b2 100755 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,6 +15,11 @@ jobs: command: | python setup.py install + - run: + name: install packages required for testing + command: | + pip install -r requirements-test.txt + - run: name: run test_neutronics_utils command: diff --git a/.github/workflows/ci_with_install.yml b/.github/workflows/ci_with_install.yml index c91cda8..7d670cd 100644 --- a/.github/workflows/ci_with_install.yml +++ b/.github/workflows/ci_with_install.yml @@ -23,6 +23,10 @@ jobs: run: | python setup.py install + - name: install packages required for testing + run: | + pip install -r requirements-test.txt + - name: run tests run: | pytest tests/test_neutronics_utils.py -v --cov=openmc_dagmc_wrapper --cov-append --cov-report term --cov-report xml diff --git a/Dockerfile b/Dockerfile index 0f4c377..8855bfb 100755 --- a/Dockerfile +++ b/Dockerfile @@ -109,7 +109,7 @@ RUN pip install --upgrade numpy cython && \ # Clone and install Double-Down -RUN git clone --shallow-submodules --single-branch --branch main --depth 1 https://github.com/pshriwise/double-down.git && \ +RUN git clone --shallow-submodules --single-branch --branch v1.0.0 --depth 1 https://github.com/pshriwise/double-down.git && \ cd double-down && \ mkdir build && \ cd build && \ @@ -125,7 +125,11 @@ RUN mkdir DAGMC && \ cd DAGMC && \ # change to version 3.2.1 when released # git clone --single-branch --branch 3.2.1 --depth 1 https://github.com/svalinn/DAGMC.git && \ - git clone --shallow-submodules --single-branch --branch develop --depth 1 https://github.com/svalinn/DAGMC.git && \ + git clone --single-branch --branch develop https://github.com/svalinn/DAGMC.git && \ + cd DAGMC && \ + # this commit is from this PR https://github.com/svalinn/DAGMC/pull/786 + git checkout fbd0cdbad100a0fd8d80de42321e69d09fdd67f4 && \ + cd .. && \ mkdir build && \ cd build && \ cmake ../DAGMC -DBUILD_TALLY=ON \ @@ -140,7 +144,11 @@ RUN mkdir DAGMC && \ # Clone and install OpenMC with DAGMC # TODO clone a specific release when the next release containing (PR 1825) is avaialble. -RUN git clone --shallow-submodules --recurse-submodules --single-branch --branch develop --depth 1 https://github.com/openmc-dev/openmc.git /opt/openmc && \ +RUN cd /opt && \ + git clone --single-branch --branch develop https://github.com/openmc-dev/openmc.git && \ + cd openmc && \ + # this commit is from this PR https://github.com/openmc-dev/openmc/pull/1900 + git checkout 0157dc219ff8dca814859b3140c6cef1e78cdee1 && \ cd /opt/openmc && \ mkdir build && \ cd build && \ diff --git a/README.md b/README.md index 57ebcdb..83584d7 100644 --- a/README.md +++ b/README.md @@ -20,33 +20,26 @@ # OpenMC DAGMC Wrapper -The openmc-dagmc-wrapper python package allows convenient access to a series of standard neutronics simulations and post using OpenMC and DAGMC. - -The intended use case is to take DAGMC compatible h5m files generated by -[cad_to_h5m](https://github.com/fusion-energy/cad_to_h5m) with CAD file inputs -from the [Paramak](https://github.com/fusion-energy/paramak) as demonstrated in -the [neutronics_workflow](https://github.com/fusion-energy/neutronics_workflow). However the package can also be used with h5m files generated in other ways. - -Standard simulations tallies are facilitated: -- Volume / cell tallies -- Regular 2D mesh tallies -- Regular 3D mesh tallies -- Unstructured mesh tally (on road map) - -Neutronics responses can be obtained: -- Tritium Breeding Ratio (TBR) -- Heating (photon and neutron) -- Effective dose (photon and neutron) -- Any supported reaction from the [standard OpenMC reactions](https://docs.openmc.org/en/latest/usersguide/tallies.html#scores) - -A standard collection of materials are available by making use of the -[neutronics_material_maker](https://github.com/fusion-energy/neutronics_material_maker) package. - -OpenMC sources definitions are used for the particle sources. - -Post processing of the OpenMC output files are also carried out to automatically -provide: JSON text files, PNG images, VTK files for convenient access to the -results. + +The openmc-dagmc-wrapper python package extends OpenMC base classes and adds +convenience features aimed as easing the use of OpenMC with DAGMC for +fixed-source simulations. + +The openmc-dagmc-wrapper is built around the assumption that a DAGMC geometry +in the form of a h5m is used as the simulation geometry. This allows several +aspects of openmc simulations to be simplified and automated. + +Additional convenience is available when making tallies as standard tally types +are added which automated the application of openmc.Filters and openmc.scores +for standard tallies such as neutron spectra, effective dose, heating, TBR and +others. + +Further simplifications are access by using additional packages from the +[fusion-neutronics-workflow](https://github.com/fusion-energy/fusion_neutronics_workflow) + +If you are looking for an easy neutronics interface for performing simulations +of fusion reactors this package was built for you. + :point_right: [Documentation](https://openmc-dagmc-wrapper.readthedocs.io) diff --git a/docs/source/conf.py b/docs/source/conf.py index ccefadd..da0cd46 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -35,7 +35,7 @@ # If your documentation needs a minimal Sphinx version, state it here. # -needs_sphinx = '3.5.4' +needs_sphinx = "3.5.4" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom @@ -136,11 +136,13 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, - "OpenMC-DAGMC-Wrapper.tex", - "OpenMC-DAGMC-Wrapper Documentation", - "OpenMC-DAGMC-Wrapper contributors", - "manual"), + ( + master_doc, + "OpenMC-DAGMC-Wrapper.tex", + "OpenMC-DAGMC-Wrapper Documentation", + "OpenMC-DAGMC-Wrapper contributors", + "manual", + ), ] @@ -149,11 +151,14 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (master_doc, - "OpenMC-DAGMC-Wrapper", - "OpenMC-DAGMC-Wrapper Documentation", - [author], - 1)] + ( + master_doc, + "OpenMC-DAGMC-Wrapper", + "OpenMC-DAGMC-Wrapper Documentation", + [author], + 1, + ) +] # -- Options for Texinfo output ---------------------------------------------- @@ -194,4 +199,4 @@ # -- Extension configuration ------------------------------------------------- -html_favicon = 'favicon.ico' +html_favicon = "favicon.ico" diff --git a/docs/source/example_neutronics_simulations.rst b/docs/source/example_neutronics_simulations.rst deleted file mode 100644 index 392fba2..0000000 --- a/docs/source/example_neutronics_simulations.rst +++ /dev/null @@ -1,51 +0,0 @@ -Examples - Neutronics Simulations -================================= - -These are minimal examples of neutronics simulations that demonstrate the core -functionality of the neutronics features. - - -ball_reactor.ipynb -^^^^^^^^^^^^^^^^^^ - -`Link to notebook `__ - - -ball_reactor_minimal.ipynb -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -`Link to notebook `__ - - -ball_reactor_source_plot.ipynb -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -`Link to notebook `__ - - -center_column_study_reactor.ipynb -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -`Link to notebook `__ - - -center_column_study_reactor_minimal.ipynb -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -`Link to notebook `__ - - -OpenMC logo simulation -^^^^^^^^^^^^^^^^^^^^^^ - -`Link to notebook `__ - -.. raw:: html - - - - -text_example.ipynb -^^^^^^^^^^^^^^^^^^ - -`Link to notebook `__ diff --git a/docs/source/fusion_settings.rst b/docs/source/fusion_settings.rst new file mode 100644 index 0000000..67f07ab --- /dev/null +++ b/docs/source/fusion_settings.rst @@ -0,0 +1,7 @@ + +FusionSettings() +---------------- + +.. automodule:: openmc_dagmc_wrapper.FusionSettings + :members: + :show-inheritance: diff --git a/docs/source/geometry.rst b/docs/source/geometry.rst new file mode 100644 index 0000000..6f5eb8c --- /dev/null +++ b/docs/source/geometry.rst @@ -0,0 +1,7 @@ + +Geometry() +---------- + +.. automodule:: openmc_dagmc_wrapper.Geometry + :members: + :show-inheritance: diff --git a/docs/source/index.rst b/docs/source/index.rst index 6e8c583..f9ca494 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,60 +1,32 @@ openmc-dagmc-wrapper ==================== -The openmc-dagmc-wrapper python package allows convenient access to a series of -standard neutronics simulations and post using OpenMC and DAGMC. +The openmc-dagmc-wrapper python package extends OpenMC base classes and adds +convenience features aimed as easing the use of OpenMC with DAGMC for +fixed-source simulations. -.. toctree:: - :maxdepth: 1 - - install - example_neutronics_simulations - neutronics_model - tests - -History -------- - -The package was originally conceived by Jonathan Shimwell to help automate -neutronics simulations of fusion reactors in a reproducible manner. - -The source code is distributed with a permissive open-source -license (MIT) and is available from the GitHub repository -`https://github.com/fusion-energy/openmc-dagmc-wrapper `_ +The openmc-dagmc-wrapper is built around the assumption that a DAGMC geometry +in the form of a h5m is used as the simulation geometry. This allows several +aspects of openmc simulations to be simplified and automated. +Additional convenience is available when making tallies as standard tally types +are added which automated the application of openmc.Filters and openmc.scores +for standard tallies such as neutron spectra, effective dose, heating, TBR and +others. -Features --------- +Further simplifications are access by using additional packages from the +`fusion-neutronics-workflow `_ -In general the openmc-dagmc-wrapper takes a DAGMC geometry in the form of a h5m -file and helps adding tallies, materials and a source term to be easily added to -create a complete neutronics model. The package will also post processes the -results of the neutronics simulation to allow easy access to the outputs. -The simulated results are extracted from the statepoint.h5 file that -OpenMC produces and converted to vtk, png and JSON files depending on the tally. +If you are looking for an easy neutronics interface for performing simulations +of fusion reactors this package was built for you. -To create a model it is also necessary to define the source and the materials -used. - -The Paramak accepts native OpenMC materials and also Neutronics Material Maker -materials. Further details on the Neutronics Material Maker is avaialbe via online -`documentation `_ -and the `source code repository `_ -. - -The `OpenMC workshop `_ -also has some tasks that make use of this package. The workshop also -demonstrates methods of creating the CAD geometry and h5m files from CAD -geometry. - -The `OpenMC workflow `_ -demonstrates the use of this package along side others in a complete neutronics -tool chain. - -`CAD-to-h5m `_ makes use of the -`Cubit API `_ to convert CAD -files (stp or sat format) into `DAGMC `_ -compatible h5m files for use in DAGMC enabled neutronics codes. +.. toctree:: + :maxdepth: 2 -For magnetic confinement fusion simulations you might want to use the parametric-plasma-source -`Git repository `_ + install + geometry + materials + fusion_settings + tally + tests + license \ No newline at end of file diff --git a/docs/source/install.rst b/docs/source/install.rst index 11c5162..4baa727 100644 --- a/docs/source/install.rst +++ b/docs/source/install.rst @@ -2,13 +2,29 @@ Installation ============ - -Install -------- - To use the OpenMC-DAGMC-Wrapper package you will need the Python, MOAB, DAGMC and OpenMC installed. + +To complete the software stack OpenMC, DAGMC and MOAB will also need installing. +We don't have simple instructions for these packages yet but one option is to +duplicate the stages in the `Dockerfile https://github.com/fusion-energy/neutronics_workflow/blob/main/Dockerfile>`_ +or to make use of the `install scripts `_ (preferable to avoid hdf5 conflicts) @@ -38,12 +54,6 @@ Then install the OpenMC-DAGMC-Wrapper package using Pip. pip install openmc-dagmc-wrapper -To complete the software stack OpenMC, DAGMC and MOAB will also need installing. -We don't have simple instructions for these packages yet but one option is to -duplicate the stages in the `Dockerfile https://github.com/fusion-energy/neutronics_workflow/blob/main/Dockerfile>`_ -or to make use of the `install scripts `_ diff --git a/docs/source/materials.rst b/docs/source/materials.rst new file mode 100644 index 0000000..60fd312 --- /dev/null +++ b/docs/source/materials.rst @@ -0,0 +1,10 @@ + +A standard collection of materials are available by making use of the +[neutronics_material_maker](https://github.com/fusion-energy/neutronics_material_maker) package. + +Materials() +----------- + +.. automodule:: openmc_dagmc_wrapper.Materials + :members: + :show-inheritance: diff --git a/docs/source/neutronics_model.rst b/docs/source/neutronics_model.rst deleted file mode 100644 index 66e9084..0000000 --- a/docs/source/neutronics_model.rst +++ /dev/null @@ -1,7 +0,0 @@ - -NeutronicsModel() -^^^^^^^^^^^^^^^^^ - -.. automodule:: openmc_dagmc_wrapper.neutronics_model - :members: - :show-inheritance: diff --git a/docs/source/tally.rst b/docs/source/tally.rst new file mode 100644 index 0000000..4709f45 --- /dev/null +++ b/docs/source/tally.rst @@ -0,0 +1,70 @@ + +tally +===== + +Standard simulations tallies are facilitated: +- Volume / cell tallies +- Regular 2D mesh tallies +- Regular 3D mesh tallies +- Unstructured mesh tally + +Neutronics responses can be obtained: +- Tritium Breeding Ratio (TBR) +- Heating (photon and neutron) +- Effective dose (photon and neutron) +- Spectrum (photon and neutron) +- Damage per Atom (DPA) +- Any supported reaction from the [standard OpenMC reactions](https://docs.openmc.org/en/latest/usersguide/tallies.html#scores) + +Additionally the ability to target the tally to material tags or volume ids +that exist in the DAGMC h5m file offer easy access to tallies. + +Bounding boxes for the tallies can be automatically found and extended using +the `dagmc-bounding-box `_ +package. + + +MeshTally2D() +------------- + +.. automodule:: openmc_dagmc_wrapper.MeshTally2D + :members: + :show-inheritance: + +MeshTallies2D() +--------------- + +.. automodule:: openmc_dagmc_wrapper.MeshTallies2D + :members: + :show-inheritance: + +MeshTally3D() +------------- + +.. automodule:: openmc_dagmc_wrapper.MeshTally3D + :members: + :show-inheritance: + +MeshTallies3D() +--------------- + +.. automodule:: openmc_dagmc_wrapper.MeshTallies3D + :members: + :show-inheritance: + +TetMeshTally() +-------------- + +.. automodule:: openmc_dagmc_wrapper.TetMeshTally + :members: + :show-inheritance: + + +TetMeshTallies() +---------------- + +.. automodule:: openmc_dagmc_wrapper.TetMeshTallies + :members: + :show-inheritance: + + diff --git a/examples/regular_2d_mesh_tally_example.py b/examples/regular_2d_mesh_tally_example.py index 4626cd3..ae7ff91 100644 --- a/examples/regular_2d_mesh_tally_example.py +++ b/examples/regular_2d_mesh_tally_example.py @@ -9,7 +9,7 @@ import openmc import openmc_dagmc_wrapper as odw from openmc_plasma_source import FusionRingSource - +from dagmc_bounding_box import DagmcBoundingBox # downloads a dagmc file for use in the example # url = "https://github.com/fusion-energy/neutronics_workflow/archive/refs/tags/v0.0.2.tar.gz" @@ -18,7 +18,6 @@ # tar.extractall(".") # tar.close() h5m_filename = "neutronics_workflow-0.0.2/example_02_multi_volume_cell_tally/stage_2_output/dagmc.h5m" -h5m_filename = "neutronics_workflow-0.0.2/example_02_multi_volume_cell_tally/stage_2_output/dagmc_no_grave_yard.h5m" # creates a geometry object from a DAGMC geometry. @@ -45,17 +44,24 @@ }, ) +# makes use of the dagmc-bound-box package to get the corners of the bounding +# box. This will be used to set the bounding box for the tally +my_bounding_box = DagmcBoundingBox(h5m_filename).corners() + + # A MeshTally2D tally allows a set of standard tally types (made from filters # and scores) to be applied to the DAGMC geometry. By default the mesh will be # applied across the entire geomtry with and the size of the geometry is # automatically found. tally1 = odw.MeshTally2D( - tally_type="photon_effective_dose", plane="xy", bounding_box=h5m_filename -) + tally_type="photon_effective_dose", + plane="xy", + bounding_box=my_bounding_box) tally2 = odw.MeshTally2D( - tally_type="neutron_effective_dose", plane="xy", bounding_box=h5m_filename -) + tally_type="neutron_effective_dose", + plane="xy", + bounding_box=my_bounding_box) # no modifications are made to the default openmc.Tallies tallies = openmc.Tallies([tally1, tally2]) diff --git a/examples/regular_3d_mesh_tally_example.py b/examples/regular_3d_mesh_tally_example.py index d5dc0cb..58c60c0 100644 --- a/examples/regular_3d_mesh_tally_example.py +++ b/examples/regular_3d_mesh_tally_example.py @@ -9,6 +9,7 @@ import openmc import openmc_dagmc_wrapper as odw from openmc_plasma_source import FusionRingSource +from dagmc_bounding_box import DagmcBoundingBox # downloads a dagmc file for use in the example # url = "https://github.com/fusion-energy/neutronics_workflow/archive/refs/tags/v0.0.2.tar.gz" @@ -43,13 +44,17 @@ }, ) +# makes use of the dagmc-bound-box package to get the corners of the bounding +# box. This will be used to set the bounding box for the tally +my_bounding_box = DagmcBoundingBox(h5m_filename).corners() + # A MeshTally3D tally allows a set of standard tally types (made from filters # and scores) to be applied to the DAGMC geometry. By default the mesh will be # applied across the entire geomtry with and the size of the geometry is # automatically found. tally1 = odw.MeshTally3D( - tally_type="neutron_effective_dose", - bounding_box=h5m_filename) + tally_type="neutron_effective_dose", bounding_box=my_bounding_box +) # no modifications are made to the default openmc.Tallies tallies = openmc.Tallies([tally1]) diff --git a/openmc_dagmc_wrapper/Geometry.py b/openmc_dagmc_wrapper/Geometry.py index bf48245..2d5a547 100644 --- a/openmc_dagmc_wrapper/Geometry.py +++ b/openmc_dagmc_wrapper/Geometry.py @@ -4,8 +4,6 @@ import openmc from numpy import cos, sin -from .utils import find_bounding_box - class Geometry(openmc.Geometry): """A openmc.Geometry object with a DAGMC Universe. If the model @@ -34,9 +32,11 @@ def __init__( self.h5m_filename = h5m_filename self.reflective_angles = reflective_angles self.graveyard_box = graveyard_box + super().__init__(root=self.make_root()) def make_root(self): + # this is the underlying geometry container that is filled with the # faceted DAGMC CAD model dag_univ = openmc.DAGMCUniverse(self.h5m_filename) @@ -102,7 +102,9 @@ def create_sphere_of_vacuum_surface(self): be used as an alternative to the traditionally DAGMC graveyard cell""" if self.graveyard_box is None: - self.graveyard_box = find_bounding_box(self.h5m_filename) + from dagmc_bounding_box import DagmcBoundingBox + + self.graveyard_box = DagmcBoundingBox(self.h5m_filename).corners() bbox = [[*self.graveyard_box[0]], [*self.graveyard_box[1]]] largest_radius = 3 * max(max(bbox[0]), max(bbox[1])) @@ -112,44 +114,3 @@ def create_sphere_of_vacuum_surface(self): ) return sphere_surface - - def create_cube_of_vacuum_surfaces(self): - """Creates six vacuum surfaces that surround the geometry and can be - used as an alternative to the traditionally DAGMC graveyard cell""" - - if self.graveyard_box is None: - self.graveyard_box = find_bounding_box(self.h5m_filename) - bbox = [[*self.graveyard_box[0]], [*self.graveyard_box[1]]] - # add reflective surfaces - # fix the x and y minimums to zero to get the universe boundary co - bbox[0][0] = 0.0 - bbox[0][1] = 0.0 - - lower_x = openmc.XPlane( - bbox[0][0], - surface_id=9999, - boundary_type="vacuum") - upper_x = openmc.XPlane( - bbox[1][0], - surface_id=9998, - boundary_type="vacuum") - - lower_y = openmc.YPlane( - bbox[0][1], - surface_id=9997, - boundary_type="vacuum") - upper_y = openmc.YPlane( - bbox[1][1], - surface_id=9996, - boundary_type="vacuum") - - lower_z = openmc.ZPlane( - bbox[0][2], - surface_id=9995, - boundary_type="vacuum") - upper_z = openmc.ZPlane( - bbox[1][2], - surface_id=9994, - boundary_type="vacuum") - - return [lower_x, upper_x, lower_y, upper_y, lower_z, upper_z] diff --git a/openmc_dagmc_wrapper/Tally.py b/openmc_dagmc_wrapper/Tally.py index 6ef34cb..988ac9e 100644 --- a/openmc_dagmc_wrapper/Tally.py +++ b/openmc_dagmc_wrapper/Tally.py @@ -1,4 +1,4 @@ -from typing import List, Tuple, Union +from typing import Iterable, List, Tuple, Union import dagmc_h5m_file_inspector as di import openmc @@ -7,8 +7,6 @@ from openmc_dagmc_wrapper import Materials -from .utils import find_bounding_box - class Tally(openmc.Tally): """ @@ -74,7 +72,8 @@ def set_score(self): ] if self.tally_type == "TBR": - self.scores = ["(n,Xt)"] # where X is a wild card + # H3-production could replace this + self.scores = ["(n,Xt)"] elif self.tally_type in flux_scores: self.scores = ["flux"] else: @@ -167,11 +166,13 @@ class CellTallies: """ def __init__( - self, - tally_types, - targets=[None], - materials=None, - h5m_filename=None): + self, + tally_types: Iterable, + targets: Iterable = [None], + materials=None, + h5m_filename=None, + ): + self.tallies = [] self.tally_types = tally_types self.targets = targets @@ -253,12 +254,13 @@ class MeshTally3D(Tally): def __init__( self, tally_type: str, - bounding_box: Union[str, List[Tuple[float]]], + bounding_box: List[Tuple[float]], mesh_resolution=(100, 100, 100), **kwargs ): self.tally_type = tally_type self.mesh_resolution = mesh_resolution + self.bounding_box = bounding_box super().__init__(tally_type, **kwargs) self.add_mesh_filter(bounding_box) @@ -266,11 +268,6 @@ def __init__( def add_mesh_filter(self, bounding_box): - if isinstance(bounding_box, str): - self.bounding_box = find_bounding_box(h5m_filename=bounding_box) - else: - self.bounding_box = bounding_box - mesh = openmc.RegularMesh(name="3d_mesh") mesh.dimension = self.mesh_resolution mesh.lower_left = self.bounding_box[0] @@ -280,19 +277,19 @@ def add_mesh_filter(self, bounding_box): class MeshTallies3D: - """[summary] + """Creates several MeshTally3D, one for each tally_type provided. The + tallies share the same mesh. Args: tally_types (list): [description] - meshes_resolutions (list): [description] - meshes_corners (list, optional): [description]. Defaults to None. bounding_box ([type], optional): [description]. Defaults to None. + meshes_resolutions (list): [description] """ def __init__( self, tally_types: str, - bounding_box: Union[str, List[Tuple[float]]], + bounding_box: List[Tuple[float]], meshes_resolution: Tuple[float] = (100, 100, 100), ): self.tallies = [] @@ -322,15 +319,15 @@ def __init__( self, tally_type: str, plane: str, - bounding_box: Union[str, List[Tuple[float]]], + bounding_box: List[Tuple[float]], + plane_slice_location: Tuple[float, float] = (1, -1), mesh_resolution: Tuple[float, float] = (400, 400), ): self.tally_type = tally_type self.plane = plane self.mesh_resolution = mesh_resolution - - self.bbox_from_h5 = None - self.bounding_box = None + self.bounding_box = bounding_box + self.plane_slice_location = plane_slice_location self.create_mesh(bounding_box) @@ -349,79 +346,53 @@ def create_mesh(self, bounding_box): self.mesh_resolution[0], 1, ] - mesh.id = 2 + mesh.lower_left = [ + self.bounding_box[0][0], + self.bounding_box[0][1], + self.plane_slice_location[1], + ] + mesh.upper_right = [ + self.bounding_box[1][0], + self.bounding_box[1][1], + self.plane_slice_location[0], + ] + elif self.plane == "xz": mesh.dimension = [ self.mesh_resolution[1], 1, self.mesh_resolution[0], ] - mesh.id = 3 + mesh.lower_left = [ + self.bounding_box[0][0], + self.plane_slice_location[1], + self.bounding_box[0][2], + ] + mesh.upper_right = [ + self.bounding_box[1][0], + self.plane_slice_location[0], + self.bounding_box[1][2], + ] + elif self.plane == "yz": mesh.dimension = [ 1, self.mesh_resolution[1], self.mesh_resolution[0], ] - mesh.id = 4 - - # mesh corners - self.set_bounding_box(bounding_box) - - if self.bbox_from_h5: - if self.plane == "xy": - mesh.lower_left = [ - self.bounding_box[0][0], - self.bounding_box[0][1], - -1, - ] - - mesh.upper_right = [ - self.bounding_box[1][0], - self.bounding_box[1][1], - 1, - ] - elif self.plane == "xz": - mesh.lower_left = [ - self.bounding_box[0][0], - -1, - self.bounding_box[0][2], - ] - - mesh.upper_right = [ - self.bounding_box[1][0], - 1, - self.bounding_box[1][2], - ] - elif self.plane == "yz": - mesh.lower_left = [ - -1, - self.bounding_box[0][1], - self.bounding_box[0][2], - ] - - mesh.upper_right = [ - 1, - self.bounding_box[1][1], - self.bounding_box[1][2], - ] - - else: - print(self.bounding_box) - mesh.lower_left = self.bounding_box[0] - mesh.upper_right = self.bounding_box[1] + mesh.lower_left = [ + self.plane_slice_location[1], + self.bounding_box[0][1], + self.bounding_box[0][2], + ] + mesh.upper_right = [ + self.plane_slice_location[0], + self.bounding_box[1][1], + self.bounding_box[1][2], + ] self.mesh = mesh - def set_bounding_box(self, bounding_box): - - if isinstance(bounding_box, str): - self.bbox_from_h5 = True - self.bounding_box = find_bounding_box(h5m_filename=bounding_box) - else: - self.bbox_from_h5 = False - self.bounding_box = bounding_box - class MeshTallies2D: """[summary] diff --git a/openmc_dagmc_wrapper/__init__.py b/openmc_dagmc_wrapper/__init__.py index e7e9385..69a1d53 100644 --- a/openmc_dagmc_wrapper/__init__.py +++ b/openmc_dagmc_wrapper/__init__.py @@ -1,4 +1,4 @@ -from .utils import create_material, find_bounding_box +from .utils import create_material, diff_between_angles from .Geometry import Geometry from .Materials import Materials @@ -10,6 +10,6 @@ MeshTally3D, MeshTallies3D, TetMeshTally, - TetMeshTallies + TetMeshTallies, ) from .Settings import FusionSettings diff --git a/openmc_dagmc_wrapper/utils.py b/openmc_dagmc_wrapper/utils.py index 4105470..0b47745 100644 --- a/openmc_dagmc_wrapper/utils.py +++ b/openmc_dagmc_wrapper/utils.py @@ -20,7 +20,8 @@ def create_material(material_tag: str, material_entry): if isinstance(material_entry, str): openmc_material = nmm.Material.from_library( - name=material_entry, material_id=None).openmc_material + name=material_entry, material_id=None + ).openmc_material elif isinstance(material_entry, openmc.Material): # sets the material name in the event that it had not been set openmc_material = material_entry @@ -43,12 +44,21 @@ def get_an_isotope_present_in_cross_sections_xml(): """Opens the xml file found with the OPENMC_CROSS_SECTIONS environmental variable""" - cross_sections_xml = os.getenv('OPENMC_CROSS_SECTIONS') + cross_sections_xml = os.getenv("OPENMC_CROSS_SECTIONS") + if cross_sections_xml is None: + msg = ( + "set your OPENMC_CROSS_SECTIONS environmental variable before " + "running this script. This can be done automatically using the " + 'openmc-data-downloader package or manually with an "export ' + 'OPENMC_CROSS_SECTIONS path to cross_sections.xml"' + ) + raise ValueError(msg) import xml.etree.ElementTree as ET + tree = ET.parse(cross_sections_xml) root = tree.getroot() for child in root[:1]: - available_isotope = child.attrib['materials'] + available_isotope = child.attrib["materials"] return available_isotope @@ -98,53 +108,3 @@ def diff_between_angles(angle_a: float, angle_b: float) -> float: if delta_mod > 180: delta_mod -= 360 return delta_mod - - -def find_bounding_box(h5m_filename: str) -> List[Tuple[float, float, float]]: - """Computes the bounding box of the DAGMC geometry - - Args: - h5m_filename: the filename of the DAGMC h5m file - - Returns: - x,y,z coordinates for the upper left and lower right corner - """ - if not Path(h5m_filename).is_file: - msg = f"h5m file with filename {h5m_filename} not found" - raise FileNotFoundError(msg) - dag_univ = openmc.DAGMCUniverse(h5m_filename, auto_geom_ids=False) - - geometry = openmc.Geometry(root=dag_univ) - geometry.root_universe = dag_univ - geometry.export_to_xml() - - silently_remove_file("materials.xml") - materials = create_placeholder_openmc_materials(h5m_filename) - materials.export_to_xml() - - openmc.Plots().export_to_xml() - - # a minimal settings .xml to allow openmc to init - settings = openmc.Settings() - settings.verbosity = 1 - settings.batches = 1 - settings.particles = 1 - settings.export_to_xml() - - # The -p runs in plotting mode which avoids the check that OpenMC does - # when looking for boundary surfaces and therefore avoids this error - # ERROR: No boundary conditions were applied to any surfaces! - openmc.lib.init(["-p"]) - - bbox = openmc.lib.global_bounding_box() - openmc.lib.finalize() - - silently_remove_file("settings.xml") - silently_remove_file("plots.xml") - silently_remove_file("geometry.xml") - silently_remove_file("materials.xml") - - return ( - (bbox[0][0], bbox[0][1], bbox[0][2]), - (bbox[1][0], bbox[1][1], bbox[1][2]), - ) diff --git a/requirements-test.txt b/requirements-test.txt index 21976d9..2ef0094 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -6,3 +6,5 @@ nbformat nbconvert requests openmc-plasma-source +dagmc_bounding_box +remove_dagmc_tags diff --git a/tests/test_materials.py b/tests/test_materials.py index 3888203..a55f673 100644 --- a/tests/test_materials.py +++ b/tests/test_materials.py @@ -1,4 +1,3 @@ - import tarfile import unittest import urllib.request @@ -39,15 +38,15 @@ def setUp(self): def test_resulting_attributes_with_single_material_and_string(self): my_material = odw.Materials( - correspondence_dict={'mat1': 'Be'}, - h5m_filename=self.h5m_filename_smaller - ) + correspondence_dict={ + "mat1": "Be"}, + h5m_filename=self.h5m_filename_smaller) assert isinstance(my_material, openmc.Materials) assert len(my_material) == 1 - assert my_material[0].nuclides[0][0] == 'Be9' - assert my_material[0].nuclides[0][1] == 1. - assert my_material[0].name == 'mat1' + assert my_material[0].nuclides[0][0] == "Be9" + assert my_material[0].nuclides[0][1] == 1.0 + assert my_material[0].name == "mat1" def test_incorrect_materials(self): """Set a material as a string which should raise an error""" diff --git a/tests/test_neutronics_utils.py b/tests/test_neutronics_utils.py index ce41eb7..aac1547 100644 --- a/tests/test_neutronics_utils.py +++ b/tests/test_neutronics_utils.py @@ -5,8 +5,7 @@ from pathlib import Path import openmc -import openmc_dagmc_wrapper -from openmc_dagmc_wrapper import create_material, find_bounding_box +import openmc_dagmc_wrapper as odw import neutronics_material_maker as nmm import pytest @@ -28,6 +27,39 @@ def setUp(self): self.h5m_filename_smaller = "tests/neutronics_workflow-0.0.2/example_01_single_volume_cell_tally/stage_2_output/dagmc.h5m" self.h5m_filename_bigger = "tests/neutronics_workflow-0.0.2/example_02_multi_volume_cell_tally/stage_2_output/dagmc.h5m" + def test_get_an_isotope_present_in_cross_sections_xml(self): + """Checks that an isotope string is returned from the + cross_sections.xml file""" + + isotope = odw.utils.get_an_isotope_present_in_cross_sections_xml() + assert isinstance(isotope, str) + # could be an isotope such as Ag107 or H3 or and element such as H + assert len(isotope) in [1, 2, 3, 4, 5] + + def test_get_an_isotope_present_in_cross_sections_xml_error_handeling( + self): + """Checks that an error message is raised if the OPENMC_CROSS_SECTIONS + variable does not exist""" + + def no_env_var(): + del os.environ["OPENMC_CROSS_SECTIONS"] + odw.utils.get_an_isotope_present_in_cross_sections_xml() + + cross_sections_xml = os.getenv("OPENMC_CROSS_SECTIONS") + self.assertRaises(ValueError, no_env_var) + # sets the variable again so that other tests don't fail + os.environ["OPENMC_CROSS_SECTIONS"] = cross_sections_xml + + def test_diff_between_angles_returns_correct_answer(self): + """Checks the angle difference works with a few known examples""" + + assert odw.diff_between_angles(0, 90) == 90 + assert odw.diff_between_angles(0, 180) == 180 + assert odw.diff_between_angles(90, 90) == 0 + assert odw.diff_between_angles(180, 90) == -90 + assert odw.diff_between_angles(360, 0) == 0 + assert odw.diff_between_angles(0, 360) == 0 + def test_create_material_from_string(self): mats = ["Be", "tungsten", "eurofer", "copper"] @@ -40,7 +72,7 @@ def test_create_material_from_string(self): expected_mat.name = tag_mat # run - produced_mat = create_material(tag_mat, mat) + produced_mat = odw.create_material(tag_mat, mat) # test assert produced_mat.density == expected_mat.density @@ -59,7 +91,7 @@ def test_create_material_as_openmc_materials(self): expected_mat.name = tag_mat # run - produced_mat = create_material(tag_mat, expected_mat) + produced_mat = odw.create_material(tag_mat, expected_mat) # test assert produced_mat.density == expected_mat.density @@ -68,40 +100,10 @@ def test_create_material_as_openmc_materials(self): def test_create_material_wrong_type(self): def incorrect_type(): - create_material("mat1", [1, 2, 3]) + odw.create_material("mat1", [1, 2, 3]) self.assertRaises(TypeError, incorrect_type) - def test_bounding_box_size(self): - - bounding_box = find_bounding_box(self.h5m_filename_bigger) - - print(bounding_box) - assert len(bounding_box) == 2 - assert len(bounding_box[0]) == 3 - assert len(bounding_box[1]) == 3 - assert bounding_box[0][0] == pytest.approx(-10005, abs=0.1) - assert bounding_box[0][1] == pytest.approx(-10005, abs=0.1) - assert bounding_box[0][2] == pytest.approx(-10005, abs=0.1) - assert bounding_box[1][0] == pytest.approx(10005, abs=0.1) - assert bounding_box[1][1] == pytest.approx(10005, abs=0.1) - assert bounding_box[1][2] == pytest.approx(10005, abs=0.1) - - def test_bounding_box_size_2(self): - - bounding_box = find_bounding_box(self.h5m_filename_smaller) - - print(bounding_box) - assert len(bounding_box) == 2 - assert len(bounding_box[0]) == 3 - assert len(bounding_box[1]) == 3 - assert bounding_box[0][0] == pytest.approx(-10005, abs=0.1) - assert bounding_box[0][1] == pytest.approx(-10005, abs=0.1) - assert bounding_box[0][2] == pytest.approx(-10005, abs=0.1) - assert bounding_box[1][0] == pytest.approx(10005, abs=0.1) - assert bounding_box[1][1] == pytest.approx(10005, abs=0.1) - assert bounding_box[1][2] == pytest.approx(10005, abs=0.1) - # def test_create_initial_source_file(self): # """Creates an initial_source.h5 from a point source""" diff --git a/tests/test_settings.py b/tests/test_settings.py index 7752009..46ab115 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -1,4 +1,3 @@ - import unittest import openmc_dagmc_wrapper as odw diff --git a/tests/test_system/test_system_multi_volume.py b/tests/test_system/test_system_multi_volume.py index 856318a..5175005 100644 --- a/tests/test_system/test_system_multi_volume.py +++ b/tests/test_system/test_system_multi_volume.py @@ -57,18 +57,19 @@ def setUp(self): def test_cell_tally_simulation(self): - os.system('rm statepoint*.h5') + os.system("rm statepoint*.h5") geometry = odw.Geometry(h5m_filename=self.h5m_filename_bigger) materials = odw.Materials( h5m_filename=self.h5m_filename_bigger, - correspondence_dict=self.material_description_bigger) + correspondence_dict=self.material_description_bigger, + ) my_tally = odw.CellTally("TBR") my_model = openmc.model.Model( geometry=geometry, materials=materials, tallies=[my_tally], - settings=self.settings + settings=self.settings, ) statepoint_file = my_model.run() diff --git a/tests/test_system/test_system_single_volume.py b/tests/test_system/test_system_single_volume.py index a633cc8..9fa1925 100644 --- a/tests/test_system/test_system_single_volume.py +++ b/tests/test_system/test_system_single_volume.py @@ -7,6 +7,8 @@ import neutronics_material_maker as nmm import openmc import openmc_dagmc_wrapper as odw +from dagmc_bounding_box import DagmcBoundingBox +from remove_dagmc_tags import remove_tags class TestShape(unittest.TestCase): @@ -66,15 +68,44 @@ def test_simulation_with_previous_h5m_file(self): geometry = odw.Geometry(h5m_filename=self.h5m_filename_smaller) materials = odw.Materials( h5m_filename=self.h5m_filename_smaller, - correspondence_dict={"mat1": "WC"}) + correspondence_dict={ + "mat1": "WC"}) my_model = openmc.model.Model( geometry=geometry, materials=materials, tallies=[], - settings=self.settings + settings=self.settings) + + statepoint_file = my_model.run() + + assert Path(statepoint_file).exists() + + def test_simulation_with_previous_h5m_file_with_graveyard_removed(self): + """This performs a simulation using previously created h5m file. The + graveyard is removed from the geometry""" + + os.system("rm statepoint.*.h5") + os.system("rm summary.h5") + + remove_tags( + input=self.h5m_filename_smaller, + output="no_graveyard_dagmc_file.h5m", + tags=["mat:graveyard", "graveyard"], ) + geometry = odw.Geometry(h5m_filename="no_graveyard_dagmc_file.h5m") + materials = odw.Materials( + h5m_filename="no_graveyard_dagmc_file.h5m", + correspondence_dict={"mat1": "WC"}, + ) + + my_model = openmc.model.Model( + geometry=geometry, + materials=materials, + tallies=[], + settings=self.settings) + statepoint_file = my_model.run() assert Path(statepoint_file).exists() @@ -92,7 +123,8 @@ def test_neutronics_component_simulation_with_openmc_mat(self): geometry = odw.Geometry(h5m_filename=self.h5m_filename_smaller) materials = odw.Materials( h5m_filename=self.h5m_filename_smaller, - correspondence_dict={"mat1": test_mat}) + correspondence_dict={"mat1": test_mat}, + ) my_tally = odw.CellTally("heating", target="mat1", materials=materials) self.settings.batches = 2 @@ -100,7 +132,7 @@ def test_neutronics_component_simulation_with_openmc_mat(self): geometry=geometry, materials=materials, tallies=[my_tally], - settings=self.settings + settings=self.settings, ) h5m_filename = my_model.run() self.settings.batches = 10 @@ -120,7 +152,8 @@ def test_neutronics_component_simulation_with_nmm(self): geometry = odw.Geometry(h5m_filename=self.h5m_filename_smaller) materials = odw.Materials( h5m_filename=self.h5m_filename_smaller, - correspondence_dict={"mat1": test_mat}) + correspondence_dict={"mat1": test_mat}, + ) my_tally = odw.CellTally("heating", target=1) @@ -128,7 +161,7 @@ def test_neutronics_component_simulation_with_nmm(self): geometry=geometry, materials=materials, tallies=[my_tally], - settings=self.settings + settings=self.settings, ) h5m_filename = my_model.run() @@ -139,6 +172,7 @@ def test_neutronics_component_simulation_with_nmm(self): def test_incorrect_cell_tallies(self): """Set a cell tally that is not accepted which should raise an error""" + def incorrect_cell_tallies(): odw.CellTally("coucou") @@ -147,6 +181,7 @@ def incorrect_cell_tallies(): def test_incorrect_cell_tally_type(self): """Set a cell tally that is the wrong type which should raise an error""" + def incorrect_cell_tally_type(): odw.CellTally(1) @@ -165,7 +200,8 @@ def test_neutronics_component_cell_simulation_heating(self): geometry = odw.Geometry(h5m_filename=self.h5m_filename_smaller) materials = odw.Materials( h5m_filename=self.h5m_filename_smaller, - correspondence_dict={"mat1": mat}) + correspondence_dict={ + "mat1": mat}) my_tallies = odw.CellTallies( tally_types=[ "heating", @@ -178,7 +214,7 @@ def test_neutronics_component_cell_simulation_heating(self): geometry=geometry, materials=materials, tallies=my_tallies.tallies, - settings=self.settings + settings=self.settings, ) # performs an openmc simulation on the model h5m_filename = my_model.run() @@ -201,15 +237,18 @@ def test_neutronics_spectra(self): geometry = odw.Geometry(h5m_filename=self.h5m_filename_smaller) materials = odw.Materials( h5m_filename=self.h5m_filename_smaller, - correspondence_dict={"mat1": mat}) + correspondence_dict={ + "mat1": mat}) my_tallies = odw.CellTallies( - tally_types=["neutron_spectra", "photon_spectra"]) + tally_types=[ + "neutron_spectra", + "photon_spectra"]) my_model = openmc.model.Model( geometry=geometry, materials=materials, tallies=my_tallies.tallies, - settings=self.settings + settings=self.settings, ) # performs an openmc simulation on the model @@ -226,17 +265,20 @@ def test_neutronics_component_2d_mesh_simulation(self): geometry = odw.Geometry(h5m_filename=self.h5m_filename_smaller) materials = odw.Materials( h5m_filename=self.h5m_filename_smaller, - correspondence_dict={"mat1": "Be"}) + correspondence_dict={ + "mat1": "Be"}) + my_tallies = odw.MeshTallies2D( tally_types=["heating"], planes=["xy", "xz", "yz"], - bounding_box=self.h5m_filename_smaller) + bounding_box=DagmcBoundingBox(self.h5m_filename_smaller).corners(), + ) my_model = openmc.model.Model( geometry=geometry, materials=materials, tallies=my_tallies.tallies, - settings=self.settings + settings=self.settings, ) # performs an openmc simulation on the model h5m_filename = my_model.run() @@ -257,23 +299,27 @@ def test_neutronics_component_3d_mesh_simulation(self): geometry = odw.Geometry(h5m_filename=self.h5m_filename_smaller) materials = odw.Materials( h5m_filename=self.h5m_filename_smaller, - correspondence_dict={"mat1": "Be"}) + correspondence_dict={ + "mat1": "Be"}) my_tallies = odw.MeshTallies3D( tally_types=["heating", "(n,Xt)"], - bounding_box=self.h5m_filename_smaller) + bounding_box=DagmcBoundingBox(self.h5m_filename_smaller).corners(), + ) my_model = openmc.model.Model( geometry=geometry, materials=materials, tallies=my_tallies.tallies, - settings=self.settings + settings=self.settings, ) # performs an openmc simulation on the model h5m_filename = my_model.run() results = openmc.StatePoint(h5m_filename) - assert len(results.meshes) == 1 + # ideally these tallies would share the same mesh and there would be 1 + # mesh + assert len(results.meshes) == 2 assert len(results.tallies.items()) == 2 assert Path(h5m_filename).exists() is True @@ -288,21 +334,25 @@ def test_neutronics_component_3d_and_2d_mesh_simulation(self): geometry = odw.Geometry(h5m_filename=self.h5m_filename_smaller) materials = odw.Materials( h5m_filename=self.h5m_filename_smaller, - correspondence_dict={"mat1": "Be"}) + correspondence_dict={ + "mat1": "Be"}) my_3d_tally = odw.MeshTally3D( - tally_type="heating", bounding_box=self.h5m_filename_smaller) + tally_type="heating", + bounding_box=DagmcBoundingBox(self.h5m_filename_smaller).corners(), + ) my_2d_tallies = odw.MeshTallies2D( planes=["xz", "xy", "yz"], tally_types=["heating"], - bounding_box=self.h5m_filename_smaller) + bounding_box=DagmcBoundingBox(self.h5m_filename_smaller).corners(), + ) my_model = openmc.model.Model( geometry=geometry, materials=materials, tallies=[my_3d_tally] + my_2d_tallies.tallies, - settings=self.settings + settings=self.settings, ) # performs an openmc simulation on the model h5m_filename = my_model.run() @@ -323,7 +373,8 @@ def test_neutronics_component_3d_and_2d_mesh_simulation_with_corner_points( geometry = odw.Geometry(h5m_filename=self.h5m_filename_smaller) materials = odw.Materials( h5m_filename=self.h5m_filename_smaller, - correspondence_dict={"mat1": "Be"}) + correspondence_dict={ + "mat1": "Be"}) my_3d_tally = odw.MeshTally3D( tally_type="heating", @@ -333,7 +384,7 @@ def test_neutronics_component_3d_and_2d_mesh_simulation_with_corner_points( my_2d_tallies = odw.MeshTallies2D( planes=["xz", "xy", "yz"], tally_types=["heating"], - bounding_box=[(5, 5, 5), (15, 15, 15)] + bounding_box=[(5, 5, 5), (15, 15, 15)], ) assert my_3d_tally.bounding_box == [(0, 0, 0), (10, 10, 10)] @@ -344,7 +395,7 @@ def test_neutronics_component_3d_and_2d_mesh_simulation_with_corner_points( geometry=geometry, materials=materials, tallies=[my_3d_tally] + my_2d_tallies.tallies, - settings=self.settings + settings=self.settings, ) # performs an openmc simulation on the model @@ -364,16 +415,16 @@ def test_reactor_from_shapes_cell_tallies(self): geometry = odw.Geometry(h5m_filename=self.h5m_filename_smaller) materials = odw.Materials( h5m_filename=self.h5m_filename_smaller, - correspondence_dict={"mat1": "Be"}) + correspondence_dict={ + "mat1": "Be"}) - my_tallies = odw.CellTallies( - tally_types=["TBR", "heating", "flux"]) + my_tallies = odw.CellTallies(tally_types=["TBR", "heating", "flux"]) my_model = openmc.model.Model( geometry=geometry, materials=materials, tallies=my_tallies.tallies, - settings=self.settings + settings=self.settings, ) # performs an openmc simulation on the model @@ -391,16 +442,18 @@ def test_cell_tallies_simulation_fast_flux(self): geometry = odw.Geometry(h5m_filename=self.h5m_filename_smaller) materials = odw.Materials( h5m_filename=self.h5m_filename_smaller, - correspondence_dict={"mat1": "Be"}) + correspondence_dict={ + "mat1": "Be"}) my_tallies = odw.CellTallies( - tally_types=["photon_fast_flux", "neutron_fast_flux", "flux"]) + tally_types=["photon_fast_flux", "neutron_fast_flux", "flux"] + ) my_model = openmc.model.Model( geometry=geometry, materials=materials, tallies=my_tallies.tallies, - settings=self.settings + settings=self.settings, ) # performs an openmc simulation on the model @@ -418,16 +471,18 @@ def test_cell_tallies_simulation_effective_dose(self): geometry = odw.Geometry(h5m_filename=self.h5m_filename_smaller) materials = odw.Materials( h5m_filename=self.h5m_filename_smaller, - correspondence_dict={"mat1": "Be"}) + correspondence_dict={ + "mat1": "Be"}) my_tallies = odw.CellTallies( - tally_types=["photon_effective_dose", "neutron_effective_dose"]) + tally_types=["photon_effective_dose", "neutron_effective_dose"] + ) my_model = openmc.model.Model( geometry=geometry, materials=materials, tallies=my_tallies.tallies, - settings=self.settings + settings=self.settings, ) # performs an openmc simulation on the model @@ -456,9 +511,9 @@ def test_cell_tallies_simulation_effective_dose(self): # ) # # performs an openmc simulation on the model - # statepoint_file = my_model.run() + # statepoint_file = my_model.run() - # assert Path(statepoint_file).exists() + # assert Path(statepoint_file).exists() def test_simulations_with_missing_h5m_files(self): """Creates NeutronicsModel objects and tries to perform simulation @@ -469,7 +524,8 @@ def test_missing_h5m_file_error_handling(): should fail with a FileNotFoundError""" import shutil - shutil.copy(self.h5m_filename_smaller, '.') + + shutil.copy(self.h5m_filename_smaller, ".") # creates xml files so that the code passes the xml file check os.system("touch geometry.xml") @@ -480,8 +536,8 @@ def test_missing_h5m_file_error_handling(): odw.Materials( h5m_filename="dagmc.h5m", - correspondence_dict={"mat1": "Be"} - ) + correspondence_dict={ + "mat1": "Be"}) self.assertRaises( FileNotFoundError, diff --git a/tests/test_tallies/test_cell_tallies.py b/tests/test_tallies/test_cell_tallies.py index 36f4346..6639b05 100644 --- a/tests/test_tallies/test_cell_tallies.py +++ b/tests/test_tallies/test_cell_tallies.py @@ -1,5 +1,7 @@ +import tarfile import unittest - +import urllib.request +from pathlib import Path import openmc import openmc_dagmc_wrapper as odw @@ -8,6 +10,19 @@ class TestCellTallies(unittest.TestCase): """Tests the CellTallies class functionality""" + def setUp(self): + + if not Path("tests/v0.0.2.tar.gz").is_file(): + url = "https://github.com/fusion-energy/neutronics_workflow/archive/refs/tags/v0.0.2.tar.gz" + urllib.request.urlretrieve(url, "tests/v0.0.2.tar.gz") + + tar = tarfile.open("tests/v0.0.2.tar.gz", "r:gz") + tar.extractall("tests") + tar.close() + + self.h5m_filename_smaller = "tests/neutronics_workflow-0.0.2/example_01_single_volume_cell_tally/stage_2_output/dagmc.h5m" + self.h5m_filename_bigger = "tests/neutronics_workflow-0.0.2/example_02_multi_volume_cell_tally/stage_2_output/dagmc.h5m" + def test_name(self): my_tally = odw.CellTally("heating", target=1) @@ -15,3 +30,29 @@ def test_name(self): my_tally = odw.CellTally("heating", target="coucou", materials=[]) assert my_tally.name == "coucou_heating" + + def test_cell_filter(self): + my_tally = odw.CellTally("heating", target=4) + + assert len(my_tally.filters[0].bins) == 1 + assert my_tally.filters[0].bins[0] == 4 + + my_tally = odw.CellTally("neutron_flux", target=2) + + assert len(my_tally.filters[0].bins) == 1 + assert my_tally.filters[0].bins[0] == "neutron" + + my_tally = odw.CellTally("photon_flux", target=2) + + assert len(my_tally.filters[0].bins) == 1 + assert my_tally.filters[0].bins[0] == "photon" + + my_tally = odw.CellTally("neutron_heating", target=2) + + assert len(my_tally.filters[0].bins) == 1 + assert my_tally.filters[0].bins[0] == "neutron" + + my_tally = odw.CellTally("photon_heating", target=2) + + assert len(my_tally.filters[0].bins) == 1 + assert my_tally.filters[0].bins[0] == "photon" diff --git a/tests/test_tallies/test_mesh_tally_2d.py b/tests/test_tallies/test_mesh_tally_2d.py index e6e12d2..a9454ad 100644 --- a/tests/test_tallies/test_mesh_tally_2d.py +++ b/tests/test_tallies/test_mesh_tally_2d.py @@ -6,6 +6,7 @@ import openmc import openmc_dagmc_wrapper as odw from openmc_plasma_source import FusionRingSource +from dagmc_bounding_box import DagmcBoundingBox class TestMeshTally2D(unittest.TestCase): @@ -58,19 +59,19 @@ def test_shape_of_resulting_png(self): tally1 = odw.MeshTally2D( tally_type="neutron_flux", plane="xy", - bounding_box=self.h5m_filename_smaller, + bounding_box=DagmcBoundingBox(self.h5m_filename_smaller).corners(), mesh_resolution=(10, 200), ) tally2 = odw.MeshTally2D( tally_type="neutron_flux", plane="xz", - bounding_box=self.h5m_filename_smaller, + bounding_box=DagmcBoundingBox(self.h5m_filename_smaller).corners(), mesh_resolution=(20, 100), ) tally3 = odw.MeshTally2D( tally_type="neutron_flux", plane="yz", - bounding_box=self.h5m_filename_smaller, + bounding_box=DagmcBoundingBox(self.h5m_filename_smaller).corners(), mesh_resolution=(30, 500), ) diff --git a/tests/test_tallies/test_mesh_tally_3d.py b/tests/test_tallies/test_mesh_tally_3d.py index f3e6b0f..72773b2 100644 --- a/tests/test_tallies/test_mesh_tally_3d.py +++ b/tests/test_tallies/test_mesh_tally_3d.py @@ -5,6 +5,7 @@ import openmc import openmc_dagmc_wrapper as odw +from dagmc_bounding_box import DagmcBoundingBox class TestMeshTally3D(unittest.TestCase): @@ -45,15 +46,17 @@ def incorrect_mesh_tally_3d_type(): def test_meshfilter_from_h5m_file(self): # build - bbox = odw.find_bounding_box(self.h5m_filename_smaller) expected_mesh = openmc.RegularMesh(mesh_id=99, name="3d_mesh_expected") + bbox = DagmcBoundingBox(self.h5m_filename_smaller).corners() expected_mesh.lower_left = bbox[0] expected_mesh.upper_right = bbox[1] expected_mesh.dimension = (100, 100, 100) # run my_tally = odw.MeshTally3D( - "heating", bounding_box=self.h5m_filename_smaller) + "heating", + bounding_box=DagmcBoundingBox(self.h5m_filename_smaller).corners(), + ) produced_filter = my_tally.filters[-1] produced_mesh = produced_filter.mesh # test