DegreeOfFreedomSetBuilder Class Reference

#include <DegreeOfFreedomSetBuilder.hpp>

Collaboration diagram for DegreeOfFreedomSetBuilder:

Collaboration graph
[legend]

List of all members.

Public Member Functions

ConstReferenceCounting
< DegreeOfFreedomSet
getDegreeOfFreedomSet () const
const DegreeOfFreedomSetdegreeOfFreedomSet () const
 DegreeOfFreedomSetBuilder (const DiscretizationType &discretizationType, const Mesh &mesh)
 DegreeOfFreedomSetBuilder (const DiscretizationType &discretizationType, const Mesh &mesh, const Domain &domain)
 ~DegreeOfFreedomSetBuilder ()

Private Member Functions

template<typename MeshType, typename FiniteElementType>
size_t __buildFEMCorrespondance (const MeshType &mesh, DegreeOfFreedomSet::Correspondance &correspondance)
template<typename MeshType>
void __buildCorrespondance (const MeshType &mesh, const DiscretizationType &discretization, DegreeOfFreedomSet::Correspondance &correspondance)
template<typename MeshType, typename FiniteElementType>
void __buildFEMFictitious (const size_t &numberOfVariables, const MeshType &mesh, const Domain &domain)
template<typename MeshType>
void __buildFictitious (const size_t &numberOfVariables, const ScalarDiscretizationTypeBase &discretization, const MeshType &mesh, const Domain &domain)

Private Attributes

ConstReferenceCounting
< DegreeOfFreedomSet
__degreeOfFreedomSet
 the degree of freedom set
ReferenceCounting
< DegreeOfFreedomPositionsSet
__dofPositionSet
 the list degree of freedom set

Classes

struct  ItemTraits
struct  ItemTraits< 0 >


Detailed Description

Definition at line 43 of file DegreeOfFreedomSetBuilder.hpp.


Constructor & Destructor Documentation

DegreeOfFreedomSetBuilder::DegreeOfFreedomSetBuilder ( const DiscretizationType discretizationType,
const Mesh mesh 
)

Builds the DegreeOfFreedomSet according to the number of variable, the periodicity and the mesh

Parameters:
discretizationType the type of discretization
mesh the mesh

Definition at line 368 of file DegreeOfFreedomSetBuilder.cpp.

References __buildCorrespondance(), __degreeOfFreedomSet, __dofPositionSet, Mesh::cartesianHexahedraMesh, Mesh::hexahedraMesh, StaticBase< DegreeOfFreedomSetManager >::instance(), DiscretizationType::number(), Mesh::octreeMesh, Mesh::spectralMesh, Mesh::tetrahedraMesh, Mesh::type(), and ErrorHandler::unexpected.

00370   : __dofPositionSet(new DegreeOfFreedomPositionsSet)
00371 {
00372   for (size_t i=0; i<discretizationType.number(); ++i) {
00373     __dofPositionSet->add(DegreeOfFreedomSetManager::instance().getDOFPositionsSet(mesh,
00374                                                                                    discretizationType[i]));
00375   }
00376 
00377   typedef DegreeOfFreedomSet::Correspondance Correspondance;
00378 
00379   size_t numberOfCorrespondances = 0;
00380   for (size_t i=0; i<__dofPositionSet->number(); ++i) {
00381     numberOfCorrespondances += (*__dofPositionSet)[i].number();
00382   }
00383 
00384   ReferenceCounting<Correspondance> pCorrespondance
00385     = new Correspondance(numberOfCorrespondances);
00386   Correspondance& correspondance = *pCorrespondance;
00387 
00388   switch(mesh.type()) {
00389   case Mesh::cartesianHexahedraMesh: {
00390     this->__buildCorrespondance(static_cast<const Structured3DMesh&>(mesh),
00391                                 discretizationType,
00392                                 correspondance);
00393     break;
00394   }
00395   case Mesh::hexahedraMesh: {
00396     this->__buildCorrespondance(static_cast<const MeshOfHexahedra&>(mesh),
00397                                 discretizationType,
00398                                 correspondance);
00399     break;
00400   }
00401   case Mesh::tetrahedraMesh: {
00402     this->__buildCorrespondance(static_cast<const MeshOfTetrahedra&>(mesh),
00403                                 discretizationType,
00404                                 correspondance);
00405     break;
00406   }
00407   case Mesh::spectralMesh: {
00408     this->__buildCorrespondance(static_cast<const SpectralMesh&>(mesh),
00409                                 discretizationType,
00410                                 correspondance);
00411     break;
00412   }
00413   case Mesh::octreeMesh: {
00414     this->__buildCorrespondance(static_cast<const OctreeMesh&>(mesh),
00415                                 discretizationType,
00416                                 correspondance);
00417     break;
00418   }
00419   default: {
00420     throw ErrorHandler(__FILE__,__LINE__,
00421                        "not implemented yet",
00422                        ErrorHandler::unexpected);
00423   }
00424   }
00425 
00426   __degreeOfFreedomSet
00427     = new DegreeOfFreedomSet(__dofPositionSet,
00428                              pCorrespondance);
00429 
00430 }

