diff --git a/src/material.cpp b/src/material.cpp index ca29ce7404..30dfa5ed50 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -349,24 +349,26 @@ Material::~Material() void Material::finalize() { // Set fissionable if any nuclide is fissionable - for (const auto& i_nuc : nuclide_) { - if (data::nuclides[i_nuc]->fissionable_) { - fissionable_ = true; - break; + if (settings::run_CE) { + for (const auto& i_nuc : nuclide_) { + if (data::nuclides[i_nuc]->fissionable_) { + fissionable_ = true; + break; + } } + + // Generate material bremsstrahlung data for electrons and positrons + if (settings::photon_transport && + settings::electron_treatment == ElectronTreatment::TTB) { + this->init_bremsstrahlung(); + } + + // Assign thermal scattering tables + this->init_thermal(); } - // Generate material bremsstrahlung data for electrons and positrons - if (settings::photon_transport && - settings::electron_treatment == ElectronTreatment::TTB) { - this->init_bremsstrahlung(); - } - - // Assign thermal scattering tables - this->init_thermal(); - - // Normalize density - this->normalize_density(); +// Normalize density +this->normalize_density(); } void Material::normalize_density() diff --git a/src/mgxs_interface.cpp b/src/mgxs_interface.cpp index 1a6dab5c6a..77085d57c8 100644 --- a/src/mgxs_interface.cpp +++ b/src/mgxs_interface.cpp @@ -123,10 +123,14 @@ void MgxsInterface::create_macro_xs() // Therefore type(nuclides[mat->nuclide_[0]]) dictates type(macroxs). // At the same time, we will find the scattering type, as that will dictate // how we allocate the scatter object within macroxs. + for (int i = 0; i < model::materials.size(); ++i) { + // First we have to normalize the densities as it has not been called yet + // for MG mode + auto& mat {model::materials[i]}; + mat->finalize(); if (kTs[i].size() > 0) { // Convert atom_densities to a vector - auto& mat {model::materials[i]}; vector atom_densities( mat->atom_density_.begin(), mat->atom_density_.end()); diff --git a/src/volume_calc.cpp b/src/volume_calc.cpp index ae738d6bb1..3ae98fdc38 100644 --- a/src/volume_calc.cpp +++ b/src/volume_calc.cpp @@ -8,6 +8,7 @@ #include "openmc/hdf5_interface.h" #include "openmc/material.h" #include "openmc/message_passing.h" +#include "openmc/mgxs_interface.h" #include "openmc/nuclide.h" #include "openmc/output.h" #include "openmc/random_lcg.h" @@ -237,7 +238,8 @@ vector VolumeCalculation::execute() const // Create 2D array to store atoms/uncertainty for each nuclide. Later this // is compressed into vectors storing only those nuclides that are // non-zero - auto n_nuc = data::nuclides.size(); + auto n_nuc = settings::run_CE ? data::nuclides.size() + : data::mg.nuclides_.size(); xt::xtensor atoms({n_nuc, 2}, 0.0); #ifdef OPENMC_MPI @@ -442,7 +444,8 @@ void VolumeCalculation::to_hdf5( vector nucnames; for (int i_nuc : result.nuclides) { - nucnames.push_back(data::nuclides[i_nuc]->name_); + nucnames.push_back(settings::run_CE ? data::nuclides[i_nuc]->name_ + : data::mg.nuclides_[i_nuc].name); } // Create array of total # of atoms with uncertainty for each nuclide diff --git a/tests/regression_tests/volume_calc/inputs_true_mg.dat b/tests/regression_tests/volume_calc/inputs_true_mg.dat new file mode 100644 index 0000000000..21c2a9834a --- /dev/null +++ b/tests/regression_tests/volume_calc/inputs_true_mg.dat @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + mg_lib.h5 + + + + + + + + + + + + + + + volume + multi-group + + cell + 1 2 3 + 100000 + -1.0 -1.0 -6.0 + 1.0 1.0 6.0 + + + material + 1 2 + 100000 + -1.0 -1.0 -6.0 + 1.0 1.0 6.0 + + + universe + 0 + 100000 + -1.0 -1.0 -6.0 + 1.0 1.0 6.0 + + + cell + 1 2 3 + 100 + -1.0 -1.0 -6.0 + 1.0 1.0 6.0 + + + + material + 1 2 + 100 + -1.0 -1.0 -6.0 + 1.0 1.0 6.0 + + + + cell + 1 2 3 + 100 + -1.0 -1.0 -6.0 + 1.0 1.0 6.0 + + + diff --git a/tests/regression_tests/volume_calc/test.py b/tests/regression_tests/volume_calc/test.py index 1f1a2c7c95..e04eac7ff7 100644 --- a/tests/regression_tests/volume_calc/test.py +++ b/tests/regression_tests/volume_calc/test.py @@ -1,6 +1,8 @@ import os import glob -import sys + +import numpy as np +import pytest import openmc @@ -9,12 +11,15 @@ from tests.testing_harness import PyAPITestHarness class VolumeTest(PyAPITestHarness): - def __init__(self, *args, **kwargs): + def __init__(self, is_ce, *args, **kwargs): super().__init__(*args, **kwargs) self.exp_std_dev = 1e-01 self.exp_rel_err = 1e-01 self.exp_variance = 5e-02 + self.is_ce = is_ce + if not is_ce: + self.inputs_true = 'inputs_true_mg.dat' def _build_inputs(self): # Define materials @@ -22,7 +27,8 @@ class VolumeTest(PyAPITestHarness): water.add_nuclide('H1', 2.0) water.add_nuclide('O16', 1.0) water.add_nuclide('B10', 0.0001) - water.add_s_alpha_beta('c_H_in_H2O') + if self.is_ce: + water.add_s_alpha_beta('c_H_in_H2O') water.set_density('g/cc', 1.0) fuel = openmc.Material(2) @@ -31,6 +37,8 @@ class VolumeTest(PyAPITestHarness): fuel.set_density('g/cc', 4.5) materials = openmc.Materials((water, fuel)) + if not self.is_ce: + materials.cross_sections = 'mg_lib.h5' materials.export_to_xml() cyl = openmc.ZCylinder(surface_id=1, r=1.0, boundary_type='vacuum') @@ -68,9 +76,52 @@ class VolumeTest(PyAPITestHarness): # Define settings settings = openmc.Settings() settings.run_mode = 'volume' + if not self.is_ce: + settings.energy_mode = 'multi-group' settings.volume_calculations = vol_calcs settings.export_to_xml() + # Create the MGXS file if necessary + if not self.is_ce: + groups = openmc.mgxs.EnergyGroups(group_edges=[0., 20.e6]) + mg_xs_file = openmc.MGXSLibrary(groups) + + nu = [2.] + fiss = [1.] + capture = [1.] + absorption_fissile = np.add(fiss, capture) + absorption_other = capture + scatter = np.array([[[1.]]]) + total_fissile = np.add(absorption_fissile, + np.sum(scatter[:, :, 0], axis=1)) + total_other = np.add(absorption_other, + np.sum(scatter[:, :, 0], axis=1)) + chi = [1.] + + for iso in ['H1', 'O16', 'B10', 'Mo99', 'U235']: + mat = openmc.XSdata(iso, groups) + mat.order = 0 + mat.atomic_weight_ratio = \ + openmc.data.atomic_mass(iso) / openmc.data.NEUTRON_MASS + mat.set_scatter_matrix(scatter) + if iso == 'U235': + mat.set_nu_fission(np.multiply(nu, fiss)) + mat.set_absorption(absorption_fissile) + mat.set_total(total_fissile) + mat.set_chi(chi) + else: + mat.set_absorption(absorption_other) + mat.set_total(total_other) + mg_xs_file.add_xsdata(mat) + mg_xs_file.export_to_hdf5('mg_lib.h5') + + def _cleanup(self): + super()._cleanup() + output = ['mg_lib.h5'] + for f in output: + if os.path.exists(f): + os.remove(f) + def _get_results(self): outstr = '' for i, filename in enumerate(sorted(glob.glob('volume_*.h5'))): @@ -116,6 +167,8 @@ class VolumeTest(PyAPITestHarness): def _test_output_created(self): pass -def test_volume_calc(): - harness = VolumeTest('') + +@pytest.mark.parametrize('is_ce', [True, False]) +def test_volume_calc(is_ce): + harness = VolumeTest(is_ce, '') harness.main()