source: palm/trunk/SOURCE/pres.f90 @ 707

Last change on this file since 707 was 707, checked in by raasch, 13 years ago

New:
---

In case of multigrid method, on coarse grid levels, gathered data are
identically processed on all PEs (before, on PE0 only), so that the subsequent
scattering of data is not neccessary any more. (modules, init_pegrid, poismg)

Changed:


Calculation of weighted average of p is now handled in the same way
regardless of the number of ghost layers (advection scheme). (pres)

multigrid and sor method are using p_loc for iterative
advancements of pressure. p_sub removed. (init_3d_model, modules, poismg, pres, sor)

bc_lr and bc_ns replaced by bc_lr_dirrad, bc_lr_raddir, bc_ns_dirrad, bc_ns_raddir
for speed optimization. (calc_spectra, check_parameters, exchange_horiz,
exchange_horiz_2d, header, init_3d_model, init_grid, init_pegrid, modules,
poismg, pres, sor, time_integration, timestep)

grid_level directly used as index for MPI data type arrays. (exchange_horiz,
poismg)

initial assignments of zero to array p for iterative solvers only (init_3d_model)

Errors:


localsum calculation modified for proper OpenMP reduction. (pres)

Bugfix: bottom (nzb) and top (nzt+1) boundary conditions set in routines
resid and restrict. They were missed before, which may have led to
unpredictable results. (poismg)

  • Property svn:keywords set to Id
