Salome HOME
85d58450b0fc33e3559d1599ee2865d87145e624
[tools/medcoupling.git] / src / INTERP_KERNEL / Polyhedron3D2DIntersectorP0P0.txx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #ifndef __POLYHEDRON3D2DINTERSECTORP0P0_TXX__
20 #define __POLYHEDRON3D2DINTERSECTORP0P0_TXX__
21
22 #include "Polyhedron3D2DIntersectorP0P0.hxx"
23 #include "Intersector3DP0P0.txx"
24 #include "MeshUtils.hxx"
25
26 #include "SplitterTetra.txx"
27
28 namespace INTERP_KERNEL
29 {
30
31   /**
32    * Constructor creating object from target cell global number 
33    * The constructor first calculates the necessary nodes, 
34    * (depending on the splitting policy) and then splits the hexahedron into 
35    * tetrahedra, placing these in the internal vector _tetra.
36    * 
37    * @param targetMesh  mesh containing the target elements
38    * @param srcMesh     mesh containing the source elements
39    * @param policy      splitting policy to be used
40    */
41   template<class MyMeshType, class MyMatrixType>
42   Polyhedron3D2DIntersectorP0P0<MyMeshType,MyMatrixType>::Polyhedron3D2DIntersectorP0P0(const MyMeshType& targetMesh,
43                                                                                         const MyMeshType& srcMesh,
44                                                                                         const double dimCaracteristic,
45                                                                                         const double precision,
46                                                                                         DuplicateFacesType& intersectFaces,
47                                                                                         SplittingPolicy policy)
48     : Intersector3DP0P0<MyMeshType,MyMatrixType>(targetMesh,srcMesh),
49       _split(targetMesh,srcMesh,policy),
50       _dim_caracteristic(dimCaracteristic),
51       _precision(precision),
52       _intersect_faces(intersectFaces)
53   {
54   }
55
56   /**
57    * Destructor.
58    * Liberates the SplitterTetra objects and potential sub-node points that have been allocated.
59    *
60    */
61   template<class MyMeshType, class MyMatrixType>
62   Polyhedron3D2DIntersectorP0P0<MyMeshType,MyMatrixType>::~Polyhedron3D2DIntersectorP0P0()
63   {
64     releaseArrays();
65   }
66     
67   template<class MyMeshType, class MyMatrixType>
68   void Polyhedron3D2DIntersectorP0P0<MyMeshType,MyMatrixType>::releaseArrays()
69   {
70     for(typename std::vector< SplitterTetra<MyMeshType>* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter)
71       delete *iter;
72     _split.releaseArrays();
73     _tetra.clear();
74   }
75
76   /**
77    * Calculates the volume of intersection of an element in the source mesh and the target element
78    * represented by the object.
79    * The calculation is performed by calling the corresponding method for
80    * each SplitterTetra object created by the splitting.
81    * 
82    * @param targetCell in C mode.
83    * @param srcCells in C mode.
84    */
85   template<class MyMeshType, class MyMatrixType>
86   void Polyhedron3D2DIntersectorP0P0<MyMeshType,MyMatrixType>::intersectCells(ConnType targetCell,
87                                                                               const std::vector<ConnType>& srcCells,
88                                                                               MyMatrixType& matrix)
89   {
90     int nbOfNodesT=Intersector3D<MyMeshType,MyMatrixType>::_target_mesh.getNumberOfNodesOfElement(OTT<ConnType,numPol>::indFC(targetCell));
91     releaseArrays();
92     _split.splitTargetCell(targetCell,nbOfNodesT,_tetra);
93
94     for(typename std::vector<ConnType>::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++)
95       {
96         double surface = 0.;
97         std::multiset<TriangleFaceKey> listOfTetraFacesTreated;
98         std::set<TriangleFaceKey> listOfTetraFacesColinear;
99
100         // calculate the coordinates of the nodes
101         typename MyMeshType::MyConnType cellSrc = *iterCellS;
102         int cellSrcIdx = OTT<ConnType,numPol>::indFC(cellSrc);
103         NormalizedCellType normCellType=Intersector3D<MyMeshType,MyMatrixType>::_src_mesh.getTypeOfElement(cellSrcIdx);
104         const CellModel& cellModelCell=CellModel::GetCellModel(normCellType);
105         const MyMeshType& src_mesh = Intersector3D<MyMeshType,MyMatrixType>::_src_mesh;
106         unsigned nbOfNodes4Type=cellModelCell.isDynamic() ? src_mesh.getNumberOfNodesOfElement(cellSrcIdx) : cellModelCell.getNumberOfNodes();
107         int *polyNodes=new int[nbOfNodes4Type];
108         double **polyCoords = new double*[nbOfNodes4Type];
109         for(int i = 0;i<(int)nbOfNodes4Type;++i)
110           {
111             // we could store mapping local -> global numbers too, but not sure it is worth it
112             const int globalNodeNum = getGlobalNumberOfNode(i, OTT<ConnType,numPol>::indFC(*iterCellS), src_mesh);
113             polyNodes[i] = globalNodeNum;
114             polyCoords[i] = const_cast<double*>(src_mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*globalNodeNum);
115           }
116
117         for(typename std::vector<SplitterTetra<MyMeshType>*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter)
118             surface += (*iter)->intersectSourceFace(normCellType,
119                                                     nbOfNodes4Type,
120                                                     polyNodes,
121                                                     polyCoords,
122                                                     _dim_caracteristic,
123                                                     _precision,
124                                                     listOfTetraFacesTreated,
125                                                     listOfTetraFacesColinear);
126
127         if(surface!=0.)
128           {
129             
130             matrix[targetCell].insert(std::make_pair(cellSrcIdx, surface));
131             
132             bool isSrcFaceColinearWithFaceOfTetraTargetCell = false;
133             std::set<TriangleFaceKey>::iterator iter;
134             for (iter = listOfTetraFacesColinear.begin(); iter != listOfTetraFacesColinear.end(); ++iter)
135               {
136                 if (listOfTetraFacesTreated.count(*iter) != 1)
137                   {
138                     isSrcFaceColinearWithFaceOfTetraTargetCell = false;
139                     break;
140                   }
141                 else
142                   {
143                     isSrcFaceColinearWithFaceOfTetraTargetCell = true;
144                   }
145               }
146             
147             if (isSrcFaceColinearWithFaceOfTetraTargetCell)
148               {
149                 DuplicateFacesType::iterator intersectFacesIter = _intersect_faces.find(cellSrcIdx);
150                 if (intersectFacesIter != _intersect_faces.end())
151                   {
152                     intersectFacesIter->second.insert(targetCell);
153                   }
154                 else
155                   {
156                     std::set<int> targetCellSet;
157                     targetCellSet.insert(targetCell);
158                     _intersect_faces.insert(std::make_pair(cellSrcIdx, targetCellSet));
159                   }
160               }
161           }
162         delete [] polyNodes;
163         delete [] polyCoords;
164       }
165     _split.releaseArrays();
166   }
167 }
168
169 #endif