• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

openmc-dev / openmc / 13526388676

25 Feb 2025 04:44PM UTC coverage: 85.189% (+0.1%) from 85.074%
13526388676

Pull #3327

github

web-flow
Merge 0614ec2dd into 27258c009
Pull Request #3327: Reflect multigroup MicroXS in IndependentOperator docstrings

51022 of 59893 relevant lines covered (85.19%)

34750622.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.0
/src/random_ray/linear_source_domain.cpp
1
#include "openmc/random_ray/linear_source_domain.h"
2

3
#include "openmc/cell.h"
4
#include "openmc/geometry.h"
5
#include "openmc/material.h"
6
#include "openmc/message_passing.h"
7
#include "openmc/mgxs_interface.h"
8
#include "openmc/output.h"
9
#include "openmc/plot.h"
10
#include "openmc/random_ray/random_ray.h"
11
#include "openmc/simulation.h"
12
#include "openmc/tallies/filter.h"
13
#include "openmc/tallies/tally.h"
14
#include "openmc/tallies/tally_scoring.h"
15
#include "openmc/timer.h"
16

17
namespace openmc {
18

19
//==============================================================================
20
// LinearSourceDomain implementation
21
//==============================================================================
22

23
void LinearSourceDomain::batch_reset()
7,565✔
24
{
25
  FlatSourceDomain::batch_reset();
7,565✔
26
#pragma omp parallel for
4,005✔
27
  for (int64_t sr = 0; sr < n_source_regions_; sr++) {
3,825,480✔
28
    source_regions_.centroid_iteration(sr) = {0.0, 0.0, 0.0};
3,821,920✔
29
    source_regions_.mom_matrix(sr) = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
3,821,920✔
30
  }
31
#pragma omp parallel for
4,005✔
32
  for (int64_t se = 0; se < n_source_elements_; se++) {
6,850,440✔
33
    source_regions_.flux_moments_new(se) = {0.0, 0.0, 0.0};
6,846,880✔
34
  }
35
}
7,565✔
36

37
void LinearSourceDomain::update_neutron_source(double k_eff)
7,565✔
38
{
39
  simulation::time_update_src.start();
7,565✔
40

41
  double inverse_k_eff = 1.0 / k_eff;
7,565✔
42

43
#pragma omp parallel for
4,005✔
44
  for (int64_t sr = 0; sr < n_source_regions_; sr++) {
3,825,480✔
45
    int material = source_regions_.material(sr);
3,821,920✔
46
    if (material == MATERIAL_VOID) {
3,821,920✔
47
      continue;
320,000✔
48
    }
49
    MomentMatrix invM = source_regions_.mom_matrix(sr).inverse();
3,501,920✔
50

51
    for (int g_out = 0; g_out < negroups_; g_out++) {
10,028,800✔
52
      double sigma_t = sigma_t_[material * negroups_ + g_out];
6,526,880✔
53

54
      double scatter_flat = 0.0f;
6,526,880✔
55
      double fission_flat = 0.0f;
6,526,880✔
56
      MomentArray scatter_linear = {0.0, 0.0, 0.0};
6,526,880✔
57
      MomentArray fission_linear = {0.0, 0.0, 0.0};
6,526,880✔
58

59
      for (int g_in = 0; g_in < negroups_; g_in++) {
34,228,480✔
60
        // Handles for the flat and linear components of the flux
61
        double flux_flat = source_regions_.scalar_flux_old(sr, g_in);
27,701,600✔
62
        MomentArray flux_linear = source_regions_.flux_moments_old(sr, g_in);
27,701,600✔
63

64
        // Handles for cross sections
65
        double sigma_s =
66
          sigma_s_[material * negroups_ * negroups_ + g_out * negroups_ + g_in];
27,701,600✔
67
        double nu_sigma_f = nu_sigma_f_[material * negroups_ + g_in];
27,701,600✔
68
        double chi = chi_[material * negroups_ + g_out];
27,701,600✔
69

70
        // Compute source terms for flat and linear components of the flux
71
        scatter_flat += sigma_s * flux_flat;
27,701,600✔
72
        fission_flat += nu_sigma_f * flux_flat * chi;
27,701,600✔
73
        scatter_linear += sigma_s * flux_linear;
27,701,600✔
74
        fission_linear += nu_sigma_f * flux_linear * chi;
27,701,600✔
75
      }
76

77
      // Compute the flat source term
78
      source_regions_.source(sr, g_out) =
13,053,760✔
79
        (scatter_flat + fission_flat * inverse_k_eff) / sigma_t;
6,526,880✔
80

81
      // Compute the linear source terms. In the first 10 iterations when the
82
      // centroids and spatial moments are not well known, we will leave the
83
      // source gradients as zero so as to avoid causing any numerical
84
      // instability. If a negative source is encountered, this region must be
85
      // very small/noisy or have poorly developed spatial moments, so we zero
86
      // the source gradients (effectively making this a flat source region
87
      // temporarily), so as to improve stability.
88
      if (simulation::current_batch > 10 &&
11,836,160✔
89
          source_regions_.source(sr, g_out) >= 0.0) {
5,309,280✔
90
        source_regions_.source_gradients(sr, g_out) =
5,052,224✔
91
          invM * ((scatter_linear + fission_linear * inverse_k_eff) / sigma_t);
10,104,448✔
92
      } else {
93
        source_regions_.source_gradients(sr, g_out) = {0.0, 0.0, 0.0};
1,474,656✔
94
      }
95
    }
96
  }
97

98
  if (settings::run_mode == RunMode::FIXED_SOURCE) {
7,565✔
99
// Add external source to flat source term if in fixed source mode
100
#pragma omp parallel for
3,285✔
101
    for (int64_t se = 0; se < n_source_elements_; se++) {
5,756,680✔
102
      source_regions_.source(se) += source_regions_.external_source(se);
5,753,760✔
103
    }
104
  }
105

106
  simulation::time_update_src.stop();
7,565✔
107
}
7,565✔
108

109
void LinearSourceDomain::normalize_scalar_flux_and_volumes(
7,565✔
110
  double total_active_distance_per_iteration)
111
{
112
  double normalization_factor = 1.0 / total_active_distance_per_iteration;
7,565✔
113
  double volume_normalization_factor =
7,565✔
114
    1.0 / (total_active_distance_per_iteration * simulation::current_batch);
7,565✔
115

116
// Normalize flux to total distance travelled by all rays this iteration
117
#pragma omp parallel for
4,005✔
118
  for (int64_t se = 0; se < n_source_elements_; se++) {
6,850,440✔
119
    source_regions_.scalar_flux_new(se) *= normalization_factor;
6,846,880✔
120
    source_regions_.flux_moments_new(se) *= normalization_factor;
6,846,880✔
121
  }
122

123
// Accumulate cell-wise ray length tallies collected this iteration, then
124
// update the simulation-averaged cell-wise volume estimates
125
#pragma omp parallel for
4,005✔
126
  for (int64_t sr = 0; sr < n_source_regions_; sr++) {
3,825,480✔
127
    source_regions_.centroid_t(sr) += source_regions_.centroid_iteration(sr);
3,821,920✔
128
    source_regions_.mom_matrix_t(sr) += source_regions_.mom_matrix(sr);
3,821,920✔
129
    source_regions_.volume_t(sr) += source_regions_.volume(sr);
3,821,920✔
130
    source_regions_.volume_sq_t(sr) += source_regions_.volume_sq(sr);
3,821,920✔
131
    source_regions_.volume_naive(sr) =
7,643,840✔
132
      source_regions_.volume(sr) * normalization_factor;
3,821,920✔
133
    source_regions_.volume(sr) =
7,643,840✔
134
      source_regions_.volume_t(sr) * volume_normalization_factor;
3,821,920✔
135
    source_regions_.volume_sq(sr) =
7,643,840✔
136
      source_regions_.volume_sq_t(sr) / source_regions_.volume_t(sr);
3,821,920✔
137
    if (source_regions_.volume_t(sr) > 0.0) {
3,821,920✔
138
      double inv_volume = 1.0 / source_regions_.volume_t(sr);
3,821,920✔
139
      source_regions_.centroid(sr) = source_regions_.centroid_t(sr);
3,821,920✔
140
      source_regions_.centroid(sr) *= inv_volume;
3,821,920✔
141
      source_regions_.mom_matrix(sr) = source_regions_.mom_matrix_t(sr);
3,821,920✔
142
      source_regions_.mom_matrix(sr) *= inv_volume;
3,821,920✔
143
    }
144
  }
145
}
7,565✔
146

147
void LinearSourceDomain::set_flux_to_flux_plus_source(
14,549,620✔
148
  int64_t sr, double volume, int g)
149
{
150
  int material = source_regions_.material(sr);
14,549,620✔
151
  if (material == MATERIAL_VOID) {
14,549,620✔
152
    FlatSourceDomain::set_flux_to_flux_plus_source(sr, volume, g);
680,000✔
153
  } else {
154
    source_regions_.scalar_flux_new(sr, g) /= volume;
13,869,620✔
155
    source_regions_.scalar_flux_new(sr, g) += source_regions_.source(sr, g);
13,869,620✔
156
  }
157
  source_regions_.flux_moments_new(sr, g) *= (1.0 / volume);
14,549,620✔
158
}
14,549,620✔
159

160
void LinearSourceDomain::set_flux_to_old_flux(int64_t sr, int g)
×
161
{
162
  source_regions_.scalar_flux_new(g) = source_regions_.scalar_flux_old(g);
×
163
  source_regions_.flux_moments_new(g) = source_regions_.flux_moments_old(g);
×
164
}
165

166
void LinearSourceDomain::accumulate_iteration_flux()
3,145✔
167
{
168
  // Accumulate scalar flux
169
  FlatSourceDomain::accumulate_iteration_flux();
3,145✔
170

171
  // Accumulate scalar flux moments
172
#pragma omp parallel for
1,665✔
173
  for (int64_t se = 0; se < n_source_elements_; se++) {
2,694,120✔
174
    source_regions_.flux_moments_t(se) += source_regions_.flux_moments_new(se);
2,692,640✔
175
  }
176
}
3,145✔
177

178
double LinearSourceDomain::evaluate_flux_at_point(
×
179
  Position r, int64_t sr, int g) const
180
{
181
  double phi_flat = FlatSourceDomain::evaluate_flux_at_point(r, sr, g);
×
182

183
  Position local_r = r - source_regions_.centroid(sr);
×
184
  MomentArray phi_linear = source_regions_.flux_moments_t(sr, g);
×
185
  phi_linear *= 1.0 / (settings::n_batches - settings::n_inactive);
×
186

187
  MomentMatrix invM = source_regions_.mom_matrix(sr).inverse();
×
188
  MomentArray phi_solved = invM * phi_linear;
×
189

190
  return phi_flat + phi_solved.dot(local_r);
×
191
}
192

193
} // namespace openmc
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc