source: trunk/LMDZ.PLUTO/libf/phypluto/writediagspecVI.F @ 4113

Last change on this file since 4113 was 4027, checked in by debatzbr, 3 months ago

Pluto PCM: Adding a slow_diagfi flag for 1D model from Generic PCM (revision 3928).
BBT

File size: 11.4 KB
Line 
1      subroutine writediagspecVI(ngrid,nom,titre,unite,dimpx,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!  "diagfi_output_rate " 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!      dimpx : dimension de px : 0, 2, ou 3 dimensions
35!
36!=================================================================
37!
38!      This is a modified version that accepts spectrally varying input
39!      RW (2010)
40!
41!=================================================================
42
43! Addition by RW (2010) to allow OSR to be saved in .nc format
44      use radinc_h, only : L_NSPECTV
45      use geometry_mod, only: cell_area
46      use mod_phys_lmdz_para, only : is_mpi_root, is_master, gather
47      use mod_grid_phy_lmdz, only : klon_glo, Grid1Dto2D_glo,
48     &                              nbp_lon, nbp_lat, grid_type,
49     &                              unstructured
50      use time_phylmdz_mod, only: diagfi_output_rate,dtphys,daysec
51      use time_phylmdz_mod, only: day_ini
52      use callkeys_mod, only: iradia
53
54      implicit none
55
56      include "netcdf.inc"
57
58! Arguments on input:
59      integer ngrid
60      character (len=*) :: nom,titre,unite
61      integer dimpx
62      real px(ngrid,L_NSPECTV)
63
64! Local variables:
65
66!      real dx3(iip1,jjp1,llm) ! to store a 3D data set
67!      real dx2(iip1,jjp1)     ! to store a 2D (surface) data set
68!      real dx0
69
70      integer isample
71      integer ierr
72      integer iq
73      integer i,j,l,zmax , ig0
74
75      integer,save :: zitau=0
76      character(len=20),save :: firstnom='1234567890'
77      real,save :: date
78!$OMP THREADPRIVATE(firstnom,zitau,date)
79
80! Ajouts
81      integer, save :: ntime=0
82!$OMP THREADPRIVATE(ntime)
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      real area((nbp_lon+1),nbp_lat)
90! added by RDW for OSR output
91      real dx3(nbp_lon+1,nbp_lat,L_NSPECTV) ! to store the data set
92      real dx3_1d(1,L_NSPECTV) ! to store the data with 1D model
93
94#ifdef CPP_PARA
95! Added to work in parallel mode
96      real dx3_glop(klon_glo,L_NSPECTV)
97      real dx3_glo(nbp_lon,nbp_lat,L_NSPECTV) ! to store a global 3D data set
98      real areafi_glo(klon_glo) ! mesh area on global physics grid
99#else
100      real areafi_glo(ngrid) ! mesh area on global physics grid
101#endif
102      if (grid_type == unstructured) then
103        return
104      endif
105
106!***************************************************************
107!Sortie des variables au rythme voulu
108
109      isample = diagfi_output_rate*iradia ! sortie au rythme de diagfi_output_rate
110!EM+JL if the spetra need to be output more frequently, need to define a ecritSpec...
111!     isample = diagfi_output_rate  ! sortie a tous les pas physique
112
113!***************************************************************
114
115! Initialisation of 'firstnom' and create/open the "diagfi.nc" NetCDF file
116! ------------------------------------------------------------------------
117! (Au tout premier appel de la subroutine durant le run.)
118
119      fichnom="diagspecVI.nc"
120
121      if (firstnom.eq.'1234567890') then ! .true. for the very first call
122      !  to this subroutine; now set 'firstnom'
123         firstnom = nom
124         ! just to be sure, check that firstnom is large enough to hold nom
125         if (len_trim(firstnom).lt.len_trim(nom)) then
126           write(*,*) "writediagfi: Error !!!"
127           write(*,*) "   firstnom string not long enough!!"
128           write(*,*) "   increase its size to at least ",len_trim(nom)
129           stop
130         endif
131
132#ifdef CPP_PARA
133          ! Gather cell_area() mesh area on physics grid
134          call Gather(cell_area,areafi_glo)
135#else
136         areafi_glo(:)=cell_area(:)
137#endif
138         ! Create the NetCDF file
139         if (is_master) then
140         ierr = NF_CREATE(fichnom, NF_CLOBBER, nid)
141         ! Define the 'Time' dimension
142         ierr = nf_def_dim(nid,"Time",NF_UNLIMITED,idim)
143         ! Define the 'Time' variable
144#ifdef NC_DOUBLE
145         ierr = NF_DEF_VAR (nid, "Time", NF_DOUBLE, 1, idim,varid)
146#else
147         ierr = NF_DEF_VAR (nid, "Time", NF_FLOAT, 1, idim,varid)
148#endif
149         ! Add a long_name attribute
150         ierr = NF_PUT_ATT_TEXT (nid, varid, "long_name",
151     .          4,"Time")
152         ! Add a units attribute
153         ierr = NF_PUT_ATT_TEXT(nid, varid,'units',29,
154     .          "days since 0000-00-0 00:00:00")
155         ! Switch out of NetCDF Define mode
156         ierr = NF_ENDDEF(nid)
157
158         ! Build area()
159         IF (klon_glo>1) THEN
160          do i=1,nbp_lon+1 ! poles
161           ! divide at the poles by nbp_lon
162           area(i,1)=areafi_glo(1)/nbp_lon
163           area(i,nbp_lat)=areafi_glo(klon_glo)/nbp_lon
164          enddo
165          do j=2,nbp_lat-1
166           ig0= 1+(j-2)*nbp_lon
167           do i=1,nbp_lon
168              area(i,j)=areafi_glo(ig0+i)
169           enddo
170           ! handle redundant point in longitude
171           area(nbp_lon+1,j)=area(1,j)
172          enddo
173         ENDIF
174
175         ! write "header" of file (longitudes, latitudes, geopotential, ...)
176         IF (klon_glo>1) THEN ! general 3D case
177           call iniwrite_specVI(nid,day_ini,area,nbp_lon+1,nbp_lat)
178         ELSE
179           call iniwrite_specVI(nid,day_ini,areafi_glo(1),1,1)
180         ENDIF
181         ! Close the NetCDF file
182               ierr= NF_CLOSE(nid)
183         endif ! of if (is_master)
184
185         zitau = -1 ! initialize zitau
186      endif ! if (firstnom.eq.'1234567890')
187
188! Increment time index 'zitau' if it is the "firstcall" (at given time level)
189! to writediagfi
190!------------------------------------------------------------------------
191      if (nom.eq.firstnom) then
192          zitau = zitau + 1
193      end if
194
195!--------------------------------------------------------
196! Write the variables to output file if it's time to do so
197!--------------------------------------------------------
198
199      if ( MOD(zitau+1,isample) .eq.0.) then
200
201! Compute/write/extend 'Time' coordinate (date given in days)
202! (done every "first call" (at given time level) to writediagfi)
203! Note: date is incremented as 1 step ahead of physics time
204!       (like the 'histoire' outputs)
205!--------------------------------------------------------
206
207        if (is_master) then
208                ! Open the NetCDF file
209                ierr = NF_OPEN(fichnom,NF_WRITE,nid)
210              endif
211
212        if (nom.eq.firstnom) then
213
214        ! We have identified a "first call" (at given date)
215           ntime=ntime+1 ! increment # of stored time steps
216           ! compute corresponding date (in days and fractions thereof)
217           date= float (zitau +1)*(dtphys/daysec)
218
219           if (is_master) then
220             ! Get NetCDF ID of 'Time' variable
221             ierr= NF_INQ_VARID(nid,"Time",varid)
222
223             ! Write (append) the new date to the 'Time' array
224#ifdef NC_DOUBLE
225             ierr= NF_PUT_VARA_DOUBLE(nid,varid,ntime,1,date)
226#else
227             ierr= NF_PUT_VARA_REAL(nid,varid,ntime,1,date)
228#endif
229             if (ierr.ne.NF_NOERR) then
230              write(*,*) "***** PUT_VAR matter in writediagspec_nc"
231              write(*,*) "***** with time"
232              write(*,*) 'ierr=', ierr
233c             call abort
234             endif
235
236             write(6,*)'WRITEDIAGSPECVI: date= ', date
237           endif ! of if (is_master)
238        end if ! of if (nom.eq.firstnom)
239
240
241
242!Case of a 3D variable
243!---------------------
244        if (dimpx.eq.3) then
245
246!         A. Recast (copy) variable from physics grid to dynamics grid
247#ifdef CPP_PARA
248  ! gather field on a "global" (without redundant longitude) array
249          call Gather(px,dx3_glop)
250!$OMP MASTER
251          if (is_mpi_root) then
252            call Grid1Dto2D_glo(dx3_glop,dx3_glo)
253            ! copy dx3_glo() to dx3(:) and add redundant longitude
254            dx3(1:nbp_lon,:,:)=dx3_glo(1:nbp_lon,:,:)
255            dx3(nbp_lon+1,:,:)=dx3(1,:,:)
256          endif
257!$OMP END MASTER
258!$OMP BARRIER
259#else
260          IF (klon_glo>1) THEN ! General case
261           DO l=1,L_NSPECTV
262             DO i=1,nbp_lon+1
263                dx3(i,1,l)=px(1,l)
264                dx3(i,nbp_lat,l)=px(ngrid,l)
265             ENDDO
266             DO j=2,nbp_lat-1
267                ig0= 1+(j-2)*nbp_lon
268                DO i=1,nbp_lon
269                   dx3(i,j,l)=px(ig0+i,l)
270                ENDDO
271                dx3(nbp_lon+1,j,l)=dx3(1,j,l)
272             ENDDO
273           ENDDO
274          ELSE ! 1D model case
275           dx3_1d(1,1:L_NSPECTV)=px(1,1:L_NSPECTV)
276          ENDIF
277#endif
278
279!         B. Write (append) the variable to the NetCDF file
280          if (is_master) then
281
282! name of the variable
283           ierr= NF_INQ_VARID(nid,nom,varid)
284           if (ierr /= NF_NOERR) then
285! corresponding dimensions
286              ierr= NF_INQ_DIMID(nid,"longitude",id(1))
287              ierr= NF_INQ_DIMID(nid,"latitude",id(2))
288              ierr= NF_INQ_DIMID(nid,"VI_Wavenumber",id(3))
289              ierr= NF_INQ_DIMID(nid,"Time",id(4))
290
291! Create the variable if it doesn't exist yet
292
293              write (*,*) "=========================="
294              write (*,*) "DIAGSPEC: creating variable ",nom
295              call def_var(nid,nom,titre,unite,4,id,varid,ierr)
296
297           endif
298
299           corner(1)=1
300           corner(2)=1
301           corner(3)=1
302           corner(4)=ntime
303
304           IF (klon_glo==1) THEN
305             edges(1)=1
306           ELSE
307             edges(1)=nbp_lon+1
308           ENDIF
309           edges(2)=nbp_lat
310           edges(3)=L_NSPECTV
311           edges(4)=1
312#ifdef NC_DOUBLE
313           IF (klon_glo>1) THEN ! General case
314             ierr= NF_PUT_VARA_DOUBLE(nid,varid,corner,edges,dx3)
315           ELSE
316             ierr= NF_PUT_VARA_DOUBLE(nid,varid,corner,edges,dx3_1d)
317           ENDIF
318#else
319           IF (klon_glo>1) THEN ! General case
320             ierr= NF_PUT_VARA_REAL(nid,varid,corner,edges,dx3)
321           ELSE
322             ierr= NF_PUT_VARA_REAL(nid,varid,corner,edges,dx3_1d)
323           ENDIF
324#endif
325
326           if (ierr.ne.NF_NOERR) then
327              write(*,*) "***** PUT_VAR problem in writediagspec"
328              write(*,*) "***** with ",nom
329              write(*,*) 'ierr=', ierr
330             call abort
331           endif
332
333          endif ! of if (is_master)
334
335        endif ! of if (dimpx.eq.3)
336
337        ! Close the NetCDF file
338              if (is_master) then
339                ierr= NF_CLOSE(nid)
340              endif
341
342      endif ! of if ( MOD(zitau+1,irythme) .eq.0.)
343
344      end
Note: See TracBrowser for help on using the repository browser.