Skip to content

Commit 014c135

Browse files
committed
improve tester
1 parent abd37b7 commit 014c135

File tree

4 files changed

+116
-50
lines changed

4 files changed

+116
-50
lines changed

src/tests/tester/foodie_test_integrand_ladvection.f90

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,19 @@ module foodie_test_integrand_ladvection
5555
real(R_P) :: a=0._R_P !< Advection coefficient.
5656
real(R_P), allocatable :: u(:) !< Integrand (state) variable.
5757
class(interpolator_object), allocatable :: interpolator !< WENO interpolator.
58+
character(99) :: initial_state !< Initial state.
5859
contains
5960
! auxiliary methods
6061
procedure, pass(self), public :: destroy !< Destroy field.
61-
procedure, pass(self), public :: dt => compute_dt !< Compute the current time step, by means of CFL condition.
62+
procedure, pass(self), public :: dt => compute_dt !< Compute the current time step by means of CFL condition.
63+
procedure, pass(self), public :: compute_dx !< Compute the space step by means of CFL condition.
6264
procedure, pass(self), public :: output !< Extract integrand state field.
6365
! integrand_tester_object deferred methods
6466
procedure, pass(self), public :: description !< Return an informative description of the test.
67+
procedure, pass(self), public :: error !< Return error.
6568
procedure, pass(self), public :: exact_solution !< Return exact solution.
6669
procedure, pass(self), public :: export_tecplot !< Export integrand to Tecplot file.
70+
procedure, pass(self), public :: initialize !< Initialize integrand.
6771
procedure, pass(self), public :: parse_cli !< Initialize from command line interface.
6872
procedure, nopass, public :: set_cli !< Set command line interface.
6973
! integrand_object deferred methods
@@ -117,14 +121,25 @@ pure function compute_dt(self, final_time, t) result(Dt)
117121
real(R_P), intent(in), optional :: t !< Time.
118122
real(R_P) :: Dt !< Time step.
119123

120-
associate(a=>self%a, Ni=>self%Ni, Dx=>self%Dx, CFL=>self%CFL)
124+
associate(a=>self%a, Dx=>self%Dx, CFL=>self%CFL)
121125
Dt = Dx * CFL / abs(a)
122126
if (present(t)) then
123127
if ((t + Dt) > final_time) Dt = final_time - t
124128
endif
125129
endassociate
126130
endfunction compute_dt
127131

132+
pure function compute_dx(self, Dt) result(Dx)
133+
!< Compute the space step step by means of CFL condition.
134+
class(integrand_ladvection), intent(in) :: self !< Advection field.
135+
real(R_P), intent(in) :: Dt !< Time step.
136+
real(R_P) :: Dx !< Space step.
137+
138+
associate(a=>self%a, CFL=>self%CFL)
139+
Dx = Dt / CFL * abs(a)
140+
endassociate
141+
endfunction compute_dx
142+
128143
pure function output(self) result(state)
129144
!< Output the advection field state.
130145
class(integrand_ladvection), intent(in) :: self !< Advection field.
@@ -145,6 +160,28 @@ pure function description(self, prefix) result(desc)
145160
desc = prefix//'linear_advection-Ni_'//trim(strz(self%Ni, 10))
146161
endfunction description
147162

163+
pure function error(self, t, U0)
164+
!< Return error.
165+
class(integrand_ladvection), intent(in) :: self !< Integrand.
166+
real(R_P), intent(in) :: t !< Time.
167+
class(integrand_object), intent(in), optional :: U0 !< Initial conditions.
168+
real(R_P), allocatable :: error(:) !< Error.
169+
integer(I_P) :: i !< Counter.
170+
171+
allocate(error(1:1))
172+
error = 0._R_P
173+
if (present(U0)) then
174+
select type(U0)
175+
type is(integrand_ladvection)
176+
do i=1, self%Ni
177+
! error = error + (U0%u(i) - self%u(i)) ** 2
178+
error = max(error, abs(U0%u(i) - self%u(i)))
179+
enddo
180+
endselect
181+
! error = sqrt(error)
182+
endif
183+
endfunction error
184+
148185
pure function exact_solution(self, t, U0) result(exact)
149186
!< Return exact solution.
150187
class(integrand_ladvection), intent(in) :: self !< Integrand.
@@ -194,11 +231,24 @@ subroutine export_tecplot(self, file_name, t, scheme, close_file)
194231
endif
195232
endsubroutine export_tecplot
196233

