source: palm/trunk/SOURCE/init_grid.f90 @ 978

Last change on this file since 978 was 978, checked in by fricke, 12 years ago

merge fricke branch back into trunk

  • Property svn:keywords set to Id
File size: 55.1 KB
Line 
1 SUBROUTINE init_grid
2
3!------------------------------------------------------------------------------!
4! Current revisions:
5! -----------------
6! Bugfix: nzb_max is set to nzt at non-cyclic lateral boundaries
7! Bugfix: Set wall_flags_0 for inflow boundary
8!
9! Former revisions:
10! -----------------
11! $Id: init_grid.f90 978 2012-08-09 08:28:32Z fricke $
12!
13! 927 2012-06-06 19:15:04Z raasch
14! Wall flags are not set for multigrid method in case of masking method
15!
16! 864 2012-03-27 15:10:33Z gryschka
17! In case of ocean and Dirichlet bottom bc for u and v dzu_mg and ddzu_pres
18! were not correctly defined for k=1.
19!
20! 861 2012-03-26 14:18:34Z suehring
21! Set wall_flags_0. The array is needed for degradation in ws-scheme near walls,
22! inflow and outflow boundaries as well as near the bottom and the top of the
23! model domain.!
24! Initialization of nzb_s_inner and nzb_w_inner.
25! gls has to be at least nbgp to do not exceed the array bounds of nzb_local
26! while setting wall_flags_0
27!
28! 843 2012-02-29 15:16:21Z gryschka
29! In case of ocean and dirichlet bc for u and v at the bottom
30! the first u-level ist defined at same height as the first w-level
31!
32! 818 2012-02-08 16:11:23Z maronga
33! Bugfix: topo_height is only required if topography is used. It is thus now
34! allocated in the topography branch
35!
36! 809 2012-01-30 13:32:58Z maronga
37! Bugfix: replaced .AND. and .NOT. with && and ! in the preprocessor directives
38!
39! 807 2012-01-25 11:53:51Z maronga
40! New cpp directive "__check" implemented which is used by check_namelist_files
41!
42! 759 2011-09-15 13:58:31Z raasch
43! Splitting of parallel I/O in blocks of PEs
44!
45! 722 2011-04-11 06:21:09Z raasch
46! Bugfix: bc_lr/ns_cyc replaced by bc_lr/ns, because variables are not yet set
47!         here
48!
49! 709 2011-03-30 09:31:40Z raasch
50! formatting adjustments
51!
52! 707 2011-03-29 11:39:40Z raasch
53! bc_lr/ns replaced by bc_lr/ns_cyc
54!
55! 667 2010-12-23 12:06:00Z suehring/gryschka
56! Definition of new array bounds nxlg, nxrg, nysg, nyng on each PE.
57! Furthermore the allocation of arrays and steering of loops is done with these
58! parameters. Call of exchange_horiz are modified.
59! In case of dirichlet bounday condition at the bottom zu(0)=0.0
60! dzu_mg has to be set explicitly for a equally spaced grid near bottom.
61! ddzu_pres added to use a equally spaced grid near bottom.
62!
63! 555 2010-09-07 07:32:53Z raasch
64! Bugfix: default setting of nzb_local for flat topography
65!
66! 274 2009-03-26 15:11:21Z heinze
67! Output of messages replaced by message handling routine.
68! new topography case 'single_street_canyon'
69!
70! 217 2008-12-09 18:00:48Z letzel
71! +topography_grid_convention
72!
73! 134 2007-11-21 07:28:38Z letzel
74! Redefine initial nzb_local as the actual total size of topography (later the
75! extent of topography in nzb_local is reduced by 1dx at the E topography walls
76! and by 1dy at the N topography walls to form the basis for nzb_s_inner);
77! for consistency redefine 'single_building' case.
78! Calculation of wall flag arrays
79!
80! 94 2007-06-01 15:25:22Z raasch
81! Grid definition for ocean version
82!
83! 75 2007-03-22 09:54:05Z raasch
84! storage of topography height arrays zu_s_inner and zw_s_inner,
85! 2nd+3rd argument removed from exchange horiz
86!
87! 19 2007-02-23 04:53:48Z raasch
88! Setting of nzt_diff
89!
90! RCS Log replace by Id keyword, revision history cleaned up
91!
92! Revision 1.17  2006/08/22 14:00:05  raasch
93! +dz_max to limit vertical stretching,
94! bugfix in index array initialization for line- or point-like topography
95! structures
96!
97! Revision 1.1  1997/08/11 06:17:45  raasch
98! Initial revision (Testversion)
99!
100!
101! Description:
102! ------------
103! Creating grid depending constants
104!------------------------------------------------------------------------------!
105
106    USE arrays_3d
107    USE control_parameters
108    USE grid_variables
109    USE indices
110    USE pegrid
111
112    IMPLICIT NONE
113
114    INTEGER ::  bh, blx, bly, bxl, bxr, byn, bys, ch, cwx, cwy, cxl, cxr, cyn, &
115                cys, gls, i, ii, inc, i_center, j, j_center, k, l, nxl_l,      &
116                nxr_l, nyn_l, nys_l, nzb_si, nzt_l, vi
117
118    INTEGER, DIMENSION(:), ALLOCATABLE   ::  vertical_influence
119
120    INTEGER, DIMENSION(:,:), ALLOCATABLE ::  corner_nl, corner_nr, corner_sl,  &
121                                             corner_sr, wall_l, wall_n, wall_r,&
122                                             wall_s, nzb_local, nzb_tmp
123
124    LOGICAL :: flag_set = .FALSE.
125
126    REAL    ::  dx_l, dy_l, dz_stretched
127
128    REAL, DIMENSION(:,:), ALLOCATABLE   ::  topo_height
129
130    REAL, DIMENSION(:,:,:), ALLOCATABLE ::  distance
131   
132!
133!-- Calculation of horizontal array bounds including ghost layers
134    nxlg = nxl - nbgp
135    nxrg = nxr + nbgp
136    nysg = nys - nbgp
137    nyng = nyn + nbgp
138
139!
140!-- Allocate grid arrays
141    ALLOCATE( ddzu(1:nzt+1), ddzw(1:nzt+1), dd2zu(1:nzt), dzu(1:nzt+1), &
142              dzw(1:nzt+1), l_grid(1:nzt), zu(nzb:nzt+1), zw(nzb:nzt+1) )
143
144!
145!-- Compute height of u-levels from constant grid length and dz stretch factors
146    IF ( dz == -1.0 )  THEN
147       message_string = 'missing dz'
148       CALL message( 'init_grid', 'PA0200', 1, 2, 0, 6, 0 ) 
149    ELSEIF ( dz <= 0.0 )  THEN
150       WRITE( message_string, * ) 'dz=',dz,' <= 0.0'
151       CALL message( 'init_grid', 'PA0201', 1, 2, 0, 6, 0 )
152    ENDIF
153
154!
155!-- Define the vertical grid levels
156    IF ( .NOT. ocean )  THEN
157!
158!--    Grid for atmosphere with surface at z=0 (k=0, w-grid).
159!--    The second u-level (k=1) corresponds to the top of the
160!--    Prandtl-layer.
161
162       IF ( ibc_uv_b == 0 .OR. ibc_uv_b == 2 ) THEN
163          zu(0) = 0.0
164      !    zu(0) = - dz * 0.5
165       ELSE
166          zu(0) = - dz * 0.5
167       ENDIF
168       zu(1) =   dz * 0.5
169
170       dz_stretch_level_index = nzt+1
171       dz_stretched = dz
172       DO  k = 2, nzt+1
173          IF ( dz_stretch_level <= zu(k-1)  .AND.  dz_stretched < dz_max )  THEN
174             dz_stretched = dz_stretched * dz_stretch_factor
175             dz_stretched = MIN( dz_stretched, dz_max )
176             IF ( dz_stretch_level_index == nzt+1 ) dz_stretch_level_index = k-1
177          ENDIF
178          zu(k) = zu(k-1) + dz_stretched
179       ENDDO
180
181!
182!--    Compute the w-levels. They are always staggered half-way between the
183!--    corresponding u-levels. In case of dirichlet bc for u and v at the
184!--    ground the first u- and w-level (k=0) are defined at same height (z=0).
185!--    The top w-level is extrapolated linearly.
186       zw(0) = 0.0
187       DO  k = 1, nzt
188          zw(k) = ( zu(k) + zu(k+1) ) * 0.5
189       ENDDO
190       zw(nzt+1) = zw(nzt) + 2.0 * ( zu(nzt+1) - zw(nzt) )
191
192    ELSE
193!
194!--    Grid for ocean with free water surface is at k=nzt (w-grid).
195!--    In case of neumann bc at the ground the first first u-level (k=0) lies
196!--    below the first w-level (k=0). In case of dirichlet bc the first u- and
197!--    w-level are defined at same height, but staggered from the second level.
198!--    The second u-level (k=1) corresponds to the top of the Prandtl-layer.
199       zu(nzt+1) =   dz * 0.5
200       zu(nzt)   = - dz * 0.5
201
202       dz_stretch_level_index = 0
203       dz_stretched = dz
204       DO  k = nzt-1, 0, -1
205          IF ( dz_stretch_level <= ABS( zu(k+1) )  .AND.  &
206               dz_stretched < dz_max )  THEN
207             dz_stretched = dz_stretched * dz_stretch_factor
208             dz_stretched = MIN( dz_stretched, dz_max )
209             IF ( dz_stretch_level_index == 0 ) dz_stretch_level_index = k+1
210          ENDIF
211          zu(k) = zu(k+1) - dz_stretched
212       ENDDO
213
214!
215!--    Compute the w-levels. They are always staggered half-way between the
216!--    corresponding u-levels, except in case of dirichlet bc for u and v
217!--    at the ground. In this case the first u- and w-level are defined at
218!--    same height. The top w-level (nzt+1) is not used but set for
219!--    consistency, since w and all scalar variables are defined up tp nzt+1.
220       zw(nzt+1) = dz
221       zw(nzt)   = 0.0
222       DO  k = 0, nzt
223          zw(k) = ( zu(k) + zu(k+1) ) * 0.5
224       ENDDO
225
226!
227!--    In case of dirichlet bc for u and v the first u- and w-level are defined
228!--    at same height.
229       IF ( ibc_uv_b == 0 ) THEN
230          zu(0) = zw(0)
231       ENDIF
232
233    ENDIF
234
235!
236!-- Compute grid lengths.
237    DO  k = 1, nzt+1
238       dzu(k)  = zu(k) - zu(k-1)
239       ddzu(k) = 1.0 / dzu(k)
240       dzw(k)  = zw(k) - zw(k-1)
241       ddzw(k) = 1.0 / dzw(k)
242    ENDDO
243
244    DO  k = 1, nzt
245       dd2zu(k) = 1.0 / ( dzu(k) + dzu(k+1) )
246    ENDDO
247   
248!   
249!-- The FFT- SOR-pressure solvers assume grid spacings of a staggered grid
250!-- everywhere. For the actual grid, the grid spacing at the lowest level
251!-- is only dz/2, but should be dz. Therefore, an additional array
252!-- containing with appropriate grid information is created for these
253!-- solvers.
254    IF ( psolver /= 'multigrid' )  THEN
255       ALLOCATE( ddzu_pres(1:nzt+1) )
256       ddzu_pres = ddzu
257       ddzu_pres(1) = ddzu_pres(2)  ! change for lowest level
258    ENDIF   
259
260!
261!-- In case of multigrid method, compute grid lengths and grid factors for the
262!-- grid levels
263    IF ( psolver == 'multigrid' )  THEN
264
265       ALLOCATE( ddx2_mg(maximum_grid_level), ddy2_mg(maximum_grid_level), &
266                 dzu_mg(nzb+1:nzt+1,maximum_grid_level),                   &
267                 dzw_mg(nzb+1:nzt+1,maximum_grid_level),                   &
268                 f1_mg(nzb+1:nzt,maximum_grid_level),                      &
269                 f2_mg(nzb+1:nzt,maximum_grid_level),                      &
270                 f3_mg(nzb+1:nzt,maximum_grid_level) )
271
272       dzu_mg(:,maximum_grid_level) = dzu
273!       
274!--    Next line to ensure an equally spaced grid.
275       dzu_mg(1,maximum_grid_level) = dzu(2)
276
277       dzw_mg(:,maximum_grid_level) = dzw
278       nzt_l = nzt
279       DO  l = maximum_grid_level-1, 1, -1
280           dzu_mg(nzb+1,l) = 2.0 * dzu_mg(nzb+1,l+1)
281           dzw_mg(nzb+1,l) = 2.0 * dzw_mg(nzb+1,l+1)
282           nzt_l = nzt_l / 2
283           DO  k = 2, nzt_l+1
284              dzu_mg(k,l) = dzu_mg(2*k-2,l+1) + dzu_mg(2*k-1,l+1)
285              dzw_mg(k,l) = dzw_mg(2*k-2,l+1) + dzw_mg(2*k-1,l+1)
286           ENDDO
287       ENDDO
288
289       nzt_l = nzt
290       dx_l  = dx
291       dy_l  = dy
292       DO  l = maximum_grid_level, 1, -1
293          ddx2_mg(l) = 1.0 / dx_l**2
294          ddy2_mg(l) = 1.0 / dy_l**2
295          DO  k = nzb+1, nzt_l
296             f2_mg(k,l) = 1.0 / ( dzu_mg(k+1,l) * dzw_mg(k,l) )
297             f3_mg(k,l) = 1.0 / ( dzu_mg(k,l)   * dzw_mg(k,l) )
298             f1_mg(k,l) = 2.0 * ( ddx2_mg(l) + ddy2_mg(l) ) + &
299                          f2_mg(k,l) + f3_mg(k,l)
300          ENDDO
301          nzt_l = nzt_l / 2
302          dx_l  = dx_l * 2.0
303          dy_l  = dy_l * 2.0
304       ENDDO
305
306    ENDIF
307
308!
309!-- Compute the reciprocal values of the horizontal grid lengths.
310    ddx = 1.0 / dx
311    ddy = 1.0 / dy
312    dx2 = dx * dx
313    dy2 = dy * dy
314    ddx2 = 1.0 / dx2
315    ddy2 = 1.0 / dy2
316
317!
318!-- Compute the grid-dependent mixing length.
319    DO  k = 1, nzt
320       l_grid(k)  = ( dx * dy * dzw(k) )**0.33333333333333
321    ENDDO
322
323!
324!-- Allocate outer and inner index arrays for topography and set
325!-- defaults.
326!-- nzb_local has to contain additional layers of ghost points for calculating
327!-- the flag arrays needed for the multigrid method
328    gls = 2**( maximum_grid_level )
329    IF ( gls < nbgp )  gls = nbgp
330
331    ALLOCATE( corner_nl(nys:nyn,nxl:nxr), corner_nr(nys:nyn,nxl:nxr),       &
332              corner_sl(nys:nyn,nxl:nxr), corner_sr(nys:nyn,nxl:nxr),       &
333              nzb_local(-gls:ny+gls,-gls:nx+gls),                                   &
334              nzb_tmp(-nbgp:ny+nbgp,-nbgp:nx+nbgp),                         &
335              wall_l(nys:nyn,nxl:nxr), wall_n(nys:nyn,nxl:nxr),             &
336              wall_r(nys:nyn,nxl:nxr), wall_s(nys:nyn,nxl:nxr) )
337    ALLOCATE( fwxm(nysg:nyng,nxlg:nxrg), fwxp(nysg:nyng,nxlg:nxrg),         &
338              fwym(nysg:nyng,nxlg:nxrg), fwyp(nysg:nyng,nxlg:nxrg),         &
339              fxm(nysg:nyng,nxlg:nxrg), fxp(nysg:nyng,nxlg:nxrg),           &
340              fym(nysg:nyng,nxlg:nxrg), fyp(nysg:nyng,nxlg:nxrg),           &
341              nzb_s_inner(nysg:nyng,nxlg:nxrg),                             &
342              nzb_s_outer(nysg:nyng,nxlg:nxrg),                             &
343              nzb_u_inner(nysg:nyng,nxlg:nxrg),                             &
344              nzb_u_outer(nysg:nyng,nxlg:nxrg),                             &
345              nzb_v_inner(nysg:nyng,nxlg:nxrg),                             &
346              nzb_v_outer(nysg:nyng,nxlg:nxrg),                             &
347              nzb_w_inner(nysg:nyng,nxlg:nxrg),                             &
348              nzb_w_outer(nysg:nyng,nxlg:nxrg),                             &
349              nzb_diff_s_inner(nysg:nyng,nxlg:nxrg),                        &
350              nzb_diff_s_outer(nysg:nyng,nxlg:nxrg),                        &
351              nzb_diff_u(nysg:nyng,nxlg:nxrg),                              &
352              nzb_diff_v(nysg:nyng,nxlg:nxrg),                              &
353              nzb_2d(nysg:nyng,nxlg:nxrg),                                  &
354              wall_e_x(nysg:nyng,nxlg:nxrg),                                &
355              wall_e_y(nysg:nyng,nxlg:nxrg),                                &
356              wall_u(nysg:nyng,nxlg:nxrg),                                  &
357              wall_v(nysg:nyng,nxlg:nxrg),                                  &
358              wall_w_x(nysg:nyng,nxlg:nxrg),                                &
359              wall_w_y(nysg:nyng,nxlg:nxrg) )
360
361
362
363    ALLOCATE( l_wall(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
364
365
366    nzb_s_inner = nzb;  nzb_s_outer = nzb
367    nzb_u_inner = nzb;  nzb_u_outer = nzb
368    nzb_v_inner = nzb;  nzb_v_outer = nzb
369    nzb_w_inner = nzb;  nzb_w_outer = nzb
370
371!
372!-- Define vertical gridpoint from (or to) which on the usual finite difference
373!-- form (which does not use surface fluxes) is applied
374    IF ( prandtl_layer  .OR.  use_surface_fluxes )  THEN
375       nzb_diff = nzb + 2
376    ELSE
377       nzb_diff = nzb + 1
378    ENDIF
379    IF ( use_top_fluxes )  THEN
380       nzt_diff = nzt - 1
381    ELSE
382       nzt_diff = nzt
383    ENDIF
384
385    nzb_diff_s_inner = nzb_diff;  nzb_diff_s_outer = nzb_diff
386    nzb_diff_u = nzb_diff;  nzb_diff_v = nzb_diff
387
388    wall_e_x = 0.0;  wall_e_y = 0.0;  wall_u = 0.0;  wall_v = 0.0
389    wall_w_x = 0.0;  wall_w_y = 0.0
390    fwxp = 1.0;  fwxm = 1.0;  fwyp = 1.0;  fwym = 1.0
391    fxp  = 1.0;  fxm  = 1.0;  fyp  = 1.0;  fym  = 1.0
392
393!
394!-- Initialize near-wall mixing length l_wall only in the vertical direction
395!-- for the moment,
396!-- multiplication with wall_adjustment_factor near the end of this routine
397    l_wall(nzb,:,:)   = l_grid(1)
398    DO  k = nzb+1, nzt
399       l_wall(k,:,:)  = l_grid(k)
400    ENDDO
401    l_wall(nzt+1,:,:) = l_grid(nzt)
402
403    ALLOCATE ( vertical_influence(nzb:nzt) )
404    DO  k = 1, nzt
405       vertical_influence(k) = MIN ( INT( l_grid(k) / &
406                     ( wall_adjustment_factor * dzw(k) ) + 0.5 ), nzt - k )
407    ENDDO
408
409    DO  k = 1, MAXVAL( nzb_s_inner )
410       IF ( l_grid(k) > 1.5 * dx * wall_adjustment_factor .OR.  &
411            l_grid(k) > 1.5 * dy * wall_adjustment_factor )  THEN
412          WRITE( message_string, * ) 'grid anisotropy exceeds ', &
413                                     'threshold given by only local', &
414                                     ' &horizontal reduction of near_wall ', &
415                                     'mixing length l_wall', &
416                                     ' &starting from height level k = ', k, '.'
417          CALL message( 'init_grid', 'PA0202', 0, 1, 0, 6, 0 )
418          EXIT
419       ENDIF
420    ENDDO
421    vertical_influence(0) = vertical_influence(1)
422
423    DO  i = nxlg, nxrg
424       DO  j = nysg, nyng
425          DO  k = nzb_s_inner(j,i) + 1, &
426                  nzb_s_inner(j,i) + vertical_influence(nzb_s_inner(j,i))
427             l_wall(k,j,i) = zu(k) - zw(nzb_s_inner(j,i))
428          ENDDO
429       ENDDO
430    ENDDO
431
432!
433!-- Set outer and inner index arrays for non-flat topography.
434!-- Here consistency checks concerning domain size and periodicity are
435!-- necessary.
436!-- Within this SELECT CASE structure only nzb_local is initialized
437!-- individually depending on the chosen topography type, all other index
438!-- arrays are initialized further below.
439    SELECT CASE ( TRIM( topography ) )
440
441       CASE ( 'flat' )
442!
443!--       nzb_local is required for the multigrid solver
444          nzb_local = 0
445
446       CASE ( 'single_building' )
447!
448!--       Single rectangular building, by default centered in the middle of the
449!--       total domain
450          blx = NINT( building_length_x / dx )
451          bly = NINT( building_length_y / dy )
452          bh  = NINT( building_height / dz )
453
454          IF ( building_wall_left == 9999999.9 )  THEN
455             building_wall_left = ( nx + 1 - blx ) / 2 * dx
456          ENDIF
457          bxl = NINT( building_wall_left / dx )
458          bxr = bxl + blx
459
460          IF ( building_wall_south == 9999999.9 )  THEN
461             building_wall_south = ( ny + 1 - bly ) / 2 * dy
462          ENDIF
463          bys = NINT( building_wall_south / dy )
464          byn = bys + bly
465
466!
467!--       Building size has to meet some requirements
468          IF ( ( bxl < 1 ) .OR. ( bxr > nx-1 ) .OR. ( bxr < bxl+3 ) .OR.  &
469               ( bys < 1 ) .OR. ( byn > ny-1 ) .OR. ( byn < bys+3 ) )  THEN
470             WRITE( message_string, * ) 'inconsistent building parameters:',   &
471                                      '& bxl=', bxl, 'bxr=', bxr, 'bys=', bys, &
472                                      'byn=', byn, 'nx=', nx, 'ny=', ny
473             CALL message( 'init_grid', 'PA0203', 1, 2, 0, 6, 0 )
474          ENDIF
475
476!
477!--       Define the building.
478          nzb_local = 0
479          nzb_local(bys:byn,bxl:bxr) = bh
480
481       CASE ( 'single_street_canyon' )
482!
483!--       Single quasi-2D street canyon of infinite length in x or y direction.
484!--       The canyon is centered in the other direction by default.
485          IF ( canyon_width_x /= 9999999.9 )  THEN
486!
487!--          Street canyon in y direction
488             cwx = NINT( canyon_width_x / dx )
489             IF ( canyon_wall_left == 9999999.9 )  THEN
490                canyon_wall_left = ( nx + 1 - cwx ) / 2 * dx
491             ENDIF
492             cxl = NINT( canyon_wall_left / dx )
493             cxr = cxl + cwx
494
495          ELSEIF ( canyon_width_y /= 9999999.9 )  THEN
496!
497!--          Street canyon in x direction
498             cwy = NINT( canyon_width_y / dy )
499             IF ( canyon_wall_south == 9999999.9 )  THEN
500                canyon_wall_south = ( ny + 1 - cwy ) / 2 * dy
501             ENDIF
502             cys = NINT( canyon_wall_south / dy )
503             cyn = cys + cwy
504
505          ELSE
506             
507             message_string = 'no street canyon width given'
508             CALL message( 'init_grid', 'PA0204', 1, 2, 0, 6, 0 )
509 
510          ENDIF
511
512          ch             = NINT( canyon_height / dz )
513          dp_level_ind_b = ch
514!
515!--       Street canyon size has to meet some requirements
516          IF ( canyon_width_x /= 9999999.9 )  THEN
517             IF ( ( cxl < 1 ) .OR. ( cxr > nx-1 ) .OR. ( cwx < 3 ) .OR.  &
518               ( ch < 3 ) )  THEN
519                WRITE( message_string, * ) 'inconsistent canyon parameters:', &
520                                           '&cxl=', cxl, 'cxr=', cxr,         &
521                                           'cwx=', cwx,                       &
522                                           'ch=', ch, 'nx=', nx, 'ny=', ny
523                CALL message( 'init_grid', 'PA0205', 1, 2, 0, 6, 0 ) 
524             ENDIF
525          ELSEIF ( canyon_width_y /= 9999999.9 )  THEN
526             IF ( ( cys < 1 ) .OR. ( cyn > ny-1 ) .OR. ( cwy < 3 ) .OR.  &
527               ( ch < 3 ) )  THEN
528                WRITE( message_string, * ) 'inconsistent canyon parameters:', &
529                                           '&cys=', cys, 'cyn=', cyn,         &
530                                           'cwy=', cwy,                       &
531                                           'ch=', ch, 'nx=', nx, 'ny=', ny
532                CALL message( 'init_grid', 'PA0206', 1, 2, 0, 6, 0 ) 
533             ENDIF
534          ENDIF
535          IF ( canyon_width_x /= 9999999.9 .AND. canyon_width_y /= 9999999.9 ) &
536               THEN
537             message_string = 'inconsistent canyon parameters:' //     & 
538                              '&street canyon can only be oriented' // &
539                              '&either in x- or in y-direction'
540             CALL message( 'init_grid', 'PA0207', 1, 2, 0, 6, 0 )
541          ENDIF
542
543          nzb_local = ch
544          IF ( canyon_width_x /= 9999999.9 )  THEN
545             nzb_local(:,cxl+1:cxr-1) = 0
546          ELSEIF ( canyon_width_y /= 9999999.9 )  THEN
547             nzb_local(cys+1:cyn-1,:) = 0
548          ENDIF
549
550       CASE ( 'read_from_file' )
551
552          ALLOCATE ( topo_height(0:ny,0:nx) )
553
554          DO  ii = 0, io_blocks-1
555             IF ( ii == io_group )  THEN
556
557!
558!--             Arbitrary irregular topography data in PALM format (exactly
559!--             matching the grid size and total domain size)
560                OPEN( 90, FILE='TOPOGRAPHY_DATA', STATUS='OLD', &
561                      FORM='FORMATTED', ERR=10 )
562                DO  j = ny, 0, -1
563                   READ( 90, *, ERR=11, END=11 )  ( topo_height(j,i), i = 0,nx )
564                ENDDO
565
566                GOTO 12
567         
568 10             message_string = 'file TOPOGRAPHY_DATA does not exist'
569                CALL message( 'init_grid', 'PA0208', 1, 2, 0, 6, 0 )
570
571 11             message_string = 'errors in file TOPOGRAPHY_DATA'
572                CALL message( 'init_grid', 'PA0209', 1, 2, 0, 6, 0 )
573
574 12             CLOSE( 90 )
575
576             ENDIF
577#if defined( __parallel ) && ! defined ( __check )
578             CALL MPI_BARRIER( comm2d, ierr )
579#endif
580          ENDDO
581
582!
583!--       Calculate the index height of the topography
584          DO  i = 0, nx
585             DO  j = 0, ny
586                nzb_local(j,i) = NINT( topo_height(j,i) / dz )
587             ENDDO
588          ENDDO
589
590          DEALLOCATE ( topo_height )
591!
592!--       Add cyclic boundaries (additional layers are for calculating
593!--       flag arrays needed for the multigrid sover)
594          nzb_local(-gls:-1,0:nx)     = nzb_local(ny-gls+1:ny,0:nx)
595          nzb_local(ny+1:ny+gls,0:nx) = nzb_local(0:gls-1,0:nx)
596          nzb_local(:,-gls:-1)        = nzb_local(:,nx-gls+1:nx)
597          nzb_local(:,nx+1:nx+gls)    = nzb_local(:,0:gls-1)
598
599       CASE DEFAULT
600!
601!--       The DEFAULT case is reached either if the parameter topography
602!--       contains a wrong character string or if the user has defined a special
603!--       case in the user interface. There, the subroutine user_init_grid
604!--       checks which of these two conditions applies.
605          CALL user_init_grid( gls, nzb_local )
606
607    END SELECT
608!
609!-- Determine the maximum level of topography. Furthermore it is used for
610!-- steering the degradation of order of the applied advection scheme.
611!-- In case of non-cyclic lateral boundaries, the order of the advection
612!-- scheme is reduced at the lateral boundaries up to nzt.
613    nzb_max = MAXVAL( nzb_local )
614    IF ( inflow_l .OR. outflow_l .OR. inflow_r .OR. outflow_r .OR.    &
615         inflow_n .OR. outflow_n .OR. inflow_s .OR. outflow_s )  THEN
616         nzb_max = nzt
617    ENDIF
618
619!
620!-- Consistency checks and index array initialization are only required for
621!-- non-flat topography, also the initialization of topography height arrays
622!-- zu_s_inner and zw_w_inner
623    IF ( TRIM( topography ) /= 'flat' )  THEN
624
625!
626!--    Consistency checks
627       IF ( MINVAL( nzb_local ) < 0  .OR.  MAXVAL( nzb_local ) > nz + 1 )  THEN
628          WRITE( message_string, * ) 'nzb_local values are outside the',      &
629                                'model domain',                               &
630                                '&MINVAL( nzb_local ) = ', MINVAL(nzb_local), &
631                                '&MAXVAL( nzb_local ) = ', MAXVAL(nzb_local)
632          CALL message( 'init_grid', 'PA0210', 1, 2, 0, 6, 0 )
633       ENDIF
634
635       IF ( bc_lr == 'cyclic' )  THEN
636          IF ( ANY( nzb_local(:,-1) /= nzb_local(:,nx)   )  .OR. &
637               ANY( nzb_local(:,0)  /= nzb_local(:,nx+1) ) )  THEN
638             message_string = 'nzb_local does not fulfill cyclic' // &
639                              ' boundary condition in x-direction'
640             CALL message( 'init_grid', 'PA0211', 1, 2, 0, 6, 0 )
641          ENDIF
642       ENDIF
643       IF ( bc_ns == 'cyclic' )  THEN
644          IF ( ANY( nzb_local(-1,:) /= nzb_local(ny,:)   )  .OR. &
645               ANY( nzb_local(0,:)  /= nzb_local(ny+1,:) ) )  THEN
646             message_string = 'nzb_local does not fulfill cyclic' // &
647                              ' boundary condition in y-direction'
648             CALL message( 'init_grid', 'PA0212', 1, 2, 0, 6, 0 )
649          ENDIF
650       ENDIF
651
652       IF ( topography_grid_convention == 'cell_edge' )  THEN
653!
654!--       The array nzb_local as defined using the 'cell_edge' convention
655!--       describes the actual total size of topography which is defined at the
656!--       cell edges where u=0 on the topography walls in x-direction and v=0
657!--       on the topography walls in y-direction. However, PALM uses individual
658!--       arrays nzb_u|v|w|s_inner|outer that are based on nzb_s_inner.
659!--       Therefore, the extent of topography in nzb_local is now reduced by
660!--       1dx at the E topography walls and by 1dy at the N topography walls
661!--       to form the basis for nzb_s_inner.
662          DO  j = -gls, ny + gls
663             DO  i = -gls, nx
664                nzb_local(j,i) = MIN( nzb_local(j,i), nzb_local(j,i+1) )
665             ENDDO
666          ENDDO
667!--       apply cyclic boundary conditions in x-direction
668!(ist das erforderlich? Ursache von Seung Bus Fehler?)
669          nzb_local(:,nx+1:nx+gls) = nzb_local(:,0:gls-1)
670          DO  i = -gls, nx + gls
671             DO  j = -gls, ny
672                nzb_local(j,i) = MIN( nzb_local(j,i), nzb_local(j+1,i) )
673             ENDDO
674          ENDDO
675!--       apply cyclic boundary conditions in y-direction
676!(ist das erforderlich? Ursache von Seung Bus Fehler?)
677          nzb_local(ny+1:ny+gls,:) = nzb_local(0:gls-1,:)
678       ENDIF
679
680!
681!--    Initialize index arrays nzb_s_inner and nzb_w_inner
682       nzb_s_inner = nzb_local(nysg:nyng,nxlg:nxrg)
683       nzb_w_inner = nzb_local(nysg:nyng,nxlg:nxrg)
684
685!
686!--    Initialize remaining index arrays:
687!--    first pre-initialize them with nzb_s_inner...
688       nzb_u_inner = nzb_s_inner
689       nzb_u_outer = nzb_s_inner
690       nzb_v_inner = nzb_s_inner
691       nzb_v_outer = nzb_s_inner
692       nzb_w_outer = nzb_s_inner
693       nzb_s_outer = nzb_s_inner
694
695!
696!--    ...then extend pre-initialized arrays in their according directions
697!--    based on nzb_local using nzb_tmp as a temporary global index array
698
699!
700!--    nzb_s_outer:
701!--    extend nzb_local east-/westwards first, then north-/southwards
702       nzb_tmp = nzb_local(-nbgp:ny+nbgp,-nbgp:nx+nbgp)
703       DO  j = -1, ny + 1
704          DO  i = 0, nx
705             nzb_tmp(j,i) = MAX( nzb_local(j,i-1), nzb_local(j,i), &
706                                 nzb_local(j,i+1) )
707          ENDDO
708       ENDDO
709       DO  i = nxl, nxr
710          DO  j = nys, nyn
711             nzb_s_outer(j,i) = MAX( nzb_tmp(j-1,i), nzb_tmp(j,i), &
712                                     nzb_tmp(j+1,i) )
713          ENDDO
714!
715!--       non-cyclic boundary conditions (overwritten by call of
716!--       exchange_horiz_2d_int below in case of cyclic boundary conditions)
717          IF ( nys == 0 )  THEN
718             j = -1
719             nzb_s_outer(j,i) = MAX( nzb_tmp(j+1,i), nzb_tmp(j,i) )
720          ENDIF
721          IF ( nys == ny )  THEN
722             j = ny + 1
723             nzb_s_outer(j,i) = MAX( nzb_tmp(j-1,i), nzb_tmp(j,i) )
724          ENDIF
725       ENDDO
726!
727!--    nzb_w_outer:
728!--    identical to nzb_s_outer
729       nzb_w_outer = nzb_s_outer
730
731!
732!--    nzb_u_inner:
733!--    extend nzb_local rightwards only
734       nzb_tmp = nzb_local(-nbgp:ny+nbgp,-nbgp:nx+nbgp)
735       DO  j = -1, ny + 1
736          DO  i = 0, nx + 1
737             nzb_tmp(j,i) = MAX( nzb_local(j,i-1), nzb_local(j,i) )
738          ENDDO
739       ENDDO
740       nzb_u_inner = nzb_tmp(nysg:nyng,nxlg:nxrg)
741
742!
743!--    nzb_u_outer:
744!--    extend current nzb_tmp (nzb_u_inner) north-/southwards
745       DO  i = nxl, nxr
746          DO  j = nys, nyn
747             nzb_u_outer(j,i) = MAX( nzb_tmp(j-1,i), nzb_tmp(j,i), &
748                                     nzb_tmp(j+1,i) )
749          ENDDO
750!
751!--       non-cyclic boundary conditions (overwritten by call of
752!--       exchange_horiz_2d_int below in case of cyclic boundary conditions)
753          IF ( nys == 0 )  THEN
754             j = -1
755             nzb_u_outer(j,i) = MAX( nzb_tmp(j+1,i), nzb_tmp(j,i) )
756          ENDIF
757          IF ( nys == ny )  THEN
758             j = ny + 1
759             nzb_u_outer(j,i) = MAX( nzb_tmp(j-1,i), nzb_tmp(j,i) )
760          ENDIF
761       ENDDO
762
763!
764!--    nzb_v_inner:
765!--    extend nzb_local northwards only
766       nzb_tmp = nzb_local(-nbgp:ny+nbgp,-nbgp:nx+nbgp)
767       DO  i = -1, nx + 1
768          DO  j = 0, ny + 1
769             nzb_tmp(j,i) = MAX( nzb_local(j-1,i), nzb_local(j,i) )
770          ENDDO
771       ENDDO
772       nzb_v_inner = nzb_tmp(nys-nbgp:nyn+nbgp,nxl-nbgp:nxr+nbgp)
773
774!
775!--    nzb_v_outer:
776!--    extend current nzb_tmp (nzb_v_inner) right-/leftwards
777       DO  j = nys, nyn
778          DO  i = nxl, nxr
779             nzb_v_outer(j,i) = MAX( nzb_tmp(j,i-1), nzb_tmp(j,i), &
780                                     nzb_tmp(j,i+1) )
781          ENDDO
782!
783!--       non-cyclic boundary conditions (overwritten by call of
784!--       exchange_horiz_2d_int below in case of cyclic boundary conditions)
785          IF ( nxl == 0 )  THEN
786             i = -1
787             nzb_v_outer(j,i) = MAX( nzb_tmp(j,i+1), nzb_tmp(j,i) )
788          ENDIF
789          IF ( nxr == nx )  THEN
790             i = nx + 1
791             nzb_v_outer(j,i) = MAX( nzb_tmp(j,i-1), nzb_tmp(j,i) )
792          ENDIF
793       ENDDO
794#if ! defined ( __check )
795!
796!--    Exchange of lateral boundary values (parallel computers) and cyclic
797!--    boundary conditions, if applicable.
798!--    Since nzb_s_inner and nzb_w_inner are derived directly from nzb_local
799!--    they do not require exchange and are not included here.
800       CALL exchange_horiz_2d_int( nzb_u_inner )
801       CALL exchange_horiz_2d_int( nzb_u_outer )
802       CALL exchange_horiz_2d_int( nzb_v_inner )
803       CALL exchange_horiz_2d_int( nzb_v_outer )
804       CALL exchange_horiz_2d_int( nzb_w_outer )
805       CALL exchange_horiz_2d_int( nzb_s_outer )
806
807!
808!--    Allocate and set the arrays containing the topography height
809       IF ( myid == 0 )  THEN
810
811          ALLOCATE( zu_s_inner(0:nx+1,0:ny+1), zw_w_inner(0:nx+1,0:ny+1) )
812
813          DO  i = 0, nx + 1
814             DO  j = 0, ny + 1
815                zu_s_inner(i,j) = zu(nzb_local(j,i))
816                zw_w_inner(i,j) = zw(nzb_local(j,i))
817             ENDDO
818          ENDDO
819         
820       ENDIF
821#endif
822    ENDIF
823
824#if ! defined ( __check )
825!
826!-- Preliminary: to be removed after completion of the topography code!
827!-- Set the former default k index arrays nzb_2d
828    nzb_2d      = nzb
829
830!
831!-- Set the individual index arrays which define the k index from which on
832!-- the usual finite difference form (which does not use surface fluxes) is
833!-- applied
834    IF ( prandtl_layer  .OR.  use_surface_fluxes )  THEN
835       nzb_diff_u         = nzb_u_inner + 2
836       nzb_diff_v         = nzb_v_inner + 2
837       nzb_diff_s_inner   = nzb_s_inner + 2
838       nzb_diff_s_outer   = nzb_s_outer + 2
839    ELSE
840       nzb_diff_u         = nzb_u_inner + 1
841       nzb_diff_v         = nzb_v_inner + 1
842       nzb_diff_s_inner   = nzb_s_inner + 1
843       nzb_diff_s_outer   = nzb_s_outer + 1
844    ENDIF
845
846!
847!-- Calculation of wall switches and factors required by diffusion_u/v.f90 and
848!-- for limitation of near-wall mixing length l_wall further below
849    corner_nl = 0
850    corner_nr = 0
851    corner_sl = 0
852    corner_sr = 0
853    wall_l    = 0
854    wall_n    = 0
855    wall_r    = 0
856    wall_s    = 0
857
858    DO  i = nxl, nxr
859       DO  j = nys, nyn
860!
861!--       u-component
862          IF ( nzb_u_outer(j,i) > nzb_u_outer(j+1,i) )  THEN
863             wall_u(j,i) = 1.0   ! north wall (location of adjacent fluid)
864             fym(j,i)    = 0.0
865             fyp(j,i)    = 1.0
866          ELSEIF ( nzb_u_outer(j,i) > nzb_u_outer(j-1,i) )  THEN
867             wall_u(j,i) = 1.0   ! south wall (location of adjacent fluid)
868             fym(j,i)    = 1.0
869             fyp(j,i)    = 0.0
870          ENDIF
871!
872!--       v-component
873          IF ( nzb_v_outer(j,i) > nzb_v_outer(j,i+1) )  THEN
874             wall_v(j,i) = 1.0   ! rigth wall (location of adjacent fluid)
875             fxm(j,i)    = 0.0
876             fxp(j,i)    = 1.0
877          ELSEIF ( nzb_v_outer(j,i) > nzb_v_outer(j,i-1) )  THEN
878             wall_v(j,i) = 1.0   ! left wall (location of adjacent fluid)
879             fxm(j,i)    = 1.0
880             fxp(j,i)    = 0.0
881          ENDIF
882!
883!--       w-component, also used for scalars, separate arrays for shear
884!--       production of tke
885          IF ( nzb_w_outer(j,i) > nzb_w_outer(j+1,i) )  THEN
886             wall_e_y(j,i) =  1.0   ! north wall (location of adjacent fluid)
887             wall_w_y(j,i) =  1.0
888             fwym(j,i)     =  0.0
889             fwyp(j,i)     =  1.0
890          ELSEIF ( nzb_w_outer(j,i) > nzb_w_outer(j-1,i) )  THEN
891             wall_e_y(j,i) = -1.0   ! south wall (location of adjacent fluid)
892             wall_w_y(j,i) =  1.0
893             fwym(j,i)     =  1.0
894             fwyp(j,i)     =  0.0
895          ENDIF
896          IF ( nzb_w_outer(j,i) > nzb_w_outer(j,i+1) )  THEN
897             wall_e_x(j,i) =  1.0   ! right wall (location of adjacent fluid)
898             wall_w_x(j,i) =  1.0
899             fwxm(j,i)     =  0.0
900             fwxp(j,i)     =  1.0
901          ELSEIF ( nzb_w_outer(j,i) > nzb_w_outer(j,i-1) )  THEN
902             wall_e_x(j,i) = -1.0   ! left wall (location of adjacent fluid)
903             wall_w_x(j,i) =  1.0
904             fwxm(j,i)     =  1.0
905             fwxp(j,i)     =  0.0
906          ENDIF
907!
908!--       Wall and corner locations inside buildings for limitation of
909!--       near-wall mixing length l_wall
910          IF ( nzb_s_inner(j,i) > nzb_s_inner(j+1,i) )  THEN
911
912             wall_n(j,i) = nzb_s_inner(j+1,i) + 1            ! North wall
913
914             IF ( nzb_s_inner(j,i) > nzb_s_inner(j,i-1) )  THEN
915                corner_nl(j,i) = MAX( nzb_s_inner(j+1,i),  & ! Northleft corner
916                                      nzb_s_inner(j,i-1) ) + 1
917             ENDIF
918
919             IF ( nzb_s_inner(j,i) > nzb_s_inner(j,i+1) )  THEN
920                corner_nr(j,i) = MAX( nzb_s_inner(j+1,i),  & ! Northright corner
921                                      nzb_s_inner(j,i+1) ) + 1
922             ENDIF
923
924          ENDIF
925
926          IF ( nzb_s_inner(j,i) > nzb_s_inner(j-1,i) )  THEN
927
928             wall_s(j,i) = nzb_s_inner(j-1,i) + 1            ! South wall
929             IF ( nzb_s_inner(j,i) > nzb_s_inner(j,i-1) )  THEN
930                corner_sl(j,i) = MAX( nzb_s_inner(j-1,i),  & ! Southleft corner
931                                      nzb_s_inner(j,i-1) ) + 1
932             ENDIF
933
934             IF ( nzb_s_inner(j,i) > nzb_s_inner(j,i+1) )  THEN
935                corner_sr(j,i) = MAX( nzb_s_inner(j-1,i),  & ! Southright corner
936                                      nzb_s_inner(j,i+1) ) + 1
937             ENDIF
938
939          ENDIF
940
941          IF ( nzb_s_inner(j,i) > nzb_s_inner(j,i-1) )  THEN
942             wall_l(j,i) = nzb_s_inner(j,i-1) + 1            ! Left wall
943          ENDIF
944
945          IF ( nzb_s_inner(j,i) > nzb_s_inner(j,i+1) )  THEN
946             wall_r(j,i) = nzb_s_inner(j,i+1) + 1            ! Right wall
947          ENDIF
948
949       ENDDO
950    ENDDO
951
952!
953!-- Calculate wall flag arrays for the multigrid method
954    IF ( psolver == 'multigrid' )  THEN
955!
956!--    Gridpoint increment of the current level
957       inc = 1
958
959       DO  l = maximum_grid_level, 1 , -1
960
961          nxl_l = nxl_mg(l)
962          nxr_l = nxr_mg(l)
963          nys_l = nys_mg(l)
964          nyn_l = nyn_mg(l)
965          nzt_l = nzt_mg(l)
966
967!
968!--       Assign the flag level to be calculated
969          SELECT CASE ( l )
970             CASE ( 1 )
971                flags => wall_flags_1
972             CASE ( 2 )
973                flags => wall_flags_2
974             CASE ( 3 )
975                flags => wall_flags_3
976             CASE ( 4 )
977                flags => wall_flags_4
978             CASE ( 5 )
979                flags => wall_flags_5
980             CASE ( 6 )
981                flags => wall_flags_6
982             CASE ( 7 )
983                flags => wall_flags_7
984             CASE ( 8 )
985                flags => wall_flags_8
986             CASE ( 9 )
987                flags => wall_flags_9
988             CASE ( 10 )
989                flags => wall_flags_10
990          END SELECT
991
992!
993!--       Depending on the grid level, set the respective bits in case of
994!--       neighbouring walls
995!--       Bit 0:  wall to the bottom
996!--       Bit 1:  wall to the top (not realized in remaining PALM code so far)
997!--       Bit 2:  wall to the south
998!--       Bit 3:  wall to the north
999!--       Bit 4:  wall to the left
1000!--       Bit 5:  wall to the right
1001!--       Bit 6:  inside building
1002
1003          flags = 0
1004
1005!
1006!--       In case of masking method, flags are not set and multigrid method
1007!--       works like FFT-solver
1008          IF ( .NOT. masking_method )  THEN
1009
1010             DO  i = nxl_l-1, nxr_l+1
1011                DO  j = nys_l-1, nyn_l+1
1012                   DO  k = nzb, nzt_l+1
1013                         
1014!
1015!--                   Inside/outside building (inside building does not need
1016!--                   further tests for walls)
1017                      IF ( k*inc <= nzb_local(j*inc,i*inc) )  THEN
1018
1019                         flags(k,j,i) = IBSET( flags(k,j,i), 6 )
1020
1021                      ELSE
1022!
1023!--                      Bottom wall
1024                         IF ( (k-1)*inc <= nzb_local(j*inc,i*inc) )  THEN
1025                            flags(k,j,i) = IBSET( flags(k,j,i), 0 )
1026                         ENDIF
1027!
1028!--                      South wall
1029                         IF ( k*inc <= nzb_local((j-1)*inc,i*inc) )  THEN
1030                            flags(k,j,i) = IBSET( flags(k,j,i), 2 )
1031                         ENDIF
1032!
1033!--                      North wall
1034                         IF ( k*inc <= nzb_local((j+1)*inc,i*inc) )  THEN
1035                            flags(k,j,i) = IBSET( flags(k,j,i), 3 )
1036                         ENDIF
1037!
1038!--                      Left wall
1039                         IF ( k*inc <= nzb_local(j*inc,(i-1)*inc) )  THEN
1040                            flags(k,j,i) = IBSET( flags(k,j,i), 4 )
1041                         ENDIF
1042!
1043!--                      Right wall
1044                         IF ( k*inc <= nzb_local(j*inc,(i+1)*inc) )  THEN
1045                            flags(k,j,i) = IBSET( flags(k,j,i), 5 )
1046                         ENDIF
1047
1048                      ENDIF
1049                           
1050                   ENDDO
1051                ENDDO
1052             ENDDO
1053
1054          ENDIF
1055
1056!
1057!--       Test output of flag arrays
1058!          i = nxl_l
1059!          WRITE (9,*)  ' '
1060!          WRITE (9,*)  '*** mg level ', l, ' ***', mg_switch_to_pe0_level
1061!          WRITE (9,*)  '    inc=', inc, '  i =', nxl_l
1062!          WRITE (9,*)  '    nxl_l',nxl_l,' nxr_l=',nxr_l,' nys_l=',nys_l,' nyn_l=',nyn_l
1063!          DO  k = nzt_l+1, nzb, -1
1064!             WRITE (9,'(194(1X,I2))')  ( flags(k,j,i), j = nys_l-1, nyn_l+1 )
1065!          ENDDO
1066
1067          inc = inc * 2
1068
1069       ENDDO
1070
1071    ENDIF
1072!
1073!-- Allocate flags needed for masking walls.
1074    ALLOCATE( wall_flags_0(nzb:nzt,nys:nyn,nxl:nxr) )
1075    wall_flags_0 = 0
1076
1077    IF ( scalar_advec == 'ws-scheme' )  THEN
1078!
1079!--    Set flags to steer the degradation of the advection scheme in advec_ws
1080!--    near topography, inflow- and outflow boundaries as well as bottom and
1081!--    top of model domain. wall_flags_0 remains zero for all non-prognostic
1082!--    grid points.
1083       DO  i = nxl, nxr
1084          DO  j = nys, nyn
1085             DO  k = nzb_s_inner(j,i)+1, nzt
1086!
1087!--             scalar - x-direction
1088!--             WS1 (0), WS3 (1), WS5 (2)
1089                IF ( k <= nzb_s_inner(j,i+1) .OR. ( ( inflow_l .OR. outflow_l )&
1090                     .AND. i == nxl ) .OR. ( ( inflow_r .OR. outflow_r )       &
1091                     .AND. i == nxr ) )  THEN
1092                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 0 )
1093                ELSEIF ( k <= nzb_s_inner(j,i+2) .OR. k <= nzb_s_inner(j,i-1)  &
1094                         .OR. ( ( inflow_r .OR. outflow_r ) .AND. i == nxr-1 ) &
1095                         .OR. ( ( inflow_l .OR. outflow_l ) .AND. i == nxlu  ) &
1096                       )  THEN
1097                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 1 )
1098                ELSE
1099                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 2 )
1100                ENDIF
1101!
1102!--             scalar - y-direction
1103!--             WS1 (3), WS3 (4), WS5 (5)
1104                IF ( k <= nzb_s_inner(j+1,i) .OR. ( ( inflow_s .OR. outflow_s )&
1105                     .AND. j == nys ) .OR. ( ( inflow_n .OR. outflow_n )       &
1106                     .AND. j == nyn ) )  THEN
1107                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 3 )
1108!--             WS3
1109                ELSEIF ( k <= nzb_s_inner(j+2,i) .OR. k <= nzb_s_inner(j-1,i)  &
1110                         .OR. ( ( inflow_s .OR. outflow_s ) .AND. j == nysv  ) &
1111                         .OR. ( ( inflow_n .OR. outflow_n ) .AND. j == nyn-1 ) &
1112                       )  THEN
1113                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 4 )
1114!--             WS5
1115                ELSE
1116                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 5 )
1117                ENDIF
1118!
1119!--             scalar - z-direction
1120!--             WS1 (6), WS3 (7), WS5 (8)
1121                flag_set = .FALSE.
1122                IF ( k == nzb_s_inner(j,i) + 1 .OR. k == nzt )  THEN
1123                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 6 )
1124                   flag_set = .TRUE.
1125                ELSEIF ( k == nzb_s_inner(j,i) + 2 .OR. k == nzt - 1 )  THEN
1126                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 7 )
1127                   flag_set = .TRUE.
1128                ELSEIF ( k > nzb_s_inner(j,i) .AND. .NOT. flag_set )  THEN
1129                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 8 )
1130                ENDIF
1131             ENDDO
1132          ENDDO
1133       ENDDO
1134    ENDIF
1135
1136    IF ( momentum_advec == 'ws-scheme' )  THEN
1137!
1138!--    Set wall_flags_0 to steer the degradation of the advection scheme in advec_ws
1139!--    near topography, inflow- and outflow boundaries as well as bottom and
1140!--    top of model domain. wall_flags_0 remains zero for all non-prognostic
1141!--    grid points.
1142       DO  i = nxl, nxr
1143          DO  j = nys, nyn
1144             DO  k = nzb_u_inner(j,i)+1, nzt
1145!
1146!--             u component - x-direction
1147!--             WS1 (9), WS3 (10), WS5 (11)
1148                IF ( k <= nzb_u_inner(j,i+1)                                  &
1149                     .OR. ( ( inflow_l .OR. outflow_l ) .AND. i == nxlu )     &
1150                     .OR. ( ( inflow_r .OR. outflow_r ) .AND. i == nxr  )     &
1151                   )  THEN
1152                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 9 )
1153                ELSEIF ( k <= nzb_u_inner(j,i+2) .OR. k <= nzb_u_inner(j,i-1) &
1154                         .OR. ( ( inflow_r .OR. outflow_r ) .AND. i == nxr-1 )&
1155                         .OR. ( ( inflow_l .OR. outflow_l ) .AND. i == nxlu+1)&
1156                       )  THEN
1157                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 10 )
1158                ELSE
1159                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 11 )
1160                ENDIF
1161
1162!
1163!--             u component - y-direction
1164!--             WS1 (12), WS3 (13), WS5 (14)
1165                IF ( k <= nzb_u_inner(j+1,i) .OR. ( ( inflow_s .OR. outflow_s )&
1166                     .AND. j == nys ) .OR. ( ( inflow_n .OR. outflow_n )       &
1167                     .AND. j == nyn ) )  THEN
1168                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 12 )
1169                ELSEIF ( k <= nzb_u_inner(j+2,i) .OR. k <= nzb_u_inner(j-1,i)  &
1170                         .OR. ( ( inflow_s .OR. outflow_s ) .AND. j == nysv  ) &
1171                         .OR. ( ( inflow_n .OR. outflow_n ) .AND. j == nyn-1 ) &
1172                       )  THEN
1173                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 13 )
1174                ELSE
1175                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 14 )
1176                ENDIF
1177!
1178!--             u component - z-direction
1179!--             WS1 (15), WS3 (16), WS5 (17)
1180                flag_set = .FALSE.
1181                IF ( k == nzb_u_inner(j,i) + 1 .OR. k == nzt )  THEN
1182                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 15 )
1183                   flag_set = .TRUE.
1184                ELSEIF ( k == nzb_u_inner(j,i) + 2 .OR. k == nzt - 1 )  THEN
1185                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 16 )
1186                   flag_set = .TRUE.
1187                ELSEIF ( k > nzb_u_inner(j,i) .AND. .NOT. flag_set )  THEN
1188                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 17 )
1189                ENDIF
1190
1191             ENDDO
1192          ENDDO
1193       ENDDO
1194
1195       DO  i = nxl, nxr
1196          DO  j = nys, nyn
1197             DO  k = nzb_v_inner(j,i)+1, nzt
1198!
1199!--             v component - x-direction
1200!--             WS1 (18), WS3 (19), WS5 (20)
1201                IF ( k <= nzb_v_inner(j,i+1) .OR. ( ( inflow_l .OR. outflow_l )&
1202                     .AND. i == nxl ) .OR. (( inflow_r .OR. outflow_r )        &
1203                     .AND. i == nxr ) )  THEN
1204                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 18 )
1205!--             WS3
1206                ELSEIF ( k <= nzb_v_inner(j,i+2) .OR. k <= nzb_v_inner(j,i-1)  &
1207                         .OR. ( ( inflow_r .OR. outflow_r ) .AND. i == nxr-1 ) &
1208                         .OR. ( ( inflow_l .OR. outflow_l ) .AND. i == nxlu  ) &
1209                       )  THEN
1210                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 19 )
1211                ELSE
1212                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 20 )
1213                ENDIF
1214!
1215!--             v component - y-direction
1216!--             WS1 (21), WS3 (22), WS5 (23)
1217                IF ( k <= nzb_v_inner(j+1,i)                                   &
1218                     .OR. ( ( inflow_s .OR. outflow_s ) .AND. i == nysv )      &
1219                     .OR. ( ( inflow_n .OR. outflow_n ) .AND. j == nyn  )      &
1220                   )  THEN
1221                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 21 )
1222                ELSEIF ( k <= nzb_v_inner(j+2,i) .OR. k <= nzb_v_inner(j-1,i)  &
1223                         .OR. ( ( inflow_s .OR. outflow_s ) .AND. j == nysv+1 )&
1224                         .OR. ( ( inflow_n .OR. outflow_n ) .AND. j == nyn-1  )&
1225                       )  THEN
1226                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 22 )
1227                ELSE
1228                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 23 )
1229                ENDIF
1230!
1231!--             v component - z-direction
1232!--             WS1 (24), WS3 (25), WS5 (26)
1233                flag_set = .FALSE.
1234                IF ( k == nzb_v_inner(j,i) + 1 .OR. k == nzt )  THEN
1235                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 24 )
1236                   flag_set = .TRUE.
1237                ELSEIF ( k == nzb_v_inner(j,i) + 2 .OR. k == nzt - 1 )  THEN
1238                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 25 )
1239                   flag_set = .TRUE.
1240                ELSEIF ( k > nzb_v_inner(j,i) .AND. .NOT. flag_set )  THEN
1241                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 26 )
1242                ENDIF
1243
1244             ENDDO
1245          ENDDO
1246       ENDDO
1247       DO  i = nxl, nxr
1248          DO  j = nys, nyn
1249             DO  k = nzb_w_inner(j,i)+1, nzt
1250!
1251!--             w component - x-direction
1252!--             WS1 (27), WS3 (28), WS5 (29)
1253                IF ( k <= nzb_w_inner(j,i+1) .OR. ( ( inflow_l .OR. outflow_l )&
1254                     .AND. i == nxl ) .OR. ( ( inflow_r .OR. outflow_r )       &
1255                     .AND. i == nxr ) )  THEN
1256                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 27 )
1257                ELSEIF ( k <= nzb_w_inner(j,i+2) .OR. k <= nzb_w_inner(j,i-1)  &
1258                         .OR. ( ( inflow_r .OR. outflow_r ) .AND. i == nxr-1 ) &
1259                         .OR. ( ( inflow_l .OR. outflow_l ) .AND. i == nxlu  ) &
1260                       )  THEN
1261                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 28 )
1262                ELSE
1263                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i),29 )
1264                ENDIF
1265!
1266!--             w component - y-direction
1267!--             WS1 (30), WS3 (31), WS5 (32)
1268                IF ( k <= nzb_w_inner(j+1,i) .OR. ( ( inflow_s .OR. outflow_s )&
1269                     .AND. j == nys ) .OR. ( ( inflow_n .OR. outflow_n )       &
1270                     .AND. j == nyn ) )  THEN
1271                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 30 )
1272                ELSEIF ( k <= nzb_w_inner(j+2,i) .OR. k <= nzb_w_inner(j-1,i)  &
1273                         .OR. ( ( inflow_s .OR. outflow_s ) .AND. j == nysv  ) &
1274                         .OR. ( ( inflow_n .OR. outflow_n ) .AND. j == nyn-1 ) &
1275                       )  THEN
1276                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 31 )
1277                ELSE
1278                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 32 )
1279                ENDIF
1280!
1281!--             w component - z-direction
1282!--             WS1 (33), WS3 (34), WS5 (35)
1283                flag_set = .FALSE.
1284                IF ( k == nzb_w_inner(j,i) .OR. k == nzb_w_inner(j,i) + 1      &
1285                                           .OR. k == nzt )  THEN
1286!
1287!--                Please note, at k == nzb_w_inner(j,i) a flag is explictely
1288!--                set, although this is not a prognostic level. However,
1289!--                contrary to the advection of u,v and s this is necessary
1290!--                because flux_t(nzb_w_inner(j,i)) is used for the tendency
1291!--                at k == nzb_w_inner(j,i)+1.
1292                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 33 )
1293                   flag_set = .TRUE.
1294                ELSEIF ( k == nzb_w_inner(j,i) + 2 .OR. k == nzt - 1 )  THEN
1295                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 34 )
1296                   flag_set = .TRUE.
1297                ELSEIF ( k > nzb_w_inner(j,i) .AND. .NOT. flag_set )  THEN
1298                   wall_flags_0(k,j,i) = IBSET( wall_flags_0(k,j,i), 35 )
1299                ENDIF
1300
1301             ENDDO
1302          ENDDO
1303       ENDDO
1304
1305    ENDIF
1306
1307!
1308!-- In case of topography: limit near-wall mixing length l_wall further:
1309!-- Go through all points of the subdomain one by one and look for the closest
1310!-- surface
1311    IF ( TRIM(topography) /= 'flat' )  THEN
1312       DO  i = nxl, nxr
1313          DO  j = nys, nyn
1314
1315             nzb_si = nzb_s_inner(j,i)
1316             vi     = vertical_influence(nzb_si)
1317
1318             IF ( wall_n(j,i) > 0 )  THEN
1319!
1320!--             North wall (y distance)
1321                DO  k = wall_n(j,i), nzb_si
1322                   l_wall(k,j+1,i) = MIN( l_wall(k,j+1,i), 0.5 * dy )
1323                ENDDO
1324!
1325!--             Above North wall (yz distance)
1326                DO  k = nzb_si + 1, nzb_si + vi
1327                   l_wall(k,j+1,i) = MIN( l_wall(k,j+1,i),     &
1328                                          SQRT( 0.25 * dy**2 + &
1329                                          ( zu(k) - zw(nzb_si) )**2 ) )
1330                ENDDO
1331!
1332!--             Northleft corner (xy distance)
1333                IF ( corner_nl(j,i) > 0 )  THEN
1334                   DO  k = corner_nl(j,i), nzb_si
1335                      l_wall(k,j+1,i-1) = MIN( l_wall(k,j+1,i-1), &
1336                                               0.5 * SQRT( dx**2 + dy**2 ) )
1337                   ENDDO
1338!
1339!--                Above Northleft corner (xyz distance)
1340                   DO  k = nzb_si + 1, nzb_si + vi
1341                      l_wall(k,j+1,i-1) = MIN( l_wall(k,j+1,i-1),             &
1342                                               SQRT( 0.25 * (dx**2 + dy**2) + &
1343                                               ( zu(k) - zw(nzb_si) )**2 ) )
1344                   ENDDO
1345                ENDIF
1346!
1347!--             Northright corner (xy distance)
1348                IF ( corner_nr(j,i) > 0 )  THEN
1349                   DO  k = corner_nr(j,i), nzb_si
1350                       l_wall(k,j+1,i+1) = MIN( l_wall(k,j+1,i+1), &
1351                                                0.5 * SQRT( dx**2 + dy**2 ) )
1352                   ENDDO
1353!
1354!--                Above northright corner (xyz distance)
1355                   DO  k = nzb_si + 1, nzb_si + vi
1356                      l_wall(k,j+1,i+1) = MIN( l_wall(k,j+1,i+1), &
1357                                               SQRT( 0.25 * (dx**2 + dy**2) + &
1358                                               ( zu(k) - zw(nzb_si) )**2 ) )
1359                   ENDDO
1360                ENDIF
1361             ENDIF
1362
1363             IF ( wall_s(j,i) > 0 )  THEN
1364!
1365!--             South wall (y distance)
1366                DO  k = wall_s(j,i), nzb_si
1367                   l_wall(k,j-1,i) = MIN( l_wall(k,j-1,i), 0.5 * dy )
1368                ENDDO
1369!
1370!--             Above south wall (yz distance)
1371                DO  k = nzb_si + 1, &
1372                        nzb_si + vi
1373                   l_wall(k,j-1,i) = MIN( l_wall(k,j-1,i),     &
1374                                          SQRT( 0.25 * dy**2 + &
1375                                          ( zu(k) - zw(nzb_si) )**2 ) )
1376                ENDDO
1377!
1378!--             Southleft corner (xy distance)
1379                IF ( corner_sl(j,i) > 0 )  THEN
1380                   DO  k = corner_sl(j,i), nzb_si
1381                      l_wall(k,j-1,i-1) = MIN( l_wall(k,j-1,i-1), &
1382                                               0.5 * SQRT( dx**2 + dy**2 ) )
1383                   ENDDO
1384!
1385!--                Above southleft corner (xyz distance)
1386                   DO  k = nzb_si + 1, nzb_si + vi
1387                      l_wall(k,j-1,i-1) = MIN( l_wall(k,j-1,i-1),             &
1388                                               SQRT( 0.25 * (dx**2 + dy**2) + &
1389                                               ( zu(k) - zw(nzb_si) )**2 ) )
1390                   ENDDO
1391                ENDIF
1392!
1393!--             Southright corner (xy distance)
1394                IF ( corner_sr(j,i) > 0 )  THEN
1395                   DO  k = corner_sr(j,i), nzb_si
1396                      l_wall(k,j-1,i+1) = MIN( l_wall(k,j-1,i+1), &
1397                                               0.5 * SQRT( dx**2 + dy**2 ) )
1398                   ENDDO
1399!
1400!--                Above southright corner (xyz distance)
1401                   DO  k = nzb_si + 1, nzb_si + vi
1402                      l_wall(k,j-1,i+1) = MIN( l_wall(k,j-1,i+1),             &
1403                                               SQRT( 0.25 * (dx**2 + dy**2) + &
1404                                               ( zu(k) - zw(nzb_si) )**2 ) )
1405                   ENDDO
1406                ENDIF
1407
1408             ENDIF
1409
1410             IF ( wall_l(j,i) > 0 )  THEN
1411!
1412!--             Left wall (x distance)
1413                DO  k = wall_l(j,i), nzb_si
1414                   l_wall(k,j,i-1) = MIN( l_wall(k,j,i-1), 0.5 * dx )
1415                ENDDO
1416!
1417!--             Above left wall (xz distance)
1418                DO  k = nzb_si + 1, nzb_si + vi
1419                   l_wall(k,j,i-1) = MIN( l_wall(k,j,i-1),     &
1420                                          SQRT( 0.25 * dx**2 + &
1421                                          ( zu(k) - zw(nzb_si) )**2 ) )
1422                ENDDO
1423             ENDIF
1424
1425             IF ( wall_r(j,i) > 0 )  THEN
1426!
1427!--             Right wall (x distance)
1428                DO  k = wall_r(j,i), nzb_si
1429                   l_wall(k,j,i+1) = MIN( l_wall(k,j,i+1), 0.5 * dx )
1430                ENDDO
1431!
1432!--             Above right wall (xz distance)
1433                DO  k = nzb_si + 1, nzb_si + vi
1434                   l_wall(k,j,i+1) = MIN( l_wall(k,j,i+1),     &
1435                                          SQRT( 0.25 * dx**2 + &
1436                                          ( zu(k) - zw(nzb_si) )**2 ) )
1437                ENDDO
1438
1439             ENDIF
1440
1441          ENDDO
1442       ENDDO
1443
1444    ENDIF
1445
1446!
1447!-- Multiplication with wall_adjustment_factor
1448    l_wall = wall_adjustment_factor * l_wall
1449
1450!
1451!-- Set lateral boundary conditions for l_wall
1452    CALL exchange_horiz( l_wall, nbgp )
1453
1454    DEALLOCATE( corner_nl, corner_nr, corner_sl, corner_sr, nzb_local, &
1455                nzb_tmp, vertical_influence, wall_l, wall_n, wall_r, wall_s )
1456
1457#endif
1458
1459 END SUBROUTINE init_grid
Note: See TracBrowser for help on using the repository browser.