source: palm/trunk/SOURCE/boundary_conds.f90 @ 4268

Last change on this file since 4268 was 4268, checked in by schwenkel, 5 years ago

Introducing module interface for boundary conditions and move module specific boundary conditions into their modules

  • Property svn:keywords set to Id
File size: 31.6 KB
RevLine 
[1682]1!> @file boundary_conds.f90
[2000]2!------------------------------------------------------------------------------!
[2696]3! This file is part of the PALM model system.
[1036]4!
[2000]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.
[1036]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!
[3655]17! Copyright 1997-2019 Leibniz Universitaet Hannover
[2000]18!------------------------------------------------------------------------------!
[1036]19!
[484]20! Current revisions:
[1]21! -----------------
[1933]22!
[3589]23!
[1321]24! Former revisions:
25! -----------------
26! $Id: boundary_conds.f90 4268 2019-10-17 11:29:38Z schwenkel $
[4268]27! Removing bulk cloud variables to respective module
28!
29! 4182 2019-08-22 15:20:23Z scharf
[4182]30! Corrected "Former revisions" section
31!
32! 4102 2019-07-17 16:00:03Z suehring
[4102]33! - Revise setting for boundary conditions at horizontal walls, use the offset
34!   index that belongs to the data structure instead of pre-calculating
35!   the offset index for each facing.
36! - Set boundary conditions for bulk-cloud quantities also at downward facing
37!   surfaces
38!
39! 4087 2019-07-11 11:35:23Z gronemeier
[4087]40! Add comment
41!
42! 4086 2019-07-11 05:55:44Z gronemeier
[4086]43! Bugfix: use constant-flux layer condition for e in all rans modes
44!
45! 3879 2019-04-08 20:25:23Z knoop
[3717]46! Bugfix, do not set boundary conditions for potential temperature in neutral
47! runs.
48!
49! 3655 2019-01-07 16:51:22Z knoop
[3634]50! OpenACC port for SPEC
[1321]51!
[4182]52! Revision 1.1  1997/09/12 06:21:34  raasch
53! Initial revision
54!
55!
[1]56! Description:
57! ------------
[1682]58!> Boundary conditions for the prognostic quantities.
59!> One additional bottom boundary condition is applied for the TKE (=(u*)**2)
60!> in prandtl_fluxes. The cyclic lateral boundary conditions are implicitly
61!> handled in routine exchange_horiz. Pressure boundary conditions are
62!> explicitly set in routines pres, poisfft, poismg and sor.
[1]63!------------------------------------------------------------------------------!
[1682]64 SUBROUTINE boundary_conds
65 
[1]66
[1320]67    USE arrays_3d,                                                             &
68        ONLY:  c_u, c_u_m, c_u_m_l, c_v, c_v_m, c_v_m_l, c_w, c_w_m, c_w_m_l,  &
[4268]69               dzu, pt, pt_init, pt_p, q,                                      &
70               q_p, s, s_p, sa, sa_p, u, u_init, u_m_l, u_m_n,                 &
[3241]71               u_m_r, u_m_s, u_p, v, v_init, v_m_l, v_m_n, v_m_r, v_m_s, v_p,  &
72               w, w_p, w_m_l, w_m_n, w_m_r, w_m_s
[2696]73
74    USE chemistry_model_mod,                                                   &
[3879]75        ONLY:  chem_boundary_conds
76
[1320]77    USE control_parameters,                                                    &
[4102]78        ONLY:  air_chemistry, bc_dirichlet_l,                                  &
[3182]79               bc_dirichlet_s, bc_radiation_l, bc_radiation_n, bc_radiation_r, &
80               bc_radiation_s, bc_pt_t_val, bc_q_t_val, bc_s_t_val,            &
[4102]81               child_domain, coupling_mode, dt_3d,                             &
[3582]82               humidity, ibc_pt_b, ibc_pt_t, ibc_q_b, ibc_q_t, ibc_s_b,        &
83               ibc_s_t, ibc_uv_b, ibc_uv_t, intermediate_timestep_count,       &
[3717]84               nesting_offline, neutral, nudging, ocean_mode, passive_scalar,  &
[4102]85               tsc, salsa, use_cmax
[1320]86
87    USE grid_variables,                                                        &
88        ONLY:  ddx, ddy, dx, dy
89
90    USE indices,                                                               &
[3294]91        ONLY:  nx, nxl, nxlg, nxr, nxrg, ny, nyn, nyng, nys, nysg, nzb, nzt
[1320]92
93    USE kinds
94
[3294]95    USE ocean_mod,                                                             &
96        ONLY:  ibc_sa_t
[3274]97
[1]98    USE pegrid
99
[1933]100    USE pmc_interface,                                                         &
[4102]101        ONLY : nesting_mode
[3467]102 
103    USE salsa_mod,                                                             &
[4268]104        ONLY:  salsa_boundary_conds
[1320]105
[2232]106    USE surface_mod,                                                           &
[4102]107        ONLY :  bc_h
[1933]108
[3129]109    USE turbulence_closure_mod,                                                &
[4102]110        ONLY:  tcm_boundary_conds
[3129]111
[1]112    IMPLICIT NONE
113
[2232]114    INTEGER(iwp) ::  i  !< grid index x direction
115    INTEGER(iwp) ::  j  !< grid index y direction
116    INTEGER(iwp) ::  k  !< grid index z direction
117    INTEGER(iwp) ::  l  !< running index boundary type, for up- and downward-facing walls
118    INTEGER(iwp) ::  m  !< running index surface elements
[1]119
[3562]120    REAL(wp)    ::  c_max !< maximum phase velocity allowed by CFL criterion, used for outflow boundary condition
121    REAL(wp)    ::  denom !< horizontal gradient of velocity component normal to the outflow boundary
[1]122
[73]123
[1]124!
[1113]125!-- Bottom boundary
126    IF ( ibc_uv_b == 1 )  THEN
127       u_p(nzb,:,:) = u_p(nzb+1,:,:)
128       v_p(nzb,:,:) = v_p(nzb+1,:,:)
129    ENDIF
[2232]130!
131!-- Set zero vertical velocity at topography top (l=0), or bottom (l=1) in case
132!-- of downward-facing surfaces.
133    DO  l = 0, 1
134       !$OMP PARALLEL DO PRIVATE( i, j, k )
[3634]135       !$ACC PARALLEL LOOP PRIVATE(i, j, k) &
136       !$ACC PRESENT(bc_h, w_p)
[2232]137       DO  m = 1, bc_h(l)%ns
[4268]138          i = bc_h(l)%i(m)
[2232]139          j = bc_h(l)%j(m)
140          k = bc_h(l)%k(m)
[4102]141          w_p(k+bc_h(l)%koff,j,i) = 0.0_wp
[1113]142       ENDDO
143    ENDDO
144
145!
[1762]146!-- Top boundary. A nested domain ( ibc_uv_t = 3 ) does not require settings.
[1113]147    IF ( ibc_uv_t == 0 )  THEN
[3634]148        !$ACC KERNELS PRESENT(u_p, v_p, u_init, v_init)
[1113]149        u_p(nzt+1,:,:) = u_init(nzt+1)
150        v_p(nzt+1,:,:) = v_init(nzt+1)
[3634]151        !$ACC END KERNELS
[1762]152    ELSEIF ( ibc_uv_t == 1 )  THEN
[1113]153        u_p(nzt+1,:,:) = u_p(nzt,:,:)
154        v_p(nzt+1,:,:) = v_p(nzt,:,:)
155    ENDIF
156
[2365]157!
158!-- Vertical nesting: Vertical velocity not zero at the top of the fine grid
[3347]159    IF (  .NOT.  child_domain  .AND.  .NOT.  nesting_offline  .AND.            &
[2365]160                 TRIM(coupling_mode) /= 'vnested_fine' )  THEN
[3634]161       !$ACC KERNELS PRESENT(w_p)
[2365]162       w_p(nzt:nzt+1,:,:) = 0.0_wp  !< nzt is not a prognostic level (but cf. pres)
[3634]163       !$ACC END KERNELS
[1762]164    ENDIF
165
[1113]166!
[2232]167!-- Temperature at bottom and top boundary.
[1113]168!-- In case of coupled runs (ibc_pt_b = 2) the temperature is given by
169!-- the sea surface temperature of the coupled ocean model.
[2232]170!-- Dirichlet
[3717]171    IF ( .NOT. neutral )  THEN
172       IF ( ibc_pt_b == 0 )  THEN
173          DO  l = 0, 1
174             !$OMP PARALLEL DO PRIVATE( i, j, k )
175             DO  m = 1, bc_h(l)%ns
[4268]176                i = bc_h(l)%i(m)
[3717]177                j = bc_h(l)%j(m)
178                k = bc_h(l)%k(m)
[4102]179                pt_p(k+bc_h(l)%koff,j,i) = pt(k+bc_h(l)%koff,j,i)
[3717]180             ENDDO
[1]181          ENDDO
[3717]182!     
183!--    Neumann, zero-gradient
184       ELSEIF ( ibc_pt_b == 1 )  THEN
185          DO  l = 0, 1
186             !$OMP PARALLEL DO PRIVATE( i, j, k )
187             !$ACC PARALLEL LOOP PRIVATE(i, j, k) &
188             !$ACC PRESENT(bc_h, pt_p)
189             DO  m = 1, bc_h(l)%ns
190                i = bc_h(l)%i(m)           
191                j = bc_h(l)%j(m)
192                k = bc_h(l)%k(m)
[4102]193                pt_p(k+bc_h(l)%koff,j,i) = pt_p(k,j,i)
[3717]194             ENDDO
[1113]195          ENDDO
[3717]196       ENDIF
197       
198!     
199!--    Temperature at top boundary
200       IF ( ibc_pt_t == 0 )  THEN
201           pt_p(nzt+1,:,:) = pt(nzt+1,:,:)
202!     
203!--        In case of nudging adjust top boundary to pt which is
204!--        read in from NUDGING-DATA
205           IF ( nudging )  THEN
206              pt_p(nzt+1,:,:) = pt_init(nzt+1)
207           ENDIF
208       ELSEIF ( ibc_pt_t == 1 )  THEN
209           pt_p(nzt+1,:,:) = pt_p(nzt,:,:)
210       ELSEIF ( ibc_pt_t == 2 )  THEN
211           !$ACC KERNELS PRESENT(pt_p, dzu)
212           pt_p(nzt+1,:,:) = pt_p(nzt,:,:) + bc_pt_t_val * dzu(nzt+1)
213           !$ACC END KERNELS
214       ENDIF
[1113]215    ENDIF
[1]216!
[1113]217!-- Boundary conditions for salinity
[3294]218    IF ( ocean_mode )  THEN
[1113]219!
220!--    Bottom boundary: Neumann condition because salinity flux is always
[2232]221!--    given.
222       DO  l = 0, 1
223          !$OMP PARALLEL DO PRIVATE( i, j, k )
224          DO  m = 1, bc_h(l)%ns
[4268]225             i = bc_h(l)%i(m)
[2232]226             j = bc_h(l)%j(m)
227             k = bc_h(l)%k(m)
[4102]228             sa_p(k+bc_h(l)%koff,j,i) = sa_p(k,j,i)
[1]229          ENDDO
[1113]230       ENDDO
[1]231!
[1113]232!--    Top boundary: Dirichlet or Neumann
233       IF ( ibc_sa_t == 0 )  THEN
234           sa_p(nzt+1,:,:) = sa(nzt+1,:,:)
235       ELSEIF ( ibc_sa_t == 1 )  THEN
236           sa_p(nzt+1,:,:) = sa_p(nzt,:,:)
[1]237       ENDIF
238
[1113]239    ENDIF
240
[1]241!
[1960]242!-- Boundary conditions for total water content,
[1113]243!-- bottom and top boundary (see also temperature)
[1960]244    IF ( humidity )  THEN
[1113]245!
246!--    Surface conditions for constant_humidity_flux
[2232]247!--    Run loop over all non-natural and natural walls. Note, in wall-datatype
248!--    the k coordinate belongs to the atmospheric grid point, therefore, set
249!--    q_p at k-1
[1113]250       IF ( ibc_q_b == 0 ) THEN
[2232]251
252          DO  l = 0, 1
253             !$OMP PARALLEL DO PRIVATE( i, j, k )
254             DO  m = 1, bc_h(l)%ns
[4268]255                i = bc_h(l)%i(m)
[2232]256                j = bc_h(l)%j(m)
257                k = bc_h(l)%k(m)
[4102]258                q_p(k+bc_h(l)%koff,j,i) = q(k+bc_h(l)%koff,j,i)
[1]259             ENDDO
260          ENDDO
[4268]261
[1113]262       ELSE
[4268]263
[2232]264          DO  l = 0, 1
265             !$OMP PARALLEL DO PRIVATE( i, j, k )
266             DO  m = 1, bc_h(l)%ns
[4268]267                i = bc_h(l)%i(m)
[2232]268                j = bc_h(l)%j(m)
269                k = bc_h(l)%k(m)
[4102]270                q_p(k+bc_h(l)%koff,j,i) = q_p(k,j,i)
[95]271             ENDDO
272          ENDDO
[1113]273       ENDIF
[95]274!
[1113]275!--    Top boundary
[1462]276       IF ( ibc_q_t == 0 ) THEN
277          q_p(nzt+1,:,:) = q(nzt+1,:,:)
278       ELSEIF ( ibc_q_t == 1 ) THEN
[1992]279          q_p(nzt+1,:,:) = q_p(nzt,:,:) + bc_q_t_val * dzu(nzt+1)
[1462]280       ENDIF
[1409]281    ENDIF
[1]282!
[1960]283!-- Boundary conditions for scalar,
284!-- bottom and top boundary (see also temperature)
285    IF ( passive_scalar )  THEN
286!
287!--    Surface conditions for constant_humidity_flux
[2232]288!--    Run loop over all non-natural and natural walls. Note, in wall-datatype
289!--    the k coordinate belongs to the atmospheric grid point, therefore, set
290!--    s_p at k-1
[1960]291       IF ( ibc_s_b == 0 ) THEN
[4268]292
[2232]293          DO  l = 0, 1
294             !$OMP PARALLEL DO PRIVATE( i, j, k )
295             DO  m = 1, bc_h(l)%ns
[4268]296                i = bc_h(l)%i(m)
[2232]297                j = bc_h(l)%j(m)
298                k = bc_h(l)%k(m)
[4102]299                s_p(k+bc_h(l)%koff,j,i) = s(k+bc_h(l)%koff,j,i)
[1960]300             ENDDO
301          ENDDO
[4268]302
[1960]303       ELSE
[4268]304
[2232]305          DO  l = 0, 1
306             !$OMP PARALLEL DO PRIVATE( i, j, k )
307             DO  m = 1, bc_h(l)%ns
[4268]308                i = bc_h(l)%i(m)
[2232]309                j = bc_h(l)%j(m)
310                k = bc_h(l)%k(m)
[4102]311                s_p(k+bc_h(l)%koff,j,i) = s_p(k,j,i)
[1960]312             ENDDO
313          ENDDO
314       ENDIF
315!
[1992]316!--    Top boundary condition
317       IF ( ibc_s_t == 0 )  THEN
[1960]318          s_p(nzt+1,:,:) = s(nzt+1,:,:)
[1992]319       ELSEIF ( ibc_s_t == 1 )  THEN
320          s_p(nzt+1,:,:) = s_p(nzt,:,:)
321       ELSEIF ( ibc_s_t == 2 )  THEN
322          s_p(nzt+1,:,:) = s_p(nzt,:,:) + bc_s_t_val * dzu(nzt+1)
[1960]323       ENDIF
324
[4102]325    ENDIF 
[1960]326!
[4102]327!-- Set boundary conditions for subgrid TKE and dissipation (RANS mode)
328    CALL tcm_boundary_conds
329!
[2696]330!-- Top/bottom boundary conditions for chemical species
331    IF ( air_chemistry )  CALL chem_boundary_conds( 'set_bc_bottomtop' )
332!
[1762]333!-- In case of inflow or nest boundary at the south boundary the boundary for v
334!-- is at nys and in case of inflow or nest boundary at the left boundary the
335!-- boundary for u is at nxl. Since in prognostic_equations (cache optimized
336!-- version) these levels are handled as a prognostic level, boundary values
337!-- have to be restored here.
[3182]338    IF ( bc_dirichlet_s )  THEN
[1409]339       v_p(:,nys,:) = v_p(:,nys-1,:)
[3182]340    ELSEIF ( bc_dirichlet_l ) THEN
[1409]341       u_p(:,:,nxl) = u_p(:,:,nxl-1)
342    ENDIF
[1]343
344!
[1762]345!-- The same restoration for u at i=nxl and v at j=nys as above must be made
[1933]346!-- in case of nest boundaries. This must not be done in case of vertical nesting
[3182]347!-- mode as in that case the lateral boundaries are actually cyclic.
[4102]348!-- Lateral oundary conditions for TKE and dissipation are set
349!-- in tcm_boundary_conds.
[3182]350    IF ( nesting_mode /= 'vertical'  .OR.  nesting_offline )  THEN
351       IF ( bc_dirichlet_s )  THEN
[1933]352          v_p(:,nys,:) = v_p(:,nys-1,:)
353       ENDIF
[3182]354       IF ( bc_dirichlet_l )  THEN
[1933]355          u_p(:,:,nxl) = u_p(:,:,nxl-1)
356       ENDIF
[1762]357    ENDIF
358
359!
[4102]360!-- Lateral boundary conditions for scalar quantities at the outflow.
361!-- Lateral oundary conditions for TKE and dissipation are set
362!-- in tcm_boundary_conds.
[3182]363    IF ( bc_radiation_s )  THEN
[1409]364       pt_p(:,nys-1,:)     = pt_p(:,nys,:)
[1960]365       IF ( humidity )  THEN
[1409]366          q_p(:,nys-1,:) = q_p(:,nys,:)
367       ENDIF
[1960]368       IF ( passive_scalar )  s_p(:,nys-1,:) = s_p(:,nys,:)
[3182]369    ELSEIF ( bc_radiation_n )  THEN
[1409]370       pt_p(:,nyn+1,:)     = pt_p(:,nyn,:)
[1960]371       IF ( humidity )  THEN
[1409]372          q_p(:,nyn+1,:) = q_p(:,nyn,:)
373       ENDIF
[1960]374       IF ( passive_scalar )  s_p(:,nyn+1,:) = s_p(:,nyn,:)
[3182]375    ELSEIF ( bc_radiation_l )  THEN
[1409]376       pt_p(:,:,nxl-1)     = pt_p(:,:,nxl)
[1960]377       IF ( humidity )  THEN
[1409]378          q_p(:,:,nxl-1) = q_p(:,:,nxl)
379       ENDIF
[1960]380       IF ( passive_scalar )  s_p(:,:,nxl-1) = s_p(:,:,nxl)
[3182]381    ELSEIF ( bc_radiation_r )  THEN
[1409]382       pt_p(:,:,nxr+1)     = pt_p(:,:,nxr)
[1960]383       IF ( humidity )  THEN
[1409]384          q_p(:,:,nxr+1) = q_p(:,:,nxr)
[1]385       ENDIF
[1960]386       IF ( passive_scalar )  s_p(:,:,nxr+1) = s_p(:,:,nxr)
[1]387    ENDIF
388
389!
[2696]390!-- Lateral boundary conditions for chemical species
391    IF ( air_chemistry )  CALL chem_boundary_conds( 'set_bc_lateral' )   
392
393!
[1159]394!-- Radiation boundary conditions for the velocities at the respective outflow.
395!-- The phase velocity is either assumed to the maximum phase velocity that
396!-- ensures numerical stability (CFL-condition) or calculated after
397!-- Orlanski(1976) and averaged along the outflow boundary.
[3182]398    IF ( bc_radiation_s )  THEN
[75]399
[1159]400       IF ( use_cmax )  THEN
401          u_p(:,-1,:) = u(:,0,:)
402          v_p(:,0,:)  = v(:,1,:)
[4268]403          w_p(:,-1,:) = w(:,0,:)
[1159]404       ELSEIF ( .NOT. use_cmax )  THEN
[75]405
[978]406          c_max = dy / dt_3d
[75]407
[1353]408          c_u_m_l = 0.0_wp 
409          c_v_m_l = 0.0_wp
410          c_w_m_l = 0.0_wp
[978]411
[1353]412          c_u_m = 0.0_wp 
413          c_v_m = 0.0_wp
414          c_w_m = 0.0_wp
[978]415
[75]416!
[996]417!--       Calculate the phase speeds for u, v, and w, first local and then
418!--       average along the outflow boundary.
419          DO  k = nzb+1, nzt+1
420             DO  i = nxl, nxr
[75]421
[106]422                denom = u_m_s(k,0,i) - u_m_s(k,1,i)
423
[1353]424                IF ( denom /= 0.0_wp )  THEN
[996]425                   c_u(k,i) = -c_max * ( u(k,0,i) - u_m_s(k,0,i) ) / ( denom * tsc(2) )
[1353]426                   IF ( c_u(k,i) < 0.0_wp )  THEN
427                      c_u(k,i) = 0.0_wp
[106]428                   ELSEIF ( c_u(k,i) > c_max )  THEN
429                      c_u(k,i) = c_max
430                   ENDIF
431                ELSE
432                   c_u(k,i) = c_max
[75]433                ENDIF
434
[106]435                denom = v_m_s(k,1,i) - v_m_s(k,2,i)
436
[1353]437                IF ( denom /= 0.0_wp )  THEN
[996]438                   c_v(k,i) = -c_max * ( v(k,1,i) - v_m_s(k,1,i) ) / ( denom * tsc(2) )
[1353]439                   IF ( c_v(k,i) < 0.0_wp )  THEN
440                      c_v(k,i) = 0.0_wp
[106]441                   ELSEIF ( c_v(k,i) > c_max )  THEN
442                      c_v(k,i) = c_max
443                   ENDIF
444                ELSE
445                   c_v(k,i) = c_max
[75]446                ENDIF
447
[106]448                denom = w_m_s(k,0,i) - w_m_s(k,1,i)
[75]449
[1353]450                IF ( denom /= 0.0_wp )  THEN
[996]451                   c_w(k,i) = -c_max * ( w(k,0,i) - w_m_s(k,0,i) ) / ( denom * tsc(2) )
[1353]452                   IF ( c_w(k,i) < 0.0_wp )  THEN
453                      c_w(k,i) = 0.0_wp
[106]454                   ELSEIF ( c_w(k,i) > c_max )  THEN
455                      c_w(k,i) = c_max
456                   ENDIF
457                ELSE
458                   c_w(k,i) = c_max
[75]459                ENDIF
[106]460
[978]461                c_u_m_l(k) = c_u_m_l(k) + c_u(k,i)
462                c_v_m_l(k) = c_v_m_l(k) + c_v(k,i)
463                c_w_m_l(k) = c_w_m_l(k) + c_w(k,i)
[106]464
[978]465             ENDDO
466          ENDDO
[75]467
[4268]468#if defined( __parallel )
[978]469          IF ( collective_wait )  CALL MPI_BARRIER( comm1dx, ierr )
470          CALL MPI_ALLREDUCE( c_u_m_l(nzb+1), c_u_m(nzb+1), nzt-nzb, MPI_REAL, &
471                              MPI_SUM, comm1dx, ierr )   
472          IF ( collective_wait )  CALL MPI_BARRIER( comm1dx, ierr )
473          CALL MPI_ALLREDUCE( c_v_m_l(nzb+1), c_v_m(nzb+1), nzt-nzb, MPI_REAL, &
474                              MPI_SUM, comm1dx, ierr ) 
475          IF ( collective_wait )  CALL MPI_BARRIER( comm1dx, ierr )
476          CALL MPI_ALLREDUCE( c_w_m_l(nzb+1), c_w_m(nzb+1), nzt-nzb, MPI_REAL, &
477                              MPI_SUM, comm1dx, ierr ) 
478#else
479          c_u_m = c_u_m_l
480          c_v_m = c_v_m_l
481          c_w_m = c_w_m_l
482#endif
483
484          c_u_m = c_u_m / (nx+1)
485          c_v_m = c_v_m / (nx+1)
486          c_w_m = c_w_m / (nx+1)
487
[75]488!
[978]489!--       Save old timelevels for the next timestep
490          IF ( intermediate_timestep_count == 1 )  THEN
491             u_m_s(:,:,:) = u(:,0:1,:)
492             v_m_s(:,:,:) = v(:,1:2,:)
493             w_m_s(:,:,:) = w(:,0:1,:)
494          ENDIF
495
496!
497!--       Calculate the new velocities
[996]498          DO  k = nzb+1, nzt+1
499             DO  i = nxlg, nxrg
[978]500                u_p(k,-1,i) = u(k,-1,i) - dt_3d * tsc(2) * c_u_m(k) *          &
[75]501                                       ( u(k,-1,i) - u(k,0,i) ) * ddy
502
[978]503                v_p(k,0,i)  = v(k,0,i)  - dt_3d * tsc(2) * c_v_m(k) *          &
[106]504                                       ( v(k,0,i) - v(k,1,i) ) * ddy
[75]505
[978]506                w_p(k,-1,i) = w(k,-1,i) - dt_3d * tsc(2) * c_w_m(k) *          &
[75]507                                       ( w(k,-1,i) - w(k,0,i) ) * ddy
[978]508             ENDDO
[75]509          ENDDO
510
511!
[978]512!--       Bottom boundary at the outflow
513          IF ( ibc_uv_b == 0 )  THEN
[1353]514             u_p(nzb,-1,:) = 0.0_wp 
515             v_p(nzb,0,:)  = 0.0_wp 
[4268]516          ELSE
[978]517             u_p(nzb,-1,:) =  u_p(nzb+1,-1,:)
518             v_p(nzb,0,:)  =  v_p(nzb+1,0,:)
519          ENDIF
[1353]520          w_p(nzb,-1,:) = 0.0_wp
[73]521
[75]522!
[978]523!--       Top boundary at the outflow
524          IF ( ibc_uv_t == 0 )  THEN
525             u_p(nzt+1,-1,:) = u_init(nzt+1)
526             v_p(nzt+1,0,:)  = v_init(nzt+1)
527          ELSE
[1742]528             u_p(nzt+1,-1,:) = u_p(nzt,-1,:)
529             v_p(nzt+1,0,:)  = v_p(nzt,0,:)
[978]530          ENDIF
[1353]531          w_p(nzt:nzt+1,-1,:) = 0.0_wp
[978]532
[75]533       ENDIF
[73]534
[75]535    ENDIF
[73]536
[3182]537    IF ( bc_radiation_n )  THEN
[73]538
[1159]539       IF ( use_cmax )  THEN
540          u_p(:,ny+1,:) = u(:,ny,:)
541          v_p(:,ny+1,:) = v(:,ny,:)
[4268]542          w_p(:,ny+1,:) = w(:,ny,:)
[1159]543       ELSEIF ( .NOT. use_cmax )  THEN
[75]544
[978]545          c_max = dy / dt_3d
[75]546
[1353]547          c_u_m_l = 0.0_wp 
548          c_v_m_l = 0.0_wp
549          c_w_m_l = 0.0_wp
[978]550
[1353]551          c_u_m = 0.0_wp 
552          c_v_m = 0.0_wp
553          c_w_m = 0.0_wp
[978]554
[1]555!
[996]556!--       Calculate the phase speeds for u, v, and w, first local and then
557!--       average along the outflow boundary.
558          DO  k = nzb+1, nzt+1
559             DO  i = nxl, nxr
[73]560
[106]561                denom = u_m_n(k,ny,i) - u_m_n(k,ny-1,i)
562
[1353]563                IF ( denom /= 0.0_wp )  THEN
[996]564                   c_u(k,i) = -c_max * ( u(k,ny,i) - u_m_n(k,ny,i) ) / ( denom * tsc(2) )
[1353]565                   IF ( c_u(k,i) < 0.0_wp )  THEN
566                      c_u(k,i) = 0.0_wp
[106]567                   ELSEIF ( c_u(k,i) > c_max )  THEN
568                      c_u(k,i) = c_max
569                   ENDIF
570                ELSE
571                   c_u(k,i) = c_max
[73]572                ENDIF
573
[106]574                denom = v_m_n(k,ny,i) - v_m_n(k,ny-1,i)
[73]575
[1353]576                IF ( denom /= 0.0_wp )  THEN
[996]577                   c_v(k,i) = -c_max * ( v(k,ny,i) - v_m_n(k,ny,i) ) / ( denom * tsc(2) )
[1353]578                   IF ( c_v(k,i) < 0.0_wp )  THEN
579                      c_v(k,i) = 0.0_wp
[106]580                   ELSEIF ( c_v(k,i) > c_max )  THEN
581                      c_v(k,i) = c_max
582                   ENDIF
583                ELSE
584                   c_v(k,i) = c_max
[73]585                ENDIF
586
[106]587                denom = w_m_n(k,ny,i) - w_m_n(k,ny-1,i)
[73]588
[1353]589                IF ( denom /= 0.0_wp )  THEN
[996]590                   c_w(k,i) = -c_max * ( w(k,ny,i) - w_m_n(k,ny,i) ) / ( denom * tsc(2) )
[1353]591                   IF ( c_w(k,i) < 0.0_wp )  THEN
592                      c_w(k,i) = 0.0_wp
[106]593                   ELSEIF ( c_w(k,i) > c_max )  THEN
594                      c_w(k,i) = c_max
595                   ENDIF
596                ELSE
597                   c_w(k,i) = c_max
[73]598                ENDIF
[106]599
[978]600                c_u_m_l(k) = c_u_m_l(k) + c_u(k,i)
601                c_v_m_l(k) = c_v_m_l(k) + c_v(k,i)
602                c_w_m_l(k) = c_w_m_l(k) + c_w(k,i)
[106]603
[978]604             ENDDO
605          ENDDO
[73]606
[978]607#if defined( __parallel )   
608          IF ( collective_wait )  CALL MPI_BARRIER( comm1dx, ierr )
609          CALL MPI_ALLREDUCE( c_u_m_l(nzb+1), c_u_m(nzb+1), nzt-nzb, MPI_REAL, &
610                              MPI_SUM, comm1dx, ierr )   
611          IF ( collective_wait )  CALL MPI_BARRIER( comm1dx, ierr )
612          CALL MPI_ALLREDUCE( c_v_m_l(nzb+1), c_v_m(nzb+1), nzt-nzb, MPI_REAL, &
613                              MPI_SUM, comm1dx, ierr ) 
614          IF ( collective_wait )  CALL MPI_BARRIER( comm1dx, ierr )
615          CALL MPI_ALLREDUCE( c_w_m_l(nzb+1), c_w_m(nzb+1), nzt-nzb, MPI_REAL, &
616                              MPI_SUM, comm1dx, ierr ) 
617#else
618          c_u_m = c_u_m_l
619          c_v_m = c_v_m_l
620          c_w_m = c_w_m_l
621#endif
622
623          c_u_m = c_u_m / (nx+1)
624          c_v_m = c_v_m / (nx+1)
625          c_w_m = c_w_m / (nx+1)
626
[73]627!
[978]628!--       Save old timelevels for the next timestep
629          IF ( intermediate_timestep_count == 1 )  THEN
630                u_m_n(:,:,:) = u(:,ny-1:ny,:)
631                v_m_n(:,:,:) = v(:,ny-1:ny,:)
632                w_m_n(:,:,:) = w(:,ny-1:ny,:)
633          ENDIF
[73]634
[978]635!
636!--       Calculate the new velocities
[996]637          DO  k = nzb+1, nzt+1
638             DO  i = nxlg, nxrg
[978]639                u_p(k,ny+1,i) = u(k,ny+1,i) - dt_3d * tsc(2) * c_u_m(k) *      &
640                                       ( u(k,ny+1,i) - u(k,ny,i) ) * ddy
[73]641
[978]642                v_p(k,ny+1,i) = v(k,ny+1,i)  - dt_3d * tsc(2) * c_v_m(k) *     &
643                                       ( v(k,ny+1,i) - v(k,ny,i) ) * ddy
[73]644
[978]645                w_p(k,ny+1,i) = w(k,ny+1,i) - dt_3d * tsc(2) * c_w_m(k) *      &
646                                       ( w(k,ny+1,i) - w(k,ny,i) ) * ddy
647             ENDDO
[1]648          ENDDO
649
650!
[978]651!--       Bottom boundary at the outflow
652          IF ( ibc_uv_b == 0 )  THEN
[1353]653             u_p(nzb,ny+1,:) = 0.0_wp
654             v_p(nzb,ny+1,:) = 0.0_wp   
[4268]655          ELSE
[978]656             u_p(nzb,ny+1,:) =  u_p(nzb+1,ny+1,:)
657             v_p(nzb,ny+1,:) =  v_p(nzb+1,ny+1,:)
658          ENDIF
[1353]659          w_p(nzb,ny+1,:) = 0.0_wp
[73]660
661!
[978]662!--       Top boundary at the outflow
663          IF ( ibc_uv_t == 0 )  THEN
664             u_p(nzt+1,ny+1,:) = u_init(nzt+1)
665             v_p(nzt+1,ny+1,:) = v_init(nzt+1)
666          ELSE
667             u_p(nzt+1,ny+1,:) = u_p(nzt,nyn+1,:)
668             v_p(nzt+1,ny+1,:) = v_p(nzt,nyn+1,:)
669          ENDIF
[1353]670          w_p(nzt:nzt+1,ny+1,:) = 0.0_wp
[978]671
[1]672       ENDIF
673
[75]674    ENDIF
675
[3182]676    IF ( bc_radiation_l )  THEN
[75]677
[1159]678       IF ( use_cmax )  THEN
[1717]679          u_p(:,:,0)  = u(:,:,1)
680          v_p(:,:,-1) = v(:,:,0)
[4268]681          w_p(:,:,-1) = w(:,:,0)
[1159]682       ELSEIF ( .NOT. use_cmax )  THEN
[75]683
[978]684          c_max = dx / dt_3d
[75]685
[1353]686          c_u_m_l = 0.0_wp 
687          c_v_m_l = 0.0_wp
688          c_w_m_l = 0.0_wp
[978]689
[1353]690          c_u_m = 0.0_wp 
691          c_v_m = 0.0_wp
692          c_w_m = 0.0_wp
[978]693
[1]694!
[996]695!--       Calculate the phase speeds for u, v, and w, first local and then
696!--       average along the outflow boundary.
697          DO  k = nzb+1, nzt+1
698             DO  j = nys, nyn
[75]699
[106]700                denom = u_m_l(k,j,1) - u_m_l(k,j,2)
701
[1353]702                IF ( denom /= 0.0_wp )  THEN
[996]703                   c_u(k,j) = -c_max * ( u(k,j,1) - u_m_l(k,j,1) ) / ( denom * tsc(2) )
[1353]704                   IF ( c_u(k,j) < 0.0_wp )  THEN
705                      c_u(k,j) = 0.0_wp
[107]706                   ELSEIF ( c_u(k,j) > c_max )  THEN
707                      c_u(k,j) = c_max
[106]708                   ENDIF
709                ELSE
[107]710                   c_u(k,j) = c_max
[75]711                ENDIF
712
[106]713                denom = v_m_l(k,j,0) - v_m_l(k,j,1)
[75]714
[1353]715                IF ( denom /= 0.0_wp )  THEN
[996]716                   c_v(k,j) = -c_max * ( v(k,j,0) - v_m_l(k,j,0) ) / ( denom * tsc(2) )
[1353]717                   IF ( c_v(k,j) < 0.0_wp )  THEN
718                      c_v(k,j) = 0.0_wp
[106]719                   ELSEIF ( c_v(k,j) > c_max )  THEN
720                      c_v(k,j) = c_max
721                   ENDIF
722                ELSE
723                   c_v(k,j) = c_max
[75]724                ENDIF
725
[106]726                denom = w_m_l(k,j,0) - w_m_l(k,j,1)
[75]727
[1353]728                IF ( denom /= 0.0_wp )  THEN
[996]729                   c_w(k,j) = -c_max * ( w(k,j,0) - w_m_l(k,j,0) ) / ( denom * tsc(2) )
[1353]730                   IF ( c_w(k,j) < 0.0_wp )  THEN
731                      c_w(k,j) = 0.0_wp
[106]732                   ELSEIF ( c_w(k,j) > c_max )  THEN
733                      c_w(k,j) = c_max
734                   ENDIF
735                ELSE
736                   c_w(k,j) = c_max
[75]737                ENDIF
[106]738
[978]739                c_u_m_l(k) = c_u_m_l(k) + c_u(k,j)
740                c_v_m_l(k) = c_v_m_l(k) + c_v(k,j)
741                c_w_m_l(k) = c_w_m_l(k) + c_w(k,j)
[106]742
[978]743             ENDDO
744          ENDDO
[75]745
[978]746#if defined( __parallel )   
747          IF ( collective_wait )  CALL MPI_BARRIER( comm1dy, ierr )
748          CALL MPI_ALLREDUCE( c_u_m_l(nzb+1), c_u_m(nzb+1), nzt-nzb, MPI_REAL, &
749                              MPI_SUM, comm1dy, ierr )   
750          IF ( collective_wait )  CALL MPI_BARRIER( comm1dy, ierr )
751          CALL MPI_ALLREDUCE( c_v_m_l(nzb+1), c_v_m(nzb+1), nzt-nzb, MPI_REAL, &
752                              MPI_SUM, comm1dy, ierr ) 
753          IF ( collective_wait )  CALL MPI_BARRIER( comm1dy, ierr )
754          CALL MPI_ALLREDUCE( c_w_m_l(nzb+1), c_w_m(nzb+1), nzt-nzb, MPI_REAL, &
755                              MPI_SUM, comm1dy, ierr ) 
756#else
757          c_u_m = c_u_m_l
758          c_v_m = c_v_m_l
759          c_w_m = c_w_m_l
760#endif
761
762          c_u_m = c_u_m / (ny+1)
763          c_v_m = c_v_m / (ny+1)
764          c_w_m = c_w_m / (ny+1)
765
[73]766!
[978]767!--       Save old timelevels for the next timestep
768          IF ( intermediate_timestep_count == 1 )  THEN
769                u_m_l(:,:,:) = u(:,:,1:2)
770                v_m_l(:,:,:) = v(:,:,0:1)
771                w_m_l(:,:,:) = w(:,:,0:1)
772          ENDIF
773
774!
775!--       Calculate the new velocities
[996]776          DO  k = nzb+1, nzt+1
[1113]777             DO  j = nysg, nyng
[978]778                u_p(k,j,0) = u(k,j,0) - dt_3d * tsc(2) * c_u_m(k) *            &
[106]779                                       ( u(k,j,0) - u(k,j,1) ) * ddx
[75]780
[978]781                v_p(k,j,-1) = v(k,j,-1) - dt_3d * tsc(2) * c_v_m(k) *          &
[75]782                                       ( v(k,j,-1) - v(k,j,0) ) * ddx
783
[978]784                w_p(k,j,-1) = w(k,j,-1) - dt_3d * tsc(2) * c_w_m(k) *          &
[75]785                                       ( w(k,j,-1) - w(k,j,0) ) * ddx
[978]786             ENDDO
[75]787          ENDDO
788
789!
[978]790!--       Bottom boundary at the outflow
791          IF ( ibc_uv_b == 0 )  THEN
[1353]792             u_p(nzb,:,0)  = 0.0_wp 
793             v_p(nzb,:,-1) = 0.0_wp
[4268]794          ELSE
[978]795             u_p(nzb,:,0)  =  u_p(nzb+1,:,0)
796             v_p(nzb,:,-1) =  v_p(nzb+1,:,-1)
797          ENDIF
[1353]798          w_p(nzb,:,-1) = 0.0_wp
[1]799
[75]800!
[978]801!--       Top boundary at the outflow
802          IF ( ibc_uv_t == 0 )  THEN
[1764]803             u_p(nzt+1,:,0)  = u_init(nzt+1)
[978]804             v_p(nzt+1,:,-1) = v_init(nzt+1)
805          ELSE
[1764]806             u_p(nzt+1,:,0)  = u_p(nzt,:,0)
[978]807             v_p(nzt+1,:,-1) = v_p(nzt,:,-1)
808          ENDIF
[1353]809          w_p(nzt:nzt+1,:,-1) = 0.0_wp
[978]810
[75]811       ENDIF
[73]812
[75]813    ENDIF
[73]814
[3182]815    IF ( bc_radiation_r )  THEN
[73]816
[1159]817       IF ( use_cmax )  THEN
818          u_p(:,:,nx+1) = u(:,:,nx)
819          v_p(:,:,nx+1) = v(:,:,nx)
[4268]820          w_p(:,:,nx+1) = w(:,:,nx)
[1159]821       ELSEIF ( .NOT. use_cmax )  THEN
[75]822
[978]823          c_max = dx / dt_3d
[75]824
[1353]825          c_u_m_l = 0.0_wp 
826          c_v_m_l = 0.0_wp
827          c_w_m_l = 0.0_wp
[978]828
[1353]829          c_u_m = 0.0_wp 
830          c_v_m = 0.0_wp
831          c_w_m = 0.0_wp
[978]832
[1]833!
[996]834!--       Calculate the phase speeds for u, v, and w, first local and then
835!--       average along the outflow boundary.
836          DO  k = nzb+1, nzt+1
837             DO  j = nys, nyn
[73]838
[106]839                denom = u_m_r(k,j,nx) - u_m_r(k,j,nx-1)
840
[1353]841                IF ( denom /= 0.0_wp )  THEN
[996]842                   c_u(k,j) = -c_max * ( u(k,j,nx) - u_m_r(k,j,nx) ) / ( denom * tsc(2) )
[1353]843                   IF ( c_u(k,j) < 0.0_wp )  THEN
844                      c_u(k,j) = 0.0_wp
[106]845                   ELSEIF ( c_u(k,j) > c_max )  THEN
846                      c_u(k,j) = c_max
847                   ENDIF
848                ELSE
849                   c_u(k,j) = c_max
[73]850                ENDIF
851
[106]852                denom = v_m_r(k,j,nx) - v_m_r(k,j,nx-1)
[73]853
[1353]854                IF ( denom /= 0.0_wp )  THEN
[996]855                   c_v(k,j) = -c_max * ( v(k,j,nx) - v_m_r(k,j,nx) ) / ( denom * tsc(2) )
[1353]856                   IF ( c_v(k,j) < 0.0_wp )  THEN
857                      c_v(k,j) = 0.0_wp
[106]858                   ELSEIF ( c_v(k,j) > c_max )  THEN
859                      c_v(k,j) = c_max
860                   ENDIF
861                ELSE
862                   c_v(k,j) = c_max
[73]863                ENDIF
864
[106]865                denom = w_m_r(k,j,nx) - w_m_r(k,j,nx-1)
[73]866
[1353]867                IF ( denom /= 0.0_wp )  THEN
[996]868                   c_w(k,j) = -c_max * ( w(k,j,nx) - w_m_r(k,j,nx) ) / ( denom * tsc(2) )
[1353]869                   IF ( c_w(k,j) < 0.0_wp )  THEN
870                      c_w(k,j) = 0.0_wp
[106]871                   ELSEIF ( c_w(k,j) > c_max )  THEN
872                      c_w(k,j) = c_max
873                   ENDIF
874                ELSE
875                   c_w(k,j) = c_max
[73]876                ENDIF
[106]877
[978]878                c_u_m_l(k) = c_u_m_l(k) + c_u(k,j)
879                c_v_m_l(k) = c_v_m_l(k) + c_v(k,j)
880                c_w_m_l(k) = c_w_m_l(k) + c_w(k,j)
[106]881
[978]882             ENDDO
883          ENDDO
[73]884
[978]885#if defined( __parallel )   
886          IF ( collective_wait )  CALL MPI_BARRIER( comm1dy, ierr )
887          CALL MPI_ALLREDUCE( c_u_m_l(nzb+1), c_u_m(nzb+1), nzt-nzb, MPI_REAL, &
888                              MPI_SUM, comm1dy, ierr )   
889          IF ( collective_wait )  CALL MPI_BARRIER( comm1dy, ierr )
890          CALL MPI_ALLREDUCE( c_v_m_l(nzb+1), c_v_m(nzb+1), nzt-nzb, MPI_REAL, &
891                              MPI_SUM, comm1dy, ierr ) 
892          IF ( collective_wait )  CALL MPI_BARRIER( comm1dy, ierr )
893          CALL MPI_ALLREDUCE( c_w_m_l(nzb+1), c_w_m(nzb+1), nzt-nzb, MPI_REAL, &
894                              MPI_SUM, comm1dy, ierr ) 
895#else
896          c_u_m = c_u_m_l
897          c_v_m = c_v_m_l
898          c_w_m = c_w_m_l
899#endif
900
901          c_u_m = c_u_m / (ny+1)
902          c_v_m = c_v_m / (ny+1)
903          c_w_m = c_w_m / (ny+1)
904
[73]905!
[978]906!--       Save old timelevels for the next timestep
907          IF ( intermediate_timestep_count == 1 )  THEN
908                u_m_r(:,:,:) = u(:,:,nx-1:nx)
909                v_m_r(:,:,:) = v(:,:,nx-1:nx)
910                w_m_r(:,:,:) = w(:,:,nx-1:nx)
911          ENDIF
[73]912
[978]913!
914!--       Calculate the new velocities
[996]915          DO  k = nzb+1, nzt+1
[1113]916             DO  j = nysg, nyng
[978]917                u_p(k,j,nx+1) = u(k,j,nx+1) - dt_3d * tsc(2) * c_u_m(k) *      &
918                                       ( u(k,j,nx+1) - u(k,j,nx) ) * ddx
[73]919
[978]920                v_p(k,j,nx+1) = v(k,j,nx+1) - dt_3d * tsc(2) * c_v_m(k) *      &
921                                       ( v(k,j,nx+1) - v(k,j,nx) ) * ddx
[73]922
[978]923                w_p(k,j,nx+1) = w(k,j,nx+1) - dt_3d * tsc(2) * c_w_m(k) *      &
924                                       ( w(k,j,nx+1) - w(k,j,nx) ) * ddx
925             ENDDO
[73]926          ENDDO
927
928!
[978]929!--       Bottom boundary at the outflow
930          IF ( ibc_uv_b == 0 )  THEN
[1353]931             u_p(nzb,:,nx+1) = 0.0_wp
932             v_p(nzb,:,nx+1) = 0.0_wp 
[4268]933          ELSE
[978]934             u_p(nzb,:,nx+1) =  u_p(nzb+1,:,nx+1)
935             v_p(nzb,:,nx+1) =  v_p(nzb+1,:,nx+1)
936          ENDIF
[1353]937          w_p(nzb,:,nx+1) = 0.0_wp
[73]938
939!
[978]940!--       Top boundary at the outflow
941          IF ( ibc_uv_t == 0 )  THEN
942             u_p(nzt+1,:,nx+1) = u_init(nzt+1)
943             v_p(nzt+1,:,nx+1) = v_init(nzt+1)
944          ELSE
945             u_p(nzt+1,:,nx+1) = u_p(nzt,:,nx+1)
946             v_p(nzt+1,:,nx+1) = v_p(nzt,:,nx+1)
947          ENDIF
[1742]948          w_p(nzt:nzt+1,:,nx+1) = 0.0_wp
[978]949
[1]950       ENDIF
951
952    ENDIF
[3864]953
[3467]954    IF ( salsa )  THEN
955       CALL salsa_boundary_conds
[3864]956    ENDIF
[1]957
958 END SUBROUTINE boundary_conds
Note: See TracBrowser for help on using the repository browser.