Skip to content

Commit 43f935b

Browse files
committed
restore error computation into tester
1 parent 19904b5 commit 43f935b

File tree

4 files changed

+98
-48
lines changed

4 files changed

+98
-48
lines changed

src/tests/tester/foodie_test_integrand_ladvection.f90

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ module foodie_test_integrand_ladvection
5959
! auxiliary methods
6060
procedure, pass(self), public :: destroy !< Destroy field.
6161
procedure, pass(self), public :: dt => compute_dt !< Compute the current time step, by means of CFL condition.
62-
procedure, pass(self), public :: exact_solution !< Return exact solution.
6362
procedure, pass(self), public :: output !< Extract integrand state field.
6463
! integrand_tester_object deferred methods
6564
procedure, pass(self), public :: description !< Return an informative description of the test.
65+
procedure, pass(self), public :: exact_solution !< Return exact solution.
6666
procedure, pass(self), public :: export_tecplot !< Export integrand to Tecplot file.
6767
procedure, pass(self), public :: parse_cli !< Initialize from command line interface.
6868
procedure, nopass, public :: set_cli !< Set command line interface.
@@ -125,15 +125,6 @@ pure function compute_dt(self, final_time, t) result(Dt)
125125
endassociate
126126
endfunction compute_dt
127127

128-
pure function exact_solution(self, u0, t) result(exact)
129-
!< Return exact solution.
130-
class(integrand_ladvection), intent(in) :: self !< Integrand.
131-
real(R_P), intent(in) :: u0(1:) !< Initial state
132-
real(R_P), intent(in) :: t !< Time.
133-
real(R_P), allocatable :: exact(:) !< Exact solution.
134-
135-
endfunction exact_solution
136-
137128
pure function output(self) result(state)
138129
!< Output the advection field state.
139130
class(integrand_ladvection), intent(in) :: self !< Advection field.
@@ -154,6 +145,15 @@ pure function description(self, prefix) result(desc)
154145
desc = prefix//'linear_advection-Ni_'//trim(strz(self%Ni, 10))
155146
endfunction description
156147

148+
pure function exact_solution(self, t, U0) result(exact)
149+
!< Return exact solution.
150+
class(integrand_ladvection), intent(in) :: self !< Integrand.
151+
real(R_P), intent(in) :: t !< Time.
152+
class(integrand_object), intent(in), optional :: U0 !< Initial conditions.
153+
real(R_P), allocatable :: exact(:) !< Exact solution.
154+
155+
endfunction exact_solution
156+
157157
subroutine export_tecplot(self, file_name, t, scheme, close_file)
158158
!< Export integrand to Tecplot file.
159159
class(integrand_ladvection), intent(in) :: self !< Advection field.

src/tests/tester/foodie_test_integrand_oscillation.f90

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ module foodie_test_integrand_oscillation
5050
contains
5151
! auxiliary methods
5252
procedure, pass(self), public :: amplitude_phase !< Return amplitude and phase of the oscillation.
53-
procedure, pass(self), public :: exact_solution !< Return exact solution.
5453
procedure, pass(self), public :: initialize !< Initialize integrand.
5554
procedure, pass(self), public :: output !< Extract integrand state field.
5655
! integrand_tester_object deferred methods
5756
procedure, pass(self), public :: description !< Return an informative description of the test.
57+
procedure, pass(self), public :: exact_solution !< Return exact solution.
5858
procedure, pass(self), public :: export_tecplot !< Export integrand to Tecplot file.
5959
procedure, pass(self), public :: parse_cli !< Initialize from command line interface.
6060
procedure, nopass, public :: set_cli !< Set command line interface.
@@ -99,16 +99,6 @@ function amplitude_phase(self) result(ap)
9999
ap(2) = atan(-self%U(1) / self%U(2))
100100
endfunction amplitude_phase
101101

