This commit is contained in:
GuySten 2026-07-17 09:09:12 -04:00 committed by GitHub
commit b29ce5aa91
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 155 additions and 277 deletions

View file

@ -32,9 +32,7 @@ the ``ifp_n_generation`` settings in the Python API::
settings.ifp_n_generation = 5
``ifp_n_generation`` should be greater than 0, but should also be lower than
or equal to the number of inactive batches declared for the calculation.
The respect of these constraints is verified by OpenMC before any calculation.
``ifp_n_generation`` should be greater than 0.
OpenMC will automatically detect the type of data that needs to be stored based
on the tally scores selected by the user. This guarantees that only information

View file

@ -5,21 +5,12 @@
#include "openmc/particle.h"
#include "openmc/particle_data.h"
#include "openmc/settings.h"
#include "openmc/simulation.h"
#include <algorithm> // for copy
namespace openmc {
//! Check the value of the IFP parameter for beta effective or both.
//!
//! \return true if "BetaEffective" or "Both", false otherwise.
bool is_beta_effective_or_both();
//! Check the value of the IFP parameter for generation time or both.
//!
//! \return true if "GenerationTime" or "Both", false otherwise.
bool is_generation_time_or_both();
//! Resize IFP vectors
//!
//! \param[in,out] delayed_groups List of delayed group numbers
@ -28,10 +19,10 @@ bool is_generation_time_or_both();
template<typename T, typename U>
void resize_ifp_data(vector<T>& delayed_groups, vector<U>& lifetimes, int64_t n)
{
if (is_beta_effective_or_both()) {
if (simulation::ifp_delayed_on) {
delayed_groups.resize(n);
}
if (is_generation_time_or_both()) {
if (simulation::ifp_lifetime_on) {
lifetimes.resize(n);
}
}
@ -85,10 +76,12 @@ void resize_simulation_ifp_banks();
//! Retrieve IFP data from the IFP fission banks.
//!
//! \param[in] i_bank Index in the fission banks
//! \param[in,out] delayed_groups Delayed group numbers
//! \param[in,out] lifetimes Lifetimes lists
void copy_ifp_data_from_fission_banks(
int i_bank, vector<int>& delayed_groups, vector<double>& lifetimes);
//! \param[in] j_bank Index in the ifp banks
//! \param[in,out] delayed_groups_bank Delayed group numbers
//! \param[in,out] lifetimes_bank Lifetimes lists
void copy_ifp_data_from_fission_banks(int i_bank, int j_bank,
vector<vector<int>>& delayed_groups_bank,
vector<vector<double>>& lifetimes_bank);
#ifdef OPENMC_MPI

View file

@ -24,14 +24,6 @@ enum class SSWCellType {
To,
};
// Type of IFP parameters
enum class IFPParameter {
None,
Both,
BetaEffective,
GenerationTime,
};
struct CollisionTrackConfig {
bool mcpl_write {false}; //!< Write collision tracks using MCPL?
std::unordered_set<int>
@ -69,8 +61,7 @@ extern bool
delayed_photon_scaling; //!< Scale fission photon yield to include delayed
extern "C" bool entropy_on; //!< calculate Shannon entropy?
extern "C" bool
event_based; //!< use event-based mode (instead of history-based)
extern bool ifp_on; //!< Use IFP for kinetics parameters?
event_based; //!< use event-based mode (instead of history-based)
extern bool legendre_to_tabular; //!< convert Legendre distributions to tabular?
extern bool material_cell_offsets; //!< create material cells offsets?
extern "C" bool output_summary; //!< write summary.h5?
@ -146,8 +137,6 @@ extern array<double, 4>
time_cutoff; //!< Time cutoff in [s] for each particle type
extern int
ifp_n_generation; //!< Number of generation for Iterated Fission Probability
extern IFPParameter
ifp_parameter; //!< Parameter to calculate for Iterated Fission Probability
extern int
legendre_to_tabular_points; //!< number of points to convert Legendres
extern int max_order; //!< Maximum Legendre order for multigroup data

View file

@ -25,6 +25,8 @@ namespace simulation {
extern int ct_current_file; //!< current collision track file index
extern "C" int current_batch; //!< current batch
extern "C" int current_gen; //!< current fission generation
extern bool ifp_delayed_on; //!< Store delayed group IFP data?
extern bool ifp_lifetime_on; //!< Store lifetime IFP data?
extern "C" bool initialized; //!< has simulation been initialized?
extern "C" double keff; //!< average k over batches
extern "C" double keff_std; //!< standard deviation of average k

View file

@ -147,6 +147,9 @@ public:
//! Whether this tally is currently being updated
bool active_ {false};
//! Offset batch to activate this tally after.
int offset_ {0};
//! Number of realizations
int n_realizations_ {0};

View file

@ -113,7 +113,7 @@ void sort_bank(SharedArray<SourceSite>& bank, bool is_fission_bank)
sorted_bank = bank.data() + bank.size();
}
if (settings::ifp_on && is_fission_bank) {
if (is_fission_bank) {
allocate_temporary_vector_ifp(
sorted_ifp_delayed_group_bank, sorted_ifp_lifetime_bank);
}
@ -135,15 +135,15 @@ void sort_bank(SharedArray<SourceSite>& bank, bool is_fission_bank)
"bank size during sorting.");
}
sorted_bank[idx] = site;
if (settings::ifp_on && is_fission_bank) {
if (is_fission_bank) {
copy_ifp_data_from_fission_banks(
i, sorted_ifp_delayed_group_bank[idx], sorted_ifp_lifetime_bank[idx]);
i, idx, sorted_ifp_delayed_group_bank, sorted_ifp_lifetime_bank);
}
}
// Copy sorted bank into the fission bank
std::copy(sorted_bank, sorted_bank + bank.size(), bank.data());
if (settings::ifp_on && is_fission_bank) {
if (is_fission_bank) {
copy_ifp_data_to_fission_banks(
sorted_ifp_delayed_group_bank.data(), sorted_ifp_lifetime_bank.data());
}

View file

@ -135,10 +135,8 @@ void synchronize_bank()
// Temporary banks for IFP
vector<vector<int>> temp_delayed_groups;
vector<vector<double>> temp_lifetimes;
if (settings::ifp_on) {
resize_ifp_data(
temp_delayed_groups, temp_lifetimes, 3 * simulation::work_per_rank);
}
resize_ifp_data(
temp_delayed_groups, temp_lifetimes, 3 * simulation::work_per_rank);
// ==========================================================================
// SAMPLE N_PARTICLES FROM FISSION BANK AND PLACE IN TEMP_SITES
@ -164,10 +162,8 @@ void synchronize_bank()
for (int64_t i = tooth_start; i < tooth_end; i++) {
int64_t idx = std::floor(tooth) - start;
temp_sites[index_temp] = simulation::fission_bank[idx];
if (settings::ifp_on) {
copy_ifp_data_from_fission_banks(
idx, temp_delayed_groups[index_temp], temp_lifetimes[index_temp]);
}
copy_ifp_data_from_fission_banks(
idx, index_temp, temp_delayed_groups, temp_lifetimes);
++index_temp;
// Next tooth
@ -206,10 +202,8 @@ void synchronize_bank()
// IFP number of generation
int ifp_n_generation;
if (settings::ifp_on) {
broadcast_ifp_n_generation(
ifp_n_generation, temp_delayed_groups, temp_lifetimes);
}
broadcast_ifp_n_generation(
ifp_n_generation, temp_delayed_groups, temp_lifetimes);
int64_t index_local = 0;
vector<MPI_Request> requests;
@ -225,7 +219,7 @@ void synchronize_bank()
simulation::work_index.begin(), simulation::work_index.end(), start);
// Resize IFP send buffers
if (settings::ifp_on && mpi::n_procs > 1) {
if (mpi::n_procs > 1) {
resize_ifp_data(send_delayed_groups, send_lifetimes,
ifp_n_generation * 3 * simulation::work_per_rank);
}
@ -243,15 +237,12 @@ void synchronize_bank()
mpi::source_site, neighbor, mpi::rank, mpi::intracomm,
&requests.back());
if (settings::ifp_on) {
// Send IFP data
if (is_beta_effective_or_both())
send_ifp_info(index_local, n, ifp_n_generation, neighbor, requests,
temp_delayed_groups, send_delayed_groups);
if (is_generation_time_or_both())
send_ifp_info(index_local, n, ifp_n_generation, neighbor, requests,
temp_lifetimes, send_lifetimes);
}
if (simulation::ifp_delayed_on)
send_ifp_info(index_local, n, ifp_n_generation, neighbor, requests,
temp_delayed_groups, send_delayed_groups);
if (simulation::ifp_lifetime_on)
send_ifp_info(index_local, n, ifp_n_generation, neighbor, requests,
temp_lifetimes, send_lifetimes);
}
// Increment all indices
@ -290,7 +281,7 @@ void synchronize_bank()
}
// Resize IFP receive buffers
if (settings::ifp_on && mpi::n_procs > 1) {
if (mpi::n_procs > 1) {
resize_ifp_data(recv_delayed_groups, recv_lifetimes,
ifp_n_generation * simulation::work_per_rank);
}
@ -314,15 +305,12 @@ void synchronize_bank()
MPI_Irecv(&simulation::source_bank[index_local], static_cast<int>(n),
mpi::source_site, neighbor, neighbor, mpi::intracomm, &requests.back());
if (settings::ifp_on) {
// Receive IFP data
if (is_beta_effective_or_both())
receive_ifp_data(index_local, n, ifp_n_generation, neighbor, requests,
recv_delayed_groups, deserialization_info);
if (is_generation_time_or_both())
receive_ifp_data(index_local, n, ifp_n_generation, neighbor, requests,
recv_lifetimes, deserialization_info);
}
if (simulation::ifp_delayed_on)
receive_ifp_data(index_local, n, ifp_n_generation, neighbor, requests,
recv_delayed_groups, deserialization_info);
if (simulation::ifp_lifetime_on)
receive_ifp_data(index_local, n, ifp_n_generation, neighbor, requests,
recv_lifetimes, deserialization_info);
} else {
// If the source sites are on this processor, we can simply copy them
@ -332,10 +320,8 @@ void synchronize_bank()
std::copy(&temp_sites[index_temp], &temp_sites[index_temp + n],
&simulation::source_bank[index_local]);
if (settings::ifp_on) {
copy_partial_ifp_data_to_source_banks(
index_temp, n, index_local, temp_delayed_groups, temp_lifetimes);
}
copy_partial_ifp_data_to_source_banks(
index_temp, n, index_local, temp_delayed_groups, temp_lifetimes);
}
// Increment all indices
@ -351,21 +337,17 @@ void synchronize_bank()
int n_request = requests.size();
MPI_Waitall(n_request, requests.data(), MPI_STATUSES_IGNORE);
if (settings::ifp_on) {
if (is_beta_effective_or_both())
deserialize_ifp_info(ifp_n_generation, recv_delayed_groups,
simulation::ifp_source_delayed_group_bank, deserialization_info);
if (is_generation_time_or_both())
deserialize_ifp_info(ifp_n_generation, recv_lifetimes,
simulation::ifp_source_lifetime_bank, deserialization_info);
}
if (simulation::ifp_delayed_on)
deserialize_ifp_info(ifp_n_generation, recv_delayed_groups,
simulation::ifp_source_delayed_group_bank, deserialization_info);
if (simulation::ifp_lifetime_on)
deserialize_ifp_info(ifp_n_generation, recv_lifetimes,
simulation::ifp_source_lifetime_bank, deserialization_info);
#else
std::copy(temp_sites.data(), temp_sites.data() + settings::n_particles,
simulation::source_bank.begin());
if (settings::ifp_on) {
copy_complete_ifp_data_to_source_banks(temp_delayed_groups, temp_lifetimes);
}
copy_complete_ifp_data_to_source_banks(temp_delayed_groups, temp_lifetimes);
#endif
simulation::time_bank_sendrecv.stop();

View file

@ -10,33 +10,15 @@
namespace openmc {
bool is_beta_effective_or_both()
{
if (settings::ifp_parameter == IFPParameter::BetaEffective ||
settings::ifp_parameter == IFPParameter::Both) {
return true;
}
return false;
}
bool is_generation_time_or_both()
{
if (settings::ifp_parameter == IFPParameter::GenerationTime ||
settings::ifp_parameter == IFPParameter::Both) {
return true;
}
return false;
}
void ifp(const Particle& p, int64_t idx)
{
if (is_beta_effective_or_both()) {
if (simulation::ifp_delayed_on) {
const auto& delayed_groups =
simulation::ifp_source_delayed_group_bank[p.current_work()];
simulation::ifp_fission_delayed_group_bank[idx] =
_ifp(p.delayed_group(), delayed_groups);
}
if (is_generation_time_or_both()) {
if (simulation::ifp_lifetime_on) {
const auto& lifetimes =
simulation::ifp_source_lifetime_bank[p.current_work()];
simulation::ifp_fission_lifetime_bank[idx] = _ifp(p.lifetime(), lifetimes);
@ -51,15 +33,16 @@ void resize_simulation_ifp_banks()
simulation::ifp_fission_lifetime_bank, 3 * simulation::work_per_rank);
}
void copy_ifp_data_from_fission_banks(
int i_bank, vector<int>& delayed_groups, vector<double>& lifetimes)
void copy_ifp_data_from_fission_banks(int i_bank, int j_bank,
vector<vector<int>>& delayed_groups_bank,
vector<vector<double>>& lifetimes_bank)
{
if (is_beta_effective_or_both()) {
delayed_groups = simulation::ifp_fission_delayed_group_bank[i_bank];
}
if (is_generation_time_or_both()) {
lifetimes = simulation::ifp_fission_lifetime_bank[i_bank];
}
if (simulation::ifp_delayed_on)
delayed_groups_bank[j_bank] =
simulation::ifp_fission_delayed_group_bank[i_bank];
if (simulation::ifp_lifetime_on)
lifetimes_bank[j_bank] = simulation::ifp_fission_lifetime_bank[i_bank];
}
#ifdef OPENMC_MPI
@ -67,28 +50,27 @@ void broadcast_ifp_n_generation(int& n_generation,
const vector<vector<int>>& delayed_groups,
const vector<vector<double>>& lifetimes)
{
if (mpi::rank == 0) {
if (is_beta_effective_or_both()) {
if (simulation::ifp_delayed_on) {
if (mpi::rank == 0)
n_generation = static_cast<int>(delayed_groups[0].size());
} else {
MPI_Bcast(&n_generation, 1, MPI_INT, 0, mpi::intracomm);
} else if (simulation::ifp_lifetime_on) {
if (mpi::rank == 0)
n_generation = static_cast<int>(lifetimes[0].size());
}
MPI_Bcast(&n_generation, 1, MPI_INT, 0, mpi::intracomm);
}
MPI_Bcast(&n_generation, 1, MPI_INT, 0, mpi::intracomm);
}
void copy_partial_ifp_data_to_source_banks(int64_t idx, int n, int64_t i_bank,
const vector<vector<int>>& delayed_groups,
const vector<vector<double>>& lifetimes)
{
if (is_beta_effective_or_both()) {
if (simulation::ifp_delayed_on)
std::copy(&delayed_groups[idx], &delayed_groups[idx + n],
&simulation::ifp_source_delayed_group_bank[i_bank]);
}
if (is_generation_time_or_both()) {
if (simulation::ifp_lifetime_on)
std::copy(&lifetimes[idx], &lifetimes[idx + n],
&simulation::ifp_source_lifetime_bank[i_bank]);
}
}
#endif
@ -96,40 +78,36 @@ void copy_complete_ifp_data_to_source_banks(
const vector<vector<int>>& delayed_groups,
const vector<vector<double>>& lifetimes)
{
if (is_beta_effective_or_both()) {
if (simulation::ifp_delayed_on)
std::copy(delayed_groups.data(),
delayed_groups.data() + settings::n_particles,
simulation::ifp_source_delayed_group_bank.begin());
}
if (is_generation_time_or_both()) {
if (simulation::ifp_lifetime_on)
std::copy(lifetimes.data(), lifetimes.data() + settings::n_particles,
simulation::ifp_source_lifetime_bank.begin());
}
}
void allocate_temporary_vector_ifp(
vector<vector<int>>& delayed_groups, vector<vector<double>>& lifetimes)
{
if (is_beta_effective_or_both()) {
if (simulation::ifp_delayed_on)
delayed_groups.resize(simulation::fission_bank.size());
}
if (is_generation_time_or_both()) {
if (simulation::ifp_lifetime_on)
lifetimes.resize(simulation::fission_bank.size());
}
}
void copy_ifp_data_to_fission_banks(const vector<int>* const delayed_groups_ptr,
const vector<double>* lifetimes_ptr)
{
if (is_beta_effective_or_both()) {
if (simulation::ifp_delayed_on)
std::copy(delayed_groups_ptr,
delayed_groups_ptr + simulation::fission_bank.size(),
simulation::ifp_fission_delayed_group_bank.data());
}
if (is_generation_time_or_both()) {
if (simulation::ifp_lifetime_on)
std::copy(lifetimes_ptr, lifetimes_ptr + simulation::fission_bank.size(),
simulation::ifp_fission_lifetime_bank.data());
}
}
} // namespace openmc

View file

@ -250,9 +250,7 @@ void create_fission_sites(Particle& p, int i_nuclide, const Reaction& rx)
break;
}
// Iterated Fission Probability (IFP) method
if (settings::ifp_on) {
ifp(p, idx);
}
ifp(p, idx);
} else {
site.wgt_born = p.wgt_born();
site.wgt_ww_born = p.wgt_ww_born();

View file

@ -55,7 +55,6 @@ bool create_fission_neutrons {true};
bool delayed_photon_scaling {true};
bool entropy_on {false};
bool event_based {false};
bool ifp_on {false};
bool legendre_to_tabular {true};
bool material_cell_offsets {true};
bool output_summary {true};
@ -114,7 +113,6 @@ ElectronTreatment electron_treatment {ElectronTreatment::TTB};
array<double, 4> energy_cutoff {0.0, 1000.0, 0.0, 0.0};
array<double, 4> time_cutoff {INFTY, INFTY, INFTY, INFTY};
int ifp_n_generation {-1};
IFPParameter ifp_parameter {IFPParameter::None};
int legendre_to_tabular_points {C_NONE};
int max_order {0};
int n_log_bins {8000};
@ -567,14 +565,8 @@ void read_settings_xml(pugi::xml_node root)
// Probability (IFP) method
if (check_for_node(root, "ifp_n_generation")) {
ifp_n_generation = std::stoi(get_node_value(root, "ifp_n_generation"));
if (ifp_n_generation <= 0) {
if (ifp_n_generation <= 0)
fatal_error("'ifp_n_generation' must be greater than 0.");
}
// Avoid tallying 0 if IFP logs are not complete when active cycles start
if (ifp_n_generation > n_inactive) {
fatal_error("'ifp_n_generation' must be lower than or equal to the "
"number of inactive cycles.");
}
}
}

View file

@ -330,6 +330,8 @@ namespace simulation {
int ct_current_file;
int current_batch;
int current_gen;
bool ifp_delayed_on {false};
bool ifp_lifetime_on {false};
bool initialized {false};
double keff {1.0};
double keff_std;
@ -459,9 +461,7 @@ void allocate_banks()
init_fission_bank(3 * simulation::work_per_rank);
// Allocate IFP bank
if (settings::ifp_on) {
resize_simulation_ifp_banks();
}
resize_simulation_ifp_banks();
}
if (settings::surf_source_write) {
@ -510,7 +510,21 @@ void initialize_batch()
simulation::time_inactive.stop();
simulation::time_active.start();
for (auto& t : model::tallies) {
t->active_ = true;
if (t->offset_ == 0)
t->active_ = true;
}
}
// Activate tallies which have activation offset.
for (auto& t : model::tallies) {
if (t->offset_ > 0) {
if (!settings::restart_run) {
if (simulation::current_batch == settings::n_inactive + 1 + t->offset_)
t->active_ = true;
} else if (simulation::current_batch == simulation::restart_batch + 1) {
if (simulation::restart_batch >= settings::n_inactive + t->offset_)
t->active_ = true;
}
}
}

View file

@ -193,64 +193,6 @@ Tally::Tally(pugi::xml_node node)
fatal_error(fmt::format("No scores specified on tally {}.", id_));
}
// Set IFP if needed
if (!settings::ifp_on) {
// Determine if this tally has an IFP score
bool has_ifp_score = false;
for (int score : scores_) {
if (score == SCORE_IFP_TIME_NUM || score == SCORE_IFP_BETA_NUM ||
score == SCORE_IFP_DENOM) {
has_ifp_score = true;
break;
}
}
// Check for errors
if (has_ifp_score) {
if (settings::run_mode == RunMode::EIGENVALUE) {
if (settings::ifp_n_generation < 0) {
settings::ifp_n_generation = DEFAULT_IFP_N_GENERATION;
warning(fmt::format(
"{} generations will be used for IFP (default value). It can be "
"changed using the 'ifp_n_generation' settings.",
settings::ifp_n_generation));
}
if (settings::ifp_n_generation > settings::n_inactive) {
fatal_error("'ifp_n_generation' must be lower than or equal to the "
"number of inactive cycles.");
}
settings::ifp_on = true;
} else if (settings::run_mode == RunMode::FIXED_SOURCE) {
fatal_error(
"Iterated Fission Probability can only be used in an eigenvalue "
"calculation.");
}
}
}
// Set IFP parameters if needed
if (settings::ifp_on) {
for (int score : scores_) {
switch (score) {
case SCORE_IFP_TIME_NUM:
if (settings::ifp_parameter == IFPParameter::None) {
settings::ifp_parameter = IFPParameter::GenerationTime;
} else if (settings::ifp_parameter == IFPParameter::BetaEffective) {
settings::ifp_parameter = IFPParameter::Both;
}
break;
case SCORE_IFP_BETA_NUM:
case SCORE_IFP_DENOM:
if (settings::ifp_parameter == IFPParameter::None) {
settings::ifp_parameter = IFPParameter::BetaEffective;
} else if (settings::ifp_parameter == IFPParameter::GenerationTime) {
settings::ifp_parameter = IFPParameter::Both;
}
break;
}
}
}
// Check if tally is compatible with particle type
if (!settings::photon_transport) {
for (int score : scores_) {
@ -686,7 +628,23 @@ void Tally::set_scores(const vector<std::string>& scores)
case SCORE_IFP_TIME_NUM:
case SCORE_IFP_BETA_NUM:
case SCORE_IFP_DENOM:
if (score == SCORE_IFP_TIME_NUM)
simulation::ifp_lifetime_on = true;
if (score == SCORE_IFP_BETA_NUM)
simulation::ifp_delayed_on = true;
if (settings::run_mode == RunMode::FIXED_SOURCE)
fatal_error(
"Iterated Fission Probability can only be used in an eigenvalue "
"calculation.");
if (settings::ifp_n_generation < 0) {
settings::ifp_n_generation = DEFAULT_IFP_N_GENERATION;
warning(fmt::format(
"{} generations will be used for IFP (default value). It can be "
"changed using the 'ifp_n_generation' settings.",
settings::ifp_n_generation));
}
estimator_ = TallyEstimator::COLLISION;
offset_ = settings::ifp_n_generation;
break;
}

View file

@ -941,61 +941,34 @@ void score_general_ce_nonanalog(Particle& p, int i_tally, int start_index,
break;
case SCORE_IFP_TIME_NUM:
if (settings::ifp_on) {
if (p.type().is_neutron() && p.fission()) {
if (is_generation_time_or_both()) {
const auto& lifetimes =
simulation::ifp_source_lifetime_bank[p.current_work()];
if (lifetimes.size() == settings::ifp_n_generation) {
score = lifetimes[0] * p.wgt_last();
}
}
}
if (p.type().is_neutron() && p.fission()) {
const auto& lifetime =
simulation::ifp_source_lifetime_bank[p.current_work()][0];
score = lifetime * p.wgt_last();
}
break;
case SCORE_IFP_BETA_NUM:
if (settings::ifp_on) {
if (p.type().is_neutron() && p.fission()) {
if (is_beta_effective_or_both()) {
const auto& delayed_groups =
simulation::ifp_source_delayed_group_bank[p.current_work()];
if (delayed_groups.size() == settings::ifp_n_generation) {
if (delayed_groups[0] > 0) {
score = p.wgt_last();
if (tally.delayedgroup_filter_ != C_NONE) {
auto i_dg_filt = tally.filters()[tally.delayedgroup_filter_];
const DelayedGroupFilter& filt {
*dynamic_cast<DelayedGroupFilter*>(
model::tally_filters[i_dg_filt].get())};
score_fission_delayed_dg(i_tally, delayed_groups[0] - 1,
score, score_index, p.filter_matches());
continue;
}
}
}
if (p.type().is_neutron() && p.fission()) {
const auto& delayed_group =
simulation::ifp_source_delayed_group_bank[p.current_work()][0];
if (delayed_group > 0) {
score = p.wgt_last();
if (tally.delayedgroup_filter_ != C_NONE) {
auto i_dg_filt = tally.filters()[tally.delayedgroup_filter_];
const DelayedGroupFilter& filt {*dynamic_cast<DelayedGroupFilter*>(
model::tally_filters[i_dg_filt].get())};
score_fission_delayed_dg(i_tally, delayed_group - 1, score,
score_index, p.filter_matches());
continue;
}
}
}
break;
case SCORE_IFP_DENOM:
if (settings::ifp_on) {
if (p.type().is_neutron() && p.fission()) {
int ifp_data_size;
if (is_beta_effective_or_both()) {
ifp_data_size = static_cast<int>(
simulation::ifp_source_delayed_group_bank[p.current_work()]
.size());
} else {
ifp_data_size = static_cast<int>(
simulation::ifp_source_lifetime_bank[p.current_work()].size());
}
if (ifp_data_size == settings::ifp_n_generation) {
score = p.wgt_last();
}
}
}
if (p.type().is_neutron() && p.fission())
score = p.wgt_last();
break;
case N_2N:

View file

@ -12,7 +12,7 @@
</geometry>
<settings>
<run_mode>eigenvalue</run_mode>
<particles>1000</particles>
<particles>10000</particles>
<batches>20</batches>
<inactive>5</inactive>
<source type="independent" strength="1.0" particle="neutron">

View file

@ -1,21 +1,21 @@
k-combined:
1.006559E+00 5.389391E-03
1.011403E+00 2.852123E-03
tally 1:
9.109384E-08
5.667165E-16
6.322790E-08
4.014613E-16
tally 2:
3.000000E-03
9.000000E-06
0.000000E+00
0.000000E+00
2.100000E-02
1.370000E-04
2.800000E-02
2.220000E-04
0.000000E+00
0.000000E+00
0.000000E+00
0.000000E+00
1.700000E-03
1.490000E-06
9.100000E-03
1.351000E-05
1.630000E-02
5.251000E-05
2.090000E-02
5.605000E-05
1.060000E-02
2.056000E-05
9.000000E-04
2.300000E-07
tally 3:
1.489000E+01
1.480036E+01
9.945300E+00
9.892586E+00

View file

@ -21,7 +21,7 @@ def ifp_model():
# Settings
settings = openmc.Settings()
settings.particles = 1000
settings.particles = 10000
settings.batches = 20
settings.inactive = 5
settings.ifp_n_generation = 5

View file

@ -1,9 +1,9 @@
k-combined:
1.006559E+00 5.389391E-03
tally 1:
9.109384E-08
5.667165E-16
5.200000E-02
5.420000E-04
1.489000E+01
1.480036E+01
6.064971E-08
3.807785E-16
3.300000E-02
3.610000E-04
9.876000E+00
9.761494E+00

View file

@ -32,8 +32,6 @@ def geometry():
({"ifp_n_generation": 0}, ValueError),
({"ifp_n_generation": -1}, ValueError),
({"run_mode": "fixed source"}, RuntimeError),
({"inactive": 5, "ifp_n_generation": 6}, RuntimeError),
({"inactive": 9}, RuntimeError)
],
)
def test_exceptions(options, error, run_in_tmpdir, geometry):