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

Last change on this file since 1409 was 1409, checked in by suehring, 10 years ago

Bugfix: set inflow boundary conditions also if no humidity or passive_scalar is used

  • Property svn:keywords set to Id
File size: 31.0 KB
Line 
1 SUBROUTINE boundary_conds
2
3!--------------------------------------------------------------------------------!
4! This file is part of PALM.
5!
6! PALM is free software: you can redistribute it and/or modify it under the terms
7! of the GNU General Public License as published by the Free Software Foundation,
8! either version 3 of the License, or (at your option) any later version.
9!
10! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
11! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13!
14! You should have received a copy of the GNU General Public License along with
15! PALM. If not, see <http://www.gnu.org/licenses/>.
16!
17! Copyright 1997-2014 Leibniz Universitaet Hannover
18!--------------------------------------------------------------------------------!
19!
20! Current revisions:
21! -----------------
22! Bugfix: set inflow boundary conditions also if no humidity or passive_scalar
23! is used.
24!
25! Former revisions:
26! -----------------
27! $Id: boundary_conds.f90 1409 2014-05-23 12:11:32Z suehring $
28!
29! 1398 2014-05-07 11:15:00Z heinze
30! Dirichlet-condition at the top for u and v changed to u_init and v_init also
31! for large_scale_forcing
32!
33! 1380 2014-04-28 12:40:45Z heinze
34! Adjust Dirichlet-condition at the top for pt in case of nudging
35!
36! 1361 2014-04-16 15:17:48Z hoffmann
37! Bottom and top boundary conditions of rain water content (qr) and
38! rain drop concentration (nr) changed to Dirichlet
39!
40! 1353 2014-04-08 15:21:23Z heinze
41! REAL constants provided with KIND-attribute
42
43! 1320 2014-03-20 08:40:49Z raasch
44! ONLY-attribute added to USE-statements,
45! kind-parameters added to all INTEGER and REAL declaration statements,
46! kinds are defined in new module kinds,
47! revision history before 2012 removed,
48! comment fields (!:) to be used for variable explanations added to
49! all variable declaration statements
50!
51! 1257 2013-11-08 15:18:40Z raasch
52! loop independent clauses added
53!
54! 1241 2013-10-30 11:36:58Z heinze
55! Adjust ug and vg at each timestep in case of large_scale_forcing
56!
57! 1159 2013-05-21 11:58:22Z fricke
58! Bugfix: Neumann boundary conditions for the velocity components at the
59! outflow are in fact radiation boundary conditions using the maximum phase
60! velocity that ensures numerical stability (CFL-condition).
61! Hence, logical operator use_cmax is now used instead of bc_lr_dirneu/_neudir.
62! Bugfix: In case of use_cmax at the outflow, u, v, w are replaced by
63! u_p, v_p, w_p 
64!
65! 1115 2013-03-26 18:16:16Z hoffmann
66! boundary conditions of two-moment cloud scheme are restricted to Neumann-
67! boundary-conditions
68!
69! 1113 2013-03-10 02:48:14Z raasch
70! GPU-porting
71! dummy argument "range" removed
72! Bugfix: wrong index in loops of radiation boundary condition
73!
74! 1053 2012-11-13 17:11:03Z hoffmann
75! boundary conditions for the two new prognostic equations (nr, qr) of the
76! two-moment cloud scheme
77!
78! 1036 2012-10-22 13:43:42Z raasch
79! code put under GPL (PALM 3.9)
80!
81! 996 2012-09-07 10:41:47Z raasch
82! little reformatting
83!
84! 978 2012-08-09 08:28:32Z fricke
85! Neumann boudnary conditions are added at the inflow boundary for the SGS-TKE.
86! Outflow boundary conditions for the velocity components can be set to Neumann
87! conditions or to radiation conditions with a horizontal averaged phase
88! velocity.
89!
90! 875 2012-04-02 15:35:15Z gryschka
91! Bugfix in case of dirichlet inflow bc at the right or north boundary
92!
93! Revision 1.1  1997/09/12 06:21:34  raasch
94! Initial revision
95!
96!
97! Description:
98! ------------
99! Boundary conditions for the prognostic quantities.
100! One additional bottom boundary condition is applied for the TKE (=(u*)**2)
101! in prandtl_fluxes. The cyclic lateral boundary conditions are implicitly
102! handled in routine exchange_horiz. Pressure boundary conditions are
103! explicitly set in routines pres, poisfft, poismg and sor.
104!------------------------------------------------------------------------------!
105
106    USE arrays_3d,                                                             &
107        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,  &
108               dzu, e_p, nr_p, pt, pt_p, q, q_p, qr_p, sa, sa_p,               &
109               u, ug, u_init, u_m_l, u_m_n, u_m_r, u_m_s, u_p,                 &
110               v, vg, v_init, v_m_l, v_m_n, v_m_r, v_m_s, v_p,                 &
111               w, w_p, w_m_l, w_m_n, w_m_r, w_m_s,&
112               pt_init
113
114    USE control_parameters,                                                    &
115        ONLY:  bc_pt_t_val, bc_q_t_val, constant_diffusion,                    &
116               cloud_physics, dt_3d, humidity,                                 &
117               ibc_pt_b, ibc_pt_t, ibc_q_b, ibc_sa_t, ibc_uv_b, ibc_uv_t,      &
118               icloud_scheme, inflow_l, inflow_n, inflow_r, inflow_s,          &
119               intermediate_timestep_count, large_scale_forcing, ocean,        &
120               outflow_l, outflow_n, outflow_r, outflow_s, passive_scalar,     &
121               precipitation, tsc, use_cmax, &
122               nudging
123
124    USE grid_variables,                                                        &
125        ONLY:  ddx, ddy, dx, dy
126
127    USE indices,                                                               &
128        ONLY:  nx, nxl, nxlg, nxr, nxrg, ny, nyn, nyng, nys, nysg,             &
129               nzb, nzb_s_inner, nzb_w_inner, nzt
130
131    USE kinds
132
133    USE pegrid
134
135
136    IMPLICIT NONE
137
138    INTEGER(iwp) ::  i !:
139    INTEGER(iwp) ::  j !:
140    INTEGER(iwp) ::  k !:
141
142    REAL(wp)    ::  c_max !:
143    REAL(wp)    ::  denom !:
144
145
146!
147!-- Bottom boundary
148    IF ( ibc_uv_b == 1 )  THEN
149       !$acc kernels present( u_p, v_p )
150       u_p(nzb,:,:) = u_p(nzb+1,:,:)
151       v_p(nzb,:,:) = v_p(nzb+1,:,:)
152       !$acc end kernels
153    ENDIF
154
155    !$acc kernels present( nzb_w_inner, w_p )
156    DO  i = nxlg, nxrg
157       DO  j = nysg, nyng
158          w_p(nzb_w_inner(j,i),j,i) = 0.0_wp
159       ENDDO
160    ENDDO
161    !$acc end kernels
162
163!
164!-- Top boundary
165    IF ( ibc_uv_t == 0 )  THEN
166       !$acc kernels present( u_init, u_p, v_init, v_p )
167        u_p(nzt+1,:,:) = u_init(nzt+1)
168        v_p(nzt+1,:,:) = v_init(nzt+1)
169       !$acc end kernels
170    ELSE
171       !$acc kernels present( u_p, v_p )
172        u_p(nzt+1,:,:) = u_p(nzt,:,:)
173        v_p(nzt+1,:,:) = v_p(nzt,:,:)
174       !$acc end kernels
175    ENDIF
176    !$acc kernels present( w_p )
177    w_p(nzt:nzt+1,:,:) = 0.0_wp  ! nzt is not a prognostic level (but cf. pres)
178    !$acc end kernels
179
180!
181!-- Temperature at bottom boundary.
182!-- In case of coupled runs (ibc_pt_b = 2) the temperature is given by
183!-- the sea surface temperature of the coupled ocean model.
184    IF ( ibc_pt_b == 0 )  THEN
185       !$acc kernels present( nzb_s_inner, pt, pt_p )
186       !$acc loop independent
187       DO  i = nxlg, nxrg
188          !$acc loop independent
189          DO  j = nysg, nyng
190             pt_p(nzb_s_inner(j,i),j,i) = pt(nzb_s_inner(j,i),j,i)
191          ENDDO
192       ENDDO
193       !$acc end kernels
194    ELSEIF ( ibc_pt_b == 1 )  THEN
195       !$acc kernels present( nzb_s_inner, pt_p )
196       !$acc loop independent
197       DO  i = nxlg, nxrg
198          !$acc loop independent
199          DO  j = nysg, nyng
200             pt_p(nzb_s_inner(j,i),j,i) = pt_p(nzb_s_inner(j,i)+1,j,i)
201          ENDDO
202       ENDDO
203      !$acc end kernels
204    ENDIF
205
206!
207!-- Temperature at top boundary
208    IF ( ibc_pt_t == 0 )  THEN
209       !$acc kernels present( pt, pt_p )
210        pt_p(nzt+1,:,:) = pt(nzt+1,:,:)
211!
212!--     In case of nudging adjust top boundary to pt which is
213!--     read in from NUDGING-DATA
214        IF ( nudging )  THEN
215           pt_p(nzt+1,:,:) = pt_init(nzt+1)
216        ENDIF
217       !$acc end kernels
218    ELSEIF ( ibc_pt_t == 1 )  THEN
219       !$acc kernels present( pt_p )
220        pt_p(nzt+1,:,:) = pt_p(nzt,:,:)
221       !$acc end kernels
222    ELSEIF ( ibc_pt_t == 2 )  THEN
223       !$acc kernels present( dzu, pt_p )
224        pt_p(nzt+1,:,:) = pt_p(nzt,:,:)   + bc_pt_t_val * dzu(nzt+1)
225       !$acc end kernels
226    ENDIF
227
228!
229!-- Boundary conditions for TKE
230!-- Generally Neumann conditions with de/dz=0 are assumed
231    IF ( .NOT. constant_diffusion )  THEN
232       !$acc kernels present( e_p, nzb_s_inner )
233       !$acc loop independent
234       DO  i = nxlg, nxrg
235          !$acc loop independent
236          DO  j = nysg, nyng
237             e_p(nzb_s_inner(j,i),j,i) = e_p(nzb_s_inner(j,i)+1,j,i)
238          ENDDO
239       ENDDO
240       e_p(nzt+1,:,:) = e_p(nzt,:,:)
241       !$acc end kernels
242    ENDIF
243
244!
245!-- Boundary conditions for salinity
246    IF ( ocean )  THEN
247!
248!--    Bottom boundary: Neumann condition because salinity flux is always
249!--    given
250       DO  i = nxlg, nxrg
251          DO  j = nysg, nyng
252             sa_p(nzb_s_inner(j,i),j,i) = sa_p(nzb_s_inner(j,i)+1,j,i)
253          ENDDO
254       ENDDO
255
256!
257!--    Top boundary: Dirichlet or Neumann
258       IF ( ibc_sa_t == 0 )  THEN
259           sa_p(nzt+1,:,:) = sa(nzt+1,:,:)
260       ELSEIF ( ibc_sa_t == 1 )  THEN
261           sa_p(nzt+1,:,:) = sa_p(nzt,:,:)
262       ENDIF
263
264    ENDIF
265
266!
267!-- Boundary conditions for total water content or scalar,
268!-- bottom and top boundary (see also temperature)
269    IF ( humidity  .OR.  passive_scalar )  THEN
270!
271!--    Surface conditions for constant_humidity_flux
272       IF ( ibc_q_b == 0 ) THEN
273          DO  i = nxlg, nxrg
274             DO  j = nysg, nyng
275                q_p(nzb_s_inner(j,i),j,i) = q(nzb_s_inner(j,i),j,i)
276             ENDDO
277          ENDDO
278       ELSE
279          DO  i = nxlg, nxrg
280             DO  j = nysg, nyng
281                q_p(nzb_s_inner(j,i),j,i) = q_p(nzb_s_inner(j,i)+1,j,i)
282             ENDDO
283          ENDDO
284       ENDIF
285!
286!--    Top boundary
287       q_p(nzt+1,:,:) = q_p(nzt,:,:)   + bc_q_t_val * dzu(nzt+1)
288
289       IF ( cloud_physics  .AND.  icloud_scheme == 0  .AND.  precipitation )  THEN
290!             
291!--       Surface conditions rain water (Dirichlet)
292          DO  i = nxlg, nxrg
293             DO  j = nysg, nyng
294                qr_p(nzb_s_inner(j,i),j,i) = 0.0_wp
295                nr_p(nzb_s_inner(j,i),j,i) = 0.0_wp
296             ENDDO
297          ENDDO
298!
299!--       Top boundary condition for rain water (Dirichlet)
300          qr_p(nzt+1,:,:) = 0.0_wp
301          nr_p(nzt+1,:,:) = 0.0_wp
302           
303       ENDIF
304    ENDIF
305!
306!-- In case of inflow at the south boundary the boundary for v is at nys
307!-- and in case of inflow at the left boundary the boundary for u is at nxl.
308!-- Since in prognostic_equations (cache optimized version) these levels are
309!-- handled as a prognostic level, boundary values have to be restored here.
310!-- For the SGS-TKE, Neumann boundary conditions are used at the inflow.
311    IF ( inflow_s )  THEN
312       v_p(:,nys,:) = v_p(:,nys-1,:)
313       IF ( .NOT. constant_diffusion ) e_p(:,nys-1,:) = e_p(:,nys,:)
314    ELSEIF ( inflow_n )  THEN
315       IF ( .NOT. constant_diffusion ) e_p(:,nyn+1,:) = e_p(:,nyn,:)
316    ELSEIF ( inflow_l ) THEN
317       u_p(:,:,nxl) = u_p(:,:,nxl-1)
318       IF ( .NOT. constant_diffusion ) e_p(:,:,nxl-1) = e_p(:,:,nxl)
319    ELSEIF ( inflow_r )  THEN
320       IF ( .NOT. constant_diffusion ) e_p(:,:,nxr+1) = e_p(:,:,nxr)
321    ENDIF
322
323!
324!-- Lateral boundary conditions for scalar quantities at the outflow
325    IF ( outflow_s )  THEN
326       pt_p(:,nys-1,:)     = pt_p(:,nys,:)
327       IF ( .NOT. constant_diffusion     )  e_p(:,nys-1,:) = e_p(:,nys,:)
328       IF ( humidity  .OR.  passive_scalar )  THEN
329          q_p(:,nys-1,:) = q_p(:,nys,:)
330          IF ( cloud_physics  .AND.  icloud_scheme == 0  .AND.              &
331               precipitation)  THEN
332             qr_p(:,nys-1,:) = qr_p(:,nys,:)
333             nr_p(:,nys-1,:) = nr_p(:,nys,:)
334          ENDIF
335       ENDIF
336    ELSEIF ( outflow_n )  THEN
337       pt_p(:,nyn+1,:)     = pt_p(:,nyn,:)
338       IF ( .NOT. constant_diffusion     )  e_p(:,nyn+1,:) = e_p(:,nyn,:)
339       IF ( humidity  .OR.  passive_scalar )  THEN
340          q_p(:,nyn+1,:) = q_p(:,nyn,:)
341          IF ( cloud_physics  .AND.  icloud_scheme == 0  .AND.              &
342               precipitation )  THEN
343             qr_p(:,nyn+1,:) = qr_p(:,nyn,:)
344             nr_p(:,nyn+1,:) = nr_p(:,nyn,:)
345          ENDIF
346       ENDIF
347    ELSEIF ( outflow_l )  THEN
348       pt_p(:,:,nxl-1)     = pt_p(:,:,nxl)
349       IF ( .NOT. constant_diffusion     )  e_p(:,:,nxl-1) = e_p(:,:,nxl)
350       IF ( humidity  .OR.  passive_scalar )  THEN
351          q_p(:,:,nxl-1) = q_p(:,:,nxl)
352          IF ( cloud_physics  .AND.  icloud_scheme == 0  .AND.              &
353               precipitation )  THEN
354             qr_p(:,:,nxl-1) = qr_p(:,:,nxl)
355             nr_p(:,:,nxl-1) = nr_p(:,:,nxl)
356          ENDIF
357       ENDIF
358    ELSEIF ( outflow_r )  THEN
359       pt_p(:,:,nxr+1)     = pt_p(:,:,nxr)
360       IF ( .NOT. constant_diffusion     )  e_p(:,:,nxr+1) = e_p(:,:,nxr)
361       IF ( humidity .OR. passive_scalar )  THEN
362          q_p(:,:,nxr+1) = q_p(:,:,nxr)
363          IF ( cloud_physics  .AND.  icloud_scheme == 0  .AND.  precipitation )  THEN
364             qr_p(:,:,nxr+1) = qr_p(:,:,nxr)
365             nr_p(:,:,nxr+1) = nr_p(:,:,nxr)
366          ENDIF
367       ENDIF
368    ENDIF
369
370!
371!-- Radiation boundary conditions for the velocities at the respective outflow.
372!-- The phase velocity is either assumed to the maximum phase velocity that
373!-- ensures numerical stability (CFL-condition) or calculated after
374!-- Orlanski(1976) and averaged along the outflow boundary.
375    IF ( outflow_s )  THEN
376
377       IF ( use_cmax )  THEN
378          u_p(:,-1,:) = u(:,0,:)
379          v_p(:,0,:)  = v(:,1,:)
380          w_p(:,-1,:) = w(:,0,:)         
381       ELSEIF ( .NOT. use_cmax )  THEN
382
383          c_max = dy / dt_3d
384
385          c_u_m_l = 0.0_wp 
386          c_v_m_l = 0.0_wp
387          c_w_m_l = 0.0_wp
388
389          c_u_m = 0.0_wp 
390          c_v_m = 0.0_wp
391          c_w_m = 0.0_wp
392
393!
394!--       Calculate the phase speeds for u, v, and w, first local and then
395!--       average along the outflow boundary.
396          DO  k = nzb+1, nzt+1
397             DO  i = nxl, nxr
398
399                denom = u_m_s(k,0,i) - u_m_s(k,1,i)
400
401                IF ( denom /= 0.0_wp )  THEN
402                   c_u(k,i) = -c_max * ( u(k,0,i) - u_m_s(k,0,i) ) / ( denom * tsc(2) )
403                   IF ( c_u(k,i) < 0.0_wp )  THEN
404                      c_u(k,i) = 0.0_wp
405                   ELSEIF ( c_u(k,i) > c_max )  THEN
406                      c_u(k,i) = c_max
407                   ENDIF
408                ELSE
409                   c_u(k,i) = c_max
410                ENDIF
411
412                denom = v_m_s(k,1,i) - v_m_s(k,2,i)
413
414                IF ( denom /= 0.0_wp )  THEN
415                   c_v(k,i) = -c_max * ( v(k,1,i) - v_m_s(k,1,i) ) / ( denom * tsc(2) )
416                   IF ( c_v(k,i) < 0.0_wp )  THEN
417                      c_v(k,i) = 0.0_wp
418                   ELSEIF ( c_v(k,i) > c_max )  THEN
419                      c_v(k,i) = c_max
420                   ENDIF
421                ELSE
422                   c_v(k,i) = c_max
423                ENDIF
424
425                denom = w_m_s(k,0,i) - w_m_s(k,1,i)
426
427                IF ( denom /= 0.0_wp )  THEN
428                   c_w(k,i) = -c_max * ( w(k,0,i) - w_m_s(k,0,i) ) / ( denom * tsc(2) )
429                   IF ( c_w(k,i) < 0.0_wp )  THEN
430                      c_w(k,i) = 0.0_wp
431                   ELSEIF ( c_w(k,i) > c_max )  THEN
432                      c_w(k,i) = c_max
433                   ENDIF
434                ELSE
435                   c_w(k,i) = c_max
436                ENDIF
437
438                c_u_m_l(k) = c_u_m_l(k) + c_u(k,i)
439                c_v_m_l(k) = c_v_m_l(k) + c_v(k,i)
440                c_w_m_l(k) = c_w_m_l(k) + c_w(k,i)
441
442             ENDDO
443          ENDDO
444
445#if defined( __parallel )   
446          IF ( collective_wait )  CALL MPI_BARRIER( comm1dx, ierr )
447          CALL MPI_ALLREDUCE( c_u_m_l(nzb+1), c_u_m(nzb+1), nzt-nzb, MPI_REAL, &
448                              MPI_SUM, comm1dx, ierr )   
449          IF ( collective_wait )  CALL MPI_BARRIER( comm1dx, ierr )
450          CALL MPI_ALLREDUCE( c_v_m_l(nzb+1), c_v_m(nzb+1), nzt-nzb, MPI_REAL, &
451                              MPI_SUM, comm1dx, ierr ) 
452          IF ( collective_wait )  CALL MPI_BARRIER( comm1dx, ierr )
453          CALL MPI_ALLREDUCE( c_w_m_l(nzb+1), c_w_m(nzb+1), nzt-nzb, MPI_REAL, &
454                              MPI_SUM, comm1dx, ierr ) 
455#else
456          c_u_m = c_u_m_l
457          c_v_m = c_v_m_l
458          c_w_m = c_w_m_l
459#endif
460
461          c_u_m = c_u_m / (nx+1)
462          c_v_m = c_v_m / (nx+1)
463          c_w_m = c_w_m / (nx+1)
464
465!
466!--       Save old timelevels for the next timestep
467          IF ( intermediate_timestep_count == 1 )  THEN
468             u_m_s(:,:,:) = u(:,0:1,:)
469             v_m_s(:,:,:) = v(:,1:2,:)
470             w_m_s(:,:,:) = w(:,0:1,:)
471          ENDIF
472
473!
474!--       Calculate the new velocities
475          DO  k = nzb+1, nzt+1
476             DO  i = nxlg, nxrg
477                u_p(k,-1,i) = u(k,-1,i) - dt_3d * tsc(2) * c_u_m(k) *          &
478                                       ( u(k,-1,i) - u(k,0,i) ) * ddy
479
480                v_p(k,0,i)  = v(k,0,i)  - dt_3d * tsc(2) * c_v_m(k) *          &
481                                       ( v(k,0,i) - v(k,1,i) ) * ddy
482
483                w_p(k,-1,i) = w(k,-1,i) - dt_3d * tsc(2) * c_w_m(k) *          &
484                                       ( w(k,-1,i) - w(k,0,i) ) * ddy
485             ENDDO
486          ENDDO
487
488!
489!--       Bottom boundary at the outflow
490          IF ( ibc_uv_b == 0 )  THEN
491             u_p(nzb,-1,:) = 0.0_wp 
492             v_p(nzb,0,:)  = 0.0_wp 
493          ELSE                   
494             u_p(nzb,-1,:) =  u_p(nzb+1,-1,:)
495             v_p(nzb,0,:)  =  v_p(nzb+1,0,:)
496          ENDIF
497          w_p(nzb,-1,:) = 0.0_wp
498
499!
500!--       Top boundary at the outflow
501          IF ( ibc_uv_t == 0 )  THEN
502             u_p(nzt+1,-1,:) = u_init(nzt+1)
503             v_p(nzt+1,0,:)  = v_init(nzt+1)
504          ELSE
505             u_p(nzt+1,-1,:) = u(nzt,-1,:)
506             v_p(nzt+1,0,:)  = v(nzt,0,:)
507          ENDIF
508          w_p(nzt:nzt+1,-1,:) = 0.0_wp
509
510       ENDIF
511
512    ENDIF
513
514    IF ( outflow_n )  THEN
515
516       IF ( use_cmax )  THEN
517          u_p(:,ny+1,:) = u(:,ny,:)
518          v_p(:,ny+1,:) = v(:,ny,:)
519          w_p(:,ny+1,:) = w(:,ny,:)         
520       ELSEIF ( .NOT. use_cmax )  THEN
521
522          c_max = dy / dt_3d
523
524          c_u_m_l = 0.0_wp 
525          c_v_m_l = 0.0_wp
526          c_w_m_l = 0.0_wp
527
528          c_u_m = 0.0_wp 
529          c_v_m = 0.0_wp
530          c_w_m = 0.0_wp
531
532!
533!--       Calculate the phase speeds for u, v, and w, first local and then
534!--       average along the outflow boundary.
535          DO  k = nzb+1, nzt+1
536             DO  i = nxl, nxr
537
538                denom = u_m_n(k,ny,i) - u_m_n(k,ny-1,i)
539
540                IF ( denom /= 0.0_wp )  THEN
541                   c_u(k,i) = -c_max * ( u(k,ny,i) - u_m_n(k,ny,i) ) / ( denom * tsc(2) )
542                   IF ( c_u(k,i) < 0.0_wp )  THEN
543                      c_u(k,i) = 0.0_wp
544                   ELSEIF ( c_u(k,i) > c_max )  THEN
545                      c_u(k,i) = c_max
546                   ENDIF
547                ELSE
548                   c_u(k,i) = c_max
549                ENDIF
550
551                denom = v_m_n(k,ny,i) - v_m_n(k,ny-1,i)
552
553                IF ( denom /= 0.0_wp )  THEN
554                   c_v(k,i) = -c_max * ( v(k,ny,i) - v_m_n(k,ny,i) ) / ( denom * tsc(2) )
555                   IF ( c_v(k,i) < 0.0_wp )  THEN
556                      c_v(k,i) = 0.0_wp
557                   ELSEIF ( c_v(k,i) > c_max )  THEN
558                      c_v(k,i) = c_max
559                   ENDIF
560                ELSE
561                   c_v(k,i) = c_max
562                ENDIF
563
564                denom = w_m_n(k,ny,i) - w_m_n(k,ny-1,i)
565
566                IF ( denom /= 0.0_wp )  THEN
567                   c_w(k,i) = -c_max * ( w(k,ny,i) - w_m_n(k,ny,i) ) / ( denom * tsc(2) )
568                   IF ( c_w(k,i) < 0.0_wp )  THEN
569                      c_w(k,i) = 0.0_wp
570                   ELSEIF ( c_w(k,i) > c_max )  THEN
571                      c_w(k,i) = c_max
572                   ENDIF
573                ELSE
574                   c_w(k,i) = c_max
575                ENDIF
576
577                c_u_m_l(k) = c_u_m_l(k) + c_u(k,i)
578                c_v_m_l(k) = c_v_m_l(k) + c_v(k,i)
579                c_w_m_l(k) = c_w_m_l(k) + c_w(k,i)
580
581             ENDDO
582          ENDDO
583
584#if defined( __parallel )   
585          IF ( collective_wait )  CALL MPI_BARRIER( comm1dx, ierr )
586          CALL MPI_ALLREDUCE( c_u_m_l(nzb+1), c_u_m(nzb+1), nzt-nzb, MPI_REAL, &
587                              MPI_SUM, comm1dx, ierr )   
588          IF ( collective_wait )  CALL MPI_BARRIER( comm1dx, ierr )
589          CALL MPI_ALLREDUCE( c_v_m_l(nzb+1), c_v_m(nzb+1), nzt-nzb, MPI_REAL, &
590                              MPI_SUM, comm1dx, ierr ) 
591          IF ( collective_wait )  CALL MPI_BARRIER( comm1dx, ierr )
592          CALL MPI_ALLREDUCE( c_w_m_l(nzb+1), c_w_m(nzb+1), nzt-nzb, MPI_REAL, &
593                              MPI_SUM, comm1dx, ierr ) 
594#else
595          c_u_m = c_u_m_l
596          c_v_m = c_v_m_l
597          c_w_m = c_w_m_l
598#endif
599
600          c_u_m = c_u_m / (nx+1)
601          c_v_m = c_v_m / (nx+1)
602          c_w_m = c_w_m / (nx+1)
603
604!
605!--       Save old timelevels for the next timestep
606          IF ( intermediate_timestep_count == 1 )  THEN
607                u_m_n(:,:,:) = u(:,ny-1:ny,:)
608                v_m_n(:,:,:) = v(:,ny-1:ny,:)
609                w_m_n(:,:,:) = w(:,ny-1:ny,:)
610          ENDIF
611
612!
613!--       Calculate the new velocities
614          DO  k = nzb+1, nzt+1
615             DO  i = nxlg, nxrg
616                u_p(k,ny+1,i) = u(k,ny+1,i) - dt_3d * tsc(2) * c_u_m(k) *      &
617                                       ( u(k,ny+1,i) - u(k,ny,i) ) * ddy
618
619                v_p(k,ny+1,i) = v(k,ny+1,i)  - dt_3d * tsc(2) * c_v_m(k) *     &
620                                       ( v(k,ny+1,i) - v(k,ny,i) ) * ddy
621
622                w_p(k,ny+1,i) = w(k,ny+1,i) - dt_3d * tsc(2) * c_w_m(k) *      &
623                                       ( w(k,ny+1,i) - w(k,ny,i) ) * ddy
624             ENDDO
625          ENDDO
626
627!
628!--       Bottom boundary at the outflow
629          IF ( ibc_uv_b == 0 )  THEN
630             u_p(nzb,ny+1,:) = 0.0_wp
631             v_p(nzb,ny+1,:) = 0.0_wp   
632          ELSE                   
633             u_p(nzb,ny+1,:) =  u_p(nzb+1,ny+1,:)
634             v_p(nzb,ny+1,:) =  v_p(nzb+1,ny+1,:)
635          ENDIF
636          w_p(nzb,ny+1,:) = 0.0_wp
637
638!
639!--       Top boundary at the outflow
640          IF ( ibc_uv_t == 0 )  THEN
641             u_p(nzt+1,ny+1,:) = u_init(nzt+1)
642             v_p(nzt+1,ny+1,:) = v_init(nzt+1)
643          ELSE
644             u_p(nzt+1,ny+1,:) = u_p(nzt,nyn+1,:)
645             v_p(nzt+1,ny+1,:) = v_p(nzt,nyn+1,:)
646          ENDIF
647          w_p(nzt:nzt+1,ny+1,:) = 0.0_wp
648
649       ENDIF
650
651    ENDIF
652
653    IF ( outflow_l )  THEN
654
655       IF ( use_cmax )  THEN
656          u_p(:,:,-1) = u(:,:,0)
657          v_p(:,:,0)  = v(:,:,1)
658          w_p(:,:,-1) = w(:,:,0)         
659       ELSEIF ( .NOT. use_cmax )  THEN
660
661          c_max = dx / dt_3d
662
663          c_u_m_l = 0.0_wp 
664          c_v_m_l = 0.0_wp
665          c_w_m_l = 0.0_wp
666
667          c_u_m = 0.0_wp 
668          c_v_m = 0.0_wp
669          c_w_m = 0.0_wp
670
671!
672!--       Calculate the phase speeds for u, v, and w, first local and then
673!--       average along the outflow boundary.
674          DO  k = nzb+1, nzt+1
675             DO  j = nys, nyn
676
677                denom = u_m_l(k,j,1) - u_m_l(k,j,2)
678
679                IF ( denom /= 0.0_wp )  THEN
680                   c_u(k,j) = -c_max * ( u(k,j,1) - u_m_l(k,j,1) ) / ( denom * tsc(2) )
681                   IF ( c_u(k,j) < 0.0_wp )  THEN
682                      c_u(k,j) = 0.0_wp
683                   ELSEIF ( c_u(k,j) > c_max )  THEN
684                      c_u(k,j) = c_max
685                   ENDIF
686                ELSE
687                   c_u(k,j) = c_max
688                ENDIF
689
690                denom = v_m_l(k,j,0) - v_m_l(k,j,1)
691
692                IF ( denom /= 0.0_wp )  THEN
693                   c_v(k,j) = -c_max * ( v(k,j,0) - v_m_l(k,j,0) ) / ( denom * tsc(2) )
694                   IF ( c_v(k,j) < 0.0_wp )  THEN
695                      c_v(k,j) = 0.0_wp
696                   ELSEIF ( c_v(k,j) > c_max )  THEN
697                      c_v(k,j) = c_max
698                   ENDIF
699                ELSE
700                   c_v(k,j) = c_max
701                ENDIF
702
703                denom = w_m_l(k,j,0) - w_m_l(k,j,1)
704
705                IF ( denom /= 0.0_wp )  THEN
706                   c_w(k,j) = -c_max * ( w(k,j,0) - w_m_l(k,j,0) ) / ( denom * tsc(2) )
707                   IF ( c_w(k,j) < 0.0_wp )  THEN
708                      c_w(k,j) = 0.0_wp
709                   ELSEIF ( c_w(k,j) > c_max )  THEN
710                      c_w(k,j) = c_max
711                   ENDIF
712                ELSE
713                   c_w(k,j) = c_max
714                ENDIF
715
716                c_u_m_l(k) = c_u_m_l(k) + c_u(k,j)
717                c_v_m_l(k) = c_v_m_l(k) + c_v(k,j)
718                c_w_m_l(k) = c_w_m_l(k) + c_w(k,j)
719
720             ENDDO
721          ENDDO
722
723#if defined( __parallel )   
724          IF ( collective_wait )  CALL MPI_BARRIER( comm1dy, ierr )
725          CALL MPI_ALLREDUCE( c_u_m_l(nzb+1), c_u_m(nzb+1), nzt-nzb, MPI_REAL, &
726                              MPI_SUM, comm1dy, ierr )   
727          IF ( collective_wait )  CALL MPI_BARRIER( comm1dy, ierr )
728          CALL MPI_ALLREDUCE( c_v_m_l(nzb+1), c_v_m(nzb+1), nzt-nzb, MPI_REAL, &
729                              MPI_SUM, comm1dy, ierr ) 
730          IF ( collective_wait )  CALL MPI_BARRIER( comm1dy, ierr )
731          CALL MPI_ALLREDUCE( c_w_m_l(nzb+1), c_w_m(nzb+1), nzt-nzb, MPI_REAL, &
732                              MPI_SUM, comm1dy, ierr ) 
733#else
734          c_u_m = c_u_m_l
735          c_v_m = c_v_m_l
736          c_w_m = c_w_m_l
737#endif
738
739          c_u_m = c_u_m / (ny+1)
740          c_v_m = c_v_m / (ny+1)
741          c_w_m = c_w_m / (ny+1)
742
743!
744!--       Save old timelevels for the next timestep
745          IF ( intermediate_timestep_count == 1 )  THEN
746                u_m_l(:,:,:) = u(:,:,1:2)
747                v_m_l(:,:,:) = v(:,:,0:1)
748                w_m_l(:,:,:) = w(:,:,0:1)
749          ENDIF
750
751!
752!--       Calculate the new velocities
753          DO  k = nzb+1, nzt+1
754             DO  j = nysg, nyng
755                u_p(k,j,0) = u(k,j,0) - dt_3d * tsc(2) * c_u_m(k) *            &
756                                       ( u(k,j,0) - u(k,j,1) ) * ddx
757
758                v_p(k,j,-1) = v(k,j,-1) - dt_3d * tsc(2) * c_v_m(k) *          &
759                                       ( v(k,j,-1) - v(k,j,0) ) * ddx
760
761                w_p(k,j,-1) = w(k,j,-1) - dt_3d * tsc(2) * c_w_m(k) *          &
762                                       ( w(k,j,-1) - w(k,j,0) ) * ddx
763             ENDDO
764          ENDDO
765
766!
767!--       Bottom boundary at the outflow
768          IF ( ibc_uv_b == 0 )  THEN
769             u_p(nzb,:,0)  = 0.0_wp 
770             v_p(nzb,:,-1) = 0.0_wp
771          ELSE                   
772             u_p(nzb,:,0)  =  u_p(nzb+1,:,0)
773             v_p(nzb,:,-1) =  v_p(nzb+1,:,-1)
774          ENDIF
775          w_p(nzb,:,-1) = 0.0_wp
776
777!
778!--       Top boundary at the outflow
779          IF ( ibc_uv_t == 0 )  THEN
780             u_p(nzt+1,:,-1) = u_init(nzt+1)
781             v_p(nzt+1,:,-1) = v_init(nzt+1)
782          ELSE
783             u_p(nzt+1,:,-1) = u_p(nzt,:,-1)
784             v_p(nzt+1,:,-1) = v_p(nzt,:,-1)
785          ENDIF
786          w_p(nzt:nzt+1,:,-1) = 0.0_wp
787
788       ENDIF
789
790    ENDIF
791
792    IF ( outflow_r )  THEN
793
794       IF ( use_cmax )  THEN
795          u_p(:,:,nx+1) = u(:,:,nx)
796          v_p(:,:,nx+1) = v(:,:,nx)
797          w_p(:,:,nx+1) = w(:,:,nx)         
798       ELSEIF ( .NOT. use_cmax )  THEN
799
800          c_max = dx / dt_3d
801
802          c_u_m_l = 0.0_wp 
803          c_v_m_l = 0.0_wp
804          c_w_m_l = 0.0_wp
805
806          c_u_m = 0.0_wp 
807          c_v_m = 0.0_wp
808          c_w_m = 0.0_wp
809
810!
811!--       Calculate the phase speeds for u, v, and w, first local and then
812!--       average along the outflow boundary.
813          DO  k = nzb+1, nzt+1
814             DO  j = nys, nyn
815
816                denom = u_m_r(k,j,nx) - u_m_r(k,j,nx-1)
817
818                IF ( denom /= 0.0_wp )  THEN
819                   c_u(k,j) = -c_max * ( u(k,j,nx) - u_m_r(k,j,nx) ) / ( denom * tsc(2) )
820                   IF ( c_u(k,j) < 0.0_wp )  THEN
821                      c_u(k,j) = 0.0_wp
822                   ELSEIF ( c_u(k,j) > c_max )  THEN
823                      c_u(k,j) = c_max
824                   ENDIF
825                ELSE
826                   c_u(k,j) = c_max
827                ENDIF
828
829                denom = v_m_r(k,j,nx) - v_m_r(k,j,nx-1)
830
831                IF ( denom /= 0.0_wp )  THEN
832                   c_v(k,j) = -c_max * ( v(k,j,nx) - v_m_r(k,j,nx) ) / ( denom * tsc(2) )
833                   IF ( c_v(k,j) < 0.0_wp )  THEN
834                      c_v(k,j) = 0.0_wp
835                   ELSEIF ( c_v(k,j) > c_max )  THEN
836                      c_v(k,j) = c_max
837                   ENDIF
838                ELSE
839                   c_v(k,j) = c_max
840                ENDIF
841
842                denom = w_m_r(k,j,nx) - w_m_r(k,j,nx-1)
843
844                IF ( denom /= 0.0_wp )  THEN
845                   c_w(k,j) = -c_max * ( w(k,j,nx) - w_m_r(k,j,nx) ) / ( denom * tsc(2) )
846                   IF ( c_w(k,j) < 0.0_wp )  THEN
847                      c_w(k,j) = 0.0_wp
848                   ELSEIF ( c_w(k,j) > c_max )  THEN
849                      c_w(k,j) = c_max
850                   ENDIF
851                ELSE
852                   c_w(k,j) = c_max
853                ENDIF
854
855                c_u_m_l(k) = c_u_m_l(k) + c_u(k,j)
856                c_v_m_l(k) = c_v_m_l(k) + c_v(k,j)
857                c_w_m_l(k) = c_w_m_l(k) + c_w(k,j)
858
859             ENDDO
860          ENDDO
861
862#if defined( __parallel )   
863          IF ( collective_wait )  CALL MPI_BARRIER( comm1dy, ierr )
864          CALL MPI_ALLREDUCE( c_u_m_l(nzb+1), c_u_m(nzb+1), nzt-nzb, MPI_REAL, &
865                              MPI_SUM, comm1dy, ierr )   
866          IF ( collective_wait )  CALL MPI_BARRIER( comm1dy, ierr )
867          CALL MPI_ALLREDUCE( c_v_m_l(nzb+1), c_v_m(nzb+1), nzt-nzb, MPI_REAL, &
868                              MPI_SUM, comm1dy, ierr ) 
869          IF ( collective_wait )  CALL MPI_BARRIER( comm1dy, ierr )
870          CALL MPI_ALLREDUCE( c_w_m_l(nzb+1), c_w_m(nzb+1), nzt-nzb, MPI_REAL, &
871                              MPI_SUM, comm1dy, ierr ) 
872#else
873          c_u_m = c_u_m_l
874          c_v_m = c_v_m_l
875          c_w_m = c_w_m_l
876#endif
877
878          c_u_m = c_u_m / (ny+1)
879          c_v_m = c_v_m / (ny+1)
880          c_w_m = c_w_m / (ny+1)
881
882!
883!--       Save old timelevels for the next timestep
884          IF ( intermediate_timestep_count == 1 )  THEN
885                u_m_r(:,:,:) = u(:,:,nx-1:nx)
886                v_m_r(:,:,:) = v(:,:,nx-1:nx)
887                w_m_r(:,:,:) = w(:,:,nx-1:nx)
888          ENDIF
889
890!
891!--       Calculate the new velocities
892          DO  k = nzb+1, nzt+1
893             DO  j = nysg, nyng
894                u_p(k,j,nx+1) = u(k,j,nx+1) - dt_3d * tsc(2) * c_u_m(k) *      &
895                                       ( u(k,j,nx+1) - u(k,j,nx) ) * ddx
896
897                v_p(k,j,nx+1) = v(k,j,nx+1) - dt_3d * tsc(2) * c_v_m(k) *      &
898                                       ( v(k,j,nx+1) - v(k,j,nx) ) * ddx
899
900                w_p(k,j,nx+1) = w(k,j,nx+1) - dt_3d * tsc(2) * c_w_m(k) *      &
901                                       ( w(k,j,nx+1) - w(k,j,nx) ) * ddx
902             ENDDO
903          ENDDO
904
905!
906!--       Bottom boundary at the outflow
907          IF ( ibc_uv_b == 0 )  THEN
908             u_p(nzb,:,nx+1) = 0.0_wp
909             v_p(nzb,:,nx+1) = 0.0_wp 
910          ELSE                   
911             u_p(nzb,:,nx+1) =  u_p(nzb+1,:,nx+1)
912             v_p(nzb,:,nx+1) =  v_p(nzb+1,:,nx+1)
913          ENDIF
914          w_p(nzb,:,nx+1) = 0.0_wp
915
916!
917!--       Top boundary at the outflow
918          IF ( ibc_uv_t == 0 )  THEN
919             u_p(nzt+1,:,nx+1) = u_init(nzt+1)
920             v_p(nzt+1,:,nx+1) = v_init(nzt+1)
921          ELSE
922             u_p(nzt+1,:,nx+1) = u_p(nzt,:,nx+1)
923             v_p(nzt+1,:,nx+1) = v_p(nzt,:,nx+1)
924          ENDIF
925          w(nzt:nzt+1,:,nx+1) = 0.0_wp
926
927       ENDIF
928
929    ENDIF
930
931 END SUBROUTINE boundary_conds
Note: See TracBrowser for help on using the repository browser.