MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
ats.f90
Go to the documentation of this file.
1 ! Outstanding issues for future work:
2 ! CSUB state advance/restore
3 ! Add courant time step constraint and other stability controls for GWT model
5 
6  use kindmodule, only: dp, i4b, lgp
11  tabcenter
12 
13  implicit none
14  private
15 
16  public :: atstype
17 
18  type :: atstype
19  integer(I4B), pointer :: nper => null() !< set equal to nper
20  integer(I4B), pointer :: maxats => null() !< number of ats entries
21  real(dp), public, pointer :: dtstable => null() !< delt value required for stability
22  integer(I4B), dimension(:), pointer, contiguous :: kperats => null() !< array of stress period numbers to apply ats (size NPER)
23  integer(I4B), dimension(:), pointer, contiguous :: iperats => null() !< array of stress period numbers to apply ats (size MAXATS)
24  real(dp), dimension(:), pointer, contiguous :: dt0 => null() !< input array of initial time step sizes
25  real(dp), dimension(:), pointer, contiguous :: dtmin => null() !< input array of minimum time step sizes
26  real(dp), dimension(:), pointer, contiguous :: dtmax => null() !< input array of maximum time step sizes
27  real(dp), dimension(:), pointer, contiguous :: dtadj => null() !< input array of time step factors for shortening or increasing
28  real(dp), dimension(:), pointer, contiguous :: dtfailadj => null() !< input array of time step factors for shortening due to nonconvergence
29  type(blockparsertype) :: parser !< block parser for reading input file
30  contains
31  procedure, public :: ats_init
32  procedure, public :: isadaptiveperiod
33  procedure, public :: ats_submit_delt
34  procedure, public :: ats_set_delt
35  procedure, public :: ats_reset_delt
36  procedure, public :: ats_period_message
37  procedure, public :: ats_set_endofperiod
38  procedure, public :: ats_da
39  ! private
40  procedure, private :: ats_allocate_scalars
41  procedure, private :: ats_allocate_arrays
42  procedure, private :: ats_read_options
43  procedure, private :: ats_read_dimensions
44  procedure, private :: ats_read_timing
45  procedure, private :: ats_process_input
46  procedure, private :: ats_input_table
47  procedure, private :: ats_check_timing
48  end type atstype
49 
50 contains
51 
52  !> @ brief Determine if period is adaptive
53  !!
54  !! Check settings and determine if kper is an adaptive
55  !! stress period.
56  !!
57  !<
58  function isadaptiveperiod(this, kper) result(lv)
59  class(atstype) :: this
60  integer(I4B), intent(in) :: kper
61  logical(LGP) :: lv
62  lv = .false.
63  if (associated(this%kperats)) then
64  if (this%kperats(kper) > 0) then
65  lv = .true.
66  end if
67  end if
68  end function isadaptiveperiod
69 
70  !> @ brief Create ATS object
71  !!
72  !! Create a new ATS object, and read and check input.
73  !!
74  !<
75  subroutine ats_init(this, inunit, nper_tdis)
76  ! -- modules
77  ! -- dummy
78  class(atstype) :: this
79  integer(I4B), intent(in) :: inunit
80  integer(I4B), intent(in) :: nper_tdis
81  ! -- local
82  ! -- formats
83  character(len=*), parameter :: fmtheader = &
84  "(1X,/1X,'ATS -- ADAPTIVE TIME STEP PACKAGE,', / &
85  &' VERSION 1 : 03/18/2021 - INPUT READ FROM UNIT ',I0)"
86  !
87  ! -- Allocate the scalar variables
88  call this%ats_allocate_scalars()
89  !
90  ! -- Identify package
91  write (iout, fmtheader) inunit
92  !
93  ! -- Initialize block parser
94  call this%parser%initialize(inunit, iout)
95  !
96  ! -- Read options
97  call this%ats_read_options()
98  !
99  ! -- store tdis nper in nper
100  this%nper = nper_tdis
101  !
102  ! -- Read dimensions and then allocate arrays
103  call this%ats_read_dimensions()
104  call this%ats_allocate_arrays()
105  !
106  ! -- Read timing
107  call this%ats_read_timing()
108  !
109  ! -- Echo input data to table
110  call this%ats_input_table()
111  !
112  ! -- Check timing
113  call this%ats_check_timing()
114  !
115  ! -- Process input
116  call this%ats_process_input()
117  !
118  ! -- Close the file
119  call this%parser%Clear()
120  end subroutine ats_init
121 
122  !> @ brief Allocate scalars
123  !!
124  !! Allocate and initialize scalars for the ATS package.
125  !!
126  !<
127  subroutine ats_allocate_scalars(this)
128  ! -- modules
130  ! -- dummy
131  class(atstype) :: this
132  ! -- memory manager variables
133  call mem_allocate(this%nper, 'NPER', 'ATS')
134  call mem_allocate(this%maxats, 'MAXATS', 'ATS')
135  call mem_allocate(this%dtstable, 'DTSTABLE', 'ATS')
136  !
137  ! -- Initialize variables
138  this%nper = 0
139  this%maxats = 0
140  this%dtstable = dnodata
141  end subroutine ats_allocate_scalars
142 
143  !> @ brief Allocate arrays
144  !!
145  !! Allocate and initialize arrays for the ATS package.
146  !!
147  !<
148  subroutine ats_allocate_arrays(this)
149  ! -- modules
151  ! -- dummy
152  class(atstype) :: this
153  ! -- local
154  integer(I4B) :: n
155  !
156  call mem_allocate(this%kperats, this%nper, 'KPERATS', 'ATS')
157  call mem_allocate(this%iperats, this%maxats, 'IPERATS', 'ATS')
158  call mem_allocate(this%dt0, this%maxats, 'DT0', 'ATS')
159  call mem_allocate(this%dtmin, this%maxats, 'DTMIN', 'ATS')
160  call mem_allocate(this%dtmax, this%maxats, 'DTMAX', 'ATS')
161  call mem_allocate(this%dtadj, this%maxats, 'DTADJ', 'ATS')
162  call mem_allocate(this%dtfailadj, this%maxats, 'DTFAILADJ', 'ATS')
163  !
164  ! -- initialize kperats
165  do n = 1, this%nper
166  this%kperats(n) = 0
167  end do
168  !
169  ! -- initialize
170  do n = 1, this%maxats
171  this%iperats(n) = 0
172  this%dt0(n) = dzero
173  this%dtmin(n) = dzero
174  this%dtmax(n) = dzero
175  this%dtadj(n) = dzero
176  this%dtfailadj(n) = dzero
177  end do
178  end subroutine ats_allocate_arrays
179 
180  !> @ brief Deallocate variables
181  !!
182  !! Deallocate all ATS variables.
183  !!
184  !<
185  subroutine ats_da(this)
187  ! -- dummy
188  class(atstype) :: this
189  ! -- Scalars
190  call mem_deallocate(this%nper)
191  call mem_deallocate(this%maxats)
192  call mem_deallocate(this%dtstable)
193  !
194  ! -- Arrays
195  call mem_deallocate(this%kperats)
196  call mem_deallocate(this%iperats)
197  call mem_deallocate(this%dt0)
198  call mem_deallocate(this%dtmin)
199  call mem_deallocate(this%dtmax)
200  call mem_deallocate(this%dtadj)
201  call mem_deallocate(this%dtfailadj)
202  end subroutine ats_da
203 
204  !> @ brief Read options
205  !!
206  !! Read options from ATS input file.
207  !!
208  !<
209  subroutine ats_read_options(this)
210  ! -- dummy
211  class(atstype) :: this
212  ! -- local
213  character(len=LINELENGTH) :: keyword
214  integer(I4B) :: ierr
215  logical :: isfound, endOfBlock
216  ! -- formats
217  !
218  ! -- get options block
219  call this%parser%GetBlock('OPTIONS', isfound, ierr, &
220  supportopenclose=.true., blockrequired=.false.)
221  !
222  ! -- parse options block if detected
223  if (isfound) then
224  write (iout, '(1x,a)') 'PROCESSING ATS OPTIONS'
225  do
226  call this%parser%GetNextLine(endofblock)
227  if (endofblock) exit
228  call this%parser%GetStringCaps(keyword)
229  select case (keyword)
230  case default
231  write (errmsg, '(a,a)') 'Unknown ATS option: ', &
232  trim(keyword)
233  call store_error(errmsg)
234  call this%parser%StoreErrorUnit()
235  end select
236  end do
237  write (iout, '(1x,a)') 'END OF ATS OPTIONS'
238  end if
239  end subroutine ats_read_options
240 
241  !> @ brief Read dimensions
242  !!
243  !! Read dimensions from ATS input file.
244  !!
245  !<
246  subroutine ats_read_dimensions(this)
247  ! -- dummy
248  class(atstype) :: this
249  ! -- local
250  character(len=LINELENGTH) :: keyword
251  integer(I4B) :: ierr
252  logical :: isfound, endOfBlock
253  ! -- formats
254  character(len=*), parameter :: fmtmaxats = &
255  &"(1X,I0,' ADAPTIVE TIME STEP RECORDS(S) WILL FOLLOW IN PERIODDATA')"
256  !
257  ! -- get DIMENSIONS block
258  call this%parser%GetBlock('DIMENSIONS', isfound, ierr, &
259  supportopenclose=.true.)
260  !
261  ! -- parse block if detected
262  if (isfound) then
263  write (iout, '(1x,a)') 'PROCESSING ATS DIMENSIONS'
264  do
265  call this%parser%GetNextLine(endofblock)
266  if (endofblock) exit
267  call this%parser%GetStringCaps(keyword)
268  select case (keyword)
269  case ('MAXATS')
270  this%maxats = this%parser%GetInteger()
271  write (iout, fmtmaxats) this%maxats
272  case default
273  write (errmsg, '(a,a)') 'Unknown ATS dimension: ', &
274  trim(keyword)
275  call store_error(errmsg)
276  call this%parser%StoreErrorUnit()
277  end select
278  end do
279  write (iout, '(1x,a)') 'END OF ATS DIMENSIONS'
280  else
281  write (errmsg, '(a)') 'Required DIMENSIONS block not found.'
282  call store_error(errmsg)
283  call this%parser%StoreErrorUnit()
284  end if
285  end subroutine ats_read_dimensions
286 
287  !> @ brief Read timing
288  !!
289  !! Read timing information from ATS input file.
290  !!
291  !<
292  subroutine ats_read_timing(this)
293  ! -- modules
294  ! -- dummy
295  class(atstype) :: this
296  ! -- local
297  integer(I4B) :: ierr
298  integer(I4B) :: n
299  logical :: isfound, endOfBlock
300  ! -- formats
301  !
302  ! -- get PERIODDATA block
303  call this%parser%GetBlock('PERIODDATA', isfound, ierr, &
304  supportopenclose=.true.)
305  !
306  ! -- parse block if detected
307  if (isfound) then
308  write (iout, '(1x,a)') 'READING ATS PERIODDATA'
309  do n = 1, this%maxats
310  call this%parser%GetNextLine(endofblock)
311  if (endofblock) exit
312  !
313  ! -- fill the ats data arrays
314  this%iperats(n) = this%parser%GetInteger()
315  this%dt0(n) = this%parser%GetDouble()
316  this%dtmin(n) = this%parser%GetDouble()
317  this%dtmax(n) = this%parser%GetDouble()
318  this%dtadj(n) = this%parser%GetDouble()
319  this%dtfailadj(n) = this%parser%GetDouble()
320  end do
321  !
322  ! -- Close the block
323  call this%parser%terminateblock()
324  !
325  ! -- Check for errors
326  if (count_errors() > 0) then
327  call this%parser%StoreErrorUnit()
328  end if
329  write (iout, '(1x,a)') 'END READING ATS PERIODDATA'
330  else
331  write (errmsg, '(a)') 'Required PERIODDATA block not found.'
332  call store_error(errmsg)
333  call this%parser%StoreErrorUnit()
334  end if
335  end subroutine ats_read_timing
336 
337  !> @ brief Process input
338  !!
339  !! Process ATS input by filling the kperats array.
340  !!
341  !<
342  subroutine ats_process_input(this)
343  ! -- dummy
344  class(atstype) :: this
345 
346  integer(I4B) :: kkper
347  integer(I4B) :: n
348  !
349  ! -- fill kperats for valid iperats values
350  do n = 1, this%maxats
351  kkper = this%iperats(n)
352  if (kkper > 0 .and. kkper <= this%nper) then
353  this%kperats(kkper) = n
354  end if
355  end do
356  end subroutine ats_process_input
357 
358  !> @ brief Write input table
359  !!
360  !! Write a table showing the ATS input read from the perioddata block.
361  !!
362  !<
363  subroutine ats_input_table(this)
364  use tablemodule, only: tabletype, table_cr
365  ! -- dummy
366  class(atstype) :: this
367 
368  integer(I4B) :: n
369  character(len=LINELENGTH) :: tag
370  type(tabletype), pointer :: inputtab => null()
371  !
372  ! -- setup table
373  call table_cr(inputtab, 'ATS', 'ATS PERIOD DATA')
374  call inputtab%table_df(this%maxats, 7, iout)
375  !
376  ! add columns
377  tag = 'RECORD'
378  call inputtab%initialize_column(tag, 10, alignment=tableft)
379  tag = 'IPERATS'
380  call inputtab%initialize_column(tag, 10, alignment=tableft)
381  tag = 'DT0'
382  call inputtab%initialize_column(tag, 10, alignment=tabcenter)
383  tag = 'DTMIN'
384  call inputtab%initialize_column(tag, 10, alignment=tabcenter)
385  tag = 'DTMAX'
386  call inputtab%initialize_column(tag, 10, alignment=tabcenter)
387  tag = 'DTADJ'
388  call inputtab%initialize_column(tag, 10, alignment=tabcenter)
389  tag = 'DTFAILADJ'
390  call inputtab%initialize_column(tag, 10, alignment=tabcenter)
391  !
392  ! -- write the data
393  do n = 1, this%maxats
394  call inputtab%add_term(n)
395  call inputtab%add_term(this%iperats(n))
396  call inputtab%add_term(this%dt0(n))
397  call inputtab%add_term(this%dtmin(n))
398  call inputtab%add_term(this%dtmax(n))
399  call inputtab%add_term(this%dtadj(n))
400  call inputtab%add_term(this%dtfailadj(n))
401  end do
402  !
403  ! -- deallocate the table
404  call inputtab%table_da()
405  deallocate (inputtab)
406  nullify (inputtab)
407  end subroutine ats_input_table
408 
409  !> @ brief Check timing
410  !!
411  !! Perform a check on the input data to make sure values are within
412  !! required ranges.
413  !!
414  !<
415  subroutine ats_check_timing(this)
416  ! -- dummy
417  class(atstype) :: this
418 
419  integer(I4B) :: n
420  write (iout, '(1x,a)') 'PROCESSING ATS INPUT'
421  do n = 1, this%maxats
422  !
423  ! -- check iperats
424  if (this%iperats(n) < 1) then
425  write (errmsg, '(a, i0, a, i0)') &
426  'IPERATS must be greater than zero. Found ', this%iperats(n), &
427  ' for ATS PERIODDATA record ', n
428  call store_error(errmsg)
429  end if
430  if (this%iperats(n) > this%nper) then
431  write (warnmsg, '(a, i0, a, i0)') &
432  'IPERATS greater than NPER. Found ', this%iperats(n), &
433  ' for ATS PERIODDATA record ', n
434  call store_warning(warnmsg)
435  end if
436  !
437  ! -- check dt0
438  if (this%dt0(n) < dzero) then
439  write (errmsg, '(a, g15.7, a, i0)') &
440  'DT0 must be >= zero. Found ', this%dt0(n), &
441  ' for ATS PERIODDATA record ', n
442  call store_error(errmsg)
443  end if
444  !
445  ! -- check dtmin
446  if (this%dtmin(n) <= dzero) then
447  write (errmsg, '(a, g15.7, a, i0)') &
448  'DTMIN must be > zero. Found ', this%dtmin(n), &
449  ' for ATS PERIODDATA record ', n
450  call store_error(errmsg)
451  end if
452  !
453  ! -- check dtmax
454  if (this%dtmax(n) <= dzero) then
455  write (errmsg, '(a, g15.7, a, i0)') &
456  'DTMAX must be > zero. Found ', this%dtmax(n), &
457  ' for ATS PERIODDATA record ', n
458  call store_error(errmsg)
459  end if
460  !
461  ! -- check dtmin <= dtmax
462  if (this%dtmin(n) > this%dtmax(n)) then
463  write (errmsg, '(a, 2g15.7, a, i0)') &
464  'DTMIN must be < dtmax. Found ', this%dtmin(n), this%dtmax(n), &
465  ' for ATS PERIODDATA record ', n
466  call store_error(errmsg)
467  end if
468  !
469  ! -- check dtadj
470  if (this%dtadj(n) .ne. dzero .and. this%dtadj(n) < done) then
471  write (errmsg, '(a, g15.7, a, i0)') &
472  'DTADJ must be 0 or >= 1.0. Found ', this%dtadj(n), &
473  ' for ATS PERIODDATA record ', n
474  call store_error(errmsg)
475  end if
476  !
477  ! -- check dtfailadj
478  if (this%dtfailadj(n) .ne. dzero .and. this%dtfailadj(n) < done) then
479  write (errmsg, '(a, g15.7, a, i0)') &
480  'DTFAILADJ must be 0 or >= 1.0. Found ', this%dtfailadj(n), &
481  ' for ATS PERIODDATA record ', n
482  call store_error(errmsg)
483  end if
484 
485  end do
486  !
487  ! -- Check for errors
488  if (count_errors() > 0) then
489  call this%parser%StoreErrorUnit()
490  end if
491  write (iout, '(1x,a)') 'DONE PROCESSING ATS INPUT'
492  end subroutine ats_check_timing
493 
494  !> @ brief Write period message
495  !!
496  !! Write message to mfsim.lst file with information on ATS settings
497  !! for this period.
498  !!
499  !<
500  subroutine ats_period_message(this, kper)
501  ! -- dummy
502  class(atstype) :: this
503  integer(I4B), intent(in) :: kper
504  ! -- local
505  integer(I4B) :: n
506  character(len=*), parameter :: fmtspts = &
507  "(28X,'ATS IS OVERRIDING TIME STEPPING FOR THIS PERIOD',/ &
508  &28X,'INITIAL TIME STEP SIZE (DT0) = ',G15.7,/ &
509  &28X,'MINIMUM TIME STEP SIZE (DTMIN) = ',G15.7,/ &
510  &28X,'MAXIMUM TIME STEP SIZE (DTMAX) = ',G15.7,/ &
511  &28X,'MULTIPLIER/DIVIDER FOR TIME STEP (DTADJ) = ',G15.7,/ &
512  &28X,'DIVIDER FOR FAILED TIME STEP (DTFAILADJ) = ',G15.7,/ &
513  &)"
514  n = this%kperats(kper)
515  write (iout, fmtspts) this%dt0(n), this%dtmin(n), this%dtmax(n), &
516  this%dtadj(n), this%dtfailadj(n)
517  end subroutine ats_period_message
518 
519  !> @ brief Allow and external caller to submit preferred time step
520  !!
521  !! Submit a preferred time step length. Alternatively, if idir is
522  !! is passed, then either increase or decrease the submitted time
523  !! step by the dtadj input variable.
524  !!
525  !<
526  subroutine ats_submit_delt(this, kstp, kper, dt, sloc, idir)
527  ! -- dummy
528  class(atstype) :: this
529  integer(I4B), intent(in) :: kstp
530  integer(I4B), intent(in) :: kper
531  real(DP), intent(in) :: dt
532  character(len=*), intent(in) :: sloc
533  integer(I4B), intent(in), optional :: idir
534  ! -- local
535  integer(I4B) :: n
536  real(DP) :: tsfact
537  real(DP) :: dt_temp
538  character(len=*), parameter :: fmtdtsubmit = &
539  &"(1x, 'ATS: ', A,' submitted a preferred time step size of ', G15.7)"
540 
541  if (this%isAdaptivePeriod(kper)) then
542  n = this%kperats(kper)
543  tsfact = this%dtadj(n)
544  if (tsfact > done) then
545  !
546  ! -- if idir is present, then dt is a length that should be adjusted
547  ! (divided by or multiplied by) by dtadj. If idir is not present
548  ! then dt is the submitted time step.
549  if (present(idir)) then
550  dt_temp = dzero
551  if (idir == -1) then
552  dt_temp = dt / tsfact
553  else if (idir == 1) then
554  dt_temp = dt * tsfact
555  end if
556  else
557  dt_temp = dt
558  end if
559  if (kstp > 1 .and. dt_temp > dzero) then
560  write (iout, fmtdtsubmit) trim(adjustl(sloc)), dt_temp
561  end if
562  if (dt_temp > dzero .and. dt_temp < this%dtstable) then
563  ! -- Reset dtstable to a smaller value
564  this%dtstable = dt_temp
565  end if
566  end if
567  end if
568  end subroutine ats_submit_delt
569 
570  !> @ brief Set time step
571  !!
572  !! Set the time step length (delt) for this time step using the ATS
573  !! controls.
574  !!
575  !<
576  subroutine ats_set_delt(this, kstp, kper, pertim, perlencurrent, delt)
577  ! -- modules
578  ! -- dummy
579  class(atstype) :: this
580  integer(I4B), intent(in) :: kstp
581  integer(I4B), intent(in) :: kper
582  real(DP), intent(inout) :: pertim
583  real(DP), intent(in) :: perlencurrent
584  real(DP), intent(inout) :: delt
585  ! -- local
586  integer(I4B) :: n
587  real(DP) :: tstart
588  ! -- formats
589  character(len=*), parameter :: fmtdt = &
590  "(1x, 'ATS: time step set to ', G15.7, ' for step ', i0, &
591  &' and period ', i0)"
592  !
593  ! -- initialize the record position (n) for this stress period
594  n = this%kperats(kper)
595  !
596  ! -- set tstart to the end of the last time step.
597  tstart = pertim
598  !
599  ! -- Calculate delt
600  !
601  ! -- Setup new stress period if kstp is 1
602  if (kstp == 1) then
603  !
604  ! -- Assign first value of delt for this stress period
605  if (this%dt0(n) /= dzero) then
606  delt = this%dt0(n)
607  else
608  ! leave delt the way it was
609  end if
610  else
611  !
612  ! -- Assign delt based on stability
613  if (this%dtstable /= dnodata) then
614  delt = this%dtstable
615  this%dtstable = dnodata
616  end if
617  end if
618  !
619  ! -- Ensure tsmin < delt < tsmax
620  if (delt < this%dtmin(n)) then
621  delt = this%dtmin(n)
622  end if
623  if (delt > this%dtmax(n)) then
624  delt = this%dtmax(n)
625  end if
626  !
627  ! -- Cut timestep down to meet end of period
628  if (tstart + delt > perlencurrent - this%dtmin(n)) then
629  delt = perlencurrent - tstart
630  end if
631  !
632  ! -- Write time step size information
633  write (iout, fmtdt) delt, kstp, kper
634  end subroutine ats_set_delt
635 
636  !> @ brief Reset time step because failure has occurred
637  !!
638  !! Reset the time step using dtfailadj because the time step
639  !! did not converge.
640  !!
641  !<
642  subroutine ats_reset_delt(this, kstp, kper, lastStepFailed, &
643  delt, finishedTrying)
644  ! -- modules
645  ! -- dummy
646  class(atstype) :: this
647  integer(I4B), intent(in) :: kstp
648  integer(I4B), intent(in) :: kper
649  integer(I4B), intent(in) :: lastStepFailed
650  real(DP), intent(inout) :: delt
651  logical, intent(inout) :: finishedTrying
652  ! -- local
653  integer(I4B) :: n
654  real(DP) :: delt_temp
655  real(DP) :: tsfact
656  ! -- formats
657  character(len=*), parameter :: fmttsi = &
658  "(1X, 'Failed solution for step ', i0, ' and period ', i0, &
659  &' will be retried using time step of ', G15.7)"
660  if (this%isAdaptivePeriod(kper)) then
661  if (laststepfailed /= 0) then
662  delt_temp = delt
663  n = this%kperats(kper)
664  tsfact = this%dtfailadj(n)
665  if (tsfact > done) then
666  delt_temp = delt / tsfact
667  if (delt_temp >= this%dtmin(n)) then
668  finishedtrying = .false.
669  delt = delt_temp
670  write (iout, fmttsi) kstp, kper, delt
671  end if
672  end if
673 
674  end if
675  end if
676  end subroutine ats_reset_delt
677 
678  !> @ brief Set end of period indicator
679  !!
680  !! Determine if it is the end of the stress period and set the endofperiod
681  !! logical variable if so.
682  !!
683  !<
684  subroutine ats_set_endofperiod(this, kper, pertim, perlencurrent, endofperiod)
685  ! -- dummy
686  class(atstype) :: this
687  integer(I4B), intent(in) :: kper
688  real(DP), intent(inout) :: pertim
689  real(DP), intent(in) :: perlencurrent
690  logical(LGP), intent(inout) :: endofperiod
691  ! -- local
692  integer(I4B) :: n
693  !
694  ! -- End of stress period and/or simulation?
695  n = this%kperats(kper)
696  if (abs(pertim - perlencurrent) < this%dtmin(n)) then
697  endofperiod = .true.
698  end if
699  end subroutine ats_set_endofperiod
700 
701 end module adaptivetimestepmodule
subroutine ats_reset_delt(this, kstp, kper, lastStepFailed, delt, finishedTrying)
@ brief Reset time step because failure has occurred
Definition: ats.f90:644
subroutine ats_allocate_scalars(this)
@ brief Allocate scalars
Definition: ats.f90:128
subroutine ats_set_endofperiod(this, kper, pertim, perlencurrent, endofperiod)
@ brief Set end of period indicator
Definition: ats.f90:685
subroutine ats_check_timing(this)
@ brief Check timing
Definition: ats.f90:416
subroutine ats_da(this)
@ brief Deallocate variables
Definition: ats.f90:186
subroutine ats_process_input(this)
@ brief Process input
Definition: ats.f90:343
subroutine ats_submit_delt(this, kstp, kper, dt, sloc, idir)
@ brief Allow and external caller to submit preferred time step
Definition: ats.f90:527
subroutine ats_input_table(this)
@ brief Write input table
Definition: ats.f90:364
subroutine ats_read_timing(this)
@ brief Read timing
Definition: ats.f90:293
subroutine ats_allocate_arrays(this)
@ brief Allocate arrays
Definition: ats.f90:149
subroutine ats_period_message(this, kper)
@ brief Write period message
Definition: ats.f90:501
subroutine ats_set_delt(this, kstp, kper, pertim, perlencurrent, delt)
@ brief Set time step
Definition: ats.f90:577
logical(lgp) function isadaptiveperiod(this, kper)
@ brief Determine if period is adaptive
Definition: ats.f90:59
subroutine ats_init(this, inunit, nper_tdis)
@ brief Create ATS object
Definition: ats.f90:76
subroutine ats_read_dimensions(this)
@ brief Read dimensions
Definition: ats.f90:247
subroutine ats_read_options(this)
@ brief Read options
Definition: ats.f90:210
This module contains block parser methods.
Definition: BlockParser.f90:7
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
@ tabcenter
centered table column
Definition: Constants.f90:172
@ tableft
left justified table column
Definition: Constants.f90:171
real(dp), parameter dnodata
real no data constant
Definition: Constants.f90:95
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
This module defines variable data types.
Definition: kind.f90:8
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_warning(msg, substring)
Store warning message.
Definition: Sim.f90:236
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
integer(i4b) function, public count_errors()
Return number of errors.
Definition: Sim.f90:59
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
character(len=maxcharlen) warnmsg
warning message string
integer(i4b) iout
file unit number for simulation output
subroutine, public table_cr(this, name, title)
Definition: Table.f90:87