14 #include "sll_assert.h"
15 #include "sll_errors.h"
44 real(
wp) :: rel_tol = 1.0e-12_wp
45 real(
wp) :: abs_tol = 1.0e-15_wp
46 integer :: maxiter = 20
81 real(wp),
intent(in) :: rel_tol
82 real(wp),
intent(in) :: abs_tol
83 integer,
intent(in) :: maxiter
86 sll_assert_always(rel_tol > 0.0_wp)
87 sll_assert_always(abs_tol > 0.0_wp)
88 sll_assert_always(maxiter > 0)
90 self%rel_tol = rel_tol
91 self%abs_tol = abs_tol
92 self%maxiter = maxiter
99 real(wp),
intent(out) :: rel_tol
100 real(wp),
intent(out) :: abs_tol
101 integer,
intent(out) :: maxiter
103 rel_tol = self%rel_tol
104 abs_tol = self%abs_tol
105 maxiter = self%maxiter
116 class(
sll_c_ode),
pointer,
intent(in) :: ode
117 real(wp),
intent(in) :: t0
121 call y0%source(self%work, 2)
122 sll_assert_always(storage_size(y0) > 0)
129 real(wp),
intent(in) :: t
131 real(wp),
intent(in) :: h
138 character(len=*),
parameter :: this_sub_name =
"sll_t_rk1d_bwd_euler % step"
139 character(len=256) :: err_msg
141 tol = self%abs_tol + self%rel_tol*y%norm()
147 call self%work(1)%copy(y)
149 do iter = 1, self%maxiter
153 call self%ode%rhs(t, self%work(1), self%work(2))
156 call ynew%mult_add(h, self%work(2), y)
159 call self%work(1)%incr_mult(-1.0_wp, ynew)
161 err = self%work(1)%norm()
167 call self%work(1)%copy(ynew)
172 if (.not. success)
then
173 write (err_msg,
'(A,I0,A)')
"could not converge after ", self%maxiter,
" iterations"
174 sll_error(this_sub_name, err_msg)
183 deallocate (self%work)
194 class(
sll_c_ode),
pointer,
intent(in) :: ode
195 real(wp),
intent(in) :: t0
199 call y0%source(self%work, 2)
200 sll_assert_always(storage_size(y0) > 0)
207 real(wp),
intent(in) :: t
209 real(wp),
intent(in) :: h
216 character(len=*),
parameter :: this_sub_name =
"sll_t_rk1d_trapezoid % step"
217 character(len=256) :: err_msg
219 tol = self%abs_tol + self%rel_tol*y%norm()
225 call self%ode%rhs(t, y, self%work(1))
228 call self%work(2)%copy(y)
230 do iter = 1, self%maxiter
234 call self%ode%rhs(t + h, self%work(2), ynew)
237 call ynew%incr(self%work(1))
240 call ynew%scal(0.5_wp*h)
247 call self%work(2)%incr_mult(-1.0_wp, ynew)
248 err = self%work(2)%norm()
254 call self%work(2)%copy(ynew)
259 if (.not. success)
then
260 write (err_msg,
'(A,I0,A)')
"could not converge after ", self%maxiter,
" iterations"
261 sll_error(this_sub_name, err_msg)
270 deallocate (self%work)
Abstract types for: 1) generic ODE system, and 2) ODE integrator.
subroutine s_rk_implicit__get_params(self, rel_tol, abs_tol, maxiter)
subroutine s_rk_implicit__set_params(self, rel_tol, abs_tol, maxiter)
subroutine rk1d_bwd_euler__step(self, t, y, h, ynew)
subroutine rk1d_trapezoid__step(self, t, y, h, ynew)
integer, parameter wp
Working precision.
subroutine rk1d_trapezoid__init(self, ode, t0, y0)
subroutine rk1d_bwd_euler__clean(self)
subroutine rk1d_bwd_euler__init(self, ode, t0, y0)
subroutine rk1d_trapezoid__clean(self)
Abstract type implementing a generic vector space.
Module to select the kind parameter.
integer, parameter, public f64
f64 is the kind type for 64-bit reals (double precision)
Base class for standard ODE integrators.
Abstract base class for all vector spaces.