Merge pull request #1403 from paulromano/delayed-group-fix

Fix off-by-one errors related to delayed group tallies in MG mode
This commit is contained in:
Adam Nelson 2019-11-11 09:53:40 -06:00 committed by GitHub
commit 0f0b65c66e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 1372 additions and 31 deletions

View file

@ -69,7 +69,7 @@ kwargs = {
'pandas', 'lxml', 'uncertainties'
],
'extras_require': {
'test': ['pytest', 'pytest-cov'],
'test': ['pytest', 'pytest-cov', 'colorama'],
'vtk': ['vtk'],
},
}

View file

@ -541,8 +541,7 @@ Mgxs::sample_fission_energy(int gin, int& dg, int& gout)
double nu_fission = xs_t->nu_fission(cache[tid].a, gin);
// Find the probability of having a prompt neutron
double prob_prompt =
xs_t->prompt_nu_fission(cache[tid].a, gin);
double prob_prompt = xs_t->prompt_nu_fission(cache[tid].a, gin);
// sample random numbers
double xi_pd = prn() * nu_fission;
@ -557,8 +556,7 @@ Mgxs::sample_fission_energy(int gin, int& dg, int& gout)
// sample the outgoing energy group
gout = 0;
double prob_gout =
xs_t->chi_prompt(cache[tid].a, gin, gout);
double prob_gout = xs_t->chi_prompt(cache[tid].a, gin, gout);
while (prob_gout < xi_gout) {
gout++;
prob_gout += xs_t->chi_prompt(cache[tid].a, gin, gout);
@ -568,11 +566,9 @@ Mgxs::sample_fission_energy(int gin, int& dg, int& gout)
// the neutron is delayed
// get the delayed group
dg = 0;
while (xi_pd >= prob_prompt) {
dg++;
prob_prompt +=
xs_t->delayed_nu_fission(cache[tid].a, dg, gin);
for (dg = 0; dg < num_delayed_groups; ++dg) {
prob_prompt += xs_t->delayed_nu_fission(cache[tid].a, dg, gin);
if (xi_pd < prob_prompt) break;
}
// adjust dg in case of round-off error
@ -580,12 +576,10 @@ Mgxs::sample_fission_energy(int gin, int& dg, int& gout)
// sample the outgoing energy group
gout = 0;
double prob_gout =
xs_t->chi_delayed(cache[tid].a, dg, gin, gout);
double prob_gout = xs_t->chi_delayed(cache[tid].a, dg, gin, gout);
while (prob_gout < xi_gout) {
gout++;
prob_gout +=
xs_t->chi_delayed(cache[tid].a, dg, gin, gout);
prob_gout += xs_t->chi_delayed(cache[tid].a, dg, gin, gout);
}
}
}

View file

