Skip to content

Commit b8e951f

Browse files
committed
add fast mode to many other inegrators
1 parent a75c016 commit b8e951f

7 files changed

+366
-21
lines changed

src/lib/foodie_integrand_object.f90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ module foodie_integrand_object
5252
! public methods for fast operational mode, must be overridden
5353
procedure, pass(self), public :: t_fast !< Time derivative, residuals, fast mode.
5454
procedure, pass(opr), public :: integrand_add_integrand_fast !< `+` fast operator.
55-
generic, public :: add_fast => integrand_add_integrand_fast !< Overloading `add` method.
55+
generic, public :: add_fast => integrand_add_integrand_fast !< Overloading `add_fast` method.
5656
procedure, pass(opr), public :: integrand_multiply_integrand_fast !< `*` fast operator.
5757
procedure, pass(opr), public :: integrand_multiply_real_scalar_fast !< `* real_scalar` fast operator.
5858
generic, public :: multiply_fast => integrand_multiply_integrand_fast, &
59-
integrand_multiply_real_scalar_fast !< Overloading `multiply` method.
59+
integrand_multiply_real_scalar_fast !< Overloading `multiply_fast` method.
6060
procedure, pass(opr), public :: integrand_subtract_integrand_fast !< `-` fast operator.
61-
generic, public :: subtract_fast => integrand_multiply_integrand_fast !< Overloading `subtract` method.
61+
generic, public :: subtract_fast => integrand_subtract_integrand_fast !< Overloading `subtract_fast` method.
6262
endtype integrand_object
6363

6464
abstract interface

src/lib/foodie_integrator_backward_differentiation_formula.f90

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ module foodie_integrator_backward_differentiation_formula
5050
trim(class_name_)//'_5', &
5151
trim(class_name_)//'_6'] !< List of supported schemes.
5252

53-
logical, parameter :: has_fast_mode_=.false. !< Flag to check if integrator provides *fast mode* integrate.
53+
logical, parameter :: has_fast_mode_=.true. !< Flag to check if integrator provides *fast mode* integrate.
5454

5555
type, extends(integrator_object) :: integrator_back_df
5656
!< FOODIE integrator: provide an implicit class of Backward-Differentiation-Formula multi-step schemes, from 1st to 6th order
@@ -73,6 +73,7 @@ module foodie_integrator_backward_differentiation_formula
7373
procedure, pass(self) :: destroy !< Destroy the integrator.
7474
procedure, pass(self) :: initialize !< Initialize (create) the integrator.
7575
procedure, pass(self) :: integrate !< Integrate integrand field.
76+
procedure, pass(self) :: integrate_fast !< Integrate integrand field, fast mode.
7677
procedure, pass(self) :: update_previous !< Cyclic update previous time steps.
7778
endtype integrator_back_df
7879

@@ -246,6 +247,38 @@ subroutine integrate(self, U, previous, Dt, t, iterations, autoupdate)
246247
if (autoupdate_) call self%update_previous(U=U, previous=previous)
247248
endsubroutine integrate
248249

250+
subroutine integrate_fast(self, U, previous, buffer, Dt, t, iterations, autoupdate)
251+
!< Integrate field with BDF class scheme.
252+
class(integrator_back_df), intent(in) :: self !< Integrator.
253+
class(integrand_object), intent(inout) :: U !< Field to be integrated.
254+
class(integrand_object), intent(inout) :: previous(1:) !< Previous time steps solutions of integrand field.
255+
class(integrand_object), intent(inout) :: buffer !< Temporary buffer for doing fast operation.
256+
real(R_P), intent(in) :: Dt !< Time steps.
257+
real(R_P), intent(in) :: t(:) !< Times.
258+
integer(I_P), optional, intent(in) :: iterations !< Fixed point iterations.
259+
logical, optional, intent(in) :: autoupdate !< Perform cyclic autoupdate of previous time steps.
260+
integer(I_P) :: iterations_ !< Fixed point iterations.
261+
logical :: autoupdate_ !< Perform cyclic autoupdate of previous time steps, dummy var.
262+
class(integrand_object), allocatable :: delta !< Delta RHS for fixed point iterations.
263+
integer(I_P) :: s !< Steps counter.
264+
265+
autoupdate_ = .true. ; if (present(autoupdate)) autoupdate_ = autoupdate
266+
iterations_ = 1 ; if (present(iterations)) iterations_ = iterations
267+
allocate(delta, mold=U)
268+
call delta%multiply_fast(lhs=previous(self%steps), rhs=-self%a(self%steps))
269+
do s=1, self%steps - 1
270+
call buffer%multiply_fast(lhs=previous(s), rhs=-self%a(s))
271+
call delta%add_fast(lhs=delta, rhs=buffer)
272+
enddo
273+
do s=1, iterations
274+
buffer = U
275+
call buffer%t_fast(t=t(self%steps) + Dt)
276+
call buffer%multiply_fast(lhs=buffer, rhs=Dt * self%b)
277+
call U%add_fast(lhs=delta, rhs=buffer)
278+
enddo
279+
if (autoupdate_) call self%update_previous(U=U, previous=previous)
280+
endsubroutine integrate_fast
281+
249282
subroutine update_previous(self, U, previous)
250283
!< Cyclic update previous time steps.
251284
class(integrator_back_df), intent(in) :: self !< Integrator.

