source: trunk/LMDZ.GENERIC/libf/phystd/writediagsoil.F90 @ 1477

Last change on this file since 1477 was 1315, checked in by milmd, 10 years ago

LMDZ.GENERIC. OpenMP directives added in generic physic. When running in pure OpenMP or hybrid OpenMP/MPI, may have some bugs with condense_cloud and wstats routines.

File size: 10.1 KB
Line 
1subroutine writediagsoil(ngrid,name,title,units,dimpx,px)
2
3! Write variable 'name' to NetCDF file 'diagsoil.nc'.
4! The variable may be 3D (lon,lat,depth) subterranean field,
5! a 2D (lon,lat) surface field, or a simple scalar (0D variable).
6!
7! Calls to 'writediagsoil' can originate from anywhere in the program;
8! An initialisation of variable 'name' is done if it is the first time
9! that this routine is called with given 'name'; otherwise data is appended
10! (yielding the sought time series of the variable)
11
12! Modifs: Aug.2010 Ehouarn: enforce outputs to be real*4
13
14use comsoil_h, only: nsoilmx
15use control_mod, only: ecritphy, day_step, iphysiq
16use mod_phys_lmdz_para, only : is_mpi_root, is_master, gather
17use mod_grid_phy_lmdz, only : klon_glo, Grid1Dto2D_glo
18
19implicit none
20
21#include"dimensions.h"
22#include"paramet.h"
23#include"netcdf.inc"
24
25! Arguments:
26integer,intent(in) :: ngrid ! number of (horizontal) points of physics grid
27! i.e. ngrid = 2+(jjm-1)*iim - 1/jjm
28character(len=*),intent(in) :: name ! 'name' of the variable
29character(len=*),intent(in) :: title ! 'long_name' attribute of the variable
30character(len=*),intent(in) :: units ! 'units' attribute of the variable
31integer,intent(in) :: dimpx ! dimension of the variable (3,2 or 0)
32real,dimension(ngrid,nsoilmx),intent(in) :: px ! variable
33! Note: nsoilmx is a parameter set in 'comsoil_h'
34
35! Local variables:
36real*4,dimension(iip1,jjp1,nsoilmx) :: data3 ! to store 3D data
37! Note iip1,jjp1 known from paramet.h; nsoilmx known from comsoil_h
38real*4,dimension(iip1,jjp1) :: data2 ! to store 2D data
39real*4 :: data0 ! to store 0D data
40integer :: i,j,l ! for loops
41integer :: ig0
42
43real*4,save :: date ! time counter (in elapsed days)
44integer,save :: isample ! sample rate at which data is to be written to output
45integer,save :: ntime=0 ! counter to internally store time steps
46character(len=20),save :: firstname="1234567890"
47integer,save :: zitau=0
48!$OMP THREADPRIVATE(date,isample,ntime,firstname,zitau)
49
50character(len=30) :: filename="diagsoil.nc"
51
52! NetCDF stuff:
53integer :: nid ! NetCDF output file ID
54integer :: varid ! NetCDF ID of a variable
55integer :: ierr ! NetCDF routines return code
56integer,dimension(4) :: id ! NetCDF IDs of the dimensions of the variable
57integer,dimension(4) :: edges,corners
58
59#ifdef CPP_PARA
60! Added to work in parallel mode
61real dx3_glop(klon_glo,nsoilmx)
62real dx3_glo(iim,jjp1,nsoilmx) ! to store a global 3D data set
63real dx2_glop(klon_glo)
64real dx2_glo(iim,jjp1)     ! to store a global 2D (surface) data set
65real px2(ngrid)
66#endif
67
68! 1. Initialization step
69if (firstname.eq."1234567890") then
70  ! Store 'name' as 'firstname'
71  firstname=name
72  ! From now on, if 'name'.eq.'firstname', then it is a new time cycle
73
74  ! just to be sure, check that firstnom is large enough to hold nom
75  if (len_trim(firstname).lt.len_trim(name)) then
76    write(*,*) "writediagsoil: Error !!!"
77    write(*,*) "   firstname string not long enough!!"
78    write(*,*) "   increase its size to at least ",len_trim(name)
79    stop
80  endif
81 
82  ! Set output sample rate
83  isample=ecritphy ! same as for diagfi outputs
84  ! Note ecritphy is known from control.h
85 
86  ! Create output NetCDF file
87  if (is_master) then
88   ierr=NF_CREATE(filename,NF_CLOBBER,nid)
89   if (ierr.ne.NF_NOERR) then
90    write(*,*)'writediagsoil: Error, failed creating file '//trim(filename)
91    stop
92   endif
93  endif ! of if (is_master)
94
95  ! Define dimensions and axis attributes
96  call iniwritesoil(nid,ngrid)
97 
98  ! set zitau to -1 to be compatible with zitau incrementation step below
99  zitau=-1
100 
101else
102  ! If not an initialization call, simply open the NetCDF file
103  if (is_master) then
104   ierr=NF_OPEN(filename,NF_WRITE,nid)
105  endif
106endif ! of if (firstname.eq."1234567890")
107
108! 2. Increment local time counter, if necessary
109if (name.eq.firstname) then
110  ! if we run across 'firstname', then it is a new time step
111  zitau=zitau+iphysiq
112  ! Note iphysiq is known from control.h
113endif
114
115! 3. Write data, if the time index matches the sample rate
116if (mod(zitau+1,isample).eq.0) then
117
118! 3.1 If first call at this date, update 'time' variable
119  if (name.eq.firstname) then
120    ntime=ntime+1
121    date=float(zitau+1)/float(day_step)
122    ! Note: day_step is known from control.h
123   
124    if (is_master) then
125     ! Get NetCDF ID for "time"
126     ierr=NF_INQ_VARID(nid,"time",varid)
127     ! Add the current value of date to the "time" array
128!#ifdef NC_DOUBLE
129!     ierr=NF_PUT_VARA_DOUBLE(nid,varid,ntime,1,date)
130!#else
131     ierr=NF_PUT_VARA_REAL(nid,varid,ntime,1,date)
132!#endif
133     if (ierr.ne.NF_NOERR) then
134      write(*,*)"writediagsoil: Failed writing date to time variable"
135      stop
136     endif
137    endif ! of if (is_master)
138  endif ! of if (name.eq.firstname)
139
140! 3.2 Write the variable to the NetCDF file
141if (dimpx.eq.3) then ! Case of a 3D variable
142  ! A. Recast data along 'dynamics' grid
143#ifdef CPP_PARA
144  ! gather field on a "global" (without redundant longitude) array
145  call Gather(px,dx3_glop)
146!$OMP MASTER
147  if (is_mpi_root) then
148    call Grid1Dto2D_glo(dx3_glop,dx3_glo)
149    ! copy dx3_glo() to dx3(:) and add redundant longitude
150    data3(1:iim,:,:)=dx3_glo(1:iim,:,:)
151    data3(iip1,:,:)=data3(1,:,:)
152  endif
153!$OMP END MASTER
154!$OMP BARRIER
155#else
156  do l=1,nsoilmx
157    ! handle the poles
158    do i=1,iip1
159      data3(i,1,l)=px(1,l)
160      data3(i,jjp1,l)=px(ngrid,l)
161    enddo
162    ! rest of the grid
163    do j=2,jjm
164      ig0=1+(j-2)*iim
165      do i=1,iim
166        data3(i,j,l)=px(ig0+i,l)
167      enddo
168      data3(iip1,j,l)=data3(1,j,l) ! extra (modulo) longitude
169    enddo
170  enddo
171#endif
172 
173  ! B. Write (append) the variable to the NetCDF file
174  if (is_master) then
175  ! B.1. Get the ID of the variable
176  ierr=NF_INQ_VARID(nid,name,varid)
177  if (ierr.ne.NF_NOERR) then
178    ! If we failed geting the variable's ID, we assume it is because
179    ! the variable doesn't exist yet and must be created.
180    ! Start by obtaining corresponding dimensions IDs
181    ierr=NF_INQ_DIMID(nid,"longitude",id(1))
182    ierr=NF_INQ_DIMID(nid,"latitude",id(2))
183    ierr=NF_INQ_DIMID(nid,"depth",id(3))
184    ierr=NF_INQ_DIMID(nid,"time",id(4))
185    ! Tell the world about it
186    write(*,*) "====================="
187    write(*,*) "writediagsoil: creating variable "//trim(name)
188    call def_var(nid,name,title,units,4,id,varid,ierr)
189  endif ! of if (ierr.ne.NF_NOERR)
190 
191  ! B.2. Prepare things to be able to write/append the variable
192  corners(1)=1
193  corners(2)=1
194  corners(3)=1
195  corners(4)=ntime
196 
197  edges(1)=iip1
198  edges(2)=jjp1
199  edges(3)=nsoilmx
200  edges(4)=1
201 
202  ! B.3. Write the slab of data
203!#ifdef NC_DOUBLE
204!  ierr=NF_PUT_VARA_DOUBLE(nid,varid,corners,edges,data3)
205!#else
206  ierr=NF_PUT_VARA_REAL(nid,varid,corners,edges,data3)
207!#endif
208  if (ierr.ne.NF_NOERR) then
209    write(*,*) "writediagsoil: Error: Failed writing "//trim(name)//&
210               " to file "//trim(filename)//" at time",date
211  endif
212  endif ! of if (is_master)
213
214elseif (dimpx.eq.2) then ! Case of a 2D variable
215
216  ! A. Recast data along 'dynamics' grid
217#ifdef CPP_PARA
218  ! gather field on a "global" (without redundant longitude) array
219  px2(:)=px(:,1)
220  call Gather(px2,dx2_glop)
221!$OMP MASTER
222  if (is_mpi_root) then
223    call Grid1Dto2D_glo(dx2_glop,dx2_glo)
224    ! copy dx3_glo() to dx3(:) and add redundant longitude
225    data2(1:iim,:)=dx2_glo(1:iim,:)
226    data2(iip1,:)=data2(1,:)
227  endif
228!$OMP END MASTER
229!$OMP BARRIER
230#else
231  ! handle the poles
232  do i=1,iip1
233    data2(i,1)=px(1,1)
234    data2(i,jjp1)=px(ngrid,1)
235  enddo
236  ! rest of the grid
237  do j=2,jjm
238    ig0=1+(j-2)*iim
239    do i=1,iim
240      data2(i,j)=px(ig0+i,1)
241    enddo
242    data2(iip1,j)=data2(1,j) ! extra (modulo) longitude
243  enddo
244#endif
245
246  ! B. Write (append) the variable to the NetCDF file
247  if (is_master) then
248  ! B.1. Get the ID of the variable
249  ierr=NF_INQ_VARID(nid,name,varid)
250  if (ierr.ne.NF_NOERR) then
251    ! If we failed geting the variable's ID, we assume it is because
252    ! the variable doesn't exist yet and must be created.
253    ! Start by obtaining corresponding dimensions IDs
254    ierr=NF_INQ_DIMID(nid,"longitude",id(1))
255    ierr=NF_INQ_DIMID(nid,"latitude",id(2))
256    ierr=NF_INQ_DIMID(nid,"time",id(3))
257    ! Tell the world about it
258    write(*,*) "====================="
259    write(*,*) "writediagsoil: creating variable "//trim(name)
260    call def_var(nid,name,title,units,3,id,varid,ierr)
261  endif ! of if (ierr.ne.NF_NOERR)
262
263  ! B.2. Prepare things to be able to write/append the variable
264  corners(1)=1
265  corners(2)=1
266  corners(3)=ntime
267 
268  edges(1)=iip1
269  edges(2)=jjp1
270  edges(3)=1
271 
272  ! B.3. Write the slab of data
273!#ifdef NC_DOUBLE
274!  ierr=NF_PUT_VARA_DOUBLE(nid,varid,corners,edges,data2)
275!#else
276  ierr=NF_PUT_VARA_REAL(nid,varid,corners,edges,data2)
277!#endif
278  if (ierr.ne.NF_NOERR) then
279    write(*,*) "writediagsoil: Error: Failed writing "//trim(name)//&
280               " to file "//trim(filename)//" at time",date
281  endif
282  endif ! of if (is_master)
283
284elseif (dimpx.eq.0) then ! Case of a 0D variable
285#ifdef CPP_PARA
286  write(*,*) "writediagsoil: dimps==0 case not implemented in // mode!!"
287  stop
288#endif
289  ! A. Copy data value
290  data0=px(1,1)
291
292  ! B. Write (append) the variable to the NetCDF file
293  ! B.1. Get the ID of the variable
294  ierr=NF_INQ_VARID(nid,name,varid)
295  if (ierr.ne.NF_NOERR) then
296    ! If we failed geting the variable's ID, we assume it is because
297    ! the variable doesn't exist yet and must be created.
298    ! Start by obtaining corresponding dimensions IDs
299    ierr=NF_INQ_DIMID(nid,"time",id(1))
300    ! Tell the world about it
301    write(*,*) "====================="
302    write(*,*) "writediagsoil: creating variable "//trim(name)
303    call def_var(nid,name,title,units,1,id,varid,ierr)
304  endif ! of if (ierr.ne.NF_NOERR)
305
306  ! B.2. Prepare things to be able to write/append the variable
307  corners(1)=ntime
308 
309  edges(1)=1
310
311  ! B.3. Write the data
312!#ifdef NC_DOUBLE
313!  ierr=NF_PUT_VARA_DOUBLE(nid,varid,corners,edges,data0)
314!#else
315  ierr=NF_PUT_VARA_REAL(nid,varid,corners,edges,data0)
316!#endif
317  if (ierr.ne.NF_NOERR) then
318    write(*,*) "writediagsoil: Error: Failed writing "//trim(name)//&
319               " to file "//trim(filename)//" at time",date
320  endif
321
322endif ! of if (dimpx.eq.3) elseif (dimpx.eq.2) ...
323endif ! of if (mod(zitau+1,isample).eq.0)
324
325! 4. Close the NetCDF file
326if (is_master) then
327  ierr=NF_CLOSE(nid)
328endif
329
330end subroutine writediagsoil
Note: See TracBrowser for help on using the repository browser.