mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 21:55:41 -04:00
Remove weight correction method for resonance scattering, rename ARES -> RVS
This commit is contained in:
parent
5f1657c9b7
commit
faa70b168f
13 changed files with 51 additions and 72 deletions
|
|
@ -321,14 +321,14 @@ or sub-elements:
|
|||
|
||||
:method:
|
||||
|
||||
Which resonance elastic scattering method is to be applied: "ares"
|
||||
(accelerated resonance elastic scattering), "dbrc" (Doppler broadening
|
||||
rejection correction), or "wcm" (weight correction method). Descriptions of
|
||||
each of these methods are documented here_.
|
||||
Which resonance elastic scattering method is to be applied: "rvs" (relative
|
||||
velocity sampling), "dbrc" (Doppler broadening rejection correction), or
|
||||
"wcm" (weight correction method). Descriptions of each of these methods are
|
||||
documented here_.
|
||||
|
||||
.. _here: http://dx.doi.org/10.1016/j.anucene.2014.01.017
|
||||
.. _here: http://dx.doi.org/10.1016/j.anucene.2017.12.044
|
||||
|
||||
*Default*: "ares"
|
||||
*Default*: "rvs"
|
||||
|
||||
:energy_min:
|
||||
The energy in eV above which the resonance elastic scattering method should
|
||||
|
|
|
|||
|
|
@ -1203,7 +1203,7 @@
|
|||
"source": [
|
||||
"## Heavy-nuclide resonance scattering\n",
|
||||
"\n",
|
||||
"OpenMC has two methods for accounting for resonance upscattering in heavy nuclides, DBRC and ARES. These methods rely on 0 K elastic scattering data being present. If you have an existing ACE/HDF5 dataset and you need to add 0 K elastic scattering data to it, this can be done using the `IncidentNeutron.add_elastic_0K_from_endf()` method. Let's do this with our original `gd157` object that we instantiated from an ACE file."
|
||||
"OpenMC has two methods for accounting for resonance upscattering in heavy nuclides, DBRC and RVS. These methods rely on 0 K elastic scattering data being present. If you have an existing ACE/HDF5 dataset and you need to add 0 K elastic scattering data to it, this can be done using the `IncidentNeutron.add_elastic_0K_from_endf()` method. Let's do this with our original `gd157` object that we instantiated from an ACE file."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -269,10 +269,11 @@ constexpr int PARTIAL_FISSION_MAX {4};
|
|||
|
||||
// Resonance elastic scattering methods
|
||||
// TODO: Convert to enum
|
||||
constexpr int RES_SCAT_ARES {1};
|
||||
constexpr int RES_SCAT_DBRC {2};
|
||||
constexpr int RES_SCAT_WCM {3};
|
||||
constexpr int RES_SCAT_CXS {4};
|
||||
enum class ResScatMethod {
|
||||
rvs, // Relative velocity sampling
|
||||
dbrc, // Doppler broadening rejection correction
|
||||
cxs // Constant cross section
|
||||
};
|
||||
|
||||
// Electron treatments
|
||||
// TODO: Convert to enum
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ void sab_scatter(int i_nuclide, int i_sab, double* E,
|
|||
//! samples the target velocity. The constant cross section free gas model is
|
||||
//! the default method. Methods for correctly accounting for the energy
|
||||
//! dependence of cross sections in treating resonance elastic scattering such
|
||||
//! as the DBRC, WCM, and a new, accelerated scheme are also implemented here.
|
||||
//! as the DBRC and a new, accelerated scheme are also implemented here.
|
||||
Direction sample_target_velocity(const Nuclide* nuc, double E, Direction u,
|
||||
Direction v_neut, double xs_eff, double kT, double* wgt);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include "pugixml.hpp"
|
||||
|
||||
#include "openmc/constants.h"
|
||||
|
||||
namespace openmc {
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -33,7 +35,7 @@ extern "C" bool output_tallies; //!< write tallies.out?
|
|||
extern "C" bool particle_restart_run; //!< particle restart run?
|
||||
extern "C" bool photon_transport; //!< photon transport turned on?
|
||||
extern "C" bool reduce_tallies; //!< reduce tallies at end of batch?
|
||||
extern "C" bool res_scat_on; //!< use resonance upscattering method?
|
||||
extern bool res_scat_on; //!< use resonance upscattering method?
|
||||
extern "C" bool restart_run; //!< restart run?
|
||||
extern "C" bool run_CE; //!< run with continuous-energy data?
|
||||
extern "C" bool source_latest; //!< write latest source at each batch?
|
||||
|
|
@ -43,8 +45,8 @@ extern "C" bool survival_biasing; //!< use survival biasing?
|
|||
extern "C" bool temperature_multipole; //!< use multipole data?
|
||||
extern "C" bool trigger_on; //!< tally triggers enabled?
|
||||
extern "C" bool trigger_predict; //!< predict batches for triggers?
|
||||
extern "C" bool ufs_on; //!< uniform fission site method on?
|
||||
extern "C" bool urr_ptables_on; //!< use unresolved resonance prob. tables?
|
||||
extern bool ufs_on; //!< uniform fission site method on?
|
||||
extern bool urr_ptables_on; //!< use unresolved resonance prob. tables?
|
||||
extern "C" bool write_all_tracks; //!< write track files for every particle?
|
||||
extern "C" bool write_initial_source; //!< write out initial source file?
|
||||
extern "C" bool dagmc; //!< indicator of DAGMC geometry
|
||||
|
|
@ -58,9 +60,8 @@ extern std::string path_source;
|
|||
extern std::string path_sourcepoint; //!< path to a source file
|
||||
extern std::string path_statepoint; //!< path to a statepoint file
|
||||
|
||||
extern "C" int32_t index_entropy_mesh; //!< Index of entropy mesh in global mesh array
|
||||
extern "C" int32_t index_ufs_mesh; //!< Index of UFS mesh in global mesh array
|
||||
extern "C" int32_t index_cmfd_mesh; //!< Index of CMFD mesh in global mesh array
|
||||
extern int32_t index_entropy_mesh; //!< Index of entropy mesh in global mesh array
|
||||
extern int32_t index_ufs_mesh; //!< Index of UFS mesh in global mesh array
|
||||
|
||||
extern "C" int32_t n_batches; //!< number of (inactive+active) batches
|
||||
extern "C" int32_t n_inactive; //!< number of inactive batches
|
||||
|
|
@ -73,9 +74,9 @@ extern "C" int legendre_to_tabular_points; //!< number of points to convert Lege
|
|||
extern "C" int max_order; //!< Maximum Legendre order for multigroup data
|
||||
extern "C" int n_log_bins; //!< number of bins for logarithmic energy grid
|
||||
extern "C" int n_max_batches; //!< Maximum number of batches
|
||||
extern "C" int res_scat_method; //!< resonance upscattering method
|
||||
extern "C" double res_scat_energy_min; //!< Min energy in [eV] for res. upscattering
|
||||
extern "C" double res_scat_energy_max; //!< Max energy in [eV] for res. upscattering
|
||||
extern ResScatMethod res_scat_method; //!< resonance upscattering method
|
||||
extern double res_scat_energy_min; //!< Min energy in [eV] for res. upscattering
|
||||
extern double res_scat_energy_max; //!< Max energy in [eV] for res. upscattering
|
||||
extern std::vector<std::string> res_scat_nuclides; //!< Nuclides using res. upscattering treatment
|
||||
extern "C" int run_mode; //!< Run mode (eigenvalue, fixed src, etc.)
|
||||
extern std::unordered_set<int> sourcepoint_batch; //!< Batches when source should be written
|
||||
|
|
@ -90,8 +91,8 @@ extern "C" int64_t trace_particle; //!< Particle ID to enable trace on
|
|||
extern std::vector<std::array<int, 3>> track_identifiers; //!< Particle numbers for writing tracks
|
||||
extern "C" int trigger_batch_interval; //!< Batch interval for triggers
|
||||
extern "C" int verbosity; //!< How verbose to make output
|
||||
extern "C" double weight_cutoff; //!< Weight cutoff for Russian roulette
|
||||
extern "C" double weight_survive; //!< Survival weight after Russian roulette
|
||||
extern double weight_cutoff; //!< Weight cutoff for Russian roulette
|
||||
extern double weight_survive; //!< Survival weight after Russian roulette
|
||||
} // namespace settings
|
||||
|
||||
//! Read settings from XML file
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import openmc.checkvalue as cv
|
|||
from openmc import VolumeCalculation, Source, Mesh
|
||||
|
||||
_RUN_MODES = ['eigenvalue', 'fixed source', 'plot', 'volume', 'particle restart']
|
||||
_RES_SCAT_METHODS = ['dbrc', 'wcm', 'ares']
|
||||
_RES_SCAT_METHODS = ['dbrc', 'rvs']
|
||||
|
||||
|
||||
class Settings(object):
|
||||
|
|
@ -82,14 +82,14 @@ class Settings(object):
|
|||
Settings for resonance elastic scattering. Accepted keys are 'enable'
|
||||
(bool), 'method' (str), 'energy_min' (float), 'energy_max' (float), and
|
||||
'nuclides' (list). The 'method' can be set to 'dbrc' (Doppler broadening
|
||||
rejection correction), 'wcm' (weight correction method), and 'ares'
|
||||
(accelerated resonance elastic scattering). If not specified, 'ares' is
|
||||
the default method. The 'energy_min' and 'energy_max' values indicate
|
||||
the minimum and maximum energies above and below which the resonance
|
||||
elastic scattering method is to be applied. The 'nuclides' list
|
||||
indicates what nuclides the method should be applied to. In its absence,
|
||||
the method will be applied to all nuclides with 0 K elastic scattering
|
||||
data present.
|
||||
rejection correction), 'wcm' (weight correction method), and 'rvs'
|
||||
(relative velocity sampling). If not specified, 'rvs' is the default
|
||||
method. The 'energy_min' and 'energy_max' values indicate the minimum
|
||||
and maximum energies above and below which the resonance elastic
|
||||
scattering method is to be applied. The 'nuclides' list indicates what
|
||||
nuclides the method should be applied to. In its absence, the method
|
||||
will be applied to all nuclides with 0 K elastic scattering data
|
||||
present.
|
||||
run_mode : {'eigenvalue', 'fixed source', 'plot', 'volume', 'particle restart'}
|
||||
The type of calculation to perform (default is 'eigenvalue')
|
||||
seed : int
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ int openmc_finalize()
|
|||
settings::photon_transport = false;
|
||||
settings::reduce_tallies = true;
|
||||
settings::res_scat_on = false;
|
||||
settings::res_scat_method = RES_SCAT_ARES;
|
||||
settings::res_scat_method = ResScatMethod::rvs;
|
||||
settings::res_scat_energy_min = 0.01;
|
||||
settings::res_scat_energy_max = 1000.0;
|
||||
settings::restart_run = false;
|
||||
|
|
|
|||
|
|
@ -799,7 +799,7 @@ Direction sample_target_velocity(const Nuclide* nuc, double E, Direction u,
|
|||
Direction v_neut, double xs_eff, double kT, double* wgt)
|
||||
{
|
||||
// check if nuclide is a resonant scatterer
|
||||
int sampling_method;
|
||||
ResScatMethod sampling_method;
|
||||
if (nuc->resonant_) {
|
||||
|
||||
// sampling method to use
|
||||
|
|
@ -811,7 +811,7 @@ Direction sample_target_velocity(const Nuclide* nuc, double E, Direction u,
|
|||
|
||||
// lower resonance scattering energy bound (should be no resonances below)
|
||||
} else if (E < settings::res_scat_energy_min) {
|
||||
sampling_method = RES_SCAT_CXS;
|
||||
sampling_method = ResScatMethod::cxs;
|
||||
}
|
||||
|
||||
// otherwise, use free gas model
|
||||
|
|
@ -819,31 +819,19 @@ Direction sample_target_velocity(const Nuclide* nuc, double E, Direction u,
|
|||
if (E >= FREE_GAS_THRESHOLD * kT && nuc->awr_ > 1.0) {
|
||||
return {};
|
||||
} else {
|
||||
sampling_method = RES_SCAT_CXS;
|
||||
sampling_method = ResScatMethod::cxs;
|
||||
}
|
||||
}
|
||||
|
||||
// use appropriate target velocity sampling method
|
||||
switch (sampling_method) {
|
||||
case RES_SCAT_CXS:
|
||||
case ResScatMethod::cxs:
|
||||
|
||||
// sample target velocity with the constant cross section (cxs) approx.
|
||||
return sample_cxs_target_velocity(nuc->awr_, E, u, kT);
|
||||
|
||||
case RES_SCAT_WCM: {
|
||||
// sample target velocity with the constant cross section (cxs) approx.
|
||||
Direction v_target = sample_cxs_target_velocity(nuc->awr_, E, u, kT);
|
||||
|
||||
// adjust weight as prescribed by the weight correction method (wcm)
|
||||
Direction v_rel = v_neut - v_target;
|
||||
double E_rel = v_rel.dot(v_rel);
|
||||
double xs_0K = nuc->elastic_xs_0K(E_rel);
|
||||
*wgt *= xs_0K / xs_eff;
|
||||
return v_target;
|
||||
}
|
||||
|
||||
case RES_SCAT_DBRC:
|
||||
case RES_SCAT_ARES: {
|
||||
case ResScatMethod::dbrc:
|
||||
case ResScatMethod::rvs: {
|
||||
double E_red = std::sqrt(nuc->awr_ * E / kT);
|
||||
double E_low = std::pow(std::max(0.0, E_red - 4.0), 2) * kT / nuc->awr_;
|
||||
double E_up = (E_red + 4.0)*(E_red + 4.0) * kT / nuc->awr_;
|
||||
|
|
@ -877,7 +865,7 @@ Direction sample_target_velocity(const Nuclide* nuc, double E, Direction u,
|
|||
return sample_cxs_target_velocity(nuc->awr_, E, u, kT);
|
||||
}
|
||||
|
||||
if (sampling_method == RES_SCAT_DBRC) {
|
||||
if (sampling_method == ResScatMethod::dbrc) {
|
||||
// interpolate xs since we're not exactly at the energy indices
|
||||
double xs_low = nuc->elastic_0K_[i_E_low];
|
||||
double m = (nuc->elastic_0K_[i_E_low + 1] - xs_low)
|
||||
|
|
@ -910,7 +898,7 @@ Direction sample_target_velocity(const Nuclide* nuc, double E, Direction u,
|
|||
if (prn() < R) return v_target;
|
||||
}
|
||||
|
||||
} else if (sampling_method == RES_SCAT_ARES) {
|
||||
} else if (sampling_method == ResScatMethod::rvs) {
|
||||
// interpolate xs CDF since we're not exactly at the energy indices
|
||||
// cdf value at lower bound attainable energy
|
||||
double m = (nuc->xs_cdf_[i_E_low] - nuc->xs_cdf_[i_E_low - 1])
|
||||
|
|
@ -952,7 +940,7 @@ Direction sample_target_velocity(const Nuclide* nuc, double E, Direction u,
|
|||
}
|
||||
}
|
||||
}
|
||||
} // case RES_SCAT_ARES, RES_SCAT_DBRC
|
||||
} // case RVS, DBRC
|
||||
} // switch (sampling_method)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -495,14 +495,6 @@ Plot::set_meshlines(pugi::xml_node plot_node)
|
|||
} else {
|
||||
index_meshlines_mesh_ = settings::index_ufs_mesh;
|
||||
}
|
||||
} else if ("cmfd" == meshtype) {
|
||||
if (!settings::cmfd_run) {
|
||||
std::stringstream err_msg;
|
||||
err_msg << "Need CMFD run to plot CMFD mesh for meshlines on plot " << id_;
|
||||
fatal_error(err_msg);
|
||||
} else {
|
||||
index_meshlines_mesh_ = settings::index_cmfd_mesh;
|
||||
}
|
||||
} else if ("entropy" == meshtype) {
|
||||
if (settings::index_entropy_mesh < 0) {
|
||||
std::stringstream err_msg;
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@ std::string path_statepoint;
|
|||
|
||||
int32_t index_entropy_mesh {-1};
|
||||
int32_t index_ufs_mesh {-1};
|
||||
int32_t index_cmfd_mesh {-1};
|
||||
|
||||
int32_t n_batches;
|
||||
int32_t n_inactive {0};
|
||||
|
|
@ -87,7 +86,7 @@ int legendre_to_tabular_points {C_NONE};
|
|||
int max_order {0};
|
||||
int n_log_bins {8000};
|
||||
int n_max_batches;
|
||||
int res_scat_method {RES_SCAT_ARES};
|
||||
ResScatMethod res_scat_method {ResScatMethod::rvs};
|
||||
double res_scat_energy_min {0.01};
|
||||
double res_scat_energy_max {1000.0};
|
||||
std::vector<std::string> res_scat_nuclides;
|
||||
|
|
@ -703,12 +702,10 @@ void read_settings_xml()
|
|||
// Determine what method is used
|
||||
if (check_for_node(node_res_scat, "method")) {
|
||||
auto temp = get_node_value(node_res_scat, "method", true, true);
|
||||
if (temp == "ares") {
|
||||
res_scat_method = RES_SCAT_ARES;
|
||||
if (temp == "rvs") {
|
||||
res_scat_method = ResScatMethod::rvs;
|
||||
} else if (temp == "dbrc") {
|
||||
res_scat_method = RES_SCAT_DBRC;
|
||||
} else if (temp == "wcm") {
|
||||
res_scat_method = RES_SCAT_WCM;
|
||||
res_scat_method = ResScatMethod::dbrc;
|
||||
} else {
|
||||
fatal_error("Unrecognized resonance elastic scattering method: "
|
||||
+ temp + ".");
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
</source>
|
||||
<resonance_scattering>
|
||||
<enable>true</enable>
|
||||
<method>ares</method>
|
||||
<method>rvs</method>
|
||||
<energy_min>1.0</energy_min>
|
||||
<energy_max>210.0</energy_max>
|
||||
<nuclides>U238 U235 Pu239</nuclides>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class ResonanceScatteringTestHarness(PyAPITestHarness):
|
|||
'enable': True,
|
||||
'energy_min': 1.0,
|
||||
'energy_max': 210.0,
|
||||
'method': 'ares',
|
||||
'method': 'rvs',
|
||||
'nuclides': ['U238', 'U235', 'Pu239']
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ def test_export_to_xml(run_in_tmpdir):
|
|||
s.trace = (10, 1, 20)
|
||||
s.track = [1, 1, 1, 2, 1, 1]
|
||||
s.ufs_mesh = mesh
|
||||
s.resonance_scattering = {'enable': True, 'method': 'ares',
|
||||
s.resonance_scattering = {'enable': True, 'method': 'rvs',
|
||||
'energy_min': 1.0, 'energy_max': 1000.0,
|
||||
'nuclides': ['U235', 'U238', 'Pu239']}
|
||||
s.volume_calculations = openmc.VolumeCalculation(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue