95 #ifndef __INTREPID2_POLYLIB_DEF_HPP__
96 #define __INTREPID2_POLYLIB_DEF_HPP__
98 #if defined(_MSC_VER) || defined(_WIN32) && defined(__ICL)
100 #ifndef _USE_MATH_DEFINES
101 #define _USE_MATH_DEFINES
106 namespace Intrepid2 {
113 template<
typename zViewType,
115 KOKKOS_INLINE_FUNCTION
117 Polylib::Serial::Cubature<POLYTYPE_GAUSS>::
118 getValues( zViewType z,
120 const ordinal_type np,
123 const double one = 1.0, two = 2.0, apb = alpha + beta;
126 JacobiZeros(z, np, alpha, beta);
127 JacobiPolynomialDerivative(np, z, w, np, alpha, beta);
129 fac = pow(two, apb + one)*GammaFunction(alpha + np + one)*GammaFunction(beta + np + one);
130 fac /= GammaFunction((np + one))*GammaFunction(apb + np + one);
132 for (ordinal_type i = 0; i < np; ++i)
133 w(i) = fac/(w(i)*w(i)*(one-z(i)*z(i)));
137 template<
typename zViewType,
139 KOKKOS_INLINE_FUNCTION
141 Polylib::Serial::Cubature<POLYTYPE_GAUSS_RADAU_LEFT>::
142 getValues( zViewType z,
144 const ordinal_type np,
151 const double one = 1.0, two = 2.0, apb = alpha + beta;
156 auto z_plus_1 = Kokkos::subview(z, Kokkos::pair<ordinal_type,ordinal_type>(1, z.extent(0)));
157 JacobiZeros(z_plus_1, np-1, alpha, beta+1);
159 Kokkos::View<typename zViewType::value_type*,Kokkos::AnonymousSpace,Kokkos::MemoryUnmanaged> null;
160 JacobiPolynomial(np, z, w, null, np-1, alpha, beta);
162 fac = pow(two, apb)*GammaFunction(alpha + np)*GammaFunction(beta + np);
163 fac /= GammaFunction(np)*(beta + np)*GammaFunction(apb + np + 1);
165 for (ordinal_type i = 0; i < np; ++i)
166 w(i) = fac*(1-z(i))/(w(i)*w(i));
167 w(0) *= (beta + one);
172 template<
typename zViewType,
174 KOKKOS_INLINE_FUNCTION
176 Polylib::Serial::Cubature<POLYTYPE_GAUSS_RADAU_RIGHT>::
177 getValues( zViewType z,
179 const ordinal_type np,
186 const double one = 1.0, two = 2.0, apb = alpha + beta;
189 JacobiZeros(z, np-1, alpha+1, beta);
192 Kokkos::View<typename zViewType::value_type*,Kokkos::AnonymousSpace,Kokkos::MemoryUnmanaged> null;
193 JacobiPolynomial(np, z, w, null, np-1, alpha, beta);
195 fac = pow(two,apb)*GammaFunction(alpha + np)*GammaFunction(beta + np);
196 fac /= GammaFunction(np)*(alpha + np)*GammaFunction(apb + np + 1);
198 for (ordinal_type i = 0; i < np; ++i)
199 w(i) = fac*(1+z(i))/(w(i)*w(i));
200 w(np-1) *= (alpha + one);
205 template<
typename zViewType,
207 KOKKOS_INLINE_FUNCTION
209 Polylib::Serial::Cubature<POLYTYPE_GAUSS_LOBATTO>::
210 getValues( zViewType z,
212 const ordinal_type np,
219 const double one = 1.0, apb = alpha + beta, two = 2.0;
225 auto z_plus_1 = Kokkos::subview(z, Kokkos::pair<ordinal_type,ordinal_type>(1, z.extent(0)));
226 JacobiZeros(z_plus_1, np-2, alpha+one, beta+one);
228 Kokkos::View<typename zViewType::value_type*,Kokkos::AnonymousSpace,Kokkos::MemoryUnmanaged> null;
229 JacobiPolynomial(np, z, w, null, np-1, alpha, beta);
231 fac = pow(two, apb + 1)*GammaFunction(alpha + np)*GammaFunction(beta + np);
232 fac /= (np-1)*GammaFunction(np)*GammaFunction(alpha + beta + np + one);
234 for (ordinal_type i = 0; i < np; ++i)
235 w(i) = fac/(w(i)*w(i));
237 w(0) *= (beta + one);
238 w(np-1) *= (alpha + one);
247 template<
typename DViewType,
249 KOKKOS_INLINE_FUNCTION
251 Polylib::Serial::Derivative<POLYTYPE_GAUSS>::
252 getValues( DViewType D,
254 const ordinal_type np,
260 const double one = 1.0, two = 2.0;
262 typename zViewType::value_type pd_buf[MaxPolylibPoint];
263 Kokkos::View<
typename zViewType::value_type*,
264 Kokkos::AnonymousSpace,Kokkos::MemoryUnmanaged>
265 pd((
typename zViewType::pointer_type)&pd_buf[0], MaxPolylibPoint);
267 JacobiPolynomialDerivative(np, z, pd, np, alpha, beta);
269 for (ordinal_type i = 0; i < np; ++i)
270 for (ordinal_type j = 0; j < np; ++j)
273 D(i,j) = pd(i)/(pd(j)*(z(i)-z(j)));
275 D(i,j) = (alpha - beta + (alpha + beta + two)*z(j))/
276 (two*(one - z(j)*z(j)));
281 template<
typename DViewType,
283 KOKKOS_INLINE_FUNCTION
285 Polylib::Serial::Derivative<POLYTYPE_GAUSS_RADAU_LEFT>::
286 getValues( DViewType D,
288 const ordinal_type np,
294 const double one = 1.0, two = 2.0;
296 typename zViewType::value_type pd_buf[MaxPolylibPoint];
297 Kokkos::View<
typename zViewType::value_type*,
298 Kokkos::AnonymousSpace,Kokkos::MemoryUnmanaged>
299 pd((
typename zViewType::pointer_type)&pd_buf[0], MaxPolylibPoint);
301 pd(0) = pow(-one,np-1)*GammaFunction(np+beta+one);
302 pd(0) /= GammaFunction(np)*GammaFunction(beta+two);
304 auto pd_plus_1 = Kokkos::subview(pd, Kokkos::pair<ordinal_type,ordinal_type>(1, pd.extent(0)));
305 auto z_plus_1 = Kokkos::subview( z, Kokkos::pair<ordinal_type,ordinal_type>(1, z.extent(0)));
307 JacobiPolynomialDerivative(np-1, z_plus_1, pd_plus_1, np-1, alpha, beta+1);
308 for(ordinal_type i = 1; i < np; ++i)
311 for (ordinal_type i = 0; i < np; ++i)
312 for (ordinal_type j = 0; j < np; ++j)
314 D(i,j) = pd(i)/(pd(j)*(z(i)-z(j)));
317 D(i,j) = -(np + alpha + beta + one)*(np - one)/
320 D(i,j) = (alpha - beta + one + (alpha + beta + one)*z(j))/
321 (two*(one - z(j)*z(j)));
326 template<
typename DViewType,
328 KOKKOS_INLINE_FUNCTION
330 Polylib::Serial::Derivative<POLYTYPE_GAUSS_RADAU_RIGHT>::
331 getValues( DViewType D,
333 const ordinal_type np,
339 const double one = 1.0, two = 2.0;
341 typename zViewType::value_type pd_buf[MaxPolylibPoint];
342 Kokkos::View<
typename zViewType::value_type*,
343 Kokkos::AnonymousSpace,Kokkos::MemoryUnmanaged>
344 pd((
typename zViewType::pointer_type)&pd_buf[0], MaxPolylibPoint);
346 JacobiPolynomialDerivative(np-1, z, pd, np-1, alpha+1, beta);
347 for (ordinal_type i = 0; i < np-1; ++i)
350 pd(np-1) = -GammaFunction(np+alpha+one);
351 pd(np-1) /= GammaFunction(np)*GammaFunction(alpha+two);
353 for (ordinal_type i = 0; i < np; ++i)
354 for (ordinal_type j = 0; j < np; ++j)
356 D(i,j) = pd(i)/(pd(j)*(z(i)-z(j)));
359 D(i,j) = (np + alpha + beta + one)*(np - one)/
362 D(i,j) = (alpha - beta - one + (alpha + beta + one)*z(j))/
363 (two*(one - z(j)*z(j)));
368 template<
typename DViewType,
370 KOKKOS_INLINE_FUNCTION
372 Polylib::Serial::Derivative<POLYTYPE_GAUSS_LOBATTO>::
373 getValues( DViewType D,
375 const ordinal_type np,
381 const double one = 1.0, two = 2.0;
383 typename zViewType::value_type pd_buf[MaxPolylibPoint];
384 Kokkos::View<
typename zViewType::value_type*,
385 Kokkos::AnonymousSpace,Kokkos::MemoryUnmanaged>
386 pd((
typename zViewType::pointer_type)&pd_buf[0], MaxPolylibPoint);
388 pd(0) = two*pow(-one,np)*GammaFunction(np + beta);
389 pd(0) /= GammaFunction(np - one)*GammaFunction(beta + two);
391 auto pd_plus_1 = Kokkos::subview(pd, Kokkos::pair<ordinal_type,ordinal_type>(1, pd.extent(0)));
392 auto z_plus_1 = Kokkos::subview( z, Kokkos::pair<ordinal_type,ordinal_type>(1, z.extent(0)));
394 JacobiPolynomialDerivative(np-2, z_plus_1, pd_plus_1, np-2, alpha+1, beta+1);
395 for (ordinal_type i = 1; i < np-1; ++i)
396 pd(i) *= (one-z(i)*z(i));
398 pd(np-1) = -two*GammaFunction(np + alpha);
399 pd(np-1) /= GammaFunction(np - one)*GammaFunction(alpha + two);
401 for (ordinal_type i = 0; i < np; ++i)
402 for (ordinal_type j = 0; j < np; ++j)
404 D(i,j) = pd(i)/(pd(j)*(z(i)-z(j)));
407 D(i,j) = (alpha - (np-1)*(np + alpha + beta))/(two*(beta+ two));
409 D(i,j) =-(beta - (np-1)*(np + alpha + beta))/(two*(alpha+ two));
411 D(i,j) = (alpha - beta + (alpha + beta)*z(j))/
412 (two*(one - z(j)*z(j)));
421 template<
typename zViewType>
422 KOKKOS_INLINE_FUNCTION
423 typename zViewType::value_type
424 Polylib::Serial::LagrangianInterpolant<POLYTYPE_GAUSS>::
425 getValue(
const ordinal_type i,
426 const typename zViewType::value_type z,
428 const ordinal_type np,
431 const double tol = tolerence();
433 typedef typename zViewType::value_type value_type;
434 typedef typename zViewType::pointer_type pointer_type;
436 value_type h, p_buf, pd_buf, zi_buf = zgj(i);
437 Kokkos::View<value_type*,Kokkos::AnonymousSpace,Kokkos::MemoryUnmanaged>
438 p((pointer_type)&p_buf, 1), pd((pointer_type)&pd_buf, 1), zi((pointer_type)&zi_buf, 1),
439 zv(const_cast<pointer_type>(&z), 1), null;
441 const auto dz = z - zi(0);
442 if (Util<value_type>::abs(dz) < tol)
445 JacobiPolynomialDerivative(1, zi, pd, np, alpha, beta);
446 JacobiPolynomial(1, zv, p, null , np, alpha, beta);
454 template<
typename zViewType>
455 KOKKOS_INLINE_FUNCTION
456 typename zViewType::value_type
457 Polylib::Serial::LagrangianInterpolant<POLYTYPE_GAUSS_RADAU_LEFT>::
458 getValue(
const ordinal_type i,
459 const typename zViewType::value_type z,
460 const zViewType zgrj,
461 const ordinal_type np,
464 const double tol = tolerence();
466 typedef typename zViewType::value_type value_type;
467 typedef typename zViewType::pointer_type pointer_type;
469 value_type h, p_buf, pd_buf, zi_buf = zgrj(i);
470 Kokkos::View<value_type*,Kokkos::AnonymousSpace,Kokkos::MemoryUnmanaged>
471 p((pointer_type)&p_buf, 1), pd((pointer_type)&pd_buf, 1), zi((pointer_type)&zi_buf, 1),
472 zv(const_cast<pointer_type>(&z), 1), null;
474 const auto dz = z - zi(0);
475 if (Util<value_type>::abs(dz) < tol)
478 JacobiPolynomial(1, zi, p , null, np-1, alpha, beta + 1);
481 JacobiPolynomialDerivative(1, zi, pd, np-1, alpha, beta + 1);
482 h = (1.0 + zi(0))*pd(0) + p(0);
484 JacobiPolynomial(1, zv, p, null, np-1, alpha, beta + 1);
485 h = (1.0 + z)*p(0)/(h*dz);
492 template<
typename zViewType>
493 KOKKOS_INLINE_FUNCTION
494 typename zViewType::value_type
495 Polylib::Serial::LagrangianInterpolant<POLYTYPE_GAUSS_RADAU_RIGHT>::
496 getValue(
const ordinal_type i,
497 const typename zViewType::value_type z,
498 const zViewType zgrj,
499 const ordinal_type np,
502 const double tol = tolerence();
504 typedef typename zViewType::value_type value_type;
505 typedef typename zViewType::pointer_type pointer_type;
507 value_type h, p_buf, pd_buf, zi_buf = zgrj(i);
508 Kokkos::View<value_type*,Kokkos::AnonymousSpace,Kokkos::MemoryUnmanaged>
509 p((pointer_type)&p_buf, 1), pd((pointer_type)&pd_buf, 1), zi((pointer_type)&zi_buf, 1),
510 zv(const_cast<pointer_type>(&z), 1), null;
512 const auto dz = z - zi(0);
513 if (Util<value_type>::abs(dz) < tol)
516 JacobiPolynomial(1, zi, p , null, np-1, alpha+1, beta);
519 JacobiPolynomialDerivative(1, zi, pd, np-1, alpha+1, beta);
520 h = (1.0 - zi(0))*pd(0) - p(0);
522 JacobiPolynomial (1, zv, p, null, np-1, alpha+1, beta);
523 h = (1.0 - z)*p(0)/(h*dz);
530 template<
typename zViewType>
531 KOKKOS_INLINE_FUNCTION
532 typename zViewType::value_type
533 Polylib::Serial::LagrangianInterpolant<POLYTYPE_GAUSS_LOBATTO>::
534 getValue(
const ordinal_type i,
535 const typename zViewType::value_type z,
536 const zViewType zglj,
537 const ordinal_type np,
540 const double one = 1.0, two = 2.0, tol = tolerence();
542 typedef typename zViewType::value_type value_type;
543 typedef typename zViewType::pointer_type pointer_type;
545 value_type h, p_buf, pd_buf, zi_buf = zglj(i);
546 Kokkos::View<value_type*,Kokkos::AnonymousSpace,Kokkos::MemoryUnmanaged>
547 p((pointer_type)&p_buf, 1), pd((pointer_type)&pd_buf, 1), zi((pointer_type)&zi_buf, 1),
548 zv(const_cast<pointer_type>(&z), 1), null;
550 const auto dz = z - zi(0);
551 if (Util<value_type>::abs(dz) < tol)
554 JacobiPolynomial(1, zi, p , null, np-2, alpha + one, beta + one);
557 JacobiPolynomialDerivative(1, zi, pd, np-2, alpha + one, beta + one);
558 h = (one - zi(0)*zi(0))*pd(0) - two*zi(0)*p(0);
560 JacobiPolynomial(1, zv, p, null, np-2, alpha + one, beta + one);
561 h = (one - z*z)*p(0)/(h*dz);
570 template<EPolyType polyType>
571 template<
typename imViewType,
572 typename zgrjViewType,
574 KOKKOS_INLINE_FUNCTION
576 Polylib::Serial::InterpolationOperator<polyType>::
577 getMatrix( imViewType im,
578 const zgrjViewType zgrj,
580 const ordinal_type nz,
581 const ordinal_type mz,
584 for (ordinal_type i = 0; i < mz; ++i) {
585 const auto zp = zm(i);
586 for (ordinal_type j = 0; j < nz; ++j)
587 im(i, j) = LagrangianInterpolant<polyType>::getValue(j, zp, zgrj, nz, alpha, beta);
593 template<
typename zViewType,
594 typename polyiViewType,
595 typename polydViewType>
596 KOKKOS_INLINE_FUNCTION
603 const ordinal_type n,
606 const double zero = 0.0, one = 1.0, two = 2.0;
614 for (ordinal_type i = 0; i < np; ++i)
617 for (ordinal_type i = 0; i < np; ++i)
621 for (ordinal_type i = 0; i < np; ++i)
622 polyi(i) = 0.5*(alpha - beta + (alpha + beta + two)*z(i));
624 for (ordinal_type i = 0; i < np; ++i)
625 polyd(i) = 0.5*(alpha + beta + two);
627 double a1, a2, a3, a4;
628 const double apb = alpha + beta;
630 typename polyiViewType::value_type
631 poly[MaxPolylibPoint]={}, polyn1[MaxPolylibPoint]={}, polyn2[MaxPolylibPoint]={};
634 for (ordinal_type i=0;i<np;++i)
637 for (ordinal_type i = 0; i < np; ++i) {
639 polyn1[i] = 0.5*(alpha - beta + (alpha + beta + two)*z(i));
642 for (
auto k = 2; k <= n; ++k) {
643 a1 = two*k*(k + apb)*(two*k + apb - two);
644 a2 = (two*k + apb - one)*(alpha*alpha - beta*beta);
645 a3 = (two*k + apb - two)*(two*k + apb - one)*(two*k + apb);
646 a4 = two*(k + alpha - one)*(k + beta - one)*(two*k + apb);
652 for (ordinal_type i = 0; i < np; ++i) {
653 poly [i] = (a2 + a3*z(i))*polyn1[i] - a4*polyn2[i];
654 polyn2[i] = polyn1[i];
655 polyn1[i] = poly [i];
660 a1 = n*(alpha - beta);
661 a2 = n*(two*n + alpha + beta);
662 a3 = two*(n + alpha)*(n + beta);
663 a4 = (two*n + alpha + beta);
669 for (ordinal_type i = 0; i < np; ++i) {
670 polyd(i) = (a1- a2*z(i))*poly[i] + a3*polyn2[i];
671 polyd(i) /= (one - z(i)*z(i));
676 for (ordinal_type i=0;i<np;++i)
681 template<
typename zViewType,
682 typename polydViewType>
683 KOKKOS_INLINE_FUNCTION
689 const ordinal_type n,
692 const double one = 1.0;
694 for(ordinal_type i = 0; i < np; ++i)
697 Kokkos::View<typename polydViewType::value_type*,Kokkos::AnonymousSpace,Kokkos::MemoryUnmanaged> null;
698 JacobiPolynomial(np, z, polyd, null, n-1, alpha+one, beta+one);
699 for(ordinal_type i = 0; i < np; ++i)
700 polyd(i) *= 0.5*(alpha + beta + n + one);
706 template<
typename zViewType,
707 bool DeflationEnabled>
708 KOKKOS_INLINE_FUNCTION
712 const ordinal_type n,
715 if (DeflationEnabled)
716 JacobiZerosPolyDeflation(z, n, alpha, beta);
718 JacobiZerosTriDiagonal(z, n, alpha, beta);
721 template<
typename zViewType>
722 KOKKOS_INLINE_FUNCTION
725 JacobiZerosPolyDeflation( zViewType z,
726 const ordinal_type n,
732 const double dth = M_PI/(2.0*n);
733 const double one = 1.0, two = 2.0;
734 const double tol = tolerence();
736 typedef typename zViewType::value_type value_type;
737 typedef typename zViewType::pointer_type pointer_type;
739 value_type r_buf, poly_buf, pder_buf;
740 Kokkos::View<value_type*,Kokkos::AnonymousSpace,Kokkos::MemoryUnmanaged>
741 poly((pointer_type)&poly_buf, 1), pder((pointer_type)&pder_buf, 1), r((pointer_type)&r_buf, 1);
743 value_type rlast = 0.0;
744 for (
auto k = 0; k < n; ++k) {
745 r(0) = -cos((two*(
double)k + one) * dth);
747 r(0) = 0.5*(r(0) + rlast);
749 for (ordinal_type j = 1; j < MaxPolylibIteration; ++j) {
750 JacobiPolynomial(1, r, poly, pder, n, alpha, beta);
753 for (ordinal_type i = 0; i < k; ++i)
754 sum += one/(r(0) - z(i));
756 const value_type delr = -poly(0) / (pder(0) - sum * poly(0));
767 template<
typename aViewType>
768 KOKKOS_INLINE_FUNCTION
771 JacobiZerosTriDiagonal( aViewType a,
772 const ordinal_type n,
778 typedef typename aViewType::value_type value_type;
779 typedef typename aViewType::pointer_type pointer_type;
781 value_type b_buf[MaxPolylibPoint];
782 Kokkos::View<value_type*,Kokkos::AnonymousSpace,Kokkos::MemoryUnmanaged>
783 b((pointer_type)&b_buf[0], MaxPolylibPoint);
786 const double apb = alpha + beta;
787 double apbi = 2.0 + apb;
789 b(n-1) = pow(2.0,apb+1.0)*GammaFunction(alpha+1.0)*GammaFunction(beta+1.0)/GammaFunction(apbi);
790 a(0) = (beta-alpha)/apbi;
791 b(0) = sqrt(4.0*(1.0+alpha)*(1.0+beta)/((apbi+1.0)*apbi*apbi));
793 const double a2b2 = beta*beta-alpha*alpha;
794 for (ordinal_type i = 1; i < n-1; ++i) {
795 apbi = 2.0*(i+1) + apb;
796 a(i) = a2b2/((apbi-2.0)*apbi);
797 b(i) = sqrt(4.0*(i+1)*(i+1+alpha)*(i+1+beta)*(i+1+apb)/
798 ((apbi*apbi-1)*apbi*apbi));
803 if (n>1) a(n-1) = a2b2/((apbi-2.0)*apbi);
810 template<
typename dViewType,
812 KOKKOS_INLINE_FUNCTION
817 const ordinal_type n) {
818 ordinal_type m,l,iter,i,k;
820 typedef typename dViewType::value_type value_type;
821 value_type s,r,p,g,f,dd,c,b;
823 for (l=0; l<n; ++l) {
826 for (m=l; m<n-1; ++m) {
831 if (iter++ == MaxPolylibIteration) {
832 INTREPID2_TEST_FOR_ABORT(
true,
833 ">>> ERROR (Polylib::Serial): Too many iterations in TQLI.");
835 g=(d(l+1)-d(l))/(2.0*e(l));
841 for (i=m-1; i>=l; i--) {
856 r=(d(i)-g)*s+2.0*c*b;
869 for (i = 0; i < n-1; ++i) {
872 for (l = i+1; l < n; ++l)
882 KOKKOS_INLINE_FUNCTION
888 if (x == -0.5) gamma = -2.0*sqrt(M_PI);
889 else if (x == 0.0) gamma = 1.0;
890 else if ((x-(ordinal_type)x) == 0.5) {
891 ordinal_type n = (ordinal_type) x;
899 }
else if ((x-(ordinal_type)x) == 0.0) {
900 ordinal_type n = (ordinal_type) x;
909 INTREPID2_TEST_FOR_ABORT(
true,
910 ">>> ERROR (Polylib::Serial): Argument is not of integer or half order.");
static KOKKOS_INLINE_FUNCTION void JacobiPolynomialDerivative(const ordinal_type np, const zViewType z, polydViewType polyd, const ordinal_type n, const double alpha, const double beta)
Calculate the derivative of Jacobi polynomials.
static KOKKOS_INLINE_FUNCTION void JacobiPolynomial(const ordinal_type np, const zViewType z, polyiViewType poly_in, polydViewType polyd, const ordinal_type n, const double alpha, const double beta)
Routine to calculate Jacobi polynomials, , and their first derivative, .
static KOKKOS_INLINE_FUNCTION void JacobiZeros(zViewType z, const ordinal_type n, const double alpha, const double beta)
Calculate the n zeros, z, of the Jacobi polynomial, i.e. .
static KOKKOS_INLINE_FUNCTION double GammaFunction(const double x)
Calculate the Gamma function , , for integer values x and halves.
static KOKKOS_INLINE_FUNCTION void TriQL(dViewType d, eViewType e, const ordinal_type n)
QL algorithm for symmetric tridiagonal matrix.