Here is the call graph for this function:

DegreeOfFreedomSetBuilder::DegreeOfFreedomSetBuilder ( const DiscretizationType discretizationType,
const Mesh mesh,
const Domain domain 
)

Builds the DegreeOfFreedomSet according to the number of variables, the periodicity, the mesh and the domain. This constructor is called in the case of fictitious domain methods

Parameters:
discretizationType the type of discretization
mesh the mesh
domain the domain

Definition at line 433 of file DegreeOfFreedomSetBuilder.cpp.

References __buildFictitious(), __dofPositionSet, Mesh::cartesianHexahedraMesh, Mesh::hexahedraMesh, StaticBase< DegreeOfFreedomSetManager >::instance(), DiscretizationType::number(), Mesh::tetrahedraMesh, Mesh::type(), and ErrorHandler::unexpected.

00436   : __dofPositionSet(new DegreeOfFreedomPositionsSet)
00437 {
00438   for (size_t i=0; i<discretizationType.number(); ++i) {
00439     __dofPositionSet->add(DegreeOfFreedomSetManager::instance().getDOFPositionsSet(mesh,
00440                                                                                    discretizationType[i]));
00441   }
00442 
00443   switch(mesh.type()) {
00444   case Mesh::cartesianHexahedraMesh: {
00445     this->__buildFictitious(discretizationType.number(),
00446                             discretizationType[0],
00447                             static_cast<const Structured3DMesh&>(mesh),
00448                             domain);
00449     break;
00450   }
00451   case Mesh::tetrahedraMesh: {
00452     this->__buildFictitious(discretizationType.number(),
00453                             discretizationType[0],
00454                             static_cast<const Structured3DMesh&>(mesh),
00455                             domain);
00456     break;
00457   }
00458   case Mesh::hexahedraMesh: {
00459     this->__buildFictitious(discretizationType.number(),
00460                             discretizationType[0],
00461                             static_cast<const Structured3DMesh&>(mesh),
00462                             domain);
00463     break;
00464   }
00465   default: {
00466     throw ErrorHandler(__FILE__,__LINE__,
00467                        "not implemented yet",
00468                        ErrorHandler::unexpected);
00469   }
00470   }
00471 }

Here is the call graph for this function:

DegreeOfFreedomSetBuilder::~DegreeOfFreedomSetBuilder (  ) 

Destructor

Definition at line 475 of file DegreeOfFreedomSetBuilder.cpp.

00476 {
00477   ;
00478 }


Member Function Documentation

template<typename MeshType, typename FiniteElementType>
size_t DegreeOfFreedomSetBuilder::__buildFEMCorrespondance ( const MeshType &  mesh,
DegreeOfFreedomSet::Correspondance correspondance 
) [inline, private]

Builds the degrees of freedom correspondance vector according to the mesh type and the discretization for a particular FEM type

Parameters:
mesh the non-abstract mesh
correspondance correspondance table
Returns:
the number of used degrees of freedom
Bug:
This uses the degrees of vertices periodic correspondance which does not work in every case. This is wrong for instance when there are not enought cells in the mesh (consecutive edges can be considered as one which is wrong). It first occures for Q2 finite element on less than 3*3*3 periodic meshes...

Definition at line 56 of file DegreeOfFreedomSetBuilder.cpp.

References ASSERT.

