@@ -389,7 +389,7 @@ end function root_name_to_method
389
389
390
390
subroutine root_scalar_by_name (method ,fun ,ax ,bx ,xzero ,fzero ,iflag ,&
391
391
ftol ,rtol ,atol ,maxiter ,fax ,fbx ,&
392
- bisect_on_failure )
392
+ bisect_on_failure , bisect_used )
393
393
394
394
implicit none
395
395
@@ -410,6 +410,7 @@ subroutine root_scalar_by_name(method,fun,ax,bx,xzero,fzero,iflag,&
410
410
! ! it will be retried using the bisection method.
411
411
! ! (default is False). Note that this can use up
412
412
! ! to `maxiter` additional function evaluations.
413
+ logical ,intent (out ),optional :: bisect_used ! ! if the bisection method was used after failure
413
414
414
415
type (root_method) :: r
415
416
@@ -418,7 +419,7 @@ subroutine root_scalar_by_name(method,fun,ax,bx,xzero,fzero,iflag,&
418
419
if (r% id /= 0 ) then
419
420
call root_scalar(r,fun,ax,bx,xzero,fzero,iflag,&
420
421
ftol,rtol,atol,maxiter,fax,fbx,&
421
- bisect_on_failure)
422
+ bisect_on_failure,bisect_used )
422
423
else
423
424
iflag = - 999 ! invalid method
424
425
return
@@ -433,7 +434,7 @@ end subroutine root_scalar_by_name
433
434
434
435
subroutine root_scalar_by_type (method ,fun ,ax ,bx ,xzero ,fzero ,iflag ,&
435
436
ftol ,rtol ,atol ,maxiter ,fax ,fbx ,&
436
- bisect_on_failure )
437
+ bisect_on_failure , bisect_used )
437
438
438
439
implicit none
439
440
@@ -454,6 +455,7 @@ subroutine root_scalar_by_type(method,fun,ax,bx,xzero,fzero,iflag,&
454
455
! ! it will be retried using the bisection method.
455
456
! ! (default is False). Note that this can use up
456
457
! ! to `maxiter` additional function evaluations.
458
+ logical ,intent (out ),optional :: bisect_used ! ! if the bisection method was used after failure
457
459
458
460
class(root_solver),allocatable :: s
459
461
@@ -486,7 +488,8 @@ subroutine root_scalar_by_type(method,fun,ax,bx,xzero,fzero,iflag,&
486
488
end select
487
489
488
490
call s% initialize(func_wrapper,ftol,rtol,atol,maxiter)
489
- call s% solve(ax,bx,xzero,fzero,iflag,fax,fbx,bisect_on_failure)
491
+ call s% solve(ax,bx,xzero,fzero,iflag,fax,fbx,&
492
+ bisect_on_failure,bisect_used)
490
493
491
494
contains
492
495
@@ -505,7 +508,7 @@ end subroutine root_scalar_by_type
505
508
! >
506
509
! Main wrapper routine for all the methods.
507
510
508
- subroutine solve (me ,ax ,bx ,xzero ,fzero ,iflag ,fax ,fbx ,bisect_on_failure )
511
+ subroutine solve (me ,ax ,bx ,xzero ,fzero ,iflag ,fax ,fbx ,bisect_on_failure , bisect_used )
509
512
510
513
implicit none
511
514
@@ -521,10 +524,13 @@ subroutine solve(me,ax,bx,xzero,fzero,iflag,fax,fbx,bisect_on_failure)
521
524
! ! it will be retried using the bisection method.
522
525
! ! (default is False). Note that this can use up
523
526
! ! to `maxiter` additional function evaluations.
527
+ logical ,intent (out ),optional :: bisect_used ! ! if the bisection method was used after failure
524
528
525
529
real (wp) :: fa ! ! `f(ax)` passed to the lower level routine
526
530
real (wp) :: fb ! ! `f(bx)` passed to the lower level routine
527
531
532
+ if (present (bisect_used)) bisect_used = .false.
533
+
528
534
if (ax== bx) then
529
535
! ax must be /= bx
530
536
iflag = - 4
@@ -563,13 +569,19 @@ subroutine solve(me,ax,bx,xzero,fzero,iflag,fax,fbx,bisect_on_failure)
563
569
! if it failed, then we have the option to then try bisection
564
570
if (iflag /= 0 ) then
565
571
if (present (bisect_on_failure)) then
566
- if (bisect_on_failure) then
567
- ! use the wrapper routine for that with the input class
568
- call root_scalar(root_method_bisection,&
569
- func_wrapper,ax,bx,xzero,fzero,iflag,&
570
- me% ftol,me% rtol,me% atol,me% maxiter,fa,fb,&
571
- bisect_on_failure = .false. )
572
- end if
572
+ select type (me)
573
+ class is (bisection_solver)
574
+ ! can't bisect after failed bisection
575
+ class default
576
+ if (bisect_on_failure) then
577
+ ! use the wrapper routine for that with the input class
578
+ call root_scalar(root_method_bisection,&
579
+ func_wrapper,ax,bx,xzero,fzero,iflag,&
580
+ me% ftol,me% rtol,me% atol,me% maxiter,fa,fb,&
581
+ bisect_on_failure = .false. )
582
+ if (present (bisect_used)) bisect_used = .true.
583
+ end if
584
+ end select
573
585
end if
574
586
end if
575
587
0 commit comments