MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
timeselectmodule Module Reference

Specify times for some event(s) to occur.

Data Types

type  timeselecttype
 Represents a series of instants at which some event should occur. More...
 

Functions/Subroutines

subroutine destroy (this)
 Destroy the time selection object. More...
 
subroutine expand (this, increment)
 Expand capacity by the given amount. Resets the current slice. More...
 
subroutine init (this)
 Initialize or clear the time selection object. More...
 
logical(lgp) function increasing (this)
 Determine if times strictly increase. Returns true if empty or not yet allocated. More...
 
subroutine select (this, t0, t1, changed)
 Select times between t0 and t1 (inclusive). More...
 
subroutine try_advance (this)
 Update the selection to match the current time step. More...
 

Function/Subroutine Documentation

◆ destroy()

subroutine timeselectmodule::destroy ( class(timeselecttype this)

Definition at line 33 of file TimeSelect.f90.

34  class(TimeSelectType) :: this
35  deallocate (this%times)

◆ expand()

subroutine timeselectmodule::expand ( class(timeselecttype this,
integer(i4b), intent(in), optional  increment 
)

Definition at line 39 of file TimeSelect.f90.

40  class(TimeSelectType) :: this
41  integer(I4B), optional, intent(in) :: increment
42  call expandarray(this%times, increment=increment)
43  this%selection = (/1, size(this%times)/)

◆ increasing()

logical(lgp) function timeselectmodule::increasing ( class(timeselecttype this)

Definition at line 55 of file TimeSelect.f90.

56  class(TimeSelectType) :: this
57  logical(LGP) :: inc
58  integer(I4B) :: i
59  real(DP) :: l, t
60 
61  inc = .true.
62  if (.not. allocated(this%times)) return
63  do i = 1, size(this%times)
64  t = this%times(i)
65  if (i /= 1) then
66  if (l >= t) then
67  inc = .false.
68  return
69  end if
70  end if
71  l = t
72  end do

◆ init()

subroutine timeselectmodule::init ( class(timeselecttype this)

Definition at line 47 of file TimeSelect.f90.

48  class(TimeSelectType) :: this
49  if (.not. allocated(this%times)) allocate (this%times(0))
50  this%selection = (/0, 0/)

◆ select()

subroutine timeselectmodule::select ( class(timeselecttype this,
real(dp), intent(in)  t0,
real(dp), intent(in)  t1,
logical(lgp), intent(inout), optional  changed 
)

Finds and stores the index of the first time at the same instant as or following the start time, and of the last time at the same instant as or preceding the end time. Allows filtering the times for e.g. a particular stress period and time step. Array indices are assumed to start at 1. If no times are found to fall within the selection (i.e. it falls entirely between two consecutive times or beyond the time range), indices are set to [-1, -1].

The given start and end times are first checked against currently stored indices to avoid recalculating them if possible, allowing multiple consuming components (e.g., subdomain particle tracking solutions) to share the object efficiently, provided all proceed through stress periods and time steps in lockstep, i.e. they all solve any given period/step before any will proceed to the next.

Definition at line 92 of file TimeSelect.f90.

93  ! -- dummy
94  class(TimeSelectType) :: this
95  real(DP), intent(in) :: t0, t1
96  logical(LGP), intent(inout), optional :: changed
97  ! -- local
98  integer(I4B) :: i, i0, i1
99  integer(I4B) :: l, u, lp, up
100  real(DP) :: t
101 
102  ! -- by default, need to iterate over all times
103  i0 = 1
104  i1 = size(this%times)
105 
106  ! -- if no times fall within the slice, set to [-1, -1]
107  l = -1
108  u = -1
109 
110  ! -- previous bounding indices
111  lp = this%selection(1)
112  up = this%selection(2)
113 
114  ! -- Check if we can reuse either the lower or upper bound.
115  ! The lower doesn't need to change if it indexes the 1st
116  ! time simultaneous with or later than the slice's start.
117  ! The upper doesn't need to change if it indexes the last
118  ! time before or simultaneous with the slice's end.
119  if (lp > 0 .and. up > 0) then
120  if (lp > 1) then
121  if (this%times(lp - 1) < t0 .and. &
122  this%times(lp) >= t0) then
123  l = lp
124  i0 = l
125  end if
126  end if
127  if (up > 1 .and. up < i1) then
128  if (this%times(up + 1) > t1 .and. &
129  this%times(up) <= t1) then
130  u = up
131  i1 = u
132  end if
133  end if
134  if (l == lp .and. u == up) then
135  this%selection = (/l, u/)
136  if (present(changed)) changed = .false.
137  return
138  end if
139  end if
140 
141  ! -- recompute bounding indices if needed
142  do i = i0, i1
143  t = this%times(i)
144  if (l < 0 .and. t >= t0 .and. t <= t1) l = i
145  if (l > 0 .and. t <= t1) u = i
146  end do
147  this%selection = (/l, u/)
148  if (present(changed)) changed = l /= lp .or. u /= up
149 

◆ try_advance()

subroutine timeselectmodule::try_advance ( class(timeselecttype this)

Definition at line 153 of file TimeSelect.f90.

154  ! -- modules
155  use tdismodule, only: kper, kstp, nper, nstp, totimc, delt
156  ! -- dummy
157  class(TimeSelectType) :: this
158  ! -- local
159  real(DP) :: l, u
160  l = minval(this%times)
161  u = maxval(this%times)
162  if (.not. (kper == 1 .and. kstp == 1)) l = totimc
163  if (.not. (kper == nper .and. kstp == nstp(kper))) u = totimc + delt
164  call this%select(l, u)
integer(i4b), dimension(:), pointer, public, contiguous nstp
number of time steps in each stress period
Definition: tdis.f90:39
real(dp), pointer, public totimc
simulation time at start of time step
Definition: tdis.f90:33
integer(i4b), pointer, public kstp
current time step number
Definition: tdis.f90:24
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:23
real(dp), pointer, public delt
length of the current time step
Definition: tdis.f90:29
integer(i4b), pointer, public nper
number of stress period
Definition: tdis.f90:21