From a0020629f044ef97662f911047fb170960450049 Mon Sep 17 00:00:00 2001 From: Nicolas Marsic <nicolas.marsic@gmail.com> Date: Fri, 19 Oct 2012 14:02:16 +0000 Subject: [PATCH] TeT: Closure OK -- Poisson OK -- Polynomial OK -- \o/ -- Still Need Conv Test --- FunctionSpace/BasisGenerator.cpp | 15 ++++ FunctionSpace/BasisGenerator.h | 18 +++++ FunctionSpace/FunctionSpace.cpp | 77 +----------------- FunctionSpace/FunctionSpaceScalar.cpp | 72 +++++++++++++++-- FunctionSpace/HexNodeBasis.cpp | 12 +-- FunctionSpace/TetNodeBasis.cpp | 109 ++++++++++++++------------ 6 files changed, 166 insertions(+), 137 deletions(-) diff --git a/FunctionSpace/BasisGenerator.cpp b/FunctionSpace/BasisGenerator.cpp index 15645c4a5b..2bdbb06439 100644 --- a/FunctionSpace/BasisGenerator.cpp +++ b/FunctionSpace/BasisGenerator.cpp @@ -9,6 +9,8 @@ #include "TriEdgeBasis.h" #include "TriNedelecBasis.h" +#include "TetNodeBasis.h" + #include "HexNodeBasis.h" #include "HexEdgeBasis.h" @@ -25,6 +27,7 @@ Basis* BasisGenerator::generate(int elementType, switch(elementType){ case TYPE_TRI: return triGen(basisType, order); case TYPE_QUA: return quaGen(basisType, order); + case TYPE_TET: return tetGen(basisType, order); case TYPE_HEX: return hexGen(basisType, order); default: throw Exception("Unknown Element Type (%d) for Basis Generation", @@ -59,6 +62,18 @@ Basis* BasisGenerator::quaGen(int basisType, } } +Basis* BasisGenerator::tetGen(int basisType, + int order){ + switch(basisType){ + case 0: return new TetNodeBasis(order); + case 1: throw Exception("1-form not implemented on Tetrahedrons"); + case 2: throw Exception("2-form not implemented on Tetrahedrons"); + case 3: throw Exception("3-form not implemented on Tetrahedrons"); + + default: throw Exception("There is no %d-form", basisType); + } +} + Basis* BasisGenerator::hexGen(int basisType, int order){ switch(basisType){ diff --git a/FunctionSpace/BasisGenerator.h b/FunctionSpace/BasisGenerator.h index 38401febed..2f9ce3cf0a 100644 --- a/FunctionSpace/BasisGenerator.h +++ b/FunctionSpace/BasisGenerator.h @@ -26,6 +26,7 @@ class BasisGenerator{ static Basis* triGen(int basisType, int order); static Basis* quaGen(int basisType, int order); + static Basis* tetGen(int basisType, int order); static Basis* hexGen(int basisType, int order); }; @@ -100,6 +101,23 @@ class BasisGenerator{ @li @c 3 for 3-Form ** + @fn BasisGenerator::tetGen + @param basisType The Basis type + @param order The order or the requested Basis + + This method will @em instanciate the requested Basis, + with a @em Tetrahedron for support + + @return Returns a @em pointer to a newly + @em instantiated Basis + + @note Basis types are: + @li @c 0 for 0-Form + @li @c 1 for 1-Form + @li @c 2 for 2-Form + @li @c 3 for 3-Form + ** + @fn BasisGenerator::hexGen @param basisType The Basis type @param order The order or the requested Basis diff --git a/FunctionSpace/FunctionSpace.cpp b/FunctionSpace/FunctionSpace.cpp index b94195a6ce..28647e5dba 100644 --- a/FunctionSpace/FunctionSpace.cpp +++ b/FunctionSpace/FunctionSpace.cpp @@ -16,17 +16,6 @@ FunctionSpace::~FunctionSpace(void){ // Basis // delete basis; - // Closure // - /* - map<const MElement*, vector<bool>*>::iterator cIt - = edgeClosure->begin(); - map<const MElement*, vector<bool>*>::iterator cStop - = edgeClosure->end(); - - for(; cIt != cStop; cIt++) - delete cIt->second; - delete edgeClosure; - */ // Dof // if(dof){ set<const Dof*>::iterator dStop = dof->end(); @@ -89,72 +78,10 @@ void FunctionSpace::build(const GroupOfElement& goe, fPerCell = basis->getNCellBased(); // We always got 1 cell - // Build Closure // - //buildClosure(); - // Build Dof // buildDof(); } -void FunctionSpace::buildClosure(void){ - // Get Elements // - const vector<const MElement*>& element = goe->getAll(); - const unsigned int size = element.size(); - - // Init // - edgeClosure = new map<const MElement*, vector<bool>*>; - - // Iterate on elements // - for(unsigned int i = 0; i < size; i++){ - // Get Element data - MElement& myElement = - const_cast<MElement&>(*element[i]); - - const unsigned int nVertex = myElement.getNumVertices(); - const unsigned int nEdge = myElement.getNumEdges(); - const unsigned int nFace = myElement.getNumFaces(); - - const unsigned int nTotVertex = nVertex * fPerVertex; - const unsigned int nTotEdge = nEdge * fPerEdge; - const unsigned int nTotFace = nFace * fPerFace; - - const unsigned int nTot = nTotVertex + nTotEdge + nTotFace + fPerCell; - - // Closure - vector<bool>* closure = new vector<bool>(nTot); - unsigned int it = 0; - - // Closure for vertices - for(unsigned int j = 0; j < nTotVertex; j++, it++) - (*closure)[it] = true; - - // Closure for edges - for(unsigned int j = 0; j < fPerEdge; j++){ - for(unsigned int k = 0; k < nEdge; k++, it++){ - // Orientation - int orientation = mesh->getOrientation(myElement.getEdge(k)); - - if(orientation == 1) - (*closure)[it] = true; - - else - (*closure)[it] = false; - } - } - - // Closure for faces - // TODO - - // Closure for cells - for(unsigned int j = 0; j < fPerCell; j++, it++) - (*closure)[it] = true; - - // Add Closure - edgeClosure->insert - (pair<const MElement*, vector<bool>*>(element[i], closure)); - } -} - void FunctionSpace::buildDof(void){ // Get Elements // unsigned int nElement = goe->getNumber(); @@ -264,7 +191,7 @@ vector<Dof> FunctionSpace::getKeys(const MElement& elem) const{ it++; } } - /* + // Add Face Based Dof // for(int i = 0; i < nFFace; i++){ for(int j = 0; j < nFace; j++){ @@ -272,7 +199,7 @@ vector<Dof> FunctionSpace::getKeys(const MElement& elem) const{ it++; } } - */ + // Add Cell Based Dof // for(int i = 0; i < nFCell; i++){ myDof[it].setDof(mesh->getGlobalId(element), i); diff --git a/FunctionSpace/FunctionSpaceScalar.cpp b/FunctionSpace/FunctionSpaceScalar.cpp index 677267d5ac..afd63a4c9e 100644 --- a/FunctionSpace/FunctionSpaceScalar.cpp +++ b/FunctionSpace/FunctionSpaceScalar.cpp @@ -13,24 +13,69 @@ getLocalFunctions(const MElement& element) const{ const BasisScalar& basis = getBasis(element); const vector <const Polynomial*>& node = basis.getNodeFunctions(); const vector<vector<const Polynomial*>*>& edge = basis.getEdgeFunctions(); + const vector<vector<const Polynomial*>*>& face = basis.getFaceFunctions(); const vector <const Polynomial*>& cell = basis.getCellFunctions(); const unsigned int nFNode = basis.getNVertexBased(); const unsigned int nFEdge = basis.getNEdgeBased(); + const unsigned int nFFace = basis.getNFaceBased(); const unsigned int nFCell = basis.getNCellBased(); + // Get not const Element (gmsh problem, not mine !) // + MElement& eelement = const_cast<MElement&>(element); + // Get Edge Closure // - MElement& eelement = const_cast<MElement&>(element); - const unsigned int nEdge = eelement.getNumEdges(); - + const unsigned int nEdge = eelement.getNumEdges(); vector<bool> edgeClosure(nEdge); - + // Look Edges for(unsigned int i = 0; i < nEdge; i++){ MEdge edge = eelement.getEdge(i); edgeClosure[i] = - edge.getVertex(0)->getNum() > edge.getVertex(1)->getNum(); + edge.getVertex(0)->getNum() < edge.getVertex(1)->getNum(); + } + + + // Get Face Closure // + const unsigned int nFace = eelement.getNumFaces(); + vector<int> faceClosure(nFace); + + // Look Faces + for(unsigned int i = 0; i < nFace; i++){ + MFace face = eelement.getFace(i); + + unsigned int v[3]; + v[0] = face.getVertex(0)->getNum(); + v[1] = face.getVertex(1)->getNum(); + v[2] = face.getVertex(2)->getNum(); + + bool c[3]; + c[0] = v[0] < v[1]; + c[1] = v[1] < v[2]; + c[2] = v[2] < v[0]; + + if(c[0]) + if(c[1]) + faceClosure[i] = 0; + + else + if(c[2]) + faceClosure[i] = 4; + + else + faceClosure[i] = 5; + + else + if(c[1]) + if(c[2]) + faceClosure[i] = 2; + + else + faceClosure[i] = 1; + + else + faceClosure[i] = 3; } @@ -63,7 +108,22 @@ getLocalFunctions(const MElement& element) const{ } } - // Vertex Based + // Face Based + // Number of basis function *per* face + // --> should always be an integer ! + const unsigned int nFPerFace = nFFace / nFace; + unsigned int fFace = 0; + + for(unsigned int j = 0; j < nFPerFace; j++){ + for(unsigned int k = 0; k < nFace; k++){ + fun[i] = (*face[faceClosure[k]])[fFace]; + + fFace++; + i++; + } + } + + // Cell Based for(unsigned int j = 0; j < nFCell; j++){ fun[i] = cell[j]; i++; diff --git a/FunctionSpace/HexNodeBasis.cpp b/FunctionSpace/HexNodeBasis.cpp index 922d33ba38..43ca97949e 100644 --- a/FunctionSpace/HexNodeBasis.cpp +++ b/FunctionSpace/HexNodeBasis.cpp @@ -119,8 +119,8 @@ HexNodeBasis::HexNodeBasis(const int order){ int i = 8; // Points definig Edges - const unsigned int edge1[12] = {0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3}; - const unsigned int edge2[12] = {1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7}; + const int edge1[12] = {0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3}; + const int edge2[12] = {1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7}; for(int l = 1; l < order; l++){ for(int e = 0; e < 12; e++){ @@ -135,10 +135,10 @@ HexNodeBasis::HexNodeBasis(const int order){ // Face Based (Preliminary) // // Points definig Faces - const unsigned int face1[6] = {0, 3, 2, 1, 5, 4}; - const unsigned int face2[6] = {1, 7, 6, 0, 6, 7}; - const unsigned int face3[6] = {2, 6, 5, 4, 7, 3}; - const unsigned int face4[6] = {3, 2, 1, 5, 4, 0}; + const int face1[6] = {0, 3, 2, 1, 5, 4}; + const int face2[6] = {1, 7, 6, 0, 6, 7}; + const int face3[6] = {2, 6, 5, 4, 7, 3}; + const int face4[6] = {3, 2, 1, 5, 4, 0}; // 'Xi' Functions for(int f = 0; f < 6; f++) diff --git a/FunctionSpace/TetNodeBasis.cpp b/FunctionSpace/TetNodeBasis.cpp index 05770e8280..efd411af37 100644 --- a/FunctionSpace/TetNodeBasis.cpp +++ b/FunctionSpace/TetNodeBasis.cpp @@ -23,25 +23,34 @@ TetNodeBasis::TetNodeBasis(unsigned int order){ Polynomial* intLegendre = new Polynomial[order]; // Classical, Scaled and Intrated-Scaled Legendre Polynomial // - const unsigned int orderMinus = order - 1; - const unsigned int orderMinusTwo = order - 2; - const unsigned int orderMinusThree = order - 3; + const int orderMinus = order - 1; + const int orderMinusTwo = order - 2; + const int orderMinusThree = order - 3; Legendre::legendre(legendre, orderMinus); Legendre::scaled(sclLegendre, orderMinus); Legendre::intScaled(intLegendre, order); - // Points definig Edges // - const unsigned int edge0[6] = {0, 1, 2, 2, 3, 3}; - const unsigned int edge1[6] = {1, 2, 0, 3, 0, 1}; - - // Points definig Faces // - const unsigned int face0[4] = {0, 0, 0, 1}; - const unsigned int face1[4] = {1, 1, 2, 2}; - const unsigned int face2[4] = {3, 2, 3, 3}; + // Vertices definig Edges // + const int edgeV[6][2] = { + {0, 1}, + {1, 2}, + {2, 0}, + {3, 0}, + {3, 2}, + {3, 1} + }; + + // Vertices definig Faces // + const int faceV[4][3] = { + {0, 2, 1}, + {0, 1, 3}, + {0, 3, 2}, + {3, 1, 2} + }; // Counter // - unsigned int i; + int i; // Basis // node = new vector<const Polynomial*>(nVertex); @@ -81,16 +90,16 @@ TetNodeBasis::TetNodeBasis(unsigned int order){ i = 0; for(unsigned int l = 1; l < order; l++){ - for(unsigned int e = 0; e < 6; e++){ + for(int e = 0; e < 6; e++){ (*(*edge)[0])[i] = new Polynomial(intLegendre[l].compose - (*(*node)[edge0[e]] - *(*node)[edge1[e]], - *(*node)[edge0[e]] + *(*node)[edge1[e]])); + (*(*node)[edgeV[e][0]] - *(*node)[edgeV[e][1]], + *(*node)[edgeV[e][0]] + *(*node)[edgeV[e][1]])); (*(*edge)[1])[i] = new Polynomial(intLegendre[l].compose - (*(*node)[edge1[e]] - *(*node)[edge0[e]], - *(*node)[edge1[e]] + *(*node)[edge0[e]])); + (*(*node)[edgeV[e][1]] - *(*node)[edgeV[e][0]], + *(*node)[edgeV[e][1]] + *(*node)[edgeV[e][0]])); i++; } @@ -100,73 +109,73 @@ TetNodeBasis::TetNodeBasis(unsigned int order){ // Face Based // i = 0; - for(unsigned int l1 = 1; l1 < orderMinus; l1++){ - for(unsigned int l2 = 0; l1 + l2 - 1 < orderMinusTwo; l2++){ - for(unsigned int m = 0; m < 4; m++){ + for(int l1 = 1; l1 < orderMinus; l1++){ + for(int l2 = 0; l1 + l2 - 1 < orderMinusTwo; l2++){ + for(int m = 0; m < 4; m++){ Polynomial sum = - *(*node)[face0[m]] + - *(*node)[face1[m]] + - *(*node)[face2[m]]; + *(*node)[faceV[m][0]] + + *(*node)[faceV[m][1]] + + *(*node)[faceV[m][2]]; (*(*face)[0])[i] = new Polynomial(intLegendre[l1].compose - (*(*node)[face0[m]] - *(*node)[face1[m]], - *(*node)[face0[m]] + *(*node)[face1[m]]) * + (*(*node)[faceV[m][0]] - *(*node)[faceV[m][1]], + *(*node)[faceV[m][0]] + *(*node)[faceV[m][1]]) * - *(*node)[face2[m]] * + *(*node)[faceV[m][2]] * sclLegendre[l2].compose - (*(*node)[face2[m]] * 2 - sum, sum)); + (*(*node)[faceV[m][2]] * 2 - sum, sum)); (*(*face)[1])[i] = new Polynomial(intLegendre[l1].compose - (*(*node)[face1[m]] - *(*node)[face0[m]], - *(*node)[face1[m]] + *(*node)[face0[m]]) * + (*(*node)[faceV[m][1]] - *(*node)[faceV[m][0]], + *(*node)[faceV[m][1]] + *(*node)[faceV[m][0]]) * - *(*node)[face2[m]] * + *(*node)[faceV[m][2]] * sclLegendre[l2].compose - (*(*node)[face2[m]] * 2 - sum, sum)); + (*(*node)[faceV[m][2]] * 2 - sum, sum)); (*(*face)[2])[i] = new Polynomial(intLegendre[l1].compose - (*(*node)[face1[m]] - *(*node)[face2[m]], - *(*node)[face1[m]] + *(*node)[face2[m]]) * + (*(*node)[faceV[m][1]] - *(*node)[faceV[m][2]], + *(*node)[faceV[m][1]] + *(*node)[faceV[m][2]]) * - *(*node)[face0[m]] * + *(*node)[faceV[m][0]] * sclLegendre[l2].compose - (*(*node)[face0[m]] * 2 - sum, sum)); + (*(*node)[faceV[m][0]] * 2 - sum, sum)); (*(*face)[3])[i] = new Polynomial(intLegendre[l1].compose - (*(*node)[face2[m]] - *(*node)[face1[m]], - *(*node)[face2[m]] + *(*node)[face1[m]]) * + (*(*node)[faceV[m][2]] - *(*node)[faceV[m][1]], + *(*node)[faceV[m][2]] + *(*node)[faceV[m][1]]) * - *(*node)[face0[m]] * + *(*node)[faceV[m][0]] * sclLegendre[l2].compose - (*(*node)[face0[m]] * 2 - sum, sum)); + (*(*node)[faceV[m][0]] * 2 - sum, sum)); (*(*face)[4])[i] = new Polynomial(intLegendre[l1].compose - (*(*node)[face2[m]] - *(*node)[face0[m]], - *(*node)[face2[m]] + *(*node)[face0[m]]) * + (*(*node)[faceV[m][2]] - *(*node)[faceV[m][0]], + *(*node)[faceV[m][2]] + *(*node)[faceV[m][0]]) * - *(*node)[face1[m]] * + *(*node)[faceV[m][1]] * sclLegendre[l2].compose - (*(*node)[face1[m]] * 2 - sum, sum)); + (*(*node)[faceV[m][1]] * 2 - sum, sum)); (*(*face)[5])[i] = new Polynomial(intLegendre[l1].compose - (*(*node)[face0[m]] - *(*node)[face2[m]], - *(*node)[face0[m]] + *(*node)[face2[m]]) * + (*(*node)[faceV[m][0]] - *(*node)[faceV[m][2]], + *(*node)[faceV[m][0]] + *(*node)[faceV[m][2]]) * - *(*node)[face1[m]] * + *(*node)[faceV[m][1]] * sclLegendre[l2].compose - (*(*node)[face1[m]] * 2 - sum, sum)); + (*(*node)[faceV[m][1]] * 2 - sum, sum)); i++; } @@ -184,9 +193,9 @@ TetNodeBasis::TetNodeBasis(unsigned int order){ i = 0; - for(unsigned int l1 = 1; l1 < orderMinusTwo; l1++){ - for(unsigned int l2 = 0; l2 + l1 - 1 < orderMinusThree; l2++){ - for(unsigned int l3 = 0; l3 + l2 + l1 - 1 < orderMinusThree; l3++){ + for(int l1 = 1; l1 < orderMinusTwo; l1++){ + for(int l2 = 0; l2 + l1 - 1 < orderMinusThree; l2++){ + for(int l3 = 0; l3 + l2 + l1 - 1 < orderMinusThree; l3++){ (*cell)[i] = new Polynomial(intLegendre[l1].compose(sub, add) * -- GitLab