source: LMDZ5/trunk/libf/dyn3d/dynredem.F90 @ 2293

Last change on this file since 2293 was 2293, checked in by dcugnet, 9 years ago

Initial states creation routines have been reorganized and simplified.
As far as possible, dynamics and physics related routines have been
separated.
Some routines have been converted to fortran 90 and repeated codes sections
have been "factorized".
Array/vector arguments have become implicit in some routines to avoid usage
of "dimensions.h" ; possible for routines with explicit interfaces and if
iim and jjm can be deduced from arguments sizes.

  • dynlonlat_phylonlat/ce0l.F90 calls now phylmd/etat0phys_netcdf.F90 and dyn3d/etat0dyn_netcdf.F90 that replace phylmd/etat0_netcdf.F90. start.nc and startphy.nc creations are now independant.
  • startvar.F90 has been suppressed ; corresponding operations have been simplified and embedded in etat0*_netcdf.F90 routines as internal procedures.
  • Routines converted to fortran 90 and "factorized":
    • dyn3d_common/conf_dat_m.F90 (replaces dyn3d_common/conf_dat2d.F

and dyn3d_common/conf_dat3d.F)

  • dyn3d/dynredem.F90 (replaces dyn3d/dynredem.F)
  • dyn3d/dynetat0.F90 (replaces dyn3d/dynetat0.F)
  • phylmd/grid_noro_m.F90 (replaces dyn3d_common/grid_noro.F)
  • dynlonlat_phylonlat/grid_atob_m.F90 (replaces dyn3d_common/grid_atob.F)
  • dyn3d_common/caldyn0.F90 (replaces dyn3d_common/caldyn0.F)
  • dyn3d_common/covcont.F90 (replaces dyn3d_common/covcont.F)
  • dyn3d_common/pression.F90 (replaces dyn3d_common/pression.F)
  • phylmd/phyredem.F90 and phylmd/limit_netcdf.F90 have been slightly factorized.

TO DO:

  • little fix needed in grid_noro_m.F90 ; untouched yet to ensure results are exactly the same as before. Unsmoothed orography is used to compute "zphi", but smoothed (should be unsmoothed) one is used at poles.
  • add the dyn3dmem versions of dynredem.F90 and dynetat0.F90 (dynredem_loc.F90 and dynetat0_loc.F90, untested yet).
  • test compilation in parallel mode for a single processor.
