@@ -17,15 +17,19 @@ program oregonator
1717 1.0e-4_wp , 1.0e-5_wp , 1.0e-6_wp , 1.0e-7_wp , 1.0e-8_wp , 1.0e-9_wp ]
1818 character (len=* ), parameter :: csv_file = ' oregonator_work_precision.csv'
1919 character (len=* ), parameter :: svg_file = ' oregonator_work_precision.svg'
20+ character (len=* ), parameter :: solution_file = ' oregonator_solution.dat'
2021
2122 integer :: i
23+ integer :: solution_unit
2224 integer :: verification_stats(6 )
2325 integer :: stats(6 ,ncases)
24- real (wp) :: y(n), w(n), errors(ncases), work(ncases), verification_error
26+ real (wp) :: y(n), w(n), errors(ncases), cpu_times(ncases), verification_error, verification_cpu
27+ logical :: solution_output_enabled
2528
2629 w = 1.0_wp
30+ solution_output_enabled = .false.
2731
28- call integrate_case(1.0e-8_wp , y, verification_stats)
32+ call integrate_case(1.0e-8_wp , y, verification_stats, verification_cpu, solution_file )
2933 verification_error = max_relative_error(y, yref)
3034 if (verification_error > verification_tol) then
3135 print ' (A,ES12.4,A,ES12.4)' , &
@@ -36,38 +40,74 @@ program oregonator
3640
3741 print ' (A,ES12.4)' , ' verified reference solution with max relative error ' , verification_error
3842 print ' (A,3(1X,ES24.16))' , ' y(360) =' , y
43+ print ' (A,1X,ES12.4,1X,A)' , ' verification cpu time:' , verification_cpu, ' s'
3944 print ' (A,6(I0,1X))' , ' verification stats [nacc nrej nfev njev nlu nsol]: ' , verification_stats
4045
4146 do i = 1 , ncases
42- call integrate_case(eps_values(i), y, stats(:,i))
47+ call integrate_case(eps_values(i), y, stats(:,i), cpu_times(i) )
4348 errors(i) = max_relative_error(y, yref)
44- work(i) = real (stats(3 ,i), wp)
4549 end do
4650
47- call write_csv(csv_file, eps_values, errors, stats)
48- call write_svg(svg_file, eps_values, errors, work )
51+ call write_csv(csv_file, eps_values, errors, cpu_times, stats)
52+ call write_svg(svg_file, eps_values, errors, cpu_times )
4953
5054 print ' (A)' , ' work-precision data:'
51- print ' (A)' , ' eps error nfev njev nlu nsol'
55+ print ' (A)' , ' eps error cpu[s] nfev njev nlu nsol'
5256 do i = 1 , ncases
53- print ' (2 (1X,ES10.2),4(1X,I6))' , eps_values(i), errors(i), &
57+ print ' (3 (1X,ES10.2),4(1X,I6))' , eps_values(i), errors(i), cpu_times (i), &
5458 stats(3 ,i), stats(4 ,i), stats(5 ,i), stats(6 ,i)
5559 end do
5660 print ' (A,1X,A)' , ' wrote' , csv_file
5761 print ' (A,1X,A)' , ' wrote' , svg_file
62+ print ' (A,1X,A)' , ' wrote' , solution_file
5863
5964contains
6065
61- subroutine integrate_case (eps , y , stats )
66+ subroutine integrate_case (eps , y , stats , cpu_time_seconds , solution_filename )
6267 real (wp), intent (in ) :: eps
6368 real (wp), intent (out ) :: y(n)
6469 integer , intent (out ) :: stats(6 )
70+ real (wp), intent (out ) :: cpu_time_seconds
71+ character (len=* ), intent (in ), optional :: solution_filename
6572
66- real (wp) :: h0
73+ integer :: ios
74+ real (wp), parameter :: min_cpu_time = 1.0e-12_wp
75+ real (wp) :: cpu_start, cpu_end, h0
76+ logical :: write_solution
6777
6878 y = y0
6979 h0 = h0_initial
70- call stiff3(n, fun, x0, y, x1, jac, h0, eps, w, stats= stats)
80+ write_solution = present (solution_filename)
81+ if (write_solution) then
82+ open (newunit= solution_unit, file= solution_filename, status= ' replace' , action= ' write' , iostat= ios)
83+ if (ios /= 0 ) error stop ' failed to open solution output file'
84+ write (solution_unit,' (A)' ) ' # t y1 y2 y3'
85+ solution_output_enabled = .true.
86+ end if
87+
88+ call cpu_time(cpu_start)
89+ call stiff3(n, fun, x0, y, x1, jac, h0, eps, w, solout= output_solution, stats= stats)
90+ call cpu_time(cpu_end)
91+ cpu_time_seconds = max (min_cpu_time, cpu_end - cpu_start)
92+
93+ if (write_solution) then
94+ close (solution_unit)
95+ solution_output_enabled = .false.
96+ end if
97+ end subroutine
98+
99+ subroutine output_solution (nr , xold , x , y , iha , qa , irtrn )
100+ integer , intent (in ) :: nr
101+ real (wp), intent (in ) :: xold
102+ real (wp), intent (in ) :: x
103+ real (wp), intent (in ) :: y(:)
104+ integer , intent (in ) :: iha
105+ real (wp), intent (in ) :: qa
106+ integer , intent (inout ) :: irtrn
107+
108+ if (solution_output_enabled) then
109+ write (solution_unit,' (ES24.16,1X,*(ES24.16,1X))' ) x, y
110+ end if
71111 end subroutine
72112
73113 function max_relative_error (y , y_reference ) result(err)
@@ -77,28 +117,28 @@ function max_relative_error(y, y_reference) result(err)
77117 err = maxval (abs (y - y_reference)/ max (1.0_wp , abs (y_reference)))
78118 end function
79119
80- subroutine write_csv (filename , eps , err , stats )
120+ subroutine write_csv (filename , eps , err , cpu , stats )
81121 character (len=* ), intent (in ) :: filename
82- real (wp), intent (in ) :: eps(:), err (:)
122+ real (wp), intent (in ) :: eps(:), err (:), cpu(:)
83123 integer , intent (in ) :: stats(:,:)
84124
85125 integer :: i, ios, unit
86126
87127 open (newunit= unit, file= filename, status= ' replace' , action= ' write' , iostat= ios)
88128 if (ios /= 0 ) error stop ' failed to open CSV output file'
89129
90- write (unit,' (A)' ) ' eps,max_relative_error,nfev,njev,nlu,nsol,nacc,nrej'
130+ write (unit,' (A)' ) ' eps,max_relative_error,cpu_time_seconds, nfev,njev,nlu,nsol,nacc,nrej'
91131 do i = 1 , size (eps)
92- write (unit,' (ES24.16,'' ,'' ,ES24.16,'' ,'' ,I0,'' ,'' ,I0,'' ,'' ,I0,'' ,'' ,I0,'' ,'' ,I0,'' ,'' ,I0)' ) &
93- eps(i), err (i), stats(3 ,i), stats(4 ,i), stats(5 ,i), stats(6 ,i), stats(1 ,i), stats(2 ,i)
132+ write (unit,' (ES24.16,'' ,'' ,ES24.16,'' ,'' ,ES24.16, '' , '' , I0,'' ,'' ,I0,'' ,'' ,I0,'' ,'' ,I0,'' ,'' ,I0,'' ,'' ,I0)' ) &
133+ eps(i), err (i), cpu(i), stats(3 ,i), stats(4 ,i), stats(5 ,i), stats(6 ,i), stats(1 ,i), stats(2 ,i)
94134 end do
95135
96136 close (unit)
97137 end subroutine
98138
99- subroutine write_svg (filename , eps , err , work )
139+ subroutine write_svg (filename , eps , err , cpu )
100140 character (len=* ), intent (in ) :: filename
101- real (wp), intent (in ) :: eps(:), err (:), work (:)
141+ real (wp), intent (in ) :: eps(:), err (:), cpu (:)
102142
103143 integer , parameter :: width = 800
104144 integer , parameter :: height = 600
@@ -109,15 +149,15 @@ subroutine write_svg(filename, eps, err, work)
109149
110150 character (len= 32 ) :: label
111151 integer :: i, ios, unit
112- real (wp) :: log_work (size (work )), log_err(size (err))
152+ real (wp) :: log_cpu (size (cpu )), log_err(size (err))
113153 real (wp) :: xmin, xmax, ymin, ymax, xpad, ypad
114154 real (wp) :: x1p, x2p, y1p, y2p, xtick, ytick, tick_value
115155
116- log_work = log10 (max (work , tiny (1.0_wp )))
156+ log_cpu = log10 (max (cpu , tiny (1.0_wp )))
117157 log_err = log10 (max (err, tiny (1.0_wp )))
118158
119- xmin = minval (log_work )
120- xmax = maxval (log_work )
159+ xmin = minval (log_cpu )
160+ xmax = maxval (log_cpu )
121161 ymin = minval (log_err)
122162 ymax = maxval (log_err)
123163 xpad = 0.05_wp * max (xmax - xmin, 1.0_wp )
@@ -163,23 +203,23 @@ subroutine write_svg(filename, eps, err, work)
163203
164204 write (unit,' (A)' ) &
165205 ' <text x="435" y="585" font-family="sans-serif" font-size="16" ' // &
166- ' text-anchor="middle">rhs evaluations (nfev) </text>'
206+ ' text-anchor="middle">CPU time [s] </text>'
167207 write (unit,' (A)' ) &
168208 ' <text x="24" y="285" font-family="sans-serif" font-size="16" ' // &
169209 ' text-anchor="middle" transform="rotate(-90 24 285)">' // &
170210 ' max relative error</text>'
171211
172- do i = 1 , size (work ) - 1
173- x1p = xcoord(log_work (i), xmin, xmax, width, left, right)
212+ do i = 1 , size (cpu ) - 1
213+ x1p = xcoord(log_cpu (i), xmin, xmax, width, left, right)
174214 y1p = ycoord(log_err(i), ymin, ymax, height, top, bottom)
175- x2p = xcoord(log_work (i + 1 ), xmin, xmax, width, left, right)
215+ x2p = xcoord(log_cpu (i + 1 ), xmin, xmax, width, left, right)
176216 y2p = ycoord(log_err(i + 1 ), ymin, ymax, height, top, bottom)
177217 write (unit,' (A,F0.3,A,F0.3,A,F0.3,A,F0.3,A)' ) ' <line x1="' , x1p, ' " y1="' , y1p, &
178218 ' " x2="' , x2p, ' " y2="' , y2p, ' " stroke="#1f77b4" stroke-width="2"/>'
179219 end do
180220
181- do i = 1 , size (work )
182- x1p = xcoord(log_work (i), xmin, xmax, width, left, right)
221+ do i = 1 , size (cpu )
222+ x1p = xcoord(log_cpu (i), xmin, xmax, width, left, right)
183223 y1p = ycoord(log_err(i), ymin, ymax, height, top, bottom)
184224 write (label,' (ES9.1)' ) eps(i)
185225 write (unit,' (A,F0.3,A,F0.3,A)' ) ' <circle cx="' , x1p, ' " cy="' , y1p, ' " r="4.5" fill="#d62728"/>'
0 commit comments