Initialize test: set Command Line Interface, parse it and check its validity.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(test_object), | intent(inout) | :: | self | Test. |
subroutine initialize(self)
!< Initialize test: set Command Line Interface, parse it and check its validity.
class(test_object), intent(inout) :: self !< Test.
call set_cli
call parse_cli
contains
subroutine set_cli()
!< Set Command Line Interface.
associate(cli => self%cli)
call cli%init(progname = 'foodie_tester', &
authors = 'Fortran-FOSS-Programmers', &
license = 'GNU GPLv3', &
description = 'Tester factory of FOODIE integrators', &
examples = ["foodie_tester test --scheme euler_explicit --save_results ", &
"foodie_tester test --scheme all -r "])
call cli%add_group(description='general test settings', group='test')
call cli%add(group='test', switch='--scheme', switch_ab='-s', help='integrator scheme used', required=.false., def='all', &
act='store')
call cli%add(group='test', switch='--time_step', switch_ab='-Dt', nargs='+', help='time step', required=.false., &
def='1e2', act='store')
call cli%add(group='test', switch='--fast', help='activate fast solvers', required=.false., act='store_true', &
def='.false.')
call cli%add(group='test', switch='--iterations', help='iterations number for implicit schemes', required=.false., &
act='store', def='5')
call cli%add(group='test', switch='--stages', help='stages number', required=.false., def='2', act='store')
call cli%add(group='test', switch='--final_time', switch_ab='-ft', help='integration time', required=.false., def='1', &
act='store')
call cli%add(group='test', switch='--save_results', switch_ab='-r',help='save result', required=.false., &
act='store_true', def='.false.')
call cli%add(group='test', switch='--output', help='output file basename', required=.false., act='store', &
def='foodie_test')
call cli%add(group='test', switch='--save_frequency', help='save frequency', required=.false., act='store', &
def='1')
endassociate
call self%lcce_0%set_cli(cli=self%cli)
call self%ladvection_0%set_cli(cli=self%cli)
call self%oscillation_0%set_cli(cli=self%cli)
endsubroutine set_cli
subroutine parse_cli()
!< Parse Command Line Interface and check its validity.
character(99), allocatable :: integrator_class_names(:) !< Name of FOODIE integrator classes.
character(99), allocatable :: integrator_schemes(:) !< Name of FOODIE integrator schemes.
real(R_P), allocatable :: initial_state(:) !< Initial integrand state.
integer(I_P) :: i !< Counter.
call self%cli%parse(error=self%error)
call self%cli%get(group='test', switch='-s', val=self%scheme, error=self%error) ; if (self%error/=0) stop
call self%cli%get_varying(group='test', switch='-Dt', val=self%Dt, error=self%error) ; if (self%error/=0) stop
call self%cli%get(group='test', switch='--fast', val=self%is_fast, error=self%error) ; if (self%error/=0) stop
call self%cli%get(group='test', switch='--iterations',val=self%implicit_iterations,error=self%error) ; if (self%error/=0) stop
call self%cli%get(group='test', switch='--stages', val=self%stages, error=self%error) ; if (self%error/=0) stop
call self%cli%get(group='test', switch='-ft', val=self%final_time, error=self%error) ; if (self%error/=0) stop
call self%cli%get(group='test', switch='-r', val=self%save_results, error=self%error) ; if (self%error/=0) stop
call self%cli%get(group='test', switch='--output', val=self%output, error=self%error) ; if (self%error/=0) stop
call self%cli%get(group='test', switch='--save_frequency',val=self%save_frequency,error=self%error) ; if (self%error/=0) stop
call self%lcce_0%parse_cli(cli=self%cli)
call self%ladvection_0%parse_cli(cli=self%cli)
call self%oscillation_0%parse_cli(cli=self%cli)
if (self%cli%run_command('lcce')) then
allocate(integrand_lcce :: self%integrand_0)
select type(integrand_0=>self%integrand_0)
type is(integrand_lcce)
integrand_0 = self%lcce_0
endselect
elseif (self%cli%run_command('linear_advection')) then
allocate(integrand_ladvection :: self%integrand_0)
select type(integrand_0=>self%integrand_0)
type is(integrand_ladvection)
integrand_0 = self%ladvection_0
endselect
elseif (self%cli%run_command('oscillation')) then
allocate(integrand_oscillation :: self%integrand_0)
select type(integrand_0=>self%integrand_0)
type is(integrand_oscillation)
integrand_0 = self%oscillation_0
endselect
else
allocate(integrand_oscillation :: self%integrand_0)
select type(integrand_0=>self%integrand_0)
type is(integrand_oscillation)
integrand_0 = self%oscillation_0
endselect
endif
if (.not.is_dt_valid()) then
write(stderr, '(A)') 'error: the final integration time must be an exact multiple of the time step used'
write(stderr, '(A)') ' and time step must respect CFL condition, if any'
write(stderr, '(A)') 'Final integration time: '//str(self%final_time, .true.)
write(stderr, '(A)') 'Time step: '//str(self%Dt, .true.)
stop
endif
if (trim(adjustl(self%scheme)) /= 'all') then
if (.not.is_available(scheme=self%scheme)) then
integrator_class_names = foodie_integrator_class_names()
integrator_schemes = foodie_integrator_schemes()
write(stderr, '(A)') 'error: the scheme "'//trim(adjustl(self%scheme))//'" is unknown!'
write(stderr, '(A)') 'Supported classes of schemes are:'
do i=1, size(integrator_class_names, dim=1)
write(stderr, '(A)') ' '//trim(integrator_class_names(i))
enddo
write(stderr, '(A)') 'Supported schemes are:'
do i=1, size(integrator_schemes, dim=1)
write(stderr, '(A)') ' '//trim(integrator_schemes(i))
enddo
stop
endif
endif
endsubroutine parse_cli
function is_dt_valid()
!< Verify if the selected time step Dt is valid.
logical :: is_dt_valid !< Return true is the selected time step Dt is valid.
integer(I_P) :: t !< Counter.
is_dt_valid = .true.
do t=1, size(self%Dt)
is_dt_valid = ((self%final_time - int(self%final_time/self%Dt(t), I_P)*self%Dt(t))==0)
! if (is_dt_valid) then
! select type(integrand=>self%integrand_0)
! type is(integrand_ladvection)
! is_dt_valid = is_dt_valid .and. self%Dt(t) <= integrand%Dt(final_time=self%final_time)
! if (.not.is_dt_valid) then
! write(stderr, '(A)') 'error: Dt violates CFL condition, Dt_max = '//str(integrand%Dt(final_time=self%final_time))
! endif
! endselect
! endif
if (.not.is_dt_valid) exit
enddo
endfunction is_dt_valid
endsubroutine initialize