Merge pull request #3 from openmc-dev/develop

CI
This commit is contained in:
John Tramm 2019-11-18 08:20:52 -06:00 committed by GitHub
commit 54698ec7da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 524 additions and 348 deletions

View file

@ -11,6 +11,7 @@
#include "openmc/constants.h"
#include "openmc/hdf5_interface.h"
#include "openmc/particle.h"
#include "openmc/xsdata.h"
@ -143,6 +144,11 @@ class Mgxs {
get_xs(int xstype, int gin, const int* gout, const double* mu,
const int* dg);
inline double
get_xs(int xstype, int gin)
{return get_xs(xstype, gin, nullptr, nullptr, nullptr);}
//! \brief Samples the fission neutron energy and if prompt or delayed.
//!
//! @param gin Incoming energy group.
@ -162,15 +168,9 @@ class Mgxs {
//! \brief Calculates cross section quantities needed for tracking.
//!
//! @param gin Incoming energy group.
//! @param sqrtkT Temperature of the material.
//! @param u Incoming particle direction.
//! @param total_xs Resultant total cross section.
//! @param abs_xs Resultant absorption cross section.
//! @param nu_fiss_xs Resultant nu-fission cross section.
//! @param p The particle whose attributes set which MGXS to get.
void
calculate_xs(int gin, double sqrtkT, Direction u,
double& total_xs, double& abs_xs, double& nu_fiss_xs);
calculate_xs(Particle& p);
//! \brief Sets the temperature index in cache given a temperature
//!

View file

@ -78,39 +78,5 @@ void set_mg_interface_nuclides_and_temps();
// After macro XS have been read, materials can be marked as fissionable
void mark_fissionable_mgxs_materials();
//==============================================================================
// Mgxs tracking/transport/tallying interface methods
//==============================================================================
extern "C" void
calculate_xs_c(int i_mat, int gin, double sqrtkT, Direction u,
double& total_xs, double& abs_xs, double& nu_fiss_xs);
double
get_nuclide_xs(int index, int xstype, int gin, const int* gout,
const double* mu, const int* dg);
inline double
get_nuclide_xs(int index, int xstype, int gin)
{return get_nuclide_xs(index, xstype, gin, nullptr, nullptr, nullptr);}
double
get_macro_xs(int index, int xstype, int gin, const int* gout,
const double* mu, const int* dg);
inline double
get_macro_xs(int index, int xstype, int gin)
{return get_macro_xs(index, xstype, gin, nullptr, nullptr, nullptr);}
//==============================================================================
// General Mgxs methods
//==============================================================================
extern "C" void
get_name_c(int index, int name_len, char* name);
extern "C" double
get_awr_c(int index);
} // namespace openmc
#endif // OPENMC_MGXS_INTERFACE_H

View file

@ -555,11 +555,10 @@ Mgxs::sample_fission_energy(int gin, int& dg, int& gout)
dg = -1;
// sample the outgoing energy group
gout = 0;
double prob_gout = xs_t->chi_prompt(cache[tid].a, gin, gout);
while (prob_gout < xi_gout) {
gout++;
double prob_gout = 0.;
for (gout = 0; gout < num_groups; ++gout) {
prob_gout += xs_t->chi_prompt(cache[tid].a, gin, gout);
if (xi_gout < prob_gout) break;
}
} else {
@ -575,11 +574,10 @@ Mgxs::sample_fission_energy(int gin, int& dg, int& gout)
dg = std::min(dg, num_delayed_groups - 1);
// sample the outgoing energy group
gout = 0;
double prob_gout = xs_t->chi_delayed(cache[tid].a, dg, gin, gout);
while (prob_gout < xi_gout) {
gout++;
double prob_gout = 0.;
for (gout = 0; gout < num_groups; ++gout) {
prob_gout += xs_t->chi_delayed(cache[tid].a, dg, gin, gout);
if (xi_gout < prob_gout) break;
}
}
}
@ -602,8 +600,7 @@ Mgxs::sample_scatter(int gin, int& gout, double& mu, double& wgt)
//==============================================================================
void
Mgxs::calculate_xs(int gin, double sqrtkT, Direction u,
double& total_xs, double& abs_xs, double& nu_fiss_xs)
Mgxs::calculate_xs(Particle& p)
{
// Set our indices
#ifdef _OPENMP
@ -611,13 +608,13 @@ Mgxs::calculate_xs(int gin, double sqrtkT, Direction u,
#else
int tid = 0;
#endif
set_temperature_index(sqrtkT);
set_angle_index(u);
set_temperature_index(p.sqrtkT_);
set_angle_index(p.u_local());
XsData* xs_t = &xs[cache[tid].t];
total_xs = xs_t->total(cache[tid].a, gin);
abs_xs = xs_t->absorption(cache[tid].a, gin);
nu_fiss_xs = fissionable ? xs_t->nu_fission(cache[tid].a, gin) : 0.;
p.macro_xs_.total = xs_t->total(cache[tid].a, p.g_);
p.macro_xs_.absorption = xs_t->absorption(cache[tid].a, p.g_);
p.macro_xs_.nu_fission =
fissionable ? xs_t->nu_fission(cache[tid].a, p.g_) : 0.;
}
//==============================================================================

View file

@ -38,7 +38,7 @@ MgxsInterface::MgxsInterface(const std::string& path_cross_sections,
void MgxsInterface::set_nuclides_and_temperatures(
std::vector<std::string> xs_to_read,
std::vector<std::vector<double>> xs_temps)
{
{
// Check to remove all duplicates
xs_to_read_ = xs_to_read;
xs_temps_to_read_ = xs_temps;
@ -287,77 +287,4 @@ void mark_fissionable_mgxs_materials()
}
}
//==============================================================================
// Mgxs tracking/transport/tallying interface methods
//==============================================================================
void
calculate_xs_c(int i_mat, int gin, double sqrtkT, Direction u,
double& total_xs, double& abs_xs, double& nu_fiss_xs)
{
data::mg.macro_xs_[i_mat].calculate_xs(gin - 1, sqrtkT, u, total_xs, abs_xs,
nu_fiss_xs);
}
//==============================================================================
double
get_nuclide_xs(int index, int xstype, int gin, const int* gout,
const double* mu, const int* dg)
{
int gout_c;
const int* gout_c_p;
if (gout != nullptr) {
gout_c = *gout - 1;
gout_c_p = &gout_c;
} else {
gout_c_p = gout;
}
return data::mg.nuclides_[index].get_xs(xstype, gin - 1, gout_c_p, mu, dg);
}
//==============================================================================
double
get_macro_xs(int index, int xstype, int gin, const int* gout,
const double* mu, const int* dg)
{
int gout_c;
const int* gout_c_p;
if (gout != nullptr) {
gout_c = *gout - 1;
gout_c_p = &gout_c;
} else {
gout_c_p = gout;
}
return data::mg.macro_xs_[index].get_xs(xstype, gin - 1, gout_c_p, mu, dg);
}
//==============================================================================
// General Mgxs methods
//==============================================================================
void
get_name_c(int index, int name_len, char* name)
{
// First blank out our input string
std::string str(name_len - 1, ' ');
std::strcpy(name, str.c_str());
// Now get the data and copy to the C-string
str = data::mg.nuclides_[index - 1].name;
std::strcpy(name, str.c_str());
// Finally, remove the null terminator
name[std::strlen(name)] = ' ';
}
//==============================================================================
double
get_awr_c(int index)
{
return data::mg.nuclides_[index - 1].awr;
}
} // namespace openmc

View file

@ -129,7 +129,7 @@ Particle::from_source(const Bank* src)
} else {
g_ = static_cast<int>(src->E);
g_last_ = static_cast<int>(src->E);
E_ = data::mg.energy_bin_avg_[g_ - 1];
E_ = data::mg.energy_bin_avg_[g_];
}
E_last_ = E_;
}
@ -210,12 +210,12 @@ Particle::transport()
model::materials[material_]->calculate_xs(*this);
}
} else {
// Get the MG data
calculate_xs_c(material_, g_, sqrtkT_, this->u_local(),
macro_xs_.total, macro_xs_.absorption, macro_xs_.nu_fission);
// Get the MG data; unlike the CE case above, we have to re-calculate
// cross sections for every collision since the cross sections may
// be angle-dependent
data::mg.macro_xs_[material_].calculate_xs(*this);
// Finally, update the particle group while we have already checked
// for if multi-group
// Update the particle's group while we know we are multi-group
g_last_ = g_;
}
} else {
@ -436,7 +436,7 @@ Particle::cross_surface()
}
return;
} else if ((surf->bc_ == BC_REFLECT || surf->bc_ == BC_WHITE)
} else if ((surf->bc_ == BC_REFLECT || surf->bc_ == BC_WHITE)
&& (settings::run_mode != RUN_MODE_PLOTTING)) {
// =======================================================================
// PARTICLE REFLECTS FROM SURFACE
@ -466,11 +466,11 @@ Particle::cross_surface()
score_surface_tally(this, model::active_meshsurf_tallies);
this->r() = r;
}
Direction u = (surf->bc_ == BC_REFLECT) ?
surf->reflect(this->r(), this->u()) :
surf->diffuse_reflect(this->r(), this->u());
// Make sure new particle direction is normalized
this->u() = u / u.norm();

