Ignore:
Timestamp:
Sep 22, 2021, 6:11:35 PM (3 years ago)
Author:
dcugnet
Message:
  • fix of the delPhase function.
  • getvar1 and getvar2 fixed and modified to avoid the usage of files with several time records and make the calls rather short.
  • works again with iadv==0
  • no more issues with tracers numbers (nqo, nqtot, etc.)
  • fixes in the algebrical reduction routine used for "isotopes_parems.def" (containing simple expressions with variables that have to be substituted).
  • still to be validated numerically
File:
1 edited

Legend:

Unmodified
Added
Removed
  • LMDZ6/branches/LMDZ-tracers/libf/dyn3dmem/dynetat0_loc.F90

    r3957 r3985  
    77!-------------------------------------------------------------------------------
    88  USE parallel_lmdz
    9   USE readTracFiles_mod, ONLY: known_phases, old_phases, nphases, phases_sep
    109  USE infotrac,    ONLY: nqtot, niso, tracers, iTraPha, tnat, alpha_ideal, tra
    11   USE netcdf,      ONLY: NF90_OPEN,  NF90_NOWRITE, NF90_INQ_VARID, NF90_INQUIRE_DIMENSION, &
    12            NF90_INQUIRE, NF90_CLOSE, NF90_GET_VAR, NF90_NoErr,     NF90_INQUIRE_VARIABLE
    13   USE strings_mod, ONLY: strIdx
     10  USE netcdf, ONLY: NF90_OPEN,  NF90_INQUIRE_DIMENSION, NF90_INQ_VARID,        &
     11      NF90_NOWRITE, NF90_CLOSE, NF90_INQUIRE_VARIABLE,  NF90_GET_VAR,          &
     12      NF90_GET_ATT, NF90_NoErr, NF90_INQUIRE
    1413  USE control_mod, ONLY: planet_type
    1514  USE assert_eq_m, ONLY: assert_eq
    1615  USE comvert_mod, ONLY: pa,preff
    17   USE comconst_mod, ONLY: cpp, daysec, dtvr, g, im, jm, kappa, lllm, omeg, rad
     16  USE comconst_mod, ONLY: cpp, daysec, dtvr, g, im, jm, kappa, lllm, &
     17                          omeg, rad
    1818  USE logic_mod, ONLY: fxyhypb, ysinus
    1919  USE serre_mod, ONLY: clon, clat, grossismx, grossismy
    20   USE temps_mod, ONLY: annee_ref, day_ini, day_ref, itau_dyn, start_time
    21   USE ener_mod,  ONLY: etot0, ptot0, ztot0, stot0, ang0
     20  USE temps_mod, ONLY: annee_ref,day_ref,itau_dyn, &
     21                       start_time,day_ini
     22  USE ener_mod, ONLY: etot0,ptot0,ztot0,stot0,ang0
     23  USE strings_mod, ONLY: strIdx
     24  USE readTracFiles_mod, ONLY: known_phases, old_phases, nphases, phases_sep
    2225
    2326  IMPLICIT NONE
     
    4144  CHARACTER(LEN=256) :: sdum, var, modname, oldH2O
    4245  INTEGER, PARAMETER :: length=100
    43   INTEGER :: iq, fID, vID, idecal, ix, ip, ierr
     46  INTEGER :: iq, fID, vID, idecal, ix, ip, ierr, ib, ie, nglo
    4447  REAL    :: time, tab_cntrl(length)               !--- RUN PARAMS TABLE
    4548  TYPE(tra), POINTER :: tr
     
    122125  END IF
    123126  CALL err(NF90_GET_VAR(fID,vID,time),"get",var)
    124   CALL get_var1("phisinit", phis, ijb_u, ije_u, ip1jmp1)
    125   CALL get_var2("ucov",     ucov, ijb_u, ije_u, ip1jmp1)
    126   CALL get_var2("vcov",     vcov, ijb_v, ije_v, ip1jm)
    127   CALL get_var2("teta",     teta, ijb_u, ije_u, ip1jmp1)
    128   CALL get_var2("masse",   masse, ijb_u, ije_u, ip1jmp1)
    129   CALL get_var1("ps",         ps, ijb_u, ije_u, ip1jmp1)
     127  ib = ijb_v; ie = ije_v; nglo = ip1jm
     128  CALL get_var2("vcov",     vcov(ib:ie,:), ib, ie, nglo)
     129  ib = ijb_u; ie = ije_u; nglo = ip1jmp1
     130  CALL get_var2("ucov",     ucov(ib:ie,:), ib, ie, nglo)
     131  CALL get_var2("teta",     teta(ib:ie,:), ib, ie, nglo)
     132  CALL get_var2("masse",   masse(ib:ie,:), ib, ie, nglo)
     133  CALL get_var1("phisinit", phis(ib:ie),   ib, ie)
     134  CALL get_var1("ps",         ps(ib:ie),   ib, ie)
    130135
    131136!--- Tracers
     
    135140    ix = strIdx([('H2O'//phases_sep//known_phases(ip:ip), ip=1, nphases)], var)
    136141    IF(NF90_INQ_VARID(fID, var, vID) == NF90_NoErr) THEN
    137       CALL get_var2(var, q(:,:,iq), ijb_u, ije_u, ip1jmp1)
     142      CALL get_var2(var, q(ib:ie,:,iq), ib, ie, nglo)
    138143#ifdef INCA
    139144    ELSE IF(NF90_INQ_VARID(fID, 'OX', vID) == NF90_NoErr .AND. var == 'O3') THEN
    140145      WRITE(lunout,*)TRIM(modname)//': Tracer <O3> is missing => initialized to OX'
    141       CALL get_var2('OX', q(:,:,iq), ijb_u, ije_u, ip1jmp1)
     146      CALL get_var2('OX', q(ib:ie,:,iq), ib, ie, nglo)
    142147#endif
    143148    ELSE IF(ix /= 0) THEN              !--- Old file, water: H2Ov/l/i instead of H2O-g/-l/-s
     
    145150      IF(NF90_INQ_VARID(fID, oldH2O, vID) == NF90_NoErr) THEN
    146151        WRITE(lunout,*)TRIM(modname)//': Tracer <'//TRIM(var)//'> is missing => initialized to '//TRIM(oldH2O)
    147         CALL get_var2(oldH2O, q(:,:,iq), ijb_u, ije_u, ip1jmp1)
     152        CALL get_var2(oldH2O, q(ib:ie,:,iq), ib, ie, nglo)
    148153      END IF
    149154    ELSE
    150155      WRITE(lunout,*)TRIM(modname)//': Tracer <'//TRIM(var)//'> is missing => initialized to zero'
    151       q(ijb_u:ije_u,:,iq)=0.
     156      q(ib:ie,:,iq)=0.
    152157      !--- CRisi: for isotopes, theoretical initialization using very simplified Rayleigh distillation law
    153158      IF(niso > 0 .AND. tr%iso_num > 0) THEN
     
    179184
    180185
    181 SUBROUTINE get_var1(var, v, ib, ie, n_glo)
     186SUBROUTINE get_var1(var, v, ib, ie)
     187!--- Usable for fields up to rank 4 with single time record (last index)
     188!--- Result: stacked in a vector. Used for 2D (single layer) fields.
    182189  CHARACTER(LEN=*),  INTENT(IN)  :: var
    183190  REAL,              INTENT(OUT) :: v(:)
    184   INTEGER, OPTIONAL, INTENT(IN)  :: ib, ie, n_glo
     191  INTEGER, OPTIONAL, INTENT(IN)  :: ib, ie
    185192  REAL, ALLOCATABLE :: w(:,:,:,:), v_glo(:)
    186   INTEGER :: nn(4), dids(4), k, nd, ntot
     193  INTEGER :: n(4), dids(4), k, nd, ntot
    187194  CALL err(NF90_INQ_VARID(fID, var, vID), "inq", var)
    188195  ierr = NF90_INQUIRE_VARIABLE(fID, vID, dimids=dids, ndims=nd)
    189   nn(:) = 1; DO k=1,nd; ierr = NF90_INQUIRE_DIMENSION(fID, dids(k), len=nn(k)); END DO
    190   ntot = PRODUCT(nn(1:nd))
    191   ALLOCATE(w(nn(1), nn(2), nn(3), nn(4)))
     196  n(:) = 1; DO k = 1, nd; ierr = NF90_INQUIRE_DIMENSION(fID, dids(k), len=n(k)); END DO
     197  IF(is_rec(fID, dids(nd)) .AND. n(nd) /= 1) &
     198    CALL abort_gcm(TRIM(modname), 'Several records records for <'//TRIM(var)//'>')
     199  ntot = PRODUCT(n(1:nd))
     200  ALLOCATE(w(n(1), n(2), n(3), n(4)), v_glo(ntot))
    192201  CALL err(NF90_GET_VAR(fID, vID, w), "get", var)
    193   ALLOCATE(v_glo(ntot)); v_glo=RESHAPE(w, [ntot]); DEALLOCATE(w)
    194   IF(PRESENT(n_glo).AND.PRESENT(ib).AND.PRESENT(ie)) THEN
    195     IF(ntot/=n_glo) CALL abort_gcm(TRIM(modname), 'Shape mismatch for "'//TRIM(var)//'"')
    196     v(ib:ie) = v_glo(ib:ie)
    197   ELSE
    198     v(:) = v_glo(:)
    199   END IF
     202  v_glo(:) = RESHAPE(w, [ntot]); DEALLOCATE(w)
     203  IF(PRESENT(ib).AND.PRESENT(ie)) THEN; v(:) = v_glo(ib:ie); ELSE; v(:) = v_glo(:); END IF
    200204  DEALLOCATE(v_glo)
    201205END SUBROUTINE get_var1
     
    203207
    204208SUBROUTINE get_var2(var, v, ib, ie, n_glo)
     209!--- Usable for fields up to rank 4 with one or several time records (last index)
     210!--- Result: stacked in a 2D array (1st/2nd index: horizontal/vertical). Used for 3D (several layers) fields.
    205211  CHARACTER(LEN=*), INTENT(IN)  :: var
    206212  REAL,             INTENT(OUT) :: v(:,:)
    207213  INTEGER,          INTENT(IN)  :: ib, ie, n_glo
    208214  REAL, ALLOCATABLE :: w(:,:,:,:), v_glo(:,:)
    209   INTEGER :: nn(4), dids(4), k, nd, nh, nv, tid
     215  INTEGER :: n(4), dids(4), k, nd, nh, nv, tid
    210216  CALL err(NF90_INQ_VARID(fID, var, vID), "inq", var)
    211217  ierr = NF90_INQUIRE_VARIABLE(fID, vID, dimids=dids, ndims=nd)
    212   nn(:) = 1; DO k=1,nd; ierr = NF90_INQUIRE_DIMENSION(fID, dids(k), len=nn(k)); END DO
    213   IF(NF90_INQUIRE(fID, unlimitedDimId=tid) == NF90_NOERR) THEN
    214     nh = PRODUCT(nn(1:nd-2)); nv = nn(nd-1); nn(nd) = 1
     218  n(:) = 1; DO k = 1, nd; ierr = NF90_INQUIRE_DIMENSION(fID, dids(k), len=n(k)); END DO
     219  IF(is_rec(fID, dids(nd))) THEN
     220    IF(n(nd) /= 1)  CALL abort_gcm(TRIM(modname), 'Several records records for <'//TRIM(var)//'>.')
     221    nh = PRODUCT(n(1:nd-2)); nv = n(nd-1)
    215222  ELSE
    216     nh = PRODUCT(nn(1:nd-1)); nv = nn(nd)
    217   END IF
    218   ALLOCATE(w(nn(1), nn(2), nn(3), nn(4)))
     223    nh = PRODUCT(n(1:nd  )); nv = n(nd)
     224  END IF
     225  IF(nh/=n_glo .OR. nv/=llm) CALL abort_gcm(TRIM(modname), 'Shape mismatch for "'//TRIM(var)//'"')
     226  ALLOCATE(w(n(1), n(2), n(3), n(4)), v_glo(nh,nv))
    219227  CALL err(NF90_GET_VAR(fID, vID, w), "get", var)
    220   ALLOCATE(v_glo(nh, nv)); v_glo = RESHAPE(w, [nh, nv]); DEALLOCATE(w)
    221   IF(nh/=n_glo .OR. nv/=llm) CALL abort_gcm(TRIM(modname), 'Shape mismatch for "'//TRIM(var)//'"')
    222   v(ib:ie,:) = v_glo(ib:ie,:)
     228  v_glo(:,:) = RESHAPE(w, [nh, nv]); DEALLOCATE(w)
     229  v(:,:) = v_glo(ib:ie,:)
    223230  DEALLOCATE(v_glo)
    224231END SUBROUTINE get_var2
     232
     233
     234LOGICAL FUNCTION is_rec(fID, did) RESULT(lrec)
     235!--- Check whether the file has a record dimension, detected as UNLIMITED diemnsion or using the attribute "units".
     236  INTEGER, INTENT(IN) :: fID, did
     237  INTEGER :: vid
     238  CHARACTER(LEN=256) :: recn, ratt
     239  !--- Check the "units" attribute of the last dimensional variable to detect record axis.
     240  lrec = NF90_INQUIRE_DIMENSION  (fID, did, name=recn)    == NF90_NOERR
     241  IF(lrec) lrec = NF90_INQ_VARID (fID, recn, vid)         == NF90_NOERR
     242  IF(lrec) lrec = NF90_GET_ATT   (fID, vid, "units", ratt)== NF90_NOERR
     243  IF(lrec) lrec = INDEX(ratt, " since ") /= 0
     244END FUNCTION is_rec
    225245
    226246
Note: See TracChangeset for help on using the changeset viewer.