@@ -54,6 +54,8 @@ module foodie_integrator_adams_moulton
5454 trim (class_name_)// ' _14' , &
5555 trim (class_name_)// ' _15' ] ! < List of supported schemes.
5656
57+ logical , parameter :: has_fast_mode_= .true. ! < Flag to check if integrator provides *fast mode* integrate.
58+
5759type, extends(integrator_object) :: integrator_adams_moulton
5860 ! < FOODIE integrator: provide an explicit class of Adams-Moulton multi-step schemes, from 1st to 16th order accurate.
5961 ! <
@@ -66,12 +68,14 @@ module foodie_integrator_adams_moulton
6668 procedure , pass(self) :: class_name ! < Return the class name of schemes.
6769 procedure , pass(self) :: description ! < Return pretty-printed object description.
6870 procedure , pass(lhs) :: integr_assign_integr ! < Operator `=`.
71+ procedure , pass(self) :: has_fast_mode ! < Return .true. if the integrator class has *fast mode* integrate.
6972 procedure , pass(self) :: is_supported ! < Return .true. if the integrator class support the given scheme.
7073 procedure , pass(self) :: supported_schemes ! < Return the list of supported schemes.
7174 ! public methods
7275 procedure , pass(self) :: destroy ! < Destroy the integrator.
7376 procedure , pass(self) :: initialize ! < Initialize (create) the integrator.
7477 procedure , pass(self) :: integrate ! < Integrate integrand field.
78+ procedure , pass(self) :: integrate_fast ! < Integrate integrand field, fast mode.
7579 procedure , pass(self) :: update_previous ! < Cyclic update previous time steps.
7680endtype integrator_adams_moulton
7781
@@ -104,6 +108,14 @@ pure function description(self, prefix) result(desc)
104108 desc = desc// prefix_// ' + ' // supported_schemes_(ubound (supported_schemes_, dim= 1 ))
105109 end function description
106110
111+ elemental function has_fast_mode (self )
112+ ! < Return .true. if the integrator class has *fast mode* integrate.
113+ class(integrator_adams_moulton), intent (in ) :: self ! < Integrator.
114+ logical :: has_fast_mode ! < Inquire result.
115+
116+ has_fast_mode = has_fast_mode_
117+ end function has_fast_mode
118+
107119 pure subroutine integr_assign_integr (lhs , rhs )
108120 ! < Operator `=`.
109121 class(integrator_adams_moulton), intent (inout ) :: lhs ! < Left hand side.
@@ -355,23 +367,75 @@ subroutine integrate(self, U, previous, Dt, t, iterations, autoupdate)
355367 allocate (delta, mold= U)
356368 delta = previous(self% steps)
357369 do s= 0 , self% steps - 1
358- delta = delta + previous(s+1 )% t(t= t(s+1 )) * (Dt * self% b(s))
370+ delta = delta + ( previous(s+1 )% t(t= t(s+1 )) * (Dt * self% b(s) ))
359371 enddo
360372 do s= 1 , iterations
361- U = delta + U% t(t= t(self% steps) + Dt) * (Dt * self% b(self% steps))
373+ U = delta + ( U% t(t= t(self% steps) + Dt) * (Dt * self% b(self% steps) ))
362374 enddo
363375 else
364- U = previous(self% steps) + U% t(t= t(self% steps) + Dt) * (Dt * self% b(self% steps))
376+ U = previous(self% steps) + ( U% t(t= t(self% steps) + Dt) * (Dt * self% b(self% steps) ))
365377 do s= 0 , self% steps - 1
366- U = U + previous(s+1 )% t(t= t(s+1 )) * (Dt * self% b(s))
378+ U = U + ( previous(s+1 )% t(t= t(s+1 )) * (Dt * self% b(s) ))
367379 enddo
368380 endif
369381 if (autoupdate_) call self% update_previous(U= U, previous= previous)
370382 else
371- U = U + U% t(t= t(1 )) * (Dt * self% b(0 ))
383+ U = U + ( U% t(t= t(1 )) * (Dt * self% b(0 ) ))
372384 endif
373385 end subroutine integrate
374386
387+ subroutine integrate_fast (self , U , previous , buffer , Dt , t , iterations , autoupdate )
388+ ! < Integrate field with Adams-Moulton class scheme, fast mode.
389+ class(integrator_adams_moulton), intent (in ) :: self ! < Integrator.
390+ class(integrand_object), intent (inout ) :: U ! < Field to be integrated.
391+ class(integrand_object), intent (inout ) :: previous(1 :) ! < Previous time steps solutions of integrand field.
392+ class(integrand_object), intent (inout ) :: buffer ! < Temporary buffer for doing fast operation.
393+ real (R_P), intent (in ) :: Dt ! < Time steps.
394+ real (R_P), intent (in ) :: t(:) ! < Times.
395+ integer (I_P), intent (in ), optional :: iterations ! < Fixed point iterations.
396+ logical , intent (in ), optional :: autoupdate ! < Cyclic autoupdate of previous time steps flag.
397+ logical :: autoupdate_ ! < Cyclic autoupdate of previous time steps flag, dummy var.
398+ class(integrand_object), allocatable :: delta ! < Delta RHS for fixed point iterations.
399+ integer (I_P) :: s ! < Steps counter.
400+
401+ autoupdate_ = .true. ; if (present (autoupdate)) autoupdate_ = autoupdate
402+ if (self% steps> 0 ) then
403+ if (present (iterations)) then ! perform fixed point iterations
404+ allocate (delta, mold= U)
405+ delta = previous(self% steps)
406+ do s= 0 , self% steps - 1
407+ buffer = previous(s+1 )
408+ call buffer% t_fast(t= t(s+1 ))
409+ call buffer% multiply_fast(lhs= buffer, rhs= Dt * self% b(s))
410+ call delta% add_fast(lhs= delta, rhs= buffer)
411+ enddo
412+ do s= 1 , iterations
413+ buffer = U
414+ call buffer% t_fast(t= t(self% steps) + Dt)
415+ call buffer% multiply_fast(lhs= buffer, rhs= Dt * self% b(self% steps))
416+ call U% add_fast(lhs= delta, rhs= buffer)
417+ enddo
418+ else
419+ buffer = U
420+ call buffer% t_fast(t= t(self% steps) + Dt)
421+ call buffer% multiply_fast(lhs= buffer, rhs= Dt * self% b(self% steps))
422+ call U% add_fast(lhs= previous(self% steps), rhs= buffer)
423+ do s= 0 , self% steps - 1
424+ buffer = previous(s+1 )
425+ call buffer% t_fast(t= t(s+1 ))
426+ call buffer% multiply_fast(lhs= buffer, rhs= Dt * self% b(s))
427+ call U% add_fast(lhs= U, rhs= buffer)
428+ enddo
429+ endif
430+ if (autoupdate_) call self% update_previous(U= U, previous= previous)
431+ else
432+ buffer = U
433+ call buffer% t_fast(t= t(1 ))
434+ call buffer% multiply_fast(lhs= buffer, rhs= Dt * self% b(0 ))
435+ call U% add_fast(lhs= U, rhs= buffer)
436+ endif
437+ end subroutine integrate_fast
438+
375439 subroutine update_previous (self , U , previous )
376440 ! < Cyclic update previous time steps.
377441 class(integrator_adams_moulton), intent (in ) :: self ! < Integrator.
0 commit comments