Skip to content

Commit 60ac876

Browse files
committed
Add SSP Linear Multistep Methods with Variable Step Size
Add Strong Stability Preserving Linear Multistep Methods with Variable Step Size. Stable release, fully barckward compatible.
1 parent 518acbe commit 60ac876

File tree

6 files changed

+407
-76
lines changed

6 files changed

+407
-76
lines changed

papers/announcement/errors_analysis/errors_analysis.sh

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ euler=0
1111
lf=0
1212
lf_raw=0
1313
lmm_ssp=0
14+
lmm_ssp_vss=0
1415
ls_rk=0
1516
tvd_rk=0
1617

@@ -20,18 +21,19 @@ function print_usage {
2021
echo "script automotion for FOODIE's errors analysis"
2122
echo "Usage: `basename $0` #solver"
2223
echo "Valid solver switches are:"
23-
echo " -ab # => adams-bashforth"
24-
echo " -abm # => adams-bashforth-moulton"
25-
echo " -am # => adams-moulton"
26-
echo " -bdf # => backward differentiation formula"
27-
echo " -emd-rk # => embeded RK"
28-
echo " -euler # => euler"
29-
echo " -lf # => leapfrog"
30-
echo " -lf-raw # => leapfrog raw filtered"
31-
echo " -lmm-ssp # => linear multistep methods SSP"
32-
echo " -ls-rk # => low storage RK"
33-
echo " -tvd-rk # => TVD RK"
34-
echo " -all # => all solvers!"
24+
echo " -ab # => adams-bashforth"
25+
echo " -abm # => adams-bashforth-moulton"
26+
echo " -am # => adams-moulton"
27+
echo " -bdf # => backward differentiation formula"
28+
echo " -emd-rk # => embeded RK"
29+
echo " -euler # => euler"
30+
echo " -lf # => leapfrog"
31+
echo " -lf-raw # => leapfrog raw filtered"
32+
echo " -lmm-ssp # => linear multistep methods SSP"
33+
echo " -lmm-ssp-vss # => linear multistep methods SSP with Variable Step Size"
34+
echo " -ls-rk # => low storage RK"
35+
echo " -tvd-rk # => TVD RK"
36+
echo " -all # => all solvers!"
3537
}
3638

3739
#parsing command line
@@ -64,6 +66,9 @@ while [ $# -gt 0 ]; do
6466
"-lmm-ssp")
6567
lmm_ssp=1
6668
;;
69+
"-lmm-ssp-vss")
70+
lmm_ssp_vss=1
71+
;;
6772
"-ls-rk")
6873
ls_rk=1
6974
;;
@@ -149,6 +154,10 @@ fi
149154
if [ $lmm_ssp -eq 1 ] ; then
150155
../tests/oscillation -r -tf 1e6 --solver lmm-ssp --ss 3 5 -Dt 5000.d0 2500.d0 1250.d0 625.d0 320.d0 100.d0 50.d0 10.d0 --errors_analysis > analysis-lmm-ssp.log
151156
fi
157+
if [ $lmm_ssp_vss -eq 1 ] ; then
158+
../tests/oscillation -r -tf 1e6 --solver lmm-ssp-vss --ss 3 5 --order 2 -Dt 5000.d0 2500.d0 1250.d0 625.d0 320.d0 100.d0 --errors_analysis > analysis-lmm-ssp-vss.log
159+
../tests/oscillation -r -tf 1e6 --solver lmm-ssp-vss --ss 3 5 --order 3 -Dt 5000.d0 2500.d0 1250.d0 625.d0 320.d0 100.d0 --errors_analysis > analysis-lmm-ssp-vss.log
160+
fi
152161
if [ $ls_rk -eq 1 ] ; then
153162
../tests/oscillation -r -tf 1e6 --solver ls-runge-kutta --ss 1 -Dt 5000.d0 2500.d0 1250.d0 625.d0 320.d0 100.d0 --errors_analysis #> analysis-leapfrog.log
154163
../tests/oscillation -r -tf 1e6 --solver ls-runge-kutta --ss 5 7 -Dt 5000.d0 2500.d0 1250.d0 625.d0 320.d0 100.d0 --errors_analysis #> analysis-leapfrog.log

