Skip to content

Commit 7aa1a80

Browse files
authored
Merge pull request #16 from yardasol/kin-rr-sim-simplification
Consistency changes, explicitly prohibit void regions in kinetic rr until it is fully supported.
2 parents 98dff82 + 649d071 commit 7aa1a80

File tree

16 files changed

+187
-151
lines changed

16 files changed

+187
-151
lines changed

include/openmc/random_ray/flat_source_domain.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class FlatSourceDomain {
7676

7777
//----------------------------------------------------------------------------
7878
// Methods for kinetic simulations
79+
void compute_single_phi_prime(SourceRegionHandle& srh);
7980
void compute_single_T1(SourceRegionHandle& srh);
8081

8182
void compute_single_delayed_fission_source(SourceRegionHandle& srh);

include/openmc/random_ray/source_region.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ class SourceRegionHandle {
197197
// Public Data Members for kinetic simulations
198198

199199
// Energy group-wise 1D time-derivative arrays
200+
double* phi_prime_;
200201
double* T1_;
201202

202203
// Delay group-wise 1D arrays
@@ -342,6 +343,9 @@ class SourceRegionHandle {
342343

343344
//---------------------------------------------------------------------------
344345
// Public Accessors for kinetic simulations
346+
double& phi_prime(int g) { return phi_prime_[g]; }
347+
const double phi_prime(int g) const { return phi_prime_[g]; }
348+
345349
double& T1(int g) { return T1_[g]; }
346350
const double T1(int g) const { return T1_[g]; }
347351

@@ -490,7 +494,9 @@ class SourceRegion {
490494
//!< active iterations (used for SDP)
491495

492496
// Energy group-wise 1D derivative arrays
493-
vector<double> T1_; //!< The combined sourcetime derivative and 2nd order
497+
vector<double>
498+
phi_prime_; //!< The 1st order scalar flux time derivative (used for TI)
499+
vector<double> T1_; //!< The combined source time derivative and 2nd order
494500
//!< scalar flux time derivative (used for SDP)
495501
// Delay group-wise 1D arrays
496502
vector<double> delayed_fission_source_; //!< The delayed fission source binned
@@ -782,6 +788,14 @@ class SourceRegionContainer {
782788

783789
//---------------------------------------
784790
// For kinetic simulations
791+
double& phi_prime(int64_t sr, int g) { return phi_prime_[index(sr, g)]; }
792+
const double& phi_prime(int64_t sr, int g) const
793+
{
794+
return phi_prime_[index(sr, g)];
795+
}
796+
double& phi_prime(int64_t se) { return phi_prime_[se]; }
797+
const double& phi_prime(int64_t se) const { return phi_prime_[se]; }
798+
785799
double& T1(int64_t sr, int g) { return T1_[index(sr, g)]; }
786800
const double& T1(int64_t sr, int g) const { return T1_[index(sr, g)]; }
787801
double& T1(int64_t se) { return T1_[se]; }
@@ -1034,6 +1048,7 @@ class SourceRegionContainer {
10341048
// Private Data Members for kinetic simulations
10351049

10361050
// SoA energy group-wise 2D derivative arrays flattened to 1D
1051+
vector<double> phi_prime_;
10371052
vector<double> T1_;
10381053

10391054
// SoA delay group-wise 2D arrays flattened to 1D

src/random_ray/flat_source_domain.cpp

Lines changed: 61 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -149,39 +149,24 @@ void FlatSourceDomain::update_single_neutron_source(SourceRegionHandle& srh)
149149
}
150150
total_source = (scatter_source + fission_source * inverse_k_eff);
151151

152-
if (settings::kinetic_simulation && !simulation::is_initial_condition) {
153-
// Add delayed source for kinetic simulation if delayed neutrons are
154-
// turned on
155-
if (settings::create_delayed_neutrons) {
156-
double delayed_source = 0.0;
157-
for (int dg = 0; dg < ndgroups_; dg++) {
158-
double chi_d =
159-
chi_d_[material * negroups_ * ndgroups_ + dg * negroups_ + g_out];
160-
double lambda = lambda_[material * ndgroups_ + dg];
161-
double precursors = srh.precursors_old(dg);
162-
delayed_source += chi_d * precursors * lambda;
163-
}
164-
total_source += delayed_source;
165-
}
166-
// Add derivative of scalar flux to source (only works for isotropic
167-
// method)
168-
if (RandomRay::time_method_ == RandomRayTimeMethod::ISOTROPIC) {
169-
double inverse_vbar = inverse_vbar_[material * negroups_ + g_out];
170-
double scalar_flux_rhs_bd = srh.scalar_flux_rhs_bd(g_out);
171-
double A0 =
172-
(bd_coefficients_first_order_.at(RandomRay::bd_order_))[0] /
173-
settings::dt;
174-
double scalar_flux = srh.scalar_flux_old(g_out);
175-
double scalar_flux_time_derivative =
176-
A0 * scalar_flux + scalar_flux_rhs_bd;
177-
total_source -= scalar_flux_time_derivative * inverse_vbar;
152+
// Add delayed source for kinetic simulation if delayed neutrons are
153+
// turned on
154+
if (settings::kinetic_simulation && !simulation::is_initial_condition &&
155+
settings::create_delayed_neutrons) {
156+
double delayed_source = 0.0;
157+
for (int dg = 0; dg < ndgroups_; dg++) {
158+
double chi_d =
159+
chi_d_[material * negroups_ * ndgroups_ + dg * negroups_ + g_out];
160+
double lambda = lambda_[material * ndgroups_ + dg];
161+
double precursors = srh.precursors_old(dg);
162+
delayed_source += chi_d * precursors * lambda;
178163
}
164+
total_source += delayed_source;
179165
}
180166
srh.source(g_out) = total_source / sigma_t;
181167
}
182168
}
183169

184-
// TODO: Add control flow for k-eigenvalue forward-weighted adjoint
185170
// Add external source if in fixed source mode
186171
if (settings::run_mode == RunMode::FIXED_SOURCE) {
187172
for (int g = 0; g < negroups_; g++) {
@@ -200,9 +185,11 @@ void FlatSourceDomain::update_all_neutron_sources()
200185
for (int64_t sr = 0; sr < n_source_regions(); sr++) {
201186
SourceRegionHandle srh = source_regions_.get_source_region_handle(sr);
202187
update_single_neutron_source(srh);
203-
if (settings::kinetic_simulation && !simulation::is_initial_condition &&
204-
RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
205-
compute_single_T1(srh);
188+
if (settings::kinetic_simulation && !simulation::is_initial_condition) {
189+
if (RandomRay::time_method_ == RandomRayTimeMethod::ISOTROPIC)
190+
compute_single_phi_prime(srh);
191+
else if (RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION)
192+
compute_single_T1(srh);
206193
}
207194
}
208195

@@ -243,7 +230,6 @@ void FlatSourceDomain::set_flux_to_flux_plus_source(
243230
int64_t sr, double volume, int g)
244231
{
245232
int material = source_regions_.material(sr);
246-
// TODO: Implement support for time-dependent void transport
247233
if (material == MATERIAL_VOID) {
248234
source_regions_.scalar_flux_new(sr, g) /= volume;
249235
if (settings::run_mode == RunMode::FIXED_SOURCE) {
@@ -252,20 +238,21 @@ void FlatSourceDomain::set_flux_to_flux_plus_source(
252238
source_regions_.volume_sq(sr);
253239
}
254240
} else {
255-
double sigma_t = sigma_t_[source_regions_.material(sr) * negroups_ + g];
241+
double sigma_t = sigma_t_[material * negroups_ + g];
256242
source_regions_.scalar_flux_new(sr, g) /= (sigma_t * volume);
257243
source_regions_.scalar_flux_new(sr, g) += source_regions_.source(sr, g);
258-
if (settings::kinetic_simulation && !simulation::is_initial_condition &&
259-
RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
260-
double inverse_vbar =
261-
inverse_vbar_[source_regions_.material(sr) * negroups_ + g];
262-
double scalar_flux_rhs_bd = source_regions_.scalar_flux_rhs_bd(sr, g);
263-
double A0 = (bd_coefficients_first_order_.at(RandomRay::bd_order_))[0] /
264-
settings::dt;
265-
source_regions_.scalar_flux_new(sr, g) -=
266-
scalar_flux_rhs_bd * inverse_vbar / sigma_t;
267-
source_regions_.scalar_flux_new(sr, g) /= 1 + A0 * inverse_vbar / sigma_t;
268-
}
244+
}
245+
if (settings::kinetic_simulation && !simulation::is_initial_condition) {
246+
double inverse_vbar =
247+
inverse_vbar_[source_regions_.material(sr) * negroups_ + g];
248+
double scalar_flux_rhs_bd = source_regions_.scalar_flux_rhs_bd(sr, g);
249+
double A0 =
250+
(bd_coefficients_first_order_.at(RandomRay::bd_order_))[0] / settings::dt;
251+
// TODO: Add support for expicit void regions
252+
double sigma_t = sigma_t_[material * negroups_ + g];
253+
source_regions_.scalar_flux_new(sr, g) -=
254+
scalar_flux_rhs_bd * inverse_vbar / sigma_t;
255+
source_regions_.scalar_flux_new(sr, g) /= 1 + A0 * inverse_vbar / sigma_t;
269256
}
270257
}
271258

@@ -1736,6 +1723,11 @@ SourceRegionHandle FlatSourceDomain::get_subdivided_source_region_handle(
17361723
}
17371724
}
17381725

1726+
if (settings::kinetic_simulation && material == MATERIAL_VOID) {
1727+
fatal_error("Explicit void treatment for kinetic simulations "
1728+
" is not currently supported.");
1729+
}
1730+
17391731
handle.material() = material;
17401732

17411733
// Store the mesh index (if any) assigned to this source region
@@ -1774,9 +1766,11 @@ SourceRegionHandle FlatSourceDomain::get_subdivided_source_region_handle(
17741766

17751767
// Compute the combined source term
17761768
update_single_neutron_source(handle);
1777-
if (settings::kinetic_simulation && !simulation::is_initial_condition &&
1778-
RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
1779-
compute_single_T1(handle);
1769+
if (settings::kinetic_simulation && !simulation::is_initial_condition) {
1770+
if (RandomRay::time_method_ == RandomRayTimeMethod::ISOTROPIC)
1771+
compute_single_phi_prime(handle);
1772+
else if (RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION)
1773+
compute_single_T1(handle);
17801774
}
17811775

17821776
// Unlock the parallel map. Note: we may be tempted to release
@@ -1936,6 +1930,22 @@ int64_t FlatSourceDomain::lookup_mesh_bin(int64_t sr, Position r) const
19361930
// kinetic simulations) sources in each source region based on the flux
19371931
// estimate from the previous iteration.
19381932

1933+
void FlatSourceDomain::compute_single_phi_prime(SourceRegionHandle& srh)
1934+
{
1935+
double A0 =
1936+
(bd_coefficients_first_order_.at(RandomRay::bd_order_))[0] / settings::dt;
1937+
int material = srh.material();
1938+
for (int g = 0; g < negroups_; g++) {
1939+
double inverse_vbar = inverse_vbar_[material * negroups_ + g];
1940+
// TODO: add support for explicit void
1941+
double sigma_t = sigma_t_[material * negroups_ + g];
1942+
1943+
double scalar_flux_time_derivative =
1944+
A0 * srh.scalar_flux_old(g) + srh.scalar_flux_rhs_bd(g);
1945+
srh.phi_prime(g) = scalar_flux_time_derivative * inverse_vbar / sigma_t;
1946+
}
1947+
}
1948+
19391949
// T1 calculation
19401950
void FlatSourceDomain::compute_single_T1(SourceRegionHandle& srh)
19411951
{
@@ -1946,9 +1956,8 @@ void FlatSourceDomain::compute_single_T1(SourceRegionHandle& srh)
19461956
int material = srh.material();
19471957
for (int g = 0; g < negroups_; g++) {
19481958
double inverse_vbar = inverse_vbar_[material * negroups_ + g];
1949-
double sigma_t = 1.0;
1950-
if (material != MATERIAL_VOID)
1951-
sigma_t = sigma_t_[material * negroups_ + g];
1959+
// TODO: add support for explicit void
1960+
double sigma_t = sigma_t_[material * negroups_ + g];
19521961

19531962
// Multiply out sigma_t to correctly compute the derivative term
19541963
float source_time_derivative =
@@ -2131,10 +2140,10 @@ void FlatSourceDomain::store_time_step_quantities(bool increment_not_initialize)
21312140
source_regions_.scalar_flux_final(sr, g), increment_not_initialize,
21322141
RandomRay::bd_order_ + j);
21332142
if (RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
2134-
// TODO: add support for void regions
21352143
// Multiply out sigma_t to store the base source
2136-
double sigma_t = sigma_t =
2137-
sigma_t_[source_regions_.material(sr) * negroups_ + g];
2144+
int material = source_regions_.material(sr);
2145+
// TODO: add support for explicit void regions
2146+
double sigma_t = sigma_t_[source_regions_.material(sr) * negroups_ + g];
21382147
float source = source_regions_.source_final(sr, g) * sigma_t;
21392148
add_value_to_bd_vector(source_regions_.source_bd(sr, g), source,
21402149
increment_not_initialize, RandomRay::bd_order_);

src/random_ray/random_ray.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -451,18 +451,21 @@ void RandomRay::attenuate_flux_flat_source(
451451
float tau = sigma_t * distance;
452452
float exponential = cjosey_exponential(tau); // exponential = 1 - exp(-tau)
453453
float new_delta_psi = (angular_flux_[g] - srh.source(g)) * exponential;
454-
if (settings::kinetic_simulation && !simulation::is_initial_condition &&
455-
RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
456-
float T1 = srh.T1(g);
457-
458-
// Source Derivative Propogation terms for Characteristic Equation
459-
float inverse_vbar = domain_->inverse_vbar_[material * negroups_ + g];
460-
new_delta_psi += T1 * inverse_vbar * exponential / sigma_t;
461-
new_delta_psi += distance * inverse_vbar * (angular_flux_prime_[g] - T1) *
462-
(1 - exponential);
463-
464-
// Time Derivative Characteristic Equation
465-
angular_flux_prime_[g] -= (angular_flux_prime_[g] - T1) * exponential;
454+
if (settings::kinetic_simulation && !simulation::is_initial_condition) {
455+
if (RandomRay::time_method_ == RandomRayTimeMethod::ISOTROPIC) {
456+
new_delta_psi += srh.phi_prime(g) * exponential;
457+
} else if (RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
458+
// Source Derivative Propogation terms for Characteristic Equation
459+
float inverse_vbar = domain_->inverse_vbar_[material * negroups_ + g];
460+
float T1 = srh.T1(g);
461+
float new_delta_psi_prime = (angular_flux_prime_[g] - T1);
462+
new_delta_psi += T1 * inverse_vbar * exponential / sigma_t;
463+
new_delta_psi +=
464+
distance * inverse_vbar * new_delta_psi_prime * (1 - exponential);
465+
466+
// Time Derivative Characteristic Equation
467+
angular_flux_prime_[g] -= new_delta_psi_prime * exponential;
468+
}
466469
}
467470
delta_psi_[g] = new_delta_psi;
468471
angular_flux_[g] -= new_delta_psi;
@@ -501,7 +504,7 @@ void RandomRay::attenuate_flux_flat_source(
501504
}
502505

503506
// Alternative flux attenuation function for true void regions.
504-
// TODO: Implement support for time dependent voids
507+
// TODO: Implement support for time-dependent voids
505508
void RandomRay::attenuate_flux_flat_source_void(
506509
SourceRegionHandle& srh, double distance, bool is_active, Position r)
507510
{
@@ -841,7 +844,6 @@ void RandomRay::initialize_ray(uint64_t ray_id, FlatSourceDomain* domain)
841844
if (settings::kinetic_simulation && !simulation::is_initial_condition &&
842845
RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
843846
for (int g = 0; g < negroups_; g++) {
844-
// T1
845847
angular_flux_prime_[g] = srh.T1(g);
846848
}
847849
}

src/random_ray/random_ray_simulation.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,6 @@ void openmc_run_random_ray()
5353
// Second steady state simulation to correct the batchwise k-eff
5454
sim.kinetic_initial_condition();
5555

56-
warning(
57-
"Time-dependent explicit void treatment has not yet been "
58-
"implemented. Use caution when interpreting results from models with "
59-
"voids, as they may contain large inaccuracies.");
6056
// Timestepping loop
6157
for (int i = 0; i < settings::n_timesteps; i++)
6258
sim.kinetic_single_time_step(i);

src/random_ray/source_region.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ SourceRegionHandle::SourceRegionHandle(SourceRegion& sr)
3131
flux_moments_old_(sr.flux_moments_old_.data()),
3232
flux_moments_new_(sr.flux_moments_new_.data()),
3333
flux_moments_t_(sr.flux_moments_t_.data()),
34-
tally_task_(sr.tally_task_.data()), T1_(sr.T1_.data()),
34+
tally_task_(sr.tally_task_.data()), phi_prime_(sr.phi_prime_.data()),
35+
T1_(sr.T1_.data()),
3536
delayed_fission_source_(sr.delayed_fission_source_.data()),
3637
precursors_old_(sr.precursors_old_.data()),
3738
precursors_new_(sr.precursors_new_.data()),
@@ -75,8 +76,11 @@ SourceRegion::SourceRegion(int negroups, int ndgroups, bool is_linear)
7576
scalar_flux_bd_.resize(negroups);
7677
scalar_flux_rhs_bd_.resize(negroups);
7778

78-
// Source Derivative Propogation arrays
79-
if (RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
79+
if (RandomRay::time_method_ == RandomRayTimeMethod::ISOTROPIC) {
80+
// Time Isotropic arrays
81+
phi_prime_.assign(negroups, 0.0);
82+
} else if (RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
83+
// Source Derivative Propogation arrays
8084
source_final_.assign(negroups, 0.0);
8185

8286
T1_.assign(negroups, 0.0);
@@ -160,8 +164,11 @@ void SourceRegionContainer::push_back(const SourceRegion& sr)
160164
scalar_flux_bd_.push_back(sr.scalar_flux_bd_[g]);
161165
scalar_flux_rhs_bd_.push_back(sr.scalar_flux_rhs_bd_[g]);
162166

163-
// Source Derivative Propogation arrays
164-
if (RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
167+
if (RandomRay::time_method_ == RandomRayTimeMethod::ISOTROPIC) {
168+
// Time Isotropic arrays
169+
phi_prime_.push_back(sr.phi_prime_[g]);
170+
} else if (RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
171+
// Source Derivative Propogation arrays
165172
source_final_.push_back(sr.source_final_[g]);
166173

167174
T1_.push_back(sr.T1_[g]);
@@ -237,7 +244,9 @@ void SourceRegionContainer::assign(
237244
scalar_flux_bd_.clear();
238245
scalar_flux_rhs_bd_.clear();
239246

240-
if (RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
247+
if (RandomRay::time_method_ == RandomRayTimeMethod::ISOTROPIC) {
248+
phi_prime_.clear();
249+
} else if (RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
241250
source_final_.clear();
242251

243252
T1_.clear();
@@ -320,7 +329,9 @@ SourceRegionHandle SourceRegionContainer::get_source_region_handle(int64_t sr)
320329
handle.scalar_flux_bd_ = &scalar_flux_bd(sr, 0);
321330
handle.scalar_flux_rhs_bd_ = &scalar_flux_rhs_bd(sr, 0);
322331

323-
if (RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
332+
if (RandomRay::time_method_ == RandomRayTimeMethod::ISOTROPIC) {
333+
handle.phi_prime_ = &phi_prime(sr, 0);
334+
} else if (RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
324335
handle.source_final_ = &source_final(sr, 0);
325336

326337
handle.T1_ = &T1(sr, 0);
@@ -394,7 +405,9 @@ void SourceRegionContainer::adjoint_reset()
394405
// BD Vectors
395406
std::fill(scalar_flux_rhs_bd_.begin(), scalar_flux_rhs_bd_.end(), 0.0);
396407

397-
if (RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
408+
if (RandomRay::time_method_ == RandomRayTimeMethod::ISOTROPIC) {
409+
std::fill(phi_prime_.begin(), phi_prime_.end(), 0.0);
410+
} else if (RandomRay::time_method_ == RandomRayTimeMethod::PROPAGATION) {
398411
std::fill(T1_.begin(), T1_.end(), 0.0);
399412

400413
std::fill(source_rhs_bd_.begin(), source_rhs_bd_.end(), 0.0);

tests/regression_tests/random_ray_k_eff_kinetic/isotropic/results_true_1.dat

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
k-combined:
22
1.325787E+00 5.102917E-04
33
tally 1:
4-
2.630190E+03
5-
3.458951E+04
4+
2.630191E+03
5+
3.458954E+04
66
1.079890E+02
7-
5.830986E+01
8-
2.651431E+02
9-
3.515147E+02
7+
5.830990E+01
8+
2.651432E+02
9+
3.515149E+02
1010
tally 2:
1111
1.077582E+00
1212
5.805916E-03

0 commit comments

Comments
 (0)