Skip to content

Commit

Permalink
Refactor (again) oscillation test
Browse files Browse the repository at this point in the history
Refactor (again) oscillation test

Why:

Sanitize and simplify.

Side effects:

Emd RK does not use adaptive time step: it uses the same fixed time
step of others in order to simplify comparison.
  • Loading branch information
szaghi committed May 10, 2017
1 parent f36a3d6 commit feb2ae4
Show file tree
Hide file tree
Showing 21 changed files with 1,268 additions and 1,972 deletions.
98 changes: 49 additions & 49 deletions src/lib/foodie.f90
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ module foodie

implicit none
private
public :: foodie_integrator
public :: foodie_integrator_class_names
public :: foodie_integrator_factory
public :: foodie_integrator_schemes
public :: integrand_object
public :: integrator_object
Expand All @@ -105,32 +105,64 @@ module foodie
public :: is_scheme_available

contains
function foodie_integrator(scheme, stages, tolerance, nu, alpha) result(integrator)
!< Return a concrete instance of [[integrator_object]] given a scheme selection.
!<
!< This is the FOODIE integrators factory.
!<
!< @note If an error occurs the error status of [[integrator_object]] is updated.
character(*), intent(in) :: scheme !< Selected integrator given.
integer(I_P), intent(in), optional :: stages !< Stages of multi-stage methods.
real(R_P), intent(in), optional :: tolerance !< Tolerance on the local truncation error.
real(R_P), intent(in), optional :: nu !< Williams-Robert-Asselin filter coefficient.
real(R_P), intent(in), optional :: alpha !< Robert-Asselin filter coefficient.
class(integrator_object), allocatable :: integrator !< The FOODIE integrator.
pure function foodie_integrator_class_names() result(names)
!< Return the list of available intergrator class of schemes names.
character(len=99), allocatable :: names(:) !< Available integrator class names.
type(integrator_adams_bashforth) :: int_adams_bashforth !< Integrator Adams Bashforth.
type(integrator_adams_bashforth_moulton) :: int_adams_bashforth_moulton !< Integrator Adams Bashforth Moulton.
type(integrator_adams_moulton) :: int_adams_moulton !< Integrator Adams Moulton.
type(integrator_back_df) :: int_back_df !< Integrator back differentiation formula.
type(integrator_euler_explicit) :: int_euler_explicit !< Integrator euler explicit.
type(integrator_leapfrog) :: int_leapfrog !< Integrator leapfrog.
type(integrator_lmm_ssp) :: int_lmm_ssp !< Integrator LMM SSP.
type(integrator_lmm_ssp_vss) :: int_lmm_ssp_vss !< Integrator LMM SSP VSS.
type(integrator_lmm_ssp) :: int_lmm_ssp !< Integrator lmm SSP.
type(integrator_lmm_ssp_vss) :: int_lmm_ssp_vss !< Integrator lmm SSP VSS.
type(integrator_ms_runge_kutta_ssp) :: int_ms_runge_kutta_ssp !< Integrator multistep Runge Kutta ssp.
type(integrator_runge_kutta_emd) :: int_runge_kutta_emd !< Integrator Runge Kutta_embdedded.
type(integrator_runge_kutta_emd) :: int_runge_kutta_emd !< Integrator Runge Kutta embdedded.
type(integrator_runge_kutta_ls) :: int_runge_kutta_ls !< Integrator Runge Kutta low storage.
type(integrator_runge_kutta_lssp) :: int_runge_kutta_lssp !< Integrator linear Runge Kutta SSP.
type(integrator_runge_kutta_ssp) :: int_runge_kutta_ssp !< Integrator Runge Kutta SSP.

names = [ int_adams_bashforth % class_name()]
names = [names, int_adams_bashforth_moulton % class_name()]
names = [names, int_adams_moulton % class_name()]
names = [names, int_back_df % class_name()]
names = [names, int_euler_explicit % class_name()]
names = [names, int_leapfrog % class_name()]
names = [names, int_lmm_ssp % class_name()]
names = [names, int_lmm_ssp_vss % class_name()]
names = [names, int_ms_runge_kutta_ssp % class_name()]
names = [names, int_runge_kutta_emd % class_name()]
names = [names, int_runge_kutta_ls % class_name()]
names = [names, int_runge_kutta_lssp % class_name()]
names = [names, int_runge_kutta_ssp % class_name()]
endfunction foodie_integrator_class_names