234+
subroutine initialize(self, Dt)
235+
!< Initialize integrand.
236+
class(integrand_ladvection), intent(inout) :: self !< Integrand.
237+
real(R_P), intent(in) :: Dt !< Time step.
238+
239+
self%Dx = self%compute_dx(Dt=Dt)
240+
self%Ni = nint(self%length / self%Dx)
241+
242+
select case(trim(adjustl(self%initial_state)))
243+
case('square_wave')
244+
call self%set_square_wave_initial_state
245+
endselect
246+
endsubroutine initialize
247+
197248
subroutine parse_cli(self, cli)
198249
!< Initialize from command line interface.
199-
class(integrand_ladvection), intent(inout) :: self !< Advection field.
200-
type(command_line_interface), intent(inout) :: cli !< Command line interface handler.
201-
character(99) :: initial_state !< Initial state.
250+
class(integrand_ladvection), intent(inout) :: self !< Advection field.
251+
type(command_line_interface), intent(inout) :: cli !< Command line interface handler.
202252

203253
call self%destroy
204254

@@ -209,16 +259,11 @@ subroutine parse_cli(self, cli)
209259
call cli%get(switch='-a', val=self%a, error=cli%error) ; if (cli%error/=0) stop
210260
call cli%get(switch='--length', val=self%length, error=cli%error) ; if (cli%error/=0) stop
211261
call cli%get(switch='--Ni', val=self%Ni, error=cli%error) ; if (cli%error/=0) stop
212-
call cli%get(switch='-is', val=initial_state, error=cli%error) ; if (cli%error/=0) stop
262+
call cli%get(switch='-is', val=self%initial_state, error=cli%error) ; if (cli%error/=0) stop
213263

214264
self%Ng = (self%weno_order + 1) / 2
215265
self%Dx = self%length / self%Ni
216266

