Skip to content

Commit 5bce5ad

Browse files
authored
Support cell densities in the random ray solver (#3720)
1 parent 7106958 commit 5bce5ad

File tree

12 files changed

+648
-30
lines changed

12 files changed

+648
-30
lines changed

include/openmc/material.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "openmc/memory.h" // for unique_ptr
1515
#include "openmc/ncrystal_interface.h"
1616
#include "openmc/particle.h"
17+
#include "openmc/settings.h"
1718
#include "openmc/vector.h"
1819

1920
namespace openmc {
@@ -110,9 +111,12 @@ class Material {
110111
//! \return Density in [atom/b-cm]
111112
double density() const { return density_; }
112113

113-
//! Get density in [g/cm^3]
114+
//! Get density in [g/cm^3].
114115
//! \return Density in [g/cm^3]
115-
double density_gpcc() const { return density_gpcc_; }
116+
double density_gpcc() const
117+
{
118+
return settings::run_CE ? density_gpcc_ : density();
119+
}
116120

117121
//! Get charge density in [e/b-cm]
118122
//! \return Charge density in [e/b-cm]

include/openmc/random_ray/source_region.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ class SourceRegionHandle {
146146

147147
// Scalar fields
148148
int* material_;
149+
double* density_mult_;
149150
int* is_small_;
150151
int* n_hits_;
151152
int* birthday_;
@@ -195,6 +196,9 @@ class SourceRegionHandle {
195196
int& material() { return *material_; }
196197
const int material() const { return *material_; }
197198

199+
double& density_mult() { return *density_mult_; }
200+
const double density_mult() const { return *density_mult_; }
201+
198202
int& is_small() { return *is_small_; }
199203
const int is_small() const { return *is_small_; }
200204

@@ -316,7 +320,9 @@ class SourceRegion {
316320
//---------------------------------------
317321
// Scalar fields
318322

319-
int material_ {0}; //!< Index in openmc::model::materials array
323+
int material_ {0}; //!< Index in openmc::model::materials array
324+
double density_mult_ {1.0}; //!< A density multiplier queried from the cell
325+
//!< corresponding to the source region.
320326
OpenMPMutex lock_;
321327
double volume_ {
322328
0.0}; //!< Volume (computed from the sum of ray crossing lengths)
@@ -394,6 +400,9 @@ class SourceRegionContainer {
394400
int& material(int64_t sr) { return material_[sr]; }
395401
const int material(int64_t sr) const { return material_[sr]; }
396402

403+
double& density_mult(int64_t sr) { return density_mult_[sr]; }
404+
const double density_mult(int64_t sr) const { return density_mult_[sr]; }
405+
397406
int& is_small(int64_t sr) { return is_small_[sr]; }
398407
const int is_small(int64_t sr) const { return is_small_[sr]; }
399408

@@ -625,6 +634,7 @@ class SourceRegionContainer {
625634

626635
// SoA storage for scalar fields (one item per source region)
627636
vector<int> material_;
637+
vector<double> density_mult_;
628638
vector<int> is_small_;
629639
vector<int> n_hits_;
630640
vector<int> mesh_;

src/random_ray/flat_source_domain.cpp

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -109,18 +109,21 @@ void FlatSourceDomain::update_single_neutron_source(SourceRegionHandle& srh)
109109

110110
// Add scattering + fission source
111111
int material = srh.material();
112+
double density_mult = srh.density_mult();
112113
if (material != MATERIAL_VOID) {
113114
double inverse_k_eff = 1.0 / k_eff_;
114115
for (int g_out = 0; g_out < negroups_; g_out++) {
115-
double sigma_t = sigma_t_[material * negroups_ + g_out];
116+
double sigma_t = sigma_t_[material * negroups_ + g_out] * density_mult;
116117
double scatter_source = 0.0;
117118
double fission_source = 0.0;
118119

119120
for (int g_in = 0; g_in < negroups_; g_in++) {
120121
double scalar_flux = srh.scalar_flux_old(g_in);
121-
double sigma_s =
122-
sigma_s_[material * negroups_ * negroups_ + g_out * negroups_ + g_in];
123-
double nu_sigma_f = nu_sigma_f_[material * negroups_ + g_in];
122+
double sigma_s = sigma_s_[material * negroups_ * negroups_ +
123+
g_out * negroups_ + g_in] *
124+
density_mult;
125+
double nu_sigma_f =
126+
nu_sigma_f_[material * negroups_ + g_in] * density_mult;
124127
double chi = chi_[material * negroups_ + g_out];
125128

126129
scatter_source += sigma_s * scalar_flux;
@@ -198,7 +201,8 @@ void FlatSourceDomain::set_flux_to_flux_plus_source(
198201
source_regions_.volume_sq(sr);
199202
}
200203
} else {
201-
double sigma_t = sigma_t_[source_regions_.material(sr) * negroups_ + g];
204+
double sigma_t = sigma_t_[source_regions_.material(sr) * negroups_ + g] *
205+
source_regions_.density_mult(sr);
202206
source_regions_.scalar_flux_new(sr, g) /= (sigma_t * volume);
203207
source_regions_.scalar_flux_new(sr, g) += source_regions_.source(sr, g);
204208
}
@@ -332,7 +336,8 @@ void FlatSourceDomain::compute_k_eff()
332336
double sr_fission_source_new = 0;
333337

334338
for (int g = 0; g < negroups_; g++) {
335-
double nu_sigma_f = nu_sigma_f_[material * negroups_ + g];
339+
double nu_sigma_f = nu_sigma_f_[material * negroups_ + g] *
340+
source_regions_.density_mult(sr);
336341
sr_fission_source_old +=
337342
nu_sigma_f * source_regions_.scalar_flux_old(sr, g);
338343
sr_fission_source_new +=
@@ -562,7 +567,8 @@ double FlatSourceDomain::compute_fixed_source_normalization_factor() const
562567
// to get the total source strength in the expected units.
563568
double sigma_t = 1.0;
564569
if (material != MATERIAL_VOID) {
565-
sigma_t = sigma_t_[material * negroups_ + g];
570+
sigma_t =
571+
sigma_t_[material * negroups_ + g] * source_regions_.density_mult(sr);
566572
}
567573
simulation_external_source_strength +=
568574
source_regions_.external_source(sr, g) * sigma_t * volume;
@@ -618,7 +624,9 @@ void FlatSourceDomain::random_ray_tally()
618624
// source strength.
619625
double volume = source_regions_.volume(sr) * simulation_volume_;
620626

621-
double material = source_regions_.material(sr);
627+
int material = source_regions_.material(sr);
628+
double density_mult = source_regions_.density_mult(sr);
629+
622630
for (int g = 0; g < negroups_; g++) {
623631
double flux =
624632
source_regions_.scalar_flux_new(sr, g) * source_normalization_factor;
@@ -634,19 +642,22 @@ void FlatSourceDomain::random_ray_tally()
634642

635643
case SCORE_TOTAL:
636644
if (material != MATERIAL_VOID) {
637-
score = flux * volume * sigma_t_[material * negroups_ + g];
645+
score =
646+
flux * volume * sigma_t_[material * negroups_ + g] * density_mult;
638647
}
639648
break;
640649

641650
case SCORE_FISSION:
642651
if (material != MATERIAL_VOID) {
643-
score = flux * volume * sigma_f_[material * negroups_ + g];
652+
score =
653+
flux * volume * sigma_f_[material * negroups_ + g] * density_mult;
644654
}
645655
break;
646656

647657
case SCORE_NU_FISSION:
648658
if (material != MATERIAL_VOID) {
649-
score = flux * volume * nu_sigma_f_[material * negroups_ + g];
659+
score = flux * volume * nu_sigma_f_[material * negroups_ + g] *
660+
density_mult;
650661
}
651662
break;
652663

@@ -913,7 +924,8 @@ void FlatSourceDomain::output_to_vtk() const
913924
for (int g = 0; g < negroups_; g++) {
914925
int64_t source_element = fsr * negroups_ + g;
915926
float flux = evaluate_flux_at_point(voxel_positions[i], fsr, g);
916-
double sigma_f = sigma_f_[mat * negroups_ + g];
927+
double sigma_f = sigma_f_[mat * negroups_ + g] *
928+
source_regions_.density_mult(fsr);
917929
total_fission += sigma_f * flux;
918930
}
919931
}
@@ -934,7 +946,8 @@ void FlatSourceDomain::output_to_vtk() const
934946
// multiply it back to get the true external source.
935947
double sigma_t = 1.0;
936948
if (mat != MATERIAL_VOID) {
937-
sigma_t = sigma_t_[mat * negroups_ + g];
949+
sigma_t = sigma_t_[mat * negroups_ + g] *
950+
source_regions_.density_mult(fsr);
938951
}
939952
total_external += source_regions_.external_source(fsr, g) * sigma_t;
940953
}
@@ -1244,7 +1257,8 @@ void FlatSourceDomain::set_adjoint_sources()
12441257
continue;
12451258
}
12461259
for (int g = 0; g < negroups_; g++) {
1247-
double sigma_t = sigma_t_[material * negroups_ + g];
1260+
double sigma_t =
1261+
sigma_t_[material * negroups_ + g] * source_regions_.density_mult(sr);
12481262
source_regions_.external_source(sr, g) /= sigma_t;
12491263
}
12501264
}
@@ -1495,6 +1509,8 @@ SourceRegionHandle FlatSourceDomain::get_subdivided_source_region_handle(
14951509

14961510
handle.material() = material;
14971511

1512+
handle.density_mult() = cell.density_mult(gs.cell_instance());
1513+
14981514
// Store the mesh index (if any) assigned to this source region
14991515
handle.mesh() = mesh_idx;
15001516

@@ -1523,7 +1539,8 @@ SourceRegionHandle FlatSourceDomain::get_subdivided_source_region_handle(
15231539
// Divide external source term by sigma_t
15241540
if (material != C_NONE) {
15251541
for (int g = 0; g < negroups_; g++) {
1526-
double sigma_t = sigma_t_[material * negroups_ + g];
1542+
double sigma_t =
1543+
sigma_t_[material * negroups_ + g] * handle.density_mult();
15271544
handle.external_source(g) /= sigma_t;
15281545
}
15291546
}
@@ -1598,16 +1615,18 @@ void FlatSourceDomain::apply_transport_stabilization()
15981615
#pragma omp parallel for
15991616
for (int64_t sr = 0; sr < n_source_regions(); sr++) {
16001617
int material = source_regions_.material(sr);
1618+
double density_mult = source_regions_.density_mult(sr);
16011619
if (material == MATERIAL_VOID) {
16021620
continue;
16031621
}
16041622
for (int g = 0; g < negroups_; g++) {
16051623
// Only apply stabilization if the diagonal (in-group) scattering XS is
16061624
// negative
16071625
double sigma_s =
1608-
sigma_s_[material * negroups_ * negroups_ + g * negroups_ + g];
1626+
sigma_s_[material * negroups_ * negroups_ + g * negroups_ + g] *
1627+
density_mult;
16091628
if (sigma_s < 0.0) {
1610-
double sigma_t = sigma_t_[material * negroups_ + g];
1629+
double sigma_t = sigma_t_[material * negroups_ + g] * density_mult;
16111630
double phi_new = source_regions_.scalar_flux_new(sr, g);
16121631
double phi_old = source_regions_.scalar_flux_old(sr, g);
16131632

src/random_ray/linear_source_domain.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,13 @@ void LinearSourceDomain::update_single_neutron_source(SourceRegionHandle& srh)
4343

4444
// Add scattering + fission source
4545
int material = srh.material();
46+
double density_mult = srh.density_mult();
4647
if (material != MATERIAL_VOID) {
4748
double inverse_k_eff = 1.0 / k_eff_;
4849
MomentMatrix invM = srh.mom_matrix().inverse();
4950

5051
for (int g_out = 0; g_out < negroups_; g_out++) {
51-
double sigma_t = sigma_t_[material * negroups_ + g_out];
52+
double sigma_t = sigma_t_[material * negroups_ + g_out] * density_mult;
5253

5354
double scatter_flat = 0.0f;
5455
double fission_flat = 0.0f;
@@ -61,9 +62,11 @@ void LinearSourceDomain::update_single_neutron_source(SourceRegionHandle& srh)
6162
MomentArray flux_linear = srh.flux_moments_old(g_in);
6263

6364
// Handles for cross sections
64-
double sigma_s =
65-
sigma_s_[material * negroups_ * negroups_ + g_out * negroups_ + g_in];
66-
double nu_sigma_f = nu_sigma_f_[material * negroups_ + g_in];
65+
double sigma_s = sigma_s_[material * negroups_ * negroups_ +
66+
g_out * negroups_ + g_in] *
67+
density_mult;
68+
double nu_sigma_f =
69+
nu_sigma_f_[material * negroups_ + g_in] * density_mult;
6770
double chi = chi_[material * negroups_ + g_out];
6871

6972
// Compute source terms for flat and linear components of the flux

src/random_ray/random_ray.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,8 @@ void RandomRay::attenuate_flux_flat_source(
435435

436436
// MOC incoming flux attenuation + source contribution/attenuation equation
437437
for (int g = 0; g < negroups_; g++) {
438-
float sigma_t = domain_->sigma_t_[material * negroups_ + g];
438+
float sigma_t =
439+
domain_->sigma_t_[material * negroups_ + g] * srh.density_mult();
439440
float tau = sigma_t * distance;
440441
float exponential = cjosey_exponential(tau); // exponential = 1 - exp(-tau)
441442
float new_delta_psi = (angular_flux_[g] - srh.source(g)) * exponential;
@@ -558,7 +559,8 @@ void RandomRay::attenuate_flux_linear_source(
558559
for (int g = 0; g < negroups_; g++) {
559560

560561
// Compute tau, the optical thickness of the ray segment
561-
float sigma_t = domain_->sigma_t_[material * negroups_ + g];
562+
float sigma_t =
563+
domain_->sigma_t_[material * negroups_ + g] * srh.density_mult();
562564
float tau = sigma_t * distance;
563565

564566
// If tau is very small, set it to zero to avoid numerical issues.

src/random_ray/source_region.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ namespace openmc {
1111
//==============================================================================
1212
SourceRegionHandle::SourceRegionHandle(SourceRegion& sr)
1313
: negroups_(sr.scalar_flux_old_.size()), material_(&sr.material_),
14-
is_small_(&sr.is_small_), n_hits_(&sr.n_hits_),
15-
is_linear_(sr.source_gradients_.size() > 0), lock_(&sr.lock_),
16-
volume_(&sr.volume_), volume_t_(&sr.volume_t_), volume_sq_(&sr.volume_sq_),
17-
volume_sq_t_(&sr.volume_sq_t_), volume_naive_(&sr.volume_naive_),
14+
density_mult_(&sr.density_mult_), is_small_(&sr.is_small_),
15+
n_hits_(&sr.n_hits_), is_linear_(sr.source_gradients_.size() > 0),
16+
lock_(&sr.lock_), volume_(&sr.volume_), volume_t_(&sr.volume_t_),
17+
volume_sq_(&sr.volume_sq_), volume_sq_t_(&sr.volume_sq_t_),
18+
volume_naive_(&sr.volume_naive_),
1819
position_recorded_(&sr.position_recorded_),
1920
external_source_present_(&sr.external_source_present_),
2021
position_(&sr.position_), centroid_(&sr.centroid_),
@@ -70,6 +71,7 @@ void SourceRegionContainer::push_back(const SourceRegion& sr)
7071

7172
// Scalar fields
7273
material_.push_back(sr.material_);
74+
density_mult_.push_back(sr.density_mult_);
7375
is_small_.push_back(sr.is_small_);
7476
n_hits_.push_back(sr.n_hits_);
7577
lock_.push_back(sr.lock_);
@@ -123,6 +125,7 @@ void SourceRegionContainer::assign(
123125
// Clear existing data
124126
n_source_regions_ = 0;
125127
material_.clear();
128+
density_mult_.clear();
126129
is_small_.clear();
127130
n_hits_.clear();
128131
lock_.clear();
@@ -180,6 +183,7 @@ SourceRegionHandle SourceRegionContainer::get_source_region_handle(int64_t sr)
180183
SourceRegionHandle handle;
181184
handle.negroups_ = negroups();
182185
handle.material_ = &material(sr);
186+
handle.density_mult_ = &density_mult(sr);
183187
handle.is_small_ = &is_small(sr);
184188
handle.n_hits_ = &n_hits(sr);
185189
handle.is_linear_ = is_linear();

tests/regression_tests/random_ray_cell_density/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)