action functions
|
Please note that the library has not been "officially" released. While we continue to work on the documentation, these web pages are likely to contain broken links and documents in draft form. Please send an email to if you wish to be informed of the library's "official" release. |
00001 //LIC// ==================================================================== 00002 //LIC// This file forms part of oomph-lib, the object-oriented, 00003 //LIC// multi-physics finite-element library, available 00004 //LIC// at http://www.oomph-lib.org. 00005 //LIC// 00006 //LIC// Version 0.90. August 3, 2009. 00007 //LIC// 00008 //LIC// Copyright (C) 2006-2009 Matthias Heil and Andrew Hazel 00009 //LIC// 00010 //LIC// This library is free software; you can redistribute it and/or 00011 //LIC// modify it under the terms of the GNU Lesser General Public 00012 //LIC// License as published by the Free Software Foundation; either 00013 //LIC// version 2.1 of the License, or (at your option) any later version. 00014 //LIC// 00015 //LIC// This library is distributed in the hope that it will be useful, 00016 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 //LIC// Lesser General Public License for more details. 00019 //LIC// 00020 //LIC// You should have received a copy of the GNU Lesser General Public 00021 //LIC// License along with this library; if not, write to the Free Software 00022 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00023 //LIC// 02110-1301 USA. 00024 //LIC// 00025 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk. 00026 //LIC// 00027 //LIC//==================================================================== 00028 //Header functions for functions used to generate orthogonal polynomials 00029 //Include guards to prevent multiple inclusion of the header 00030 00031 #ifndef OOMPH_ORTHPOLY_HEADER 00032 #define OOMPH_ORTHPOLY_HEADER 00033 00034 // Config header generated by autoconfig 00035 #ifdef HAVE_CONFIG_H 00036 #include <oomph-lib-config.h> 00037 #endif 00038 00039 //Oomph-lib include 00040 #include "Vector.h" 00041 #include "oomph_utilities.h" 00042 00043 #include <cmath> 00044 00045 namespace oomph 00046 { 00047 00048 //Let's put these things in a namespace 00049 namespace Orthpoly 00050 { 00051 const double pi = 4.0*std::atan(1.0); 00052 const double eps = 1.0e-15; 00053 00054 ///\short Calculates Legendre polynomial of degree p at x 00055 /// using the three term recurrence relation 00056 /// \f$ (n+1) P_{n+1} = (2n+1)xP_{n} - nP_{n-1} \f$ 00057 inline double legendre(const unsigned &p, const double &x) 00058 { 00059 //Return the constant value 00060 if(p==0) return 1.0; 00061 //Return the linear polynomial 00062 else if(p==1) return x; 00063 //Otherwise use the recurrence relation 00064 else{ 00065 //Initialise the terms in the recurrence relation, we're going 00066 //to shift down before using the relation. 00067 double L0 = 1.0, L1 = 1.0, L2 = x; 00068 //Loop over the remaining polynomials 00069 for(unsigned n=1;n<p;n++) 00070 { 00071 //Shift down the values 00072 L0 = L1; L1 = L2; 00073 //Use the three term recurrence 00074 L2 = ((2*n + 1)*x*L1 - n*L0)/(n+1); 00075 } 00076 //Once we've finished return the final value 00077 return L2; 00078 } 00079 } 00080 00081 00082 /// \short Calculates Legendre polynomial of degree p at x 00083 /// using three term recursive formula. Returns all polynomials up to 00084 /// order p in the vector 00085 inline void legendre_vector(const unsigned &p, const double &x, 00086 Vector<double> &polys) 00087 { 00088 //Set the constant term 00089 polys[0] = 1.0; 00090 //If we're only asked for the constant term return 00091 if(p==0) {return;} 00092 //Set the linear polynomial 00093 polys[1] = x; 00094 //Initialise terms for the recurrence relation 00095 double L0 = 1.0, L1 = 1.0, L2 = x; 00096 //Loop over the remaining terms 00097 for(unsigned n=1;n<p;n++){ 00098 //Shift down the values 00099 L0=L1; 00100 L1=L2; 00101 //Use the recurrence relation 00102 L2 = ((2*n+1)*x*L1 - n*L0)/(n+1); 00103 //Set the newly calculated polynomial 00104 polys[n+1] = L2; 00105 } 00106 } 00107 00108 00109 /// \short Calculates first derivative of Legendre 00110 /// polynomial of degree p at x 00111 /// using three term recursive formula. 00112 /// \f$ nP_{n+1}^{'} = (2n+1)xP_{n}^{'} - (n+1)P_{n-1}^{'} \f$ 00113 inline double dlegendre(const unsigned &p, const double &x) 00114 { 00115 double dL1 = 1.0, dL2 = 3*x, dL3=0.0; 00116 if(p==0) return 0.0; 00117 else if(p==1) return dL1; 00118 else if(p==2) return dL2; 00119 else{ 00120 for(unsigned n=2;n<p;n++){ 00121 dL3 = 1.0/n*((2.0*n+1.0)*x*dL2-(n+1.0)*dL1); 00122 dL1=dL2; 00123 dL2=dL3; 00124 } 00125 return dL3; 00126 } 00127 } 00128 00129 /// \short Calculates second derivative of Legendre 00130 /// polynomial of degree p at x 00131 /// using three term recursive formula. 00132 inline double ddlegendre(const unsigned &p, const double &x) 00133 { 00134 double ddL2 = 3.0, ddL3 = 15*x, ddL4=0.0; 00135 if(p==0) return 0.0; 00136 else if(p==1) return 0.0; 00137 else if(p==2) return ddL2; 00138 else if(p==3) return ddL3; 00139 else{ 00140 for(unsigned i=3;i<p;i++){ 00141 ddL4 = 1.0/(i-1.0)*((2.0*i+1.0)*x*ddL3-(i+2.0)*ddL2); 00142 ddL2=ddL3; 00143 ddL3=ddL4; 00144 } 00145 return ddL4; 00146 } 00147 } 00148 00149 /// \short Calculate the Jacobi polnomials 00150 inline double jacobi(const int &alpha, const int &beta, const unsigned &p, 00151 const double &x) 00152 { 00153 double P0 = 1.0; 00154 double P1 = 0.5*(alpha-beta+(alpha+beta+2.0)*x); 00155 double P2; 00156 if(p==0) return P0; 00157 else if(p==1) return P1; 00158 else{ 00159 for(unsigned n=1;n<p;n++){ 00160 double a1n = 2*(n+1)*(n+alpha+beta+1)*(2*n+alpha+beta); 00161 double a2n = (2*n+alpha+beta+1)*(alpha*alpha-beta*beta); 00162 double a3n = (2*n+alpha+beta)*(2*n+alpha+beta+1)*(2*n+alpha+beta+2); 00163 double a4n = 2*(n+alpha)*(n+beta)*(2*n+alpha+beta+2); 00164 P2 = ( (a2n+a3n*x)*P1 - a4n*P0 ) / a1n; 00165 P0 = P1; 00166 P1 = P2; 00167 } 00168 return P2; 00169 } 00170 } 00171 00172 /// \short Calculate the Jacobi polnomials all in one goe 00173 inline void jacobi(const int &alpha, const int &beta, const unsigned &p, 00174 const double &x, 00175 Vector<double> &polys) 00176 { 00177 //Set the constant term 00178 polys[0] = 1.0; 00179 //If we've only been asked for the constant term, bin out 00180 if(p==0) {return;} 00181 //Set the linear polynomial 00182 polys[1] = 0.5*(alpha-beta+(alpha+beta+2.0)*x); 00183 //Initialise the terms for the recurrence relation 00184 double P0 = 1.0; 00185 double P1 = 1.0; 00186 double P2 = 0.5*(alpha-beta+(alpha+beta+2.0)*x); 00187 //Loop over the remaining terms 00188 for(unsigned n=1;n<p;n++) 00189 { 00190 //Shift down the terms 00191 P0 = P1; 00192 P1 = P2; 00193 //Set the constants 00194 double a1n = 2*(n+1)*(n+alpha+beta+1)*(2*n+alpha+beta); 00195 double a2n = (2*n+alpha+beta+1)*(alpha*alpha-beta*beta); 00196 double a3n = (2*n+alpha+beta)*(2*n+alpha+beta+1)*(2*n+alpha+beta+2); 00197 double a4n = 2*(n+alpha)*(n+beta)*(2*n+alpha+beta+2); 00198 //Set the latest term 00199 P2 = ( (a2n+a3n*x)*P1 - a4n*P0 ) / a1n; 00200 //Set the newly calculate polynomial 00201 polys[n+1] = P2; 00202 } 00203 } 00204 00205 00206 /// Calculates the Gauss Lobatto Legendre abscissas for degree p = NNode-1 00207 void gll_nodes(const unsigned &Nnode, Vector<double> &x); 00208 00209 // This version of gll_nodes calculates the abscissas AND weights 00210 void gll_nodes(const unsigned &Nnode, Vector<double> &x, Vector<double> &w); 00211 00212 // Calculates the Gauss Legendre abscissas of degree p=Nnode-1 00213 void gl_nodes(const unsigned &Nnode, Vector<double> &x); 00214 00215 // This version of gl_nodes calculates the abscissas AND weights 00216 void gl_nodes(const unsigned &Nnode, Vector<double> &x, Vector<double> &w); 00217 00218 } //End of the namespace 00219 00220 } 00221 00222 #endif
1.4.7