src/lib/foodie.f90

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ module foodie
7272
use foodie_integrator_euler_explicit, only : integrator_euler_explicit
7373
use foodie_integrator_leapfrog, only : integrator_leapfrog
7474
use foodie_integrator_lmm_ssp, only : integrator_lmm_ssp
75+
use foodie_integrator_lmm_ssp_vss, only : integrator_lmm_ssp_vss
7576
use foodie_integrator_runge_kutta_emd, only : integrator_runge_kutta_emd
7677
use foodie_integrator_runge_kutta_low_storage, only : integrator_runge_kutta_ls
7778
use foodie_integrator_runge_kutta_tvd, only : integrator_runge_kutta_tvd
@@ -87,13 +88,14 @@ module foodie
8788
public :: integrator_euler_explicit
8889
public :: integrator_leapfrog
8990
public :: integrator_lmm_ssp
91+
public :: integrator_lmm_ssp_vss
9092
public :: integrator_runge_kutta_emd
9193
public :: integrator_runge_kutta_ls
9294
public :: foodie_integrator
9395
public :: integrator_runge_kutta_tvd
9496

9597
contains
96-
function foodie_integrator(scheme, steps, stages, tolerance, nu, alpha) result(integrator)
98+
function foodie_integrator(scheme, steps, stages, order, tolerance, nu, alpha) result(integrator)
9799
!< Return a concrete instance of [[integrator]] given a scheme selection.
98100
!<
99101
!< This is the FOODIE integrators factory.
@@ -102,6 +104,7 @@ function foodie_integrator(scheme, steps, stages, tolerance, nu, alpha) result(i
102104
character(*), intent(in) :: scheme !< Selected integrator given.
103105
integer(I_P), intent(in), optional :: steps !< Number of time steps used in multi-step schemes.
104106
integer(I_P), intent(in), optional :: stages !< Number of Runge-Kutta stages used in multi-stage schemes.
107+
integer(I_P), intent(in), optional :: order !< Order of accuracy.
105108
real(R_P), intent(in), optional :: tolerance !< Tolerance on the local truncation error.
106109
real(R_P), intent(in), optional :: nu !< Williams-Robert-Asselin filter coefficient.
107110
real(R_P), intent(in), optional :: alpha !< Robert-Asselin filter coefficient.
@@ -176,6 +179,18 @@ function foodie_integrator(scheme, steps, stages, tolerance, nu, alpha) result(i
176179
error_message='missing steps number for initializing integrator!', &
177180
is_severe=.true.)
178181
endif
182+
case('lmm_ssp_vss')
183+
allocate(integrator_lmm_ssp_vss :: integrator)
184+
if ((.not.present(steps)).or.(.not.present(order))) then
185+
call integrator%trigger_error(error=ERROR_MISSING_STEPS_NUMBER, &
186+
error_message='missing steps number for initializing integrator!', &
187+
is_severe=.true.)
188+
else
189+
select type(integrator)
190+
type is(integrator_lmm_ssp_vss)
191+
call integrator%init(steps=steps, order=order)
192+
endselect
193+
endif
179194
case('runge_kutta_emd')
180195
allocate(integrator_runge_kutta_emd :: integrator)
181196
if (present(stages)) then

src/lib/foodie_error_codes.f90

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ module foodie_error_codes
1111
public :: ERROR_BAD_STEPS_NUMBER
1212
public :: ERROR_MISSING_STAGES_NUMBER
1313
public :: ERROR_BAD_STAGES_NUMBER
14+
public :: ERROR_INTEGRATOR_INIT_FAIL
1415

1516
integer(I_P), parameter :: ERROR_MISSING_STEPS_NUMBER = 1 !< Error missing steps number (for FOODIE factory).
1617
integer(I_P), parameter :: ERROR_BAD_STEPS_NUMBER = 2 !< Error bad (unsupported) steps number.
1718
integer(I_P), parameter :: ERROR_MISSING_STAGES_NUMBER = 3 !< Error missing stages number (for FOODIE factory).
1819
integer(I_P), parameter :: ERROR_BAD_STAGES_NUMBER = 4 !< Error bad (unsupported) stages number.
20+
integer(I_P), parameter :: ERROR_INTEGRATOR_INIT_FAIL = 5 !< Error integrator initialization failed.
1921
endmodule foodie_error_codes

src/lib/foodie_integrator_lmm_ssp.f90

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -115,39 +115,39 @@ subroutine init(self, steps)
115115
if (self%is_supported(steps)) then
116116
call self%destroy
117117
self%steps = steps
118-
allocate(self%a(1:steps)) ; self%a = 0.0_R_P
119-
allocate(self%b(1:steps)) ; self%b = 0.0_R_P
118+
allocate(self%a(1:steps)) ; self%a = 0._R_P
119+
allocate(self%b(1:steps)) ; self%b = 0._R_P
120120
select case(steps)
121121
case(3) ! LMM-SSP(3,2)
122-
self%a(1) = 1.0_R_P/4.0_R_P
123-
self%a(2) = 0.0_R_P
124-
self%a(3) = 3.0_R_P/4.0_R_P
122+
self%a(1) = 1._R_P/4._R_P
123+
self%a(2) = 0._R_P
124+
self%a(3) = 3._R_P/4._R_P
125125

126-
self%b(1) = 0.0_R_P
127-
self%b(2) = 0.0_R_P
128-
self%b(3) = 3.0_R_P/2.0_R_P
126+
self%b(1) = 0._R_P
127+
self%b(2) = 0._R_P
128+
self%b(3) = 3._R_P/2._R_P
129129
case(4) ! LMM-SSP(4,3)
130-
self%a(1) = 11.0_R_P/27.0_R_P
131-
self%a(2) = 0.0_R_P
132-
self%a(3) = 0.0_R_P
133-
self%a(4) = 16.0_R_P/27.0_R_P
134-
135-
self%b(1) = 12.0_R_P/27.0_R_P
136-
self%b(2) = 0.0_R_P
137-
self%b(3) = 0.0_R_P
138-
self%b(4) = 16.0_R_P/9.0_R_P
130+
self%a(1) = 11._R_P/27._R_P
131+
self%a(2) = 0._R_P
132+
self%a(3) = 0._R_P
133+
self%a(4) = 16._R_P/27._R_P
134+
135+
self%b(1) = 12._R_P/27._R_P
136+
self%b(2) = 0._R_P
137+
self%b(3) = 0._R_P
138+
self%b(4) = 16._R_P/9._R_P
139139
case(5) ! LMM-SSP(5,3)
140-
self%a(1) = 7.0_R_P/32.0_R_P
141-
self%a(2) = 0.0_R_P
142-
self%a(3) = 0.0_R_P
143-
self%a(4) = 0.0_R_P
144-
self%a(5) = 25.0_R_P/32.0_R_P
145-
146-
self%b(1) = 5.0_R_P/16.0_R_P
147-
self%b(2) = 0.0_R_P
148-
self%b(3) = 0.0_R_P
149-
self%b(4) = 0.0_R_P
150-
self%b(5) = 25.0_R_P/16.0_R_P
140+
self%a(1) = 7._R_P/32._R_P
141+
self%a(2) = 0._R_P
142+
self%a(3) = 0._R_P
143+
self%a(4) = 0._R_P
144+
self%a(5) = 25._R_P/32._R_P
145+
146+
self%b(1) = 5._R_P/16._R_P
147+
self%b(2) = 0._R_P
148+
self%b(3) = 0._R_P
149+
self%b(4) = 0._R_P
150+
self%b(5) = 25._R_P/16._R_P
151151
endselect
152152
else
153153
call self%trigger_error(error=ERROR_BAD_STEPS_NUMBER, &
@@ -170,7 +170,9 @@ subroutine integrate(self, U, previous, Dt, t, autoupdate)
170170
autoupdate_ = .true. ; if (present(autoupdate)) autoupdate_ = autoupdate
171171
U = U * 0._R_P
172172
do s=1, self%steps
173-
U = U + previous(s) * self%a(s) + previous(s)%t(t=t(s)) * (Dt * self%b(s))
173+
if (self%a(s) /= 0._R_P) U = U + previous(s) * self%a(s)
174+
if (self%b(s) /= 0._R_P) U = U + previous(s)%t(t=t(s)) * (Dt * self%b(s))
175+
! U = U + previous(s) * self%a(s) + previous(s)%t(t=t(s)) * (Dt * self%b(s))
174176
enddo
175177
if (autoupdate_) call self%update_previous(U=U, previous=previous)
176178
endsubroutine integrate

0 commit comments

Comments
 (0)