102-
pure function exact_solution(self, t) result(exact)
103-
!< Return exact solution.
104-
class(integrand_oscillation), intent(in) :: self !< Integrand.
105-
real(R_P), intent(in) :: t !< Time.
106-
real(R_P) :: exact(1:2) !< Exact solution.
107-
108-
exact(1) = self%U0(1) * cos(self%f * t) - self%U0(2) * sin(self%f * t)
109-
exact(2) = self%U0(1) * sin(self%f * t) + self%U0(2) * cos(self%f * t)
110-
endfunction exact_solution
111-
112102
pure subroutine initialize(self, U0, frequency)
113103
!< Initialize integrand.
114104
class(integrand_oscillation), intent(inout) :: self !< Integrand.
@@ -140,6 +130,17 @@ pure function description(self, prefix) result(desc)
140130
desc = prefix//'oscillation'
141131
endfunction description
142132

133+
pure function exact_solution(self, t, U0) result(exact)
134+
!< Return exact solution.
135+
class(integrand_oscillation), intent(in) :: self !< Integrand.
136+
real(R_P), intent(in) :: t !< Time.
137+
class(integrand_object), intent(in), optional :: U0 !< Initial conditions.
138+
real(R_P), allocatable :: exact(:) !< Exact solution.
139+
140+
exact = [self%U0(1) * cos(self%f * t) - self%U0(2) * sin(self%f * t), &
141+
self%U0(1) * sin(self%f * t) + self%U0(2) * cos(self%f * t)]
142+
endfunction exact_solution
143+
143144
subroutine export_tecplot(self, file_name, t, scheme, close_file)
144145
!< Export integrand to Tecplot file.
145146
class(integrand_oscillation), intent(in) :: self !< Advection field.

src/tests/tester/foodie_test_integrand_tester_object.f90

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module foodie_test_integrand_tester_object
1717
!< This abstract provided some auxiliary methods useful for the tester machinery.
1818
contains
1919
procedure(description_interface), pass(self), deferred :: description !< Return an informative description of the test.
20+
procedure(exact_solution_interface), pass(self), deferred :: exact_solution !< Return exact solution.
2021
procedure(export_tecplot_interface), pass(self), deferred :: export_tecplot !< Export integrand to Tecplot file.
2122
procedure(parse_cli_interface), pass(self), deferred :: parse_cli !< Initialize from command line interface.
2223
procedure(set_cli_interface), nopass, deferred :: set_cli !< Set command line interface.
@@ -32,6 +33,15 @@ pure function description_interface(self, prefix) result(desc)
3233
character(len=:), allocatable :: desc !< Description.
3334
endfunction description_interface
3435

36+
pure function exact_solution_interface(self, t, U0) result(exact)
37+
!< Return exact solution.
38+
import :: integrand_object, integrand_tester_object, R_P
39+
class(integrand_tester_object), intent(in) :: self !< Integrand.
40+
real(R_P), intent(in) :: t !< Time.
41+
class(integrand_object), intent(in), optional :: U0 !< Initial conditions.
42+
real(R_P), allocatable :: exact(:) !< Exact solution.
43+
endfunction exact_solution_interface
44+
3545
subroutine export_tecplot_interface(self, file_name, t, scheme, close_file)
3646
!< Export integrand to Tecplot file.
3747
import :: integrand_tester_object, R_P

src/tests/tester/foodie_tester.f90

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ module foodie_test_object
5555
logical :: save_results !< Flag for activating results saving.
5656
character(99) :: output !< Output files basename.
5757
integer(I_P) :: save_frequency !< Save frequency.
58-
logical :: verbose !< Flag for activating verbose output.
5958
type(integrand_ladvection) :: ladvection_0 !< Initial conditions for linear advection test.
6059
type(integrand_oscillation) :: oscillation_0 !< Initial conditions for oscillation test.
6160
class(integrand_tester_object), allocatable :: integrand_0 !< Initial conditions.
@@ -72,6 +71,8 @@ subroutine execute(self)
7271
!< Execute test(s).
7372
class(test_object), intent(inout) :: self !< Test.
7473
character(99), allocatable :: integrator_schemes(:) !< Name of FOODIE integrator schemes.
74+
real(R_P), allocatable :: error(:,:) !< Error of integrand integration.
75+
real(R_P), allocatable :: order(:,:) !< Observed order of accuravy.
7576
integer(I_P) :: s !< Counter.
7677
integer(I_P) :: t !< Counter.
7778

