! $Id: MAPL_Base.F90,v 1.8.2.3 2008/04/28 15:11:56 trayanov Exp $
#include "MAPL_ErrLog.h"
module MAPL_BaseMod 12,17
use ESMF_Mod
implicit none
private
!=============================================================================
!BOP
! !MODULE: -- A container module for global constants
! !PUBLIC PARAMETERS
integer, public, parameter :: MAPL_CplUNKNOWN = 0
integer, public, parameter :: MAPL_CplSATISFIED = 1
integer, public, parameter :: MAPL_CplNEEDED = 2
integer, public, parameter :: MAPL_CplNOTNEEDED = 4
integer, public, parameter :: MAPL_FriendlyVariable = 8
integer, public, parameter :: MAPL_FieldItem = 8
integer, public, parameter :: MAPL_BundleItem = 16
integer, public, parameter :: MAPL_NoRestart = 32
integer, public, parameter :: MAPL_Write2Disk = 0
integer, public, parameter :: MAPL_Write2RAM = 1
integer, public, parameter :: MAPL_VLocationNone = 0
integer, public, parameter :: MAPL_VLocationEdge = 1
integer, public, parameter :: MAPL_VLocationCenter = 2
integer, public, parameter :: MAPL_DimsUnknown = 0
integer, public, parameter :: MAPL_DimsVertOnly = 1
integer, public, parameter :: MAPL_DimsHorzOnly = 2
integer, public, parameter :: MAPL_DimsHorzVert = 3
integer, public, parameter :: MAPL_DimsTileOnly = 4
integer, public, parameter :: MAPL_DimsTileTile = 5
integer, public, parameter :: MAPL_DuplicateEntry = -99
integer, public, parameter :: MAPL_Self = 0
integer, public, parameter :: MAPL_Import = 1
integer, public, parameter :: MAPL_Export = 2
integer, public, parameter :: MAPL_ConnUnknown = -1
integer, public, parameter :: MAPL_RecordPhase = 99
integer, public, parameter :: MAPL_ColdstartPhase = 99
integer, public, parameter :: MAPL_FirstPhase = 81
integer, public, parameter :: MAPL_SecondPhase = MAPL_FirstPhase+1
integer, public, parameter :: MAPL_ThirdPhase = MAPL_FirstPhase+2
integer, public, parameter :: MAPL_FourthPhase = MAPL_FirstPhase+3
integer, public, parameter :: MAPL_FifthPhase = MAPL_FirstPhase+4
real, public, parameter :: MAPL_UNDEF = 1.0e15
integer, public, parameter :: MAPL_Ocean = 0
integer, public, parameter :: MAPL_Lake = 19
integer, public, parameter :: MAPL_LandIce = 20
integer, public, parameter :: MAPL_BroadleafEvergreen = 1
integer, public, parameter :: MAPL_BroadleafDeciduous = 2
integer, public, parameter :: MAPL_Needleleaf = 3
integer, public, parameter :: MAPL_GroundCover = 4
integer, public, parameter :: MAPL_BroadleafShrubs = 5
integer, public, parameter :: MAPL_Tundra = 6
integer, public, parameter :: MAPL_BareSoil = 7
integer, public, parameter :: MAPL_Desert = 8
integer, public, parameter :: MAPL_NumVegTypes = 8
integer, public, parameter :: MAPL_Land = 100
integer, public, parameter :: MAPL_Vegetated = 101
! !PUBLIC VARIABLES:
!EOP
public MAPL_ArrayF90Deallocate
type WRAP1R4
real(kind=4), dimension(:) , pointer :: ptr
end type WRAP1R4
type WRAP2R4
real(kind=4), dimension(:,:) , pointer :: ptr
end type WRAP2R4
type WRAP3R4
real(kind=4), dimension(:,:,:) , pointer :: ptr
end type WRAP3R4
type WRAP4R4
real(kind=4), dimension(:,:,:,:) , pointer :: ptr
end type WRAP4R4
type WRAP1R8
real(kind=8), dimension(:) , pointer :: ptr
end type WRAP1R8
type WRAP2R8
real(kind=8), dimension(:,:) , pointer :: ptr
end type WRAP2R8
type WRAP3R8
real(kind=8), dimension(:,:,:) , pointer :: ptr
end type WRAP3R8
type WRAP4R8
real(kind=8), dimension(:,:,:,:) , pointer :: ptr
end type WRAP4R8
public MAPL_RTRN
public MAPL_VRFY
public MAPL_ASRT
public MAPL_AllocateCoupling
public MAPL_ConnectCoupling
public MAPL_DecomposeDim
public MAPL_Interp_Fac
public MAPL_ClimInterpFac
public MAPL_PackTime
public MAPL_UnpackTime
public MAPL_TimeStringGet
public MAPL_FieldSetTime
public MAPL_FieldGetTime
public MAPL_tick
public MAPL_incymd
public MAPL_nhmsf
public MAPL_nsecf2
public MAPL_FieldCreate
public MAPL_RemapBounds
interface MAPL_FieldCreate
module procedure
module procedure
end interface
interface MAPL_FieldGetTime 1
module procedure MAPL_GetFieldTimeFromField
module procedure MAPL_GetFieldTimeFromState
end interface
interface MAPL_FieldSetTime 1
module procedure MAPL_SetFieldTimeFromField
module procedure MAPL_SetFieldTimeFromState
end interface
interface MAPL_AllocateCoupling 10
module procedure MAPL_AllocateCouplingFromArray
module procedure MAPL_AllocateCouplingFromField
end interface
interface MAPL_ConnectCoupling 1
module procedure MAPL_ConnectCouplingFromArray
module procedure MAPL_ConnectCouplingFromField
end interface
interface MAPL_RemapBounds
module procedure
end interface
interface MAPL_VRFY 1
module procedure MAPL_VRFY
module procedure
end interface
interface MAPL_ASRT 1
module procedure MAPL_ASRT
module procedure
end interface
interface MAPL_RTRN 1
module procedure MAPL_RTRN
module procedure
end interface
contains
subroutine MAPL_AllocateCouplingFromField(field, rc) 1,1
type(ESMF_Field), intent(INOUT) :: field
integer, optional, intent( OUT) :: rc
integer :: status
character(len=ESMF_MAXSTR), parameter :: IAm='MAPL_AllocateCouplingFromField'
type(ESMF_Array) :: array
#ifdef ESMF_1_0_4
call ESMF_FieldGetData (FIELD, ARRAY, RC=STATUS)
#else
call ESMF_FieldGetArray (FIELD, ARRAY, RC=STATUS)
#endif
VERIFY_(STATUS)
call MAPL_AllocateCouplingFromArray
(array, rc=STATUS)
VERIFY_(STATUS)
RETURN_(ESMF_SUCCESS)
end subroutine MAPL_AllocateCouplingFromField
subroutine MAPL_AllocateCouplingFromArray(array, rc) 2
type(ESMF_Array), intent(INOUT) :: array
integer, optional, intent( OUT) :: rc
integer :: rank
type(ESMF_DataType) :: type
type(ESMF_DataKind) :: dk
integer, dimension(ESMF_MAXDIM) :: counts, lbounds, ubounds
type(ESMF_Pointer) :: base
integer :: status
character(len=ESMF_MAXSTR), parameter :: IAm='MAPL_AllocateCouplingFromArray'
real(kind=4), dimension(:) , pointer :: r4d1
real(kind=4), dimension(:,:) , pointer :: r4d2
real(kind=4), dimension(:,:,:) , pointer :: r4d3
real(kind=4), dimension(:,:,:,:) , pointer :: r4d4
real(kind=8), dimension(:) , pointer :: r8d1
real(kind=8), dimension(:,:) , pointer :: r8d2
real(kind=8), dimension(:,:,:) , pointer :: r8d3
real(kind=8), dimension(:,:,:,:) , pointer :: r8d4
type (WRAP1R4) :: wrap1dr4
type (WRAP2R4) :: wrap2dr4
type (WRAP3R4) :: wrap3dr4
type (WRAP4R4) :: wrap4dr4
type (WRAP1R8) :: wrap1dr8
type (WRAP2R8) :: wrap2dr8
type (WRAP3R8) :: wrap3dr8
type (WRAP4R8) :: wrap4dr8
call ESMF_ArrayGet(array, rank, kind=dk, &
counts = counts, lbounds=lbounds, ubounds=ubounds, &
base=base, rc=status)
VERIFY_(STATUS)
!ALT in case the counts=0 emsf keeps ubounds=lbounds
where (counts==0) ubounds = lbounds + counts - 1
if (dk .eq. ESMF_R4) then
if (rank .eq. 1) then
call ESMF_ArrayGetData(array, r4d1, rc=status)
VERIFY_(STATUS)
if (.not. associated(r4d1)) then
allocate(r4d1(lbounds(1):ubounds(1)), stat=status)
VERIFY_(STATUS)
r4d1 = 0.0
call c_ESMC_ArraySetBaseAddr(array, r4d1, status)
VERIFY_(STATUS)
wrap1dr4%ptr => r4d1
call c_ESMC_ArraySetF90Ptr(array, wrap1dr4, status)
VERIFY_(STATUS)
endif
else if (rank .eq. 2) then
call ESMF_ArrayGetData(array, r4d2, rc=status)
VERIFY_(STATUS)
if (.not. associated(r4d2)) then
allocate(r4d2(lbounds(1):ubounds(1), &
lbounds(2):ubounds(2)), stat=status)
VERIFY_(STATUS)
r4d2 = 0.0
call c_ESMC_ArraySetBaseAddr(array, r4d2, status)
VERIFY_(STATUS)
wrap2dr4%ptr => r4d2
call c_ESMC_ArraySetF90Ptr(array, wrap2dr4, status)
VERIFY_(STATUS)
endif
else if (rank .eq. 3) then
call ESMF_ArrayGetData(array, r4d3, rc=status)
VERIFY_(STATUS)
if (.not. associated(r4d3)) then
allocate(r4d3(lbounds(1):ubounds(1), &
lbounds(2):ubounds(2), &
lbounds(3):ubounds(3)), stat=status)
VERIFY_(STATUS)
r4d3 = 0.0
call c_ESMC_ArraySetBaseAddr(array, r4d3, status)
VERIFY_(STATUS)
wrap3dr4%ptr => r4d3
call c_ESMC_ArraySetF90Ptr(array, wrap3dr4, status)
VERIFY_(STATUS)
endif
else if (rank .eq. 4) then
call ESMF_ArrayGetData(array, r4d4, rc=status)
VERIFY_(STATUS)
if (.not. associated(r4d4)) then
allocate(r4d4(lbounds(1):ubounds(1), &
lbounds(2):ubounds(2), &
lbounds(3):ubounds(3), &
lbounds(4):ubounds(4)), stat=status)
VERIFY_(STATUS)
r4d4 = 0.0
call c_ESMC_ArraySetBaseAddr(array, r4d4, status)
VERIFY_(STATUS)
wrap4dr4%ptr => r4d4
call c_ESMC_ArraySetF90Ptr(array, wrap4dr4, status)
VERIFY_(STATUS)
end if
else
RETURN_(ESMF_FAILURE)
endif
else if (dk .eq. ESMF_R8) then
if (rank .eq. 1) then
call ESMF_ArrayGetData(array, r8d1, rc=status)
VERIFY_(STATUS)
if (.not. associated(r8d1)) then
allocate(r8d1(lbounds(1):ubounds(1)), stat=status)
VERIFY_(STATUS)
r8d1 = 0.0
call c_ESMC_ArraySetBaseAddr(array, r8d1, status)
VERIFY_(STATUS)
wrap1dr8%ptr => r8d1
call c_ESMC_ArraySetF90Ptr(array, wrap1dr8, status)
VERIFY_(STATUS)
endif
else if (rank .eq. 2) then
call ESMF_ArrayGetData(array, r8d2, rc=status)
VERIFY_(STATUS)
if (.not. associated(r8d2)) then
allocate(r8d2(lbounds(1):ubounds(1), &
lbounds(2):ubounds(2)), stat=status)
VERIFY_(STATUS)
r8d2 = 0.0
call c_ESMC_ArraySetBaseAddr(array, r8d2, status)
VERIFY_(STATUS)
wrap2dr8%ptr => r8d2
call c_ESMC_ArraySetF90Ptr(array, wrap2dr8, status)
VERIFY_(STATUS)
endif
else if (rank .eq. 3) then
call ESMF_ArrayGetData(array, r8d3, rc=status)
VERIFY_(STATUS)
if (.not. associated(r8d3)) then
allocate(r8d3(lbounds(1):ubounds(1), &
lbounds(2):ubounds(2), &
lbounds(3):ubounds(3)), stat=status)
VERIFY_(STATUS)
r8d3 = 0.0
call c_ESMC_ArraySetBaseAddr(array, r8d3, status)
VERIFY_(STATUS)
wrap3dr8%ptr => r8d3
call c_ESMC_ArraySetF90Ptr(array, wrap3dr8, status)
VERIFY_(STATUS)
endif
else if (rank .eq. 4) then
call ESMF_ArrayGetData(array, r8d4, rc=status)
VERIFY_(STATUS)
if (.not. associated(r8d4)) then
allocate(r8d4(lbounds(1):ubounds(1), &
lbounds(2):ubounds(2), &
lbounds(3):ubounds(3), &
lbounds(4):ubounds(4)), stat=status)
VERIFY_(STATUS)
r8d4 = 0.0
call c_ESMC_ArraySetBaseAddr(array, r8d4, status)
VERIFY_(STATUS)
wrap4dr8%ptr => r8d4
call c_ESMC_ArraySetF90Ptr(array, wrap4dr8, status)
VERIFY_(STATUS)
end if
else
RETURN_(ESMF_FAILURE)
endif
else
RETURN_(ESMF_FAILURE)
endif
RETURN_(ESMF_SUCCESS)
end subroutine MAPL_AllocateCouplingFromArray
subroutine MAPL_ConnectCouplingFromField(field, from_field, rc) 1,1
type(ESMF_Field), intent(INOUT) :: field
type(ESMF_Field), intent(IN ) :: from_field
integer, optional, intent( OUT) :: rc
integer :: status
character(len=ESMF_MAXSTR), parameter :: IAm='MAPL_ConnectCouplingFromField'
type(ESMF_Array) :: array
type(ESMF_Array) :: from_array
#ifdef ESMF_1_0_4
call ESMF_FieldGetData (FIELD, ARRAY, RC=STATUS)
#else
call ESMF_FieldGetArray (FIELD, ARRAY, RC=STATUS)
#endif
VERIFY_(STATUS)
#ifdef ESMF_1_0_4
call ESMF_FieldGetData (FROM_FIELD, FROM_ARRAY, RC=STATUS)
#else
call ESMF_FieldGetArray (FROM_FIELD, FROM_ARRAY, RC=STATUS)
#endif
VERIFY_(STATUS)
call MAPL_ConnectCouplingFromArray
(array, from_array, rc=STATUS)
VERIFY_(STATUS)
RETURN_(ESMF_SUCCESS)
end subroutine MAPL_ConnectCouplingFromField
subroutine MAPL_ConnectCouplingFromArray(array, from_array, rc) 2
type(ESMF_Array), intent(INOUT) :: array
type(ESMF_Array), intent(IN ) :: from_array
integer, optional, intent( OUT) :: rc
integer :: rank
type(ESMF_DataType) :: type
type(ESMF_DataKind) :: dk
integer, dimension(ESMF_MAXDIM) :: counts, lbounds, ubounds
type(ESMF_Pointer) :: base
integer :: status
character(len=ESMF_MAXSTR), parameter :: IAm='MAPL_ConnectCouplingFromArray'
real(kind=4), dimension(:) , pointer :: p4d1
real(kind=4), dimension(:,:) , pointer :: p4d2
real(kind=4), dimension(:,:,:) , pointer :: p4d3
real(kind=4), dimension(:,:,:,:) , pointer :: p4d4
real(kind=4), dimension(:) , pointer :: r4d1
real(kind=4), dimension(:,:) , pointer :: r4d2
real(kind=4), dimension(:,:,:) , pointer :: r4d3
real(kind=4), dimension(:,:,:,:) , pointer :: r4d4
real(kind=8), dimension(:) , pointer :: r8d1
real(kind=8), dimension(:,:) , pointer :: r8d2
real(kind=8), dimension(:,:,:) , pointer :: r8d3
real(kind=8), dimension(:,:,:,:) , pointer :: r8d4
type (WRAP1R4) :: wrap1dr4
type (WRAP2R4) :: wrap2dr4
type (WRAP3R4) :: wrap3dr4
type (WRAP4R4) :: wrap4dr4
type (WRAP1R8) :: wrap1dr8
type (WRAP2R8) :: wrap2dr8
type (WRAP3R8) :: wrap3dr8
type (WRAP4R8) :: wrap4dr8
call ESMF_ArrayGet(array, rank, kind=dk, &
counts = counts, lbounds=lbounds, ubounds=ubounds, &
base=base, rc=status)
VERIFY_(STATUS)
where (counts==0) ubounds = lbounds + counts - 1
if (dk .eq. ESMF_R4) then
if (rank .eq. 1) then
call ESMF_ArrayGetData(from_array, p4d1, rc=status)
VERIFY_(STATUS)
call ESMF_ArrayGetData(array, r4d1, rc=status)
VERIFY_(STATUS)
if (associated(r4d1)) then
deallocate(r4d1, stat=status)
VERIFY_(STATUS)
endif
r4d1 => p4d1
call c_ESMC_ArraySetBaseAddr(array, r4d1, status)
VERIFY_(STATUS)
wrap1dr4%ptr => r4d1
call c_ESMC_ArraySetF90Ptr(array, wrap1dr4, status)
VERIFY_(STATUS)
else if (rank .eq. 2) then
call ESMF_ArrayGetData(from_array, p4d2, rc=status)
VERIFY_(STATUS)
call ESMF_ArrayGetData(array, r4d2, rc=status)
VERIFY_(STATUS)
if (associated(r4d2)) then
deallocate(r4d2, stat=status)
VERIFY_(STATUS)
endif
r4d2 => p4d2
call c_ESMC_ArraySetBaseAddr(array, r4d2, status)
VERIFY_(STATUS)
wrap2dr4%ptr => r4d2
call c_ESMC_ArraySetF90Ptr(array, wrap2dr4, status)
VERIFY_(STATUS)
else if (rank .eq. 3) then
call ESMF_ArrayGetData(from_array, p4d3, rc=status)
VERIFY_(STATUS)
call ESMF_ArrayGetData(array, r4d3, rc=status)
VERIFY_(STATUS)
if (associated(r4d3)) then
deallocate(r4d3, stat=status)
VERIFY_(STATUS)
end if
r4d3 => p4d3
call c_ESMC_ArraySetBaseAddr(array, r4d3, status)
VERIFY_(STATUS)
wrap3dr4%ptr => r4d3
call c_ESMC_ArraySetF90Ptr(array, wrap3dr4, status)
VERIFY_(STATUS)
else if (rank .eq. 4) then
call ESMF_ArrayGetData(from_array, p4d4, rc=status)
VERIFY_(STATUS)
call ESMF_ArrayGetData(array, r4d4, rc=status)
VERIFY_(STATUS)
if (associated(r4d4)) then
deallocate(r4d4, stat=status)
VERIFY_(STATUS)
end if
r4d4 => p4d4
call c_ESMC_ArraySetBaseAddr(array, r4d4, status)
VERIFY_(STATUS)
wrap4dr4%ptr => r4d4
call c_ESMC_ArraySetF90Ptr(array, wrap4dr4, status)
VERIFY_(STATUS)
else
RETURN_(ESMF_FAILURE)
endif
else if (dk .eq. ESMF_R8) then
!ALT: temporaty set to FAIL; if compiles OK, copy and paste from above; replace r4=>r8
RETURN_(ESMF_FAILURE)
else
RETURN_(ESMF_FAILURE)
endif
RETURN_(ESMF_SUCCESS)
end subroutine MAPL_ConnectCouplingFromArray
subroutine MAPL_ArrayF90Deallocate(array, rc) 9
type(ESMF_Array), intent(INOUT) :: array
integer, optional, intent( OUT) :: rc
integer :: rank
type(ESMF_DataType) :: type
type(ESMF_DataKind) :: dk
integer, dimension(ESMF_MAXDIM) :: counts, lbounds, ubounds
type(ESMF_Pointer) :: base
integer :: status
character(len=ESMF_MAXSTR), parameter :: IAm='MAPL_ArrayF90Deallocate'
real(kind=4), dimension(:) , pointer :: r4d1
real(kind=4), dimension(:,:) , pointer :: r4d2
real(kind=4), dimension(:,:,:) , pointer :: r4d3
real(kind=4), dimension(:,:,:,:) , pointer :: r4d4
real(kind=8), dimension(:) , pointer :: r8d1
real(kind=8), dimension(:,:) , pointer :: r8d2
real(kind=8), dimension(:,:,:) , pointer :: r8d3
real(kind=8), dimension(:,:,:,:) , pointer :: r8d4
type (WRAP1R4) :: wrap1dr4
type (WRAP2R4) :: wrap2dr4
type (WRAP3R4) :: wrap3dr4
type (WRAP4R4) :: wrap4dr4
type (WRAP1R8) :: wrap1dr8
type (WRAP2R8) :: wrap2dr8
type (WRAP3R8) :: wrap3dr8
type (WRAP4R8) :: wrap4dr8
call ESMF_ArrayGet(array, rank, kind=dk, &
counts = counts, lbounds=lbounds, ubounds=ubounds, &
base=base, rc=status)
VERIFY_(STATUS)
if (dk .eq. ESMF_R4) then
if (rank .eq. 1) then
call ESMF_ArrayGetData(array, r4d1, rc=status)
VERIFY_(STATUS)
if (associated(r4d1)) then
deallocate(r4d1, stat=status)
VERIFY_(STATUS)
wrap1dr4%ptr => r4d1
call c_ESMC_ArraySetF90Ptr(array, wrap1dr4, status)
VERIFY_(STATUS)
endif
else if (rank .eq. 2) then
call ESMF_ArrayGetData(array, r4d2, rc=status)
VERIFY_(STATUS)
if (associated(r4d2)) then
deallocate(r4d2, stat=status)
VERIFY_(STATUS)
wrap2dr4%ptr => r4d2
call c_ESMC_ArraySetF90Ptr(array, wrap2dr4, status)
VERIFY_(STATUS)
endif
else if (rank .eq. 3) then
call ESMF_ArrayGetData(array, r4d3, rc=status)
VERIFY_(STATUS)
if (associated(r4d3)) then
deallocate(r4d3, stat=status)
VERIFY_(STATUS)
wrap3dr4%ptr => r4d3
call c_ESMC_ArraySetF90Ptr(array, wrap3dr4, status)
VERIFY_(STATUS)
endif
else if (rank .eq. 4) then
call ESMF_ArrayGetData(array, r4d4, rc=status)
VERIFY_(STATUS)
if (associated(r4d4)) then
deallocate(r4d4, stat=status)
VERIFY_(STATUS)
wrap4dr4%ptr => r4d4
call c_ESMC_ArraySetF90Ptr(array, wrap4dr4, status)
VERIFY_(STATUS)
end if
else
RETURN_(ESMF_FAILURE)
endif
else if (dk .eq. ESMF_R8) then
!ALT: temporaty set to FAIL; if compiles OK, copy and paste from above; replace r4=>r8
RETURN_(ESMF_FAILURE)
else
RETURN_(ESMF_FAILURE)
endif
RETURN_(ESMF_SUCCESS)
end subroutine MAPL_ArrayF90Deallocate
subroutine MAPL_DecomposeDim ( dim_world,dim,NDEs ) 10
implicit none
integer dim_world, NDEs
integer dim(0:NDEs-1)
integer n,im,rm,nbeg,nend
im = dim_world/NDEs
rm = dim_world-NDEs*im
do n=0,NDEs-1
dim(n) = im
if( n.le.rm-1 ) dim(n) = im+1
enddo
end subroutine MAPL_DecomposeDim
subroutine MAPL_Interp_Fac (TIME0, TIME1, TIME2, FAC1, FAC2, RC) 3
!------------------------------------------------------------
! PURPOSE:
! ========
!
! Compute interpolation factors, fac, to be used
! in the calculation of the instantaneous boundary
! conditions, ie:
!
! q(i,j) = fac1*q1(i,j) + (1.-fac1)*q2(i,j)
!
! where:
! q(i,j) => Boundary Data valid at time0
! q1(i,j) => Boundary Data centered at time1
! q2(i,j) => Boundary Data centered at time2
! INPUT:
! ======
! time0 : Time of current timestep
! time1 : Time of boundary data 1
! time2 : Time of boundary data 2
! OUTPUT:
! =======
! fac1 : Interpolation factor for Boundary Data 1
!
! ------------------------------------------------------------
! GODDARD LABORATORY FOR ATMOSPHERES
! ------------------------------------------------------------
type(ESMF_Time), intent(in ) :: TIME0, TIME1, TIME2
real, intent(out) :: FAC1
real, optional, intent(out) :: FAC2
integer, optional, intent(out) :: RC
type(ESMF_TimeInterval) :: TimeDif1
type(ESMF_TimeInterval) :: TimeDif
TimeDif1 = TIME2-TIME0
TimeDif = TIME2-TIME1
FAC1 = TimeDif1/TimeDif
if(present(FAC2)) FAC2 = 1.-FAC1
if(present(RC )) RC = ESMF_SUCCESS
end subroutine MAPL_Interp_Fac
subroutine MAPL_ClimInterpFac (CLOCK,I1,I2,FAC, RC) 1,1
!------------------------------------------------------------
type(ESMF_CLOCK), intent(in ) :: CLOCK
integer, intent(OUT) :: I1, I2
real, intent(out) :: FAC
integer, optional, intent(out) :: RC
integer :: STATUS
character(len=ESMF_MAXSTR), parameter :: IAm='MAPL_ClimInterpFac'
type (ESMF_Time) :: CurrTime
type (ESMF_Time) :: midMonth
type (ESMF_Time) :: BEFORE, AFTER
type (ESMF_TimeInterval) :: oneMonth
type (ESMF_Calendar) :: cal
call ESMF_ClockGet ( CLOCK, CurrTime=CurrTime, calendar=cal, rc=STATUS )
VERIFY_(STATUS)
call ESMF_TimeGet ( CurrTime, midMonth=midMonth, rc=STATUS )
VERIFY_(STATUS)
call ESMF_TimeIntervalSet( oneMonth, MM = 1, calendar=cal, rc=status )
VERIFY_(STATUS)
if( CURRTIME < midMonth ) then
AFTER = midMonth
midMonth = midMonth - oneMonth
call ESMF_TimeGet (midMonth, midMonth=BEFORE, rc=STATUS )
VERIFY_(STATUS)
else
BEFORE = midMonth
midMonth = midMonth + oneMonth
call ESMF_TimeGet (midMonth, midMonth=AFTER , rc=STATUS )
VERIFY_(STATUS)
endif
call MAPL_Interp_Fac
( CURRTIME, BEFORE, AFTER, FAC, RC=STATUS)
VERIFY_(STATUS)
call ESMF_TimeGet (BEFORE, MM=I1, rc=STATUS )
VERIFY_(STATUS)
call ESMF_TimeGet (AFTER , MM=I2, rc=STATUS )
VERIFY_(STATUS)
RETURN_(ESMF_SUCCESS)
end subroutine MAPL_ClimInterpFac
subroutine MAPL_TimeStringGet(TIMESTRING,YY,MM,DD,H,M,S) 1
character(len=*), intent (IN ) :: TIMESTRING
integer, optional, intent (OUT) :: YY
integer, optional, intent (OUT) :: MM
integer, optional, intent (OUT) :: DD
integer, optional, intent (OUT) :: H
integer, optional, intent (OUT) :: M
integer, optional, intent (OUT) :: S
integer :: IYY, IMM, IDD, IHH, IMN, ISS
read(TIMESTRING,'(I4,1X,I2,1X,I2,1X,I2,1X,I2,1X,I2)') IYY,IMM,IDD,IHH,IMN,ISS
!ALT: SGI compiler does not like this format read(TIMESTRING,'(I4,"-",I2,"-",I2,"T",I2,":",I2,":",I2)') IYY,IMM,IDD,IHH,IMN,ISS
if(present(YY)) YY = IYY
if(present(MM)) MM = IMM
if(present(DD)) DD = IDD
if(present(H )) H = IHH
if(present(M )) M = IMN
if(present(S )) S = ISS
return
end subroutine MAPL_TimeStringGet
subroutine MAPL_UnpackTime(TIME,IYY,IMM,IDD) 2
integer, intent (IN ) :: TIME
integer, intent (OUT) :: IYY
integer, intent (OUT) :: IMM
integer, intent (OUT) :: IDD
IYY = TIME/10000
IMM = mod(TIME/100,100)
IDD = mod(TIME,100)
end subroutine MAPL_UnpackTime
subroutine MAPL_PackTime(TIME,IYY,IMM,IDD) 6
integer, intent (OUT) :: TIME
integer, intent (IN ) :: IYY
integer, intent (IN ) :: IMM
integer, intent (IN ) :: IDD
TIME=IYY*10000+IMM*100+IDD
end subroutine MAPL_PackTime
subroutine MAPL_tick (nymd,nhms,ndt)
integer nymd,nhms,ndt,nsec,nsecf
nsecf(nhms) = nhms/10000*3600 + mod(nhms,10000)/100*60 + mod(nhms,100)
IF(NDT.NE.0) THEN
NSEC = NSECF(NHMS) + NDT
IF (NSEC.GT.86400) THEN
DO WHILE (NSEC.GT.86400)
NSEC = NSEC - 86400
NYMD = MAPL_INCYMD (NYMD,1)
ENDDO
ENDIF
IF (NSEC.EQ.86400) THEN
NSEC = 0
NYMD = MAPL_INCYMD (NYMD,1)
ENDIF
IF (NSEC.LT.00000) THEN
DO WHILE (NSEC.LT.0)
NSEC = 86400 + NSEC
NYMD = MAPL_INCYMD (NYMD,-1)
ENDDO
ENDIF
NHMS = MAPL_NHMSF (NSEC)
ENDIF
RETURN
end subroutine MAPL_tick
logical function MAPL_RTRN(A,iam,line,rc) 1
integer, intent(IN ) :: A
character*(*), intent(IN ) :: iam
integer, intent(IN ) :: line
integer, optional, intent(OUT) :: RC
MAPL_RTRN = .true.
if(A/=ESMF_SUCCESS)print'(A40,I10)',Iam,line
if(present(RC)) RC=A
end function MAPL_RTRN
logical function MAPL_VRFY(A,iam,line,rc) 1
integer, intent(IN ) :: A
character*(*), intent(IN ) :: iam
integer, intent(IN ) :: line
integer, optional, intent(OUT) :: RC
MAPL_VRFY = A/=ESMF_SUCCESS
if(MAPL_VRFY)then
if(present(RC)) then
print'(A40,I10)',Iam,line
RC=A
endif
endif
end function MAPL_VRFY
logical function MAPL_ASRT(A,iam,line,rc) 1
logical, intent(IN ) :: A
character*(*), intent(IN ) :: iam
integer, intent(IN ) :: line
integer, optional, intent(OUT) :: RC
MAPL_ASRT = .not.A
if(MAPL_ASRT)then
if(present(RC))then
print'(A40,I10)',Iam,LINE
RC=ESMF_FAILURE
endif
endif
end function MAPL_ASRT
logical function MAPL_RTRNt(A,text,iam,line,rc)
integer, intent(IN ) :: A
character*(*), intent(IN ) :: text,iam
integer, intent(IN ) :: line
integer, optional, intent(OUT) :: RC
MAPL_RTRNt = .true.
if(A/=ESMF_SUCCESS)then
print'(A40,I10)',Iam,line
print *, text
end if
if(present(RC)) RC=A
end function MAPL_RTRNT
logical function MAPL_VRFYt(A,text,iam,line,rc)
integer, intent(IN ) :: A
character*(*), intent(IN ) :: iam,text
integer, intent(IN ) :: line
integer, optional, intent(OUT) :: RC
MAPL_VRFYt = MAPL_VRFY(A,iam,line,rc)
if(MAPL_VRFYt) print *, text
end function MAPL_VRFYT
logical function MAPL_ASRTt(A,text,iam,line,rc)
logical, intent(IN ) :: A
character*(*), intent(IN ) :: iam,text
integer, intent(IN ) :: line
integer, optional, intent(OUT) :: RC
MAPL_ASRTt = MAPL_ASRT(A,iam,line,rc)
if(MAPL_ASRTt) print *, text
end function MAPL_ASRTT
integer function MAPL_nsecf2 (nhhmmss,nmmdd,nymd)
integer nhhmmss,nmmdd,nymd,nhms,nday,month
integer nsday, ncycle,iday,iday2
integer nsecf,i,nsegm,nsegd
PARAMETER ( NSDAY = 86400 )
PARAMETER ( NCYCLE = 1461*24*3600 )
INTEGER YEAR, DAY, SEC, YEAR0, DAY0, SEC0
integer MNDY(12,4), mnd48(48)
DATA MND48/0,31,60,91,121,152,182,213,244,274,305,335,366,397,34*0 /
! DATA MNDY /0,31,60,91,121,152,182,213,244,274,305,335,366,397,34*0 /
equivalence ( mndy(1,1), mnd48(1) )
nsecf(nhms) = nhms/10000*3600 + mod(nhms,10000)/100*60 + mod(nhms,100)
MAPL_nsecf2 = nsecf( nhhmmss )
if( nmmdd.eq.0 ) return
DO 100 I=15,48
! MNDY(I,1) = MNDY(I-12,1) + 365
MND48(I) = MND48(I-12) + 365
100 CONTINUE
nsegm = nmmdd/100
nsegd = mod(nmmdd,100)
YEAR = NYMD / 10000
MONTH = MOD(NYMD,10000) / 100
DAY = MOD(NYMD,100)
SEC = NSECF(nhhmmss)
IDAY = MNDY( MONTH ,MOD(YEAR ,4)+1 )
month = month + nsegm
If( month.gt.12 ) then
month = month - 12
year = year + 1
endif
IDAY2 = MNDY( MONTH ,MOD(YEAR ,4)+1 )
nday = iday2-iday
if(nday.lt.0) nday = nday + 1461
nday = nday + nsegd
MAPL_nsecf2 = MAPL_nsecf2 + nday*nsday
end function MAPL_nsecf2
integer function MAPL_nhmsf (nsec)
implicit none
integer nsec
MAPL_nhmsf = nsec/3600*10000 + mod(nsec,3600)/60*100 + mod(nsec,60)
end function MAPL_nhmsf
integer function MAPL_incymd (NYMD,M)
integer nymd,ny,nm,nd,m,ny00
INTEGER NDPM(12)
DATA NDPM /31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/
LOGICAL LEAP
DATA NY00 / 1900 /
LEAP(NY) = MOD(NY,4).EQ.0 .AND. (NY.NE.0 .OR. MOD(NY00,400).EQ.0)
NY = NYMD / 10000
NM = MOD(NYMD,10000) / 100
ND = MOD(NYMD,100) + M
IF (ND.EQ.0) THEN
NM = NM - 1
IF (NM.EQ.0) THEN
NM = 12
NY = NY - 1
ENDIF
ND = NDPM(NM)
IF (NM.EQ.2 .AND. LEAP(NY)) ND = 29
ENDIF
IF (ND.EQ.29 .AND. NM.EQ.2 .AND. LEAP(NY)) GO TO 20
IF (ND.GT.NDPM(NM)) THEN
ND = 1
NM = NM + 1
IF (NM.GT.12) THEN
NM = 1
NY = NY + 1
ENDIF
ENDIF
20 CONTINUE
MAPL_INCYMD = NY*10000 + NM*100 + ND
RETURN
end function MAPL_incymd
subroutine MAPL_PICKEM(II,JJ,IM,JM,COUNT)
integer, intent(IN ) :: IM, JM, COUNT
integer, intent(OUT) :: II(COUNT), JJ(COUNT)
integer, parameter :: NT=3
logical :: MASK(IM,JM)
integer :: L, NN, IX, JX
real :: IIR(NT*COUNT), JJR(NT*COUNT)
MASK=.true.
NN=1
call RANDOM_NUMBER(IIR)
call RANDOM_NUMBER(JJR)
do L=1, COUNT
do
IX=IIR(NN)*(IM-1)+2
JX=JJR(NN)*(JM-2)+2
NN = NN + 1
if(MASK(IX,JX)) then
II(L) = IX
JJ(L) = JX
MASK(IX-1:IX+1,JX-1:JX+1) = .false.
exit
endif
if(NN>NT*COUNT) stop 222
enddo
enddo
!!$ DO L=1,JM
!!$ PRINT '(144L1)',MASK(:,L)
!!$ ENDDO
!!$
!!$ PRINT *, COUNT, NN
return
end subroutine MAPL_PICKEM
subroutine MAPL_GetFieldTimeFromField ( FIELD, TIME, RC ) 1,3
type(ESMF_Field), intent(IN ) :: FIELD
type(ESMF_Time), intent( OUT) :: TIME
integer, optional, intent( OUT) :: RC
character(len=ESMF_MAXSTR),parameter :: IAm=" MAPL_GetFieldTimeFromField"
integer :: STATUS
integer :: YEAR, MONTH, DAY
integer :: HOUR, MINUTE, SCND
character(len=ESMF_MAXSTR) :: TIMESTAMP
call ESMF_FieldGetAttribute(FIELD, NAME="TimeStamp", VALUE=TIMESTAMP, RC=STATUS)
if(STATUS/=0) then
call ESMF_TimeSet (TIME, YY=0, RC=STATUS)
else
call MAPL_TimeStringGet
(TIMESTAMP, YY=YEAR, MM=MONTH, DD=DAY, &
H =HOUR, M =MINUTE, S =SCND )
VERIFY_(STATUS)
call ESMF_TimeSet (TIME, YY=YEAR, MM=MONTH, DD=DAY, &
H =HOUR, M =MINUTE, S =SCND, &
RC=STATUS)
VERIFY_(STATUS)
end if
RETURN_(ESMF_SUCCESS)
end subroutine MAPL_GetFieldTimeFromField
! ------------------------------------------------------------------------------
subroutine MAPL_SetFieldTimeFromField (FIELD, TIME, RC ) 1
type(ESMF_FIELD), intent(INOUT) :: FIELD
type(ESMF_TIME), intent(IN ) :: TIME
integer, optional, intent( OUT) :: RC
character(len=ESMF_MAXSTR),parameter :: IAm=" MAPL_SetFieldTimeFromField"
integer :: STATUS
integer :: YEAR, MONTH, DAY
character(len=ESMF_MAXSTR) :: TIMESTAMP
call ESMF_TimeGet (TIME, timeString=TIMESTAMP, RC=STATUS)
VERIFY_(STATUS)
call ESMF_FieldSetAttribute(FIELD, NAME="TimeStamp", VALUE=TIMESTAMP, RC=STATUS)
VERIFY_(STATUS)
RETURN_(ESMF_SUCCESS)
end subroutine MAPL_SetFieldTimeFromField
subroutine MAPL_GetFieldTimeFromState ( STATE, Fieldname, TIME, RC ) 1
type(ESMF_STATE), intent(IN ) :: STATE
character(len=*), intent(IN ) :: Fieldname
type(ESMF_Time), intent( OUT) :: TIME
integer, optional, intent( OUT) :: RC
character(len=ESMF_MAXSTR),parameter :: IAm=" MAPL_GetFieldTimeFromState"
integer :: STATUS
type(ESMF_FIELD) :: FIELD
integer :: YEAR, MONTH, DAY
character(len=ESMF_MAXSTR) :: TIMESTAMP
call ESMF_StateGetField (STATE, FIELDNAME, FIELD, RC=STATUS )
VERIFY_(STATUS)
call MAPL_FieldGetTime
(FIELD, TIME, RC=STATUS)
VERIFY_(STATUS)
RETURN_(ESMF_SUCCESS)
end subroutine MAPL_GetFieldTimeFromState
! ------------------------------------------------------------------------------
subroutine MAPL_SetFieldTimeFromState ( STATE, Fieldname, TIME, RC ) 1
type(ESMF_STATE), intent(INOUT) :: STATE
character(len=*), intent(IN ) :: Fieldname
type(ESMF_Time), intent(IN ) :: TIME
integer, optional, intent( OUT) :: RC
character(len=ESMF_MAXSTR),parameter :: IAm=" MAPL_SetFieldTimeFromState"
integer :: STATUS
type(ESMF_FIELD) :: FIELD
integer :: YEAR, MONTH, DAY
character(len=ESMF_MAXSTR) :: TIMESTAMP
call ESMF_StateGetField (STATE, FIELDNAME, FIELD, RC=STATUS)
VERIFY_(STATUS)
call MAPL_FieldSetTime
(FIELD, TIME, RC=STATUS)
VERIFY_(STATUS)
RETURN_(ESMF_SUCCESS)
end subroutine MAPL_SetFieldTimeFromState
function MAPL_FieldCreateRename(FIELD, NAME, RC) RESULT(F),1
type (ESMF_Field), intent(IN ) :: FIELD
character(len=*), intent(IN ) :: NAME
integer, optional, intent( OUT) :: RC
type (ESMF_Field) :: F
type (ESMF_DataType) :: dt
type (ESMF_DataKind) :: dk
! we are creating new field so that we can change the name of the field;
! the important thing is that the data (ESMF_Array) and the grid (ESMF_Grid)
! are the SAME as the one in the original Field
type(ESMF_FieldDataMap) :: datamap
type(ESMF_RelLoc) :: relloc
type(ESMF_Grid) :: grid
type(ESMF_Array) :: array
character(len=ESMF_MAXSTR) :: attname
integer :: status
character(len=ESMF_MAXSTR), parameter :: Iam='MAPL_FieldCreateRename'
!ALT added kludge (next 6 lines)
call ESMF_FieldGet(FIELD, name=attname, RC=STATUS)
VERIFY_(STATUS)
if (NAME == attname) then
F = FIELD
RETURN_(ESMF_SUCCESS)
endif
call ESMF_FieldGet(FIELD, grid=GRID, RC=STATUS)
VERIFY_(STATUS)
call ESMF_FieldGet(FIELD, datamap=DATAMAP, RC=STATUS)
VERIFY_(STATUS)
call ESMF_FieldGet(FIELD, horzRelLoc=RELLOC, RC=STATUS)
VERIFY_(STATUS)
call ESMF_FieldGetArray(FIELD, Array, RC=STATUS)
VERIFY_(STATUS)
F = ESMF_FieldCreate(GRID, ARRAY, &
datamap = datamap, &
horzRelloc = relloc, &
name = NAME, RC=STATUS )
VERIFY_(STATUS)
call MAPL_FieldCopyAttributes
(FIELD_IN=field, FIELD_OUT=f, RC=status)
VERIFY_(STATUS)
RETURN_(ESMF_SUCCESS)
end function MAPL_FieldCreateRename
function MAPL_FieldCreateRegrid(FIELD, GRID, RC) RESULT(F),1
type (ESMF_Field), intent(IN ) :: FIELD
type (ESMF_Grid), intent(IN ) :: GRID
integer, optional, intent( OUT) :: RC
type (ESMF_Field) :: F
type (ESMF_DataType) :: dt
type (ESMF_DataKind) :: dk
! we are creating new field so that we can change the grid of the field
! (and allocate array accordingly);
type(ESMF_FieldDataMap) :: datamap
type(ESMF_RelLoc) :: hrelloc
type(ESMF_RelLoc) :: vrelloc
type(ESMF_Array) :: array
integer :: rank
integer :: COUNTS(3)
real, pointer :: VAR_1D(:), VAR_2D(:,:), VAR_3D(:,:,:)
character(len=ESMF_MAXSTR) :: NAME
integer :: status
integer :: DIMS
character(len=ESMF_MAXSTR), parameter :: Iam='MAPL_FieldCreateRegrid'
call ESMF_FieldGet(FIELD, name=name, RC=STATUS)
VERIFY_(STATUS)
call ESMF_FieldGet(FIELD, datamap=DATAMAP, RC=STATUS)
VERIFY_(STATUS)
call ESMF_FieldGet(FIELD, horzRelLoc=HRELLOC, vertRelLoc=VRELLOC, RC=STATUS)
VERIFY_(STATUS)
call ESMF_FieldGetArray(FIELD, Array, RC=STATUS)
VERIFY_(STATUS)
call ESMF_GridGetDELocalInfo(GRID, &
horzRelLoc=ESMF_CELL_CENTER, &
vertRelLoc=ESMF_CELL_CELL, &
localCellCountPerDim=COUNTS,RC=STATUS)
VERIFY_(STATUS)
call ESMF_ArrayGet(array, rank=rank, rc=status)
VERIFY_(STATUS)
if (rank == 1) then
rank = 2
call ESMF_FieldDataMapSetDefault(datamap, rank, rc=status)
VERIFY_(STATUS)
end if
if (rank == 2) then
!ALT halowidth assumed 0
allocate(VAR_2D(COUNTS(1), COUNTS(2)), STAT=STATUS)
VERIFY_(STATUS)
ARRAY = ESMF_ArrayCreate(VAR_2D, ESMF_DATA_REF, RC=STATUS)
VERIFY_(STATUS)
DIMS = MAPL_DimsHorzOnly
else
!ALT halowidth assumed 0
allocate(VAR_3D(COUNTS(1), COUNTS(2), COUNTS(3)), STAT=STATUS)
VERIFY_(STATUS)
ARRAY = ESMF_ArrayCreate(VAR_3D, ESMF_DATA_REF, RC=STATUS)
VERIFY_(STATUS)
DIMS = MAPL_DimsHorzVert
end if
F = ESMF_FieldCreate(GRID, ARRAY, &
datamap = datamap, &
horzRelloc = hrelloc, &
vertRelloc = vrelloc, &
name = NAME, RC=STATUS )
VERIFY_(STATUS)
call MAPL_FieldCopyAttributes
(FIELD_IN=field, FIELD_OUT=f, RC=status)
VERIFY_(STATUS)
! Overwrite DIMS attribute
call ESMF_FieldSetAttribute(F, NAME='DIMS', VALUE=DIMS, RC=STATUS)
VERIFY_(STATUS)
RETURN_(ESMF_SUCCESS)
end function MAPL_FieldCreateRegrid
subroutine MAPL_FieldCopyAttributes(FIELD_IN, FIELD_OUT, RC) 2
type (ESMF_Field), intent(IN ) :: FIELD_IN
type (ESMF_Field), intent(INOUT) :: FIELD_OUT
integer, optional, intent( OUT) :: RC
type (ESMF_DataType) :: dt
type (ESMF_DataKind) :: dk
integer :: status
character(len=ESMF_MAXSTR), parameter :: Iam='MAPL_FieldCopyAttributes'
integer :: i, n, count
character(len=ESMF_MAXSTR) :: attname
character(len=ESMF_MAXSTR) :: att
integer, pointer :: iptr(:)
type(ESMF_Logical), pointer :: lptr(:)
real, pointer :: rptr(:)
call ESMF_FieldGetAttributeCount(field_in, count=n, rc=status)
VERIFY_(STATUS)
do i = 1, n
call ESMF_FieldGetAttributeInfo(field_in, attributeIndex=i, name=attname, &
datatype=dt, datakind=dk, count=count, rc=status)
VERIFY_(STATUS)
if (dt == ESMF_Data_Integer) then
allocate(iptr(count), stat=status)
VERIFY_(STATUS)
call ESMF_FieldGetAttribute(field_in, NAME=attname, count=count, VALUELIST=iptr, RC=STATUS)
VERIFY_(STATUS)
call ESMF_FieldSetAttribute(field_out, NAME=attname, count=count, VALUELIST=iptr, RC=STATUS)
VERIFY_(STATUS)
deallocate(iptr)
else if (dt == ESMF_Data_Logical) then
allocate(lptr(count), stat=status)
VERIFY_(STATUS)
call ESMF_FieldGetAttribute(field_in, NAME=attname, count=count, VALUELIST=lptr, RC=STATUS)
VERIFY_(STATUS)
call ESMF_FieldSetAttribute(field_out, NAME=attname, count=count, VALUELIST=lptr, RC=STATUS)
VERIFY_(STATUS)
deallocate(lptr)
else if (dt == ESMF_Data_Real) then
allocate(rptr(count), stat=status)
VERIFY_(STATUS)
call ESMF_FieldGetAttribute(field_in, NAME=attname, count=count, VALUELIST=rptr, RC=STATUS)
VERIFY_(STATUS)
call ESMF_FieldSetAttribute(field_out, NAME=attname, count=count, VALUELIST=rptr, RC=STATUS)
VERIFY_(STATUS)
deallocate(rptr)
else if (dt == ESMF_Data_Character) then
call ESMF_FieldGetAttribute(field_in, NAME=attname, VALUE=att, RC=STATUS)
VERIFY_(STATUS)
call ESMF_FieldSetAttribute(field_out, NAME=attname, VALUE=att, RC=STATUS)
VERIFY_(STATUS)
end if
end do
RETURN_(ESMF_SUCCESS)
end subroutine MAPL_FieldCopyAttributes
!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function MAPL_RemapBounds_3dr4(A,I1,IM,J1,JM,L1,LM)
integer, intent(IN) :: I1,IM,J1,JM,L1,LM
real, target, intent(IN) :: A(I1:IM,J1:JM,L1:LM)
real, pointer :: MAPL_RemapBounds_3dr4(:,:,:)
MAPL_RemapBounds_3dr4 => A
end function MAPL_RemapBounds_3dr4
end module MAPL_BaseMod