00058 {
00059   size_t numberOfUsedDOF = 0;
00060   size_t dofPositionNumber = 0;
00061 
00062   const VerticesCorrespondance& verticesCorrespondance = *mesh.verticesCorrespondance();
00063 
00064   // vertices dof management
00065   if (FiniteElementType::numberOfVertexDegreesOfFreedom > 0) {
00066     for (size_t i=0; i<mesh.numberOfVertices(); ++i) {
00067       correspondance[i] = verticesCorrespondance[i];
00068       numberOfUsedDOF = std::max(verticesCorrespondance[i],numberOfUsedDOF);
00069       dofPositionNumber++;
00070     }
00071   }
00072 
00073   // edge dof management
00074   if (FiniteElementType::numberOfEdgeDegreesOfFreedom > 0) {
00075     ASSERT(mesh.hasEdges());
00076 
00077     typedef TinyVector<2,size_t> VerticesPair;
00078 
00079     typedef
00080       typename ItemTraits<FiniteElementType::numberOfEdgeDegreesOfFreedom>::DOFList
00081       EdgeDOFNumbers;
00082 
00083     typedef std::map<VerticesPair, EdgeDOFNumbers> SortedEdgeSet;
00084     SortedEdgeSet sortedEdgeSet;
00085 
00086     for (size_t i=0; i<mesh.numberOfEdges(); ++i) {
00087       const Edge& edge = mesh.edge(i);
00088       const size_t v0 = verticesCorrespondance[mesh.vertexNumber(edge(0))];
00089       const size_t v1 = verticesCorrespondance[mesh.vertexNumber(edge(1))];
00090 
00091       TinyVector<2,size_t> verticesPair;
00092       verticesPair[0] = std::min(v0,v1);
00093       verticesPair[1] = std::max(v0,v1);
00094 
00095       typename SortedEdgeSet::iterator iedge = sortedEdgeSet.find(verticesPair);
00096       if (iedge == sortedEdgeSet.end()) {
00097         EdgeDOFNumbers dofNumbers;
00098         for (size_t j=0; j<FiniteElementType::numberOfEdgeDegreesOfFreedom; ++j) {
00099           numberOfUsedDOF++;
00100           dofNumbers[j]=numberOfUsedDOF;
00101         }
00102         
00103         iedge = sortedEdgeSet.insert(iedge,std::make_pair(verticesPair, dofNumbers));
00104       }
00105       for (size_t j=0; j<FiniteElementType::numberOfEdgeDegreesOfFreedom; ++j) {
00106         correspondance[dofPositionNumber] = iedge->second[j];
00107         dofPositionNumber++;
00108       }
00109     }
00110   }
00111 
00112   // faces dof management
00113   if (FiniteElementType::numberOfFaceDegreesOfFreedom > 0) {
00114     ASSERT(mesh.hasFaces());
00115 
00116     typedef TinyVector<MeshType::FaceType::NumberOfVertices,size_t> VerticesList;
00117 
00118     typedef
00119       typename ItemTraits<FiniteElementType::numberOfFaceDegreesOfFreedom>::DOFList
00120       FaceDOFNumbers;
00121 
00122     typedef std::map<VerticesList, FaceDOFNumbers> SortedFaceSet;
00123     SortedFaceSet sortedFaceSet;
00124 
00125     for (size_t i=0; i<mesh.numberOfFaces(); ++i) {
00126       const typename MeshType::FaceType& face = mesh.face(i);
00127       std::set<size_t> verticesSet;
00128 
00129       for (size_t j=0; j<MeshType::FaceType::NumberOfVertices; ++j) {
00130         verticesSet.insert(verticesCorrespondance[mesh.vertexNumber(face(j))]);
00131       }
00132       VerticesList verticesList;
00133       {
00134         size_t j=0;
00135         for (std::set<size_t>::const_iterator k = verticesSet.begin();
00136              k != verticesSet.end(); ++k, ++j) {
00137           verticesList[j] = *k;
00138         }
00139       }
00140 
00141       typename SortedFaceSet::iterator iface = sortedFaceSet.find(verticesList);
00142       if (iface == sortedFaceSet.end()) {
00143         FaceDOFNumbers dofNumbers;
00144         for (size_t j=0; j<FiniteElementType::numberOfFaceDegreesOfFreedom; ++j) {
00145           numberOfUsedDOF++;
00146           dofNumbers[j]=numberOfUsedDOF;
00147         }
00148         
00149         iface = sortedFaceSet.insert(iface,std::make_pair(verticesList, dofNumbers));
00150       }
00151       for (size_t j=0; j<FiniteElementType::numberOfFaceDegreesOfFreedom; ++j) {
00152         correspondance[dofPositionNumber] = iface->second[j];
00153         dofPositionNumber++;
00154       }
00155     }
00156   }
00157 
00158   // cell dof management
00159   if (FiniteElementType::numberOfVolumeDegreesOfFreedom > 0) {
00160     for (size_t i=0;i<mesh.numberOfCells(); ++i) {
00161       for (size_t j=0;j<FiniteElementType::numberOfVolumeDegreesOfFreedom; ++j) {
00162         correspondance[dofPositionNumber] = numberOfUsedDOF;
00163         dofPositionNumber++;
00164         numberOfUsedDOF++;
00165       }
00166     }
00167   }
00168   return numberOfUsedDOF+1;
00169 }