@@ -85,7 +86,10 @@ subroutine execute(self)
8586
else
8687
integrator_schemes = foodie_integrator_schemes()
8788
endif
89+
allocate(error(1:self%integrand_0%integrand_dimension(), 1:size(self%Dt, dim=1)))
90+
if (size(self%Dt, dim=1) > 1) allocate(order(1:self%integrand_0%integrand_dimension(), 1:size(error, dim=2)-1))
8891
do s=1, size(integrator_schemes, dim=1)
92+
print '(A)', trim(integrator_schemes(s))
8993
do t=1, size(self%Dt)
9094
call integrate(scheme=trim(integrator_schemes(s)), &
9195
integrand_0=self%integrand_0, &
@@ -96,7 +100,13 @@ subroutine execute(self)
96100
is_fast=self%is_fast, &
97101
save_results=self%save_results, &
98102
output_base_name=trim(adjustl(self%output)), &
99-
save_frequency=self%save_frequency)
103+
save_frequency=self%save_frequency, &
104+
error=error(:,t))
105+
print*, 'Dt = ', self%Dt(t), ', error = ', error(:,t)
106+
if (t > 1) then
107+
order(:, t-1) = observed_order(error=error(:, t-1:t), Dt=self%Dt(t-1:t))
108+
print '(A,'//trim(str(size(order, dim=1), no_sign=.true.))//'F6.2)', ' Observed order =', order(:,t-1)
109+
endif
100110
enddo
101111
enddo
102112
endsubroutine execute
@@ -130,7 +140,6 @@ subroutine set_cli()
130140
call cli%add(switch='--save_results', switch_ab='-r',help='save result', required=.false., act='store_true', def='.false.')
131141
call cli%add(switch='--output', help='output file basename', required=.false., act='store', def='foodie_test')
132142
call cli%add(switch='--save_frequency', help='save frequency', required=.false., act='store', def='1')
133-
call cli%add(switch='--verbose', help='Verbose output', required=.false., act='store_true', def='.false.')
134143
endassociate
135144
call self%ladvection_0%set_cli(cli=self%cli)
136145
call self%oscillation_0%set_cli(cli=self%cli)
@@ -154,7 +163,6 @@ subroutine parse_cli()
154163
call self%cli%get(switch='-r', val=self%save_results, error=self%error) ; if (self%error/=0) stop
155164
call self%cli%get(switch='--output', val=self%output, error=self%error) ; if (self%error/=0) stop
156165
call self%cli%get(switch='--save_frequency', val=self%save_frequency, error=self%error) ; if (self%error/=0) stop
157-
call self%cli%get(switch='--verbose', val=self%verbose, error=self%error) ; if (self%error/=0) stop
158166
call self%ladvection_0%parse_cli(cli=self%cli)
159167
call self%oscillation_0%parse_cli(cli=self%cli)
160168

@@ -228,23 +236,24 @@ subroutine check_scheme_has_fast_mode(scheme, integrator)
228236
endsubroutine check_scheme_has_fast_mode
229237

