From 1812d6e2cbb0e3060ec2db3af834ff21335dd9dd Mon Sep 17 00:00:00 2001 From: Stefano Zaghi Date: Fri, 26 May 2017 17:32:16 +0200 Subject: [PATCH] dehydrate tester --- src/lib/foodie_integrator_adams_bashforth.f90 | 21 +-- ...die_integrator_adams_bashforth_moulton.f90 | 21 +-- src/lib/foodie_integrator_adams_moulton.f90 | 23 +-- ...rator_backward_differentiation_formula.f90 | 23 +-- src/lib/foodie_integrator_euler_explicit.f90 | 49 +++--- src/lib/foodie_integrator_leapfrog.f90 | 41 ++--- src/lib/foodie_integrator_lmm_ssp.f90 | 147 ++++++++---------- src/lib/foodie_integrator_lmm_ssp_vss.f90 | 79 ++++------ .../foodie_integrator_ms_runge_kutta_ssp.f90 | 21 +-- src/lib/foodie_integrator_object.f90 | 20 ++- ...foodie_integrator_runge_kutta_embedded.f90 | 29 +--- ...die_integrator_runge_kutta_low_storage.f90 | 21 +-- .../foodie_integrator_runge_kutta_lssp.f90 | 23 +-- src/lib/foodie_integrator_runge_kutta_ssp.f90 | 21 +-- .../foodie_test_integrand_ladvection.f90 | 14 +- .../foodie_test_integrand_oscillation.f90 | 12 ++ .../foodie_test_integrand_tester_object.f90 | 17 +- src/tests/tester/foodie_tester.f90 | 42 ++--- 18 files changed, 213 insertions(+), 411 deletions(-) diff --git a/src/lib/foodie_integrator_adams_bashforth.f90 b/src/lib/foodie_integrator_adams_bashforth.f90 index 15e25b3c..eee8348d 100644 --- a/src/lib/foodie_integrator_adams_bashforth.f90 +++ b/src/lib/foodie_integrator_adams_bashforth.f90 @@ -68,7 +68,6 @@ module foodie_integrator_adams_bashforth 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) :: integrate !< Integrate integrand field. @@ -90,25 +89,6 @@ pure function class_name(self) class_name = trim(adjustl(class_name_)) endfunction class_name - pure function description(self, prefix) result(desc) - !< Return a pretty-formatted object description. - class(integrator_adams_bashforth), intent(in) :: self !< Integrator. - character(*), intent(in), optional :: prefix !< Prefixing string. - character(len=:), allocatable :: desc !< Description. - character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. - character(len=1), parameter :: NL=new_line('a') !< New line character. - integer(I_P) :: s !< Counter. - - prefix_ = '' ; if (present(prefix)) prefix_ = prefix - desc = '' - desc = desc//prefix_//'Adams-Bashforth multi-step schemes class'//NL - desc = desc//prefix_//' Supported schemes:'//NL - do s=lbound(supported_schemes_, dim=1), ubound(supported_schemes_, dim=1) - 1 - desc = desc//prefix_//' + '//supported_schemes_(s)//NL - enddo - desc = desc//prefix_//' + '//supported_schemes_(ubound(supported_schemes_, dim=1)) - endfunction description - elemental function has_fast_mode(self) !< Return .true. if the integrator class has *fast mode* integrate. class(integrator_adams_bashforth), intent(in) :: self !< Integrator. @@ -207,6 +187,7 @@ subroutine initialize(self, scheme, autoupdate, U, stop_on_fail) if (self%is_supported(scheme=scheme)) then call self%destroy + self%description_ = trim(adjustl(scheme)) select case(trim(adjustl(scheme))) case('adams_bashforth_1') self%steps = 1 ; allocate(self%b(1:self%steps)) ; self%b = 0.0_R_P diff --git a/src/lib/foodie_integrator_adams_bashforth_moulton.f90 b/src/lib/foodie_integrator_adams_bashforth_moulton.f90 index 367c37d1..297ba49c 100644 --- a/src/lib/foodie_integrator_adams_bashforth_moulton.f90 +++ b/src/lib/foodie_integrator_adams_bashforth_moulton.f90 @@ -121,7 +121,6 @@ module foodie_integrator_adams_bashforth_moulton 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) :: integrate !< Integrate integrand field. @@ -144,25 +143,6 @@ pure function class_name(self) class_name = trim(adjustl(class_name_)) endfunction class_name - pure function description(self, prefix) result(desc) - !< Return a pretty-formatted object description. - class(integrator_adams_bashforth_moulton), intent(in) :: self !< Integrator. - character(*), intent(in), optional :: prefix !< Prefixing string. - character(len=:), allocatable :: desc !< Description. - character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. - character(len=1), parameter :: NL=new_line('a') !< New line character. - integer(I_P) :: s !< Counter. - - prefix_ = '' ; if (present(prefix)) prefix_ = prefix - desc = '' - desc = desc//prefix_//'Adams-Bashforth-Moulton multi-step (predictor-corrector) schemes class'//NL - desc = desc//prefix_//' Supported schemes:'//NL - do s=lbound(supported_schemes_, dim=1), ubound(supported_schemes_, dim=1) - 1 - desc = desc//prefix_//' + '//supported_schemes_(s)//NL - enddo - desc = desc//prefix_//' + '//supported_schemes_(ubound(supported_schemes_, dim=1)) - endfunction description - elemental function has_fast_mode(self) !< Return .true. if the integrator class has *fast mode* integrate. class(integrator_adams_bashforth_moulton), intent(in) :: self !< Integrator. @@ -282,6 +262,7 @@ subroutine initialize(self, scheme, iterations, autoupdate, U, stop_on_fail) if (self%is_supported(scheme=scheme)) then call self%destroy + self%description_ = trim(adjustl(scheme)) scheme_number_ = self%scheme_number(scheme=scheme) schemes_ab = self%predictor%supported_schemes() schemes_am = self%corrector%supported_schemes() diff --git a/src/lib/foodie_integrator_adams_moulton.f90 b/src/lib/foodie_integrator_adams_moulton.f90 index 9f54c321..62b0e73c 100644 --- a/src/lib/foodie_integrator_adams_moulton.f90 +++ b/src/lib/foodie_integrator_adams_moulton.f90 @@ -69,7 +69,6 @@ module foodie_integrator_adams_moulton 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(lhs) :: integr_assign_integr !< Operator `=`. procedure, pass(self) :: has_fast_mode !< Return .true. if the integrator class has *fast mode* integrate. procedure, pass(self) :: integrate !< Integrate integrand field. @@ -91,25 +90,6 @@ pure function class_name(self) class_name = trim(adjustl(class_name_)) endfunction class_name - pure function description(self, prefix) result(desc) - !< Return a pretty-formatted object description. - class(integrator_adams_moulton), intent(in) :: self !< Integrator. - character(*), intent(in), optional :: prefix !< Prefixing string. - character(len=:), allocatable :: desc !< Description. - character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. - character(len=1), parameter :: NL=new_line('a') !< New line character. - integer(I_P) :: s !< Counter. - - prefix_ = '' ; if (present(prefix)) prefix_ = prefix - desc = '' - desc = desc//prefix_//'Adams-Moulton multi-step schemes class'//NL - desc = desc//prefix_//' Supported schemes:'//NL - do s=lbound(supported_schemes_, dim=1), ubound(supported_schemes_, dim=1) - 1 - desc = desc//prefix_//' + '//supported_schemes_(s)//NL - enddo - desc = desc//prefix_//' + '//supported_schemes_(ubound(supported_schemes_, dim=1)) - endfunction description - elemental function has_fast_mode(self) !< Return .true. if the integrator class has *fast mode* integrate. class(integrator_adams_moulton), intent(in) :: self !< Integrator. @@ -252,7 +232,8 @@ subroutine initialize(self, scheme, iterations, autoupdate, U, stop_on_fail) logical, intent(in), optional :: stop_on_fail !< Stop execution if initialization fail. if (self%is_supported(scheme=scheme)) then - call self%destroy + call self%destroy + self%description_ = trim(adjustl(scheme)) select case(trim(adjustl(scheme))) case('adams_moulton_0') self%steps = 0 ; allocate(self%b(0:self%steps)) ; self%b = 0.0_R_P diff --git a/src/lib/foodie_integrator_backward_differentiation_formula.f90 b/src/lib/foodie_integrator_backward_differentiation_formula.f90 index af6c85f6..52f7eb13 100644 --- a/src/lib/foodie_integrator_backward_differentiation_formula.f90 +++ b/src/lib/foodie_integrator_backward_differentiation_formula.f90 @@ -67,7 +67,6 @@ module foodie_integrator_backward_differentiation_formula 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) :: integrate !< Integrate integrand field. @@ -89,25 +88,6 @@ pure function class_name(self) class_name = trim(adjustl(class_name_)) endfunction class_name - pure function description(self, prefix) result(desc) - !< Return a pretty-formatted object description. - class(integrator_back_df), intent(in) :: self !< Integrator. - character(*), intent(in), optional :: prefix !< Prefixing string. - character(len=:), allocatable :: desc !< Description. - character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. - character(len=1), parameter :: NL=new_line('a') !< New line character. - integer(I_P) :: s !< Counter. - - prefix_ = '' ; if (present(prefix)) prefix_ = prefix - desc = '' - desc = desc//prefix_//'Backward-Differentiation-Formula multi-step schemes class'//NL - desc = desc//prefix_//' Supported schemes:'//NL - do s=lbound(supported_schemes_, dim=1), ubound(supported_schemes_, dim=1) - 1 - desc = desc//prefix_//' + '//supported_schemes_(s)//NL - enddo - desc = desc//prefix_//' + '//supported_schemes_(ubound(supported_schemes_, dim=1)) - endfunction description - elemental function has_fast_mode(self) !< Return .true. if the integrator class has *fast mode* integrate. class(integrator_back_df), intent(in) :: self !< Integrator. @@ -219,7 +199,8 @@ subroutine initialize(self, scheme, iterations, autoupdate, U, stop_on_fail) logical, intent(in), optional :: stop_on_fail !< Stop execution if initialization fail. if (self%is_supported(scheme=scheme)) then - call self%destroy + call self%destroy + self%description_ = trim(adjustl(scheme)) select case(trim(adjustl(scheme))) case('back_df_1') self%steps = 1 ; allocate(self%a(1:self%steps)) ; self%a = 0.0_R_P diff --git a/src/lib/foodie_integrator_euler_explicit.f90 b/src/lib/foodie_integrator_euler_explicit.f90 index 5dafdb61..90b1f030 100644 --- a/src/lib/foodie_integrator_euler_explicit.f90 +++ b/src/lib/foodie_integrator_euler_explicit.f90 @@ -34,7 +34,6 @@ module foodie_integrator_euler_explicit 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) :: integrate !< Integrate integrand field. @@ -55,17 +54,6 @@ pure function class_name(self) class_name = trim(adjustl(class_name_)) endfunction class_name - pure function description(self, prefix) result(desc) - !< Return a pretty-formatted object description. - class(integrator_euler_explicit), intent(in) :: self !< Integrator. - character(*), intent(in), optional :: prefix !< Prefixing string. - character(len=:), allocatable :: desc !< Description. - character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. - - prefix_ = '' ; if (present(prefix)) prefix_ = prefix - desc = prefix_//'Euler, Explicit (1 step/stage) 1st order scheme' - endfunction description - elemental function has_fast_mode(self) !< Return .true. if the integrator class has *fast mode* integrate. class(integrator_euler_explicit), intent(in) :: self !< Integrator. @@ -142,22 +130,23 @@ elemental subroutine destroy(self) call self%destroy_multistage endsubroutine destroy - subroutine initialize(self, scheme, U, stop_on_fail) - !< Create the actual RK integrator: initialize the Butcher' table coefficients. - class(integrator_euler_explicit), intent(inout) :: self !< Integrator. - character(*), intent(in) :: scheme !< Selected scheme. - class(integrand_object), intent(in), optional :: U !< Integrand molding prototype. - logical, intent(in), optional :: stop_on_fail !< Stop execution if initialization fail. - - if (self%is_supported(scheme=scheme)) then - call self%destroy - self%stages = 0 - self%registers = self%stages - if (present(U)) call self%allocate_integrand_members(U=U) - else - call self%trigger_error(error=ERROR_UNSUPPORTED_SCHEME, & - error_message='"'//trim(adjustl(scheme))//'" unsupported scheme', & - is_severe=stop_on_fail) - endif - endsubroutine initialize + subroutine initialize(self, scheme, U, stop_on_fail) + !< Create the actual RK integrator: initialize the Butcher' table coefficients. + class(integrator_euler_explicit), intent(inout) :: self !< Integrator. + character(*), intent(in) :: scheme !< Selected scheme. + class(integrand_object), intent(in), optional :: U !< Integrand molding prototype. + logical, intent(in), optional :: stop_on_fail !< Stop execution if initialization fail. + + if (self%is_supported(scheme=scheme)) then + call self%destroy + self%description_ = trim(adjustl(scheme)) + self%stages = 0 + self%registers = self%stages + if (present(U)) call self%allocate_integrand_members(U=U) + else + call self%trigger_error(error=ERROR_UNSUPPORTED_SCHEME, & + error_message='"'//trim(adjustl(scheme))//'" unsupported scheme', & + is_severe=stop_on_fail) + endif + endsubroutine initialize endmodule foodie_integrator_euler_explicit diff --git a/src/lib/foodie_integrator_leapfrog.f90 b/src/lib/foodie_integrator_leapfrog.f90 index 8c266070..697af33c 100644 --- a/src/lib/foodie_integrator_leapfrog.f90 +++ b/src/lib/foodie_integrator_leapfrog.f90 @@ -67,7 +67,6 @@ module foodie_integrator_leapfrog 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) :: integrate !< Integrate integrand field. @@ -91,17 +90,6 @@ pure function class_name(self) class_name = trim(adjustl(class_name_)) endfunction class_name - pure function description(self, prefix) result(desc) - !< Return a pretty-formatted object description. - class(integrator_leapfrog), intent(in) :: self !< Integrator. - character(*), intent(in), optional :: prefix !< Prefixing string. - character(len=:), allocatable :: desc !< Description. - character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. - - prefix_ = '' ; if (present(prefix)) prefix_ = prefix - desc = desc//prefix_//'Explicit leapfrog multi-step 2nd order scheme' - endfunction description - elemental function has_fast_mode(self) !< Return .true. if the integrator class has *fast mode* integrate. class(integrator_leapfrog), intent(in) :: self !< Integrator. @@ -219,21 +207,22 @@ subroutine initialize(self, scheme, nu, alpha, autoupdate, U, stop_on_fail) logical, intent(in), optional :: stop_on_fail !< Stop execution if initialization fail. if (self%is_supported(scheme=scheme)) then - call self%destroy - select case(trim(adjustl(scheme))) - case('leapfrog_raw') - self%nu = 0.01_R_P ; if (present(nu)) self%nu = nu - self%alpha = 0.53_R_P ; if (present(alpha)) self%alpha = alpha - self%is_filtered = .true. - endselect - self%autoupdate = .true. ; if (present(autoupdate)) self%autoupdate = autoupdate - self%steps = 2 - self%registers = self%steps - if (present(U)) call self%allocate_integrand_members(U=U) + call self%destroy + self%description_ = trim(adjustl(scheme)) + select case(trim(adjustl(scheme))) + case('leapfrog_raw') + self%nu = 0.01_R_P ; if (present(nu)) self%nu = nu + self%alpha = 0.53_R_P ; if (present(alpha)) self%alpha = alpha + self%is_filtered = .true. + endselect + self%autoupdate = .true. ; if (present(autoupdate)) self%autoupdate = autoupdate + self%steps = 2 + self%registers = self%steps + if (present(U)) call self%allocate_integrand_members(U=U) else - call self%trigger_error(error=ERROR_UNSUPPORTED_SCHEME, & - error_message='"'//trim(adjustl(scheme))//'" unsupported scheme', & - is_severe=stop_on_fail) + call self%trigger_error(error=ERROR_UNSUPPORTED_SCHEME, & + error_message='"'//trim(adjustl(scheme))//'" unsupported scheme', & + is_severe=stop_on_fail) endif endsubroutine initialize diff --git a/src/lib/foodie_integrator_lmm_ssp.f90 b/src/lib/foodie_integrator_lmm_ssp.f90 index 4545d4ff..6916cd9d 100644 --- a/src/lib/foodie_integrator_lmm_ssp.f90 +++ b/src/lib/foodie_integrator_lmm_ssp.f90 @@ -57,7 +57,6 @@ module foodie_integrator_lmm_ssp 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) :: integrate !< Integrate integrand field. @@ -79,25 +78,6 @@ pure function class_name(self) class_name = trim(adjustl(class_name_)) endfunction class_name - pure function description(self, prefix) result(desc) - !< Return a pretty-formatted object description. - class(integrator_lmm_ssp), intent(in) :: self !< Integrator. - character(*), intent(in), optional :: prefix !< Prefixing string. - character(len=:), allocatable :: desc !< Description. - character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. - character(len=1), parameter :: NL=new_line('a') !< New line character. - integer(I_P) :: s !< Counter. - - prefix_ = '' ; if (present(prefix)) prefix_ = prefix - desc = '' - desc = desc//prefix_//'Strong Stability preserving Linear-Multistep-Methods class'//NL - desc = desc//prefix_//' Supported schemes:'//NL - do s=lbound(supported_schemes_, dim=1), ubound(supported_schemes_, dim=1) - 1 - desc = desc//prefix_//' + '//supported_schemes_(s)//NL - enddo - desc = desc//prefix_//' + '//supported_schemes_(ubound(supported_schemes_, dim=1)) - endfunction description - elemental function has_fast_mode(self) !< Return .true. if the integrator class has *fast mode* integrate. class(integrator_lmm_ssp), intent(in) :: self !< Integrator. @@ -195,67 +175,68 @@ elemental subroutine destroy(self) if (allocated(self%b)) deallocate(self%b) endsubroutine destroy - subroutine initialize(self, scheme, autoupdate, U, stop_on_fail) - !< Create the actual LMM-SSP integrator: initialize the *a,b* coefficients. - !< - !< @note If the integrator is initialized with a bad (unsupported) number of required time steps the initialization fails and - !< the integrator error status is updated consistently for external-provided errors handling. - class(integrator_lmm_ssp), intent(inout) :: self !< Integrator. - character(*), intent(in) :: scheme !< Selected scheme. - logical, intent(in), optional :: autoupdate !< Enable cyclic autoupdate of previous time steps. - class(integrand_object), intent(in), optional :: U !< Integrand molding prototype. - logical, intent(in), optional :: stop_on_fail !< Stop execution if initialization fail. - - if (self%is_supported(scheme=scheme)) then - call self%destroy - select case(trim(adjustl(scheme))) - case('lmm_ssp_steps_3_order_2') - self%steps = 3 - allocate(self%a(1:self%steps)) ; self%a = 0.0_R_P - allocate(self%b(1:self%steps)) ; self%b = 0.0_R_P - self%a(1) = 1._R_P/4._R_P - self%a(2) = 0._R_P - self%a(3) = 3._R_P/4._R_P - - self%b(1) = 0._R_P - self%b(2) = 0._R_P - self%b(3) = 3._R_P/2._R_P - case('lmm_ssp_steps_4_order_3') - self%steps = 4 - allocate(self%a(1:self%steps)) ; self%a = 0.0_R_P - allocate(self%b(1:self%steps)) ; self%b = 0.0_R_P - self%a(1) = 11._R_P/27._R_P - self%a(2) = 0._R_P - self%a(3) = 0._R_P - self%a(4) = 16._R_P/27._R_P - - self%b(1) = 12._R_P/27._R_P - self%b(2) = 0._R_P - self%b(3) = 0._R_P - self%b(4) = 16._R_P/9._R_P - case('lmm_ssp_steps_5_order_3') - self%steps = 5 - allocate(self%a(1:self%steps)) ; self%a = 0.0_R_P - allocate(self%b(1:self%steps)) ; self%b = 0.0_R_P - self%a(1) = 7._R_P/32._R_P - self%a(2) = 0._R_P - self%a(3) = 0._R_P - self%a(4) = 0._R_P - self%a(5) = 25._R_P/32._R_P - - self%b(1) = 5._R_P/16._R_P - self%b(2) = 0._R_P - self%b(3) = 0._R_P - self%b(4) = 0._R_P - self%b(5) = 25._R_P/16._R_P - endselect - self%autoupdate = .true. ; if (present(autoupdate)) self%autoupdate = autoupdate - self%registers = self%steps - if (present(U)) call self%allocate_integrand_members(U=U) - else - call self%trigger_error(error=ERROR_UNSUPPORTED_SCHEME, & - error_message='"'//trim(adjustl(scheme))//'" unsupported scheme', & - is_severe=stop_on_fail) - endif - endsubroutine initialize + subroutine initialize(self, scheme, autoupdate, U, stop_on_fail) + !< Create the actual LMM-SSP integrator: initialize the *a,b* coefficients. + !< + !< @note If the integrator is initialized with a bad (unsupported) number of required time steps the initialization fails and + !< the integrator error status is updated consistently for external-provided errors handling. + class(integrator_lmm_ssp), intent(inout) :: self !< Integrator. + character(*), intent(in) :: scheme !< Selected scheme. + logical, intent(in), optional :: autoupdate !< Enable cyclic autoupdate of previous time steps. + class(integrand_object), intent(in), optional :: U !< Integrand molding prototype. + logical, intent(in), optional :: stop_on_fail !< Stop execution if initialization fail. + + if (self%is_supported(scheme=scheme)) then + call self%destroy + self%description_ = trim(adjustl(scheme)) + select case(trim(adjustl(scheme))) + case('lmm_ssp_steps_3_order_2') + self%steps = 3 + allocate(self%a(1:self%steps)) ; self%a = 0.0_R_P + allocate(self%b(1:self%steps)) ; self%b = 0.0_R_P + self%a(1) = 1._R_P/4._R_P + self%a(2) = 0._R_P + self%a(3) = 3._R_P/4._R_P + + self%b(1) = 0._R_P + self%b(2) = 0._R_P + self%b(3) = 3._R_P/2._R_P + case('lmm_ssp_steps_4_order_3') + self%steps = 4 + allocate(self%a(1:self%steps)) ; self%a = 0.0_R_P + allocate(self%b(1:self%steps)) ; self%b = 0.0_R_P + self%a(1) = 11._R_P/27._R_P + self%a(2) = 0._R_P + self%a(3) = 0._R_P + self%a(4) = 16._R_P/27._R_P + + self%b(1) = 12._R_P/27._R_P + self%b(2) = 0._R_P + self%b(3) = 0._R_P + self%b(4) = 16._R_P/9._R_P + case('lmm_ssp_steps_5_order_3') + self%steps = 5 + allocate(self%a(1:self%steps)) ; self%a = 0.0_R_P + allocate(self%b(1:self%steps)) ; self%b = 0.0_R_P + self%a(1) = 7._R_P/32._R_P + self%a(2) = 0._R_P + self%a(3) = 0._R_P + self%a(4) = 0._R_P + self%a(5) = 25._R_P/32._R_P + + self%b(1) = 5._R_P/16._R_P + self%b(2) = 0._R_P + self%b(3) = 0._R_P + self%b(4) = 0._R_P + self%b(5) = 25._R_P/16._R_P + endselect + self%autoupdate = .true. ; if (present(autoupdate)) self%autoupdate = autoupdate + self%registers = self%steps + if (present(U)) call self%allocate_integrand_members(U=U) + else + call self%trigger_error(error=ERROR_UNSUPPORTED_SCHEME, & + error_message='"'//trim(adjustl(scheme))//'" unsupported scheme', & + is_severe=stop_on_fail) + endif + endsubroutine initialize endmodule foodie_integrator_lmm_ssp diff --git a/src/lib/foodie_integrator_lmm_ssp_vss.f90 b/src/lib/foodie_integrator_lmm_ssp_vss.f90 index 25f86221..2f1d3680 100644 --- a/src/lib/foodie_integrator_lmm_ssp_vss.f90 +++ b/src/lib/foodie_integrator_lmm_ssp_vss.f90 @@ -67,7 +67,6 @@ module foodie_integrator_lmm_ssp_vss 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) :: integrate !< Integrate integrand field. @@ -115,25 +114,6 @@ pure function class_name(self) class_name = trim(adjustl(class_name_)) endfunction class_name - pure function description(self, prefix) result(desc) - !< Return a pretty-formatted object description. - class(integrator_lmm_ssp_vss), intent(in) :: self !< Integrator. - character(*), intent(in), optional :: prefix !< Prefixing string. - character(len=:), allocatable :: desc !< Description. - character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. - character(len=1), parameter :: NL=new_line('a') !< New line character. - integer(I_P) :: s !< Counter. - - prefix_ = '' ; if (present(prefix)) prefix_ = prefix - desc = '' - desc = desc//prefix_//'Strong Stability preserving Linear-Multistep-Methods Variable Stepsize class'//NL - desc = desc//prefix_//' Supported schemes:'//NL - do s=lbound(supported_schemes_, dim=1), ubound(supported_schemes_, dim=1) - 1 - desc = desc//prefix_//' + '//supported_schemes_(s)//NL - enddo - desc = desc//prefix_//' + '//supported_schemes_(ubound(supported_schemes_, dim=1)) - endfunction description - elemental function has_fast_mode(self) !< Return .true. if the integrator class has *fast mode* integrate. class(integrator_lmm_ssp_vss), intent(in) :: self !< Integrator. @@ -220,36 +200,37 @@ subroutine initialize(self, scheme, autoupdate, U, stop_on_fail) logical, intent(in), optional :: stop_on_fail !< Stop execution if initialization fail. if (self%is_supported(scheme=scheme)) then - call self%destroy - select case(trim(adjustl(scheme))) - case('lmm_ssp_vss_steps_2_order_2') - self%steps = 2 - self%integrate_ => integrate_order_2 - self%integrate_fast_ => integrate_order_2_fast - case('lmm_ssp_vss_steps_3_order_2') - self%steps = 3 - self%integrate_ => integrate_order_2 - self%integrate_fast_ => integrate_order_2_fast - case('lmm_ssp_vss_steps_3_order_3') - self%steps = 3 - self%integrate_ => integrate_order_3 - self%integrate_fast_ => integrate_order_3_fast - case('lmm_ssp_vss_steps_4_order_3') - self%steps = 4 - self%integrate_ => integrate_order_3 - self%integrate_fast_ => integrate_order_3_fast - case('lmm_ssp_vss_steps_5_order_3') - self%steps = 5 - self%integrate_ => integrate_order_3 - self%integrate_fast_ => integrate_order_3_fast - endselect - self%autoupdate = .true. ; if (present(autoupdate)) self%autoupdate = autoupdate - self%registers = self%steps - if (present(U)) call self%allocate_integrand_members(U=U) + call self%destroy + self%description_ = trim(adjustl(scheme)) + select case(trim(adjustl(scheme))) + case('lmm_ssp_vss_steps_2_order_2') + self%steps = 2 + self%integrate_ => integrate_order_2 + self%integrate_fast_ => integrate_order_2_fast + case('lmm_ssp_vss_steps_3_order_2') + self%steps = 3 + self%integrate_ => integrate_order_2 + self%integrate_fast_ => integrate_order_2_fast + case('lmm_ssp_vss_steps_3_order_3') + self%steps = 3 + self%integrate_ => integrate_order_3 + self%integrate_fast_ => integrate_order_3_fast + case('lmm_ssp_vss_steps_4_order_3') + self%steps = 4 + self%integrate_ => integrate_order_3 + self%integrate_fast_ => integrate_order_3_fast + case('lmm_ssp_vss_steps_5_order_3') + self%steps = 5 + self%integrate_ => integrate_order_3 + self%integrate_fast_ => integrate_order_3_fast + endselect + self%autoupdate = .true. ; if (present(autoupdate)) self%autoupdate = autoupdate + self%registers = self%steps + if (present(U)) call self%allocate_integrand_members(U=U) else - call self%trigger_error(error=ERROR_UNSUPPORTED_SCHEME, & - error_message='"'//trim(adjustl(scheme))//'" unsupported scheme', & - is_severe=stop_on_fail) + call self%trigger_error(error=ERROR_UNSUPPORTED_SCHEME, & + error_message='"'//trim(adjustl(scheme))//'" unsupported scheme', & + is_severe=stop_on_fail) endif endsubroutine initialize diff --git a/src/lib/foodie_integrator_ms_runge_kutta_ssp.f90 b/src/lib/foodie_integrator_ms_runge_kutta_ssp.f90 index ab505c74..02a376a8 100644 --- a/src/lib/foodie_integrator_ms_runge_kutta_ssp.f90 +++ b/src/lib/foodie_integrator_ms_runge_kutta_ssp.f90 @@ -67,7 +67,6 @@ module foodie_integrator_ms_runge_kutta_ssp 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) :: integrate !< Integrate integrand field. @@ -89,25 +88,6 @@ pure function class_name(self) class_name = trim(adjustl(class_name_)) endfunction class_name - pure function description(self, prefix) result(desc) - !< Return a pretty-formatted object description. - class(integrator_ms_runge_kutta_ssp), intent(in) :: self !< Integrator. - character(*), intent(in), optional :: prefix !< Prefixing string. - character(len=:), allocatable :: desc !< Description. - character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. - character(len=1), parameter :: NL=new_line('a') !< New line character. - integer(I_P) :: s !< Counter. - - prefix_ = '' ; if (present(prefix)) prefix_ = prefix - desc = '' - desc = desc//prefix_//'Multi-step Strong Stability preserving Runge-Kutta schemes class'//NL - desc = desc//prefix_//' Supported schemes:'//NL - do s=lbound(supported_schemes_, dim=1), ubound(supported_schemes_, dim=1) - 1 - desc = desc//prefix_//' + '//supported_schemes_(s)//NL - enddo - desc = desc//prefix_//' + '//supported_schemes_(ubound(supported_schemes_, dim=1)) - endfunction description - elemental function has_fast_mode(self) !< Return .true. if the integrator class has *fast mode* integrate. class(integrator_ms_runge_kutta_ssp), intent(in) :: self !< Integrator. @@ -284,6 +264,7 @@ subroutine initialize(self, scheme, iterations, autoupdate, U, stop_on_fail) if (self%is_supported(scheme=scheme)) then call self%destroy + self%description_ = trim(adjustl(scheme)) select case(trim(adjustl(scheme))) case('ms_runge_kutta_ssp_steps_2_stages_2_order_3') self%steps = 2 diff --git a/src/lib/foodie_integrator_object.f90 b/src/lib/foodie_integrator_object.f90 index 19559243..d74d36d4 100644 --- a/src/lib/foodie_integrator_object.f90 +++ b/src/lib/foodie_integrator_object.f90 @@ -12,17 +12,18 @@ module foodie_integrator_object type, abstract :: integrator_object !< Abstract type of FOODIE ODE integrators. + character(len=:), allocatable :: description_ !< Informative description of the integrator. integer(I_P) :: error=0 !< Error status code. character(len=:), allocatable :: error_message !< Error message, hopefully meaningful. contains ! public methods procedure, pass(lhs) :: assign_abstract !< Assign ony members of abstract [[integrator_object]] type. procedure, pass(self) :: check_error !< Check for error occurrencies. + procedure, pass(self) :: description !< Return informative integrator description. procedure, pass(self) :: destroy_abstract !< Destroy only members of abstract [[integrator_object]] type. procedure, pass(self) :: trigger_error !< Trigger an error. ! deferred methods procedure(class_name_interface), pass(self), deferred :: class_name !< Return the class name of schemes. - procedure(description_interface), pass(self), deferred :: description !< Return pretty-printed obj. description. procedure(has_fast_mode_interface), pass(self), deferred :: has_fast_mode !< Return .true. if the integrator class !< has *fast mode* integrate. procedure(assignment_interface), pass(lhs), deferred :: integr_assign_integr !< Operator `=`. @@ -105,6 +106,7 @@ pure subroutine assign_abstract(lhs, rhs) class(integrator_object), intent(inout) :: lhs !< Left hand side. class(integrator_object), intent(in) :: rhs !< Right hand side. + if (allocated(rhs%description_ )) lhs%description_ = rhs%description_ lhs%error = rhs%error if (allocated(rhs%error_message)) lhs%error_message = rhs%error_message endsubroutine assign_abstract @@ -129,10 +131,26 @@ subroutine check_error(self, is_severe) endif endsubroutine check_error + pure function description(self, prefix) result(desc) + !< Return informative integrator description. + class(integrator_object), intent(in) :: self !< Integrator. + character(*), intent(in), optional :: prefix !< Prefixing string. + character(len=:), allocatable :: desc !< Description. + character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. + + prefix_ = '' ; if (present(prefix)) prefix_ = prefix + if (allocated(self%description_)) then + desc = prefix//self%description_ + else + desc = prefix//self%class_name() + endif + endfunction description + elemental subroutine destroy_abstract(self) !< Destroy only members of abstract [[integrator_object]] type. class(integrator_object), intent(inout) :: self !< Integrator. + if (allocated(self%description_)) deallocate(self%description_) self%error = 0 if (allocated(self%error_message)) deallocate(self%error_message) endsubroutine destroy_abstract diff --git a/src/lib/foodie_integrator_runge_kutta_embedded.f90 b/src/lib/foodie_integrator_runge_kutta_embedded.f90 index 0368554c..7e1d84a7 100644 --- a/src/lib/foodie_integrator_runge_kutta_embedded.f90 +++ b/src/lib/foodie_integrator_runge_kutta_embedded.f90 @@ -283,8 +283,6 @@ module foodie_integrator_runge_kutta_emd trim(class_name_)//'_stages_17_order_10'] !< List of supported schemes. logical, parameter :: has_fast_mode_=.true. !< Flag to check if integrator provides *fast mode* integrate. -logical, parameter :: is_multistage_=.true. !< Flag to check if integrator is multistage. -logical, parameter :: is_multistep_=.false. !< Flag to check if integrator is multistep. type, extends(integrator_multistage_object) :: integrator_runge_kutta_emd !< FOODIE integrator: provide an explicit class of embedded Runge-Kutta schemes, from 2nd to 10th order accurate. @@ -301,7 +299,6 @@ module foodie_integrator_runge_kutta_emd 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) :: integrate !< Integrate integrand field. @@ -326,25 +323,6 @@ pure function class_name(self) class_name = trim(adjustl(class_name_)) endfunction class_name - pure function description(self, prefix) result(desc) - !< Return a pretty-formatted object description. - class(integrator_runge_kutta_emd), intent(in) :: self !< Integrator. - character(*), intent(in), optional :: prefix !< Prefixing string. - character(len=:), allocatable :: desc !< Description. - character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. - character(len=1), parameter :: NL=new_line('a') !< New line character. - integer(I_P) :: s !< Counter. - - prefix_ = '' ; if (present(prefix)) prefix_ = prefix - desc = '' - desc = desc//prefix_//'Embedded Runge-Kutta multi-stage schemes class'//NL - desc = desc//prefix_//' Supported schemes:'//NL - do s=lbound(supported_schemes_, dim=1), ubound(supported_schemes_, dim=1) - 1 - desc = desc//prefix_//' + '//supported_schemes_(s)//NL - enddo - desc = desc//prefix_//' + '//supported_schemes_(ubound(supported_schemes_, dim=1)) - endfunction description - elemental function has_fast_mode(self) !< Return .true. if the integrator class has *fast mode* integrate. class(integrator_runge_kutta_emd), intent(in) :: self !< Integrator. @@ -499,11 +477,8 @@ subroutine initialize(self, scheme, U, tolerance, stop_on_fail) if (self%is_supported(scheme=scheme)) then call self%destroy - if (present(tolerance)) then - self%tolerance = tolerance - else - self%tolerance = 0.01_R_P - endif + self%description_ = trim(adjustl(scheme)) + self%tolerance = 0.01_R_P ; if (present(tolerance)) self%tolerance = tolerance select case(trim(adjustl(scheme))) case('runge_kutta_emd_stages_2_order_2') ! do not use, seems to not work! self%stages = 2 diff --git a/src/lib/foodie_integrator_runge_kutta_low_storage.f90 b/src/lib/foodie_integrator_runge_kutta_low_storage.f90 index 92022343..4803239a 100644 --- a/src/lib/foodie_integrator_runge_kutta_low_storage.f90 +++ b/src/lib/foodie_integrator_runge_kutta_low_storage.f90 @@ -181,7 +181,6 @@ module foodie_integrator_runge_kutta_low_storage 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) :: integrate !< Integrate integrand field. @@ -204,25 +203,6 @@ pure function class_name(self) class_name = trim(adjustl(class_name_)) endfunction class_name - pure function description(self, prefix) result(desc) - !< Return a pretty-formatted object description. - class(integrator_runge_kutta_ls), intent(in) :: self !< Integrator. - character(*), intent(in), optional :: prefix !< Prefixing string. - character(len=:), allocatable :: desc !< Description. - character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. - character(len=1), parameter :: NL=new_line('a') !< New line character. - integer(I_P) :: s !< Counter. - - prefix_ = '' ; if (present(prefix)) prefix_ = prefix - desc = '' - desc = desc//prefix_//'Low storage (2-registers) Runge-Kutta multi-stage schemes class'//NL - desc = desc//prefix_//' Supported schemes:'//NL - do s=lbound(supported_schemes_, dim=1), ubound(supported_schemes_, dim=1) - 1 - desc = desc//prefix_//' + '//supported_schemes_(s)//NL - enddo - desc = desc//prefix_//' + '//supported_schemes_(ubound(supported_schemes_, dim=1)) - endfunction description - elemental function has_fast_mode(self) !< Return .true. if the integrator class has *fast mode* integrate. class(integrator_runge_kutta_ls), intent(in) :: self !< Integrator. @@ -336,6 +316,7 @@ subroutine initialize(self, scheme, U, stop_on_fail) if (self%is_supported(scheme=scheme)) then call self%destroy + self%description_ = trim(adjustl(scheme)) select case(trim(adjustl(scheme))) case('runge_kutta_ls_stages_1_order_1') self%stages = 1 diff --git a/src/lib/foodie_integrator_runge_kutta_lssp.f90 b/src/lib/foodie_integrator_runge_kutta_lssp.f90 index 4ec0a736..d062c470 100644 --- a/src/lib/foodie_integrator_runge_kutta_lssp.f90 +++ b/src/lib/foodie_integrator_runge_kutta_lssp.f90 @@ -66,7 +66,7 @@ module foodie_integrator_runge_kutta_lssp use foodie_integrand_object, only : integrand_object use foodie_integrator_multistage_object, only : integrator_multistage_object use foodie_integrator_object, only : integrator_object -use penf, only : I_P, R_P +use penf, only : I_P, R_P, str implicit none private @@ -89,7 +89,6 @@ module foodie_integrator_runge_kutta_lssp 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) :: integrate !< Integrate integrand field. @@ -137,25 +136,6 @@ pure function class_name(self) class_name = trim(adjustl(class_name_)) endfunction class_name - pure function description(self, prefix) result(desc) - !< Return a pretty-formatted object description. - class(integrator_runge_kutta_lssp), intent(in) :: self !< Integrator. - character(*), intent(in), optional :: prefix !< Prefixing string. - character(len=:), allocatable :: desc !< Description. - character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. - character(len=1), parameter :: NL=new_line('a') !< New line character. - integer(I_P) :: s !< Counter. - - prefix_ = '' ; if (present(prefix)) prefix_ = prefix - desc = '' - desc = desc//prefix_//'Linear SSP Runge-Kutta multi-stage schemes class'//NL - desc = desc//prefix_//' Supported schemes:'//NL - do s=lbound(supported_schemes_, dim=1), ubound(supported_schemes_, dim=1) - 1 - desc = desc//prefix_//' + '//supported_schemes_(s)//NL - enddo - desc = desc//prefix_//' + '//supported_schemes_(ubound(supported_schemes_, dim=1)) - endfunction description - elemental function has_fast_mode(self) !< Return .true. if the integrator class has *fast mode* integrate. class(integrator_runge_kutta_lssp), intent(in) :: self !< Integrator. @@ -268,6 +248,7 @@ subroutine initialize(self, scheme, U, stages, stop_on_fail) allocate(self%alpha(1:self%stages)) ; self%alpha = 0._R_P call self%initialize_order_s endselect + self%description_ = trim(adjustl(scheme))//'_stages_'//trim(str(self%stages)) self%registers = self%stages if (present(U)) call self%allocate_integrand_members(U=U) else diff --git a/src/lib/foodie_integrator_runge_kutta_ssp.f90 b/src/lib/foodie_integrator_runge_kutta_ssp.f90 index d66b4369..6803e44b 100644 --- a/src/lib/foodie_integrator_runge_kutta_ssp.f90 +++ b/src/lib/foodie_integrator_runge_kutta_ssp.f90 @@ -129,7 +129,6 @@ module foodie_integrator_runge_kutta_ssp 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) :: integrate !< Integrate integrand field. @@ -151,25 +150,6 @@ pure function class_name(self) class_name = trim(adjustl(class_name_)) endfunction class_name - pure function description(self, prefix) result(desc) - !< Return a pretty-formatted object description. - class(integrator_runge_kutta_ssp), intent(in) :: self !< Integrator. - character(*), intent(in), optional :: prefix !< Prefixing string. - character(len=:), allocatable :: desc !< Description. - character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. - character(len=1), parameter :: NL=new_line('a') !< New line character. - integer(I_P) :: s !< Counter. - - prefix_ = '' ; if (present(prefix)) prefix_ = prefix - desc = '' - desc = desc//prefix_//'SSP Runge-Kutta multi-stage schemes class'//NL - desc = desc//prefix_//' Supported schemes:'//NL - do s=lbound(supported_schemes_, dim=1), ubound(supported_schemes_, dim=1) - 1 - desc = desc//prefix_//' + '//supported_schemes_(s)//NL - enddo - desc = desc//prefix_//' + '//supported_schemes_(ubound(supported_schemes_, dim=1)) - endfunction description - elemental function has_fast_mode(self) !< Return .true. if the integrator class has *fast mode* integrate. class(integrator_runge_kutta_ssp), intent(in) :: self !< Integrator. @@ -291,6 +271,7 @@ subroutine initialize(self, scheme, U, stop_on_fail) if (self%is_supported(scheme=scheme)) then call self%destroy + self%description_ = trim(adjustl(scheme)) select case(trim(adjustl(scheme))) case('runge_kutta_ssp_stages_1_order_1') self%stages = 1 diff --git a/src/tests/tester/foodie_test_integrand_ladvection.f90 b/src/tests/tester/foodie_test_integrand_ladvection.f90 index 853d343b..0f7dc959 100644 --- a/src/tests/tester/foodie_test_integrand_ladvection.f90 +++ b/src/tests/tester/foodie_test_integrand_ladvection.f90 @@ -9,7 +9,7 @@ module foodie_test_integrand_ladvection use flap, only : command_line_interface use foodie, only : integrand_object use foodie_test_integrand_tester_object, only : integrand_tester_object -use penf, only : FR_P, I_P, R_P, str +use penf, only : FR_P, I_P, R_P, str, strz use wenoof, only : interpolator_object, wenoof_create implicit none @@ -62,6 +62,7 @@ module foodie_test_integrand_ladvection procedure, pass(self), public :: exact_solution !< Return exact solution. procedure, pass(self), public :: output !< Extract integrand state field. ! integrand_tester_object deferred methods + procedure, pass(self), public :: description !< Return an informative description of the test. procedure, pass(self), public :: export_tecplot !< Export integrand to Tecplot file. procedure, pass(self), public :: parse_cli !< Initialize from command line interface. procedure, nopass, public :: set_cli !< Set command line interface. @@ -142,6 +143,17 @@ pure function output(self) result(state) endfunction output ! integrand_tester_object deferred methods + pure function description(self, prefix) result(desc) + !< Return informative integrator description. + class(integrand_ladvection), intent(in) :: self !< Integrator. + character(*), intent(in), optional :: prefix !< Prefixing string. + character(len=:), allocatable :: desc !< Description. + character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. + + prefix_ = '' ; if (present(prefix)) prefix_ = prefix + desc = prefix//'linear_advection-Ni_'//trim(strz(self%Ni, 10)) + endfunction description + subroutine export_tecplot(self, file_name, t, scheme, close_file) !< Export integrand to Tecplot file. class(integrand_ladvection), intent(in) :: self !< Advection field. diff --git a/src/tests/tester/foodie_test_integrand_oscillation.f90 b/src/tests/tester/foodie_test_integrand_oscillation.f90 index 9b7f7d5f..c0d932c6 100644 --- a/src/tests/tester/foodie_test_integrand_oscillation.f90 +++ b/src/tests/tester/foodie_test_integrand_oscillation.f90 @@ -54,6 +54,7 @@ module foodie_test_integrand_oscillation procedure, pass(self), public :: initialize !< Initialize integrand. procedure, pass(self), public :: output !< Extract integrand state field. ! integrand_tester_object deferred methods + procedure, pass(self), public :: description !< Return an informative description of the test. procedure, pass(self), public :: export_tecplot !< Export integrand to Tecplot file. procedure, pass(self), public :: parse_cli !< Initialize from command line interface. procedure, nopass, public :: set_cli !< Set command line interface. @@ -128,6 +129,17 @@ pure function output(self) result(state) endfunction output ! integrand_tester_object deferred methods + pure function description(self, prefix) result(desc) + !< Return informative integrator description. + class(integrand_oscillation), intent(in) :: self !< Integrator. + character(*), intent(in), optional :: prefix !< Prefixing string. + character(len=:), allocatable :: desc !< Description. + character(len=:), allocatable :: prefix_ !< Prefixing string, local variable. + + prefix_ = '' ; if (present(prefix)) prefix_ = prefix + desc = prefix//'oscillation' + endfunction description + subroutine export_tecplot(self, file_name, t, scheme, close_file) !< Export integrand to Tecplot file. class(integrand_oscillation), intent(in) :: self !< Advection field. diff --git a/src/tests/tester/foodie_test_integrand_tester_object.f90 b/src/tests/tester/foodie_test_integrand_tester_object.f90 index e3d4235c..50d3bc54 100644 --- a/src/tests/tester/foodie_test_integrand_tester_object.f90 +++ b/src/tests/tester/foodie_test_integrand_tester_object.f90 @@ -16,14 +16,22 @@ module foodie_test_integrand_tester_object !< !< This abstract provided some auxiliary methods useful for the tester machinery. contains - ! auxiliary methods - procedure(export_tecplot_interface), pass(self), deferred :: export_tecplot !< Export integrand to Tecplot file. - procedure(parse_cli_interface), pass(self), deferred :: parse_cli !< Initialize from command line interface. - procedure(set_cli_interface), nopass, deferred :: set_cli !< Set command line interface. + procedure(description_interface), pass(self), deferred :: description !< Return an informative description of the test. + procedure(export_tecplot_interface), pass(self), deferred :: export_tecplot !< Export integrand to Tecplot file. + procedure(parse_cli_interface), pass(self), deferred :: parse_cli !< Initialize from command line interface. + procedure(set_cli_interface), nopass, deferred :: set_cli !< Set command line interface. endtype integrand_tester_object abstract interface !< Abstract interfaces of [[integrand_tester_object]] class. + pure function description_interface(self, prefix) result(desc) + !< Return informative integrator description. + import :: integrand_tester_object + class(integrand_tester_object), intent(in) :: self !< Integrand. + character(*), intent(in), optional :: prefix !< Prefixing string. + character(len=:), allocatable :: desc !< Description. + endfunction description_interface + subroutine export_tecplot_interface(self, file_name, t, scheme, close_file) !< Export integrand to Tecplot file. import :: integrand_tester_object, R_P @@ -48,4 +56,3 @@ subroutine set_cli_interface(cli) endsubroutine set_cli_interface endinterface endmodule foodie_test_integrand_tester_object - diff --git a/src/tests/tester/foodie_tester.f90 b/src/tests/tester/foodie_tester.f90 index adb40167..33733711 100644 --- a/src/tests/tester/foodie_tester.f90 +++ b/src/tests/tester/foodie_tester.f90 @@ -72,7 +72,6 @@ subroutine execute(self) !< Execute test(s). class(test_object), intent(inout) :: self !< Test. character(99), allocatable :: integrator_schemes(:) !< Name of FOODIE integrator schemes. - character(len=:), allocatable :: output_file_name !< File name of output results file. integer(I_P) :: s !< Counter. integer(I_P) :: t !< Counter. @@ -88,28 +87,15 @@ subroutine execute(self) endif do s=1, size(integrator_schemes, dim=1) do t=1, size(self%Dt) - select type(integrand=>self%integrand_0) - type is(integrand_ladvection) - output_file_name = trim(adjustl(self%output))//'-'//& - trim(adjustl(self%test))//'-'//& - trim(adjustl(integrator_schemes(s)))//'-'//& - trim(strz(integrand%Ni, 10))//'-steps_'//& - trim(strz(int(self%final_time/self%Dt(t)), 10))//'.dat' - type is(integrand_oscillation) - output_file_name = trim(adjustl(self%output))//'-'//& - trim(adjustl(self%test))//'-'//& - trim(adjustl(integrator_schemes(s)))//'-steps_'//& - trim(strz(int(self%final_time/self%Dt(t)), 10))//'.dat' - endselect - call integrate(scheme=trim(integrator_schemes(s)), & - integrand_0=self%integrand_0, & - Dt=self%Dt(t), & - final_time=self%final_time, & - iterations=self%implicit_iterations, & - stages=self%stages, & - is_fast=self%is_fast, & - save_results=self%save_results, & - output_file_name=output_file_name, & + call integrate(scheme=trim(integrator_schemes(s)), & + integrand_0=self%integrand_0, & + Dt=self%Dt(t), & + final_time=self%final_time, & + iterations=self%implicit_iterations, & + stages=self%stages, & + is_fast=self%is_fast, & + save_results=self%save_results, & + output_base_name=trim(adjustl(self%output)), & save_frequency=self%save_frequency) enddo enddo @@ -241,7 +227,7 @@ subroutine check_scheme_has_fast_mode(scheme, integrator) endif endsubroutine check_scheme_has_fast_mode - subroutine integrate(scheme, integrand_0, Dt, final_time, iterations, stages, is_fast, save_results, output_file_name, & + subroutine integrate(scheme, integrand_0, Dt, final_time, iterations, stages, is_fast, save_results, output_base_name, & save_frequency) !< Integrate integrand by means of the given scheme. character(*), intent(in) :: scheme !< Selected scheme. @@ -252,7 +238,7 @@ subroutine integrate(scheme, integrand_0, Dt, final_time, iterations, stages, is integer(I_P), intent(in) :: stages !< Number of stages. logical, intent(in) :: is_fast !< Activate fast mode integration. logical, intent(in) :: save_results !< Save results. - character(*), intent(in) :: output_file_name !< File name of output results file. + character(*), intent(in) :: output_base_name !< Base name of output results file. integer(I_P), intent(in) :: save_frequency !< Save frequency. class(integrator_object), allocatable :: integrator !< The integrator. type(integrator_runge_kutta_ssp) :: integrator_start !< The (auto) start integrator. @@ -270,7 +256,11 @@ subroutine integrate(scheme, integrand_0, Dt, final_time, iterations, stages, is step = 0 time = 0._R_P - if (save_results) call integrand%export_tecplot(file_name=output_file_name, t=time, scheme=scheme) + if (save_results) call integrand%export_tecplot(file_name=output_base_name// & + integrand%description(prefix='-')// & + integrator%description(prefix='-')// & + '-steps_'//trim(strz(int(final_time/Dt), 10))//'.dat', & + t=time, scheme=scheme) select type(integrator) class is(integrator_multistage_object)