View file

@ -52,7 +52,7 @@ void read_particle_restart(Particle& p, int& previous_run_mode)
// Set energy group and average energy in multi-group mode
if (!settings::run_CE) {
p.g_ = p.E_;
p.E_ = data::mg.energy_bin_avg_[p.g_ - 1];
p.E_ = data::mg.energy_bin_avg_[p.g_];
}
// Set particle last attributes

View file

@ -77,22 +77,14 @@ sample_reaction(Particle* p)
void
scatter(Particle* p)
{
// Adjust indices for Fortran to C++ indexing
// TODO: Remove when no longer needed
int gin = p->g_last_ - 1;
int gout = p->g_ - 1;
int i_mat = p->material_;
data::mg.macro_xs_[i_mat].sample_scatter(gin, gout, p->mu_, p->wgt_);
// Adjust return value for fortran indexing
// TODO: Remove when no longer needed
p->g_ = gout + 1;
data::mg.macro_xs_[p->material_].sample_scatter(p->g_last_, p->g_, p->mu_,
p->wgt_);
// Rotate the angle
p->u() = rotate_angle(p->u(), p->mu_, nullptr);
// Update energy value for downstream compatability (in tallying)
p->E_ = data::mg.energy_bin_avg_[gout];
p->E_ = data::mg.energy_bin_avg_[p->g_];
// Set event component
p->event_ = EVENT_SCATTER;
@ -144,12 +136,14 @@ create_fission_sites(Particle* p, std::vector<Particle::Bank>& bank)
site.u.y = std::sqrt(1. - mu * mu) * std::cos(phi);
site.u.z = std::sqrt(1. - mu * mu) * std::sin(phi);
// Sample secondary energy distribution for the fission reaction and set
// the energy in the fission bank
// Sample secondary energy distribution for the fission reaction
int dg;
int gout;
data::mg.macro_xs_[p->material_].sample_fission_energy(p->g_ - 1, dg, gout);
site.E = gout + 1;
data::mg.macro_xs_[p->material_].sample_fission_energy(p->g_, dg, gout);
// Store the energy and delayed groups on the fission bank
site.E = gout;
// We add 1 to the delayed_group bc in MG, -1 is prompt, but in the rest
// of the code, 0 is prompt.
site.delayed_group = dg + 1;
// Set the delayed group on the particle as well

View file

@ -171,14 +171,12 @@ ScattData::sample_energy(int gin, int& gout, int& i_gout)
{
// Sample the outgoing group
double xi = prn();
double prob = 0.;
i_gout = 0;
gout = gmin[gin];
double prob = energy[gin][i_gout];
while((prob < xi) && (gout < gmax[gin])) {
gout++;
i_gout++;
for (gout = gmin[gin]; gout < gmax[gin]; ++gout) {
prob += energy[gin][i_gout];
if (xi < prob) break;
++i_gout;
}
}
@ -358,20 +356,18 @@ ScattDataLegendre::sample(int gin, int& gout, double& mu, double& wgt)
// Now we can sample mu using the scattering kernel using rejection
// sampling from a rectangular bounding box
double M = max_val[gin][i_gout];
int samples = 0;
while(true) {
int samples;
for (samples = 0; samples < MAX_SAMPLE; ++samples) {
mu = 2. * prn() - 1.;
double f = calc_f(gin, gout, mu);
if (f > 0.) {
double u = prn() * M;
if (u <= f) break;
}
samples++;
if (samples > MAX_SAMPLE) {
fatal_error("Maximum number of Legendre expansion samples reached");
}
};
}
if (samples == MAX_SAMPLE) {
fatal_error("Maximum number of Legendre expansion samples reached!");
}
// Update the weight to reflect neutron multiplicity
wgt *= mult[gin][i_gout];

View file

@ -311,11 +311,11 @@ Particle::Bank sample_external_source()
// Sample source site from i-th source distribution
Particle::Bank site {model::external_sources[i].sample()};
// If running in MG, convert site % E to group
// If running in MG, convert site.E to group
if (!settings::run_CE) {
site.E = lower_bound_index(data::mg.rev_energy_bins_.begin(),
data::mg.rev_energy_bins_.end(), site.E);
site.E = data::mg.num_energy_groups_ - site.E;
site.E = data::mg.num_energy_groups_ - site.E - 1.;
}
// Set the random number generator back to the tracking stream.

View file

@ -61,9 +61,9 @@ const
{
if (p->g_ != F90_NONE && matches_transport_groups_) {
if (estimator == ESTIMATOR_TRACKLENGTH) {
match.bins_.push_back(data::mg.num_energy_groups_ - p->g_);
match.bins_.push_back(data::mg.num_energy_groups_ - p->g_ - 1);
} else {
match.bins_.push_back(data::mg.num_energy_groups_ - p->g_last_);
match.bins_.push_back(data::mg.num_energy_groups_ - p->g_last_ - 1);
}
match.weights_.push_back(1.0);
@ -104,7 +104,7 @@ EnergyoutFilter::get_all_bins(const Particle* p, int estimator,
FilterMatch& match) const
{
if (p->g_ != F90_NONE && matches_transport_groups_) {
match.bins_.push_back(data::mg.num_energy_groups_ - p->g_);
match.bins_.push_back(data::mg.num_energy_groups_ - p->g_ - 1);
match.weights_.push_back(1.0);
} else {

View file

@ -348,9 +348,9 @@ score_fission_eout(const Particle* p, int i_tally, int i_score, int score_bin)
// determine outgoing energy group from fission bank
auto g_out = static_cast<int>(bank.E);
// modify the value so that g_out = 1 corresponds to the highest energy
// modify the value so that g_out = 0 corresponds to the highest energy
// bin
g_out = eo_filt.n_bins() - g_out;
g_out = eo_filt.n_bins() - g_out - 1;
// change outgoing energy bin
simulation::filter_matches[i_eout_filt].bins_[i_bin] = g_out;
@ -1374,15 +1374,15 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
p_g = p->g_;
}
// To significantly reduce de-referencing, point matxs to the macroscopic
// Mgxs for the material of interest
data::mg.macro_xs_[p->material_].set_angle_index(p_u);
// For shorthand, assign pointers to the material and nuclide xs set
auto& nuc_xs = data::mg.nuclides_[i_nuclide];
auto& macro_xs = data::mg.macro_xs_[p->material_];
// Do same for nucxs, point it to the microscopic nuclide data of interest
// Find the temperature and angle indices of interest
macro_xs.set_angle_index(p_u);
if (i_nuclide >= 0) {
// And since we haven't calculated this temperature index yet, do so now
data::mg.nuclides_[i_nuclide].set_temperature_index(p->sqrtkT_);
data::mg.nuclides_[i_nuclide].set_angle_index(p_u);
nuc_xs.set_temperature_index(p->sqrtkT_);
nuc_xs.set_angle_index(p_u);
}
for (auto i = 0; i < tally.scores_.size(); ++i) {
@ -1426,14 +1426,12 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
}
//TODO: should flux be multiplied in above instead of below?
if (i_nuclide >= 0) {
score *= flux * atom_density
* get_nuclide_xs(i_nuclide, MG_GET_XS_TOTAL, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_TOTAL, p_g);
score *= flux * atom_density * nuc_xs.get_xs(MG_GET_XS_TOTAL, p_g)
/ macro_xs.get_xs(MG_GET_XS_TOTAL, p_g);
}
} else {
if (i_nuclide >= 0) {
score = get_nuclide_xs(i_nuclide, MG_GET_XS_TOTAL, p_g)
* atom_density * flux;
score = atom_density * flux * nuc_xs.get_xs(MG_GET_XS_TOTAL, p_g);
} else {
score = p->macro_xs_.total * flux;
}
@ -1455,21 +1453,17 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
score = p->wgt_last_;
}
if (i_nuclide >= 0) {
score *= flux
* get_nuclide_xs(i_nuclide, MG_GET_XS_INVERSE_VELOCITY, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_TOTAL, p_g);
score *= flux * nuc_xs.get_xs(MG_GET_XS_INVERSE_VELOCITY, p_g)
/ macro_xs.get_xs(MG_GET_XS_TOTAL, p_g);
} else {
score *= flux
* get_macro_xs(p->material_, MG_GET_XS_INVERSE_VELOCITY, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_TOTAL, p_g);
score *= flux * macro_xs.get_xs(MG_GET_XS_INVERSE_VELOCITY, p_g)
/ macro_xs.get_xs(MG_GET_XS_TOTAL, p_g);
}
} else {
if (i_nuclide >= 0) {
score = flux
* get_nuclide_xs(i_nuclide, MG_GET_XS_INVERSE_VELOCITY, p_g);
score = flux * nuc_xs.get_xs(MG_GET_XS_INVERSE_VELOCITY, p_g);
} else {
score = flux
* get_macro_xs(p->material_, MG_GET_XS_INVERSE_VELOCITY, p_g);
score = flux * macro_xs.get_xs(MG_GET_XS_INVERSE_VELOCITY, p_g);
}
}
break;
@ -1483,19 +1477,18 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
// weight entering the collision as the estimator for the reaction rate
score = p->wgt_last_ * flux;
if (i_nuclide >= 0) {
score *= atom_density
* get_nuclide_xs(i_nuclide, MG_GET_XS_SCATTER_FMU_MULT,
p->g_last_, &p->g_, &p->mu_, nullptr)
/ get_macro_xs(p->material_, MG_GET_XS_SCATTER_FMU_MULT,
p->g_last_, &p->g_, &p->mu_, nullptr);
score *= atom_density * nuc_xs.get_xs(
MG_GET_XS_SCATTER_FMU_MULT, p->g_last_, &p->g_, &p->mu_, nullptr)
/ macro_xs.get_xs(
MG_GET_XS_SCATTER_FMU_MULT, p->g_last_, &p->g_, &p->mu_, nullptr);
}
} else {
if (i_nuclide >= 0) {
score = atom_density * flux * get_nuclide_xs(
i_nuclide, MG_GET_XS_SCATTER_MULT, p_g, nullptr, &p->mu_, nullptr);
score = atom_density * flux * nuc_xs.get_xs(
MG_GET_XS_SCATTER_MULT, p_g, nullptr, &p->mu_, nullptr);
} else {
score = flux * get_macro_xs(
p->material_, MG_GET_XS_SCATTER_MULT, p_g, nullptr, &p->mu_, nullptr);
score = flux * macro_xs.get_xs(
MG_GET_XS_SCATTER_MULT, p_g, nullptr, &p->mu_, nullptr);
}
}
break;
@ -1514,17 +1507,16 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
// adjust the score by the actual probability for that nuclide.
if (i_nuclide >= 0) {
score *= atom_density
* get_nuclide_xs(i_nuclide, MG_GET_XS_SCATTER_FMU,
p->g_last_, &p->g_, &p->mu_, nullptr)
/ get_macro_xs(p->material_, MG_GET_XS_SCATTER_FMU,
p->g_last_, &p->g_, &p->mu_, nullptr);
* nuc_xs.get_xs(MG_GET_XS_SCATTER_FMU, p->g_last_, &p->g_,
&p->mu_, nullptr)
/ macro_xs.get_xs(MG_GET_XS_SCATTER_FMU, p->g_last_, &p->g_,
&p->mu_, nullptr);
}
} else {
if (i_nuclide >= 0) {
score = atom_density * flux * get_nuclide_xs(
i_nuclide, MG_GET_XS_SCATTER, p_g);
score = atom_density * flux * nuc_xs.get_xs(MG_GET_XS_SCATTER, p_g);
} else {
score = flux * get_macro_xs(p->material_, MG_GET_XS_SCATTER, p_g);
score = flux * macro_xs.get_xs(MG_GET_XS_SCATTER, p_g);
}
}
break;
@ -1544,14 +1536,13 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
score = p->wgt_last_ * flux;
}
if (i_nuclide >= 0) {
score *= atom_density
* get_nuclide_xs(i_nuclide, MG_GET_XS_ABSORPTION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
score *= atom_density * nuc_xs.get_xs(MG_GET_XS_ABSORPTION, p_g)
/ macro_xs.get_xs(MG_GET_XS_ABSORPTION, p_g);
}
} else {
if (i_nuclide >= 0) {
score = atom_density * flux
* get_nuclide_xs(i_nuclide, MG_GET_XS_ABSORPTION, p_g);
* nuc_xs.get_xs(MG_GET_XS_ABSORPTION, p_g);
} else {
score = p->macro_xs_.absorption * flux;
}
@ -1575,20 +1566,17 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
score = p->wgt_last_ * flux;
}
if (i_nuclide >= 0) {
score *= atom_density
* get_nuclide_xs(i_nuclide, MG_GET_XS_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
score *= atom_density * nuc_xs.get_xs(MG_GET_XS_FISSION, p_g)
/ macro_xs.get_xs(MG_GET_XS_ABSORPTION, p_g);
} else {
score *=
get_macro_xs(p->material_, MG_GET_XS_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
score *= macro_xs.get_xs(MG_GET_XS_FISSION, p_g)
/ macro_xs.get_xs(MG_GET_XS_ABSORPTION, p_g);
}
} else {
if (i_nuclide >= 0) {
score = get_nuclide_xs(i_nuclide, MG_GET_XS_FISSION, p_g)
* atom_density * flux;
score = atom_density * flux * nuc_xs.get_xs(MG_GET_XS_FISSION, p_g);
} else {
score = get_macro_xs(p->material_, MG_GET_XS_FISSION, p_g) * flux;
score = flux * macro_xs.get_xs(MG_GET_XS_FISSION, p_g);
}
}
break;
@ -1610,13 +1598,11 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
// nu-fission
score = p->wgt_absorb_ * flux;
if (i_nuclide >= 0) {
score *= atom_density
* get_nuclide_xs(i_nuclide, MG_GET_XS_NU_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
score *= atom_density * nuc_xs.get_xs(MG_GET_XS_NU_FISSION, p_g)
/ macro_xs.get_xs(MG_GET_XS_ABSORPTION, p_g);
} else {
score *=
get_macro_xs(p->material_, MG_GET_XS_NU_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
score *= macro_xs.get_xs(MG_GET_XS_NU_FISSION, p_g)
/ macro_xs.get_xs(MG_GET_XS_ABSORPTION, p_g);
}
} else {
// Skip any non-fission events
@ -1628,17 +1614,16 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
// score.
score = simulation::keff * p->wgt_bank_ * flux;
if (i_nuclide >= 0) {
score *= atom_density
* get_nuclide_xs(i_nuclide, MG_GET_XS_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_FISSION, p_g);
score *= atom_density * nuc_xs.get_xs(MG_GET_XS_FISSION, p_g)
/ macro_xs.get_xs(MG_GET_XS_FISSION, p_g);
}
}
} else {
if (i_nuclide >= 0) {
score = get_nuclide_xs(i_nuclide, MG_GET_XS_NU_FISSION, p_g)
* atom_density * flux;
score = atom_density * flux
* nuc_xs.get_xs(MG_GET_XS_NU_FISSION, p_g);
} else {
score = get_macro_xs(p->material_, MG_GET_XS_NU_FISSION, p_g) * flux;
score = flux * macro_xs.get_xs(MG_GET_XS_NU_FISSION, p_g);
}
}
break;
@ -1660,13 +1645,12 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
// prompt-nu-fission
score = p->wgt_absorb_ * flux;
if (i_nuclide >= 0) {
score *= atom_density
* get_nuclide_xs(i_nuclide, MG_GET_XS_PROMPT_NU_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
score *= atom_density *
nuc_xs.get_xs(MG_GET_XS_PROMPT_NU_FISSION, p_g)
/ macro_xs.get_xs(MG_GET_XS_ABSORPTION, p_g);
} else {
score *=
get_macro_xs(p->material_, MG_GET_XS_PROMPT_NU_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
score *= macro_xs.get_xs(MG_GET_XS_PROMPT_NU_FISSION, p_g)
/ macro_xs.get_xs(MG_GET_XS_ABSORPTION, p_g);
}
} else {
// Skip any non-fission events
@ -1681,18 +1665,16 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
auto prompt_frac = 1. - n_delayed / static_cast<double>(p->n_bank_);
score = simulation::keff * p->wgt_bank_ * prompt_frac * flux;
if (i_nuclide >= 0) {
score *= atom_density
* get_nuclide_xs(i_nuclide, MG_GET_XS_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_FISSION, p_g);
score *= atom_density * nuc_xs.get_xs(MG_GET_XS_FISSION, p_g)
/ macro_xs.get_xs(MG_GET_XS_FISSION, p_g);
}
}
} else {
if (i_nuclide >= 0) {
score = get_nuclide_xs(i_nuclide, MG_GET_XS_PROMPT_NU_FISSION, p_g)
* atom_density * flux;
score = atom_density * flux *
nuc_xs.get_xs(MG_GET_XS_PROMPT_NU_FISSION, p_g);
} else {
score = get_macro_xs(p->material_, MG_GET_XS_PROMPT_NU_FISSION, p_g)
* flux;
score = flux * macro_xs.get_xs(MG_GET_XS_PROMPT_NU_FISSION, p_g);
}
}
break;
@ -1712,7 +1694,8 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
// No fission events occur if survival biasing is on -- need to
// calculate fraction of absorptions that would have resulted in
// delayed-nu-fission
if (get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g) > 0) {
double abs_xs = macro_xs.get_xs(MG_GET_XS_ABSORPTION, p_g);
if (abs_xs > 0.) {
if (tally.delayedgroup_filter_ != C_NONE) {
auto i_dg_filt = tally.filters()[tally.delayedgroup_filter_];
const DelayedGroupFilter& filt
@ -1723,18 +1706,15 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
auto d = filt.groups()[d_bin] - 1;
score = p->wgt_absorb_ * flux;
if (i_nuclide >= 0) {
score *=
get_nuclide_xs(i_nuclide, MG_GET_XS_DELAYED_NU_FISSION,
p_g, nullptr, nullptr, &d)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
score *= nuc_xs.get_xs(MG_GET_XS_DELAYED_NU_FISSION, p_g,
nullptr, nullptr, &d)
/ abs_xs;
} else {
score *=
get_macro_xs(p->material_, MG_GET_XS_DELAYED_NU_FISSION,
p_g, nullptr, nullptr, &d)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
score *= macro_xs.get_xs(MG_GET_XS_DELAYED_NU_FISSION, p_g,
nullptr, nullptr, &d)
/ abs_xs;
}
score_fission_delayed_dg(i_tally, d_bin, score,
score_index);
score_fission_delayed_dg(i_tally, d_bin, score, score_index);
}
continue;
} else {
@ -1743,13 +1723,11 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
// delayed-nu-fission xs to the absorption xs
score = p->wgt_absorb_ * flux;
if (i_nuclide >= 0) {
score *=
get_nuclide_xs(i_nuclide, MG_GET_XS_DELAYED_NU_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
score *= nuc_xs.get_xs(MG_GET_XS_DELAYED_NU_FISSION, p_g)
/ abs_xs;
} else {
score *=
get_macro_xs(p->material_, MG_GET_XS_DELAYED_NU_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
score *= macro_xs.get_xs(MG_GET_XS_DELAYED_NU_FISSION, p_g)
/ abs_xs;
}
}
}
@ -1774,9 +1752,8 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
score = simulation::keff * p->wgt_bank_ / p->n_bank_
* p->n_delayed_bank_[d-1] * flux;
if (i_nuclide >= 0) {
score *= atom_density
* get_nuclide_xs(i_nuclide, MG_GET_XS_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_FISSION, p_g);
score *= atom_density * nuc_xs.get_xs(MG_GET_XS_FISSION, p_g)
/ macro_xs.get_xs(MG_GET_XS_FISSION, p_g);
}
score_fission_delayed_dg(i_tally, d_bin, score, score_index);
}
@ -1788,9 +1765,8 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
score = simulation::keff * p->wgt_bank_ / p->n_bank_ * n_delayed
* flux;
if (i_nuclide >= 0) {
score *= atom_density
* get_nuclide_xs(i_nuclide, MG_GET_XS_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_FISSION, p_g);
score *= atom_density * nuc_xs.get_xs(MG_GET_XS_FISSION, p_g)
/ macro_xs.get_xs(MG_GET_XS_FISSION, p_g);
}
}
}
@ -1804,24 +1780,21 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
for (auto d_bin = 0; d_bin < filt.n_bins(); ++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,
p_g, nullptr, nullptr, &d);
score = flux * atom_density * nuc_xs.get_xs(
MG_GET_XS_DELAYED_NU_FISSION, p_g, nullptr, nullptr, &d);
} else {
score = flux
* get_macro_xs(p->material_, MG_GET_XS_DELAYED_NU_FISSION,
p_g, nullptr, nullptr, &d);
score = flux * macro_xs.get_xs(
MG_GET_XS_DELAYED_NU_FISSION, p_g, nullptr, nullptr, &d);
}
score_fission_delayed_dg(i_tally, d_bin, score, score_index);
}
continue;
} else {
if (i_nuclide >= 0) {
score = flux * atom_density
* get_nuclide_xs(i_nuclide, MG_GET_XS_DELAYED_NU_FISSION, p_g);
score = flux * atom_density *
nuc_xs.get_xs(MG_GET_XS_DELAYED_NU_FISSION, p_g);
} else {
score = flux
* get_macro_xs(p->material_, MG_GET_XS_DELAYED_NU_FISSION, p_g);
score = flux * macro_xs.get_xs(MG_GET_XS_DELAYED_NU_FISSION, p_g);
}
}
}
@ -1834,7 +1807,8 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
// No fission events occur if survival biasing is on -- need to
// calculate fraction of absorptions that would have resulted in
// delayed-nu-fission
if (get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g) > 0) {
double abs_xs = macro_xs.get_xs(MG_GET_XS_ABSORPTION, p_g);
if (abs_xs > 0) {
if (tally.delayedgroup_filter_ != C_NONE) {
auto i_dg_filt = tally.filters()[tally.delayedgroup_filter_];
const DelayedGroupFilter& filt
@ -1845,22 +1819,17 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
auto d = filt.groups()[d_bin] - 1;
score = p->wgt_absorb_ * flux;
if (i_nuclide >= 0) {
score *=
get_nuclide_xs(i_nuclide, MG_GET_XS_DECAY_RATE,
p_g, nullptr, nullptr, &d)
* get_nuclide_xs(i_nuclide, MG_GET_XS_DELAYED_NU_FISSION,
p_g, nullptr, nullptr, &d)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
score *= nuc_xs.get_xs(MG_GET_XS_DECAY_RATE, p_g,
nullptr, nullptr, &d)
* nuc_xs.get_xs(MG_GET_XS_DELAYED_NU_FISSION, p_g,
nullptr, nullptr, &d) / abs_xs;
} else {
score *=
get_macro_xs(p->material_, MG_GET_XS_DECAY_RATE,
p_g, nullptr, nullptr, &d)
* get_macro_xs(p->material_, MG_GET_XS_DELAYED_NU_FISSION,
p_g, nullptr, nullptr, &d)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
score *= macro_xs.get_xs(MG_GET_XS_DECAY_RATE, p_g, nullptr,
nullptr, &d)
* macro_xs.get_xs(MG_GET_XS_DELAYED_NU_FISSION, p_g,
nullptr, nullptr, &d) / abs_xs;
}
score_fission_delayed_dg(i_tally, d_bin, score,
score_index);
score_fission_delayed_dg(i_tally, d_bin, score, score_index);
}
continue;
} else {
@ -1872,18 +1841,16 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
for (auto d = 0; d < data::mg.num_delayed_groups_; ++d) {
if (i_nuclide >= 0) {
score += p->wgt_absorb_ * flux
* get_nuclide_xs(i_nuclide, MG_GET_XS_DECAY_RATE,
p_g, nullptr, nullptr, &d)
* get_nuclide_xs(i_nuclide, MG_GET_XS_DELAYED_NU_FISSION,
p_g, nullptr, nullptr, &d)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
* nuc_xs.get_xs(MG_GET_XS_DECAY_RATE, p_g, nullptr,
nullptr, &d)
* nuc_xs.get_xs(MG_GET_XS_DELAYED_NU_FISSION, p_g,
nullptr, nullptr, &d) / abs_xs;
} else {
score += p->wgt_absorb_ * flux
* get_macro_xs(p->material_, MG_GET_XS_DECAY_RATE,
p_g, nullptr, nullptr, &d)
* get_macro_xs(p->material_, MG_GET_XS_DELAYED_NU_FISSION,
p_g, nullptr, nullptr, &d)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
* macro_xs.get_xs(MG_GET_XS_DECAY_RATE, p_g, nullptr,
nullptr, &d)
* macro_xs.get_xs(MG_GET_XS_DELAYED_NU_FISSION, p_g,
nullptr, nullptr, &d) / abs_xs;
}
}
}
@ -1902,18 +1869,16 @@ 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 - 1;
if (g != -1) {
auto d = bank.delayed_group - 1;
if (d != -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,
nullptr, nullptr, &g)
* get_nuclide_xs(i_nuclide, MG_GET_XS_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_FISSION, p_g);
* nuc_xs.get_xs(MG_GET_XS_DECAY_RATE, p_g, nullptr, nullptr, &d)
* nuc_xs.get_xs(MG_GET_XS_FISSION, p_g)
/ macro_xs.get_xs(MG_GET_XS_FISSION, p_g);
} else {
score += simulation::keff * bank.wgt * flux
* get_macro_xs(p->material_, MG_GET_XS_DECAY_RATE, p_g,
nullptr, nullptr, &g);
* macro_xs.get_xs(MG_GET_XS_DECAY_RATE, p_g, nullptr, nullptr, &d);
}
if (tally.delayedgroup_filter_ != C_NONE) {
auto i_dg_filt = tally.filters()[tally.delayedgroup_filter_];
@ -1922,10 +1887,10 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
model::tally_filters[i_dg_filt].get())};
// 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 + 1)
auto dg = filt.groups()[d_bin];
if (dg == d + 1)
score_fission_delayed_dg(i_tally, d_bin, score,
score_index);
score_index);
}
score = 0.;
}
@ -1944,16 +1909,16 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
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,
p_g, nullptr, nullptr, &d)
* get_nuclide_xs(i_nuclide, MG_GET_XS_DELAYED_NU_FISSION,
p_g, nullptr, nullptr, &d);
* nuc_xs.get_xs(MG_GET_XS_DECAY_RATE, p_g, nullptr,
nullptr, &d)
* nuc_xs.get_xs(MG_GET_XS_DELAYED_NU_FISSION, p_g, nullptr,
nullptr, &d);
} else {
score += flux
* get_macro_xs(p->material_, MG_GET_XS_DECAY_RATE,
p_g, nullptr, nullptr, &d)
* get_macro_xs(p->material_, MG_GET_XS_DELAYED_NU_FISSION,
p_g, nullptr, nullptr, &d);
* macro_xs.get_xs(MG_GET_XS_DECAY_RATE, p_g, nullptr,
nullptr, &d)
* macro_xs.get_xs(MG_GET_XS_DELAYED_NU_FISSION, p_g, nullptr,
nullptr, &d);
}
score_fission_delayed_dg(i_tally, d_bin, score, score_index);
}
@ -1963,16 +1928,12 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
for (auto d = 0; d < data::mg.num_delayed_groups_; ++d) {
if (i_nuclide >= 0) {
score += atom_density * flux
* get_nuclide_xs(i_nuclide, MG_GET_XS_DECAY_RATE,
p_g, nullptr, nullptr, &d)
* get_nuclide_xs(i_nuclide, MG_GET_XS_DELAYED_NU_FISSION,
p_g, nullptr, nullptr, &d);
* nuc_xs.get_xs(MG_GET_XS_DECAY_RATE, p_g, nullptr, nullptr, &d)
* nuc_xs.get_xs(MG_GET_XS_DELAYED_NU_FISSION, p_g, nullptr, nullptr, &d);
} else {
score += flux
* get_macro_xs(p->material_, MG_GET_XS_DECAY_RATE,
p_g, nullptr, nullptr, &d)
* get_macro_xs(p->material_, MG_GET_XS_DELAYED_NU_FISSION,
p_g, nullptr, nullptr, &d);
* macro_xs.get_xs(MG_GET_XS_DECAY_RATE, p_g, nullptr, nullptr, &d)
* macro_xs.get_xs(MG_GET_XS_DELAYED_NU_FISSION, p_g, nullptr, nullptr, &d);
}
}
}
@ -1997,25 +1958,22 @@ score_general_mg(const Particle* p, int i_tally, int start_index,
}
if (i_nuclide >= 0) {
score *= atom_density
* get_nuclide_xs(i_nuclide, MG_GET_XS_KAPPA_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
* nuc_xs.get_xs(MG_GET_XS_KAPPA_FISSION, p_g)
/ macro_xs.get_xs(MG_GET_XS_ABSORPTION, p_g);
} else {
score *=
get_macro_xs(p->material_, MG_GET_XS_KAPPA_FISSION, p_g)
/ get_macro_xs(p->material_, MG_GET_XS_ABSORPTION, p_g);
macro_xs.get_xs(MG_GET_XS_KAPPA_FISSION, p_g)
/ macro_xs.get_xs(MG_GET_XS_ABSORPTION, p_g);
}
} else {
if (i_nuclide >= 0) {
score = get_nuclide_xs(i_nuclide, MG_GET_XS_KAPPA_FISSION, p_g)
* atom_density * flux;
score = atom_density * flux * nuc_xs.get_xs(MG_GET_XS_KAPPA_FISSION, p_g);
} else {
score = get_macro_xs(p->material_, MG_GET_XS_KAPPA_FISSION, p_g)
* flux;
score = flux * macro_xs.get_xs(MG_GET_XS_KAPPA_FISSION, p_g);
}
}
break;
case SCORE_EVENTS:
// Simply count the number of scoring events
score = 1.;

