Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 : 4 : // This library is free software; you can redistribute it and/or 5 : // modify it under the terms of the GNU Lesser General Public 6 : // License as published by the Free Software Foundation; either 7 : // version 2.1 of the License, or (at your option) any later version. 8 : 9 : // This library is distributed in the hope that it will be useful, 10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : // Lesser General Public License for more details. 13 : 14 : // You should have received a copy of the GNU Lesser General Public 15 : // License along with this library; if not, write to the Free Software 16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : 18 : #ifndef LIBMESH_JACOBI_POLYNOMIALS_H 19 : #define LIBMESH_JACOBI_POLYNOMIALS_H 20 : 21 : // libMesh includes 22 : #include "libmesh/libmesh_common.h" // Real 23 : 24 : // C++ includes 25 : #include <utility> // std::swap 26 : 27 : namespace libMesh 28 : { 29 : 30 : namespace JacobiPolynomials 31 : { 32 : 33 : /** 34 : * The Jacobi polynomial value and derivative formulas are based on 35 : * the corresponding Wikipedia article [0]. Note that we have shifted 36 : * the indices used in the recurrence relation, otherwise this is 37 : * identical to the recurrence relation given in the article. When 38 : * alpha = beta = 0, the Jacobi polynomials reduce to the Legendre 39 : * polynomials. 40 : * 41 : * [0]: https://en.wikipedia.org/wiki/Jacobi_polynomials 42 : */ 43 : inline 44 9198 : Real value(unsigned n, unsigned alpha, unsigned beta, Real x) 45 : { 46 9198 : if (n == 0) 47 186 : return 1.; 48 : 49 : // Compute constants independent of loop index. 50 8733 : unsigned int ab = alpha + beta; 51 8733 : unsigned int a2 = alpha * alpha; 52 8733 : unsigned int b2 = beta * beta; 53 : 54 1899 : Real p0 = 1; 55 8733 : Real p1 = (alpha + 1) + (ab + 2) * 0.5 * (x - 1); 56 : 57 1899 : unsigned int i = 1; 58 28356 : while (i < n) 59 : { 60 : // Note: we swap before updating p1, so p0 and p1 appear in 61 : // opposite positions than is usual in the update formula. 62 1935 : std::swap(p0, p1); 63 25428 : p1 = (((2*i + ab + 1) * 64 23493 : ((2*i + ab + 2) * (2*i + ab) * x + a2 - b2)) * p0 65 25428 : - 2 * (i + alpha) * (i + beta) * (2*i + ab + 2) * p1) / 66 21558 : (2 * (i + 1) * (i + 1 + ab) * (2*i + ab)); 67 : 68 1935 : ++i; 69 : } 70 1899 : return p1; 71 : } 72 : 73 : inline 74 1875 : Real deriv(unsigned n, unsigned alpha, unsigned beta, Real x) 75 : { 76 : // Call value() with elevated (alpha, beta) and decremented n. 77 1875 : return n == 0 ? 0 : 0.5 * (1 + alpha + beta + n) * value(n-1, alpha+1, beta+1, x); 78 : } 79 : 80 : } // namespace JacobiPolynomials 81 : } // namespace libMesh 82 : 83 : #endif // LIBMESH_JACOBI_POLYNOMIALS_H