nonlin 1.5.2
A library that provides routines to compute the solutions to systems of nonlinear equations.
Loading...
Searching...
No Matches
nonlin_fcn1var_helper.f90
1! nonlin_fcn1var_helper.f90
2
3submodule(nonlin_core) nonlin_fcn1var_helper
4 implicit none
5contains
6! ------------------------------------------------------------------------------
7 module function f1h_fcn(this, x) result(f)
8 class(fcn1var_helper), intent(in) :: this
9 real(real64), intent(in) :: x
10 real(real64) :: f
11 if (associated(this%m_fcn)) then
12 f = this%m_fcn(x)
13 end if
14 end function
15
16! ------------------------------------------------------------------------------
17 module function f1h_is_fcn_defined(this) result(x)
18 class(fcn1var_helper), intent(in) :: this
19 logical :: x
20 x = associated(this%m_fcn)
21 end function
22
23! ------------------------------------------------------------------------------
24 module subroutine f1h_set_fcn(this, fcn)
25 class(fcn1var_helper), intent(inout) :: this
26 procedure(fcn1var), intent(in), pointer :: fcn
27 this%m_fcn => fcn
28 end subroutine
29
30! ------------------------------------------------------------------------------
31 module function f1h_is_diff_defined(this) result(x)
32 class(fcn1var_helper), intent(in) :: this
33 logical :: x
34 x = associated(this%m_diff)
35 end function
36
37! ------------------------------------------------------------------------------
38 module function f1h_diff_fcn(this, x, f) result(df)
39 ! Arguments
40 class(fcn1var_helper), intent(in) :: this
41 real(real64), intent(in) :: x
42 real(real64), intent(in), optional :: f
43 real(real64) :: df
44
45 ! Parameters
46 real(real64), parameter :: zero = 0.0d0
47
48 ! Local Variables
49 real(real64) :: eps, epsmch, h, temp, f1, f0
50
51 ! Initialization
52 epsmch = epsilon(epsmch)
53 eps = sqrt(epsmch)
54
55 ! Process
56 if (this%is_derivative_defined()) then
57 ! Use the user-defined routine to compute the derivative
58 df = this%m_diff(x)
59 else
60 ! Compute the derivative via a forward difference
61 h = eps * abs(x)
62 if (h < epsmch) h = eps
63 temp = x + h
64 f1 = this%fcn(temp)
65 if (present(f)) then
66 f0 = f
67 else
68 f0 = this%fcn(x)
69 end if
70 df = (f1 - f0) / h
71 end if
72 end function
73
74! ------------------------------------------------------------------------------
75 module subroutine f1h_set_diff(this, diff)
76 class(fcn1var_helper), intent(inout) :: this
77 procedure(fcn1var), pointer, intent(in) :: diff
78 this%m_diff => diff
79 end subroutine
80
81! ------------------------------------------------------------------------------
82end submodule
nonlin_core