File size: 14.6 KB
Line 
1SUBROUTINE dynredem0(fichnom,iday_end,phis)
2!
3!-------------------------------------------------------------------------------
4! Write the NetCDF restart file (initialization).
5!-------------------------------------------------------------------------------
6#ifdef CPP_IOIPSL
7  USE IOIPSL
8#endif
9  USE infotrac
10  USE netcdf, ONLY:   NF90_CREATE, NF90_DEF_DIM, NF90_REDEF,  NF90_INQ_VARID, &
11      NF90_CLOBBER,   NF90_CLOSE,  NF90_DEF_VAR, NF90_ENDDEF, NF90_PUT_ATT,   &
12      NF90_UNLIMITED, NF90_GLOBAL, NF90_FLOAT,   NF90_DOUBLE
13  USE netcdf95, ONLY: NF95_PUT_VAR
14  IMPLICIT NONE
15  include "dimensions.h"
16  include "paramet.h"
17  include "comconst.h"
18  include "comvert.h"
19  include "comgeom2.h"
20  include "temps.h"
21  include "ener.h"
22  include "logic.h"
23  include "netcdf.inc"
24  include "description.h"
25  include "serre.h"
26  include "iniprint.h"
27!===============================================================================
28! Arguments:
29  CHARACTER(LEN=*), INTENT(IN) :: fichnom          !--- FILE NAME
30  INTEGER,          INTENT(IN) :: iday_end         !---
31  REAL,             INTENT(IN) :: phis(iip1, jjp1) !--- GROUND GEOPOTENTIAL
32!===============================================================================
33! Local variables:
34  INTEGER :: iq, l
35  INTEGER, PARAMETER :: length=100
36  REAL    :: tab_cntrl(length)                     !--- RUN PARAMETERS TABLE
37  CHARACTER(LEN=20) :: modname
38!   For NetCDF:
39  CHARACTER(LEN=30) :: unites
40  INTEGER :: indexID
41  INTEGER :: rlonuID, rlonvID, rlatuID, rlatvID
42  INTEGER :: sID, sigID, nID, vID, timID
43  INTEGER :: yyears0, jjour0, mmois0
44  REAL :: zan0, zjulian, hours
45!===============================================================================
46  modname='dynredem0'
47#ifdef CPP_IOIPSL
48  CALL ymds2ju(annee_ref, 1, iday_end, 0.0, zjulian)
49  CALL ju2ymds(zjulian, yyears0, mmois0, jjour0, hours)
50#else
51! set yyears0, mmois0, jjour0 to 0,1,1 (hours is not used)
52  yyears0=0
53  mmois0=1
54  jjour0=1
55#endif       
56
57  tab_cntrl(:)  = 0.
58  tab_cntrl(1)  = REAL(iim)
59  tab_cntrl(2)  = REAL(jjm)
60  tab_cntrl(3)  = REAL(llm)
61  tab_cntrl(4)  = REAL(day_ref)
62  tab_cntrl(5)  = REAL(annee_ref)
63  tab_cntrl(6)  = rad
64  tab_cntrl(7)  = omeg
65  tab_cntrl(8)  = g
66  tab_cntrl(9)  = cpp
67  tab_cntrl(10) = kappa
68  tab_cntrl(11) = daysec
69  tab_cntrl(12) = dtvr
70  tab_cntrl(13) = etot0
71  tab_cntrl(14) = ptot0
72  tab_cntrl(15) = ztot0
73  tab_cntrl(16) = stot0
74  tab_cntrl(17) = ang0
75  tab_cntrl(18) = pa
76  tab_cntrl(19) = preff
77
78!    .....    parameters for zoom    ......   
79  tab_cntrl(20) = clon
80  tab_cntrl(21) = clat
81  tab_cntrl(22) = grossismx
82  tab_cntrl(23) = grossismy
83!
84  IF ( fxyhypb )   THEN
85    tab_cntrl(24) = 1.
86    tab_cntrl(25) = dzoomx
87    tab_cntrl(26) = dzoomy
88    tab_cntrl(27) = 0.
89    tab_cntrl(28) = taux
90    tab_cntrl(29) = tauy
91  ELSE
92    tab_cntrl(24) = 0.
93    tab_cntrl(25) = dzoomx
94    tab_cntrl(26) = dzoomy
95    tab_cntrl(27) = 0.
96    tab_cntrl(28) = 0.
97    tab_cntrl(29) = 0.
98    IF( ysinus )  tab_cntrl(27) = 1.
99  END IF
100  tab_cntrl(30) = REAL(iday_end)
101  tab_cntrl(31) = REAL(itau_dyn + itaufin)
102! start_time: start_time of simulation (not necessarily 0.)
103  tab_cntrl(32) = start_time
104!.........................................................
105
106!--- File creation
107  CALL err(NF90_CREATE(fichnom,NF90_CLOBBER,nid))
108
109!--- Some global attributes
110  CALL err(NF90_PUT_ATT(nid,NF90_GLOBAL,"title","Fichier demarrage dynamique"))
111
112!--- Dimensions
113  CALL err(NF90_DEF_DIM(nid,"index", length, indexID))
114  CALL err(NF90_DEF_DIM(nid,"rlonu", iip1,   rlonuID))
115  CALL err(NF90_DEF_DIM(nid,"rlatu", jjp1,   rlatuID))
116  CALL err(NF90_DEF_DIM(nid,"rlonv", iip1,   rlonvID))
117  CALL err(NF90_DEF_DIM(nid,"rlatv", jjm,    rlatvID))
118  CALL err(NF90_DEF_DIM(nid,"sigs",  llm,        sID))
119  CALL err(NF90_DEF_DIM(nid,"sig",   llmp1,    sigID))
120  CALL err(NF90_DEF_DIM(nid,"temps", NF90_UNLIMITED, timID))
121
122!--- Define and save invariant fields
123  CALL put_var1("controle","Parametres de controle" ,[indexID],tab_cntrl)
124  CALL put_var1("rlonu"   ,"Longitudes des points U",[rlonuID],rlonu)
125  CALL put_var1("rlatu"   ,"Latitudes des points U" ,[rlatuID],rlatu)
126  CALL put_var1("rlonv"   ,"Longitudes des points V",[rlonvID],rlonv)
127  CALL put_var1("rlatv"   ,"Latitudes des points V" ,[rlatvID],rlatv)
128  CALL put_var1("nivsigs" ,"Numero naturel des couches s"    ,[sID]  ,nivsigs)
129  CALL put_var1("nivsig"  ,"Numero naturel des couches sigma",[sigID],nivsig)
130  CALL put_var1("ap"      ,"Coefficient A pour hybride"      ,[sigID],ap)
131  CALL put_var1("bp"      ,"Coefficient B pour hybride"      ,[sigID],bp)
132  CALL put_var1("presnivs",""                                ,[sID]  ,presnivs)
133! covariant <-> contravariant <-> natural conversion coefficients
134  CALL put_var2("cu","Coefficient de passage pour U",[rlonuID,rlatuID],cu)
135  CALL put_var2("cv","Coefficient de passage pour V",[rlonvID,rlatvID],cv)
136  CALL put_var2("aire","Aires de chaque maille"     ,[rlonvID,rlatuID],aire)
137  CALL put_var2("phisinit","Geopotentiel au sol"    ,[rlonvID,rlatuID],phis)
138
139!--- Define fields saved later
140  WRITE(unites,"('days since ',i4,'-',i2.2,'-',i2.2,' 00:00:00')"),&
141               yyears0,mmois0,jjour0
142  CALL put_var0("temps","Temps de simulation",[timID],unites)
143  CALL put_var0("ucov" ,"Vitesse U"  ,[rlonuID,rlatuID,sID,timID])
144  CALL put_var0("vcov" ,"Vitesse V"  ,[rlonvID,rlatvID,sID,timID])
145  CALL put_var0("teta" ,"Temperature",[rlonvID,rlatuID,sID,timID])
146  DO iq=1,nqtot
147    CALL put_var0(tname(iq),ttext(iq) ,[rlonvID,rlatuID,sID,timID])
148  END DO
149  CALL put_var0("masse","Masse d air"    ,[rlonvID,rlatuID,sID,timID])
150  CALL put_var0("ps"   ,"Pression au sol",[rlonvID,rlatuID    ,timID])
151  CALL err(NF90_ENDDEF(nid))
152  CALL err(NF90_CLOSE (nid))
153
154  WRITE(lunout,*)TRIM(modname)//': iim,jjm,llm,iday_end',iim,jjm,llm,iday_end
155  WRITE(lunout,*)TRIM(modname)//': rad,omeg,g,cpp,kappa',rad,omeg,g,cpp,kappa
156
157
158CONTAINS
159
160
161SUBROUTINE put_var0(var,title,did,units)
162  CHARACTER(LEN=*),           INTENT(IN) :: var, title
163  INTEGER,                    INTENT(IN) :: did(:)
164  CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: units
165#ifdef NC_DOUBLE
166  CALL err(NF90_DEF_VAR(nid,var,NF90_DOUBLE,did,vID),var)
167#else
168  CALL err(NF90_DEF_VAR(nid,var,NF90_FLOAT,did,vID),var)
169#endif
170  IF(title/="")      CALL err(NF90_PUT_ATT(nid,vID,"title",title),var)
171  IF(PRESENT(units)) CALL err(NF90_PUT_ATT(nid,vID,"units",units),var)
172END SUBROUTINE put_var0
173
174
175SUBROUTINE put_var1(var,title,did,v,units)
176  CHARACTER(LEN=*),           INTENT(IN) :: var, title
177  INTEGER,                    INTENT(IN) :: did(1)
178#ifdef NC_DOUBLE
179  DOUBLE PRECISION,           INTENT(IN) :: v(:)
180#else
181  REAL,                       INTENT(IN) :: v(:)
182#endif
183  CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: units
184#ifdef NC_DOUBLE
185  CALL err(NF90_DEF_VAR(nid,var,NF90_DOUBLE,did,vID),var)
186#else
187  CALL err(NF90_DEF_VAR(nid,var,NF90_FLOAT,did,vID),var)
188#endif
189  IF(title/="")      CALL err(NF90_PUT_ATT(nid,vID,"title",title),var)
190  IF(PRESENT(units)) CALL err(NF90_PUT_ATT(nid,vID,"units",units),var)
191  CALL err(NF90_ENDDEF(nid))
192  CALL NF95_PUT_VAR(nid,vID,v)
193  CALL err(NF90_REDEF(nid))
194END SUBROUTINE put_var1
195
196
197SUBROUTINE put_var2(var,title,did,v,units)
198  CHARACTER(LEN=*),           INTENT(IN) :: var, title
199  INTEGER,                    INTENT(IN) :: did(2)
200#ifdef NC_DOUBLE
201  DOUBLE PRECISION,           INTENT(IN) :: v(:,:)
202#else
203  REAL,                       INTENT(IN) :: v(:,:)
204#endif
205  CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: units
206#ifdef NC_DOUBLE
207  CALL err(NF90_DEF_VAR(nid,var,NF90_DOUBLE,did,vID),var)
208#else
209  CALL err(NF90_DEF_VAR(nid,var,NF90_FLOAT,did,vID),var)
210#endif
211  IF(title/="")      CALL err(NF90_PUT_ATT(nid,vID,"title",title),var)
212  IF(PRESENT(units)) CALL err(NF90_PUT_ATT(nid,vID,"units",units),var)
213  CALL err(NF90_ENDDEF(nid))
214  CALL NF95_PUT_VAR(nid,vID,v)
215  CALL err(NF90_REDEF(nid))
216
217END SUBROUTINE put_var2
218
219
220SUBROUTINE err(ierr,var)
221  USE netcdf, ONLY: NF90_STRERROR, NF90_NOERR
222  IMPLICIT NONE
223  INTEGER,                    INTENT(IN) :: ierr   !--- NetCDF ERROR CODE
224  CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: var    !--- VARIABLE NAME
225  CHARACTER(LEN=256) :: file, msg
226  IF(ierr==NF90_NoERR) RETURN
227  msg='Error in "'//TRIM(modname)//'" for file "'//TRIM(fichnom)//'"'
228  IF(PRESENT(var)) msg=TRIM(msg)//'" and variable "'//TRIM(var)//'"'
229  WRITE(lunout,*)TRIM(msg)//': '//NF90_STRERROR(ierr)
230
231END SUBROUTINE err
232
233END SUBROUTINE dynredem0
234!
235!-------------------------------------------------------------------------------
236
237
238!-------------------------------------------------------------------------------
239!
240SUBROUTINE dynredem1(fichnom,time,vcov,ucov,teta,q,masse,ps)
241!
242!-------------------------------------------------------------------------------
243! Purpose: Write the NetCDF restart file (append).
244!-------------------------------------------------------------------------------
245  USE infotrac
246  USE control_mod
247  USE netcdf,   ONLY: NF90_OPEN,  NF90_NOWRITE, NF90_INQ_VARID, NF90_NoErr,    &
248                      NF90_CLOSE, NF90_WRITE,   NF90_GET_VAR
249  USE netcdf95, ONLY: NF95_PUT_VAR
250  USE assert_eq_m, ONLY: assert_eq
251  IMPLICIT NONE
252#include "dimensions.h"
253#include "paramet.h"
254#include "description.h"
255#include "comvert.h"
256#include "comgeom.h"
257#include "temps.h"
258#include "iniprint.h"
259!===============================================================================
260! Arguments:
261  CHARACTER(LEN=*), INTENT(IN) :: fichnom           !-- FILE NAME
262  REAL, INTENT(IN) ::  time                         !-- TIME
263  REAL, INTENT(IN) ::  vcov(iip1,jjm, llm)          !-- V COVARIANT WIND
264  REAL, INTENT(IN) ::  ucov(iip1,jjp1,llm)          !-- U COVARIANT WIND
265  REAL, INTENT(IN) ::  teta(iip1,jjp1,llm)          !-- POTENTIAL TEMPERATURE
266  REAL, INTENT(IN) ::     q(iip1,jjp1,llm,nqtot)    !-- TRACERS
267  REAL, INTENT(IN) :: masse(iip1,jjp1,llm)          !-- MASS PER CELL
268  REAL, INTENT(IN) ::    ps(iip1,jjp1)              !-- GROUND PRESSURE
269!===============================================================================
270! Local variables:
271  INTEGER :: l, iq, nid, vID, nid_trac, vID_trac
272  INTEGER, SAVE :: nb=0
273  INTEGER, PARAMETER :: length=100
274#ifdef NC_DOUBLE
275  DOUBLE PRECISION   :: trac_tmp(ip1jmp1,llm)
276#else
277  REAL               :: trac_tmp(ip1jmp1,llm)
278#endif
279  REAL               :: tab_cntrl(length) ! tableau des parametres du run
280  CHARACTER(LEN=256) :: modname, var, fil
281  LOGICAL            :: exist_file
282!===============================================================================
283  modname='dynredem1'
284  fil=fichnom
285  CALL err(NF90_OPEN(fil,NF90_WRITE,nid),"open",fil)
286
287!--- Write/extend time coordinate
288  nb = nb + 1
289  CALL sav_var1("temps",[time],nb)
290  WRITE(lunout,*)TRIM(modname)//": Saving for ", nb, time
291
292!--- Rewrite control table (itaufin undefined in dynredem0)
293  var="controle"
294  CALL get_var1(var,tab_cntrl); tab_cntrl(31)=DBLE(itau_dyn + itaufin)
295  CALL err(NF90_INQ_VARID(nid,var,vID),"inq",var)
296  CALL NF95_PUT_VAR(nid,vID,tab_cntrl)
297
298!--- Save fields
299  CALL sav_var3("ucov",ucov)
300  CALL sav_var3("vcov",vcov)
301  CALL sav_var3("teta",teta)
302  CALL sav_var3("masse",masse)
303  CALL sav_var2("ps"   ,ps)
304
305!--- Tracers in file "start_trac.nc" (added by Anne)
306  IF (type_trac == 'inca') THEN
307    fil="start_trac.nc"; INQUIRE(FILE=fil,EXIST=exist_file)
308    IF(.NOT.exist_file) CALL war(-1,"open",fil)
309  END IF
310  DO iq=1,nqtot; var=tname(iq)
311
312  !--- Usual case
313    IF(type_trac/='inca') THEN
314      CALL sav_var3(var,q(:,:,:,iq)); CYCLE
315    END IF
316
317  !--- Special case for INCA tracer read from "start_trac.nc"
318    IF(NF90_INQ_VARID(nid_trac,var,vID_trac)/=NF90_NoErr) THEN
319      CALL war(-1,"inq",var,fil)
320      CALL err(NF90_INQ_VARID(nid,var,vID),"inq",var,fil)
321      CALL NF95_PUT_VAR(nid,vID,q(:,:,:,iq))
322    ELSE
323      WRITE(lunout,*)TRIM(modname)//": <"//TRIM(var)//"> found in "//fil
324      CALL err(NF90_GET_VAR(nid_trac,vID_trac,trac_tmp),"get",var,fil)
325    END IF
326    CALL sav_var3(var,RESHAPE(trac_tmp,SHAPE=[iip1,jjp1,llm]))
327  END DO
328  CALL err(NF90_CLOSE(nid),"close",fichnom)
329
330
331CONTAINS
332
333
334SUBROUTINE get_var1(var,v)
335  CHARACTER(LEN=*), INTENT(IN) :: var
336  REAL,             INTENT(OUT) :: v(:)
337  CALL err(NF90_INQ_VARID(nid,var,vID),"inq",var)
338  CALL err(NF90_GET_VAR(nid,vID,v),"get",var)
339END SUBROUTINE get_var1
340
341
342SUBROUTINE sav_var1(var,v,start)
343  CHARACTER(LEN=*),  INTENT(IN) :: var
344#ifdef NC_DOUBLE
345  DOUBLE PRECISION,  INTENT(IN) :: v(:)
346#else
347  REAL,              INTENT(IN) :: v(:)
348#endif
349  INTEGER, OPTIONAL, INTENT(IN) :: start
350  CALL err(NF90_INQ_VARID(nid,var,vID),"inq",var)
351  IF(PRESENT(start)) THEN
352    CALL NF95_PUT_VAR(nid,vID,v,start=[start])
353  ELSE
354    CALL NF95_PUT_VAR(nid,vID,v)
355  END IF
356END SUBROUTINE sav_var1
357
358
359SUBROUTINE sav_var2(var,v)
360  CHARACTER(LEN=*), INTENT(IN) :: var
361#ifdef NC_DOUBLE
362  DOUBLE PRECISION, INTENT(IN) :: v(:,:)
363#else
364  REAL,             INTENT(IN) :: v(:,:)
365#endif
366  CALL err(NF90_INQ_VARID(nid,var,vID),"inq",var)
367  CALL NF95_PUT_VAR(nid,vID,v)
368END SUBROUTINE sav_var2
369
370
371SUBROUTINE sav_var3(var,v)
372  CHARACTER(LEN=*), INTENT(IN) :: var
373#ifdef NC_DOUBLE
374  DOUBLE PRECISION, INTENT(IN) :: v(:,:,:)
375#else
376  REAL,             INTENT(IN) :: v(:,:,:)
377#endif
378
379print*,'var='//TRIM(var)
380print*,SHAPE(v)
381  CALL err(NF90_INQ_VARID(nid,var,vID),"inq",var)
382  CALL NF95_PUT_VAR(nid,vID,v)
383END SUBROUTINE sav_var3
384
385
386FUNCTION msg(typ,nam,fil)
387  IMPLICIT NONE
388  CHARACTER(LEN=256)           :: msg    !--- STANDARDIZED MESSAGE
389  CHARACTER(LEN=*), INTENT(IN) :: typ    !--- TYPE OF OPERATION
390  CHARACTER(LEN=*), INTENT(IN) :: nam    !--- FIELD NAME
391  CHARACTER(LEN=*), INTENT(IN) :: fil    !--- FILE  NAME
392  SELECT CASE(typ)
393    CASE('inq');   msg="Missing field <"//TRIM(nam)//">"
394    CASE('get');   msg="Reading failed for <"//TRIM(nam)//">"
395    CASE('open');  msg="Opening failed for <"//TRIM(nam)//">"
396    CASE('close'); msg="Closing failed for <"//TRIM(nam)//">"
397  END SELECT
398  msg=TRIM(modname)//": "//TRIM(msg)
399  IF(typ=="inq".AND.fil/="") msg=TRIM(msg)//" in file <"//TRIM(fil)//">"
400
401END FUNCTION msg
402
403
404SUBROUTINE err(ierr,typ,nam,fil)
405  IMPLICIT NONE
406  INTEGER,                    INTENT(IN) :: ierr   !--- NetCDF ERROR CODE
407  CHARACTER(LEN=*),           INTENT(IN) :: typ    !--- TYPE OF OPERATION
408  CHARACTER(LEN=*),           INTENT(IN) :: nam    !--- FIELD NAME
409  CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fil    !--- FILE  NAME
410  CHARACTER(LEN=256) :: file
411  IF(ierr==NF90_NoERR) RETURN
412  file=""; IF(PRESENT(fil)) file=fil
413  CALL ABORT_gcm(modname,msg(typ,nam,file),ierr)
414END SUBROUTINE err
415
416
417SUBROUTINE war(ierr,typ,nam,fil)
418  IMPLICIT NONE
419  INTEGER,                    INTENT(IN) :: ierr   !--- NetCDF ERROR CODE
420  CHARACTER(LEN=*),           INTENT(IN) :: typ    !--- TYPE OF OPERATION
421  CHARACTER(LEN=*),           INTENT(IN) :: nam    !--- FIELD NAME
422  CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: fil    !--- FILE  NAME
423  CHARACTER(LEN=256) :: file
424  IF(ierr==NF90_NoERR) RETURN
425  file=""; IF(PRESENT(fil)) file=fil
426  WRITE(lunout,*)msg(typ,nam,file)
427END SUBROUTINE war
428
429
430END SUBROUTINE dynredem1
431
Note: See TracBrowser for help on using the repository browser.