@ -1720,7 +1720,7 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
model::tally_filters[i_dg_filt].get())};
// Tally each delayed group bin individually
for (auto d_bin = 0; d_bin < filt.n_bins(); ++d_bin) {
auto d = filt.groups()[d_bin];
auto d = filt.groups()[d_bin] - 1;
score = p->wgt_absorb_ * flux;
if (i_nuclide >= 0) {
score *=
@ -1802,7 +1802,7 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
model::tally_filters[i_dg_filt].get())};
// Tally each delayed group bin individually
for (auto d_bin = 0; d_bin < filt.n_bins(); ++d_bin) {
auto d = filt.groups()[d_bin];
auto d = filt.groups()[d_bin] - 1;
if (i_nuclide >= 0) {
score = flux * atom_density
* get_nuclide_xs(i_nuclide, MG_GET_XS_DELAYED_NU_FISSION,
@ -1842,7 +1842,7 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
model::tally_filters[i_dg_filt].get())};
// Tally each delayed group bin individually
for (auto d_bin = 0; d_bin < filt.n_bins(); ++d_bin) {
auto d = filt.groups()[d_bin];
auto d = filt.groups()[d_bin] - 1;
score = p->wgt_absorb_ * flux;
if (i_nuclide >= 0) {
score *=
@ -1902,8 +1902,8 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
for (auto i = 0; i < p->n_bank_; ++i) {
auto i_bank = simulation::fission_bank.size() - p->n_bank_ + i;
const auto& bank = simulation::fission_bank[i_bank];
auto g = bank.delayed_group;
if (g != 0) {
auto g = bank.delayed_group - 1;
if (g != -1) {
if (i_nuclide >= 0) {
score += simulation::keff * atom_density * bank.wgt * flux
* get_nuclide_xs(i_nuclide, MG_GET_XS_DECAY_RATE, p_g,
@ -1923,7 +1923,7 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
// Find the corresponding filter bin and then score
for (auto d_bin = 0; d_bin < filt.n_bins(); ++d_bin) {
auto d = filt.groups()[d_bin];
if (d == g)
if (d == g + 1)
score_fission_delayed_dg(i_tally, d_bin, score,
score_index);
}
@ -1941,7 +1941,7 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
model::tally_filters[i_dg_filt].get())};
// Tally each delayed group bin individually
for (auto d_bin = 0; d_bin < filt.n_bins(); ++d_bin) {
auto d = filt.groups()[d_bin];
auto d = filt.groups()[d_bin] - 1;
if (i_nuclide >= 0) {
score += atom_density * flux
* get_nuclide_xs(i_nuclide, MG_GET_XS_DECAY_RATE,

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@ import numpy as np
import openmc
from openmc.examples import slab_mg
from tests.testing_harness import HashedPyAPITestHarness
from tests.testing_harness import PyAPITestHarness
def create_library():
@ -49,7 +49,7 @@ def create_library():
mg_cross_sections_file.export_to_hdf5('2g.h5')
class MGXSTestHarness(HashedPyAPITestHarness):
class MGXSTestHarness(PyAPITestHarness):
def _cleanup(self):
super()._cleanup()
f = '2g.h5'
@ -144,5 +144,5 @@ def test_mg_tallies():
t.nuclides = nuclides
model.tallies.append(t)
harness = HashedPyAPITestHarness('statepoint.10.h5', model)
harness = MGXSTestHarness('statepoint.10.h5', model)
harness.main()

View file

@ -10,9 +10,25 @@ import sys
import numpy as np
import openmc
from openmc.examples import pwr_core
from colorama import Fore, init
from tests.regression_tests import config
init()
def colorize(diff):
"""Produce colored diff for test results"""
for line in diff:
if line.startswith('+'):
yield Fore.RED + line + Fore.RESET
elif line.startswith('-'):
yield Fore.GREEN + line + Fore.RESET
elif line.startswith('^'):
yield Fore.BLUE + line + Fore.RESET
else:
yield line
class TestHarness(object):
"""General class for running OpenMC regression tests."""
@ -108,11 +124,17 @@ class TestHarness(object):
shutil.copyfile('results_test.dat', 'results_true.dat')
def _compare_results(self):
"""Make sure the current results agree with the _true standard."""
"""Make sure the current results agree with the reference."""
compare = filecmp.cmp('results_test.dat', 'results_true.dat')
if not compare:
expected = open('results_true.dat').readlines()
actual = open('results_test.dat').readlines()
diff = unified_diff(expected, actual, 'results_true.dat',
'results_test.dat')
print('Result differences:')
print(''.join(colorize(diff)))
os.rename('results_test.dat', 'results_error.dat')
assert compare, 'Results do not agree.'
assert compare, 'Results do not agree'
def _cleanup(self):
"""Delete statepoints, tally, and test files."""
@ -325,11 +347,13 @@ class PyAPITestHarness(TestHarness):
"""Make sure the current inputs agree with the _true standard."""
compare = filecmp.cmp('inputs_test.dat', 'inputs_true.dat')
if not compare:
expected = open('inputs_true.dat', 'r').readlines()
actual = open('inputs_error.dat', 'r').readlines()
diff = unified_diff(expected, actual, 'inputs_true.dat',
'inputs_error.dat')
print('Input differences:')
print(''.join(colorize(diff)))
os.rename('inputs_test.dat', 'inputs_error.dat')
for line in unified_diff(open('inputs_true.dat', 'r').readlines(),
open('inputs_error.dat', 'r').readlines(),
'inputs_true.dat', 'inputs_error.dat'):
print(line, end='')
assert compare, 'Input files are broken.'
def _cleanup(self):