From: vbd Date: Fri, 14 Sep 2007 08:12:09 +0000 (+0000) Subject: staffan : X-Git-Tag: trio_trio_coupling~35 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=e151581cce9433e2961d884aca35d5f1914cf3f8;p=tools%2Fmedcoupling.git staffan : * documented IntersectorHexa --- diff --git a/src/INTERP_KERNEL/IntersectorHexa.cxx b/src/INTERP_KERNEL/IntersectorHexa.cxx index b80ea655a..d6fddf0f3 100644 --- a/src/INTERP_KERNEL/IntersectorHexa.cxx +++ b/src/INTERP_KERNEL/IntersectorHexa.cxx @@ -12,7 +12,18 @@ using namespace MEDMEM; namespace INTERP_UTILS { - + + /** + * Constructor creating object from target cell global number + * The constructor first calculates the necessary nodes, + * (depending on the splitting policy) and then splits the hexahedron into + * tetrahedra, placing these in the internal vector _tetra. + * + * @param srcMesh mesh containing the source elements + * @param targetMesh mesh containing the target elements + * @param targetCell global number of the target cell + * @param policy splitting policy to be used + */ IntersectorHexa::IntersectorHexa(const MEDMEM::MESH& srcMesh, const MEDMEM::MESH& targetMesh, int targetCell, SplittingPolicy policy) { @@ -60,6 +71,11 @@ namespace INTERP_UTILS } } + /** + * Destructor. + * Liberates the IntersectorTetra objects and potential sub-node points that have been allocated. + * + */ IntersectorHexa::~IntersectorHexa() { for(vector::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) @@ -76,8 +92,30 @@ namespace INTERP_UTILS } } + /** + * Splits the hexahedron into five tetrahedra. + * This method adds five IntersectorTetra objects to the vector _tetra. + * + * @param srcMesh the source mesh + * @param subZone the local node numbers corresponding to the hexahedron corners - these are mapped onto {0,..,7}. Providing this allows the + * splitting to be reused on the subzones of the GENERAL_* types of splitting + */ void IntersectorHexa::fiveSplit(const MEDMEM::MESH& srcMesh, const int* const subZone) { + // Schema according to which the splitting is performed. + // Each line represents one tetrahedron. The numbering is as follows : + // + // 7 ------ 6 + // /| /| + // / | / | + // 3 ------ 2 | + // | | | | + // | | | | + // | 4-----|- 5 + // | / | / + // 0 ------ 1 + + static const int SPLIT_NODES_5[20] = { 0, 1, 5, 2, @@ -87,6 +125,7 @@ namespace INTERP_UTILS 0, 2, 5, 7 }; + // create tetrahedra for(int i = 0; i < 5; ++i) { const double* nodes[4]; @@ -99,8 +138,29 @@ namespace INTERP_UTILS } } + /** + * Splits the hexahedron into six tetrahedra. + * This method adds six IntersectorTetra objects to the vector _tetra. + * + * @param srcMesh the source mesh + * @param subZone the local node numbers corresponding to the hexahedron corners - these are mapped onto {0,..,7}. Providing this allows the + * splitting to be reused on the subzones of the GENERAL_* types of splitting + */ void IntersectorHexa::sixSplit(const MEDMEM::MESH& srcMesh, const int* const subZone) { + // Schema according to which the splitting is performed. + // Each line represents one tetrahedron. The numbering is as follows : + // + // 7 ------ 6 + // /| /| + // / | / | + // 3 ------ 2 | + // | | | | + // | | | | + // | 4-----|- 5 + // | / | / + // 0 ------ 1 + static const int SPLIT_NODES_6[24] = { 0, 1, 5, 6, @@ -123,10 +183,20 @@ namespace INTERP_UTILS } } + /** + * Splits the hexahedron into 24 tetrahedra. + * The splitting is done by combining the barycenter of the tetrahedron, the barycenter of each face + * and the nodes of each edge of the face. This creates 6 faces * 4 edges / face = 24 tetrahedra. + * The submesh nodes introduced are the barycenters of the faces and the barycenter of the cell. + * + * @param srcMesh the source mesh + * + */ void IntersectorHexa::calculateGeneral24Tetra(const MEDMEM::MESH& srcMesh) { - // the two mesh nodes used in each tetrahedron - // the tetrahedra all have nodes (cellCenter, faceCenter, edgeNode1, edgeNode2) + // The two nodes of the original mesh cell used in each tetrahedron. + // The tetrahedra all have nodes (cellCenter, faceCenter, edgeNode1, edgeNode2) + // For the correspondance of the nodes, see the GENERAL_48_SUB_NODES table in calculateSubNodes static const int TETRA_EDGES[48] = { // face with center 9 @@ -161,6 +231,7 @@ namespace INTERP_UTILS 4, 3 }; + // nodes to use for tetrahedron const double* nodes[4]; // get the cell center @@ -182,12 +253,22 @@ namespace INTERP_UTILS } } + + /** + * Splits the hexahedron into 48 tetrahedra. + * The splitting is done by introducing the midpoints of all the edges + * and the barycenter of the element as submesh nodes. The 8 hexahedral subzones thus defined + * are then split into 6 tetrahedra each, as in Grandy, p. 449. The division of the subzones + * is done by calling sixSplit(). + * + * @param srcMesh the source mesh + * + */ void IntersectorHexa::calculateGeneral48Tetra(const MEDMEM::MESH& srcMesh) { - // define 8 hexahedral subzones as in Grandy, p449 + // Define 8 hexahedral subzones as in Grandy, p449 // the values correspond to the nodes that correspond to nodes 1,2,3,4,5,6,7,8 in the subcell - // these nodes have correspondance 1 -> 0, 2 -> a, 3 -> e, 4 -> d, 5 -> b, 6 -> c, 7 -> g, 8 -> f - // with the Fig. 4.c in Grandy + // For the correspondance of the nodes, see the GENERAL_48_SUB_NODES table in calculateSubNodes static const int subZones[64] = { 1, 9, 22, 13, 10, 21, 27, 23, @@ -206,6 +287,17 @@ namespace INTERP_UTILS } } + /** + * Precalculates all the nodes. + * Retrieves the mesh nodes and allocates the necessary sub-mesh + * nodes according to the splitting policy used. + * This method is meant to be called once by the constructor. + * + * @param targetMesh the target mesh + * @param targetCell the global number of the cell that the object represents + * @param policy the splitting policy of the object + * + */ void IntersectorHexa::calculateSubNodes(const MEDMEM::MESH& targetMesh, int targetCell, SplittingPolicy policy) { // retrieve real mesh nodes @@ -220,6 +312,9 @@ namespace INTERP_UTILS { case GENERAL_24: { + // Each sub-node is the barycenter of 4 other nodes. + // For the faces, these are on the orignal mesh. + // For the barycenter, the four face sub-nodes are used. static const int GENERAL_24_SUB_NODES[28] = { 1, 2, 5, 6, // sub-node 9 (face) @@ -242,6 +337,10 @@ namespace INTERP_UTILS case GENERAL_48: { + // Each sub-node is the barycenter of two other nodes. + // For the edges, these lie on the original mesh. + // For the faces, these are the edge sub-nodes. + // For the cell these are two face sub-nodes. static const int GENERAL_48_SUB_NODES[38] = { 1, 2, // sub-node 9 (edge) @@ -279,6 +378,15 @@ namespace INTERP_UTILS } } + /** + * Calculates the volume of intersection of an element in the source mesh and the target element + * represented by the object. + * The calculation is performed by calling the corresponding method for + * each IntersectorTetra object created by the splitting. + * + * @param srcCell global number of the source element (1 <= srcCell < # source cells) + * + */ double IntersectorHexa::intersectSourceCell(int srcCell) { double volume = 0.0; diff --git a/src/INTERP_KERNEL/IntersectorHexa.hxx b/src/INTERP_KERNEL/IntersectorHexa.hxx index 47efdca41..1b0d72821 100644 --- a/src/INTERP_KERNEL/IntersectorHexa.hxx +++ b/src/INTERP_KERNEL/IntersectorHexa.hxx @@ -12,8 +12,8 @@ namespace INTERP_UTILS class IntersectorTetra; /** - * Class representing a hexahedron, which allows - * + * \brief Class responsible for calculating intersection between a hexahedron target element and + * the source elements. * */ class IntersectorHexa : public TargetIntersector @@ -21,9 +21,13 @@ namespace INTERP_UTILS public: + /// Type describing the different ways in which the hexahedron can be split into tetrahedra. + /// The PLANAR_* policies persume that each face is to be considered planar, while the general + /// policies make no such hypothesis. The integer at the end gives the number of tetrahedra + /// that result from the split. enum SplittingPolicy { PLANAR_FACE_5 = 5, PLANAR_FACE_6 = 6, GENERAL_24 = 24, GENERAL_48 = 48 }; - IntersectorHexa(const MEDMEM::MESH& srcMesh, const MEDMEM::MESH& targetMesh, int targetCell, SplittingPolicy policy = GENERAL_48); + IntersectorHexa(const MEDMEM::MESH& srcMesh, const MEDMEM::MESH& targetMesh, int targetCell, SplittingPolicy policy = GENERAL_24); ~IntersectorHexa(); @@ -46,19 +50,35 @@ namespace INTERP_UTILS template inline void calcBarycenter(double* barycenter, const int* const pts); + /// pointers to the IntersectorTetra objects representing the tetrahedra + /// that result from the splitting of the hexahedron vector _tetra; + /// vector of pointers to double[3] containing the coordinates of the + /// (sub) - nodes vector _nodes; }; - + /** + * Accessor to the coordinates of a given (sub)-node + * + * @param node local number of the (sub)-node 1,..,8 are the elements nodes, sub-nodes are numbered from 9,.. + * @return pointer to double[3] containing the coordinates of the nodes + */ inline const double* IntersectorHexa::getCoordsOfSubNode(int node) { - // replace at with [] for unsafe but faster access + // replace "at()" with [] for unsafe but faster access return _nodes.at(node - 1); } + /** + * Calculates the barycenter of n (sub) - nodes + * + * @param n number of nodes for which to calculate barycenter + * @param barycenter pointer to double[3] array in which to store the result + * @param pts pointer to int[n] array containing the (sub)-nodes for which to calculate the barycenter + */ template inline void IntersectorHexa::calcBarycenter(double* barycenter, const int* const pts) { diff --git a/src/INTERP_KERNEL/IntersectorTetra.hxx b/src/INTERP_KERNEL/IntersectorTetra.hxx index d09af0b38..fd06c51fe 100644 --- a/src/INTERP_KERNEL/IntersectorTetra.hxx +++ b/src/INTERP_KERNEL/IntersectorTetra.hxx @@ -148,7 +148,7 @@ namespace INTERP_UTILS { /** - * Class calculating the volume of intersection between a tetrahedral target element and + * \brief Class calculating the volume of intersection between a tetrahedral target element and * source elements with triangular or quadratilateral faces. * */