source: trunk/LMDZ.GENERIC/libf/phystd/wstats.F90 @ 1157

Last change on this file since 1157 was 965, checked in by emillour, 12 years ago

Common dynamics and generic/universal GCM:

  • LMDZ.COMMON: minor bug fix on the computation of physics mesh area in gcm.F
  • LMDZ.UNIVERSAL: missing clean initialization of tab_cntrl(:) array in phyredem.F90
  • LMDZ.GENERIC: minor bug fix in hydrol.F90, only output runoff if it is used. Update output routines so that all outputs files (stats, diagfi.nc, diagsoil.nc, diagspecIR.nc and diagspecVI.nc) can be generated when running LMDZ.UNIVERSAL in MPI mode.

EM

File size: 9.0 KB
Line 
1subroutine wstats(ngrid,nom,titre,unite,dim,px)
2
3#ifdef CPP_PARA
4use mod_phys_lmdz_para, only : is_mpi_root, is_master, gather, klon_mpi_begin
5use mod_grid_phy_lmdz, only : klon_glo, Grid1Dto2D_glo
6#endif
7
8implicit none
9
10#include "dimensions.h"
11#include "dimphys.h"
12#include "comconst.h"
13#include "statto.h"
14#include "netcdf.inc"
15
16integer,intent(in) :: ngrid
17character (len=*),intent(in) :: nom,titre,unite
18integer,intent(in) :: dim
19integer,parameter :: iip1=iim+1
20integer,parameter :: jjp1=jjm+1
21real,intent(in) :: px(ngrid,llm)
22real, dimension(iip1,jjp1,llm) :: mean3d,sd3d,dx3
23real, dimension(iip1,jjp1) :: mean2d,sd2d,dx2
24character (len=50) :: namebis
25character (len=50), save :: firstvar
26integer :: ierr,varid,nbdim,nid
27integer :: meanid,sdid
28integer, dimension(4)  :: id,start,sizes
29logical, save :: firstcall=.TRUE.
30integer :: l,i,j,ig0
31integer,save :: indx
32
33integer, save :: step=0
34
35! Added to work in parallel mode
36#ifdef CPP_PARA
37real px3_glop(klon_glo,llm) ! to store a 3D data set on global physics grid
38real px3_glo(iim,jjp1,llm) ! to store a global 3D data set on global lonxlat grid
39real px2_glop(klon_glo) ! to store a 2D data set on global physics grid
40real px2_glo(iim,jjp1) ! to store a 2D data set on global lonxlat grid
41real px2(ngrid)
42real px3(ngrid,llm)
43#else
44! When not running in parallel mode:
45real px3_glop(ngrid,llm) ! to store a 3D data set on global physics grid
46real px3_glo(iim,jjp1,llm) ! to store a global 3D data set on global lonxlat grid
47real px2_glop(ngrid) ! to store a 2D data set on global physics grid
48real px2_glo(iim,jjp1) ! to store a 2D data set on global lonxlat grid
49logical,parameter :: is_master=.true.
50logical,parameter :: is_mpi_root=.true.
51integer,parameter :: klon_mpi_begin=1
52#endif
53
54! 1. Initialization (creation of stats.nc file)
55if (firstcall) then
56   firstcall=.false.
57   firstvar=trim((nom))
58   call inistats(ierr)
59endif
60
61if (firstvar==nom) then ! If we're back to the first variable, increment time counter
62      step = step + 1
63endif
64
65if (mod(step,istats).ne.0) then
66  ! if its not time to write to file, exit
67   RETURN
68endif
69
70! collect fields on a global physics grid
71#ifdef CPP_PARA
72 if (dim.eq.3) then
73  px3(1:ngrid,1:llm)=px(1:ngrid,1:llm)
74  ! Gather fieds on a "global" (without redundant longitude) array
75  call Gather(px3,px3_glop)
76!$OMP MASTER
77  if (is_mpi_root) then
78    call Grid1Dto2D_glo(px3_glop,px3_glo)
79    ! copy dx3_glo() to dx3(:) and add redundant longitude
80    dx3(1:iim,:,:)=px3_glo(1:iim,:,:)
81    dx3(iip1,:,:)=dx3(1,:,:)
82  endif
83!$OMP END MASTER
84!$OMP BARRIER
85 else ! dim.eq.2
86  ! Gather fieds on a "global" (without redundant longitude) array
87  px2(:)=px(:,1)
88  call Gather(px2,px2_glop)
89!$OMP MASTER
90          if (is_mpi_root) then
91            call Grid1Dto2D_glo(px2_glop,px2_glo)
92            ! copy px2_glo() to dx2(:) and add redundant longitude
93            dx2(1:iim,:)=px2_glo(1:iim,:)
94            dx2(iip1,:)=dx2(1,:)
95          endif
96!$OMP END MASTER
97!$OMP BARRIER
98 endif
99#else
100  if (dim.eq.3) then
101    px3_glop(:,1:llm)=px(:,1:llm)
102!  Passage variable physique -->  variable dynamique
103    DO l=1,llm
104      DO i=1,iim
105         px3_glo(i,1,l)=px(1,l)
106         px3_glo(i,jjp1,l)=px(ngrid,l)
107      ENDDO
108      DO j=2,jjm
109         ig0= 1+(j-2)*iim
110         DO i=1,iim
111            px3_glo(i,j,l)=px(ig0+i,l)
112         ENDDO
113      ENDDO
114    ENDDO
115  else ! dim.eq.2
116    px2_glop(:)=px(:,1)
117!    Passage variable physique -->  physique dynamique
118   DO i=1,iim
119     px2_glo(i,1)=px(1,1)
120     px2_glo(i,jjp1)=px(ngrid,1)
121   ENDDO
122   DO j=2,jjm
123     ig0= 1+(j-2)*iim
124     DO i=1,iim
125        px2_glo(i,j)=px(ig0+i,1)
126     ENDDO
127   ENDDO
128  endif
129#endif
130
131! 2. Write field to file
132
133if (is_master) then
134! only master needs do this
135
136ierr = NF_OPEN("stats.nc",NF_WRITE,nid)
137
138namebis=trim(nom)
139
140! test: check if that variable already exists in file
141ierr= NF_INQ_VARID(nid,namebis,meanid)
142
143if (ierr.ne.NF_NOERR) then
144  ! variable not in file, create/define it
145   if (firstvar==nom) then
146      indx=1
147      count(:)=0
148   endif
149
150
151!declaration de la variable
152
153! choix du nom des coordonnees
154   ierr= NF_INQ_DIMID(nid,"longitude",id(1))
155   ierr= NF_INQ_DIMID(nid,"latitude",id(2))
156   if (dim.eq.3) then
157      ierr= NF_INQ_DIMID(nid,"altitude",id(3))
158      ierr= NF_INQ_DIMID(nid,"Time",id(4))
159      nbdim=4
160   else if (dim==2) then
161      ierr= NF_INQ_DIMID(nid,"Time",id(3))
162      nbdim=3
163   endif
164
165   write (*,*) "====================="
166   write (*,*) "STATS: creation de ",nom
167   namebis=trim(nom)
168   call def_var(nid,namebis,titre,unite,nbdim,id,meanid,ierr)
169   if (dim.eq.3) then
170     call inivar(nid,meanid,size(px3_glop,1),dim,indx,px3_glop,ierr)
171   else ! dim.eq.2
172     call inivar(nid,meanid,size(px2_glop,1),dim,indx,px2_glop,ierr)
173   endif
174   namebis=trim(nom)//"_sd"
175   call def_var(nid,namebis,trim(titre)//" total standard deviation over the season",unite,nbdim,id,sdid,ierr)
176   if (dim.eq.3) then
177     call inivar(nid,sdid,size(px3_glop,1),dim,indx,px3_glop,ierr)
178   else ! dim.eq.2
179     call inivar(nid,sdid,size(px2_glop,1),dim,indx,px2_glop,ierr)
180   endif
181
182   ierr= NF_CLOSE(nid)
183   return
184
185else
186   ! variable found in file
187   namebis=trim(nom)//"_sd"
188   ierr= NF_INQ_VARID(nid,namebis,sdid)
189
190endif
191
192if (firstvar==nom) then
193   count(indx)=count(int(indx))+1
194   indx=indx+1
195   if (indx>istime) then
196      indx=1
197   endif
198endif
199
200if (count(indx)==0) then
201   ! very first time we write the variable to file
202   if (dim.eq.3) then
203      start=(/1,1,1,indx/)
204      sizes=(/iip1,jjp1,llm,1/)
205      mean3d(:,:,:)=0
206      sd3d(:,:,:)=0
207   else if (dim.eq.2) then
208      start=(/1,1,indx,0/)
209      sizes=(/iip1,jjp1,1,0/)
210      mean2d(:,:)=0
211      sd2d(:,:)=0
212   endif
213else
214   ! load values from file
215   if (dim.eq.3) then
216      start=(/1,1,1,indx/)
217      sizes=(/iip1,jjp1,llm,1/)
218#ifdef NC_DOUBLE
219      ierr = NF_GET_VARA_DOUBLE(nid,meanid,start,sizes,mean3d)
220      ierr = NF_GET_VARA_DOUBLE(nid,sdid,start,sizes,sd3d)
221#else
222      ierr = NF_GET_VARA_REAL(nid,meanid,start,sizes,mean3d)
223      ierr = NF_GET_VARA_REAL(nid,sdid,start,sizes,sd3d)
224#endif
225      if (ierr.ne.NF_NOERR) then
226         write (*,*) NF_STRERROR(ierr)
227         stop ""
228      endif
229
230   else if (dim.eq.2) then
231      start=(/1,1,indx,0/)
232      sizes=(/iip1,jjp1,1,0/)
233#ifdef NC_DOUBLE
234      ierr = NF_GET_VARA_DOUBLE(nid,meanid,start,sizes,mean2d)
235      ierr = NF_GET_VARA_DOUBLE(nid,sdid,start,sizes,sd2d)
236#else
237      ierr = NF_GET_VARA_REAL(nid,meanid,start,sizes,mean2d)
238      ierr = NF_GET_VARA_REAL(nid,sdid,start,sizes,sd2d)
239#endif
240      if (ierr.ne.NF_NOERR) then
241         write (*,*) NF_STRERROR(ierr)
242         stop ""
243      endif
244   endif
245endif ! of if (count(indx)==0)
246
247
248! 2.1. Build dx* (data on lon-lat grid, with redundant longitude)
249
250if (dim.eq.3) then
251  dx3(1:iim,:,:)=px3_glo(:,:,:)
252  dx3(iip1,:,:)=dx3(1,:,:)
253else ! dim.eq.2
254  dx2(1:iim,:)=px2_glo(:,:)
255  dx2(iip1,:)=dx2(1,:)
256endif
257
258
259! 2.2. Add current values to previously stored sums
260
261if (dim.eq.3) then
262
263   mean3d(:,:,:)=mean3d(:,:,:)+dx3(:,:,:)
264   sd3d(:,:,:)=sd3d(:,:,:)+dx3(:,:,:)**2
265
266#ifdef NC_DOUBLE
267   ierr = NF_PUT_VARA_DOUBLE(nid,meanid,start,sizes,mean3d)
268   ierr = NF_PUT_VARA_DOUBLE(nid,sdid,start,sizes,sd3d)
269#else
270   ierr = NF_PUT_VARA_REAL(nid,meanid,start,sizes,mean3d)
271   ierr = NF_PUT_VARA_REAL(nid,sdid,start,sizes,sd3d)
272#endif
273
274else if (dim.eq.2) then
275
276   mean2d(:,:)= mean2d(:,:)+dx2(:,:)
277   sd2d(:,:)=sd2d(:,:)+dx2(:,:)**2
278
279#ifdef NC_DOUBLE
280   ierr = NF_PUT_VARA_DOUBLE(nid,meanid,start,sizes,mean2d)
281   ierr = NF_PUT_VARA_DOUBLE(nid,sdid,start,sizes,sd2d)
282#else
283   ierr = NF_PUT_VARA_REAL(nid,meanid,start,sizes,mean2d)
284   ierr = NF_PUT_VARA_REAL(nid,sdid,start,sizes,sd2d)
285#endif
286
287endif ! of if (dim.eq.3) elseif (dim.eq.2)
288
289  ierr= NF_CLOSE(nid)
290endif ! of if (is_master)
291
292end
293
294!======================================================
295subroutine inivar(nid,varid,ngrid,dim,indx,px,ierr)
296
297implicit none
298
299include "dimensions.h"
300include "dimphys.h"
301include "netcdf.inc"
302
303integer, intent(in) :: nid,varid,dim,indx,ngrid
304real, dimension(ngrid,llm), intent(in) :: px
305integer, intent(out) :: ierr
306
307integer,parameter :: iip1=iim+1
308integer,parameter :: jjp1=jjm+1
309
310integer :: l,i,j,ig0
311integer, dimension(4) :: start,sizes
312real, dimension(iip1,jjp1,llm) :: dx3
313real, dimension(iip1,jjp1) :: dx2
314
315if (dim.eq.3) then
316
317   start=(/1,1,1,indx/)
318   sizes=(/iip1,jjp1,llm,1/)
319
320!  Passage variable physique -->  variable dynamique
321
322   DO l=1,llm
323      DO i=1,iip1
324         dx3(i,1,l)=px(1,l)
325         dx3(i,jjp1,l)=px(ngrid,l)
326      ENDDO
327      DO j=2,jjm
328         ig0= 1+(j-2)*iim
329         DO i=1,iim
330            dx3(i,j,l)=px(ig0+i,l)
331         ENDDO
332         dx3(iip1,j,l)=dx3(1,j,l)
333      ENDDO
334   ENDDO
335
336#ifdef NC_DOUBLE
337   ierr = NF_PUT_VARA_DOUBLE(nid,varid,start,sizes,dx3)
338#else
339   ierr = NF_PUT_VARA_REAL(nid,varid,start,sizes,dx3)
340#endif
341
342else if (dim.eq.2) then
343
344      start=(/1,1,indx,0/)
345      sizes=(/iip1,jjp1,1,0/)
346
347!    Passage variable physique -->  physique dynamique
348
349  DO i=1,iip1
350     dx2(i,1)=px(1,1)
351     dx2(i,jjp1)=px(ngrid,1)
352  ENDDO
353  DO j=2,jjm
354     ig0= 1+(j-2)*iim
355     DO i=1,iim
356        dx2(i,j)=px(ig0+i,1)
357     ENDDO
358     dx2(iip1,j)=dx2(1,j)
359  ENDDO
360
361#ifdef NC_DOUBLE
362   ierr = NF_PUT_VARA_DOUBLE(nid,varid,start,sizes,dx2)
363#else
364   ierr = NF_PUT_VARA_REAL(nid,varid,start,sizes,dx2)
365#endif
366
367endif
368
369end
Note: See TracBrowser for help on using the repository browser.