template<typename MeshType>
void DegreeOfFreedomSetBuilder::__buildCorrespondance ( const MeshType &  mesh,
const DiscretizationType discretization,
DegreeOfFreedomSet::Correspondance correspondance 
) [inline, private]

Builds the degrees of freedom correspondance vector according to the mesh type and the discretization

Parameters:
mesh the non-abstract mesh
discretization the discretization type
correspondance correspondance table

Definition at line 173 of file DegreeOfFreedomSetBuilder.cpp.

References __dofPositionSet, ScalarDiscretizationTypeBase::lagrangianFEM1, ScalarDiscretizationTypeBase::lagrangianFEM2, Vector< T >::size(), and ErrorHandler::unexpected.

Referenced by DegreeOfFreedomSetBuilder().

00176 {
00177   if (not mesh.isPeriodic()) {
00178     for (size_t i=0; i<correspondance.size(); ++i) {
00179       correspondance[i]=i;
00180     }
00181     return;
00182   }
00183 
00184   typedef typename MeshType::CellType CellType;
00185 
00186   switch (discretization[0].type()) {
00187   case ScalarDiscretizationTypeBase::lagrangianFEM1: {
00188     typedef
00189       typename FiniteElementTraits<CellType,
00190       ScalarDiscretizationTypeBase::lagrangianFEM1>::Type
00191       FiniteElementType;
00192 
00193     this->__buildFEMCorrespondance<MeshType,FiniteElementType>(mesh,correspondance);
00194     break;
00195   }
00196   case ScalarDiscretizationTypeBase::lagrangianFEM2: {
00197     typedef
00198       typename FiniteElementTraits<CellType,
00199       ScalarDiscretizationTypeBase::lagrangianFEM2>::Type
00200       FiniteElementType;
00201 
00202     this->__buildFEMCorrespondance<MeshType,FiniteElementType>(mesh,correspondance);
00203     break;
00204   }
00205   default: {
00206     throw ErrorHandler(__FILE__,__LINE__,
00207                        "not implemented",
00208                        ErrorHandler::unexpected);
00209   }
00210   }
00211 
00212   {
00213 #warning this only works for Pk-Pk elements
00214     size_t offset = 0;
00215     for (size_t i=1; i<__dofPositionSet->number(); ++i) {
00216       offset += (*__dofPositionSet)[i-1].number();
00217       for (size_t j=0; j<(*__dofPositionSet)[i].number(); ++j) {
00218         correspondance[j+offset] = correspondance[j]+offset;
00219       }
00220     }
00221   }
00222 }

Here is the call graph for this function:

template<typename MeshType, typename FiniteElementType>
void DegreeOfFreedomSetBuilder::__buildFEMFictitious ( const size_t &  numberOfVariables,
const MeshType &  mesh,
const Domain domain 
) [inline, private]

Builds the degrees of freedom set for non abstract mesh classes in the case of fictitious domain methods for a particular FEM

Parameters:
numberOfVariables the number of variables
mesh the non-abstract mesh
domain the computational domain

Definition at line 227 of file DegreeOfFreedomSetBuilder.cpp.

