24 use,
intrinsic :: iso_fortran_env
41 integer,
public,
parameter :: &
46 integer :: solver_type
50 real(real64) :: abs_tolerance
51 real(real64) :: rel_tolerance
57 subroutine root_solver_init(rs, namespace, dimensionality, solver_type, maxiter, &
58 rel_tolerance, abs_tolerance)
59 type(root_solver_t),
intent(out) :: rs
60 type(namespace_t),
intent(in) :: namespace
61 integer,
intent(in) :: dimensionality
62 integer,
optional,
intent(in) :: solver_type, maxiter
63 real(real64),
optional,
intent(in) :: rel_tolerance, abs_tolerance
68 rs%dim = dimensionality
73 if (
present(solver_type)) rs%solver_type = solver_type
74 if (
present(maxiter)) rs%maxiter = maxiter
75 if (
present(rel_tolerance)) rs%rel_tolerance = rel_tolerance
76 if (
present(abs_tolerance)) rs%abs_tolerance = abs_tolerance
83 type(root_solver_t),
intent(inout) :: rs
84 type(namespace_t),
intent(in) :: namespace
97 call parse_variable(namespace,
'RootSolver', root_newton, rs%solver_type)
110 call parse_variable(namespace,
'RootSolverMaxIter', 500, rs%maxiter)
119 call parse_variable(namespace,
'RootSolverRelTolerance', 1e-10_real64, rs%rel_tolerance)
128 call parse_variable(namespace,
'RootSolverAbsTolerance', 1e-10_real64, rs%abs_tolerance)
136 real(real64),
intent(out) :: root(:)
137 logical,
intent(out) :: success
138 real(real64),
optional,
intent(in) :: startval(:)
143 real(real64),
intent(in) :: z(:)
144 real(real64),
intent(out) :: f(:), jf(:, :)
154 select case (rs%solver_type)
158 write(
message(1),
'(a,i4,a)')
"Error in droot_solver_run: '", rs%solver_type,
"' is not a valid root solver"
166 subroutine droot_newton(rs, func, root, startval, success)
168 real(real64),
intent(out) :: root(:)
169 real(real64),
intent(in) :: startval(:)
170 logical,
intent(out) :: success
172 subroutine func(z, f, jf)
175 real(real64),
intent(in) :: z(:)
176 real(real64),
intent(out) :: f(:), jf(:, :)
181 real(real64) :: err, prev_err
182 real(real64),
allocatable :: f(:), jf(:, :), delta(:, :), rhs(:, :)
184 real(real64) :: mm, prev_m
188 safe_allocate( f(1:rs%dim))
189 safe_allocate( jf(1:rs%dim, 1:rs%dim))
190 safe_allocate(delta(1:rs%dim, 1))
191 safe_allocate( rhs(1:rs%dim, 1))
194 call func(root, f, jf)
195 err = sum(f(1:rs%dim)**2)
200 do while(err > rs%abs_tolerance)
201 rhs(1:rs%dim, 1) = -mm * f(1:rs%dim)
204 root(1:rs%dim) = root(1:rs%dim) + delta(1:rs%dim, 1)
206 if (iter > rs%maxiter)
then
210 call func(root, f, jf)
212 err = sum(f(1:rs%dim)**2)
230 if(abs(mm - prev_m) > 0.5_real64) mm =
m_one
232 if( mm > 10._real64 ) mm =
m_one
237 safe_deallocate_a(jf)
238 safe_deallocate_a(delta)
239 safe_deallocate_a(rhs)
double floor(double __x) __attribute__((__nothrow__
real(real64) function func(r1, rn, n, a)
real(real64), parameter, public m_zero
real(real64), parameter, public m_one
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_input_error(namespace, var, details, row, column)
subroutine droot_newton(rs, func, root, startval, success)
Newton-Raphson scheme can only be used in the real case.
subroutine, public root_solver_init(rs, namespace, dimensionality, solver_type, maxiter, rel_tolerance, abs_tolerance)
subroutine, public droot_solver_run(rs, func, root, success, startval)
subroutine, public root_solver_read(rs, namespace)