diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 050c8e287..b7c548a37 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,9 +34,6 @@ jobs: vectfit: [n] include: - - python-version: 3.6 - omp: n - mpi: n - python-version: 3.7 omp: n mpi: n diff --git a/docs/source/devguide/styleguide.rst b/docs/source/devguide/styleguide.rst index 44d80915e..2a744b819 100644 --- a/docs/source/devguide/styleguide.rst +++ b/docs/source/devguide/styleguide.rst @@ -142,7 +142,7 @@ Style for Python code should follow PEP8_. Docstrings for functions and methods should follow numpydoc_ style. -Python code should work with Python 3.6+. +Python code should work with Python 3.7+. Use of third-party Python packages should be limited to numpy_, scipy_, matplotlib_, pandas_, and h5py_. Use of other third-party packages must be diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index b57958814..74be9ba0b 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -511,7 +511,7 @@ to install the Python package in :ref:`"editable" mode `. Prerequisites ------------- -The Python API works with Python 3.6+. In addition to Python itself, the API +The Python API works with Python 3.7+. In addition to Python itself, the API relies on a number of third-party packages. All prerequisites can be installed using Conda_ (recommended), pip_, or through the package manager in most Linux distributions. diff --git a/openmc/mesh.py b/openmc/mesh.py index 8f47e4e7b..f381d99b0 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -514,7 +514,7 @@ class RegularMesh(StructuredMesh): def from_domain( cls, domain, - dimension=[100, 100, 100], + dimension=(10, 10, 10), mesh_id=None, name='' ): @@ -1147,6 +1147,76 @@ class CylindricalMesh(StructuredMesh): return mesh + @classmethod + def from_domain( + cls, + domain, + dimension=(10, 10, 10), + mesh_id=None, + phi_grid_bounds=(0.0, 2*pi), + name='' + ): + """Creates a regular CylindricalMesh from an existing openmc domain. + + Parameters + ---------- + domain : openmc.Cell or openmc.Region or openmc.Universe or openmc.Geometry + The object passed in will be used as a template for this mesh. The + bounding box of the property of the object passed will be used to + set the r_grid, z_grid ranges. + dimension : Iterable of int + The number of equally spaced mesh cells in each direction (r_grid, + phi_grid, z_grid) + mesh_id : int + Unique identifier for the mesh + phi_grid_bounds : numpy.ndarray + Mesh bounds points along the phi-axis in radians. The default value + is (0, 2π), i.e., the full phi range. + name : str + Name of the mesh + + Returns + ------- + openmc.RegularMesh + RegularMesh instance + + """ + cv.check_type( + "domain", + domain, + (openmc.Cell, openmc.Region, openmc.Universe, openmc.Geometry), + ) + + mesh = cls(mesh_id, name) + + # loaded once to avoid reading h5m file repeatedly + cached_bb = domain.bounding_box + max_bounding_box_radius = max( + [ + cached_bb[0][0], + cached_bb[0][1], + cached_bb[1][0], + cached_bb[1][1], + ] + ) + mesh.r_grid = np.linspace( + 0, + max_bounding_box_radius, + num=dimension[0]+1 + ) + mesh.phi_grid = np.linspace( + phi_grid_bounds[0], + phi_grid_bounds[1], + num=dimension[1]+1 + ) + mesh.z_grid = np.linspace( + cached_bb[0][2], + cached_bb[1][2], + num=dimension[2]+1 + ) + + return mesh + def to_xml_element(self): """Return XML representation of the mesh diff --git a/setup.py b/setup.py index 477f29dec..2a7e6a58d 100755 --- a/setup.py +++ b/setup.py @@ -57,14 +57,14 @@ kwargs = { 'Topic :: Scientific/Engineering' 'Programming Language :: C++', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', ], # Dependencies - 'python_requires': '>=3.6', + 'python_requires': '>=3.7', 'install_requires': [ 'numpy>=1.9', 'h5py', 'scipy', 'ipython', 'matplotlib', 'pandas', 'lxml', 'uncertainties' diff --git a/src/state_point.cpp b/src/state_point.cpp index 648d1a249..470dd7718 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -527,6 +527,7 @@ hid_t h5banktype() H5Tinsert(banktype, "r", HOFFSET(SourceSite, r), postype); H5Tinsert(banktype, "u", HOFFSET(SourceSite, u), postype); H5Tinsert(banktype, "E", HOFFSET(SourceSite, E), H5T_NATIVE_DOUBLE); + H5Tinsert(banktype, "time", HOFFSET(SourceSite, time), H5T_NATIVE_DOUBLE); H5Tinsert(banktype, "wgt", HOFFSET(SourceSite, wgt), H5T_NATIVE_DOUBLE); H5Tinsert(banktype, "delayed_group", HOFFSET(SourceSite, delayed_group), H5T_NATIVE_INT); diff --git a/tests/regression_tests/surface_source/surface_source_true.h5 b/tests/regression_tests/surface_source/surface_source_true.h5 index 2ea48b2ac..c26afee86 100644 Binary files a/tests/regression_tests/surface_source/surface_source_true.h5 and b/tests/regression_tests/surface_source/surface_source_true.h5 differ diff --git a/tests/unit_tests/test_mesh_from_domain.py b/tests/unit_tests/test_mesh_from_domain.py index ce27288ad..b4edae196 100644 --- a/tests/unit_tests/test_mesh_from_domain.py +++ b/tests/unit_tests/test_mesh_from_domain.py @@ -16,6 +16,22 @@ def test_reg_mesh_from_cell(): assert np.array_equal(mesh.upper_right, cell.bounding_box[1]) +def test_cylindrical_mesh_from_cell(): + """Tests a CylindricalMesh can be made from a Cell and the specified + dimensions are propagated through. Cell is not centralized""" + cy_surface = openmc.ZCylinder(r=50) + z_surface_1 = openmc.ZPlane(z0=30) + z_surface_2 = openmc.ZPlane(z0=0) + cell = openmc.Cell(region=-cy_surface & -z_surface_1 & +z_surface_2) + mesh = openmc.CylindricalMesh.from_domain(cell, dimension=[2, 4, 3]) + + assert isinstance(mesh, openmc.CylindricalMesh) + assert np.array_equal(mesh.dimension, (2, 4, 3)) + assert np.array_equal(mesh.r_grid, [0., 25., 50.]) + assert np.array_equal(mesh.phi_grid, [0., 0.5*np.pi, np.pi, 1.5*np.pi, 2.*np.pi]) + assert np.array_equal(mesh.z_grid, [0., 10., 20., 30.]) + + def test_reg_mesh_from_region(): """Tests a RegularMesh can be made from a Region and the default dimensions are propagated through. Region is not centralized""" @@ -24,28 +40,48 @@ def test_reg_mesh_from_region(): mesh = openmc.RegularMesh.from_domain(region) assert isinstance(mesh, openmc.RegularMesh) - assert np.array_equal(mesh.dimension, (100, 100, 100)) # default values + assert np.array_equal(mesh.dimension, (10, 10, 10)) # default values assert np.array_equal(mesh.lower_left, region.bounding_box[0]) assert np.array_equal(mesh.upper_right, region.bounding_box[1]) +def test_cylindrical_mesh_from_region(): + """Tests a CylindricalMesh can be made from a Region and the specified + dimensions and phi_grid_bounds are propagated through. Cell is centralized""" + cy_surface = openmc.ZCylinder(r=6) + z_surface_1 = openmc.ZPlane(z0=30) + z_surface_2 = openmc.ZPlane(z0=-30) + cell = openmc.Cell(region=-cy_surface & -z_surface_1 & +z_surface_2) + mesh = openmc.CylindricalMesh.from_domain( + cell, + dimension=(6, 2, 3), + phi_grid_bounds=(0., np.pi) + ) + + assert isinstance(mesh, openmc.CylindricalMesh) + assert np.array_equal(mesh.dimension, (6, 2, 3)) + assert np.array_equal(mesh.r_grid, [0., 1., 2., 3., 4., 5., 6.]) + assert np.array_equal(mesh.phi_grid, [0., 0.5*np.pi, np.pi]) + assert np.array_equal(mesh.z_grid, [-30., -10., 10., 30.]) + + def test_reg_mesh_from_universe(): - """Tests a RegularMesh can be made from a Universe and the default dimensions - are propagated through. Universe is centralized""" + """Tests a RegularMesh can be made from a Universe and the default + dimensions are propagated through. Universe is centralized""" surface = openmc.Sphere(r=42) cell = openmc.Cell(region=-surface) universe = openmc.Universe(cells=[cell]) mesh = openmc.RegularMesh.from_domain(universe) assert isinstance(mesh, openmc.RegularMesh) - assert np.array_equal(mesh.dimension, (100, 100, 100)) # default values + assert np.array_equal(mesh.dimension, (10, 10, 10)) # default values assert np.array_equal(mesh.lower_left, universe.bounding_box[0]) assert np.array_equal(mesh.upper_right, universe.bounding_box[1]) def test_reg_mesh_from_geometry(): - """Tests a RegularMesh can be made from a Geometry and the default dimensions - are propagated through. Geometry is centralized""" + """Tests a RegularMesh can be made from a Geometry and the default + dimensions are propagated through. Geometry is centralized""" surface = openmc.Sphere(r=42) cell = openmc.Cell(region=-surface) universe = openmc.Universe(cells=[cell]) @@ -53,7 +89,7 @@ def test_reg_mesh_from_geometry(): mesh = openmc.RegularMesh.from_domain(geometry) assert isinstance(mesh, openmc.RegularMesh) - assert np.array_equal(mesh.dimension, (100, 100, 100)) # default values + assert np.array_equal(mesh.dimension, (10, 10, 10)) # default values assert np.array_equal(mesh.lower_left, geometry.bounding_box[0]) assert np.array_equal(mesh.upper_right, geometry.bounding_box[1]) diff --git a/tests/unit_tests/test_source_file.py b/tests/unit_tests/test_source_file.py index 1398088e5..78115a1f6 100644 --- a/tests/unit_tests/test_source_file.py +++ b/tests/unit_tests/test_source_file.py @@ -75,3 +75,25 @@ def test_wrong_source_attributes(run_in_tmpdir): with pytest.raises(RuntimeError) as excinfo: openmc.run() assert 'platypus, axolotl, narwhal' in str(excinfo.value) + + +def test_source_file_transport(run_in_tmpdir): + # Create a source file with a single particle + particle = openmc.SourceParticle() + openmc.write_source_file([particle], 'source.h5') + + # Created simple model to use source file + model = openmc.Model() + al = openmc.Material() + al.add_element('Al', 1.0) + al.set_density('g/cm3', 2.7) + sph = openmc.Sphere(r=10.0, boundary_type='vacuum') + cell = openmc.Cell(fill=al, region=-sph) + model.geometry = openmc.Geometry([cell]) + model.settings.source = openmc.Source(filename='source.h5') + model.settings.particles = 10 + model.settings.batches = 3 + model.settings.run_mode = 'fixed source' + + # Try running OpenMC + model.run()