Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions include/openmc/bank.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ extern SharedArray<CollisionTrackSite> collision_track_bank;

extern SharedArray<SourceSite> fission_bank;

extern vector<vector<int>> ifp_source_delayed_group_bank;

extern vector<vector<double>> ifp_source_lifetime_bank;

extern vector<vector<int>> ifp_fission_delayed_group_bank;

extern vector<vector<double>> ifp_fission_lifetime_bank;

extern vector<int64_t> progeny_per_particle;

extern SharedArray<SourceSite> shared_secondary_bank_read;
Expand Down
199 changes: 132 additions & 67 deletions include/openmc/ifp.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,6 @@

namespace openmc {

//! Resize IFP vectors
//!
//! \param[in,out] delayed_groups List of delayed group numbers
//! \param[in,out] lifetimes List of lifetimes
//! \param[in] n Dimension to resize vectors
template<typename T, typename U>
void resize_ifp_data(vector<T>& delayed_groups, vector<U>& lifetimes, int64_t n)
{
if (settings::ifp_delayed_group_on) {
delayed_groups.resize(n);
}
if (settings::ifp_lifetime_on) {
lifetimes.resize(n);
}
}

//! Update a list of values by adding a new value if the size
//! of the list can accomodate the new value or by shifting all
//! values to the left (removing the first value of the list
Expand Down Expand Up @@ -56,12 +40,129 @@ vector<T> _ifp(const T& value, const vector<T>& data)
return updated;
}

//==============================================================================
//! One stream of Iterated Fission Probability history data.
//
//! IFP tracks two quantities with identical bookkeeping: the delayed group
//! number of the ancestor neutron (an int) and its lifetime (a double). Each is
//! a per-particle list of the last ifp_n_generation values, held in a source
//! bank and a fission bank, and each is maintained only if a tally asked for
//! it.
//!
//! Bundling the flag with the two banks it governs means every operation is a
//! no-op when the stream is off, so callers do not branch, and the banks cannot
//! be resized independently of the flag.
//==============================================================================

template<typename T>
class IFPStream {
public:
//! Whether this stream is being maintained
bool enabled() const { return enabled_; }

//! Begin maintaining this stream, when a tally requests a dependent score
void enable() { enabled_ = true; }

//! Clear the stream, including the flag. Derived from the tallies present in
//! the model, so it must not persist into the next model in this process.
void reset()
{
enabled_ = false;
source_bank_.clear();
fission_bank_.clear();
}

vector<vector<T>>& source_bank() { return source_bank_; }
const vector<vector<T>>& source_bank() const { return source_bank_; }
vector<vector<T>>& fission_bank() { return fission_bank_; }

//! Resize both banks
void resize_banks(int64_t n_source, int64_t n_fission)
{
if (!enabled_)
return;
source_bank_.resize(n_source);
fission_bank_.resize(n_fission);
}

//! Append a value to the ancestor history of a new fission site
void store(int64_t i_source, int64_t i_fission, const T& value)
{
if (!enabled_)
return;
fission_bank_[i_fission] = _ifp(value, source_bank_[i_source]);
}

//! Resize a caller-owned buffer for this stream, if it is enabled.
//
//! Templated on the container because callers pass both the per-particle
//! banks (`vector<vector<T>>`) and the flat MPI serialization buffers
//! (`vector<T>`).
template<typename V>
void resize_temp(V& temp, int64_t n) const
{
if (enabled_)
temp.resize(n);
}

//! Copy one entry of the fission bank into a caller-owned buffer
//
//! \param[in] i_fission Index in this stream's fission bank
//! \param[in] i_temp Index in the destination buffer
//! \param[out] out Destination buffer
void copy_from_fission(
int64_t i_fission, int64_t i_temp, vector<vector<T>>& out) const
{
if (enabled_)
out[i_temp] = fission_bank_[i_fission];
}

//! Copy a temporary buffer into the fission bank
void copy_temp_to_fission(const vector<T>* temp, size_t n)
{
if (enabled_)
std::copy(temp, temp + n, fission_bank_.data());
}

//! Copy a run of a temporary buffer into the source bank
void copy_temp_to_source(
int64_t i_temp, int64_t n, int64_t i_source, const vector<vector<T>>& temp)
{
if (enabled_)
std::copy(&temp[i_temp], &temp[i_temp + n], &source_bank_[i_source]);
}

//! Copy a whole temporary buffer into the source bank
void copy_all_temp_to_source(const vector<vector<T>>& temp, int64_t n)
{
if (enabled_)
std::copy(temp.data(), temp.data() + n, source_bank_.begin());
}

private:
bool enabled_ {false};
vector<vector<T>> source_bank_;
vector<vector<T>> fission_bank_;
};

