diff --git a/FunctionSpace/BasisGenerator.cpp b/FunctionSpace/BasisGenerator.cpp index 31d526f2c2f3a6e4674a9650d8c57f44b6fc469d..7eeb73f0e42055e7bc7962fd0e7e870b40ef7221 100644 --- a/FunctionSpace/BasisGenerator.cpp +++ b/FunctionSpace/BasisGenerator.cpp @@ -17,6 +17,7 @@ #include "TetNodeBasis.h" #include "TetEdgeBasis.h" #include "TetNedelecBasis.h" +#include "TetLagrangeBasis.h" #include "HexNodeBasis.h" #include "HexEdgeBasis.h" @@ -70,7 +71,7 @@ BasisLocal* BasisGenerator::generateLagrange(unsigned int elementType, case TYPE_LIN: throw Exception("Lagrange Basis on Lines not Implemented"); case TYPE_TRI: return new TriLagrangeBasis(order); case TYPE_QUA: throw Exception("Lagrange Basis on Quads not Implemented"); - case TYPE_TET: throw Exception("Lagrange Basis on Tets not Implemented"); + case TYPE_TET: return new TetLagrangeBasis(order); case TYPE_HEX: throw Exception("Lagrange Basis on Hexs not Implemented"); default: throw Exception("Unknown Element Type (%d) for Basis Generation", diff --git a/FunctionSpace/CMakeLists.txt b/FunctionSpace/CMakeLists.txt index a4a0b6894485c71846237dfcda847d331a5a9694..5e052f9b307e18e1fa017a4903c4b91d99341a78 100644 --- a/FunctionSpace/CMakeLists.txt +++ b/FunctionSpace/CMakeLists.txt @@ -38,6 +38,7 @@ set(SRC TetNodeBasis.cpp TetEdgeBasis.cpp TetNedelecBasis.cpp + TetLagrangeBasis.cpp FunctionSpace.cpp FunctionSpaceScalar.cpp diff --git a/FunctionSpace/TetEdgeBasis.cpp b/FunctionSpace/TetEdgeBasis.cpp index e29bcb5599be0635cb27c930a595305cef3920f8..2b546f000fbda362cb8aa7ff39e98a802066a789 100644 --- a/FunctionSpace/TetEdgeBasis.cpp +++ b/FunctionSpace/TetEdgeBasis.cpp @@ -17,7 +17,7 @@ TetEdgeBasis::TetEdgeBasis(unsigned int order){ // Set Basis Type // this->order = order; - + type = 1; dim = 3; @@ -40,19 +40,19 @@ TetEdgeBasis::TetEdgeBasis(unsigned int order){ Legendre::legendre(legendre, orderMinusTwo); Legendre::scaled(sclLegendre, orderMinusTwo); Legendre::intScaled(intLegendre, orderPlus); - + // Lagrange Polynomial // - const Polynomial lagrange[4] = + const Polynomial lagrange[4] = { - Polynomial(Polynomial(1, 0, 0, 0) - - Polynomial(1, 1, 0, 0) - - Polynomial(1, 0, 1, 0) - + Polynomial(Polynomial(1, 0, 0, 0) - + Polynomial(1, 1, 0, 0) - + Polynomial(1, 0, 1, 0) - Polynomial(1, 0, 0, 1)), - + Polynomial(Polynomial(1, 1, 0, 0)), Polynomial(Polynomial(1, 0, 1, 0)), - + Polynomial(Polynomial(1, 0, 0, 1)) }; @@ -62,7 +62,7 @@ TetEdgeBasis::TetEdgeBasis(unsigned int order){ for(unsigned int s = 0; s < nRefSpace; s++) basis[s] = new vector<Polynomial>*[nFunction]; - + // Edge Based // for(unsigned int s = 0; s < nRefSpace; s++){ unsigned int i = 0; @@ -73,130 +73,130 @@ TetEdgeBasis::TetEdgeBasis(unsigned int order){ if(l == 0){ vector<Polynomial> tmp1 = lagrange[(*(*edgeV[s])[e])[1]].gradient(); vector<Polynomial> tmp2 = lagrange[(*(*edgeV[s])[e])[0]].gradient(); - + tmp1[0].mul(lagrange[(*(*edgeV[s])[e])[0]]); tmp1[1].mul(lagrange[(*(*edgeV[s])[e])[0]]); tmp1[2].mul(lagrange[(*(*edgeV[s])[e])[0]]); - + tmp2[0].mul(lagrange[(*(*edgeV[s])[e])[1]]); tmp2[1].mul(lagrange[(*(*edgeV[s])[e])[1]]); - tmp2[2].mul(lagrange[(*(*edgeV[s])[e])[1]]); - - tmp1[0].sub(tmp2[0]); - tmp1[1].sub(tmp2[1]); - tmp1[2].sub(tmp2[2]); - + tmp2[2].mul(lagrange[(*(*edgeV[s])[e])[1]]); + + tmp2[0].sub(tmp1[0]); + tmp2[1].sub(tmp1[1]); + tmp2[2].sub(tmp1[2]); + basis[s][i] = new vector<Polynomial>(tmp1); } // High Order else{ - basis[s][i] = + basis[s][i] = new vector<Polynomial> - ((intLegendre[l].compose(lagrange[(*(*edgeV[s])[e])[0]] - + ((intLegendre[l].compose(lagrange[(*(*edgeV[s])[e])[0]] - lagrange[(*(*edgeV[s])[e])[1]] , - lagrange[(*(*edgeV[s])[e])[0]] + + lagrange[(*(*edgeV[s])[e])[0]] + lagrange[(*(*edgeV[s])[e])[1]])).gradient()); } i++; } } } - + // Face Based // for(unsigned int s = 0; s < nRefSpace; s++){ unsigned int i = nEdge; - + for(int f = 0; f < 4; f++){ for(unsigned int l1 = 1; l1 < order; l1++){ for(int l2 = 0; l2 + (int)l1 - 1 < orderMinus; l2++){ // Preliminary Type 1 - Polynomial sum = + Polynomial sum = lagrange[(*(*faceV[s])[f])[0]] + lagrange[(*(*faceV[s])[f])[1]] + - lagrange[(*(*faceV[s])[f])[2]]; - - Polynomial u = - intLegendre[l1].compose(lagrange[(*(*faceV[s])[f])[0]] - + lagrange[(*(*faceV[s])[f])[2]]; + + Polynomial u = + intLegendre[l1].compose(lagrange[(*(*faceV[s])[f])[0]] - lagrange[(*(*faceV[s])[f])[1]] , - lagrange[(*(*faceV[s])[f])[0]] + + lagrange[(*(*faceV[s])[f])[0]] + lagrange[(*(*faceV[s])[f])[1]]); - Polynomial v = - lagrange[(*(*faceV[s])[f])[2]] * + Polynomial v = + lagrange[(*(*faceV[s])[f])[2]] * sclLegendre[l2].compose(lagrange[(*(*faceV[s])[f])[2]] * 2 - sum, sum); - + // Preliminary Type 2 vector<Polynomial> gradU = u.gradient(); vector<Polynomial> gradV = v.gradient(); - + vector<Polynomial> vGradU(gradU); vGradU[0].mul(v); vGradU[1].mul(v); vGradU[2].mul(v); - + vector<Polynomial> uGradV(gradV); uGradV[0].mul(u); uGradV[1].mul(u); uGradV[2].mul(u); - + vector<Polynomial> subGradUV(vGradU); subGradUV[0].sub(uGradV[0]); subGradUV[1].sub(uGradV[1]); subGradUV[2].sub(uGradV[2]); - + // Preliminary Type 3 vector<Polynomial> gradL1 = lagrange[(*(*faceV[s])[f])[0]].gradient(); vector<Polynomial> gradL2 = lagrange[(*(*faceV[s])[f])[1]].gradient(); - + vector<Polynomial> l2GradL1(gradL1); l2GradL1[0].mul(lagrange[(*(*faceV[s])[f])[1]]); l2GradL1[1].mul(lagrange[(*(*faceV[s])[f])[1]]); l2GradL1[2].mul(lagrange[(*(*faceV[s])[f])[1]]); - + vector<Polynomial> l1GradL2(gradL2); l1GradL2[0].mul(lagrange[(*(*faceV[s])[f])[0]]); l1GradL2[1].mul(lagrange[(*(*faceV[s])[f])[0]]); l1GradL2[2].mul(lagrange[(*(*faceV[s])[f])[0]]); - + vector<Polynomial> subGradL1L2V(l2GradL1); subGradL1L2V[0].sub(l1GradL2[0]); subGradL1L2V[1].sub(l1GradL2[1]); subGradL1L2V[2].sub(l1GradL2[2]); - + subGradL1L2V[0].mul(v); subGradL1L2V[1].mul(v); subGradL1L2V[2].mul(v); - - + + // Type 1 - basis[s][i] = + basis[s][i] = new vector<Polynomial>((u * v).gradient()); - + i++; - + // Type 2 basis[s][i] = new vector<Polynomial>(subGradUV); - + i++; - + // Type 3 if(l1 == 1){ basis[s][i] = new vector<Polynomial>(subGradL1L2V); - + i++; } } } } - } - + } + // Cell Based // const Polynomial one(1, 0, 0, 0); - + for(unsigned int s = 0; s < nRefSpace; s++){ unsigned int i = nEdge + nFace; @@ -205,105 +205,105 @@ TetEdgeBasis::TetEdgeBasis(unsigned int order){ for(int l3 = 0; l3 + l2 + l1 - 1 < orderMinusTwo; l3++){ // Preliminary Type 1 Polynomial u = intLegendre[l1].compose - (lagrange[0] - lagrange[1], + (lagrange[0] - lagrange[1], lagrange[0] + lagrange[1]); - + Polynomial v = lagrange[2] * sclLegendre[l2].compose (lagrange[2] * 2 - (one - lagrange[3]), one - lagrange[3]); - + Polynomial w = lagrange[3] * legendre[l3].compose (lagrange[3] * 2 - one); - + // Preliminary Type 2 vector<Polynomial> gradU = u.gradient(); vector<Polynomial> gradV = v.gradient(); vector<Polynomial> gradW = w.gradient(); - + vector<Polynomial> vwGradU(gradU); vwGradU[0].mul(v); vwGradU[1].mul(v); vwGradU[2].mul(v); - + vwGradU[0].mul(w); vwGradU[1].mul(w); vwGradU[2].mul(w); - + vector<Polynomial> uwGradV(gradV); uwGradV[0].mul(u); uwGradV[1].mul(u); uwGradV[2].mul(u); - + uwGradV[0].mul(w); uwGradV[1].mul(w); uwGradV[2].mul(w); - + vector<Polynomial> uvGradW(gradW); uvGradW[0].mul(u); uvGradW[1].mul(u); uvGradW[2].mul(u); - + uvGradW[0].mul(v); uvGradW[1].mul(v); uvGradW[2].mul(v); - + vector<Polynomial> term1(vwGradU); term1[0].sub(uwGradV[0]); term1[1].sub(uwGradV[1]); term1[2].sub(uwGradV[2]); - + term1[0].add(uvGradW[0]); term1[1].add(uvGradW[1]); term1[2].add(uvGradW[2]); - + vector<Polynomial> term2(vwGradU); term2[0].add(uwGradV[0]); term2[1].add(uwGradV[1]); term2[2].add(uwGradV[2]); - + term2[0].sub(uvGradW[0]); term2[1].sub(uvGradW[1]); term2[2].sub(uvGradW[2]); - + // Preliminary Type 3 vector<Polynomial> gradL1 = lagrange[0].gradient(); vector<Polynomial> gradL2 = lagrange[1].gradient(); - + vector<Polynomial> l2GradL1(gradL1); l2GradL1[0].mul(lagrange[1]); l2GradL1[1].mul(lagrange[1]); l2GradL1[2].mul(lagrange[1]); - + vector<Polynomial> l1GradL2(gradL2); l1GradL2[0].mul(lagrange[0]); l1GradL2[1].mul(lagrange[0]); l1GradL2[2].mul(lagrange[0]); - + vector<Polynomial> subGradL1L2VW(l2GradL1); subGradL1L2VW[0].sub(l1GradL2[0]); subGradL1L2VW[1].sub(l1GradL2[1]); subGradL1L2VW[2].sub(l1GradL2[2]); - + subGradL1L2VW[0].mul(v); subGradL1L2VW[1].mul(v); subGradL1L2VW[2].mul(v); - + subGradL1L2VW[0].mul(w); subGradL1L2VW[1].mul(w); subGradL1L2VW[2].mul(w); - - + + // Type 1 basis[s][i] = new vector<Polynomial>((u * v * w).gradient()); i++; - + // Type 2 -- Part 1 basis[s][i] = new vector<Polynomial>(term1); i++; - + // Type 2 -- Part 2 basis[s][i] = new vector<Polynomial>(term2); i++; - + // Type 3 if(l1 == 1){ basis[s][i] = new vector<Polynomial>(subGradL1L2VW); @@ -313,7 +313,7 @@ TetEdgeBasis::TetEdgeBasis(unsigned int order){ } } } - + // Free Temporary Space // // Legendre delete[] legendre; diff --git a/FunctionSpace/TetLagrangeBasis.cpp b/FunctionSpace/TetLagrangeBasis.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4913e3e2c3bf6f58d27cf7a465cd203c68a33a9d --- /dev/null +++ b/FunctionSpace/TetLagrangeBasis.cpp @@ -0,0 +1,372 @@ +#include "Exception.h" +#include "TetLagrangeBasis.h" + +TetLagrangeBasis::TetLagrangeBasis(unsigned int order){ + // Set Basis Type // + this->order = order; + + type = 0; + dim = 3; + + nVertex = 4; + nEdge = 6 * (order - 1); + nFace = 2 * (order - 1) * (order - 2); + nCell = (order - 1) * (order - 2) * (order - 3) / 6; + nFunction = nVertex + nEdge + nFace + nCell; + + // Init polynomialBasis // + lBasis = new polynomialBasis(getTag(order)); + + // Init Lagrange Point // + lPoint = new fullMatrix<double>(tetPoint(order)); +} + +TetLagrangeBasis::~TetLagrangeBasis(void){ + delete lBasis; + delete lPoint; +} + +unsigned int TetLagrangeBasis::getTag(unsigned int order){ + unsigned int tag = nodalBasis::getTag(TYPE_TET, order, false); + + if(tag) + return tag; + + else + throw Exception + ("Can't instanciate an order %d Lagrangian Basis for a Tetrahedron", + order); +} + +fullMatrix<double> TetLagrangeBasis:: +tetPoint(unsigned int order){ + unsigned int nbPoints = (order + 1) * (order + 2) * (order + 3) / 6; + fullMatrix<double> point(nbPoints, 3); + + double overOrder = (order == 0 ? 1. : 1. / order); + + point(0, 0) = 0.; + point(0, 1) = 0.; + point(0, 2) = 0.; + + if(order > 0){ + point(1, 0) = order; + point(1, 1) = 0; + point(1, 2) = 0; + + point(2, 0) = 0.; + point(2, 1) = order; + point(2, 2) = 0.; + + point(3, 0) = 0.; + point(3, 1) = 0.; + point(3, 2) = order; + + if(order > 1){ + for(unsigned int k = 0; k < (order - 1); k++){ + point(4 + k, 0) = k + 1; + point(4 + order - 1 + k, 0) = order - 1 - k; + point(4 + 2 * (order - 1) + k, 0) = 0.; + point(4 + 3 * (order - 1) + k, 0) = 0.; + point(4 + 4 * (order - 1) + k, 0) = 0.; + point(4 + 5 * (order - 1) + k, 0) = k+1; + + point(4 + k, 1) = 0.; + point(4 + order - 1 + k, 1) = k + 1; + point(4 + 2 * (order - 1) + k, 1) = order - 1 - k; + point(4 + 3 * (order - 1) + k, 1) = 0.; + point(4 + 4 * (order - 1) + k, 1) = k+1; + point(4 + 5 * (order - 1) + k, 1) = 0.; + + point(4 + k, 2) = 0.; + point(4 + order - 1 + k, 2) = 0.; + point(4 + 2 * (order - 1) + k, 2) = 0.; + point(4 + 3 * (order - 1) + k, 2) = order - 1 - k; + point(4 + 4 * (order - 1) + k, 2) = order - 1 - k; + point(4 + 5 * (order - 1) + k, 2) = order - 1 - k; + } + + if(order > 2){ + unsigned int ns = 4 + 6 * (order - 1); + unsigned int nbdofface = nbdoftriangle(order - 3); + + double *u = new double[nbdofface]; + double *v = new double[nbdofface]; + double *w = new double[nbdofface]; + + nodepositionface0(order - 3, u, v, w); + + // u-v plane + + for(unsigned int i = 0; i < nbdofface; i++){ + point(ns + i, 0) = u[i] * (order - 3) + 1.; + point(ns + i, 1) = v[i] * (order - 3) + 1.; + point(ns + i, 2) = w[i] * (order - 3); + } + + ns = ns + nbdofface; + + // u-w plane + + nodepositionface1(order - 3, u, v, w); + + for(unsigned int i=0; i < nbdofface; i++){ + point(ns + i, 0) = u[i] * (order - 3) + 1.; + point(ns + i, 1) = v[i] * (order - 3) ; + point(ns + i, 2) = w[i] * (order - 3) + 1.; + } + + // v-w plane + + ns = ns + nbdofface; + + nodepositionface2(order - 3, u, v, w); + + for(unsigned int i = 0; i < nbdofface; i++){ + point(ns + i, 0) = u[i] * (order - 3); + point(ns + i, 1) = v[i] * (order - 3) + 1.; + point(ns + i, 2) = w[i] * (order - 3) + 1.; + } + + // u-v-w plane + + ns = ns + nbdofface; + + nodepositionface3(order - 3, u, v, w); + + for(unsigned int i = 0; i < nbdofface; i++){ + point(ns + i, 0) = u[i] * (order - 3) + 1.; + point(ns + i, 1) = v[i] * (order - 3) + 1.; + point(ns + i, 2) = w[i] * (order - 3) + 1.; + } + + ns = ns + nbdofface; + + delete [] u; + delete [] v; + delete [] w; + + if(order > 3){ + fullMatrix<double> interior = tetPoint(order - 4); + + for(int k = 0; k < interior.size1(); k++){ + point(ns + k, 0) = 1. + interior(k, 0) * (order - 4); + point(ns + k, 1) = 1. + interior(k, 1) * (order - 4); + point(ns + k, 2) = 1. + interior(k, 2) * (order - 4); + } + } + } + } + } + + point.scale(overOrder); + return point; +} + +unsigned int TetLagrangeBasis::nbdoftriangle(unsigned int order){ + return (order + 1) * (order + 2) / 2; +} + +void TetLagrangeBasis:: +nodepositionface0(unsigned int order, double *u, double *v, double *w){ + + unsigned int ndofT = nbdoftriangle(order); + + if(order == 0){ + u[0] = 0.; + v[0] = 0.; + w[0] = 0.; + return; + } + + u[0]= 0.; v[0]= 0.; w[0] = 0.; + u[1]= 0.; v[1]= order; w[1] = 0.; + u[2]= order; v[2]= 0.; w[2] = 0.; + + // edges + for(unsigned int k = 0; k < (order - 1); k++){ + u[3 + k] = 0.; + v[3 + k] = k + 1; + w[3 + k] = 0.; + + u[3 + order - 1 + k] = k + 1; + v[3 + order - 1 + k] = order - 1 - k ; + w[3 + order - 1 + k] = 0.; + + u[3 + 2 * (order - 1) + k] = order - 1 - k; + v[3 + 2 * (order - 1) + k] = 0.; + w[3 + 2 * (order - 1) + k] = 0.; + } + + if(order > 2){ + unsigned int nbdoftemp = nbdoftriangle(order - 3); + + nodepositionface0(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order - 1)], + &w[3 + 3* (order - 1)]); + + for(unsigned int k = 0; k < nbdoftemp; k++){ + u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3); + } + } + + for(unsigned int k = 0; k < ndofT; k++){ + u[k] = u[k] / order; + v[k] = v[k] / order; + w[k] = w[k] / order; + } +} + +void TetLagrangeBasis::nodepositionface1 +(unsigned int order, double *u, double *v, double *w){ + + unsigned int ndofT = nbdoftriangle(order); + + if(order == 0){ + u[0] = 0.; + v[0] = 0.; + w[0] = 0.; + return; + } + + u[0] = 0.; v[0]= 0.; w[0] = 0.; + u[1] = order; v[1]= 0.; w[1] = 0.; + u[2] = 0.; v[2]= 0.; w[2] = order; + + // edges + for(unsigned int k = 0; k < (order - 1); k++){ + u[3 + k] = k + 1; + v[3 + k] = 0.; + w[3 + k] = 0.; + + u[3 + order - 1 + k] = order - 1 - k; + v[3 + order - 1 + k] = 0.; + w[3 + order - 1+ k ] = k + 1; + + u[3 + 2 * (order - 1) + k] = 0. ; + v[3 + 2 * (order - 1) + k] = 0.; + w[3 + 2 * (order - 1) + k] = order - 1 - k; + } + + if(order > 2){ + unsigned int nbdoftemp = nbdoftriangle(order - 3); + + nodepositionface1(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order -1 )], + &w[3 + 3 * (order - 1)]); + + for(unsigned int k = 0; k < nbdoftemp; k++){ + u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3); + w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + } + } + + for (unsigned int k = 0; k < ndofT; k++){ + u[k] = u[k] / order; + v[k] = v[k] / order; + w[k] = w[k] / order; + } +} + +void TetLagrangeBasis:: +nodepositionface2(unsigned int order, double *u, double *v, double *w){ + + unsigned int ndofT = nbdoftriangle(order); + + if(order == 0){ + u[0] = 0.; + v[0] = 0.; + w[0] = 0.; + return; + } + + u[0]= 0.; v[0]= 0.; w[0] = 0.; + u[1]= 0.; v[1]= 0.; w[1] = order; + u[2]= 0.; v[2]= order; w[2] = 0.; + + // edges + for(unsigned int k = 0; k < (order - 1); k++){ + u[3 + k] = 0.; + v[3 + k] = 0.; + w[3 + k] = k + 1; + + u[3 + order - 1 + k] = 0.; + v[3 + order - 1 + k] = k + 1; + w[3 + order - 1 + k] = order - 1 - k; + + u[3 + 2 * (order - 1) + k] = 0.; + v[3 + 2 * (order - 1) + k] = order - 1 - k; + w[3 + 2 * (order - 1) + k] = 0.; + } + + if(order > 2){ + unsigned int nbdoftemp = nbdoftriangle(order - 3); + + nodepositionface2(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order - 1)], + &w[3 + 3 * (order - 1)]); + + for(unsigned int k = 0; k < nbdoftemp; k++){ + u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3); + v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + } + } + + for(unsigned int k = 0; k < ndofT; k++){ + u[k] = u[k] / order; + v[k] = v[k] / order; + w[k] = w[k] / order; + } +} + +void TetLagrangeBasis:: +nodepositionface3(unsigned int order, double *u, double *v, double *w){ + + unsigned int ndofT = nbdoftriangle(order); + + if(order == 0){ + u[0] = 0.; + v[0] = 0.; + w[0] = 0.; + return; + } + + u[0]= 0.; v[0]= 0.; w[0] = order; + u[1]= order; v[1]= 0.; w[1] = 0.; + u[2]= 0.; v[2]= order; w[2] = 0.; + + // edges + for(unsigned int k = 0; k < (order - 1); k++){ + u[3 + k] = k + 1; + v[3 + k] = 0.; + w[3 + k] = order - 1 - k; + + u[3 + order - 1 + k] = order - 1 - k; + v[3 + order - 1 + k] = k + 1; + w[3 + order - 1 + k] = 0.; + + u[3 + 2 * (order - 1) + k] = 0.; + v[3 + 2 * (order - 1) + k] = order - 1 - k; + w[3 + 2 * (order - 1) + k] = k + 1; + } + + if(order > 2){ + unsigned int nbdoftemp = nbdoftriangle(order - 3); + + nodepositionface3(order - 3, &u[3 + 3 * (order - 1)], &v[3 + 3 * (order - 1)], + &w[3 + 3 * (order - 1)]); + + for(unsigned int k = 0; k < nbdoftemp; k++){ + u[3 + k + 3 * (order - 1)] = u[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + v[3 + k + 3 * (order - 1)] = v[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + w[3 + k + 3 * (order - 1)] = w[3 + k + 3 * (order - 1)] * (order - 3) + 1.; + } + } + + for (unsigned int k = 0; k < ndofT; k++){ + u[k] = u[k] / order; + v[k] = v[k] / order; + w[k] = w[k] / order; + } +} diff --git a/FunctionSpace/TetLagrangeBasis.h b/FunctionSpace/TetLagrangeBasis.h new file mode 100644 index 0000000000000000000000000000000000000000..27f7e5a6ecf181025c677e6d020f6d3a9bad7b5a --- /dev/null +++ b/FunctionSpace/TetLagrangeBasis.h @@ -0,0 +1,60 @@ +#ifndef _TETLAGRANGEBASIS_H_ +#define _TETLAGRANGEBASIS_H_ + +#include "BasisLagrange.h" + +/** + @class TetLagrangeBasis + @brief Lagrange Basis for Tetrahedra + + This class can instantiate a @em Lagrange @em Basis + for a Tetrahedron and for a given Order.@n + + It uses + <a href="http://geuz.org/gmsh/">gmsh</a> Basis. + */ + +class TetLagrangeBasis: public BasisLagrange{ + public: + //! @param order A natural number + //! + //! Returns a new TetLagrangeBasis + //! of the given Order + TetLagrangeBasis(unsigned int order); + + //! Deletes this Basis + //! + virtual ~TetLagrangeBasis(void); + + private: + //! @param order A natural number + //! @return Returns the @em tag of a @em Tetrahedron of + //! the given order + static unsigned int getTag(unsigned int order); + + //! @param order A natural number + //! @return Returns Lagrangian Points on a Tetrahedron + //! for the given Order + static fullMatrix<double> tetPoint(unsigned int order); + + //! Unknown gmsh function + static unsigned int nbdoftriangle(unsigned int order); + + //! Unknown gmsh function + static void nodepositionface0(unsigned int order, + double *u, double *v, double *w); + + //! Unknown gmsh function + static void nodepositionface1(unsigned int order, + double *u, double *v, double *w); + + //! Unknown gmsh function + static void nodepositionface2(unsigned int order, + double *u, double *v, double *w); + + //! Unknown gmsh function + static void nodepositionface3(unsigned int order, + double *u, double *v, double *w); +}; + +#endif diff --git a/FunctionSpace/TriLagrangeBasis.cpp b/FunctionSpace/TriLagrangeBasis.cpp index 99ff0469da87fec71debcf68ee1923239fe7e8df..d9258206f8fee9580c6d31c436a727e96486cc0b 100644 --- a/FunctionSpace/TriLagrangeBasis.cpp +++ b/FunctionSpace/TriLagrangeBasis.cpp @@ -6,7 +6,7 @@ TriLagrangeBasis::TriLagrangeBasis(unsigned int order){ this->order = order; type = 0; - dim = 2; + dim = 2; nVertex = 3; nEdge = 3 * (order - 1); @@ -27,23 +27,15 @@ TriLagrangeBasis::~TriLagrangeBasis(void){ } unsigned int TriLagrangeBasis::getTag(unsigned int order){ - switch(order){ - case 1: return MSH_TRI_3; - case 2: return MSH_TRI_6; - case 3: return MSH_TRI_10; - case 4: return MSH_TRI_15; - case 5: return MSH_TRI_21; - case 6: return MSH_TRI_28; - case 7: return MSH_TRI_36; - case 8: return MSH_TRI_45; - case 9: return MSH_TRI_55; - case 10: return MSH_TRI_66; - - default: + unsigned int tag = nodalBasis::getTag(TYPE_TRI, order, false); + + if(tag) + return tag; + + else throw Exception ("Can't instanciate an order %d Lagrangian Basis for a Triangle", order); - } } fullMatrix<double> TriLagrangeBasis:: @@ -57,17 +49,17 @@ triPoint(unsigned int order){ if(order > 0){ double dd = 1. / order; - + point(1, 0) = 1; point(1, 1) = 0; point(1, 2) = 0; - + point(2, 0) = 0; point(2, 1) = 1; point(2, 2) = 0; - + unsigned int index = 3; - + if(order > 1){ double ksi = 0; double eta = 0; @@ -104,7 +96,7 @@ triPoint(unsigned int order){ if(order > 2){ fullMatrix<double> inner = triPoint(order - 3); - + inner.scale(1. - 3. * dd); inner.add(dd); point.copy(inner, 0, nbPoints - index, 0, 2, index, 0);