230238
subroutine integrate(scheme, integrand_0, Dt, final_time, iterations, stages, is_fast, save_results, output_base_name, &
231-
save_frequency)
239+
save_frequency, error)
232240
!< Integrate integrand by means of the given scheme.
233-
character(*), intent(in) :: scheme !< Selected scheme.
234-
class(integrand_tester_object), intent(in) :: integrand_0 !< Initial conditions.
235-
real(R_P), intent(in) :: Dt !< Time step.
236-
real(R_P), intent(in) :: final_time !< Final integration time.
237-
integer(I_P), intent(in) :: iterations !< Number of fixed point iterations.
238-
integer(I_P), intent(in) :: stages !< Number of stages.
239-
logical, intent(in) :: is_fast !< Activate fast mode integration.
240-
logical, intent(in) :: save_results !< Save results.
241-
character(*), intent(in) :: output_base_name !< Base name of output results file.
242-
integer(I_P), intent(in) :: save_frequency !< Save frequency.
243-
class(integrator_object), allocatable :: integrator !< The integrator.
244-
type(integrator_runge_kutta_ssp) :: integrator_start !< The (auto) start integrator.
245-
class(integrand_tester_object), allocatable :: integrand !< Integrand.
246-
real(R_P) :: time !< Time.
247-
integer(I_P) :: step !< Time steps counter.
241+
character(*), intent(in) :: scheme !< Selected scheme.
242+
class(integrand_tester_object), intent(in) :: integrand_0 !< Initial conditions.
243+
real(R_P), intent(in) :: Dt !< Time step.
244+
real(R_P), intent(in) :: final_time !< Final integration time.
245+
integer(I_P), intent(in) :: iterations !< Number of fixed point iterations.
246+
integer(I_P), intent(in) :: stages !< Number of stages.
247+
logical, intent(in) :: is_fast !< Activate fast mode integration.
248+
logical, intent(in) :: save_results !< Save results.
249+
character(*), intent(in) :: output_base_name !< Base name of output results file.
250+
integer(I_P), intent(in) :: save_frequency !< Save frequency.
251+
real(R_P), intent(out) :: error(:) !< Error of integrand integration.
252+
class(integrand_tester_object) , allocatable :: integrand !< Integrand.
253+
class(integrator_object), allocatable :: integrator !< The integrator.
254+
type(integrator_runge_kutta_ssp) :: integrator_start !< The (auto) start integrator.
255+
real(R_P) :: time !< Time.
256+
integer(I_P) :: step !< Time steps counter.
248257

249258
allocate(integrand, mold=integrand_0) ; integrand = integrand_0
250259

@@ -319,14 +328,32 @@ subroutine integrate(scheme, integrand_0, Dt, final_time, iterations, stages, is
319328
enddo
320329
endselect
321330

322-
select type(integrand)
323-
type is(integrand_ladvection)
324-
if (save_results .and. mod(step, save_frequency)==0) call integrand%export_tecplot(t=time, scheme=scheme)
325-
type is(integrand_oscillation)
326-
if (save_results .and. mod(step, save_frequency)==0) call integrand%export_tecplot(t=time)
327-
endselect
328-
if (save_results) call integrand%export_tecplot(close_file=.true.)
331+
call integrand_close_tecplot
332+
333+
call integrand_compute_error
329334
contains
335+
subroutine integrand_close_tecplot
336+
!< Close current integrand tecplot file.
337+
338+
select type(integrand)
339+
type is(integrand_ladvection)
340+
if (save_results .and. mod(step, save_frequency)==0) call integrand%export_tecplot(t=time, scheme=scheme)
341+
type is(integrand_oscillation)
342+
if (save_results .and. mod(step, save_frequency)==0) call integrand%export_tecplot(t=time)
343+
endselect
344+
if (save_results) call integrand%export_tecplot(close_file=.true.)
345+
endsubroutine integrand_close_tecplot
346+
347+
subroutine integrand_compute_error
348+
!< Close current integrand tecplot file.
349+
350+
select type(integrand)
351+
type is(integrand_ladvection)
352+
type is(integrand_oscillation)
353+
error = abs(integrand%output() - integrand%exact_solution(t=time))
354+
endselect
355+
endsubroutine integrand_compute_error
356+
330357
subroutine integrand_export_tecplot
331358
!< Export current integrand solution to tecplot file.
332359

@@ -338,6 +365,18 @@ subroutine integrand_export_tecplot
338365
endselect
339366
endsubroutine integrand_export_tecplot
340367
endsubroutine integrate
368+
369+
pure function observed_order(error, Dt)
370+
!< Estimate the order of accuracy using 2 subsequent refined numerical solutions.
371+
real(R_P), intent(in) :: error(1:, 1:) !< Computed errors.
372+
real(R_P), intent(in) :: Dt(1:) !< Time steps used.
373+
real(R_P) :: observed_order(1:size(error, dim=1)) !< Estimation of the order of accuracy.
374+
integer(I_P) :: v !< Variables counter.
375+
376+
do v=1, size(error, dim=1)
377+
observed_order(v) = log(error(v, 1) / error(v, 2)) / log(Dt(1) / Dt(2))
378+
enddo
379+
endfunction observed_order
341380
endmodule foodie_test_object
342381

343382
program foodie_tester

0 commit comments

Comments
 (0)