Skip to content

Commit 3fa4b68

Browse files
committed
Merge branch 'develop' into IFP_beta_nuc
2 parents 180ad9a + 179048b commit 3fa4b68

14 files changed

Lines changed: 708 additions & 33 deletions

File tree

.github/workflows/ci.yml

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: CI
1+
name: Tests and Coverage
22

33
on:
44
# allows us to run workflows manually
@@ -21,7 +21,25 @@ env:
2121
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2222

2323
jobs:
24+
filter-changes:
25+
runs-on: ubuntu-latest
26+
outputs:
27+
source_changed: ${{ steps.filter.outputs.source_changed }}
28+
steps:
29+
- name: Check out the repository
30+
uses: actions/checkout@v4
31+
- name: Examine changed files
32+
id: filter
33+
uses: dorny/paths-filter@668c092af3649c4b664c54e4b704aa46782f6f7c # latest master commit, not released yet
34+
with:
35+
filters: |
36+
source_changed:
37+
- '!docs/**'
38+
- '!**/*.md'
39+
predicate-quantifier: 'every'
2440
main:
41+
needs: filter-changes
42+
if: ${{ needs.filter-changes.outputs.source_changed == 'true' }}
2543
runs-on: ubuntu-22.04
2644
strategy:
2745
matrix:
@@ -205,12 +223,33 @@ jobs:
205223
flag-name: C++ and Python
206224
path-to-lcov: coverage.lcov
207225

208-
finish:
209-
needs: main
226+
coverage:
227+
needs: [filter-changes, main]
228+
if: ${{ always() }}
210229
runs-on: ubuntu-latest
211230
steps:
212231
- name: Coveralls Finished
232+
if: ${{ needs.filter-changes.outputs.source_changed == 'true' }}
213233
uses: coverallsapp/github-action@v2
214234
with:
215235
github-token: ${{ secrets.GITHUB_TOKEN }}
216236
parallel-finished: true
237+
238+
ci-pass:
239+
needs: [filter-changes, main, coverage]
240+
name: Check CI status
241+
if: ${{ always() }}
242+
runs-on: ubuntu-latest
243+
steps:
244+
- name: Check CI status
245+
run: |
246+
if [[ "${{ needs.filter-changes.outputs.source_changed }}" == "false" ]]; then
247+
echo "Documentation-only change - CI skipped successfully"
248+
exit 0
249+
fi
250+
if [[ "${{ needs.main.result }}" == "success" && "${{ needs.coverage.result }}" == "success" ]]; then
251+
echo "CI passed"
252+
exit 0
253+
fi
254+
echo "CI failed"
255+
exit 1

AGENTS.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,24 @@ C++17/Python codebase where:
3131
- **Depletion**: `openmc.deplete` implements burnup via operator-splitting with various integrators (Predictor, CECM, etc.)
3232
- **Nuclear Data**: `openmc.data` provides programmatic access to nuclear data files (ENDF, ACE, HDF5)
3333

34+
## Git Branching Workflow
35+
36+
OpenMC uses a git flow branching model with two primary branches:
37+
38+
- **`develop` branch**: The main development branch where all ongoing development takes place. This is the **primary branch against which pull requests are submitted and merged**. This branch is not guaranteed to be stable and may contain work-in-progress features.
39+
- **`master` branch**: The stable release branch containing the latest stable release of OpenMC. This branch only receives merges from `develop` when the development team decides a release should occur.
40+
41+
### Instructions for Code Review
42+
43+
When analyzing code changes on a feature or bugfix branch (e.g., when a user asks "what do you think of these changes?"), **compare the branch changes against `develop`, not `master`**. Pull requests are submitted to merge into `develop`, so differences relative to `develop` represent the actual proposed changes. Comparing against `master` will include unrelated changes from other features that have already been merged to `develop`.
44+
45+
### Workflow for contributors
46+
47+
1. Create a feature/bugfix branch off `develop`
48+
2. Make changes and commit to the feature branch
49+
3. Open a pull request to merge the feature branch into `develop`
50+
4. A committer reviews and merges the PR into `develop`
51+
3452
## Critical Build & Test Workflows
3553

3654
### Build Dependencies

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.

0 commit comments

Comments
 (0)