@@ -48,7 +48,7 @@ subroutine jacobian_sub(n,y,df)
4848 subroutine output_sub (nr ,xold ,x ,y ,iha ,qa ,irtrn )
4949 import wp
5050 integer , intent (in ) :: nr
51- ! ! Number of successful steps that have been taken
51+ ! ! Number of the current grid point, starting at 1 for the initial value
5252 real (wp), intent (in ) :: xold
5353 ! ! Previous value of the independent variable
5454 real (wp), intent (in ) :: x
@@ -105,8 +105,8 @@ subroutine stiff3_auto(n,fun,x,y,xend,jac,h0,eps,w,solout,stats,hmax)
105105 ! ! dependent variables at `xend`.
106106 procedure (output_sub), optional :: solout
107107 ! ! User supplied subprogram for output.
108- integer , intent (out ), optional :: stats(3 )
109- ! ! Statistics array with `[nfev, njev, nlu]`.
108+ integer , intent (out ), optional :: stats(6 )
109+ ! ! Statistics array with `[nacc, nrej, nfev, njev, nlu, nsol ]`.
110110 real (wp), intent (in ), optional :: hmax
111111 ! ! Maximum absolute half-step size. If absent or zero, defaults to
112112 ! ! `abs(xend - x)`.
@@ -153,8 +153,8 @@ subroutine stiff3_work(n,fun,x,y,xend,jac,h0,eps,w,rwork,iwork,solout,stats,hmax
153153 ! ! Integer workspace of size `n`.
154154 procedure (output_sub), optional :: solout
155155 ! ! User supplied subprogram for output.
156- integer , intent (out ), optional :: stats(3 )
157- ! ! Statistics array with `[nfev, njev, nlu]`.
156+ integer , intent (out ), optional :: stats(6 )
157+ ! ! Statistics array with `[nacc, nrej, nfev, njev, nlu, nsol ]`.
158158 real (wp), intent (in ), optional :: hmax
159159 ! ! Maximum absolute half-step size. If absent or zero, defaults to
160160 ! ! `abs(xend - x)`.
@@ -191,18 +191,17 @@ subroutine stiff3_core(n,fun,x,y,xend,jac,h0,eps,w, &
191191 real (wp), intent (inout ) :: df(n,n), dfold(n,n)
192192 integer , intent (inout ) :: ip(n)
193193 procedure (output_sub), optional :: solout
194- integer , intent (out ), optional :: stats(3 )
194+ integer , intent (out ), optional :: stats(6 )
195195 real (wp), intent (in ), optional :: hmax
196196
197- integer :: icon, iha, i, j, nr, irtrn
198- integer :: nfev, njev, nlu
197+ integer :: icon, iha, i, j, irtrn
198+ integer :: nfev, njev, nlu, nacc, nrej, nsol
199199 real (wp) :: x_current, xold, h, e, es, q, qa, hmax_used
200200 logical :: have_f
201201
202202 ! icon = 0 except for last step which ends exactly at x1
203203 icon = 0
204204
205- nr = 0
206205 x_current = x
207206 if (present (hmax)) then
208207 if (hmax < 0.0_wp ) error stop ' stiff3: hmax must be a non-negative real value'
@@ -218,8 +217,21 @@ subroutine stiff3_core(n,fun,x,y,xend,jac,h0,eps,w, &
218217 nfev = 0
219218 njev = 0
220219 nlu = 0
220+ nacc = 0
221+ nrej = 0
222+ nsol = 0
221223 have_f = .false.
222224
225+ if (present (solout)) then
226+ irtrn = 0
227+ call solout(1 ,x_current,x_current,y,0 ,0.0_wp ,irtrn)
228+ if (irtrn < 0 ) then
229+ h0 = h
230+ if (present (stats)) stats = [nacc, nrej, nfev, njev, nlu, nsol]
231+ return
232+ end if
233+ end if
234+
223235 outer: do
224236
225237 ! last step - or first step longer than interval
@@ -259,7 +271,7 @@ subroutine stiff3_core(n,fun,x,y,xend,jac,h0,eps,w, &
259271
260272 ! perform full integration step
261273
262- call sirk3(n,fun,ip,f,y,yk1,yk2,df,2 * h,nfev,nlu)
274+ call sirk3(n,fun,ip,f,y,yk1,yk2,df,2 * h,nfev,nlu,nsol )
263275
264276 do i = 1 , n
265277 ya(i) = y(i)
@@ -277,15 +289,15 @@ subroutine stiff3_core(n,fun,x,y,xend,jac,h0,eps,w, &
277289 inner: do
278290 iha = iha + 1
279291
280- call sirk3(n,fun,ip,f,y,yk1,yk2,df,h,nfev,nlu)
292+ call sirk3(n,fun,ip,f,y,yk1,yk2,df,h,nfev,nlu,nsol )
281293 call fun(n,y,f)
282294 nfev = nfev + 1
283295 call jac(n,y,df)
284296 njev = njev + 1
285297
286298 yold1 = y
287299
288- call sirk3(n,fun,ip,f,y,yk1,yk2,df,h,nfev,nlu)
300+ call sirk3(n,fun,ip,f,y,yk1,yk2,df,h,nfev,nlu,nsol )
289301
290302 ! half step integration finished
291303 ! compute deviation and compare with tolerance
@@ -314,6 +326,7 @@ subroutine stiff3_core(n,fun,x,y,xend,jac,h0,eps,w, &
314326
315327 h = h/ 2.0_wp
316328 icon = 0
329+ nrej = nrej + 1
317330
318331 end do inner
319332
@@ -338,13 +351,13 @@ subroutine stiff3_core(n,fun,x,y,xend,jac,h0,eps,w, &
338351
339352 ! perform output if appropriate
340353
341- nr = nr + 1
354+ nacc = nacc + 1
342355 if (present (solout)) then
343356 irtrn = 0
344- call solout(nr ,xold,x_current,y,iha,qa,irtrn)
357+ call solout(nacc +1 ,xold,x_current,y,iha,qa,irtrn)
345358 if (irtrn < 0 ) then
346359 h0 = h
347- if (present (stats)) stats = [nfev, njev, nlu]
360+ if (present (stats)) stats = [nacc, nrej, nfev, njev, nlu, nsol ]
348361 return
349362 end if
350363 end if
@@ -353,7 +366,7 @@ subroutine stiff3_core(n,fun,x,y,xend,jac,h0,eps,w, &
353366
354367 if (icon == 1 ) then
355368 h0 = h
356- if (present (stats)) stats = [nfev, njev, nlu]
369+ if (present (stats)) stats = [nacc, nrej, nfev, njev, nlu, nsol ]
357370 return
358371 end if
359372
@@ -441,7 +454,7 @@ subroutine stiff3_interp_vector(xold,x,y,rwork,xeval,yeval)
441454
442455 ! > Single-step semi-implicit integration
443456 !
444- subroutine sirk3 (n ,fun ,ipiv ,f ,y ,yk1 ,yk2 ,df ,h ,nfev ,nlu )
457+ subroutine sirk3 (n ,fun ,ipiv ,f ,y ,yk1 ,yk2 ,df ,h ,nfev ,nlu , nsol )
445458 integer , intent (in ) :: n
446459 ! ! Size of the system of ODEs
447460 procedure (rhs_sub) :: fun
@@ -464,6 +477,8 @@ subroutine sirk3(n,fun,ipiv,f,y,yk1,yk2,df,h,nfev,nlu)
464477 ! ! Number of right-hand side evaluations
465478 integer , intent (inout ) :: nlu
466479 ! ! Number of LU decompositions
480+ integer , intent (inout ) :: nsol
481+ ! ! Number of linear-system solves (back substitutions)
467482
468483 integer :: i
469484
@@ -487,6 +502,7 @@ subroutine sirk3(n,fun,ipiv,f,y,yk1,yk2,df,h,nfev,nlu)
487502 call lu(df,ipiv)
488503 nlu = nlu + 1
489504 call back(df,f,ipiv)
505+ nsol = nsol + 1
490506
491507 do i = 1 , n
492508 yk1(i) = h* f(i)
@@ -495,6 +511,7 @@ subroutine sirk3(n,fun,ipiv,f,y,yk1,yk2,df,h,nfev,nlu)
495511 call fun(n,yk2,f)
496512 nfev = nfev + 1
497513 call back(df,f,ipiv)
514+ nsol = nsol + 1
498515
499516 !
500517 ! evaluate k2
@@ -510,6 +527,7 @@ subroutine sirk3(n,fun,ipiv,f,y,yk1,yk2,df,h,nfev,nlu)
510527 ! for convenience stored in yk2
511528 !
512529 call back(df,yk2,ipiv)
530+ nsol = nsol + 1
513531 do i = 1 , n
514532 y(i) = y(i) + yk2(i)
515533 end do
0 commit comments