Octopus
math.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
22module math_oct_m
23 use debug_oct_m
24 use global_oct_m
25 use, intrinsic :: iso_fortran_env
30
31 implicit none
32
33 private
34 public :: &
35 is_close, &
37 ylmr_cmplx, &
38 ylmr_real, &
39 weights, &
40 factorial, &
41 hermite, &
46 ddelta, &
47 member, &
51 even, &
52 odd, &
56 pad, &
57 pad_pow2, &
58 log2, &
60 phi1, &
61 phi2, &
63 is_prime, &
71
72
73 interface is_close
74 module procedure dis_close_scalar, zis_close_scalar
75 end interface
76
77 interface diagonal_matrix
79 end interface diagonal_matrix
80
84
88
89
90 ! ------------------------------------------------------------------------------
93 interface interpolate
96 end interface interpolate
97 ! ------------------------------------------------------------------------------
98
99 interface log2
100 module procedure dlog2, ilog2, llog2
101 end interface log2
102
103 interface pad
104 module procedure pad4, pad8, pad48, pad88
105 end interface pad
106
107contains
108
127 elemental logical function dis_close_scalar(x, y, rtol, atol)
128 real(real64), intent(in) :: x, y
129 real(real64), optional, intent(in) :: rtol
130 real(real64), optional, intent(in) :: atol
131 real(real64) :: atol_, rtol_
132
133 atol_ = optional_default(atol, 1.e-8_real64)
134 rtol_ = optional_default(rtol, 1.e-5_real64)
135
136 dis_close_scalar = abs(x - y) <= (atol_ + rtol_ * abs(y))
137 end function dis_close_scalar
138
140 elemental logical function zis_close_scalar(x, y, rtol, atol)
141 complex(real64), intent(in) :: x, y
142 real(real64), optional, intent(in) :: rtol
143 real(real64), optional, intent(in) :: atol
144 real(real64) :: atol_, rtol_
145
146 atol_ = optional_default(atol, 1.e-8_real64)
147 rtol_ = optional_default(rtol, 1.e-5_real64)
148
149 zis_close_scalar = abs(x - y) <= (atol_ + rtol_ * abs(y))
150 end function zis_close_scalar
151
152
153 ! ---------------------------------------------------------
156 pure function idiagonal_matrix(dim, diag) result(matrix)
157 integer, intent(in) :: dim
158 integer, intent(in) :: diag
159 integer :: matrix(dim, dim)
160
161 integer :: ii
162
163 matrix = 0
164 do ii = 1, dim
165 matrix(ii, ii) = diag
166 end do
167
168 end function idiagonal_matrix
169
170 ! ---------------------------------------------------------
171 recursive function hermite(n, x) result (h)
172 integer, intent(in) :: n
173 real(real64), intent(in) :: x
175 real(real64) :: h
176
177 ! no push_sub, called too frequently
179 if (n <= 0) then
180 h = m_one
181 elseif (n == 1) then
182 h = m_two*x
183 else
184 h = m_two*x*hermite(n-1,x) - m_two*(n-1)*hermite(n-2,x)
185 end if
187 end function hermite
188
189
190 ! ---------------------------------------------------------
191 recursive function factorial (n) RESULT (fac)
192 integer, intent(in) :: n
193
194 integer :: fac
195
196 ! no push_sub for recursive function
197
198 if (n <= 1) then
199 fac = 1
200 else
201 fac = n * factorial(n-1)
202 end if
203 end function factorial
204
205 ! ---------------------------------------------------------
207 subroutine ylmr_cmplx(xx, li, mi, ylm)
208 real(real64), intent(in) :: xx(3)
209 integer, intent(in) :: li, mi
210 complex(real64), intent(out) :: ylm
211
212 integer :: i
213 real(real64) :: dx, dy, dz, r, plm, cosm, sinm, cosmm1, sinmm1, cosphi, sinphi
214 real(real64), parameter :: tiny = 1.e-15_real64
215
216 ! no push_sub: this routine is called too many times
217
218 ! if l=0, no calculations are required
219 if (li == 0) then
220 ylm = cmplx(sqrt(m_one/(m_four*m_pi)), m_zero, real64)
221 return
222 end if
223
224 r = sqrt(xx(1)**2 + xx(2)**2 + xx(3)**2)
225
226 ! if r=0, direction is undefined => make ylm=0 except for l=0
227 if (r <= tiny) then
228 ylm = m_z0
229 return
230 end if
231 dx = xx(1)/r
232 dy = xx(2)/r
233 dz = xx(3)/r
234
235 ! get the associated Legendre polynomial (including the normalization factor)
236 ! We need to avoid getting outside [-1:1] due to rounding errors
237 if(abs(dz) > m_one) dz = sign(m_one, dz)
238 plm = loct_legendre_sphplm(li, abs(mi), dz)
239
240 ! compute sin(|m|*phi) and cos(|m|*phi)
241 r = sqrt(dx*dx + dy*dy)
242 if(r > tiny) then
243 cosphi = dx/r
244 sinphi = dy/r
245 else ! In this case the values are ill defined so we choose \phi=0
246 cosphi = m_zero
247 sinphi = m_zero
248 end if
250 cosm = m_one
251 sinm = m_zero
252 do i = 1, abs(mi)
253 cosmm1 = cosm
254 sinmm1 = sinm
255 cosm = cosmm1*cosphi - sinmm1*sinphi
256 sinm = cosmm1*sinphi + sinmm1*cosphi
257 end do
258
259 !And now ylm
260 ylm = plm*cmplx(cosm, sinm, real64)
261
262 if (mi < 0) then
263 ylm = conjg(ylm)
264 do i = 1, abs(mi)
265 ylm = -ylm
266 end do
267 end if
268
269 end subroutine ylmr_cmplx
270
271
272 ! ---------------------------------------------------------
278 subroutine ylmr_real(xx, li, mi, ylm)
279 real(real64), intent(in) :: xx(3)
280 integer, intent(in) :: li, mi
281 real(real64), intent(out) :: ylm
282
283 integer, parameter :: lmaxd = 20
284 real(real64), parameter :: tiny = 1.e-15_real64
285 integer :: i, ilm0, l, m, mabs
286 integer, save :: lmax = -1
287
288 real(real64) :: cmi, cosm, cosmm1, cosphi, dphase, dplg, fac, &
289 fourpi, plgndr, phase, pll, pmm, pmmp1, sinm, &
290 sinmm1, sinphi, rsize, rx, ry, rz, xysize
291 real(real64), save :: c(0:(lmaxd+1)*(lmaxd+1))
292
293 ! no push_sub: called too frequently
294
295 ! evaluate normalization constants once and for all
296 if (li > lmax) then
297 fourpi = m_four*m_pi
298 do l = 0, li
299 ilm0 = l*l + l
300 do m = 0, l
301 fac = (2*l+1)/fourpi
302 do i = l - m + 1, l + m
303 fac = fac/i
304 end do
305 c(ilm0 + m) = sqrt(fac)
306 ! next line because ylm are real combinations of m and -m
307 if (m /= 0) c(ilm0 + m) = c(ilm0 + m)*sqrt(m_two)
308 c(ilm0 - m) = c(ilm0 + m)
309 end do
310 end do
311 lmax = li
312 end if
313
314 ! if l=0, no calculations are required
315 if (li == 0) then
316 ylm = c(0)
317 return
318 end if
319
320 ! if r=0, direction is undefined => make ylm=0 except for l=0
321 rsize = sqrt(xx(1)**2 + xx(2)**2 + xx(3)**2)
322 if (rsize < tiny) then
323 ylm = m_zero
324 return
325 end if
326
327 rx = xx(1)/rsize
328 ry = xx(2)/rsize
329 rz = xx(3)/rsize
330
331 ! explicit formulas for l=1 and l=2
332 if (li == 1) then
333 select case (mi)
334 case (-1)
335 ylm = (-c(1))*ry
336 case (0)
337 ylm = c(2)*rz
338 case (1)
339 ylm = (-c(3))*rx
340 end select
341 return
342 end if
343
344 if (li == 2) then
345 select case (mi)
346 case (-2)
347 ylm = c(4)*6.0_real64*rx*ry
348 case (-1)
349 ylm = (-c(5))*m_three*ry*rz
350 case (0)
351 ylm = c(6)*m_half*(m_three*rz*rz - m_one)
352 case (1)
353 ylm = (-c(7))*m_three*rx*rz
354 case (2)
355 ylm = c(8)*m_three*(rx*rx - ry*ry)
356 end select
357 return
358 end if
359
360 ! general algorithm based on routine plgndr of numerical recipes
361 mabs = abs(mi)
362 xysize = sqrt(max(rx*rx + ry*ry, tiny))
363 cosphi = rx/xysize
364 sinphi = ry/xysize
365 cosm = m_one
366 sinm = m_zero
367 do m = 1, mabs
368 cosmm1 = cosm
369 sinmm1 = sinm
370 cosm = cosmm1*cosphi - sinmm1*sinphi
371 sinm = cosmm1*sinphi + sinmm1*cosphi
372 end do
373
374 if (mi < 0) then
375 phase = sinm
376 dphase = mabs*cosm
377 else
378 phase = cosm
379 dphase = (-mabs)*sinm
380 end if
381
382 pmm = m_one
383 fac = m_one
384
385 if (mabs > m_zero) then
386 do i = 1, mabs
387 pmm = (-pmm)*fac*xysize
388 fac = fac + m_two
389 end do
390 end if
391
392 if (li == mabs) then
393 plgndr = pmm
394 dplg = (-li)*rz*pmm/(xysize**2)
395 else
396 pmmp1 = rz*(2*mabs + 1)*pmm
397 if (li == mabs + 1) then
398 plgndr = pmmp1
399 dplg = -((li*rz*pmmp1 - (mabs + li)*pmm)/(xysize**2))
400 else
401 do l = mabs + 2, li
402 pll = (rz*(2*l - 1)*pmmp1 - (l + mabs - 1)*pmm)/(l - mabs)
403 pmm = pmmp1
404 pmmp1 = pll
405 end do
406 plgndr = pll
407 dplg = -((li*rz*pll - (l + mabs - 1)*pmm)/(xysize**2))
408 end if
409 end if
410
411 ilm0 = li*li + li
412 cmi = c(ilm0 + mi)
413 ylm = cmi*plgndr*phase
414
415 end subroutine ylmr_real
416
417
418 ! ---------------------------------------------------------
428 subroutine weights(N, M, cc, side)
429 integer, intent(in) :: n, m
430 real(real64), intent(out) :: cc(0:,0:,0:)
431 integer, optional, intent(in) :: side
432
433 integer :: i, j, k, mn, side_
434 real(real64) :: c1, c2, c3, c4, c5, xi
435 real(real64), allocatable :: x(:)
436
437 push_sub(weights)
438
439 safe_allocate(x(0:m))
440
441 if (present(side)) then
442 side_ = side
443 else
444 side_ = 0
445 end if
446
447 select case (side_)
448 case (-1)
449 ! grid-points for left-side finite-difference formulas on an equi-spaced grid
450 mn = m
451 x(:) = (/(-i,i=0,mn)/)
452 case (+1)
453 ! grid-points for right-side finite-difference formulas on an equi-spaced grid
454 mn = m
455 x(:) = (/(i,i=0,mn)/)
456 case default
457 ! grid-points for centered finite-difference formulas on an equi-spaced grid
458 mn = m/2
459 x(:) = (/0,(-i,i,i=1,mn)/)
460 end select
461
462
463
464 xi = m_zero ! point at which the approx. are to be accurate
465
466 cc = m_zero
467 cc(0,0,0) = m_one
468
469 c1 = m_one
470 c4 = x(0) - xi
471
472 do j = 1, m
473 mn = min(j,n)
474 c2 = m_one
475 c5 = c4
476 c4 = x(j) - xi
477
478 do k = 0, j - 1
479 c3 = x(j) - x(k)
480 c2 = c2*c3
481
482 if (j <= n) cc(k, j - 1, j) = m_zero
483 cc(k, j, 0) = c4*cc(k, j - 1, 0)/c3
484
485 do i = 1, mn
486 cc(k, j, i) = (c4*cc(k, j - 1, i) - i*cc(k, j - 1, i - 1))/c3
487 end do
488
489 cc(j, j, 0) = -c1*c5*cc(j - 1, j - 1, 0) / c2
490 end do
491
492 do i = 1, mn
493 cc(j, j, i) = c1*(i*cc(j - 1, j - 1, i - 1) - c5*cc(j - 1, j - 1, i))/c2
494 end do
495
496 c1 = c2
497 end do
498
499 safe_deallocate_a(x)
500 pop_sub(weights)
501 end subroutine weights
502
503 ! ---------------------------------------------------------
504 real(real64) pure function ddelta(i, j)
505 integer, intent(in) :: i
506 integer, intent(in) :: j
507
508 ! no push_sub in pure function
509
510 if (i == j) then
511 ddelta = m_one
512 else
513 ddelta = m_zero
514 end if
515
516 end function ddelta
517
518
519 ! ---------------------------------------------------------
522 subroutine make_idx_set(n, out, length, in)
523 integer, intent(in) :: n
524 integer, allocatable, intent(out) :: out(:)
525 integer, intent(out) :: length
526 integer, optional, intent(in) :: in(:)
527
528 integer :: i
529
530 push_sub(make_idx_set)
531
532 if (present(in)) then
533 length = ubound(in, 1)
534 safe_allocate(out(1:length))
535 out = in
536 else
537 length = n
538 safe_allocate(out(1:length))
539 do i = 1, length
540 out(i) = i
541 end do
542 end if
543
544 pop_sub(make_idx_set)
545 end subroutine make_idx_set
546
547
548 ! ---------------------------------------------------------
551 logical function member(n, a)
552 integer, intent(in) :: n
553 integer, intent(in) :: a(:)
554
555 integer :: i
556
557 ! no push_sub, called too frequently
558
559 member = .false.
560
561 do i = 1, ubound(a, 1)
562 if (a(i) == n) then
563 member = .true.
564 exit
565 end if
566 end do
567
568 end function member
569
570
571 ! ---------------------------------------------------------
572 subroutine interpolation_coefficients(nn, xa, xx, cc)
573 integer, intent(in) :: nn
574 real(real64), intent(in) :: xa(:)
575 real(real64), intent(in) :: xx
576 real(real64), intent(out) :: cc(:)
577
578 integer :: ii, kk
579
580 ! no push_sub, called too frequently
581
582 do ii = 1, nn
583 cc(ii) = m_one
584 do kk = 1, nn
585 if (kk == ii) cycle
586 cc(ii) = cc(ii)*(xx - xa(kk))/(xa(ii) - xa(kk))
587 end do
588 end do
589
590 end subroutine interpolation_coefficients
591
592
593 ! ---------------------------------------------------------
595 logical pure function even(n)
596 integer, intent(in) :: n
598 even = (mod(n, 2) == 0)
599
600 end function even
601
602
603 ! ---------------------------------------------------------
605 logical pure function odd(n)
606 integer, intent(in) :: n
607
608 odd = .not. even(n)
609
610 end function odd
611
612 ! ---------------------------------------------------------
616 real(real64), intent(in) :: x(:)
617 real(real64), intent(out) :: u(:)
618
619 integer :: n, k, j
620 real(real64) :: sumx2
621 real(real64), allocatable :: xx(:)
622
624
625 n = size(x)
626 assert(n>1)
627 assert(size(u) == n-1)
628
629 ! These lines make the code less machine-dependent.
630 safe_allocate(xx(1:n))
631 do j = 1, n
632 if (abs(x(j))<1.0e-8_real64) then
633 xx(j) = m_zero
634 else
635 xx(j) = x(j)
636 end if
637 end do
638
639 u = m_zero
640 do k = 1, n-1
641 sumx2 = m_zero
642 do j = k+1, n
643 sumx2 = sumx2 + xx(j)**2
644 end do
645 if (abs(sumx2) <= m_epsilon .and. abs(xx(k)) <= m_epsilon) exit
646 if (k < n - 1) then
647 u(k) = atan2(sqrt(sumx2), xx(k))
648 else
649 u(n-1) = atan2(xx(n), xx(n-1))
650 end if
651 end do
652
653
655 end subroutine cartesian2hyperspherical
656 ! ---------------------------------------------------------
657
658
659 ! ---------------------------------------------------------
662 subroutine hyperspherical2cartesian(u, x)
663 real(real64), intent(in) :: u(:)
664 real(real64), intent(out) :: x(:)
666 integer :: n, j, k
667
669
670 n = size(x)
671 assert(n>1)
672 assert(size(u) == n-1)
673
674 if (n == 2) then
675 x(1) = cos(u(1))
676 x(2) = sin(u(1))
677 elseif (n == 3) then
678 x(1) = cos(u(1))
679 x(2) = sin(u(1))*cos(u(2))
680 x(3) = sin(u(1))*sin(u(2))
681 else
682 x(1) = cos(u(1))
683 x(2) = sin(u(1))*cos(u(2))
684 x(3) = sin(u(1))*sin(u(2))*cos(u(3))
685 do j = 4, n - 1
686 x(j) = m_one
687 do k = 1, j - 1
688 x(j) = x(j) * sin(u(k))
689 end do
690 x(j) = x(j) * cos(u(j))
691 end do
692 x(n) = m_one
693 do k = 1, n - 2
694 x(n) = x(n) * sin(u(k))
695 end do
696 x(n) = x(n) * sin(u(n-1))
697 end if
700 end subroutine hyperspherical2cartesian
701 ! ---------------------------------------------------------
702
703
704 ! ---------------------------------------------------------
708 subroutine hypersphere_grad_matrix(grad_matrix, r, x)
709 real(real64), intent(out) :: grad_matrix(:,:)
710 real(real64), intent(in) :: r
711 real(real64), intent(in) :: x(:)
712
713 integer :: n, l, m
714
716
717 n = size(x)+1 ! the dimension of the matrix is (n-1)x(n)
718
719 ! --- l=1 ---
720 grad_matrix = m_one
721 grad_matrix(1,1) = -r*sin(x(1))
722 do m = 2, n-1
723 grad_matrix(m,1) = m_zero
724 end do
725
726 ! --- l=2..(n-1) ---
727 do l=2, n-1
728 do m=1, n-1
729 if (m == l) then
730 grad_matrix(m,l) = -r*grad_matrix(m,l)*product(sin(x(1:l)))
731 elseif (m < l) then
732 grad_matrix(m,l) = grad_matrix(m,l)*r*cos(x(m))*cos(x(l))*product(sin(x(1:m-1)))*product(sin(x(m+1:l-1)))
733 else
734 grad_matrix(m,l) = m_zero
735 end if
736 end do
737 end do
738
739 ! --- l=n ---
740 do m=1, n-1
741 grad_matrix(m,n) = r*cos(x(m))*grad_matrix(m,n)*product(sin(x(1:m-1)))*product(sin(x(m+1:n-1)))
742 end do
743
745 end subroutine hypersphere_grad_matrix
746
747 ! ---------------------------------------------------------
748 integer(int64) pure function pad88(size, blk)
749 integer(int64), intent(in) :: size
750 integer(int64), intent(in) :: blk
751
752 integer(int64) :: mm
753
754 mm = mod(size, blk)
755 if (mm == 0) then
756 pad88 = size
757 else
758 pad88 = size + blk - mm
759 end if
760 end function pad88
761
762 ! ---------------------------------------------------------
763 integer(int64) pure function pad48(size, blk)
764 integer, intent(in) :: size
765 integer(int64), intent(in) :: blk
766
767 pad48 = pad88(int(size, int64), blk)
768 end function pad48
769
770 ! ---------------------------------------------------------
771 integer(int64) pure function pad8(size, blk)
772 integer(int64), intent(in) :: size
773 integer, intent(in) :: blk
774
775 pad8 = pad88(size, int(blk, int64))
776 end function pad8
777
778 ! ---------------------------------------------------------
779 integer pure function pad4(size, blk)
780 integer, intent(in) :: size
781 integer, intent(in) :: blk
782
783 pad4 = int(pad88(int(size, int64), int(blk, int64)), int32)
784 end function pad4
785
786 ! ---------------------------------------------------------
787
792 integer pure function pad_pow2(size)
793 integer, intent(in) :: size
794
795 integer :: mm, mm2
796
797 mm = size
798 pad_pow2 = 1
799
800 ! loop below never terminates otherwise! just pick 1 as value.
801 if (size == 0) return
802
803 ! first we divide by two all the times we can, so we catch exactly
804 ! the case when size is already a power of two
805 do
806 mm2 = mm/2
807 if (mm - 2*mm2 /= 0) exit
809 mm = mm2
810 end do
811
812 ! the rest is handled by log2
813 if (mm /= 1) then
814 pad_pow2 = pad_pow2*2**(ceiling(log(real(mm, real64) )/log(2.0_8)))
815 end if
816
817 end function pad_pow2
818
819 ! -------------------------------------------------------
820
821 real(real64) pure function dlog2(xx)
822 real(real64), intent(in) :: xx
823
824 dlog2 = log(xx)/log(m_two)
825 end function dlog2
826
827 ! -------------------------------------------------------
828
829 integer pure function ilog2(xx)
830 integer, intent(in) :: xx
831
832 ilog2 = nint(log2(real(xx, real64) ))
833 end function ilog2
834
835 ! -------------------------------------------------------
836
837 integer(int64) pure function llog2(xx)
838 integer(int64), intent(in) :: xx
839
840 llog2 = nint(log2(real(xx, real64) ), kind=int64)
841 end function llog2
842
843 ! -------------------------------------------------------
845 complex(real64) pure function exponential(z)
846 complex(real64), intent(in) :: z
847
848 exponential = exp(z)
849 end function exponential
850
851 ! -------------------------------------------------------
857 complex(real64) pure function phi1(z)
858 complex(real64), intent(in) :: z
859
860 real(real64), parameter :: cut = 0.002_real64
861
862 if (abs(z) < cut) then
863 phi1 = m_one + m_half*z*(m_one + z/m_three*(m_one + m_fourth*z*(m_one + z/m_five)))
864 else
865 phi1 = (exp(z) - m_z1)/z
866 end if
867 end function phi1
868
869 ! -------------------------------------------------------
876 complex(real64) pure function phi2(z)
877 complex(real64), intent(in) :: z
878
879 real(real64), parameter :: cut = 0.002_real64
880
881 if (abs(z) < cut) then
882 phi2 = m_half + z/6.0_real64*(m_one + m_fourth*z*(m_one + z/m_five*(m_one + z/6.0_real64)))
883 else
884 phi2 = (exp(z) - z - m_z1)/z**2
885 end if
886 end function phi2
887
888 ! -------------------------------------------------------
890 real(real64) pure function square_root(x)
891 real(real64), intent(in) :: x
892
893 square_root = sqrt(x)
894 end function square_root
895
896 ! -------------------------------------------------------
897
898 logical function is_prime(n)
899 integer, intent(in) :: n
900
901 integer :: i, root
902
903 push_sub(is_prime)
904
905 if (n < 1) then
906 message(1) = "Internal error: is_prime does not take negative numbers."
907 call messages_fatal(1)
908 end if
909 if (n == 1) then
910 is_prime = .false.
911 pop_sub(is_prime)
912 return
913 end if
915 root = nint(sqrt(real(n, real64) ))
916 do i = 2, root
917 if (mod(n,i) == 0) then
918 is_prime = .false.
919 pop_sub(is_prime)
920 return
921 end if
922 end do
923
924 is_prime = .true.
925 pop_sub(is_prime)
926 end function is_prime
927
928 ! ---------------------------------------------------------
933 subroutine generate_rotation_matrix(R, ff, tt)
934 real(real64), intent(out) :: r(:,:)
935 real(real64), intent(in) :: ff(:)
936 real(real64), intent(in) :: tt(:)
937
938 integer :: dim, i, j
939 real(real64) :: th, uv, uu, vv, ft
940 real(real64), allocatable :: axis(:), u(:), v(:), f(:), t(:), p(:)
941
943
944 dim = size(ff,1)
945
946 assert((dim < 3) .or. (dim > 2))
947 assert(size(tt,1) == dim)
948 assert((size(r,1) == dim) .and. (size(r,2) == dim))
949
950 safe_allocate(u(1:dim))
951 safe_allocate(v(1:dim))
952 safe_allocate(f(1:dim))
953 safe_allocate(t(1:dim))
954
955
956 !normalize
957 f = ff / norm2(ff)
958 t = tt / norm2(tt)
959
960 ft = dot_product(f,t)
961
962 if (abs(ft) < m_one) then
963 select case (dim)
964 case (2)
965 th = acos(ft)
966 r(1,1) = cos(th)
967 r(1,2) = -sin(th)
968
969 r(2,1) = sin(th)
970 r(2,2) = cos(th)
971
972 case (3)
973 if (.false.) then
974 !Old implementation
975 safe_allocate(axis(1:dim))
976 th = acos(ft)
977
978 u = f / dot_product(f,f)
979 v = t /dot_product(t,t)
980
981 axis = dcross_product(u,v)
982 axis = axis / norm2(axis)
984 r(1,1) = cos(th) + axis(1)**2 * (1 - cos(th))
985 r(1,2) = axis(1)*axis(2)*(1-cos(th)) + axis(3)*sin(th)
986 r(1,3) = axis(1)*axis(3)*(1-cos(th)) - axis(2)*sin(th)
987
988 r(2,1) = axis(2)*axis(1)*(1-cos(th)) - axis(3)*sin(th)
989 r(2,2) = cos(th) + axis(2)**2 * (1 - cos(th))
990 r(2,3) = axis(2)*axis(3)*(1-cos(th)) + axis(1)*sin(th)
992 r(3,1) = axis(3)*axis(1)*(1-cos(th)) + axis(2)*sin(th)
993 r(3,2) = axis(3)*axis(2)*(1-cos(th)) - axis(1)*sin(th)
994 r(3,3) = cos(th) + axis(3)**2 * (1 - cos(th))
995
996 safe_deallocate_a(axis)
997 end if
998
999 if (.true.) then
1000 !Naive implementation
1001 th = acos(ft)
1002 u = dcross_product(f,t)
1003 u = u / norm2(u)
1004
1005 r(1,1) = u(1)**2 + (1-u(1)**2)*cos(th)
1006 r(1,2) = u(1)*u(2)*(1-cos(th)) - u(3)*sin(th)
1007 r(1,3) = u(1)*u(3) + u(2)*sin(th)
1008
1009 r(2,1) = u(1)*u(2)*(1-cos(th)) + u(3)*sin(th)
1010 r(2,2) = u(2)**2 + (1-u(2)**2)*cos(th)
1011 r(2,3) = u(2)*u(3)*(1-cos(th)) - u(1)*sin(th)
1012
1013 r(3,1) = u(1)*u(3)*(1-cos(th)) - u(2)*sin(th)
1014 r(3,2) = u(2)*u(3)*(1-cos(th)) + u(1)*sin(th)
1015 r(3,3) = u(3)**2 + (1-u(3)**2)*cos(th)
1016 end if
1017
1018 if (.false.) then
1019 !Fast
1020 safe_allocate(p(1:dim))
1021
1022 if (abs(f(1)) <= abs(f(2)) .and. abs(f(1)) < abs(f(3))) then
1023 p = (/m_one, m_zero, m_zero/)
1024 else if (abs(f(2)) < abs(f(1)) .and. abs(f(2)) <= abs(f(3))) then
1025 p = (/m_zero, m_one, m_zero/)
1026 else if (abs(f(3)) <= abs(f(1)) .and. abs(f(3)) < abs(f(2))) then
1027 p = (/m_zero, m_zero, m_one/)
1028 end if
1029
1030 u = p - f
1031 v = p - t
1032
1033 uu = dot_product(u,u)
1034 vv = dot_product(v,v)
1035 uv = dot_product(u,v)
1036
1037 do i = 1,3
1038 do j = 1,3
1039
1040 r(i,j) = ddelta(i,j) - m_two * u(i)*u(j)/uu - m_two * v(i)*v(j)/vv &
1041 + 4_real64*uv * v(i)*u(j) /(uu*vv)
1042
1043 end do
1044 end do
1045
1046 safe_deallocate_a(p)
1047 end if
1048
1049
1050 end select
1051
1052 else
1053
1054 r = m_zero
1055 do i = 1,dim
1056 r(i,i) = m_one
1057 end do
1058
1059 end if
1060
1061
1062 safe_deallocate_a(u)
1063 safe_deallocate_a(v)
1064
1066 end subroutine generate_rotation_matrix
1067
1068 ! ---------------------------------------------------------
1077 subroutine numder_ridders(x, h, res, err, f)
1078 implicit none
1079 real(real64), intent(in) :: x, h
1080 real(real64), intent(out) :: res, err
1081 interface
1082 subroutine f(x, fx)
1083 use, intrinsic :: iso_fortran_env
1084 implicit none
1085 real(real64), intent(in) :: x
1086 real(real64), intent(inout) :: fx
1087 end subroutine f
1088 end interface
1089
1090 real(real64) :: con = 1.4_real64, big = 1.0e30_real64, safe = m_two
1091 integer :: ntab = 20, i, j
1092 real(real64) :: errt, fac, hh, fx1, fx2
1093 real(real64), allocatable :: a(:, :)
1094
1095 push_sub(numder_ridders)
1096
1097 if (abs(h) <= m_epsilon) then
1098 message(1) = "h must be nonzero in numder_ridders"
1099 call messages_fatal(1)
1100 end if
1101
1102 safe_allocate(a(1:ntab, 1:ntab))
1103
1104 hh = h
1105 call f(x+hh, fx1)
1106 call f(x-hh, fx2)
1107 a(1,1) = (fx1-fx2) / (m_two*hh)
1108 err = big
1109 do i = 2, ntab
1110 hh = hh / con
1111 call f(x+hh, fx1)
1112 call f(x-hh, fx2)
1113 a(1,i) = (fx1-fx2) / (m_two*hh)
1114 fac = con**2
1115 do j = 2, i
1116 a(j,i) = (a(j-1,i)*fac-a(j-1,i-1)) / (fac-m_one)
1117 fac = con**2*fac
1118 errt = max(abs(a(j,i)-a(j-1,i)),abs(a(j,i)-a(j-1,i-1)))
1119 if (errt .le. err) then
1120 err = errt
1121 res = a(j,i)
1122 end if
1123 end do
1124 if (abs(a(i,i)-a(i-1,i-1)) .ge. safe*err) return
1125 end do
1126
1127 safe_deallocate_a(a)
1128 pop_sub(numder_ridders)
1129 end subroutine numder_ridders
1130
1131 ! ---------------------------------------------------------
1132 pure function dzcross_product(a, b) result(c)
1133 real(real64), intent(in) :: a(:)
1134 complex(real64), intent(in) :: b(:)
1135
1136 complex(real64) :: c(1:3)
1137
1138 c(1) = a(2)*b(3) - a(3)*b(2)
1139 c(2) = a(3)*b(1) - a(1)*b(3)
1140 c(3) = a(1)*b(2) - a(2)*b(1)
1141
1142 end function dzcross_product
1143
1144 ! ---------------------------------------------------------
1145 pure function zdcross_product(a, b) result(c)
1146 complex(real64), intent(in) :: a(:)
1147 real(real64), intent(in) :: b(:)
1148
1149 complex(real64) :: c(1:3)
1150
1151 c(1) = a(2)*b(3) - a(3)*b(2)
1152 c(2) = a(3)*b(1) - a(1)*b(3)
1153 c(3) = a(1)*b(2) - a(2)*b(1)
1154
1155 end function zdcross_product
1156
1157
1158!*****************************************************************************80
1159!
1160!! LM_POLYNOMIAL evaluates Laguerre polynomials Lm(n,m,x).
1161!
1162! First terms:
1163!
1164! M = 0
1165!
1166! Lm(0,0,X) = 1
1167! Lm(1,0,X) = -X + 1
1168! Lm(2,0,X) = X^2 - 4 X + 2
1169! Lm(3,0,X) = -X^3 + 9 X^2 - 18 X + 6
1170! Lm(4,0,X) = X^4 - 16 X^3 + 72 X^2 - 96 X + 24
1171! Lm(5,0,X) = -X^5 + 25 X^4 - 200 X^3 + 600 X^2 - 600 x + 120
1172! Lm(6,0,X) = X^6 - 36 X^5 + 450 X^4 - 2400 X^3 + 5400 X^2 - 4320 X + 720
1173!
1174! M = 1
1175!
1176! Lm(0,1,X) = 0
1177! Lm(1,1,X) = -1,
1178! Lm(2,1,X) = 2 X - 4,
1179! Lm(3,1,X) = -3 X^2 + 18 X - 18,
1180! Lm(4,1,X) = 4 X^3 - 48 X^2 + 144 X - 96
1181!
1182! M = 2
1183!
1184! Lm(0,2,X) = 0
1185! Lm(1,2,X) = 0,
1186! Lm(2,2,X) = 2,
1187! Lm(3,2,X) = -6 X + 18,
1188! Lm(4,2,X) = 12 X^2 - 96 X + 144
1189!
1190! M = 3
1191!
1192! Lm(0,3,X) = 0
1193! Lm(1,3,X) = 0,
1194! Lm(2,3,X) = 0,
1195! Lm(3,3,X) = -6,
1196! Lm(4,3,X) = 24 X - 96
1197!
1198! M = 4
1199!
1200! Lm(0,4,X) = 0
1201! Lm(1,4,X) = 0
1202! Lm(2,4,X) = 0
1203! Lm(3,4,X) = 0
1204! Lm(4,4,X) = 24
1205!
1206! Recursion:
1207!
1208! Lm(0,M,X) = 1
1209! Lm(1,M,X) = (M+1-X)
1210!
1211! if 2 <= N:
1212!
1213! Lm(N,M,X) = ( (M+2*N-1-X) * Lm(N-1,M,X)
1214! + (1-M-N) * Lm(N-2,M,X) ) / N
1215!
1216! Special values:
1217!
1218! For M = 0, the associated Laguerre polynomials Lm(N,M,X) are equal
1219! to the Laguerre polynomials L(N,X).
1220!
1221! Licensing:
1222!
1223! This code is distributed under the GNU LGPL license.
1224!
1225! Modified:
1226!
1227! 08 February 2003
1228!
1229! Author:
1230!
1231! John Burkardt
1232!
1233! Reference:
1234!
1235! Milton Abramowitz, Irene Stegun,
1236! Handbook of Mathematical Functions,
1237! National Bureau of Standards, 1964,
1238! ISBN: 0-486-61272-4,
1239! LC: QA47.A34.
1240!
1241! Parameters:
1242!
1243! Input, integer ( kind = 4 ) MM, the number of evaluation points.
1244!
1245! Input, integer ( kind = 4 ) N, the highest order polynomial to compute.
1246! Note that polynomials 0 through N will be computed.
1247!
1248! Input, integer ( kind = 4 ) M, the parameter. M must be nonnegative.
1249!
1250! Input, real ( kind = rk ) X(MM), the evaluation points.
1251!
1252! Output, real ( kind = rk ) CX(MM,0:N), the associated Laguerre polynomials
1253! of degrees 0 through N evaluated at the evaluation points.
1254!
1255! Taken from
1256! https://people.sc.fsu.edu/~jburkardt/f_src/laguerre_polynomial/laguerre_polynomial.html
1257! and adapted to Octopus by N. Tancogne-Dejean
1258 subroutine generalized_laguerre_polynomial ( np, nn, mm, xx, cx )
1259 integer, intent(in) :: np
1260 integer, intent(in) :: nn, mm
1261 real(real64), intent(in) :: xx(np)
1262 real(real64), intent(out) :: cx(np)
1263
1264 integer ii
1265 real(real64), allocatable :: cx_tmp(:,:)
1266
1267 assert(mm >= 0)
1268
1269 safe_allocate(cx_tmp(1:np, 0:nn))
1270
1271 if (nn < 0) then
1272 cx = m_zero
1273 return
1274 end if
1275
1276 if (nn == 0) then
1277 cx(1:np) = m_one
1278 return
1279 end if
1280
1281 cx_tmp(1:np,0) = m_one
1282 cx_tmp(1:np,1) = real(mm + 1, real64) - xx(1:np)
1283
1284 do ii = 2, nn
1285 cx_tmp(1:np, ii) = &
1286 (( real(mm + 2*ii - 1, real64) - xx(1:np)) * cx_tmp(1:np,ii-1) &
1287 + real(-mm -ii + 1, real64) * cx_tmp(1:np,ii-2)) / real(ii, real64)
1288 end do
1289
1290 cx(1:np) = cx_tmp(1:np, nn)
1291
1292 safe_deallocate_a(cx_tmp)
1293
1294 end subroutine generalized_laguerre_polynomial
1295
1296 subroutine dupper_triangular_to_hermitian(nn, aa)
1297 integer, intent(in) :: nn
1298 real(real64), intent(inout) :: aa(:, :)
1299
1300 integer :: ii, jj
1301
1302 do jj = 1, nn
1303 do ii = 1, jj-1
1304 aa(jj, ii) = aa(ii, jj)
1305 end do
1306 end do
1307 end subroutine dupper_triangular_to_hermitian
1308
1309 subroutine zupper_triangular_to_hermitian(nn, aa)
1310 integer, intent(in) :: nn
1311 complex(real64), intent(inout) :: aa(:, :)
1312
1313 integer :: ii, jj
1314
1315 do jj = 1, nn
1316 do ii = 1, jj-1
1317 aa(jj, ii) = conjg(aa(ii, jj))
1318 end do
1319 aa(jj, jj) = real(aa(jj, jj), real64)
1320 end do
1321 end subroutine zupper_triangular_to_hermitian
1322
1323 subroutine dlower_triangular_to_hermitian(nn, aa)
1324 integer, intent(in) :: nn
1325 real(real64), intent(inout) :: aa(:, :)
1326
1327 integer :: ii, jj
1328
1329 do jj = 1, nn
1330 do ii = 1, jj-1
1331 aa(ii, jj) = aa(jj, ii)
1332 end do
1333 end do
1334 end subroutine dlower_triangular_to_hermitian
1335
1336 subroutine zlower_triangular_to_hermitian(nn, aa)
1337 integer, intent(in) :: nn
1338 complex(real64), intent(inout) :: aa(:, :)
1339
1340 integer :: ii, jj
1341
1342 do jj = 1, nn
1343 do ii = 1, jj-1
1344 aa(ii, jj) = conjg(aa(jj, ii))
1345 end do
1346 aa(jj, jj) = real(aa(jj, jj), real64)
1347 end do
1348 end subroutine zlower_triangular_to_hermitian
1349
1350
1351 subroutine dsymmetrize_matrix(nn, aa)
1352 integer, intent(in) :: nn
1353 real(real64), intent(inout) :: aa(:, :)
1354
1355 integer :: ii, jj
1356
1357 do ii = 1, nn
1358 do jj = ii+1, nn
1359 aa(ii, jj) = m_half * (aa(ii, jj) + aa(jj, ii))
1360 aa(jj, ii) = aa(ii, jj)
1361 end do
1362 end do
1363 end subroutine dsymmetrize_matrix
1364
1365 subroutine dzero_small_elements_matrix(nn, aa, tol)
1366 integer, intent(in) :: nn
1367 real(real64), intent(inout) :: aa(:, :)
1368 real(real64) :: tol
1369
1370 where(abs(aa)<tol)
1371 aa = m_zero
1372 end where
1373 end subroutine dzero_small_elements_matrix
1374
1375#include "undef.F90"
1376#include "complex.F90"
1377#include "math_inc.F90"
1378
1379#include "undef.F90"
1380#include "real.F90"
1381#include "math_inc.F90"
1382
1383end module math_oct_m
1384
1385!! Local Variables:
1386!! mode: f90
1387!! coding: utf-8
1388!! End:
This is the common interface to a simple-minded polynomical interpolation procedure (simple use of th...
Definition: math.F90:186
double acos(double __x) __attribute__((__nothrow__
double log(double __x) __attribute__((__nothrow__
double exp(double __x) __attribute__((__nothrow__
double sin(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
double cos(double __x) __attribute__((__nothrow__
double atan2(double __y, double __x) __attribute__((__nothrow__
real(real64), parameter, public m_two
Definition: global.F90:189
real(real64), parameter, public m_zero
Definition: global.F90:187
real(real64), parameter, public m_four
Definition: global.F90:191
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:185
complex(real64), parameter, public m_z0
Definition: global.F90:197
real(real64), parameter, public m_half
Definition: global.F90:193
real(real64), parameter, public m_one
Definition: global.F90:188
real(real64), parameter, public m_three
Definition: global.F90:190
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
subroutine, public dsymmetrize_matrix(nn, aa)
Definition: math.F90:1445
complex(real64) pure function, public phi2(z)
Compute phi2(z) = (phi1(z)-1)/z = (exp(z) - z - 1)/z^2.
Definition: math.F90:970
integer pure function ilog2(xx)
Definition: math.F90:923
logical pure function, public even(n)
Returns if n is even.
Definition: math.F90:689
pure real(real64) function, dimension(dim, dim) ddiagonal_matrix(dim, diag)
Currently only returns a matrix whose diagonal elements are all the same. Note that the integer versi...
Definition: math.F90:1730
subroutine, public generalized_laguerre_polynomial(np, nn, mm, xx, cx)
Definition: math.F90:1352
complex(real64) pure function, public exponential(z)
Wrapper for exponential.
Definition: math.F90:939
subroutine dinterpolate_0(xa, ya, x, y)
Definition: math.F90:1808
subroutine, public ylmr_cmplx(xx, li, mi, ylm)
Computes spherical harmonics ylm at position (x, y, z)
Definition: math.F90:301
subroutine zinterpolate_0(xa, ya, x, y)
Definition: math.F90:1617
subroutine dinterpolate_1(xa, ya, x, y)
Definition: math.F90:1780
real(real64) pure function dlog2(xx)
Definition: math.F90:915
integer(int64) pure function pad88(size, blk)
Definition: math.F90:842
real(real64) pure function, public square_root(x)
Wrapper for sqrt.
Definition: math.F90:984
logical function, public member(n, a)
Considers a(1:ubound(a, 1)) as an integer set and checks if n is a member of it.
Definition: math.F90:645
integer pure function pad4(size, blk)
Definition: math.F90:873
subroutine dlower_triangular_to_hermitian(nn, aa)
Definition: math.F90:1417
pure complex(real64) function, dimension(1:3), public dzcross_product(a, b)
Definition: math.F90:1226
subroutine, public cartesian2hyperspherical(x, u)
Performs a transformation of an n-dimensional vector from Cartesian coordinates to hyperspherical coo...
Definition: math.F90:709
integer pure function, public pad_pow2(size)
create array size, which is padded to powers of 2
Definition: math.F90:886
subroutine zinterpolate_1(xa, ya, x, y)
Definition: math.F90:1589
pure real(real64) function, dimension(1:3), public dcross_product(a, b)
Definition: math.F90:1833
integer(int64) pure function pad48(size, blk)
Definition: math.F90:857
subroutine, public ylmr_real(xx, li, mi, ylm)
This is a Numerical Recipes-based subroutine computes real spherical harmonics ylm at position (x,...
Definition: math.F90:372
subroutine dupper_triangular_to_hermitian(nn, aa)
Definition: math.F90:1390
subroutine, public interpolation_coefficients(nn, xa, xx, cc)
Definition: math.F90:666
subroutine, public generate_rotation_matrix(R, ff, tt)
Generates a rotation matrix R to rotate a vector f to t.
Definition: math.F90:1027
elemental logical function zis_close_scalar(x, y, rtol, atol)
Same as dis_close_scalar for complex numbers.
Definition: math.F90:234
logical pure function, public odd(n)
Returns if n is odd.
Definition: math.F90:699
real(real64) pure function, public ddelta(i, j)
Definition: math.F90:598
subroutine, public make_idx_set(n, out, length, in)
Construct out(1:length) = (/1, ..., n/) if in is not present, out(1:length) = in otherwise.
Definition: math.F90:616
logical function, public is_prime(n)
Definition: math.F90:992
complex(real64) pure function, public phi1(z)
Compute phi1(z) = (exp(z)-1)/z.
Definition: math.F90:951
pure complex(real64) function, dimension(1:3), public zcross_product(a, b)
Definition: math.F90:1642
subroutine, public weights(N, M, cc, side)
Compute the weights for finite-difference calculations:
Definition: math.F90:522
subroutine zinterpolate_2(xa, ya, x, y)
Definition: math.F90:1554
pure complex(real64) function, dimension(dim, dim) zdiagonal_matrix(dim, diag)
Currently only returns a matrix whose diagonal elements are all the same. Note that the integer versi...
Definition: math.F90:1539
subroutine zlower_triangular_to_hermitian(nn, aa)
Definition: math.F90:1430
subroutine zupper_triangular_to_hermitian(nn, aa)
Definition: math.F90:1403
pure integer function, dimension(dim, dim) idiagonal_matrix(dim, diag)
Currently only returns a matrix whose diagonal elements are all the same. Note that the real and comp...
Definition: math.F90:250
integer(int64) pure function pad8(size, blk)
Definition: math.F90:865
subroutine dinterpolate_2(xa, ya, x, y)
Definition: math.F90:1745
subroutine, public numder_ridders(x, h, res, err, f)
Numerical derivative (Ridder`s algorithm).
Definition: math.F90:1171
integer(int64) pure function llog2(xx)
Definition: math.F90:931
recursive real(real64) function, public hermite(n, x)
Definition: math.F90:265
elemental logical function dis_close_scalar(x, y, rtol, atol)
Are and equal within a tolerance.
Definition: math.F90:221
pure complex(real64) function, dimension(1:3), public zdcross_product(a, b)
Definition: math.F90:1239
subroutine, public hyperspherical2cartesian(u, x)
Performs the inverse transformation of cartesian2hyperspherical.
Definition: math.F90:756
subroutine, public dzero_small_elements_matrix(nn, aa, tol)
Definition: math.F90:1459
subroutine, public hypersphere_grad_matrix(grad_matrix, r, x)
Gives the hyperspherical gradient matrix, which contains the derivatives of the Cartesian coordinates...
Definition: math.F90:802
recursive integer function, public factorial(n)
Definition: math.F90:285
int true(void)