Salome HOME
Merge from V6_main 01/04/2013
[modules/med.git] / src / INTERP_KERNEL / Polyhedron3D2DIntersectorP0P0.txx
1 // Copyright (C) 2007-2013  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.
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    */
86   template<class MyMeshType, class MyMatrixType>
87   void Polyhedron3D2DIntersectorP0P0<MyMeshType,MyMatrixType>::intersectCells(ConnType targetCell,
88                                                                               const std::vector<ConnType>& srcCells,
89                                                                               MyMatrixType& matrix)
90   {
91     int nbOfNodesT=Intersector3D<MyMeshType,MyMatrixType>::_target_mesh.getNumberOfNodesOfElement(OTT<ConnType,numPol>::indFC(targetCell));
92     releaseArrays();
93     _split.splitTargetCell(targetCell,nbOfNodesT,_tetra);
94
95     for(typename std::vector<ConnType>::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++)
96       {
97         double surface = 0.;
98         std::multiset<TriangleFaceKey> listOfTetraFacesTreated;
99         std::set<TriangleFaceKey> listOfTetraFacesColinear;
100
101         // calculate the coordinates of the nodes
102         typename MyMeshType::MyConnType cellSrc = *iterCellS;
103         int cellSrcIdx = OTT<ConnType,numPol>::indFC(cellSrc);
104         NormalizedCellType normCellType=Intersector3D<MyMeshType,MyMatrixType>::_src_mesh.getTypeOfElement(cellSrcIdx);
105         const CellModel& cellModelCell=CellModel::GetCellModel(normCellType);
106         const MyMeshType& src_mesh = Intersector3D<MyMeshType,MyMatrixType>::_src_mesh;
107         unsigned nbOfNodes4Type=cellModelCell.isDynamic() ? src_mesh.getNumberOfNodesOfElement(cellSrcIdx) : cellModelCell.getNumberOfNodes();
108         int *polyNodes=new int[nbOfNodes4Type];
109         double **polyCoords = new double*[nbOfNodes4Type];
110         for(int i = 0;i<(int)nbOfNodes4Type;++i)
111           {
112             // we could store mapping local -> global numbers too, but not sure it is worth it
113             const int globalNodeNum = getGlobalNumberOfNode(i, OTT<ConnType,numPol>::indFC(*iterCellS), src_mesh);
114             polyNodes[i]=globalNodeNum;
115             polyCoords[i] = const_cast<double*>(src_mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*globalNodeNum);
116           }
117
118         for(typename std::vector<SplitterTetra<MyMeshType>*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter)
119             surface += (*iter)->intersectSourceFace(normCellType,
120                                                     nbOfNodes4Type,
121                                                     polyNodes,
122                                                     polyCoords,
123                                                     _dim_caracteristic,
124                                                     _precision,
125                                                     listOfTetraFacesTreated,
126                                                     listOfTetraFacesColinear);
127
128         if(surface!=0.) {
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
163         }
164
165         delete[] polyNodes;
166         delete[] polyCoords;
167
168       }
169     _split.releaseArrays();
170   }
171 }
172
173 #endif