217-
select case(trim(adjustl(initial_state)))
218-
case('square_wave')
219-
call self%set_square_wave_initial_state
220-
endselect
221-
222267
if (self%weno_order>1) call wenoof_create(interpolator_type=trim(adjustl(self%w_scheme)), &
223268
S=self%Ng, &
224269
interpolator=self%interpolator, &
@@ -433,6 +478,7 @@ pure subroutine assign_integrand(lhs, rhs)
433478
lhs%CFL = rhs%CFL
434479
lhs%Ni = rhs%Ni
435480
lhs%Ng = rhs%Ng
481+
lhs%length = rhs%length
436482
lhs%Dx = rhs%Dx
437483
lhs%a = rhs%a
438484
if (allocated(rhs%u)) then
@@ -447,6 +493,7 @@ pure subroutine assign_integrand(lhs, rhs)
447493
else
448494
if (allocated(lhs%interpolator)) deallocate(lhs%interpolator)
449495
endif
496+
lhs%initial_state = rhs%initial_state
450497
endselect
451498
endsubroutine assign_integrand
452499

src/tests/tester/foodie_test_integrand_oscillation.f90

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,13 @@ 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 :: initialize !< Initialize integrand.
5453
procedure, pass(self), public :: output !< Extract integrand state field.
5554
! integrand_tester_object deferred methods
5655
procedure, pass(self), public :: description !< Return an informative description of the test.
56+
procedure, pass(self), public :: error !< Return error.
5757
procedure, pass(self), public :: exact_solution !< Return exact solution.
5858
procedure, pass(self), public :: export_tecplot !< Export integrand to Tecplot file.
59+
procedure, pass(self), public :: initialize !< Initialize field.
5960
procedure, pass(self), public :: parse_cli !< Initialize from command line interface.
6061
procedure, nopass, public :: set_cli !< Set command line interface.
6162
! integrand_object deferred methods
@@ -99,17 +100,6 @@ function amplitude_phase(self) result(ap)
99100
ap(2) = atan(-self%U(1) / self%U(2))
100101
endfunction amplitude_phase
101102

102-
pure subroutine initialize(self, U0, frequency)
103-
!< Initialize integrand.
104-
class(integrand_oscillation), intent(inout) :: self !< Integrand.
105-
real(R_P), intent(in) :: U0(1:2) !< Initial state.
106-
real(R_P), intent(in) :: frequency !< Frequency of oscillation.
107-
108-
self%U = U0
109-
self%f = frequency
110-
self%U0 = U0
111-
endsubroutine initialize
112-
113103
pure function output(self) result(state)
114104
!< Extract integrand state field.
115105
class(integrand_oscillation), intent(in) :: self !< Integrand.
@@ -130,6 +120,17 @@ pure function description(self, prefix) result(desc)
130120
desc = prefix//'oscillation'
131121
endfunction description
132122

123+
pure function error(self, t, U0)
124+
!< Return error.
125+
class(integrand_oscillation), intent(in) :: self !< Integrand.
126+
real(R_P), intent(in) :: t !< Time.
127+
class(integrand_object), intent(in), optional :: U0 !< Initial conditions.
128+
real(R_P), allocatable :: error(:) !< Error.
129+
130+
allocate(error(1:2))
131+
error = abs(self%U - self%exact_solution(t=t))
132+
endfunction error
133+
133134
pure function exact_solution(self, t, U0) result(exact)
134135
!< Return exact solution.
135136
class(integrand_oscillation), intent(in) :: self !< Integrand.
@@ -173,6 +174,14 @@ subroutine export_tecplot(self, file_name, t, scheme, close_file)
173174
endif
174175
endsubroutine export_tecplot
175176

177+
pure subroutine initialize(self, Dt)
178+
!< Initialize integrand.
179+
!<
180+
!< Intentionally empty, all is done in `parse_cli` method.
181+
class(integrand_oscillation), intent(inout) :: self !< Integrand.
182+
real(R_P), intent(in) :: Dt !< Time step.
183+
endsubroutine initialize
184+
176185
subroutine parse_cli(self, cli)
177186
!< Initialize from command line interface.
178187
class(integrand_oscillation), intent(inout) :: self !< Advection field.

src/tests/tester/foodie_test_integrand_tester_object.f90

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ 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(error_interface), pass(self), deferred :: error !< Return error.
2021
procedure(exact_solution_interface), pass(self), deferred :: exact_solution !< Return exact solution.
2122
procedure(export_tecplot_interface), pass(self), deferred :: export_tecplot !< Export integrand to Tecplot file.
23+
procedure(initialize_interface), pass(self), deferred :: initialize !< Initialize integrand.
2224
procedure(parse_cli_interface), pass(self), deferred :: parse_cli !< Initialize from command line interface.
2325
procedure(set_cli_interface), nopass, deferred :: set_cli !< Set command line interface.
2426
endtype integrand_tester_object
@@ -33,6 +35,15 @@ pure function description_interface(self, prefix) result(desc)
3335
character(len=:), allocatable :: desc !< Description.
3436
endfunction description_interface
3537

38+
pure function error_interface(self, t, U0) result(error)
39+
!< Return error.
40+
import :: integrand_object, integrand_tester_object, R_P
41+
class(integrand_tester_object), intent(in) :: self !< Integrand.
42+
real(R_P), intent(in) :: t !< Time.
43+
class(integrand_object), intent(in), optional :: U0 !< Initial conditions.
44+
real(R_P), allocatable :: error(:) !< Error.
45+
endfunction error_interface
46+
3647
pure function exact_solution_interface(self, t, U0) result(exact)
3748
!< Return exact solution.
3849
import :: integrand_object, integrand_tester_object, R_P
@@ -45,17 +56,24 @@ pure function exact_solution_interface(self, t, U0) result(exact)
4556
subroutine export_tecplot_interface(self, file_name, t, scheme, close_file)
4657
!< Export integrand to Tecplot file.
4758
import :: integrand_tester_object, R_P
48-
class(integrand_tester_object), intent(in) :: self !< Advection field.
59+
class(integrand_tester_object), intent(in) :: self !< Integrand.
4960
character(*), intent(in), optional :: file_name !< File name.
5061
real(R_P), intent(in), optional :: t !< Time.
5162
character(*), intent(in), optional :: scheme !< Scheme used to integrate integrand.
5263
logical, intent(in), optional :: close_file !< Flag for closing file.
5364
endsubroutine export_tecplot_interface
5465

66+
subroutine initialize_interface(self, Dt)
67+
!< Initialize integrand.
68+
import :: integrand_tester_object, R_P
69+
class(integrand_tester_object), intent(inout) :: self !< Integrand.
70+
real(R_P), intent(in) :: Dt !< Time step.
71+
endsubroutine initialize_interface
72+
5573
subroutine parse_cli_interface(self, cli)
5674
!< Initialize from command line interface.
5775
import :: command_line_interface, integrand_tester_object
58-
class(integrand_tester_object), intent(inout) :: self !< Advection field.
76+
class(integrand_tester_object), intent(inout) :: self !< Integrand.
5977
type(command_line_interface), intent(inout) :: cli !< Command line interface handler.
6078
endsubroutine parse_cli_interface
6179

src/tests/tester/foodie_tester.f90

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,12 @@ subroutine execute(self)
8686
else
8787
integrator_schemes = foodie_integrator_schemes()
8888
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))
89+
allocate(error(1:size(self%integrand_0%error(t=0._R_P), dim=1), 1:size(self%Dt, dim=1)))
90+
if (size(self%Dt, dim=1) > 1) allocate(order(1:size(error, dim=1), 1:size(error, dim=2)-1))
9191
do s=1, size(integrator_schemes, dim=1)
9292
print '(A)', trim(integrator_schemes(s))
9393
do t=1, size(self%Dt)
94+
call self%integrand_0%initialize(Dt=self%Dt(t))
9495
call integrate(scheme=trim(integrator_schemes(s)), &
9596
integrand_0=self%integrand_0, &
9697
Dt=self%Dt(t), &
@@ -102,10 +103,10 @@ subroutine execute(self)
102103
output_base_name=trim(adjustl(self%output)), &
103104
save_frequency=self%save_frequency, &
104105
error=error(:,t))
105-
print*, 'Dt = ', self%Dt(t), ', error (max) = ', maxval(error(:,t))
106+
print*, 'Dt = ', self%Dt(t), ', error = ', error(:,t)
106107
if (t > 1) then
107108
order(:, t-1) = observed_order(error=error(:, t-1:t), Dt=self%Dt(t-1:t))
108-
print '(A,F6.2)', ' Observed order (min) =', minval(order(:,t-1))
109+
print '(A,'//trim(str(size(order, dim=1), no_sign=.true.))//'F6.2)', ' Observed order =', order(:,t-1)
109110
endif
110111
enddo
111112
enddo
@@ -209,15 +210,15 @@ function is_dt_valid()
209210
is_dt_valid = .true.
210211
do t=1, size(self%Dt)
211212
is_dt_valid = ((self%final_time - int(self%final_time/self%Dt(t), I_P)*self%Dt(t))==0)
212-
if (is_dt_valid) then
213-
select type(integrand=>self%integrand_0)
214-
type is(integrand_ladvection)
215-
is_dt_valid = is_dt_valid .and. self%Dt(t) <= integrand%Dt(final_time=self%final_time)
216-
if (.not.is_dt_valid) then
217-
write(stderr, '(A)') 'error: Dt violates CFL condition, Dt_max = '//str(integrand%Dt(final_time=self%final_time))
218-
endif
219-
endselect
220-
endif
213+
! if (is_dt_valid) then
214+
! select type(integrand=>self%integrand_0)
215+
! type is(integrand_ladvection)
216+
! is_dt_valid = is_dt_valid .and. self%Dt(t) <= integrand%Dt(final_time=self%final_time)
217+
! if (.not.is_dt_valid) then
218+
! write(stderr, '(A)') 'error: Dt violates CFL condition, Dt_max = '//str(integrand%Dt(final_time=self%final_time))
219+
! endif
220+
! endselect
221+
! endif
221222
if (.not.is_dt_valid) exit
222223
enddo
223224
endfunction is_dt_valid
@@ -249,6 +250,7 @@ subroutine integrate(scheme, integrand_0, Dt, final_time, iterations, stages, is
249250
character(*), intent(in) :: output_base_name !< Base name of output results file.
250251
integer(I_P), intent(in) :: save_frequency !< Save frequency.
251252
real(R_P), intent(out) :: error(:) !< Error of integrand integration.
253+
real(R_P), allocatable :: error_(:) !< Error of integrand integration.
252254
class(integrand_tester_object) , allocatable :: integrand !< Integrand.
253255
class(integrator_object), allocatable :: integrator !< The integrator.
254256
type(integrator_runge_kutta_ssp) :: integrator_start !< The (auto) start integrator.
@@ -330,7 +332,8 @@ subroutine integrate(scheme, integrand_0, Dt, final_time, iterations, stages, is
330332

331333
call integrand_close_tecplot
332334

333-
call integrand_compute_error
335+
error_ = integrand%error(t=time, U0=integrand_0)
336+
error(:) = error_(:)
334337
contains
335338
subroutine integrand_close_tecplot
336339
!< Close current integrand tecplot file.
@@ -344,17 +347,6 @@ subroutine integrand_close_tecplot
344347
if (save_results) call integrand%export_tecplot(close_file=.true.)
345348
endsubroutine integrand_close_tecplot
346349

347-
subroutine integrand_compute_error
348-
!< Close current integrand tecplot file.
349-
350-
select type(integrand)
351-
type is(integrand_ladvection)
352-
error = abs(integrand%output() - integrand%exact_solution(t=time))
353-
type is(integrand_oscillation)
354-
error = abs(integrand%output() - integrand%exact_solution(t=time))
355-
endselect
356-
endsubroutine integrand_compute_error
357-
358350
subroutine integrand_export_tecplot
359351
!< Export current integrand solution to tecplot file.
360352

0 commit comments

Comments
 (0)