41 #ifndef STRUCTUREDMESH3D_HPP 42 #define STRUCTUREDMESH3D_HPP 1
44 #include <lifev/core/LifeV.hpp> 45 #include <lifev/core/mesh/RegionMesh.hpp> 46 #include <lifev/core/mesh/MeshChecks.hpp> 125 template <
typename GeoShape,
typename MC>
131 bool verbose =
false,
132 const Real& l_x = 1.0,
133 const Real& l_y = 1.0,
134 const Real& l_z = 1.0,
135 const Real& t_x = 0.0,
136 const Real& t_y = 0.0,
137 const Real& t_z = 0.0
141 std::stringstream discardedLog;
142 std::ostream& oStr = verbose ? std::cout : discardedLog;
145 Real dx ( l_x / m_x );
146 Real dy ( l_y / m_y );
147 Real dz ( l_z / m_z );
150 UInt n_x ( m_x + 1 );
151 UInt n_y ( m_y + 1 );
152 UInt n_z ( m_z + 1 );
160 UInt N_z ( n_x * n_y );
165 UInt mid_x ( m_x / 2 );
166 UInt mid_y ( m_y / 2 );
167 UInt mid_z ( m_z / 2 );
170 UInt verticesNumber ( n_x * n_y * n_z );
171 UInt boundaryVerticesNumber ( verticesNumber - ( n_x - 2 ) * ( n_y - 2 ) * ( n_z - 2 ) );
172 UInt boundaryEdgesNumber (
173 2 * ( m_x * ( n_y - 2 ) + m_y * ( n_x - 2 ) + m_x * m_y ) +
174 2 * ( m_x * ( n_z - 2 ) + m_z * ( n_x - 2 ) + m_x * m_z ) +
175 2 * ( m_y * ( n_z - 2 ) + m_z * ( n_y - 2 ) + m_y * m_z ) +
176 4 * ( m_x + m_y + m_z )
190 UInt boundaryFacesNumber ( 2 * 2 * ( m_x * m_y + m_y * m_z + m_x * m_z ) );
192 UInt facesNumber ( ( m_x * m_y * m_z * 12 + boundaryFacesNumber ) / 2 + 6 * m_x * m_y * m_z );
193 UInt volumesNumber ( m_x * m_y * m_z * 6 );
195 UInt pointsNumber ( 0 );
196 UInt boundaryPointsNumber ( 0 );
197 if ( GeoShape::S_numPoints > 4 )
199 oStr <<
"Quadratic Tetra Mesh ( from Linear geometry )" << std::endl;
201 pointsNumber = verticesNumber + edgesNumber;
202 boundaryPointsNumber = boundaryVerticesNumber + boundaryEdgesNumber;
206 oStr <<
"Linear Tetra Mesh" << std::endl;
207 pointsNumber = verticesNumber;
208 boundaryPointsNumber = boundaryVerticesNumber;
212 oStr <<
"initialization of mesh...";
219 mesh.setNumBPoints ( boundaryPointsNumber );
220 mesh.setMaxNumPoints ( pointsNumber,
true );
221 mesh.setMaxNumGlobalPoints ( pointsNumber );
224 mesh.setNumVertices ( verticesNumber );
225 mesh.setNumGlobalVertices ( verticesNumber );
226 mesh.setNumBVertices ( boundaryVerticesNumber );
230 mesh.setNumEdges ( edgesNumber );
231 mesh.setNumBEdges ( boundaryEdgesNumber );
233 mesh.setMaxNumEdges ( boundaryEdgesNumber );
234 mesh.setMaxNumGlobalEdges ( edgesNumber );
237 mesh.setNumFaces ( facesNumber );
238 mesh.setNumBFaces ( boundaryFacesNumber );
240 mesh.setMaxNumFaces ( boundaryFacesNumber );
241 mesh.setMaxNumGlobalFaces ( boundaryFacesNumber );
244 mesh.setMaxNumVolumes ( volumesNumber,
true );
245 mesh.setMaxNumGlobalVolumes ( volumesNumber );
247 mesh.setMarkerID ( regionFlag );
248 oStr <<
"done" << std::endl;
251 typename RegionMesh<GeoShape, MC>::point_Type* pointPtr = 0;
253 typename RegionMesh<GeoShape, MC>::face_Type* facePtr = 0;
254 typename RegionMesh<GeoShape, MC>::volume_Type* volumePtr = 0;
257 oStr <<
"building the points of the mesh...";
258 Real xPosition ( 0.0 ), yPosition ( 0.0 ), zPosition ( 0.0 );
261 UInt P0 ( 0 ), P1 ( 0 ), P2 ( 0 ), P3 ( 0 ), P4 ( 0 ), P5 ( 0 ), P6 ( 0 ), P7 ( 0 );
263 for (
UInt k (0); k < n_z; ++k )
267 for (
UInt j (0); j < n_y; ++j )
271 for (
UInt i (0); i < n_x; ++i )
277 pointPtr = &mesh.addPoint ( nodeMarkerID > 0,
true );
280 nodeID = k * N_z + j * N_y + i;
281 pointPtr->setId ( nodeID );
283 pointPtr->setMarkerID ( nodeMarkerID );
284 pointPtr->x() = xPosition + t_x;
285 pointPtr->y() = yPosition + t_y;
286 pointPtr->z() = zPosition + t_z;
290 oStr <<
"done" << std::endl;
578 oStr <<
"building the boundary faces...";
581 for (
UInt j (0); j < m_y; ++j )
583 for (
UInt i (0); i < m_x; ++i )
597 if ( ( i < mid_x && j < mid_y ) || ( i >= mid_x && j >= mid_y ) )
600 facePtr = &mesh.addFace (
true );
601 facePtr->setMarkerID (5);
602 facePtr->setId ( faceCount++ );
603 facePtr->setPoint ( 0, mesh.point (P0) );
604 facePtr->setPoint ( 1, mesh.point (P3) );
605 facePtr->setPoint ( 2, mesh.point (P1) );
608 facePtr = &mesh.addFace (
true );
609 facePtr->setMarkerID (5);
610 facePtr->setId ( faceCount++ );
611 facePtr->setPoint ( 0, mesh.point (P0) );
612 facePtr->setPoint ( 1, mesh.point (P2) );
613 facePtr->setPoint ( 2, mesh.point (P3) );
618 facePtr = &mesh.addFace (
true );
619 facePtr->setMarkerID (5);
620 facePtr->setId ( faceCount++ );
621 facePtr->setPoint ( 0, mesh.point (P0) );
622 facePtr->setPoint ( 1, mesh.point (P2) );
623 facePtr->setPoint ( 2, mesh.point (P1) );
626 facePtr = &mesh.addFace (
true );
627 facePtr->setMarkerID (5);
628 facePtr->setId ( faceCount++ );
629 facePtr->setPoint ( 0, mesh.point (P1) );
630 facePtr->setPoint ( 1, mesh.point (P2) );
631 facePtr->setPoint ( 2, mesh.point (P3) );
641 P0 += N_z * ( n_z - 1 );
646 if ( ( i < mid_x && j < mid_y ) || ( i >= mid_x && j >= mid_y ) )
649 facePtr = &mesh.addFace (
true );
650 facePtr->setMarkerID (6);
651 facePtr->setId ( faceCount++ );
652 facePtr->setPoint ( 0, mesh.point (P0) );
653 facePtr->setPoint ( 1, mesh.point (P1) );
654 facePtr->setPoint ( 2, mesh.point (P3) );
657 facePtr = &mesh.addFace (
true );
658 facePtr->setMarkerID (6);
659 facePtr->setId ( faceCount++ );
660 facePtr->setPoint ( 0, mesh.point (P0) );
661 facePtr->setPoint ( 1, mesh.point (P3) );
662 facePtr->setPoint ( 2, mesh.point (P2) );
667 facePtr = &mesh.addFace (
true );
668 facePtr->setMarkerID (6);
669 facePtr->setId ( faceCount++ );
670 facePtr->setPoint ( 0, mesh.point (P0) );
671 facePtr->setPoint ( 1, mesh.point (P1) );
672 facePtr->setPoint ( 2, mesh.point (P2) );
675 facePtr = &mesh.addFace (
true );
676 facePtr->setMarkerID (6);
677 facePtr->setId ( faceCount++ );
678 facePtr->setPoint ( 0, mesh.point (P1) );
679 facePtr->setPoint ( 1, mesh.point (P3) );
680 facePtr->setPoint ( 2, mesh.point (P2) );
685 for (
UInt j (0); j < m_z; ++j )
687 for (
UInt i (0); i < m_x; ++i )
699 if ( ( i < mid_x && j < mid_z ) || ( i >= mid_x && j >= mid_z ) )
702 facePtr = &mesh.addFace (
true );
703 facePtr->setMarkerID (1);
704 facePtr->setId ( faceCount++ );
705 facePtr->setPoint ( 0, mesh.point (P0) );
706 facePtr->setPoint ( 1, mesh.point (P1) );
707 facePtr->setPoint ( 2, mesh.point (P3) );
710 facePtr = &mesh.addFace (
true );
711 facePtr->setMarkerID (1);
712 facePtr->setId ( faceCount++ );
713 facePtr->setPoint ( 0, mesh.point (P0) );
714 facePtr->setPoint ( 1, mesh.point (P3) );
715 facePtr->setPoint ( 2, mesh.point (P2) );
720 facePtr = &mesh.addFace (
true );
721 facePtr->setMarkerID (1);
722 facePtr->setId ( faceCount++ );
723 facePtr->setPoint ( 0, mesh.point (P0) );
724 facePtr->setPoint ( 1, mesh.point (P1) );
725 facePtr->setPoint ( 2, mesh.point (P2) );
728 facePtr = &mesh.addFace (
true );
729 facePtr->setMarkerID (1);
730 facePtr->setId ( faceCount++ );
731 facePtr->setPoint ( 0, mesh.point (P1) );
732 facePtr->setPoint ( 1, mesh.point (P3) );
733 facePtr->setPoint ( 2, mesh.point (P2) );
741 P0 += N_y * ( n_y - 1 );
746 if ( ( i < mid_x && j < mid_z ) || ( i >= mid_x && j >= mid_z ) )
749 facePtr = &mesh.addFace (
true );
750 facePtr->setMarkerID (3);
751 facePtr->setId ( faceCount++ );
752 facePtr->setPoint ( 0, mesh.point (P0) );
753 facePtr->setPoint ( 1, mesh.point (P2) );
754 facePtr->setPoint ( 2, mesh.point (P3) );
757 facePtr = &mesh.addFace (
true );
758 facePtr->setMarkerID (3);
759 facePtr->setId ( faceCount++ );
760 facePtr->setPoint ( 0, mesh.point (P0) );
761 facePtr->setPoint ( 1, mesh.point (P3) );
762 facePtr->setPoint ( 2, mesh.point (P1) );
767 facePtr = &mesh.addFace (
true );
768 facePtr->setMarkerID (3);
769 facePtr->setId ( faceCount++ );
770 facePtr->setPoint ( 0, mesh.point (P0) );
771 facePtr->setPoint ( 1, mesh.point (P2) );
772 facePtr->setPoint ( 2, mesh.point (P1) );
775 facePtr = &mesh.addFace (
true );
776 facePtr->setMarkerID (3);
777 facePtr->setId ( faceCount++ );
778 facePtr->setPoint ( 0, mesh.point (P1) );
779 facePtr->setPoint ( 1, mesh.point (P2) );
780 facePtr->setPoint ( 2, mesh.point (P3) );
785 for (
UInt j (0); j < m_z; ++j )
787 for (
UInt i (0); i < m_y; ++i )
796 P0 = j * N_z + i * N_y;
801 if ( ( i < mid_y && j < mid_z ) || ( i >= mid_y && j >= mid_z ) )
804 facePtr = &mesh.addFace (
true );
805 facePtr->setMarkerID (4);
806 facePtr->setId ( faceCount++ );
807 facePtr->setPoint ( 0, mesh.point (P0) );
808 facePtr->setPoint ( 1, mesh.point (P2) );
809 facePtr->setPoint ( 2, mesh.point (P3) );
812 facePtr = &mesh.addFace (
true );
813 facePtr->setMarkerID (4);
814 facePtr->setId ( faceCount++ );
815 facePtr->setPoint ( 0, mesh.point (P0) );
816 facePtr->setPoint ( 1, mesh.point (P3) );
817 facePtr->setPoint ( 2, mesh.point (P1) );
822 facePtr = &mesh.addFace (
true );
823 facePtr->setMarkerID (4);
824 facePtr->setId ( faceCount++ );
825 facePtr->setPoint ( 0, mesh.point (P0) );
826 facePtr->setPoint ( 1, mesh.point (P2) );
827 facePtr->setPoint ( 2, mesh.point (P1) );
830 facePtr = &mesh.addFace (
true );
831 facePtr->setMarkerID (4);
832 facePtr->setId ( faceCount++ );
833 facePtr->setPoint ( 0, mesh.point (P1) );
834 facePtr->setPoint ( 1, mesh.point (P2) );
835 facePtr->setPoint ( 2, mesh.point (P3) );
845 P0 += N_x * ( n_x - 1 );
850 if ( ( i < mid_y && j < mid_z ) || ( i >= mid_y && j >= mid_z ) )
853 facePtr = &mesh.addFace (
true );
854 facePtr->setMarkerID (2);
855 facePtr->setId ( faceCount++ );
856 facePtr->setPoint ( 0, mesh.point (P0) );
857 facePtr->setPoint ( 1, mesh.point (P3) );
858 facePtr->setPoint ( 2, mesh.point (P2) );
861 facePtr = &mesh.addFace (
true );
862 facePtr->setMarkerID (2);
863 facePtr->setId ( faceCount++ );
864 facePtr->setPoint ( 0, mesh.point (P0) );
865 facePtr->setPoint ( 1, mesh.point (P1) );
866 facePtr->setPoint ( 2, mesh.point (P3) );
871 facePtr = &mesh.addFace (
true );
872 facePtr->setMarkerID (2);
873 facePtr->setId ( faceCount++ );
874 facePtr->setPoint ( 0, mesh.point (P0) );
875 facePtr->setPoint ( 1, mesh.point (P1) );
876 facePtr->setPoint ( 2, mesh.point (P2) );
879 facePtr = &mesh.addFace (
true );
880 facePtr->setMarkerID (2);
881 facePtr->setId ( faceCount++ );
882 facePtr->setPoint ( 0, mesh.point (P1) );
883 facePtr->setPoint ( 1, mesh.point (P3) );
884 facePtr->setPoint ( 2, mesh.point (P2) );
888 oStr <<
"done" << std::endl;
891 oStr <<
"building the volumes...";
893 for (
UInt k (0); k < m_z; ++k )
895 for (
UInt j (0); j < m_y; ++j )
897 for (
UInt i (0); i < m_x; ++i )
899 volumeID = ( k * m_y * m_x + j * m_x + i ) * 6;
901 if ( ( i + 1 <= mid_x && j + 1 <= mid_y && k + 1 <= mid_z ) ||
902 ( i + 1 > mid_x && j + 1 > mid_y && k + 1 > mid_z ) )
905 nodeID = k * N_z + j * N_y + i;
909 P7 = nodeID + N_x + N_y;
911 P2 = nodeID + N_x + N_z;
912 P1 = nodeID + N_y + N_z;
913 P3 = nodeID + N_x + N_y + N_z;
915 else if ( ( i + 1 > mid_x && j + 1 <= mid_y && k + 1 <= mid_z ) ||
916 ( i + 1 <= mid_x && j + 1 > mid_y && k + 1 > mid_z ) )
919 nodeID = k * N_z + j * N_y + i;
923 P2 = nodeID + N_x + N_y;
925 P7 = nodeID + N_x + N_z;
926 P4 = nodeID + N_y + N_z;
927 P6 = nodeID + N_x + N_y + N_z;
929 else if ( ( i + 1 <= mid_x && j + 1 > mid_y && k + 1 <= mid_z ) ||
930 ( i + 1 > mid_x && j + 1 <= mid_y && k + 1 > mid_z ) )
933 nodeID = k * N_z + j * N_y + i;
937 P1 = nodeID + N_x + N_y;
939 P4 = nodeID + N_x + N_z;
940 P7 = nodeID + N_y + N_z;
941 P5 = nodeID + N_x + N_y + N_z;
943 else if ( ( i + 1 <= mid_x && j + 1 <= mid_y && k + 1 > mid_z ) ||
944 ( i + 1 > mid_x && j + 1 > mid_y && k + 1 <= mid_z ) )
947 nodeID = k * N_z + j * N_y + i;
951 P3 = nodeID + N_x + N_y;
953 P5 = nodeID + N_x + N_z;
954 P6 = nodeID + N_y + N_z;
955 P7 = nodeID + N_x + N_y + N_z;
959 volumePtr = &mesh.addVolume();
960 volumePtr->setId ( volumeID );
961 volumePtr->setPoint ( 0, mesh.point (P0) );
962 volumePtr->setPoint ( 1, mesh.point (P1) );
963 volumePtr->setPoint ( 2, mesh.point (P3) );
964 volumePtr->setPoint ( 3, mesh.point (P4) );
965 volumePtr->setMarkerID ( regionFlag );
968 volumePtr = &mesh.addVolume();
969 volumePtr->setId ( volumeID + 1 );
970 volumePtr->setPoint ( 0, mesh.point (P1) );
971 volumePtr->setPoint ( 1, mesh.point (P3) );
972 volumePtr->setPoint ( 2, mesh.point (P4) );
973 volumePtr->setPoint ( 3, mesh.point (P5) );
974 volumePtr->setMarkerID ( regionFlag );
977 volumePtr = &mesh.addVolume();
978 volumePtr->setId ( volumeID + 2 );
979 volumePtr->setPoint ( 0, mesh.point (P4) );
980 volumePtr->setPoint ( 1, mesh.point (P5) );
981 volumePtr->setPoint ( 2, mesh.point (P3) );
982 volumePtr->setPoint ( 3, mesh.point (P7) );
983 volumePtr->setMarkerID ( regionFlag );
986 volumePtr = &mesh.addVolume();
987 volumePtr->setId ( volumeID + 3 );
988 volumePtr->setPoint ( 0, mesh.point (P0) );
989 volumePtr->setPoint ( 1, mesh.point (P3) );
990 volumePtr->setPoint ( 2, mesh.point (P2) );
991 volumePtr->setPoint ( 3, mesh.point (P4) );
992 volumePtr->setMarkerID ( regionFlag );
995 volumePtr = &mesh.addVolume();
996 volumePtr->setId ( volumeID + 4 );
997 volumePtr->setPoint ( 0, mesh.point (P6) );
998 volumePtr->setPoint ( 1, mesh.point (P3) );
999 volumePtr->setPoint ( 2, mesh.point (P4) );
1000 volumePtr->setPoint ( 3, mesh.point (P2) );
1001 volumePtr->setMarkerID ( regionFlag );
1004 volumePtr = &mesh.addVolume();
1005 volumePtr->setId (volumeID + 5);
1006 volumePtr->setPoint (0, mesh.point (P7) );
1007 volumePtr->setPoint (1, mesh.point (P6) );
1008 volumePtr->setPoint (2, mesh.point (P3) );
1009 volumePtr->setPoint (3, mesh.point (P4) );
1010 volumePtr->setMarkerID (regionFlag);
1014 oStr <<
"done" << std::endl;
1017 if ( GeoShape::S_numPoints > 4 )
1026 if ( !checkMesh3D ( mesh, sw,
true,
false, oStr, std::cerr, oStr ) )
1032 getVolumeFromFaces ( mesh, vols, oStr );
1033 oStr <<
" VOLUME ENCLOSED BY THE MESH COMPUTED BY INTEGRATION ON" <<
1034 " BOUNDARY FACES" << std::endl;
1035 oStr <<
"INT(X) INT(Y) INT(Z) <- they should be equal and equal to" 1037 <<
" the volume enclosed by the mesh " 1039 oStr << vols[0] <<
" " << vols[1] <<
" " << vols[2] << std::endl;
1041 oStr <<
" BOUNDARY FACES ARE DEFINING A CLOSED SURFACE IF " 1042 << testClosedDomain ( mesh, oStr) << std::endl
1043 <<
" IS (ALMOST) ZERO" << std::endl;
1046 mesh.updateElementEdges (
true, verbose );
1047 mesh.updateElementFaces (
true, verbose );
I use standard constructor/destructors.
ID markerID_Type
markerID_Type is the type used to store the geometric entity marker IDs
markerID_Type regularMeshPointPosition(const UInt &i_x, const UInt &i_y, const UInt &i_z, const UInt &n_x, const UInt &n_y, const UInt &n_z)
This method gives the flags for a parallelepiped.
Class for 3D, 2D and 1D Mesh.
double Real
Generic real data.
void regularMesh3D(RegionMesh< GeoShape, MC > &mesh, markerID_Type regionFlag, const UInt &m_x, const UInt &m_y, const UInt &m_z, bool verbose=false, const Real &l_x=1.0, const Real &l_y=1.0, const Real &l_z=1.0, const Real &t_x=0.0, const Real &t_y=0.0, const Real &t_z=0.0)
This method generate a parallelepiped structured mesh.
uint32_type UInt
generic unsigned integer (used mainly for addressing)