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

Last change on this file since 2214 was 2214, checked in by kanani, 4 years ago

last commit documented

  • Property svn:keywords set to Id
File size: 64.1 KB
Line 
1!> @file plant_canopy_model_mod.f90
2!------------------------------------------------------------------------------!
3! This file is part of PALM.
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-2017 Leibniz Universitaet Hannover
18!------------------------------------------------------------------------------!
19!
20! Current revisions:
21! -----------------
22!
23!
24! Former revisions:
25! -----------------
26! $Id: plant_canopy_model_mod.f90 2214 2017-04-24 15:11:32Z kanani $
27!
28! 2213 2017-04-24 15:10:35Z kanani
29! Bugfix: exchange of ghost points in array pc_heating_rate needed for output
30! of pcm_heatrate, onetime ghost point exchange of lad_s after initialization.
31! Formatting and clean-up of subroutine pcm_read_plant_canopy_3d,
32! minor re-organization of canopy-heating initialization.
33!
34! 2209 2017-04-19 09:34:46Z kanani
35! Added 3d output of leaf area density (pcm_lad) and canopy
36! heat rate (pcm_heatrate)
37!
38! 2024 2016-10-12 16:42:37Z kanani
39! Added missing lad_s initialization
40!
41! 2011 2016-09-19 17:29:57Z kanani
42! Renamed canopy_heat_flux to pc_heating_rate, since the original meaning/
43! calculation of the quantity has changed, related to the urban surface model
44! and similar future applications.
45!
46! 2007 2016-08-24 15:47:17Z kanani
47! Added SUBROUTINE pcm_read_plant_canopy_3d for reading 3d plant canopy data
48! from file (new case canopy_mode=read_from_file_3d) in the course of
49! introduction of urban surface model,
50! introduced variable ext_coef,
51! resorted SUBROUTINEs to alphabetical order
52!
53! 2000 2016-08-20 18:09:15Z knoop
54! Forced header and separation lines into 80 columns
55!
56! 1960 2016-07-12 16:34:24Z suehring
57! Separate humidity and passive scalar
58!
59! 1953 2016-06-21 09:28:42Z suehring
60! Bugfix, lad_s and lad must be public
61!
62! 1826 2016-04-07 12:01:39Z maronga
63! Further modularization
64!
65! 1721 2015-11-16 12:56:48Z raasch
66! bugfixes: shf is reduced in areas covered with canopy only,
67!           canopy is set on top of topography
68!
69! 1682 2015-10-07 23:56:08Z knoop
70! Code annotations made doxygen readable
71!
72! 1484 2014-10-21 10:53:05Z kanani
73! Changes due to new module structure of the plant canopy model:
74!   module plant_canopy_model_mod now contains a subroutine for the
75!   initialization of the canopy model (pcm_init),
76!   limitation of the canopy drag (previously accounted for by calculation of
77!   a limiting canopy timestep for the determination of the maximum LES timestep
78!   in subroutine timestep) is now realized by the calculation of pre-tendencies
79!   and preliminary velocities in subroutine pcm_tendency,
80!   some redundant MPI communication removed in subroutine pcm_init
81!   (was previously in init_3d_model),
82!   unnecessary 3d-arrays lad_u, lad_v, lad_w removed - lad information on the
83!   respective grid is now provided only by lad_s (e.g. in the calculation of
84!   the tendency terms or of cum_lai_hf),
85!   drag_coefficient, lai, leaf_surface_concentration,
86!   scalar_exchange_coefficient, sec and sls renamed to canopy_drag_coeff,
87!   cum_lai_hf, leaf_surface_conc, leaf_scalar_exch_coeff, lsec and lsc,
88!   respectively,
89!   unnecessary 3d-arrays cdc, lsc and lsec now defined as single-value constants,
90!   USE-statements and ONLY-lists modified accordingly
91!
92! 1340 2014-03-25 19:45:13Z kanani
93! REAL constants defined as wp-kind
94!
95! 1320 2014-03-20 08:40:49Z raasch
96! ONLY-attribute added to USE-statements,
97! kind-parameters added to all INTEGER and REAL declaration statements,
98! kinds are defined in new module kinds,
99! old module precision_kind is removed,
100! revision history before 2012 removed,
101! comment fields (!:) to be used for variable explanations added to
102! all variable declaration statements
103!
104! 1036 2012-10-22 13:43:42Z raasch
105! code put under GPL (PALM 3.9)
106!
107! 138 2007-11-28 10:03:58Z letzel
108! Initial revision
109!
110! Description:
111! ------------
112!> 1) Initialization of the canopy model, e.g. construction of leaf area density
113!> profile (subroutine pcm_init).
114!> 2) Calculation of sinks and sources of momentum, heat and scalar concentration
115!> due to canopy elements (subroutine pcm_tendency).
116!------------------------------------------------------------------------------!
117 MODULE plant_canopy_model_mod
118 
119    USE arrays_3d,                                                             &
120        ONLY:  dzu, dzw, e, q, s, shf, tend, u, v, w, zu, zw
121
122    USE indices,                                                               &
123        ONLY:  nbgp, nxl, nxlg, nxlu, nxr, nxrg, nyn, nyng, nys, nysg, nysv,   &
124               nz, nzb, nzb_s_inner, nzb_u_inner, nzb_v_inner, nzb_w_inner, nzt
125
126    USE kinds
127
128
129    IMPLICIT NONE
130
131
132    CHARACTER (LEN=20)   ::  canopy_mode = 'block' !< canopy coverage
133
134    INTEGER(iwp) ::  pch_index = 0                 !< plant canopy height/top index
135    INTEGER(iwp) ::                                                            &
136       lad_vertical_gradient_level_ind(10) = -9999 !< lad-profile levels (index)
137
138    LOGICAL ::  calc_beta_lad_profile = .FALSE. !< switch for calc. of lad from beta func.
139    LOGICAL ::  plant_canopy = .FALSE.          !< switch for use of canopy model
140
141    REAL(wp) ::  alpha_lad = 9999999.9_wp   !< coefficient for lad calculation
142    REAL(wp) ::  beta_lad = 9999999.9_wp    !< coefficient for lad calculation
143    REAL(wp) ::  canopy_drag_coeff = 0.0_wp !< canopy drag coefficient (parameter)
144    REAL(wp) ::  cdc = 0.0_wp               !< canopy drag coeff. (abbreviation used in equations)
145    REAL(wp) ::  cthf = 0.0_wp              !< canopy top heat flux
146    REAL(wp) ::  dt_plant_canopy = 0.0_wp   !< timestep account. for canopy drag
147    REAL(wp) ::  ext_coef = 0.6_wp          !< extinction coefficient
148    REAL(wp) ::  lad_surface = 0.0_wp       !< lad surface value
149    REAL(wp) ::  lai_beta = 0.0_wp          !< leaf area index (lai) for lad calc.
150    REAL(wp) ::                                                                &
151       leaf_scalar_exch_coeff = 0.0_wp      !< canopy scalar exchange coeff.
152    REAL(wp) ::                                                                &
153       leaf_surface_conc = 0.0_wp           !< leaf surface concentration
154    REAL(wp) ::  lsec = 0.0_wp              !< leaf scalar exchange coeff.
155    REAL(wp) ::  lsc = 0.0_wp               !< leaf surface concentration
156
157    REAL(wp) ::                                                                &
158       lad_vertical_gradient(10) = 0.0_wp              !< lad gradient
159    REAL(wp) ::                                                                &
160       lad_vertical_gradient_level(10) = -9999999.9_wp !< lad-prof. levels (in m)
161
162    REAL(wp), DIMENSION(:), ALLOCATABLE ::  lad            !< leaf area density
163    REAL(wp), DIMENSION(:), ALLOCATABLE ::  pre_lad        !< preliminary lad
164   
165    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::                                 &
166       pc_heating_rate                                    !< plant canopy heating rate
167    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  cum_lai_hf !< cumulative lai for heatflux calc.
168    REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::  lad_s      !< lad on scalar-grid
169
170
171    SAVE
172
173
174    PRIVATE
175 
176!
177!-- Public functions
178    PUBLIC pcm_check_data_output, pcm_check_parameters, pcm_data_output_3d,    &
179           pcm_define_netcdf_grid, pcm_header, pcm_init, pcm_parin, pcm_tendency
180
181!
182!-- Public variables and constants
183    PUBLIC pc_heating_rate, canopy_mode, cthf, dt_plant_canopy, lad, lad_s,   &
184           pch_index, plant_canopy
185           
186
187    INTERFACE pcm_check_data_output
188       MODULE PROCEDURE pcm_check_data_output
189    END INTERFACE pcm_check_data_output
190   
191    INTERFACE pcm_check_parameters
192       MODULE PROCEDURE pcm_check_parameters
193    END INTERFACE pcm_check_parameters
194
195    INTERFACE pcm_data_output_3d
196       MODULE PROCEDURE pcm_data_output_3d
197    END INTERFACE pcm_data_output_3d
198
199    INTERFACE pcm_define_netcdf_grid
200       MODULE PROCEDURE pcm_define_netcdf_grid
201    END INTERFACE pcm_define_netcdf_grid
202   
203     INTERFACE pcm_header
204       MODULE PROCEDURE pcm_header
205    END INTERFACE pcm_header       
206   
207    INTERFACE pcm_init
208       MODULE PROCEDURE pcm_init
209    END INTERFACE pcm_init
210
211    INTERFACE pcm_parin
212       MODULE PROCEDURE pcm_parin
213    END INTERFACE pcm_parin
214
215    INTERFACE pcm_read_plant_canopy_3d
216       MODULE PROCEDURE pcm_read_plant_canopy_3d
217    END INTERFACE pcm_read_plant_canopy_3d
218   
219    INTERFACE pcm_tendency
220       MODULE PROCEDURE pcm_tendency
221       MODULE PROCEDURE pcm_tendency_ij
222    END INTERFACE pcm_tendency
223
224
225 CONTAINS
226
227
228!------------------------------------------------------------------------------!
229! Description:
230! ------------
231!> Check data output for plant canopy model
232!------------------------------------------------------------------------------!
233 SUBROUTINE pcm_check_data_output( var, unit )
234 
235 
236    USE control_parameters,                                                 &
237        ONLY:  data_output, message_string
238
239    IMPLICIT NONE
240
241    CHARACTER (LEN=*) ::  unit  !<
242    CHARACTER (LEN=*) ::  var   !<
243
244
245    SELECT CASE ( TRIM( var ) )
246
247       CASE ( 'pcm_heatrate' )
248          unit = 'K s-1'
249   
250       CASE ( 'pcm_lad' )
251          unit = 'm2 m-3'
252
253
254       CASE DEFAULT
255          unit = 'illegal'
256
257    END SELECT
258
259
260 END SUBROUTINE pcm_check_data_output
261 
262 
263!------------------------------------------------------------------------------!
264! Description:
265! ------------
266!> Check parameters routine for plant canopy model
267!------------------------------------------------------------------------------!
268    SUBROUTINE pcm_check_parameters
269
270       USE control_parameters,                                                 &
271           ONLY: cloud_physics, message_string, microphysics_seifert
272                 
273   
274       IMPLICIT NONE
275
276   
277       IF ( canopy_drag_coeff == 0.0_wp )  THEN
278          message_string = 'plant_canopy = .TRUE. requires a non-zero drag '// &
279                           'coefficient & given value is canopy_drag_coeff = 0.0'
280          CALL message( 'check_parameters', 'PA0041', 1, 2, 0, 6, 0 )
281       ENDIF
282   
283       IF ( ( alpha_lad /= 9999999.9_wp  .AND.  beta_lad == 9999999.9_wp )  .OR.&
284              beta_lad /= 9999999.9_wp   .AND.  alpha_lad == 9999999.9_wp )  THEN
285          message_string = 'using the beta function for the construction ' //  &
286                           'of the leaf area density profile requires '    //  &
287                           'both alpha_lad and beta_lad to be /= 9999999.9'
288          CALL message( 'check_parameters', 'PA0118', 1, 2, 0, 6, 0 )
289       ENDIF
290   
291       IF ( calc_beta_lad_profile  .AND.  lai_beta == 0.0_wp )  THEN
292          message_string = 'using the beta function for the construction ' //  &
293                           'of the leaf area density profile requires '    //  &
294                           'a non-zero lai_beta, but given value is '      //  &
295                           'lai_beta = 0.0'
296          CALL message( 'check_parameters', 'PA0119', 1, 2, 0, 6, 0 )
297       ENDIF
298
299       IF ( calc_beta_lad_profile  .AND.  lad_surface /= 0.0_wp )  THEN
300          message_string = 'simultaneous setting of alpha_lad /= 9999999.9' // &
301                           'and lad_surface /= 0.0 is not possible, '       // &
302                           'use either vertical gradients or the beta '     // &
303                           'function for the construction of the leaf area '// &
304                           'density profile'
305          CALL message( 'check_parameters', 'PA0120', 1, 2, 0, 6, 0 )
306       ENDIF
307
308       IF ( cloud_physics  .AND.  microphysics_seifert )  THEN
309          message_string = 'plant_canopy = .TRUE. requires cloud_scheme /=' // &
310                          ' seifert_beheng'
311          CALL message( 'check_parameters', 'PA0360', 1, 2, 0, 6, 0 )
312       ENDIF
313
314 
315    END SUBROUTINE pcm_check_parameters
316 
317
318!------------------------------------------------------------------------------!
319!
320! Description:
321! ------------
322!> Subroutine defining 3D output variables
323!------------------------------------------------------------------------------!
324 SUBROUTINE pcm_data_output_3d( av, variable, found, local_pf )
325 
326    USE control_parameters,                                                    &
327        ONLY :  nz_do3d
328 
329    USE indices
330
331    USE kinds
332
333
334    IMPLICIT NONE
335
336    CHARACTER (LEN=*) ::  variable !<
337
338    INTEGER(iwp) ::  av    !<
339    INTEGER(iwp) ::  i     !<
340    INTEGER(iwp) ::  j     !<
341    INTEGER(iwp) ::  k     !<
342
343    LOGICAL      ::  found !<
344
345    REAL(sp), DIMENSION(nxlg:nxrg,nysg:nyng,nzb:nz_do3d) ::  local_pf !<
346
347
348    found = .TRUE.
349
350
351    SELECT CASE ( TRIM( variable ) )
352
353      CASE ( 'pcm_heatrate' )
354         CALL exchange_horiz( pc_heating_rate, nbgp )
355         IF ( av == 0 )  THEN
356            DO  i = nxlg, nxrg
357               DO  j = nysg, nyng
358                  DO  k = nzb_s_inner(j,i), nz_do3d
359                     local_pf(i,j,k) = pc_heating_rate(k-nzb_s_inner(j,i),j,i)
360                  ENDDO
361               ENDDO
362            ENDDO
363         ENDIF
364   
365   
366      CASE ( 'pcm_lad' )
367         IF ( av == 0 )  THEN
368            DO  i = nxlg, nxrg
369               DO  j = nysg, nyng
370                  DO  k = nzb_s_inner(j,i), nz_do3d
371                     local_pf(i,j,k) = lad_s(k-nzb_s_inner(j,i),j,i)
372                  ENDDO
373               ENDDO
374            ENDDO
375         ENDIF
376                 
377         
378       CASE DEFAULT
379          found = .FALSE.
380
381    END SELECT
382
383
384 END SUBROUTINE pcm_data_output_3d
385         
386!------------------------------------------------------------------------------!
387!
388! Description:
389! ------------
390!> Subroutine defining appropriate grid for netcdf variables.
391!> It is called from subroutine netcdf.
392!------------------------------------------------------------------------------!
393 SUBROUTINE pcm_define_netcdf_grid( var, found, grid_x, grid_y, grid_z )
394   
395     IMPLICIT NONE
396
397     CHARACTER (LEN=*), INTENT(IN)  ::  var         !<
398     LOGICAL, INTENT(OUT)           ::  found       !<
399     CHARACTER (LEN=*), INTENT(OUT) ::  grid_x      !<
400     CHARACTER (LEN=*), INTENT(OUT) ::  grid_y      !<
401     CHARACTER (LEN=*), INTENT(OUT) ::  grid_z      !<
402
403     found  = .TRUE.
404
405!
406!--  Check for the grid
407     SELECT CASE ( TRIM( var ) )
408
409        CASE ( 'pcm_heatrate', 'pcm_lad' )
410           grid_x = 'x'
411           grid_y = 'y'
412           grid_z = 'zu'
413
414        CASE DEFAULT
415           found  = .FALSE.
416           grid_x = 'none'
417           grid_y = 'none'
418           grid_z = 'none'
419     END SELECT
420
421 END SUBROUTINE pcm_define_netcdf_grid
422 
423 
424!------------------------------------------------------------------------------!
425! Description:
426! ------------
427!> Header output for plant canopy model
428!------------------------------------------------------------------------------!
429    SUBROUTINE pcm_header ( io )
430
431       USE control_parameters,                                                 &
432           ONLY: dz, passive_scalar
433
434
435       IMPLICIT NONE
436 
437       CHARACTER (LEN=10) ::  coor_chr            !<
438
439       CHARACTER (LEN=86) ::  coordinates         !<
440       CHARACTER (LEN=86) ::  gradients           !<
441       CHARACTER (LEN=86) ::  leaf_area_density   !<
442       CHARACTER (LEN=86) ::  slices              !<
443 
444       INTEGER(iwp) :: i                !<
445       INTEGER(iwp),  INTENT(IN) ::  io !< Unit of the output file
446       INTEGER(iwp) :: k                !<       
447   
448       REAL(wp) ::  canopy_height       !< canopy height (in m)
449       
450       canopy_height = pch_index * dz
451
452       WRITE ( io, 1 )  canopy_mode, canopy_height, pch_index,                 &
453                          canopy_drag_coeff
454       IF ( passive_scalar )  THEN
455          WRITE ( io, 2 )  leaf_scalar_exch_coeff,                             &
456                             leaf_surface_conc
457       ENDIF
458
459!
460!--    Heat flux at the top of vegetation
461       WRITE ( io, 3 )  cthf
462
463!
464!--    Leaf area density profile, calculated either from given vertical
465!--    gradients or from beta probability density function.
466       IF (  .NOT.  calc_beta_lad_profile )  THEN
467
468!--       Building output strings, starting with surface value
469          WRITE ( leaf_area_density, '(F7.4)' )  lad_surface
470          gradients = '------'
471          slices = '     0'
472          coordinates = '   0.0'
473          i = 1
474          DO  WHILE ( i < 11  .AND.  lad_vertical_gradient_level_ind(i)        &
475                      /= -9999 )
476
477             WRITE (coor_chr,'(F7.2)')  lad(lad_vertical_gradient_level_ind(i))
478             leaf_area_density = TRIM( leaf_area_density ) // ' ' //           &
479                                 TRIM( coor_chr )
480 
481             WRITE (coor_chr,'(F7.2)')  lad_vertical_gradient(i)
482             gradients = TRIM( gradients ) // ' ' // TRIM( coor_chr )
483
484             WRITE (coor_chr,'(I7)')  lad_vertical_gradient_level_ind(i)
485             slices = TRIM( slices ) // ' ' // TRIM( coor_chr )
486
487             WRITE (coor_chr,'(F7.1)')  lad_vertical_gradient_level(i)
488             coordinates = TRIM( coordinates ) // ' '  // TRIM( coor_chr )
489
490             i = i + 1
491          ENDDO
492
493          WRITE ( io, 4 )  TRIM( coordinates ), TRIM( leaf_area_density ),     &
494                             TRIM( gradients ), TRIM( slices )
495
496       ELSE
497       
498          WRITE ( leaf_area_density, '(F7.4)' )  lad_surface
499          coordinates = '   0.0'
500         
501          DO  k = 1, pch_index
502
503             WRITE (coor_chr,'(F7.2)')  lad(k)
504             leaf_area_density = TRIM( leaf_area_density ) // ' ' //           &
505                                 TRIM( coor_chr )
506 
507             WRITE (coor_chr,'(F7.1)')  zu(k)
508             coordinates = TRIM( coordinates ) // ' '  // TRIM( coor_chr )
509
510          ENDDO       
511
512          WRITE ( io, 5 ) TRIM( coordinates ), TRIM( leaf_area_density ),      &
513                          alpha_lad, beta_lad, lai_beta
514
515       ENDIF 
516
5171 FORMAT (//' Vegetation canopy (drag) model:'/                                &
518              ' ------------------------------'//                              &
519              ' Canopy mode: ', A /                                            &
520              ' Canopy height: ',F6.2,'m (',I4,' grid points)' /               &
521              ' Leaf drag coefficient: ',F6.2 /)
5222 FORMAT (/ ' Scalar exchange coefficient: ',F6.2 /                            &
523              ' Scalar concentration at leaf surfaces in kg/m**3: ',F6.2 /)
5243 FORMAT (' Predefined constant heatflux at the top of the vegetation: ',F6.2, &
525          ' K m/s')
5264 FORMAT (/ ' Characteristic levels of the leaf area density:'//               &
527              ' Height:              ',A,'  m'/                                &
528              ' Leaf area density:   ',A,'  m**2/m**3'/                        &
529              ' Gradient:            ',A,'  m**2/m**4'/                        &
530              ' Gridpoint:           ',A)
5315 FORMAT (//' Characteristic levels of the leaf area density and coefficients:'&
532          //  ' Height:              ',A,'  m'/                                &
533              ' Leaf area density:   ',A,'  m**2/m**3'/                        &
534              ' Coefficient alpha: ',F6.2 /                                    &
535              ' Coefficient beta: ',F6.2 /                                     &
536              ' Leaf area index: ',F6.2,'  m**2/m**2' /)   
537       
538    END SUBROUTINE pcm_header
539 
540 
541!------------------------------------------------------------------------------!
542! Description:
543! ------------
544!> Initialization of the plant canopy model
545!------------------------------------------------------------------------------!
546    SUBROUTINE pcm_init
547   
548
549       USE control_parameters,                                                 &
550           ONLY:  coupling_char, dz, humidity, io_blocks, io_group,            &
551                  message_string, ocean, passive_scalar
552
553       USE control_parameters,                                                 &
554           ONLY:  urban_surface
555
556       IMPLICIT NONE
557
558       CHARACTER(10) :: pct
559       
560       INTEGER(iwp) ::  i   !< running index
561       INTEGER(iwp) ::  ii  !< index       
562       INTEGER(iwp) ::  j   !< running index
563       INTEGER(iwp) ::  k   !< running index
564
565       REAL(wp) ::  int_bpdf        !< vertical integral for lad-profile construction
566       REAL(wp) ::  dzh             !< vertical grid spacing in units of canopy height
567       REAL(wp) ::  gradient        !< gradient for lad-profile construction
568       REAL(wp) ::  canopy_height   !< canopy height for lad-profile construction
569       REAL(wp) ::  pcv(nzb:nzt+1)  !<
570       
571!
572!--    Allocate one-dimensional arrays for the computation of the
573!--    leaf area density (lad) profile
574       ALLOCATE( lad(0:nz+1), pre_lad(0:nz+1) )
575       lad = 0.0_wp
576       pre_lad = 0.0_wp
577
578!
579!--    Set flag that indicates that the lad-profile shall be calculated by using
580!--    a beta probability density function
581       IF ( alpha_lad /= 9999999.9_wp  .AND.  beta_lad /= 9999999.9_wp )  THEN
582          calc_beta_lad_profile = .TRUE.
583       ENDIF
584       
585       
586!
587!--    Compute the profile of leaf area density used in the plant
588!--    canopy model. The profile can either be constructed from
589!--    prescribed vertical gradients of the leaf area density or by
590!--    using a beta probability density function (see e.g. Markkanen et al.,
591!--    2003: Boundary-Layer Meteorology, 106, 437-459)
592       IF (  .NOT.  calc_beta_lad_profile )  THEN   
593
594!
595!--       Use vertical gradients for lad-profile construction   
596          i = 1
597          gradient = 0.0_wp
598
599          IF (  .NOT.  ocean )  THEN
600
601             lad(0) = lad_surface
602             lad_vertical_gradient_level_ind(1) = 0
603 
604             DO k = 1, pch_index
605                IF ( i < 11 )  THEN
606                   IF ( lad_vertical_gradient_level(i) < zu(k)  .AND.          &
607                        lad_vertical_gradient_level(i) >= 0.0_wp )  THEN
608                      gradient = lad_vertical_gradient(i)
609                      lad_vertical_gradient_level_ind(i) = k - 1
610                      i = i + 1
611                   ENDIF
612                ENDIF
613                IF ( gradient /= 0.0_wp )  THEN
614                   IF ( k /= 1 )  THEN
615                      lad(k) = lad(k-1) + dzu(k) * gradient
616                   ELSE
617                      lad(k) = lad_surface + dzu(k) * gradient
618                   ENDIF
619                ELSE
620                   lad(k) = lad(k-1)
621                ENDIF
622             ENDDO
623
624          ENDIF
625
626!
627!--       In case of no given leaf area density gradients, choose a vanishing
628!--       gradient. This information is used for the HEADER and the RUN_CONTROL
629!--       file.
630          IF ( lad_vertical_gradient_level(1) == -9999999.9_wp )  THEN
631             lad_vertical_gradient_level(1) = 0.0_wp
632          ENDIF
633
634       ELSE
635
636!
637!--       Use beta function for lad-profile construction
638          int_bpdf = 0.0_wp
639          canopy_height = pch_index * dz
640
641          DO k = nzb, pch_index
642             int_bpdf = int_bpdf +                                             &
643                      ( ( ( zw(k) / canopy_height )**( alpha_lad-1.0_wp ) ) *  &
644                      ( ( 1.0_wp - ( zw(k) / canopy_height ) )**(              &
645                          beta_lad-1.0_wp ) )                                  &
646                      * ( ( zw(k+1)-zw(k) ) / canopy_height ) )
647          ENDDO
648
649!
650!--       Preliminary lad profile (defined on w-grid)
651          DO k = nzb, pch_index
652             pre_lad(k) =  lai_beta *                                          &
653                        ( ( ( zw(k) / canopy_height )**( alpha_lad-1.0_wp ) )  &
654                        * ( ( 1.0_wp - ( zw(k) / canopy_height ) )**(          &
655                              beta_lad-1.0_wp ) ) / int_bpdf                   &
656                        ) / canopy_height
657          ENDDO
658
659!
660!--       Final lad profile (defined on scalar-grid level, since most prognostic
661!--       quantities are defined there, hence, less interpolation is required
662!--       when calculating the canopy tendencies)
663          lad(0) = pre_lad(0)
664          DO k = nzb+1, pch_index
665             lad(k) = 0.5 * ( pre_lad(k-1) + pre_lad(k) )
666          ENDDO         
667
668       ENDIF
669
670!
671!--    Allocate 3D-array for the leaf area density (lad_s).
672       ALLOCATE( lad_s(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
673
674!
675!--    Initialize canopy parameters cdc (canopy drag coefficient),
676!--    lsec (leaf scalar exchange coefficient), lsc (leaf surface concentration)
677!--    with the prescribed values
678       cdc = canopy_drag_coeff
679       lsec = leaf_scalar_exch_coeff
680       lsc = leaf_surface_conc
681
682!
683!--    Initialization of the canopy coverage in the model domain:
684!--    Setting the parameter canopy_mode = 'block' initializes a canopy, which
685!--    fully covers the domain surface
686       SELECT CASE ( TRIM( canopy_mode ) )
687
688          CASE( 'block' )
689
690             DO  i = nxlg, nxrg
691                DO  j = nysg, nyng
692                   lad_s(:,j,i) = lad(:)
693                ENDDO
694             ENDDO
695
696          CASE ( 'read_from_file_3d' )
697!
698!--          Initialize canopy parameters cdc (canopy drag coefficient),
699!--          lsec (leaf scalar exchange coefficient), lsc (leaf surface concentration)
700!--          from file which contains complete 3D data (separate vertical profiles for
701!--          each location).
702             CALL pcm_read_plant_canopy_3d
703
704          CASE DEFAULT
705!
706!--          The DEFAULT case is reached either if the parameter
707!--          canopy mode contains a wrong character string or if the
708!--          user has coded a special case in the user interface.
709!--          There, the subroutine user_init_plant_canopy checks
710!--          which of these two conditions applies.
711             CALL user_init_plant_canopy
712 
713       END SELECT
714
715!
716!--    Initialization of the canopy heat source distribution due to heating
717!--    of the canopy layers by incoming solar radiation, in case that a non-zero
718!--    value is set for the canopy top heat flux (cthf), which equals the
719!--    available net radiation at canopy top.
720!--    The heat source distribution is calculated by a decaying exponential
721!--    function of the downward cumulative leaf area index (cum_lai_hf),
722!--    assuming that the foliage inside the plant canopy is heated by solar
723!--    radiation penetrating the canopy layers according to the distribution
724!--    of net radiation as suggested by Brown & Covey (1966; Agric. Meteorol. 3,
725!--    73–96). This approach has been applied e.g. by Shaw & Schumann (1992;
726!--    Bound.-Layer Meteorol. 61, 47–64).
727!--    When using the urban surface model (USM), canopy heating (pc_heating_rate)
728!--    by radiation is calculated in the USM.
729       IF ( cthf /= 0.0_wp  .AND. .NOT.  urban_surface)  THEN
730
731          ALLOCATE( cum_lai_hf(nzb:nzt+1,nysg:nyng,nxlg:nxrg),                 &
732                    pc_heating_rate(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
733!
734!--       Piecewise calculation of the cumulative leaf area index by vertical
735!--       integration of the leaf area density
736          cum_lai_hf(:,:,:) = 0.0_wp
737          DO  i = nxlg, nxrg
738             DO  j = nysg, nyng
739                DO  k = pch_index-1, 0, -1
740                   IF ( k == pch_index-1 )  THEN
741                      cum_lai_hf(k,j,i) = cum_lai_hf(k+1,j,i) +                &
742                         ( 0.5_wp * lad_s(k+1,j,i) *                           &
743                           ( zw(k+1) - zu(k+1) ) )  +                          &
744                         ( 0.5_wp * ( 0.5_wp * ( lad_s(k+1,j,i) +              &
745                                                 lad_s(k,j,i) ) +              &
746                                      lad_s(k+1,j,i) ) *                       &
747                           ( zu(k+1) - zw(k) ) ) 
748                   ELSE
749                      cum_lai_hf(k,j,i) = cum_lai_hf(k+1,j,i) +                &
750                         ( 0.5_wp * ( 0.5_wp * ( lad_s(k+2,j,i) +              &
751                                                 lad_s(k+1,j,i) ) +            &
752                                      lad_s(k+1,j,i) ) *                       &
753                           ( zw(k+1) - zu(k+1) ) )  +                          &
754                         ( 0.5_wp * ( 0.5_wp * ( lad_s(k+1,j,i) +              &
755                                                 lad_s(k,j,i) ) +              &
756                                      lad_s(k+1,j,i) ) *                       &
757                           ( zu(k+1) - zw(k) ) )
758                   ENDIF
759                ENDDO
760             ENDDO
761          ENDDO
762
763!
764!--       Calculation of the heating rate (K/s) within the different layers of
765!--       the plant canopy
766          DO  i = nxlg, nxrg
767             DO  j = nysg, nyng
768!
769!--             Calculation only necessary in areas covered with canopy
770                IF ( cum_lai_hf(0,j,i) /= 0.0_wp )  THEN
771!--             
772!--                In areas with canopy the surface value of the canopy heat
773!--                flux distribution overrides the surface heat flux (shf)
774                   shf(j,i) = cthf * exp( -ext_coef * cum_lai_hf(0,j,i) )
775!
776!--                Within the different canopy layers the plant-canopy heating
777!--                rate (pc_heating_rate) is calculated as the vertical
778!--                divergence of the canopy heat fluxes at the top and bottom
779!--                of the respective layer
780                   DO  k = 1, pch_index
781                      pc_heating_rate(k,j,i) = cthf *                         &
782                                                ( exp(-ext_coef*cum_lai_hf(k,j,i)) -  &
783                                                  exp(-ext_coef*cum_lai_hf(k-1,j,i)) ) / dzw(k)
784                   ENDDO
785                ENDIF
786             ENDDO
787          ENDDO
788
789       ENDIF
790
791
792
793    END SUBROUTINE pcm_init
794
795
796!------------------------------------------------------------------------------!
797! Description:
798! ------------
799!> Parin for &canopy_par for plant canopy model
800!------------------------------------------------------------------------------!
801    SUBROUTINE pcm_parin
802
803
804       IMPLICIT NONE
805
806       CHARACTER (LEN=80) ::  line  !< dummy string that contains the current line of the parameter file
807       
808       NAMELIST /canopy_par/      alpha_lad, beta_lad, canopy_drag_coeff,      &
809                                  canopy_mode, cthf,                           &
810                                  lad_surface,                                 & 
811                                  lad_vertical_gradient,                       &
812                                  lad_vertical_gradient_level,                 &
813                                  lai_beta,                                    &
814                                  leaf_scalar_exch_coeff,                      &
815                                  leaf_surface_conc, pch_index
816       
817       line = ' '
818       
819!
820!--    Try to find radiation model package
821       REWIND ( 11 )
822       line = ' '
823       DO   WHILE ( INDEX( line, '&canopy_par' ) == 0 )
824          READ ( 11, '(A)', END=10 )  line
825       ENDDO
826       BACKSPACE ( 11 )
827
828!
829!--    Read user-defined namelist
830       READ ( 11, canopy_par )
831
832!
833!--    Set flag that indicates that the radiation model is switched on
834       plant_canopy = .TRUE.
835
836 10    CONTINUE
837       
838
839    END SUBROUTINE pcm_parin
840
841
842
843!------------------------------------------------------------------------------!
844! Description:
845! ------------
846!
847!> Loads 3D plant canopy data from file. File format is as follows:
848!>
849!> num_levels
850!> dtype,x,y,value(nzb),value(nzb+1), ... ,value(nzb+num_levels-1)
851!> dtype,x,y,value(nzb),value(nzb+1), ... ,value(nzb+num_levels-1)
852!> dtype,x,y,value(nzb),value(nzb+1), ... ,value(nzb+num_levels-1)
853!> ...
854!>
855!> i.e. first line determines number of levels and further lines represent plant
856!> canopy data, one line per column and variable. In each data line,
857!> dtype represents variable to be set:
858!>
859!> dtype=1: leaf area density (lad_s)
860!> dtype=2....n: some additional plant canopy input data quantity
861!>
862!> Zeros are added automatically above num_levels until top of domain.  Any
863!> non-specified (x,y) columns have zero values as default.
864!------------------------------------------------------------------------------!
865    SUBROUTINE pcm_read_plant_canopy_3d
866   
867       USE control_parameters,                                                 &
868           ONLY:  message_string, passive_scalar
869
870       USE indices,                                                            &
871           ONLY:  nbgp
872           
873       IMPLICIT NONE
874
875       INTEGER(iwp)                        ::  dtype     !< type of input data (1=lad)
876       INTEGER(iwp)                        ::  i, j      !< running index
877       INTEGER(iwp)                        ::  nzp       !< number of vertical layers of plant canopy
878       INTEGER(iwp)                        ::  nzpltop   !<
879       INTEGER(iwp)                        ::  nzpl      !<
880       
881       REAL(wp), DIMENSION(:), ALLOCATABLE ::  col   !< vertical column of input data
882
883!
884!--    Initialize lad_s array
885       lad_s = 0.0_wp
886       
887!
888!--    Open and read plant canopy input data
889       OPEN(152, file='PLANT_CANOPY_DATA_3D', access='SEQUENTIAL', &
890                 action='READ', status='OLD', form='FORMATTED', err=515)
891       READ(152, *, err=516, end=517) nzp   !< read first line = number of vertical layers
892       
893       ALLOCATE(col(0:nzp-1))
894
895       DO
896          READ(152, *, err=516, end=517) dtype, i, j, col(:)
897          IF ( i < nxlg .or. i > nxrg .or. j < nysg .or. j > nyng ) CYCLE
898
899             SELECT CASE (dtype)
900                CASE( 1 )   !< leaf area density
901!
902!--                 This is just the pure canopy layer assumed to be grounded to
903!--                 a flat domain surface. At locations where plant canopy sits
904!--                 on top of any kind of topography, the vertical plant column
905!--                 must be "lifted", which is done in SUBROUTINE pcm_tendency.
906                    lad_s(0:nzp-1, j, i) = col(0:nzp-1)
907                   
908                CASE DEFAULT
909                   write(message_string, '(a,i2,a)')   &
910                      'Unknown record type in file PLANT_CANOPY_DATA_3D: "', dtype, '"'
911                   CALL message( 'pcm_read_plant_canopy_3d', 'PA0530', 1, 2, 0, 6, 0 )
912             END SELECT
913       ENDDO
914
915515    message_string = 'error opening file PLANT_CANOPY_DATA_3D'
916       CALL message( 'pcm_read_plant_canopy_3d', 'PA0531', 1, 2, 0, 6, 0 )
917
918516    message_string = 'error reading file PLANT_CANOPY_DATA_3D'
919       CALL message( 'pcm_read_plant_canopy_3d', 'PA0532', 1, 2, 0, 6, 0 )
920
921517    CLOSE(152)
922       DEALLOCATE(col)
923       
924       CALL exchange_horiz( lad_s, nbgp )
925       
926    END SUBROUTINE pcm_read_plant_canopy_3d
927   
928   
929
930!------------------------------------------------------------------------------!
931! Description:
932! ------------
933!> Calculation of the tendency terms, accounting for the effect of the plant
934!> canopy on momentum and scalar quantities.
935!>
936!> The canopy is located where the leaf area density lad_s(k,j,i) > 0.0
937!> (defined on scalar grid), as initialized in subroutine pcm_init.
938!> The lad on the w-grid is vertically interpolated from the surrounding
939!> lad_s. The upper boundary of the canopy is defined on the w-grid at
940!> k = pch_index. Here, the lad is zero.
941!>
942!> The canopy drag must be limited (previously accounted for by calculation of
943!> a limiting canopy timestep for the determination of the maximum LES timestep
944!> in subroutine timestep), since it is physically impossible that the canopy
945!> drag alone can locally change the sign of a velocity component. This
946!> limitation is realized by calculating preliminary tendencies and velocities.
947!> It is subsequently checked if the preliminary new velocity has a different
948!> sign than the current velocity. If so, the tendency is limited in a way that
949!> the velocity can at maximum be reduced to zero by the canopy drag.
950!>
951!>
952!> Call for all grid points
953!------------------------------------------------------------------------------!
954    SUBROUTINE pcm_tendency( component )
955
956
957       USE control_parameters,                                                 &
958           ONLY:  dt_3d, message_string
959
960       USE kinds
961
962       IMPLICIT NONE
963
964       INTEGER(iwp) ::  component !< prognostic variable (u,v,w,pt,q,e)
965       INTEGER(iwp) ::  i         !< running index
966       INTEGER(iwp) ::  j         !< running index
967       INTEGER(iwp) ::  k         !< running index
968       INTEGER(iwp) ::  kk        !< running index for flat lad arrays
969
970       REAL(wp) ::  ddt_3d    !< inverse of the LES timestep (dt_3d)
971       REAL(wp) ::  lad_local !< local lad value
972       REAL(wp) ::  pre_tend  !< preliminary tendency
973       REAL(wp) ::  pre_u     !< preliminary u-value
974       REAL(wp) ::  pre_v     !< preliminary v-value
975       REAL(wp) ::  pre_w     !< preliminary w-value
976
977
978       ddt_3d = 1.0_wp / dt_3d
979 
980!
981!--    Compute drag for the three velocity components and the SGS-TKE:
982       SELECT CASE ( component )
983
984!
985!--       u-component
986          CASE ( 1 )
987             DO  i = nxlu, nxr
988                DO  j = nys, nyn
989                   DO  k = nzb_u_inner(j,i)+1, nzb_u_inner(j,i)+pch_index
990
991                      kk = k - nzb_u_inner(j,i)  !- lad arrays are defined flat
992!
993!--                   In order to create sharp boundaries of the plant canopy,
994!--                   the lad on the u-grid at index (k,j,i) is equal to
995!--                   lad_s(k,j,i), rather than being interpolated from the
996!--                   surrounding lad_s, because this would yield smaller lad
997!--                   at the canopy boundaries than inside of the canopy.
998!--                   For the same reason, the lad at the rightmost(i+1)canopy
999!--                   boundary on the u-grid equals lad_s(k,j,i).
1000                      lad_local = lad_s(kk,j,i)
1001                      IF ( lad_local == 0.0_wp .AND. lad_s(kk,j,i-1) > 0.0_wp )&
1002                      THEN
1003                         lad_local = lad_s(kk,j,i-1)
1004                      ENDIF
1005
1006                      pre_tend = 0.0_wp
1007                      pre_u = 0.0_wp
1008!
1009!--                   Calculate preliminary value (pre_tend) of the tendency
1010                      pre_tend = - cdc *                                       &
1011                                   lad_local *                                 &
1012                                   SQRT( u(k,j,i)**2 +                         &
1013                                         ( 0.25_wp * ( v(k,j,i-1) +            &
1014                                                       v(k,j,i)   +            &
1015                                                       v(k,j+1,i) +            &
1016                                                       v(k,j+1,i-1) )          &
1017                                         )**2 +                                &
1018                                         ( 0.25_wp * ( w(k-1,j,i-1) +          &
1019                                                       w(k-1,j,i)   +          &
1020                                                       w(k,j,i-1)   +          &
1021                                                       w(k,j,i) )              &
1022                                         )**2                                  &
1023                                       ) *                                     &
1024                                   u(k,j,i)
1025
1026!
1027!--                   Calculate preliminary new velocity, based on pre_tend
1028                      pre_u = u(k,j,i) + dt_3d * pre_tend
1029!
1030!--                   Compare sign of old velocity and new preliminary velocity,
1031!--                   and in case the signs are different, limit the tendency
1032                      IF ( SIGN(pre_u,u(k,j,i)) /= pre_u )  THEN
1033                         pre_tend = - u(k,j,i) * ddt_3d
1034                      ELSE
1035                         pre_tend = pre_tend
1036                      ENDIF
1037!
1038!--                   Calculate final tendency
1039                      tend(k,j,i) = tend(k,j,i) + pre_tend
1040
1041                   ENDDO
1042                ENDDO
1043             ENDDO
1044
1045!
1046!--       v-component
1047          CASE ( 2 )
1048             DO  i = nxl, nxr
1049                DO  j = nysv, nyn
1050                   DO  k = nzb_v_inner(j,i)+1, nzb_v_inner(j,i)+pch_index
1051
1052                      kk = k - nzb_v_inner(j,i)  !- lad arrays are defined flat
1053!
1054!--                   In order to create sharp boundaries of the plant canopy,
1055!--                   the lad on the v-grid at index (k,j,i) is equal to
1056!--                   lad_s(k,j,i), rather than being interpolated from the
1057!--                   surrounding lad_s, because this would yield smaller lad
1058!--                   at the canopy boundaries than inside of the canopy.
1059!--                   For the same reason, the lad at the northmost(j+1) canopy
1060!--                   boundary on the v-grid equals lad_s(k,j,i).
1061                      lad_local = lad_s(kk,j,i)
1062                      IF ( lad_local == 0.0_wp .AND. lad_s(kk,j-1,i) > 0.0_wp )&
1063                      THEN
1064                         lad_local = lad_s(kk,j-1,i)
1065                      ENDIF
1066
1067                      pre_tend = 0.0_wp
1068                      pre_v = 0.0_wp
1069!
1070!--                   Calculate preliminary value (pre_tend) of the tendency
1071                      pre_tend = - cdc *                                       &
1072                                   lad_local *                                 &
1073                                   SQRT( ( 0.25_wp * ( u(k,j-1,i)   +          &
1074                                                       u(k,j-1,i+1) +          &
1075                                                       u(k,j,i)     +          &
1076                                                       u(k,j,i+1) )            &
1077                                         )**2 +                                &
1078                                         v(k,j,i)**2 +                         &
1079                                         ( 0.25_wp * ( w(k-1,j-1,i) +          &
1080                                                       w(k-1,j,i)   +          &
1081                                                       w(k,j-1,i)   +          &
1082                                                       w(k,j,i) )              &
1083                                         )**2                                  &
1084                                       ) *                                     &
1085                                   v(k,j,i)
1086
1087!
1088!--                   Calculate preliminary new velocity, based on pre_tend
1089                      pre_v = v(k,j,i) + dt_3d * pre_tend
1090!
1091!--                   Compare sign of old velocity and new preliminary velocity,
1092!--                   and in case the signs are different, limit the tendency
1093                      IF ( SIGN(pre_v,v(k,j,i)) /= pre_v )  THEN
1094                         pre_tend = - v(k,j,i) * ddt_3d
1095                      ELSE
1096                         pre_tend = pre_tend
1097                      ENDIF
1098!
1099!--                   Calculate final tendency
1100                      tend(k,j,i) = tend(k,j,i) + pre_tend
1101
1102                   ENDDO
1103                ENDDO
1104             ENDDO
1105
1106!
1107!--       w-component
1108          CASE ( 3 )
1109             DO  i = nxl, nxr
1110                DO  j = nys, nyn
1111                   DO  k = nzb_w_inner(j,i)+1, nzb_w_inner(j,i)+pch_index-1
1112
1113                      kk = k - nzb_w_inner(j,i)  !- lad arrays are defined flat
1114
1115                      pre_tend = 0.0_wp
1116                      pre_w = 0.0_wp
1117!
1118!--                   Calculate preliminary value (pre_tend) of the tendency
1119                      pre_tend = - cdc *                                       &
1120                                   (0.5_wp *                                   &
1121                                      ( lad_s(kk+1,j,i) + lad_s(kk,j,i) )) *   &
1122                                   SQRT( ( 0.25_wp * ( u(k,j,i)   +            &
1123                                                       u(k,j,i+1) +            &
1124                                                       u(k+1,j,i) +            &
1125                                                       u(k+1,j,i+1) )          &
1126                                         )**2 +                                &
1127                                         ( 0.25_wp * ( v(k,j,i)   +            &
1128                                                       v(k,j+1,i) +            &
1129                                                       v(k+1,j,i) +            &
1130                                                       v(k+1,j+1,i) )          &
1131                                         )**2 +                                &
1132                                         w(k,j,i)**2                           &
1133                                       ) *                                     &
1134                                   w(k,j,i)
1135!
1136!--                   Calculate preliminary new velocity, based on pre_tend
1137                      pre_w = w(k,j,i) + dt_3d * pre_tend
1138!
1139!--                   Compare sign of old velocity and new preliminary velocity,
1140!--                   and in case the signs are different, limit the tendency
1141                      IF ( SIGN(pre_w,w(k,j,i)) /= pre_w )  THEN
1142                         pre_tend = - w(k,j,i) * ddt_3d
1143                      ELSE
1144                         pre_tend = pre_tend
1145                      ENDIF
1146!
1147!--                   Calculate final tendency
1148                      tend(k,j,i) = tend(k,j,i) + pre_tend
1149
1150                   ENDDO
1151                ENDDO
1152             ENDDO
1153
1154!
1155!--       potential temperature
1156          CASE ( 4 )
1157             DO  i = nxl, nxr
1158                DO  j = nys, nyn
1159                   DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
1160                      kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
1161                      tend(k,j,i) = tend(k,j,i) + pc_heating_rate(kk,j,i)
1162                   ENDDO
1163                ENDDO
1164             ENDDO
1165
1166!
1167!--       humidity
1168          CASE ( 5 )
1169             DO  i = nxl, nxr
1170                DO  j = nys, nyn
1171                   DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
1172                      kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
1173                      tend(k,j,i) = tend(k,j,i) -                              &
1174                                       lsec *                                  &
1175                                       lad_s(kk,j,i) *                         &
1176                                       SQRT( ( 0.5_wp * ( u(k,j,i) +           &
1177                                                          u(k,j,i+1) )         &
1178                                             )**2 +                            &
1179                                             ( 0.5_wp * ( v(k,j,i) +           &
1180                                                          v(k,j+1,i) )         &
1181                                             )**2 +                            &
1182                                             ( 0.5_wp * ( w(k-1,j,i) +         & 
1183                                                          w(k,j,i) )           &
1184                                             )**2                              &
1185                                           ) *                                 &
1186                                       ( q(k,j,i) - lsc )
1187                   ENDDO
1188                ENDDO
1189             ENDDO
1190
1191!
1192!--       sgs-tke
1193          CASE ( 6 )
1194             DO  i = nxl, nxr
1195                DO  j = nys, nyn
1196                   DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
1197                      kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
1198                      tend(k,j,i) = tend(k,j,i) -                              &
1199                                       2.0_wp * cdc *                          &
1200                                       lad_s(kk,j,i) *                         &
1201                                       SQRT( ( 0.5_wp * ( u(k,j,i) +           &
1202                                                          u(k,j,i+1) )         &
1203                                             )**2 +                            &
1204                                             ( 0.5_wp * ( v(k,j,i) +           &
1205                                                          v(k,j+1,i) )         &
1206                                             )**2 +                            &
1207                                             ( 0.5_wp * ( w(k,j,i) +           &
1208                                                          w(k+1,j,i) )         &
1209                                             )**2                              &
1210                                           ) *                                 &
1211                                       e(k,j,i)
1212                   ENDDO
1213                ENDDO
1214             ENDDO
1215!
1216!--       scalar concentration
1217          CASE ( 7 )
1218             DO  i = nxl, nxr
1219                DO  j = nys, nyn
1220                   DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
1221                      kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
1222                      tend(k,j,i) = tend(k,j,i) -                              &
1223                                       lsec *                                  &
1224                                       lad_s(kk,j,i) *                         &
1225                                       SQRT( ( 0.5_wp * ( u(k,j,i) +           &
1226                                                          u(k,j,i+1) )         &
1227                                             )**2 +                            &
1228                                             ( 0.5_wp * ( v(k,j,i) +           &
1229                                                          v(k,j+1,i) )         &
1230                                             )**2 +                            &
1231                                             ( 0.5_wp * ( w(k-1,j,i) +         & 
1232                                                          w(k,j,i) )           &
1233                                             )**2                              &
1234                                           ) *                                 &
1235                                       ( s(k,j,i) - lsc )
1236                   ENDDO
1237                ENDDO
1238             ENDDO   
1239
1240
1241
1242          CASE DEFAULT
1243
1244             WRITE( message_string, * ) 'wrong component: ', component
1245             CALL message( 'pcm_tendency', 'PA0279', 1, 2, 0, 6, 0 ) 
1246
1247       END SELECT
1248
1249    END SUBROUTINE pcm_tendency
1250
1251
1252!------------------------------------------------------------------------------!
1253! Description:
1254! ------------
1255!> Calculation of the tendency terms, accounting for the effect of the plant
1256!> canopy on momentum and scalar quantities.
1257!>
1258!> The canopy is located where the leaf area density lad_s(k,j,i) > 0.0
1259!> (defined on scalar grid), as initialized in subroutine pcm_init.
1260!> The lad on the w-grid is vertically interpolated from the surrounding
1261!> lad_s. The upper boundary of the canopy is defined on the w-grid at
1262!> k = pch_index. Here, the lad is zero.
1263!>
1264!> The canopy drag must be limited (previously accounted for by calculation of
1265!> a limiting canopy timestep for the determination of the maximum LES timestep
1266!> in subroutine timestep), since it is physically impossible that the canopy
1267!> drag alone can locally change the sign of a velocity component. This
1268!> limitation is realized by calculating preliminary tendencies and velocities.
1269!> It is subsequently checked if the preliminary new velocity has a different
1270!> sign than the current velocity. If so, the tendency is limited in a way that
1271!> the velocity can at maximum be reduced to zero by the canopy drag.
1272!>
1273!>
1274!> Call for grid point i,j
1275!------------------------------------------------------------------------------!
1276    SUBROUTINE pcm_tendency_ij( i, j, component )
1277
1278
1279       USE control_parameters,                                                 &
1280           ONLY:  dt_3d, message_string
1281
1282       USE kinds
1283
1284       IMPLICIT NONE
1285
1286       INTEGER(iwp) ::  component !< prognostic variable (u,v,w,pt,q,e)
1287       INTEGER(iwp) ::  i         !< running index
1288       INTEGER(iwp) ::  j         !< running index
1289       INTEGER(iwp) ::  k         !< running index
1290       INTEGER(iwp) ::  kk        !< running index for flat lad arrays
1291
1292       REAL(wp) ::  ddt_3d    !< inverse of the LES timestep (dt_3d)
1293       REAL(wp) ::  lad_local !< local lad value
1294       REAL(wp) ::  pre_tend  !< preliminary tendency
1295       REAL(wp) ::  pre_u     !< preliminary u-value
1296       REAL(wp) ::  pre_v     !< preliminary v-value
1297       REAL(wp) ::  pre_w     !< preliminary w-value
1298
1299
1300       ddt_3d = 1.0_wp / dt_3d
1301
1302!
1303!--    Compute drag for the three velocity components and the SGS-TKE
1304       SELECT CASE ( component )
1305
1306!
1307!--       u-component
1308          CASE ( 1 )
1309             DO  k = nzb_u_inner(j,i)+1, nzb_u_inner(j,i)+pch_index
1310
1311                kk = k - nzb_u_inner(j,i)  !- lad arrays are defined flat
1312!
1313!--             In order to create sharp boundaries of the plant canopy,
1314!--             the lad on the u-grid at index (k,j,i) is equal to lad_s(k,j,i),
1315!--             rather than being interpolated from the surrounding lad_s,
1316!--             because this would yield smaller lad at the canopy boundaries
1317!--             than inside of the canopy.
1318!--             For the same reason, the lad at the rightmost(i+1)canopy
1319!--             boundary on the u-grid equals lad_s(k,j,i).
1320                lad_local = lad_s(kk,j,i)
1321                IF ( lad_local == 0.0_wp .AND. lad_s(kk,j,i-1) > 0.0_wp )  THEN
1322                   lad_local = lad_s(kk,j,i-1)
1323                ENDIF
1324
1325                pre_tend = 0.0_wp
1326                pre_u = 0.0_wp
1327!
1328!--             Calculate preliminary value (pre_tend) of the tendency
1329                pre_tend = - cdc *                                             &
1330                             lad_local *                                       &   
1331                             SQRT( u(k,j,i)**2 +                               &
1332                                   ( 0.25_wp * ( v(k,j,i-1)  +                 &
1333                                                 v(k,j,i)    +                 &
1334                                                 v(k,j+1,i)  +                 &
1335                                                 v(k,j+1,i-1) )                &
1336                                   )**2 +                                      &
1337                                   ( 0.25_wp * ( w(k-1,j,i-1) +                &
1338                                                 w(k-1,j,i)   +                &
1339                                                 w(k,j,i-1)   +                &
1340                                                 w(k,j,i) )                    &
1341                                   )**2                                        &
1342                                 ) *                                           &
1343                             u(k,j,i)
1344
1345!
1346!--             Calculate preliminary new velocity, based on pre_tend
1347                pre_u = u(k,j,i) + dt_3d * pre_tend
1348!
1349!--             Compare sign of old velocity and new preliminary velocity,
1350!--             and in case the signs are different, limit the tendency
1351                IF ( SIGN(pre_u,u(k,j,i)) /= pre_u )  THEN
1352                   pre_tend = - u(k,j,i) * ddt_3d
1353                ELSE
1354                   pre_tend = pre_tend
1355                ENDIF
1356!
1357!--             Calculate final tendency
1358                tend(k,j,i) = tend(k,j,i) + pre_tend
1359             ENDDO
1360
1361
1362!
1363!--       v-component
1364          CASE ( 2 )
1365             DO  k = nzb_v_inner(j,i)+1, nzb_v_inner(j,i)+pch_index
1366
1367                kk = k - nzb_v_inner(j,i)  !- lad arrays are defined flat
1368!
1369!--             In order to create sharp boundaries of the plant canopy,
1370!--             the lad on the v-grid at index (k,j,i) is equal to lad_s(k,j,i),
1371!--             rather than being interpolated from the surrounding lad_s,
1372!--             because this would yield smaller lad at the canopy boundaries
1373!--             than inside of the canopy.
1374!--             For the same reason, the lad at the northmost(j+1)canopy
1375!--             boundary on the v-grid equals lad_s(k,j,i).
1376                lad_local = lad_s(kk,j,i)
1377                IF ( lad_local == 0.0_wp .AND. lad_s(kk,j-1,i) > 0.0_wp )  THEN
1378                   lad_local = lad_s(kk,j-1,i)
1379                ENDIF
1380
1381                pre_tend = 0.0_wp
1382                pre_v = 0.0_wp
1383!
1384!--             Calculate preliminary value (pre_tend) of the tendency
1385                pre_tend = - cdc *                                             &
1386                             lad_local *                                       &
1387                             SQRT( ( 0.25_wp * ( u(k,j-1,i)   +                &
1388                                                 u(k,j-1,i+1) +                &
1389                                                 u(k,j,i)     +                &
1390                                                 u(k,j,i+1) )                  &
1391                                   )**2 +                                      &
1392                                   v(k,j,i)**2 +                               &
1393                                   ( 0.25_wp * ( w(k-1,j-1,i) +                &
1394                                                 w(k-1,j,i)   +                &
1395                                                 w(k,j-1,i)   +                &
1396                                                 w(k,j,i) )                    &
1397                                   )**2                                        &
1398                                 ) *                                           &
1399                             v(k,j,i)
1400
1401!
1402!--             Calculate preliminary new velocity, based on pre_tend
1403                pre_v = v(k,j,i) + dt_3d * pre_tend
1404!
1405!--             Compare sign of old velocity and new preliminary velocity,
1406!--             and in case the signs are different, limit the tendency
1407                IF ( SIGN(pre_v,v(k,j,i)) /= pre_v )  THEN
1408                   pre_tend = - v(k,j,i) * ddt_3d
1409                ELSE
1410                   pre_tend = pre_tend
1411                ENDIF
1412!
1413!--             Calculate final tendency
1414                tend(k,j,i) = tend(k,j,i) + pre_tend
1415             ENDDO
1416
1417
1418!
1419!--       w-component
1420          CASE ( 3 )
1421             DO  k = nzb_w_inner(j,i)+1, nzb_w_inner(j,i)+pch_index-1
1422
1423                kk = k - nzb_w_inner(j,i)  !- lad arrays are defined flat
1424
1425                pre_tend = 0.0_wp
1426                pre_w = 0.0_wp
1427!
1428!--             Calculate preliminary value (pre_tend) of the tendency
1429                pre_tend = - cdc *                                             &
1430                             (0.5_wp *                                         &
1431                                ( lad_s(kk+1,j,i) + lad_s(kk,j,i) )) *         &
1432                             SQRT( ( 0.25_wp * ( u(k,j,i)    +                 & 
1433                                                 u(k,j,i+1)  +                 &
1434                                                 u(k+1,j,i)  +                 &
1435                                                 u(k+1,j,i+1) )                &
1436                                   )**2 +                                      &
1437                                   ( 0.25_wp * ( v(k,j,i)    +                 &
1438                                                 v(k,j+1,i)  +                 &
1439                                                 v(k+1,j,i)  +                 &
1440                                                 v(k+1,j+1,i) )                &
1441                                   )**2 +                                      &
1442                                   w(k,j,i)**2                                 &
1443                                 ) *                                           &
1444                             w(k,j,i)
1445!
1446!--             Calculate preliminary new velocity, based on pre_tend
1447                pre_w = w(k,j,i) + dt_3d * pre_tend
1448!
1449!--             Compare sign of old velocity and new preliminary velocity,
1450!--             and in case the signs are different, limit the tendency
1451                IF ( SIGN(pre_w,w(k,j,i)) /= pre_w )  THEN
1452                   pre_tend = - w(k,j,i) * ddt_3d
1453                ELSE
1454                   pre_tend = pre_tend
1455                ENDIF
1456!
1457!--             Calculate final tendency
1458                tend(k,j,i) = tend(k,j,i) + pre_tend
1459             ENDDO
1460
1461!
1462!--       potential temperature
1463          CASE ( 4 )
1464             DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
1465                kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
1466                tend(k,j,i) = tend(k,j,i) + pc_heating_rate(kk,j,i)
1467             ENDDO
1468
1469
1470!
1471!--       humidity
1472          CASE ( 5 )
1473             DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
1474                kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
1475                tend(k,j,i) = tend(k,j,i) -                                    &
1476                                 lsec *                                        &
1477                                 lad_s(kk,j,i) *                               &
1478                                 SQRT( ( 0.5_wp * ( u(k,j,i) +                 &
1479                                                    u(k,j,i+1) )               &
1480                                       )**2  +                                 &
1481                                       ( 0.5_wp * ( v(k,j,i) +                 &
1482                                                    v(k,j+1,i) )               &
1483                                       )**2 +                                  &
1484                                       ( 0.5_wp * ( w(k-1,j,i) +               &
1485                                                    w(k,j,i) )                 &
1486                                       )**2                                    &
1487                                     ) *                                       &
1488                                 ( q(k,j,i) - lsc )
1489             ENDDO   
1490
1491!
1492!--       sgs-tke
1493          CASE ( 6 )
1494             DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
1495                kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
1496                tend(k,j,i) = tend(k,j,i) -                                    &
1497                                 2.0_wp * cdc *                                &
1498                                 lad_s(kk,j,i) *                               &
1499                                 SQRT( ( 0.5_wp * ( u(k,j,i) +                 &
1500                                                    u(k,j,i+1) )               &
1501                                       )**2 +                                  & 
1502                                       ( 0.5_wp * ( v(k,j,i) +                 &
1503                                                    v(k,j+1,i) )               &
1504                                       )**2 +                                  &
1505                                       ( 0.5_wp * ( w(k,j,i) +                 &
1506                                                    w(k+1,j,i) )               &
1507                                       )**2                                    &
1508                                     ) *                                       &
1509                                 e(k,j,i)
1510             ENDDO
1511             
1512!
1513!--       scalar concentration
1514          CASE ( 7 )
1515             DO  k = nzb_s_inner(j,i)+1, nzb_s_inner(j,i)+pch_index
1516                kk = k - nzb_s_inner(j,i)  !- lad arrays are defined flat
1517                tend(k,j,i) = tend(k,j,i) -                                    &
1518                                 lsec *                                        &
1519                                 lad_s(kk,j,i) *                               &
1520                                 SQRT( ( 0.5_wp * ( u(k,j,i) +                 &
1521                                                    u(k,j,i+1) )               &
1522                                       )**2  +                                 &
1523                                       ( 0.5_wp * ( v(k,j,i) +                 &
1524                                                    v(k,j+1,i) )               &
1525                                       )**2 +                                  &
1526                                       ( 0.5_wp * ( w(k-1,j,i) +               &
1527                                                    w(k,j,i) )                 &
1528                                       )**2                                    &
1529                                     ) *                                       &
1530                                 ( s(k,j,i) - lsc )
1531             ENDDO               
1532
1533       CASE DEFAULT
1534
1535          WRITE( message_string, * ) 'wrong component: ', component
1536          CALL message( 'pcm_tendency', 'PA0279', 1, 2, 0, 6, 0 ) 
1537
1538       END SELECT
1539
1540    END SUBROUTINE pcm_tendency_ij
1541
1542
1543
1544 END MODULE plant_canopy_model_mod
Note: See TracBrowser for help on using the repository browser.