View file

@ -0,0 +1,251 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="1" material="1" name="Fuel" region="-1" universe="0" />
<cell id="2" material="2" name="Cladding" region="1 -2" universe="0" />
<cell id="3" material="3" name="Water" region="2 3 -4 5 -6" universe="0" />
<surface coeffs="0 0 0.39218" id="1" name="Fuel OR" type="z-cylinder" />
<surface coeffs="0 0 0.4572" id="2" name="Clad OR" type="z-cylinder" />
<surface boundary="reflective" coeffs="-0.63" id="3" name="left" type="x-plane" />
<surface boundary="reflective" coeffs="0.63" id="4" name="right" type="x-plane" />
<surface boundary="reflective" coeffs="-0.63" id="5" name="bottom" type="y-plane" />
<surface boundary="reflective" coeffs="0.63" id="6" name="top" type="y-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<material depletable="true" id="1" name="UO2 (2.4%)">
<density units="g/cm3" value="10.29769" />
<nuclide ao="4.4843e-06" name="U234" />
<nuclide ao="0.00055815" name="U235" />
<nuclide ao="0.022408" name="U238" />
<nuclide ao="0.045829" name="O16" />
</material>
<material id="2" name="Zircaloy">
<density units="g/cm3" value="6.55" />
<nuclide ao="0.021827" name="Zr90" />
<nuclide ao="0.00476" name="Zr91" />
<nuclide ao="0.0072758" name="Zr92" />
<nuclide ao="0.0073734" name="Zr94" />
<nuclide ao="0.0011879" name="Zr96" />
</material>
<material id="3" name="Hot borated water">
<density units="g/cm3" value="0.740582" />
<nuclide ao="0.049457" name="H1" />
<nuclide ao="0.024672" name="O16" />
<nuclide ao="8.0042e-06" name="B10" />
<nuclide ao="3.2218e-05" name="B11" />
<sab name="c_H_in_H2O" />
</material>
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="fission">
<parameters>-0.63 -0.63 -1 0.63 0.63 1</parameters>
</space>
</source>
</settings>
<?xml version='1.0' encoding='utf-8'?>
<tallies>
<filter id="1" type="material">
<bins>1</bins>
</filter>
<filter id="2" type="energy">
<bins>0.0 0.625 20000000.0</bins>
</filter>
<filter id="7" type="energyout">
<bins>0.0 0.625 20000000.0</bins>
</filter>
<filter id="11" type="legendre">
<order>3</order>
</filter>
<filter id="15" type="material">
<bins>2</bins>
</filter>
<filter id="29" type="material">
<bins>3</bins>
</filter>
<tally id="1">
<filters>1 2</filters>
<nuclides>total</nuclides>
<scores>flux</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="2">
<filters>1 2</filters>
<nuclides>U234 U235 U238 O16</nuclides>
<scores>total</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="3">
<filters>1 2</filters>
<nuclides>total</nuclides>
<scores>flux</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="4">
<filters>1 2</filters>
<nuclides>U234 U235 U238 O16</nuclides>
<scores>absorption</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="5">
<filters>1 2</filters>
<nuclides>total</nuclides>
<scores>flux</scores>
<estimator>analog</estimator>
</tally>
<tally id="6">
<filters>1 2 7</filters>
<nuclides>U234 U235 U238 O16</nuclides>
<scores>nu-fission</scores>
<estimator>analog</estimator>
</tally>
<tally id="7">
<filters>1 2</filters>
<nuclides>total</nuclides>
<scores>flux</scores>
<estimator>analog</estimator>
</tally>
<tally id="8">
<filters>1 2 7 11</filters>
<nuclides>U234 U235 U238 O16</nuclides>
<scores>nu-scatter</scores>
<estimator>analog</estimator>
</tally>
<tally id="9">
<filters>1 2 7</filters>
<nuclides>U234 U235 U238 O16</nuclides>
<scores>nu-scatter</scores>
<estimator>analog</estimator>
</tally>
<tally id="10">
<filters>1 2 7</filters>
<nuclides>U234 U235 U238 O16</nuclides>
<scores>scatter</scores>
<estimator>analog</estimator>
</tally>
<tally id="11">
<filters>15 2</filters>
<nuclides>total</nuclides>
<scores>flux</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="12">
<filters>15 2</filters>
<nuclides>Zr90 Zr91 Zr92 Zr94 Zr96</nuclides>
<scores>total</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="13">
<filters>15 2</filters>
<nuclides>total</nuclides>
<scores>flux</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="14">
<filters>15 2</filters>
<nuclides>Zr90 Zr91 Zr92 Zr94 Zr96</nuclides>
<scores>absorption</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="15">
<filters>15 2</filters>
<nuclides>total</nuclides>
<scores>flux</scores>
<estimator>analog</estimator>
</tally>
<tally id="16">
<filters>15 2 7</filters>
<nuclides>Zr90 Zr91 Zr92 Zr94 Zr96</nuclides>
<scores>nu-fission</scores>
<estimator>analog</estimator>
</tally>
<tally id="17">
<filters>15 2</filters>
<nuclides>total</nuclides>
<scores>flux</scores>
<estimator>analog</estimator>
</tally>
<tally id="18">
<filters>15 2 7 11</filters>
<nuclides>Zr90 Zr91 Zr92 Zr94 Zr96</nuclides>
<scores>nu-scatter</scores>
<estimator>analog</estimator>
</tally>
<tally id="19">
<filters>15 2 7</filters>
<nuclides>Zr90 Zr91 Zr92 Zr94 Zr96</nuclides>
<scores>nu-scatter</scores>
<estimator>analog</estimator>
</tally>
<tally id="20">
<filters>15 2 7</filters>
<nuclides>Zr90 Zr91 Zr92 Zr94 Zr96</nuclides>
<scores>scatter</scores>
<estimator>analog</estimator>
</tally>
<tally id="21">
<filters>29 2</filters>
<nuclides>total</nuclides>
<scores>flux</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="22">
<filters>29 2</filters>
<nuclides>H1 O16 B10 B11</nuclides>
<scores>total</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="23">
<filters>29 2</filters>
<nuclides>total</nuclides>
<scores>flux</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="24">
<filters>29 2</filters>
<nuclides>H1 O16 B10 B11</nuclides>
<scores>absorption</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="25">
<filters>29 2</filters>
<nuclides>total</nuclides>
<scores>flux</scores>
<estimator>analog</estimator>
</tally>
<tally id="26">
<filters>29 2 7</filters>
<nuclides>H1 O16 B10 B11</nuclides>
<scores>nu-fission</scores>
<estimator>analog</estimator>
</tally>
<tally id="27">
<filters>29 2</filters>
<nuclides>total</nuclides>
<scores>flux</scores>
<estimator>analog</estimator>
</tally>
<tally id="28">
<filters>29 2 7 11</filters>
<nuclides>H1 O16 B10 B11</nuclides>
<scores>nu-scatter</scores>
<estimator>analog</estimator>
</tally>
<tally id="29">
<filters>29 2 7</filters>
<nuclides>H1 O16 B10 B11</nuclides>
<scores>nu-scatter</scores>
<estimator>analog</estimator>
</tally>
<tally id="30">
<filters>29 2 7</filters>
<nuclides>H1 O16 B10 B11</nuclides>
<scores>scatter</scores>
<estimator>analog</estimator>
</tally>
</tallies>

