source: tags/ORCHIDEE_1_9_5_2/ORCHIDEE_OL/forcesoil.f90 @ 560

Last change on this file since 560 was 395, checked in by martial.mancip, 13 years ago

Optimize allocation in forcesoil restart writes.

File size: 12.9 KB
Line 
1PROGRAM forcesoil
2  !---------------------------------------------------------------------
3  ! This program reads a forcing file for STOMATE's soil carbon routine
4  ! which was created with STOMATE.
5  ! It then integrates STOMATE's soil carbon parameterizations
6  ! for a given number of years using this forcing.
7  !---------------------------------------------------------------------
8  !- IPSL (2006)
9  !-  This software is governed by the CeCILL licence see ORCHIDEE/ORCHIDEE_CeCILL.LIC
10  USE netcdf
11  !-
12  USE defprec
13  USE constantes
14  USE constantes_veg
15  USE constantes_co2
16  USE stomate_constants
17  USE ioipsl
18  USE stomate_soilcarbon
19  USE parallel
20  !-
21  IMPLICIT NONE
22  !-
23  CHARACTER(LEN=80) :: sto_restname_in,sto_restname_out
24  INTEGER(i_std)                             :: iim,jjm
25
26  INTEGER(i_std),PARAMETER                   :: llm = 1
27  INTEGER(i_std)                             :: kjpindex
28
29  INTEGER(i_std)                             :: itau_dep,itau_len
30  CHARACTER(LEN=30)                         :: time_str
31  REAL(r_std)                                :: dt_files
32  REAL(r_std)                                :: date0
33  INTEGER(i_std)                             :: rest_id_sto
34  CHARACTER(LEN=20), SAVE                    :: thecalendar = 'noleap'
35  !-
36  CHARACTER(LEN=100) :: Cforcing_name
37  INTEGER            :: Cforcing_id
38  INTEGER            :: v_id
39  REAL(r_std)                                :: dt_forcesoil
40  INTEGER                                   :: nparan
41
42  INTEGER(i_std),DIMENSION(:),ALLOCATABLE    :: indices
43  INTEGER(i_std),DIMENSION(:),ALLOCATABLE    :: indices_g
44  REAL(r_std),DIMENSION(:),ALLOCATABLE       :: x_indices_g
45  REAL(r_std),DIMENSION(:,:),ALLOCATABLE     :: lon, lat
46  REAL(r_std),DIMENSION(llm)                 :: lev
47
48
49  INTEGER                                   :: i,m,iatt,iv,iyear
50
51  CHARACTER(LEN=80)                         :: var_name
52  CHARACTER(LEN=400)                        :: taboo_vars
53  REAL(r_std),DIMENSION(1)                   :: xtmp
54  INTEGER(i_std),PARAMETER                   :: nbvarmax=300
55  INTEGER(i_std)                             :: nbvar
56  CHARACTER(LEN=50),DIMENSION(nbvarmax)     :: varnames
57  INTEGER(i_std)                             :: varnbdim
58  INTEGER(i_std),PARAMETER                   :: varnbdim_max=20
59  INTEGER,DIMENSION(varnbdim_max)           :: vardims
60  LOGICAL                                   :: l1d
61  REAL(r_std),DIMENSION(:,:),ALLOCATABLE     :: var_3d
62  REAL(r_std)                                :: x_tmp
63  ! string suffix indicating an index
64  CHARACTER(LEN=10)  :: part_str
65  !
66  ! clay fraction
67  REAL(r_std),ALLOCATABLE,SAVE,DIMENSION(:)  :: clay_g
68  REAL(r_std),DIMENSION(:,:,:,:),ALLOCATABLE :: soilcarbon_input_g
69  REAL(r_std),DIMENSION(:,:,:),ALLOCATABLE   :: control_temp_g
70  REAL(r_std),DIMENSION(:,:,:),ALLOCATABLE   :: control_moist_g
71  REAL(r_std),DIMENSION(:,:,:),ALLOCATABLE   :: carbon_g
72
73  REAL(r_std),ALLOCATABLE :: clay(:)
74  REAL(r_std),ALLOCATABLE :: soilcarbon_input(:,:,:,:)
75  REAL(r_std),ALLOCATABLE :: control_temp(:,:,:)
76  REAL(r_std),ALLOCATABLE :: control_moist(:,:,:)
77  REAL(r_std),ALLOCATABLE :: carbon(:,:,:)
78  REAL(r_std),DIMENSION(:,:),ALLOCATABLE     :: resp_hetero_soil
79
80  INTEGER(i_std)                             :: ier,iret
81
82  LOGICAL :: debug
83
84  CALL Init_para(.FALSE.) 
85  CALL init_timer
86
87!---------------------------------------------------------------------
88!-
89! set debug to have more information
90!-
91  !Config  Key  = DEBUG_INFO
92  !Config  Desc = Flag for debug information
93  !Config  Def  = n
94  !Config  Help = This option allows to switch on the output of debug
95  !Config         information without recompiling the code.
96!-
97  debug = .FALSE.
98  CALL getin_p('DEBUG_INFO',debug)
99  !-
100  ! Stomate's restart files
101  !-
102  IF (is_root_prc) THEN
103     sto_restname_in = 'stomate_start.nc'
104     CALL getin ('STOMATE_RESTART_FILEIN',sto_restname_in)
105     WRITE(numout,*) 'STOMATE INPUT RESTART_FILE: ',TRIM(sto_restname_in)
106     sto_restname_out = 'stomate_rest_out.nc'
107     CALL getin ('STOMATE_RESTART_FILEOUT',sto_restname_out)
108     WRITE(numout,*) 'STOMATE OUTPUT RESTART_FILE: ',TRIM(sto_restname_out)
109     !-
110     ! We need to know iim_g, jjm.
111     ! Get them from the restart files themselves.
112     !-
113     iret = NF90_OPEN (sto_restname_in, NF90_NOWRITE, rest_id_sto)
114     iret = NF90_INQUIRE_DIMENSION (rest_id_sto,1,len=iim_g)
115     iret = NF90_INQUIRE_DIMENSION (rest_id_sto,2,len=jjm_g)
116     iret = NF90_INQ_VARID (rest_id_sto, "time", iv)
117     iret = NF90_GET_ATT (rest_id_sto, iv, 'calendar',thecalendar)
118     iret = NF90_CLOSE (rest_id_sto)
119     i=INDEX(thecalendar,ACHAR(0))
120     IF ( i > 0 ) THEN
121        thecalendar(i:20)=' '
122     ENDIF
123     !-
124     ! Allocate longitudes and latitudes
125     !-
126     ALLOCATE (lon(iim_g,jjm_g))
127     ALLOCATE (lat(iim_g,jjm_g))
128     lon(:,:) = 0.0
129     lat(:,:) = 0.0
130     lev(1)   = 0.0
131     !-
132     CALL restini &
133          & (sto_restname_in, iim_g, jjm_g, lon, lat, llm, lev, &
134          &  sto_restname_out, itau_dep, date0, dt_files, rest_id_sto)
135  ENDIF
136  CALL bcast(date0)
137  CALL bcast(thecalendar)
138  WRITE(numout,*) "calendar = ",thecalendar
139  !-
140  ! calendar
141  !-
142  CALL ioconf_calendar (thecalendar)
143  CALL ioget_calendar  (one_year,one_day)
144  CALL ioconf_startdate(date0)
145  !
146  IF (is_root_prc) THEN
147     !-
148     ! open FORCESOIL's forcing file to read some basic info
149     !-
150     Cforcing_name = 'NONE'
151     CALL getin ('STOMATE_CFORCING_NAME',Cforcing_name)
152     !-
153     iret = NF90_OPEN (TRIM(Cforcing_name),NF90_NOWRITE,Cforcing_id)
154     IF (iret /= NF90_NOERR) THEN
155        CALL ipslerr (3,'forcesoil', &
156             &        'Could not open file : ', &
157             &          Cforcing_name,'(Do you have forget it ?)')
158     ENDIF
159     !-
160     ier = NF90_GET_ATT (Cforcing_id,NF90_GLOBAL,'kjpindex',x_tmp)
161     nbp_glo = NINT(x_tmp)
162     ier = NF90_GET_ATT (Cforcing_id,NF90_GLOBAL,'nparan',x_tmp)
163     nparan = NINT(x_tmp)
164     !-
165     ALLOCATE (indices_g(nbp_glo))
166     ALLOCATE (clay_g(nbp_glo))
167     !-
168     ALLOCATE (x_indices_g(nbp_glo),stat=ier)
169     ier = NF90_INQ_VARID (Cforcing_id,'index',v_id)
170     ier = NF90_GET_VAR   (Cforcing_id,v_id,x_indices_g)
171     indices_g(:) = NINT(x_indices_g(:))
172     WRITE(numout,*) mpi_rank,"indices globaux : ",indices_g
173     DEALLOCATE (x_indices_g)
174     !-
175     ier = NF90_INQ_VARID (Cforcing_id,'clay',v_id)
176     ier = NF90_GET_VAR   (Cforcing_id,v_id,clay_g)
177     !-
178     ! time step of forcesoil
179     !-
180     dt_forcesoil = one_year / FLOAT(nparan)
181     WRITE(numout,*) 'time step (d): ',dt_forcesoil
182     !-
183     ! read (and partially write) the restart file
184     !-
185     ! read and write the variables we do not need
186     !-
187     taboo_vars = '$lon$ $lat$ $lev$ $nav_lon$ $nav_lat$ $nav_lev$ $time$ $time_steps$ '// &
188          &             '$day_counter$ $dt_days$ $date$ '// &
189          &             '$carbon_01$ $carbon_02$ $carbon_03$ $carbon_04$ $carbon_05$'// &
190          &             '$carbon_06$ $carbon_07$ $carbon_08$ $carbon_09$ $carbon_10$'// &
191          &             '$carbon_11$ $carbon_12$ $carbon_13$'
192     !-
193     CALL ioget_vname(rest_id_sto, nbvar, varnames)
194     !-
195     ! read and write some special variables (1D or variables that we need)
196     !-
197     var_name = 'day_counter'
198     CALL restget (rest_id_sto, var_name, 1, 1, 1, itau_dep, .TRUE., xtmp)
199     CALL restput (rest_id_sto, var_name, 1, 1, 1, itau_dep, xtmp)
200     !-
201     var_name = 'dt_days'
202     CALL restget (rest_id_sto, var_name, 1, 1, 1, itau_dep, .TRUE., xtmp)
203     CALL restput (rest_id_sto, var_name, 1, 1, 1, itau_dep, xtmp)
204     !-
205     var_name = 'date'
206     CALL restget (rest_id_sto, var_name, 1, 1, 1, itau_dep, .TRUE., xtmp)
207     CALL restput (rest_id_sto, var_name, 1, 1, 1, itau_dep, xtmp)
208     !-
209     DO iv=1,nbvar
210        !-- check if the variable is to be written here
211        IF (INDEX(taboo_vars,'$'//TRIM(varnames(iv))//'$') == 0 ) THEN
212           !---- get variable dimensions, especially 3rd dimension
213           CALL ioget_vdim &
214                &      (rest_id_sto, varnames(iv), varnbdim_max, varnbdim, vardims)
215           l1d = ALL(vardims(1:varnbdim) == 1)
216           !---- read it
217           IF (l1d) THEN
218              CALL restget &
219                   &        (rest_id_sto, TRIM(varnames(iv)), 1, vardims(3), &
220                   &         1, itau_dep, .TRUE., xtmp)
221           ELSE
222              ALLOCATE( var_3d(nbp_glo,vardims(3)), stat=ier)
223              IF (ier /= 0) STOP 'ALLOCATION PROBLEM'
224              !----
225              CALL restget &
226                   &        (rest_id_sto, TRIM(varnames(iv)), nbp_glo, vardims(3), &
227                   &         1, itau_dep, .TRUE., var_3d, "gather", nbp_glo, indices_g)
228           ENDIF
229           !---- write it
230           IF (l1d) THEN
231              CALL restput &
232                   &        (rest_id_sto, TRIM(varnames(iv)), 1, vardims(3), &
233                   &         1, itau_dep, xtmp)
234           ELSE
235              CALL restput &
236                   &        (rest_id_sto, TRIM(varnames(iv)), nbp_glo, vardims(3), &
237                   &         1, itau_dep, var_3d, 'scatter',  nbp_glo, indices_g)
238              !----
239              DEALLOCATE(var_3d)
240           ENDIF
241        ENDIF
242     ENDDO
243     !-
244     ! read soil carbon
245     !-
246     ALLOCATE(carbon_g(nbp_glo,ncarb,nvm))
247     carbon_g(:,:,:) = val_exp
248     DO m = 1, nvm
249        WRITE (part_str, '(I2)') m
250        IF (m<10) part_str(1:1)='0'
251        var_name = 'carbon_'//part_str(1:LEN_TRIM(part_str))
252        CALL restget &
253             &    (rest_id_sto, var_name, nbp_glo, ncarb , 1, itau_dep, &
254             &     .TRUE., carbon_g(:,:,m), 'gather', nbp_glo, indices_g)
255        IF (ALL(carbon_g(:,:,m) == val_exp)) carbon_g(:,:,m) = zero
256        !-- do not write this variable: it will be modified.
257     ENDDO
258     WRITE(numout,*) "date0 : ",date0, itau_dep
259     !-
260     ! Length of run
261     !-
262     WRITE(time_str,'(a)') '10000Y'
263     CALL getin('TIME_LENGTH', time_str)
264     write(numout,*) 'Number of years for carbon spinup : ',time_str
265     ! transform into itau
266     CALL tlen2itau(time_str, dt_forcesoil*one_day, date0, itau_len)
267     write(numout,*) 'Number of time steps to do: ',itau_len
268     !-
269     ! read the rest of the forcing file and store forcing in an array.
270     ! We read an average year.
271     !-
272     ALLOCATE(soilcarbon_input_g(nbp_glo,ncarb,nvm,nparan))
273     ALLOCATE(control_temp_g(nbp_glo,nlevs,nparan))
274     ALLOCATE(control_moist_g(nbp_glo,nlevs,nparan))
275     !-
276     ier = NF90_INQ_VARID (Cforcing_id,'soilcarbon_input',v_id)
277     ier = NF90_GET_VAR   (Cforcing_id,v_id,soilcarbon_input_g)
278     ier = NF90_INQ_VARID (Cforcing_id,   'control_moist',v_id)
279     ier = NF90_GET_VAR   (Cforcing_id,v_id,control_moist_g)
280     ier = NF90_INQ_VARID (Cforcing_id,    'control_temp',v_id)
281     ier = NF90_GET_VAR   (Cforcing_id,v_id,control_temp_g)
282     !-
283     ier = NF90_CLOSE (Cforcing_id)
284     !-
285  ENDIF
286  CALL bcast(nparan)
287  CALL bcast(dt_forcesoil)
288  CALL bcast(iim_g)
289  CALL bcast(jjm_g)
290  call bcast(nbp_glo)
291  CALL bcast(itau_dep)
292  CALL bcast(itau_len)
293  !
294  ! We must initialize data_para :
295     !
296     !
297  CALL init_data_para(iim_g,jjm_g,nbp_glo,indices_g)
298
299  kjpindex=nbp_loc
300  jjm=jj_nb
301  iim=iim_g
302  IF (debug) WRITE(numout,*) "Local grid : ",kjpindex,iim,jjm
303
304  !---
305  !--- Create the index table
306  !---
307  !--- This job return a LOCAL kindex
308  !---
309  ALLOCATE (indices(kjpindex),stat=ier)
310  CALL scatter(indices_g,indices)
311  indices(1:kjpindex)=indices(1:kjpindex)-(jj_begin-1)*iim_g
312  IF (debug) WRITE(numout,*) mpi_rank,"indices locaux = ",indices(1:kjpindex)
313  !-
314  !-
315  ! there we go: time loop
316  !-
317  ALLOCATE(clay(kjpindex))
318  ALLOCATE(soilcarbon_input(kjpindex,ncarb,nvm,nparan))
319  ALLOCATE(control_temp(kjpindex,nlevs,nparan))
320  ALLOCATE(control_moist(kjpindex,nlevs,nparan))
321  ALLOCATE(carbon(kjpindex,ncarb,nvm))
322  ALLOCATE(resp_hetero_soil(kjpindex,nvm))
323  iatt = 0
324
325  CALL Scatter(clay_g,clay)
326  CALL Scatter(soilcarbon_input_g,soilcarbon_input)
327  CALL Scatter(control_temp_g,control_temp)
328  CALL Scatter(control_moist_g,control_moist)
329  CALL Scatter(carbon_g,carbon)
330
331  iyear=1
332  DO i=1,itau_len
333     iatt = iatt+1
334     IF (iatt > nparan) THEN
335        IF (debug) WRITE(numout,*) iyear
336        iatt = 1
337        iyear=iyear+1
338     ENDIF
339     CALL soilcarbon &
340          &    (kjpindex, dt_forcesoil, clay, &
341          &     soilcarbon_input(:,:,:,iatt), &
342          &     control_temp(:,:,iatt), control_moist(:,:,iatt), &
343          &     carbon, resp_hetero_soil)
344  ENDDO
345  WRITE(numout,*) "End of soilcarbon LOOP."
346  CALL Gather(carbon,carbon_g)
347  !-
348  ! write new carbon into restart file
349  !-
350  IF (is_root_prc) THEN
351     DO m=1,nvm
352        WRITE (part_str, '(I2)') m
353        IF (m<10) part_str(1:1)='0'
354        var_name = 'carbon_'//part_str(1:LEN_TRIM(part_str))
355        CALL restput &
356             &    (rest_id_sto, var_name, nbp_glo, ncarb , 1, itau_dep, &
357             &     carbon_g(:,:,m), 'scatter', nbp_glo, indices_g)
358     ENDDO
359     !-
360     CALL getin_dump
361     CALL restclo
362  ENDIF
363#ifdef CPP_PARA
364  CALL MPI_FINALIZE(ier)
365#endif
366  WRITE(numout,*) "End of forcesoil."
367  !--------------------
368END PROGRAM forcesoil
Note: See TracBrowser for help on using the repository browser.