mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 21:55:41 -04:00
Add a helper function to calculate the maximum size of the stack used in atomic relaxation
This commit is contained in:
parent
ba1a39e281
commit
07a0ff5072
2 changed files with 60 additions and 0 deletions
|
|
@ -104,6 +104,9 @@ public:
|
|||
private:
|
||||
void compton_doppler(
|
||||
double alpha, double mu, double* E_out, int* i_shell, uint64_t* seed) const;
|
||||
|
||||
int calc_max_stack_size() const;
|
||||
int calc_helper(std::unordered_map<int, int>& visited, int i_shell) const;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "openmc/constants.h"
|
||||
#include "openmc/distribution_multi.h"
|
||||
#include "openmc/hdf5_interface.h"
|
||||
#include "openmc/message_passing.h"
|
||||
#include "openmc/nuclide.h"
|
||||
#include "openmc/particle.h"
|
||||
#include "openmc/random_dist.h"
|
||||
|
|
@ -187,6 +188,14 @@ PhotonInteraction::PhotonInteraction(hid_t group)
|
|||
}
|
||||
close_group(rgroup);
|
||||
|
||||
// Check the maximum size of the atomic relaxation stack
|
||||
auto max_size = this->calc_max_stack_size();
|
||||
if (max_size > MAX_STACK_SIZE && mpi::master) {
|
||||
warning("The subshell vacancy stack in atomic relaxation can grow up to " +
|
||||
std::to_string(max_size) + ", but the stack size limit is set to " +
|
||||
std::to_string(MAX_STACK_SIZE) + ".");
|
||||
}
|
||||
|
||||
// Determine number of electron shells
|
||||
rgroup = open_group(group, "compton_profiles");
|
||||
|
||||
|
|
@ -314,6 +323,54 @@ PhotonInteraction::~PhotonInteraction()
|
|||
data::element_map.erase(name_);
|
||||
}
|
||||
|
||||
int PhotonInteraction::calc_max_stack_size() const
|
||||
{
|
||||
// Table to store solutions to sub-problems
|
||||
std::unordered_map<int, int> visited;
|
||||
|
||||
// Find the maximum possible size of the stack used to store holes created
|
||||
// during atomic relaxation, checking over every subshell the initial hole
|
||||
// could be in
|
||||
int max_size = 0;
|
||||
for (int i_shell = 0; i_shell < shells_.size(); ++i_shell) {
|
||||
max_size = std::max(max_size, this->calc_helper(visited, i_shell));
|
||||
}
|
||||
return max_size;
|
||||
}
|
||||
|
||||
int PhotonInteraction::calc_helper(
|
||||
std::unordered_map<int, int>& visited, int i_shell) const
|
||||
{
|
||||
// No transitions for this subshell, so this is the only shell in the stack
|
||||
const auto& shell {shells_[i_shell]};
|
||||
if (shell.transitions.empty()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check the table to see if the maximum stack size has already been
|
||||
// calculated for this shell
|
||||
auto it = visited.find(i_shell);
|
||||
if (it != visited.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int max_size = 0;
|
||||
for (const auto& transition : shell.transitions) {
|
||||
// If this is a non-radiative transition two vacancies are created and
|
||||
// the stack grows by one; if this is a radiative transition only one
|
||||
// vacancy is created and the stack size stays the same
|
||||
int size = 0;
|
||||
if (transition.secondary_subshell != -1) {
|
||||
size = this->calc_helper(visited, transition.secondary_subshell) + 1;
|
||||
}
|
||||
size =
|
||||
std::max(size, this->calc_helper(visited, transition.primary_subshell));
|
||||
max_size = std::max(max_size, size);
|
||||
}
|
||||
visited[i_shell] = max_size;
|
||||
return max_size;
|
||||
}
|
||||
|
||||
void PhotonInteraction::compton_scatter(double alpha, bool doppler,
|
||||
double* alpha_out, double* mu, int* i_shell, uint64_t* seed) const
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue