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