source: codes/icosagcm/branches/SATURN_DYNAMICO/LMDZ.COMMON/libf/phystd/writediagsoil.F90 @ 242

Last change on this file since 242 was 227, checked in by milmd, 10 years ago

Last LMDZ version (1315) with OpenMP directives and other stuff

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.