Repository navigation
Random Ray Transport #2823
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Random Ray Transport #2823
Changes from 1 commit
d76033a
c2fa6aa
dc30912
31609b0
0e2dcec
7db4a7d
a782fa4
785c4d6
2ccc838
168ca04
2c45008
003c646
f232980
04e7e12
d66cdbb
588f1ce
442153c
baf1f5a
2c2770b
e785b26
9566890
7646594
7b46663
f28d655
2b43008
5548628
7503eb6
1eb5eec
958a73a
ec78527
eeda6ab
6a6d100
34c35db
e19e3e3
68af51e
7673afb
cfab02a
f40f807
c373560
ebee0ef
25f1fcc
aa9b732
a3ed5dd
e9708d6
8d22e78
247e8df
9610a2d
84cfdaa
d74781e
68bee19
a3c9804
0c5200b
4b60bd5
64a6d6e
b1167d9
6566cdc
738910a
1d9254e
d998d06
58d516b
7ffb30d
5ff2be8
69abd98
2cb971c
504cb54
a6a00b3
ecc0087
f363645
c5fbb4c
56e84f7
bbd325d
2854d51
8e91d50
94705ef
54f39de
b3ea0f6
2d90cd4
872ff56
39cdd66
43df38a
6cf75a6
dad86a0
f7e0400
6eb99bd
b4fffb8
ed34ab2
fe4194d
bec2b82
1fbd373
027653b
1789d41
fefe9aa
3bf3134
811c399
95ebeed
b3a38e0
00f0e4c
4939ceb
bce3b70
8704ee7
98f0696
3254e3b
a7d90df
54d0a71
8a49e5d
1419f39
dd90d63
1818989
cf0f69b
2248ec4
8216a6c
735fcfd
33c333b
0b0dc42
12f24f0
69ae4f4
99a34cc
a07c534
e0b62a7
63857aa
57dad69
d3cfd4b
ead8cfa
561d8fa
bb24326
a060d4e
a42e0eb
53d3a5e
74d7ac7
2893ecf
872bcfe
32c65d8
66387b4
2ec33be
5c63a31
4a0500f
4727569
f20bc1e
98b65d1
916b2bd
524f2b4
f122ef0
4a92297
3821eb2
00d07dc
14faa19
5555dd9
28942b9
383bd31
e3bc76a
e5cdc3e
eb66a04
b715f03
b4ad777
2d7eec3
ef0fdca
30d0d1d
7de305b
007a935
15e6bec
591d0e2
1d8722f
a58be8c
3d2eab9
982272c
43b842d
4819aaa
c9c691d
03333d2
e8ff8f5
0d94bbe
66b4a3d
06d4343
3c13dd2
433b000
3f585ef
cb813ce
fa0b844
45e3bc9
de456e0
936d703
d426075
efe6353
581229e
d60c3c0
93bb5b2
c8ffddb
f3dec7d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
…f previous flux in case where FSR has nonzero volume but was not hit this iteration. Appears to improve fidelity considerably for very low ray density cases
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -107,36 +107,50 @@ void validate_random_ray_inputs() | |
|
|
||
| int openmc_run_random_ray() | ||
| { | ||
| // Initialize OpenMC general data structures | ||
| openmc_simulation_init(); | ||
|
|
||
| // Validate that inputs meet requirements for random ray mode | ||
| validate_random_ray_inputs(); | ||
|
|
||
| double k_eff = 1.0; | ||
|
|
||
| // Intialize Cell (FSR) data structures | ||
| // Intialize Cell (Flat Source Region) data structures | ||
| initialize_source_regions(); | ||
|
|
||
| uint64_t total_geometric_intersections = 0; | ||
|
|
||
| openmc::simulation::time_total.start(); | ||
|
|
||
| // Random ray mode does not have an inner loop over generations within a batch, so set the current gen to 1 | ||
| simulation::current_gen = 1; | ||
|
|
||
| // There are no source sites in random ray mode, so be sure to disable to ensure we don't attempt | ||
| // to write source sites to statepoint | ||
| settings::source_write = false; | ||
|
|
||
| // If all source regions have been hit by a ray during transport, then we can skip the mapping process | ||
| // for future iterations. | ||
| bool mapped_all_tallies = false; | ||
|
|
||
| // Random ray eigenvalue | ||
| // TODO: Use OpenMC native eigenvalue? | ||
| double k_eff = 1.0; | ||
|
|
||
| // Tracks the average FSR miss rate for analysis and reporting | ||
| double avg_miss_rate = 0.0; | ||
|
|
||
| // Power Iteration Loop | ||
| // Tracks the total number of geometric intersections by all rays for reporting | ||
| uint64_t total_geometric_intersections = 0; | ||
|
|
||
| // Begin main simulation timer | ||
| simulation::time_total.start(); | ||
|
|
||
| // Random ray power iteration loop | ||
| while (simulation::current_batch < settings::n_batches) { | ||
|
|
||
| // Initialize the current batch | ||
| initialize_batch(); | ||
| initialize_generation(); | ||
|
|
||
| // Reset total starting particle weight used for normalizing tallies | ||
| simulation::total_weight = 1.0; | ||
|
|
||
| // Update neutron source | ||
| // Update source term (scattering + fission) | ||
| update_neutron_source(k_eff); | ||
|
|
||
| // Reset scalar fluxes, iteration volume tallies, and region hit flags to zero | ||
|
|
@@ -147,7 +161,7 @@ int openmc_run_random_ray() | |
| // Start timer for transport | ||
| simulation::time_transport.start(); | ||
|
|
||
| // Transport Sweep | ||
| // Transport sweep over all random rays for the iteration | ||
| #pragma omp parallel for schedule(runtime) reduction(+:total_geometric_intersections) | ||
| for (int i = 0; i < settings::n_particles; i++) | ||
| { | ||
|
|
@@ -162,37 +176,44 @@ int openmc_run_random_ray() | |
| // Normalize scalar flux and update volumes | ||
| normalize_scalar_flux_and_volumes(); | ||
|
|
||
| // Add source to scalar flux | ||
| // Add source to scalar flux, compute number of FSR hits | ||
| int64_t n_hits = add_source_to_scalar_flux(); | ||
|
|
||
| // Compute k-eff | ||
| // Compute random ray k-eff | ||
| k_eff = compute_k_eff(k_eff); | ||
|
|
||
| // Store random ray k-eff into OpenMC's native k-eff variable | ||
| global_tally_tracklength = k_eff; | ||
|
|
||
| // Tally fission rates | ||
| // Execute all tallying tasks, if this is an active batch | ||
| if (simulation::current_batch > settings::n_inactive) { | ||
|
|
||
| // Create tally tasks for all source regions | ||
| // Generate mapping between source regions and tallies | ||
| if (!mapped_all_tallies) { | ||
| mapped_all_tallies = convert_source_regions_to_tallies(); | ||
| } | ||
|
|
||
| // Use above mapping to contribute FSR flux data to appropriate tallies | ||
| random_ray_tally(); | ||
| } | ||
|
|
||
| // Set phi_old = phi_new | ||
| random_ray::scalar_flux_old.swap(random_ray::scalar_flux_new); | ||
|
|
||
| // Check for any obvious insabilities/nans/infs | ||
| instability_check(n_hits, k_eff, avg_miss_rate); | ||
|
|
||
| // Finalize the current batch | ||
| finalize_generation(); | ||
|
|
||
| finalize_batch(); | ||
| } | ||
| } // End random ray power iteration loop | ||
|
|
||
| openmc::simulation::time_total.stop(); | ||
|
|
||
| // Finalize OpenMC | ||
| openmc_simulation_finalize(); | ||
|
|
||
| // Print random ray results | ||
| print_results_random_ray(total_geometric_intersections, avg_miss_rate/settings::n_batches); | ||
|
|
||
| return 0; | ||
|
jtramm marked this conversation as resolved.
Resolved
|
||
|
|
@@ -291,21 +312,21 @@ int64_t add_source_to_scalar_flux() | |
| int64_t idx = (sr * negroups) + e; | ||
|
|
||
| // There are three scenarios we need to consider: | ||
|
|
||
| if (was_cell_hit) { | ||
| // If it was hit, then finish computing the scalar flux estimate for the iteration | ||
| // 1. If the FSR was hit this iteration, then the new flux is equal to the flat source from the previous iteration | ||
| // plus the contributions from rays passing through the source region (computed during the transport sweep) | ||
| float Sigma_t = data::mg.macro_xs_[material].get_xs(MgxsType::TOTAL, e, nullptr, nullptr, nullptr, t, a); | ||
| random_ray::scalar_flux_new[idx] /= (Sigma_t * volume); | ||
| random_ray::scalar_flux_new[idx] += random_ray::source[idx]; | ||
| } else if (volume == 0.0) { | ||
| // If it was not hit this iteration, and the simulation averaged volume is still 0, | ||
| // then it has never been hit. In this case, just set it to 0 | ||
| random_ray::scalar_flux_new[idx] = 0.f; | ||
| } else if (volume > 0.0) { | ||
| // 2. If the FSR was not hit this iteration, but has been hit some previous iteration, then we simply set the | ||
| // new scalar flux to be equal to the contribution from the flat source alone. | ||
| random_ray::scalar_flux_new[idx] = random_ray::source[idx]; | ||
| } else { | ||
| // If it was not hit this iteration, but the simulation averaged volume is nonzero, | ||
| // then we can reuse the previous iteration's estimate of the scalar flux. This | ||
| // induces a small amount of error, but may be beneficial for maintaining stability | ||
| // when the ray density is extremely low. | ||
| random_ray::scalar_flux_new[idx] = random_ray::scalar_flux_old[idx]; | ||
| // If the FSR was not hit this iteration, and it has never been hit in any iteration (i.e., volume is zero), | ||
| // then we want to set this to 0 to avoid dividing anything by a zero volume. | ||
| random_ray::scalar_flux_new[idx] = 0.f; | ||
| } | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a very interesting approach, and not something we looked at in Ben's transport theory class. I always assumed you need to run enough rays to hit each source region, so this is very neat!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it's surprising how many FSRs you can miss and get away with! It remains stable even missing like 30% of the FSRs each iteration (though becomes a bit inefficient at that point due to static iteration costs).
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be mentioned in some documentation, since IIRC this was not specifically highlighted in your JCP paper! It's very important for a user to consider when setting up the calculation.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is now discussed in the docs (in the user guide -> random ray section -> ray density subsection). |
||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.