! Copyright (c) 2013-2017, 2019, 2021 Harald Klimach <harald.klimach@uni-siegen.de> ! Copyright (c) 2013-2014 Simon Zimny <s.zimny@grs-sim.de> ! Copyright (c) 2013, 2016 Verena Krupp <verena.krupp@uni-siegen.de> ! Copyright (c) 2013-2015, 2018 Kannan Masilamani <kannan.masilamani@uni-siegen.de> ! Copyright (c) 2014 Kartik Jain <kartik.jain@uni-siegen.de> ! Copyright (c) 2014-2016 Jiaxing Qi <jiaxing.qi@uni-siegen.de> ! Copyright (c) 2016 Tobias Schneider <tobias1.schneider@student.uni-siegen.de> ! Copyright (c) 2016, 2020 Peter Vitt <peter.vitt2@uni-siegen.de> ! ! Redistribution and use in source and binary forms, with or without ! modification, are permitted provided that the following conditions are met: ! ! 1. Redistributions of source code must retain the above copyright notice, this ! list of conditions and the following disclaimer. ! ! 2. Redistributions in binary form must reproduce the above copyright notice, ! this list of conditions and the following disclaimer in the documentation ! and/or other materials provided with the distribution. ! ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ! DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE ! FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ! SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER ! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ! OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ! ****************************************************************************** ! !> author: Harald Klimach !! Initialize general infrastructure settings of treelm. !! !! This module provides a central point to initialize the !! various general settings in treelm. module tem_general_module ! include aotus modules use aotus_module, only: flu_State, aot_get_val ! include treelm modules use env_module, only: rk, tem_load_env_params, io_buffer_size, & & printRuntimeInfo, init_env, fin_env, & & print_self_status, null_device, pathLen, & & stdOutUnit, labelLen use tem_aux_module, only: tem_abort use tem_abortCriteria_module, only: tem_solverAborts_type use tem_comm_module, only: tem_commpattern_type, tem_load_commpattern use tem_logging_module, only: logUnit use tem_solveHead_module, only: tem_solveHead_type, tem_init_solveHead use tem_restart_module, only: tem_restart_type use tem_timer_module, only: tem_addTimer, tem_startTimer, & & tem_stopTimer, tem_getTimerVal, & & tem_getTimerName, tem_timer_dump_glob, & & tem_timer_loadconfig_glob use tem_balance_module, only: tem_balance_type, tem_balance_load use tem_status_module, only: tem_status_type, tem_status_run_terminate use tem_comm_env_module, only: tem_comm_env_init, tem_comm_env_fin, & & tem_comm_env_type use tem_tools_module, only: tem_horizontalSpacer use tem_simControl_module, only: tem_simControl_type, tem_simControl_load, & & tem_simControl_dump, tem_simControl_start use tem_precice_module, only: precice_available, tem_precice_load use tem_sparse_comm_module, only: tem_sparse_comm_load implicit none private public :: tem_start public :: tem_finalize public :: tem_load_general public :: tem_general_type !> Global parameter type contains all general information !! needed for all solvers type tem_general_type !> General description of the deployed solver. type(tem_solveHead_type) :: solver !> contains current simulation time, timeControl, abortCriteria and !! simulation status type(tem_simControl_type) :: simControl !> MPI communication enviroment including MPI communicator. !! !!@todo HK: not sure, if this should be here! type(tem_comm_env_type) :: proc !> MPI communication pattern type. type(tem_commPattern_type) :: commPattern !> Global restart type !! !!@todo HK: not sure, if this should be here! type(tem_restart_type) :: restart !> Load balancing information. !! !!@todo HK: not sure, if this should be here! type(tem_balance_type) :: balance !> Filename for solver timing output character(len=pathLen) :: timingFile end type tem_general_type contains ! ************************************************************************** ! !> Load general treelm settings from the Lua script in conf. !! subroutine tem_load_general( me, conf, timingFile, solverAborts ) ! ---------------------------------------------------------------------- !> global general parameter type( tem_general_type ), intent(inout) :: me !> Handle to the Lua script containing the configuration. type(flu_state) :: conf !> Default timing filename provided by the caller, overwritten by config !! file. character(len=*), optional, intent(in) :: timingFile !> Solver specific abort criteria to load. !! !! See [[tem_abortCriteria_module]] for details on this additional !! abortCriteria parameters, that the solver may define to be loaded !! from the configuration. class(tem_solverAborts_type), intent(inout), optional :: solverAborts ! ---------------------------------------------------------------------- integer :: iError character(len=pathLen) :: def_timingFile ! ---------------------------------------------------------------------- if ( me%proc%isRoot ) then call tem_horizontalSpacer(fUnit = logUnit(1)) write(logUnit(1),"(A)") 'Loading general parameters:' end if ! load global enviromental parameters from config file call tem_load_env_params(conf) if ( me%proc%isRoot ) then write(logUnit(1),"(A)") 'Using '//trim(null_device)//' as null device.' if (printRuntimeInfo) then write(logUnit(1),"(A)") 'Will print run time info in the end' write(logUnit(1),"(A)") '(/proc/self/status).' else write(logUnit(1),"(A)") 'Will NOT print run time info.' end if write(logUnit(1),"(A,I0)") 'Size of the IO Buffer (MB): ', & & (io_buffer_size*8/1024/1024) end if ! load simulation name call aot_get_val( L = conf, & & key = 'simulation_name', & & val = me%solver%simName, & & ErrCode = iError, & & default = 'simulation' ) if ( me%proc%isRoot ) then write(logUnit(1),"(A)") 'Simulation Name: ' // trim( me%solver%simName ) end if ! load simulation time control call tem_simControl_load( me = me%simControl, & & conf = conf, & & solverAborts = solverAborts ) if ( me%proc%isRoot ) then call tem_simControl_dump(me = me%simControl, outUnit = logUnit(1)) end if ! Get the setting, whether to use sparse communication patterns or not. call tem_sparse_comm_load(conf) ! load communication pattern and initialize commuication ! infrastructure call tem_load_commpattern(conf = conf, me = me%commpattern) ! load timing filename if (present(timingFile)) then def_timingFile = timingFile else def_timingFile = 'timing.res' end if call aot_get_val( L = conf, & & key = 'timing_file', & & val = me%timingFile, & & default = def_timingFile, & & ErrCode = iError ) write(logUnit(1),"(A)") 'Write timings to: ' // trim( me%timingFile ) ! Get load balancing config call tem_balance_load( conf = conf, & & me = me%balance ) ! Load configuration of timer output from timer table. call tem_timer_loadconfig_glob( conf ) ! load precice if available if (precice_available) then write(logUnit(1),"(A)") 'Loading precice data' call tem_precice_load(conf = conf) end if call tem_horizontalSpacer(fUnit = logUnit(1)) end subroutine tem_load_general ! ************************************************************************ ! ! ************************************************************************ ! !> Initialize the environment. Should be the very first call in the program. !! subroutine tem_start(codeName, version, general, comm, simControl) ! ---------------------------------------------------------------------- !> name of code character(len=*), intent(in) :: codeName !> version of the code character(len=*), intent(in) :: version !> encapsulates global parameters which are common for all solvers type(tem_general_type), intent(out) :: general !> mpi communicator if it is predefined as in apesmate integer, intent(in), optional :: comm !> simulation control to initialize type(tem_simControl_type), intent(out), optional :: simControl ! ---------------------------------------------------------------------- integer :: nProcs, nThreads ! ---------------------------------------------------------------------- ! Initialize all logunits to point to the stdout unit. logunit = stdoutunit ! if comm is present initialize environment already called ! so should not be called again if(.not. present(comm)) call init_env() ! initialize mpi environment call tem_comm_env_init(general%proc, comm) nProcs = general%proc%comm_size nThreads = general%proc%nThreads ! initialize solverHead call tem_init_solveHead( me = general%solver, & & solName = codeName, & & version = version ) if (present(simControl)) call tem_simControl_start(simControl) if ( general%proc%isRoot ) then write(logUnit(1),*) "Starting up " // trim(codeName) & & // " with nprocs: ", nProcs !$ write(logUnit(1),*)" and nThreads pp: ", nThreads end if call tem_addTimer( timerHandle = general%solver%timerHandle, & & timerName = trim(codeName) ) call tem_startTimer(timerHandle = general%solver%timerHandle ) end subroutine tem_start ! ************************************************************************ ! ! ************************************************************************ ! !> Finalize the environment, should be the very last call in the program. subroutine tem_finalize(general) ! ---------------------------------------------------------------------- !> encapsulates global parameters which are common for all solvers type(tem_general_type), intent(in) :: general ! ---------------------------------------------------------------------- character(len=labelLen) :: timerName real(kind=rk) :: timerValue ! ---------------------------------------------------------------------- if ( tem_status_run_terminate(general%simControl%status) ) then call tem_abort() end if call tem_timer_dump_glob( comm = general%proc%comm, & & myrank = general%proc%rank, & & nProcs = general%proc%comm_size ) if ( general%proc%isRoot ) then if ( printRuntimeInfo ) call print_self_status() timerName = tem_getTimerName(timerHandle = general%solver%timerHandle ) timerValue = tem_getTimerVal( timerHandle = general%solver%timerHandle ) write(logUnit(1),*) write(logUnit(1),"(A,F10.2,A)") " Done with " // trim(timerName) & & // " in ", timerValue, ' s' end if ! finialize mpi call fin_env() end subroutine tem_finalize ! ************************************************************************ ! end module tem_general_module ! **************************************************************************** !