namespace simulation {

extern IFPStream<int> ifp_delayed_group; //!< Delayed group numbers
extern IFPStream<double> ifp_lifetime; //!< Neutron lifetimes

} // namespace simulation

//! Whether Iterated Fission Probability is in use at all
inline bool ifp_on()
{
return simulation::ifp_delayed_group.enabled() ||
simulation::ifp_lifetime.enabled();
}

//! \brief Iterated Fission Probability (IFP) method.
//!
//! Add the IFP information in the IFP banks using the same index
//! as the one used to append the fission site to the fission bank.
//! The information stored are the delayed group number and lifetime
//! of the neutron that created the fission event.
//! Multithreading protection is guaranteed by the index returned by the
//! thread_safe_append call in physics.cpp.
//!
Expand All @@ -72,14 +173,8 @@ void ifp(const Particle& p, int64_t idx);
//! Resize the IFP banks used in the simulation
void resize_simulation_ifp_banks();

//! Retrieve IFP data from the IFP fission banks.
//!
//! \param[in] i_bank Index in the fission banks
//! \param[in] i_temp Index in the temporary bank vectors
//! \param[in,out] delayed_groups Delayed group numbers
//! \param[in,out] lifetimes Lifetimes lists
void copy_ifp_data_from_fission_banks(int64_t i_bank, int64_t i_temp,
vector<vector<int>>& delayed_groups, vector<vector<double>>& lifetimes);
//! Clear both streams, including their flags
void reset_ifp_streams();

#ifdef OPENMC_MPI

Expand All @@ -89,10 +184,10 @@ struct DeserializationInfo {
int64_t n; //!< number of sites sent
};

//! Broadcast the number of generation determined by the size of the first
//! element on the first processor.
//! Broadcast the number of generations, determined from the first element on
//! the first processor of whichever stream is enabled.
//!
//! \param[in] n_generation Number of generations
//! \param[in,out] n_generation Number of generations
//! \param[in] delayed_groups List of delayed group numbers lists
//! \param[in] lifetimes List of lifetimes lists
void broadcast_ifp_n_generation(int& n_generation,
Expand Down Expand Up @@ -150,28 +245,20 @@ void receive_ifp_data(int64_t idx, int64_t n, int n_generation, int neighbor,
deserialization.push_back(info);
}

//! Copy partial IFP data from local lists to source banks.
//!
//! \param[in] idx Index of the first site
//! \param[in] n Number of sites to copy
//! \param[in] i_bank Index in the IFP source banks
//! \param[in] delayed_groups List of delayed group numbers lists
//! \param[in] lifetimes List of lifetimes lists
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);

