source: branches/ORCHIDEE_2_2/ORCHIDEE/src_sechiba/routing_native_lake.f90 @ 8227

Last change on this file since 8227 was 8227, checked in by yann.meurdesoif, 9 months ago

New version of routing simple => become routing_native ; after validation routing_simple will be supress

  • more robust routing scheme on native grid
  • rearchitecturing of routing by spliting routing sub-process into separate file/module => smaller file
  • works on global as well on regional (orchidee) grid.
  • works on standard 50km routing grid and highres routing MERIT grid (1-2km), for regional studies
  • integrate irrigation old scheme et new scheme (pedro arboleda)
  • more water conservative (1e-16 Vs 1e-7 relative for simple routing)
  • To be tested : ICOLMDZOR grid and ICOLAMDZ-LAM grid that are expeted to work also.

It is a first guess, not the definitive native routing package that will continue to evolve.
No side effect is expected on other configurations since it is just some files adding.
Native routing is activated using the run.def key :
ROUTING_METHOD=native

YM

File size: 9.6 KB
Line 
1MODULE routing_native_lake_mod
2  USE constantes
3   
4  PRIVATE
5 
6  PUBLIC :: routing_lake_initialize, routing_lake_mean_make, routing_lake_main, routing_lake_route_coast, routing_lake_finalize
7 
8  REAL(r_std), SAVE, ALLOCATABLE :: lake_reservoir(:)
9!$OMP THREADPRIVATE(lake_reservoir)
10
11  REAL(r_std), SAVE, ALLOCATABLE :: humrel_mean(:)
12!$OMP THREADPRIVATE(humrel_mean)
13 
14  INTEGER,SAVE  :: nbpt
15!$OMP THREADPRIVATE( nbpt)
16 
17  LOGICAL,SAVE :: do_swamps
18!$OMP THREADPRIVATE(do_swamps)
19
20  INTEGER,SAVE :: nb_coast_cells
21!$OMP THREADPRIVATE(nb_coast_cells)
22
23REAL(r_std), PARAMETER   :: maxevap_lake = 7.5/86400.   !! Maximum evaporation rate from lakes (kg/m^2/s)
24
25REAL(r_std), SAVE    :: max_lake_reservoir           !! Maximum limit of water in lake_reservoir [kg/m2]
26!$OMP THREADPRIVATE(max_lake_reservoir)
27 
28LOGICAL, ALLOCATABLE :: is_coastline(:)
29!$OMP THREADPRIVATE(is_coastline) 
30
31CONTAINS
32 
33 SUBROUTINE routing_lake_initialize(kjit, rest_id, nbpt_, contfrac)
34 IMPLICIT NONE
35   INTEGER, INTENT(IN)     :: kjit
36   INTEGER, INTENT(IN)     :: rest_id
37   INTEGER,INTENT(IN)      :: nbpt_
38   REAL(r_std), INTENT(IN)    :: contfrac(nbpt)     !! Fraction of land in each grid box (unitless;0-1)
39
40
41   CALL routing_lake_init_local(kjit, rest_id, nbpt_, contfrac)
42   CALL routing_lake_mean_init(kjit, rest_id)
43
44 END SUBROUTINE routing_lake_initialize
45
46
47 SUBROUTINE routing_lake_finalize(kjit, rest_id)
48 IMPLICIT NONE
49   INTEGER, INTENT(IN)     :: kjit
50   INTEGER, INTENT(IN)     :: rest_id
51
52   CALL routing_lake_finalize_local(kjit, rest_id)
53   CALL routing_lake_mean_finalize(kjit, rest_id)
54
55 END SUBROUTINE routing_lake_finalize
56
57 
58 SUBROUTINE routing_lake_init_local(kjit, rest_id, nbpt_, contfrac)
59 USE mod_orchidee_para, ONLY : reduce_sum, bcast
60 USE ioipsl_para
61 USE grid, ONLY : nbp_glo, index_g
62 USE sechiba_io_p
63 USE routing_native_flow_mod, ONLY : compute_coastline
64 IMPLICIT NONE
65   INTEGER, INTENT(IN) :: kjit
66   INTEGER, INTENT(IN) :: rest_id
67   INTEGER,INTENT(IN) :: nbpt_
68   REAL(r_std), INTENT(IN)    :: contfrac(nbpt)     !! Fraction of land in each grid box (unitless;0-1)
69   
70   INTEGER :: ier   
71   CHARACTER(LEN=80)   :: var_name       !! To store variables names for I/O (unitless)
72 
73   INTEGER  :: ig
74   INTEGER  :: nb_cells
75   
76   nbpt=nbpt_
77   
78   
79    ALLOCATE(lake_reservoir(nbpt),stat=ier)
80    IF (ier /= 0) CALL ipslerr_p(3,'routing_init','Pb in allocate for lake_reservoir','','')
81    var_name = 'lakeres'
82    CALL ioconf_setatt_p('UNITS', 'Kg')
83    CALL ioconf_setatt_p('LONG_NAME','Water in the lake reservoir')
84    CALL restget_p (rest_id, var_name, nbp_glo, 1, 1, kjit, .TRUE., lake_reservoir, "gather", nbp_glo, index_g)
85    CALL setvar_p (lake_reservoir, val_exp, 'NO_KEYWORD', zero)
86       
87    !
88    !Config Key   = DO_SWAMPS
89    !Config Desc  = Should we include swamp parameterization
90    !Config If    = RIVER_ROUTING
91    !Config Def   = n
92    !Config Help  = This parameters allows the user to ask the model
93    !Config         to take into account the swamps and return
94    !Config         the water into the bottom of the soil. It then can go
95    !Config         back to the atmopshere. This tried to simulate
96    !Config         internal deltas of rivers.
97    !Config Units = [FLAG]
98    !
99    do_swamps = .FALSE.
100    CALL getin_p('DO_SWAMPS', do_swamps)
101
102    !Config Key   = MAX_LAKE_RESERVOIR
103    !Config Desc  = Maximum limit of water in lake_reservoir
104    !Config If    = RIVER_ROUTING
105    !Config Def   = 7000
106    !Config Help  =
107    !Config Units = [kg/m2(routing area)]
108    max_lake_reservoir = 7000
109    CALL getin_p("MAX_LAKE_RESERVOIR", max_lake_reservoir)
110       
111   
112    ! compute  number of coast cells
113    ! WARNING : contfrac is fraction of ter, but 1-contfrac is not fraction of ocean because of landice
114    ! => to be corrected...
115    ALLOCATE(is_coastline(nbpt))
116    CALL compute_coastline(contfrac, is_coastline)
117    nb_cells=0
118   
119    DO ig=1,nbpt
120      IF (is_coastline(ig)) nb_cells=nb_cells+1
121    ENDDO
122   
123    CALL reduce_sum(nb_cells, nb_coast_cells)
124    CALL bcast(nb_coast_cells)
125 
126  END SUBROUTINE routing_lake_init_local
127
128
129  SUBROUTINE routing_lake_finalize_local(kjit, rest_id)
130  USE ioipsl_para
131  USE grid, ONLY : nbp_glo, index_g
132  IMPLICIT NONE
133    INTEGER, INTENT(IN) :: kjit
134    INTEGER, INTENT(IN) :: rest_id
135 
136    CALL restput_p (rest_id, 'lakeres', nbp_glo, 1, 1, kjit, lake_reservoir, 'scatter',  nbp_glo, index_g)
137    DEALLOCATE(lake_reservoir)
138
139  END SUBROUTINE  routing_lake_finalize_local
140 
141 
142
143 SUBROUTINE routing_lake_mean_init(kjit, rest_id)
144 USE ioipsl_para
145 USE grid
146 USE sechiba_io_p
147 IMPLICIT NONE
148    INTEGER, INTENT(IN) :: kjit
149    INTEGER, INTENT(IN) :: rest_id
150
151    INTEGER :: ier   
152    CHARACTER(LEN=80)   :: var_name       !! To store variables names for I/O (unitless)
153 
154    ALLOCATE(humrel_mean(nbpt), stat=ier)
155
156    IF (ier /= 0) CALL ipslerr_p(3,'routing_init','Pb in allocate for humrel_mean','','')
157    var_name = 'humrel_lake'
158    CALL ioconf_setatt_p('UNITS', '-')
159    CALL ioconf_setatt_p('LONG_NAME','Mean humrel for irrigation')
160    CALL restget_p (rest_id, var_name, nbp_glo, 1, 1, kjit, .TRUE., humrel_mean, "gather", nbp_glo, index_g)
161    CALL setvar_p (humrel_mean, val_exp, 'NO_KEYWORD', un)
162   
163 END SUBROUTINE  routing_lake_mean_init
164 
165 SUBROUTINE routing_lake_mean_make(dt_routing, humrel, veget_max)
166 USE constantes
167 USE pft_parameters
168 IMPLICIT NONE
169   REAL(r_std), INTENT(IN)    :: dt_routing 
170   REAL(r_std), INTENT(IN)    :: humrel(:,:)       !! Soil moisture stress, root extraction potential (unitless)
171   REAL(r_std), INTENT(IN)    :: veget_max(:,:)       !! Soil moisture stress, root extraction potential (unitless)
172   INTEGER :: jv
173   
174   IF ( .NOT. old_irrig_scheme ) THEN
175     DO jv=1,nvm
176       humrel_mean(:) = humrel_mean(:) + humrel(:,jv)*veget_max(:,jv)*dt_sechiba/dt_routing
177     ENDDO
178   ELSE
179     DO jv=2,nvm
180       humrel_mean(:) = humrel_mean(:) + humrel(:,jv)*veget_max(:,jv)*dt_sechiba/dt_routing
181     ENDDO
182   ENDIF
183   
184 END SUBROUTINE routing_lake_mean_make 
185
186 
187 SUBROUTINE routing_lake_mean_reset
188 IMPLICIT NONE
189   humrel_mean(:) = 0
190 END SUBROUTINE routing_lake_mean_reset 
191
192 
193 SUBROUTINE routing_lake_mean_finalize(kjit, rest_id)
194 USE ioipsl_para
195 USE grid
196 IMPLICIT NONE
197   INTEGER, INTENT(IN) :: kjit
198   INTEGER, INTENT(IN) :: rest_id
199   
200   CALL restput_p (rest_id, 'humrel_lake', nbp_glo, 1, 1, kjit, humrel_mean, 'scatter',  nbp_glo, index_g)
201   DEALLOCATE(humrel_mean)
202 
203 END SUBROUTINE routing_lake_mean_finalize
204 
205 
206 SUBROUTINE routing_lake_route_coast(contfrac, coastalflow)
207 USE grid, ONLY : area
208 USE mod_orchidee_para, ONLY : reduce_sum, bcast
209
210 IMPLICIT NONE
211   REAL(r_std), INTENT(IN)    :: contfrac(nbpt)     !! Fraction of land in each grid box (unitless;0-1)
212   REAL(r_std), INTENT(INOUT) :: coastalflow(nbpt)   !! Water inflow to the lakes (kg/dt)
213   
214   REAL(r_std) :: sum_lake_overflow, lake_overflow, total_lake_overflow
215   INTEGER :: ig
216   
217   !! Remove water from lake reservoir if it exceeds the maximum limit and distribute it
218   !! uniformly over all possible the coastflow gridcells
219   
220   ! Calculate lake_overflow and remove it from lake_reservoir
221    sum_lake_overflow=0
222    DO ig=1,nbpt
223      lake_overflow = MAX(0., lake_reservoir(ig) - max_lake_reservoir*area(ig)*contfrac(ig))
224      lake_reservoir(ig) = lake_reservoir(ig) - lake_overflow
225      sum_lake_overflow = sum_lake_overflow + lake_overflow
226    END DO
227
228   ! Calculate the sum of the lake_overflow and distribute it uniformly over all gridboxes
229    CALL reduce_sum(sum_lake_overflow, total_lake_overflow)
230    CALL bcast(total_lake_overflow)
231
232    WHERE (is_coastline) coastalflow = coastalflow + total_lake_overflow/nb_coast_cells 
233 
234 END SUBROUTINE routing_lake_route_coast
235
236
237
238 
239 SUBROUTINE routing_lake_main(dt_routing, contfrac, lakeinflow, return_lakes)
240
241    USE grid, ONLY : area
242   
243    IMPLICIT NONE
244    !! 0 Variable and parameter description
245    !! 0.1 Input variables
246
247    REAL(r_std), INTENT(IN)    :: dt_routing         !! Routing time step (s)
248    REAL(r_std), INTENT(IN)    :: lakeinflow(nbpt)   !! Water inflow to the lakes (kg/dt)
249    REAL(r_std), INTENT(IN)    :: contfrac(nbpt)     !! Fraction of land in each grid box (unitless;0-1)
250   
251    !! 0.2 Output variables
252    REAL(r_std), INTENT(OUT)   :: return_lakes(nbpt) !! Water from lakes flowing back into soil moisture (kg/m^2/dt)
253   
254    !! 0.3 Local variables
255    INTEGER(i_std)             :: ig                 !! Indices (unitless)
256    REAL(r_std)                :: refill             !!
257    REAL(r_std)                :: total_area         !! Sum of all the surfaces of the basins (m^2)
258
259    !_ ================================================================================================================================
260
261   
262    DO ig=1,nbpt
263       !
264       total_area = area(ig)*contfrac(ig)
265       !
266       lake_reservoir(ig) = lake_reservoir(ig) + lakeinflow(ig)
267       !uptake in Kg/dt
268       IF ( do_swamps ) THEN
269         ! Calculate a return flow that will be extracted from the lake reservoir and reinserted in the soil in hydrol
270         ! Uptake in Kg/dt
271         refill = MAX(zero, maxevap_lake * (un - humrel_mean(ig)) * dt_routing * total_area)
272         return_lakes(ig) = MIN(refill, lake_reservoir(ig))
273         lake_reservoir(ig) = lake_reservoir(ig) - return_lakes(ig)
274         !Return in Kg/m^2/dt
275          return_lakes(ig) = return_lakes(ig)/total_area
276       ELSE
277          return_lakes(ig) = zero
278       ENDIF
279       !
280       ! This is the volume of the lake scaled to the entire grid.
281       ! It would be batter to scale it to the size of the lake
282       ! but this information is not yet available.
283!ym for now       lake_diag(ig) = lake_reservoir(ig)/total_area
284       !
285    ENDDO
286
287    CALL routing_lake_mean_reset
288 
289  END SUBROUTINE routing_lake_main
290
291END MODULE routing_native_lake_mod
Note: See TracBrowser for help on using the repository browser.