subroutine foodie_integrator_factory(scheme, integrator, stages, tolerance, nu, alpha)
!< Return a concrete instance of [[integrator_object]] given a scheme selection.
!<
!< This is the FOODIE integrators factory.
!<
!< @note If an error occurs the error status of [[integrator_object]] is updated.
character(*), intent(in) :: scheme !< Selected integrator given.
class(integrator_object), allocatable, intent(out) :: integrator !< The FOODIE integrator.
integer(I_P), optional, intent(in) :: stages !< Stages of multi-stage methods.
real(R_P), optional, intent(in) :: tolerance !< Tolerance on the local truncation error.
real(R_P), optional, intent(in) :: nu !< Williams-Robert-Asselin filter coefficient.
real(R_P), optional, intent(in) :: alpha !< Robert-Asselin filter coefficient.
type(integrator_adams_bashforth) :: int_adams_bashforth !< Integrator Adams Bashforth.
type(integrator_adams_bashforth_moulton) :: int_adams_bashforth_moulton !< Integrator Adams Bashforth Moulton.
type(integrator_adams_moulton) :: int_adams_moulton !< Integrator Adams Moulton.
type(integrator_back_df) :: int_back_df !< Integrator back differentiation formula.
type(integrator_euler_explicit) :: int_euler_explicit !< Integrator euler explicit.
type(integrator_leapfrog) :: int_leapfrog !< Integrator leapfrog.
type(integrator_lmm_ssp) :: int_lmm_ssp !< Integrator LMM SSP.
type(integrator_lmm_ssp_vss) :: int_lmm_ssp_vss !< Integrator LMM SSP VSS.
type(integrator_ms_runge_kutta_ssp) :: int_ms_runge_kutta_ssp !< Integrator multistep Runge Kutta ssp.
type(integrator_runge_kutta_emd) :: int_runge_kutta_emd !< Integrator Runge Kutta_embdedded.
type(integrator_runge_kutta_ls) :: int_runge_kutta_ls !< Integrator Runge Kutta low storage.
type(integrator_runge_kutta_lssp) :: int_runge_kutta_lssp !< Integrator linear Runge Kutta SSP.
type(integrator_runge_kutta_ssp) :: int_runge_kutta_ssp !< Integrator Runge Kutta SSP.