src/lib/foodie_integrator_euler_explicit.f90

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ module foodie_integrator_euler_explicit
2525
character(len=99), parameter :: class_name_='euler_explicit' !< Name of the class of schemes.
2626
character(len=99), parameter :: supported_schemes_(1:1)=[trim(class_name_)] !< List of supported schemes.
2727

28-
logical, parameter :: has_fast_mode_=.false. !< Flag to check if integrator provides *fast mode* integrate.
28+
logical, parameter :: has_fast_mode_=.true. !< Flag to check if integrator provides *fast mode* integrate.
2929

3030
type, extends(integrator_object) :: integrator_euler_explicit
3131
!< FOODIE integrator: provide explicit Euler scheme, it being 1st order accurate.
@@ -40,8 +40,9 @@ module foodie_integrator_euler_explicit
4040
procedure, pass(self) :: is_supported !< Return .true. if the integrator class support the given scheme.
4141
procedure, pass(self) :: supported_schemes !< Return the list of supported schemes.
4242
! public methods
43-
procedure, pass(self) :: destroy !< Destroy the integrator.
44-
procedure, nopass :: integrate !< Integrate integrand field.
43+
procedure, pass(self) :: destroy !< Destroy the integrator.
44+
procedure, nopass :: integrate !< Integrate integrand field.
45+
procedure, nopass :: integrate_fast !< Integrate integrand field, fast mode.
4546
endtype integrator_euler_explicit
4647
contains
4748
! deferred methods
@@ -121,4 +122,17 @@ subroutine integrate(U, Dt, t)
121122

122123
U = U + (U%t(t=t) * Dt)
123124
endsubroutine integrate
125+
126+
subroutine integrate_fast(U, buffer, Dt, t)
127+
!< Integrate field with explicit Euler scheme, 1st order, fast mode.
128+
class(integrand_object), intent(inout) :: U !< Field to be integrated.
129+
class(integrand_object), intent(inout) :: buffer !< Temporary buffer for doing fast operation.
130+
real(R_P), intent(in) :: Dt !< Time step.
131+
real(R_P), optional, intent(in) :: t !< Time.
132+
133+
buffer = U
134+
call buffer%t_fast(t=t)
135+
call buffer%multiply_fast(lhs=buffer, rhs=Dt)
136+
call U%add_fast(lhs=U, rhs=buffer)
137+
endsubroutine integrate_fast
124138
endmodule foodie_integrator_euler_explicit

