source: trunk/MESOSCALE/LMDZ.MARS/libf_gcm/phymars/writediagfi.F @ 1242

Last change on this file since 1242 was 57, checked in by aslmd, 14 years ago

mineur LMD_MM_MARS: ajout du GCM ancienne physique, systeme maintenant complet sur SVN (ne manque que la base de donnees d'etats initiaux)

File size: 11.0 KB
Line 
1      subroutine writediagfi(ngrid,nom,titre,unite,dim,px)
2
3!  Ecriture de variables diagnostiques au choix dans la physique
4!  dans un fichier NetCDF nomme  'diagfi'. Ces variables peuvent etre
5!  3d (ex : temperature), 2d (ex : temperature de surface), ou
6!  0d (pour un scalaire qui ne depend que du temps : ex : la longitude
7!  solaire)
8!  Dans la version 2000, la periode d'ecriture est celle de
9!  "ecritphy " regle dans le fichier de controle de run :  run.def
10!
11!    writediagfi peut etre appele de n'importe quelle subroutine
12!    de la physique, plusieurs fois. L'initialisation et la creation du
13!    fichier se fait au tout premier appel.
14!
15! WARNING : les variables dynamique (u,v,t,q,ps)
16!  sauvees par writediagfi avec une
17! date donnee sont legerement differentes que dans le fichier histoire car
18! on ne leur a pas encore ajoute de la dissipation et de la physique !!!
19! IL est  RECOMMANDE d'ajouter les tendance physique a ces variables
20! avant l'ecriture dans diagfi (cf. physiq.F)
21
22!
23!  parametres (input) :
24!  ----------
25!      ngrid : nombres de point ou est calcule la physique
26!                (ngrid = 2+(jjm-1)*iim - 1/jjm)
27!                 (= nlon ou klon dans la physique terrestre)
28!     
29!      unit : unite logique du fichier de sortie (toujours la meme)
30!      nom  : nom de la variable a sortir (chaine de caracteres)
31!      titre: titre de la variable (chaine de caracteres)
32!      unite : unite de la variable (chaine de caracteres)
33!      px : variable a sortir (real 0, 2, ou 3d)
34!      dim : dimension de px : 0, 2, ou 3 dimensions
35!
36!=================================================================
37 
38      implicit none
39
40! Commons
41#include "dimensions.h"
42#include "dimphys.h"
43#include "paramet.h"
44#include "control.h"
45#include "comvert.h"
46#include "comgeom.h"
47#include "description.h"
48#include "netcdf.inc"
49#include "temps.h"
50#include "surfdat.h"
51
52! Arguments on input:
53      integer ngrid
54      character (len=*) :: nom,titre,unite
55      integer dim
56      real px(ngrid,llm)
57
58! Local variables:
59
60      real dx3(iip1,jjp1,llm) ! to store a 3D data set
61      real dx2(iip1,jjp1)     ! to store a 2D (surface) data set
62      real dx0
63
64      real date
65
66      REAL phis(ip1jmp1)
67
68      integer irythme
69      integer ierr
70      integer iq
71      integer i,j,l,zmax , ig0
72
73      integer zitau
74      character firstnom*10
75      SAVE firstnom
76      SAVE zitau
77      SAVE date
78      data firstnom /'1234567890'/
79      data zitau /0/
80
81! Ajouts
82      integer, save :: ntime=0
83      integer :: idim,varid
84      integer :: nid
85      character (len =50):: fichnom
86      integer, dimension(4) :: id
87      integer, dimension(4) :: edges,corner
88     
89
90!***************************************************************
91!Sortie des variables au rythme voulu
92
93      irythme = int(ecritphy) ! sortie au rythme de ecritphy
94!     irythme = iconser  ! sortie au rythme des variables de controle
95!     irythme = iphysiq  ! sortie a tous les pas physique
96!     irythme = iecri*day_step ! sortie au rythme des fichiers histoires
97!     irythme = periodav*day_step ! sortie au rythme des fichiers histmoy
98
99!***************************************************************
100
101! The following test is here to enforce that writediagfi is not used with the
102! 1D version of the GCM
103      if (ngrid.eq.1) return
104     
105c     nom=trim((nom))
106c     unite=trim((unite))
107c     titre=trim((titre))
108
109! Initialisation of 'firstnom' and create/open the "diagfi.nc" NetCDF file
110! ------------------------------------------------------------------------
111! (Au tout premier appel de la subroutine durant le run.)
112
113      fichnom="diagfi.nc"
114
115      if (firstnom.eq.'1234567890') then ! .true. for the very first call
116      !  to this subroutine; now set 'firstnom'
117         firstnom = nom
118
119         call gr_fi_dyn(1,ngrid,iip1,jjp1,phisfi,phis)
120         ! Create the NetCDF file
121         ierr = NF_CREATE(fichnom, NF_CLOBBER, nid)
122         ! Define the 'Time' dimension
123         ierr = nf_def_dim(nid,"Time",NF_UNLIMITED,idim)
124         ! Define the 'Time' variable
125#ifdef NC_DOUBLE
126         ierr = NF_DEF_VAR (nid, "Time", NF_DOUBLE, 1, idim,varid)
127#else
128         ierr = NF_DEF_VAR (nid, "Time", NF_FLOAT, 1, idim,varid)
129#endif
130         ! Add a long_name attribute
131         ierr = NF_PUT_ATT_TEXT (nid, varid, "long_name",
132     .          4,"Time")
133         ! Add a units attribute
134         ierr = NF_PUT_ATT_TEXT(nid, varid,'units',29,
135     .          "days since 0000-00-0 00:00:00")
136         ! Switch out of NetCDF Define mode
137         ierr = NF_ENDDEF(nid)
138
139         ! write "header" of file (longitudes, latitudes, geopotential, ...)
140         call iniwrite(nid,day_ini,phis)
141         
142         zitau = -1 ! initialize zitau
143      else
144         ! Open the NetCDF file
145         ierr = NF_OPEN(fichnom,NF_WRITE,nid)
146      endif ! if (firstnom.eq.'1234567890')
147
148! Increment time index 'zitau' if it is the "fist call" (at given time level)
149! to writediagfi
150!------------------------------------------------------------------------
151      if (nom.eq.firstnom) then
152          zitau = zitau + iphysiq
153      end if
154
155!--------------------------------------------------------
156! Write the variables to output file if it's time to do so
157!--------------------------------------------------------
158
159      if ( MOD(zitau+1,irythme) .eq.0.) then
160
161! Compute/write/extend 'Time' coordinate (date given in days)
162! (done every "first call" (at given time level) to writediagfi)
163! Note: date is incremented as 1 step ahead of physics time
164!       (like the 'histoire' outputs)
165!--------------------------------------------------------
166
167        if (nom.eq.firstnom) then
168        ! We have identified a "first call" (at given date)
169           ntime=ntime+1 ! increment # of stored time steps
170           ! compute corresponding date (in days and fractions thereof)
171           date= float (zitau +1)/float (day_step)
172           ! Get NetCDF ID of 'Time' variable
173           ierr= NF_INQ_VARID(nid,"Time",varid)
174           ! Write (append) the new date to the 'Time' array
175#ifdef NC_DOUBLE
176           ierr= NF_PUT_VARA_DOUBLE(nid,varid,ntime,1,date)
177#else
178           ierr= NF_PUT_VARA_REAL(nid,varid,ntime,1,date)
179#endif
180           if (ierr.ne.NF_NOERR) then
181              write(*,*) "***** PUT_VAR matter in writediagfi_nc"
182              write(*,*) "***** with time"
183              write(*,*) 'ierr=', ierr   
184c             call abort
185           endif
186
187           write(6,*)'WRITEDIAGFI: date= ', date
188        end if ! of if (nom.eq.firstnom)
189
190!Case of a 3D variable
191!---------------------
192        if (dim.eq.3) then
193
194!         Passage variable physique -->  variable dynamique
195!         recast (copy) variable from physics grid to dynamics grid
196           DO l=1,llm
197             DO i=1,iip1
198                dx3(i,1,l)=px(1,l)
199                dx3(i,jjp1,l)=px(ngrid,l)
200             ENDDO
201             DO j=2,jjm
202                ig0= 1+(j-2)*iim
203                DO i=1,iim
204                   dx3(i,j,l)=px(ig0+i,l)
205                ENDDO
206                dx3(iip1,j,l)=dx3(1,j,l)
207             ENDDO
208           ENDDO
209
210!         Ecriture du champs
211
212!         write (*,*) 'In  writediagfi, on sauve:  ' , nom
213!         write (*,*) 'In  writediagfi. Estimated date = ' ,date
214! name of the variable
215           ierr= NF_INQ_VARID(nid,nom,varid)
216           if (ierr /= NF_NOERR) then
217! corresponding dimensions
218              ierr= NF_INQ_DIMID(nid,"longitude",id(1))
219              ierr= NF_INQ_DIMID(nid,"latitude",id(2))
220              ierr= NF_INQ_DIMID(nid,"altitude",id(3))
221              ierr= NF_INQ_DIMID(nid,"Time",id(4))
222
223! Create the variable if it doesn't exist yet
224
225              write (*,*) "=========================="
226              write (*,*) "DIAGFI: creating variable ",nom
227              call def_var(nid,nom,titre,unite,4,id,varid,ierr)
228
229           endif
230
231           corner(1)=1
232           corner(2)=1
233           corner(3)=1
234           corner(4)=ntime
235
236           edges(1)=iip1
237           edges(2)=jjp1
238           edges(3)=llm
239           edges(4)=1
240#ifdef NC_DOUBLE
241           ierr= NF_PUT_VARA_DOUBLE(nid,varid,corner,edges,dx3)
242#else
243           ierr= NF_PUT_VARA_REAL(nid,varid,corner,edges,dx3)
244#endif
245
246           if (ierr.ne.NF_NOERR) then
247              write(*,*) "***** PUT_VAR problem in writediagfi"
248              write(*,*) "***** with ",nom
249              write(*,*) 'ierr=', ierr
250c             call abort
251           endif
252
253!Case of a 2D variable
254!---------------------
255
256        else if (dim.eq.2) then
257
258!         Passage variable physique -->  physique dynamique
259!         recast (copy) variable from physics grid to dynamics grid
260
261             DO i=1,iip1
262                dx2(i,1)=px(1,1)
263                dx2(i,jjp1)=px(ngrid,1)
264             ENDDO
265             DO j=2,jjm
266                ig0= 1+(j-2)*iim
267                DO i=1,iim
268                   dx2(i,j)=px(ig0+i,1)
269                ENDDO
270                dx2(iip1,j)=dx2(1,j)
271             ENDDO
272
273!         write (*,*) 'In  writediagfi, on sauve:  ' , nom
274!         write (*,*) 'In  writediagfi. Estimated date = ' ,date
275           ierr= NF_INQ_VARID(nid,nom,varid)
276           if (ierr /= NF_NOERR) then
277! corresponding dimensions
278              ierr= NF_INQ_DIMID(nid,"longitude",id(1))
279              ierr= NF_INQ_DIMID(nid,"latitude",id(2))
280              ierr= NF_INQ_DIMID(nid,"Time",id(3))
281
282! Create the variable if it doesn't exist yet
283
284              write (*,*) "=========================="
285              write (*,*) "DIAGFI: creating variable ",nom
286
287              call def_var(nid,nom,titre,unite,3,id,varid,ierr)
288
289           endif
290
291           corner(1)=1
292           corner(2)=1
293           corner(3)=ntime
294           edges(1)=iip1
295           edges(2)=jjp1
296           edges(3)=1
297
298
299#ifdef NC_DOUBLE
300           ierr = NF_PUT_VARA_DOUBLE (nid,varid,corner,edges,dx2)
301#else         
302           ierr= NF_PUT_VARA_REAL(nid,varid,corner,edges,dx2)
303#endif     
304
305           if (ierr.ne.NF_NOERR) then
306              write(*,*) "***** PUT_VAR matter in writediagfi"
307              write(*,*) "***** with ",nom
308              write(*,*) 'ierr=', ierr
309c             call abort
310           endif
311
312!Case of a 0D variable (ie: a time-dependent scalar)
313!---------------------------------------------------
314
315        else if (dim.eq.0) then
316           dx0 = px (1,1)
317
318           ierr= NF_INQ_VARID(nid,nom,varid)
319           if (ierr /= NF_NOERR) then
320! corresponding dimensions
321              ierr= NF_INQ_DIMID(nid,"Time",id(1))
322
323! Create the variable if it doesn't exist yet
324
325              write (*,*) "=========================="
326              write (*,*) "DIAGFI: creating variable ",nom
327
328              call def_var(nid,nom,titre,unite,1,id,varid,ierr)
329
330           endif
331
332           corner(1)=ntime
333           edges(1)=1
334
335#ifdef NC_DOUBLE
336           ierr = NF_PUT_VARA_DOUBLE (nid,varid,corner,edges,dx0) 
337#else
338           ierr= NF_PUT_VARA_REAL(nid,varid,corner,edges,dx0)
339#endif
340           if (ierr.ne.NF_NOERR) then
341              write(*,*) "***** PUT_VAR matter in writediagfi"
342              write(*,*) "***** with ",nom
343              write(*,*) 'ierr=', ierr
344c             call abort
345           endif
346
347        endif ! of if (dim.eq.3) elseif(dim.eq.2)...
348
349      endif ! of if ( MOD(zitau+1,irythme) .eq.0.)
350
351      ierr= NF_CLOSE(nid)
352
353      end
Note: See TracBrowser for help on using the repository browser.