source: palm/trunk/SOURCE/timestep.f90 @ 2815

Last change on this file since 2815 was 2718, checked in by maronga, 7 years ago

deleting of deprecated files; headers updated where needed

  • Property svn:keywords set to Id
File size: 14.5 KB
RevLine 
[1682]1!> @file timestep.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!
[2718]17! Copyright 1997-2018 Leibniz Universitaet Hannover
[2000]18!------------------------------------------------------------------------------!
[1036]19!
[258]20! Current revisions:
[866]21! ------------------
[1485]22!
[2258]23!
[1485]24! Former revisions:
25! -----------------
26! $Id: timestep.f90 2718 2018-01-02 08:49:38Z kanani $
[2716]27! Corrected "Former revisions" section
28!
29! 2696 2017-12-14 17:12:51Z kanani
30! Change in file header (GPL part)
31!
32! 2365 2017-08-21 14:59:59Z kanani
[2365]33! Vertical grid nesting: Sync fine and coarse grid timestep (SadiqHuq)
34!
35! 2258 2017-06-08 07:55:13Z suehring
[2258]36! Bugfix, add pre-preprocessor directives to enable non-parrallel mode
[1485]37!
[2258]38! 2168 2017-03-06 13:08:38Z suehring
39!
[2131]40! 2130 2017-01-24 16:25:39Z raasch
41! bugfix: in case of nested runs the stop condition in case of too small
42! timesteps is communicated to all parent/child processes,
43! some formatting done
44!
[2119]45! 2118 2017-01-17 16:38:49Z raasch
46! OpenACC directives and related part of code removed
47!
[2001]48! 2000 2016-08-20 18:09:15Z knoop
49! Forced header and separation lines into 80 columns
50!
[1851]51! 1849 2016-04-08 11:33:18Z hoffmann
52! Adapted for modularization of microphysics
[1852]53!
[1683]54! 1682 2015-10-07 23:56:08Z knoop
55! Code annotations made doxygen readable
56!
[1485]57! 1484 2014-10-21 10:53:05Z kanani
[1484]58! Changes due to new module structure of the plant canopy model:
59!   calculations and parameters related to the plant canopy model removed
60!   (the limitation of the canopy drag, i.e. that the canopy drag itself should
61!   not change the sign of the velocity components, is now assured for in the
62!   calculation of the canopy tendency terms in subroutine plant_canopy_model)
[1343]63!
64! 1342 2014-03-26 17:04:47Z kanani
65! REAL constants defined as wp-kind
66!
[1323]67! 1322 2014-03-20 16:38:49Z raasch
68! REAL functions provided with KIND-attribute
69!
[1321]70! 1320 2014-03-20 08:40:49Z raasch
[1320]71! ONLY-attribute added to USE-statements,
72! kind-parameters added to all INTEGER and REAL declaration statements,
73! kinds are defined in new module kinds,
74! old module precision_kind is removed,
75! revision history before 2012 removed,
76! comment fields (!:) to be used for variable explanations added to
77! all variable declaration statements
[1321]78!
[1258]79! 1257 2013-11-08 15:18:40Z raasch
80! openacc porting
81! bugfix for calculation of advective timestep in case of vertically stretched
82! grids
83!
[1093]84! 1092 2013-02-02 11:24:22Z raasch
85! unused variables removed
86!
[1054]87! 1053 2012-11-13 17:11:03Z hoffmann
88! timestep is reduced in two-moment cloud scheme according to the maximum
89! terminal velocity of rain drops
90!
[1037]91! 1036 2012-10-22 13:43:42Z raasch
92! code put under GPL (PALM 3.9)
93!
[1002]94! 1001 2012-09-13 14:08:46Z raasch
95! all actions concerning leapfrog scheme removed
96!
[979]97! 978 2012-08-09 08:28:32Z fricke
98! restriction of the outflow damping layer in the diffusion criterion removed
99!
[867]100! 866 2012-03-28 06:44:41Z raasch
101! bugfix for timestep calculation in case of Galilei transformation,
102! special treatment in case of mirror velocity boundary condition removed
103!
[1]104! Revision 1.1  1997/08/11 06:26:19  raasch
105! Initial revision
106!
107!
108! Description:
109! ------------
[1682]110!> Compute the time step under consideration of the FCL and diffusion criterion.
[1]111!------------------------------------------------------------------------------!
[1682]112 SUBROUTINE timestep
113 
[1]114
[1320]115    USE arrays_3d,                                                             &
[1484]116        ONLY:  dzu, dzw, kh, km, u, v, w
[1320]117
118    USE control_parameters,                                                    &
119        ONLY:  cfl_factor, coupling_mode, dt_3d, dt_fixed, dt_max,             &
[1484]120               galilei_transformation, old_dt, message_string,                 &
[1320]121               stop_dt, terminate_coupled, terminate_coupled_remote,           &
122               timestep_reason, u_gtrans, use_ug_for_galilei_tr, v_gtrans
123
124    USE cpulog,                                                                &
125        ONLY:  cpu_log, log_point
126
127    USE grid_variables,                                                        &
128        ONLY:  dx, dx2, dy, dy2
129
130    USE indices,                                                               &
131        ONLY:  nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg, nzb, nzt
132
[1]133    USE interfaces
[1320]134
135    USE kinds
136
[1849]137    USE microphysics_mod,                                                      &
138        ONLY:  dt_precipitation
139
[1]140    USE pegrid
141
[2130]142    USE pmc_interface,                                                         &
143        ONLY:  nested_run
144
[1320]145    USE statistics,                                                            &
146        ONLY:  flow_statistics_called, hom, u_max, u_max_ijk, v_max, v_max_ijk,&
147               w_max, w_max_ijk
148
[2365]149    USE vertical_nesting_mod,                                                  &
150        ONLY:  vnested, vnest_timestep_sync
151
[1]152    IMPLICIT NONE
153
[1682]154    INTEGER(iwp) ::  i !<
155    INTEGER(iwp) ::  j !<
156    INTEGER(iwp) ::  k !<
[1]157
[2130]158    LOGICAL ::  stop_dt_local !< local switch for controlling the time stepping
159
[1682]160    REAL(wp) ::  div               !<
161    REAL(wp) ::  dt_diff           !<
162    REAL(wp) ::  dt_diff_l         !<
163    REAL(wp) ::  dt_u              !<
164    REAL(wp) ::  dt_u_l            !<
165    REAL(wp) ::  dt_v              !<
166    REAL(wp) ::  dt_v_l            !<
167    REAL(wp) ::  dt_w              !<
168    REAL(wp) ::  dt_w_l            !<
169    REAL(wp) ::  u_gtrans_l        !<
170    REAL(wp) ::  u_max_l           !<
171    REAL(wp) ::  u_min_l           !<
172    REAL(wp) ::  value             !<
173    REAL(wp) ::  v_gtrans_l        !<
174    REAL(wp) ::  v_max_l           !<
175    REAL(wp) ::  v_min_l           !<
176    REAL(wp) ::  w_max_l           !<
177    REAL(wp) ::  w_min_l           !<
[1320]178 
[1682]179    REAL(wp), DIMENSION(2)         ::  uv_gtrans   !<
180    REAL(wp), DIMENSION(2)         ::  uv_gtrans_l !<
181    REAL(wp), DIMENSION(3)         ::  reduce      !<
182    REAL(wp), DIMENSION(3)         ::  reduce_l    !<
183    REAL(wp), DIMENSION(nzb+1:nzt) ::  dxyz2_min   !< 
[1]184
185
[667]186
[1]187    CALL cpu_log( log_point(12), 'calculate_timestep', 'start' )
188
189!
190!-- In case of Galilei-transform not using the geostrophic wind as translation
191!-- velocity, compute the volume-averaged horizontal velocity components, which
192!-- will then be subtracted from the horizontal wind for the time step and
193!-- horizontal advection routines.
194    IF ( galilei_transformation  .AND. .NOT.  use_ug_for_galilei_tr )  THEN
195       IF ( flow_statistics_called )  THEN
196!
197!--       Horizontal averages already existent, just need to average them
198!--       vertically.
[1342]199          u_gtrans = 0.0_wp
200          v_gtrans = 0.0_wp
[1]201          DO  k = nzb+1, nzt
202             u_gtrans = u_gtrans + hom(k,1,1,0)
203             v_gtrans = v_gtrans + hom(k,1,2,0)
204          ENDDO
[1322]205          u_gtrans = u_gtrans / REAL( nzt - nzb, KIND=wp )
206          v_gtrans = v_gtrans / REAL( nzt - nzb, KIND=wp )
[1]207       ELSE
208!
209!--       Averaging over the entire model domain.
[1342]210          u_gtrans_l = 0.0_wp
211          v_gtrans_l = 0.0_wp
[1]212          DO  i = nxl, nxr
213             DO  j = nys, nyn
214                DO  k = nzb+1, nzt
[1257]215                   u_gtrans_l = u_gtrans_l + u(k,j,i)
216                   v_gtrans_l = v_gtrans_l + v(k,j,i)
[1]217                ENDDO
218             ENDDO
219          ENDDO
[2130]220          uv_gtrans_l(1) = u_gtrans_l /                                        &
221                           REAL( (nxr-nxl+1)*(nyn-nys+1)*(nzt-nzb), KIND=wp )
222          uv_gtrans_l(2) = v_gtrans_l /                                        &
223                           REAL( (nxr-nxl+1)*(nyn-nys+1)*(nzt-nzb), KIND=wp )
[1]224#if defined( __parallel )
[622]225          IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
[2130]226          CALL MPI_ALLREDUCE( uv_gtrans_l, uv_gtrans, 2, MPI_REAL, MPI_SUM,    &
[1]227                              comm2d, ierr )
[1322]228          u_gtrans = uv_gtrans(1) / REAL( numprocs, KIND=wp )
229          v_gtrans = uv_gtrans(2) / REAL( numprocs, KIND=wp )
[1]230#else
231          u_gtrans = uv_gtrans_l(1)
232          v_gtrans = uv_gtrans_l(2)
233#endif
234       ENDIF
235    ENDIF
236
[866]237!
[1257]238!-- Determine the maxima of the velocity components, including their
239!-- grid index positions.
[1320]240    CALL global_min_max( nzb, nzt+1, nysg, nyng, nxlg, nxrg, u, 'abs', 0.0_wp, &
[866]241                         u_max, u_max_ijk )
[1320]242    CALL global_min_max( nzb, nzt+1, nysg, nyng, nxlg, nxrg, v, 'abs', 0.0_wp, &
[866]243                         v_max, v_max_ijk )
[1320]244    CALL global_min_max( nzb, nzt+1, nysg, nyng, nxlg, nxrg, w, 'abs', 0.0_wp, &
[866]245                         w_max, w_max_ijk )
246
[1257]247    IF ( .NOT. dt_fixed )  THEN
[866]248!
[1257]249!--    Variable time step:
250!--    Calculate the maximum time step according to the CFL-criterion,
251!--    individually for each velocity component
[1342]252       dt_u_l = 999999.9_wp
253       dt_v_l = 999999.9_wp
254       dt_w_l = 999999.9_wp
[1257]255       DO  i = nxl, nxr
256          DO  j = nys, nyn
257             DO  k = nzb+1, nzt
[2130]258                dt_u_l = MIN( dt_u_l, ( dx     /                               &
259                                 ( ABS( u(k,j,i) - u_gtrans ) + 1.0E-10_wp ) ) )
260                dt_v_l = MIN( dt_v_l, ( dy     /                               &
261                                 ( ABS( v(k,j,i) - v_gtrans ) + 1.0E-10_wp ) ) )
262                dt_w_l = MIN( dt_w_l, ( dzu(k) /                               &
263                                 ( ABS( w(k,j,i) )            + 1.0E-10_wp ) ) )
[1257]264             ENDDO
265          ENDDO
266       ENDDO
[1]267
[1257]268#if defined( __parallel )
269       reduce_l(1) = dt_u_l
270       reduce_l(2) = dt_v_l
271       reduce_l(3) = dt_w_l
272       IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
273       CALL MPI_ALLREDUCE( reduce_l, reduce, 3, MPI_REAL, MPI_MIN, comm2d, ierr )
274       dt_u = reduce(1)
275       dt_v = reduce(2)
276       dt_w = reduce(3)
277#else
278       dt_u = dt_u_l
279       dt_v = dt_v_l
280       dt_w = dt_w_l
281#endif
282
[1]283!
284!--    Compute time step according to the diffusion criterion.
285!--    First calculate minimum grid spacing which only depends on index k
[1342]286       dt_diff_l = 999999.0_wp
[1]287
288       DO  k = nzb+1, nzt
[1342]289           dxyz2_min(k) = MIN( dx2, dy2, dzw(k)*dzw(k) ) * 0.125_wp
[1]290       ENDDO
291
[2118]292       !$OMP PARALLEL private(i,j,k,value) reduction(MIN: dt_diff_l)
293       !$OMP DO
[1]294       DO  i = nxl, nxr
295          DO  j = nys, nyn
296             DO  k = nzb+1, nzt
[2130]297                dt_diff_l = MIN( dt_diff_l, dxyz2_min(k) /                     &
298                                    ( MAX( kh(k,j,i), km(k,j,i) ) + 1E-20_wp ) )
[1]299             ENDDO
300          ENDDO
301       ENDDO
[2118]302       !$OMP END PARALLEL
[1]303#if defined( __parallel )
[622]304       IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
[2130]305       CALL MPI_ALLREDUCE( dt_diff_l, dt_diff, 1, MPI_REAL, MPI_MIN, comm2d,   &
[1]306                           ierr )
307#else
308       dt_diff = dt_diff_l
309#endif
310
311!
[316]312!--    The time step is the minimum of the 3-4 components and the diffusion time
[1001]313!--    step minus a reduction (cfl_factor) to be on the safe side.
[1]314!--    The time step must not exceed the maximum allowed value.
[2130]315       dt_3d = cfl_factor * MIN( dt_diff, dt_u, dt_v, dt_w, dt_precipitation )
[1]316       dt_3d = MIN( dt_3d, dt_max )
317
318!
319!--    Remember the restricting time step criterion for later output.
[1484]320       IF ( MIN( dt_u, dt_v, dt_w ) < dt_diff )  THEN
[1]321          timestep_reason = 'A'
322       ELSE
323          timestep_reason = 'D'
324       ENDIF
325
326!
327!--    Set flag if the time step becomes too small.
[1342]328       IF ( dt_3d < ( 0.00001_wp * dt_max ) )  THEN
[1]329          stop_dt = .TRUE.
[108]330
[2130]331          WRITE( message_string, * ) 'Time step has reached minimum limit.',   &
332               '&dt              = ', dt_3d, ' s  Simulation is terminated.',  &
333               '&old_dt          = ', old_dt, ' s',                            &
334               '&dt_u            = ', dt_u, ' s',                              &
335               '&dt_v            = ', dt_v, ' s',                              &
336               '&dt_w            = ', dt_w, ' s',                              &
337               '&dt_diff         = ', dt_diff, ' s',                           &
338               '&u_max           = ', u_max, ' m/s   k=', u_max_ijk(1),        &
339               '  j=', u_max_ijk(2), '  i=', u_max_ijk(3),                     &
340               '&v_max           = ', v_max, ' m/s   k=', v_max_ijk(1),        &
341               '  j=', v_max_ijk(2), '  i=', v_max_ijk(3),                     &
342               '&w_max           = ', w_max, ' m/s   k=', w_max_ijk(1),        &
[320]343               '  j=', w_max_ijk(2), '  i=', w_max_ijk(3)
[258]344          CALL message( 'timestep', 'PA0312', 0, 1, 0, 6, 0 )
[108]345!
346!--       In case of coupled runs inform the remote model of the termination
347!--       and its reason, provided the remote model has not already been
348!--       informed of another termination reason (terminate_coupled > 0) before.
[222]349#if defined( __parallel )
[108]350          IF ( coupling_mode /= 'uncoupled' .AND. terminate_coupled == 0 )  THEN
351             terminate_coupled = 2
[2130]352             IF ( myid == 0 )  THEN
[667]353                CALL MPI_SENDRECV( &
[2130]354                     terminate_coupled,        1, MPI_INTEGER, target_id,  0,  &
355                     terminate_coupled_remote, 1, MPI_INTEGER, target_id,  0,  &
[667]356                     comm_inter, status, ierr )
357             ENDIF
[2130]358             CALL MPI_BCAST( terminate_coupled_remote, 1, MPI_INTEGER, 0,      &
359                             comm2d, ierr)
[108]360          ENDIF
[222]361#endif
[1]362       ENDIF
363
364!
[2130]365!--    In case of nested runs all parent/child processes have to terminate if
366!--    one process has set the stop flag, i.e. they need to set the stop flag
367!--    too.
368       IF ( nested_run )  THEN
369          stop_dt_local = stop_dt
[2258]370#if defined( __parallel )
[2130]371          CALL MPI_ALLREDUCE( stop_dt_local, stop_dt, 1, MPI_LOGICAL, MPI_LOR, &
372                              MPI_COMM_WORLD, ierr )
[2258]373#endif
[2130]374       ENDIF
375
376!
[1001]377!--    Ensure a smooth value (two significant digits) of the timestep.
[1342]378       div = 1000.0_wp
[1001]379       DO  WHILE ( dt_3d < div )
[1342]380          div = div / 10.0_wp
[1001]381       ENDDO
[1342]382       dt_3d = NINT( dt_3d * 100.0_wp / div ) * div / 100.0_wp
[1]383
384!
[1001]385!--    Adjust the time step
386       old_dt = dt_3d
[1]387
[1001]388    ENDIF
[1]389
[2365]390!
391!-- Vertical nesting: coarse and fine grid timestep has to be identical   
392    IF ( vnested )  CALL vnest_timestep_sync
393
[1]394    CALL cpu_log( log_point(12), 'calculate_timestep', 'stop' )
395
396 END SUBROUTINE timestep
Note: See TracBrowser for help on using the repository browser.