References __degreeOfFreedomSet, __dofPositionSet, Domain::inside(), ScalarDegreeOfFreedomPositionsSet::number(), Vector< T >::number(), and ScalarDegreeOfFreedomPositionsSet::vertex().

00230 {
00231   typedef DegreeOfFreedomSet::Correspondance Correspondance;
00232 
00233   size_t numberOfCorrespondances = 0;
00234   for (size_t i=0; i<__dofPositionSet->number(); ++i) {
00235     numberOfCorrespondances += (*__dofPositionSet)[i].number();
00236   }
00237 
00238   ReferenceCounting<Correspondance> pCorrespondance
00239     = new Correspondance(numberOfCorrespondances);
00240 
00241   Correspondance& correspondance = *pCorrespondance;
00242 
00243   // ONLY VALID FOR Pk-Pk elements
00244   this->__buildFEMCorrespondance<MeshType,FiniteElementType>(mesh,correspondance);
00245 
00246   {
00247 #warning this only works for Pk-Pk elements
00248     size_t offset = 0;
00249     for (size_t i=1; i<__dofPositionSet->number(); ++i) {
00250       offset += (*__dofPositionSet)[i-1].number();
00251       for (size_t j=0; j<(*__dofPositionSet)[i].number(); ++j) {
00252         correspondance[j+offset] = correspondance[j]+offset;
00253       }
00254     }
00255   }
00256 
00257   Vector<bool> nonFictitiousDOF(numberOfCorrespondances);
00258   nonFictitiousDOF = false;
00259 
00260   {
00261     size_t offset = 0;
00262     for(size_t i=0; i<__dofPositionSet->number(); ++i) {
00263       const ScalarDegreeOfFreedomPositionsSet& scalarDOFPositions = (*__dofPositionSet)[i];
00264       if (i>0) offset += (*__dofPositionSet)[i-1].number();
00265       for (size_t j=0; j<scalarDOFPositions.number(); ++j) {
00266         nonFictitiousDOF[offset+j] = domain.inside(scalarDOFPositions.vertex(j));
00267       }
00268     }
00269   }
00270 
00271   typedef typename MeshType::CellType CellType;
00272 
00273   size_t offset = 0;
00274   for(size_t i=0; i<(*__dofPositionSet).number(); ++i) {
00275     if (i>0) offset += (*__dofPositionSet)[i-1].number();
00276     const ScalarDegreeOfFreedomPositionsSet& scalarDOFPositions = (*__dofPositionSet)[i];
00277     for (size_t j=0; j<mesh.numberOfCells();++j) {
00278       size_t numberIn = 0;
00279       const CellType& C = mesh.cell(j);
00280       const size_t cellNumer = mesh.cellNumber(C);
00281       // Computation of the caracteristic function
00282       for (size_t k=0; k<FiniteElementType::numberOfDegreesOfFreedom; ++k) {
00283         numberIn += (nonFictitiousDOF(offset+scalarDOFPositions(cellNumer,k)))?1:0;
00284       }
00285 
00286       // reduction of degrees of freedom
00287       if (numberIn != 0) {
00288         for (size_t k=0; k<FiniteElementType::numberOfDegreesOfFreedom; ++k) {
00289           const size_t n = scalarDOFPositions(cellNumer,k);
00290           nonFictitiousDOF[offset+n] = true;
00291         }
00292       }
00293     }
00294   }
00295 
00296   // numbering correspondant vertices remapping
00297   std::map<size_t, size_t> newVerticesCorrespondance;
00298   for (size_t i=0; i<numberOfCorrespondances; ++i) {
00299     if (nonFictitiousDOF[i]) {
00300       newVerticesCorrespondance[correspondance[i]] = 0;
00301     }
00302   }
00303 
00304   size_t numberOfDLVertices = 0;
00305   for (std::map<size_t, size_t>::iterator i=newVerticesCorrespondance.begin();
00306        i != newVerticesCorrespondance.end(); ++i) {
00307     i->second = numberOfDLVertices++;
00308   }
00309 
00310   ReferenceCounting<Correspondance> pFDMCorrespondance
00311     = new Correspondance(numberOfCorrespondances);
00312 
00313   DegreeOfFreedomSet::Correspondance& fdmCorrespondance = *pFDMCorrespondance;
00314   fdmCorrespondance = -1;
00315 
00316   for(size_t i=0; i<correspondance.size(); ++i) {
00317     if (nonFictitiousDOF[i]) {
00318       fdmCorrespondance[i] = newVerticesCorrespondance[correspondance[i]];
00319     }
00320   }
00321   
00322   __degreeOfFreedomSet
00323     = new DegreeOfFreedomSet(__dofPositionSet,
00324                              pFDMCorrespondance);
00325 }