src/lib/foodie_integrator_leapfrog.f90

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ module foodie_integrator_leapfrog
4949
character(len=99), parameter :: supported_schemes_(1:2)=[trim(class_name_)//' ', &
5050
trim(class_name_)//'_raw'] !< List of supported schemes.
5151

52-
logical, parameter :: has_fast_mode_=.false. !< Flag to check if integrator provides *fast mode* integrate.
52+
logical, parameter :: has_fast_mode_=.true. !< Flag to check if integrator provides *fast mode* integrate.
5353

5454
type, extends(integrator_object) :: integrator_leapfrog
5555
!< FOODIE integrator: provide an explicit class of leapfrog multi-step schemes, 2nd order accurate.
@@ -69,9 +69,10 @@ module foodie_integrator_leapfrog
6969
procedure, pass(self) :: is_supported !< Return .true. if the integrator class support the given scheme.
7070
procedure, pass(self) :: supported_schemes !< Return the list of supported schemes.
7171
! public methods
72-
procedure, pass(self) :: destroy !< Destroy the integrator.
73-
procedure, pass(self) :: initialize !< Initialize (create) the integrator.
74-
procedure, pass(self) :: integrate !< Integrate integrand field.
72+
procedure, pass(self) :: destroy !< Destroy the integrator.
73+
procedure, pass(self) :: initialize !< Initialize (create) the integrator.
74+
procedure, pass(self) :: integrate !< Integrate integrand field.
75+
procedure, pass(self) :: integrate_fast !< Integrate integrand field, fast mode.
7576
endtype integrator_leapfrog
7677

7778
contains
@@ -189,4 +190,34 @@ subroutine integrate(self, U, previous, Dt, t, filter)
189190
previous(1) = previous(2)
190191
previous(2) = U
191192
endsubroutine integrate
193+
194+
subroutine integrate_fast(self, U, previous, buffer, Dt, t, filter)
195+
!< Integrate field with leapfrog class scheme, fast mode.
196+
class(integrator_leapfrog), intent(in) :: self !< Integrator.
197+
class(integrand_object), intent(inout) :: U !< Field to be integrated.
198+
class(integrand_object), intent(inout) :: previous(1:2) !< Previous time steps solutions of integrand field.
199+
class(integrand_object), intent(inout) :: buffer !< Temporary buffer for doing fast operation.
200+
real(R_P), intent(in) :: Dt !< Time step.
201+
real(R_P), intent(in) :: t !< Time.
202+
class(integrand_object), optional, intent(inout) :: filter !< Filter field displacement.
203+
204+
buffer = previous(2)
205+
call buffer%t_fast(t=t)
206+
call buffer%multiply_fast(lhs=buffer, rhs=Dt * 2._R_P)
207+
call U%add_fast(lhs=previous(1), rhs=buffer)
208+
if (present(filter)) then
209+
call buffer%multiply_fast(lhs=previous(2), rhs=2._R_P)
210+
call buffer%subtract_fast(lhs=previous(1), rhs=buffer)
211+
call buffer%add_fast(lhs=buffer, rhs=U)
212+
call filter%multiply_fast(lhs=buffer, rhs=self%nu * 0.5_R_P)
213+
214+
call buffer%multiply_fast(lhs=filter, rhs=self%alpha)
215+
call previous(2)%add_fast(lhs=previous(2), rhs=buffer)
216+
217+
call buffer%multiply_fast(lhs=filter, rhs=self%alpha - 1._R_P)
218+
call U%add_fast(lhs=U, rhs=buffer)
219+
endif
220+
previous(1) = previous(2)
221+
previous(2) = U
222+
endsubroutine integrate_fast
192223
endmodule foodie_integrator_leapfrog

src/lib/foodie_integrator_lmm_ssp.f90

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ module foodie_integrator_lmm_ssp
4040
trim(class_name_)//'_steps_4_order_3', &
4141
trim(class_name_)//'_steps_5_order_3'] !< List of supported schemes.
4242

43-
logical, parameter :: has_fast_mode_=.false. !< Flag to check if integrator provides *fast mode* integrate.
43+
logical, parameter :: has_fast_mode_=.true. !< Flag to check if integrator provides *fast mode* integrate.
4444

4545
type, extends(integrator_object) :: integrator_lmm_ssp
4646
!< FOODIE integrator: provide an explicit class of Linear Multi-step Methods (LLM) with Strong Stability Preserving property,
@@ -63,6 +63,7 @@ module foodie_integrator_lmm_ssp
6363
procedure, pass(self) :: destroy !< Destroy the integrator.
6464
procedure, pass(self) :: initialize !< Initialize (create) the integrator.
6565
procedure, pass(self) :: integrate !< Integrate integrand field.
66+
procedure, pass(self) :: integrate_fast !< Integrate integrand field, fast mode.
6667
procedure, pass(self) :: update_previous !< Cyclic update previous time steps.
6768
endtype integrator_lmm_ssp
6869

@@ -231,6 +232,35 @@ subroutine integrate(self, U, previous, Dt, t, autoupdate)
231232
if (autoupdate_) call self%update_previous(U=U, previous=previous)
232233
endsubroutine integrate
233234

235+
subroutine integrate_fast(self, U, previous, buffer, Dt, t, autoupdate)
236+
!< Integrate field with LMM-SSP class scheme, fast mode.
237+
class(integrator_lmm_ssp), intent(in) :: self !< Integrator.
238+
class(integrand_object), intent(inout) :: U !< Field to be integrated.
239+
class(integrand_object), intent(inout) :: previous(1:) !< Previous time steps solutions of integrand field.
240+
class(integrand_object), intent(inout) :: buffer !< Temporary buffer for doing fast operation.
241+
real(R_P), intent(in) :: Dt !< Time steps.
242+
real(R_P), intent(in) :: t(:) !< Times.
243+
logical, optional, intent(in) :: autoupdate !< Perform cyclic autoupdate of previous time steps.
244+
logical :: autoupdate_ !< Perform cyclic autoupdate of previous time steps, dummy var.
245+
integer(I_P) :: s !< Steps counter.
246+
247+
autoupdate_ = .true. ; if (present(autoupdate)) autoupdate_ = autoupdate
248+
call U%multiply_fast(lhs=U, rhs=0._R_P)
249+
do s=1, self%steps
250+
if (self%a(s) /= 0._R_P) then
251+
call buffer%multiply_fast(lhs=previous(s), rhs=self%a(s))
252+
call U%add_fast(lhs=U, rhs=buffer)
253+
endif
254+
if (self%b(s) /= 0._R_P) then
255+
buffer = previous(s)
256+
call buffer%t_fast(t=t(s))
257+
call buffer%multiply_fast(lhs=buffer, rhs=self%b(s))
258+
call U%add_fast(lhs=U, rhs=buffer)
259+
endif
260+
enddo
261+
if (autoupdate_) call self%update_previous(U=U, previous=previous)
262+
endsubroutine integrate_fast
263+
234264
subroutine update_previous(self, U, previous)
235265
!< Cyclic update previous time steps.
236266
class(integrator_lmm_ssp), intent(in) :: self !< Integrator.

src/lib/foodie_integrator_lmm_ssp_vss.f90

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -357,11 +357,18 @@ subroutine integrate_order_3_fast(self, U, previous, buffer, Dt, t, autoupdate)
357357

358358
autoupdate_ = .true. ; if (present(autoupdate)) autoupdate_ = autoupdate
359359
omega_= omega(Dt=Dt, s=self%steps-1)
360-
! @TODO to be completed
361-
U = (previous(1) * ((3._R_P * omega_ + 2._R_P) / omega_ ** 3 )) + &
362-
(previous(self%steps) * (((omega_ + 1._R_P) ** 2) * (omega_ - 2._R_P) / omega_ ** 3)) + &
363-
(previous(1)%t(t=t(1)) * (Dt(self%steps) * (omega_ + 1._R_P) / omega_ ** 2)) + &
364-
(previous(self%steps)%t(t=t(self%steps)) * (Dt(self%steps) * (omega_ + 1._R_P) ** 2 / omega_ ** 2))
360+
361+
call U%multiply_fast(lhs=previous(1), rhs=(3._R_P * omega_ + 2._R_P) / (omega_ ** 3))
362+
call buffer%multiply_fast(lhs=previous(self%steps), rhs=(((omega_ + 1._R_P) ** 2) * (omega_ - 2._R_P) / (omega_ ** 3)))
363+
call U%add_fast(lhs=U, rhs=buffer)
364+
buffer = previous(1)
365+
call buffer%t_fast(t=t(1))
366+
call buffer%multiply_fast(lhs=buffer, rhs=Dt(self%steps) * (omega_ + 1._R_P) / (omega_ ** 2))
367+
call U%add_fast(lhs=U, rhs=buffer)
368+
buffer = previous(self%steps)
369+
call buffer%t_fast(t=t(self%steps))
370+
call buffer%multiply_fast(lhs=buffer, rhs=(Dt(self%steps) * (omega_ + 1._R_P) ** 2 / (omega_ ** 2)))
371+
call U%add_fast(lhs=U, rhs=buffer)
365372
if (autoupdate_) call self%update_previous(U=U, previous=previous, Dt=Dt)
366373
endsubroutine integrate_order_3_fast
367374

0 commit comments

Comments
 (0)