14 #include "sll_assert.h"
123 class(
sll_c_ode),
pointer,
intent(in) :: ode
124 real(wp),
intent(in) :: t0
128 sll_assert(t0 >= 0.0)
129 sll_assert(storage_size(y0) > 0)
136 real(wp),
intent(in) :: t
138 real(wp),
intent(in) :: h
142 call self%ode%rhs(t, y, ynew)
152 sll_assert(storage_size(self) > 0)
160 class(
sll_c_ode),
pointer,
intent(in) :: ode
161 real(wp),
intent(in) :: t0
165 call y0%source(self%work, 1)
166 sll_assert(t0 >= 0.0)
173 real(wp),
intent(in) :: t
175 real(wp),
intent(in) :: h
186 call self%ode%rhs(t, y, self%work(1))
189 call ynew%mult_add(h2, self%work(1), y)
192 call self%ode%rhs(t + h2, ynew, self%work(1))
195 call ynew%mult_add(h, self%work(1), y)
202 deallocate (self%work)
210 class(
sll_c_ode),
pointer,
intent(in) :: ode
211 real(wp),
intent(in) :: t0
215 call y0%source(self%work, 2)
216 sll_assert(t0 >= 0.0)
223 real(wp),
intent(in) :: t
225 real(wp),
intent(in) :: h
229 call self%ode%rhs(t, y, self%work(1))
232 call ynew%mult_add(h, self%work(1), y)
235 call self%ode%rhs(t + h, ynew, self%work(2))
239 call self%work(1)%incr(self%work(2))
242 call ynew%mult_add(h*0.5_f64, self%work(1), y)
249 deallocate (self%work)
257 class(
sll_c_ode),
pointer,
intent(in) :: ode
258 real(wp),
intent(in) :: t0
262 call y0%source(self%work, 2)
264 sll_assert(t0 >= 0.0)
270 real(wp),
intent(in) :: t
272 real(wp),
intent(in) :: h
275 real(wp),
parameter :: two_thirds = 2.0_f64/3.0_f64
278 call self%ode%rhs(t, y, self%work(1))
281 call ynew%mult_add(h*two_thirds, self%work(1), y)
284 call self%ode%rhs(t + h*two_thirds, ynew, self%work(2))
288 call self%work(1)%incr_mult(3.0_f64, self%work(2))
291 call ynew%mult_add(h*0.25_f64, self%work(1), y)
298 deallocate (self%work)
306 class(
sll_c_ode),
pointer,
intent(in) :: ode
307 real(wp),
intent(in) :: t0
311 call y0%source(self%work, 2)
313 sll_assert(t0 >= 0.0)
320 real(wp),
intent(in) :: t
322 real(wp),
intent(in) :: h
326 call self%ode%rhs(t, y, self%work(1))
329 call ynew%mult_add(h/3.0_f64, self%work(1), y)
332 call self%ode%rhs(t + h/3.0_f64, ynew, self%work(2))
335 call ynew%mult_add(h/1.5_f64, self%work(2), y)
338 call self%ode%rhs(t + h/1.5_f64, ynew, self%work(2))
342 call self%work(1)%incr_mult(3.0_f64, self%work(2))
345 call ynew%mult_add(h*0.25_f64, self%work(1), y)
352 deallocate (self%work)
360 class(
sll_c_ode),
pointer,
intent(in) :: ode
361 real(wp),
intent(in) :: t0
365 call y0%source(self%work, 2)
366 sll_assert(t0 >= 0.0)
373 real(wp),
intent(in) :: t
375 real(wp),
intent(in) :: h
379 real(wp),
parameter :: f3 = 1.0_f64/3.0_f64, f6 = 1.0_f64/6.0_f64
380 real(wp),
parameter :: &
381 c2 = 0.5_f64, a21 = 0.5_f64, &
382 c3 = 0.5_f64, a32 = 0.5_f64, &
383 c4 = 1.0_f64, a43 = 1.0_f64, &
384 b1 = f6, b2 = f3, b3 = f3, b4 = f6
387 call self%ode%rhs(t, y, self%work(2))
388 call ynew%mult_add(h*b1, self%work(2), y)
391 call self%work(1)%mult_add(h*a21, self%work(2), y)
392 call self%ode%rhs(t + h*c2, self%work(1), self%work(2))
393 call ynew%incr_mult(h*b2, self%work(2))
396 call self%work(1)%mult_add(h*a32, self%work(2), y)
397 call self%ode%rhs(t + h*c3, self%work(1), self%work(2))
398 call ynew%incr_mult(h*b3, self%work(2))
401 call self%work(1)%mult_add(h*a43, self%work(2), y)
402 call self%ode%rhs(t + h*c4, self%work(1), self%work(2))
403 call ynew%incr_mult(h*b4, self%work(2))
410 deallocate (self%work)
Abstract types for: 1) generic ODE system, and 2) ODE integrator.
subroutine clean__rk1e_fwd_euler(self)
subroutine step__rk1e_fwd_euler(self, t, y, h, ynew)
subroutine step__rk2e_heun(self, t, y, h, ynew)
subroutine step__rk2e_midpoint(self, t, y, h, ynew)
subroutine step__rk3e_heun3(self, t, y, h, ynew)
subroutine clean__rk3e_heun3(self)
integer, parameter wp
Working precision.
subroutine clean__rk2e_heun(self)
subroutine step__rk4e_classic(self, t, y, h, ynew)
subroutine init__rk2e_heun(self, ode, t0, y0)
subroutine init__rk3e_heun3(self, ode, t0, y0)
subroutine clean__rk2e_midpoint(self)
subroutine init__rk1e_fwd_euler(self, ode, t0, y0)
subroutine step__rk2e_ralston(self, t, y, h, ynew)
subroutine init__rk2e_ralston(self, ode, t0, y0)
subroutine clean__rk4e_classic(self)
subroutine init__rk4e_classic(self, ode, t0, y0)
subroutine clean__rk2e_ralston(self)
subroutine init__rk2e_midpoint(self, ode, t0, y0)
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.