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

Last change on this file since 1243 was 1216, checked in by emillour, 11 years ago

Generic model:
Major cleanup, in order to ease the use of LMDZ.GENERIC with (parallel) dynamics
in LMDZ.COMMON: (NB: this will break LMDZ.UNIVERSAL, which should be thrashed
in the near future)

  • Updated makegcm_* scripts (and makdim) and added the "-full" (to enforce full recomputation of the model) option
  • In dyn3d: converted control.h to module control_mod.F90 and converted iniadvtrac.F to module infotrac.F90
  • Added module mod_const_mpi.F90 in dyn3d (not used in serial mode)
  • Rearanged input/outputs routines everywhere to handle serial/MPI cases. physdem.F => phyredem.F90 , phyetat0.F => phyetat0.F90 ; all read/write routines for startfi files are gathered in module iostart.F90
  • added parallelism related routines init_phys_lmdz.F90, comgeomphy.F90, dimphy.F90, iniphysiq.F90, mod_grid_phy_lmdz.F90, mod_phys_lmdz_mpi_data.F90, mod_phys_lmdz_mpi_transfert.F90, mod_phys_lmdz_omp_data.F90, mod_phys_lmdz_omp_transfert.F90, mod_phys_lmdz_para.F90, mod_phys_lmdz_transfert_para.F90 in phymars and mod_const_mpi.F90 in dyn3d (for compliance with parallelism)
  • added created generic routines 'planetwide_maxval' and 'planetwide_minval', in module "planetwide_mod", that enable obtaining the max and min of a field over the whole planet. This should be further imroved with computation of means (possibly area weighed), etc.

EM

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