00001 namespace Intrepid {
00002
00003 template<class Scalar>
00004 void OrthogonalBases::jrc(const Scalar &alpha , const Scalar &beta ,
00005 const int &n ,
00006 Scalar &an , Scalar &bn, Scalar &cn )
00007 {
00008 an = (2.0 * n + 1.0 + alpha + beta) * ( 2.0 * n + 2.0 + alpha + beta )
00009 / ( 2.0 * ( n + 1 ) * ( n + 1 + alpha + beta ) );
00010 bn = (alpha*alpha-beta*beta)*(2.0*n+1.0+alpha+beta)
00011 / ( 2.0*(n+1.0)*(2.0*n+alpha+beta)*(n+1.0+alpha+beta) );
00012 cn = (n+alpha)*(n+beta)*(2.0*n+2.0+alpha+beta)
00013 / ( (n+1.0)*(n+1.0+alpha+beta)*(2.0*n+alpha+beta) );
00014
00015 return;
00016 }
00017
00018
00019 template<class Scalar, class ScalarArray1, class ScalarArray2>
00020 void OrthogonalBases::tabulateTriangle( const ScalarArray1& z ,
00021 const int n ,
00022 ScalarArray2 & poly_val )
00023 {
00024 const int np = z.dimension( 0 );
00025
00026
00027
00028
00029
00030
00031 int idx_cur = OrthogonalBases::idxtri(0,0);
00032 int idx_curp1,idx_curm1;
00033
00034
00035 for (int i=0;i<np;i++) {
00036 poly_val(idx_cur,i) = 1.0;
00037 }
00038
00039 Teuchos::Array<Scalar> f1(np),f2(np),f3(np);
00040
00041 for (int i=0;i<np;i++) {
00042 f1[i] = 0.5 * (1.0+2.0*(2.0*z(i,0)-1.0)+(2.0*z(i,1)-1.0));
00043 f2[i] = 0.5 * (1.0-(2.0*z(i,1)-1.0));
00044 f3[i] = f2[i] * f2[i];
00045 }
00046
00047
00048 idx_cur = OrthogonalBases::idxtri(1,0);
00049 for (int i=0;i<np;i++) {
00050 poly_val(idx_cur,i) = f1[i];
00051 }
00052
00053
00054 for (int p=1;p<n;p++) {
00055 idx_cur = OrthogonalBases::idxtri(p,0);
00056 idx_curp1 = OrthogonalBases::idxtri(p+1,0);
00057 idx_curm1 = OrthogonalBases::idxtri(p-1,0);
00058 Scalar a = (2.0*p+1.0)/(1.0+p);
00059 Scalar b = p / (p+1.0);
00060
00061 for (int i=0;i<np;i++) {
00062 poly_val(idx_curp1,i) = a * f1[i] * poly_val(idx_cur,i)
00063 - b * f3[i] * poly_val(idx_curm1,i);
00064 }
00065 }
00066
00067
00068 for (int p=0;p<n;p++) {
00069 int idxp0 = OrthogonalBases::idxtri(p,0);
00070 int idxp1 = OrthogonalBases::idxtri(p,1);
00071 for (int i=0;i<np;i++) {
00072 poly_val(idxp1,i) = poly_val(idxp0,i)
00073 *0.5*(1.0+2.0*p+(3.0+2.0*p)*(2.0*z(i,1)-1.0));
00074 }
00075 }
00076
00077
00078 for (int p=0;p<n-1;p++) {
00079 for (int q=1;q<n-p;q++) {
00080 int idxpqp1=OrthogonalBases::idxtri(p,q+1);
00081 int idxpq=OrthogonalBases::idxtri(p,q);
00082 int idxpqm1=OrthogonalBases::idxtri(p,q-1);
00083 Scalar a,b,c;
00084 jrc((Scalar)(2*p+1),(Scalar)0,q,a,b,c);
00085 for (int i=0;i<np;i++) {
00086 poly_val(idxpqp1,i)
00087 = (a*(2.0*z(i,1)-1.0)+b)*poly_val(idxpq,i)
00088 - c*poly_val(idxpqm1,i);
00089 }
00090 }
00091 }
00092
00093 return;
00094 }
00095
00096 template<class Scalar, class ScalarArray1, class ScalarArray2>
00097 void OrthogonalBases::tabulateTetrahedron(const ScalarArray1 &z ,
00098 const int n ,
00099 ScalarArray2 &poly_val )
00100 {
00101 const int np = z.dimension( 0 );
00102 int idxcur;
00103
00104
00105
00106
00107
00108
00109 Teuchos::Array<Scalar> f1(np),f2(np),f3(np),f4(np),f5(np);
00110
00111 for (int i=0;i<np;i++) {
00112 f1[i] = 0.5 * ( 2.0 + 2.0*(2.0*z(i,0)-1.0) + (2.0*z(i,1)-1.0) + (2.0*z(i,2)-1.0) );
00113 f2[i] = pow( 0.5 * ( (2.0*z(i,1)-1.0) + (2.0*z(i,2)-1.0) ) , 2 );
00114 f3[i] = 0.5 * ( 1.0 + 2.0 * (2.0*z(i,1)-1.0) + (2.0*z(i,2)-1.0) );
00115 f4[i] = 0.5 * ( 1.0 - (2.0*z(i,2)-1.0) );
00116 f5[i] = f4[i] * f4[i];
00117 }
00118
00119
00120 idxcur = idxtet(0,0,0);
00121 for (int i=0;i<np;i++) {
00122 poly_val(idxcur,i) = 1.0;
00123 }
00124
00125
00126 idxcur = idxtet(1,0,0);
00127 for (int i=0;i<np;i++) {
00128 poly_val(idxcur,i) = f1[i];
00129 }
00130
00131
00132 for (int p=1;p<n;p++) {
00133 Scalar a1 = (2.0 * p + 1.0) / ( p + 1.0);
00134 Scalar a2 = p / ( p + 1.0 );
00135 int idxp = idxtet(p,0,0);
00136 int idxpp1 = idxtet(p+1,0,0);
00137 int idxpm1 = idxtet(p-1,0,0);
00138
00139 for (int i=0;i<np;i++) {
00140 poly_val(idxpp1,i) = a1 * f1[i] * poly_val(idxp,i) - a2 * f2[i] * poly_val(idxpm1,i);
00141 }
00142 }
00143
00144 for (int p=0;p<n;p++) {
00145 int idx0 = idxtet(p,0,0);
00146 int idx1 = idxtet(p,1,0);
00147 for (int i=0;i<np;i++) {
00148 poly_val(idx1,i) = poly_val(idx0,i) * ( p * ( 1.0 + (2.0*z(i,1)-1.0) ) + 0.5 * ( 2.0 + 3.0 * (2.0*z(i,1)-1.0) + (2.0*z(i,2)-1.0) ) );
00149 }
00150 }
00151
00152
00153 for (int p=0;p<n-1;p++) {
00154 for (int q=1;q<n-p;q++) {
00155 Scalar aq,bq,cq;
00156 jrc((Scalar)(2.0*p+1.0),(Scalar)(0),q,aq,bq,cq);
00157 int idxpqp1 = idxtet(p,q+1,0);
00158 int idxpq = idxtet(p,q,0);
00159 int idxpqm1 = idxtet(p,q-1,0);
00160 for (int i=0;i<np;i++) {
00161 poly_val(idxpqp1,i) = ( aq * f3[i] + bq * f4[i] ) * poly_val(idxpq,i)
00162 - ( cq * f5[i] ) * poly_val(idxpqm1,i);
00163 }
00164 }
00165 }
00166
00167
00168 for (int p=0;p<n;p++) {
00169 for (int q=0;q<n-p;q++) {
00170 int idxpq1 = idxtet(p,q,1);
00171 int idxpq0 = idxtet(p,q,0);
00172 for (int i=0;i<np;i++) {
00173 poly_val(idxpq1,i) = poly_val(idxpq0,i) * ( 1.0 + p + q + ( 2.0 + q + p ) * (2.0*z(i,2)-1.0) );
00174 }
00175 }
00176 }
00177
00178
00179 for (int p=0;p<n-1;p++) {
00180 for (int q=0;q<n-p-1;q++) {
00181 for (int r=1;r<n-p-q;r++) {
00182 Scalar ar,br,cr;
00183 int idxpqrp1 = idxtet(p,q,r+1);
00184 int idxpqr = idxtet(p,q,r);
00185 int idxpqrm1 = idxtet(p,q,r-1);
00186 jrc(2.0*p+2.0*q+2.0,0.0,r,ar,br,cr);
00187 for (int i=0;i<np;i++) {
00188 poly_val(idxpqrp1,i) = (ar * (2.0*z(i,2)-1.0) + br) * poly_val( idxpqr , i ) - cr * poly_val(idxpqrm1,i);
00189 }
00190 }
00191 }
00192 }
00193
00194 return;
00195
00196 }
00197
00198 }