source: palm/trunk/SOURCE/plant_canopy_model_mod.f90 @ 4448

Last change on this file since 4448 was 4448, checked in by moh.hefny, 4 years ago

bugfix: removed the error message PA0672 to consider allow PC 3d data via ascii file

  • Property svn:keywords set to Id
File size: 109.8 KB
Line 
1!> @file plant_canopy_model_mod.f90
2!------------------------------------------------------------------------------!
3! This file is part of the PALM model system.
4!
5! PALM is free software: you can redistribute it and/or modify it under the
6! terms of the GNU General Public License as published by the Free Software
7! Foundation, either version 3 of the License, or (at your option) any later
8! version.
9!
10! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
11! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13!
14! You should have received a copy of the GNU General Public License along with
15! PALM. If not, see <http://www.gnu.org/licenses/>.
16!
17! Copyright 1997-2020 Leibniz Universitaet Hannover
18! Copyright 2017-2020 Institute of Computer Science of the
19!                     Czech Academy of Sciences, Prague
20!------------------------------------------------------------------------------!
21!
22! Current revisions:
23! ------------------
24!
25!
26! Former revisions:
27! -----------------
28!
29! $Id: plant_canopy_model_mod.f90 4448 2020-03-09 09:29:12Z moh.hefny $
30! (salim) removed the error message PA0672 to consider PC 3d data via ascii file
31!
32! 4392 2020-01-31 16:14:57Z pavelkrc (resler)
33! Make pcm_heatrate_av, pcm_latentrate_av public to allow calculation
34! of averaged Bowen ratio in the user procedure
35!
36! 4381 2020-01-20 13:51:46Z suehring
37! Give error message 313 only once
38!
39! 4363 2020-01-07 18:11:28Z suehring
40! Fix for last commit
41!
42! 4362 2020-01-07 17:15:02Z suehring
43! Input of plant canopy variables from static driver moved to plant-canopy
44! model
45!
46! 4361 2020-01-07 12:22:38Z suehring
47! - Remove unused arrays in pmc_rrd_local
48! - Remove one exchange of ghost points
49!
50! 4360 2020-01-07 11:25:50Z suehring
51! - Bugfix, read restart data for time-averaged pcm output quantities
52! - Output of plant-canopy quantities will fill values
53!
54! 4356 2019-12-20 17:09:33Z suehring
55! Correct single message call, local check must be given by the respective
56! mpi rank.
57!
58! 4346 2019-12-18 11:55:56Z motisi
59! Introduction of wall_flags_total_0, which currently sets bits based on static
60! topography information used in wall_flags_static_0
61!
62! 4342 2019-12-16 13:49:14Z Giersch
63! Use statements moved to module level, ocean dependency removed, redundant
64! variables removed
65!
66! 4341 2019-12-16 10:43:49Z motisi
67! - Unification of variable names: pc_-variables now pcm_-variables
68!   (pc_latent_rate, pc_heating_rate, pc_transpiration_rate)
69! - Removal of pcm_bowenratio output
70! - Renamed canopy-mode 'block' to 'homogeneous'
71! - Renamed value 'read_from_file_3d' to 'read_from_file'
72! - Removal of confusing comment lines
73! - Replacement of k_wall by topo_top_ind
74! - Removal of Else-Statement in tendency-calculation
75!
76! 4335 2019-12-12 16:39:05Z suehring
77! Fix for LAD at building edges also implemented in vector branch.
78!
79! 4331 2019-12-10 18:25:02Z suehring
80! Typo corrected
81!
82! 4329 2019-12-10 15:46:36Z motisi
83! Renamed wall_flags_0 to wall_flags_static_0
84!
85! 4314 2019-11-29 10:29:20Z suehring
86! - Bugfix, plant canopy was still considered at building edges on for the u-
87!   and v-component.
88! - Relax restriction of LAD on building tops. LAD is only omitted at
89!   locations where building grid points emerged artificially by the
90!   topography filtering.
91!
92! 4309 2019-11-26 18:49:59Z suehring
93! Typo
94!
95! 4302 2019-11-22 13:15:56Z suehring
96! Omit tall canopy mapped on top of buildings
97!
98! 4279 2019-10-29 08:48:17Z scharf
99! unused variables removed
100!
101! 4258 2019-10-07 13:29:08Z scharf
102! changed check for static driver and fixed bugs in initialization and header
103!
104! 4258 2019-10-07 13:29:08Z suehring
105! Check if any LAD is prescribed when plant-canopy model is applied.
106!
107! 4226 2019-09-10 17:03:24Z suehring
108! Bugfix, missing initialization of heating rate
109!
110! 4221 2019-09-09 08:50:35Z suehring
111! Further bugfix in 3d data output for plant canopy
112!
113! 4216 2019-09-04 09:09:03Z suehring
114! Bugfixes in 3d data output
115!
116! 4205 2019-08-30 13:25:00Z suehring
117! Missing working precision + bugfix in calculation of wind speed
118!
119! 4188 2019-08-26 14:15:47Z suehring
120! Minor adjustment in error number
121!
122! 4187 2019-08-26 12:43:15Z suehring
123! Give specific error numbers instead of PA0999
124!
125! 4182 2019-08-22 15:20:23Z scharf
126! Corrected "Former revisions" section
127!
128! 4168 2019-08-16 13:50:17Z suehring
129! Replace function get_topography_top_index by topo_top_ind
130!
131! 4127 2019-07-30 14:47:10Z suehring
132! Output of 3D plant canopy variables changed. It is now relative to the local
133! terrain rather than located at the acutal vertical level in the model. This
134! way, the vertical dimension of the output can be significantly reduced.
135! (merge from branch resler)
136!
137! 3885 2019-04-11 11:29:34Z kanani
138! Changes related to global restructuring of location messages and introduction
139! of additional debug messages
140!
141! 3864 2019-04-05 09:01:56Z monakurppa
142! unsed variables removed
143!
144! 3745 2019-02-15 18:57:56Z suehring
145! Bugfix in transpiration, floating invalid when temperature
146! becomes > 40 degrees
147!
148! 3744 2019-02-15 18:38:58Z suehring
149! Some interface calls moved to module_interface + cleanup
150!
151! 3655 2019-01-07 16:51:22Z knoop
152! unused variables removed
153!
154! 138 2007-11-28 10:03:58Z letzel
155! Initial revision
156!
157! Description:
158! ------------
159!> 1) Initialization of the canopy model, e.g. construction of leaf area density
160!> profile (subroutine pcm_init).
161!> 2) Calculation of sinks and sources of momentum, heat and scalar concentration
162!> due to canopy elements (subroutine pcm_tendency).
163!
164! @todo - precalculate constant terms in pcm_calc_transpiration_rate
165! @todo - unify variable names (pcm_, pc_, ...)
166!------------------------------------------------------------------------------!
167 MODULE plant_canopy_model_mod
168
169    USE arrays_3d,                                                             &
170        ONLY:  dzu, dzw, e, exner, hyp, pt, q, s, tend, u, v, w, zu, zw
171
172    USE basic_constants_and_equations_mod,                                     &
173        ONLY:  c_p, degc_to_k, l_v, lv_d_cp, r_d, rd_d_rv
174
175    USE bulk_cloud_model_mod,                                                  &
176        ONLY: bulk_cloud_model, microphysics_seifert
177
178    USE control_parameters,                                                    &
179        ONLY: average_count_3d,                                                &
180              coupling_char,                                                   &
181              debug_output,                                                    &
182              dt_3d,                                                           &
183              dz,                                                              &
184              humidity,                                                        &
185              length,                                                          &
186              message_string,                                                  &
187              ocean_mode,                                                      &
188              passive_scalar,                                                  &
189              plant_canopy,                                                    &
190              restart_string,                                                  &
191              urban_surface
192
193    USE grid_variables,                                                        &
194        ONLY:  dx, dy
195
196    USE indices,                                                               &
197        ONLY:  nbgp, nxl, nxlg, nxlu, nxr, nxrg, nyn, nyng, nys, nysg, nysv,   &
198               nz, nzb, nzt, topo_top_ind, wall_flags_total_0
199
200    USE kinds
201
202    USE netcdf_data_input_mod,                                                 &
203        ONLY:  input_pids_static,                                              &
204               char_fill,                                                      &
205               check_existence,                                                &
206               close_input_file,                                               &
207               get_attribute,                                                  &
208               get_dimension_length,                                           &
209               get_variable,                                                   &
210               inquire_num_variables,                                          &
211               inquire_variable_names,                                         &
212               input_file_static,                                              &
213               num_var_pids,                                                   &
214               open_read_file,                                                 &
215               pids_id,                                                        &
216               real_3d,                                                        &
217               vars_pids
218
219    USE pegrid
220
221    USE surface_mod,                                                           &
222        ONLY: surf_def_h, surf_lsm_h, surf_usm_h
223
224
225    IMPLICIT NONE
226
227    CHARACTER (LEN=30)   ::  canopy_mode = 'homogeneous'           !< canopy coverage
228    LOGICAL              ::  plant_canopy_transpiration = .FALSE.  !< flag to switch calculation of transpiration and corresponding latent heat
229                                                                   !< for resolved plant canopy inside radiation model
230                                                                   !< (calls subroutine pcm_calc_transpiration_rate from module plant_canopy_mod)
231
232    INTEGER(iwp) ::  pch_index = 0                                 !< plant canopy height/top index
233    INTEGER(iwp) ::  lad_vertical_gradient_level_ind(10) = -9999   !< lad-profile levels (index)
234
235    INTEGER(iwp), DIMENSION(:,:), ALLOCATABLE ::  pch_index_ji     !< local plant canopy top
236
237    LOGICAL ::  calc_beta_lad_profile = .FALSE.   !< switch for calc. of lad from beta func.
238
239    REAL(wp) ::  alpha_lad = 9999999.9_wp         !< coefficient for lad calculation
240    REAL(wp) ::  beta_lad = 9999999.9_wp          !< coefficient for lad calculation
241    REAL(wp) ::  canopy_drag_coeff = 0.0_wp       !< canopy drag coefficient (parameter)
242    REAL(wp) ::  cthf = 0.0_wp                    !< canopy top heat flux
243    REAL(wp) ::  dt_plant_canopy = 0.0_wp         !< timestep account. for canopy drag
244    REAL(wp) ::  ext_coef = 0.6_wp                !< extinction coefficient
245    REAL(wp) ::  lad_surface = 0.0_wp             !< lad surface value
246    REAL(wp) ::  lai_beta = 0.0_wp                !< leaf area index (lai) for lad calc.
247    REAL(wp) ::  leaf_scalar_exch_coeff = 0.0_wp  !< canopy scalar exchange coeff.
248    REAL(wp) ::  leaf_surface_conc = 0.0_wp       !< leaf surface concentration
249
250    REAL(wp) ::  lad_vertical_gradient(10) = 0.0_wp              !< lad gradient
251    REAL(wp) ::  lad_vertical_gradient_level(10) = -9999999.9_wp !< lad-prof. levels (in m)
252
253    REAL(wp) ::  lad_type_coef(0:10) = 1.0_wp   !< multiplicative coeficients for particular types
254                                                !< of plant canopy (e.g. deciduous tree during winter)
255
256    REAL(wp), DIMENSION(:), ALLOCATABLE ::  lad            !< leaf area density
257    REAL(wp), DIMENSION(:), ALLOCATABLE ::  pre_lad        !< preliminary lad
258   
259    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  cum_lai_hf               !< cumulative lai for heatflux calc.
260    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  lad_s                    !< lad on scalar-grid
261    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  pcm_heating_rate         !< plant canopy heating rate
262    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  pcm_transpiration_rate   !< plant canopy transpiration rate
263    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  pcm_latent_rate          !< plant canopy latent heating rate
264
265    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  pcm_heatrate_av          !< array for averaging plant canopy sensible heating rate
266    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  pcm_latentrate_av        !< array for averaging plant canopy latent heating rate
267    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  pcm_transpirationrate_av !< array for averaging plant canopy transpiration rate
268
269    TYPE(real_3d) ::  basal_area_density_f    !< input variable for basal area density - resolved vegetation
270    TYPE(real_3d) ::  leaf_area_density_f     !< input variable for leaf area density - resolved vegetation
271    TYPE(real_3d) ::  root_area_density_lad_f !< input variable for root area density - resolved vegetation
272
273    SAVE
274
275    PRIVATE
276   
277!
278!-- Public functions
279    PUBLIC pcm_calc_transpiration_rate,                                       &
280           pcm_check_data_output,                                             &
281           pcm_check_parameters,                                              &
282           pcm_3d_data_averaging,                                             &
283           pcm_data_output_3d,                                                &
284           pcm_define_netcdf_grid,                                            &
285           pcm_header,                                                        &
286           pcm_init,                                                          &
287           pcm_parin,                                                         &
288           pcm_rrd_local,                                                     &
289           pcm_tendency,                                                      &
290           pcm_wrd_local
291
292!
293!-- Public variables and constants
294    PUBLIC canopy_drag_coeff, pcm_heating_rate, pcm_transpiration_rate,       &
295           pcm_latent_rate, canopy_mode, cthf, dt_plant_canopy, lad, lad_s,   &
296           pch_index, plant_canopy_transpiration,                             &
297           pcm_heatrate_av, pcm_latentrate_av
298
299    INTERFACE pcm_calc_transpiration_rate
300       MODULE PROCEDURE pcm_calc_transpiration_rate
301    END INTERFACE pcm_calc_transpiration_rate
302
303    INTERFACE pcm_check_data_output
304       MODULE PROCEDURE pcm_check_data_output
305    END INTERFACE pcm_check_data_output
306   
307    INTERFACE pcm_check_parameters
308       MODULE PROCEDURE pcm_check_parameters
309    END INTERFACE pcm_check_parameters
310
311    INTERFACE pcm_3d_data_averaging
312       MODULE PROCEDURE pcm_3d_data_averaging
313    END INTERFACE pcm_3d_data_averaging
314
315    INTERFACE pcm_data_output_3d
316       MODULE PROCEDURE pcm_data_output_3d
317    END INTERFACE pcm_data_output_3d
318
319    INTERFACE pcm_define_netcdf_grid
320       MODULE PROCEDURE pcm_define_netcdf_grid
321    END INTERFACE pcm_define_netcdf_grid
322   
323     INTERFACE pcm_header
324       MODULE PROCEDURE pcm_header
325    END INTERFACE pcm_header       
326   
327    INTERFACE pcm_init
328       MODULE PROCEDURE pcm_init
329    END INTERFACE pcm_init
330
331    INTERFACE pcm_parin
332       MODULE PROCEDURE pcm_parin
333    END INTERFACE pcm_parin
334
335    INTERFACE pcm_read_plant_canopy_3d
336       MODULE PROCEDURE pcm_read_plant_canopy_3d
337    END INTERFACE pcm_read_plant_canopy_3d
338
339    INTERFACE pcm_rrd_local
340       MODULE PROCEDURE pcm_rrd_local
341    END INTERFACE pcm_rrd_local
342
343    INTERFACE pcm_tendency
344       MODULE PROCEDURE pcm_tendency
345       MODULE PROCEDURE pcm_tendency_ij
346    END INTERFACE pcm_tendency
347
348    INTERFACE pcm_wrd_local
349       MODULE PROCEDURE pcm_wrd_local
350    END INTERFACE pcm_wrd_local
351
352
353 CONTAINS
354 
355 
356!------------------------------------------------------------------------------!
357! Description:
358! ------------
359!> Calculation of the plant canopy transpiration rate based on the Jarvis-Stewart
360!> with parametrizations described in Daudet et al. (1999; Agricult. and Forest
361!> Meteorol. 97) and Ngao, Adam and Saudreau (2017;  Agricult. and Forest Meteorol
362!> 237-238). Model functions f1-f4 were adapted from Stewart (1998; Agric.
363!> and Forest. Meteorol. 43) instead, because they are valid for broader intervals
364!> of values. Funcion f4 used in form present in van Wijk et al. (1998;
365!> Tree Physiology 20).
366!>
367!> This subroutine is called from subroutine radiation_interaction
368!> after the calculation of radiation in plant canopy boxes.
369!> (arrays pcbinsw and pcbinlw).
370!>
371!------------------------------------------------------------------------------!
372 SUBROUTINE pcm_calc_transpiration_rate(i, j, k, kk, pcbsw, pcblw, pcbtr, pcblh)
373
374!
375!--  input parameters
376     INTEGER(iwp), INTENT(IN) ::  i, j, k, kk        !< indices of the pc gridbox
377     REAL(wp), INTENT(IN)     ::  pcbsw              !< sw radiation in gridbox (W)
378     REAL(wp), INTENT(IN)     ::  pcblw              !< lw radiation in gridbox (W)
379     REAL(wp), INTENT(OUT)    ::  pcbtr              !< transpiration rate dq/dt (kg/kg/s)
380     REAL(wp), INTENT(OUT)    ::  pcblh              !< latent heat from transpiration dT/dt (K/s)
381
382!--  variables and parameters for calculation of transpiration rate
383     REAL(wp)             ::  sat_press, sat_press_d, temp, v_lad
384     REAL(wp)             ::  d_fact, g_b, g_s, wind_speed, evapor_rate
385     REAL(wp)             ::  f1, f2, f3, f4, vpd, rswc, e_eq, e_imp, rad
386     REAL(wp), PARAMETER  ::  gama_psychr = 66.0_wp !< psychrometric constant (Pa/K)
387     REAL(wp), PARAMETER  ::  g_s_max = 0.01        !< maximum stomatal conductivity (m/s)
388     REAL(wp), PARAMETER  ::  m_soil = 0.4_wp       !< soil water content (needs to adjust or take from LSM)
389     REAL(wp), PARAMETER  ::  m_wilt = 0.01_wp      !< wilting point soil water content (needs to adjust or take from LSM)
390     REAL(wp), PARAMETER  ::  m_sat = 0.51_wp       !< saturation soil water content (needs to adjust or take from LSM)
391     REAL(wp), PARAMETER  ::  t2_min = 0.0_wp       !< minimal temperature for calculation of f2
392     REAL(wp), PARAMETER  ::  t2_max = 40.0_wp      !< maximal temperature for calculation of f2
393
394
395!--  Temperature (deg C)
396     temp = pt(k,j,i) * exner(k) - degc_to_k
397!--  Coefficient for conversion of radiation to grid to radiation to unit leaves surface
398     v_lad = 1.0_wp / ( MAX( lad_s(kk,j,i), 1.0E-10_wp ) * dx * dy * dz(1) )
399!--  Magnus formula for the saturation pressure (see Ngao, Adam and Saudreau (2017) eq. 1)
400!--  There are updated formulas available, kept consistent with the rest of the parametrization
401     sat_press = 610.8_wp * exp(17.27_wp * temp/(temp + 237.3_wp))
402!--  Saturation pressure derivative (derivative of the above)
403     sat_press_d = sat_press * 17.27_wp * 237.3_wp / (temp + 237.3_wp)**2
404!--  Wind speed
405     wind_speed = SQRT( ( 0.5_wp * ( u(k,j,i) + u(k,j,i+1) ) )**2 +            &
406                        ( 0.5_wp * ( v(k,j,i) + v(k,j+1,i) ) )**2 +            &
407                        ( 0.5_wp * ( w(k,j,i) + w(k-1,j,i) ) )**2 )
408!--  Aerodynamic conductivity (Daudet et al. (1999) eq. 14
409     g_b = 0.01_wp * wind_speed + 0.0071_wp
410!--  Radiation flux per leaf surface unit
411     rad = pcbsw * v_lad
412!--  First function for calculation of stomatal conductivity (radiation dependency)
413!--  Stewart (1988; Agric. and Forest. Meteorol. 43) eq. 17
414     f1 = rad * (1000.0_wp+42.1_wp) / 1000.0_wp / (rad+42.1_wp)
415!--  Second function for calculation of stomatal conductivity (temperature dependency)
416!--  Stewart (1988; Agric. and Forest. Meteorol. 43) eq. 21
417     f2 = MAX(t2_min, (temp-t2_min) * MAX(0.0_wp,t2_max-temp)**((t2_max-16.9_wp)/(16.9_wp-t2_min)) / &
418              ((16.9_wp-t2_min) * (t2_max-16.9_wp)**((t2_max-16.9_wp)/(16.9_wp-t2_min))) )
419!--  Water pressure deficit
420!--  Ngao, Adam and Saudreau (2017) eq. 6 but with water vapour partial pressure
421     vpd = max( sat_press - q(k,j,i) * hyp(k) / rd_d_rv, 0._wp )
422!--  Third function for calculation of stomatal conductivity (water pressure deficit dependency)
423!--  Ngao, Adam and Saudreau (2017) Table 1, limited from below according to Stewart (1988)
424!--  The coefficients of the linear dependence should better correspond to broad-leaved trees
425!--  than the coefficients from Stewart (1988) which correspond to conifer trees.
426     vpd = MIN(MAX(vpd,770.0_wp),3820.0_wp)
427     f3 = -2E-4_wp * vpd + 1.154_wp
428!--  Fourth function for calculation of stomatal conductivity (soil moisture dependency)
429!--  Residual soil water content
430!--  van Wijk et al. (1998; Tree Physiology 20) eq. 7
431!--  TODO - over LSM surface might be calculated from LSM parameters
432     rswc = ( m_sat - m_soil ) / ( m_sat - m_wilt )
433!--  van Wijk et al. (1998; Tree Physiology 20) eq. 5-6 (it is a reformulation of eq. 22-23 of Stewart(1988))
434     f4 = MAX(0.0_wp, MIN(1.0_wp - 0.041_wp * EXP(3.2_wp * rswc), 1.0_wp - 0.041_wp))
435!--  Stomatal conductivity
436!--  Stewart (1988; Agric. and Forest. Meteorol. 43) eq. 12
437!--  (notation according to Ngao, Adam and Saudreau (2017) and others)
438     g_s = g_s_max * f1 * f2 * f3 * f4 + 1.0E-10_wp
439!--  Decoupling factor
440!--  Daudet et al. (1999) eq. 6
441     d_fact = (sat_press_d / gama_psychr + 2.0_wp ) /                        &
442              (sat_press_d / gama_psychr + 2.0_wp + 2.0_wp * g_b / g_s )
443!--  Equilibrium evaporation rate
444!--  Daudet et al. (1999) eq. 4
445     e_eq = (pcbsw + pcblw) * v_lad * sat_press_d /                         &
446                 gama_psychr /( sat_press_d / gama_psychr + 2.0_wp ) / l_v
447!--  Imposed evaporation rate
448!--  Daudet et al. (1999) eq. 5
449     e_imp = r_d * pt(k,j,i) * exner(k) / hyp(k) * c_p * g_s * vpd / gama_psychr / l_v
450!--  Evaporation rate
451!--  Daudet et al. (1999) eq. 3
452!--  (evaporation rate is limited to non-negative values)
453     evapor_rate = MAX(d_fact * e_eq + ( 1.0_wp - d_fact ) * e_imp, 0.0_wp)
454!--  Conversion of evaporation rate to q tendency in gridbox
455!--  dq/dt = E * LAD * V_g / (rho_air * V_g)
456     pcbtr = evapor_rate * r_d * pt(k,j,i) * exner(k) * lad_s(kk,j,i) / hyp(k)  !-- = dq/dt
457!--  latent heat from evaporation
458     pcblh = pcbtr * lv_d_cp  !-- = - dT/dt
459
460 END SUBROUTINE pcm_calc_transpiration_rate
461
462
463!------------------------------------------------------------------------------!
464! Description:
465! ------------
466!> Check data output for plant canopy model
467!------------------------------------------------------------------------------!
468 SUBROUTINE pcm_check_data_output( var, unit )
469
470    CHARACTER (LEN=*) ::  unit  !<
471    CHARACTER (LEN=*) ::  var   !<
472
473
474    SELECT CASE ( TRIM( var ) )
475
476       CASE ( 'pcm_heatrate' )
477          IF ( cthf == 0.0_wp  .AND. .NOT.  urban_surface )  THEN
478             message_string = 'output of "' // TRIM( var ) // '" requi' //  &
479                              'res setting of parameter cthf /= 0.0'
480             CALL message( 'pcm_check_data_output', 'PA1000', 1, 2, 0, 6, 0 )
481          ENDIF
482          unit = 'K s-1'
483   
484       CASE ( 'pcm_transpirationrate' )
485          unit = 'kg kg-1 s-1'
486
487       CASE ( 'pcm_latentrate' )
488          unit = 'K s-1'
489
490       CASE ( 'pcm_lad' )
491          unit = 'm2 m-3'
492
493
494       CASE DEFAULT
495          unit = 'illegal'
496
497    END SELECT
498
499
500 END SUBROUTINE pcm_check_data_output
501 
502 
503!------------------------------------------------------------------------------!
504! Description:
505! ------------
506!> Check parameters routine for plant canopy model
507!------------------------------------------------------------------------------!
508    SUBROUTINE pcm_check_parameters
509           
510       IF ( ocean_mode )  THEN
511          message_string = 'plant_canopy = .TRUE. is not allowed in the '//    &
512                           'ocean'
513          CALL message( 'pcm_check_parameters', 'PA0696', 1, 2, 0, 6, 0 )
514       ENDIF
515           
516       IF ( canopy_drag_coeff == 0.0_wp )  THEN
517          message_string = 'plant_canopy = .TRUE. requires a non-zero drag '// &
518                           'coefficient & given value is canopy_drag_coeff = 0.0'
519          CALL message( 'pcm_check_parameters', 'PA0041', 1, 2, 0, 6, 0 )
520       ENDIF
521
522       IF ( ( alpha_lad /= 9999999.9_wp  .AND.  beta_lad == 9999999.9_wp ) .OR.&
523              beta_lad /= 9999999.9_wp   .AND.  alpha_lad == 9999999.9_wp )  THEN
524          message_string = 'using the beta function for the construction ' //  &
525                           'of the leaf area density profile requires '    //  &
526                           'both alpha_lad and beta_lad to be /= 9999999.9'
527          CALL message( 'pcm_check_parameters', 'PA0118', 1, 2, 0, 6, 0 )
528       ENDIF
529
530       IF ( calc_beta_lad_profile  .AND.  lai_beta == 0.0_wp )  THEN
531          message_string = 'using the beta function for the construction ' //  &
532                           'of the leaf area density profile requires '    //  &
533                           'a non-zero lai_beta, but given value is '      //  &
534                           'lai_beta = 0.0'
535          CALL message( 'pcm_check_parameters', 'PA0119', 1, 2, 0, 6, 0 )
536       ENDIF
537
538       IF ( calc_beta_lad_profile  .AND.  lad_surface /= 0.0_wp )  THEN
539          message_string = 'simultaneous setting of alpha_lad /= 9999999.9 '// &
540                           'combined with beta_lad /= 9999999.9 '           // &
541                           'and lad_surface /= 0.0 is not possible, '       // &
542                           'use either vertical gradients or the beta '     // &
543                           'function for the construction of the leaf area '// &
544                           'density profile'
545          CALL message( 'pcm_check_parameters', 'PA0120', 1, 2, 0, 6, 0 )
546       ENDIF
547
548       IF ( bulk_cloud_model  .AND.  microphysics_seifert )  THEN
549          message_string = 'plant_canopy = .TRUE. requires cloud_scheme /=' // &
550                          ' seifert_beheng'
551          CALL message( 'pcm_check_parameters', 'PA0360', 1, 2, 0, 6, 0 )
552       ENDIF
553
554    END SUBROUTINE pcm_check_parameters 
555 
556
557!------------------------------------------------------------------------------!
558!
559! Description:
560! ------------
561!> Subroutine for averaging 3D data
562!------------------------------------------------------------------------------!
563 SUBROUTINE pcm_3d_data_averaging( mode, variable )
564
565    CHARACTER (LEN=*) ::  mode    !<
566    CHARACTER (LEN=*) :: variable !<
567
568    INTEGER(iwp) ::  i            !<
569    INTEGER(iwp) ::  j            !<
570    INTEGER(iwp) ::  k            !<
571
572
573    IF ( mode == 'allocate' )  THEN
574
575       SELECT CASE ( TRIM( variable ) )
576
577          CASE ( 'pcm_heatrate' )
578             IF ( .NOT. ALLOCATED( pcm_heatrate_av ) )  THEN
579                ALLOCATE( pcm_heatrate_av(0:pch_index,nysg:nyng,nxlg:nxrg) )
580             ENDIF
581             pcm_heatrate_av = 0.0_wp
582
583
584          CASE ( 'pcm_latentrate' )
585             IF ( .NOT. ALLOCATED( pcm_latentrate_av ) )  THEN
586                ALLOCATE( pcm_latentrate_av(0:pch_index,nysg:nyng,nxlg:nxrg) )
587             ENDIF
588             pcm_latentrate_av = 0.0_wp
589
590
591          CASE ( 'pcm_transpirationrate' )
592             IF ( .NOT. ALLOCATED( pcm_transpirationrate_av ) )  THEN
593                ALLOCATE( pcm_transpirationrate_av(0:pch_index,nysg:nyng,nxlg:nxrg) )
594             ENDIF
595             pcm_transpirationrate_av = 0.0_wp
596
597          CASE DEFAULT
598             CONTINUE
599
600       END SELECT
601
602    ELSEIF ( mode == 'sum' )  THEN
603
604       SELECT CASE ( TRIM( variable ) )
605
606          CASE ( 'pcm_heatrate' )
607             IF ( ALLOCATED( pcm_heatrate_av ) ) THEN
608                DO  i = nxl, nxr
609                   DO  j = nys, nyn
610                      IF ( pch_index_ji(j,i) /= 0 )  THEN
611                         DO  k = 0, pch_index_ji(j,i)
612                            pcm_heatrate_av(k,j,i) = pcm_heatrate_av(k,j,i) + pcm_heating_rate(k,j,i)
613                         ENDDO
614                      ENDIF
615                   ENDDO
616                ENDDO
617             ENDIF
618
619
620          CASE ( 'pcm_latentrate' )
621             IF ( ALLOCATED( pcm_latentrate_av ) ) THEN
622                DO  i = nxl, nxr
623                   DO  j = nys, nyn
624                      IF ( pch_index_ji(j,i) /= 0 )  THEN
625                         DO  k = 0, pch_index_ji(j,i)
626                            pcm_latentrate_av(k,j,i) = pcm_latentrate_av(k,j,i) + pcm_latent_rate(k,j,i)
627                         ENDDO
628                      ENDIF
629                   ENDDO
630                ENDDO
631             ENDIF
632
633
634          CASE ( 'pcm_transpirationrate' )
635             IF ( ALLOCATED( pcm_transpirationrate_av ) ) THEN
636                DO  i = nxl, nxr
637                   DO  j = nys, nyn
638                      IF ( pch_index_ji(j,i) /= 0 )  THEN
639                         DO  k = 0, pch_index_ji(j,i)
640                            pcm_transpirationrate_av(k,j,i) = pcm_transpirationrate_av(k,j,i) + pcm_transpiration_rate(k,j,i)
641                         ENDDO
642                      ENDIF
643                   ENDDO
644                ENDDO
645             ENDIF
646
647          CASE DEFAULT
648             CONTINUE
649
650       END SELECT
651
652    ELSEIF ( mode == 'average' )  THEN
653
654       SELECT CASE ( TRIM( variable ) )
655
656          CASE ( 'pcm_heatrate' )
657             IF ( ALLOCATED( pcm_heatrate_av ) ) THEN
658                DO  i = nxlg, nxrg
659                   DO  j = nysg, nyng
660                      IF ( pch_index_ji(j,i) /= 0 )  THEN
661                         DO  k = 0, pch_index_ji(j,i)
662                            pcm_heatrate_av(k,j,i) = pcm_heatrate_av(k,j,i)                 &
663                                                     / REAL( average_count_3d, KIND=wp )
664                         ENDDO
665                      ENDIF
666                   ENDDO
667                ENDDO
668             ENDIF
669
670
671          CASE ( 'pcm_latentrate' )
672             IF ( ALLOCATED( pcm_latentrate_av ) ) THEN
673                DO  i = nxlg, nxrg
674                   DO  j = nysg, nyng
675                      IF ( pch_index_ji(j,i) /= 0 )  THEN
676                         DO  k = 0, pch_index_ji(j,i)
677                            pcm_latentrate_av(k,j,i) = pcm_latentrate_av(k,j,i)              &
678                                                       / REAL( average_count_3d, KIND=wp )
679                         ENDDO
680                      ENDIF
681                   ENDDO
682                ENDDO
683             ENDIF
684
685
686          CASE ( 'pcm_transpirationrate' )
687             IF ( ALLOCATED( pcm_transpirationrate_av ) ) THEN
688                DO  i = nxlg, nxrg
689                   DO  j = nysg, nyng
690                      IF ( pch_index_ji(j,i) /= 0 )  THEN
691                         DO  k = 0, pch_index_ji(j,i)
692                            pcm_transpirationrate_av(k,j,i) = pcm_transpirationrate_av(k,j,i)  &
693                                                              / REAL( average_count_3d, KIND=wp )
694                         ENDDO
695                      ENDIF
696                   ENDDO
697                ENDDO
698             ENDIF
699
700       END SELECT
701
702    ENDIF
703
704 END SUBROUTINE pcm_3d_data_averaging
705
706!------------------------------------------------------------------------------!
707!
708! Description:
709! ------------
710!> Subroutine defining 3D output variables.
711!> Note, 3D plant-canopy output has it's own vertical output dimension, meaning
712!> that 3D output is relative to the model surface now rather than at the actual
713!> grid point where the plant canopy is located.
714!------------------------------------------------------------------------------!
715 SUBROUTINE pcm_data_output_3d( av, variable, found, local_pf, fill_value,     &
716                                nzb_do, nzt_do )
717
718    CHARACTER (LEN=*) ::  variable !< treated variable
719
720    INTEGER(iwp) ::  av     !< flag indicating instantaneous or averaged data output
721    INTEGER(iwp) ::  i      !< grid index x-direction
722    INTEGER(iwp) ::  j      !< grid index y-direction
723    INTEGER(iwp) ::  k      !< grid index z-direction
724    INTEGER(iwp) ::  nzb_do !< lower limit of the data output (usually 0)
725    INTEGER(iwp) ::  nzt_do !< vertical upper limit of the data output (usually nz_do3d)
726
727    LOGICAL      ::  found  !< flag indicating if variable is found
728
729    REAL(wp)     ::  fill_value !< fill value
730    REAL(sp), DIMENSION(nxl:nxr,nys:nyn,nzb_do:nzt_do) ::  local_pf !< data output array
731
732
733    found = .TRUE.
734
735    local_pf = REAL( fill_value, KIND = 4 )
736
737    SELECT CASE ( TRIM( variable ) )
738!
739!--    Note, to save memory arrays for heating are allocated from 0:pch_index.
740!--    Thus, output must be relative to these array indices. Further, check
741!--    whether the output is within the vertical output range,
742!--    i.e. nzb_do:nzt_do, which is necessary as local_pf is only allocated
743!--    for this index space. Note, plant-canopy output has a separate
744!--    vertical output coordinate zlad, so that output is mapped down to the
745!--    surface.
746       CASE ( 'pcm_heatrate' )
747          IF ( av == 0 )  THEN
748             DO  i = nxl, nxr
749                DO  j = nys, nyn
750                   DO  k = MAX( 1, nzb_do ), MIN( pch_index_ji(j,i), nzt_do )
751                      local_pf(i,j,k) = pcm_heating_rate(k,j,i)
752                   ENDDO
753                ENDDO
754             ENDDO
755          ELSE
756             DO  i = nxl, nxr
757                DO  j = nys, nyn
758                   DO  k = MAX( 1, nzb_do ), MIN( pch_index_ji(j,i), nzt_do )
759                      local_pf(i,j,k) = pcm_heatrate_av(k,j,i)
760                   ENDDO
761                ENDDO
762             ENDDO
763          ENDIF
764
765       CASE ( 'pcm_latentrate' )
766          IF ( av == 0 )  THEN
767             DO  i = nxl, nxr
768                DO  j = nys, nyn
769                   DO  k = MAX( 1, nzb_do ), MIN( pch_index_ji(j,i), nzt_do )
770                      local_pf(i,j,k) = pcm_latent_rate(k,j,i)
771                   ENDDO
772                ENDDO
773             ENDDO
774          ELSE
775             DO  i = nxl, nxr
776                DO  j = nys, nyn
777                   DO  k = MAX( 1, nzb_do ), MIN( pch_index_ji(j,i), nzt_do )
778                      local_pf(i,j,k) = pcm_latentrate_av(k,j,i)
779                   ENDDO
780                ENDDO
781             ENDDO
782          ENDIF
783
784       CASE ( 'pcm_transpirationrate' )
785          IF ( av == 0 )  THEN
786             DO  i = nxl, nxr
787                DO  j = nys, nyn
788                   DO  k = MAX( 1, nzb_do ), MIN( pch_index_ji(j,i), nzt_do )
789                      local_pf(i,j,k) = pcm_transpiration_rate(k,j,i)
790                   ENDDO
791                ENDDO
792             ENDDO
793          ELSE
794             DO  i = nxl, nxr
795                DO  j = nys, nyn
796                   DO  k = MAX( 1, nzb_do ), MIN( pch_index_ji(j,i), nzt_do )
797                      local_pf(i,j,k) = pcm_transpirationrate_av(k,j,i)
798                   ENDDO
799                ENDDO
800             ENDDO
801          ENDIF
802
803       CASE ( 'pcm_lad' )
804          IF ( av == 0 )  THEN
805             DO  i = nxl, nxr
806                DO  j = nys, nyn
807                   DO  k = MAX( 1, nzb_do ), MIN( pch_index_ji(j,i), nzt_do )
808                      local_pf(i,j,k) = lad_s(k,j,i)
809                   ENDDO
810                ENDDO
811             ENDDO
812          ENDIF
813
814       CASE DEFAULT
815          found = .FALSE.
816
817    END SELECT
818
819 END SUBROUTINE pcm_data_output_3d 
820         
821!------------------------------------------------------------------------------!
822!
823! Description:
824! ------------
825!> Subroutine defining appropriate grid for netcdf variables.
826!> It is called from subroutine netcdf.
827!------------------------------------------------------------------------------!
828 SUBROUTINE pcm_define_netcdf_grid( var, found, grid_x, grid_y, grid_z )
829
830     CHARACTER (LEN=*), INTENT(IN)  ::  var         !<
831     LOGICAL, INTENT(OUT)           ::  found       !<
832     CHARACTER (LEN=*), INTENT(OUT) ::  grid_x      !<
833     CHARACTER (LEN=*), INTENT(OUT) ::  grid_y      !<
834     CHARACTER (LEN=*), INTENT(OUT) ::  grid_z      !<
835
836     found  = .TRUE.
837
838!
839!--  Check for the grid. zpc is zu(nzb:nzb+pch_index)
840     SELECT CASE ( TRIM( var ) )
841
842        CASE ( 'pcm_heatrate', 'pcm_lad', 'pcm_transpirationrate', 'pcm_latentrate')
843           grid_x = 'x'
844           grid_y = 'y'
845           grid_z = 'zpc'
846
847        CASE DEFAULT
848           found  = .FALSE.
849           grid_x = 'none'
850           grid_y = 'none'
851           grid_z = 'none'
852     END SELECT
853
854 END SUBROUTINE pcm_define_netcdf_grid
855 
856 
857!------------------------------------------------------------------------------!
858! Description:
859! ------------
860!> Header output for plant canopy model
861!------------------------------------------------------------------------------!
862 SUBROUTINE pcm_header ( io )
863 
864    CHARACTER (LEN=10) ::  coor_chr            !<
865
866    CHARACTER (LEN=86) ::  coordinates         !<
867    CHARACTER (LEN=86) ::  gradients           !<
868    CHARACTER (LEN=86) ::  leaf_area_density   !<
869    CHARACTER (LEN=86) ::  slices              !<
870 
871    INTEGER(iwp) :: i                !<
872    INTEGER(iwp),  INTENT(IN) ::  io !< Unit of the output file
873    INTEGER(iwp) :: k                !<       
874 
875    REAL(wp) ::  canopy_height       !< canopy height (in m)
876   
877    canopy_height = zw(pch_index)
878
879    WRITE ( io, 1 )  canopy_mode, canopy_height, pch_index,                    &
880                       canopy_drag_coeff                                       
881    IF ( passive_scalar )  THEN                                               
882       WRITE ( io, 2 )  leaf_scalar_exch_coeff,                                &
883                          leaf_surface_conc
884    ENDIF
885
886!
887!   Heat flux at the top of vegetation
888    WRITE ( io, 3 )  cthf
889
890!
891!   Leaf area density profile, calculated either from given vertical
892!   gradients or from beta probability density function.
893    IF (  .NOT.  calc_beta_lad_profile )  THEN
894
895!      Building output strings, starting with surface value
896       WRITE ( leaf_area_density, '(F7.4)' )  lad_surface
897       gradients = '------'
898       slices = '     0'
899       coordinates = '   0.0'
900       DO i = 1, UBOUND(lad_vertical_gradient_level_ind, DIM=1)
901          IF  ( lad_vertical_gradient_level_ind(i) /= -9999 ) THEN
902
903             WRITE (coor_chr,'(F7.2)') lad(lad_vertical_gradient_level_ind(i))
904             leaf_area_density = TRIM( leaf_area_density ) // ' ' // TRIM( coor_chr )
905
906             WRITE (coor_chr,'(F7.2)') lad_vertical_gradient(i)
907             gradients = TRIM( gradients ) // ' ' // TRIM( coor_chr )
908
909             WRITE (coor_chr,'(I7)') lad_vertical_gradient_level_ind(i)
910             slices = TRIM( slices ) // ' ' // TRIM( coor_chr )
911
912             WRITE (coor_chr,'(F7.1)') lad_vertical_gradient_level(i)
913             coordinates = TRIM( coordinates ) // ' '  // TRIM( coor_chr )
914          ELSE
915             EXIT
916          ENDIF
917       ENDDO
918
919       WRITE ( io, 4 )  TRIM( coordinates ), TRIM( leaf_area_density ),        &
920                          TRIM( gradients ), TRIM( slices )
921
922    ELSE
923   
924       WRITE ( leaf_area_density, '(F7.4)' )  lad_surface
925       coordinates = '   0.0'
926       
927       DO  k = 1, pch_index
928
929          WRITE (coor_chr,'(F7.2)')  lad(k)
930          leaf_area_density = TRIM( leaf_area_density ) // ' ' //              &
931                              TRIM( coor_chr )                                 
932                                                                               
933          WRITE (coor_chr,'(F7.1)')  zu(k)                                     
934          coordinates = TRIM( coordinates ) // ' '  // TRIM( coor_chr )       
935                                                                               
936       ENDDO                                                                   
937                                                                               
938       WRITE ( io, 5 ) TRIM( coordinates ), TRIM( leaf_area_density ),         &
939                       alpha_lad, beta_lad, lai_beta
940
941    ENDIF 
942
9431   FORMAT (//' Vegetation canopy (drag) model:'/                              &
944              ' ------------------------------'//                              &
945              ' Canopy mode: ', A /                                            &
946              ' Canopy height: ',F6.2,'m (',I4,' grid points)' /               &
947              ' Leaf drag coefficient: ',F6.2 /)
9482   FORMAT (/ ' Scalar exchange coefficient: ',F6.2 /                          &
949              ' Scalar concentration at leaf surfaces in kg/m**3: ',F6.2 /)
9503   FORMAT (' Predefined constant heatflux at the top of the vegetation: ',    &
951             F6.2, ' K m/s')
9524   FORMAT (/ ' Characteristic levels of the leaf area density:'//             &
953              ' Height:              ',A,'  m'/                                &
954              ' Leaf area density:   ',A,'  m**2/m**3'/                        &
955              ' Gradient:            ',A,'  m**2/m**4'/                        &
956              ' Gridpoint:           ',A)
9575   FORMAT (//' Characteristic levels of the leaf area density and coefficients:'&
958          //  ' Height:              ',A,'  m'/                                &
959              ' Leaf area density:   ',A,'  m**2/m**3'/                        &
960              ' Coefficient alpha: ',F6.2 /                                    &
961              ' Coefficient beta: ',F6.2 /                                     &
962              ' Leaf area index: ',F6.2,'  m**2/m**2' /)   
963       
964    END SUBROUTINE pcm_header
965 
966 
967!------------------------------------------------------------------------------!
968! Description:
969! ------------
970!> Initialization of the plant canopy model
971!------------------------------------------------------------------------------!
972    SUBROUTINE pcm_init
973
974       INTEGER(iwp) ::  i   !< running index
975       INTEGER(iwp) ::  j   !< running index
976       INTEGER(iwp) ::  k   !< running index
977       INTEGER(iwp) ::  m   !< running index
978
979       LOGICAL      ::  lad_on_top = .FALSE.  !< dummy flag to indicate that LAD is defined on a building roof
980
981       REAL(wp) ::  canopy_height   !< canopy height for lad-profile construction
982       REAL(wp) ::  gradient        !< gradient for lad-profile construction
983       REAL(wp) ::  int_bpdf        !< vertical integral for lad-profile construction     
984       REAL(wp) ::  lad_max         !< maximum LAD value in the model domain, used to perform a check
985
986       IF ( debug_output )  CALL debug_message( 'pcm_init', 'start' )
987!
988!--    Allocate one-dimensional arrays for the computation of the
989!--    leaf area density (lad) profile
990       ALLOCATE( lad(0:nz+1), pre_lad(0:nz+1) )
991       lad = 0.0_wp
992       pre_lad = 0.0_wp
993
994!
995!--    Set flag that indicates that the lad-profile shall be calculated by using
996!--    a beta probability density function
997       IF ( alpha_lad /= 9999999.9_wp  .AND.  beta_lad /= 9999999.9_wp )  THEN
998          calc_beta_lad_profile = .TRUE.
999       ENDIF
1000       
1001       
1002!
1003!--    Compute the profile of leaf area density used in the plant
1004!--    canopy model. The profile can either be constructed from
1005!--    prescribed vertical gradients of the leaf area density or by
1006!--    using a beta probability density function (see e.g. Markkanen et al.,
1007!--    2003: Boundary-Layer Meteorology, 106, 437-459)
1008       IF (  .NOT.  calc_beta_lad_profile )  THEN   
1009
1010!
1011!--       Use vertical gradients for lad-profile construction   
1012          i = 1
1013          gradient = 0.0_wp
1014
1015          lad(0) = lad_surface
1016          lad_vertical_gradient_level_ind(1) = 0
1017
1018          DO k = 1, pch_index
1019             IF ( i < 11 )  THEN
1020                IF ( lad_vertical_gradient_level(i) < zu(k)  .AND.          &
1021                     lad_vertical_gradient_level(i) >= 0.0_wp )  THEN
1022                   gradient = lad_vertical_gradient(i)
1023                   lad_vertical_gradient_level_ind(i) = k - 1
1024                   i = i + 1
1025                ENDIF
1026             ENDIF
1027             IF ( gradient /= 0.0_wp )  THEN
1028                IF ( k /= 1 )  THEN
1029                   lad(k) = lad(k-1) + dzu(k) * gradient
1030                ELSE
1031                   lad(k) = lad_surface + dzu(k) * gradient
1032                ENDIF
1033             ELSE
1034                lad(k) = lad(k-1)
1035             ENDIF
1036          ENDDO
1037
1038!
1039!--       In case of no given leaf area density gradients, choose a vanishing
1040!--       gradient. This information is used for the HEADER and the RUN_CONTROL
1041!--       file.
1042          IF ( lad_vertical_gradient_level(1) == -9999999.9_wp )  THEN
1043             lad_vertical_gradient_level(1) = 0.0_wp
1044          ENDIF
1045
1046       ELSE
1047
1048!
1049!--       Use beta function for lad-profile construction
1050          int_bpdf = 0.0_wp
1051          canopy_height = zw(pch_index)
1052
1053          DO k = 0, pch_index
1054             int_bpdf = int_bpdf +                                             &
1055                      ( ( ( zw(k) / canopy_height )**( alpha_lad-1.0_wp ) ) *  &
1056                      ( ( 1.0_wp - ( zw(k) / canopy_height ) )**(              &
1057                          beta_lad-1.0_wp ) )                                  &
1058                      * ( ( zw(k+1)-zw(k) ) / canopy_height ) )
1059          ENDDO
1060
1061!
1062!--       Preliminary lad profile (defined on w-grid)
1063          DO k = 0, pch_index
1064             pre_lad(k) =  lai_beta *                                          &
1065                        ( ( ( zw(k) / canopy_height )**( alpha_lad-1.0_wp ) )  &
1066                        * ( ( 1.0_wp - ( zw(k) / canopy_height ) )**(          &
1067                              beta_lad-1.0_wp ) ) / int_bpdf                   &
1068                        ) / canopy_height
1069          ENDDO
1070
1071!
1072!--       Final lad profile (defined on scalar-grid level, since most prognostic
1073!--       quantities are defined there, hence, less interpolation is required
1074!--       when calculating the canopy tendencies)
1075          lad(0) = pre_lad(0)
1076          DO k = 1, pch_index
1077             lad(k) = 0.5 * ( pre_lad(k-1) + pre_lad(k) )
1078          ENDDO
1079
1080       ENDIF
1081
1082!
1083!--    Allocate 3D-array for the leaf area density (lad_s).
1084       ALLOCATE( lad_s(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
1085
1086!
1087!--    Initialization of the canopy coverage in the model domain:
1088!--    Setting the parameter canopy_mode = 'homogeneous' initializes a canopy, which
1089!--    fully covers the domain surface
1090       SELECT CASE ( TRIM( canopy_mode ) )
1091
1092          CASE( 'homogeneous' )
1093
1094             DO  i = nxlg, nxrg
1095                DO  j = nysg, nyng
1096                   lad_s(:,j,i) = lad(:)
1097                ENDDO
1098             ENDDO
1099
1100          CASE ( 'read_from_file' )
1101!
1102!--          Read plant canopy
1103             IF ( input_pids_static )  THEN
1104!
1105!--             Open the static input file
1106#if defined( __netcdf )
1107                CALL open_read_file( TRIM( input_file_static ) //              &
1108                                     TRIM( coupling_char ),                    &
1109                                     pids_id )
1110
1111                CALL inquire_num_variables( pids_id, num_var_pids )
1112!
1113!--             Allocate memory to store variable names and read them
1114                ALLOCATE( vars_pids(1:num_var_pids) )
1115                CALL inquire_variable_names( pids_id, vars_pids )
1116!
1117!--             Read leaf area density - resolved vegetation
1118                IF ( check_existence( vars_pids, 'lad' ) )  THEN
1119                   leaf_area_density_f%from_file = .TRUE.
1120                   CALL get_attribute( pids_id, char_fill,                     &
1121                                       leaf_area_density_f%fill,               &
1122                                       .FALSE., 'lad' )
1123!
1124!--                Inquire number of vertical vegetation layer
1125                   CALL get_dimension_length( pids_id,                         &
1126                                              leaf_area_density_f%nz,          &
1127                                              'zlad' )
1128!
1129!--                Allocate variable for leaf-area density
1130                   ALLOCATE( leaf_area_density_f%var                           &
1131                                                (0:leaf_area_density_f%nz-1,   &
1132                                                 nys:nyn,nxl:nxr) )
1133
1134                   CALL get_variable( pids_id, 'lad', leaf_area_density_f%var, &
1135                                      nxl, nxr, nys, nyn,                      &
1136                                      0, leaf_area_density_f%nz-1 )
1137
1138                ELSE
1139                   leaf_area_density_f%from_file = .FALSE.
1140                ENDIF
1141!
1142!--             Read basal area density - resolved vegetation
1143                IF ( check_existence( vars_pids, 'bad' ) )  THEN
1144                   basal_area_density_f%from_file = .TRUE.
1145                   CALL get_attribute( pids_id, char_fill,                     &
1146                                       basal_area_density_f%fill,              &
1147                                       .FALSE., 'bad' )
1148!
1149!--                Inquire number of vertical vegetation layer
1150                   CALL get_dimension_length( pids_id,                         &
1151                                              basal_area_density_f%nz,         & 
1152                                              'zlad' )
1153!
1154!--                Allocate variable
1155                   ALLOCATE( basal_area_density_f%var                          &
1156                                              (0:basal_area_density_f%nz-1,    &
1157                                               nys:nyn,nxl:nxr) )
1158
1159                   CALL get_variable( pids_id, 'bad', basal_area_density_f%var,&
1160                                      nxl, nxr, nys, nyn,                      &
1161                                      0,  basal_area_density_f%nz-1 )
1162                ELSE
1163                   basal_area_density_f%from_file = .FALSE.
1164                ENDIF
1165!
1166!--             Read root area density - resolved vegetation
1167                IF ( check_existence( vars_pids, 'root_area_dens_r' ) )  THEN
1168                   root_area_density_lad_f%from_file = .TRUE.
1169                   CALL get_attribute( pids_id, char_fill,                     &
1170                                       root_area_density_lad_f%fill,           &
1171                                       .FALSE., 'root_area_dens_r' )
1172!
1173!--                Inquire number of vertical soil layers
1174                   CALL get_dimension_length( pids_id,                         &
1175                                              root_area_density_lad_f%nz,      &
1176                                              'zsoil' )
1177!
1178!--                Allocate variable
1179                   ALLOCATE( root_area_density_lad_f%var                       &
1180                                               (0:root_area_density_lad_f%nz-1,&
1181                                                nys:nyn,nxl:nxr) )
1182
1183                   CALL get_variable( pids_id, 'root_area_dens_r',             &
1184                                      root_area_density_lad_f%var,             &
1185                                      nxl, nxr, nys, nyn,                      &
1186                                      0,  root_area_density_lad_f%nz-1 )
1187                ELSE
1188                   root_area_density_lad_f%from_file = .FALSE.
1189                ENDIF
1190
1191                DEALLOCATE( vars_pids )
1192!
1193!--             Finally, close the input file and deallocate temporary array
1194                CALL close_input_file( pids_id )
1195#endif
1196             ENDIF
1197
1198!
1199!--          Initialize LAD with data from file. If LAD is given in NetCDF file,
1200!--          use these values, else take LAD profiles from ASCII file.
1201!--          Please note, in NetCDF file LAD is only given up to the maximum
1202!--          canopy top, indicated by leaf_area_density_f%nz. 
1203             lad_s = 0.0_wp
1204             IF ( leaf_area_density_f%from_file )  THEN
1205!
1206!--             Set also pch_index, used to be the upper bound of the vertical
1207!--             loops. Therefore, use the global top of the canopy layer.
1208                pch_index = leaf_area_density_f%nz - 1
1209
1210                DO  i = nxl, nxr
1211                   DO  j = nys, nyn
1212                      DO  k = 0, leaf_area_density_f%nz - 1
1213                         IF ( leaf_area_density_f%var(k,j,i) /=                &
1214                              leaf_area_density_f%fill )                       &
1215                         lad_s(k,j,i) = leaf_area_density_f%var(k,j,i)
1216                      ENDDO
1217!
1218!--                   Check if resolved vegetation is mapped onto buildings.
1219!--                   In general, this is allowed and also meaningful, e.g.
1220!--                   when trees carry across roofs. However, due to the
1221!--                   topography filtering, new building grid points can emerge
1222!--                   at location where also plant canopy is defined. As a
1223!--                   result, plant canopy is mapped on top of roofs, with
1224!--                   siginficant impact on the downstream flow field and the
1225!--                   nearby surface radiation. In order to avoid that
1226!--                   plant canopy is mistakenly mapped onto building roofs,
1227!--                   check for building grid points (bit 6) that emerge from
1228!--                   the filtering (bit 4) and set LAD to zero at these
1229!--                   artificially  created building grid points. This case,
1230!--                   an informative message is given.
1231                      IF ( ANY( lad_s(:,j,i) /= 0.0_wp )  .AND.                &
1232                           ANY( BTEST( wall_flags_total_0(:,j,i), 6 ) ) .AND.  &
1233                           ANY( BTEST( wall_flags_total_0(:,j,i), 4 ) ) )  THEN
1234                         lad_s(:,j,i) = 0.0_wp
1235                         lad_on_top   = .TRUE.
1236                      ENDIF
1237                   ENDDO
1238                ENDDO
1239#if defined( __parallel )
1240               CALL MPI_ALLREDUCE( MPI_IN_PLACE, lad_on_top, 1, MPI_LOGICAL,  &
1241                                   MPI_LOR, comm2d, ierr)
1242#endif
1243                IF ( lad_on_top )  THEN
1244                   WRITE( message_string, * )                                  &
1245                                        'Resolved plant-canopy is ' //         &
1246                                        'defined on top of an artificially '// &
1247                                        'created building grid point(s) ' //   &
1248                                        '(emerged from the filtering) - ' //   &
1249                                        'LAD profile is omitted at this / ' // &
1250                                        'these grid point(s).'
1251                   CALL message( 'pcm_init', 'PA0313', 0, 0, 0, 6, 0 )
1252                ENDIF
1253                CALL exchange_horiz( lad_s, nbgp )
1254!
1255!            ASCII file
1256!--          Initialize canopy parameters canopy_drag_coeff,
1257!--          leaf_scalar_exch_coeff, leaf_surface_conc
1258!--          from file which contains complete 3D data (separate vertical profiles for
1259!--          each location).
1260             ELSE
1261                CALL pcm_read_plant_canopy_3d
1262             ENDIF
1263
1264          CASE DEFAULT
1265!
1266!--          The DEFAULT case is reached either if the parameter
1267!--          canopy mode contains a wrong character string or if the
1268!--          user has coded a special case in the user interface.
1269!--          There, the subroutine user_init_plant_canopy checks
1270!--          which of these two conditions applies.
1271             CALL user_init_plant_canopy
1272 
1273       END SELECT
1274!
1275!--    Check that at least one grid point has an LAD /= 0, else this may
1276!--    cause errors in the radiation model.
1277       lad_max = MAXVAL( lad_s )
1278#if defined( __parallel )
1279       CALL MPI_ALLREDUCE( MPI_IN_PLACE, lad_max, 1, MPI_REAL, MPI_MAX,        &
1280                           comm2d, ierr)
1281#endif
1282       IF ( lad_max <= 0.0_wp )  THEN
1283          message_string = 'Plant-canopy model is switched-on but no ' //      &
1284                           'plant canopy is present in the model domain.'
1285          CALL message( 'pcm_init', 'PA0685', 1, 2, 0, 6, 0 )
1286       ENDIF
1287   
1288!
1289!--    Initialize 2D index array indicating canopy top index.
1290       ALLOCATE( pch_index_ji(nysg:nyng,nxlg:nxrg) )
1291       pch_index_ji = 0
1292       
1293       DO  i = nxlg, nxrg
1294          DO  j = nysg, nyng
1295             DO  k = 0, pch_index
1296                IF ( lad_s(k,j,i) /= 0 )  pch_index_ji(j,i) = k
1297             ENDDO
1298!
1299!--          Check whether topography and local vegetation on top exceed
1300!--          height of the model domain.
1301             IF ( topo_top_ind(j,i,0) + pch_index_ji(j,i) >= nzt + 1 )  THEN
1302                message_string =  'Local vegetation height on top of ' //      &
1303                                  'topography exceeds height of model domain.'
1304                CALL message( 'pcm_init', 'PA0674', 2, 2, myid, 6, 0 )
1305             ENDIF
1306
1307          ENDDO
1308       ENDDO
1309!
1310!--    Calculate global pch_index value (index of top of plant canopy from ground)
1311       pch_index = MAXVAL( pch_index_ji )
1312!
1313!--    Exchange pch_index from all processors
1314#if defined( __parallel )
1315       CALL MPI_ALLREDUCE( MPI_IN_PLACE, pch_index, 1, MPI_INTEGER,            &
1316                           MPI_MAX, comm2d, ierr)
1317#endif
1318!
1319!--    Allocation of arrays pcm_heating_rate, pcm_transpiration_rate and pcm_latent_rate
1320       ALLOCATE( pcm_heating_rate(0:pch_index,nysg:nyng,nxlg:nxrg) )
1321       pcm_heating_rate = 0.0_wp
1322       
1323       IF ( humidity )  THEN
1324          ALLOCATE( pcm_transpiration_rate(0:pch_index,nysg:nyng,nxlg:nxrg) )
1325          pcm_transpiration_rate = 0.0_wp
1326          ALLOCATE( pcm_latent_rate(0:pch_index,nysg:nyng,nxlg:nxrg) )
1327          pcm_latent_rate = 0.0_wp
1328       ENDIF
1329!
1330!--    Initialization of the canopy heat source distribution due to heating
1331!--    of the canopy layers by incoming solar radiation, in case that a non-zero
1332!--    value is set for the canopy top heat flux (cthf), which equals the
1333!--    available net radiation at canopy top.
1334!--    The heat source distribution is calculated by a decaying exponential
1335!--    function of the downward cumulative leaf area index (cum_lai_hf),
1336!--    assuming that the foliage inside the plant canopy is heated by solar
1337!--    radiation penetrating the canopy layers according to the distribution
1338!--    of net radiation as suggested by Brown & Covey (1966; Agric. Meteorol. 3,
1339!--    73–96). This approach has been applied e.g. by Shaw & Schumann (1992;
1340!--    Bound.-Layer Meteorol. 61, 47–64).
1341!--    When using the radiation_interactions, canopy heating (pcm_heating_rate)
1342!--    and plant canopy transpiration (pcm_transpiration_rate, pcm_latent_rate)
1343!--    are calculated in the RTM after the calculation of radiation.
1344       IF ( cthf /= 0.0_wp )  THEN
1345
1346          ALLOCATE( cum_lai_hf(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
1347!
1348!--       Piecewise calculation of the cumulative leaf area index by vertical
1349!--       integration of the leaf area density
1350          cum_lai_hf(:,:,:) = 0.0_wp
1351          DO  i = nxlg, nxrg
1352             DO  j = nysg, nyng
1353                DO  k = pch_index_ji(j,i)-1, 0, -1
1354                   IF ( k == pch_index_ji(j,i)-1 )  THEN
1355                      cum_lai_hf(k,j,i) = cum_lai_hf(k+1,j,i) +                &
1356                         ( 0.5_wp * lad_s(k+1,j,i) *                           &
1357                           ( zw(k+1) - zu(k+1) ) )  +                          &
1358                         ( 0.5_wp * ( 0.5_wp * ( lad_s(k+1,j,i) +              &
1359                                                 lad_s(k,j,i) ) +              &
1360                                      lad_s(k+1,j,i) ) *                       &
1361                           ( zu(k+1) - zw(k) ) ) 
1362                   ELSE
1363                      cum_lai_hf(k,j,i) = cum_lai_hf(k+1,j,i) +                &
1364                         ( 0.5_wp * ( 0.5_wp * ( lad_s(k+2,j,i) +              &
1365                                                 lad_s(k+1,j,i) ) +            &
1366                                      lad_s(k+1,j,i) ) *                       &
1367                           ( zw(k+1) - zu(k+1) ) )  +                          &
1368                         ( 0.5_wp * ( 0.5_wp * ( lad_s(k+1,j,i) +              &
1369                                                 lad_s(k,j,i) ) +              &
1370                                      lad_s(k+1,j,i) ) *                       &
1371                           ( zu(k+1) - zw(k) ) )
1372                   ENDIF
1373                ENDDO
1374             ENDDO
1375          ENDDO
1376
1377!
1378!--       In areas with canopy the surface value of the canopy heat
1379!--       flux distribution overrides the surface heat flux (shf)
1380!--       Start with default surface type
1381          DO  m = 1, surf_def_h(0)%ns
1382             i = surf_def_h(0)%i(m)
1383             j = surf_def_h(0)%j(m)
1384             IF ( cum_lai_hf(0,j,i) /= 0.0_wp )                                &
1385                surf_def_h(0)%shf(m) = cthf * exp( -ext_coef * cum_lai_hf(0,j,i) )
1386          ENDDO
1387!
1388!--       Natural surfaces
1389          DO  m = 1, surf_lsm_h%ns
1390             i = surf_lsm_h%i(m)
1391             j = surf_lsm_h%j(m)
1392             IF ( cum_lai_hf(0,j,i) /= 0.0_wp )                                &
1393                surf_lsm_h%shf(m) = cthf * exp( -ext_coef * cum_lai_hf(0,j,i) )
1394          ENDDO
1395!
1396!--       Urban surfaces
1397          DO  m = 1, surf_usm_h%ns
1398             i = surf_usm_h%i(m)
1399             j = surf_usm_h%j(m)
1400             IF ( cum_lai_hf(0,j,i) /= 0.0_wp )                                &
1401                surf_usm_h%shf(m) = cthf * exp( -ext_coef * cum_lai_hf(0,j,i) )
1402          ENDDO
1403!
1404!
1405!--       Calculation of the heating rate (K/s) within the different layers of
1406!--       the plant canopy. Calculation is only necessary in areas covered with
1407!--       canopy.
1408!--       Within the different canopy layers the plant-canopy heating
1409!--       rate (pcm_heating_rate) is calculated as the vertical
1410!--       divergence of the canopy heat fluxes at the top and bottom
1411!--       of the respective layer
1412          DO  i = nxlg, nxrg
1413             DO  j = nysg, nyng
1414                DO  k = 1, pch_index_ji(j,i)
1415                   IF ( cum_lai_hf(0,j,i) /= 0.0_wp )  THEN
1416                      pcm_heating_rate(k,j,i) = cthf *                          &
1417                                ( exp(-ext_coef*cum_lai_hf(k,j,i)) -           &
1418                                  exp(-ext_coef*cum_lai_hf(k-1,j,i) ) ) / dzw(k)
1419                   ENDIF
1420                ENDDO
1421             ENDDO
1422          ENDDO
1423
1424       ENDIF
1425
1426       IF ( debug_output )  CALL debug_message( 'pcm_init', 'end' )
1427
1428    END SUBROUTINE pcm_init
1429
1430
1431!------------------------------------------------------------------------------!
1432! Description:
1433! ------------
1434!> Parin for &plant_canopy_parameters for plant canopy model
1435!------------------------------------------------------------------------------!
1436    SUBROUTINE pcm_parin
1437
1438       CHARACTER (LEN=80) ::  line  !< dummy string that contains the current line of the parameter file
1439       
1440       NAMELIST /plant_canopy_parameters/                                      &
1441                                  alpha_lad, beta_lad, canopy_drag_coeff,      &
1442                                  canopy_mode, cthf,                           &
1443                                  lad_surface, lad_type_coef,                  & 
1444                                  lad_vertical_gradient,                       &
1445                                  lad_vertical_gradient_level,                 &
1446                                  lai_beta,                                    &
1447                                  leaf_scalar_exch_coeff,                      &
1448                                  leaf_surface_conc, pch_index,                &
1449                                  plant_canopy_transpiration
1450
1451       NAMELIST /canopy_par/      alpha_lad, beta_lad, canopy_drag_coeff,      &
1452                                  canopy_mode, cthf,                           &
1453                                  lad_surface, lad_type_coef,                  & 
1454                                  lad_vertical_gradient,                       &
1455                                  lad_vertical_gradient_level,                 &
1456                                  lai_beta,                                    &
1457                                  leaf_scalar_exch_coeff,                      &
1458                                  leaf_surface_conc, pch_index,                &
1459                                  plant_canopy_transpiration
1460
1461       line = ' '
1462
1463!
1464!--    Try to find plant-canopy model package
1465       REWIND ( 11 )
1466       line = ' '
1467       DO WHILE ( INDEX( line, '&plant_canopy_parameters' ) == 0 )
1468          READ ( 11, '(A)', END=12 )  line
1469       ENDDO
1470       BACKSPACE ( 11 )
1471
1472!
1473!--    Read user-defined namelist
1474       READ ( 11, plant_canopy_parameters, ERR = 10 )
1475
1476!
1477!--    Set flag that indicates that the plant-canopy model is switched on
1478       plant_canopy = .TRUE.
1479
1480       GOTO 14
1481
1482 10    BACKSPACE( 11 )
1483       READ( 11 , '(A)') line
1484       CALL parin_fail_message( 'plant_canopy_parameters', line )
1485!
1486!--    Try to find old namelist
1487 12    REWIND ( 11 )
1488       line = ' '
1489       DO WHILE ( INDEX( line, '&canopy_par' ) == 0 )
1490          READ ( 11, '(A)', END=14 )  line
1491       ENDDO
1492       BACKSPACE ( 11 )
1493
1494!
1495!--    Read user-defined namelist
1496       READ ( 11, canopy_par, ERR = 13, END = 14 )
1497
1498       message_string = 'namelist canopy_par is deprecated and will be ' // &
1499                     'removed in near future. Please use namelist ' //      &
1500                     'plant_canopy_parameters instead'
1501       CALL message( 'pcm_parin', 'PA0487', 0, 1, 0, 6, 0 )
1502
1503!
1504!--    Set flag that indicates that the plant-canopy model is switched on
1505       plant_canopy = .TRUE.
1506
1507       GOTO 14
1508
1509 13    BACKSPACE( 11 )
1510       READ( 11 , '(A)') line
1511       CALL parin_fail_message( 'canopy_par', line )
1512
1513 14    CONTINUE
1514
1515    END SUBROUTINE pcm_parin
1516
1517
1518!------------------------------------------------------------------------------!
1519! Description:
1520! ------------
1521!
1522!> Loads 3D plant canopy data from file. File format is as follows:
1523!>
1524!> num_levels
1525!> dtype,x,y,pctype,value(nzb),value(nzb+1), ... ,value(nzb+num_levels-1)
1526!> dtype,x,y,pctype,value(nzb),value(nzb+1), ... ,value(nzb+num_levels-1)
1527!> dtype,x,y,pctype,value(nzb),value(nzb+1), ... ,value(nzb+num_levels-1)
1528!> ...
1529!>
1530!> i.e. first line determines number of levels and further lines represent plant
1531!> canopy data, one line per column and variable. In each data line,
1532!> dtype represents variable to be set:
1533!>
1534!> dtype=1: leaf area density (lad_s)
1535!> dtype=2....n: some additional plant canopy input data quantity
1536!>
1537!> Zeros are added automatically above num_levels until top of domain.  Any
1538!> non-specified (x,y) columns have zero values as default.
1539!------------------------------------------------------------------------------!
1540    SUBROUTINE pcm_read_plant_canopy_3d
1541
1542       INTEGER(iwp)                        ::  dtype     !< type of input data (1=lad)
1543       INTEGER(iwp)                        ::  pctype    !< type of plant canopy (deciduous,non-deciduous,...)
1544       INTEGER(iwp)                        ::  i, j      !< running index
1545       INTEGER(iwp)                        ::  nzp       !< number of vertical layers of plant canopy
1546       INTEGER(iwp)                        ::  nzpltop   !<
1547       INTEGER(iwp)                        ::  nzpl      !<
1548       INTEGER(iwp)                        ::  kk        !<
1549       
1550       REAL(wp), DIMENSION(:), ALLOCATABLE ::  col   !< vertical column of input data
1551
1552!
1553!--    Initialize lad_s array
1554       lad_s = 0.0_wp
1555       
1556!
1557!--    Open and read plant canopy input data
1558       OPEN(152, FILE='PLANT_CANOPY_DATA_3D' // TRIM( coupling_char ),         &
1559                 ACCESS='SEQUENTIAL', ACTION='READ', STATUS='OLD',             &
1560                 FORM='FORMATTED', ERR=515)
1561       READ(152, *, ERR=516, END=517)  nzp   !< read first line = number of vertical layers
1562       nzpltop = MIN(nzt+1, nzb+nzp-1)
1563       nzpl = nzpltop - nzb + 1    !< no. of layers to assign
1564       ALLOCATE( col(0:nzp-1) )
1565
1566       DO
1567          READ(152, *, ERR=516, END=517) dtype, i, j, pctype, col(:)
1568          IF ( i < nxlg  .OR.  i > nxrg  .OR.  j < nysg  .OR.  j > nyng )  CYCLE
1569         
1570          SELECT CASE (dtype)
1571             CASE( 1 )   !< leaf area density
1572!
1573!--             This is just the pure canopy layer assumed to be grounded to
1574!--             a flat domain surface. At locations where plant canopy sits
1575!--             on top of any kind of topography, the vertical plant column
1576!--             must be "lifted", which is done in SUBROUTINE pcm_tendency.           
1577                IF ( pctype < 0  .OR.  pctype > 10 )  THEN   !< incorrect plant canopy type
1578                   WRITE( message_string, * ) 'Incorrect type of plant canopy. '   //  &
1579                                              'Allowed values 0 <= pctype <= 10, ' //  &
1580                                              'but pctype is ', pctype
1581                   CALL message( 'pcm_read_plant_canopy_3d', 'PA0349', 1, 2, 0, 6, 0 )
1582                ENDIF
1583                kk = topo_top_ind(j,i,0)
1584                lad_s(nzb:nzpltop-kk, j, i) = col(kk:nzpl-1)*lad_type_coef(pctype)
1585             CASE DEFAULT
1586                WRITE(message_string, '(a,i2,a)')   &
1587                     'Unknown record type in file PLANT_CANOPY_DATA_3D: "', dtype, '"'
1588                CALL message( 'pcm_read_plant_canopy_3d', 'PA0530', 1, 2, 0, 6, 0 )
1589          END SELECT
1590       ENDDO
1591
1592515    message_string = 'error opening file PLANT_CANOPY_DATA_3D'
1593       CALL message( 'pcm_read_plant_canopy_3d', 'PA0531', 1, 2, 0, 6, 0 )
1594
1595516    message_string = 'error reading file PLANT_CANOPY_DATA_3D'
1596       CALL message( 'pcm_read_plant_canopy_3d', 'PA0532', 1, 2, 0, 6, 0 )
1597
1598517    CLOSE(152)
1599       DEALLOCATE( col )
1600       
1601       CALL exchange_horiz( lad_s, nbgp )
1602       
1603    END SUBROUTINE pcm_read_plant_canopy_3d
1604
1605!------------------------------------------------------------------------------!
1606! Description:
1607! ------------
1608!> Subroutine reads local (subdomain) restart data
1609!------------------------------------------------------------------------------!
1610    SUBROUTINE pcm_rrd_local( k, nxlf, nxlc, nxl_on_file, nxrf, nxrc,          &
1611                              nxr_on_file, nynf, nync, nyn_on_file, nysf,      &
1612                              nysc, nys_on_file, found )
1613
1614       INTEGER(iwp) ::  k               !<
1615       INTEGER(iwp) ::  nxlc            !<
1616       INTEGER(iwp) ::  nxlf            !<
1617       INTEGER(iwp) ::  nxl_on_file     !<
1618       INTEGER(iwp) ::  nxrc            !<
1619       INTEGER(iwp) ::  nxrf            !<
1620       INTEGER(iwp) ::  nxr_on_file     !<
1621       INTEGER(iwp) ::  nync            !<
1622       INTEGER(iwp) ::  nynf            !<
1623       INTEGER(iwp) ::  nyn_on_file     !<
1624       INTEGER(iwp) ::  nysc            !<
1625       INTEGER(iwp) ::  nysf            !<
1626       INTEGER(iwp) ::  nys_on_file     !<
1627
1628       LOGICAL, INTENT(OUT)  :: found
1629
1630       REAL(wp), DIMENSION(0:pch_index,                                        &
1631                           nys_on_file-nbgp:nyn_on_file+nbgp,                  &
1632                           nxl_on_file-nbgp:nxr_on_file+nbgp) :: tmp_3d2  !< temporary 3D array for entire vertical
1633                                                                          !< extension of canopy layer
1634       found = .TRUE.
1635
1636       SELECT CASE ( restart_string(1:length) )
1637
1638          CASE ( 'pcm_heatrate_av' )
1639             IF ( .NOT. ALLOCATED( pcm_heatrate_av ) )  THEN
1640                ALLOCATE( pcm_heatrate_av(0:pch_index,nysg:nyng,nxlg:nxrg) )
1641                pcm_heatrate_av = 0.0_wp
1642             ENDIF 
1643             IF ( k == 1 )  READ ( 13 )  tmp_3d2
1644             pcm_heatrate_av(0:pch_index,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
1645                        tmp_3d2(0:pch_index,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
1646
1647          CASE ( 'pcm_latentrate_av' )
1648             IF ( .NOT. ALLOCATED( pcm_latentrate_av ) )  THEN
1649                ALLOCATE( pcm_latentrate_av(0:pch_index,nysg:nyng,nxlg:nxrg) )
1650                pcm_latentrate_av = 0.0_wp
1651             ENDIF 
1652             IF ( k == 1 )  READ ( 13 )  tmp_3d2
1653             pcm_latentrate_av(0:pch_index,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
1654                        tmp_3d2(0:pch_index,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
1655
1656          CASE ( 'pcm_transpirationrate_av' )
1657             IF ( .NOT. ALLOCATED( pcm_transpirationrate_av ) )  THEN
1658                ALLOCATE( pcm_transpirationrate_av(0:pch_index,nysg:nyng,nxlg:nxrg) )
1659                pcm_transpirationrate_av = 0.0_wp
1660             ENDIF 
1661             IF ( k == 1 )  READ ( 13 )  tmp_3d2
1662             pcm_transpirationrate_av(0:pch_index,nysc-nbgp:nync+nbgp,nxlc-nbgp:nxrc+nbgp) = &
1663                        tmp_3d2(0:pch_index,nysf-nbgp:nynf+nbgp,nxlf-nbgp:nxrf+nbgp)
1664
1665          CASE DEFAULT
1666
1667             found = .FALSE.
1668
1669       END SELECT
1670
1671    END SUBROUTINE pcm_rrd_local
1672
1673!------------------------------------------------------------------------------!
1674! Description:
1675! ------------
1676!> Calculation of the tendency terms, accounting for the effect of the plant
1677!> canopy on momentum and scalar quantities.
1678!>
1679!> The canopy is located where the leaf area density lad_s(k,j,i) > 0.0
1680!> (defined on scalar grid), as initialized in subroutine pcm_init.
1681!> The lad on the w-grid is vertically interpolated from the surrounding
1682!> lad_s. The upper boundary of the canopy is defined on the w-grid at
1683!> k = pch_index. Here, the lad is zero.
1684!>
1685!> The canopy drag must be limited (previously accounted for by calculation of
1686!> a limiting canopy timestep for the determination of the maximum LES timestep
1687!> in subroutine timestep), since it is physically impossible that the canopy
1688!> drag alone can locally change the sign of a velocity component. This
1689!> limitation is realized by calculating preliminary tendencies and velocities.
1690!> It is subsequently checked if the preliminary new velocity has a different
1691!> sign than the current velocity. If so, the tendency is limited in a way that
1692!> the velocity can at maximum be reduced to zero by the canopy drag.
1693!>
1694!>
1695!> Call for all grid points
1696!------------------------------------------------------------------------------!
1697    SUBROUTINE pcm_tendency( component )
1698
1699       INTEGER(iwp) ::  component !< prognostic variable (u,v,w,pt,q,e)
1700       INTEGER(iwp) ::  i         !< running index
1701       INTEGER(iwp) ::  j         !< running index
1702       INTEGER(iwp) ::  k         !< running index
1703       INTEGER(iwp) ::  kk        !< running index for flat lad arrays
1704
1705       LOGICAL ::  building_edge_e !< control flag indicating an eastward-facing building edge
1706       LOGICAL ::  building_edge_n !< control flag indicating a north-facing building edge
1707       LOGICAL ::  building_edge_s !< control flag indicating a south-facing building edge
1708       LOGICAL ::  building_edge_w !< control flag indicating a westward-facing building edge
1709
1710       REAL(wp) ::  ddt_3d    !< inverse of the LES timestep (dt_3d)
1711       REAL(wp) ::  lad_local !< local lad value
1712       REAL(wp) ::  pre_tend  !< preliminary tendency
1713       REAL(wp) ::  pre_u     !< preliminary u-value
1714       REAL(wp) ::  pre_v     !< preliminary v-value
1715       REAL(wp) ::  pre_w     !< preliminary w-value
1716
1717
1718       ddt_3d = 1.0_wp / dt_3d
1719 
1720!
1721!--    Compute drag for the three velocity components and the SGS-TKE:
1722       SELECT CASE ( component )
1723
1724!
1725!--       u-component
1726          CASE ( 1 )
1727             DO  i = nxlu, nxr
1728                DO  j = nys, nyn
1729!
1730!--                Set control flags indicating east- and westward-orientated
1731!--                building edges. Note, building_egde_w is set from the perspective
1732!--                of the potential rooftop grid point, while building_edge_e is
1733!--                is set from the perspective of the non-building grid point.
1734                   building_edge_w = ANY( BTEST( wall_flags_total_0(:,j,i),   6 ) )&
1735                        .AND.  .NOT. ANY( BTEST( wall_flags_total_0(:,j,i-1), 6 ) )
1736                   building_edge_e = ANY( BTEST( wall_flags_total_0(:,j,i-1), 6 ) )&
1737                        .AND.  .NOT. ANY( BTEST( wall_flags_total_0(:,j,i),   6 ) )
1738!
1739!--                Determine topography-top index on u-grid
1740                   DO  k = topo_top_ind(j,i,1)+1, topo_top_ind(j,i,1) + pch_index_ji(j,i)
1741
1742                      kk = k - topo_top_ind(j,i,1)   !- lad arrays are defined flat
1743!
1744!--                   In order to create sharp boundaries of the plant canopy,
1745!--                   the lad on the u-grid at index (k,j,i) is equal to lad_s(k,j,i),
1746!--                   rather than being interpolated from the surrounding lad_s,
1747!--                   because this would yield smaller lad at the canopy boundaries
1748!--                   than inside of the canopy.
1749!--                   For the same reason, the lad at the rightmost(i+1)canopy
1750!--                   boundary on the u-grid equals lad_s(k,j,i), which is considered
1751!--                   in the next if-statement. Note, at left-sided building edges
1752!--                   this is not applied, here the LAD is equals the LAD at grid
1753!--                   point (k,j,i), in order to avoid that LAD is mistakenly mapped
1754!--                   on top of a roof where (usually) is no LAD is defined.
1755                      lad_local = lad_s(kk,j,i)
1756                      IF ( lad_local == 0.0_wp .AND. lad_s(kk,j,i-1) > 0.0_wp  &
1757                           .AND.  .NOT. building_edge_w )  lad_local = lad_s(kk,j,i-1)
1758!
1759!--                   In order to avoid that LAD is mistakenly considered at right-
1760!--                   sided building edges (here the topography-top index for the
1761!--                   u-component at index j,i is still on the building while the
1762!--                   topography top for the scalar isn't), LAD is taken from grid
1763!--                   point (j,i-1).
1764                      IF ( lad_local > 0.0_wp .AND. lad_s(kk,j,i-1) == 0.0_wp  &
1765                           .AND.  building_edge_e )  lad_local = lad_s(kk,j,i-1)
1766
1767                      pre_tend = 0.0_wp
1768                      pre_u = 0.0_wp
1769!
1770!--                   Calculate preliminary value (pre_tend) of the tendency
1771                      pre_tend = - canopy_drag_coeff *                         &
1772                                   lad_local *                                 &
1773                                   SQRT( u(k,j,i)**2 +                         &
1774                                         ( 0.25_wp * ( v(k,j,i-1) +            &
1775                                                       v(k,j,i)   +            &
1776                                                       v(k,j+1,i) +            &
1777                                                       v(k,j+1,i-1) )          &
1778                                         )**2 +                                &
1779                                         ( 0.25_wp * ( w(k-1,j,i-1) +          &
1780                                                       w(k-1,j,i)   +          &
1781                                                       w(k,j,i-1)   +          &
1782                                                       w(k,j,i) )              &
1783                                         )**2                                  &
1784                                       ) *                                     &
1785                                   u(k,j,i)
1786
1787!
1788!--                   Calculate preliminary new velocity, based on pre_tend
1789                      pre_u = u(k,j,i) + dt_3d * pre_tend
1790!
1791!--                   Compare sign of old velocity and new preliminary velocity,
1792!--                   and in case the signs are different, limit the tendency
1793                      IF ( SIGN(pre_u,u(k,j,i)) /= pre_u )  THEN
1794                         pre_tend = - u(k,j,i) * ddt_3d
1795                      ENDIF
1796!
1797!--                   Calculate final tendency
1798                      tend(k,j,i) = tend(k,j,i) + pre_tend
1799
1800                   ENDDO
1801                ENDDO
1802             ENDDO
1803
1804!
1805!--       v-component
1806          CASE ( 2 )
1807             DO  i = nxl, nxr
1808                DO  j = nysv, nyn
1809!
1810!--                Set control flags indicating north- and southward-orientated
1811!--                building edges. Note, building_egde_s is set from the perspective
1812!--                of the potential rooftop grid point, while building_edge_n is
1813!--                is set from the perspective of the non-building grid point.
1814                   building_edge_s = ANY( BTEST( wall_flags_total_0(:,j,i),   6 ) )&
1815                        .AND.  .NOT. ANY( BTEST( wall_flags_total_0(:,j-1,i), 6 ) )
1816                   building_edge_n = ANY( BTEST( wall_flags_total_0(:,j-1,i), 6 ) )&
1817                        .AND.  .NOT. ANY( BTEST( wall_flags_total_0(:,j,i),   6 ) )
1818!
1819!--                Determine topography-top index on v-grid
1820                   DO  k = topo_top_ind(j,i,2)+1, topo_top_ind(j,i,2) + pch_index_ji(j,i)
1821
1822                      kk = k - topo_top_ind(j,i,2)   !- lad arrays are defined flat
1823!
1824!--                   In order to create sharp boundaries of the plant canopy,
1825!--                   the lad on the v-grid at index (k,j,i) is equal to lad_s(k,j,i),
1826!--                   rather than being interpolated from the surrounding lad_s,
1827!--                   because this would yield smaller lad at the canopy boundaries
1828!--                   than inside of the canopy.
1829!--                   For the same reason, the lad at the northmost(j+1)canopy
1830!--                   boundary on the v-grid equals lad_s(k,j,i), which is considered
1831!--                   in the next if-statement. Note, at left-sided building edges
1832!--                   this is not applied, here the LAD is equals the LAD at grid
1833!--                   point (k,j,i), in order to avoid that LAD is mistakenly mapped
1834!--                   on top of a roof where (usually) is no LAD is defined.
1835                      lad_local = lad_s(kk,j,i)
1836                      IF ( lad_local == 0.0_wp .AND. lad_s(kk,j-1,i) > 0.0_wp &
1837                       .AND.  .NOT. building_edge_s )  lad_local = lad_s(kk,j-1,i)
1838!
1839!--                   In order to avoid that LAD is mistakenly considered at right-
1840!--                   sided building edges (here the topography-top index for the
1841!--                   u-component at index j,i is still on the building while the
1842!--                   topography top for the scalar isn't), LAD is taken from grid
1843!--                   point (j,i-1).
1844                      IF ( lad_local > 0.0_wp .AND. lad_s(kk,j-1,i) == 0.0_wp  &
1845                       .AND.  building_edge_n )  lad_local = lad_s(kk,j-1,i)
1846
1847                      pre_tend = 0.0_wp
1848                      pre_v = 0.0_wp
1849!
1850!--                   Calculate preliminary value (pre_tend) of the tendency
1851                      pre_tend = - canopy_drag_coeff *                         &
1852                                   lad_local *                                 &
1853                                   SQRT( ( 0.25_wp * ( u(k,j-1,i)   +          &
1854                                                       u(k,j-1,i+1) +          &
1855                                                       u(k,j,i)     +          &
1856                                                       u(k,j,i+1) )            &
1857                                         )**2 +                                &
1858                                         v(k,j,i)**2 +                         &
1859                                         ( 0.25_wp * ( w(k-1,j-1,i) +          &
1860                                                       w(k-1,j,i)   +          &
1861                                                       w(k,j-1,i)   +          &
1862                                                       w(k,j,i) )              &
1863                                         )**2                                  &
1864                                       ) *                                     &
1865                                   v(k,j,i)
1866
1867!
1868!--                   Calculate preliminary new velocity, based on pre_tend
1869                      pre_v = v(k,j,i) + dt_3d * pre_tend
1870!
1871!--                   Compare sign of old velocity and new preliminary velocity,
1872!--                   and in case the signs are different, limit the tendency
1873                      IF ( SIGN(pre_v,v(k,j,i)) /= pre_v )  THEN
1874                         pre_tend = - v(k,j,i) * ddt_3d
1875                      ELSE
1876                         pre_tend = pre_tend
1877                      ENDIF
1878!
1879!--                   Calculate final tendency
1880                      tend(k,j,i) = tend(k,j,i) + pre_tend
1881
1882                   ENDDO
1883                ENDDO
1884             ENDDO
1885
1886!
1887!--       w-component
1888          CASE ( 3 )
1889             DO  i = nxl, nxr
1890                DO  j = nys, nyn
1891!
1892!--                Determine topography-top index on w-grid
1893                   DO  k = topo_top_ind(j,i,3)+1, topo_top_ind(j,i,3) + pch_index_ji(j,i) - 1
1894
1895                      kk = k - topo_top_ind(j,i,3)   !- lad arrays are defined flat
1896
1897                      pre_tend = 0.0_wp
1898                      pre_w = 0.0_wp
1899!
1900!--                   Calculate preliminary value (pre_tend) of the tendency
1901                      pre_tend = - canopy_drag_coeff *                         &
1902                                   (0.5_wp *                                   &
1903                                      ( lad_s(kk+1,j,i) + lad_s(kk,j,i) )) *   &
1904                                   SQRT( ( 0.25_wp * ( u(k,j,i)   +            &
1905                                                       u(k,j,i+1) +            &
1906                                                       u(k+1,j,i) +            &
1907                                                       u(k+1,j,i+1) )          &
1908                                         )**2 +                                &
1909                                         ( 0.25_wp * ( v(k,j,i)   +            &
1910                                                       v(k,j+1,i) +            &
1911                                                       v(k+1,j,i) +            &
1912                                                       v(k+1,j+1,i) )          &
1913                                         )**2 +                                &
1914                                         w(k,j,i)**2                           &
1915                                       ) *                                     &
1916                                   w(k,j,i)
1917!
1918!--                   Calculate preliminary new velocity, based on pre_tend
1919                      pre_w = w(k,j,i) + dt_3d * pre_tend
1920!
1921!--                   Compare sign of old velocity and new preliminary velocity,
1922!--                   and in case the signs are different, limit the tendency
1923                      IF ( SIGN(pre_w,w(k,j,i)) /= pre_w )  THEN
1924                         pre_tend = - w(k,j,i) * ddt_3d
1925                      ELSE
1926                         pre_tend = pre_tend
1927                      ENDIF
1928!
1929!--                   Calculate final tendency
1930                      tend(k,j,i) = tend(k,j,i) + pre_tend
1931
1932                   ENDDO
1933                ENDDO
1934             ENDDO
1935
1936!
1937!--       potential temperature
1938          CASE ( 4 )
1939             IF ( humidity ) THEN
1940                DO  i = nxl, nxr
1941                   DO  j = nys, nyn
1942!--                   Determine topography-top index on scalar-grid
1943                      DO  k = topo_top_ind(j,i,0)+1, topo_top_ind(j,i,0) + pch_index_ji(j,i)
1944                         kk = k - topo_top_ind(j,i,0)   !- lad arrays are defined flat
1945                         tend(k,j,i) = tend(k,j,i) + pcm_heating_rate(kk,j,i) - pcm_latent_rate(kk,j,i)
1946                      ENDDO
1947                   ENDDO
1948                ENDDO
1949             ELSE
1950                DO  i = nxl, nxr
1951                   DO  j = nys, nyn
1952!--                   Determine topography-top index on scalar-grid
1953                      DO  k = topo_top_ind(j,i,0)+1, topo_top_ind(j,i,0) + pch_index_ji(j,i)
1954                         kk = k - topo_top_ind(j,i,0)   !- lad arrays are defined flat
1955                         tend(k,j,i) = tend(k,j,i) + pcm_heating_rate(kk,j,i)
1956                      ENDDO
1957                   ENDDO
1958                ENDDO
1959             ENDIF
1960
1961!
1962!--       humidity
1963          CASE ( 5 )
1964             DO  i = nxl, nxr
1965                DO  j = nys, nyn
1966!
1967!--                Determine topography-top index on scalar-grid
1968                   DO  k = topo_top_ind(j,i,0)+1, topo_top_ind(j,i,0) + pch_index_ji(j,i)
1969
1970                      kk = k - topo_top_ind(j,i,0)   !- lad arrays are defined flat
1971
1972                      IF ( .NOT. plant_canopy_transpiration ) THEN
1973                         ! pcm_transpiration_rate is calculated in radiation model
1974                         ! in case of plant_canopy_transpiration = .T.
1975                         ! to include also the dependecy to the radiation
1976                         ! in the plant canopy box
1977                         pcm_transpiration_rate(kk,j,i) =  - leaf_scalar_exch_coeff &
1978                                          * lad_s(kk,j,i) *                         &
1979                                          SQRT( ( 0.5_wp * ( u(k,j,i) +             &
1980                                                             u(k,j,i+1) )           &
1981                                                )**2 +                              &
1982                                                ( 0.5_wp * ( v(k,j,i) +             &
1983                                                             v(k,j+1,i) )           &
1984                                                )**2 +                              &
1985                                                ( 0.5_wp * ( w(k-1,j,i) +           &
1986                                                             w(k,j,i) )             &
1987                                                )**2                                &
1988                                              ) *                                   &
1989                                          ( q(k,j,i) - leaf_surface_conc )
1990                      ENDIF
1991
1992                      tend(k,j,i) = tend(k,j,i) + pcm_transpiration_rate(kk,j,i)
1993                   ENDDO
1994                ENDDO
1995             ENDDO
1996
1997!
1998!--       sgs-tke
1999          CASE ( 6 )
2000             DO  i = nxl, nxr
2001                DO  j = nys, nyn
2002!
2003!--                Determine topography-top index on scalar-grid
2004                   DO  k = topo_top_ind(j,i,0)+1, topo_top_ind(j,i,0) + pch_index_ji(j,i)
2005
2006                      kk = k - topo_top_ind(j,i,0)   !- lad arrays are defined flat
2007                      tend(k,j,i) = tend(k,j,i) -                              &
2008                                       2.0_wp * canopy_drag_coeff *            &
2009                                       lad_s(kk,j,i) *                         &
2010                                       SQRT( ( 0.5_wp * ( u(k,j,i) +           &
2011                                                          u(k,j,i+1) )         &
2012                                             )**2 +                            &
2013                                             ( 0.5_wp * ( v(k,j,i) +           &
2014                                                          v(k,j+1,i) )         &
2015                                             )**2 +                            &
2016                                             ( 0.5_wp * ( w(k,j,i) +           &
2017                                                          w(k+1,j,i) )         &
2018                                             )**2                              &
2019                                           ) *                                 &
2020                                       e(k,j,i)
2021                   ENDDO
2022                ENDDO
2023             ENDDO 
2024!
2025!--       scalar concentration
2026          CASE ( 7 )
2027             DO  i = nxl, nxr
2028                DO  j = nys, nyn
2029!
2030!--                Determine topography-top index on scalar-grid
2031                   DO  k = topo_top_ind(j,i,0)+1, topo_top_ind(j,i,0) + pch_index_ji(j,i)
2032
2033                      kk = k - topo_top_ind(j,i,0)   !- lad arrays are defined flat
2034                      tend(k,j,i) = tend(k,j,i) -                              &
2035                                       leaf_scalar_exch_coeff *                &
2036                                       lad_s(kk,j,i) *                         &
2037                                       SQRT( ( 0.5_wp * ( u(k,j,i) +           &
2038                                                          u(k,j,i+1) )         &
2039                                             )**2 +                            &
2040                                             ( 0.5_wp * ( v(k,j,i) +           &
2041                                                          v(k,j+1,i) )         &
2042                                             )**2 +                            &
2043                                             ( 0.5_wp * ( w(k-1,j,i) +         & 
2044                                                          w(k,j,i) )           &
2045                                             )**2                              &
2046                                           ) *                                 &
2047                                       ( s(k,j,i) - leaf_surface_conc )
2048                   ENDDO
2049                ENDDO
2050             ENDDO   
2051
2052
2053
2054          CASE DEFAULT
2055
2056             WRITE( message_string, * ) 'wrong component: ', component
2057             CALL message( 'pcm_tendency', 'PA0279', 1, 2, 0, 6, 0 ) 
2058
2059       END SELECT
2060
2061    END SUBROUTINE pcm_tendency
2062
2063
2064!------------------------------------------------------------------------------!
2065! Description:
2066! ------------
2067!> Calculation of the tendency terms, accounting for the effect of the plant
2068!> canopy on momentum and scalar quantities.
2069!>
2070!> The canopy is located where the leaf area density lad_s(k,j,i) > 0.0
2071!> (defined on scalar grid), as initialized in subroutine pcm_init.
2072!> The lad on the w-grid is vertically interpolated from the surrounding
2073!> lad_s. The upper boundary of the canopy is defined on the w-grid at
2074!> k = pch_index. Here, the lad is zero.
2075!>
2076!> The canopy drag must be limited (previously accounted for by calculation of
2077!> a limiting canopy timestep for the determination of the maximum LES timestep
2078!> in subroutine timestep), since it is physically impossible that the canopy
2079!> drag alone can locally change the sign of a velocity component. This
2080!> limitation is realized by calculating preliminary tendencies and velocities.
2081!> It is subsequently checked if the preliminary new velocity has a different
2082!> sign than the current velocity. If so, the tendency is limited in a way that
2083!> the velocity can at maximum be reduced to zero by the canopy drag.
2084!>
2085!>
2086!> Call for grid point i,j
2087!------------------------------------------------------------------------------!
2088    SUBROUTINE pcm_tendency_ij( i, j, component )
2089
2090       INTEGER(iwp) ::  component !< prognostic variable (u,v,w,pt,q,e)
2091       INTEGER(iwp) ::  i         !< running index
2092       INTEGER(iwp) ::  j         !< running index
2093       INTEGER(iwp) ::  k         !< running index
2094       INTEGER(iwp) ::  kk        !< running index for flat lad arrays
2095
2096       LOGICAL ::  building_edge_e !< control flag indicating an eastward-facing building edge
2097       LOGICAL ::  building_edge_n !< control flag indicating a north-facing building edge
2098       LOGICAL ::  building_edge_s !< control flag indicating a south-facing building edge
2099       LOGICAL ::  building_edge_w !< control flag indicating a westward-facing building edge
2100
2101       REAL(wp) ::  ddt_3d    !< inverse of the LES timestep (dt_3d)
2102       REAL(wp) ::  lad_local !< local lad value
2103       REAL(wp) ::  pre_tend  !< preliminary tendency
2104       REAL(wp) ::  pre_u     !< preliminary u-value
2105       REAL(wp) ::  pre_v     !< preliminary v-value
2106       REAL(wp) ::  pre_w     !< preliminary w-value
2107
2108
2109       ddt_3d = 1.0_wp / dt_3d
2110!
2111!--    Compute drag for the three velocity components and the SGS-TKE
2112       SELECT CASE ( component )
2113
2114!
2115!--       u-component
2116          CASE ( 1 )
2117!
2118!--          Set control flags indicating east- and westward-orientated
2119!--          building edges. Note, building_egde_w is set from the perspective
2120!--          of the potential rooftop grid point, while building_edge_e is
2121!--          is set from the perspective of the non-building grid point.
2122             building_edge_w = ANY( BTEST( wall_flags_total_0(:,j,i),   6 ) )  .AND. &
2123                         .NOT. ANY( BTEST( wall_flags_total_0(:,j,i-1), 6 ) )
2124             building_edge_e = ANY( BTEST( wall_flags_total_0(:,j,i-1), 6 ) )  .AND. &
2125                         .NOT. ANY( BTEST( wall_flags_total_0(:,j,i),   6 ) )
2126!
2127!--          Determine topography-top index on u-grid
2128             DO  k = topo_top_ind(j,i,1) + 1, topo_top_ind(j,i,1) + pch_index_ji(j,i)
2129
2130                kk = k - topo_top_ind(j,i,1)  !- lad arrays are defined flat
2131
2132!
2133!--             In order to create sharp boundaries of the plant canopy,
2134!--             the lad on the u-grid at index (k,j,i) is equal to lad_s(k,j,i),
2135!--             rather than being interpolated from the surrounding lad_s,
2136!--             because this would yield smaller lad at the canopy boundaries
2137!--             than inside of the canopy.
2138!--             For the same reason, the lad at the rightmost(i+1)canopy
2139!--             boundary on the u-grid equals lad_s(k,j,i), which is considered
2140!--             in the next if-statement. Note, at left-sided building edges
2141!--             this is not applied, here the LAD is equals the LAD at grid
2142!--             point (k,j,i), in order to avoid that LAD is mistakenly mapped
2143!--             on top of a roof where (usually) is no LAD is defined.
2144                lad_local = lad_s(kk,j,i)
2145                IF ( lad_local == 0.0_wp .AND. lad_s(kk,j,i-1) > 0.0_wp  .AND. &
2146                     .NOT. building_edge_w )  lad_local = lad_s(kk,j,i-1)
2147!
2148!--             In order to avoid that LAD is mistakenly considered at right-
2149!--             sided building edges (here the topography-top index for the
2150!--             u-component at index j,i is still on the building while the
2151!--             topography top for the scalar isn't), LAD is taken from grid
2152!--             point (j,i-1).
2153                IF ( lad_local > 0.0_wp .AND. lad_s(kk,j,i-1) == 0.0_wp  .AND. &
2154                     building_edge_e )  lad_local = lad_s(kk,j,i-1)
2155
2156                pre_tend = 0.0_wp
2157                pre_u = 0.0_wp
2158!
2159!--             Calculate preliminary value (pre_tend) of the tendency
2160                pre_tend = - canopy_drag_coeff *                               &
2161                             lad_local *                                       &   
2162                             SQRT( u(k,j,i)**2 +                               &
2163                                   ( 0.25_wp * ( v(k,j,i-1)  +                 &
2164                                                 v(k,j,i)    +                 &
2165                                                 v(k,j+1,i)  +                 &
2166                                                 v(k,j+1,i-1) )                &
2167                                   )**2 +                                      &
2168                                   ( 0.25_wp * ( w(k-1,j,i-1) +                &
2169                                                 w(k-1,j,i)   +                &
2170                                                 w(k,j,i-1)   +                &
2171                                                 w(k,j,i) )                    &
2172                                   )**2                                        &
2173                                 ) *                                           &
2174                             u(k,j,i)
2175
2176!
2177!--             Calculate preliminary new velocity, based on pre_tend
2178                pre_u = u(k,j,i) + dt_3d * pre_tend
2179!
2180!--             Compare sign of old velocity and new preliminary velocity,
2181!--             and in case the signs are different, limit the tendency
2182                IF ( SIGN(pre_u,u(k,j,i)) /= pre_u )  THEN
2183                   pre_tend = - u(k,j,i) * ddt_3d
2184                ELSE
2185                   pre_tend = pre_tend
2186                ENDIF
2187!
2188!--             Calculate final tendency
2189                tend(k,j,i) = tend(k,j,i) + pre_tend
2190             ENDDO
2191
2192
2193!
2194!--       v-component
2195          CASE ( 2 )
2196!
2197!--          Set control flags indicating north- and southward-orientated
2198!--          building edges. Note, building_egde_s is set from the perspective
2199!--          of the potential rooftop grid point, while building_edge_n is
2200!--          is set from the perspective of the non-building grid point.
2201             building_edge_s = ANY( BTEST( wall_flags_total_0(:,j,i),   6 ) )  .AND. &
2202                         .NOT. ANY( BTEST( wall_flags_total_0(:,j-1,i), 6 ) )
2203             building_edge_n = ANY( BTEST( wall_flags_total_0(:,j-1,i), 6 ) )  .AND. &
2204                         .NOT. ANY( BTEST( wall_flags_total_0(:,j,i),   6 ) )
2205!
2206!--          Determine topography-top index on v-grid
2207             DO  k = topo_top_ind(j,i,2) + 1, topo_top_ind(j,i,2) + pch_index_ji(j,i)
2208
2209                kk = k - topo_top_ind(j,i,2)  !- lad arrays are defined flat
2210!
2211!--             In order to create sharp boundaries of the plant canopy,
2212!--             the lad on the v-grid at index (k,j,i) is equal to lad_s(k,j,i),
2213!--             rather than being interpolated from the surrounding lad_s,
2214!--             because this would yield smaller lad at the canopy boundaries
2215!--             than inside of the canopy.
2216!--             For the same reason, the lad at the northmost(j+1)canopy
2217!--             boundary on the v-grid equals lad_s(k,j,i), which is considered
2218!--             in the next if-statement. Note, at left-sided building edges
2219!--             this is not applied, here the LAD is equals the LAD at grid
2220!--             point (k,j,i), in order to avoid that LAD is mistakenly mapped
2221!--             on top of a roof where (usually) is no LAD is defined.
2222                lad_local = lad_s(kk,j,i)
2223                IF ( lad_local == 0.0_wp .AND. lad_s(kk,j-1,i) > 0.0_wp  .AND. &
2224                     .NOT. building_edge_s )  lad_local = lad_s(kk,j-1,i)
2225!
2226!--             In order to avoid that LAD is mistakenly considered at right-
2227!--             sided building edges (here the topography-top index for the
2228!--             u-component at index j,i is still on the building while the
2229!--             topography top for the scalar isn't), LAD is taken from grid
2230!--             point (j,i-1).
2231                IF ( lad_local > 0.0_wp .AND. lad_s(kk,j-1,i) == 0.0_wp  .AND. &
2232                     building_edge_n )  lad_local = lad_s(kk,j-1,i)
2233
2234                pre_tend = 0.0_wp
2235                pre_v = 0.0_wp
2236!
2237!--             Calculate preliminary value (pre_tend) of the tendency
2238                pre_tend = - canopy_drag_coeff *                               &
2239                             lad_local *                                       &
2240                             SQRT( ( 0.25_wp * ( u(k,j-1,i)   +                &
2241                                                 u(k,j-1,i+1) +                &
2242                                                 u(k,j,i)     +                &
2243                                                 u(k,j,i+1) )                  &
2244                                   )**2 +                                      &
2245                                   v(k,j,i)**2 +                               &
2246                                   ( 0.25_wp * ( w(k-1,j-1,i) +                &
2247                                                 w(k-1,j,i)   +                &
2248                                                 w(k,j-1,i)   +                &
2249                                                 w(k,j,i) )                    &
2250                                   )**2                                        &
2251                                 ) *                                           &
2252                             v(k,j,i)
2253
2254!
2255!--             Calculate preliminary new velocity, based on pre_tend
2256                pre_v = v(k,j,i) + dt_3d * pre_tend
2257!
2258!--             Compare sign of old velocity and new preliminary velocity,
2259!--             and in case the signs are different, limit the tendency
2260                IF ( SIGN(pre_v,v(k,j,i)) /= pre_v )  THEN
2261                   pre_tend = - v(k,j,i) * ddt_3d
2262                ELSE
2263                   pre_tend = pre_tend
2264                ENDIF
2265!
2266!--             Calculate final tendency
2267                tend(k,j,i) = tend(k,j,i) + pre_tend
2268             ENDDO
2269
2270
2271!
2272!--       w-component
2273          CASE ( 3 )
2274!
2275!--          Determine topography-top index on w-grid
2276             DO  k = topo_top_ind(j,i,3) + 1, topo_top_ind(j,i,3) + pch_index_ji(j,i) - 1
2277
2278                kk = k - topo_top_ind(j,i,3)  !- lad arrays are defined flat
2279
2280                pre_tend = 0.0_wp
2281                pre_w = 0.0_wp
2282!
2283!--             Calculate preliminary value (pre_tend) of the tendency
2284                pre_tend = - canopy_drag_coeff *                               &
2285                             (0.5_wp *                                         &
2286                                ( lad_s(kk+1,j,i) + lad_s(kk,j,i) )) *         &
2287                             SQRT( ( 0.25_wp * ( u(k,j,i)    +                 & 
2288                                                 u(k,j,i+1)  +                 &
2289                                                 u(k+1,j,i)  +                 &
2290                                                 u(k+1,j,i+1) )                &
2291                                   )**2 +                                      &
2292                                   ( 0.25_wp * ( v(k,j,i)    +                 &
2293                                                 v(k,j+1,i)  +                 &
2294                                                 v(k+1,j,i)  +                 &
2295                                                 v(k+1,j+1,i) )                &
2296                                   )**2 +                                      &
2297                                   w(k,j,i)**2                                 &
2298                                 ) *                                           &
2299                             w(k,j,i)
2300!
2301!--             Calculate preliminary new velocity, based on pre_tend
2302                pre_w = w(k,j,i) + dt_3d * pre_tend
2303!
2304!--             Compare sign of old velocity and new preliminary velocity,
2305!--             and in case the signs are different, limit the tendency
2306                IF ( SIGN(pre_w,w(k,j,i)) /= pre_w )  THEN
2307                   pre_tend = - w(k,j,i) * ddt_3d
2308                ELSE
2309                   pre_tend = pre_tend
2310                ENDIF
2311!
2312!--             Calculate final tendency
2313                tend(k,j,i) = tend(k,j,i) + pre_tend
2314             ENDDO
2315
2316!
2317!--       potential temperature
2318          CASE ( 4 )
2319!
2320!--          Determine topography-top index on scalar grid
2321             IF ( humidity ) THEN
2322                DO  k = topo_top_ind(j,i,0) + 1, topo_top_ind(j,i,0) + pch_index_ji(j,i)
2323                   kk = k - topo_top_ind(j,i,0)  !- lad arrays are defined flat
2324                   tend(k,j,i) = tend(k,j,i) + pcm_heating_rate(kk,j,i) -       &
2325                                 pcm_latent_rate(kk,j,i)
2326                ENDDO
2327             ELSE
2328                DO  k = topo_top_ind(j,i,0) + 1, topo_top_ind(j,i,0) + pch_index_ji(j,i)
2329                   kk = k - topo_top_ind(j,i,0)  !- lad arrays are defined flat
2330                   tend(k,j,i) = tend(k,j,i) + pcm_heating_rate(kk,j,i)
2331                ENDDO
2332             ENDIF
2333
2334!
2335!--       humidity
2336          CASE ( 5 )
2337!
2338!--          Determine topography-top index on scalar grid
2339             DO  k = topo_top_ind(j,i,0) + 1, topo_top_ind(j,i,0) + pch_index_ji(j,i)
2340                kk = k - topo_top_ind(j,i,0)  !- lad arrays are defined flat
2341                IF ( .NOT. plant_canopy_transpiration ) THEN
2342                   ! pcm_transpiration_rate is calculated in radiation model
2343                   ! in case of plant_canopy_transpiration = .T.
2344                   ! to include also the dependecy to the radiation
2345                   ! in the plant canopy box
2346                   pcm_transpiration_rate(kk,j,i) = - leaf_scalar_exch_coeff   &
2347                                    * lad_s(kk,j,i) *                          &
2348                                    SQRT( ( 0.5_wp * ( u(k,j,i) +              &
2349                                                       u(k,j,i+1) )            &
2350                                          )**2  +                              &
2351                                          ( 0.5_wp * ( v(k,j,i) +              &
2352                                                       v(k,j+1,i) )            &
2353                                          )**2 +                               &
2354                                          ( 0.5_wp * ( w(k-1,j,i) +            &
2355                                                       w(k,j,i) )              &
2356                                          )**2                                 &
2357                                        ) *                                    &
2358                                    ( q(k,j,i) - leaf_surface_conc )
2359                ENDIF
2360
2361                tend(k,j,i) = tend(k,j,i) + pcm_transpiration_rate(kk,j,i)
2362
2363             ENDDO   
2364
2365!
2366!--       sgs-tke
2367          CASE ( 6 )
2368!
2369!--          Determine topography-top index on scalar grid
2370             DO  k = topo_top_ind(j,i,0) + 1, topo_top_ind(j,i,0) + pch_index_ji(j,i)
2371
2372                kk = k - topo_top_ind(j,i,0)
2373                tend(k,j,i) = tend(k,j,i) -                                    &
2374                                 2.0_wp * canopy_drag_coeff *                  &
2375                                 lad_s(kk,j,i) *                               &
2376                                 SQRT( ( 0.5_wp * ( u(k,j,i) +                 &
2377                                                    u(k,j,i+1) )               &
2378                                       )**2 +                                  & 
2379                                       ( 0.5_wp * ( v(k,j,i) +                 &
2380                                                    v(k,j+1,i) )               &
2381                                       )**2 +                                  &
2382                                       ( 0.5_wp * ( w(k,j,i) +                 &
2383                                                    w(k+1,j,i) )               &
2384                                       )**2                                    &
2385                                     ) *                                       &
2386                                 e(k,j,i)
2387             ENDDO
2388             
2389!
2390!--       scalar concentration
2391          CASE ( 7 )
2392!
2393!--          Determine topography-top index on scalar grid
2394             DO  k = topo_top_ind(j,i,0) + 1, topo_top_ind(j,i,0) + pch_index_ji(j,i)
2395
2396                kk = k - topo_top_ind(j,i,0)
2397                tend(k,j,i) = tend(k,j,i) -                                    &
2398                                 leaf_scalar_exch_coeff *                      &
2399                                 lad_s(kk,j,i) *                               &
2400                                 SQRT( ( 0.5_wp * ( u(k,j,i) +                 &
2401                                                    u(k,j,i+1) )               &
2402                                       )**2  +                                 &
2403                                       ( 0.5_wp * ( v(k,j,i) +                 &
2404                                                    v(k,j+1,i) )               &
2405                                       )**2 +                                  &
2406                                       ( 0.5_wp * ( w(k-1,j,i) +               &
2407                                                    w(k,j,i) )                 &
2408                                       )**2                                    &
2409                                     ) *                                       &
2410                                 ( s(k,j,i) - leaf_surface_conc )
2411             ENDDO               
2412
2413       CASE DEFAULT
2414
2415          WRITE( message_string, * ) 'wrong component: ', component
2416          CALL message( 'pcm_tendency', 'PA0279', 1, 2, 0, 6, 0 ) 
2417
2418       END SELECT
2419
2420    END SUBROUTINE pcm_tendency_ij
2421
2422!------------------------------------------------------------------------------!
2423! Description:
2424! ------------
2425!> Subroutine writes local (subdomain) restart data
2426!------------------------------------------------------------------------------!
2427    SUBROUTINE pcm_wrd_local
2428
2429       IF ( ALLOCATED( pcm_heatrate_av ) )  THEN
2430          CALL wrd_write_string( 'pcm_heatrate_av' )
2431          WRITE ( 14 )  pcm_heatrate_av
2432       ENDIF
2433
2434       IF ( ALLOCATED( pcm_latentrate_av ) )  THEN
2435          CALL wrd_write_string( 'pcm_latentrate_av' )
2436          WRITE ( 14 )  pcm_latentrate_av
2437       ENDIF
2438
2439       IF ( ALLOCATED( pcm_transpirationrate_av ) )  THEN
2440          CALL wrd_write_string( 'pcm_transpirationrate_av' )
2441          WRITE ( 14 )  pcm_transpirationrate_av
2442       ENDIF
2443
2444    END SUBROUTINE pcm_wrd_local
2445
2446
2447 END MODULE plant_canopy_model_mod
Note: See TracBrowser for help on using the repository browser.