1 #include "cpp_macros.h"
9 integer,
parameter,
public :: af_num_integrators = 8
11 integer,
parameter,
public :: af_forward_euler = 1
14 integer,
parameter,
public :: af_heuns_method = 2
16 integer,
parameter,
public :: af_midpoint_method = 3
19 integer,
parameter,
public :: af_ssprk33_method = 4
22 integer,
parameter,
public :: af_ssprk43_method = 5
24 integer,
parameter,
public :: af_imex_euler = 6
26 integer,
parameter,
public :: af_imex_trapezoidal = 7
29 integer,
parameter,
public :: af_rk4_method = 8
31 character(len=af_nlen),
public :: af_integrator_names(af_num_integrators) = &
32 [character(len=af_nlen) ::
"forward_euler",
"heuns_method", &
33 "midpoint_method",
"ssprk33",
"ssprk43",
"imex_euler", &
34 "imex_trapezoidal",
"rk4"]
37 integer,
parameter,
public :: &
38 af_advance_num_steps(af_num_integrators) = [1, 2, 2, 3, 4, 1, 2, 4]
41 integer,
parameter :: req_copies(af_num_integrators) = af_advance_num_steps
44 logical,
parameter :: req_implicit(af_num_integrators) = &
45 [.false., .false., .false., .false., .false., .true., .true., .false.]
70 subroutine subr_feuler(tree, dt, dt_stiff, dt_lim, time, s_deriv, n_prev, &
71 s_prev, w_prev, s_out, i_step, n_steps)
73 type(
af_t),
intent(inout) :: tree
74 real(dp),
intent(in) :: dt
75 real(dp),
intent(in) :: dt_stiff
76 real(dp),
intent(inout) :: dt_lim
77 real(dp),
intent(in) :: time
78 integer,
intent(in) :: s_deriv
79 integer,
intent(in) :: n_prev
80 integer,
intent(in) :: s_prev(n_prev)
81 real(dp),
intent(in) :: w_prev(n_prev)
82 integer,
intent(in) :: s_out
83 integer,
intent(in) :: i_step
84 integer,
intent(in) :: n_steps
94 subroutine subr_implicit(tree, dt_stiff, time, n_prev, s_prev, w_prev, s_out)
96 type(
af_t),
intent(inout) :: tree
97 real(dp),
intent(in) :: dt_stiff
98 real(dp),
intent(in) :: time
99 integer,
intent(in) :: n_prev
100 integer,
intent(in) :: s_prev(n_prev)
101 real(dp),
intent(in) :: w_prev(n_prev)
102 integer,
intent(in) :: s_out
118 subroutine af_advance(tree, dt, dt_lim, time, i_cc, time_integrator, &
119 forward_euler, implicit_solver)
120 type(
af_t),
intent(inout) :: tree
121 real(dp),
intent(in) :: dt
122 real(dp),
intent(out) :: dt_lim
123 real(dp),
intent(inout) :: time
124 integer,
intent(in) :: i_cc(:)
126 integer,
intent(in) :: time_integrator
133 real(dp),
parameter :: third = 1/3.0_dp
134 real(dp),
parameter :: sixth = 1/6.0_dp
136 if (time_integrator < 1 .or. time_integrator > af_num_integrators) &
137 error stop
"Invalid time integrator"
139 if (any(tree%cc_num_copies(i_cc) < req_copies(time_integrator))) &
140 error stop
"Not enough copies available"
142 if (req_implicit(time_integrator) .and. .not.
present(implicit_solver)) &
143 error stop
"implicit_solver required"
145 n_steps = af_advance_num_steps(time_integrator)
148 select case (time_integrator)
149 case (af_forward_euler)
150 call forward_euler(tree, dt, dt, dt_lim, time, 0, &
151 1, [0], [1.0_dp], 0, 1, n_steps)
152 case (af_midpoint_method)
153 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time, 0, &
154 1, [0], [1.0_dp], 1, 1, n_steps)
155 call forward_euler(tree, dt, dt, dt_lim, time+0.5_dp*dt, 1, &
156 1, [0], [1.0_dp], 0, 2, n_steps)
157 case (af_heuns_method)
158 call forward_euler(tree, dt, dt, dt_lim, time, 0, &
159 1, [0], [1.0_dp], 1, 1, n_steps)
160 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time+dt, 1, &
161 2, [0, 1], [0.5_dp, 0.5_dp], 0, 2, n_steps)
162 case (af_ssprk33_method)
163 call forward_euler(tree, dt, dt, dt_lim, time, 0, &
164 1, [0], [1.0_dp], 1, 1, n_steps)
165 call forward_euler(tree, 0.25_dp*dt, 0.25_dp*dt, dt_lim, time+dt, 1, &
166 2, [0, 1], [0.75_dp, 0.25_dp], 2, 2, n_steps)
167 call forward_euler(tree, 2*third*dt, 2*third*dt, dt_lim, time+0.5_dp*dt, 2, &
168 2, [0, 2], [third, 2*third], 0, 3, n_steps)
169 case (af_ssprk43_method)
170 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time, 0, &
171 1, [0], [1.0_dp], 1, 1, n_steps)
172 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time+0.5_dp*dt, 1, &
173 1, [1], [1.0_dp], 2, 2, n_steps)
174 call forward_euler(tree, sixth*dt, sixth*dt, dt_lim, time+dt, 2, &
175 2, [0, 2], [2*third, third], 3, 3, n_steps)
176 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time+0.5_dp*dt, 3, &
177 1, [3], [1.0_dp], 0, 4, n_steps)
179 call forward_euler(tree, dt, 0*dt, dt_lim, time, 0, &
180 1, [0], [1.0_dp], 0, 1, n_steps)
181 call implicit_solver(tree, dt, time, 1, [0], [1.0_dp], 0)
182 case (af_imex_trapezoidal)
184 call forward_euler(tree, dt, 0.5_dp*dt, dt_lim, time, 0, &
185 1, [0], [1.0_dp], 1, 1, n_steps)
186 call implicit_solver(tree, 0.5_dp*dt, time, 1, [1], [1.0_dp], 1)
189 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time, 0, &
190 1, [0], [1.0_dp], 0, 1, n_steps)
191 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time, 1, &
192 1, [0], [1.0_dp], 0, 2, n_steps)
198 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time, 0, &
199 1, [0], [1.0_dp], 1, 1, n_steps)
200 call forward_euler(tree, 0.5_dp*dt, 0.5_dp*dt, dt_lim, time+0.5_dp*dt, 1, &
201 1, [0], [1.0_dp], 2, 2, n_steps)
202 call forward_euler(tree, dt, dt, dt_lim, time+0.5_dp*dt, 2, &
203 1, [0], [1.0_dp], 3, 3, n_steps)
204 call forward_euler(tree, sixth*dt, sixth*dt, dt_lim, time+dt, 3, &
205 4, [0, 1, 2, 3], [-third, third, 2*third, third], 0, 4, n_steps)
207 error stop
"Unknown time integrator"
211 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,...