source: LMDZ6/branches/LMDZ-tracers/libf/dyn3dmem/dynetat0_loc.F90 @ 4448

Last change on this file since 4448 was 3991, checked in by dcugnet, 3 years ago
  • fixed a bug in dynetat0[_loc].F90 for old style tracers description files having more water tracers than the initial state file.
  • changes (mainly cosmetic) to make dynetat0 and dynetat0_loc more similar.
  • fix a bug in readTracFiles_mod for tagging tracers.
  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory
File size: 11.6 KB
Line 
1SUBROUTINE dynetat0_loc(fichnom,vcov,ucov,teta,q,masse,ps,phis,time)
2!
3!-------------------------------------------------------------------------------
4! Authors: P. Le Van , L.Fairhead
5!-------------------------------------------------------------------------------
6! Purpose: Initial state reading.
7!-------------------------------------------------------------------------------
8  USE parallel_lmdz
9  USE infotrac,    ONLY: nqtot, niso, tracers, iTraPha, tnat, alpha_ideal, tra
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
13  USE control_mod, ONLY: planet_type
14  USE assert_eq_m, ONLY: assert_eq
15  USE comvert_mod, ONLY: pa,preff
16  USE comconst_mod, ONLY: cpp, daysec, dtvr, g, im, jm, kappa, lllm, omeg, rad
17  USE logic_mod, ONLY: fxyhypb, ysinus
18  USE serre_mod, ONLY: clon, clat, grossismx, grossismy
19  USE temps_mod, ONLY: annee_ref, day_ini, day_ref, itau_dyn, start_time
20  USE ener_mod,  ONLY: etot0, ptot0, ztot0, stot0, ang0
21  USE strings_mod, ONLY: strIdx
22  USE readTracFiles_mod, ONLY: known_phases, old_phases, nphases, phases_sep
23
24  IMPLICIT NONE
25  include "dimensions.h"
26  include "paramet.h"
27  include "comgeom.h"
28  include "description.h"
29  include "iniprint.h"
30!===============================================================================
31! Arguments:
32  CHARACTER(LEN=*), INTENT(IN) :: fichnom          !--- FILE NAME
33  REAL, INTENT(OUT) ::  vcov(ijb_v:ije_v,llm)      !--- V COVARIANT WIND
34  REAL, INTENT(OUT) ::  ucov(ijb_u:ije_u,llm)      !--- U COVARIANT WIND
35  REAL, INTENT(OUT) ::  teta(ijb_u:ije_u,llm)      !--- POTENTIAL TEMP.
36  REAL, INTENT(OUT) ::     q(ijb_u:ije_u,llm,nqtot)!--- TRACERS
37  REAL, INTENT(OUT) :: masse(ijb_u:ije_u,llm)      !--- MASS PER CELL
38  REAL, INTENT(OUT) ::    ps(ijb_u:ije_u)          !--- GROUND PRESSURE
39  REAL, INTENT(OUT) ::  phis(ijb_u:ije_u)          !--- GEOPOTENTIAL
40!===============================================================================
41! Local variables:
42  CHARACTER(LEN=256) :: sdum, var, modname, oldH2O
43  INTEGER, PARAMETER :: length=100
44  INTEGER :: iq, fID, vID, idecal, ix, ip, ierr, ib, ie, nglo
45  REAL    :: time, tab_cntrl(length)               !--- RUN PARAMS TABLE
46  TYPE(tra), POINTER :: tr
47!-------------------------------------------------------------------------------
48  modname="dynetat0_loc"
49
50!--- Initial state file opening
51  var=fichnom
52  CALL err(NF90_OPEN(var,NF90_NOWRITE,fID),"open",var)
53  CALL get_var1("controle",tab_cntrl)
54
55!!! AS: idecal is a hack to be able to read planeto starts...
56!!!     .... while keeping everything OK for LMDZ EARTH
57  IF(planet_type=="generic") THEN
58    WRITE(lunout,*)'NOTE NOTE NOTE : Planeto-like start files'
59    idecal = 4
60    annee_ref  = 2000
61  ELSE
62    WRITE(lunout,*)'NOTE NOTE NOTE : Earth-like start files'
63    idecal = 5
64    annee_ref  = tab_cntrl(5)
65  END IF
66  im         = tab_cntrl(1)
67  jm         = tab_cntrl(2)
68  lllm       = tab_cntrl(3)
69  day_ref    = tab_cntrl(4)
70  rad        = tab_cntrl(idecal+1)
71  omeg       = tab_cntrl(idecal+2)
72  g          = tab_cntrl(idecal+3)
73  cpp        = tab_cntrl(idecal+4)
74  kappa      = tab_cntrl(idecal+5)
75  daysec     = tab_cntrl(idecal+6)
76  dtvr       = tab_cntrl(idecal+7)
77  etot0      = tab_cntrl(idecal+8)
78  ptot0      = tab_cntrl(idecal+9)
79  ztot0      = tab_cntrl(idecal+10)
80  stot0      = tab_cntrl(idecal+11)
81  ang0       = tab_cntrl(idecal+12)
82  pa         = tab_cntrl(idecal+13)
83  preff      = tab_cntrl(idecal+14)
84!
85  clon       = tab_cntrl(idecal+15)
86  clat       = tab_cntrl(idecal+16)
87  grossismx  = tab_cntrl(idecal+17)
88  grossismy  = tab_cntrl(idecal+18)
89!
90  IF ( tab_cntrl(idecal+19)==1. )  THEN
91    fxyhypb  = .TRUE.
92!   dzoomx   = tab_cntrl(25)
93!   dzoomy   = tab_cntrl(26)
94!   taux     = tab_cntrl(28)
95!   tauy     = tab_cntrl(29)
96  ELSE
97    fxyhypb = .FALSE.
98    ysinus  = tab_cntrl(idecal+22)==1.
99  END IF
100
101  day_ini    = tab_cntrl(30)
102  itau_dyn   = tab_cntrl(31)
103  start_time = tab_cntrl(32)
104
105!-------------------------------------------------------------------------------
106  WRITE(lunout,*)TRIM(modname)//': rad,omeg,g,cpp,kappa',rad,omeg,g,cpp,kappa
107  CALL check_dim(im,iim,'im','im')
108  CALL check_dim(jm,jjm,'jm','jm')
109  CALL check_dim(lllm,llm,'lm','lllm')
110  CALL get_var1("rlonu", rlonu)
111  CALL get_var1("rlatu", rlatu)
112  CALL get_var1("rlonv", rlonv)
113  CALL get_var1("rlatv", rlatv)
114  CALL get_var1("cu",       cu)
115  CALL get_var1("cv",       cv)
116  CALL get_var1("aire",   aire)
117
118  var="temps"
119  IF(NF90_INQ_VARID(fID,var,vID)/=NF90_NoErr) THEN
120    WRITE(lunout,*)TRIM(modname)//": missing field <temps>"
121    WRITE(lunout,*)TRIM(modname)//": trying with <Time>"; var="Time"
122    CALL err(NF90_INQ_VARID(fID,var,vID),"inq",var)
123  END IF
124  CALL err(NF90_GET_VAR(fID,vID,time),"get",var)
125  ib = ijb_v; ie = ije_v; nglo = ip1jm
126  CALL get_var2("vcov",     vcov(ib:ie,:), ib, ie, nglo)
127  ib = ijb_u; ie = ije_u; nglo = ip1jmp1
128  CALL get_var2("ucov",     ucov(ib:ie,:), ib, ie, nglo)
129  CALL get_var2("teta",     teta(ib:ie,:), ib, ie, nglo)
130  CALL get_var2("masse",   masse(ib:ie,:), ib, ie, nglo)
131  CALL get_var1("phisinit", phis(ib:ie),   ib, ie)
132  CALL get_var1("ps",         ps(ib:ie),   ib, ie)
133
134!--- Tracers
135  DO iq=1,nqtot
136    tr => tracers(iq)
137    var = tr%name
138    ix = strIdx([('H2O'//phases_sep//known_phases(ip:ip), ip=1, nphases)], var)
139    oldH2O = '***'; IF(ix/=0) oldH2O = 'H2O'//old_phases(ix:ix)
140    !------------------------------------------------------------------------------------------------------------------
141    IF(NF90_INQ_VARID(fID, var, vID) == NF90_NoErr) THEN                                 !=== REGULAR CASE
142      CALL get_var2(var, q(ib:ie,:,iq), ib, ie, nglo)
143    !------------------------------------------------------------------------------------------------------------------
144#ifdef INCA
145    ELSE IF(NF90_INQ_VARID(fID, 'OX',   vID) == NF90_NoErr .AND. var == 'O3') THEN       !=== INCA: OX INSTEAD OF O3
146      WRITE(lunout,*)TRIM(modname)//': Tracer <O3> is missing => initialized to OX'
147      CALL get_var2('OX', q(ib:ie,:,iq), ib, ie, nglo)
148#endif
149    !------------------------------------------------------------------------------------------------------------------
150    ELSE IF(NF90_INQ_VARID(fID, oldH2O, vID) == NF90_NoErr .AND. ix  /= 0   ) THEN       !=== OLD WATER PHASES
151      WRITE(lunout,*)TRIM(modname)//': Tracer <'//TRIM(var)//'> is missing => initialized to '//TRIM(oldH2O)
152      CALL get_var2(oldH2O, q(ib:ie,:,iq), ib, ie, nglo)
153    !------------------------------------------------------------------------------------------------------------------
154    ELSE IF(niso > 0 .AND. tr%iso_num > 0) THEN                                          !=== ISOTOPES, CRisi
155      IF(tr%iso_zon == 0) THEN
156        WRITE(lunout,*)TRIM(modname)//': Isotope <'//TRIM(var)//'> is missing => initialized with a' &
157          //' simplified Rayleigh distillation law'
158        q(:,:,iq) = q(:,:,tr%iprnt)         *        tnat(tr%iso_num) &
159                  *(q(:,:,tr%iprnt)/30.e-3)**(alpha_ideal(tr%iso_num)-1)
160      ELSE
161        WRITE(lunout,*)TRIM(modname)//': Isotope geographical tracer <'//TRIM(var)//'> is missing '  &
162          //'=> initialized its parent isotope concentration'
163        q(:,:,iq) = q(:,:,iTraPha(tr%iso_num,tr%iso_pha))
164      END IF
165    !------------------------------------------------------------------------------------------------------------------
166    ELSE                                                                                 !=== MISSING: SET TO 0
167      WRITE(lunout,*)TRIM(modname)//': Tracer <'//TRIM(var)//'> is missing => initialized to zero'
168      q(ib:ie,:,iq)=0.
169    END IF
170    !------------------------------------------------------------------------------------------------------------------
171  END DO
172  CALL err(NF90_CLOSE(fID),"close",fichnom)
173  day_ini=day_ini+INT(time)
174  time=time-INT(time)
175
176
177  CONTAINS
178
179
180SUBROUTINE check_dim(n1,n2,str1,str2)
181  INTEGER,          INTENT(IN) :: n1, n2
182  CHARACTER(LEN=*), INTENT(IN) :: str1, str2
183  CHARACTER(LEN=256) :: s1, s2
184  IF(n1/=n2) THEN
185    s1='value of '//TRIM(str1)//' ='
186    s2=' read in starting file differs from parametrized '//TRIM(str2)//' ='
187    WRITE(sdum,'(10x,a,i4,2x,a,i4)'),TRIM(s1),n1,TRIM(s2),n2
188    CALL ABORT_gcm(TRIM(modname),TRIM(sdum),1)
189  END IF
190END SUBROUTINE check_dim
191
192
193SUBROUTINE get_var1(var, v, ib, ie)
194!--- Usable for fields up to rank 4 with single time record (last index)
195!--- Result: stacked in a vector. Used for 2D (single layer) fields.
196  CHARACTER(LEN=*),  INTENT(IN)  :: var
197  REAL,              INTENT(OUT) :: v(:)
198  INTEGER, OPTIONAL, INTENT(IN)  :: ib, ie
199  REAL, ALLOCATABLE :: w(:,:,:,:), v_glo(:)
200  INTEGER :: n(4), dids(4), k, nd, ntot
201  CALL err(NF90_INQ_VARID(fID, var, vID), "inq", var)
202  ierr = NF90_INQUIRE_VARIABLE(fID, vID, dimids=dids, ndims=nd)
203  n(:) = 1; DO k = 1, nd; ierr = NF90_INQUIRE_DIMENSION(fID, dids(k), len=n(k)); END DO
204  IF(is_rec(fID, dids(nd)) .AND. n(nd) /= 1) &
205    CALL abort_gcm(TRIM(modname), 'Several records records for <'//TRIM(var)//'>')
206  ntot = PRODUCT(n(1:nd))
207  ALLOCATE(w(n(1), n(2), n(3), n(4)), v_glo(ntot))
208  CALL err(NF90_GET_VAR(fID, vID, w), "get", var)
209  v_glo(:) = RESHAPE(w, [ntot]); DEALLOCATE(w)
210  IF(PRESENT(ib).AND.PRESENT(ie)) THEN; v(:) = v_glo(ib:ie); ELSE; v(:) = v_glo(:); END IF
211  DEALLOCATE(v_glo)
212END SUBROUTINE get_var1
213
214
215SUBROUTINE get_var2(var, v, ib, ie, n_glo)
216!--- Usable for fields up to rank 4 with one or several time records (last index)
217!--- Result: stacked in a 2D array (1st/2nd index: horizontal/vertical). Used for 3D (several layers) fields.
218  CHARACTER(LEN=*), INTENT(IN)  :: var
219  REAL,             INTENT(OUT) :: v(:,:)
220  INTEGER,          INTENT(IN)  :: ib, ie, n_glo
221  REAL, ALLOCATABLE :: w(:,:,:,:), v_glo(:,:)
222  INTEGER :: n(4), dids(4), k, nd, nh, nv, tid
223  CALL err(NF90_INQ_VARID(fID, var, vID), "inq", var)
224  ierr = NF90_INQUIRE_VARIABLE(fID, vID, dimids=dids, ndims=nd)
225  n(:) = 1; DO k = 1, nd; ierr = NF90_INQUIRE_DIMENSION(fID, dids(k), len=n(k)); END DO
226  IF(is_rec(fID, dids(nd))) THEN
227    IF(n(nd) /= 1)  CALL abort_gcm(TRIM(modname), 'Several records records for <'//TRIM(var)//'>.')
228    nh = PRODUCT(n(1:nd-2)); nv = n(nd-1)
229  ELSE
230    nh = PRODUCT(n(1:nd  )); nv = n(nd)
231  END IF
232  IF(nh/=n_glo .OR. nv/=llm) CALL abort_gcm(TRIM(modname), 'Shape mismatch for "'//TRIM(var)//'"')
233  ALLOCATE(w(n(1), n(2), n(3), n(4)), v_glo(nh,nv))
234  CALL err(NF90_GET_VAR(fID, vID, w), "get", var)
235  v_glo(:,:) = RESHAPE(w, [nh, nv]); DEALLOCATE(w)
236  v(:,:) = v_glo(ib:ie,:)
237  DEALLOCATE(v_glo)
238END SUBROUTINE get_var2
239
240
241LOGICAL FUNCTION is_rec(fID, did) RESULT(lrec)
242!--- Check whether the file has a record dimension, detected as UNLIMITED diemnsion or using the attribute "units".
243  INTEGER, INTENT(IN) :: fID, did
244  INTEGER :: vid
245  CHARACTER(LEN=256) :: recn, ratt
246  !--- Check the "units" attribute of the last dimensional variable to detect record axis.
247  lrec = NF90_INQUIRE_DIMENSION  (fID, did, name=recn)    == NF90_NOERR
248  IF(lrec) lrec = NF90_INQ_VARID (fID, recn, vid)         == NF90_NOERR
249  IF(lrec) lrec = NF90_GET_ATT   (fID, vid, "units", ratt)== NF90_NOERR
250  IF(lrec) lrec = INDEX(ratt, " since ") /= 0
251END FUNCTION is_rec
252
253
254SUBROUTINE err(ierr, typ, nam)
255  INTEGER,          INTENT(IN) :: ierr   !--- NetCDF ERROR CODE
256  CHARACTER(LEN=*), INTENT(IN) :: typ    !--- TYPE OF OPERATION
257  CHARACTER(LEN=*), INTENT(IN) :: nam    !--- FIELD/FILE NAME
258  IF(ierr==NF90_NoERR) RETURN
259  SELECT CASE(typ)
260    CASE('inq');   sdum="Field <"//TRIM(nam)//"> is missing"
261    CASE('get');   sdum="Reading failed for <"//TRIM(nam)//">"
262    CASE('open');  sdum="File opening failed for <"//TRIM(nam)//">"
263    CASE('close'); sdum="File closing failed for <"//TRIM(nam)//">"
264  END SELECT
265  CALL ABORT_gcm(TRIM(modname),TRIM(sdum),ierr)
266END SUBROUTINE err
267
268END SUBROUTINE dynetat0_loc
Note: See TracBrowser for help on using the repository browser.