nonlin 1.5.2
A library that provides routines to compute the solutions to systems of nonlinear equations.
Loading...
Searching...
No Matches
nonlin_core.f90
1! nonlin_core.f90
2
149
150! ------------------------------------------------------------------------------
151
168 use, intrinsic :: iso_fortran_env, only : real64, int32
170 implicit none
171 private
172 public :: vecfcn
173 public :: fcn1var
174 public :: fcnnvar
175 public :: jacobianfcn
176 public :: gradientfcn
177 public :: vecfcn_helper
178 public :: fcn1var_helper
179 public :: fcnnvar_helper
180 public :: iteration_behavior
181 public :: equation_solver
182 public :: equation_solver_1var
183 public :: equation_optimizer
184 public :: value_pair
185 public :: nonlin_solver
186 public :: nonlin_solver_1var
187 public :: nonlin_optimize_fcn
188 public :: print_status
189
190! ******************************************************************************
191! INTERFACES
192! ------------------------------------------------------------------------------
193 interface
194
198 function fcn1var(x) result(f)
199 use, intrinsic :: iso_fortran_env, only : real64
200 real(real64), intent(in) :: x
201 real(real64) :: f
202 end function
203
209 subroutine vecfcn(x, f)
210 use, intrinsic :: iso_fortran_env, only : real64
211 real(real64), intent(in), dimension(:) :: x
212 real(real64), intent(out), dimension(:) :: f
213 end subroutine
214
220 subroutine jacobianfcn(x, jac)
221 use, intrinsic :: iso_fortran_env, only : real64
222 real(real64), intent(in), dimension(:) :: x
223 real(real64), intent(out), dimension(:,:) :: jac
224 end subroutine
225
230 function fcnnvar(x) result(f)
231 use, intrinsic :: iso_fortran_env, only : real64
232 real(real64), intent(in), dimension(:) :: x
233 real(real64) :: f
234 end function
235
242 subroutine gradientfcn(x, g)
243 use, intrinsic :: iso_fortran_env, only : real64
244 real(real64), intent(in), dimension(:) :: x
245 real(real64), intent(out), dimension(:) :: g
246 end subroutine
247 end interface
248
249! ******************************************************************************
250! TYPES
251! ------------------------------------------------------------------------------
256 integer(int32) :: iter_count
258 integer(int32) :: fcn_count
260 integer(int32) :: jacobian_count
262 integer(int32) :: gradient_count
265 logical :: converge_on_fcn
268 logical :: converge_on_chng
272 logical :: converge_on_zero_diff
273 end type
274
275! ------------------------------------------------------------------------------
277 type, bind(C) :: value_pair
279 real(real64) :: x1
281 real(real64) :: x2
282 end type
283
284! ******************************************************************************
285! NONLIN_VECFCN_HELPER.F90
286! ------------------------------------------------------------------------------
340 private
342 procedure(vecfcn), pointer, nopass :: m_fcn => null()
344 procedure(jacobianfcn), pointer, nopass :: m_jac => null()
346 integer(int32) :: m_nfcn = 0
348 integer(int32) :: m_nvar = 0
349 contains
410 procedure, public :: set_fcn => vfh_set_fcn
486 procedure, public :: set_jacobian => vfh_set_jac
497 procedure, public :: is_fcn_defined => vfh_is_fcn_defined
508 procedure, public :: is_jacobian_defined => vfh_is_jac_defined
522 procedure, public :: fcn => vfh_fcn
557 procedure, public :: jacobian => vfh_jac_fcn
567 procedure, public :: get_equation_count => vfh_get_nfcn
577 procedure, public :: get_variable_count => vfh_get_nvar
578 end type
579
580! ------------------------------------------------------------------------------
581 interface
582 module subroutine vfh_set_fcn(this, fcn, nfcn, nvar)
583 class(vecfcn_helper), intent(inout) :: this
584 procedure(vecfcn), intent(in), pointer :: fcn
585 integer(int32), intent(in) :: nfcn, nvar
586 end subroutine
587
588 module subroutine vfh_set_jac(this, jac)
589 class(vecfcn_helper), intent(inout) :: this
590 procedure(jacobianfcn), intent(in), pointer :: jac
591 end subroutine
592
593 module function vfh_is_fcn_defined(this) result(x)
594 class(vecfcn_helper), intent(in) :: this
595 logical :: x
596 end function
597
598 module function vfh_is_jac_defined(this) result(x)
599 class(vecfcn_helper), intent(in) :: this
600 logical :: x
601 end function
602
603 module subroutine vfh_fcn(this, x, f)
604 class(vecfcn_helper), intent(in) :: this
605 real(real64), intent(in), dimension(:) :: x
606 real(real64), intent(out), dimension(:) :: f
607 end subroutine
608
609 module subroutine vfh_jac_fcn(this, x, jac, fv, work, olwork, err)
610 class(vecfcn_helper), intent(in) :: this
611 real(real64), intent(inout), dimension(:) :: x
612 real(real64), intent(out), dimension(:,:) :: jac
613 real(real64), intent(in), dimension(:), optional, target :: fv
614 real(real64), intent(out), dimension(:), optional, target :: work
615 integer(int32), intent(out), optional :: olwork, err
616 end subroutine
617
618 module function vfh_get_nfcn(this) result(n)
619 class(vecfcn_helper), intent(in) :: this
620 integer(int32) :: n
621 end function
622
623 module function vfh_get_nvar(this) result(n)
624 class(vecfcn_helper), intent(in) :: this
625 integer(int32) :: n
626 end function
627 end interface
628
629! ******************************************************************************
630! NONLIN_FCN1VAR_HELPER.F90
631! ------------------------------------------------------------------------------
682 type fcn1var_helper
683 private
685 procedure(fcn1var), pointer, nopass :: m_fcn => null()
687 procedure(fcn1var), pointer, nopass :: m_diff => null()
688 contains
700 procedure, public :: fcn => f1h_fcn
711 procedure, public :: is_fcn_defined => f1h_is_fcn_defined
771 procedure, public :: set_fcn => f1h_set_fcn
782 procedure, public :: is_derivative_defined => f1h_is_diff_defined
796 procedure, public :: diff => f1h_diff_fcn
797 !!
798 !! @par Syntax
799 !! @code{.f90}
800 !! subroutine set_diff(class(fcn1var_helper) this, procedure(fcn1var) pointer diff)
801 !! @endcode
802 !!
803 !! @param[in,out] this The fcn1var_helper object.
804 !! @param[in] diff A pointer to the function for computing the first
805 !! derivative.
806 procedure, public :: set_diff => f1h_set_diff
807 end type
808
809! ------------------------------------------------------------------------------
810 interface
811 module function f1h_fcn(this, x) result(f)
812 class(fcn1var_helper), intent(in) :: this
813 real(real64), intent(in) :: x
814 real(real64) :: f
815 end function
816
817 module function f1h_is_fcn_defined(this) result(x)
818 class(fcn1var_helper), intent(in) :: this
819 logical :: x
820 end function
821
822 module subroutine f1h_set_fcn(this, fcn)
823 class(fcn1var_helper), intent(inout) :: this
824 procedure(fcn1var), intent(in), pointer :: fcn
825 end subroutine
826
827 module function f1h_is_diff_defined(this) result(x)
828 class(fcn1var_helper), intent(in) :: this
829 logical :: x
830 end function
831
832 module function f1h_diff_fcn(this, x, f) result(df)
833 class(fcn1var_helper), intent(in) :: this
834 real(real64), intent(in) :: x
835 real(real64), intent(in), optional :: f
836 real(real64) :: df
837 end function
838
839 module subroutine f1h_set_diff(this, diff)
840 class(fcn1var_helper), intent(inout) :: this
841 procedure(fcn1var), pointer, intent(in) :: diff
842 end subroutine
843 end interface
844
845! ******************************************************************************
846! NONLIN_FCNNVAR_HELPER.F90
847! ------------------------------------------------------------------------------
896 type fcnnvar_helper
897 private
899 procedure(fcnnvar), pointer, nopass :: m_fcn => null()
901 procedure(gradientfcn), pointer, nopass :: m_grad => null()
903 integer(int32) :: m_nvar = 0
904 contains
916 procedure, public :: fcn => fnh_fcn
926 procedure, public :: is_fcn_defined => fnh_is_fcn_defined
983 procedure, public :: set_fcn => fnh_set_fcn
993 procedure, public :: get_variable_count => fnh_get_nvar
1070 procedure, public :: set_gradient_fcn => fnh_set_grad
1081 procedure, public :: is_gradient_defined => fnh_is_grad_defined
1104 procedure, public :: gradient => fnh_grad_fcn
1105 end type
1106
1107! ------------------------------------------------------------------------------
1108 interface
1109 module function fnh_fcn(this, x) result(f)
1110 class(fcnnvar_helper), intent(in) :: this
1111 real(real64), intent(in), dimension(:) :: x
1112 real(real64) :: f
1113 end function
1114
1115 module function fnh_is_fcn_defined(this) result(x)
1116 class(fcnnvar_helper), intent(in) :: this
1117 logical :: x
1118 end function
1119
1120 module subroutine fnh_set_fcn(this, fcn, nvar)
1121 class(fcnnvar_helper), intent(inout) :: this
1122 procedure(fcnnvar), intent(in), pointer :: fcn
1123 integer(int32), intent(in) :: nvar
1124 end subroutine
1125
1126 module function fnh_get_nvar(this) result(n)
1127 class(fcnnvar_helper), intent(in) :: this
1128 integer(int32) :: n
1129 end function
1130
1131 module subroutine fnh_set_grad(this, fcn)
1132 class(fcnnvar_helper), intent(inout) :: this
1133 procedure(gradientfcn), pointer, intent(in) :: fcn
1134 end subroutine
1135
1136 module function fnh_is_grad_defined(this) result(x)
1137 class(fcnnvar_helper), intent(in) :: this
1138 logical :: x
1139 end function
1140
1141 module subroutine fnh_grad_fcn(this, x, g, fv, err)
1142 class(fcnnvar_helper), intent(in) :: this
1143 real(real64), intent(inout), dimension(:) :: x
1144 real(real64), intent(out), dimension(:) :: g
1145 real(real64), intent(in), optional :: fv
1146 integer(int32), intent(out), optional :: err
1147 end subroutine
1148 end interface
1149
1150! ******************************************************************************
1151! NONLIN_EQUATION_SOLVER.F90
1152! ------------------------------------------------------------------------------
1260 type, abstract :: equation_solver
1261 private
1263 integer(int32) :: m_maxeval = 100
1265 real(real64) :: m_fcntol = 1.0d-8
1267 real(real64) :: m_xtol = 1.0d-12
1269 real(real64) :: m_gtol = 1.0d-12
1271 logical :: m_printstatus = .false.
1272 contains
1283 procedure, public :: get_max_fcn_evals => es_get_max_eval
1298 procedure, public :: set_max_fcn_evals => es_set_max_eval
1308 procedure, public :: get_fcn_tolerance => es_get_fcn_tol
1322 procedure, public :: set_fcn_tolerance => es_set_fcn_tol
1332 procedure, public :: get_var_tolerance => es_get_var_tol
1346 procedure, public :: set_var_tolerance => es_set_var_tol
1357 procedure, public :: get_gradient_tolerance => es_get_grad_tol
1372 procedure, public :: set_gradient_tolerance => es_set_grad_tol
1383 procedure, public :: get_print_status => es_get_print_status
1398 procedure, public :: set_print_status => es_set_print_status
1404 procedure(nonlin_solver), deferred, public, pass :: solve
1405 end type
1406
1407! ------------------------------------------------------------------------------
1408 interface
1409 pure module function es_get_max_eval(this) result(n)
1410 class(equation_solver), intent(in) :: this
1411 integer(int32) :: n
1412 end function
1413
1414 module subroutine es_set_max_eval(this, n)
1415 class(equation_solver), intent(inout) :: this
1416 integer(int32), intent(in) :: n
1417 end subroutine
1418
1419 pure module function es_get_fcn_tol(this) result(x)
1420 class(equation_solver), intent(in) :: this
1421 real(real64) :: x
1422 end function
1423
1424 module subroutine es_set_fcn_tol(this, x)
1425 class(equation_solver), intent(inout) :: this
1426 real(real64), intent(in) :: x
1427 end subroutine
1428
1429 pure module function es_get_var_tol(this) result(x)
1430 class(equation_solver), intent(in) :: this
1431 real(real64) :: x
1432 end function
1433
1434 module subroutine es_set_var_tol(this, x)
1435 class(equation_solver), intent(inout) :: this
1436 real(real64), intent(in) :: x
1437 end subroutine
1438
1439 pure module function es_get_grad_tol(this) result(x)
1440 class(equation_solver), intent(in) :: this
1441 real(real64) :: x
1442 end function
1443
1444 module subroutine es_set_grad_tol(this, x)
1445 class(equation_solver), intent(inout) :: this
1446 real(real64), intent(in) :: x
1447 end subroutine
1448
1449 pure module function es_get_print_status(this) result(x)
1450 class(equation_solver), intent(in) :: this
1451 logical :: x
1452 end function
1453
1454 module subroutine es_set_print_status(this, x)
1455 class(equation_solver), intent(inout) :: this
1456 logical, intent(in) :: x
1457 end subroutine
1458 end interface
1459
1460! ******************************************************************************
1461! NONLIN_EQUATION_SOLVER_1VAR.F90
1462! ------------------------------------------------------------------------------
1512 type, abstract :: equation_solver_1var
1513 private
1515 integer(int32) :: m_maxeval = 100
1517 real(real64) :: m_fcntol = 1.0d-8
1519 real(real64) :: m_xtol = 1.0d-12
1521 real(real64) :: m_difftol = 1.0d-12
1523 logical :: m_printstatus = .false.
1524 contains
1535 procedure, public :: get_max_fcn_evals => es1_get_max_eval
1546 procedure, public :: set_max_fcn_evals => es1_set_max_eval
1556 procedure, public :: get_fcn_tolerance => es1_get_fcn_tol
1566 procedure, public :: set_fcn_tolerance => es1_set_fcn_tol
1576 procedure, public :: get_var_tolerance => es1_get_var_tol
1586 procedure, public :: set_var_tolerance => es1_set_var_tol
1597 procedure, public :: get_print_status => es1_get_print_status
1608 procedure, public :: set_print_status => es1_set_print_status
1614 procedure(nonlin_solver_1var), deferred, public, pass :: solve
1625 procedure, public :: get_diff_tolerance => es1_get_diff_tol
1640 procedure, public :: set_diff_tolerance => es1_set_diff_tol
1641 end type
1642
1643! ------------------------------------------------------------------------------
1644 interface
1645 pure module function es1_get_max_eval(this) result(n)
1646 class(equation_solver_1var), intent(in) :: this
1647 integer(int32) :: n
1648 end function
1649
1650 module subroutine es1_set_max_eval(this, n)
1651 class(equation_solver_1var), intent(inout) :: this
1652 integer(int32), intent(in) :: n
1653 end subroutine
1654
1655 pure module function es1_get_fcn_tol(this) result(x)
1656 class(equation_solver_1var), intent(in) :: this
1657 real(real64) :: x
1658 end function
1659
1660 module subroutine es1_set_fcn_tol(this, x)
1661 class(equation_solver_1var), intent(inout) :: this
1662 real(real64), intent(in) :: x
1663 end subroutine
1664
1665 pure module function es1_get_var_tol(this) result(x)
1666 class(equation_solver_1var), intent(in) :: this
1667 real(real64) :: x
1668 end function
1669
1670 module subroutine es1_set_var_tol(this, x)
1671 class(equation_solver_1var), intent(inout) :: this
1672 real(real64), intent(in) :: x
1673 end subroutine
1674
1675 pure module function es1_get_print_status(this) result(x)
1676 class(equation_solver_1var), intent(in) :: this
1677 logical :: x
1678 end function
1679
1680 module subroutine es1_set_print_status(this, x)
1681 class(equation_solver_1var), intent(inout) :: this
1682 logical, intent(in) :: x
1683 end subroutine
1684
1685 pure module function es1_get_diff_tol(this) result(x)
1686 class(equation_solver_1var), intent(in) :: this
1687 real(real64) :: x
1688 end function
1689
1690 ! --------------------
1691 module subroutine es1_set_diff_tol(this, x)
1692 class(equation_solver_1var), intent(inout) :: this
1693 real(real64), intent(in) :: x
1694 end subroutine
1695 end interface
1696
1697! ******************************************************************************
1698! NONLIN_EQUATION_OPTIMIZER.F90
1699! ------------------------------------------------------------------------------
1767 type, abstract :: equation_optimizer
1768 private
1770 integer(int32) :: m_maxeval = 500
1772 real(real64) :: m_tol = 1.0d-12
1774 logical :: m_printstatus = .false.
1775 contains
1785 procedure, public :: get_max_fcn_evals => oe_get_max_eval
1795 procedure, public :: set_max_fcn_evals => oe_set_max_eval
1805 procedure, public :: get_tolerance => oe_get_tol
1815 procedure, public :: set_tolerance => oe_set_tol
1826 procedure, public :: get_print_status => oe_get_print_status
1837 procedure, public :: set_print_status => oe_set_print_status
1843 procedure(nonlin_optimize_fcn), deferred, public, pass :: solve
1844 end type
1845
1846! ------------------------------------------------------------------------------
1847 interface
1848 pure module function oe_get_max_eval(this) result(n)
1849 class(equation_optimizer), intent(in) :: this
1850 integer(int32) :: n
1851 end function
1852
1853 module subroutine oe_set_max_eval(this, n)
1854 class(equation_optimizer), intent(inout) :: this
1855 integer(int32), intent(in) :: n
1856 end subroutine
1857
1858 pure module function oe_get_tol(this) result(x)
1859 class(equation_optimizer), intent(in) :: this
1860 real(real64) :: x
1861 end function
1862
1863 module subroutine oe_set_tol(this, x)
1864 class(equation_optimizer), intent(inout) :: this
1865 real(real64), intent(in) :: x
1866 end subroutine
1867
1868 pure module function oe_get_print_status(this) result(x)
1869 class(equation_optimizer), intent(in) :: this
1870 logical :: x
1871 end function
1872
1873 module subroutine oe_set_print_status(this, x)
1874 class(equation_optimizer), intent(inout) :: this
1875 logical, intent(in) :: x
1876 end subroutine
1877 end interface
1878
1879! ******************************************************************************
1880! ABSTRACT ROUTINE INTERFACES
1881! ------------------------------------------------------------------------------
1882 interface
1883
1902 subroutine nonlin_solver(this, fcn, x, fvec, ib, err)
1903 use, intrinsic :: iso_fortran_env, only : real64
1904 use ferror, only : errors
1905 import equation_solver
1906 import vecfcn_helper
1907 import iteration_behavior
1908 class(equation_solver), intent(inout) :: this
1909 class(vecfcn_helper), intent(in) :: fcn
1910 real(real64), intent(inout), dimension(:) :: x
1911 real(real64), intent(out), dimension(:) :: fvec
1912 type(iteration_behavior), optional :: ib
1913 class(errors), intent(inout), optional, target :: err
1914 end subroutine
1915
1935 subroutine nonlin_solver_1var(this, fcn, x, lim, f, ib, err)
1936 use, intrinsic :: iso_fortran_env, only : real64
1937 use ferror, only : errors
1938 import equation_solver_1var
1939 import fcn1var_helper
1940 import value_pair
1941 import iteration_behavior
1942 class(equation_solver_1var), intent(inout) :: this
1943 class(fcn1var_helper), intent(in) :: fcn
1944 real(real64), intent(inout) :: x
1945 type(value_pair), intent(in) :: lim
1946 real(real64), intent(out), optional :: f
1947 type(iteration_behavior), optional :: ib
1948 class(errors), intent(inout), optional, target :: err
1949 end subroutine
1950
1969 subroutine nonlin_optimize_fcn(this, fcn, x, fout, ib, err)
1970 use, intrinsic :: iso_fortran_env, only : real64
1971 use ferror, only : errors
1972 import equation_optimizer
1973 import fcnnvar_helper
1974 import iteration_behavior
1975 class(equation_optimizer), intent(inout) :: this
1976 class(fcnnvar_helper), intent(in) :: fcn
1977 real(real64), intent(inout), dimension(:) :: x
1978 real(real64), intent(out), optional :: fout
1979 type(iteration_behavior), optional :: ib
1980 class(errors), intent(inout), optional, target :: err
1981 end subroutine
1982 end interface
1983
1984contains
1985! ******************************************************************************
1986! MISC. ROUTINES
1987! ------------------------------------------------------------------------------
1995 subroutine print_status(iter, nfeval, njaceval, xnorm, fnorm)
1996 ! Arguments
1997 integer(int32), intent(in) :: iter, nfeval, njaceval
1998 real(real64), intent(in) :: xnorm, fnorm
1999
2000 ! Process
2001 print *, ""
2002 print 100, "Iteration: ", iter
2003 print 100, "Function Evaluations: ", nfeval
2004 if (njaceval > 0) print 100, "Jacobian Evaluations: ", njaceval
2005 print 101, "Change in Variable: ", xnorm
2006 print 101, "Residual: ", fnorm
2007
2008 ! Formatting
2009100 format(a, i0)
2010101 format(a, e10.3)
2011 end subroutine
2012end module
Describes a function of one variable.
Describes a function of N variables.
Describes a routine capable of computing the gradient vector of an equation of N variables.
Describes a routine capable of computing the Jacobian matrix of M functions of N unknowns.
Describes the interface of a routine for optimizing an equation of N variables.
Describes the interface of a solver for an equation of one variable.
Describes the interface of a nonlinear equation solver.
Describes an M-element vector-valued function of N-variables.
nonlin_constants
nonlin_core
A base class for optimization of an equation of multiple variables.
A base class for various solvers of equations of one variable.
A base class for various solvers of nonlinear systems of equations.
Defines a type capable of encapsulating an equation of one variable of the form: f(x) = 0.
Defines a type capable of encapsulating an equation of N variables.
Defines a set of parameters that describe the behavior of the iteration process.
Defines a pair of numeric values.
Defines a type capable of encapsulating a system of nonlinear equations of the form: F(X) = 0....