source: palm/trunk/SOURCE/diffusion_s.f90 @ 1686

Last change on this file since 1686 was 1683, checked in by knoop, 9 years ago

last commit documented

  • Property svn:keywords set to Id
File size: 20.0 KB
RevLine 
[1682]1!> @file diffusion_s.f90
[1036]2!--------------------------------------------------------------------------------!
3! This file is part of PALM.
4!
5! PALM is free software: you can redistribute it and/or modify it under the terms
6! of the GNU General Public License as published by the Free Software Foundation,
7! either version 3 of the License, or (at your option) any later version.
8!
9! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
10! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12!
13! You should have received a copy of the GNU General Public License along with
14! PALM. If not, see <http://www.gnu.org/licenses/>.
15!
[1310]16! Copyright 1997-2014 Leibniz Universitaet Hannover
[1036]17!--------------------------------------------------------------------------------!
18!
[484]19! Current revisions:
[1001]20! ------------------
[1341]21!
[1683]22!
[1321]23! Former revisions:
24! -----------------
25! $Id: diffusion_s.f90 1683 2015-10-07 23:57:51Z raasch $
26!
[1683]27! 1682 2015-10-07 23:56:08Z knoop
28! Code annotations made doxygen readable
29!
[1375]30! 1374 2014-04-25 12:55:07Z raasch
31! missing variables added to ONLY list
32!
[1341]33! 1340 2014-03-25 19:45:13Z kanani
34! REAL constants defined as wp-kind
35!
[1321]36! 1320 2014-03-20 08:40:49Z raasch
[1320]37! ONLY-attribute added to USE-statements,
38! kind-parameters added to all INTEGER and REAL declaration statements,
39! kinds are defined in new module kinds,
40! revision history before 2012 removed,
41! comment fields (!:) to be used for variable explanations added to
42! all variable declaration statements
[1321]43!
[1258]44! 1257 2013-11-08 15:18:40Z raasch
45! openacc loop and loop vector clauses removed
46!
[1132]47! 1128 2013-04-12 06:19:32Z raasch
48! loop index bounds in accelerator version replaced by i_left, i_right, j_south,
49! j_north
50!
[1093]51! 1092 2013-02-02 11:24:22Z raasch
52! unused variables removed
53!
[1037]54! 1036 2012-10-22 13:43:42Z raasch
55! code put under GPL (PALM 3.9)
56!
[1017]57! 1015 2012-09-27 09:23:24Z raasch
58! accelerator version (*_acc) added
59!
[1011]60! 1010 2012-09-20 07:59:54Z raasch
61! cpp switch __nopointer added for pointer free version
62!
[1002]63! 1001 2012-09-13 14:08:46Z raasch
64! some arrays comunicated by module instead of parameter list
65!
[1]66! Revision 1.1  2000/04/13 14:54:02  schroeter
67! Initial revision
68!
69!
70! Description:
71! ------------
[1682]72!> Diffusion term of scalar quantities (temperature and water content)
[1]73!------------------------------------------------------------------------------!
[1682]74 MODULE diffusion_s_mod
75 
[1]76
77    PRIVATE
[1015]78    PUBLIC diffusion_s, diffusion_s_acc
[1]79
80    INTERFACE diffusion_s
81       MODULE PROCEDURE diffusion_s
82       MODULE PROCEDURE diffusion_s_ij
83    END INTERFACE diffusion_s
84
[1015]85    INTERFACE diffusion_s_acc
86       MODULE PROCEDURE diffusion_s_acc
87    END INTERFACE diffusion_s_acc
88
[1]89 CONTAINS
90
91
92!------------------------------------------------------------------------------!
[1682]93! Description:
94! ------------
95!> Call for all grid points
[1]96!------------------------------------------------------------------------------!
[1001]97    SUBROUTINE diffusion_s( s, s_flux_b, s_flux_t, wall_s_flux )
[1]98
[1320]99       USE arrays_3d,                                                          &
100           ONLY:  ddzu, ddzw, kh, tend
101       
102       USE control_parameters,                                                 & 
103           ONLY: use_surface_fluxes, use_top_fluxes
104       
105       USE grid_variables,                                                     &
106           ONLY:  ddx2, ddy2, fwxm, fwxp, fwym, fwyp, wall_w_x, wall_w_y
107       
108       USE indices,                                                            &
[1374]109           ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb,             &
[1320]110                  nzb_diff_s_inner, nzb_s_inner, nzb_s_outer, nzt, nzt_diff
111       
112       USE kinds
[1]113
114       IMPLICIT NONE
115
[1682]116       INTEGER(iwp) ::  i                 !<
117       INTEGER(iwp) ::  j                 !<
118       INTEGER(iwp) ::  k                 !<
119       REAL(wp)     ::  wall_s_flux(0:4)  !<
120       REAL(wp), DIMENSION(nysg:nyng,nxlg:nxrg) ::  s_flux_b, s_flux_t !<
[1010]121#if defined( __nopointer )
[1682]122       REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ::  s  !<
[1010]123#else
[1682]124       REAL(wp), DIMENSION(:,:,:), POINTER ::  s  !<
[1010]125#endif
[1]126
127       DO  i = nxl, nxr
128          DO  j = nys,nyn
129!
130!--          Compute horizontal diffusion
[19]131             DO  k = nzb_s_outer(j,i)+1, nzt
[1]132
[1320]133                tend(k,j,i) = tend(k,j,i)                                      &
[1340]134                                          + 0.5_wp * (                         &
[1320]135                        ( kh(k,j,i) + kh(k,j,i+1) ) * ( s(k,j,i+1)-s(k,j,i) )  &
136                      - ( kh(k,j,i) + kh(k,j,i-1) ) * ( s(k,j,i)-s(k,j,i-1) )  &
[1340]137                                                     ) * ddx2                  &
138                                          + 0.5_wp * (                         &
[1320]139                        ( kh(k,j,i) + kh(k,j+1,i) ) * ( s(k,j+1,i)-s(k,j,i) )  &
140                      - ( kh(k,j,i) + kh(k,j-1,i) ) * ( s(k,j,i)-s(k,j-1,i) )  &
[1340]141                                                     ) * ddy2
[1]142             ENDDO
143
144!
145!--          Apply prescribed horizontal wall heatflux where necessary
[1340]146             IF ( ( wall_w_x(j,i) .NE. 0.0_wp ) .OR. ( wall_w_y(j,i) .NE. 0.0_wp ) ) &
[1]147             THEN
148                DO  k = nzb_s_inner(j,i)+1, nzb_s_outer(j,i)
149
[1320]150                   tend(k,j,i) = tend(k,j,i)                                   &
[1340]151                                                + ( fwxp(j,i) * 0.5_wp *       &
[1320]152                        ( kh(k,j,i) + kh(k,j,i+1) ) * ( s(k,j,i+1)-s(k,j,i) )  &
[1340]153                        + ( 1.0_wp - fwxp(j,i) ) * wall_s_flux(1)              &
154                                                   -fwxm(j,i) * 0.5_wp *       &
[1320]155                        ( kh(k,j,i) + kh(k,j,i-1) ) * ( s(k,j,i)-s(k,j,i-1) )  &
[1340]156                        + ( 1.0_wp - fwxm(j,i) ) * wall_s_flux(2)              &
[1320]157                                                  ) * ddx2                     &
[1340]158                                                + ( fwyp(j,i) * 0.5_wp *       &
[1320]159                        ( kh(k,j,i) + kh(k,j+1,i) ) * ( s(k,j+1,i)-s(k,j,i) )  &
[1340]160                        + ( 1.0_wp - fwyp(j,i) ) * wall_s_flux(3)              &
161                                                   -fwym(j,i) * 0.5_wp *       &
[1320]162                        ( kh(k,j,i) + kh(k,j-1,i) ) * ( s(k,j,i)-s(k,j-1,i) )  &
[1340]163                        + ( 1.0_wp - fwym(j,i) ) * wall_s_flux(4)              &
[1]164                                                  ) * ddy2
165                ENDDO
166             ENDIF
167
168!
169!--          Compute vertical diffusion. In case that surface fluxes have been
[19]170!--          prescribed or computed at bottom and/or top, index k starts/ends at
171!--          nzb+2 or nzt-1, respectively.
172             DO  k = nzb_diff_s_inner(j,i), nzt_diff
[1]173
[1320]174                tend(k,j,i) = tend(k,j,i)                                      &
[1340]175                                       + 0.5_wp * (                            &
[1320]176            ( kh(k,j,i) + kh(k+1,j,i) ) * ( s(k+1,j,i)-s(k,j,i) ) * ddzu(k+1)  &
177          - ( kh(k,j,i) + kh(k-1,j,i) ) * ( s(k,j,i)-s(k-1,j,i) ) * ddzu(k)    &
[1340]178                                                  ) * ddzw(k)
[1]179             ENDDO
180
181!
[19]182!--          Vertical diffusion at the first computational gridpoint along
[1]183!--          z-direction
184             IF ( use_surface_fluxes )  THEN
185
186                k = nzb_s_inner(j,i)+1
187
[1320]188                tend(k,j,i) = tend(k,j,i)                                      &
[1340]189                                       + ( 0.5_wp * ( kh(k,j,i)+kh(k+1,j,i) )  &
190                                                  * ( s(k+1,j,i)-s(k,j,i) )    &
191                                                  * ddzu(k+1)                  &
[1320]192                                           + s_flux_b(j,i)                     &
[1]193                                         ) * ddzw(k)
194
195             ENDIF
196
[19]197!
198!--          Vertical diffusion at the last computational gridpoint along
199!--          z-direction
200             IF ( use_top_fluxes )  THEN
201
202                k = nzt
203
[1320]204                tend(k,j,i) = tend(k,j,i)                                      &
205                                       + ( - s_flux_t(j,i)                     &
[1340]206                                           - 0.5_wp * ( kh(k-1,j,i)+kh(k,j,i) )&
207                                                    * ( s(k,j,i)-s(k-1,j,i) )  &
208                                                    * ddzu(k)                  &
[19]209                                         ) * ddzw(k)
210
211             ENDIF
212
[1]213          ENDDO
214       ENDDO
215
216    END SUBROUTINE diffusion_s
217
218
219!------------------------------------------------------------------------------!
[1682]220! Description:
221! ------------
222!> Call for all grid points - accelerator version
[1015]223!------------------------------------------------------------------------------!
224    SUBROUTINE diffusion_s_acc( s, s_flux_b, s_flux_t, wall_s_flux )
225
[1320]226       USE arrays_3d,                                                          &
227           ONLY:  ddzu, ddzw, kh, tend
228           
229       USE control_parameters,                                                 & 
230           ONLY: use_surface_fluxes, use_top_fluxes
231       
232       USE grid_variables,                                                     &
233           ONLY:  ddx2, ddy2, fwxm, fwxp, fwym, fwyp, wall_w_x, wall_w_y
234       
235       USE indices, &
236           ONLY: i_left, i_right, j_north, j_south, nxlg, nxrg, nyng, nysg,    &
[1374]237                 nzb, nzb_diff_s_inner, nzb_s_inner, nzb_s_outer, nzt, nzt_diff
[1320]238           
239       USE kinds
[1015]240
241       IMPLICIT NONE
242
[1682]243       INTEGER(iwp) ::  i                 !<
244       INTEGER(iwp) ::  j                 !<
245       INTEGER(iwp) ::  k                 !<
246       REAL(wp)     ::  wall_s_flux(0:4)  !<
247       REAL(wp), DIMENSION(nysg:nyng,nxlg:nxrg) ::  s_flux_b !<
248       REAL(wp), DIMENSION(nysg:nyng,nxlg:nxrg) ::  s_flux_t !<
[1015]249#if defined( __nopointer )
[1682]250       REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ::  s  !<
[1015]251#else
[1682]252       REAL(wp), DIMENSION(:,:,:), POINTER ::  s  !<
[1015]253#endif
254
255       !$acc kernels present( ddzu, ddzw, fwxm, fwxp, fwym, fwyp, kh )        &
256       !$acc         present( nzb_diff_s_inner, nzb_s_inner, nzb_s_outer, s ) &
257       !$acc         present( s_flux_b, s_flux_t, tend, wall_s_flux )         &
258       !$acc         present( wall_w_x, wall_w_y )
[1128]259       DO  i = i_left, i_right
260          DO  j = j_south, j_north
[1015]261!
262!--          Compute horizontal diffusion
263             DO  k = 1, nzt
264                IF ( k > nzb_s_outer(j,i) )  THEN
265
[1320]266                   tend(k,j,i) = tend(k,j,i)                                   &
[1340]267                                          + 0.5_wp * (                         &
[1320]268                        ( kh(k,j,i) + kh(k,j,i+1) ) * ( s(k,j,i+1)-s(k,j,i) )  &
269                      - ( kh(k,j,i) + kh(k,j,i-1) ) * ( s(k,j,i)-s(k,j,i-1) )  &
[1340]270                                                     ) * ddx2                  &
271                                          + 0.5_wp * (                         &
[1320]272                        ( kh(k,j,i) + kh(k,j+1,i) ) * ( s(k,j+1,i)-s(k,j,i) )  &
273                      - ( kh(k,j,i) + kh(k,j-1,i) ) * ( s(k,j,i)-s(k,j-1,i) )  &
[1340]274                                                     ) * ddy2
[1015]275                ENDIF
276             ENDDO
277
278!
279!--          Apply prescribed horizontal wall heatflux where necessary
280             DO  k = 1, nzt
281                IF ( k > nzb_s_inner(j,i)  .AND.  k <= nzb_s_outer(j,i)  .AND. &
[1340]282                     ( wall_w_x(j,i) /= 0.0_wp  .OR.  wall_w_y(j,i) /= 0.0_wp ) )    &
[1015]283                THEN
[1320]284                   tend(k,j,i) = tend(k,j,i)                                   &
[1340]285                                                + ( fwxp(j,i) * 0.5_wp *       &
[1320]286                        ( kh(k,j,i) + kh(k,j,i+1) ) * ( s(k,j,i+1)-s(k,j,i) )  &
[1340]287                        + ( 1.0_wp - fwxp(j,i) ) * wall_s_flux(1)              &
288                                                   -fwxm(j,i) * 0.5_wp *       &
[1320]289                        ( kh(k,j,i) + kh(k,j,i-1) ) * ( s(k,j,i)-s(k,j,i-1) )  &
[1340]290                        + ( 1.0_wp - fwxm(j,i) ) * wall_s_flux(2)              &
[1320]291                                                  ) * ddx2                     &
[1340]292                                                + ( fwyp(j,i) * 0.5_wp *       &
[1320]293                        ( kh(k,j,i) + kh(k,j+1,i) ) * ( s(k,j+1,i)-s(k,j,i) )  &
[1340]294                        + ( 1.0_wp - fwyp(j,i) ) * wall_s_flux(3)              &
295                                                   -fwym(j,i) * 0.5_wp *       &
[1320]296                        ( kh(k,j,i) + kh(k,j-1,i) ) * ( s(k,j,i)-s(k,j-1,i) )  &
[1340]297                        + ( 1.0_wp - fwym(j,i) ) * wall_s_flux(4)              &
[1015]298                                                  ) * ddy2
299                ENDIF
300             ENDDO
301
302!
303!--          Compute vertical diffusion. In case that surface fluxes have been
304!--          prescribed or computed at bottom and/or top, index k starts/ends at
305!--          nzb+2 or nzt-1, respectively.
306             DO  k = 1, nzt_diff
307                IF ( k >= nzb_diff_s_inner(j,i) )  THEN
[1320]308                   tend(k,j,i) = tend(k,j,i)                                   &
[1340]309                                       + 0.5_wp * (                            &
[1320]310            ( kh(k,j,i) + kh(k+1,j,i) ) * ( s(k+1,j,i)-s(k,j,i) ) * ddzu(k+1)  &
311          - ( kh(k,j,i) + kh(k-1,j,i) ) * ( s(k,j,i)-s(k-1,j,i) ) * ddzu(k)    &
[1340]312                                                  ) * ddzw(k)
[1015]313                ENDIF
314             ENDDO
315
316!
317!--          Vertical diffusion at the first computational gridpoint along
318!--          z-direction
319             DO  k = 1, nzt
320                IF ( use_surface_fluxes  .AND.  k == nzb_s_inner(j,i)+1 )  THEN
[1320]321                   tend(k,j,i) = tend(k,j,i)                                   &
[1340]322                                          + ( 0.5_wp * ( kh(k,j,i)+kh(k+1,j,i) )&
323                                                     * ( s(k+1,j,i)-s(k,j,i) ) &
324                                                     * ddzu(k+1)               &
[1320]325                                              + s_flux_b(j,i)                  &
[1015]326                                            ) * ddzw(k)
327                ENDIF
328
329!
330!--             Vertical diffusion at the last computational gridpoint along
331!--             z-direction
332                IF ( use_top_fluxes  .AND.  k == nzt )  THEN
333                   tend(k,j,i) = tend(k,j,i)                                   &
334                                          + ( - s_flux_t(j,i)                  &
[1340]335                                              - 0.5_wp * ( kh(k-1,j,i)+kh(k,j,i) )&
336                                                       * ( s(k,j,i)-s(k-1,j,i) )  &
337                                                       * ddzu(k)                  &
[1015]338                                            ) * ddzw(k)
339                ENDIF
340             ENDDO
341
342          ENDDO
343       ENDDO
344       !$acc end kernels
345
346    END SUBROUTINE diffusion_s_acc
347
348
349!------------------------------------------------------------------------------!
[1682]350! Description:
351! ------------
352!> Call for grid point i,j
[1]353!------------------------------------------------------------------------------!
[1001]354    SUBROUTINE diffusion_s_ij( i, j, s, s_flux_b, s_flux_t, wall_s_flux )
[1]355
[1320]356       USE arrays_3d,                                                          &
357           ONLY:  ddzu, ddzw, kh, tend
358           
359       USE control_parameters,                                                 & 
360           ONLY: use_surface_fluxes, use_top_fluxes
361       
362       USE grid_variables,                                                     &
363           ONLY:  ddx2, ddy2, fwxm, fwxp, fwym, fwyp, wall_w_x, wall_w_y
364       
365       USE indices,                                                            &
[1374]366           ONLY:  nxlg, nxrg, nyng, nysg, nzb, nzb_diff_s_inner, nzb_s_inner,  &
[1320]367                  nzb_s_outer, nzt, nzt_diff
368       
369       USE kinds
[1]370
371       IMPLICIT NONE
372
[1682]373       INTEGER(iwp) ::  i                 !<
374       INTEGER(iwp) ::  j                 !<
375       INTEGER(iwp) ::  k                 !<
376       REAL(wp)     ::  wall_s_flux(0:4)  !<
377       REAL(wp), DIMENSION(nysg:nyng,nxlg:nxrg) ::  s_flux_b  !<
378       REAL(wp), DIMENSION(nysg:nyng,nxlg:nxrg) ::  s_flux_t  !<
[1010]379#if defined( __nopointer )
[1682]380       REAL(wp), DIMENSION(nzb:nzt+1,nysg:nyng,nxlg:nxrg) ::  s !<
[1010]381#else
[1682]382       REAL(wp), DIMENSION(:,:,:), POINTER ::  s  !<
[1010]383#endif
[1]384
385!
386!--    Compute horizontal diffusion
[19]387       DO  k = nzb_s_outer(j,i)+1, nzt
[1]388
[1320]389          tend(k,j,i) = tend(k,j,i)                                            &
[1340]390                                          + 0.5_wp * (                         &
[1320]391                        ( kh(k,j,i) + kh(k,j,i+1) ) * ( s(k,j,i+1)-s(k,j,i) )  &
392                      - ( kh(k,j,i) + kh(k,j,i-1) ) * ( s(k,j,i)-s(k,j,i-1) )  &
[1340]393                                                     ) * ddx2                  &
394                                          + 0.5_wp * (                         &
[1320]395                        ( kh(k,j,i) + kh(k,j+1,i) ) * ( s(k,j+1,i)-s(k,j,i) )  &
396                      - ( kh(k,j,i) + kh(k,j-1,i) ) * ( s(k,j,i)-s(k,j-1,i) )  &
[1340]397                                                     ) * ddy2
[1]398       ENDDO
399
400!
401!--    Apply prescribed horizontal wall heatflux where necessary
[1340]402       IF ( ( wall_w_x(j,i) .NE. 0.0_wp ) .OR. ( wall_w_y(j,i) .NE. 0.0_wp ) )       &
[1]403       THEN
404          DO  k = nzb_s_inner(j,i)+1, nzb_s_outer(j,i)
405
[1320]406             tend(k,j,i) = tend(k,j,i)                                         &
[1340]407                                                + ( fwxp(j,i) * 0.5_wp *       &
[1320]408                        ( kh(k,j,i) + kh(k,j,i+1) ) * ( s(k,j,i+1)-s(k,j,i) )  &
[1340]409                        + ( 1.0_wp - fwxp(j,i) ) * wall_s_flux(1)              &
410                                                   -fwxm(j,i) * 0.5_wp *       &
[1320]411                        ( kh(k,j,i) + kh(k,j,i-1) ) * ( s(k,j,i)-s(k,j,i-1) )  &
[1340]412                        + ( 1.0_wp - fwxm(j,i) ) * wall_s_flux(2)              &
[1320]413                                                  ) * ddx2                     &
[1340]414                                                + ( fwyp(j,i) * 0.5_wp *       &
[1320]415                        ( kh(k,j,i) + kh(k,j+1,i) ) * ( s(k,j+1,i)-s(k,j,i) )  &
[1340]416                        + ( 1.0_wp - fwyp(j,i) ) * wall_s_flux(3)              &
417                                                   -fwym(j,i) * 0.5_wp *       &
[1320]418                        ( kh(k,j,i) + kh(k,j-1,i) ) * ( s(k,j,i)-s(k,j-1,i) )  &
[1340]419                        + ( 1.0_wp - fwym(j,i) ) * wall_s_flux(4)              &
[1]420                                                  ) * ddy2
421          ENDDO
422       ENDIF
423
424!
425!--    Compute vertical diffusion. In case that surface fluxes have been
[19]426!--    prescribed or computed at bottom and/or top, index k starts/ends at
427!--    nzb+2 or nzt-1, respectively.
428       DO  k = nzb_diff_s_inner(j,i), nzt_diff
[1]429
[1320]430          tend(k,j,i) = tend(k,j,i)                                            &
[1340]431                                       + 0.5_wp * (                            &
[1320]432            ( kh(k,j,i) + kh(k+1,j,i) ) * ( s(k+1,j,i)-s(k,j,i) ) * ddzu(k+1)  &
433          - ( kh(k,j,i) + kh(k-1,j,i) ) * ( s(k,j,i)-s(k-1,j,i) ) * ddzu(k)    &
[1340]434                                                  ) * ddzw(k)
[1]435       ENDDO
436
437!
[19]438!--    Vertical diffusion at the first computational gridpoint along z-direction
[1]439       IF ( use_surface_fluxes )  THEN
440
441          k = nzb_s_inner(j,i)+1
442
[1340]443          tend(k,j,i) = tend(k,j,i) + ( 0.5_wp * ( kh(k,j,i)+kh(k+1,j,i) )     &
444                                               * ( s(k+1,j,i)-s(k,j,i) )       &
445                                               * ddzu(k+1)                     &
[1320]446                                        + s_flux_b(j,i)                        &
[19]447                                      ) * ddzw(k)
[1]448
449       ENDIF
450
[19]451!
452!--    Vertical diffusion at the last computational gridpoint along z-direction
453       IF ( use_top_fluxes )  THEN
454
455          k = nzt
456
[1320]457          tend(k,j,i) = tend(k,j,i) + ( - s_flux_t(j,i)                        &
[1340]458                                      - 0.5_wp * ( kh(k-1,j,i)+kh(k,j,i) )     &
459                                               * ( s(k,j,i)-s(k-1,j,i) )       &
460                                               * ddzu(k)                       &
[19]461                                      ) * ddzw(k)
462
463       ENDIF
464
[1]465    END SUBROUTINE diffusion_s_ij
466
467 END MODULE diffusion_s_mod
Note: See TracBrowser for help on using the repository browser.