123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- #define TRACEBACK write (gol,'("in ",a," (",a,i6,")")') rname, __FILE__, __LINE__ ; call goErr
- #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
- #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
- !
- #include "tm5.inc"
- !
- !
- ! Tools for climatologies
- !
- module Climat
- use GO, only : TDate
-
- implicit none
-
-
- ! --- in/out -------------------------
-
- private
-
- public :: TClimat
- public :: Init, Done
- public :: Set, Setup
-
-
- ! --- const -----------------------------
-
- character(len=*), parameter :: mname = 'Climat'
-
- ! --- types --------------------------
- type TClimat
- character(len=16) :: name, unit
- ! actual climatology:
- real, pointer :: data(:,:,:)
- ! current data can be used to interpolate to this interval:
- type(TDate) :: tr(2)
- ! fields used for temporal interpolation:
- character(len=10) :: tinterp
- integer :: nt
- type(TDate), pointer :: t_in(:)
- real, pointer :: data_in(:,:,:,:)
- end type TClimat
-
-
- ! --- interfaces ------------------------
-
- interface Init
- module procedure climat_Init
- end interface
-
- interface Done
- module procedure climat_Done
- end interface
-
- interface Setup
- module procedure climat_Setup
- end interface
-
- interface Set
- module procedure climat_Set
- end interface
-
-
- contains
- ! =========================================================
-
-
- subroutine climat_Init( climat, name, unit, tinterp, im, jm, lm, status )
- use GO, only : gol, goErr
- use GO, only : AnyDate
-
- ! --- in/out --------------------------------
-
- type(TClimat), intent(out) :: climat
- character(len=*), intent(in) :: name, unit
- character(len=*), intent(in) :: tinterp
- integer, intent(in) :: im, jm, lm
- integer, intent(inout) :: status
-
- ! --- const ------------------------------
- character(len=*), parameter :: rname = mname//'/climat_Init'
-
- ! --- local -------------------------------
-
- integer :: it
-
- ! --- begin --------------------------------
-
- ! trap previous errors:
- if (status>0) return
-
- ! store info:
- climat%name = name
- climat%unit = unit
- climat%tinterp = tinterp
-
- ! setup target data:
- allocate( climat%data (im,jm,lm) )
-
- ! data not valid yet:
- climat%tr(1) = AnyDate()
- climat%tr(2) = AnyDate()
-
- ! setup interpolation data if necessary:
- select case ( climat%tinterp )
- case ( 'linear' )
- climat%nt = 2
- allocate( climat%data_in(im,jm,lm,climat%nt) )
- allocate( climat%t_in(climat%nt) )
- do it = 1, climat%nt
- climat%t_in(it) = AnyDate()
- end do
- case ( 'constant' )
- climat%nt = 0
- nullify( climat%data_in )
- case default
- write (gol,'("unsupported time interpolation : ",a)') trim(climat%tinterp); call goErr
- write (gol,'("in ",a)') rname; call goErr; status=1; return
- end select
-
- ! ok
- status = 0
-
- end subroutine climat_Init
-
-
- ! ***
-
- subroutine climat_Done( climat, status )
-
- use GO, only : gol, goErr
-
- ! --- in/out --------------------------------
-
- type(TClimat), intent(inout) :: climat
- integer, intent(inout) :: status
-
- ! --- const ------------------------------
- character(len=*), parameter :: rname = mname//'/climat_Done'
-
- ! --- begin --------------------------------
-
- ! trap previous errors:
- if (status>0) return
-
- ! clear arrays:
- deallocate( climat%data )
- select case ( climat%tinterp )
- case ( 'linear' )
- deallocate( climat%data_in )
- deallocate( climat%t_in )
- case ( 'constant' )
- ! nothing to clear
- case default
- write (gol,'("unsupported time interpolation : ",a)') trim(climat%tinterp); call goErr
- write (gol,'("in ",a)') rname; call goErr; status=1; return
- end select
-
- ! ok
- status = 0
-
- end subroutine climat_Done
-
-
- ! ***
-
-
- subroutine climat_Set( climat, status, data, tr, t_in, data_in, it_in )
-
- use GO, only : gol, goErr
-
- ! --- in/out --------------------------------
-
- type(TClimat), intent(inout) :: climat
- integer, intent(inout) :: status
-
- real, intent(in), optional :: data(:,:,:)
- type(TDate), intent(in), optional :: tr(2)
- type(TDate), intent(in), optional :: t_in
- real, intent(in), optional :: data_in(:,:,:)
- integer, optional :: it_in
-
- ! --- const ------------------------------
- character(len=*), parameter :: rname = mname//'/climat_Set'
-
- ! --- begin --------------------------------
-
- ! trap previous errors:
- if (status>0) return
-
- ! store data ?
- if ( present(data) ) climat%data = data
-
- ! store time range within which data is valid:
- if ( present(tr) ) climat%tr = tr
-
- ! input fields for time interpolation ?
- if ( present(t_in) .or. present(data_in) .or. present(it_in) ) then
- ! all should be present ...
- if ( .not. ( present(t_in) .and. present(data_in) .and. present(it_in) ) ) then
- write (gol,'("all or none input arguments should be present:")'); call goErr
- write (gol,'(" t_in : ",l1)') present(t_in)
- write (gol,'(" data_in : ",l1)') present(data_in)
- write (gol,'(" it_in : ",l1)') present(it_in)
- write (gol,'("in ",a)') rname; call goErr; status=1; return
- end if
- ! check it_inex ...
- if ( (it_in < 1) .or. (it_in > climat%nt) ) then
- write (gol,'("it_in not valid:")'); call goErr
- write (gol,'(" it_in : ",i2)') it_in
- write (gol,'(" nt : ",i2)') climat%nt
- write (gol,'(" tinterp : ",a)') trim(climat%tinterp)
- write (gol,'("in ",a)') rname; call goErr; status=1; return
- end if
- ! store:
- climat%t_in(it_in) = t_in
- climat%data_in(:,:,:,it_in) = data_in
- end if
- ! ok
- status = 0
-
- end subroutine climat_Set
-
-
- ! ***
-
- subroutine climat_Setup( climat, t, status )
-
- use GO, only : gol, goErr
- use GO, only : TDate, IsAnyDate, operator(<), InterpolFractions
-
- ! --- in/out --------------------------------
-
- type(TClimat), intent(inout) :: climat
- type(TDate), intent(in) :: t
- integer, intent(inout) :: status
-
- ! --- const ------------------------------
- character(len=*), parameter :: rname = mname//'/climat_Setup'
-
- ! --- local -------------------------------
-
- real :: alfa(2)
- integer :: it
-
- ! --- begin --------------------------------
-
- ! trap previous errors:
- if (status>0) return
-
- ! not filled yet ?
- if ( IsAnyDate(climat%tr(1)) .or. IsAnyDate(climat%tr(2)) ) then
- ! return as a warning; calling program should fill data ...
- status=-1; return
- end if
-
- ! t outside time range for which current data is valid ?
- if ( (t < climat%tr(1)) .or. (climat%tr(2) < t) ) then
- ! return as a warning; calling program should fill data ...
- status=-1; return
- end if
- ! apply time interpolation:
- select case ( climat%tinterp )
- case ( 'linear' )
- ! determine fractions to be applied to data1 and data2:
- call InterpolFractions( t, climat%t_in(1), climat%t_in(2), alfa(1), alfa(2), status )
- if (status/=0) then; write (gol,'("in ",a)') rname; call goErr; status=1; return; end if
- ! interpolate and store :
- climat%data = alfa(1) * climat%data_in(:,:,:,1) + alfa(2) * climat%data_in(:,:,:,2)
- case ( 'constant' )
-
- ! nothing to be done
-
- case default
- write (gol,'("unsupported time interpolation : ",a)') trim(climat%tinterp); call goErr
- write (gol,'("in ",a)') rname; call goErr; status=1; return
- end select
-
- ! ok
- status = 0
-
- end subroutine climat_Setup
-
-
- end module Climat
|