From 6080c3a9114e35b6a7a772d8bb57b34e5a42411e Mon Sep 17 00:00:00 2001 From: Shikhar Kumar Date: Wed, 15 Aug 2018 12:23:48 -0400 Subject: [PATCH] Create skeleton for cmfd execute through CAPI --- openmc/capi/core.py | 45 +++++++++++++ openmc/cmfd.py | 22 ++++++- src/simulation.F90 | 150 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 211 insertions(+), 6 deletions(-) diff --git a/openmc/capi/core.py b/openmc/capi/core.py index a1f908c1c5..a47bbf287a 100644 --- a/openmc/capi/core.py +++ b/openmc/capi/core.py @@ -39,6 +39,15 @@ _dll.openmc_get_keff.errcheck = _error_handler _dll.openmc_next_batch.argtypes = [POINTER(c_int)] _dll.openmc_next_batch.restype = c_int _dll.openmc_next_batch.errcheck = _error_handler +_dll.openmc_next_batch_before_cmfd_init.argtypes = [] +_dll.openmc_next_batch_before_cmfd_init.restype = c_int +_dll.openmc_next_batch_before_cmfd_init.errcheck = _error_handler +_dll.openmc_next_batch_between_cmfd_init_execute.argtypes = [POINTER(c_int)] +_dll.openmc_next_batch_between_cmfd_init_execute.restype = c_int +_dll.openmc_next_batch_between_cmfd_init_execute.errcheck = _error_handler +_dll.openmc_next_batch_after_cmfd_execute.argtypes = [POINTER(c_int)] +_dll.openmc_next_batch_after_cmfd_execute.restype = c_int +_dll.openmc_next_batch_after_cmfd_execute.errcheck = _error_handler _dll.openmc_plot_geometry.restype = c_int _dll.openmc_plot_geometry.restype = _error_handler _dll.openmc_run.restype = c_int @@ -225,6 +234,42 @@ def next_batch(): return status.value +def next_batch_before_cmfd_init(): + """Run everything in batch that occurs before CMFD initialized.""" + _dll.openmc_next_batch_before_cmfd_init() + + +def next_batch_between_cmfd_init_execute(): + """Run everything in batch that occurs between CMFD + initialization and execution. + + Returns + ------- + int + Status after running block (0=batch is part of restart batch so don't + run CMFD, 3=normal execution, continue with CMFD solver) + + """ + status = c_int() + _dll.openmc_next_batch_between_cmfd_init_execute(status) + return status.value + + +def next_batch_after_cmfd_execute(): + """Run next batch. + + Returns + ------- + int + Status after running a batch (0=normal, 1=reached maximum number of + batches, 2=tally triggers reached) + + """ + status = c_int() + _dll.openmc_next_batch_after_cmfd_execute(status) + return status.value + + def plot_geometry(): """Plot geometry""" _dll.openmc_plot_geometry() diff --git a/openmc/cmfd.py b/openmc/cmfd.py index cf532e28f9..84cb121e3e 100644 --- a/openmc/cmfd.py +++ b/openmc/cmfd.py @@ -824,7 +824,21 @@ class CMFDRun(object): openmc.capi.init() self._configure_cmfd() openmc.capi.simulation_init() - openmc.capi.run() + + while(True): + openmc.capi.next_batch_before_cmfd_init() + self._cmfd_init() + # Status determines whether batch should continue with a + # CMFD update or skip it entirely if it is a restart run + status = openmc.capi.next_batch_between_cmfd_init_execute() + if status != 0: + self._cmfd_execute() + # Status now determines whether another batch should be run + # or simulation should be terminated. + status = openmc.capi.next_batch_after_cmfd_execute() + if status != 0: + break + openmc.capi.simulation_finalize() openmc.capi.finalize() @@ -880,6 +894,12 @@ class CMFDRun(object): # Create tally objects self._create_cmfd_tally() + def _cmfd_init(self): + pass + + def _cmfd_execute(self): + pass + def _create_cmfd_tally(self): # Create Mesh object based on CMFDMesh, stored internally cmfd_mesh = openmc.capi.Mesh() diff --git a/src/simulation.F90 b/src/simulation.F90 index c8c9dfcf8e..fa1036fc5f 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -47,10 +47,14 @@ module simulation public :: openmc_next_batch public :: openmc_simulation_init public :: openmc_simulation_finalize + public :: openmc_next_batch_before_cmfd_init + public :: openmc_next_batch_between_cmfd_init_execute + public :: openmc_next_batch_after_cmfd_execute integer(C_INT), parameter :: STATUS_EXIT_NORMAL = 0 integer(C_INT), parameter :: STATUS_EXIT_MAX_BATCH = 1 integer(C_INT), parameter :: STATUS_EXIT_ON_TRIGGER = 2 + integer(C_INT), parameter :: STATUS_CONTINUE_BATCH = 3 contains @@ -129,6 +133,147 @@ contains end function openmc_next_batch +!=============================================================================== +! OPENMC_NEXT_BATCH_BEFORE_CMFD_INIT +!=============================================================================== + + function openmc_next_batch_before_cmfd_init() result(err) bind(C) + integer(C_INT) :: err + + err = 0 + + ! Make sure simulation has been initialized + if (.not. simulation_initialized) then + err = E_ALLOCATE + call set_errmsg("Simulation has not been initialized yet.") + return + end if + + call initialize_batch() + + end function openmc_next_batch_before_cmfd_init + +!=============================================================================== +! OPENMC_NEXT_BATCH_BETWEEN_CMFD_INIT_EXECUTE +!=============================================================================== + + function openmc_next_batch_between_cmfd_init_execute(status) result(err) bind(C) + integer(C_INT), intent(out), optional :: status + integer(C_INT) :: err + + type(Particle) :: p + integer(8) :: i_work + + err = 0 + + ! Handle restart runs + if (restart_run .and. current_batch <= restart_batch) then + call replay_batch_history() + status = STATUS_EXIT_NORMAL + return + end if + + ! ======================================================================= + ! LOOP OVER GENERATIONS + GENERATION_LOOP: do current_gen = 1, gen_per_batch + + call initialize_generation() + + ! Start timer for transport + call time_transport % start() + + ! ==================================================================== + ! LOOP OVER PARTICLES +!$omp parallel do schedule(runtime) firstprivate(p) copyin(tally_derivs) + PARTICLE_LOOP: do i_work = 1, work + current_work = i_work + + ! grab source particle from bank + call initialize_history(p, current_work) + + ! transport particle + call transport(p) + + end do PARTICLE_LOOP +!$omp end parallel do + + ! Accumulate time for transport + call time_transport % stop() + + call finalize_generation() + + end do GENERATION_LOOP + + ! Reduce tallies onto master process and accumulate + call time_tallies % start() + call accumulate_tallies() + call time_tallies % stop() + + ! Reset global tally results + if (current_batch <= n_inactive) then + global_tallies(:,:) = ZERO + n_realizations = 0 + end if + + if (present(status)) then + status = STATUS_CONTINUE_BATCH + end if + + end function openmc_next_batch_between_cmfd_init_execute + +!=============================================================================== +! OPENMC_NEXT_BATCH_AFTER_CMFD_EXECUTE +!=============================================================================== + + function openmc_next_batch_after_cmfd_execute(status) result(err) bind(C) + integer(C_INT), intent(out), optional :: status + integer(C_INT) :: err +#ifdef OPENMC_MPI + integer :: mpi_err ! MPI error code +#endif + + err = 0 + + if (run_mode == MODE_EIGENVALUE) then + ! Write batch output + if (master .and. verbosity >= 7) call print_batch_keff() + end if + + ! Check_triggers + if (master) call check_triggers() +#ifdef OPENMC_MPI + call MPI_BCAST(satisfy_triggers, 1, MPI_LOGICAL, 0, & + mpi_intracomm, mpi_err) +#endif + if (satisfy_triggers .or. & + (trigger_on .and. current_batch == n_max_batches)) then + call statepoint_batch % add(current_batch) + end if + + ! Write out state point if it's been specified for this batch + if (statepoint_batch % contains(current_batch)) then + err = openmc_statepoint_write() + end if + + ! Write out source point if it's been specified for this batch + if ((sourcepoint_batch % contains(current_batch) .or. source_latest) .and. & + source_write) then + call write_source_point() + end if + + ! Check simulation ending criteria + if (present(status)) then + if (current_batch == n_max_batches) then + status = STATUS_EXIT_MAX_BATCH + elseif (satisfy_triggers) then + status = STATUS_EXIT_ON_TRIGGER + else + status = STATUS_EXIT_NORMAL + end if + end if + + end function openmc_next_batch_after_cmfd_execute + !=============================================================================== ! INITIALIZE_HISTORY !=============================================================================== @@ -206,11 +351,6 @@ contains end do end if - ! check CMFD initialize batch - if (run_mode == MODE_EIGENVALUE) then - if (cmfd_run) call cmfd_init_batch() - end if - ! Add user tallies to active tallies list call setup_active_tallies()