3 #include "cpp_macros.h"
9 integer,
parameter,
public :: af_num_integrators = 8
13 integer,
parameter,
public :: af_forward_euler = 1
16 integer,
parameter,
public :: af_heuns_method = 2
18 integer,
parameter,
public :: af_midpoint_method = 3
21 integer,
parameter,
public :: af_ssprk33_method = 4
24 integer,
parameter,
public :: af_ssprk43_method = 5
26 integer,
parameter,
public :: af_imex_euler = 6
28 integer,
parameter,
public :: af_imex_trapezoidal = 7
31 integer,
parameter,
public :: af_rk4_method = 8
34 character(len=af_nlen),
public :: af_integrator_names(af_num_integrators) = &
35 [character(len=af_nlen) ::
"forward_euler",
"heuns_method", &
36 "midpoint_method",
"ssprk33",
"ssprk43",
"imex_euler", &
37 "imex_trapezoidal",
"rk4"]
40 integer,
parameter,
public :: &
41 af_advance_num_steps(af_num_integrators) = [1, 2, 2, 3, 4, 1, 2, 4]
44 integer,
parameter :: req_copies(af_num_integrators) = af_advance_num_steps
47 logical,
parameter :: req_implicit(af_num_integrators) = &
48 [.false., .false., .false., .false., .false., .true., .true., .false.]
73 subroutine subr_feuler(tree, dt, dt_stiff, dt_lim, time, s_deriv, n_prev, &
74 s_prev, w_prev, s_out, i_step, n_steps)
76 type(
af_t),
intent(inout) :: tree
77 real(dp),
intent(in) :: dt
78 real(dp),
intent(in) :: dt_stiff
79 real(dp),
intent(inout) :: dt_lim
80 real(dp),
intent(in) :: time
81 integer,
intent(in) :: s_deriv
82 integer,
intent(in) :: n_prev
83 integer,
intent(in) :: s_prev(n_prev)
84 real(dp),
intent(in) :: w_prev(n_prev)
85 integer,
intent(in) :: s_out
86 integer,
intent(in) :: i_step
87 integer,
intent(in) :: n_steps
97 subroutine subr_implicit(tree, dt_stiff, time, n_prev, s_prev, w_prev, s_out)
99 type(
af_t),
intent(inout) :: tree
100 real(dp),
intent(in) :: dt_stiff
101 real(dp),
intent(in) :: time
102 integer,
intent(in) :: n_prev
103 integer,
intent(in) :: s_prev(n_prev)
104 real(dp),
intent(in) :: w_prev(n_prev)
105 integer,
intent(in) :: s_out
121 subroutine af_advance(tree, dt, dt_lim, time, i_cc, time_integrator, &
122 forward_euler, implicit_solver)
123 type(
af_t),
intent(inout) :: tree
124 real(dp),
intent(in) :: dt
125 real(dp),
intent(out) :: dt_lim
126 real(dp),
intent(inout) :: time
127 integer,
intent(in) :: i_cc(:)
129 integer,
intent(in) :: time_integrator
136 real(dp),
parameter :: third = 1/3.0_dp
137 real(dp),
parameter :: sixth = 1/6.0_dp
139 if (time_integrator < 1 .or. time_integrator > af_num_integrators) &
140 error stop
"Invalid time integrator"
142 if (any(tree%cc_num_copies(i_cc) < req_copies(time_integrator))) &
143 error stop
"Not enough copies available"
145 if (req_implicit(time_integrator) .and. .not.
present(implicit_solver)) &
146 error stop
"implicit_solver required"
148 n_steps = af_advance_num_steps(time_integrator)
151 select case (time_integrator)
152 case (af_forward_euler)
153 call forward_euler(tree, dt, dt, dt_lim, time, 0, &
154 1, [0], [1.0_dp], 0, 1, n_steps)
155 case (af_midpoint_method)
156 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time, 0, &
157 1, [0], [1.0_dp], 1, 1, n_steps)
158 call forward_euler(tree, dt, dt, dt_lim, time+0.5_dp*dt, 1, &
159 1, [0], [1.0_dp], 0, 2, n_steps)
160 case (af_heuns_method)
161 call forward_euler(tree, dt, dt, dt_lim, time, 0, &
162 1, [0], [1.0_dp], 1, 1, n_steps)
163 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time+dt, 1, &
164 2, [0, 1], [0.5_dp, 0.5_dp], 0, 2, n_steps)
165 case (af_ssprk33_method)
166 call forward_euler(tree, dt, dt, dt_lim, time, 0, &
167 1, [0], [1.0_dp], 1, 1, n_steps)
168 call forward_euler(tree, 0.25_dp*dt, 0.25_dp*dt, dt_lim, time+dt, 1, &
169 2, [0, 1], [0.75_dp, 0.25_dp], 2, 2, n_steps)
170 call forward_euler(tree, 2*third*dt, 2*third*dt, dt_lim, time+0.5_dp*dt, 2, &
171 2, [0, 2], [third, 2*third], 0, 3, n_steps)
172 case (af_ssprk43_method)
173 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time, 0, &
174 1, [0], [1.0_dp], 1, 1, n_steps)
175 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time+0.5_dp*dt, 1, &
176 1, [1], [1.0_dp], 2, 2, n_steps)
177 call forward_euler(tree, sixth*dt, sixth*dt, dt_lim, time+dt, 2, &
178 2, [0, 2], [2*third, third], 3, 3, n_steps)
179 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time+0.5_dp*dt, 3, &
180 1, [3], [1.0_dp], 0, 4, n_steps)
182 call forward_euler(tree, dt, 0*dt, dt_lim, time, 0, &
183 1, [0], [1.0_dp], 0, 1, n_steps)
184 call implicit_solver(tree, dt, time, 1, [0], [1.0_dp], 0)
185 case (af_imex_trapezoidal)
187 call forward_euler(tree, dt, 0.5_dp*dt, dt_lim, time, 0, &
188 1, [0], [1.0_dp], 1, 1, n_steps)
189 call implicit_solver(tree, 0.5_dp*dt, time, 1, [1], [1.0_dp], 1)
192 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time, 0, &
193 1, [0], [1.0_dp], 0, 1, n_steps)
194 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time, 1, &
195 1, [0], [1.0_dp], 0, 2, n_steps)
201 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time, 0, &
202 1, [0], [1.0_dp], 1, 1, n_steps)
203 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time+0.5_dp*dt, 1, &
204 1, [0], [1.0_dp], 2, 2, n_steps)
205 call forward_euler(tree, dt, dt, dt_lim, time+0.5_dp*dt, 2, &
206 1, [0], [1.0_dp], 3, 3, n_steps)
207 call forward_euler(tree, sixth*dt, sixth*dt, dt_lim, time+dt, 3, &
208 4, [0, 1, 2, 3], [-third, third, 2*third, third], 0, 4, n_steps)
210 error stop
"Unknown time integrator"
214 end subroutine af_advance
Interface for a generic forward Euler scheme for time integration.
Interface for a implicit solver for integrating stiff terms over time.
Module with methods to perform time integration.
This module contains the basic types and constants that are used in the NDIM-dimensional version of A...
Type which stores all the boxes and levels, as well as some information about the number of boxes,...