Octopus
curv_gygi.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!! Copyright (C) 2025 S. Ohlmann
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
24
25module curv_gygi_oct_m
27 use debug_oct_m
28 use global_oct_m
29 use, intrinsic :: iso_fortran_env
31 use math_oct_m
34 use parser_oct_m
37 use unit_oct_m
39
40 implicit none
41
42 private
43 public :: &
47
48 type, extends(coordinate_system_t) :: curv_gygi_t
49 private
50 real(real64), public :: A
51 real(real64), public :: alpha
52 real(real64), public :: beta
53 real(real64), allocatable :: pos(:, :)
54 integer :: npos
55 type(root_solver_t) :: rs
56 contains
57 procedure :: to_cartesian => curv_gygi_to_cartesian
58 procedure :: from_cartesian => curv_gygi_from_cartesian
59 procedure :: write_info => curv_gygi_write_info
60 procedure :: surface_element => curv_gygi_surface_element
61 procedure :: jacobian => curv_gygi_jacobian
62 procedure :: jacobian_inverse => curv_gygi_jacobian_inverse
63 procedure :: trace_hessian => curv_gygi_trace_hessian
64 final :: curv_gygi_finalize
65 end type curv_gygi_t
66
67 interface curv_gygi_t
68 procedure curv_gygi_constructor
69 end interface curv_gygi_t
70
71 ! Auxiliary variables for the root solver. They are threadprivate, as
72 ! to_cartesian is called from OpenMP regions. They must not be local
73 ! variables of to_cartesian, as getf would then need a trampoline on
74 ! the stack, which marks the stack as executable.
75 class(curv_gygi_t), pointer :: gygi_p
76 type(curv_gygi_t), allocatable, target :: gygi_relaxed
77 real(real64), allocatable :: chi_p(:)
78 !$omp threadprivate(gygi_p, gygi_relaxed, chi_p)
79
80contains
81
82 ! ---------------------------------------------------------
83 function curv_gygi_constructor(namespace, dim, npos, pos) result(gygi)
84 type(namespace_t), intent(in) :: namespace
85 integer, intent(in) :: dim
86 integer, intent(in) :: npos
87 real(real64), intent(in) :: pos(1:dim,1:npos)
88 class(curv_gygi_t), pointer :: gygi
89
90 push_sub(curv_gygi_constructor)
91
92 safe_allocate(gygi)
93
94 gygi%dim = dim
95 gygi%local_basis = .true.
96 gygi%orthogonal = .true. ! This needs to be checked.
97
98 gygi%npos = npos
99 safe_allocate(gygi%pos(1:dim, 1:gygi%npos))
100 gygi%pos(:, :) = pos(:, :)
101
102 !%Variable CurvGygiA
103 !%Type float
104 !%Default 0.5
105 !%Section Mesh::Curvilinear::Gygi
106 !%Description
107 !% The grid spacing is reduced locally around each atom, and the reduction is
108 !% given by 1/(1+<i>A</i>), where <i>A</i> is specified by this variable. So, if
109 !% <i>A</i>=1/2 (the default), the grid spacing is reduced to two thirds = 1/(1+1/2).
110 !% [This is the <math>A_{\alpha}</math> variable in Eq. 2 of F. Gygi and G. Galli, <i>Phys.
111 !% Rev. B</i> <b>52</b>, R2229 (1995)]. It must be larger than zero.
112 !% It must not be larger than two, as the coordinate transformation is not bijective
113 !% anymore for larger values of <i>A</i>. This caps the local refinement that can be
114 !% obtained at 1/(1+2), i.e. a factor of three, which is the governing limitation when
115 !% attempting all-electron calculations on heavy atoms.
116 !%End
117 call parse_variable(namespace, 'CurvGygiA', m_half, gygi%A)
118
119 !%Variable CurvGygiAlpha
120 !%Type float
121 !%Default 2.0 a.u.
122 !%Section Mesh::Curvilinear::Gygi
123 !%Description
124 !% This number determines the region over which the grid is enhanced (range of
125 !% enhancement of the resolution). That is, the grid is enhanced on a sphere
126 !% around each atom, whose radius is given by this variable. [This is the <math>a_{\alpha}</math>
127 !% variable in Eq. 2 of F. Gygi and G. Galli, <i>Phys. Rev. B</i> <b>52</b>, R2229 (1995)].
128 !% It must be larger than zero.
129 !%End
130
131 call parse_variable(namespace, 'CurvGygiAlpha', m_two, gygi%alpha, units_inp%length)
132 !%Variable CurvGygiBeta
133 !%Type float
134 !%Default 4.0 a.u.
135 !%Section Mesh::Curvilinear::Gygi
136 !%Description
137 !% This number determines the distance over which Euclidean coordinates are
138 !% recovered. [This is the <math>b_{\alpha}</math> variable in Eq. 2 of F. Gygi and G. Galli,
139 !% <i>Phys. Rev. B</i> <b>52</b>, R2229 (1995)]. It must be larger than zero.
140 !%End
141 call parse_variable(namespace, 'CurvGygiBeta', m_four, gygi%beta, units_inp%length)
142
143 if (gygi%a <= m_zero) call messages_input_error(namespace, 'CurvGygiA')
144 if (gygi%a > m_two) call messages_input_error(namespace, 'CurvGygiA')
145 if (gygi%alpha <= m_zero) call messages_input_error(namespace, 'CurvGygiAlpha')
146 if (gygi%beta <= m_zero) call messages_input_error(namespace, 'CurvGygiBeta')
148 gygi%min_mesh_scaling_product = (m_one / (m_one + gygi%A))**gygi%dim
150 ! initialize root solver
151 call root_solver_init(gygi%rs, namespace, dim, solver_type = root_newton, maxiter = 500, abs_tolerance = 1.0e-10_real64)
156 ! ---------------------------------------------------------
157 subroutine curv_gygi_copy(this_out, this_in)
158 type(curv_gygi_t), intent(inout) :: this_out
159 type(curv_gygi_t), intent(in) :: this_in
160
161 push_sub(curv_gygi_copy)
162
163 this_out%A = this_in%A
164 this_out%alpha = this_in%alpha
165 this_out%beta = this_in%beta
166 safe_allocate_source_a(this_out%pos, this_in%pos)
167 this_out%pos = this_in%pos
168 this_out%npos = this_in%npos
169 this_out%dim = this_in%dim
170 this_out%local_basis = this_in%local_basis
171 this_out%orthogonal = this_in%orthogonal
172 call root_solver_init(this_out%rs, global_namespace, this_in%dim, solver_type = root_newton, &
173 maxiter = 500, abs_tolerance = 1.0e-10_real64)
174
175 pop_sub(curv_gygi_copy)
176 end subroutine curv_gygi_copy
177
178 ! ---------------------------------------------------------
179 subroutine curv_gygi_finalize(this)
180 type(curv_gygi_t), intent(inout) :: this
181
182 push_sub(curv_gygi_finalize)
183
184 safe_deallocate_a(this%pos)
185
186 pop_sub(curv_gygi_finalize)
187 end subroutine curv_gygi_finalize
188
189 ! ---------------------------------------------------------
190 real(real64) pure function gygi_f(this, r)
191 class(curv_gygi_t), intent(in) :: this
192 real(real64), intent(in) :: r
193
194 ! no PUSH_SUB, called too often
195
196 if (r < 1.0e-4_real64) then
197 ! below 1e-4, the relative deviation of this Taylor expansion from the function is less than 1e-15
198 gygi_f = this%A * (m_one + (-m_one/(m_three*this%alpha**2) - m_one/this%beta**2)*r**2)
199 else if (-(r/this%beta)**2 <= m_min_exp_arg) then
200 gygi_f = m_zero
201 else
202 gygi_f = this%A * this%alpha/r * tanh(r/this%alpha) * exp(-(r/this%beta)**2)
203 end if
204 end function gygi_f
205
206 ! ---------------------------------------------------------
207 ! absorb division by r into the function to get the correct expansion
208 real(real64) pure function gygi_dfdr_over_r(this, r)
209 class(curv_gygi_t), intent(in) :: this
210 real(real64), intent(in) :: r
211
212 ! no PUSH_SUB, called too often
213
214 if (r < 3.0e-3_real64) then
215 ! below 3e-3, the expansion is closer than 1e-13 to the function and does not suffer from
216 ! rounding errors
217 gygi_dfdr_over_r = this%A * ((-m_two/(m_three*this%alpha**2) - m_two/this%beta**2) + &
218 (8._real64/(15._real64*this%alpha**4) + m_four/(m_three*this%alpha**2*this%beta**2) &
219 + m_two/this%beta**4) * r**2)
220 else if (-(r/this%beta)**2 <= m_min_exp_arg) then
221 gygi_dfdr_over_r = m_zero
222 else
223 gygi_dfdr_over_r = this%A * (this%beta**2*r/cosh(r/this%alpha)**2 - &
224 this%alpha*(this%beta**2+m_two*r**2) * tanh(r/this%alpha)) &
225 / (this%beta**2*r**3) * exp(-(r/this%beta)**2)
226 end if
227 end function gygi_dfdr_over_r
228
229 ! ---------------------------------------------------------
230 ! only a combination of the second derivative is needed, namely
231 ! (d2f/d2r - 1/r df/dr)/r**2
232 real(real64) pure function gygi_d2fdr2_combination(this, r)
233 class(curv_gygi_t), intent(in) :: this
234 real(real64), intent(in) :: r
235
236 ! no PUSH_SUB, called too often
237
238 if (r < 3.0e-3_real64) then
239 ! below 3e-3, the expansion is closer than 1e-5 to the function and does not suffer from
240 ! rounding errors
241 gygi_d2fdr2_combination = this%A * ( &
242 m_two*(8._real64/(15._real64*this%alpha**4) + m_four/(m_three*this%alpha**2*this%beta**2) &
243 + m_two/this%beta**4) &
244 - m_four*(34._real64/(105._real64*this%alpha**6) + m_four/(m_five*this%alpha**4*this%beta**2) &
245 + m_one/(this%alpha**2*this%beta**4) + m_one/this%beta**6) * r**2 &
246 )
247 else if (-(r/this%beta)**2 <= m_min_exp_arg) then
249 else
250 gygi_d2fdr2_combination = this%A * exp(-(r/this%beta)**2)*( &
251 -m_two*tanh(r/this%alpha)/(cosh(r/this%alpha)**2*this%alpha*r) &
252 + tanh(r/this%alpha)*(m_three*this%alpha/r**3+m_four*this%alpha/(this%beta**2*r)+m_four*this%alpha*r/this%beta**4) &
253 + m_one/cosh(r/this%alpha)**2*(-m_three/r**2-m_four/this%beta**2))/r**2
254 end if
255 end function gygi_d2fdr2_combination
256
257
258 ! ---------------------------------------------------------
259 function curv_gygi_to_cartesian(this, chi) result(xx)
260 class(curv_gygi_t), target, intent(in) :: this
261 real(real64), intent(in) :: chi(:)
262 real(real64) :: xx(1:this%dim)
263
264 logical :: conv
265
266 ! no PUSH_SUB, called too often
267
268 gygi_p => this
269 safe_allocate(chi_p(1:this%dim))
270 chi_p(:) = chi(:)
271
272 call droot_solver_run(this%rs, getf, xx, conv, startval = chi)
273 nullify(gygi_p)
275 if (.not. conv) call curv_gygi_to_cartesian_relaxed(this, chi, xx, conv)
276
277 safe_deallocate_a(chi_p)
278
279 if (.not. conv) then
280 message(1) = "During the construction of the adaptive grid, the Newton-Raphson"
281 message(2) = "method did not converge for point:"
282 write(message(3),'(9f14.6)') xx(1:this%dim)
283 message(4) = "Try varying the Gygi parameters -- usually reducing CurvGygiA or"
284 message(5) = "CurvGygiAlpha (or both) solves the problem."
285 call messages_fatal(5)
286 end if
287
288 end function curv_gygi_to_cartesian
289
290 ! ---------------------------------------------------------
294 subroutine curv_gygi_to_cartesian_relaxed(this, chi, xx, conv)
295 class(curv_gygi_t), intent(in) :: this
296 real(real64), intent(in) :: chi(:)
297 real(real64), intent(inout) :: xx(:)
298 logical, intent(out) :: conv
299
300 real(real64) :: xx_start(1:this%dim)
301 integer :: i_conv, n_conv
302
303 allocate(gygi_relaxed)
304 call curv_gygi_copy(gygi_relaxed, this)
306 ! try to converge with decreasing A
307 n_conv = 8
308 do i_conv = 1, n_conv
309 gygi_p%A = gygi_p%A / m_two
310 call droot_solver_run(gygi_p%rs, getf, xx, conv, startval = chi)
311 if (conv) then
312 exit
313 end if
314 end do
315 if (conv) then
316 ! increase A again and take previous xx as starting point
317 n_conv = i_conv
318 do i_conv = n_conv, 1, -1
319 gygi_p%A = gygi_p%A * m_two
320 xx_start = xx
321 call droot_solver_run(gygi_p%rs, getf, xx, conv, startval = xx_start)
322 end do
323 end if
324 nullify(gygi_p)
326 deallocate(gygi_relaxed)
328 end subroutine curv_gygi_to_cartesian_relaxed
329
330 ! ---------------------------------------------------------
331 pure function curv_gygi_from_cartesian(this, xx) result(chi)
332 class(curv_gygi_t), target, intent(in) :: this
333 real(real64), intent(in) :: xx(:)
334 real(real64) :: chi(1:this%dim)
335
336 integer :: i, ia
337 real(real64) :: diff(this%dim), f
338
339 ! no PUSH_SUB, called too often
340
341 chi(1:this%dim) = xx(1:this%dim)
342 do ia = 1, this%npos
343 diff = xx(1:this%dim) - this%pos(1:this%dim, ia)
344 f = gygi_f(this, norm2(diff))
345 do i = 1, this%dim
346 chi(i) = chi(i) + diff(i) * f
347 end do
348 end do
349
350 end function curv_gygi_from_cartesian
351
352 ! ---------------------------------------------------------
353 subroutine curv_gygi_write_info(this, iunit, namespace)
354 class(curv_gygi_t), intent(in) :: this
355 integer, optional, intent(in) :: iunit
356 type(namespace_t), optional, intent(in) :: namespace
357
358 push_sub(curv_gygi_write_info)
359
360 write(message(1), '(a)') ' Curvilinear Method = gygi'
361 write(message(2), '(a)') ' Gygi Parameters:'
362 write(message(3), '(4x,a,f6.3)') 'A = ', this%a
363 write(message(4), '(4x,3a,f6.3)') 'alpha [', trim(units_abbrev(units_out%length)), '] = ', &
364 units_from_atomic(units_out%length, this%alpha)
365 write(message(5), '(4x,3a,f6.3)') 'beta [', trim(units_abbrev(units_out%length)), '] = ', &
366 units_from_atomic(units_out%length, this%beta)
367 call messages_info(5, iunit=iunit, namespace=namespace)
368
369 pop_sub(curv_gygi_write_info)
370 end subroutine curv_gygi_write_info
371
372 ! ---------------------------------------------------------
373 real(real64) function curv_gygi_surface_element(this, idir) result(ds)
374 class(curv_gygi_t), intent(in) :: this
375 integer, intent(in) :: idir
376
377 ds = m_zero
378 message(1) = 'Surface element with gygi curvilinear coordinates not implemented'
379 call messages_fatal(1)
380
381 end function curv_gygi_surface_element
382
383 ! ---------------------------------------------------------
384 function curv_gygi_jacobian(this, chi) result(jacobian)
385 class(curv_gygi_t), intent(in) :: this
386 real(real64), intent(in) :: chi(:)
387 real(real64) :: jacobian(1:this%dim, 1:this%dim)
388
389 jacobian = this%jacobian_inverse(chi)
390 call lalg_inverse(this%dim, jacobian, "dir")
391 end function curv_gygi_jacobian
392
393 ! ---------------------------------------------------------
394 function curv_gygi_jacobian_inverse(this, chi) result(jacobian_inverse)
395 class(curv_gygi_t), intent(in) :: this
396 real(real64), intent(in) :: chi(:)
397 real(real64) :: jacobian_inverse(1:this%dim, 1:this%dim)
398
399 real(real64) :: xx(1:this%dim)
400
401 ! no PUSH_SUB, called too often
402
403 xx(:) = this%to_cartesian(chi)
404 jacobian_inverse = curv_gygi_jacobian_inverse_cartesian(this, xx)
405
406 end function curv_gygi_jacobian_inverse
407
408 ! ---------------------------------------------------------
409 function curv_gygi_jacobian_inverse_cartesian(this, xx) result(jacobian_inverse)
410 class(curv_gygi_t), intent(in) :: this
411 real(real64), intent(in) :: xx(:)
412 real(real64) :: jacobian_inverse(1:this%dim, 1:this%dim)
413
414 integer :: i, ix, iy
415 real(real64) :: r, diff(1:this%dim), dfdr_over_r, f
416
417 ! no PUSH_SUB, called too often
418
419 jacobian_inverse(1:this%dim, 1:this%dim) = diagonal_matrix(this%dim, m_one)
420
421 do i = 1, this%npos
422 diff = xx(1:this%dim) - this%pos(1:this%dim, i)
423 r = norm2(diff)
424
425 f = gygi_f(this, r)
426 dfdr_over_r = gygi_dfdr_over_r(this, r)
427
428 do ix = 1, this%dim
429 jacobian_inverse(ix, ix) = jacobian_inverse(ix, ix) + f
430 do iy = 1, this%dim
431 jacobian_inverse(ix, iy) = jacobian_inverse(ix, iy) + diff(ix)*diff(iy)*dfdr_over_r
432 end do
433 end do
434 end do
435
437
438
439 ! ---------------------------------------------------------
440 pure subroutine curv_gygi_hessian(this, xx, hessian, natoms)
441 class(curv_gygi_t), intent(in) :: this
442 real(real64), contiguous, intent(in) :: xx(:)
443 real(real64), contiguous, intent(out) :: hessian(:, :, :)
444 integer, optional, intent(in) :: natoms
445
446 integer :: ia, i, j, k, natoms_
447 real(real64) :: r, diff(this%dim), dfdr_over_r, d2fdr2_combination
449 ! no PUSH_SUB, called too often
450
451 hessian(1:this%dim, 1:this%dim, 1:this%dim) = m_zero
452
453 natoms_ = this%npos
454 if (present(natoms)) natoms_ = natoms
455
456 do ia = 1, natoms_
457 diff = xx(1:this%dim) - this%pos(1:this%dim, ia)
458 r = norm2(diff)
459
460 dfdr_over_r = gygi_dfdr_over_r(this, r)
461 d2fdr2_combination = gygi_d2fdr2_combination(this, r)
462
463 do i = 1, this%dim
464 do j = 1, this%dim
465 do k = 1, this%dim
466 if (i == j) then
467 hessian(i, j, k) = hessian(i, j, k) + diff(k)*dfdr_over_r
468 end if
469 if (i == k) then
470 hessian(i, j, k) = hessian(i, j, k) + diff(j)*dfdr_over_r
471 end if
472 if (j == k) then
473 hessian(i, j, k) = hessian(i, j, k) + diff(i)*dfdr_over_r
474 end if
475 hessian(i, j, k) = hessian(i, j, k) + diff(i)*diff(j)*diff(k)*d2fdr2_combination
476 end do
477 end do
478 end do
479 end do
480
481 end subroutine curv_gygi_hessian
482
483 ! ---------------------------------------------------------
484 function curv_gygi_trace_hessian(this, chi) result(trace_hessian)
485 class(curv_gygi_t), intent(in) :: this
486 real(real64), intent(in) :: chi(:)
487 real(real64) :: trace_hessian(1:this%dim)
488
489 integer :: ia, i, k
490 real(real64) :: r, xx(this%dim), diff(this%dim), dfdr_over_r, d2fdr2_combination
491
492 ! no PUSH_SUB, called too often
493
494 xx(:) = this%to_cartesian(chi)
495 trace_hessian(:) = m_zero
496
497 do ia = 1, this%npos
498 diff = xx(1:this%dim) - this%pos(1:this%dim, ia)
499 r = norm2(diff)
500
501 dfdr_over_r = gygi_dfdr_over_r(this, r)
502 d2fdr2_combination = gygi_d2fdr2_combination(this, r)
503
504 do i = 1, this%dim
505 do k = 1, this%dim
506 if (i == k) then
507 trace_hessian(i) = trace_hessian(i) + m_two*diff(k)*dfdr_over_r
508 end if
509 trace_hessian(i) = trace_hessian(i) + diff(i)*dfdr_over_r
510 trace_hessian(i) = trace_hessian(i) + diff(i)*diff(k)*diff(k)*d2fdr2_combination
511 end do
512 end do
513 end do
514
515 end function curv_gygi_trace_hessian
516
517 ! ---------------------------------------------------------
518 subroutine getf(y, f, jf)
519 real(real64), intent(in) :: y(:)
520 real(real64), intent(out) :: f(:), jf(:, :)
521
522 ! no PUSH_SUB, called too often
523
525 f = gygi_p%from_cartesian(y)
526 f(1:gygi_p%dim) = f(1:gygi_p%dim) - chi_p(1:gygi_p%dim)
527
528 end subroutine getf
529
530end module curv_gygi_oct_m
531
532!! Local Variables:
533!! mode: f90
534!! coding: utf-8
535!! End:
double exp(double __x) __attribute__((__nothrow__
double tanh(double __x) __attribute__((__nothrow__
double cosh(double __x) __attribute__((__nothrow__
This module implements the curvilinear coordinates given in F. Gygi and G. Galli, PRB 52 R2229 (1996)...
Definition: curv_gygi.F90:120
subroutine curv_gygi_write_info(this, iunit, namespace)
Definition: curv_gygi.F90:449
real(real64), dimension(:), allocatable chi_p
Definition: curv_gygi.F90:172
real(real64) pure function gygi_f(this, r)
Definition: curv_gygi.F90:286
real(real64) pure function gygi_d2fdr2_combination(this, r)
Definition: curv_gygi.F90:328
real(real64) pure function gygi_dfdr_over_r(this, r)
Definition: curv_gygi.F90:304
pure subroutine, public curv_gygi_hessian(this, xx, hessian, natoms)
Definition: curv_gygi.F90:536
real(real64) function, dimension(1:this%dim, 1:this%dim) curv_gygi_jacobian_inverse_cartesian(this, xx)
Definition: curv_gygi.F90:505
real(real64) function, dimension(1:this%dim) curv_gygi_trace_hessian(this, chi)
Definition: curv_gygi.F90:580
pure real(real64) function, dimension(1:this%dim) curv_gygi_from_cartesian(this, xx)
Definition: curv_gygi.F90:427
subroutine, public curv_gygi_copy(this_out, this_in)
Definition: curv_gygi.F90:253
real(real64) function, dimension(1:this%dim) curv_gygi_to_cartesian(this, chi)
Definition: curv_gygi.F90:355
subroutine getf(y, f, jf)
Definition: curv_gygi.F90:614
real(real64) function curv_gygi_surface_element(this, idir)
Definition: curv_gygi.F90:469
subroutine curv_gygi_to_cartesian_relaxed(this, chi, xx, conv)
Retry the root search with a reduced A, then increase A back. Kept out of curv_gygi_to_cartesian,...
Definition: curv_gygi.F90:390
class(curv_gygi_t) function, pointer curv_gygi_constructor(namespace, dim, npos, pos)
Definition: curv_gygi.F90:179
type(curv_gygi_t), allocatable, target gygi_relaxed
Definition: curv_gygi.F90:171
class(curv_gygi_t), pointer gygi_p
Definition: curv_gygi.F90:170
real(real64) function, dimension(1:this%dim, 1:this%dim) curv_gygi_jacobian(this, chi)
Definition: curv_gygi.F90:480
real(real64) function, dimension(1:this%dim, 1:this%dim) curv_gygi_jacobian_inverse(this, chi)
Definition: curv_gygi.F90:490
subroutine curv_gygi_finalize(this)
Definition: curv_gygi.F90:275
real(real64), parameter, public m_two
Definition: global.F90:202
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public m_four
Definition: global.F90:204
real(real64), parameter, public m_min_exp_arg
Definition: global.F90:219
real(real64), parameter, public m_half
Definition: global.F90:206
real(real64), parameter, public m_one
Definition: global.F90:201
real(real64), parameter, public m_three
Definition: global.F90:203
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:691
type(namespace_t), public global_namespace
Definition: namespace.F90:135
integer, parameter, public root_newton
subroutine, public root_solver_init(rs, namespace, dimensionality, solver_type, maxiter, rel_tolerance, abs_tolerance)
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
This module defines the unit system, used for input and output.
type(unit_system_t), public units_inp
the units systems for reading and writing
static double f(double w, void *p)
abstract class to describe coordinate systems
int true(void)