Skip to content
Snippets Groups Projects
Commit ddb25bd0 authored by Nicolas Marsic's avatar Nicolas Marsic
Browse files

New way of handling Basis in FunctionSpace: getBasis uses geomtrical type as input

parent 8f318f07
Branches
Tags
No related merge requests found
...@@ -9,12 +9,16 @@ ...@@ -9,12 +9,16 @@
using namespace std; using namespace std;
const size_t FunctionSpace::nGeoType = 9;
FunctionSpace::FunctionSpace(void){ FunctionSpace::FunctionSpace(void){
} }
FunctionSpace::~FunctionSpace(void){ FunctionSpace::~FunctionSpace(void){
// Delete Vector of Basis if(self)
// (FunctionSpace is not responsible for 'true' Basis Deletion) for(size_t i = 0; i < nGeoType; i++)
if(basis[i])
delete basis[i];
} }
void FunctionSpace::build(GroupOfElement& goe, void FunctionSpace::build(GroupOfElement& goe,
...@@ -24,40 +28,98 @@ void FunctionSpace::build(GroupOfElement& goe, ...@@ -24,40 +28,98 @@ void FunctionSpace::build(GroupOfElement& goe,
this->goe = &goe; this->goe = &goe;
this->mesh = &(goe.getMesh()); this->mesh = &(goe.getMesh());
// Get Geo Data (WARNING HOMOGENE MESH REQUIRED)// // Check if homogene GoE and get geo type //
const MElement& element = goe.get(0); const vector<size_t>& gType = goe.getTypeStats();
MElement& myElement = const size_t nGType = gType.size();
const_cast<MElement&>(element); size_t eType = (size_t)(-1);
for(size_t i = 0; i < nGType; i++)
if((eType == (size_t)(-1)) && (gType[i] != 0))
eType = i;
else if((eType != (size_t)(-1)) && (gType[i] != 0))
throw Exception("FunctionSpace needs a uniform mesh");
// Check if basis is matching type //
if(eType != basis.getType())
throw Exception("FunctionSpace: Basis is not matching type");
// Alloc Bases and save given Basis //
this->self = false;
this->basis.resize(nGeoType, NULL);
this->basis[eType] = &basis;
// Get Number of Function per Entity //
// Same for all basis since we have a uniform order
MElement& myElement = const_cast<MElement&>(goe.get(0));
int nVertex = myElement.getNumPrimaryVertices(); int nVertex = myElement.getNumPrimaryVertices();
int nEdge = myElement.getNumEdges(); int nEdge = myElement.getNumEdges();
int nFace = myElement.getNumFaces(); int nFace = myElement.getNumFaces();
// Init Struct //
this->basis.resize(1);
this->basis[0] = &basis;
// Number of *Per* Entity functions // // Number of *Per* Entity functions //
// Init fPerVertex = this->basis[eType]->getNVertexBased() / nVertex;
fPerVertex.resize(1);
fPerEdge.resize(1); if(nEdge)
fPerFace.resize(1); fPerEdge = this->basis[eType]->getNEdgeBased() / nEdge;
fPerCell.resize(1); else
fPerEdge = 0;
if(nFace)
fPerFace = this->basis[eType]->getNFaceBased() / nFace;
else
fPerFace = 0;
fPerCell = this->basis[eType]->getNCellBased();
// Build Dof //
buildDof();
}
void FunctionSpace::build(GroupOfElement& goe,
size_t order, size_t form, string family){
// Save GroupOfElement & Mesh //
this->goe = &goe;
this->mesh = &(goe.getMesh());
// Alloc Basis Vector for all possible geomtrical types //
self = true;
basis.resize(nGeoType, NULL);
// Generate Bases //
const vector<const MElement*>& element = goe.getAll();
// Get geomtrical type statistics
const vector<size_t>& geoTypeStat = goe.getTypeStats();
const size_t nGeoType = geoTypeStat.size();
// Buils basis for existing geomtrical type
for(size_t i = 0; i < nGeoType; i++)
if(geoTypeStat[i])
basis[i] = BasisGenerator::generate(i, form, order, family);
// Get Number of Function per Entity //
// Same for all basis since we have a uniform order
MElement& myElement = const_cast<MElement&>(*element[0]);
int nVertex = myElement.getNumPrimaryVertices();
int nEdge = myElement.getNumEdges();
int nFace = myElement.getNumFaces();
int type = myElement.getType();
// Populate fPerVertex = basis[type]->getNVertexBased() / nVertex;
fPerVertex[0] = this->basis[0]->getNVertexBased() / nVertex;
if(nEdge) if(nEdge)
fPerEdge[0] = this->basis[0]->getNEdgeBased() / nEdge; fPerEdge = this->basis[type]->getNEdgeBased() / nEdge;
else else
fPerEdge[0] = 0; fPerEdge = 0;
if(nFace) if(nFace)
fPerFace[0] = this->basis[0]->getNFaceBased() / nFace; fPerFace = this->basis[type]->getNFaceBased() / nFace;
else else
fPerFace[0] = 0; fPerFace = 0;
fPerCell[0] = this->basis[0]->getNCellBased(); fPerCell = this->basis[type]->getNCellBased();
// Build Dof // // Build Dof //
buildDof(); buildDof();
...@@ -117,10 +179,10 @@ vector<Dof> FunctionSpace::getUnorderedKeys(const MElement& elem) const{ ...@@ -117,10 +179,10 @@ vector<Dof> FunctionSpace::getUnorderedKeys(const MElement& elem) const{
// Create Dof // // Create Dof //
size_t nDof = size_t nDof =
fPerVertex[0] * nVertex + fPerVertex * nVertex +
fPerEdge[0] * nEdge + fPerEdge * nEdge +
fPerFace[0] * nFace + fPerFace * nFace +
fPerCell[0] * nCell; fPerCell * nCell;
vector<Dof> myDof(nDof); vector<Dof> myDof(nDof);
...@@ -128,7 +190,7 @@ vector<Dof> FunctionSpace::getUnorderedKeys(const MElement& elem) const{ ...@@ -128,7 +190,7 @@ vector<Dof> FunctionSpace::getUnorderedKeys(const MElement& elem) const{
// Add Vertex Based Dof // // Add Vertex Based Dof //
for(size_t i = 0; i < nVertex; i++){ for(size_t i = 0; i < nVertex; i++){
for(size_t j = 0; j < fPerVertex[0]; j++){ for(size_t j = 0; j < fPerVertex; j++){
myDof[it].setDof(mesh->getGlobalId(*vertex[i]), j); myDof[it].setDof(mesh->getGlobalId(*vertex[i]), j);
it++; it++;
} }
...@@ -136,7 +198,7 @@ vector<Dof> FunctionSpace::getUnorderedKeys(const MElement& elem) const{ ...@@ -136,7 +198,7 @@ vector<Dof> FunctionSpace::getUnorderedKeys(const MElement& elem) const{
// Add Edge Based Dof // // Add Edge Based Dof //
for(size_t i = 0; i < nEdge; i++){ for(size_t i = 0; i < nEdge; i++){
for(size_t j = 0; j < fPerEdge[0]; j++){ for(size_t j = 0; j < fPerEdge; j++){
myDof[it].setDof(mesh->getGlobalId(edge[i]), j); myDof[it].setDof(mesh->getGlobalId(edge[i]), j);
it++; it++;
} }
...@@ -144,7 +206,7 @@ vector<Dof> FunctionSpace::getUnorderedKeys(const MElement& elem) const{ ...@@ -144,7 +206,7 @@ vector<Dof> FunctionSpace::getUnorderedKeys(const MElement& elem) const{
// Add Face Based Dof // // Add Face Based Dof //
for(size_t i = 0; i < nFace; i++){ for(size_t i = 0; i < nFace; i++){
for(size_t j = 0; j < fPerFace[0]; j++){ for(size_t j = 0; j < fPerFace; j++){
myDof[it].setDof(mesh->getGlobalId(face[i]), j); myDof[it].setDof(mesh->getGlobalId(face[i]), j);
it++; it++;
} }
...@@ -152,7 +214,7 @@ vector<Dof> FunctionSpace::getUnorderedKeys(const MElement& elem) const{ ...@@ -152,7 +214,7 @@ vector<Dof> FunctionSpace::getUnorderedKeys(const MElement& elem) const{
// Add Cell Based Dof // // Add Cell Based Dof //
for(size_t i = 0; i < nCell; i++){ for(size_t i = 0; i < nCell; i++){
for(size_t j = 0; j < fPerCell[0]; j++){ for(size_t j = 0; j < fPerCell; j++){
myDof[it].setDof(mesh->getGlobalId(element), j); myDof[it].setDof(mesh->getGlobalId(element), j);
it++; it++;
} }
......
...@@ -23,26 +23,29 @@ ...@@ -23,26 +23,29 @@
A FunctionSpace is also responsible for the generation of all A FunctionSpace is also responsible for the generation of all
the Dof%s related to its geometrical Support. the Dof%s related to its geometrical Support.
@todo
Allow Hybrid Mesh
*/ */
class Mesh; class Mesh;
class GroupOfElement; class GroupOfElement;
class FunctionSpace{ class FunctionSpace{
protected:
// Number of possible geomtrical topologies //
static const size_t nGeoType;
protected: protected:
// Geometry // // Geometry //
const Mesh* mesh; const Mesh* mesh;
GroupOfElement* goe; GroupOfElement* goe;
// Basis // // Basis //
bool self;
std::vector<const Basis*> basis; std::vector<const Basis*> basis;
std::vector<size_t> fPerVertex;
std::vector<size_t> fPerEdge; size_t fPerVertex;
std::vector<size_t> fPerFace; size_t fPerEdge;
std::vector<size_t> fPerCell; size_t fPerFace;
size_t fPerCell;
// Scalar Field ? // // Scalar Field ? //
bool scalar; bool scalar;
...@@ -72,6 +75,8 @@ class FunctionSpace{ ...@@ -72,6 +75,8 @@ class FunctionSpace{
FunctionSpace(void); FunctionSpace(void);
void build(GroupOfElement& goe, const Basis& basis); void build(GroupOfElement& goe, const Basis& basis);
void build(GroupOfElement& goe,
size_t order, size_t form, std::string family);
void buildDof(void); void buildDof(void);
}; };
......
...@@ -7,6 +7,11 @@ FunctionSpaceScalar::FunctionSpaceScalar(GroupOfElement& goe, ...@@ -7,6 +7,11 @@ FunctionSpaceScalar::FunctionSpaceScalar(GroupOfElement& goe,
build(goe, basis); build(goe, basis);
} }
FunctionSpaceScalar::FunctionSpaceScalar(GroupOfElement& goe, size_t order){
scalar = true;
build(goe, order, 0, "hierarchical");
}
FunctionSpaceScalar::~FunctionSpaceScalar(void){ FunctionSpaceScalar::~FunctionSpaceScalar(void){
// Done by FunctionSpace // Done by FunctionSpace
} }
...@@ -15,12 +20,14 @@ double FunctionSpaceScalar:: ...@@ -15,12 +20,14 @@ double FunctionSpaceScalar::
interpolateInABC(const MElement& element, interpolateInABC(const MElement& element,
const std::vector<double>& coef, const std::vector<double>& coef,
double abc[3]) const{ double abc[3]) const{
// Element Type //
const int eType = element.getType();
// Get Basis Functions // // Get Basis Functions //
const size_t nFun = basis[0]->getNFunction(); const size_t nFun = basis[eType]->getNFunction();
fullMatrix<double> fun(nFun, 1); fullMatrix<double> fun(nFun, 1);
basis[0]->getFunctions(fun, element, abc[0], abc[1], abc[2]); basis[eType]->getFunctions(fun, element, abc[0], abc[1], abc[2]);
// Interpolate (in Reference Place) // // Interpolate (in Reference Place) //
double val = 0; double val = 0;
...@@ -41,11 +48,14 @@ interpolateDerivativeInABC(const MElement& element, ...@@ -41,11 +48,14 @@ interpolateDerivativeInABC(const MElement& element,
ReferenceSpaceManager::getJacobian(element, abc[0], abc[1], abc[2], invJac); ReferenceSpaceManager::getJacobian(element, abc[0], abc[1], abc[2], invJac);
invJac.invertInPlace(); invJac.invertInPlace();
// Element Type //
const int eType = element.getType();
// Get Basis Functions // // Get Basis Functions //
const size_t nFun = basis[0]->getNFunction(); const size_t nFun = basis[eType]->getNFunction();
fullMatrix<double> fun(nFun, 3); fullMatrix<double> fun(nFun, 3);
basis[0]->getDerivative(fun, element, abc[0], abc[1], abc[2]); basis[eType]->getDerivative(fun, element, abc[0], abc[1], abc[2]);
// Interpolate (in Reference Place) // // Interpolate (in Reference Place) //
fullMatrix<double> val(1, 3); fullMatrix<double> val(1, 3);
......
...@@ -11,15 +11,14 @@ ...@@ -11,15 +11,14 @@
This class is a @em Scalar FunctionSpaces.@n This class is a @em Scalar FunctionSpaces.@n
A FunctionSpaceScalar can be @em interpolated. A FunctionSpaceScalar can be @em interpolated.
@todo
Allow interpolation with multiple basis
*/ */
class FunctionSpaceScalar : public FunctionSpace{ class FunctionSpaceScalar : public FunctionSpace{
public: public:
FunctionSpaceScalar(GroupOfElement& goe, const Basis& basis); FunctionSpaceScalar(GroupOfElement& goe, const Basis& basis);
FunctionSpaceScalar(GroupOfElement& goe, size_t order);
virtual ~FunctionSpaceScalar(void); virtual ~FunctionSpaceScalar(void);
double double
......
...@@ -21,11 +21,14 @@ interpolateInABC(const MElement& element, ...@@ -21,11 +21,14 @@ interpolateInABC(const MElement& element,
ReferenceSpaceManager::getJacobian(element, abc[0], abc[1], abc[2], invJac); ReferenceSpaceManager::getJacobian(element, abc[0], abc[1], abc[2], invJac);
invJac.invertInPlace(); invJac.invertInPlace();
// Element Type //
const int eType = element.getType();
// Get Basis Functions // // Get Basis Functions //
const size_t nFun = basis[0]->getNFunction(); const size_t nFun = basis[eType]->getNFunction();
fullMatrix<double> fun(nFun, 3); fullMatrix<double> fun(nFun, 3);
basis[0]->getFunctions(fun, element, abc[0], abc[1], abc[2]); basis[eType]->getFunctions(fun, element, abc[0], abc[1], abc[2]);
// Interpolate (in Reference Place) // // Interpolate (in Reference Place) //
fullMatrix<double> val(1, 3); fullMatrix<double> val(1, 3);
......
...@@ -12,9 +12,6 @@ ...@@ -12,9 +12,6 @@
This class is a @em Vectorial FunctionSpaces.@n This class is a @em Vectorial FunctionSpaces.@n
A FunctionSpaceVector can be @em interpolated. A FunctionSpaceVector can be @em interpolated.
@todo
Allow interpolation with multiple basis
*/ */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment