mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 13:45:36 -04:00
Removed TriggerDistance derived type
This commit is contained in:
parent
33db577898
commit
4d9638c643
11 changed files with 71 additions and 72 deletions
|
|
@ -190,7 +190,7 @@ should be performed. It has the following attributes/sub-elements:
|
|||
:rel_err:
|
||||
Relative error of the batch mean :math:`\frac{\sigma}{\mu}`
|
||||
|
||||
*Default*: None
|
||||
*Default*: None
|
||||
|
||||
:threshold:
|
||||
The precision trigger's convergence criterion for the
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ contains
|
|||
|
||||
! ==========================================================================
|
||||
! LOOP OVER BATCHES
|
||||
BATCH_LOOP: do current_batch = 1, max_batches
|
||||
BATCH_LOOP: do current_batch = 1, n_max_batches
|
||||
|
||||
call initialize_batch()
|
||||
|
||||
|
|
@ -228,7 +228,7 @@ contains
|
|||
MPI_COMM_WORLD, mpi_err)
|
||||
#endif
|
||||
if (satisfy_triggers .or. &
|
||||
(trigger_on .and. current_batch == max_batches)) then
|
||||
(trigger_on .and. current_batch == n_max_batches)) then
|
||||
call statepoint_batch % add(current_batch)
|
||||
end if
|
||||
|
||||
|
|
@ -243,7 +243,7 @@ contains
|
|||
call write_source_point()
|
||||
end if
|
||||
|
||||
if (master .and. current_batch == max_batches) then
|
||||
if (master .and. current_batch == n_max_batches) then
|
||||
! Make sure combined estimate of k-effective is calculated at the last
|
||||
! batch in case no state point is written
|
||||
call calculate_combined_keff()
|
||||
|
|
@ -504,7 +504,7 @@ contains
|
|||
call MPI_WAITALL(n_request, request, MPI_STATUSES_IGNORE, mpi_err)
|
||||
|
||||
! Deallocate space for bank_position on the very last generation
|
||||
if (current_batch == max_batches .and. current_gen == gen_per_batch) &
|
||||
if (current_batch == n_max_batches .and. current_gen == gen_per_batch) &
|
||||
deallocate(bank_position)
|
||||
#else
|
||||
source_bank = temp_sites(1:n_particles)
|
||||
|
|
@ -513,7 +513,7 @@ contains
|
|||
call time_bank_sendrecv % stop()
|
||||
|
||||
! Deallocate space for the temporary source bank on the last generation
|
||||
if (current_batch == max_batches .and. current_gen == gen_per_batch) &
|
||||
if (current_batch == n_max_batches .and. current_gen == gen_per_batch) &
|
||||
deallocate(temp_sites)
|
||||
|
||||
end subroutine synchronize_bank
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ contains
|
|||
|
||||
! ==========================================================================
|
||||
! LOOP OVER BATCHES
|
||||
BATCH_LOOP: do current_batch = 1, max_batches
|
||||
BATCH_LOOP: do current_batch = 1, n_max_batches
|
||||
|
||||
! In a restart run, skip any batches that have already been simulated
|
||||
if (restart_run .and. current_batch <= restart_batch) then
|
||||
|
|
@ -129,7 +129,7 @@ contains
|
|||
MPI_COMM_WORLD, mpi_err)
|
||||
#endif
|
||||
if (satisfy_triggers .or. &
|
||||
(trigger_on .and. current_batch == max_batches)) then
|
||||
(trigger_on .and. current_batch == n_max_batches)) then
|
||||
call statepoint_batch % add(current_batch)
|
||||
end if
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ module global
|
|||
use set_header, only: SetInt
|
||||
use source_header, only: ExtSource
|
||||
use tally_header, only: TallyObject, TallyMap, TallyResult
|
||||
use trigger_header, only: TriggerDistance, KTrigger
|
||||
use trigger_header, only: KTrigger
|
||||
use timer_header, only: Timer
|
||||
|
||||
#ifdef HDF5
|
||||
|
|
@ -138,29 +138,28 @@ module global
|
|||
|
||||
! Use confidence intervals for results instead of standard deviations
|
||||
logical :: confidence_intervals = .false.
|
||||
|
||||
! Whether user-specified tally precision triggers are satisfied
|
||||
logical :: satisfy_triggers = .false.
|
||||
|
||||
! The distance from convergence for user-specified tally precision triggers
|
||||
type(TriggerDistance) :: trig_dist
|
||||
|
||||
! ============================================================================
|
||||
! EIGENVALUE SIMULATION VARIABLES
|
||||
|
||||
integer(8) :: n_particles = 0 ! # of particles per generation
|
||||
integer :: n_batches ! # of batches
|
||||
integer :: max_batches ! maximum # of batches when using triggers
|
||||
integer :: n_inactive ! # of inactive batches
|
||||
integer :: n_active ! # of active batches
|
||||
integer :: gen_per_batch = 1 ! # of generations per batch
|
||||
integer :: current_batch = 0 ! current batch
|
||||
integer :: current_gen = 0 ! current generation within a batch
|
||||
integer :: overall_gen = 0 ! overall generation in the run
|
||||
integer :: n_batch_interval = 1 ! batch interval for triggers
|
||||
logical :: pred_batches = .false. ! predict batches for triggers
|
||||
logical :: trigger_on = .false. ! flag for turning triggers on/off
|
||||
type(KTrigger) :: keff_trigger ! trigger for k-effective
|
||||
|
||||
! ============================================================================
|
||||
! TALLY PRECISION TRIGGER VARIABLES
|
||||
|
||||
integer :: n_max_batches ! max # of batches
|
||||
integer :: n_batch_interval = 1 ! batch interval for triggers
|
||||
logical :: pred_batches = .false. ! predict batches for triggers
|
||||
logical :: trigger_on = .false. ! flag for turning triggers on/off
|
||||
type(KTrigger) :: keff_trigger ! trigger for k-effective
|
||||
logical :: satisfy_triggers = .false. ! whether triggers are satisfied
|
||||
|
||||
! External source
|
||||
type(ExtSource), target :: external_source
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ contains
|
|||
if (trigger_on) then
|
||||
|
||||
if (check_for_node(node_trigger, "max_batches") )then
|
||||
call get_node_value(node_trigger, "max_batches", max_batches)
|
||||
call get_node_value(node_trigger, "max_batches", n_max_batches)
|
||||
else
|
||||
call fatal_error("The max_batches must be specified with triggers")
|
||||
end if
|
||||
|
|
@ -193,7 +193,7 @@ contains
|
|||
! Get number of basic batches
|
||||
call get_node_value(node_mode, "batches", n_batches)
|
||||
if (.not. trigger_on) then
|
||||
max_batches = n_batches
|
||||
n_max_batches = n_batches
|
||||
end if
|
||||
|
||||
!Get number of inactive batches
|
||||
|
|
@ -204,8 +204,8 @@ contains
|
|||
end if
|
||||
|
||||
! Allocate array for batch keff and entropy
|
||||
allocate(k_generation(max_batches*gen_per_batch))
|
||||
allocate(entropy(max_batches*gen_per_batch))
|
||||
allocate(k_generation(n_max_batches*gen_per_batch))
|
||||
allocate(entropy(n_max_batches*gen_per_batch))
|
||||
entropy = ZERO
|
||||
|
||||
! Get the trigger information for keff
|
||||
|
|
@ -263,7 +263,7 @@ contains
|
|||
! Copy batch information
|
||||
call get_node_value(node_mode, "batches", n_batches)
|
||||
if (.not. trigger_on) then
|
||||
max_batches = n_batches
|
||||
n_max_batches = n_batches
|
||||
end if
|
||||
n_active = n_batches
|
||||
n_inactive = 0
|
||||
|
|
@ -3000,8 +3000,8 @@ contains
|
|||
|
||||
! Get the trigger type - "variance", "std_dev" or "rel_err"
|
||||
if (check_for_node(node_trigger, "type")) then
|
||||
call get_node_value(node_trigger, "type", temp_str)
|
||||
temp_str = to_lower(temp_str)
|
||||
call get_node_value(node_trigger, "type", temp_str)
|
||||
temp_str = to_lower(temp_str)
|
||||
else
|
||||
call fatal_error("Must specify trigger type for tally " // &
|
||||
trim(to_str(t % id)) // " in tally XML file.")
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ element tallies {
|
|||
element trigger {
|
||||
(element type { xsd:string } | attribute type { xsd:string }) &
|
||||
(element threshold { xsd:double} | attribute threshold { xsd:double }) &
|
||||
(element scores { list { xsd:string { maxLength = "20" }+ } } | attribute threshold { list { xsd:string { maxLength = "20"}+ } } )?
|
||||
(element scores { list { xsd:string { maxLength = "20" }+ } } | attribute scores { list { xsd:string { maxLength = "20"}+ } } )?
|
||||
}?
|
||||
}* &
|
||||
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@
|
|||
</oneOrMore>
|
||||
</list>
|
||||
</element>
|
||||
<attribute name="threshold">
|
||||
<attribute name="scores">
|
||||
<list>
|
||||
<oneOrMore>
|
||||
<data type="string">
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ contains
|
|||
|
||||
! Set filename for state point
|
||||
filename = trim(path_output) // 'statepoint.' // &
|
||||
& zero_padded(current_batch, count_digits(max_batches))
|
||||
& zero_padded(current_batch, count_digits(n_max_batches))
|
||||
|
||||
! Append appropriate extension
|
||||
#ifdef HDF5
|
||||
|
|
@ -405,7 +405,7 @@ contains
|
|||
|
||||
! Set filename
|
||||
filename = trim(path_output) // 'source.' // &
|
||||
& zero_padded(current_batch, count_digits(max_batches))
|
||||
& zero_padded(current_batch, count_digits(n_max_batches))
|
||||
|
||||
#ifdef HDF5
|
||||
filename = trim(filename) // '.h5'
|
||||
|
|
@ -427,7 +427,7 @@ contains
|
|||
|
||||
! Set filename for state point
|
||||
filename = trim(path_output) // 'statepoint.' // &
|
||||
& zero_padded(current_batch, count_digits(max_batches))
|
||||
& zero_padded(current_batch, count_digits(n_max_batches))
|
||||
#ifdef HDF5
|
||||
filename = trim(filename) // '.h5'
|
||||
#else
|
||||
|
|
@ -523,7 +523,7 @@ contains
|
|||
#endif
|
||||
|
||||
! Transfer values to value on master
|
||||
if (current_batch == max_batches .or. satisfy_triggers) then
|
||||
if (current_batch == n_max_batches .or. satisfy_triggers) then
|
||||
global_tallies(:) % sum = global_temp(1,:)
|
||||
global_tallies(:) % sum_sq = global_temp(2,:)
|
||||
end if
|
||||
|
|
@ -595,7 +595,7 @@ contains
|
|||
|
||||
! At the end of the simulation, store the results back in the
|
||||
! regular TallyResults array
|
||||
if (current_batch == max_batches .or. satisfy_triggers) then
|
||||
if (current_batch == n_max_batches .or. satisfy_triggers) then
|
||||
tally % results(:,:) % sum = tally_temp(1,:,:)
|
||||
tally % results(:,:) % sum_sq = tally_temp(2,:,:)
|
||||
end if
|
||||
|
|
|
|||
|
|
@ -23,15 +23,21 @@ contains
|
|||
subroutine check_triggers()
|
||||
|
||||
implicit none
|
||||
integer :: n_pred_batches ! predicted # batches to satisfy all triggers
|
||||
|
||||
! Variables to reflect distance to trigger convergence criteria
|
||||
real(8) :: max_ratio ! max uncertainty/thresh ratio
|
||||
integer :: tally_id ! id for tally with max ratio
|
||||
character(len=52) :: name ! "eigenvalue" or tally score
|
||||
|
||||
integer :: n_pred_batches ! predicted # batches to satisfy all triggers
|
||||
|
||||
! Checks if current_batch is one for which the triggers must be checked
|
||||
if (current_batch < n_batches .or. (.not. trigger_on)) return
|
||||
if (mod((current_batch - n_batches), n_batch_interval) /= 0 .and. &
|
||||
current_batch /= max_batches) return
|
||||
current_batch /= n_max_batches) return
|
||||
|
||||
! Check the trigger and output the result
|
||||
call check_tally_triggers()
|
||||
call check_tally_triggers(max_ratio, tally_id, name)
|
||||
|
||||
! When trigger threshold is reached, write information
|
||||
if (satisfy_triggers) then
|
||||
|
|
@ -39,15 +45,13 @@ contains
|
|||
trim(to_str(current_batch)))
|
||||
|
||||
! When trigger is not reached write convergence info for user
|
||||
elseif (trig_dist % name == "eigenvalue") then
|
||||
elseif (name == "eigenvalue") then
|
||||
call write_message("Triggers unsatisfied, max unc./thresh. is " // &
|
||||
trim(to_str(trig_dist % max_ratio)) // " for " // &
|
||||
trim(trig_dist % name))
|
||||
trim(to_str(max_ratio)) // " for " // trim(name))
|
||||
else
|
||||
call write_message("Triggers unsatisfied, max unc./thresh. is " // &
|
||||
trim(to_str(trig_dist % max_ratio)) // " for " // &
|
||||
trim(trig_dist % name) // " in tally " // &
|
||||
trim(to_str(trig_dist % tally_id)))
|
||||
trim(to_str(max_ratio)) // " for " // trim(name) // &
|
||||
" in tally " // trim(to_str(tally_id)))
|
||||
end if
|
||||
|
||||
! If batch_interval is not set, estimate batches till triggers are satisfied
|
||||
|
|
@ -57,11 +61,11 @@ contains
|
|||
! The prediction uses the fact that tally variances are proportional
|
||||
! to 1/N where N is the number of the batches/particles
|
||||
n_batch_interval = int((current_batch-n_inactive) * &
|
||||
(trig_dist % max_ratio ** 2)) + n_inactive-n_batches + 1
|
||||
(max_ratio ** 2)) + n_inactive-n_batches + 1
|
||||
n_pred_batches = n_batch_interval + n_batches
|
||||
|
||||
! Write the predicted number of batches for the user
|
||||
if (n_pred_batches > max_batches) then
|
||||
if (n_pred_batches > n_max_batches) then
|
||||
call warning("The estimated number of batches is " // &
|
||||
trim(to_str(n_pred_batches)) // &
|
||||
" -- greater than max batches. ")
|
||||
|
|
@ -74,12 +78,17 @@ contains
|
|||
|
||||
|
||||
!===============================================================================
|
||||
! CHECK whether uncertainty reach the threshold, find the maximum
|
||||
! uncertainty/threshold ratio for all triggers
|
||||
! CHECK_TALLY_TRIGGERS checks whether uncertainties are below the threshold,
|
||||
! and finds the maximum uncertainty/threshold ratio for all triggers
|
||||
!===============================================================================
|
||||
|
||||
subroutine check_tally_triggers()
|
||||
|
||||
subroutine check_tally_triggers(max_ratio, tally_id, name)
|
||||
|
||||
! Variables to reflect distance to trigger convergence criteria
|
||||
real(8), intent(inout) :: max_ratio ! max uncertainty/thresh ratio
|
||||
integer, intent(inout) :: tally_id ! id for tally with max ratio
|
||||
character(len=52), intent(inout) :: name ! "eigenvalue" or tally score
|
||||
|
||||
integer :: i ! index in tallies array
|
||||
integer :: j ! level in tally hierarchy
|
||||
integer :: n ! loop index for nuclides
|
||||
|
|
@ -96,7 +105,7 @@ contains
|
|||
type(TriggerObject), pointer :: trigger ! tally trigger
|
||||
|
||||
! Initialize tally trigger maximum uncertainty ratio to zero
|
||||
trig_dist % max_ratio = 0
|
||||
max_ratio = 0
|
||||
|
||||
if (master) then
|
||||
|
||||
|
|
@ -123,9 +132,9 @@ contains
|
|||
else
|
||||
ratio = uncertainty / keff_trigger % threshold
|
||||
end if
|
||||
if (trig_dist % max_ratio < ratio) then
|
||||
trig_dist % max_ratio = ratio
|
||||
trig_dist % name = "eigenvalue"
|
||||
if (max_ratio < ratio) then
|
||||
max_ratio = ratio
|
||||
name = "eigenvalue"
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
|
@ -268,10 +277,10 @@ contains
|
|||
ratio = uncertainty / t % triggers(s) % threshold
|
||||
end if
|
||||
|
||||
if (trig_dist % max_ratio < ratio) then
|
||||
trig_dist % max_ratio = ratio
|
||||
trig_dist % name = t % triggers(s) % score_name
|
||||
trig_dist % tally_id = t % id
|
||||
if (max_ratio < ratio) then
|
||||
max_ratio = ratio
|
||||
name = t % triggers(s) % score_name
|
||||
tally_id = t % id
|
||||
end if
|
||||
end if
|
||||
end do NUCLIDE_LOOP
|
||||
|
|
@ -303,9 +312,9 @@ contains
|
|||
logical :: print_ebin ! should incoming energy bin be displayed?
|
||||
real(8) :: rel_err = 0.0 ! temporary relative error of result
|
||||
real(8) :: std_dev = 0.0 ! temporary standard deviration of result
|
||||
type(TallyObject), pointer :: t ! tally pointer
|
||||
type(TriggerObject) :: trigger ! tally trigger
|
||||
type(StructuredMesh), pointer :: m => null()
|
||||
type(TallyObject), pointer :: t ! surface current tally
|
||||
type(TriggerObject) :: trigger ! surface current tally trigger
|
||||
type(StructuredMesh), pointer :: m ! surface current mesh
|
||||
|
||||
! Get pointer to mesh
|
||||
i_filter_mesh = t % find_filter(FILTER_MESH)
|
||||
|
|
|
|||
|
|
@ -17,15 +17,6 @@ module trigger_header
|
|||
real(8) :: std_dev =0.0 ! temp std. dev. container
|
||||
real(8) :: rel_err =0.0 ! temp rel. err. container
|
||||
end type TriggerObject
|
||||
|
||||
!===============================================================================
|
||||
! TRIGGERDISTANCE enables the search for the max uncertainty/threshold ratio
|
||||
!===============================================================================
|
||||
type TriggerDistance
|
||||
integer :: tally_id ! id for tally with max uncertainty
|
||||
real(8) :: max_ratio = 0 ! maximum uncertainty ratio
|
||||
character(len=52) :: name ! "eigenvalue" or tally score
|
||||
end type TriggerDistance
|
||||
|
||||
!===============================================================================
|
||||
! KTRIGGER describes a user-specified precision trigger for k-effective
|
||||
|
|
|
|||
|
|
@ -583,7 +583,7 @@ class Mesh(object):
|
|||
|
||||
class Trigger(object):
|
||||
|
||||
def __init__(self, trigger_type='rel_err', threshold=1E-2):
|
||||
def __init__(self, trigger_type, threshold):
|
||||
|
||||
# Initialize Mesh class attributes
|
||||
self.trigger_type = trigger_type
|
||||
|
|
@ -595,11 +595,11 @@ class Trigger(object):
|
|||
|
||||
existing = memo.get(id(self))
|
||||
|
||||
# If this is the first time we have tried to copy this object, create a copy
|
||||
# If this is first time we have tried to copy this object, create a copy
|
||||
if existing is None:
|
||||
|
||||
clone = type(self).__new__(type(self))
|
||||
clone._ytrigger_type = self._trigger_type
|
||||
clone._trigger_type = self._trigger_type
|
||||
clone._threshold = self._threshold
|
||||
|
||||
clone._scores = []
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue