38 #ifndef BCMANAGENORMAL_H 39 #define BCMANAGENORMAL_H 41 #include <lifev/core/fem/BCHandler.hpp> 55 template<
typename MatrixType>
128 template<
typename MeshType>
140 template <
typename VectorType>
151 template <
typename VectorType>
162 template <
typename VectorType,
typename MeshType>
182 template<
typename MeshType>
206 template<
typename MeshType>
270 template<
typename MatrixType>
280 template<
typename MatrixType>
291 M_flags (bcManageNormal.M_flags),
298 template<
typename MatrixType>
309 template<
typename MatrixType>
313 if (
this != &bcManageNormal)
316 M_rotationMatrixPtr.reset (
new matrix_Type (*bcManageNormal.M_rotationMatrixPtr) );
317 M_localMapEpetraPtr.reset (
new MapEpetra (*bcManageNormal.M_localMapEpetraPtr) );
318 M_firstTangentPtr.reset (
new VectorEpetra (*bcManageNormal.M_firstTangentPtr) );
319 M_secondTangentPtr.reset (
new VectorEpetra (*bcManageNormal.M_secondTangentPtr) );
320 M_normalPtr.reset (
new VectorEpetra (*bcManageNormal.M_normalPtr) );
321 M_coordPtr.reset (
new VectorEpetra (*bcManageNormal.M_coordPtr) );
324 M_flags = bcManageNormal.M_flags;
334 template<
typename MatrixType>
360 template<
typename MeshType>
370 UInt nbPoints (M_flags.size() + M_givenVersors.size() );
372 std::vector<Int> idList (3 * nbPoints);
378 flagsMap_Type::iterator mapIt;
379 versorsMap_Type::iterator mapIt2;
382 for ( mapIt = M_flags.begin() ; mapIt != M_flags.end(); mapIt++ )
384 idList[i] = (*mapIt).first;
385 idList[i + nbPoints] = (*mapIt).first + M_numDof;
386 idList[i + 2 * nbPoints] = (*mapIt).first + 2 * M_numDof;
389 for ( mapIt2 = M_givenVersors.begin() ; mapIt2 != M_givenVersors.end(); mapIt2++ )
391 idList[i] = (*mapIt2).first;
392 idList[i + nbPoints] = (*mapIt2).first + M_numDof;
393 idList[i + 2 * nbPoints] = (*mapIt2).first + 2 * M_numDof;
397 M_localMapEpetraPtr.reset (
new MapEpetra (-1, 3 * nbPoints, &idList[0], map.commPtr() ) );
402 M_calculateNormals (mesh, dof, currentBdFE);
406 M_calculateCoordinates (mesh);
413 template <
typename VectorType>
421 matrix_Type C (systemMatrix.map(), systemMatrix.meanNumEntries() );
422 M_rotationMatrixPtr->multiply (
false, systemMatrix,
false, C);
425 matrix_Type D (systemMatrix.map(), systemMatrix.meanNumEntries() );
426 C.multiply (
false, *M_rotationMatrixTransposePtr,
false, D);
427 systemMatrix.swapCrsMatrix (D);
430 VectorType c (rightHandSide);
431 M_rotationMatrixPtr->multiply (
false, c, rightHandSide);
436 template <
typename VectorType>
442 matrix_Type C (systemMatrix.map(), systemMatrix.meanNumEntries() );
443 M_rotationMatrixTransposePtr->multiply (
false, systemMatrix,
false, C);
446 matrix_Type D (systemMatrix.map(), systemMatrix.meanNumEntries() );
447 C.multiply (
false, *M_rotationMatrixPtr,
false, D);
448 systemMatrix.swapCrsMatrix (D);
451 VectorType c (rightHandSide);
452 M_rotationMatrixTransposePtr->multiply (
false, c, rightHandSide);
457 template<
typename VectorType,
typename MeshType>
465 VectorType repNormals (normals.map(),
Repeated);
467 for (
UInt iFace = 0; iFace < mesh.numBoundaryFacets(); ++iFace )
471 UInt nDofF = currentBdFE.nbFEDof();
474 for (
UInt icheck = 0; icheck < nDofF; ++icheck)
479 if (M_flags.find (idf) != M_flags.end() )
485 if ( (flag == mesh.boundaryFacet (iFace).markerID() ) || (flag == 0) )
498 (repNormals) [idf] += nx * area;
510 normals = VectorType (repNormals,
Unique);
517 Int NumMyElements = normals.map().map (
Unique)->NumMyElements();
518 std::vector<Int> MyGlobalElements (NumMyElements);
519 normals.map().map (Unique)->MyGlobalElements (& (MyGlobalElements[0]) );
529 id = MyGlobalElements[i];
530 Real nx ( (normals) [id] );
533 norm = std::sqrt ( nx * nx + ny * ny + nz * nz );
534 (normals) [id] /= norm;
541 template<
typename MatrixType>
546 fileName.append (
"_proc");
547 std::ostringstream ossMyPid;
548 ossMyPid << M_localMapEpetraPtr->comm().MyPID();
549 fileName.append ( ossMyPid.str() );
550 fileName.append (
".vtk");
551 std::ofstream file (fileName.c_str() );
556 std::cerr <<
"Error: The file " << fileName <<
" is not opened " << std::endl;
561 Int NumMyElements = M_localMapEpetraPtr->map (Unique)->NumMyElements();
562 std::vector<Int> MyGlobalElements (NumMyElements);
563 M_localMapEpetraPtr->map (Unique)->MyGlobalElements (&MyGlobalElements[0]);
567 file <<
"# vtk DataFile Version 2.0" << std::endl;
568 file <<
"Normal directions" << std::endl;
569 file <<
"ASCII" << std::endl;
572 file <<
"DATASET POLYDATA" << std::endl;
573 file <<
"POINTS " << M_numInvoledDof <<
" float" << std::endl;
579 idof = MyGlobalElements[i];
581 file << (*M_coordPtr) [idof] <<
"\t";
582 file << (*M_coordPtr) [idof + M_numDof] <<
"\t";
583 file << (*M_coordPtr) [idof + 2 * M_numDof] << std::endl;
587 file <<
"POINT_DATA " << M_numInvoledDof << std::endl;
590 file <<
"VECTORS cell_tangent_1 float" << std::endl;
596 idof = MyGlobalElements[i];
598 file << (*M_firstTangentPtr) [idof] <<
"\t";
599 file << (*M_firstTangentPtr) [idof + M_numDof] <<
"\t";
600 file << (*M_firstTangentPtr) [idof + 2 * M_numDof] << std::endl;
604 file <<
"VECTORS cell_tangent_2 float" << std::endl;
610 idof = MyGlobalElements[i];
612 file << (*M_secondTangentPtr) [idof] <<
"\t";
613 file << (*M_secondTangentPtr) [idof + M_numDof] <<
"\t";
614 file << (*M_secondTangentPtr) [idof + 2 * M_numDof] << std::endl;
618 file <<
"VECTORS cell_normals float" << std::endl;
624 idof = MyGlobalElements[i];
626 file << (*M_normalPtr) [idof] <<
"\t";
627 file << (*M_normalPtr) [idof + M_numDof] <<
"\t";
628 file << (*M_normalPtr) [idof + 2 * M_numDof] << std::endl;
642 template<
typename MeshType >
645 M_coordPtr.reset (
new VectorEpetra (*M_localMapEpetraPtr, Unique) );
648 Int NumMyElements = M_localMapEpetraPtr->map (Unique)->NumMyElements();
649 std::vector<Int> MyGlobalElements (NumMyElements);
650 M_localMapEpetraPtr->map (Unique)->MyGlobalElements (&MyGlobalElements[0]);
658 id = MyGlobalElements[i];
660 for (
UInt j (0); j < mesh.pointList.size(); ++j)
662 if (id == mesh.pointList[j].id() )
664 (*M_coordPtr) [id] = mesh.pointList[j].x();
665 (*M_coordPtr) [id + M_numDof] = mesh.pointList[j].y();
666 (*M_coordPtr) [id + 2 * M_numDof] = mesh.pointList[j].z();
667 j = mesh.pointList.size();
673 template<
typename MatrixType>
676 M_flags.insert (std::pair<ID, ID> (idof, flag) );
680 template<
typename MatrixType>
687 M_givenVersors.insert (std::pair<ID, Vector> (idof, n) );
691 template<
typename MeshType>
698 M_normalPtr.reset (
new VectorEpetra (*M_localMapEpetraPtr, Repeated) );
700 computeIntegratedNormals (dof, currentBdFE, *M_normalPtr, mesh);
710 template<
typename MatrixType>
718 Int NumMyElements = M_localMapEpetraPtr->map (Unique)->NumMyElements();
719 std::vector<Int> MyGlobalElements (NumMyElements);
720 M_localMapEpetraPtr->map (Unique)->MyGlobalElements (&MyGlobalElements[0]);
730 id = MyGlobalElements[i];
732 if ( M_givenVersors.find (id) != M_givenVersors.end() )
737 norm = std::sqrt ( nx * nx + ny * ny + nz * nz );
738 (*M_normalPtr) [id] = nx / norm;
739 (*M_normalPtr) [id + M_numDof] = ny / norm;
740 (*M_normalPtr) [id + 2 * M_numDof] = nz / norm;
748 M_givenVersors.clear();
752 template<
typename MatrixType>
760 Int NumMyElements = M_localMapEpetraPtr->map (Unique)->NumMyElements();
761 std::vector<Int> MyGlobalElements (NumMyElements);
762 M_localMapEpetraPtr->map (Unique)->MyGlobalElements (&MyGlobalElements[0]);
765 M_firstTangentPtr.reset (
new VectorEpetra (*M_localMapEpetraPtr, Unique) );
766 (*M_firstTangentPtr) *= 0;
767 M_secondTangentPtr.reset (
new VectorEpetra (*M_localMapEpetraPtr, Unique) );
768 (*M_secondTangentPtr) *= 0;
786 id = MyGlobalElements[i];
794 Real nx ( (*M_normalPtr) [id] );
795 Real ny ( (*M_normalPtr) [id + M_numDof] );
796 Real nz ( (*M_normalPtr) [id + 2 * M_numDof] );
797 Real nxi = std::sqrt (ny * ny + nz * nz);
798 Real nxj = std::sqrt (nx * nx + nz * nz);
799 Real nxk = std::sqrt (nx * nx + ny * ny);
801 if ( (nxi >= nxj) && (nxi >= nxk) )
804 (*M_firstTangentPtr) [id] = 0;
805 (*M_firstTangentPtr) [id + M_numDof] = nz / nxi;
806 (*M_firstTangentPtr) [id + 2 * M_numDof] = -ny / nxi;
809 (*M_secondTangentPtr) [id] = -nxi;
810 (*M_secondTangentPtr) [id + M_numDof] = nx * ny / nxi;
811 (*M_secondTangentPtr) [id + 2 * M_numDof] = nx * nz / nxi;
813 else if ( (nxj >= nxi) && (nxj >= nxk) )
816 (*M_firstTangentPtr) [id] = -nz / nxj;
817 (*M_firstTangentPtr) [id + M_numDof] = 0;
818 (*M_firstTangentPtr) [id + 2 * M_numDof] = nx / nxj;
821 (*M_secondTangentPtr) [id] = nx * ny / nxj;
822 (*M_secondTangentPtr) [id + M_numDof] = -nxj;
823 (*M_secondTangentPtr) [id + 2 * M_numDof] = ny * nz / nxj;
828 (*M_firstTangentPtr) [id] = ny / nxk;
829 (*M_firstTangentPtr) [id + M_numDof] = -nx / nxk;
830 (*M_firstTangentPtr) [id + 2 * M_numDof] = 0;
833 (*M_secondTangentPtr) [id] = nx * nz / nxk;
834 (*M_secondTangentPtr) [id + M_numDof] = ny * nz / nxk;
835 (*M_secondTangentPtr) [id + 2 * M_numDof] = -nxk;
840 template<
typename MatrixType>
844 std::map< ID, std::vector< Real > >::iterator mapIt;
847 M_rotationMatrixPtr.reset (
new matrix_Type (map, 3) );
850 M_rotationMatrixPtr->insertOneDiagonal();
852 static const Int nbRows (3);
853 static const Int nbCols (3);
854 std::vector<Real*> values (nbCols);
856 for (
Int n = 0; n < nbCols; ++n )
858 values[n] =
new Real[nbRows];
859 for (
Int m = 0; m < nbRows; ++m )
865 std::vector<Int> rows;
866 std::vector<Int> cols;
869 Int NumMyElements = M_localMapEpetraPtr->map (Unique)->NumMyElements();
870 std::vector<Int> MyGlobalElements (NumMyElements);
871 M_localMapEpetraPtr->map (Unique)->MyGlobalElements (&MyGlobalElements[0]);
879 id = MyGlobalElements[i];
885 Indices[0] = id + offset;
886 Indices[1] = id +
M_numDof + offset;
887 Indices[2] = id + 2 *
M_numDof + offset;
890 cols.push_back (Indices[0]);
891 cols.push_back (Indices[1]);
892 cols.push_back (Indices[2]);
895 rows.push_back (Indices[0]);
896 rows.push_back (Indices[1]);
897 rows.push_back (Indices[2]);
900 values[0][0] = (*M_firstTangentPtr) [id];
901 values[1][0] = (*M_firstTangentPtr) [id + M_numDof];
902 values[2][0] = (*M_firstTangentPtr) [id + 2 * M_numDof];
905 M_rotationMatrixPtr->addToCoefficient (Indices[0], Indices[0], -1.0);
908 values[0][1] = (*M_secondTangentPtr) [id];
909 values[1][1] = (*M_secondTangentPtr) [id + M_numDof];
910 values[2][1] = (*M_secondTangentPtr) [id + 2 * M_numDof];
913 M_rotationMatrixPtr->addToCoefficient (Indices[1], Indices[1], -1.0);
916 values[0][2] = (*M_normalPtr) [id];
917 values[1][2] = (*M_normalPtr) [id + M_numDof];
918 values[2][2] = (*M_normalPtr) [id + 2 * M_numDof];
921 M_rotationMatrixPtr->addToCoefficient (Indices[2], Indices[2], -1.0);
923 M_rotationMatrixPtr->addToCoefficients (nbCols, nbRows, cols, rows, &values[0]);
926 for (
Int n = 0; n < nbRows; ++n )
931 M_rotationMatrixPtr->globalAssemble();
932 M_rotationMatrixTransposePtr = M_rotationMatrixPtr->transpose();
epetraVectorPtr_type M_secondTangentPtr
Shared pointer to the vector of the second tangents to the domain boundary.
const flag_Type UPDATE_NORMALS(UPDATE_ONLY_NORMALS|UPDATE_ONLY_TANGENTS|UPDATE_ONLY_CELL_NODES)
epetraVectorPtr_type M_firstTangentPtr
Shared pointer to the vector of the first tangents to the domain boundary.
~BCManageNormal()
Destructor.
std::shared_ptr< matrix_Type > matrixPtr_Type
void computeIntegratedNormals(const DOF &dof, CurrentFEManifold ¤tBdFE, VectorType &normals, const MeshType &mesh)
This method computes the normals to the domain boundary.
const Real & y() const
Recovering the node's y-coordinate.
void M_buildRotationMatrix(const MapEpetra &systemMatrixMap, UInt offset=0)
This function builds the rotation matrix for the change the basis.
void M_storeGivenVersors()
Store in *M_normalPtr the versors given by the user.
Real measure() const
Compute the measure of the current element.
const Real & z() const
Recovering the node's z-coordinate.
A class for a finite element on a manifold.
void bcShiftToCartesianCoordSystem(matrix_Type &systemMatrix, VectorType &rightHandSide) const
This function modify the system matrix to apply a change of basis from the local coordinate system gi...
std::map< ID, Vector > versorsMap_Type
bcFlag_Type flag() const
Returns the flag associated to the boundary condition name.
Real vectFct(const Real &t, const Real &x, const Real &y, const Real &z, const ID &component) const
Evaluate the versors' function.
int32_type Int
Generic integer data.
BCManageNormal & operator=(const BCManageNormal &bcManageNormal)
Assignment operator.
UInt M_numInvoledDof
Number of degree of freedom (of one component) involved in boundary conditions.
epetraVectorPtr_type M_coordPtr
Shared coordinates of the point.
void updateInverseJacobian(const UInt &iQuadPt)
void bcShiftToNormalTangentialCoordSystem(matrix_Type &systemMatrix, VectorType &rightHandSide) const
This function modify the system matrix to apply a change of basis from the Cartesian coordinate syste...
BCManageNormal - class for handling normal essential boundary conditions.
std::shared_ptr< VectorEpetra > epetraVectorPtr_type
std::map< ID, ID > flagsMap_Type
matrixPtr_Type M_rotationMatrixTransposePtr
Epetra_Import const & importer()
Getter for the Epetra_Import.
void M_addBoundaryPoint(const ID &dofId, const ID &flag)
Add point to the map of flags.
Real normal(UInt coordinate, UInt quadNode) const
Values of the normal on the quadrature points.
bcMode_Type mode() const
Returns the boundary condition mode.
epetraMapPtr_Type M_localMapEpetraPtr
Shared pointer to the local Map.
const UInt & numTotalDof() const
The total number of Dof.
versorsMap_Type M_givenVersors
Versors that are given by the user.
void build(const MeshType &mesh, const DOF &dof, CurrentFEManifold ¤tBdFE, const MapEpetra &map, UInt offset)
Build the rotation matrix.
void M_calculateNormals(const MeshType &mesh, const DOF &dof, CurrentFEManifold ¤tBdFE)
Calculate the normal vectors.
double Real
Generic real data.
std::shared_ptr< MapEpetra > epetraMapPtr_Type
void M_addVersor(const ID &dofId, const Real &vx, const Real &vy, const Real &vz)
Add point to the map of flags.
flagsMap_Type M_flags
flag of the boundary elements
const flag_Type UPDATE_W_ROOT_DET_METRIC(UPDATE_ONLY_W_ROOT_DET_METRIC|UPDATE_METRIC|UPDATE_ONLY_DET_METRIC)
BCManageNormal()
Empty Constructor.
ID localToGlobalMapByBdFacet(const ID &facetId, const ID &localDof) const
const BCIdentifierBase * operator[](const ID &i) const
Returns a pointer to the (i)-th element of the list of identifiers.
const ID & id() const
Returns the ID of the BCIdentifier.
BCFunctionUDepBase - class that holds the function used for prescribing boundary conditions.
BCManageNormal(BCManageNormal const &bcManageNormal)
Copy constructor.
const UInt nDimensions(NDIM)
BCIdentifierEssential - BCIdentifier for implementing Essential Boundary Conditions.
void M_calculateTangentVectors()
Compute the tangential vectors.
matrixPtr_Type M_rotationMatrixPtr
Shared pointer to the rotation matrix and its transpose.
const Real & x() const
Recovering the node's x-coordinate.
UInt M_numDof
Number of degree of freedom (of one component)
const BCFunctionBase * pointerToFunctor() const
Returns a pointer to the BCFunctionBase object.
epetraVectorPtr_type M_normalPtr
Shared pointer to the vector of the normals to the domain boundary.
void M_calculateCoordinates(const MeshType &mesh)
stores the coordinates of the mesh vertices involved in the normal boundary conditions ...
UInt list_size() const
Returns the size of the identifiers list.
std::vector< std::shared_ptr< BCIdentifierBase > > M_idVector
container for id's when the list is finalized
void exportToParaview(std::string fileName) const
Export in the vtk format the tangential and normal vectors (t1, t2, n) for each DOF on the domain bou...
uint32_type UInt
generic unsigned integer (used mainly for addressing)
void init(const BCBase &boundaryCondition, const Real &time)
Store boundary DOFs id and coordinates related to the boundary conditions.
bool M_dataBuilt
true when there are stored normals