Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(RootFinderDataType), | intent(inout) | :: | RootFinderData |
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed arrows point from an interface to procedures which implement that interface. This could include the module procedures in a generic interface or the implementation in a submodule of an interface in a parent module. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed arrows point from an interface to procedures which implement that interface. This could include the module procedures in a generic interface or the implementation in a submodule of an interface in a parent module. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
SUBROUTINE AdvanceRootFinder( RootFinderData )
! SUBROUTINE INFORMATION:
! AUTHOR Dimitri Curtil (LBNL)
! DATE WRITTEN February 2006
! MODIFIED
! RE-ENGINEERED na
! PURPOSE OF THIS SUBROUTINE:
! This subroutine computes the next candidate value based on the information available so far.
! Stores new value into RootFinderData%XCandidate
!
! PRECONDITION:
! na
!
! POSTCONDITION:
! - LowerPoint%X < XCandidate < UpperPoint%X
! - RootFinderData%CurrentMethodType update with current solution method.
!
! METHODOLOGY EMPLOYED:
! The subroutine first attempts to bracket the root within a lower and upper point.
! Once it is bracketed, then we use the specified solution methods (Bisection,
! False position, Secant and Brent) to compute the next candidate.
!
! REFERENCES:
! na
! USE STATEMENTS:
! na
IMPLICIT NONE ! Enforce explicit typing of all variables in this routine
! SUBROUTINE ARGUMENT DEFINITIONS:
TYPE(RootFinderDataType), INTENT(INOUT) :: RootFinderData ! Data used by root finding algorithm
! SUBROUTINE PARAMETER DEFINITIONS:
! na
! INTERFACE BLOCK SPECIFICATIONS
! na
! DERIVED TYPE DEFINITIONS
! na
! SUBROUTINE LOCAL VARIABLE DECLARATIONS:
REAL(r64) :: XNext = 0.0d0
! FLOW:
!----------------------------------------------------------------------------
! First attempt to bracket root between a lower point and an upper point.
!----------------------------------------------------------------------------
! Detect the lower bracket
IF ( .NOT.RootFinderData%LowerPoint%DefinedFlag ) THEN
RootFinderData%CurrentMethodType = iMethodBracket
! If we have 2 points already, try to detect lower point using the Secant formula
IF ( BracketRoot( RootFinderData, XNext ) ) THEN
RootFinderData%XCandidate = XNext
ELSE
IF ( .NOT.RootFinderData%MinPoint%DefinedFlag ) THEN
RootFinderData%XCandidate = RootFinderData%MinPoint%X
ELSE
! Should never happen
CALL ShowFatalError('AdvanceRootFinder: Cannot find lower bracket.')
END IF
END IF
! Detect the upper bracket
ELSE IF ( .NOT.RootFinderData%UpperPoint%DefinedFlag ) THEN
RootFinderData%CurrentMethodType = iMethodBracket
! If we have 2 points already, try to detect upper point using the Secant formula
IF ( BracketRoot( RootFinderData, XNext ) ) THEN
RootFinderData%XCandidate = XNext
ELSE
IF ( .NOT.RootFinderData%MaxPoint%DefinedFlag ) THEN
RootFinderData%XCandidate = RootFinderData%MaxPoint%X
ELSE
! Should never happen
CALL ShowFatalError('AdvanceRootFinder: Cannot find upper bracket.')
END IF
END IF
!----------------------------------------------------------------------------
! Root finding can start ...
!
! Assumptions:
! - the lower and upper support points are defined.
! - the increments are defined (at least 2 history points are available)
!----------------------------------------------------------------------------
ELSE
SelectRecoveryMethod: SELECT CASE ( RootFinderData%StatusFlag )
CASE ( iStatusOKRoundOff )
! Should never happen if we exit the root finder upon detecting round-off condition
RootFinderData%XCandidate = BisectionMethod(RootFinderData)
CASE ( iStatusWarningSingular, iStatusWarningNonMonotonic )
! Following local singularity or non-monotonicity warnings we attempt
! to recover with the false position method to avoid running into trouble
! because the latest iterate did nt produce any improvement compared to
! the previous lower and upper brackets.
RootFinderData%XCandidate = FalsePositionMethod(RootFinderData)
CASE DEFAULT
! Assuming that the root is bracketed between the lower and upper points,
! we execute the requested solution method to produce the next candidate value
! for the root.
SelectMethod: SELECT CASE(RootFinderData%Controls%MethodType)
CASE (iMethodBisection)
! Bisection method (aka interval halving)
RootFinderData%XCandidate = BisectionMethod(RootFinderData)
CASE (iMethodFalsePosition)
! False position method (aka regula falsi)
RootFinderData%XCandidate = FalsePositionMethod(RootFinderData)
CASE (iMethodSecant)
! Secant method
RootFinderData%XCandidate = SecantMethod(RootFinderData)
CASE (iMethodBrent)
! Brent method
RootFinderData%XCandidate = BrentMethod(RootFinderData)
CASE DEFAULT
CALL ShowSevereError('AdvanceRootFinder: Invalid solution method specification. Valid choices are:' )
CALL ShowContinueError('AdvanceRootFinder: iMethodBisection='//TRIM(TrimSigDigits(iMethodBisection)))
CALL ShowContinueError('AdvanceRootFinder: iMethodFalsePosition='//TRIM(TrimSigDigits(iMethodFalsePosition)))
CALL ShowContinueError('AdvanceRootFinder: iMethodSecant='//TRIM(TrimSigDigits(iMethodSecant)))
CALL ShowContinueError('AdvanceRootFinder: iMethodBrent='//TRIM(TrimSigDigits(iMethodBrent)))
CALL ShowFatalError('AdvanceRootFinder: Preceding error causes program termination.')
END SELECT SelectMethod
END SELECT SelectRecoveryMethod
END IF
RETURN
END SUBROUTINE AdvanceRootFinder