View file

@ -0,0 +1,2 @@
k-combined:
5.350442E-01 1.484490E-02

View file

@ -0,0 +1,85 @@
import os
import openmc
import openmc.mgxs
from openmc.examples import pwr_pin_cell
from tests.testing_harness import PyAPITestHarness
from tests.regression_tests import config
class MGXSTestHarness(PyAPITestHarness):
def __init__(self, *args, **kwargs):
# Generate inputs using parent class routine
super().__init__(*args, **kwargs)
# Initialize a two-group structure
energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625, 20.e6])
# Initialize MGXS Library for a few cross section types
self.mgxs_lib = openmc.mgxs.Library(self._model.geometry)
self.mgxs_lib.by_nuclide = True
self.mgxs_lib.mgxs_types = ['total', 'absorption', 'nu-fission matrix',
'nu-scatter matrix', 'multiplicity matrix']
self.mgxs_lib.energy_groups = energy_groups
self.mgxs_lib.correction = None
self.mgxs_lib.legendre_order = 3
self.mgxs_lib.domain_type = 'material'
self.mgxs_lib.build_library()
# Initialize a tallies file
self.mgxs_lib.add_to_tallies_file(self._model.tallies, merge=False)
def _run_openmc(self):
# Initial run
if config['mpi']:
mpi_args = [config['mpiexec'], '-n', config['mpi_np']]
openmc.run(openmc_exec=config['exe'], mpi_args=mpi_args)
else:
openmc.run(openmc_exec=config['exe'])
# Build MG Inputs
# Get data needed to execute Library calculations.
sp = openmc.StatePoint(self._sp_name)
self.mgxs_lib.load_from_statepoint(sp)
self._model.mgxs_file, self._model.materials, \
self._model.geometry = self.mgxs_lib.create_mg_mode()
# Modify materials and settings so we can run in MG mode
self._model.materials.cross_sections = './mgxs.h5'
self._model.settings.energy_mode = 'multi-group'
# Write modified input files
self._model.settings.export_to_xml()
self._model.geometry.export_to_xml()
self._model.materials.export_to_xml()
self._model.mgxs_file.export_to_hdf5()
# Dont need tallies.xml, so remove the file
if os.path.exists('tallies.xml'):
os.remove('tallies.xml')
# Enforce closing statepoint and summary files so HDF5
# does not throw an error during the next OpenMC execution
sp._f.close()
sp._summary._f.close()
# Re-run MG mode.
if config['mpi']:
mpi_args = [config['mpiexec'], '-n', config['mpi_np']]
openmc.run(openmc_exec=config['exe'], mpi_args=mpi_args)
else:
openmc.run(openmc_exec=config['exe'])
def _cleanup(self):
super()._cleanup()
f = 'mgxs.h5'
if os.path.exists(f):
os.remove(f)
def test_mgxs_library_ce_to_mg():
# Set the input set to use the pincell model
model = pwr_pin_cell()
harness = MGXSTestHarness('statepoint.10.h5', model)
harness.main()