Line |
Branch |
Exec |
Source |
1 |
|
|
// ______ ______ _ _ _____ ______ |
2 |
|
|
// | ____| ____| | (_)/ ____| | ____| |
3 |
|
|
// | |__ | |__ | | _| (___ ___| |__ |
4 |
|
|
// | __| | __| | | | |\___ \ / __| __| |
5 |
|
|
// | | | |____| |____| |____) | (__| |____ |
6 |
|
|
// |_| |______|______|_|_____/ \___|______| |
7 |
|
|
// Finite Elements for Life Sciences and Engineering |
8 |
|
|
// |
9 |
|
|
// License: LGL2.1 License |
10 |
|
|
// FELiScE default license: LICENSE in root folder |
11 |
|
|
// |
12 |
|
|
// Main authors: J. Foulon & J-F. Gerbeau |
13 |
|
|
// |
14 |
|
|
|
15 |
|
|
#ifndef __DOFBOUNDARY_HPP__ |
16 |
|
|
#define __DOFBOUNDARY_HPP__ |
17 |
|
|
|
18 |
|
|
// System includes |
19 |
|
|
|
20 |
|
|
// External includes |
21 |
|
|
|
22 |
|
|
// Project includes |
23 |
|
|
#include "Core/NoThirdPartyWarning/Petsc/ao.hpp" |
24 |
|
|
#include "DegreeOfFreedom/dof.hpp" |
25 |
|
|
#include "PETScInterface/petscMatrix.hpp" |
26 |
|
|
#include "PETScInterface/petscVector.hpp" |
27 |
|
|
|
28 |
|
|
namespace felisce |
29 |
|
|
{ |
30 |
|
|
//forward declaration |
31 |
|
|
class LinearProblem; |
32 |
|
|
// class PetscMatrix; |
33 |
|
|
/*! \class DofBoundary |
34 |
|
|
\author M.Aletti |
35 |
|
|
\date 2015 |
36 |
|
|
|
37 |
|
|
DofBoundary contains several tools to: |
38 |
|
|
- list the dofs at the interface in order to create a one to one mapping within two different linear problems that share a common interface. |
39 |
|
|
- create a new ordering (local, application and petsc) to describe dofs at the interface in order to define matrices and vectors therein. |
40 |
|
|
- mappings to associate dofs on the boundary to the corresponding ones on the volume. |
41 |
|
|
- it also creates a subcommunicator where procs are divided into two separate groups: those who have at least one dof on the boundary and those who don't. |
42 |
|
|
*/ |
43 |
|
|
class DofBoundary { |
44 |
|
|
|
45 |
|
|
public: |
46 |
|
|
/// Two types of PetsVec, to improve readibility |
47 |
|
|
enum vectorType { sequential, ///< Sequential vectors |
48 |
|
|
parallel ///< Parallel vectors |
49 |
|
|
}; |
50 |
|
|
|
51 |
|
|
//=============== |
52 |
|
|
// INITIALIZATION METHODS AND DATA MEMBERS |
53 |
|
|
//============== |
54 |
|
|
public: |
55 |
|
|
DofBoundary(); |
56 |
|
|
void initialize( LinearProblem* lpb_ptr ); |
57 |
|
|
//! it fills the interface mappings in. |
58 |
|
|
void buildBoundaryVolumeMapping(int iUnknown, int iComponent ); |
59 |
|
|
void buildBoundaryVolumeMapping(int iUnknown, std::vector<int> components ); |
60 |
|
|
/*! |
61 |
|
|
@{ \name General information taken from LinearProblem |
62 |
|
|
*/ |
63 |
|
|
private: |
64 |
|
|
Dof* m_dofPtr; //!< Pointer to m_dof of LinearProblem. |
65 |
|
|
AO m_ao; //!< The ApplicationOrdering of LinearProblem. |
66 |
|
|
std::vector < int > *m_dofPartPtr; //!< |
67 |
|
|
/*!@}*/ |
68 |
|
|
public: |
69 |
|
|
//! it fills m_boundaryPattern in, taking the pattern from the volume matrix pattern. |
70 |
|
|
void buildBoundaryPattern(); |
71 |
|
|
//! it allocates a matrix on the boundary using the boundary pattern. |
72 |
|
|
void allocateMatrixOnBoundary( PetscMatrix& theMatrix ); |
73 |
|
|
|
74 |
|
|
/** |
75 |
|
|
* @brief it allocates a vector on the boundary |
76 |
|
|
* Note that it is necessary to pass v as a reference since the allocation is done at this time and therefore even the pointer is changed. |
77 |
|
|
* The vector is allocated only if you actually have some dofs on the boundary. |
78 |
|
|
*/ |
79 |
|
|
PetscVector allocateBoundaryVector(vectorType type); |
80 |
|
|
|
81 |
|
|
/** |
82 |
|
|
* @brief It restricts a volume std::vector to a PARALLEL boundary vector |
83 |
|
|
* @param[in] volumeVector, parallel or sequential vector defined on the volume |
84 |
|
|
* @param[out] parallelBoundaryVector, a std::vector defined on the boundary |
85 |
|
|
* Given a vector on the volume the value on the boundary of the domain are read and written |
86 |
|
|
* on a smaller vector defined only on the boundary |
87 |
|
|
*/ |
88 |
|
|
void restrictOnBoundary(PetscVector& volume, PetscVector& boundary); |
89 |
|
|
|
90 |
|
|
/** |
91 |
|
|
* @brief It provides the extension of a boundary vector to a PARALLEL volume vector |
92 |
|
|
* @param[in] boundaryVector parallel or serial vector defined on the boundary. |
93 |
|
|
* @param[out] parallelVolumeVector a parallel vector defined on the volume. |
94 |
|
|
* Given a (sequential or parallel) vector defined on the boundary. |
95 |
|
|
* The function extends it to a PARALLEL volume vector. The function leaves untouched the value corresponing to the volume dofs. |
96 |
|
|
* Then outside the function you can do a gather, no need to call assembly on the volume vector out of this function. |
97 |
|
|
*/ |
98 |
|
|
void extendOnVolume(PetscVector& volume, PetscVector& boundary); |
99 |
|
|
|
100 |
|
|
// it builds some maps: |
101 |
|
|
// These maps are global with respect to the different processors. |
102 |
|
|
// |
103 |
|
|
// m_listOfBoundaryPetscDofs: it depends on iVar and iComp |
104 |
|
|
// l = label of a region of the interface |--> map_l: |
105 |
|
|
// i \in (0, numDofOfThisLabel) |--> idDofInPetscOrdering_i |
106 |
|
|
// m_mapLab2FirstPoint: /* it does not really depend on nothing, but the geometry */ |
107 |
|
|
// l = label of a region of the interface |--> point, 3D coordinates of the first point |
108 |
|
|
// |
109 |
|
|
// m_mapLab2AllPoints: /* no matter which iVar and which iComp, the ordering will be the same! */ |
110 |
|
|
// l = label of a region of the interface |--> std::vector containing all the points in the same order as in m_listOfBoundaryPetscDofs |
111 |
|
|
// |
112 |
|
|
void buildListOfBoundaryPetscDofs(LinearProblem* lpb_ptr, std::vector<int> labelOfInterface, int iUnknown, int iComponent); |
113 |
|
|
|
114 |
|
|
/*! |
115 |
|
|
@{ \name Getters |
116 |
|
|
*/ |
117 |
|
|
// =================== |
118 |
|
|
// GETTERS |
119 |
|
|
// =================== |
120 |
|
|
public: |
121 |
|
|
//! Number of local dofs on the interface. |
122 |
|
1908 |
inline std::size_t numLocalDofInterface() const { return m_numLocalDofInterface; } |
123 |
|
|
//! Number of local dofs on the interface. |
124 |
|
644 |
inline std::size_t numGlobalDofInterface() const { return m_numGlobalDofInterface; } |
125 |
|
|
//! Application ordering std::unordered_map for the interface. |
126 |
|
324 |
inline AO ao() const { return m_aoInterface; } |
127 |
|
|
//! Boundary communicator. |
128 |
|
632 |
inline MPI_Comm comm() const { return m_boundaryComm; } |
129 |
|
|
//! true if the current processor has at least one of its dofs on the boundary |
130 |
|
1116 |
inline bool hasDofsOnBoundary() const { return ( m_numLocalDofInterface > 0 ); } |
131 |
|
|
/*! \brief given the idUnkComp, the label and the id, it returns the dof id in the petsc volume ordering |
132 |
|
|
|
133 |
|
|
\param[in] idUnkComp the composed id that denotes both the unknown and the component |
134 |
|
|
\param[in] bdLabel the label of the portion of the boundary we are looking at |
135 |
|
|
\param[in] id the id of the dofTODO: in which ordering?? |
136 |
|
|
\return id of the dof in the petsc volume ordering |
137 |
|
|
*/ |
138 |
|
37584 |
inline felInt getPetscDofs( felInt idUnkComp, felInt bdLabel, felInt id ) const { return m_listOfBoundaryPetscDofs.at(idUnkComp).at(bdLabel).at(id); } |
139 |
|
|
/*! \brief given the unknown index and the component it returns a mapping that, for each label, contains the list of ids in petsc volume ordering |
140 |
|
|
\param[in] iUnknown id of the unknown |
141 |
|
|
\param[in] iComponent number of the component |
142 |
|
|
\return a std::unordered_map from a label of a portion of the boundary to a std::unordered_map which in fact is a list of ids petsc volume ordering |
143 |
|
|
*/ |
144 |
1/2
✓ Branch 2 taken 464 times.
✗ Branch 3 not taken.
|
464 |
inline const std::map<int,std::map<int,int> >& listOfBoundaryPetscDofs( int iUnknown, int iComponent ) const { return m_listOfBoundaryPetscDofs.at(m_dofPtr->getNumGlobComp(iUnknown,iComponent)); } |
145 |
|
✗ |
inline const std::map<int, std::map<int, std::map<int, int > > > listOfBoundaryPetscDofs() const { return m_listOfBoundaryPetscDofs;} |
146 |
|
|
//! function returning a pointer to the starting point of #m_loc2PetscVolume |
147 |
|
636 |
inline const felInt* loc2PetscVolPtr() const { return &m_loc2PetscVolume[0]; } |
148 |
|
|
//! function returning a pointer to the starting point of #m_loc2PetscInterface |
149 |
|
636 |
inline const felInt* loc2PetscBDPtr() const { return &m_loc2PetscInterface[0]; } |
150 |
|
|
//! function returning a pointer to the starting point of #m_glob2PetscVolume |
151 |
|
✗ |
inline const felInt* glob2PetscVolPtr() const { return &m_glob2PetscVolume[0]; } |
152 |
|
|
//! given an index in the petsc volume ordering it returns the correspoding index in the application boundary ordering |
153 |
|
✗ |
inline felInt petscVol2ApplicationBD( int id ) const { return m_petscVolume2Glob.at(id) ; } |
154 |
|
|
//! given an index in the application boundary ordering it returns the coresponding index in the petsc volume ordering |
155 |
|
324 |
inline felInt globBD2PetscVol( int id ) const { return m_glob2PetscVolume[id]; } |
156 |
|
|
//! it returns the mapping associating each label its first point |
157 |
|
8 |
inline const std::map<int, Point >& getMapLab2FirstPoint() const { return m_mapLab2FirstPoint; } |
158 |
|
|
//! it returns the mapping associating each label all its points |
159 |
|
8 |
inline const std::map<int, std::vector<Point> > & lab2AllPoints() const { return m_mapLab2AllPoints; } |
160 |
|
|
// It returns the std::vector of std::set of pairs of (PetscVolDof,Point) |
161 |
|
|
inline const std::vector<setOfPairOfIntAndPoint> & localVecOfSet() const { return m_localVecOfSet; } |
162 |
|
|
/*!@}*/ |
163 |
|
|
public: |
164 |
|
|
// =================== |
165 |
|
|
// DEBUG AND PRINTING FUNCTIONS |
166 |
|
|
// =================== |
167 |
|
|
void displayBoundaryVolumeMapping () const; |
168 |
|
|
void exportInterfacePoints( int iUnknown, int iComp ) const; |
169 |
|
|
void BoundaryVolumeMappingForExample() const; |
170 |
|
|
private: |
171 |
|
|
// ==================================================================== |
172 |
|
|
// Number of dofs at interface: local and global |
173 |
|
|
// ==================================================================== |
174 |
|
|
felInt m_numLocalDofInterface; //!< The local number of interface dofs on the interface. |
175 |
|
|
felInt m_numGlobalDofInterface; //!< The local number of interface dofs on the interface. |
176 |
|
|
// ==================================================================== |
177 |
|
|
// mappings from labels to first and all points |
178 |
|
|
// ==================================================================== |
179 |
|
|
std::map<int, Point > m_mapLab2FirstPoint; |
180 |
|
|
std::map<int, std::vector<Point> > m_mapLab2AllPoints; |
181 |
|
|
//! For each label, std::set of (PetscVolDof,Point) |
182 |
|
|
std::vector<setOfPairOfIntAndPoint> m_localVecOfSet; |
183 |
|
|
//! mapping from iUnkComp to a mapping from labels to the petscdofs |
184 |
|
|
std::map<int, std::map<int, std::map<int, int > > > m_listOfBoundaryPetscDofs; |
185 |
|
|
// ==================================================================== |
186 |
|
|
// mappings for the interface |
187 |
|
|
// ==================================================================== |
188 |
|
|
AO m_aoInterface; //! The AO mapping between application ordering and petsc ordering on the interface. |
189 |
|
|
std::vector<felInt> m_loc2GlobInterface ; //! Local ids (0 ,..., #m_numLocalDofInterface - 1) --> global ids in application ordering. |
190 |
|
|
std::vector<felInt> m_loc2PetscInterface; //! Local ids (0 ,..., #m_numLocalDofInterface - 1) --> global ids in interface petsc ordering. |
191 |
|
|
std::vector<felInt> m_glob2PetscVolume; //! Global ids (0 ,..., #m_numGlobDofInterface - 1) --> global ids in the volume in petsc ordering. |
192 |
|
|
std::map<felInt,felInt> m_petscVolume2Glob; //! Inverse of #m_glob2PetscVolume. |
193 |
|
|
std::vector<felInt> m_loc2PetscVolume; /*! Composition of #m_loc2GlobInterface and #m_glob2PetscVolume: #m_glob2PetscVolume[#m_loc2GlobInterface[i]] = #m_loc2PetscVolume. |
194 |
|
|
it lists all the local dofs of the interface in the petsc volume ordering */ |
195 |
|
|
// ==================================================================== |
196 |
|
|
// MPI BOUNDARY COMMUNICATOR |
197 |
|
|
// ==================================================================== |
198 |
|
|
MPI_Comm m_boundaryComm; //!<communicator that contains all the procs in the boarder and the others in two saparete groups. |
199 |
|
|
// ==================================================================== |
200 |
|
|
// PATTERN INFORMATION |
201 |
|
|
// ==================================================================== |
202 |
|
|
CSRMatrixPattern m_boundaryPattern; //!< The patter of a matrix defined on the boundary. |
203 |
|
|
// ========================================== |
204 |
|
|
// BOOLEAN VALUES TO CHECK ERRORS |
205 |
|
|
// ========================================== |
206 |
|
|
bool m_boundaryPatternAlreadyBuilt; |
207 |
|
|
bool m_dofBoundaryHasBeenInitialized; |
208 |
|
|
bool m_volumeInterfaceMappingBuilt; |
209 |
|
|
std::vector<bool> m_dofsHaveBeenComputed; |
210 |
|
|
public: |
211 |
|
|
bool isOnSurface( felInt iUnkComp, felInt petscDof ); |
212 |
|
|
private: |
213 |
|
|
void unRoll(felInt iUnkComp); |
214 |
|
|
std::vector<std::set<felInt> > m_unRolledList; |
215 |
|
|
public: |
216 |
|
|
// ==================================================================== |
217 |
|
|
// SURFACE INTERPOLATOR |
218 |
|
|
// ==================================================================== |
219 |
|
|
void writeSurfaceInterpolatorFile(int iUnknown, int numComp, std::string filename, std::string folder) const; |
220 |
|
|
}; |
221 |
|
|
}//namespace |
222 |
|
|
#endif |
223 |
|
|
|