!*------------------------------------------------------------------------------ !* FILE: !* METASWAP_COMP.FOR !* !* COPYRIGHT: 2011 !* Alterra !* !* This PROGRAM, or parts thereof, may not be reproduced, !* modified or transferred to third parties without the !* written permission of Alterra !* !*------------------------------------------------------------------------------ !* PROGRAM: !* !* SYNOPSIS: !* !* DESCRIPTION: !* See manual !* !* !------------------------------------------------------------------------------- ! SUBROUTINE MetaSWAP_initComponent ! #ifdef INCLUDE_METASWAP USE SIMVAR #endif IMPLICIT NONE ! ! Set flag for use of MetaSWAP as component #ifdef INCLUDE_METASWAP MetaSWAP_comp = .TRUE. #else write(*,*) 'Error: MetaSWAP_initComponent'; stop 1 #endif END ! !------------------------------------------------------------------------------- SUBROUTINE MetaSWAP_initSimulation(time) ! IMPLICIT NONE REAL*8 time ! input INTEGER*4 iact INTEGER*4 iter REAL*8 dt LOGICAL*4 cvg ! output LOGICAL*4 ready ! output ! call timing_tic('METASWAP','initSimulation') ! Read data for setting up simulation, check that time is within meteo period iact = 0 iter = 0 #ifdef INCLUDE_METASWAP CALL SIMGRO(iact,iter,time,dt,cvg,ready) #else write(*,*) 'Error: MetaSWAP_initSimulation'; stop 1 #endif ! call timing_toc('METASWAP','initSimulation') END ! ! !<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>< ! ! Data exchange: ! - GET initial heads from MODFLOW ! ! !------------------------------------------------------------------------------ SUBROUTINE MetaSWAP_prepareTimestep(dt) ! IMPLICIT NONE INTEGER*4 iact INTEGER*4 iter REAL*8 time REAL*8 dt LOGICAL*4 ready ! ! No actions ! END ! !------------------------------------------------------------------------------ LOGICAL FUNCTION MetaSWAP_getEndofCurrentTimestep(time_arg) ! IMPLICIT NONE INTEGER*4 iact INTEGER*4 iter REAL*8 time_arg, time REAL*8 dt LOGICAL*4 cvg ! output LOGICAL*4 ready ! ! Determine the end-time of meteo data iact = 10 iter = 0 #ifdef INCLUDE_METASWAP CALL SIMGRO(iact,iter,time,dt,cvg,ready) #else write(*,*) 'Error: MetaSWAP_getEndofCurrentTimestep'; stop 1 #endif time_arg = time MetaSWAP_getEndofCurrentTimestep = .TRUE. ! END ! !------------------------------------------------------------------------------ SUBROUTINE MetaSWAP_initTimestep(dt) ! IMPLICIT NONE INTEGER*4 iact INTEGER*4 iter REAL*8 time REAL*8 dt ! input LOGICAL*4 cvg ! output LOGICAL*4 ready ! ! If this is the first time step: ! - process initial heads from MODFLOW, do the MetaSWAP inits ! - save the initial SIMGRO state ! ! Do the simulation for the fast processes: evapotranspiration, runoff call timing_tic('METASWAP','initTimestep') iact = 1 iter = 0 #ifdef INCLUDE_METASWAP CALL SIMGRO(iact,iter,time,dt,cvg,ready) #else write(*,*) 'Error: MetaSWAP_initTimestep'; stop 1 #endif ! call timing_toc('METASWAP','initTimestep') END ! !------------------------------------------------------------------------------ SUBROUTINE MetaSWAP_prepareIter(iter) ! IMPLICIT NONE INTEGER*4 iact INTEGER*4 iter REAL*8 time REAL*8 dt LOGICAL*4 cvg ! output LOGICAL*4 ready ! ! No actions needed ! #ifdef EXCLUDE_METASWAP write(*,*) 'Error: MetaSWAP_prepareIter'; stop 1 #endif iter=iter+1 ! AL 2011-07-05 RETURN END ! !------------------------------------------------------------------------------ SUBROUTINE MetaSWAP_performIter(iter) ! IMPLICIT NONE INTEGER*4 iact INTEGER*4 iter ! input REAL*8 time REAL*8 dt LOGICAL*4 cvg ! output LOGICAL*4 ready ! ! Update the unsaturated zone ! Compute recharges and storage coefficients for MODFLOW call timing_tic('METASWAP','performIter') iact = 2 #ifdef INCLUDE_METASWAP CALL SIMGRO(iact,iter,time,dt,cvg,ready) #else write(*,*) 'Error: MetaSWAP_performIter'; stop 1 #endif ! call timing_toc('METASWAP','performIter') RETURN END ! ! !<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>< ! ! Data exchange: ! - PUT recharges to MODFLOW ! - PUT storage coefficients to MODFLOW ! !------------------------------------------------------------------------------ !<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>< ! ! Data exchange: ! - GET heads from MODFLOW ! !------------------------------------------------------------------------------ SUBROUTINE MetaSWAP_finishIter(iter,ready) ! IMPLICIT NONE INTEGER*4 iact INTEGER*4 iter REAL*8 time REAL*8 dt LOGICAL*4 cvg ! output LOGICAL*4 ready ! ! Process MODFLOW heads for update of: ! - MODFLOW net flux as seen by MetaSWAP ! - MetaSWAP groundwater level call timing_tic('METASWAP','finishIter') iact = 3 #ifdef INCLUDE_METASWAP CALL SIMGRO(iact,iter,time,dt,cvg,ready) #else write(*,*) 'Error: MetaSWAP_finishIter'; stop 1 #endif ! call timing_toc('METASWAP','finishIter') RETURN END ! !------------------------------------------------------------------------------ SUBROUTINE MetaSWAP_finishTimestep(time) ! IMPLICIT NONE INTEGER*4 iact INTEGER*4 iter REAL*8 time ! input for synchro check REAL*8 dt LOGICAL*4 cvg ! output LOGICAL*4 ready ! ! Finalize unsaturated zone ! Budget calculations ! Write data to file call timing_tic('METASWAP','finishTimestep') iact = 4 #ifdef INCLUDE_METASWAP CALL SIMGRO(iact,iter,time,dt,cvg,ready) #else write(*,*) 'Error: MetaSWAP_finishTimestep'; stop 1 #endif ! call timing_toc('METASWAP','finishTimestep') RETURN END ! !------------------------------------------------------------------------------ SUBROUTINE MetaSWAP_finishSimulation() ! IMPLICIT NONE INTEGER*4 iact INTEGER*4 iter REAL*8 time REAL*8 dt LOGICAL*4 cvg ! output LOGICAL*4 ready ! ! Finalize simulation call timing_tic('METASWAP','finishSimulation') iact = 5 #ifdef INCLUDE_METASWAP CALL SIMGRO(iact,iter,time,dt,cvg,ready) #else write(*,*) 'Error: MetaSWAP_finishSimulation'; stop 1 #endif ! call timing_toc('METASWAP','finishSimulation') RETURN END ! !------------------------------------------------------------------------------ SUBROUTINE MetaSWAP_saveState() ! IMPLICIT NONE #ifdef INCLUDE_METASWAP CALL SIMGRO_save #else write(*,*) 'Error: MetaSWAP_saveState'; stop 1 #endif ! RETURN END ! !------------------------------------------------------------------------------ SUBROUTINE MetaSWAP_restoreState() ! IMPLICIT NONE INTEGER*4 iact INTEGER*4 iter REAL*8 time REAL*8 dt LOGICAL*4 cvg ! output LOGICAL*4 ready ! iact = -1 #ifdef INCLUDE_METASWAP CALL SIMGRO(iact,iter,time,dt,cvg,ready) #else write(*,*) 'Error: MetaSWAP_restoreState'; stop 1 #endif ! RETURN END !------------------------------------------------------------------------------ SUBROUTINE MetaSWAP_saveRestore(stsave,strestore) ! IMPLICIT NONE logical, intent(in) :: stsave logical, intent(in) :: strestore ! INTEGER*4 iact ! INTEGER*4 iter ! REAL*8 time ! REAL*8 dt ! LOGICAL*4 status ! call timing_tic('METASWAP','saveRestore') #ifdef INCLUDE_METASWAP if (strestore) then write(*,*) ' RESTORE STATE: MetaSwap' call MetaSWAP_restoreState() else if (stsave) then write(*,*) ' SAVE STATE: MetaSwap' call MetaSWAP_saveState() endif #else write(*,*) 'Error: MetaSWAP_saveRestore'; stop 1 #endif ! call timing_toc('METASWAP','saveRestore') RETURN END !-----------INTERFACE ROUTINES------------------------------------------------- !> Return the number of exchange items (IDs). logical function metaswap_PutModSimNumberOfIDs(nxch) !... modules #ifdef INCLUDE_METASWAP use simvar, only: mfi ! integer*4 #endif implicit none !... arguments integer, intent(out) :: nxch !... locals logical :: retval !....................................................................... #ifdef INCLUDE_METASWAP nxch = size(mfi) #else write(*,*) 'Error: metaswap_PutModSimNumberOfIDs'; stop 1 nxch=0 #endif !if (nxch.le.0) then ! retval = .false. !else retval = .true. !end if metaswap_PutModSimNumberOfIDs = retval end function ! Put exchange IDs. logical function metaswap_PutModSimIDs(ids) !... modules #ifdef INCLUDE_METASWAP use simvar, only: mfi ! integer*4 #endif implicit none !... arguments logical :: retval integer, dimension(*), intent(out) :: ids !... locals integer :: i !....................................................................... #ifdef INCLUDE_METASWAP do i =1, size(mfi) ids(i) = mfi(i) end do #else write(*,*) 'Error: metaswap_PutModSimIDs'; stop 1 ids(1)=0 #endif retval = .true. metaswap_PutModSimIDs = retval end function !> Get MODFLOW heads. logical function metaswap_GetHeads(gwheads,nid, 1 xchIdx,xchOff,mv) !... modules #ifdef INCLUDE_METASWAP use simvar, only: hgwmod, mfi use pks_imod_utl, only: pks_imod_utl_iarmwp_xch ! PKS #endif implicit none !... arguments integer, intent(in) :: nid real, dimension(*), intent(inout) :: gwheads integer, dimension(*), intent(in) :: xchIdx integer, dimension(*), intent(in) :: xchOff real, intent(in) :: mv !... locals logical :: ok integer :: i, j, js, je, k, n !....................................................................... #ifdef INCLUDE_METASWAP n = size(mfi) if (n.ne.nid) then ok = .false. else ok = .true. end if call pks_imod_utl_iarmwp_xch(gwheads,'h') ! PKS js = 1 do i = 1, nid ! get index in receive array je = xchOff(i) if (je-js.gt.0) then write(*,*) 'Warning: svat received >1 heads' end if do j = js, je k = xchIdx(j) if (k.le.0) then ok = .false. metaswap_GetHeads = ok return end if hgwmod(i) = gwheads(k) end do js = je + 1 end do #else write(*,*) 'Error: metaswap_GetHeads'; stop 1 #endif metaswap_GetHeads = ok end function !> Put unsaturated zone flux. logical function metaswap_PutModSimUnsaturatedZoneFlux(uszflux,mv) !... modules #ifdef INCLUDE_METASWAP use pksmpi_mod,only:myrank use simvar, only: vsim, mfi, ki #endif implicit none !... arguments real, dimension(*), intent(out) :: uszflux real, intent(in) :: mv ! not used yet !... locals logical ok integer :: i, n real :: rmask ! PKS !....................................................................... #ifdef INCLUDE_METASWAP n = size(mfi) !... checks: to do ok = .true. !... copy unsaturated zone flux do i = 1, size(mfi) uszflux(i) = vsim(i) call pks7mpimsiarmwpmask(mfi(i),ki(i),rmask) ! PKS uszflux(i) = rmask*uszflux(i) ! PKS end do #else write(*,*) 'Error: metaswap_PutModSimUnsaturatedZoneFlux'; stop 1 uszflux(1)=1 #endif metaswap_PutModSimUnsaturatedZoneFlux = ok end function !> Put unsaturated zone flux. logical function metaswap_PutSimMozUnsaturatedZoneFlux(uszflux,mv) !... modules #ifdef INCLUDE_METASWAP use simvar, only: vsim, nuomilsw, klswi #endif implicit none !... arguments real, dimension(*), intent(out) :: uszflux real, intent(in) :: mv ! not used yet !... locals logical ok integer :: i, n !....................................................................... !... checks: to do ok = .true. !... copy unsaturated zone flux #ifdef INCLUDE_METASWAP do i = 1, nuomilsw uszflux(i) = vsim(klswi(i)) end do #else write(*,*) 'Error: metaswap_PutSimMozUnsaturatedZoneFlux'; stop 1 uszflux(1)=0 #endif metaswap_PutSimMozUnsaturatedZoneFlux = ok end function logical function metaswap_PutStorageFactor(strfct,mv) !... modules #ifdef INCLUDE_METASWAP use simvar, only: sc1sim, mfi #endif implicit none !... arguments real, dimension(*), intent(out) :: strfct real, intent(in) :: mv ! not used yet !... locals logical :: ok integer :: i, n !....................................................................... !... checks: to do ok = .true. #ifdef INCLUDE_METASWAP n = size(mfi) do i = 1, size(mfi) strfct(i) = sc1sim(i) end do #else write(*,*) 'Error: metaswap_PutStorageFactor'; stop 1 strfct(1)=0 #endif metaswap_PutStorageFactor = ok end function logical function metaswap_PutModMozNumberOfIDs(nid) !... modules #ifdef INCLUDE_METASWAP use simvar, only: nuomilsw #endif implicit none !... arguments integer, intent(out) :: nid !... locals logical :: ok !....................................................................... #ifdef INCLUDE_METASWAP if (nuomilsw.le.0) then ok = .false. metaswap_PutModMozNumberOfIDs = ok return end if nid = nuomilsw #else write(*,*) 'Error: metaswap_PutModMozNumberOfIDs'; stop 1 nid=0 #endif ok = .true. metaswap_PutModMozNumberOfIDs = ok end function logical function metaswap_PutModMozIDs(ids) !... modules #ifdef INCLUDE_METASWAP use simvar, only: nuomilsw, lswi #endif implicit none !... arguments integer, dimension(*), intent(out) :: ids !... locals logical :: ok integer :: i !....................................................................... #ifdef INCLUDE_METASWAP do i = 1, nuomilsw ids(i) = lswi(i) end do #else write(*,*) 'Error: metaswap_PutModMozIDs'; stop 1 ids(1)=0 #endif ok = .true. metaswap_PutModMozIDs = ok end function logical function MetaSWAP_PutCumSWSprinklingDemandFluxes(sprflux, 1 mvin) !... modules #ifdef INCLUDE_METASWAP use simvar, only: nuomilsw, cupsswdemm3i #endif implicit none !... arguments real, dimension(*), intent(out) :: sprflux real, intent(in) :: mvin !... parameters real, parameter :: mv = -9999. ! In the future this should be defined by MetaSWAP ! !... locals logical :: ok integer :: i real :: flux !....................................................................... ok = .true. #ifdef INCLUDE_METASWAP if (nuomilsw.le.0) ok = .false. do i = 1, nuomilsw flux = cupsswdemm3i(i) if (flux.eq.mv) flux = mvin sprflux(i) = flux end do #else write(*,*) 'Error: MetaSWAP_PutCumSWSprinklingDemandFluxes' stop 1 sprflux(1)=0. #endif MetaSWAP_PutCumSWSprinklingDemandFluxes = ok end function logical function MetaSWAP_PutCumRunonFluxes(runonflux,mvin) !... modules #ifdef INCLUDE_METASWAP use simvar, only: nuomilsw, cuqrunm3i #endif implicit none !... arguments real, dimension(*), intent(out) :: runonflux real, intent(in) :: mvin !... parameters real, parameter :: mv = -9999.! In the future this should be defined by MetaSWAP ! !... locals logical :: ok integer :: i real :: flux !....................................................................... ok = .true. #ifdef INCLUDE_METASWAP if (nuomilsw.le.0) ok = .false. do i = 1, nuomilsw flux = cuqrunm3i(i) if (flux.eq.mv) flux = mvin runonflux(i) = flux end do #else write(*,*) 'Error: MetaSWAP_PutCumRunonFluxes'; stop 1 runonflux(1)=0. #endif MetaSWAP_PutCumRunonFluxes = ok end function !> Get MOZART fractions. logical function metaswap_GetFractions(fractions,nid, 1 xchIdx,xchOff,mvin) !... modules #ifdef INCLUDE_METASWAP use simvar, only: frpsswi, lswi #endif implicit none !... arguments integer, intent(in) :: nid real, dimension(*), intent(in) :: fractions integer, dimension(*), intent(in) :: xchIdx integer, dimension(nid), intent(in) :: xchOff real, intent(in) :: mvin !... parameters real, parameter :: mv = -9999. ! MetaSWAP missing value: in future this should be set from module !... locals logical :: ok integer :: i, j, js, je, k, n real :: frc !....................................................................... #ifdef INCLUDE_METASWAP n = size(lswi) if (n.ne.nid) then ok = .false. else ok = .true. end if js = 1 do i = 1, nid ! get index in receive array je = xchOff(i) if (je-js.gt.0) 1 write(*,*) 'Warning: svat received >1 fractions' do j = js, je k = xchIdx(j) if (k.le.0) then ok = .false. metaswap_GetFractions = ok return end if frc = fractions(k) if (frc.eq.mvin) frc = mv frpsswi(i) = frc end do js = je + 1 end do #else write(*,*) 'Error: metaswap_GetFractions'; stop 1 #endif metaswap_GetFractions = ok end function !======================================================================= logical function metaswap_PutSurfacewaterTimestep(dt) !... modules #ifdef INCLUDE_METASWAP use simvar, only: dtsw #endif implicit none !... arguments double precision, intent(out) :: dt !....................................................................... dt = dtsw metaswap_PutSurfacewaterTimestep = .true. end function metaswap_PutSurfacewaterTimestep !======================================================================= logical function metaswap_PutNumberOfSvats(n) !... modules #ifdef INCLUDE_METASWAP use msw1var, only: nuk #endif implicit none !... arguments integer, intent(out) :: n !....................................................................... n = nuk metaswap_PutNumberOfSvats = .true. end function metaswap_PutNumberOfSvats !======================================================================= logical function metaswap_PutSvatIDs(ids) !... modules #ifdef INCLUDE_METASWAP use msw1var, only: ek, nuk #endif implicit none !... arguments integer, dimension(:), intent(out) :: ids ! len(ids) == number of svats !... locals integer :: i logical :: lok !....................................................................... do i = 1, nuk ids(i) = ek(i) enddo lok = .true. metaswap_PutSvatIDs = lok end function metaswap_PutSvatIDs !======================================================================= logical function metaswap_Get2DWaterlevels(SurfacewaterLevels, 1 mvin) !... modules #ifdef INCLUDE_METASWAP use msw1var, only: nuk, dfm2lvswk #endif implicit none !... arguments double precision, dimension(:), intent(in) :: SurfacewaterLevels ! len(ids) == number of svats real, intent(in) :: mvin ! values ordered according to svat ID array !... locals double precision, parameter :: mv = -9999.d0 integer :: i logical :: lok double precision :: lev !....................................................................... do i = 1, nuk lev = SurfacewaterLevels(i) if (lev == dble(mvin)) then lev = mv end if dfm2lvswk(i) = lev enddo lok = .true. metaswap_Get2DWaterlevels = lok end function metaswap_Get2DWaterlevels !======================================================================= logical function MetaSWAP_PutSprinklingDemand(sprflux) !... modules #ifdef INCLUDE_METASWAP use msw1var, only: nuk use simvar, only: ts2dfmputsp !m3/dtsw #endif implicit none !... arguments double precision, dimension(:), intent(out) :: sprflux ! len(ids) == number of svats ! values ordered according to svat ID array !... locals integer :: i logical :: lok !....................................................................... do i = 1, nuk sprflux(i) = ts2dfmputsp(i) enddo lok = .true. MetaSWAP_PutSprinklingDemand = lok end function MetaSWAP_PutSprinklingDemand !======================================================================= logical function metaswap_PutPondingDeltaVolumes(delvol) !... modules #ifdef INCLUDE_METASWAP use msw1var, only: nuk use simvar, only: ts2dfmput !m3/dtsw #endif implicit none !... arguments double precision, dimension(:), intent(out) :: delvol !< len(ids) == number of svats !< units: m3 for dtsw ! values ordered according to svat ID array; delvol(i)==0.d0 means !... locals integer :: i logical :: lok double precision :: sumabsdelvol !....................................................................... sumabsdelvol = 0.d0 do i = 1, nuk delvol(i) = ts2dfmput(i) sumabsdelvol = sumabsdelvol + abs(ts2dfmput(i)) enddo !write(*,*) '@@@@@@@ sum delvol =',sumabsdelvol lok = .true. metaswap_PutPondingDeltaVolumes = lok end function metaswap_PutPondingDeltaVolumes !======================================================================= logical function MetaSWAP_GetSprinklingAllocation(sprflux, mv) !... modules #ifdef INCLUDE_METASWAP use msw1var, only: nuk use simvar, only: dfm2tsgetsp #endif implicit none !... arguments double precision, dimension(:), intent(in) :: sprflux ! len(ids) == number of svats real, intent(in) :: mv ! values ordered according to svat ID array !... locals integer :: i logical :: lok double precision :: dval !....................................................................... do i = 1, nuk dval = sprflux(i) if (dval == dble(mv)) then dval = 0.d0 end if dfm2tsgetsp(i) = dval enddo lok = .true. MetaSWAP_GetSprinklingAllocation = lok end function MetaSWAP_GetSprinklingAllocation !======================================================================= logical function MetaSWAP_GetDeltaPondingAllocation(delvol, mv) !... modules #ifdef INCLUDE_METASWAP use msw1var, only: nuk use simvar, only: ts2dfmget #endif implicit none !... arguments double precision, dimension(:), intent(in) :: delvol ! len(ids) == number of svats real, intent(in) :: mv ! values ordered according to svat ID array !... locals integer :: i logical :: lok double precision :: dval !....................................................................... do i = 1, nuk dval = delvol(i) if (dval == dble(mv)) then dval = 0.d0 end if ts2dfmget(i) = dval enddo lok = .true. MetaSWAP_GetDeltaPondingAllocation = lok end function MetaSWAP_GetDeltaPondingAllocation !======================================================================= logical function metaswap_Put2DAreas(areas) #ifdef INCLUDE_METASWAP use msw1var, only: ark, nuk #endif implicit none !... arguments double precision, dimension(:), intent(out) :: areas !... locals integer :: i logical :: lok !....................................................................... lok = .true. do i = 1, nuk areas(i) = ark(i) enddo metaswap_Put2DAreas = .true. end function metaswap_Put2DAreas !======================================================================= subroutine MetaSWAP_performSurfacewaterTimestep(idtsw) implicit none integer, intent(in) :: idtsw!< surface water timestep !... local integer :: iact !....................................................................... iact = 1 call SIMGRO_DTSW(iact,idtsw) end subroutine MetaSWAP_performSurfacewaterTimestep !======================================================================= subroutine MetaSWAP_finishSurfacewaterTimestep(idtsw) implicit none integer, intent(in) :: idtsw!< surface water timestep !... local integer :: iact !....................................................................... iact = 2 call SIMGRO_DTSW(iact,idtsw) end subroutine MetaSWAP_finishSurfacewaterTimestep !======================================================================= subroutine MetaSWAP_SW_initComponent() implicit none !... local integer :: idtsw integer :: iact !....................................................................... iact = 0 idtsw = 0 call SIMGRO_DTSW(iact,idtsw) end subroutine MetaSWAP_SW_initComponent