@@ -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 end subroutine 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 end subroutine 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+ end function observed_order
341380endmodule foodie_test_object
342381
343382program foodie_tester
0 commit comments