Skip to content

Commit ea49853

Browse files
committed
Add chi to MGXS machinery
1 parent 51ea89c commit ea49853

File tree

5 files changed

+83
-10
lines changed

5 files changed

+83
-10
lines changed

include/openmc/constants.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ enum class MgxsType {
285285
PROMPT_NU_FISSION,
286286
DELAYED_NU_FISSION,
287287
NU_FISSION,
288+
CHI,
288289
CHI_PROMPT,
289290
CHI_DELAYED
290291
};

include/openmc/xsdata.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ class XsData {
8383
// delayed_nu_fission has the following dimensions:
8484
// [angle][delayed group][incoming group]
8585
xt::xtensor<double, 3> delayed_nu_fission;
86+
// chi has the following dimensions:
87+
// [angle][incoming group][outgoing group]
88+
xt::xtensor<double, 3> chi;
8689
// chi_prompt has the following dimensions:
8790
// [angle][incoming group][outgoing group]
8891
xt::xtensor<double, 3> chi_prompt;

src/mgxs.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,31 +434,39 @@ double Mgxs::get_xs(MgxsType xstype, int gin, const int* gout, const double* mu,
434434
{
435435
XsData* xs_t = &xs[t];
436436
double val;
437+
std::string mgxs_type;
437438
switch (xstype) {
438439
case MgxsType::TOTAL:
439440
val = xs_t->total(a, gin);
441+
mgxs_type = "total";
440442
break;
441443
case MgxsType::NU_FISSION:
442444
val = fissionable ? xs_t->nu_fission(a, gin) : 0.;
445+
mgxs_type = "nu-fission";
443446
break;
444447
case MgxsType::ABSORPTION:
445448
val = xs_t->absorption(a, gin);
449+
mgxs_type = "absorption";
446450
;
447451
break;
448452
case MgxsType::FISSION:
449453
val = fissionable ? xs_t->fission(a, gin) : 0.;
454+
mgxs_type = "fission";
450455
break;
451456
case MgxsType::KAPPA_FISSION:
452457
val = fissionable ? xs_t->kappa_fission(a, gin) : 0.;
458+
mgxs_type = "kappa-fission";
453459
break;
454460
case MgxsType::NU_SCATTER:
455461
case MgxsType::SCATTER:
456462
case MgxsType::NU_SCATTER_FMU:
457463
case MgxsType::SCATTER_FMU:
458464
val = xs_t->scatter[a]->get_xs(xstype, gin, gout, mu);
465+
mgxs_type = "scatter_data";
459466
break;
460467
case MgxsType::PROMPT_NU_FISSION:
461468
val = fissionable ? xs_t->prompt_nu_fission(a, gin) : 0.;
469+
mgxs_type = "prompt-nu-fission";
462470
break;
463471
case MgxsType::DELAYED_NU_FISSION:
464472
if (fissionable) {
@@ -473,6 +481,23 @@ double Mgxs::get_xs(MgxsType xstype, int gin, const int* gout, const double* mu,
473481
} else {
474482
val = 0.;
475483
}
484+
mgxs_type = "delayed-nu-fission";
485+
break;
486+
case MgxsType::CHI:
487+
if (fissionable) {
488+
if (gout != nullptr) {
489+
val = xs_t->chi(a, gin, *gout);
490+
} else {
491+
// provide an outgoing group-wise sum
492+
val = 0.;
493+
for (int g = 0; g < xs_t->chi.shape()[2]; g++) {
494+
val += xs_t->chi(a, gin, g);
495+
}
496+
}
497+
} else {
498+
val = 0.;
499+
}
500+
mgxs_type = "chi";
476501
break;
477502
case MgxsType::CHI_PROMPT:
478503
if (fissionable) {
@@ -488,6 +513,7 @@ double Mgxs::get_xs(MgxsType xstype, int gin, const int* gout, const double* mu,
488513
} else {
489514
val = 0.;
490515
}
516+
mgxs_type = "chi-prompt";
491517
break;
492518
case MgxsType::CHI_DELAYED:
493519
if (fissionable) {
@@ -515,20 +541,32 @@ double Mgxs::get_xs(MgxsType xstype, int gin, const int* gout, const double* mu,
515541
} else {
516542
val = 0.;
517543
}
544+
mgxs_type = "chi-delayed";
518545
break;
519546
case MgxsType::INVERSE_VELOCITY:
520547
val = xs_t->inverse_velocity(a, gin);
548+
mgxs_type = "inverse-velocity";
521549
break;
522550
case MgxsType::DECAY_RATE:
523551
if (dg != nullptr) {
524552
val = xs_t->decay_rate(a, *dg);
525553
} else {
526554
val = xs_t->decay_rate(a, 0);
527555
}
556+
mgxs_type = "decay-rate";
528557
break;
529558
default:
530559
val = 0.;
531560
}
561+
// TODO: need to add more robust handling of zero-values cross sections that
562+
// produce NANs on normalization
563+
if (val != val) {
564+
warning(
565+
fmt::format("The {} cross section for this material has a nan present "
566+
"(possibly due to a division by zero). Setting to zero...",
567+
mgxs_type));
568+
val = 0;
569+
}
532570
return val;
533571
}
534572

src/random_ray/flat_source_domain.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,8 +1156,7 @@ void FlatSourceDomain::flatten_xs()
11561156
m.get_xs(MgxsType::FISSION, g_out, NULL, NULL, NULL, t, a);
11571157
sigma_f_.push_back(sigma_f);
11581158

1159-
double chi =
1160-
m.get_xs(MgxsType::CHI_PROMPT, g_out, &g_out, NULL, NULL, t, a);
1159+
double chi = m.get_xs(MgxsType::CHI, g_out, &g_out, NULL, NULL, t, a);
11611160
if (!std::isfinite(chi)) {
11621161
// MGXS interface may return NaN in some cases, such as when material
11631162
// is fissionable but has very small sigma_f.

src/xsdata.cpp

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ XsData::XsData(bool fissionable, AngleDistributionType scatter_format,
5656
// allocate delayed_nu_fission; [temperature][angle][delay group][in group]
5757
delayed_nu_fission = xt::zeros<double>(shape);
5858

59-
// chi_prompt; [temperature][angle][in group][out group]
59+
// chi and chi_prompt; [temperature][angle][in group][out group]
6060
shape = {n_ang, n_g_, n_g_};
61+
chi = xt::zeros<double>(shape);
6162
chi_prompt = xt::zeros<double>(shape);
6263

6364
// chi_delayed; [temperature][angle][delay group][in group][out group]
@@ -133,8 +134,13 @@ void XsData::fission_vector_beta_from_hdf5(
133134
// Normalize chi by summing over the outgoing groups for each incoming angle
134135
temp_chi /= xt::view(xt::sum(temp_chi, {1}), xt::all(), xt::newaxis());
135136

137+
// Store chi in chi
138+
chi = xt::view(temp_chi, xt::all(), xt::newaxis(), xt::all());
139+
136140
// Now every incoming group in prompt_chi and delayed_chi is the normalized
137141
// chi we just made
142+
// TODO: This is incorrect. This makes chi_prompt and chi_delayed identical
143+
// to chi.
138144
chi_prompt = xt::view(temp_chi, xt::all(), xt::newaxis(), xt::all());
139145
chi_delayed =
140146
xt::view(temp_chi, xt::all(), xt::newaxis(), xt::newaxis(), xt::all());
@@ -176,20 +182,31 @@ void XsData::fission_vector_beta_from_hdf5(
176182

177183
void XsData::fission_vector_no_beta_from_hdf5(hid_t xsdata_grp, size_t n_ang)
178184
{
179-
// Data is provided separately as prompt + delayed nu-fission and chi
185+
// If chi is included in the dataset, we should store it!
186+
if (object_exists(xsdata_grp, "chi")) {
187+
xt::xtensor<double, 2> temp_chi({n_ang, n_g_}, 0.);
188+
read_nd_vector(xsdata_grp, "chi", temp_chi, true);
189+
// Normalize chi by summing over the outgoing groups for each incoming angle
190+
temp_chi /= xt::view(xt::sum(temp_chi, {1}), xt::all(), xt::newaxis());
191+
// Now every incoming group in self.chi is the normalized chi we just made
192+
chi = xt::view(temp_chi, xt::all(), xt::newaxis(), xt::all());
193+
}
180194

195+
// Data is provided separately as prompt + delayed nu-fission and chi
181196
// Get chi-prompt
182197
xt::xtensor<double, 2> temp_chi_p({n_ang, n_g_}, 0.);
183198
read_nd_vector(xsdata_grp, "chi-prompt", temp_chi_p, true);
184199

185-
// Normalize chi by summing over the outgoing groups for each incoming angle
200+
// Normalize chi-prompt by summing over the outgoing groups for each incoming
201+
// angle
186202
temp_chi_p /= xt::view(xt::sum(temp_chi_p, {1}), xt::all(), xt::newaxis());
187203

188204
// Get chi-delayed
189205
xt::xtensor<double, 3> temp_chi_d({n_ang, n_dg_, n_g_}, 0.);
190206
read_nd_vector(xsdata_grp, "chi-delayed", temp_chi_d, true);
191207

192-
// Normalize chi by summing over the outgoing groups for each incoming angle
208+
// Normalize chi-delayed by summing over the outgoing groups for each incoming
209+
// angle
193210
temp_chi_d /=
194211
xt::view(xt::sum(temp_chi_d, {2}), xt::all(), xt::all(), xt::newaxis());
195212

@@ -217,6 +234,7 @@ void XsData::fission_vector_no_delayed_from_hdf5(hid_t xsdata_grp, size_t n_ang)
217234
temp_chi /= xt::view(xt::sum(temp_chi, {1}), xt::all(), xt::newaxis());
218235

219236
// Now every incoming group in self.chi is the normalized chi we just made
237+
chi = xt::view(temp_chi, xt::all(), xt::newaxis(), xt::all());
220238
chi_prompt = xt::view(temp_chi, xt::all(), xt::newaxis(), xt::all());
221239

222240
// Get nu-fission directly
@@ -268,6 +286,10 @@ void XsData::fission_matrix_beta_from_hdf5(
268286
xt::view(temp_beta, xt::all(), xt::all(), xt::newaxis(), xt::newaxis()) *
269287
xt::view(temp_matrix, xt::all(), xt::newaxis(), xt::all(), xt::all());
270288

289+
// Store chi
290+
chi =
291+
chi_prompt * (1. - temp_beta_sum) + xt::sum(temp_beta * chi_delayed, {1});
292+
271293
} else if (beta_ndims == ndim_target + 1) {
272294
xt::xtensor<double, 3> temp_beta({n_ang, n_dg_, n_g_}, 0.);
273295
read_nd_vector(xsdata_grp, "beta", temp_beta, true);
@@ -293,14 +315,20 @@ void XsData::fission_matrix_beta_from_hdf5(
293315
chi_delayed =
294316
xt::view(temp_beta, xt::all(), xt::all(), xt::all(), xt::newaxis()) *
295317
xt::view(temp_matrix, xt::all(), xt::newaxis(), xt::all(), xt::all());
318+
319+
// Store chi
320+
chi =
321+
chi_prompt * (1. - temp_beta_sum) + xt::sum(temp_beta * chi_delayed, {1});
296322
}
297323

298-
// Normalize both chis
324+
// Normalize chis
299325
chi_prompt /=
300326
xt::view(xt::sum(chi_prompt, {2}), xt::all(), xt::all(), xt::newaxis());
301327

302328
chi_delayed /= xt::view(
303329
xt::sum(chi_delayed, {3}), xt::all(), xt::all(), xt::all(), xt::newaxis());
330+
331+
chi /= xt::view(xt::sum(chi, {2}), xt::all(), xt::all(), xt::newaxis());
304332
}
305333

306334
void XsData::fission_matrix_no_beta_from_hdf5(hid_t xsdata_grp, size_t n_ang)
@@ -326,8 +354,8 @@ void XsData::fission_matrix_no_beta_from_hdf5(hid_t xsdata_grp, size_t n_ang)
326354
// delayed_nu_fission is the sum over outgoing groups
327355
delayed_nu_fission = xt::sum(temp_matrix_d, {3});
328356

329-
// chi_prompt is this matrix but normalized over outgoing groups, which we
330-
// have already stored in prompt_nu_fission
357+
// chi_delayee is this matrix but normalized over outgoing groups, which we
358+
// have already stored in delayed_nu_fission
331359
chi_delayed = temp_matrix_d / xt::view(delayed_nu_fission, xt::all(),
332360
xt::all(), xt::all(), xt::newaxis());
333361
}
@@ -346,6 +374,8 @@ void XsData::fission_matrix_no_delayed_from_hdf5(hid_t xsdata_grp, size_t n_ang)
346374

347375
// chi_prompt is this matrix but normalized over outgoing groups, which we
348376
// have already stored in prompt_nu_fission
377+
chi = temp_matrix /
378+
xt::view(prompt_nu_fission, xt::all(), xt::all(), xt::newaxis());
349379
chi_prompt = temp_matrix /
350380
xt::view(prompt_nu_fission, xt::all(), xt::all(), xt::newaxis());
351381
}
@@ -525,6 +555,7 @@ void XsData::combine(
525555
kappa_fission += scalar * that->kappa_fission;
526556
fission += scalar * that->fission;
527557
delayed_nu_fission += scalar * that->delayed_nu_fission;
558+
chi += scalar * that->chi;
528559
chi_prompt += scalar *
529560
xt::view(xt::sum(that->prompt_nu_fission, {1}), xt::all(),
530561
xt::newaxis(), xt::newaxis()) *
@@ -537,8 +568,9 @@ void XsData::combine(
537568
decay_rate += scalar * that->decay_rate;
538569
}
539570

540-
// Ensure the chi_prompt and chi_delayed are normalized to 1 for each
571+
// Ensure chi, chi_prompt and chi_delayed are normalized to 1 for each
541572
// azimuthal angle and delayed group (for chi_delayed)
573+
chi /= xt::view(xt::sum(chi, {2}), xt::all(), xt::all(), xt::newaxis());
542574
chi_prompt /=
543575
xt::view(xt::sum(chi_prompt, {2}), xt::all(), xt::all(), xt::newaxis());
544576
chi_delayed /= xt::view(

0 commit comments

Comments
 (0)