49 namespace LibUtilities
55 for(
int i=0; i<matA.GetRows(); ++i )
64 for(
int i=0; i<int(matA.GetRows()); ++i )
79 NekMatrix<NekDouble>
Invert(
const NekMatrix<NekDouble> & matA)
81 int rows = matA.GetRows(), columns = matA.GetColumns();
82 NekMatrix<NekDouble> matX(rows,columns);
88 for(
int j=0; j<columns; ++j )
96 NekMatrix<NekDouble>
GetTranspose(
const NekMatrix<NekDouble> & matA)
98 int rows = matA.GetRows(), columns = matA.GetColumns();
99 NekMatrix<NekDouble> matX(rows,columns);
101 for(
int i=0; i<rows; ++i )
103 for(
int j=0; j<columns; ++j )
105 matX(j,i) = matA(i,j);
111 int GetSize(
const Array<OneD, const NekDouble> & x)
113 return x.num_elements();
136 for(
int i=0; i<size; ++i )
148 for(
int i=0; i<size; ++i )
150 z[i] = pow( x[i], p );
160 s << setprecision(precision);
161 int M = int(A.GetRows()), N =
int(A.GetColumns());
163 for(
int i=0; i<M; ++i )
165 for(
int j=0; j<N; ++j)
168 s << setw(7) << right << a;
186 s << setprecision(precision) <<
"[ ";
188 for(
int j=0; j<N; ++j )
191 s << setw(7) << right << x;
204 return (degree+1) * (degree+2) / 2;
209 int degree = int(
MakeRound((-3.0 + sqrt(1.0 + 8.0*nBasisFunctions))/2.0));
212 ASSERTL1(
GetTriNumPoints(degree) == nBasisFunctions,
"The number of points defines an expansion of fractional degree, which is not supported." );
218 return (degree+1) * (degree+2) * (degree+3) / 6;
224 NekDouble eq = pow( 81.0 * nBasisFunc + 3.0 * sqrt(-3.0 + 729.0 * nBasisFunc * nBasisFunc), 1.0/3.0);
225 int degree = int(
MakeRound(eq/3.0 + 1.0/eq - 1.0)) - 1;
227 ASSERTL1(
GetTetNumPoints(degree) == nBasisFunc,
"The number of points defines an expansion of fractional degree, which is not supported." );
233 return floor(x + 0.5);
264 else if (degree == 1)
266 for(
int el=0; el<size; ++el)
268 y[el] = 0.5*(alpha - beta + (alpha + beta + 2.0) * x[el]);
275 NekDouble tmp = 2.0 * degm1 + alpha + beta;
276 NekDouble a1 = 2.0 * (degm1 + 1.0) * (degm1 + alpha + beta + 1.0) * tmp;
277 NekDouble a2 = (tmp + 1.0) * (alpha * alpha - beta * beta);
278 NekDouble a3 = tmp * (tmp + 1.0) * (tmp + 2.0);
279 NekDouble a4 = 2.0 * (degm1 + alpha) * (degm1 + beta) * (tmp + 2.0);
286 for (
int el=0; el<size; ++el)
288 y[el] = ((a2 + a3 * x[el]) * z1[el] - a4 * z2[el])/a1;
294 cerr <<
"Bad degree" << endl;
309 else if (degree == 1)
311 y = 0.5*(alpha - beta + (alpha + beta + 2.0) * x);
317 NekDouble tmp = 2.0 * degm1 + alpha + beta;
318 NekDouble a1 = 2.0 * (degm1 + 1.0) * (degm1 + alpha + beta + 1.0) * tmp;
319 NekDouble a2 = (tmp + 1.0) * (alpha * alpha - beta * beta);
320 NekDouble a3 = tmp * (tmp + 1.0) * (tmp + 2.0);
321 NekDouble a4 = 2.0 * (degm1 + alpha) * (degm1 + beta) * (tmp + 2.0);
328 y = ((a2 + a3 * x) * z1 - a4 * z2)/a1;
333 cerr <<
"Bad degree" << endl;
351 for(
int i=2; i<=degree; ++i)
363 else if( degree == 1 )
382 for(
int el=0; el<size; ++el)
384 if( y[el] < 1.0 - 1e-16 )
386 eta_1[el] = 2.0*(1.0 + x[el]) / (1.0 - y[el]) - 1.0;
398 int alpha = 2*p + 1;
int beta = 0;
402 NekDouble w = sqrt((2.0 * p + 1.0) * (p + q + 1.0) / 2.0);
404 for(
int el=0; el<size; ++el)
406 NekDouble zeta = pow((1.0 - eta_2[el])/2.0, p);
408 phi[el] = w * psi_a[el] * psi_b;
423 for(
int el=0; el<size; ++el)
425 if( z[el] < -y[el] - numeric_limits<NekDouble>::epsilon() )
427 eta_1[el] = 2.0*(1.0 + x[el])/(-y[el]-z[el]) - 1.0;
436 for(
int el=0; el<size; ++el)
438 if( z[el] < 1.0 - numeric_limits<NekDouble>::epsilon())
440 eta_2[el] = 2.0*(1.0 + y[el]) / (1.0 - z[el]) - 1.0;
453 int alpha = 2*p + 1;
int beta = 0;
454 int alpha_r = 2*p + 2*q + 2;
int beta_r = 0;
461 for(
int el=0; el<size; ++el)
463 NekDouble zeta_1 = pow((1.0 - eta_2[el])/2.0, p);
464 NekDouble zeta_2 = pow((1.0 - eta_3[el])/2.0, p+q);
469 phi[el] = w * psi_a[el] * psi_b * psi_c;
481 int cols = (degree + 1) * (degree + 2) * (degree + 3)/6;
483 NekMatrix<NekDouble> matV(rows, cols, 0.0);
485 for(
int d=0, n=0; d<=degree; ++d)
487 for(
int p=0; p <= d; ++p)
489 for(
int q=0; q <= d - p; ++q, ++n)
496 for(
int i=0; i<rows; ++i)
498 matV(i,n) = columnVector[i];
518 int cols = (degree + 1) * (degree + 2) / 2;
520 NekMatrix<NekDouble> matV(rows, cols, 0.0);
522 for(
int d=0, n=0; d<=degree; ++d)
524 for(
int p=0; p<=d; ++p, ++n)
530 for(
int i=0; i<rows; ++i)
532 matV(i,n) = columnVector[i];
603 NekMatrix<NekDouble> invertMatrix =
Invert(matS);
606 return matT*invertMatrix;
618 NekMatrix<NekDouble> invertMatrix =
Invert(matS);
621 return matT*invertMatrix;
634 for(
int n=3; n<=degree; ++n)
636 a2 = ((2.0*n - 3.0)/(n - 1.0)) *
Hadamard(x, a1) - (n - 2.0)/(n - 1.0) * a0;
640 b3 = (2.0*n - 1.0)/n * (
Hadamard(b2, x) + a2) - (n - 1.0)/n * b1;
673 for(
int el=0; el<size; ++el)
675 if(y[el] < 1.0 - 1e-16)
677 eta_1[el] = 2.0*(1.0 + x[el]) / (1.0 - y[el]) - 1.0;
688 int alpha = 2*p + 1;
int beta = 0;
691 NekDouble w = sqrt((2.0*p + 1.0) * (p + q + 1.0) / 2.0);
693 for(
int i=0; i<size; ++i)
695 NekDouble zeta = pow((1.0 - eta_2[i])/2.0, (p-1.0));
697 psi_x[i] = w * psi_a_x[i] * psi_b;
702 for(
int i=0; i<int(x.
GetRows()); ++i)
720 for(
int el=0; el<size; ++el)
722 if( y[el] < -z[el] - numeric_limits<NekDouble>::epsilon())
724 eta_1[el] = 2.0*(1.0 + x[el])/(-y[el]-z[el]) - 1.0;
732 for(
int el=0; el<size; ++el)
734 if( z[el] < 1.0 - numeric_limits<NekDouble>::epsilon())
736 eta_2[el] = 2.0*(1.0 + y[el]) / (1.0 - z[el]) - 1.0;
747 int alpha = 2*p + 1;
int beta = 0;
748 int alpha_r = 2*p + 2*q + 2;
int beta_r = 0;
753 for(
int el=0; el<size; ++el)
755 NekDouble jacobi_b = pow((1.0-eta_2[el])/2.0, p-1.0);
756 NekDouble jacobi_c = pow((1.0-eta_3[el])/2.0,p+q-1.0);
757 NekDouble psi_b = jacobi_b * psi_bpq[el];
758 NekDouble psi_c = jacobi_c * psi_cpqr[el];
759 psi_x[el] = psi_a_x[el] * psi_b * psi_c;
764 for(
int el=0; el<int(x.
GetRows()); ++el)
776 int cols = (degree + 1) * (degree + 2) * (degree + 3)/6;
777 NekMatrix<NekDouble> matVx(rows, cols, 0.0);
779 for(
int d=0, n=0; d<=degree; ++d)
781 for(
int p=0; p <= d; ++p)
783 for(
int q=0; q <= d - p; ++q, ++n)
789 for(
int i=0; i<rows; ++i)
791 matVx(i,n) = columnVector[i];
814 NekMatrix<NekDouble> invertMatrix =
Invert(matS);
824 int cols = (degree + 1) * (degree + 2)/2;
825 NekMatrix<NekDouble> matVx(rows, cols, 0.0);
826 for(
int d=0, n=0; d<=degree; ++d)
828 for(
int p=0; p<=d; ++p, ++n)
834 for(
int i=0; i<rows; ++i)
836 matVx(i, n) = columnVector[i];
860 NekMatrix<NekDouble> invertMatrix =
Invert(matS);
879 y = 0.5 * (alpha + beta + degree + 1) *
JacobiPoly(degree - 1, x, alpha + 1, beta + 1);
895 for(
int el=0; el<size; ++el)
897 if( y[el] < -z[el] - numeric_limits<NekDouble>::epsilon())
899 eta_1[el] = 2.0*(1.0 + x[el])/(-y[el]-z[el]) - 1.0;
900 eta_1_dy[el] = 2.0*(1.0 + x[el])/((y[el]+z[el])*(y[el]+z[el]));
910 for(
int el=0; el<size; ++el)
912 if( z[el] < 1.0 - numeric_limits<NekDouble>::epsilon())
914 eta_2[el] = 2.0*(1.0 + y[el]) / (1.0 - z[el]) - 1.0;
915 eta_2_dy[el] = 2.0/(1.0 - z[el]);
929 int alpha_b = 2*p + 1;
int beta_b = 0;
930 int alpha_c = 2*p + 2*q + 2;
int beta_c = 0;
950 for(
int i=0; i<size; ++i)
952 NekDouble jacobi_b_dy = -p / 2.0 * pow( (1.0 - eta_2[i])/2.0, p-1.0 );
953 secondComponentOfPsi_b_dy[i] = J_q[i] * jacobi_b_dy;
958 for(
int i=0; i<size; ++i)
960 secondComponentOfPsi_b_dy[i] = 0.0;
966 + secondComponentOfPsi_b_dy, eta_2_dy );
969 for(
int k=0; k<size; ++k)
971 psi_dy[k] = (psi_a_dy[k]*psi_b[k]*psi_c[k]) + (psi_a[k]*psi_b_dy[k]*psi_c[k]);
975 for(
int k=0; k<size; ++k)
977 if( z[k] >= 1.0 - numeric_limits<NekDouble>::epsilon() )
981 psi_dy[k] = ((2.0*p+q+2.0)*
JacobiPoly(q, eta_2[k], alpha_b, 1) - (p+q+2.0)*J_q[k]) *
982 psi_a[k] * pow( (1.0-eta_3[k])/2.0, p+q-1 ) / 2.0 * ((p+q+r+3.0)*J_r[k] - (2.0*p+2.0*q+r+3.0)*
JacobiPoly(r, eta_3[k], alpha_c, 1));
1016 int cols = (degree + 1) * (degree + 2) * (degree + 3)/6;
1017 NekMatrix<NekDouble> matVy(rows, cols, 0.0);
1019 for(
int d=0, n=0; d<=degree; ++d)
1021 for(
int p=0; p <= d; ++p)
1023 for(
int q=0; q <= d - p; ++q, ++n)
1029 for(
int i=0; i<rows; ++i)
1031 matVy(i,n) = columnVector[i];
1056 NekMatrix<NekDouble> invertMatrix =
Invert(matS);
1058 NekMatrix<NekDouble> makeDerivativeMatrix = matTy*invertMatrix;
1072 for(
int el=0; el<size; ++el)
1074 if( y[el] < -z[el] - numeric_limits<NekDouble>::epsilon())
1076 eta_1[el] = 2.0*(1.0 + x[el]) / (-y[el]-z[el]) - 1.0;
1077 eta_1_dz[el] = 2.0*(1.0 + x[el]) / ((y[el]+z[el])*(y[el]+z[el]));
1087 for(
int el=0; el<size; ++el)
1089 if( z[el] < 1.0 - numeric_limits<NekDouble>::epsilon())
1091 eta_2[el] = 2.0*(1.0 + y[el]) / (1.0 - z[el]) - 1.0;
1092 eta_2_dz[el] = 2.0*(1.0 + y[el]) / ((1.0 - z[el])*(1.0 - z[el]));
1109 int alpha_b = 2*p + 1;
int beta_b = 0;
1110 int alpha_c = 2*p + 2*q + 2;
int beta_c = 0;
1129 for(
int i=0; i<size; ++i)
1131 NekDouble jacobi_b_dz = -p / 2.0 * pow( (1.0 - eta_2[i])/2.0, p-1.0 );
1132 secondComponentOfPsi_b_dz[i] = J_q[i] * jacobi_b_dz;
1138 for(
int i=0; i<size; ++i)
1140 NekDouble jacobi_c_dz = -(p+q)/2.0*pow( (1.0 - eta_3[i])/2.0, p+q-1.0);
1141 secondComponentOfPsi_c_dz[i] = J_r[i] * jacobi_c_dz;
1147 + secondComponentOfPsi_b_dz, eta_2_dz );
1149 + secondComponentOfPsi_c_dz, eta_3_dz );
1153 for(
int k=0; k<size; ++k)
1155 psi_dz[k] = psi_a_dz[k] * psi_b[k] * psi_c[k] + psi_a[k] * psi_b_dz[k] * psi_c[k] + psi_a[k] * psi_b[k] * psi_c_dz[k];
1164 int cols = (degree + 1) * (degree + 2) * (degree + 3)/6;
1165 NekMatrix<NekDouble> matVz(rows, cols, 0.0);
1167 for(
int d=0, n=0; d<=degree; ++d)
1169 for(
int p=0; p <= d; ++p)
1171 for(
int q=0; q <= d - p; ++q, ++n)
1177 for(
int i=0; i<rows; ++i)
1179 matVz(i,n) = columnVector[i];
1206 NekMatrix<NekDouble> invertMatrix =
Invert(matS);
1208 NekMatrix<NekDouble> makeDerivativeMatrix = matTz*invertMatrix;
1224 for(
int el=0; el<size; ++el)
1226 if(y[el] < 1.0 - 1e-16)
1228 eta_1[el] = 2.0*(1.0 + x[el]) / (1.0 - y[el]) - 1.0;
1239 int alpha = 2*p + 1;
int beta = 0;
1252 for(
int i=0; i<size; ++i)
1255 first_part_derivative[i] = (1.0 + eta_1[i])/2.0 * psi_a_y[i] * pow((1.0 - eta_2[i])/2.0, p-1.0) * psi_b[i];
1256 secondComponentOf_psi_b[i] = -p/2.0 * pow(((1.0 - eta_2[i]) / 2.0), p - 1.0) * psi_b[i];
1262 for(
int i=0; i<size; ++i)
1264 secondComponentOf_psi_b[i] = 0.0;
1265 first_part_derivative[i] = 0.0;
1268 for(
int k=0; k<size; ++k)
1270 psi_y[k] = first_part_derivative[k] + psi_a[k] * ( pow((1.0 - eta_2[k])/2.0, p) * psi_b_y[k] + secondComponentOf_psi_b[k] );
1273 NekDouble w = sqrt((2.0*p + 1.0)*(p + q + 1.0)/2.0);
1283 int cols = (degree + 1) * (degree + 2)/2;
1284 NekMatrix<NekDouble> matVy(rows, cols, 0.0);
1286 for(
int d=0, n=0; d<=degree; ++d)
1288 for(
int p=0; p<=d; ++p, ++n)
1293 for(
int i=0; i<rows; ++i)
1295 matVy(i, n) = columnVector[i];
1312 NekMatrix<NekDouble> invertMatrix =
Invert(matS);
1330 int cols = (degree + 1)*(degree + 2)/2;
1331 NekMatrix<NekDouble>matV(rows,cols, 0.0);
1333 for(
int d=0, n=0; d <= degree; ++d)
1335 for(
int p=0; p <= d; ++p, ++n)
1339 for(
int i=0; i<rows; ++i)
1341 matV(i, n) = pow(x[i], p) * pow(y[i], q);
1352 int cols = (degree + 1) * (degree + 2) * (degree + 3)/6;
1354 NekMatrix<NekDouble> matV(rows, cols, 0.0);
1356 for(
int d=0, n=0; d<=degree; ++d)
1358 for(
int p=0; p <= d; ++p)
1360 for(
int q=0; q <= d - p; ++q, ++n)
1365 for(
int i=0; i<rows; ++i)
1367 matV(i,n) = pow(x[i],p) * pow(y[i],q) * pow(z[i],r);
1392 int cols = (degree + 1) * (degree + 2) / 2;
1393 NekMatrix<NekDouble> matVx(rows, cols, 0.0);
1395 for(
int d=0, n=0; d <= degree; ++d)
1397 for(
int p=0; p <= d; ++p, ++n)
1403 for(
int i=0; i<rows; ++i)
1405 matVx(i, n) = p * pow(x[i], p-1.0) * pow(y[i],q);
1410 for(
int j=0; j<rows; ++j)
1431 int cols = (degree + 1) * (degree + 2) * (degree + 3) / 6;
1432 NekMatrix<NekDouble> matVx(rows, cols, 0.0);
1433 for(
int d=0, n=0; d<=degree; ++d)
1435 for(
int p=0; p <= d; ++p)
1437 for(
int q=0; q <= d - p; ++q, ++n)
1443 for(
int i=0; i<rows; ++i)
1445 matVx(i,n) = p * pow(x[i],p-1.0) * pow(y[i],q) * pow(z[i],r);
1449 for(
int j=0; j<rows; ++j)
1472 int cols = (degree + 1) * (degree + 2) * (degree + 3) / 6;
1473 NekMatrix<NekDouble> matVy(rows, cols, 0.0);
1474 for(
int d=0, n=0; d<=degree; ++d)
1476 for(
int p=0; p <= d; ++p)
1478 for(
int q=0; q <= d - p; ++q, ++n)
1484 for(
int i=0; i<rows; ++i)
1486 matVy(i,n) = q * pow(x[i],p) * pow(y[i],q-1.0) * pow(z[i],r);
1491 for(
int j=0; j<rows; ++j)
1514 int cols = (degree + 1) * (degree + 2) * (degree + 3) / 6;
1515 NekMatrix<NekDouble> matVz(rows, cols, 0.0);
1516 for(
int d=0, n=0; d<=degree; ++d)
1518 for(
int p=0; p <= d; ++p)
1520 for(
int q=0; q <= d - p; ++q, ++n)
1526 for(
int i=0; i<rows; ++i)
1528 matVz(i,n) = r * pow(x[i],p) * pow(y[i],q) * pow(z[i],r-1.0);
1532 for(
int j=0; j<rows; ++j)
1554 int cols = (degree + 1) * (degree + 2) / 2;
1555 NekMatrix<NekDouble> matVy(rows, cols, 0.0);
1557 for(
int d=0, n=0; d <= degree; ++d)
1559 for(
int p=0; p <= d; ++p, ++n)
1564 for(
int i=0; i<rows; ++i)
1566 matVy(i, n) = q * pow(x[i], p) * pow(y[i], q-1.0);
1571 for(
int j=0; j<rows; ++j)
1590 int cols = (degree + 1) * (degree + 2) / 2;
1593 for(
int d=0, n=0; d <= degree; ++d)
1595 for(
int p=0; p <= d; ++p, ++n)
1598 int sp = 1 - 2 * (p % 2);
1599 int sq = 1 - 2 * (q % 2);
1601 integralMVandermonde(n) =
NekDouble(sp * (p+1) + sq * (q+1) + sp * sq * (p+q+2)) / ((p+1) * (q+1) * (p+q+2));
1604 return integralMVandermonde;