! #define PRINTINFO module libxbeach_module use iso_c_binding, only: c_int, c_char use params, only: parameters use spaceparamsdef, only: spacepars use timestep_module, only: timepars use ship_module, only: ship use vegetation_module, only: veggie implicit none private public executestep, outputext, final, init, getversion public par, tpar, s, sglobal #ifdef USEMPI public slocal #endif save type(parameters) :: par type(timepars) :: tpar type(spacepars), pointer :: s type(spacepars), target :: sglobal type(ship), dimension(:), pointer :: sh integer :: n,it,error real*8 :: tbegin #ifdef USEMPI type(spacepars), target :: slocal real*8 :: t0,t01 logical :: toall = .true. logical :: end_program #endif !startinit !-----------------------------------------------------------------------------! ! Initialize program ! !-----------------------------------------------------------------------------! contains integer(c_int) function init() use params, only: params_inio, all_input use spaceparams, only: space_alloc_scalars, ranges_init use xmpi_module, only: xmaster use initialize_module, only: drifter_init, wave_init, sed_init, flow_init, discharge_init use initialize_module, only: setbathy_init, grid_bathy use readtide_module, only: readtide use readwind_module, only: readwind use beachwizard_module, only: bwinit use timestep_module, only: timestep_init use logging_module, only: writelog use groundwaterflow, only: gw_init use logging_module, only: start_logfiles, writelog_startup use means_module, only: means_init use output_module, only: output_init, output use ship_module, only: ship_init use nonh_module, only: nonh_init use vegetation_module, only: veggie_init use paramsconst #ifdef USEMPI use xmpi_module, only: xomaster, xmpi_barrier, xmpi_wtime, xmpi_proc_null use xmpi_module, only: xmpi_initialize, xmpi_determine_processor_grid use logging_module, only: writelog_mpi use spaceparams, only: space_alloc_arrays_dummies, space_distribute_space use params, only: distribute_par #ifdef printsummary use xmpi_module, only: xmpi_imaster, xmpi_omaster use xmpi_module, only: xmpi_highx, xmpi_highy, xmpi_lowx, xmpi_lowy, xmpi_orank, xmpi_osize use xmpi_module, only: xmpi_pcol, xmpi_prow, xmpi_rank, xmpi_send use spaceparamsdef, only: manage_highx, manage_highy, manage_lowx, manage_lowy #endif #ifdef printsummary integer :: rank,i integer, dimension(12) :: info character(256) :: line integer :: rank #endif #endif error = 0 n = 0 ! setup of MPI #ifdef USEMPI s=>slocal call xmpi_initialize call xmpi_barrier(toall) t0 = xMPI_Wtime() #endif ! create log files call start_logfiles(error) ! set starting time and date call cpu_time(tbegin) ! show statup message call writelog_startup() !-----------------------------------------------------------------------------! ! Initialize simulation ! !-----------------------------------------------------------------------------! ! initialize time counter it = 0 ! read input from params.txt params_inio = .false. call all_input(par) ! allocate space scalars call space_alloc_scalars(sglobal) s => sglobal ! read grid and bathymetry call grid_bathy(s,par) ! distribute grid over processors #ifdef USEMPI call xmpi_determine_processor_grid(s%nx,s%ny,par%mpiboundary,par%mmpi,par%nmpi,par%cyclic,error) #ifdef PRINTINFO ! print information about the neighbours of the processes info = 0 info(1) = xmpi_orank info(2) = xmpi_rank info(3) = xmpi_prow info(4) = xmpi_pcol info(5) = xmpi_lowy info(6) = xmpi_highy info(7) = xmpi_lowx info(8) = xmpi_highx if(manage_lowy) info(9) = 1 if(manage_highy) info(10) = 1 if(manage_lowx) info(11) = 1 if(manage_highx) info(12) = 1 do i=5,8 if(info(i) .eq. xMPI_PROC_NULL) then info(i) = -99 endif enddo call writelog("ls"," "," ranks and neigbours (-99 means: no neighbour):") call writelog("ls"," ",' ') call writelog("ls"," "," orank rank pcol prow left right top bot islowy ishighy islowx ishighx") do rank = 0,xmpi_osize-1 if (rank .ne. xmpi_omaster) then call xmpi_send(rank,xmpi_imaster,info) if (xmaster) then write(line,'(i5,i5,i5,i5,i5,i6,i5,i5,i7,i8,i6,i6)') info endif call writelog("ls"," ",trim(line)) endif enddo call writelog("ls"," ",' ') #endif call writelog_mpi(par%mpiboundary,error) #endif ! initialize timestep call timestep_init(par, tpar) if (xmaster) then call writelog('ls','','Initializing .....') endif call setbathy_init (s,par) ! initialize physics call readtide (s,par) call readwind (s,par) call flow_init (s,par) call discharge_init (s,par) call drifter_init (s,par) call wave_init (s,par) call gw_init (s,par) ! TODO, fix ordening of arguments.... call bwinit (s) ! works only on master process call sed_init (s,par) call ship_init (s,par,sh) ! always need to call initialise in order ! to reserve memory on MPI subprocesses. ! Note: if par%ships==0 then don't allocate ! and read stuff for sh structures call veggie_init (s,par) #ifdef USEMPI call distribute_par(par) s => slocal ! ! here an hack to ensure that sglobal is populated, also on ! the not-(o)master processes, just to get valid addresses. ! if (.not. xmaster .and. .not. xomaster) then !nxbak = sglobal%nx !nybak = sglobal%ny !sglobal%nx=0 !sglobal%ny=0 call space_alloc_arrays_dummies(sglobal) !sglobal%nx = nxbak !sglobal%ny = nybak endif call space_distribute_space (sglobal,s,par ) #endif call ranges_init(s,par) ! nonh_init does not always need to be called if (par%wavemodel==WAVEMODEL_NONH) call nonh_init(s,par) ! initialize output call means_init (sglobal,s,par ) call output_init (sglobal,s,par,tpar) ! store first timestep ! from this point on, xomaster will hang in subroutine output ! until a broadcast .true. is received call output(sglobal,s,par,tpar) init = 0 end function init integer(c_int) function outputext() use output_module, only: output, output_error ! store first timestep call output(sglobal,s,par,tpar,.false.) outputext = 0 ! to quiet the compiler if(error==0) then outputext = 0 elseif(error==1) then call output_error(s,sglobal,par,tpar) outputext = 1 endif end function outputext !-----------------------------------------------------------------------------! ! Start simulation ! !-----------------------------------------------------------------------------! !_____________________________________________________________________________ integer(c_int) function executestep(dt) use loopcounters_module, only: execute_counter use xmpi_module, only: xcompute use drifter_module, only: drifter use flow_timestep_module, only: flow use boundaryconditions, only: wave_bc, flow_bc use morphevolution, only: bed_update, setbathy_update, transus use wave_timestep_module, only: wave use timestep_module, only: timestep, outputtimes_update use groundwaterflow, only: gw_bc, gwflow use beachwizard_module, only: assim, assim_update use ship_module, only: shipwave use vegetation_module, only: vegatt use wetcells_module, only: compute_wetcells use output_module, only: log_progress use paramsconst #ifdef USEMPI use xmpi_module, only: xmpi_barrier, xmpi_wtime #endif real*8, optional :: dt #ifdef USEMPI if (execute_counter .eq. 1) then ! exclude first pass from time measurement call xmpi_barrier t01 = xMPI_Wtime() endif #endif execute_counter = execute_counter + 1 executestep = -1 ! determine timestep if(xcompute) then ! determine this time step's wet points call compute_wetcells(s,par) ! ! determine time step call timestep(s,par,tpar,it,dt=dt,ierr=error) call outputtimes_update(par, tpar) ! update log call log_progress(par) if (error==0) then ! ! Boundary conditions call wave_bc (sglobal,s,par) if (par%gwflow==1) call gw_bc (s,par) if ((par%flow==1).or.(par%wavemodel==WAVEMODEL_NONH)) call flow_bc (s,par) ! ! Compute timestep if (par%ships==1) call shipwave (s,par,sh) if (par%swave==1) call wave (s,par) if (par%vegetation==1) call vegatt (s,par) if (par%gwflow==1) call gwflow (s,par) if ((par%flow==1).or.(par%wavemodel==WAVEMODEL_NONH)) call flow (s,par) if (par%ndrifter>0) call drifter (s,par) if (par%sedtrans==1) call transus (s,par) if (par%bchwiz>0) call assim (s,par) ! Beach wizard ! ! Bed level update if ((par%morphology==1).and.(.not. par%bchwiz==1).and.(.not. par%setbathy==1)) call bed_update(s,par) if (par%bchwiz>0) call assim_update (s, par) if (par%setbathy==1) call setbathy_update(s, par) endif endif n = n + 1 executestep = 0 end function executestep !_____________________________________________________________________________ integer(c_int) function final() use logging_module, only: writelog_finalize #ifdef USEMPI use xmpi_module, only: xmpi_imaster, xmpi_omaster, xmpi_barrier, xmpi_bcast use xmpi_module, only: xmpi_send_sleep, xmpi_finalize #endif !-----------------------------------------------------------------------------! ! Finalize simulation ! !-----------------------------------------------------------------------------! #ifdef USEMPI end_program = .true. call xmpi_send_sleep(xmpi_imaster,xmpi_omaster) ! wake up omaster call xmpi_bcast(end_program,toall) call xmpi_barrier(toall) call writelog_finalize(tbegin,n,par%t,par%nx,par%ny,t0,t01) call xmpi_finalize #else call writelog_finalize(tbegin,n,par%t,par%nx,par%ny) #endif final = 0 end function final subroutine getversion(version) use version_module, only: Build_Revision character(kind=c_char,len=*),intent(inout) :: version version = Build_Revision end subroutine end module libxbeach_module #ifdef PRINTINFO #undef PRINTINFO #endif