diff --git a/.github/actions/fix-etc-hosts/action.yml b/.github/actions/fix-etc-hosts/action.yml deleted file mode 100644 index 15efcaed2e..0000000000 --- a/.github/actions/fix-etc-hosts/action.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Fix /etc/hosts -description: | - Workaround for - "Reverse name lookup is broken for current hostname in ubuntu-latest VMs", - reported as https://github.com/actions/virtual-environments/issues/3185 -runs: - using: composite - steps: - - run: | - if [[ "$OSTYPE" == "linux-gnu"* ]]; then - # Ensure that reverse lookups for current hostname are handled properly - # Add the current IP address, long hostname and short hostname record to /etc/hosts file - eth0_ip_addr=$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1) - hostname_fqdn=$(hostname -f) - hostname_short=$(hostname -s) - echo -e "${eth0_ip_addr}\t${hostname_fqdn} ${hostname_short}" | sudo tee -a /etc/hosts - fi - shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f4bff2339..15392cde0e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,8 +78,6 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: ./.github/actions/fix-etc-hosts - - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 @@ -97,12 +95,11 @@ jobs: shell: bash run: | sudo apt -y update - sudo apt install -y mpich \ - libmpich-dev \ + sudo apt install -y libopenmpi-dev \ libnetcdf-dev \ libpnetcdf-dev \ libhdf5-serial-dev \ - libhdf5-mpich-dev \ + libhdf5-openmpi-dev \ libeigen3-dev - name: install diff --git a/src/surface.cpp b/src/surface.cpp index 8b2bb12832..1f542e64e0 100644 --- a/src/surface.cpp +++ b/src/surface.cpp @@ -1168,6 +1168,8 @@ void read_surfaces(pugi::xml_node node) // Compute the dot product of the surface normals Direction norm1 = surf1.normal({0, 0, 0}); Direction norm2 = surf2.normal({0, 0, 0}); + norm1 /= norm1.norm(); + norm2 /= norm2.norm(); double dot_prod = norm1.dot(norm2); // If the dot product is 1 (to within floating point precision) then the diff --git a/tests/regression_tests/cpp_driver/driver.cpp b/tests/regression_tests/cpp_driver/driver.cpp index 3b4bd1daa2..995d91e084 100644 --- a/tests/regression_tests/cpp_driver/driver.cpp +++ b/tests/regression_tests/cpp_driver/driver.cpp @@ -1,6 +1,10 @@ +#ifdef OPENMC_MPI +#include +#endif #include "openmc/capi.h" #include "openmc/cell.h" +#include "openmc/error.h" #include "openmc/geometry.h" #include "openmc/message_passing.h" #include "openmc/summary.h" @@ -11,7 +15,13 @@ using namespace openmc; int main(int argc, char** argv) { - openmc_init(argc, argv, nullptr); +#ifdef OPENMC_MPI + MPI_Comm world {MPI_COMM_WORLD}; + int err = openmc_init(argc, argv, &world); +#else + int err = openmc_init(argc, argv, nullptr); +#endif + if (err) fatal_error(openmc_err_msg); // create a new cell filter auto cell_filter = Filter::create(); @@ -57,5 +67,10 @@ int main(int argc, char** argv) { openmc_run(); openmc_finalize(); + +#ifdef OPENMC_MPI + MPI_Finalize(); +#endif + return 0; } diff --git a/tests/regression_tests/periodic/test.py b/tests/regression_tests/periodic/test.py index f9d26392f2..51a70a6aa7 100644 --- a/tests/regression_tests/periodic/test.py +++ b/tests/regression_tests/periodic/test.py @@ -1,58 +1,53 @@ import openmc +import pytest from tests.testing_harness import PyAPITestHarness -class PeriodicTest(PyAPITestHarness): - def _build_inputs(self): - # Define materials - water = openmc.Material(1) - water.add_nuclide('H1', 2.0) - water.add_nuclide('O16', 1.0) - water.add_s_alpha_beta('c_H_in_H2O') - water.set_density('g/cc', 1.0) +@pytest.fixture +def box_model(): + model = openmc.model.Model() + # Define materials + water = openmc.Material() + water.add_nuclide('H1', 2.0) + water.add_nuclide('O16', 1.0) + water.add_s_alpha_beta('c_H_in_H2O') + water.set_density('g/cc', 1.0) - fuel = openmc.Material(2) - fuel.add_nuclide('U235', 1.0) - fuel.set_density('g/cc', 4.5) + fuel = openmc.Material() + fuel.add_nuclide('U235', 1.0) + fuel.set_density('g/cc', 4.5) - materials = openmc.Materials((water, fuel)) - materials.default_temperature = '294K' - materials.export_to_xml() + # Define geometry + x_min = openmc.XPlane(surface_id=1, x0=0., boundary_type='periodic') + x_max = openmc.XPlane(surface_id=2, x0=5., boundary_type='reflective') - # Define geometry - x_min = openmc.XPlane(surface_id=1, x0=0., boundary_type='periodic') - x_max = openmc.XPlane(surface_id=2, x0=5., boundary_type='reflective') + y_min = openmc.YPlane(surface_id=3, y0=0., boundary_type='periodic') + y_max = openmc.YPlane(surface_id=4, y0=5., boundary_type='reflective') + y_min.periodic_surface = x_min - y_min = openmc.YPlane(surface_id=3, y0=0., boundary_type='periodic') - y_max = openmc.YPlane(surface_id=4, y0=5., boundary_type='reflective') - y_min.periodic_surface = x_min + z_min = openmc.ZPlane(surface_id=5, z0=-5., boundary_type='periodic') + z_max = openmc.Plane(surface_id=6, a=0, b=0, c=1, d=5., + boundary_type='periodic') + z_cyl = openmc.ZCylinder(surface_id=7, x0=2.5, y0=0., r=2.0) - z_min = openmc.ZPlane(surface_id=5, z0=-5., boundary_type='periodic') - z_max = openmc.Plane(surface_id=6, a=0, b=0, c=1, d=5., - boundary_type='periodic') - z_cyl = openmc.ZCylinder(surface_id=7, x0=2.5, y0=0., r=2.0) + outside_cyl = openmc.Cell(1, fill=water, region=( + +x_min & -x_max & +y_min & -y_max & +z_min & -z_max & +z_cyl)) + inside_cyl = openmc.Cell(2, fill=fuel, region=( + +y_min & +z_min & -z_max & -z_cyl)) + root_universe = openmc.Universe(0, cells=(outside_cyl, inside_cyl)) + model.geometry = openmc.Geometry(root_universe) - outside_cyl = openmc.Cell(1, fill=water, region=( - +x_min & -x_max & +y_min & -y_max & +z_min & -z_max & +z_cyl)) - inside_cyl = openmc.Cell(2, fill=fuel, region=( - +y_min & +z_min & -z_max & -z_cyl)) - root_universe = openmc.Universe(0, cells=(outside_cyl, inside_cyl)) - - geometry = openmc.Geometry() - geometry.root_universe = root_universe - geometry.export_to_xml() - - # Define settings - settings = openmc.Settings() - settings.particles = 1000 - settings.batches = 4 - settings.inactive = 0 - settings.source = openmc.Source(space=openmc.stats.Box( - (0, 0, 0), (5, 5, 0))) - settings.export_to_xml() + # Define settings + model.settings.particles = 1000 + model.settings.batches = 4 + model.settings.inactive = 0 + model.settings.source = openmc.Source(space=openmc.stats.Box( + (0, 0, 0), (5, 5, 0)) + ) + return model -def test_periodic(): - harness = PeriodicTest('statepoint.4.h5') +def test_periodic(box_model): + harness = PyAPITestHarness('statepoint.4.h5', box_model) harness.main() diff --git a/tests/regression_tests/periodic_6fold/inputs_true.dat b/tests/regression_tests/periodic_6fold/inputs_true.dat index 46c2a6ff55..35bbcc0475 100644 --- a/tests/regression_tests/periodic_6fold/inputs_true.dat +++ b/tests/regression_tests/periodic_6fold/inputs_true.dat @@ -1,11 +1,11 @@ - - - - - - + + + + + + diff --git a/tests/regression_tests/periodic_6fold/test.py b/tests/regression_tests/periodic_6fold/test.py index 1f8efdbf71..555ab24f9f 100644 --- a/tests/regression_tests/periodic_6fold/test.py +++ b/tests/regression_tests/periodic_6fold/test.py @@ -1,62 +1,59 @@ import openmc import numpy as np +import pytest from tests.testing_harness import PyAPITestHarness -class Periodic6FoldTest(PyAPITestHarness): - def _build_inputs(self): - # Define materials - water = openmc.Material(1) - water.add_nuclide('H1', 2.0) - water.add_nuclide('O16', 1.0) - water.add_s_alpha_beta('c_H_in_H2O') - water.set_density('g/cc', 1.0) +@pytest.fixture +def model(): + model = openmc.model.Model() - fuel = openmc.Material(2) - fuel.add_nuclide('U235', 1.0) - fuel.set_density('g/cc', 4.5) + # Define materials + water = openmc.Material() + water.add_nuclide('H1', 2.0) + water.add_nuclide('O16', 1.0) + water.add_s_alpha_beta('c_H_in_H2O') + water.set_density('g/cc', 1.0) - materials = openmc.Materials((water, fuel)) - materials.default_temperature = '294K' - materials.export_to_xml() + fuel = openmc.Material() + fuel.add_nuclide('U235', 1.0) + fuel.set_density('g/cc', 4.5) - # Define the geometry. Note that this geometry is somewhat non-sensical - # (it essentially defines a circle of half-cylinders), but it is - # designed so that periodic and reflective BCs will give different - # answers. - theta1 = (-1/6 + 1/2) * np.pi - theta2 = (1/6 - 1/2) * np.pi - plane1 = openmc.Plane(a=np.cos(theta1), b=np.sin(theta1), - boundary_type='periodic') - plane2 = openmc.Plane(a=np.cos(theta2), b=np.sin(theta2), - boundary_type='periodic') + # Define the geometry. Note that this geometry is somewhat non-sensical + # (it essentially defines a circle of half-cylinders), but it is + # designed so that periodic and reflective BCs will give different + # answers. + theta1 = (-1/6 + 1/2) * np.pi + theta2 = (1/6 - 1/2) * np.pi + plane1 = openmc.Plane(a=np.cos(theta1), b=np.sin(theta1), + boundary_type='periodic') + plane2 = openmc.Plane(a=np.cos(theta2), b=np.sin(theta2), + boundary_type='periodic') - x_max = openmc.XPlane(x0=5., boundary_type='reflective') + x_max = openmc.XPlane(x0=5., boundary_type='reflective') - z_cyl = openmc.ZCylinder(x0=3*np.cos(np.pi/6), y0=3*np.sin(np.pi/6), - r=2.0) + z_cyl = openmc.ZCylinder(x0=3*np.cos(np.pi/6), y0=3*np.sin(np.pi/6), + r=2.0) - outside_cyl = openmc.Cell(1, fill=water, region=( - +plane1 & +plane2 & -x_max & +z_cyl)) - inside_cyl = openmc.Cell(2, fill=fuel, region=( - +plane1 & +plane2 & -z_cyl)) - root_universe = openmc.Universe(0, cells=(outside_cyl, inside_cyl)) + outside_cyl = openmc.Cell(1, fill=water, region=( + +plane1 & +plane2 & -x_max & +z_cyl)) + inside_cyl = openmc.Cell(2, fill=fuel, region=( + +plane1 & +plane2 & -z_cyl)) + root_universe = openmc.Universe(0, cells=(outside_cyl, inside_cyl)) + model.geometry = openmc.Geometry(root_universe) - geometry = openmc.Geometry() - geometry.root_universe = root_universe - geometry.export_to_xml() - - # Define settings - settings = openmc.Settings() - settings.particles = 1000 - settings.batches = 4 - settings.inactive = 0 - settings.source = openmc.Source(space=openmc.stats.Box( - (0, 0, 0), (5, 5, 0))) - settings.export_to_xml() + # Define settings + model.settings = openmc.Settings() + model.settings.particles = 1000 + model.settings.batches = 4 + model.settings.inactive = 0 + model.settings.source = openmc.Source(space=openmc.stats.Box( + (0, 0, 0), (5, 5, 0)) + ) + return model -def test_periodic(): - harness = Periodic6FoldTest('statepoint.4.h5') +def test_periodic(model): + harness = PyAPITestHarness('statepoint.4.h5', model) harness.main() diff --git a/tests/regression_tests/periodic_hex/__init__.py b/tests/regression_tests/periodic_hex/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/periodic_hex/inputs_true.dat b/tests/regression_tests/periodic_hex/inputs_true.dat new file mode 100644 index 0000000000..00e539d4bf --- /dev/null +++ b/tests/regression_tests/periodic_hex/inputs_true.dat @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + eigenvalue + 1000 + 5 + 0 + diff --git a/tests/regression_tests/periodic_hex/results_true.dat b/tests/regression_tests/periodic_hex/results_true.dat new file mode 100644 index 0000000000..09c5a77f58 --- /dev/null +++ b/tests/regression_tests/periodic_hex/results_true.dat @@ -0,0 +1,2 @@ +k-combined: +2.276564E+00 7.905769E-04 diff --git a/tests/regression_tests/periodic_hex/test.py b/tests/regression_tests/periodic_hex/test.py new file mode 100644 index 0000000000..a21819b1ad --- /dev/null +++ b/tests/regression_tests/periodic_hex/test.py @@ -0,0 +1,28 @@ +import openmc +import pytest + +from tests.testing_harness import PyAPITestHarness + + +@pytest.fixture +def hex_model(): + model = openmc.model.Model() + + fuel = openmc.Material() + fuel.add_nuclide('U235', 1.0) + fuel.set_density('g/cc', 4.5) + + hex_region = openmc.model.hexagonal_prism(10.0, boundary_type='periodic') + cell = openmc.Cell(fill=fuel, region=hex_region) + model.geometry = openmc.Geometry([cell]) + + # Define settings + model.settings.particles = 1000 + model.settings.batches = 5 + model.settings.inactive = 0 + return model + + +def test_periodic_hex(hex_model): + harness = PyAPITestHarness('statepoint.5.h5', hex_model) + harness.main() diff --git a/tools/ci/gha-install.sh b/tools/ci/gha-install.sh index 3fb66ca764..2ef4ab9925 100755 --- a/tools/ci/gha-install.sh +++ b/tools/ci/gha-install.sh @@ -24,9 +24,15 @@ if [[ $LIBMESH = 'y' ]]; then ./tools/ci/gha-install-libmesh.sh fi -# Install mpi4py for MPI configurations +# For MPI configurations, make sure mpi4py and h5py are built against the +# correct version of MPI if [[ $MPI == 'y' ]]; then pip install --no-binary=mpi4py mpi4py + + export CC=mpicc + export HDF5_MPI=ON + export HDF5_DIR=/usr/lib/x86_64-linux-gnu/hdf5/openmpi + pip install --no-binary=h5py h5py fi # Build and install OpenMC executable