File size: 22.2 KB
RevLine 
[1]1 SUBROUTINE pres
2
3!------------------------------------------------------------------------------!
[484]4! Current revisions:
[1]5! -----------------
[707]6! Calculation of weighted average of p is now handled in the same way
7! regardless of the number of ghost layers (advection scheme),
8! multigrid and sor method are using p_loc for iterative advancements of
9! pressure,
10! localsum calculation modified for proper OpenMP reduction,
11! bc_lr/ns replaced by bc_lr/ns_cyc
[674]12!
[668]13! Former revisions:
14! -----------------
[694]15! $Id: pres.f90 707 2011-03-29 11:39:40Z raasch $
16!
17! 693 2011-03-08 09:..:..Z raasch
[695]18! bugfix: weighting coefficient added to ibm branch
[694]19!
20! 680 2011-02-04 23:16:06Z gryschka
[681]21! bugfix: collective_wait
[668]22!
[676]23! 675 2011-01-19 10:56:55Z suehring
24! Removed bugfix while copying tend.
25!
[674]26! 673 2011-01-18 16:19:48Z suehring
27! Weighting coefficients added for right computation of the pressure during
28! Runge-Kutta substeps.
29!
[668]30! 667 2010-12-23 12:06:00Z suehring/gryschka
[667]31! New allocation of tend when ws-scheme and multigrid is used. This is due to
32! reasons of perforance of the data_exchange. The same is done with p after
33! poismg is called.
34! nxl-1, nxr+1, nys-1, nyn+1 replaced by nxlg, nxrg, nysg, nyng when no
35! multigrid is used. Calls of exchange_horiz are modified.
36! bugfix: After pressure correction no volume flow correction in case of
37! non-cyclic boundary conditions
38! (has to be done only before pressure correction)
39! Call of SOR routine is referenced with ddzu_pres.
40!
[623]41! 622 2010-12-10 08:08:13Z raasch
42! optional barriers included in order to speed up collective operations
43!
[198]44! 151 2008-03-07 13:42:18Z raasch
45! Bugfix in volume flow control for non-cyclic boundary conditions
46!
[110]47! 106 2007-08-16 14:30:26Z raasch
48! Volume flow conservation added for the remaining three outflow boundaries
49!
[90]50! 85 2007-05-11 09:35:14Z raasch
51! Division through dt_3d replaced by multiplication of the inverse.
52! For performance optimisation, this is done in the loop calculating the
53! divergence instead of using a seperate loop.
54!
[77]55! 75 2007-03-22 09:54:05Z raasch
[75]56! Volume flow control for non-cyclic boundary conditions added (currently only
[76]57! for the north boundary!!), 2nd+3rd argument removed from exchange horiz,
58! mean vertical velocity is removed in case of Neumann boundary conditions
59! both at the bottom and the top
[1]60!
[3]61! RCS Log replace by Id keyword, revision history cleaned up
62!
[1]63! Revision 1.25  2006/04/26 13:26:12  raasch
64! OpenMP optimization (+localsum, threadsum)
65!
66! Revision 1.1  1997/07/24 11:24:44  raasch
67! Initial revision
68!
69!
70! Description:
71! ------------
72! Compute the divergence of the provisional velocity field. Solve the Poisson
73! equation for the perturbation pressure. Compute the final velocities using
74! this perturbation pressure. Compute the remaining divergence.
75!------------------------------------------------------------------------------!
76
77    USE arrays_3d
78    USE constants
79    USE control_parameters
80    USE cpulog
81    USE grid_variables
82    USE indices
83    USE interfaces
84    USE pegrid
85    USE poisfft_mod
86    USE poisfft_hybrid_mod
87    USE statistics
88
89    IMPLICIT NONE
90
91    INTEGER ::  i, j, k, sr
92
[673]93    REAL    ::  ddt_3d, localsum, threadsum, d_weight_pres
[1]94
95    REAL, DIMENSION(1:2) ::  volume_flow_l, volume_flow_offset
[76]96    REAL, DIMENSION(1:nzt) ::  w_l, w_l_l
[1]97
98
99    CALL cpu_log( log_point(8), 'pres', 'start' )
100
[85]101
102    ddt_3d = 1.0 / dt_3d
[673]103    d_weight_pres = 1. / weight_pres(intermediate_timestep_count)
[85]104
[1]105!
[707]106!-- Multigrid method expects array d to have one ghost layer.
107!--
[1]108    IF ( psolver == 'multigrid' )  THEN
[667]109     
[1]110       DEALLOCATE( d )
[667]111       ALLOCATE( d(nzb:nzt+1,nys-1:nyn+1,nxl-1:nxr+1) ) 
[707]112
113!
114!--    Since p is later used to hold the weighted average of the substeps, it
115!--    cannot be used in the iterative solver. Therefore, its initial value is
116!--    stored on p_loc, which is then iteratively advanced in every substep.
117       IF ( intermediate_timestep_count == 1 )  THEN
118          DO  i = nxl-1, nxr+1
119             DO  j = nys-1, nyn+1
120                DO  k = nzb, nzt+1
121                   p_loc(k,j,i) = p(k,j,i)
122                ENDDO
123             ENDDO
124          ENDDO
[667]125       ENDIF
126       
[707]127    ELSEIF ( psolver == 'sor'  .AND.  intermediate_timestep_count == 1 )  THEN
128
129!
130!--    Since p is later used to hold the weighted average of the substeps, it
131!--    cannot be used in the iterative solver. Therefore, its initial value is
132!--    stored on p_loc, which is then iteratively advanced in every substep.
133       p_loc = p
134
[1]135    ENDIF
136
137!
[75]138!-- Conserve the volume flow at the outflow in case of non-cyclic lateral
139!-- boundary conditions
[106]140!-- WARNING: so far, this conservation does not work at the left/south
141!--          boundary if the topography at the inflow differs from that at the
142!--          outflow! For this case, volume_flow_area needs adjustment!
143!
144!-- Left/right
[680]145
[106]146    IF ( conserve_volume_flow  .AND.  ( outflow_l  .OR. outflow_r ) )  THEN
[75]147
[106]148       volume_flow(1)   = 0.0
149       volume_flow_l(1) = 0.0
150
151       IF ( outflow_l )  THEN
152          i = 0
153       ELSEIF ( outflow_r )  THEN
154          i = nx+1
155       ENDIF
156
157       DO  j = nys, nyn
158!
159!--       Sum up the volume flow through the south/north boundary
160          DO  k = nzb_2d(j,i) + 1, nzt
[667]161             volume_flow_l(1) = volume_flow_l(1) + u(k,j,i) * dzw(k)
[106]162          ENDDO
163       ENDDO
164
165#if defined( __parallel )   
[680]166       IF ( collective_wait )  CALL MPI_BARRIER( comm1dy, ierr )
[106]167       CALL MPI_ALLREDUCE( volume_flow_l(1), volume_flow(1), 1, MPI_REAL, &
168                           MPI_SUM, comm1dy, ierr )   
169#else
170       volume_flow = volume_flow_l 
171#endif
172       volume_flow_offset(1) = ( volume_flow_initial(1) - volume_flow(1) )    &
173                               / volume_flow_area(1)
174
[667]175       DO  j = nysg, nyng
176          DO  k = nzb_2d(j,i) + 1, nzt
[106]177             u(k,j,i) = u(k,j,i) + volume_flow_offset(1)
178          ENDDO
179       ENDDO
180
181    ENDIF
182
183!
184!-- South/north
185    IF ( conserve_volume_flow  .AND.  ( outflow_n  .OR. outflow_s ) )  THEN
186
[75]187       volume_flow(2)   = 0.0
188       volume_flow_l(2) = 0.0
189
[106]190       IF ( outflow_s )  THEN
191          j = 0
192       ELSEIF ( outflow_n )  THEN
[75]193          j = ny+1
[106]194       ENDIF
195
196       DO  i = nxl, nxr
[75]197!
[106]198!--       Sum up the volume flow through the south/north boundary
199          DO  k = nzb_2d(j,i) + 1, nzt
[667]200             volume_flow_l(2) = volume_flow_l(2) + v(k,j,i) * dzw(k)
[75]201          ENDDO
[106]202       ENDDO
203
[75]204#if defined( __parallel )   
[680]205       IF ( collective_wait )  CALL MPI_BARRIER( comm1dx, ierr )
[75]206       CALL MPI_ALLREDUCE( volume_flow_l(2), volume_flow(2), 1, MPI_REAL, &
207                           MPI_SUM, comm1dx, ierr )   
208#else
209       volume_flow = volume_flow_l 
210#endif
211       volume_flow_offset(2) = ( volume_flow_initial(2) - volume_flow(2) )    &
[106]212                               / volume_flow_area(2)
[75]213
[667]214       DO  i = nxlg, nxrg
[106]215          DO  k = nzb_v_inner(j,i) + 1, nzt
216             v(k,j,i) = v(k,j,i) + volume_flow_offset(2)
[75]217          ENDDO
[106]218       ENDDO
[75]219
220    ENDIF
221
[76]222!
223!-- Remove mean vertical velocity
224    IF ( ibc_p_b == 1  .AND.  ibc_p_t == 1 )  THEN
225       IF ( simulated_time > 0.0 )  THEN ! otherwise nzb_w_inner is not yet known
226          w_l = 0.0;  w_l_l = 0.0
227          DO  i = nxl, nxr
228             DO  j = nys, nyn
229                DO  k = nzb_w_inner(j,i)+1, nzt
230                   w_l_l(k) = w_l_l(k) + w(k,j,i)
231                ENDDO
232             ENDDO
233          ENDDO
234#if defined( __parallel )   
[622]235          IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
[76]236          CALL MPI_ALLREDUCE( w_l_l(1), w_l(1), nzt, MPI_REAL, MPI_SUM, comm2d, &
237                              ierr )
238#else
239          w_l = w_l_l 
240#endif
241          DO  k = 1, nzt
242             w_l(k) = w_l(k) / ngp_2dh_outer(k,0)
243          ENDDO
[667]244          DO  i = nxlg, nxrg
245             DO  j = nysg, nyng
[76]246                DO  k = nzb_w_inner(j,i)+1, nzt
247                   w(k,j,i) = w(k,j,i) - w_l(k)
248                ENDDO
249             ENDDO
250          ENDDO
251       ENDIF
252    ENDIF
[75]253
254!
[1]255!-- Compute the divergence of the provisional velocity field.
256    CALL cpu_log( log_point_s(1), 'divergence', 'start' )
257
258    IF ( psolver == 'multigrid' )  THEN
259       !$OMP PARALLEL DO SCHEDULE( STATIC )
260       DO  i = nxl-1, nxr+1
261          DO  j = nys-1, nyn+1
262             DO  k = nzb, nzt+1
263                d(k,j,i) = 0.0
264             ENDDO
265          ENDDO
266       ENDDO
267    ELSE
268       !$OMP PARALLEL DO SCHEDULE( STATIC )
269       DO  i = nxl, nxra
270          DO  j = nys, nyna
271             DO  k = nzb+1, nzta
272                d(k,j,i) = 0.0
273             ENDDO
274          ENDDO
275       ENDDO
276    ENDIF
277
278    localsum  = 0.0
279    threadsum = 0.0
280
281#if defined( __ibm )
282    !$OMP PARALLEL PRIVATE (i,j,k) FIRSTPRIVATE(threadsum) REDUCTION(+:localsum)
283    !$OMP DO SCHEDULE( STATIC )
284    DO  i = nxl, nxr
285       DO  j = nys, nyn
286          DO  k = nzb_s_inner(j,i)+1, nzt
[85]287             d(k,j,i) = ( ( u(k,j,i+1) - u(k,j,i) ) * ddx + &
288                          ( v(k,j+1,i) - v(k,j,i) ) * ddy + &
[673]289                          ( w(k,j,i) - w(k-1,j,i) ) * ddzw(k) ) * ddt_3d      &
290                                                                * d_weight_pres 
[1]291          ENDDO
292!
293!--       Additional pressure boundary condition at the bottom boundary for
294!--       inhomogeneous Prandtl layer heat fluxes and temperatures, respectively
295!--       dp/dz = -(dtau13/dx + dtau23/dy) + g*pt'/pt0.
296!--       This condition must not be applied at the start of a run, because then
297!--       flow_statistics has not yet been called and thus sums = 0.
298          IF ( ibc_p_b == 2  .AND.  sums(nzb+1,4) /= 0.0 )  THEN
299             k = nzb_s_inner(j,i)
300             d(k+1,j,i) = d(k+1,j,i) + (                                     &
301                                         ( usws(j,i+1) - usws(j,i) ) * ddx   &
302                                       + ( vsws(j+1,i) - vsws(j,i) ) * ddy   &
303                                       - g * ( pt(k+1,j,i) - sums(k+1,4) ) / &
304                                         sums(k+1,4)                         &
[673]305                                       ) * ddzw(k+1) * ddt_3d * d_weight_pres 
[1]306          ENDIF
307
308!
309!--       Compute possible PE-sum of divergences for flow_statistics
310          DO  k = nzb_s_inner(j,i)+1, nzt
311             threadsum = threadsum + ABS( d(k,j,i) )
312          ENDDO
313
314       ENDDO
315    ENDDO
316
[707]317    localsum = localsum + threadsum * dt_3d * &
318                          weight_pres(intermediate_timestep_count)
[693]319
[1]320    !$OMP END PARALLEL
321#else
322    IF ( ibc_p_b == 2 .AND. sums(nzb+1,4) /= 0.0 )  THEN
323       !$OMP PARALLEL PRIVATE (i,j,k)
324       !$OMP DO SCHEDULE( STATIC )
325       DO  i = nxl, nxr
326          DO  j = nys, nyn
327             DO  k = nzb_s_inner(j,i)+1, nzt
[667]328             d(k,j,i) = ( ( u(k,j,i+1) - u(k,j,i) ) * ddx + &
329                          ( v(k,j+1,i) - v(k,j,i) ) * ddy + &
[673]330                          ( w(k,j,i) - w(k-1,j,i) ) * ddzw(k) ) * ddt_3d      &
331                                                                * d_weight_pres 
[1]332             ENDDO
333          ENDDO
334!
335!--       Additional pressure boundary condition at the bottom boundary for
336!--       inhomogeneous Prandtl layer heat fluxes and temperatures, respectively
337!--       dp/dz = -(dtau13/dx + dtau23/dy) + g*pt'/pt0.
338!--       This condition must not be applied at the start of a run, because then
339!--       flow_statistics has not yet been called and thus sums = 0.
340          DO  j = nys, nyn
341              k = nzb_s_inner(j,i)
342              d(k+1,j,i) = d(k+1,j,i) + (                        &
343                             ( usws(j,i+1) - usws(j,i) ) * ddx   &
344                           + ( vsws(j+1,i) - vsws(j,i) ) * ddy   &
345                           - g * ( pt(k+1,j,i) - sums(k+1,4) ) / &
346                             sums(k+1,4)                         &
[673]347                                        ) * ddzw(k+1) * ddt_3d   &
348                                          * d_weight_pres 
[1]349          ENDDO
350       ENDDO
351       !$OMP END PARALLEL
352
353    ELSE
354
355       !$OMP PARALLEL PRIVATE (i,j,k)
356       !$OMP DO SCHEDULE( STATIC )
357       DO  i = nxl, nxr
358          DO  j = nys, nyn
359             DO  k = nzb_s_inner(j,i)+1, nzt
[85]360                d(k,j,i) = ( ( u(k,j,i+1) - u(k,j,i) ) * ddx + &
[667]361                          ( v(k,j+1,i) - v(k,j,i) ) * ddy + &
[673]362                          ( w(k,j,i) - w(k-1,j,i) ) * ddzw(k) ) * ddt_3d      &
363                                                                * d_weight_pres 
[1]364             ENDDO
365          ENDDO
366       ENDDO
367       !$OMP END PARALLEL
368
369    ENDIF
370
371!
372!-- Compute possible PE-sum of divergences for flow_statistics
373    !$OMP PARALLEL PRIVATE (i,j,k) FIRSTPRIVATE(threadsum) REDUCTION(+:localsum)
374    !$OMP DO SCHEDULE( STATIC )
375    DO  i = nxl, nxr
376       DO  j = nys, nyn
377          DO  k = nzb+1, nzt
378             threadsum = threadsum + ABS( d(k,j,i) )
379          ENDDO
380       ENDDO
381    ENDDO
[707]382    localsum = localsum + threadsum * dt_3d * &
383                          weight_pres(intermediate_timestep_count)
[1]384    !$OMP END PARALLEL
385#endif
386
387!
388!-- For completeness, set the divergence sum of all statistic regions to those
389!-- of the total domain
390    sums_divold_l(0:statistic_regions) = localsum
391
392    CALL cpu_log( log_point_s(1), 'divergence', 'stop' )
393
394!
395!-- Compute the pressure perturbation solving the Poisson equation
396    IF ( psolver(1:7) == 'poisfft' )  THEN
397
398!
399!--    Enlarge the size of tend, used as a working array for the transpositions
400       IF ( nxra > nxr  .OR.  nyna > nyn  .OR.  nza > nz )  THEN
401          DEALLOCATE( tend )
402          ALLOCATE( tend(1:nza,nys:nyna,nxl:nxra) )
403       ENDIF
404
405!
406!--    Solve Poisson equation via FFT and solution of tridiagonal matrices
407       IF ( psolver == 'poisfft' )  THEN
408!
409!--       Solver for 2d-decomposition
410          CALL poisfft( d, tend )
411       ELSEIF ( psolver == 'poisfft_hybrid' )  THEN 
412!
413!--       Solver for 1d-decomposition (using MPI and OpenMP).
414!--       The old hybrid-solver is still included here, as long as there
415!--       are some optimization problems in poisfft
416          CALL poisfft_hybrid( d )
417       ENDIF
418
419!
420!--    Resize tend to its normal size
421       IF ( nxra > nxr  .OR.  nyna > nyn  .OR.  nza > nz )  THEN
422          DEALLOCATE( tend )
[667]423          ALLOCATE( tend(nzb:nzt+1,nysg:nyng,nxlg:nxrg) )
[1]424       ENDIF
425
426!
427!--    Store computed perturbation pressure and set boundary condition in
428!--    z-direction
429       !$OMP PARALLEL DO
430       DO  i = nxl, nxr
431          DO  j = nys, nyn
432             DO  k = nzb+1, nzt
433                tend(k,j,i) = d(k,j,i)
434             ENDDO
435          ENDDO
436       ENDDO
437
438!
439!--    Bottom boundary:
440!--    This condition is only required for internal output. The pressure
441!--    gradient (dp(nzb+1)-dp(nzb))/dz is not used anywhere else.
442       IF ( ibc_p_b == 1 )  THEN
443!
444!--       Neumann (dp/dz = 0)
445          !$OMP PARALLEL DO
[667]446          DO  i = nxlg, nxrg
447             DO  j = nysg, nyng
[1]448                tend(nzb_s_inner(j,i),j,i) = tend(nzb_s_inner(j,i)+1,j,i)
449             ENDDO
450          ENDDO
451
452       ELSEIF ( ibc_p_b == 2 )  THEN
453!
454!--       Neumann condition for inhomogeneous surfaces,
455!--       here currently still in the form of a zero gradient. Actually
456!--       dp/dz = -(dtau13/dx + dtau23/dy) + g*pt'/pt0 would have to be used for
457!--       the computation (cf. above: computation of divergences).
458          !$OMP PARALLEL DO
[667]459          DO  i = nxlg, nxrg
460             DO  j = nysg, nyng
[1]461                tend(nzb_s_inner(j,i),j,i) = tend(nzb_s_inner(j,i)+1,j,i)
462             ENDDO
463          ENDDO
464
465       ELSE
466!
467!--       Dirichlet
468          !$OMP PARALLEL DO
[667]469          DO  i = nxlg, nxrg
470             DO  j = nysg, nyng
[1]471                tend(nzb_s_inner(j,i),j,i) = 0.0
472             ENDDO
473          ENDDO
474
475       ENDIF
476
477!
478!--    Top boundary
479       IF ( ibc_p_t == 1 )  THEN
480!
481!--       Neumann
482          !$OMP PARALLEL DO
[667]483          DO  i = nxlg, nxrg
484             DO  j = nysg, nyng
[1]485                tend(nzt+1,j,i) = tend(nzt,j,i)
486             ENDDO
487          ENDDO
488
489       ELSE
490!
491!--       Dirichlet
492          !$OMP PARALLEL DO
[667]493          DO  i = nxlg, nxrg
494             DO  j = nysg, nyng
[1]495                tend(nzt+1,j,i) = 0.0
496             ENDDO
497          ENDDO
498
499       ENDIF
500
501!
502!--    Exchange boundaries for p
[667]503       CALL exchange_horiz( tend, nbgp )
[1]504     
505    ELSEIF ( psolver == 'sor' )  THEN
506
507!
508!--    Solve Poisson equation for perturbation pressure using SOR-Red/Black
509!--    scheme
[707]510       CALL sor( d, ddzu_pres, ddzw, p_loc )
511       tend = p_loc
[1]512
513    ELSEIF ( psolver == 'multigrid' )  THEN
514
515!
516!--    Solve Poisson equation for perturbation pressure using Multigrid scheme,
[667]517!--    array tend is used to store the residuals, logical exchange_mg is used
518!--    to discern data exchange in multigrid ( 1 ghostpoint ) and normal grid
519!--    ( nbgp ghost points ).
[1]520       CALL poismg( tend )
[707]521
[1]522!
523!--    Restore perturbation pressure on tend because this array is used
524!--    further below to correct the velocity fields
[707]525       DO  i = nxl-1, nxr+1
526          DO  j = nys-1, nyn+1
527             DO  k = nzb, nzt+1
528                tend(k,j,i) = p_loc(k,j,i)
529             ENDDO
530          ENDDO
531       ENDDO
[667]532
[1]533    ENDIF
534
535!
[707]536!-- Store perturbation pressure on array p, used for pressure data output.
537!-- Ghost layers are added in the output routines (except sor-method: see below)
538    IF ( intermediate_timestep_count == 1 )  THEN
539       !$OMP PARALLEL PRIVATE (i,j,k)
540       !$OMP DO
541       DO  i = nxl-1, nxr+1
542          DO  j = nys-1, nyn+1
543             DO  k = nzb, nzt+1
544                p(k,j,i) = tend(k,j,i) * &
545                           weight_substep(intermediate_timestep_count)
[673]546             ENDDO
[1]547          ENDDO
[707]548       ENDDO
549       !$OMP END PARALLEL
550
551    ELSE 
552       !$OMP PARALLEL PRIVATE (i,j,k)
553       !$OMP DO
554       DO  i = nxl-1, nxr+1
555          DO  j = nys-1, nyn+1
556             DO  k = nzb, nzt+1
557                p(k,j,i) = p(k,j,i) + tend(k,j,i) * &
558                           weight_substep(intermediate_timestep_count)
[673]559             ENDDO
560          ENDDO
[707]561       ENDDO
562       !$OMP END PARALLEL
563
564    ENDIF
[673]565       
[707]566!
567!-- SOR-method needs ghost layers for the next timestep
568    IF ( psolver == 'sor' )  CALL exchange_horiz( p, nbgp )
[682]569
[1]570!
571!-- Correction of the provisional velocities with the current perturbation
572!-- pressure just computed
[707]573    IF ( conserve_volume_flow  .AND.  ( bc_lr_cyc  .OR.  bc_ns_cyc ) )  THEN
[1]574       volume_flow_l(1) = 0.0
575       volume_flow_l(2) = 0.0
576    ENDIF
[707]577
[1]578    !$OMP PARALLEL PRIVATE (i,j,k)
579    !$OMP DO
[673]580    DO  i = nxl, nxr   
[1]581       DO  j = nys, nyn
582          DO  k = nzb_w_inner(j,i)+1, nzt
[707]583             w(k,j,i) = w(k,j,i) - dt_3d *                                 &
584                        ( tend(k+1,j,i) - tend(k,j,i) ) * ddzu(k+1) *      &
585                        weight_pres(intermediate_timestep_count)
[1]586          ENDDO
587          DO  k = nzb_u_inner(j,i)+1, nzt
[673]588             u(k,j,i) = u(k,j,i) - dt_3d *                                 &
[707]589                        ( tend(k,j,i) - tend(k,j,i-1) ) * ddx *            &
590                        weight_pres(intermediate_timestep_count)
[1]591          ENDDO
592          DO  k = nzb_v_inner(j,i)+1, nzt
[673]593             v(k,j,i) = v(k,j,i) - dt_3d *                                 &
[707]594                        ( tend(k,j,i) - tend(k,j-1,i) ) * ddy *            &
595                        weight_pres(intermediate_timestep_count)
[673]596          ENDDO                                                         
[1]597!
598!--       Sum up the volume flow through the right and north boundary
[707]599          IF ( conserve_volume_flow  .AND.  bc_lr_cyc  .AND.  bc_ns_cyc  .AND. &
600               i == nx )  THEN
[1]601             !$OMP CRITICAL
602             DO  k = nzb_2d(j,i) + 1, nzt
[667]603                volume_flow_l(1) = volume_flow_l(1) + u(k,j,i) * dzw(k)
[1]604             ENDDO
605             !$OMP END CRITICAL
606          ENDIF
[707]607          IF ( conserve_volume_flow  .AND.  bc_ns_cyc  .AND.  bc_lr_cyc  .AND. &
608               j == ny )  THEN
[1]609             !$OMP CRITICAL
610             DO  k = nzb_2d(j,i) + 1, nzt
[667]611                volume_flow_l(2) = volume_flow_l(2) + v(k,j,i) * dzw(k)
[1]612             ENDDO
613             !$OMP END CRITICAL
614          ENDIF
615
616       ENDDO
617    ENDDO
618    !$OMP END PARALLEL
[673]619   
[1]620!
621!-- Conserve the volume flow
[707]622    IF ( conserve_volume_flow  .AND.  ( bc_lr_cyc  .AND.  bc_ns_cyc ) )  THEN
[1]623
624#if defined( __parallel )   
[622]625       IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
[1]626       CALL MPI_ALLREDUCE( volume_flow_l(1), volume_flow(1), 2, MPI_REAL, &
627                           MPI_SUM, comm2d, ierr ) 
628#else
629       volume_flow = volume_flow_l 
630#endif   
631
632       volume_flow_offset = ( volume_flow_initial - volume_flow ) / &
633                            volume_flow_area
634
635       !$OMP PARALLEL PRIVATE (i,j,k)
636       !$OMP DO
637       DO  i = nxl, nxr
638          DO  j = nys, nyn
[667]639             DO  k = nzb_u_inner(j,i) + 1, nzt
640                u(k,j,i) = u(k,j,i) + volume_flow_offset(1)
641                v(k,j,i) = v(k,j,i) + volume_flow_offset(2)
642             ENDDO
[1]643          ENDDO
644       ENDDO
[667]645
[1]646       !$OMP END PARALLEL
647
648    ENDIF
649
650!
651!-- Exchange of boundaries for the velocities
[667]652    CALL exchange_horiz( u, nbgp )
653    CALL exchange_horiz( v, nbgp )
654    CALL exchange_horiz( w, nbgp )
[1]655
656!
657!-- Compute the divergence of the corrected velocity field,
658!-- a possible PE-sum is computed in flow_statistics
659    CALL cpu_log( log_point_s(1), 'divergence', 'start' )
660    sums_divnew_l = 0.0
661
662!
663!-- d must be reset to zero because it can contain nonzero values below the
664!-- topography
665    IF ( topography /= 'flat' )  d = 0.0
666
667    localsum  = 0.0
668    threadsum = 0.0
669
670    !$OMP PARALLEL PRIVATE (i,j,k) FIRSTPRIVATE(threadsum) REDUCTION(+:localsum)
671    !$OMP DO SCHEDULE( STATIC )
672#if defined( __ibm )
673    DO  i = nxl, nxr
674       DO  j = nys, nyn
675          DO  k = nzb_s_inner(j,i)+1, nzt
676             d(k,j,i) = ( u(k,j,i+1) - u(k,j,i) ) * ddx + &
677                        ( v(k,j+1,i) - v(k,j,i) ) * ddy + &
678                        ( w(k,j,i) - w(k-1,j,i) ) * ddzw(k)
679          ENDDO
680          DO  k = nzb+1, nzt
681             threadsum = threadsum + ABS( d(k,j,i) )
682          ENDDO
683       ENDDO
684    ENDDO
685#else
686    DO  i = nxl, nxr
687       DO  j = nys, nyn
688          DO  k = nzb_s_inner(j,i)+1, nzt
689             d(k,j,i) = ( u(k,j,i+1) - u(k,j,i) ) * ddx + &
690                        ( v(k,j+1,i) - v(k,j,i) ) * ddy + &
691                        ( w(k,j,i) - w(k-1,j,i) ) * ddzw(k)
692             threadsum = threadsum + ABS( d(k,j,i) )
693          ENDDO
694       ENDDO
695    ENDDO
696#endif
[667]697
[1]698    localsum = localsum + threadsum
699    !$OMP END PARALLEL
700
701!
702!-- For completeness, set the divergence sum of all statistic regions to those
703!-- of the total domain
704    sums_divnew_l(0:statistic_regions) = localsum
705
706    CALL cpu_log( log_point_s(1), 'divergence', 'stop' )
707
708    CALL cpu_log( log_point(8), 'pres', 'stop' )
[667]709   
[1]710
711
712 END SUBROUTINE pres
Note: See TracBrowser for help on using the repository browser.