29 #include "../base/base_uses.f90"
44 #define IF_CHECK(x,y) x
46 #define IF_CHECK(x,y) y
49 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'd3_poly'
58 LOGICAL,
SAVE :: module_initialized = .false.
59 INTEGER,
SAVE,
DIMENSION(2, cached_dim2) :: a_mono_exp2
60 INTEGER,
SAVE,
DIMENSION(3, cached_dim3) :: a_mono_exp3
61 INTEGER,
SAVE,
DIMENSION(cached_dim3) :: a_reduce_idx3
62 INTEGER,
SAVE,
DIMENSION(3, cached_dim3) :: a_deriv_idx3
63 INTEGER,
SAVE,
DIMENSION(cached_dim2, cached_dim2) :: a_mono_mult2
64 INTEGER,
SAVE,
DIMENSION(cached_dim3, cached_dim3) :: a_mono_mult3
65 INTEGER,
SAVE,
DIMENSION(4, cached_dim3) :: a_mono_mult3a
74 INTEGER :: grad, i, ii, ij, j, nthreads, subg
75 INTEGER,
DIMENSION(2) :: monores2
76 INTEGER,
DIMENSION(3) :: monores3
80 IF (nthreads /= 1) cpabort(
"init_d3_poly_module must not be called within OMP PARALLEL")
82 IF (module_initialized)
RETURN
87 a_mono_exp2(1, ii) = i
88 a_mono_exp2(2, ii) = grad - i
95 DO j = grad - i, 0, -1
96 a_mono_exp3(1, ii) = i
97 a_mono_exp3(2, ii) = j
98 a_mono_exp3(3, ii) = grad - i - j
104 subg = a_mono_exp3(2, ii) + a_mono_exp3(3, ii)
105 a_reduce_idx3(ii) = subg*(subg + 1)/2 + a_mono_exp3(3, ii) + 1
108 IF (a_mono_exp3(1, ii) > 0)
THEN
109 a_deriv_idx3(1, ii) = mono_index3(a_mono_exp3(1, ii) - 1, a_mono_exp3(2, ii), a_mono_exp3(3, ii))
111 a_deriv_idx3(1, ii) = 0
113 IF (a_mono_exp3(2, ii) > 0)
THEN
114 a_deriv_idx3(2, ii) = mono_index3(a_mono_exp3(1, ii), a_mono_exp3(2, ii) - 1, a_mono_exp3(3, ii))
116 a_deriv_idx3(2, ii) = 0
118 IF (a_mono_exp3(3, ii) > 0)
THEN
119 a_deriv_idx3(3, ii) = mono_index3(a_mono_exp3(1, ii), a_mono_exp3(2, ii), a_mono_exp3(3, ii) - 1)
121 a_deriv_idx3(3, ii) = 0
126 monores2 = a_mono_exp2(:, ii) + a_mono_exp2(:, ij)
127 a_mono_mult2(ii, ij) = mono_index2(monores2(1), monores2(2)) + 1
128 a_mono_mult2(ij, ii) = a_mono_mult2(ii, ij)
133 monores3 = a_mono_exp3(:, ii) + a_mono_exp3(:, ij)
134 a_mono_mult3(ii, ij) = mono_index3(monores3(1), monores3(2), monores3(3)) + 1
135 a_mono_mult3(ij, ii) = a_mono_mult3(ii, ij)
141 a_mono_mult3a(j, i) = a_mono_mult3(j, i)
146 module_initialized = .true.
155 INTEGER,
INTENT(in) :: maxgrad
167 INTEGER,
INTENT(in) :: maxgrad
170 res = (maxgrad + 1)*(maxgrad + 2)/2
179 INTEGER,
INTENT(in) :: maxgrad
182 res = (maxgrad + 1)*(maxgrad + 2)*(maxgrad + 3)/6
190 PURE FUNCTION grad_size1(n)
RESULT(res)
191 INTEGER,
INTENT(in) :: n
202 PURE FUNCTION grad_size2(n)
RESULT(res)
203 INTEGER,
INTENT(in) :: n
206 res = int(floor(0.5_dp*(sqrt(1.0_dp + 8.0_dp*real(n,
dp)) - 1.0_dp) - 2.e-6_dp))
215 INTEGER,
INTENT(in) :: n
225 g1 = (108.0_dp*nn + 12.0_dp*sqrt(81.0_dp*nn*nn - 12.0_dp))**(1.0_dp/3.0_dp)
226 res = floor(g1/6.0_dp + 2.0_dp/g1 - 1.0_dp - 2.e-6_dp)
235 PURE FUNCTION mono_index1(i)
RESULT(res)
236 INTEGER,
INTENT(in) :: i
248 PURE FUNCTION mono_index2(i, j)
RESULT(res)
249 INTEGER,
INTENT(in) :: i, j
255 res = grad*(grad + 1)/2 + j
265 PURE FUNCTION mono_index3(i, j, k)
RESULT(res)
266 INTEGER,
INTENT(in) :: i, j, k
269 INTEGER :: grad, sgrad
273 res = grad*(grad + 1)*(grad + 2)/6 + (sgrad)*(sgrad + 1)/2 + k
281 PURE FUNCTION mono_exp1(ii)
RESULT(res)
282 INTEGER,
INTENT(in) :: ii
293 PURE FUNCTION mono_exp2(ii)
RESULT(res)
294 INTEGER,
INTENT(in) :: ii
295 INTEGER,
DIMENSION(2) :: res
299 grad = int(floor(0.5_dp*(sqrt(9.0_dp + 8.0_dp*ii) - 1.0_dp) - 2.e-6_dp))
300 res(2) = ii - (grad)*(grad + 1)/2
301 res(1) = grad - res(2)
309 PURE FUNCTION mono_exp3(n)
RESULT(res)
310 INTEGER,
INTENT(in) :: n
311 INTEGER,
DIMENSION(3) :: res
313 INTEGER :: grad, grad1, ii, nn
317 g1 = (108.0_dp*nn + 12.0_dp*sqrt(81.0_dp*nn*nn - 12.0_dp))**(1.0_dp/3.0_dp)
318 grad1 = int(floor(g1/6.0_dp + 2.0_dp/g1 - 1.0_dp - 2.e-6_dp))
319 ii = n - grad1*(grad1 + 1)*(grad1 + 2)/6
320 grad = int(floor(0.5_dp*(sqrt(9.0_dp + 8.0_dp*ii) - 1.0_dp) - 1.e-6_dp))
321 res(3) = ii - grad*(grad + 1)/2
322 res(2) = grad - res(3)
323 res(1) = grad1 - grad
332 PURE FUNCTION mono_mult1(ii, ij)
RESULT(res)
333 INTEGER,
INTENT(in) :: ii, ij
345 PURE FUNCTION mono_mult2(ii, ij)
RESULT(res)
346 INTEGER,
INTENT(in) :: ii, ij
349 INTEGER,
DIMENSION(2) :: monores
351 monores = mono_exp2(ii) + mono_exp2(ij)
352 res = mono_index2(monores(1), monores(2))
361 PURE FUNCTION mono_mult3(ii, ij)
RESULT(res)
362 INTEGER,
INTENT(in) :: ii, ij
365 INTEGER,
DIMENSION(3) :: monores
367 monores = mono_exp3(ii) + mono_exp3(ij)
368 res = mono_index3(monores(1), monores(2), monores(3))
379 SUBROUTINE poly_mult1(p1, p2, pRes, np1, sumUp)
380 REAL(
dp),
DIMENSION(:),
INTENT(in) :: p1, p2
381 REAL(
dp),
DIMENSION(:),
INTENT(inout) :: pres
382 INTEGER,
INTENT(in),
OPTIONAL :: np1
383 LOGICAL,
INTENT(in),
OPTIONAL :: sumup
385 INTEGER :: i, ipoly, ipos, j, mynp1, newgrad, &
386 newsize, respos, resshift_0, size_p1, &
390 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
393 IF (
PRESENT(np1)) mynp1 = np1
394 IF (
PRESENT(sumup)) mysumup = sumup
395 size_p1 =
SIZE(p1)/mynp1
397 newgrad = grad_size1(size_p1) + grad_size1(size_p2)
398 newsize =
SIZE(pres)/mynp1
400 IF (.NOT. mysumup) pres = 0
403 DO ipoly = 0, mynp1 - 1
405 respos = resshift_0 + i
407 pres(respos) = pres(respos) + p1(ipos)*p2(j)
412 resshift_0 = resshift_0 + newsize
424 SUBROUTINE poly_mult2(p1, p2, pRes, np1, sumUp)
425 REAL(
dp),
DIMENSION(:),
INTENT(in) :: p1, p2
426 REAL(
dp),
DIMENSION(:),
INTENT(inout) :: pres
427 INTEGER,
INTENT(in),
OPTIONAL :: np1
428 LOGICAL,
INTENT(in),
OPTIONAL :: sumup
430 INTEGER :: g1, g1g2, g2, grad1, grad2, i, ipoly, ishift, j, msize_p1, mynp1, newgrad, &
431 newsize, shift1, shift2, shiftres, shiftres_0, size_p1, size_p2, subg2
434 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
436 IF (
PRESENT(sumup)) mysumup = sumup
438 IF (
PRESENT(np1)) mynp1 = np1
439 size_p1 =
SIZE(p1)/mynp1
441 grad1 = grad_size2(size_p1)
442 grad2 = grad_size2(size_p2)
443 newgrad = grad1 + grad2
444 newsize =
SIZE(pres)/mynp1
446 IF (.NOT. mysumup) pres = 0
452 pres(shiftres + a_mono_mult2(j, i)) = pres(shiftres + a_mono_mult2(j, i)) &
453 + p1(ishift + i)*p2(j)
456 ishift = ishift + size_p1
457 shiftres = shiftres + newsize
462 DO ipoly = 0, mynp1 - 1
463 shift1 = ipoly*size_p1
469 g1g2 = shiftres_0 - 1
473 g1g2 = shiftres_0 + g1*subg2 - 1
477 shiftres = shift1 + shift2 + g1g2
478 DO i = 1, min(g1 + 1, msize_p1 - shift1)
479 DO j = 1, min(g2 + 1, size_p2 - shift2)
480 pres(shiftres + i + j) = pres(shiftres + i + j) + p1(shift1 + i)*p2(shift2 + j)
483 shift2 = shift2 + g2 + 1
486 shift1 = shift1 + g1 + 1
488 shiftres_0 = shiftres_0 + newsize - size_p1
489 msize_p1 = msize_p1 + size_p1
502 SUBROUTINE poly_mult3(p1, p2, pRes, np1, sumUp)
503 REAL(
dp),
DIMENSION(:),
INTENT(in) :: p1, p2
504 REAL(
dp),
DIMENSION(:),
INTENT(inout) :: pres
505 INTEGER,
INTENT(in),
OPTIONAL :: np1
506 LOGICAL,
INTENT(in),
OPTIONAL :: sumup
508 INTEGER :: grad1, grad2, mynp1, newgrad, newsize, &
512 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
514 IF (
PRESENT(sumup)) mysumup = sumup
516 IF (
PRESENT(np1)) mynp1 = np1
517 size_p1 =
SIZE(p1)/mynp1
521 newgrad = grad1 + grad2
522 newsize =
SIZE(pres)/mynp1
524 CALL poly_mult3b(p1,
SIZE(p1), grad1, p2,
SIZE(p2), grad2, pres,
SIZE(pres), mynp1, mysumup)
540 SUBROUTINE poly_mult3b(p1, size_p1, grad1, p2, size_p2, grad2, pRes, size_pRes, np1, sumUp)
541 INTEGER,
INTENT(in) :: size_p1
542 REAL(
dp),
DIMENSION(IF_CHECK(size_p1, *)), &
544 INTEGER,
INTENT(in) :: grad1, size_p2
545 REAL(
dp),
DIMENSION(IF_CHECK(size_p2, *)), &
547 INTEGER,
INTENT(in) :: grad2, size_pres
548 REAL(
dp),
DIMENSION(IF_CHECK(size_pRes, *)), &
549 INTENT(inout) :: pres
550 INTEGER,
INTENT(in) :: np1
551 LOGICAL,
INTENT(in) :: sumup
553 INTEGER :: g1, g2, i, i1, i2, ipoly, ishift, j, j1, j2, msize_p1, my_size_p1, newsize, &
554 shift1, shift1i, shift1j, shift2, shift2i, shift2j, shiftres, shiftres_0, shiftresi, &
555 shiftresi_0, shiftresj, subg2, subgrad
557 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
558 my_size_p1 = size_p1/np1
559 newsize = size_pres/np1
561 IF (.NOT. sumup) pres(1:size_pres) = 0.0_dp
567 pres(shiftres + a_mono_mult3(j, i)) = pres(shiftres + a_mono_mult3(j, i)) &
568 + p1(ishift + i)*p2(j)
571 ishift = ishift + my_size_p1
572 shiftres = shiftres + newsize
576 msize_p1 = my_size_p1
577 DO ipoly = 0, np1 - 1
578 shift1 = 1 + ipoly*my_size_p1
579 shiftres_0 = 1 + ipoly*newsize
586 shift2 = subg2*(subg2 + 1)*(subg2 + 2)/6 + 1
589 shiftres = (g1 + g2)*(g1 + g2 + 1)*(g1 + g2 + 2)/6 + shiftres_0
591 shiftresi_0 = shiftres
593 IF (shift1i > msize_p1)
EXIT
595 shiftresi = shiftresi_0
601 IF (shift2i > size_p2)
EXIT
602 DO j1 = g1 - i1, 0, -1
603 shift1j = shift1i + g1 - i1 - j1
604 IF (shift1j > msize_p1)
EXIT
605 DO j2 = g2 - i2, 0, -1
606 shift2j = shift2i + g2 - i2 - j2
607 IF (shift2j > size_p2)
EXIT
608 shiftresj = shiftresi + (subgrad - j1 - j2)
612 pres(shiftresj) = pres(shiftresj) + p1(shift1j)*p2(shift2j)
615 subgrad = subgrad + 1
616 shift2i = shift2i + (g2 - i2 + 1)
617 shiftresi = shiftresi + subgrad
619 shift1i = shift1i + (g1 - i1 + 1)
620 shiftresi_0 = shiftresi_0 + (g1 - i1 + 1)
622 shift2 = shift2 + (g2 + 1)*(g2 + 2)/2
624 shift1 = shift1 + (g1 + 1)*(g1 + 2)/2
626 msize_p1 = msize_p1 + my_size_p1
642 SUBROUTINE poly_mult3ab(p1, size_p1, grad1, p2, pRes, size_pRes, np1, sumUp)
643 INTEGER,
INTENT(in) :: size_p1
644 REAL(
dp),
DIMENSION(IF_CHECK(size_p1, *)), &
646 INTEGER,
INTENT(in) :: grad1
647 REAL(
dp),
DIMENSION(IF_CHECK(4, *)),
INTENT(in) :: p2
648 INTEGER,
INTENT(in) :: size_pres
649 REAL(
dp),
DIMENSION(IF_CHECK(size_pRes, *)), &
650 INTENT(inout) :: pres
651 INTEGER,
INTENT(in) :: np1
652 LOGICAL,
INTENT(in) :: sumup
654 INTEGER,
PARAMETER :: grad2 = 1
656 INTEGER :: g1, g2, i, i1, i2, ipoly, ishift, j1, j2, msize_p1, my_size_p1, newsize, shift1, &
657 shift1i, shift1j, shift2, shift2i, shift2j, shiftres, shiftres_0, shiftresi, shiftresi_0, &
658 shiftresj, subg2, subgrad
660 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
661 my_size_p1 = size_p1/np1
662 newsize = size_pres/np1
664 IF (.NOT. sumup) pres(1:size_pres) = 0.0_dp
669 pres(shiftres + a_mono_mult3a(1, i)) = pres(shiftres + a_mono_mult3a(1, i)) &
670 + p1(ishift + i)*p2(1)
671 pres(shiftres + a_mono_mult3a(2, i)) = pres(shiftres + a_mono_mult3a(2, i)) &
672 + p1(ishift + i)*p2(2)
673 pres(shiftres + a_mono_mult3a(3, i)) = pres(shiftres + a_mono_mult3a(3, i)) &
674 + p1(ishift + i)*p2(3)
675 pres(shiftres + a_mono_mult3a(4, i)) = pres(shiftres + a_mono_mult3a(4, i)) &
676 + p1(ishift + i)*p2(4)
678 ishift = ishift + my_size_p1
679 shiftres = shiftres + newsize
683 msize_p1 = my_size_p1
684 DO ipoly = 0, np1 - 1
686 shiftres_0 = 1 + ipoly*newsize
691 shiftres = (g1 + g2)*(g1 + g2 + 1)*(g1 + g2 + 2)/6 + shiftres_0
693 shiftresi_0 = shiftres
695 IF (shift1i > msize_p1)
EXIT
697 shiftresi = shiftresi_0
703 DO j1 = g1 - i1, 0, -1
704 shift1j = shift1i + g1 - i1 - j1
705 IF (shift1j > msize_p1)
EXIT
706 DO j2 = g2 - i2, 0, -1
707 shift2j = shift2i + g2 - i2 - j2
708 shiftresj = shiftresi + (subgrad - j1 - j2)
712 pres(shiftresj) = pres(shiftresj) + p1(shift1j)*p2(shift2j)
715 subgrad = subgrad + 1
716 shift2i = shift2i + (g2 - i2 + 1)
717 shiftresi = shiftresi + subgrad
719 shift1i = shift1i + (g1 - i1 + 1)
720 shiftresi_0 = shiftresi_0 + (g1 - i1 + 1)
722 shift2 = shift2 + (g2 + 1)*(g2 + 2)/2
724 shift1 = shift1 + (g1 + 1)*(g1 + 2)/2
726 msize_p1 = msize_p1 + my_size_p1
736 SUBROUTINE poly_write1(p, out_f)
737 REAL(
dp),
DIMENSION(:),
INTENT(in) :: p
738 INTEGER,
INTENT(in) :: out_f
746 IF (p(i) >= 0)
WRITE (out_f,
'("+")', advance=
'NO')
747 WRITE (out_f,
'(G20.10)', advance=
'NO') p(i)
748 IF (i /= 1)
WRITE (out_f,
'("*x^",I3)', advance=
'NO') i - 1
752 IF (.NOT. did_write)
WRITE (out_f,
'("0.0")', advance=
'NO')
760 SUBROUTINE poly_write2(p, out_f)
761 REAL(
dp),
DIMENSION(:),
INTENT(in) :: p
762 INTEGER,
INTENT(in) :: out_f
765 INTEGER,
DIMENSION(2) :: mono_e
768 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
771 mono_e = mono_exp2(i - 1)
773 IF (p(i) >= 0)
WRITE (out_f,
'("+")', advance=
'NO')
774 WRITE (out_f,
'(G20.10)', advance=
'NO') p(i)
775 IF (mono_e(1) /= 0)
WRITE (out_f,
'("*x^",I3)', advance=
'NO') mono_e(1)
776 IF (mono_e(2) /= 0)
WRITE (out_f,
'("*y^",I3)', advance=
'NO') mono_e(2)
780 IF (.NOT. did_write)
WRITE (out_f,
'("0.0")', advance=
'NO')
788 SUBROUTINE poly_write3(p, out_f)
789 REAL(
dp),
DIMENSION(:),
INTENT(in) :: p
790 INTEGER,
INTENT(in) :: out_f
793 INTEGER,
DIMENSION(3) :: mono_e
796 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
799 mono_e = mono_exp3(i - 1)
801 IF (p(i) >= 0)
WRITE (out_f,
'("+")', advance=
'NO')
802 WRITE (out_f,
'(G20.10)', advance=
'NO') p(i)
803 IF (mono_e(1) /= 0)
WRITE (out_f,
'("*x^",I3)', advance=
'NO') mono_e(1)
804 IF (mono_e(2) /= 0)
WRITE (out_f,
'("*y^",I3)', advance=
'NO') mono_e(2)
805 IF (mono_e(3) /= 0)
WRITE (out_f,
'("*z^",I3)', advance=
'NO') mono_e(3)
809 IF (.NOT. did_write)
WRITE (out_f,
'("0.0")', advance=
'NO')
820 FUNCTION poly_random(p, maxSize, minSize)
RESULT(res)
821 REAL(
dp),
DIMENSION(:),
INTENT(out) :: p
822 INTEGER,
INTENT(in) :: maxsize
823 INTEGER,
INTENT(in),
OPTIONAL :: minsize
826 INTEGER :: i, myminsize, psize
829 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
831 IF (
PRESENT(minsize)) myminsize = minsize
832 CALL random_number(g)
833 psize = min(maxsize, myminsize + int((maxsize - myminsize + 1)*g))
834 cpassert(
SIZE(p) >= psize)
835 CALL random_number(p)
837 p(i) = real(int(p(i)*200.0_dp - 100.0_dp),
dp)/100.0_dp
839 DO i = psize + 1,
SIZE(p)
855 REAL(
dp),
DIMENSION(:),
INTENT(in) :: p
856 REAL(
dp),
DIMENSION(3, 3),
INTENT(in) :: m
857 REAL(
dp),
DIMENSION(3),
INTENT(in) :: b
858 REAL(
dp),
DIMENSION(:),
INTENT(out) :: pres
859 INTEGER,
INTENT(in),
OPTIONAL :: npoly
861 INTEGER :: grad, i, igrad, ii, ii1, ipoly, j, k, minressize, monodim1, monodim2, monodimatt, &
862 monodimatt2, monofulldim1, monofulldim2, monosize1, monosize2, my_npoly, pcoeff, pidx, &
863 pshift, rescoeff, resshift, rest_size_p, size_p, size_res, start_idx1
864 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: monog1, monog2
865 REAL(
dp),
DIMENSION(4, 3) :: basepoly
867 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
869 IF (
PRESENT(npoly)) my_npoly = npoly
873 basepoly(j + 1, i) = m(i, j)
876 size_p =
SIZE(pres)/my_npoly
877 size_res =
SIZE(p)/my_npoly
880 cpassert(size_res == minressize)
881 cpassert(size_p >= minressize)
883 IF (size_p == 0)
RETURN
886 DO ipoly = 1, my_npoly
891 IF (size_p == 1)
RETURN
893 ALLOCATE (monog1((grad + 1)*(grad + 2)/2*minressize), &
894 monog2((grad + 1)*(grad + 2)/2*minressize))
900 monog1(ii1) = basepoly(i, j)
908 monofulldim1 = monodim1*monosize1
909 rest_size_p = size_p - 1
911 k = min(rest_size_p, monosize1)
916 DO ipoly = 1, my_npoly
920 DO rescoeff = 1, monodim1
921 pres(pidx) = pres(pidx) + p(resshift + rescoeff)*monog1(ii)
926 resshift = resshift + size_res
927 pshift = pshift + size_p
930 rest_size_p = rest_size_p - k
932 IF (rest_size_p <= 0)
EXIT
934 monosize2 = igrad + 2 + monosize1
935 monodim2 = monodim1 + monosize2
936 monofulldim2 = monosize2*monodim2
937 monodimatt = monosize1*monodim2
938 CALL poly_mult3ab(if_check(monog1(1:monofulldim1), monog1(1)), monofulldim1, igrad, &
939 if_check(basepoly(:, 1), basepoly(1, 1)), &
940 if_check(monog2(1:monodimatt), monog2(1)), monodimatt, monosize1, .false.)
941 monodimatt2 = monofulldim2 - monodim2
942 start_idx1 = (monosize1 - igrad - 1)*monodim1
943 CALL poly_mult3ab(if_check(monog1(start_idx1 + 1:monofulldim1), monog1(start_idx1 + 1)), &
944 monofulldim1 - start_idx1, igrad, if_check(basepoly(:, 2), basepoly(1, 2)), &
945 if_check(monog2(monodimatt + 1:monodimatt2), monog2(monodimatt + 1)), &
946 monodimatt2 - monodimatt, igrad + 1, .false.)
947 CALL poly_mult3ab(if_check(monog1(monofulldim1 - monodim1 + 1:monofulldim1), monog1(monofulldim1 - monodim1 + 1)), &
948 monodim1, igrad, if_check(basepoly(:, 3), basepoly(1, 3)), &
949 if_check(monog2(monodimatt2 + 1:monofulldim2), monog2(monodimatt2 + 1)), &
950 monofulldim2 - monodimatt2, 1, .false.)
955 k = min(rest_size_p, monosize2)
960 DO ipoly = 1, my_npoly
964 DO rescoeff = 1, monodim2
965 pres(pidx) = pres(pidx) + p(resshift + rescoeff)*monog2(ii)
970 resshift = resshift + size_res
971 pshift = pshift + size_p
974 rest_size_p = rest_size_p - k
976 IF (rest_size_p <= 0)
EXIT
978 monosize1 = igrad + 2 + monosize2
979 monodim1 = monodim2 + monosize1
980 monofulldim1 = monosize1*monodim1
981 monodimatt = monosize2*monodim1
982 CALL poly_mult3ab(if_check(monog2(1:monofulldim2), monog2(1)), monofulldim2, igrad, &
983 if_check(basepoly(:, 1), basepoly(1, 1)), if_check(monog1(1:monodimatt), monog1(1)), &
984 monodimatt, monosize2, .false.)
985 monodimatt2 = monofulldim1 - monodim1
986 start_idx1 = (monosize2 - igrad - 1)*monodim2
987 CALL poly_mult3ab(if_check(monog2(start_idx1 + 1:monofulldim2), monog2(start_idx1 + 1)), &
988 monofulldim2 - start_idx1, igrad, if_check(basepoly(:, 2), basepoly(1, 2)), &
989 if_check(monog1(monodimatt + 1:monodimatt2), monog1(monodimatt + 1)), monodimatt2 - monodimatt, &
991 CALL poly_mult3ab(if_check(monog2(monofulldim2 - monodim2 + 1:monofulldim2), monog2(monofulldim2 - monodim2 + 1)), &
992 monodim2, igrad, if_check(basepoly(:, 3), basepoly(1, 3)), &
993 if_check(monog1(monodimatt2 + 1:monofulldim1), monog1(monodimatt2 + 1)), &
994 monofulldim1 - monodimatt2, 1, .false.)
1003 DEALLOCATE (monog1, monog2)
1015 REAL(
dp),
DIMENSION(:),
INTENT(in) :: p
1016 REAL(
dp),
DIMENSION(3, 3),
INTENT(in) :: m
1017 REAL(
dp),
DIMENSION(3),
INTENT(in) :: b
1018 REAL(
dp),
DIMENSION(:),
INTENT(out) :: pres
1019 INTEGER,
INTENT(in),
OPTIONAL :: npoly
1021 INTEGER :: grad, i, igrad, ii, ii1, ipoly, j, k, minressize, monodim1, monodim2, monodimatt, &
1022 monodimatt2, monofulldim1, monofulldim2, monosize1, monosize2, my_npoly, pcoeff, pidx, &
1023 pshift, rescoeff, resshift, rest_size_p, size_p, size_res, start_idx1
1024 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: monog1, monog2
1025 REAL(
dp),
DIMENSION(4, 3) :: basepoly
1027 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
1029 IF (
PRESENT(npoly)) my_npoly = npoly
1033 basepoly(j + 1, i) = m(i, j)
1036 size_p =
SIZE(p)/my_npoly
1038 size_res =
SIZE(pres)/my_npoly
1040 cpassert(size_res >= minressize)
1042 IF (size_p == 0)
RETURN
1045 DO ipoly = 1, my_npoly
1050 IF (size_p == 1)
RETURN
1052 ALLOCATE (monog1((grad + 1)*(grad + 2)/2*minressize), &
1053 monog2((grad + 1)*(grad + 2)/2*minressize))
1059 monog1(ii1) = basepoly(i, j)
1067 monofulldim1 = monodim1*monosize1
1068 rest_size_p = size_p - 1
1070 k = min(rest_size_p, monosize1)
1075 DO ipoly = 1, my_npoly
1079 DO rescoeff = 1, monodim1
1080 pres(resshift + rescoeff) = pres(resshift + rescoeff) + p(pidx)*monog1(ii)
1085 resshift = resshift + size_res
1086 pshift = pshift + size_p
1089 rest_size_p = rest_size_p - k
1091 IF (rest_size_p <= 0)
EXIT
1093 monosize2 = igrad + 2 + monosize1
1094 monodim2 = monodim1 + monosize2
1095 monofulldim2 = monosize2*monodim2
1096 monodimatt = monosize1*monodim2
1097 CALL poly_mult3ab(if_check(monog1(1:monofulldim1), monog1(1)), monofulldim1, igrad, &
1098 if_check(basepoly(:, 1), basepoly(1, 1)), &
1099 if_check(monog2(1:monodimatt), monog2(1)), monodimatt, monosize1, .false.)
1100 monodimatt2 = monofulldim2 - monodim2
1101 start_idx1 = (monosize1 - igrad - 1)*monodim1
1102 CALL poly_mult3ab(if_check(monog1(start_idx1 + 1:monofulldim1), monog1(start_idx1 + 1)), &
1103 monofulldim1 - start_idx1, igrad, if_check(basepoly(:, 2), basepoly(1, 2)), &
1104 if_check(monog2(monodimatt + 1:monodimatt2), monog2(monodimatt + 1)), &
1105 monodimatt2 - monodimatt, igrad + 1, .false.)
1106 CALL poly_mult3ab(if_check(monog1(monofulldim1 - monodim1 + 1:monofulldim1), monog1(monofulldim1 - monodim1 + 1)), &
1107 monodim1, igrad, if_check(basepoly(:, 3), basepoly(1, 3)), &
1108 if_check(monog2(monodimatt2 + 1:monofulldim2), monog2(monodimatt2 + 1)), &
1109 monofulldim2 - monodimatt2, 1, .false.)
1114 k = min(rest_size_p, monosize2)
1119 DO ipoly = 1, my_npoly
1123 DO rescoeff = 1, monodim2
1124 pres(resshift + rescoeff) = pres(resshift + rescoeff) + p(pidx)*monog2(ii)
1129 resshift = resshift + size_res
1130 pshift = pshift + size_p
1133 rest_size_p = rest_size_p - k
1135 IF (rest_size_p <= 0)
EXIT
1137 monosize1 = igrad + 2 + monosize2
1138 monodim1 = monodim2 + monosize1
1139 monofulldim1 = monosize1*monodim1
1140 monodimatt = monosize2*monodim1
1141 CALL poly_mult3ab(if_check(monog2(1:monofulldim2), monog2(1)), monofulldim2, igrad, &
1142 if_check(basepoly(:, 1), basepoly(1, 1)), &
1143 if_check(monog1(1:monodimatt), monog1(1)), monodimatt, monosize2, .false.)
1144 monodimatt2 = monofulldim1 - monodim1
1145 start_idx1 = (monosize2 - igrad - 1)*monodim2
1146 CALL poly_mult3ab(if_check(monog2(start_idx1 + 1:monofulldim2), monog2(start_idx1 + 1)), &
1147 monofulldim2 - start_idx1, igrad, &
1148 if_check(basepoly(:, 2), basepoly(1, 2)), &
1149 if_check(monog1(monodimatt + 1:monodimatt2), monog1(monodimatt + 1)), monodimatt2 - monodimatt, &
1151 CALL poly_mult3ab(if_check(monog2(monofulldim2 - monodim2 + 1:monofulldim2), monog2(monofulldim2 - monodim2 + 1)), &
1152 monodim2, igrad, if_check(basepoly(:, 3), basepoly(1, 3)), &
1153 if_check(monog1(monodimatt2 + 1:monofulldim1), monog1(monodimatt2 + 1)), &
1154 monofulldim1 - monodimatt2, 1, .false.)
1163 DEALLOCATE (monog1, monog2)
1173 SUBROUTINE poly_p_eval3(p, x, pRes, npoly)
1174 REAL(
dp),
DIMENSION(:),
INTENT(in) :: p
1175 REAL(
dp),
INTENT(in) :: x
1176 REAL(
dp),
DIMENSION(:),
INTENT(inout) :: pres
1177 INTEGER,
INTENT(in),
OPTIONAL :: npoly
1179 INTEGER :: grad, my_npoly, newsize, size_p
1180 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: xi
1182 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
1184 IF (
PRESENT(npoly)) my_npoly = npoly
1185 size_p =
SIZE(p)/my_npoly
1187 newsize =
SIZE(pres)/my_npoly
1190 ALLOCATE (xi(grad + 1))
1191 CALL poly_p_eval3b(p,
SIZE(p), x, pres,
SIZE(pres), my_npoly, grad, xi)
1207 INTEGER,
INTENT(in) :: size_p
1208 REAL(
dp),
DIMENSION(IF_CHECK(size_p, *)), &
1210 REAL(
dp),
INTENT(in) :: x
1211 INTEGER,
INTENT(in) :: size_pres
1212 REAL(
dp),
DIMENSION(IF_CHECK(size_pRes, *)), &
1213 INTENT(inout) :: pres
1214 INTEGER,
INTENT(in) :: npoly, grad
1215 REAL(
dp),
DIMENSION(IF_CHECK(grad+1, *)), &
1218 INTEGER :: i, igrad, ii, ii0, insize, ipoly, j, &
1219 msize_p, newsize, pshift, shiftres, &
1222 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
1223 insize = size_p/npoly
1224 newsize = size_pres/npoly
1225 pres(1:size_pres) = 0.0
1234 pres(shiftres + a_reduce_idx3(ii)) = pres(shiftres + a_reduce_idx3(ii)) + p(pshift + ii)*xi(a_mono_exp3(1, ii) + 1)
1236 shiftres = shiftres + newsize
1237 pshift = pshift + insize
1247 shiftres = shiftres_0
1253 IF (msize_p < ii)
EXIT grad_do
1254 pres(shiftres - j) = pres(shiftres - j) + p(ii)*xi(i + 1)
1257 shiftres = shiftres + subg + 2
1262 shiftres_0 = shiftres_0 + newsize
1263 msize_p = msize_p + insize
1277 SUBROUTINE poly_padd_uneval3(p, x, pRes, npoly)
1278 REAL(
dp),
DIMENSION(:),
INTENT(inout) :: p
1279 REAL(
dp),
INTENT(in) :: x
1280 REAL(
dp),
DIMENSION(:),
INTENT(in) :: pres
1281 INTEGER,
INTENT(in),
OPTIONAL :: npoly
1283 INTEGER :: grad, my_npoly, newsize, size_p
1284 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: xi
1286 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
1288 IF (
PRESENT(npoly)) my_npoly = npoly
1289 size_p =
SIZE(p)/my_npoly
1290 newsize =
SIZE(pres)/my_npoly
1291 grad = grad_size2(newsize)
1294 ALLOCATE (xi(grad + 1))
1312 INTEGER,
INTENT(in) :: size_p
1313 REAL(
dp),
DIMENSION(IF_CHECK(size_p, *)), &
1315 REAL(
dp),
INTENT(in) :: x
1316 INTEGER,
INTENT(in) :: size_pres
1317 REAL(
dp),
DIMENSION(IF_CHECK(size_pRes, *)), &
1319 INTEGER,
INTENT(in) :: npoly, grad
1320 REAL(
dp),
DIMENSION(IF_CHECK(grad+1, *)), &
1323 INTEGER :: i, igrad, ii, ii0, insize, ipoly, j, &
1324 msize_p, newsize, pshift, shiftres, &
1325 shiftres_0, subg, upsize
1327 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
1328 insize = size_p/npoly
1329 newsize = size_pres/npoly
1330 upsize = (grad + 1)*(grad + 2)*(grad + 3)/6
1339 p(pshift + ii) = p(pshift + ii) + pres(shiftres + a_reduce_idx3(ii))*xi(a_mono_exp3(1, ii) + 1)
1341 shiftres = shiftres + newsize
1342 pshift = pshift + insize
1352 shiftres = shiftres_0
1358 IF (msize_p < ii)
EXIT grad_do
1359 p(ii) = p(ii) + pres(shiftres - j)*xi(i + 1)
1362 shiftres = shiftres + subg + 2
1367 shiftres_0 = shiftres_0 + newsize
1368 msize_p = msize_p + insize
1380 SUBROUTINE poly_p_eval2(p, x, pRes, npoly)
1381 REAL(
dp),
DIMENSION(:),
INTENT(in) :: p
1382 REAL(
dp),
INTENT(in) :: x
1383 REAL(
dp),
DIMENSION(:),
INTENT(inout) :: pres
1384 INTEGER,
INTENT(in),
OPTIONAL :: npoly
1386 INTEGER :: grad, my_npoly, newsize, size_p
1387 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: xi
1389 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
1391 IF (
PRESENT(npoly)) my_npoly = npoly
1392 size_p =
SIZE(p)/my_npoly
1393 grad = grad_size2(size_p)
1394 newsize =
SIZE(pres)/my_npoly
1397 ALLOCATE (xi(grad + 1))
1398 CALL poly_p_eval2b(p,
SIZE(p), x, pres,
SIZE(pres), my_npoly, grad, xi)
1414 INTEGER,
INTENT(in) :: size_p
1415 REAL(
dp),
DIMENSION(IF_CHECK(size_p, *)), &
1417 REAL(
dp),
INTENT(in) :: x
1418 INTEGER,
INTENT(in) :: size_pres
1419 REAL(
dp),
DIMENSION(IF_CHECK(size_pRes, *)), &
1420 INTENT(inout) :: pres
1421 INTEGER,
INTENT(in) :: npoly
1423 REAL(
dp),
DIMENSION(IF_CHECK(grad+1, *)) :: xi
1425 INTEGER :: i, igrad, ii, ii0, ij, insize, ipoly, &
1426 msize_p, newsize, pshift, shiftres
1428 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
1429 insize = size_p/npoly
1430 newsize = size_pres/npoly
1431 pres(1:size_pres) = 0.0_dp
1441 pres(shiftres + a_mono_exp2(2, ii)) = pres(shiftres + a_mono_exp2(2, ii)) + p(pshift + ii)*xi(a_mono_exp2(1, ii) + 1)
1443 shiftres = shiftres + newsize
1444 pshift = pshift + insize
1452 grad_do2:
DO igrad =
max_grad2 + 1, grad
1456 IF (msize_p < ii)
EXIT grad_do2
1458 pres(ij) = pres(ij) + p(ii)*xi(i + 1)
1463 msize_p = msize_p + insize
1464 shiftres = shiftres + newsize
1479 SUBROUTINE poly_padd_uneval2(p, x, pRes, npoly)
1480 REAL(
dp),
DIMENSION(:),
INTENT(inout) :: p
1481 REAL(
dp),
INTENT(in) :: x
1482 REAL(
dp),
DIMENSION(:),
INTENT(in) :: pres
1483 INTEGER,
INTENT(in),
OPTIONAL :: npoly
1485 INTEGER :: grad, my_npoly, newsize, size_p
1486 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: xi
1488 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
1490 IF (
PRESENT(npoly)) my_npoly = npoly
1491 size_p =
SIZE(p)/my_npoly
1492 newsize =
SIZE(pres)/my_npoly
1493 grad = grad_size1(newsize)
1496 ALLOCATE (xi(grad + 1))
1513 INTEGER,
INTENT(in) :: size_p
1514 REAL(
dp),
DIMENSION(IF_CHECK(size_p, *)), &
1516 REAL(
dp),
INTENT(in) :: x
1517 INTEGER,
INTENT(in) :: size_pres
1518 REAL(
dp),
DIMENSION(IF_CHECK(size_pRes, *)), &
1520 INTEGER,
INTENT(in) :: npoly
1522 REAL(
dp),
DIMENSION(IF_CHECK(grad+1, *)) :: xi
1524 INTEGER :: i, igrad, ii, ii0, ij, insize, ipoly, &
1525 msize_p, newsize, pshift, shiftres, &
1528 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
1529 insize = size_p/npoly
1530 upsize = (grad + 1)*(grad + 2)/2
1531 newsize = size_pres/npoly
1541 p(pshift + ii) = p(pshift + ii) + pres(shiftres + a_mono_exp2(2, ii))*xi(a_mono_exp2(1, ii) + 1)
1543 shiftres = shiftres + newsize
1544 pshift = pshift + insize
1552 grad_do2:
DO igrad =
max_grad2 + 1, grad
1556 IF (msize_p < ii)
EXIT grad_do2
1558 p(ii) = p(ii) + pres(ij)*xi(i + 1)
1563 msize_p = msize_p + insize
1564 shiftres = shiftres + newsize
1577 SUBROUTINE poly_eval1(p, x, pRes, npoly)
1578 REAL(
dp),
DIMENSION(:),
INTENT(in) :: p
1579 REAL(
dp),
INTENT(in) :: x
1580 REAL(
dp),
DIMENSION(:),
INTENT(inout) :: pres
1581 INTEGER,
INTENT(in),
OPTIONAL :: npoly
1583 INTEGER :: i, ipoly, my_npoly, pshift, size_p
1587 IF (
PRESENT(npoly)) my_npoly = npoly
1588 size_p =
SIZE(p)/my_npoly
1589 cpassert(
SIZE(pres) >= my_npoly)
1591 DO ipoly = 1, my_npoly
1595 vv = vv + p(pshift + i)*xx
1599 pshift = pshift + size_p
1611 SUBROUTINE poly_eval2(p, x, y, pRes, npoly)
1612 REAL(
dp),
DIMENSION(:),
INTENT(in) :: p
1613 REAL(
dp),
INTENT(in) :: x, y
1614 REAL(
dp),
DIMENSION(:),
INTENT(inout) :: pres
1615 INTEGER,
INTENT(in),
OPTIONAL :: npoly
1617 INTEGER :: grad, i, igrad, ii, ipoly, j, msize_p, &
1618 my_npoly, pshift, size_p
1620 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: xi, yi
1622 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
1624 IF (
PRESENT(npoly)) my_npoly = npoly
1625 size_p =
SIZE(p)/my_npoly
1626 grad = grad_size2(size_p)
1627 cpassert(
SIZE(pres) >= my_npoly)
1628 ALLOCATE (xi(grad + 1), yi(grad + 1))
1638 DO ipoly = 1, my_npoly
1641 v = v + p(pshift + ii)*xi(a_mono_exp2(1, ii) + 1)*yi(a_mono_exp2(2, ii) + 1)
1644 pshift = pshift + size_p
1649 DO ipoly = 1, my_npoly
1652 grad_do4:
DO igrad =
max_grad2 + 1, grad
1656 IF (msize_p < ii)
EXIT grad_do4
1657 v = v + p(ii)*xi(i + 1)*yi(j)
1662 pres(ipoly) = pres(ipoly) + v
1663 pshift = pshift + size_p
1664 msize_p = msize_p + size_p
1678 SUBROUTINE poly_eval3(p, x, y, z, pRes, npoly)
1679 REAL(
dp),
DIMENSION(:),
INTENT(in) :: p
1680 REAL(
dp),
INTENT(in) :: x, y, z
1681 REAL(
dp),
DIMENSION(:),
INTENT(inout) :: pres
1682 INTEGER,
INTENT(in),
OPTIONAL :: npoly
1684 INTEGER :: grad, i, igrad, ii, ipoly, j, k, &
1685 msize_p, my_npoly, pshift, size_p
1687 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: xi, yi, zi
1689 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
1691 IF (
PRESENT(npoly)) my_npoly = npoly
1692 size_p =
SIZE(p)/my_npoly
1694 cpassert(
SIZE(pres) >= my_npoly)
1695 ALLOCATE (xi(grad + 1), yi(grad + 1), zi(grad + 1))
1709 DO ipoly = 1, my_npoly
1712 v = v + p(pshift + ii)*xi(a_mono_exp3(1, ii) + 1)*yi(a_mono_exp3(2, ii) + 1) &
1713 *zi(a_mono_exp3(3, ii) + 1)
1716 pshift = pshift + size_p
1721 DO ipoly = 1, my_npoly
1724 grad_do3:
DO igrad =
max_grad3 + 1, grad
1728 DO j = igrad - i, 0, -1
1729 ii = (ipoly - 1)*size_p + mono_index3(i, j, igrad - i - j) + 1
1730 IF (msize_p < ii)
EXIT grad_do3
1731 v = v + p(ii)*xi(i + 1)*yi(j + 1)*zi(k)
1737 pres(ipoly) = pres(ipoly) + v
1738 pshift = pshift + size_p
1739 msize_p = msize_p + size_p
1751 SUBROUTINE poly_derive3(p, pRes, npoly, sumUp)
1752 REAL(
dp),
DIMENSION(:),
INTENT(in) :: p
1753 REAL(
dp),
DIMENSION(:),
INTENT(inout) :: pres
1754 INTEGER,
INTENT(in),
OPTIONAL :: npoly
1755 LOGICAL,
INTENT(in),
OPTIONAL :: sumup
1757 INTEGER :: grad, i, igrad, ii, ii2, ipoly, j, k, msize_p, my_npoly, newsize, pshift, size_p, &
1758 xderivshift, yderivshift, yshift, zderivshift, zshift
1761 IF (.NOT. module_initialized) cpabort(
"module d3_poly not initialized")
1763 IF (
PRESENT(npoly)) my_npoly = npoly
1765 IF (
PRESENT(sumup)) my_sumup = sumup
1766 size_p =
SIZE(p)/my_npoly
1767 newsize =
SIZE(pres)/(3*my_npoly)
1770 IF (.NOT. my_sumup) pres = 0
1772 yderivshift = my_npoly*newsize + 1
1773 zderivshift = 2*yderivshift - 1
1775 DO ipoly = 1, my_npoly
1778 pres(xderivshift + a_deriv_idx3(1, ii)) = pres(xderivshift + a_deriv_idx3(1, ii)) &
1779 + p(pshift + ii)*a_mono_exp3(1, ii)
1780 pres(yderivshift + a_deriv_idx3(2, ii)) = pres(yderivshift + a_deriv_idx3(2, ii)) &
1781 + p(pshift + ii)*a_mono_exp3(2, ii)
1782 pres(zderivshift + a_deriv_idx3(3, ii)) = pres(zderivshift + a_deriv_idx3(3, ii)) &
1783 + p(pshift + ii)*a_mono_exp3(3, ii)
1785 xderivshift = xderivshift + newsize
1786 yderivshift = yderivshift + newsize
1787 zderivshift = zderivshift + newsize
1788 pshift = pshift + size_p
1792 yderivshift = my_npoly*newsize
1793 zderivshift = 2*yderivshift - 1
1797 DO ipoly = 1, my_npoly
1800 grad_do5:
DO igrad =
max_grad3 + 1, grad
1801 yshift = yderivshift
1802 zshift = zderivshift
1805 DO j = igrad - i, 0, -1
1806 IF (ii > msize_p)
EXIT grad_do5
1808 IF (i > 0) pres(ii2) = pres(ii2) + p(ii)*i
1809 IF (j > 0) pres(yshift + ii2) = pres(yshift + ii2) + p(ii)*j
1810 IF (k > 0) pres(zshift + ii2) = pres(zshift + ii2) + k*p(ii)
1818 ii2 = ii2 - igrad - 1
1820 pshift = pshift + size_p
1821 xderivshift = xderivshift + newsize
1822 msize_p = msize_p + size_p
1834 REAL(
dp),
DIMENSION(:),
INTENT(in) :: poly_cp2k
1835 INTEGER,
INTENT(in) :: grad
1836 REAL(
dp),
DIMENSION(:),
INTENT(out) :: poly_d3
1838 INTEGER :: cp_ii, i, j, k, mgrad, mgrad2, sgrad, &
1839 sgrad2, sgrad2k, sgrad3, sgrad3k, &
1840 shifti, shiftj, shiftk, size_p
1842 size_p = (grad + 1)*(grad + 2)*(grad + 3)/6
1843 cpassert(
SIZE(poly_cp2k) >= size_p)
1844 cpassert(
SIZE(poly_d3) >= size_p)
1850 sgrad2k = sgrad2k + k
1851 sgrad3k = sgrad3k + sgrad2k
1857 shiftj = mgrad2 + shiftk
1859 shifti = shiftj + sgrad3
1860 DO i = 0, grad - j - k
1862 poly_d3(shifti) = poly_cp2k(cp_ii)
1864 mgrad2 = mgrad2 + mgrad
1865 shifti = shifti + mgrad2
1867 sgrad2 = sgrad2 + sgrad + 1
1868 sgrad3 = sgrad3 + sgrad2
1871 IF (
SIZE(poly_d3) >= size_p)
THEN
1872 poly_d3(size_p + 1:) = 0.0_dp
1883 REAL(
dp),
DIMENSION(:),
INTENT(out) :: poly_cp2k
1884 INTEGER,
INTENT(in) :: grad
1885 REAL(
dp),
DIMENSION(:),
INTENT(in) :: poly_d3
1887 INTEGER :: cp_ii, i, j, k, mgrad, mgrad2, sgrad, &
1888 sgrad2, sgrad2k, sgrad3, sgrad3k, &
1889 shifti, shiftj, shiftk, size_p
1891 size_p = (grad + 1)*(grad + 2)*(grad + 3)/6
1892 cpassert(
SIZE(poly_cp2k) >= size_p)
1893 cpassert(
SIZE(poly_d3) >= size_p)
1899 sgrad2k = sgrad2k + k
1900 sgrad3k = sgrad3k + sgrad2k
1906 shiftj = mgrad2 + shiftk
1908 shifti = shiftj + sgrad3
1909 DO i = 0, grad - j - k
1911 poly_cp2k(cp_ii) = poly_d3(shifti)
1913 mgrad2 = mgrad2 + mgrad
1914 shifti = shifti + mgrad2
1916 sgrad2 = sgrad2 + sgrad + 1
1917 sgrad3 = sgrad3 + sgrad2
1920 IF (
SIZE(poly_d3) >= size_p)
THEN
1921 poly_cp2k(size_p + 1:) = 0.0_dp
Routines to efficiently handle dense polynomial in 3 variables up to a given degree....
integer, parameter, public cached_dim2
subroutine, public poly_cp2k2d3(poly_cp2k, grad, poly_d3)
subroutine that converts from the cp2k poly format to the d3 poly format
subroutine, public poly_p_eval2b(p, size_p, x, pRes, size_pRes, npoly, grad, xi)
low level routine of poly_p_eval2 without checks
pure integer function, public poly_size1(maxgrad)
size of a polynomial in x up to the given degree
subroutine, public poly_padd_uneval2b(p, size_p, x, pRes, size_pRes, npoly, grad, xi)
low level routine of poly_p_uneval2 without checks
subroutine, public init_d3_poly_module()
initialization of the cache, is called by functions in this module that use cached values
subroutine, public poly_d32cp2k(poly_cp2k, grad, poly_d3)
subroutine that converts from the d3 poly format to the cp2k poly format
subroutine, public poly_affine_t3(p, m, b, pRes, npoly)
returns in the polynomials pRes the affine transformation x -> m*x+b of p
subroutine, public poly_padd_uneval3b(p, size_p, x, pRes, size_pRes, npoly, grad, xi)
low level routine of poly_padd_uneval3 without checks
pure integer function, public poly_size2(maxgrad)
size of a polynomial in x,y up to the given degree
subroutine, public poly_affine_t3t(p, m, b, pRes, npoly)
returns in the polynomials pRes the transpose of the affine transformation x -> m*x+b of p
integer, parameter, public cached_dim3
integer, parameter, public cached_dim1
pure integer function, public grad_size3(n)
max grad for a polynom of the given size
subroutine, public poly_p_eval3b(p, size_p, x, pRes, size_pRes, npoly, grad, xi)
low level routine of poly_p_eval3 without checks
pure integer function, public poly_size3(maxgrad)
size of a polynomial in x,y,z up to the given degree
integer, parameter, public max_grad2
integer, parameter, public max_grad3
Defines the basic variable types.
integer, parameter, public dp