diff --git a/openmc/capi/core.py b/openmc/capi/core.py index 53c3c32bd6..fa6517488d 100644 --- a/openmc/capi/core.py +++ b/openmc/capi/core.py @@ -62,6 +62,18 @@ def calculate_volumes(): _dll.openmc_calculate_volumes() +def current_batch(): + """Return the current batch of the simulation. + + Returns + ------- + int + Current batch of the simulation + + """ + return c_int.in_dll(_dll, 'openmc_current_batch').value + + def finalize(): """Finalize simulation and free memory""" _dll.openmc_finalize() @@ -214,6 +226,18 @@ def keff(): return (mean, std_dev) +def master(): + """Return whether processor is master processor or not. + + Returns + ------- + bool + Whether is master processor or not + + """ + return c_bool.in_dll(_dll, 'openmc_master').value + + def next_batch(): """Run next batch. diff --git a/openmc/capi/settings.py b/openmc/capi/settings.py index 1063d6463e..115962395d 100644 --- a/openmc/capi/settings.py +++ b/openmc/capi/settings.py @@ -1,4 +1,5 @@ -from ctypes import c_int, c_int32, c_int64, c_double, c_char_p, POINTER +from ctypes import (c_int, c_int32, c_int64, c_double, c_char_p, c_bool, + POINTER) from . import _dll from .core import _DLLGlobal @@ -17,9 +18,11 @@ _dll.openmc_get_seed.restype = c_int64 class _Settings(object): # Attributes that are accessed through a descriptor batches = _DLLGlobal(c_int32, 'n_batches') + entropy_on = _DLLGlobal(c_bool, 'entropy_on') generations_per_batch = _DLLGlobal(c_int32, 'gen_per_batch') inactive = _DLLGlobal(c_int32, 'n_inactive') particles = _DLLGlobal(c_int64, 'n_particles') + run_CE = _DLLGlobal(c_bool, 'run_CE') verbosity = _DLLGlobal(c_int, 'verbosity') @property diff --git a/src/cmfd_data.F90 b/src/cmfd_data.F90 index ec07a4d04c..ef85949b9c 100644 --- a/src/cmfd_data.F90 +++ b/src/cmfd_data.F90 @@ -265,39 +265,39 @@ contains ! Left surface cmfd % current(1,h,i,j,k) = t % results(RESULT_SUM, 1, & - score_index + OUT_LEFT) + score_index + 1 + ng*(OUT_LEFT - 1)) cmfd % current(2,h,i,j,k) = t % results(RESULT_SUM, 1, & - score_index + IN_LEFT) + score_index + 1 + ng*(IN_LEFT - 1)) ! Right surface cmfd % current(3,h,i,j,k) = t % results(RESULT_SUM, 1, & - score_index + IN_RIGHT) + score_index + 1 + ng*(IN_RIGHT - 1)) cmfd % current(4,h,i,j,k) = t % results(RESULT_SUM, 1, & - score_index + OUT_RIGHT) + score_index + 1 + ng*(OUT_RIGHT - 1)) ! Back surface cmfd % current(5,h,i,j,k) = t % results(RESULT_SUM, 1, & - score_index + OUT_BACK) + score_index + 1 + ng*(OUT_BACK - 1)) cmfd % current(6,h,i,j,k) = t % results(RESULT_SUM, 1, & - score_index + IN_BACK) + score_index + 1 + ng*(IN_BACK - 1)) ! Front surface cmfd % current(7,h,i,j,k) = t % results(RESULT_SUM, 1, & - score_index + IN_FRONT) + score_index + 1 + ng*(IN_FRONT - 1)) cmfd % current(8,h,i,j,k) = t % results(RESULT_SUM, 1, & - score_index + OUT_FRONT) + score_index + 1 + ng*(OUT_FRONT - 1)) ! Left surface cmfd % current(9,h,i,j,k) = t % results(RESULT_SUM, 1, & - score_index + OUT_BOTTOM) + score_index + 1 + ng*(OUT_BOTTOM - 1)) cmfd % current(10,h,i,j,k) = t % results(RESULT_SUM, 1, & - score_index + IN_BOTTOM) + score_index + 1 + ng*(IN_BOTTOM - 1)) ! Right surface cmfd % current(11,h,i,j,k) = t % results(RESULT_SUM, 1, & - score_index + IN_TOP) + score_index + 1 + ng*(IN_TOP - 1)) cmfd % current(12,h,i,j,k) = t % results(RESULT_SUM, 1, & - score_index + OUT_TOP) + score_index + 1 + ng*(OUT_TOP - 1)) else if (ital == 4) then diff --git a/src/cmfd_execute.cpp b/src/cmfd_execute.cpp index 7774cfe1d2..740c1f51f0 100644 --- a/src/cmfd_execute.cpp +++ b/src/cmfd_execute.cpp @@ -25,8 +25,6 @@ cmfd_populate_sourcecounts(int n_energy, const double* energies, auto& m = meshes.at(index_cmfd_mesh); xt::xarray counts = m->count_sites(openmc_work, source_bank, n_energy, energies, outside); - std::cout << counts << "\n"; - // Copy data from the xarray into the source counts array std::copy(counts.begin(), counts.end(), source_counts); } diff --git a/src/cmfd_solver.F90 b/src/cmfd_solver.F90 index 99d482480a..01404d9b0e 100644 --- a/src/cmfd_solver.F90 +++ b/src/cmfd_solver.F90 @@ -146,8 +146,13 @@ contains call loss % assemble() call prod % assemble() if (cmfd_write_matrices) then - call loss % write('loss.dat') - call prod % write('prod.dat') + if (adjoint) then + call loss % write('adj_loss.dat') + call prod % write('adj_prod.dat') + else + call loss % write('loss.dat') + call prod % write('prod.dat') + end if end if ! Set norms to 0 @@ -740,7 +745,7 @@ contains else filename = 'fluxvec.dat' end if - ! TODO: call phi_n % write(filename) + call phi_n % write(filename) end if end subroutine extract_results diff --git a/src/simulation.F90 b/src/simulation.F90 index 176dfb921b..b1087e21d2 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -87,13 +87,6 @@ contains call initialize_batch() - ! 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 @@ -204,10 +197,12 @@ contains ! Reset total starting particle weight used for normalizing tallies total_weight = ZERO - if (n_inactive > 0 .and. current_batch == 1) then + if ((n_inactive > 0 .and. current_batch == 1) .or. & + (restart_run .and. restart_batch < n_inactive .and. current_batch == restart_batch + 1)) then ! Turn on inactive timer call time_inactive % start() - elseif (current_batch == n_inactive + 1) then + elseif ((current_batch == n_inactive + 1) .or. & + (restart_run .and. restart_batch > n_inactive .and. current_batch == restart_batch + 1)) then ! Switch from inactive batch timer to active batch timer call time_inactive % stop() call time_active % start() @@ -386,46 +381,6 @@ contains end subroutine finalize_batch -!=============================================================================== -! REPLAY_BATCH_HISTORY displays keff and entropy for each generation within a -! batch using data read from a state point file -!=============================================================================== - - subroutine replay_batch_history - - ! Write message at beginning - if (current_batch == 1) then - call write_message("Replaying history from state point...", 6) - end if - - if (run_mode == MODE_EIGENVALUE) then - do current_gen = 1, gen_per_batch - call calculate_average_keff() - - ! print out batch keff - if (verbosity >= 7) then - if (current_gen < gen_per_batch) then - if (master) call print_generation() - else - if (master) call print_batch_keff() - end if - end if - end do - end if - - ! Increment n_realizations as would ordinarily be done in finalize_batch - if (reduce_tallies) then - n_realizations = n_realizations + 1 - else - n_realizations = n_realizations + n_procs - end if - - ! Write message at end - if (current_batch == restart_batch) then - call write_message("Resuming simulation...", 6) - end if - - end subroutine replay_batch_history !=============================================================================== ! INITIALIZE_SIMULATION @@ -489,23 +444,11 @@ contains ! file if (restart_run) then call load_state_point() + call write_message("Resuming simulation...", 6) else call initialize_source() end if - ! In restart, set the batch to begin from in order to reproduce the correct - ! average keff (used in sampling the fission bank). Use n_realizations from - ! the statepoint rather than n_inactive in case openmc_reset was called in - ! the previous run. - if (restart_run) then - if (reduce_tallies) then - current_batch = restart_batch - n_realizations - else - current_batch = restart_batch - n_realizations*n_procs - end if - n_realizations = 0 - end if - ! Display header if (master) then if (run_mode == MODE_FIXEDSOURCE) then diff --git a/src/state_point.F90 b/src/state_point.F90 index 526066c529..91d0f10908 100644 --- a/src/state_point.F90 +++ b/src/state_point.F90 @@ -16,7 +16,7 @@ module state_point use bank_header, only: Bank use cmfd_header use constants - use eigenvalue, only: openmc_get_keff + use eigenvalue, only: openmc_get_keff, k_sum use endf, only: reaction_name use error, only: fatal_error, warning, write_message use hdf5_interface @@ -749,6 +749,20 @@ contains ! Read number of realizations for global tallies call read_dataset(n_realizations, file_id, "n_realizations", indep=.true.) + ! Set k_sum, keff, and current_batch based on whether restart file is part + ! of active cycle or inactive cycle + if (restart_batch > n_inactive) then + do i = n_inactive + 1, restart_batch + k_sum(1) = k_sum(1) + k_generation % data(i) + k_sum(2) = k_sum(2) + k_generation % data(i)**2 + end do + n = gen_per_batch*n_realizations + keff = k_sum(1) / n + else + keff = k_generation % data(n) + end if + current_batch = restart_batch + ! Check to make sure source bank is present if (path_source_point == path_state_point .and. .not. source_present) then call fatal_error("Source bank must be contained in statepoint restart & diff --git a/src/tallies/tally_header.F90 b/src/tallies/tally_header.F90 index 367214a930..db84056812 100644 --- a/src/tallies/tally_header.F90 +++ b/src/tallies/tally_header.F90 @@ -280,6 +280,7 @@ contains end subroutine tally_allocate_results + function tally_set_filters(this, filter_indices) result(err) class(TallyObject), intent(inout) :: this integer(C_INT32_T), intent(in) :: filter_indices(:) @@ -1025,6 +1026,7 @@ contains end if end function openmc_tally_set_scores + function openmc_tally_set_type(index, type) result(err) bind(C) ! Update the type of a tally that is already allocated integer(C_INT32_T), value, intent(in) :: index diff --git a/src/vector_header.F90 b/src/vector_header.F90 index 1ada0fba74..fd7726c79e 100644 --- a/src/vector_header.F90 +++ b/src/vector_header.F90 @@ -14,7 +14,7 @@ module vector_header procedure :: destroy => vector_destroy procedure :: add_value => vector_add_value procedure :: copy => vector_copy - ! TODO: procedure :: write => vector_write + procedure :: write => vector_write end type Vector contains @@ -88,4 +88,26 @@ contains end subroutine vector_copy +!=============================================================================== +! VECTOR_WRITE writes a vector to file +!=============================================================================== + + subroutine vector_write(self, filename) + + class(Vector), target, intent(inout) :: self ! vector instance + character(*), intent(in) :: filename ! filename to output to + + integer :: unit_ + integer :: i + + open(newunit=unit_, file=filename) + + do i = 1, self % n + write(unit_,*) i, self % data(i) + end do + + close(unit_) + + end subroutine vector_write + end module vector_header diff --git a/tests/unit_tests/test_capi.py b/tests/unit_tests/test_capi.py index 9d3bc106d2..ae2d927191 100644 --- a/tests/unit_tests/test_capi.py +++ b/tests/unit_tests/test_capi.py @@ -375,13 +375,13 @@ def test_restart(capi_init): openmc.capi.next_batch() keff0 = openmc.capi.keff() - # Restart the simulation from the statepoint and the 5 active batches. + # Restart the simulation from the statepoint and the 3 remaining active batches. openmc.capi.simulation_finalize() openmc.capi.hard_reset() openmc.capi.finalize() openmc.capi.init(args=('-r', 'restart_test.h5')) openmc.capi.simulation_init() - for i in range(5): + for i in range(3): openmc.capi.next_batch() keff1 = openmc.capi.keff() openmc.capi.simulation_finalize()