source: trunk/LMDZ.GENERIC/libf/phystd/writediagfi.F @ 146

Last change on this file since 146 was 135, checked in by aslmd, 14 years ago

CHANGEMENT ARBORESCENCE ETAPE 2 -- NON COMPLET

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