Octopus
curv_modine.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
28
31 use debug_oct_m
32 use global_oct_m
33 use, intrinsic :: iso_fortran_env
37 use parser_oct_m
40 use unit_oct_m
42
43 implicit none
44
45 private
46 public :: &
49
50 type, extends(coordinate_system_t) :: curv_modine_t
51 private
52 real(real64), allocatable :: lsize(:)
53 real(real64) :: xbar
54 real(real64) :: Jbar
55
56 real(real64), allocatable :: Jlocal(:)
57 real(real64), allocatable :: Jrange(:)
58
59 real(real64), allocatable :: xi(:,:)
60 real(real64), allocatable :: Q(:,:,:)
61
62 integer :: npos
63 type(root_solver_t) :: rs, rs_init
64 contains
65 procedure :: to_cartesian => curv_modine_to_cartesian
66 procedure :: from_cartesian => curv_modine_from_cartesian
67 procedure :: jacobian => curv_modine_jacobian
68 procedure :: jacobian_inverse => curv_modine_jacobian_inverse
69 procedure :: write_info => curv_modine_write_info
70 procedure :: surface_element => curv_modine_surface_element
72 end type curv_modine_t
73
74 interface curv_modine_t
75 procedure curv_modine_constructor
76 end interface curv_modine_t
77
78 ! Auxiliary variables for the root solver. They are threadprivate, as
79 ! from_cartesian is called from OpenMP regions. They must not be local
80 ! variables of from_cartesian, as getf would then need a trampoline on
81 ! the stack, which marks the stack as executable.
82 class(curv_modine_t), pointer :: modine_p
83 real(real64), allocatable :: x_p(:)
84 !$omp threadprivate(modine_p, x_p)
85
86contains
87
88 ! ---------------------------------------------------------
89 function curv_modine_constructor(namespace, dim, npos, pos, lsize, spacing) result(modine)
90 type(namespace_t), intent(in) :: namespace
91 integer, intent(in) :: dim
92 integer, intent(in) :: npos
93 real(real64), intent(in) :: pos(1:dim,1:npos)
94 real(real64), intent(in) :: lsize(1:dim)
95 real(real64), intent(in) :: spacing(1:dim)
96 class(curv_modine_t), pointer :: modine
97
98 integer :: iatom, n
99 real(real64) :: kappa(1:npos)
100 type(block_t) :: blk
101
103
104 safe_allocate(modine)
105
106 modine%dim = dim
107 modine%local_basis = .true.
108 modine%orthogonal = .true. ! This needs to be checked.
109
110 modine%npos = npos
111
112 safe_allocate(modine%lsize(1:dim))
113 modine%lsize = lsize
114
115 !%Variable CurvModineXBar
116 !%Type float
117 !%Default 0.25
118 !%Section Mesh::Curvilinear::Modine
119 !%Description
120 !% Size of central flat region (in units of <tt>2*Lsize</tt>). Must be between 0 and 1.
121 !% See N. A. Modine, G. Zumbach, and E. Kaxiras, <i>Phys. Rev. B</i> <b>55</b>, 10289-10301 (1997).
122 !%End
123 call parse_variable(namespace, 'CurvModineXBar', m_one/m_four, modine%xbar)
125 !%Variable CurvModineJBar
126 !%Type float
127 !%Default 0.5
128 !%Section Mesh::Curvilinear::Modine
129 !%Description
130 !% Increase in density of points is inverse of this parameter.
131 !% See N. A. Modine, G. Zumbach, and E. Kaxiras, <i>Phys. Rev. B</i> <b>55</b>, 10289-10301 (1997).
132 !%End
133 call parse_variable(namespace, 'CurvModineJBar', m_half, modine%Jbar)
134
135 if (modine%xbar < m_zero .or. modine%xbar > m_one) then
136 message(1) = 'The parameter "CurvModineXBar" must lie between 0 and 1.'
137 call messages_fatal(1, namespace=namespace)
138 end if
139 if (modine%Jbar <= modine%xbar) then
140 message(1) = 'The parameter "CurvModineJBar" must be larger than the parameter "CurvModineXBar".'
141 call messages_fatal(1, namespace=namespace)
142 end if
143
144 safe_allocate(modine%Jlocal(1:npos))
145 safe_allocate(modine%Jrange(1:npos))
146
147 !%Variable CurvModineJlocal
148 !%Type block
149 !%Default 0.125
150 !%Section Mesh::Curvilinear::Modine
151 !%Description
152 !% Local refinement around the atoms for each atom. If only one line is specified, the value is taken
153 !% for all atoms. Must be between 0 and 1.
154 !% See N. A. Modine, G. Zumbach, and E. Kaxiras, <i>Phys. Rev. B</i> <b>55</b>, 10289-10301 (1997).
155 !%End
156 if (parse_block(namespace, "CurvModineJlocal", blk) == 0) then
158 if (n == 1) then
159 call parse_block_float(blk, 0, 0, modine%Jlocal(1))
160 modine%Jlocal(:) = modine%Jlocal(1)
161 else if (n == npos) then
162 do iatom = 1, npos
163 call parse_block_float(blk, iatom - 1, 0, modine%Jlocal(iatom))
164 end do
165 else
166 write(message(1), '(3a,i2)') 'Error in block CurvModineJlocal: number of lines must be 1 or ', npos
167 call messages_fatal(1, namespace=namespace)
168 end if
169 else
170 ! for default value, see page 55, second paragraph
171 modine%Jlocal(:) = 0.125_real64
172 end if
173
174 do iatom = 1, npos
175 if (modine%Jlocal(iatom)<m_zero.or.modine%Jlocal(iatom)>m_one) then
176 message(1) = 'The parameter "CurvModineJlocal" must lie between 0 and 1.'
177 call messages_fatal(1, namespace=namespace)
178 end if
179 end do
180
181 !%Variable CurvModineJrange
182 !%Type block
183 !%Default 1.2 b
184 !%Section Mesh::Curvilinear::Modine
185 !%Description
186 !% Local refinement range (a length) for each atom. If only one line is specified, the value is
187 !% taken for all atoms.
188 !% See N. A. Modine, G. Zumbach, and E. Kaxiras, <i>Phys. Rev. B</i> <b>55</b>, 10289-10301 (1997).
189 !%End
190 if (parse_block(namespace, "CurvModineJrange", blk) == 0) then
191 n = parse_block_n(blk)
192 if (n == 1) then
193 call parse_block_float(blk, 0, 0, kappa(1), units_inp%length)
194 kappa(:) = kappa(1)
195 else if (n == npos) then
196 do iatom = 1, npos
197 call parse_block_float(blk, iatom - 1, 0, kappa(iatom), units_inp%length)
198 end do
199 else
200 write(message(1), '(3a,i2)') 'Error in block CurvModineJrange: number of lines must be 1 or ', npos
201 call messages_fatal(1, namespace=namespace)
202 end if
203 else
204 ! for default value, see page 55, second paragraph
205 kappa(:) = 1.2_real64
206 end if
207
208 ! solve eq. 18
209 do iatom = 1, npos
210 if (modine%Jlocal(iatom) > m_one-1e-5_real64) then
211 modine%Jrange(iatom) = kappa(iatom)
212 else
213 modine%Jrange(iatom) = kappa(iatom) / &
214 sqrt(m_one - product_log(-m_half*(((m_one+modine%Jlocal(1))/m_two)**m_third/(m_one-modine%Jlocal(iatom)**m_third)-m_one)&
215 *sqrt(m_e)))
216 end if
217 end do
218
219 ! initialize root solver for the inversion of the coordinates
220 call root_solver_init(modine%rs, namespace, dim, &
221 solver_type = root_newton, maxiter = 500, abs_tolerance = 1.0e-13_real64)
222
223 safe_allocate(modine%xi(1:modine%dim, 1:modine%npos))
224 safe_allocate(modine%Q(1:modine%dim, 1:modine%dim, 1:modine%npos))
225 call optimize()
226
227 modine%min_mesh_scaling_product = modine%Jbar**modine%dim
228
230 contains
231
232 ! product log function, i.e., the inverse of x exp(x)
233 real(real64) pure function product_log(x)
234 real(real64), intent(in) :: x
235
236 ! no push_sub/pop_sub, pure function
237
238 ! Third-order Taylor expansion around 0
239 product_log = x * (m_one + x * (-m_one + m_three*m_half*x))
240 end function product_log
241
242 subroutine optimize()
243 integer :: iatom, idim
244 real(real64), allocatable :: xi_tmp(:, :), q_tmp(:, :, :)
245 real(real64) :: residue, rr2, dd
246 integer :: iter, nu, mu, idim1, idim2
247 integer, parameter :: maxiter = 1000
248 real(real64), parameter :: tolerance = 1.0e-10_real64
249
251
252 safe_allocate(xi_tmp(1:modine%dim, 1:modine%npos))
253 safe_allocate(q_tmp(1:modine%dim, 1:modine%dim, 1:modine%npos))
254
255 ! initial guess: xi = R, Q = delta (1-J**1/3)
256 modine%Q(:, :, :) = m_zero
257 do iatom = 1, modine%npos
258 modine%xi(:, iatom) = pos(:, iatom)
259 do idim = 1, modine%dim
260 modine%Q(idim, idim, iatom) = m_one-modine%Jlocal(iatom)**(m_one/real(modine%dim, real64))
261 end do
262 end do
263
264 ! relaxation method to solve eq. 16 and 17
265 do iter = 1, maxiter
266 ! copy current values to temporary arrays
267 xi_tmp(:, :) = modine%xi(:, :)
268 q_tmp(:, :, :) = modine%Q(:, :, :)
269
270 modine%Q(:, :, :) = m_zero
271 do mu = 1, modine%npos
272 ! right-hand side
273 modine%xi(:, mu) = pos(:, mu)
274 do idim = 1, modine%dim
275 ! right-hand side and diagonal part
276 modine%Q(idim, idim, mu) = m_one-modine%Jlocal(mu)**(m_one/real(modine%dim, real64))
277 end do
278 do nu = 1, modine%npos
279 if (mu == nu) cycle
280 rr2 = sum((xi_tmp(:, mu) - xi_tmp(:, nu))**2)
281 dd = exp(-rr2/(m_two*modine%Jrange(nu)**2))
282
283 modine%xi(:, mu) = modine%xi(:, mu) + &
284 matmul(modine%Q(:, :, mu), xi_tmp(:, mu) - xi_tmp(:, nu)) * dd
285
286 do idim1 = 1, modine%dim
287 do idim2 = 1, modine%dim
288 modine%Q(idim1, idim2, mu) = modine%Q(idim1, idim2, mu) - q_tmp(idim1, idim2, nu) * dd
289 modine%Q(idim1, idim2, mu) = modine%Q(idim1, idim2, mu) + &
290 sum(q_tmp(idim1, :, nu)*(xi_tmp(:, mu) - xi_tmp(:, nu)))*(xi_tmp(idim2, mu) - xi_tmp(idim2, nu)) * &
291 m_one/modine%Jrange(nu) * dd
292 end do
293 end do
294 end do
295 end do
296
297 ! compute residue
298 residue = norm2(xi_tmp(:, :) - modine%xi(:, :)) / real(modine%dim*modine%npos, real64)
299 residue = residue + norm2(q_tmp(:, :, :) - modine%Q(:, :, :)) / real(modine%dim*modine%dim*modine%npos, real64)
300 if (residue <= tolerance) exit
301 end do
302
303 ! check for convergence
304 if (residue > tolerance) then
305 message(1) = "During the construction of the adaptive grid, the relaxation"
306 message(2) = "method did not converge."
307 message(3) = "This might be due to values of CurvModineJrange that are too large"
308 message(4) = "or CurvModineJlocal that are too small."
309 call messages_fatal(4, namespace=namespace)
310 end if
311
312
313 safe_deallocate_a(xi_tmp)
314 safe_deallocate_a(q_tmp)
315
317 end subroutine optimize
318
319 end function curv_modine_constructor
320
321 ! ---------------------------------------------------------
322 subroutine curv_modine_copy(this_out, this_in)
323 type(curv_modine_t), intent(inout) :: this_out
324 type(curv_modine_t), intent(in) :: this_in
325
326 push_sub(curv_modine_copy)
327
328 this_out%dim = this_in%dim
329 this_out%local_basis = this_in%local_basis
330 safe_allocate_source_a(this_out%lsize, this_in%lsize)
331 this_out%xbar = this_in%xbar
332 this_out%Jbar = this_in%Jbar
333 safe_allocate_source_a(this_out%Jlocal, this_in%Jlocal)
334 safe_allocate_source_a(this_out%Jrange, this_in%Jrange)
335 safe_allocate_source_a(this_out%xi, this_in%xi)
336 safe_allocate_source_a(this_out%Q, this_in%Q)
337 this_out%npos = this_in%npos
338
339 pop_sub(curv_modine_copy)
340 end subroutine curv_modine_copy
341
342 ! ---------------------------------------------------------
343 subroutine curv_modine_finalize(this)
344 type(curv_modine_t), intent(inout) :: this
345
346 push_sub(curv_modine_finalize)
347
348 safe_deallocate_a(this%lsize)
349 safe_deallocate_a(this%Jlocal)
350 safe_deallocate_a(this%Jrange)
351 safe_deallocate_a(this%xi)
352 safe_deallocate_a(this%Q)
353
354 pop_sub(curv_modine_finalize)
355 end subroutine curv_modine_finalize
356
357 ! ---------------------------------------------------------
358 function curv_modine_to_cartesian(this, chi) result(xx)
359 class(curv_modine_t), target, intent(in) :: this
360 real(real64), intent(in) :: chi(:)
361 real(real64) :: xx(1:this%dim)
362
363 real(real64) :: chi2(this%dim), rr2, dd
364 integer :: iatom
365
366 ! no PUSH_SUB, called too often
367
368 ! eq. 14
369 call curv_modine_chi2chi2(this, chi, chi2)
370
371 ! eq. 15
372 xx(:) = chi2(:)
373 do iatom = 1, this%npos
374 rr2 = sum((chi2(:) - this%xi(:, iatom))**2)
375 dd = exp(-rr2/(m_two*this%Jrange(iatom)**2))
376
377 xx(:) = xx(:) - matmul(this%Q(:, :, iatom), chi2(:) - this%xi(:, iatom)) * dd
378 end do
379
380 end function curv_modine_to_cartesian
381
382 ! ---------------------------------------------------------
383 function curv_modine_from_cartesian(this, xx) result(chi)
384 class(curv_modine_t), target, intent(in) :: this
385 real(real64), intent(in) :: xx(:)
386 real(real64) :: chi(1:this%dim)
387
388 logical :: conv
389 real(real64) :: start(1:this%dim)
390 integer :: i
391
392 ! no PUSH_SUB, called too often
393
394 modine_p => this
395 safe_allocate(x_p(1:this%dim))
396 x_p(:) = xx(:)
397
398 ! get a better starting point for the global backdrop
399 do i = 1, this%dim
400 if (abs(xx(i)) > this%lsize(i)) then
401 start(i) = xx(i)
402 else if (abs(xx(i)) > this%xbar*this%lsize(i)) then
403 ! linear interpolation between the two cases
404 start(i) = sign(m_one, xx(i)) * (abs(xx(i))/this%Jbar + abs(xx(i)) *(m_one - m_one/this%Jbar) * &
405 (abs(xx(i)) - this%xbar*this%lsize(i)) / (this%lsize(i) - this%xbar*this%lsize(i)))
406 ! ensure that we stay in the bounds
407 if (abs(start(i)) >= this%lsize(i)) then
408 start(i) = sign(this%lsize(i), xx(i))
409 end if
410 else
411 start(i) = xx(i)/this%Jbar
412 end if
413 end do
414
415 call droot_solver_run(this%rs, getf, chi, conv, startval=start)
416
417 safe_deallocate_a(x_p)
418 nullify(modine_p)
419
420 if (.not. conv) then
421 message(1) = "During the construction of the adaptive grid, the Newton-Raphson"
422 message(2) = "method did not converge for point:"
423 write(message(3),'(3f14.6)') xx(1:this%dim)
424 call messages_fatal(3)
425 end if
426
427 end function curv_modine_from_cartesian
428
429 ! ---------------------------------------------------------
430 subroutine curv_modine_write_info(this, iunit, namespace)
431 class(curv_modine_t), intent(in) :: this
432 integer, optional, intent(in) :: iunit
433 type(namespace_t), optional, intent(in) :: namespace
434
435 push_sub(curv_modine_write_info)
436
437 write(message(1), '(a)') ' Curvilinear Method = modine'
438 call messages_info(1, iunit=iunit, namespace=namespace)
439
441 end subroutine curv_modine_write_info
442
443 ! ---------------------------------------------------------
444 real(real64) function curv_modine_surface_element(this, idir) result(ds)
445 class(curv_modine_t), intent(in) :: this
446 integer, intent(in) :: idir
447
448 ds = m_zero
449 message(1) = 'Surface element with modine curvilinear coordinates not implemented'
450 call messages_fatal(1)
451
452 end function curv_modine_surface_element
454 ! ---------------------------------------------------------
455 pure subroutine curv_modine_chi2chi2(this, chi_, chi2, Jac)
456 class(curv_modine_t), intent(in) :: this
457 real(real64), intent(in) :: chi_(:)
458 real(real64), contiguous, intent(out) :: chi2(:)
459 real(real64), contiguous, optional, intent(out) :: jac(:)
460
461 integer, parameter :: qq = 3
462 real(real64) :: chibar(this%dim), rr, chi
463 logical :: neg
464 integer :: i
465
466 ! no PUSH_SUB, called too often
467
468 chibar = this%xbar*this%lsize/this%Jbar
469
470 do i = 1, this%dim
471 neg = (chi_(i) < 0)
472 chi = abs(chi_(i))
473
474 chi2(i) = this%Jbar * chi
475 if (present(jac)) jac(i) = this%Jbar
476
477 if (chi > this%lsize(i)) then
478 ! needed for boundary points
479 chi2(i) = chi
480 if (present(jac)) jac(i) = m_one
481 else if (chi > chibar(i)) then
482 rr = (chi - chibar(i))/(this%lsize(i) - chibar(i))
483
484 chi2(i) = chi2(i) + this%lsize(i)/m_two*(1 - this%Jbar) * rr**qq * &
485 (qq + m_one - (qq - m_one)*rr)
486
487 if (present(jac)) then
488 jac(i) = jac(i) + this%lsize(i)/m_two*(m_one - this%Jbar) * rr**(qq - 1)/(this%lsize(i) - chibar(i)) * &
489 (qq*(qq + m_one) - (qq**2 - m_one)*rr)
490 end if
491 end if
492
493 if (neg) chi2(i) = -chi2(i)
494 ! CHECK if Jacobian does not have to be negated!
495 end do
496
497 end subroutine curv_modine_chi2chi2
498
499 ! ---------------------------------------------------------
500 ! Jacobian for the coordinate transformation, i.e. for eqs. 14 and 15
501 pure subroutine curv_modine_jacobian_inv(this, chi, xx, Jac)
502 type(curv_modine_t), intent(in) :: this
503 real(real64), intent(in) :: chi(:)
504 real(real64), intent(out) :: xx(:)
505 real(real64), intent(out) :: jac(:, :)
506
507 real(real64) :: chi2(this%dim), rr2, dd, j2(this%dim)
508 integer :: iatom, idim, idim2
509
510 ! no PUSH_SUB, called too often
511
512 call curv_modine_chi2chi2(this, chi, chi2, j2)
513
514 ! initialize both xx and the Jacobian
515 xx(:) = chi2(:)
516 jac(:,:) = m_zero
517 do idim = 1, this%dim
518 jac(idim, idim) = m_one
519 end do
520
521 do iatom = 1, this%npos
522 rr2 = sum((chi2(:) - this%xi(:, iatom))**2)
523 dd = exp(-rr2/(m_two*this%Jrange(iatom)**2))
524
525 xx(:) = xx(:) - matmul(this%Q(:, :, iatom), chi2(:) - this%xi(:, iatom)) * dd
526
527 do idim = 1, this%dim
528 do idim2 = 1, this%dim
529 jac(idim, idim2) = jac(idim, idim2) - this%Q(idim, idim2, iatom) * dd
530 jac(idim, idim2) = jac(idim, idim2) + &
531 sum(this%Q(idim, :, iatom)*(chi2(:) - this%xi(:, iatom)))*(chi2(idim2) - this%xi(idim2, iatom)) * &
532 m_one/this%Jrange(iatom) * dd
533 end do
534 end do
535 end do
536
537 do idim = 1, this%dim
538 jac(idim, :) = jac(idim, :) * j2(:)
539 end do
540
541 end subroutine curv_modine_jacobian_inv
542
543 ! ---------------------------------------------------------
544 pure subroutine getf(yy, ff, jf)
545 real(real64), intent(in) :: yy(:)
546 real(real64), intent(out) :: ff(:), jf(:, :)
547
548 ! no PUSH_SUB, called too often
549
551 ff(:) = ff(:) - x_p(:)
552
553 end subroutine getf
554
555 ! ---------------------------------------------------------
556 function curv_modine_jacobian(this, chi) result(jacobian)
557 class(curv_modine_t), intent(in) :: this
558 real(real64), intent(in) :: chi(:)
559 real(real64) :: jacobian(1:this%dim, 1:this%dim)
560
561 real(real64) :: dummy(this%dim)
562
563 call curv_modine_jacobian_inv(this, chi, dummy, jacobian)
564
565 end function curv_modine_jacobian
566
567 ! ---------------------------------------------------------
568 function curv_modine_jacobian_inverse(this, chi) result(jacobian_inverse)
569 class(curv_modine_t), intent(in) :: this
570 real(real64), intent(in) :: chi(:)
571 real(real64) :: jacobian_inverse(1:this%dim, 1:this%dim)
572
573 real(real64) :: dummy(this%dim)
574
575 call curv_modine_jacobian_inv(this, chi, dummy, jacobian_inverse)
576 call lalg_inverse(this%dim, jacobian_inverse, "dir")
577
579
580end module curv_modine_oct_m
581
582!! Local Variables:
583!! mode: f90
584!! coding: utf-8
585!! End:
subroutine optimize()
real(real64) pure function product_log(x)
double exp(double __x) __attribute__((__nothrow__
This module implements the curvilinear coordinates given in N. A. Modine, G. Zumbach,...
class(curv_modine_t), pointer modine_p
real(real64) function, dimension(1:this%dim) curv_modine_from_cartesian(this, xx)
real(real64) function curv_modine_surface_element(this, idir)
real(real64) function, dimension(1:this%dim, 1:this%dim) curv_modine_jacobian_inverse(this, chi)
pure subroutine curv_modine_jacobian_inv(this, chi, xx, Jac)
real(real64) function, dimension(1:this%dim, 1:this%dim) curv_modine_jacobian(this, chi)
class(curv_modine_t) function, pointer curv_modine_constructor(namespace, dim, npos, pos, lsize, spacing)
pure subroutine getf(yy, ff, jf)
subroutine curv_modine_finalize(this)
real(real64), dimension(:), allocatable x_p
pure subroutine curv_modine_chi2chi2(this, chi_, chi2, Jac)
subroutine, public curv_modine_copy(this_out, this_in)
subroutine curv_modine_write_info(this, iunit, namespace)
real(real64) function, dimension(1:this%dim) curv_modine_to_cartesian(this, chi)
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_third
Definition: global.F90:207
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
real(real64), parameter, public m_e
Definition: global.F90:199
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:623
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
abstract class to describe coordinate systems
int true(void)