From 85b08109c38a36013e070582f7ce45213926cade Mon Sep 17 00:00:00 2001 From: Nicolas Marsic <nicolas.marsic@gmail.com> Date: Thu, 25 Oct 2012 13:26:25 +0000 Subject: [PATCH] Grad for Local Basis of a Function Space + Grad/Curl/Div of a Basis --- FunctionSpace/Basis.h | 19 +++++ FunctionSpace/BasisScalar.cpp | 17 ++++- FunctionSpace/CMakeLists.txt | 4 + FunctionSpace/CurlBasis.cpp | 96 ++++++++++++++++++++++++ FunctionSpace/CurlBasis.h | 26 +++++++ FunctionSpace/DivBasis.cpp | 96 ++++++++++++++++++++++++ FunctionSpace/DivBasis.h | 27 +++++++ FunctionSpace/FunctionSpace.cpp | 8 +- FunctionSpace/FunctionSpace.h | 4 +- FunctionSpace/FunctionSpaceNode.cpp | 4 + FunctionSpace/FunctionSpaceScalar.cpp | 103 +++++++++++++++++++++++--- FunctionSpace/FunctionSpaceScalar.h | 19 ++++- FunctionSpace/GradBasis.cpp | 96 ++++++++++++++++++++++++ FunctionSpace/GradBasis.h | 27 +++++++ FunctionSpace/HexEdgeBasis.cpp | 3 + FunctionSpace/HexNodeBasis.cpp | 3 + FunctionSpace/Polynomial.cpp | 41 ++++++++++ FunctionSpace/Polynomial.h | 4 +- FunctionSpace/QuadEdgeBasis.cpp | 3 + FunctionSpace/QuadNodeBasis.cpp | 3 + FunctionSpace/TetEdgeBasis.cpp | 5 +- FunctionSpace/TetNodeBasis.cpp | 3 + FunctionSpace/TriEdgeBasis.cpp | 3 + FunctionSpace/TriNedelecBasis.cpp | 3 + FunctionSpace/TriNodeBasis.cpp | 3 + 25 files changed, 596 insertions(+), 24 deletions(-) create mode 100644 FunctionSpace/CurlBasis.cpp create mode 100644 FunctionSpace/CurlBasis.h create mode 100644 FunctionSpace/DivBasis.cpp create mode 100644 FunctionSpace/DivBasis.h create mode 100644 FunctionSpace/GradBasis.cpp create mode 100644 FunctionSpace/GradBasis.h diff --git a/FunctionSpace/Basis.h b/FunctionSpace/Basis.h index 4c272d9988..76b0a5f48e 100644 --- a/FunctionSpace/Basis.h +++ b/FunctionSpace/Basis.h @@ -29,6 +29,9 @@ class Basis{ int nFace; int nCell; + int nEdgeClosure; + int nFaceClosure; + int size; public: @@ -79,6 +82,14 @@ class Basis{ //! @em Based functions of this Basis int getNCellBased(void) const; + //! @return Returns the number of @em edge + //! @em closures for this Basis + int getNEdgeClosure(void) const; + + //! @return Returns the number of @em face + //! @em closures for this Basis + int getNFaceClosure(void) const; + //! @return Returns the number of Polynomial%s //! (or Vector%s of Polynomial%s) in the Basis int getSize(void) const; @@ -130,6 +141,14 @@ inline int Basis::getNCellBased(void) const{ return nCell; } +inline int Basis::getNEdgeClosure(void) const{ + return nEdgeClosure; +} + +inline int Basis::getNFaceClosure(void) const{ + return nFaceClosure; +} + inline int Basis::getSize(void) const{ return size; } diff --git a/FunctionSpace/BasisScalar.cpp b/FunctionSpace/BasisScalar.cpp index 3d62551f6b..1e792ed936 100644 --- a/FunctionSpace/BasisScalar.cpp +++ b/FunctionSpace/BasisScalar.cpp @@ -13,8 +13,21 @@ BasisScalar::~BasisScalar(void){ string BasisScalar::toString(void) const{ stringstream stream; - for(int i = 0; i < size; i++) - stream << "f(" << i << ") = " << endl; + for(int i = 0; i < nVertex; i++) + stream << "f(" << i << ") = " + << (*node)[i]->toString() << endl; + + for(int i = 0; i < nEdge; i++) + stream << "f(" << i + nVertex << ") = " + << (*(*edge)[0])[i]->toString() << endl; + + for(int i = 0; i < nFace; i++) + stream << "f(" << i + nVertex + nEdge << ") = " + << (*(*face)[0])[i]->toString() << endl; + + for(int i = 0; i < nCell; i++) + stream << "f(" << i + nVertex + nEdge + nFace << ") = " + << (*cell)[i]->toString() << endl; return stream.str(); } diff --git a/FunctionSpace/CMakeLists.txt b/FunctionSpace/CMakeLists.txt index 3ef4e3e3ac..19fe8c16a8 100644 --- a/FunctionSpace/CMakeLists.txt +++ b/FunctionSpace/CMakeLists.txt @@ -12,6 +12,10 @@ set(SRC BasisVector.cpp BasisGenerator.cpp + GradBasis.cpp + CurlBasis.cpp + DivBasis.cpp + QuadNodeBasis.cpp QuadEdgeBasis.cpp TriNodeBasis.cpp diff --git a/FunctionSpace/CurlBasis.cpp b/FunctionSpace/CurlBasis.cpp new file mode 100644 index 0000000000..fc55ef79a1 --- /dev/null +++ b/FunctionSpace/CurlBasis.cpp @@ -0,0 +1,96 @@ +#include "CurlBasis.h" + +using namespace std; + +CurlBasis::CurlBasis(const BasisVector& other){ + // Set Basis Type // + order = other.getOrder(); + + type = other.getType(); + dim = other.getDim(); + + nVertex = other.getNVertexBased(); + nEdge = other.getNEdgeBased(); + nFace = other.getNFaceBased(); + nCell = other.getNCellBased(); + + nEdgeClosure = other.getNEdgeClosure(); + nFaceClosure = other.getNFaceClosure(); + + size = other.getSize(); + + // Alloc Basis // + node = new vector<vector<Polynomial>*>(nVertex); + edge = new vector<vector<vector<Polynomial>*>*>(nEdgeClosure); + face = new vector<vector<vector<Polynomial>*>*>(nFaceClosure); + cell = new vector<vector<Polynomial>*>(nCell); + + for(int i = 0; i < nEdgeClosure; i++) + (*edge)[i] = new vector<vector<Polynomial>*>(nEdge); + + for(int i = 0; i < nFaceClosure; i++) + (*face)[i] = new vector<vector<Polynomial>*>(nFace); + + // Node Based // + for(int i = 0; i < nVertex; i++) + (*node)[i] = + new vector<Polynomial> + (Polynomial::curl(other.getNodeFunction(i))); + + // Edge Based // + for(int i = 0; i < nEdgeClosure; i++) + for(int j = 0; j < nEdge; j++) + (*(*edge)[i])[j] = + new vector<Polynomial> + (Polynomial::curl(other.getEdgeFunction(i, j))); + + // Face Based // + for(int i = 0; i < nFaceClosure; i++) + for(int j = 0; j < nFace; j++) + (*(*face)[i])[j] = + new vector<Polynomial> + (Polynomial::curl(other.getFaceFunction(i, j))); + + // Cell Based // + for(int i = 0; i < nCell; i++) + (*cell)[i] = + new vector<Polynomial> + (Polynomial::curl(other.getCellFunction(i))); +} + +CurlBasis::~CurlBasis(void){ + // Vertex Based // + for(int i = 0; i < nVertex; i++) + delete (*node)[i]; + + delete node; + + + // Edge Based // + for(int c = 0; c < nEdgeClosure; c++){ + for(int i = 0; i < nEdge; i++) + delete (*(*edge)[c])[i]; + + delete (*edge)[c]; + } + + delete edge; + + + // Face Based // + for(int c = 0; c < nFaceClosure; c++){ + for(int i = 0; i < nFace; i++) + delete (*(*face)[c])[i]; + + delete (*face)[c]; + } + + delete face; + + + // Cell Based // + for(int i = 0; i < nCell; i++) + delete (*cell)[i]; + + delete cell; +} diff --git a/FunctionSpace/CurlBasis.h b/FunctionSpace/CurlBasis.h new file mode 100644 index 0000000000..ffedacf3fe --- /dev/null +++ b/FunctionSpace/CurlBasis.h @@ -0,0 +1,26 @@ +#ifndef _CURLBASIS_H_ +#define _CURLBASIS_H_ + +#include "BasisVector.h" + +/** + @class CurlBasis + @brief The Curl of an other Basis + + This class can instantiate a Curl Basis. + */ + +class CurlBasis: public BasisVector{ + public: + //! @param other An Other Basis + //! + //! Returns a new Basis, which is the curl of + //! the given Basis + CurlBasis(const BasisVector& other); + + //! Deletes this Basis + //! + virtual ~CurlBasis(void); +}; + +#endif diff --git a/FunctionSpace/DivBasis.cpp b/FunctionSpace/DivBasis.cpp new file mode 100644 index 0000000000..15a4a38720 --- /dev/null +++ b/FunctionSpace/DivBasis.cpp @@ -0,0 +1,96 @@ +#include "DivBasis.h" + +using namespace std; + +DivBasis::DivBasis(const BasisVector& other){ + // Set Basis Type // + order = other.getOrder(); + + type = other.getType(); + dim = other.getDim(); + + nVertex = other.getNVertexBased(); + nEdge = other.getNEdgeBased(); + nFace = other.getNFaceBased(); + nCell = other.getNCellBased(); + + nEdgeClosure = other.getNEdgeClosure(); + nFaceClosure = other.getNFaceClosure(); + + size = other.getSize(); + + // Alloc Basis // + node = new vector<Polynomial*>(nVertex); + edge = new vector<vector<Polynomial*>*>(2); + face = new vector<vector<Polynomial*>*>(6); + cell = new vector<Polynomial*>(nCell); + + for(int i = 0; i < nEdgeClosure; i++) + (*edge)[i] = new vector<Polynomial*>(nEdge); + + for(int i = 0; i < nFaceClosure; i++) + (*face)[i] = new vector<Polynomial*>(nFace); + + // Node Based // + for(int i = 0; i < nVertex; i++) + (*node)[i] = + new Polynomial + (Polynomial::divergence(other.getNodeFunction(i))); + + // Edge Based // + for(int i = 0; i < nEdgeClosure; i++) + for(int j = 0; j < nEdge; j++) + (*(*edge)[i])[j] = + new Polynomial + (Polynomial::divergence(other.getEdgeFunction(i, j))); + + // Face Based // + for(int i = 0; i < nFaceClosure; i++) + for(int j = 0; j < nFace; j++) + (*(*face)[i])[j] = + new Polynomial + (Polynomial::divergence(other.getFaceFunction(i, j))); + + // Cell Based // + for(int i = 0; i < nCell; i++) + (*cell)[i] = + new Polynomial + (Polynomial::divergence(other.getCellFunction(i))); +} + +DivBasis::~DivBasis(void){ + // Vertex Based // + for(int i = 0; i < nVertex; i++) + delete (*node)[i]; + + delete node; + + + // Edge Based // + for(int c = 0; c < nEdgeClosure; c++){ + for(int i = 0; i < nEdge; i++) + delete (*(*edge)[c])[i]; + + delete (*edge)[c]; + } + + delete edge; + + + // Face Based // + for(int c = 0; c < nFaceClosure; c++){ + for(int i = 0; i < nFace; i++) + delete (*(*face)[c])[i]; + + delete (*face)[c]; + } + + delete face; + + + // Cell Based // + for(int i = 0; i < nCell; i++) + delete (*cell)[i]; + + delete cell; +} diff --git a/FunctionSpace/DivBasis.h b/FunctionSpace/DivBasis.h new file mode 100644 index 0000000000..2ebf45e9bd --- /dev/null +++ b/FunctionSpace/DivBasis.h @@ -0,0 +1,27 @@ +#ifndef _DIVBASIS_H_ +#define _DIVBASIS_H_ + +#include "BasisScalar.h" +#include "BasisVector.h" + +/** + @class DivBasis + @brief The Divergence of an other Basis + + This class can instantiate a Divergence Basis. + */ + +class DivBasis: public BasisScalar{ + public: + //! @param other An Other Basis + //! + //! Returns a new Basis, which is the divergence of + //! the given Basis + DivBasis(const BasisVector& other); + + //! Deletes this Basis + //! + virtual ~DivBasis(void); +}; + +#endif diff --git a/FunctionSpace/FunctionSpace.cpp b/FunctionSpace/FunctionSpace.cpp index 68fb467119..868209ecad 100644 --- a/FunctionSpace/FunctionSpace.cpp +++ b/FunctionSpace/FunctionSpace.cpp @@ -61,7 +61,7 @@ void FunctionSpace::build(const GroupOfElement& goe, basis = BasisGenerator::generate(elementType, basisType, order); - + // Number of *Per* Entity functions // fPerVertex = basis->getNVertexBased() / nVertex; // NB: fPreVertex = 0 *or* 1 @@ -99,7 +99,7 @@ void FunctionSpace::buildDof(void){ // Get Dof for this Element vector<Dof> myDof = getKeys(*(element[i])); unsigned int nDof = myDof.size(); - + // Create new GroupOfDof GroupOfDof* god = new GroupOfDof(nDof, *(element[i])); (*group)[i] = god; @@ -221,7 +221,7 @@ const GroupOfDof& FunctionSpace::getGoDFromElement(const MElement& element) cons return *(it->second); } -vector<int> FunctionSpace::getEdgeClosure(const MElement& element) const{ +vector<int> FunctionSpace::getEdgeClosure(const MElement& element){ // Get not const Element (gmsh problem, not mine !) // MElement& eelement = const_cast<MElement&>(element); @@ -246,7 +246,7 @@ vector<int> FunctionSpace::getEdgeClosure(const MElement& element) const{ return edgeClosure; } -vector<int> FunctionSpace::getFaceClosure(const MElement& element) const{ +vector<int> FunctionSpace::getFaceClosure(const MElement& element){ // Get not const Element (gmsh problem, not mine !) // MElement& eelement = const_cast<MElement&>(element); diff --git a/FunctionSpace/FunctionSpace.h b/FunctionSpace/FunctionSpace.h index 4949652788..18f0cf3873 100644 --- a/FunctionSpace/FunctionSpace.h +++ b/FunctionSpace/FunctionSpace.h @@ -97,8 +97,8 @@ class FunctionSpace{ void insertDof(Dof& d, GroupOfDof* god); // Closure - std::vector<int> getEdgeClosure(const MElement& element) const; - std::vector<int> getFaceClosure(const MElement& element) const; + static std::vector<int> getEdgeClosure(const MElement& element); + static std::vector<int> getFaceClosure(const MElement& element); }; diff --git a/FunctionSpace/FunctionSpaceNode.cpp b/FunctionSpace/FunctionSpaceNode.cpp index cb41efbd27..10928c769c 100644 --- a/FunctionSpace/FunctionSpaceNode.cpp +++ b/FunctionSpace/FunctionSpaceNode.cpp @@ -10,6 +10,10 @@ FunctionSpaceNode::FunctionSpaceNode(const GroupOfElement& goe, int order){ // Build 0Form Basis // build(goe, 0, order); + + // Init BasisScalar // + basisScalar = + static_cast<const BasisScalar*>(basis); } FunctionSpaceNode::~FunctionSpaceNode(void){ diff --git a/FunctionSpace/FunctionSpaceScalar.cpp b/FunctionSpace/FunctionSpaceScalar.cpp index dc0919a618..8480ee7543 100644 --- a/FunctionSpace/FunctionSpaceScalar.cpp +++ b/FunctionSpace/FunctionSpaceScalar.cpp @@ -3,31 +3,36 @@ using namespace std; +FunctionSpaceScalar::FunctionSpaceScalar(void){ + hasGrad = false; + gradBasis = NULL; +} + FunctionSpaceScalar::~FunctionSpaceScalar(void){ + if(hasGrad) + delete gradBasis; } const vector<const Polynomial*> FunctionSpaceScalar:: getLocalFunctions(const MElement& element) const{ // Get Basis // - const BasisScalar& basis = getBasis(element); - - const unsigned int nFNode = basis.getNVertexBased(); - const unsigned int nFEdge = basis.getNEdgeBased(); - const unsigned int nFFace = basis.getNFaceBased(); - const unsigned int nFCell = basis.getNCellBased(); + const unsigned int nFNode = basisScalar->getNVertexBased(); + const unsigned int nFEdge = basisScalar->getNEdgeBased(); + const unsigned int nFFace = basisScalar->getNFaceBased(); + const unsigned int nFCell = basisScalar->getNCellBased(); // Get Closure // vector<int> edgeClosure = getEdgeClosure(element); vector<int> faceClosure = getFaceClosure(element); // Get Functions // - vector<const Polynomial*> fun(basis.getSize()); + vector<const Polynomial*> fun(basisScalar->getSize()); unsigned int i = 0; // Vertex Based for(unsigned int j = 0; j < nFNode; j++){ - fun[i] = &basis.getNodeFunction(j); + fun[i] = &basisScalar->getNodeFunction(j); i++; } @@ -41,7 +46,7 @@ getLocalFunctions(const MElement& element) const{ for(unsigned int j = 0; j < nFPerEdge; j++){ for(unsigned int k = 0; k < nEdge; k++){ fun[i] = - &basis.getEdgeFunction(edgeClosure[k], fEdge); + &basisScalar->getEdgeFunction(edgeClosure[k], fEdge); fEdge++; i++; @@ -58,7 +63,7 @@ getLocalFunctions(const MElement& element) const{ for(unsigned int j = 0; j < nFPerFace; j++){ for(unsigned int k = 0; k < nFace; k++){ fun[i] = - &basis.getFaceFunction(faceClosure[k], fFace); + &basisScalar->getFaceFunction(faceClosure[k], fFace); fFace++; i++; @@ -67,7 +72,7 @@ getLocalFunctions(const MElement& element) const{ // Cell Based for(unsigned int j = 0; j < nFCell; j++){ - fun[i] = &basis.getCellFunction(j); + fun[i] = &basisScalar->getCellFunction(j); i++; } @@ -75,3 +80,79 @@ getLocalFunctions(const MElement& element) const{ // Return // return fun; } + +const vector<const vector<Polynomial>*> FunctionSpaceScalar:: +getGradLocalFunctions(const MElement& element) const{ + + // Got Grad Basis ? // + // --> mutable data + // --> Just a 'cache memory' + if(!hasGrad){ + gradBasis = new GradBasis(*basisScalar); + hasGrad = true; + } + + // Get Basis // + const unsigned int nFNode = gradBasis->getNVertexBased(); + const unsigned int nFEdge = gradBasis->getNEdgeBased(); + const unsigned int nFFace = gradBasis->getNFaceBased(); + const unsigned int nFCell = gradBasis->getNCellBased(); + + // Get Closure // + vector<int> edgeClosure = getEdgeClosure(element); + vector<int> faceClosure = getFaceClosure(element); + + // Get Functions // + vector<const vector<Polynomial>*> fun(gradBasis->getSize()); + unsigned int i = 0; + + // Vertex Based + for(unsigned int j = 0; j < nFNode; j++){ + fun[i] = &gradBasis->getNodeFunction(j); + i++; + } + + // Edge Based + // Number of basis function *per* edge + // --> should always be an integer ! + const unsigned int nEdge = edgeClosure.size(); + const unsigned int nFPerEdge = nFEdge / nEdge; + unsigned int fEdge = 0; + + for(unsigned int j = 0; j < nFPerEdge; j++){ + for(unsigned int k = 0; k < nEdge; k++){ + fun[i] = + &gradBasis->getEdgeFunction(edgeClosure[k], fEdge); + + fEdge++; + i++; + } + } + + // Face Based + // Number of basis function *per* face + // --> should always be an integer ! + const unsigned int nFace = faceClosure.size(); + 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] = + &gradBasis->getFaceFunction(faceClosure[k], fFace); + + fFace++; + i++; + } + } + + // Cell Based + for(unsigned int j = 0; j < nFCell; j++){ + fun[i] = &gradBasis->getCellFunction(j); + i++; + } + + + // Return // + return fun; +} diff --git a/FunctionSpace/FunctionSpaceScalar.h b/FunctionSpace/FunctionSpaceScalar.h index 7f1b536cb3..8b0999e0b7 100644 --- a/FunctionSpace/FunctionSpaceScalar.h +++ b/FunctionSpace/FunctionSpaceScalar.h @@ -3,6 +3,7 @@ #include "fullMatrix.h" #include "BasisScalar.h" +#include "GradBasis.h" #include "FunctionSpace.h" /** @@ -21,6 +22,12 @@ class FunctionSpaceScalar : public FunctionSpace{ + protected: + const BasisScalar* basisScalar; + + mutable bool hasGrad; + mutable GradBasis* gradBasis; + public: virtual ~FunctionSpaceScalar(void); @@ -31,8 +38,14 @@ class FunctionSpaceScalar : public FunctionSpace{ const std::vector<const Polynomial*> getLocalFunctions(const MElement& element) const; + + const std::vector<const std::vector<Polynomial>*> + getGradLocalFunctions(const MElement& element) const; const BasisScalar& getBasis(const MElement& element) const; + + protected: + FunctionSpaceScalar(void); }; @@ -77,10 +90,10 @@ class FunctionSpaceScalar : public FunctionSpace{ ////////////////////// // Inline Functions // ////////////////////// - +/* inline const BasisScalar& FunctionSpaceScalar:: getBasis(const MElement& element) const{ - return static_cast<const BasisScalar&>(*basis); + return *basisScalar; } - +*/ #endif diff --git a/FunctionSpace/GradBasis.cpp b/FunctionSpace/GradBasis.cpp new file mode 100644 index 0000000000..c4829e3ba5 --- /dev/null +++ b/FunctionSpace/GradBasis.cpp @@ -0,0 +1,96 @@ +#include "GradBasis.h" + +using namespace std; + +GradBasis::GradBasis(const BasisScalar& other){ + // Set Basis Type // + order = other.getOrder(); + + type = other.getType(); + dim = other.getDim(); + + nVertex = other.getNVertexBased(); + nEdge = other.getNEdgeBased(); + nFace = other.getNFaceBased(); + nCell = other.getNCellBased(); + + nEdgeClosure = other.getNEdgeClosure(); + nFaceClosure = other.getNFaceClosure(); + + size = other.getSize(); + + // Alloc Basis // + node = new vector<vector<Polynomial>*>(nVertex); + edge = new vector<vector<vector<Polynomial>*>*>(nEdgeClosure); + face = new vector<vector<vector<Polynomial>*>*>(nFaceClosure); + cell = new vector<vector<Polynomial>*>(nCell); + + for(int i = 0; i < nEdgeClosure; i++) + (*edge)[i] = new vector<vector<Polynomial>*>(nEdge); + + for(int i = 0; i < nFaceClosure; i++) + (*face)[i] = new vector<vector<Polynomial>*>(nFace); + + // Node Based // + for(int i = 0; i < nVertex; i++) + (*node)[i] = + new vector<Polynomial> + (other.getNodeFunction(i).gradient()); + + // Edge Based // + for(int i = 0; i < nEdgeClosure; i++) + for(int j = 0; j < nEdge; j++) + (*(*edge)[i])[j] = + new vector<Polynomial> + (other.getEdgeFunction(i, j).gradient()); + + // Face Based // + for(int i = 0; i < nFaceClosure; i++) + for(int j = 0; j < nFace; j++) + (*(*face)[i])[j] = + new vector<Polynomial> + (other.getFaceFunction(i, j).gradient()); + + // Cell Based // + for(int i = 0; i < nCell; i++) + (*cell)[i] = + new vector<Polynomial> + (other.getCellFunction(i).gradient()); +} + +GradBasis::~GradBasis(void){ + // Vertex Based // + for(int i = 0; i < nVertex; i++) + delete (*node)[i]; + + delete node; + + + // Edge Based // + for(int c = 0; c < nEdgeClosure; c++){ + for(int i = 0; i < nEdge; i++) + delete (*(*edge)[c])[i]; + + delete (*edge)[c]; + } + + delete edge; + + + // Face Based // + for(int c = 0; c < nFaceClosure; c++){ + for(int i = 0; i < nFace; i++) + delete (*(*face)[c])[i]; + + delete (*face)[c]; + } + + delete face; + + + // Cell Based // + for(int i = 0; i < nCell; i++) + delete (*cell)[i]; + + delete cell; +} diff --git a/FunctionSpace/GradBasis.h b/FunctionSpace/GradBasis.h new file mode 100644 index 0000000000..34b32974c1 --- /dev/null +++ b/FunctionSpace/GradBasis.h @@ -0,0 +1,27 @@ +#ifndef _GRADBASIS_H_ +#define _GRADBASIS_H_ + +#include "BasisVector.h" +#include "BasisScalar.h" + +/** + @class GradBasis + @brief The Gradient of an other Basis + + This class can instantiate a Gradient Basis. + */ + +class GradBasis: public BasisVector{ + public: + //! @param other An Other Basis + //! + //! Returns a new Basis, which is the gradient of + //! the given Basis + GradBasis(const BasisScalar& other); + + //! Deletes this Basis + //! + virtual ~GradBasis(void); +}; + +#endif diff --git a/FunctionSpace/HexEdgeBasis.cpp b/FunctionSpace/HexEdgeBasis.cpp index f456994021..7ebbbdee41 100644 --- a/FunctionSpace/HexEdgeBasis.cpp +++ b/FunctionSpace/HexEdgeBasis.cpp @@ -17,6 +17,9 @@ HexEdgeBasis::HexEdgeBasis(int order){ nFace = 12 * order * (order + 1); nCell = 3 * order * order * (order + 1); + nEdgeClosure = 2; + nFaceClosure = 8; + size = 3 * (order + 2) * (order + 2) * (order + 1); // Alloc Temporary Space // diff --git a/FunctionSpace/HexNodeBasis.cpp b/FunctionSpace/HexNodeBasis.cpp index cd3c99b97b..5cc68e7f0c 100644 --- a/FunctionSpace/HexNodeBasis.cpp +++ b/FunctionSpace/HexNodeBasis.cpp @@ -16,6 +16,9 @@ HexNodeBasis::HexNodeBasis(int order){ nFace = 6 * (order - 1) * (order - 1); nCell = (order - 1) * (order - 1) * (order - 1); + nEdgeClosure = 2; + nFaceClosure = 8; + size = nVertex + nEdge + nFace + nCell; // Alloc Temporary Space // diff --git a/FunctionSpace/Polynomial.cpp b/FunctionSpace/Polynomial.cpp index 1edda763e1..fe952cc856 100644 --- a/FunctionSpace/Polynomial.cpp +++ b/FunctionSpace/Polynomial.cpp @@ -101,6 +101,47 @@ vector<Polynomial> Polynomial::gradient(void) const{ return grad; } +vector<Polynomial> Polynomial::curl(const vector<Polynomial>& p){ + vector<Polynomial> rot(3); + + // Partial Derivatives // + Polynomial dP0d1 = p[0]; + Polynomial dP0d2 = p[0]; + Polynomial dP1d0 = p[1]; + Polynomial dP1d2 = p[1]; + Polynomial dP2d0 = p[2]; + Polynomial dP2d1 = p[2]; + + dP0d1.derivative(1); + dP0d2.derivative(2); + dP1d0.derivative(0); + dP1d2.derivative(2); + dP2d0.derivative(0); + dP2d1.derivative(1); + + // Curl // + rot[0] = dP2d1 - dP1d2; + rot[1] = dP0d2 - dP2d0; + rot[2] = dP1d0 - dP0d1; + + // Return // + return rot; +} + +Polynomial Polynomial::divergence(const vector<Polynomial>& p){ + // Partial Derivatives // + Polynomial dP0d0 = p[0]; + Polynomial dP1d1 = p[1]; + Polynomial dP2d2 = p[2]; + + dP0d0.derivative(0); + dP1d1.derivative(1); + dP2d2.derivative(2); + + // Return Div // + return dP0d0 + dP1d1 + dP2d2; +} + double Polynomial::at (const double x, const double y, const double z) const{ diff --git a/FunctionSpace/Polynomial.h b/FunctionSpace/Polynomial.h index fe5571e04b..1e30fabe2e 100644 --- a/FunctionSpace/Polynomial.h +++ b/FunctionSpace/Polynomial.h @@ -36,8 +36,10 @@ class Polynomial{ Polynomial(void); ~Polynomial(void); - void derivative(const int dim); + void derivative(const int dim); std::vector<Polynomial> gradient(void) const; + static std::vector<Polynomial> curl(const std::vector<Polynomial>& p); + static Polynomial divergence(const std::vector<Polynomial>& p); double operator() (const double x, const double y, const double z) const; diff --git a/FunctionSpace/QuadEdgeBasis.cpp b/FunctionSpace/QuadEdgeBasis.cpp index 3b76a66b6b..56e6570e3b 100644 --- a/FunctionSpace/QuadEdgeBasis.cpp +++ b/FunctionSpace/QuadEdgeBasis.cpp @@ -15,6 +15,9 @@ QuadEdgeBasis::QuadEdgeBasis(int order){ nFace = 0; nCell = 2 * (order + 1) * order; + nEdgeClosure = 2; + nFaceClosure = 0; + size = nVertex + nEdge + nFace + nCell; // Alloc Temporary Space // diff --git a/FunctionSpace/QuadNodeBasis.cpp b/FunctionSpace/QuadNodeBasis.cpp index 2d1e2e233d..68b0fc26a0 100644 --- a/FunctionSpace/QuadNodeBasis.cpp +++ b/FunctionSpace/QuadNodeBasis.cpp @@ -15,6 +15,9 @@ QuadNodeBasis::QuadNodeBasis(int order){ nFace = 0; nCell = (order - 1) * (order - 1); + nEdgeClosure = 2; + nFaceClosure = 0; + size = nVertex + nEdge + nFace + nCell; // Alloc Temporary Space // diff --git a/FunctionSpace/TetEdgeBasis.cpp b/FunctionSpace/TetEdgeBasis.cpp index 705f36a783..bc98182939 100644 --- a/FunctionSpace/TetEdgeBasis.cpp +++ b/FunctionSpace/TetEdgeBasis.cpp @@ -15,6 +15,9 @@ TetEdgeBasis::TetEdgeBasis(int order){ nFace = 4 * (order + 1) * (order - 1); nCell = (order + 1) * (order - 1) * (order - 2) / 2; + nEdgeClosure = 2; + nFaceClosure = 6; + size = nVertex + nEdge + nFace + nCell; // Alloc Temporary Space // @@ -343,7 +346,7 @@ TetEdgeBasis::TetEdgeBasis(int order){ } TetEdgeBasis::~TetEdgeBasis(void){ - // Vertex Based // + // Vertex Based // for(int i = 0; i < nVertex; i++) delete (*node)[i]; diff --git a/FunctionSpace/TetNodeBasis.cpp b/FunctionSpace/TetNodeBasis.cpp index c608aa7949..05125b2d5d 100644 --- a/FunctionSpace/TetNodeBasis.cpp +++ b/FunctionSpace/TetNodeBasis.cpp @@ -15,6 +15,9 @@ TetNodeBasis::TetNodeBasis(int order){ nFace = 2 * (order - 1) * (order - 2); nCell = (order - 1) * (order - 2) * (order - 3) / 6; + nEdgeClosure = 2; + nFaceClosure = 6; + size = nVertex + nEdge + nFace + nCell; // Alloc Temporary Space // diff --git a/FunctionSpace/TriEdgeBasis.cpp b/FunctionSpace/TriEdgeBasis.cpp index 332bf3fa06..eb02ba7dc8 100644 --- a/FunctionSpace/TriEdgeBasis.cpp +++ b/FunctionSpace/TriEdgeBasis.cpp @@ -15,6 +15,9 @@ TriEdgeBasis::TriEdgeBasis(int order){ nFace = 0; nCell = ((order - 1) * order + order - 1); + nEdgeClosure = 2; + nFaceClosure = 0; + size = nVertex + nEdge + nFace + nCell; // Alloc Temporary Space // diff --git a/FunctionSpace/TriNedelecBasis.cpp b/FunctionSpace/TriNedelecBasis.cpp index 929bdb43b9..061e6161fc 100644 --- a/FunctionSpace/TriNedelecBasis.cpp +++ b/FunctionSpace/TriNedelecBasis.cpp @@ -14,6 +14,9 @@ TriNedelecBasis::TriNedelecBasis(void){ nFace = 0; nCell = 0; + nEdgeClosure = 2; + nFaceClosure = 0; + size = 3; // Vertices definig Edges & Permutations // diff --git a/FunctionSpace/TriNodeBasis.cpp b/FunctionSpace/TriNodeBasis.cpp index 43a11e6580..1cf10b7f7b 100644 --- a/FunctionSpace/TriNodeBasis.cpp +++ b/FunctionSpace/TriNodeBasis.cpp @@ -15,6 +15,9 @@ TriNodeBasis::TriNodeBasis(int order){ nFace = 0; nCell = (order - 1) * (order - 2) / 2; + nEdgeClosure = 2; + nFaceClosure = 0; + size = nVertex + nEdge + nFace + nCell; // Alloc Temporary Space // -- GitLab