//! Deserialize IFP information received using MPI and store it in
//! the IFP source banks.
//! Deserialize IFP information received using MPI into a stream's source bank.
//!
//! \param[in] n_generation Number of generations
//! \param[in] data data to deserialize
//! \param[in] bank bank to store data
//! \param[out] deserialization Information to deserialize the received data
//! \param[in,out] stream Stream whose source bank receives the data
//! \param[in] deserialization Information to deserialize the received data
template<typename T>
void deserialize_ifp_info(int n_generation, const vector<T>& data,
vector<vector<T>>& bank, const vector<DeserializationInfo>& deserialization)
IFPStream<T>& stream, const vector<DeserializationInfo>& deserialization)
{
if (!stream.enabled())
return;

auto& bank = stream.source_bank();
for (auto info : deserialization) {
int64_t index_local = info.index_local;
int64_t n = info.n;
Expand All @@ -186,28 +273,6 @@ void deserialize_ifp_info(int n_generation, const vector<T>& data,

#endif

//! Copy IFP temporary vectors to source banks.
//!
//! \param[in] delayed_groups List of delayed group numbers lists
//! \param[in] lifetimes List of lifetimes lists
void copy_complete_ifp_data_to_source_banks(
const vector<vector<int>>& delayed_groups,
const vector<vector<double>>& lifetimes);

//! Allocate temporary vectors for IFP data.
//!
//! \param[in,out] delayed_groups List of delayed group numbers lists
//! \param[in,out] lifetimes List of delayed group numbers lists
void allocate_temporary_vector_ifp(
vector<vector<int>>& delayed_groups, vector<vector<double>>& lifetimes);

//! Copy local IFP data to IFP fission banks.
//!
//! \param[in] delayed_groups_ptr Pointer to delayed group numbers
//! \param[in] lifetimes_ptr Pointer to lifetimes
void copy_ifp_data_to_fission_banks(
const vector<int>* delayed_groups_ptr, const vector<double>* lifetimes_ptr);

} // namespace openmc

#endif // OPENMC_IFP_H
8 changes: 0 additions & 8 deletions include/openmc/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ extern bool
extern "C" bool entropy_on; //!< calculate Shannon entropy?
extern "C" bool
event_based; //!< use event-based mode (instead of history-based)
extern bool ifp_delayed_group_on; //!< Store delayed group IFP data?
extern bool ifp_lifetime_on; //!< Store lifetime IFP data?
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?
Expand Down Expand Up @@ -195,12 +193,6 @@ extern "C" int verbosity; //!< How verbose to make output
extern double weight_cutoff; //!< Weight cutoff for Russian roulette
extern double weight_survive; //!< Survival weight after Russian roulette

//! Whether Iterated Fission Probability is in use at all.
inline bool ifp_on()
{
return ifp_delayed_group_on || ifp_lifetime_on;
}

} // namespace settings

//==============================================================================
Expand Down
37 changes: 16 additions & 21 deletions src/bank.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,6 @@ SharedArray<CollisionTrackSite> collision_track_bank;
// function.
SharedArray<SourceSite> fission_bank;

vector<vector<int>> ifp_source_delayed_group_bank;

vector<vector<double>> ifp_source_lifetime_bank;

vector<vector<int>> ifp_fission_delayed_group_bank;

vector<vector<double>> ifp_fission_lifetime_bank;

// Each entry in this vector corresponds to the number of progeny produced
// this generation for the particle located at that index. This vector is
// used to efficiently sort the fission bank after each iteration.
Expand All @@ -64,10 +56,7 @@ void free_memory_bank()
simulation::collision_track_bank.clear();
simulation::fission_bank.clear();
simulation::progeny_per_particle.clear();
simulation::ifp_source_delayed_group_bank.clear();
simulation::ifp_source_lifetime_bank.clear();
simulation::ifp_fission_delayed_group_bank.clear();
simulation::ifp_fission_lifetime_bank.clear();
reset_ifp_streams();
simulation::shared_secondary_bank_read.clear();
simulation::shared_secondary_bank_write.clear();
}
Expand Down Expand Up @@ -113,9 +102,10 @@ void sort_bank(SharedArray<SourceSite>& bank, bool is_fission_bank)
sorted_bank = bank.data() + bank.size();
}

if (settings::ifp_on() && is_fission_bank) {
allocate_temporary_vector_ifp(
sorted_ifp_delayed_group_bank, sorted_ifp_lifetime_bank);
if (ifp_on() && is_fission_bank) {
int64_t n = simulation::fission_bank.size();
simulation::ifp_delayed_group.resize_temp(sorted_ifp_delayed_group_bank, n);
simulation::ifp_lifetime.resize_temp(sorted_ifp_lifetime_bank, n);
}

// Use parent and progeny indices to sort bank
Expand All @@ -135,17 +125,22 @@ 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) {
copy_ifp_data_from_fission_banks(
i, idx, sorted_ifp_delayed_group_bank, sorted_ifp_lifetime_bank);
if (ifp_on() && is_fission_bank) {
simulation::ifp_delayed_group.copy_from_fission(
i, idx, sorted_ifp_delayed_group_bank);
simulation::ifp_lifetime.copy_from_fission(
i, idx, 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) {
copy_ifp_data_to_fission_banks(
sorted_ifp_delayed_group_bank.data(), sorted_ifp_lifetime_bank.data());
if (ifp_on() && is_fission_bank) {
size_t n = simulation::fission_bank.size();
simulation::ifp_delayed_group.copy_temp_to_fission(
sorted_ifp_delayed_group_bank.data(), n);
simulation::ifp_lifetime.copy_temp_to_fission(
sorted_ifp_lifetime_bank.data(), n);
}
}

Expand Down
Loading
Loading