if (index(trim(adjustl(scheme)), trim(int_adams_bashforth_moulton%class_name())) > 0) then
allocate(integrator_adams_bashforth_moulton :: integrator)
select type(integrator)
Expand Down Expand Up @@ -209,39 +241,7 @@ function foodie_integrator(scheme, stages, tolerance, nu, alpha) result(integrat
write(stderr, '(A)')'error: "'//trim(adjustl(scheme))//'" scheme is unknown!'
stop
endif
endfunction foodie_integrator

pure function foodie_integrator_class_names() result(names)
!< Return the list of available intergrator class of schemes names.
character(len=99), allocatable :: names(:) !< Available integrator class names.
type(integrator_adams_bashforth) :: int_adams_bashforth !< Integrator Adams Bashforth.
type(integrator_adams_bashforth_moulton) :: int_adams_bashforth_moulton !< Integrator Adams Bashforth Moulton.
type(integrator_adams_moulton) :: int_adams_moulton !< Integrator Adams Moulton.
type(integrator_back_df) :: int_back_df !< Integrator back differentiation formula.
type(integrator_euler_explicit) :: int_euler_explicit !< Integrator euler explicit.
type(integrator_leapfrog) :: int_leapfrog !< Integrator leapfrog.
type(integrator_lmm_ssp) :: int_lmm_ssp !< Integrator lmm SSP.
type(integrator_lmm_ssp_vss) :: int_lmm_ssp_vss !< Integrator lmm SSP VSS.
type(integrator_ms_runge_kutta_ssp) :: int_ms_runge_kutta_ssp !< Integrator multistep Runge Kutta ssp.
type(integrator_runge_kutta_emd) :: int_runge_kutta_emd !< Integrator Runge Kutta embdedded.
type(integrator_runge_kutta_ls) :: int_runge_kutta_ls !< Integrator Runge Kutta low storage.
type(integrator_runge_kutta_lssp) :: int_runge_kutta_lssp !< Integrator linear Runge Kutta SSP.
type(integrator_runge_kutta_ssp) :: int_runge_kutta_ssp !< Integrator Runge Kutta SSP.

names = [ int_adams_bashforth % class_name()]
names = [names, int_adams_bashforth_moulton % class_name()]
names = [names, int_adams_moulton % class_name()]
names = [names, int_back_df % class_name()]
names = [names, int_euler_explicit % class_name()]
names = [names, int_leapfrog % class_name()]
names = [names, int_lmm_ssp % class_name()]
names = [names, int_lmm_ssp_vss % class_name()]
names = [names, int_ms_runge_kutta_ssp % class_name()]
names = [names, int_runge_kutta_emd % class_name()]
names = [names, int_runge_kutta_ls % class_name()]
names = [names, int_runge_kutta_lssp % class_name()]
names = [names, int_runge_kutta_ssp % class_name()]
endfunction foodie_integrator_class_names
endsubroutine foodie_integrator_factory

pure function foodie_integrator_schemes(class_name) result(schemes)
!< Return the list of all available intergrator schemes, or only the schemes belonging to the given class name.
Expand Down
42 changes: 40 additions & 2 deletions src/lib/foodie_integrator_adams_bashforth.f90
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,28 @@ module foodie_integrator_adams_bashforth
trim(class_name_)//'_15', &
trim(class_name_)//'_16'] !< List of supported schemes.

logical, parameter :: has_fast_mode_=.true. !< Flag to check if integrator provides *fast mode* integrate.
logical, parameter :: has_fast_mode_=.true. !< Flag to check if integrator provides *fast mode* integrate.
logical, parameter :: is_multistage_=.false. !< Flag to check if integrator is multistage.
logical, parameter :: is_multistep_=.true. !< Flag to check if integrator is multistep.

type, extends(integrator_object) :: integrator_adams_bashforth
!< FOODIE integrator: provide an explicit class of Adams-Bashforth multi-step schemes, from 1st to 16th order accurate.
!<
!< @note The integrator must be created or initialized (initialize the *b* coefficients) before used.
private
integer(I_P), public :: steps=0 !< Number of time steps.
integer(I_P) :: steps=0 !< Number of time steps.
real(R_P), allocatable :: b(:) !< *b* coefficients.
contains
! deferred methods
procedure, pass(self) :: class_name !< Return the class name of schemes.
procedure, pass(self) :: description !< Return pretty-printed object description.
procedure, pass(self) :: has_fast_mode !< Return .true. if the integrator class has *fast mode* integrate.
procedure, pass(lhs) :: integr_assign_integr !< Operator `=`.
procedure, pass(self) :: is_multistage !< Return .true. for multistage integrator.
procedure, pass(self) :: is_multistep !< Return .true. for multistep integrator.
procedure, pass(self) :: is_supported !< Return .true. if the integrator class support the given scheme.
procedure, pass(self) :: stages_number !< Return number of stages used.
procedure, pass(self) :: steps_number !< Return number of steps used.
procedure, pass(self) :: supported_schemes !< Return the list of supported schemes.
! public methods
procedure, pass(self) :: destroy !< Destroy the integrator.
Expand Down Expand Up @@ -128,6 +134,22 @@ pure subroutine integr_assign_integr(lhs, rhs)
endselect
endsubroutine integr_assign_integr

elemental function is_multistage(self)
!< Return .true. for multistage integrator.
class(integrator_adams_bashforth), intent(in) :: self !< Integrator.
logical :: is_multistage !< Inquire result.

is_multistage = is_multistage_
endfunction is_multistage

elemental function is_multistep(self)
!< Return .true. for multistage integrator.
class(integrator_adams_bashforth), intent(in) :: self !< Integrator.
logical :: is_multistep !< Inquire result.

is_multistep = is_multistep_
endfunction is_multistep

elemental function is_supported(self, scheme)
!< Return .true. if the integrator class support the given scheme.
class(integrator_adams_bashforth), intent(in) :: self !< Integrator.
Expand All @@ -144,6 +166,22 @@ elemental function is_supported(self, scheme)
enddo
endfunction is_supported

elemental function stages_number(self)
!< Return number of stages used.
class(integrator_adams_bashforth), intent(in) :: self !< Integrator.
integer(I_P) :: stages_number !< Number of stages used.

stages_number = 0
endfunction stages_number

elemental function steps_number(self)
!< Return number of steps used.
class(integrator_adams_bashforth), intent(in) :: self !< Integrator.
integer(I_P) :: steps_number !< Number of steps used.

steps_number = self%steps
endfunction steps_number

pure function supported_schemes(self) result(schemes)
!< Return the list of supported schemes.
class(integrator_adams_bashforth), intent(in) :: self !< Integrator.
Expand Down
44 changes: 41 additions & 3 deletions src/lib/foodie_integrator_adams_bashforth_moulton.f90
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,16 @@ module foodie_integrator_adams_bashforth_moulton
trim(class_name_)//'_15', &
trim(class_name_)//'_16'] !< List of supported schemes.

logical, parameter :: has_fast_mode_=.true. !< Flag to check if integrator provides *fast mode* integrate.
logical, parameter :: has_fast_mode_=.true. !< Flag to check if integrator provides *fast mode* integrate.
logical, parameter :: is_multistage_=.false. !< Flag to check if integrator is multistage.
logical, parameter :: is_multistep_=.true. !< Flag to check if integrator is multistep.

type, extends(integrator_object) :: integrator_adams_bashforth_moulton
!< FOODIE integrator: provide an explicit class of Adams-Bashforth-Moulton multi-step schemes, from 1st to 4rd order accurate.
!<
!< @note The integrator must be created or initialized (predictor and corrector schemes selection) before used.
private
integer(I_P), public :: steps=0 !< Number of time steps.
integer(I_P) :: steps=0 !< Number of time steps.
type(integrator_adams_bashforth) :: predictor !< Predictor solver.
type(integrator_adams_moulton) :: corrector !< Corrector solver.
contains
Expand All @@ -121,7 +123,11 @@ module foodie_integrator_adams_bashforth_moulton
procedure, pass(self) :: description !< Return pretty-printed object description.
procedure, pass(self) :: has_fast_mode !< Return .true. if the integrator class has *fast mode* integrate.
procedure, pass(lhs) :: integr_assign_integr !< Operator `=`.
procedure, pass(self) :: is_multistage !< Return .true. for multistage integrator.
procedure, pass(self) :: is_multistep !< Return .true. for multistep integrator.
procedure, pass(self) :: is_supported !< Return .true. if the integrator class support the given scheme.
procedure, pass(self) :: stages_number !< Return number of stages used.
procedure, pass(self) :: steps_number !< Return number of steps used.
procedure, pass(self) :: supported_schemes !< Return the list of supported schemes.
! public methods
procedure, pass(self) :: destroy !< Destroy the integrator.
Expand Down Expand Up @@ -182,6 +188,22 @@ pure subroutine integr_assign_integr(lhs, rhs)
endselect
endsubroutine integr_assign_integr

elemental function is_multistage(self)
!< Return .true. for multistage integrator.
class(integrator_adams_bashforth_moulton), intent(in) :: self !< Integrator.
logical :: is_multistage !< Inquire result.

is_multistage = is_multistage_
endfunction is_multistage

elemental function is_multistep(self)
!< Return .true. for multistage integrator.
class(integrator_adams_bashforth_moulton), intent(in) :: self !< Integrator.
logical :: is_multistep !< Inquire result.

is_multistep = is_multistep_
endfunction is_multistep

elemental function is_supported(self, scheme)
!< Return .true. if the integrator class support the given scheme.
class(integrator_adams_bashforth_moulton), intent(in) :: self !< Integrator.
Expand All @@ -198,6 +220,22 @@ elemental function is_supported(self, scheme)
enddo
endfunction is_supported

elemental function stages_number(self)
!< Return number of stages used.
class(integrator_adams_bashforth_moulton), intent(in) :: self !< Integrator.
integer(I_P) :: stages_number !< Number of stages used.

stages_number = 0
endfunction stages_number

elemental function steps_number(self)
!< Return number of steps used.
class(integrator_adams_bashforth_moulton), intent(in) :: self !< Integrator.
integer(I_P) :: steps_number !< Number of steps used.

steps_number = self%steps
endfunction steps_number

pure function supported_schemes(self) result(schemes)
!< Return the list of supported schemes.
class(integrator_adams_bashforth_moulton), intent(in) :: self !< Integrator.
Expand Down Expand Up @@ -233,7 +271,7 @@ subroutine initialize(self, scheme)
schemes_am = self%corrector%supported_schemes()
call self%predictor%initialize(scheme=schemes_ab(scheme_number_))
call self%corrector%initialize(scheme=schemes_am(scheme_number_))
self%steps = self%predictor%steps
self%steps = self%predictor%steps_number()
else
call self%trigger_error(error=ERROR_UNSUPPORTED_SCHEME, &
error_message='"'//trim(adjustl(scheme))//'" unsupported scheme', &
Expand Down
Loading

0 comments on commit feb2ae4

Please sign in to comment.