Here is the call graph for this function:

template<typename MeshType>
void DegreeOfFreedomSetBuilder::__buildFictitious ( const size_t &  numberOfVariables,
const ScalarDiscretizationTypeBase discretization,
const MeshType &  mesh,
const Domain domain 
) [inline, private]

Builds the degrees of freedom set for non abstract mesh classes in the case of fictitious domain methods

Parameters:
numberOfVariables the number of variables
discretization the discretization type
mesh the non-abstract mesh
domain the computational domain

Definition at line 329 of file DegreeOfFreedomSetBuilder.cpp.

References ScalarDiscretizationTypeBase::lagrangianFEM1, ScalarDiscretizationTypeBase::lagrangianFEM2, ScalarDiscretizationTypeBase::type(), and ErrorHandler::unexpected.

Referenced by DegreeOfFreedomSetBuilder().

00333 {
00334   typedef typename MeshType::CellType CellType;
00335 
00336   switch (discretization.type()) {
00337   case ScalarDiscretizationTypeBase::lagrangianFEM1: {
00338     typedef
00339       typename FiniteElementTraits<CellType,
00340       ScalarDiscretizationTypeBase::lagrangianFEM1>::Type
00341       FiniteElementType;
00342 
00343     this->__buildFEMFictitious<MeshType,FiniteElementType>(numberOfVariables,
00344                                                            mesh,
00345                                                            domain);
00346     break;
00347   }
00348   case ScalarDiscretizationTypeBase::lagrangianFEM2: {
00349     typedef
00350       typename FiniteElementTraits<CellType,
00351       ScalarDiscretizationTypeBase::lagrangianFEM2>::Type
00352       FiniteElementType;
00353 
00354     this->__buildFEMFictitious<MeshType,FiniteElementType>(numberOfVariables,
00355                                                            mesh,
00356                                                            domain);
00357     break;
00358   }
00359   default: {
00360     throw ErrorHandler(__FILE__,__LINE__,
00361                        "not implemented",
00362                        ErrorHandler::unexpected);
00363   }
00364   }
00365 }

Here is the call graph for this function:

ConstReferenceCounting<DegreeOfFreedomSet> DegreeOfFreedomSetBuilder::getDegreeOfFreedomSet (  )  const [inline]

Read only access to the degree of freedom set

Returns:
the degree of freedom set

Definition at line 123 of file DegreeOfFreedomSetBuilder.hpp.

References __degreeOfFreedomSet.

00124   {
00125     return __degreeOfFreedomSet;
00126   }

const DegreeOfFreedomSet& DegreeOfFreedomSetBuilder::degreeOfFreedomSet (  )  const [inline]

Read only access to the degree of freedom set

Returns:
the degree of freedom set

Definition at line 133 of file DegreeOfFreedomSetBuilder.hpp.

References __degreeOfFreedomSet.

Referenced by SpectralFEMPreconditioner::Internal::__solveFEM().

00134   {
00135     return *__degreeOfFreedomSet;
00136   }


Member Data Documentation

the degree of freedom set

Definition at line 47 of file DegreeOfFreedomSetBuilder.hpp.

Referenced by __buildFEMFictitious(), degreeOfFreedomSet(), DegreeOfFreedomSetBuilder(), and getDegreeOfFreedomSet().

the list degree of freedom set

Definition at line 50 of file DegreeOfFreedomSetBuilder.hpp.

Referenced by __buildCorrespondance(), __buildFEMFictitious(), and DegreeOfFreedomSetBuilder().


The documentation for this class was generated from the following files:

Generated on Wed Nov 19 00:05:31 2008 for FreeFEM3D (aka ff3d) by  doxygen 1.5.6