52 num_groups_ = num_groups;
53 sigma_t_.resize(num_groups, sigma_t);
54 sigma_a_.resize(num_groups, sigma_t);
56 ComputeDiffusionParameters();
67MakeSimple1(
unsigned int num_groups,
double sigma_t,
double c)
71 num_groups_ = num_groups;
72 sigma_t_.resize(num_groups, sigma_t);
73 transfer_matrices_.emplace_back(num_groups, num_groups);
79 auto& S = transfer_matrices_.back();
80 double scale = (num_groups_ == 1) ? 1.0 : 0.5;
81 S.SetDiagonal(std::vector<double>(num_groups, sigma_t * c * scale));
94 for (
unsigned int g = 0; g < num_groups_; ++g)
98 S.Insert(g, g - 1, sigma_t * c * 0.5);
101 if (g > num_groups_ / 2)
103 if (g < num_groups_ - 1)
105 S.Insert(g, g - 1, sigma_t * c * 0.25);
106 S.Insert(g, g + 1, sigma_t * c * 0.25);
109 S.Insert(g, g - 1, sigma_t * c * 0.5);
114 ComputeDiffusionParameters();
121MakeCombined(std::vector<std::pair<int, double> > &combinations)
126 std::vector<std::shared_ptr<MultiGroupXS>> xsecs;
127 xsecs.reserve(combinations.size());
129 unsigned int n_grps = 0;
130 unsigned int n_precs = 0;
131 double Nf_total = 0.0;
134 for (
auto combo : combinations)
137 std::shared_ptr<MultiGroupXS> xs;
140 std::string(__FUNCTION__));
144 if (xs->IsFissionable())
146 is_fissionable_ =
true;
147 Nf_total += combo.second;
151 if (xsecs.size() == 1)
152 n_grps = xs->NumGroups();
153 else if (xs->NumGroups() != n_grps)
154 throw std::logic_error(
155 "Incompatible cross sections encountered.\n"
156 "All cross sections being combined must have the "
157 "same number of energy groups.");
160 n_precs += xs->NumPrecursors();
166 if (Nf_total < 1.0e-12)
167 is_fissionable_ =
false;
172 for (
const auto& xs : xsecs)
173 if (xs->IsFissionable() and xs->NumPrecursors() == 0)
174 throw std::logic_error(
175 "Incompatible cross sections encountered.\n"
176 "If any fissionable cross sections specify delayed neutron "
177 "data, all fissionable cross sections must specify delayed "
184 num_groups_ = n_grps;
185 num_precursors_ = n_precs;
186 scattering_order_ = 0;
187 for (
const auto& xs : xsecs)
188 scattering_order_ = std::max(scattering_order_,
189 xs->ScatteringOrder());
192 sigma_t_.assign(n_grps, 0.0);
193 sigma_a_.assign(n_grps, 0.0);
197 if (std::any_of(xsecs.begin(), xsecs.end(),
199 { return not x->TransferMatrices().empty(); }))
200 transfer_matrices_.assign(scattering_order_ + 1,
206 sigma_f_.assign(n_grps, 0.0);
207 nu_sigma_f_.assign(n_grps, 0.0);
208 production_matrix_.assign(
209 num_groups_, std::vector<double>(num_groups_, 0.0));
214 nu_prompt_sigma_f_.assign(n_grps, 0.0);
215 nu_delayed_sigma_f_.assign(n_grps, 0.0);
216 precursors_.resize(n_precs);
224 unsigned int precursor_count = 0;
225 for (
size_t x = 0; x < xsecs.size(); ++x)
228 double N_i = combinations[x].second;
232 if (xsecs[x]->IsFissionable())
233 ff_i = N_i / Nf_total;
239 const auto& sig_t = xsecs[x]->SigmaTotal();
240 const auto& sig_a = xsecs[x]->SigmaAbsorption();
241 const auto& sig_f = xsecs[x]->SigmaFission();
242 const auto& nu_p_sig_f = xsecs[x]->NuPromptSigmaF();
243 const auto& nu_d_sig_f = xsecs[x]->NuDelayedSigmaF();
244 const auto& F = xsecs[x]->ProductionMatrix();
248 for (
unsigned int g = 0; g < n_grps; ++g)
250 sigma_t_[g] += sig_t[g] * N_i;
251 sigma_a_[g] += sig_a[g] * N_i;
253 if (xsecs[x]->IsFissionable())
255 sigma_f_[g] += sig_f[g] * N_i;
256 nu_sigma_f_[g] += sig_f[g] * N_i;
257 for (
unsigned int gp = 0; gp < num_groups_; ++gp)
258 production_matrix_[g][gp] += F[g][gp] * N_i;
262 nu_prompt_sigma_f_[g] += nu_p_sig_f[g] * N_i;
263 nu_delayed_sigma_f_[g] += nu_d_sig_f[g] * N_i;
281 if (xsecs[x]->NumPrecursors() > 0)
283 const auto& precursors = xsecs[x]->Precursors();
284 for (
unsigned int j = 0; j < xsecs[x]->NumPrecursors(); ++j)
286 unsigned int count = precursor_count + j;
287 const auto& precursor = precursors[j];
288 precursors_[count].decay_constant = precursor.decay_constant;
289 precursors_[count].fractional_yield = precursor.fractional_yield * ff_i;
290 precursors_[count].emission_spectrum = precursor.emission_spectrum;
293 precursor_count += xsecs[x]->NumPrecursors();
300 if (x == 0 && !xsecs[x]->InverseVelocity().empty())
301 inv_velocity_ = xsecs[x]->InverseVelocity();
302 else if (xsecs[x]->InverseVelocity() != inv_velocity_)
303 throw std::logic_error(
304 "Invalid cross sections encountered.\n"
305 "All cross sections being combined must share a group "
306 "structure. This implies that the inverse speeds for "
307 "each of the cross sections must be equivalent.");
318 if (not xsecs[x]->TransferMatrices().empty())
320 for (
unsigned int m = 0; m < xsecs[x]->ScatteringOrder() + 1; ++m)
322 auto& Sm = transfer_matrices_[m];
323 const auto& Sm_other = xsecs[x]->TransferMatrix(m);
324 for (
unsigned int g = 0; g < num_groups_; ++g)
326 const auto& cols = Sm_other.rowI_indices_[g];
327 const auto& vals = Sm_other.rowI_values_[g];
328 for (
size_t t = 0; t < cols.size(); ++t)
329 Sm.InsertAdd(g, t, vals[t] * N_i);
335 ComputeDiffusionParameters();
static std::vector< chi_physics::MultiGroupXSPtr > multigroup_xs_stack
static std::shared_ptr< T > & GetStackItemPtr(std::vector< std::shared_ptr< T > > &stack, const size_t handle, const std::string &calling_function_name="Unknown")
std::vector< double > diffusion_coeff_
Transport corrected diffusion coeff.
unsigned int scattering_order_
Legendre scattering order.
std::vector< double > sigma_f_
Fission cross section.
std::vector< double > sigma_removal_
Removal cross section.
std::vector< std::vector< double > > production_matrix_
std::vector< double > nu_prompt_sigma_f_
unsigned int num_groups_
Total number of groups.
unsigned int num_precursors_
Number of precursors.
std::vector< double > sigma_t_
Total cross section.
std::vector< std::vector< AnglePairs > > scat_angles_gprime_g_
std::vector< chi_math::SparseMatrix > transfer_matrices_
std::vector< double > inv_velocity_
std::vector< double > sigma_s_gtog_
Within-group scattering xs.
std::vector< std::vector< double > > cdf_gprime_g_
void MakeCombined(std::vector< std::pair< int, double > > &combinations)
std::vector< Precursor > precursors_
void MakeSimple0(unsigned int num_groups, double sigma_t)
std::vector< double > nu_sigma_f_
bool scattering_initialized_
std::vector< double > nu_delayed_sigma_f_
void MakeSimple1(unsigned int num_groups, double sigma_t, double c)
std::vector< double > sigma_a_
Absorption cross section.
bool diffusion_initialized_
std::shared_ptr< MultiGroupXS > MultiGroupXSPtr
std::shared_ptr< chi_physics::MultiGroupXS > XSPtr