Salome HOME
Debug on GENERAL_24 and GENERAL_48
[tools/medcoupling.git] / src / INTERP_KERNEL / InterpolationPlanar.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 // Author : Anthony Geay (CEA/DEN)
20 #ifndef __INTERPOLATIONPLANAR_TXX__
21 #define __INTERPOLATIONPLANAR_TXX__
22
23 #include "InterpolationPlanar.hxx"
24 #include "Interpolation.txx"
25 #include "InterpolationOptions.hxx"
26 #include "PlanarIntersector.hxx"
27 #include "PlanarIntersector.txx"
28 #include "TriangulationIntersector.hxx"
29 #include "TriangulationIntersector.txx"
30 #include "ConvexIntersector.hxx"
31 #include "ConvexIntersector.txx"
32 #include "Geometric2DIntersector.hxx"
33 #include "Geometric2DIntersector.txx"
34 #include "PointLocator2DIntersector.hxx"
35 #include "PointLocator2DIntersector.txx"
36 #include "PlanarIntersectorP0P1PL.hxx"
37 #include "PlanarIntersectorP0P1PL.txx"
38 #include "PlanarIntersectorP1P0PL.hxx"
39 #include "PlanarIntersectorP1P0PL.txx"
40 #include "PlanarIntersectorP1P1PL.hxx"
41 #include "PlanarIntersectorP1P1PL.txx"
42 #include "VectorUtils.hxx"
43 #include "BBTree.txx"
44
45 #include <limits>
46 #include <time.h>
47
48 namespace INTERP_KERNEL
49 {
50   /**
51    * \defgroup interpolationPlanar InterpolationPlanar
52    *
53    * \class InterpolationPlanar
54    * \brief Class used to compute the coefficients of the interpolation matrix between 
55    * two local meshes in two dimensions. Meshes can contain mixed triangular and quadrangular elements.
56    */
57   template<class RealPlanar>
58   InterpolationPlanar<RealPlanar>::InterpolationPlanar():_dim_caracteristic(1)
59                                                          
60   {
61   }
62
63   template<class RealPlanar>
64   InterpolationPlanar<RealPlanar>::InterpolationPlanar(const InterpolationOptions& io):Interpolation< InterpolationPlanar<RealPlanar> >(io),_dim_caracteristic(1)
65                                                          
66   {
67   }
68
69   /**
70    *  \brief  Function used to set the options for the intersection calculation
71    * \details The following options can be modified:
72    *  -# Intersection_type: the type of algorithm to be used in the computation of the cell-cell intersections.
73    *   - Values: Triangle, Convex.
74    *   - Default: Triangle.
75    *  -# Precision: Level of precision of the computations is precision times the characteristic size of the mesh.
76    *   - Values: positive real number.
77    *   - Default: 1.0E-12.
78    *  -# PrintLevel: Level of verboseness during the computations.
79    *   - Values: interger between 0 and 3.
80    *   - Default: 0.
81    */
82   template<class RealPlanar>
83   void InterpolationPlanar<RealPlanar>::setOptions(double precision, int printLevel, IntersectionType intersectionType, int orientation)
84   {
85     InterpolationOptions::setPrecision(precision);
86     InterpolationOptions::setPrintLevel(printLevel);
87     InterpolationOptions::setIntersectionType(intersectionType);
88     InterpolationOptions::setOrientation(orientation);
89   }
90   
91   
92   /** \brief Main function to interpolate triangular or quadrangular meshes.
93       \details  The algorithm proceeds in two steps: first a filtering process reduces the number of pairs of elements for which the
94       * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the 
95       * volume of intersection is calculated by an object of type IntersectorPlanar for the remaining pairs, and entered into the
96       * intersection matrix. 
97       * 
98       * The matrix is partially sparse : it is a vector of maps of integer - double pairs. 
99       * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless
100       * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements
101       * which have a non-zero intersection volume with the target element. The vector has indices running from 
102       * 0 to (#target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however,
103       * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j].
104       * 
105    
106       * @param myMeshS  Planar source mesh
107       * @Param myMeshT  Planar target mesh
108       * @return            vector containing for each element i of the source mesh, a map giving for each element j
109       *                    of the target mesh which i intersects, the area of the intersection
110       *
111       */
112   template<class RealPlanar>
113   template<class MyMeshType, class MatrixType>
114   int InterpolationPlanar<RealPlanar>::interpolateMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, MatrixType& result, const char *method)
115   {
116     static const int SPACEDIM=MyMeshType::MY_SPACEDIM;
117     typedef typename MyMeshType::MyConnType ConnType;
118     static const NumberingPolicy numPol=MyMeshType::My_numPol;
119
120     long global_start =clock();
121     int counter=0;   
122     /***********************************************************/
123     /* Check both meshes are made of triangles and quadrangles */
124     /***********************************************************/
125
126     long nbMailleS=myMeshS.getNumberOfElements();
127     long nbMailleT=myMeshT.getNumberOfElements();
128     
129     /**************************************************/
130     /* Search the characteristic size of the meshes   */
131     /**************************************************/
132     
133     double BoxS[2*SPACEDIM]; myMeshS.getBoundingBox(BoxS);
134     double BoxT[2*SPACEDIM]; myMeshT.getBoundingBox(BoxT);
135     double diagonalS,dimCaracteristicS=std::numeric_limits<double>::max();
136     if(nbMailleS!=0)
137       {
138         diagonalS=getDistanceBtw2Pts<SPACEDIM>(BoxS+SPACEDIM,BoxS);
139         dimCaracteristicS=diagonalS/nbMailleS;
140       }
141     double diagonalT,dimCaracteristicT=std::numeric_limits<double>::max();
142     if(nbMailleT!=0)
143       {
144         diagonalT=getDistanceBtw2Pts<SPACEDIM>(BoxT+SPACEDIM,BoxT);
145         dimCaracteristicT=diagonalT/nbMailleT;
146       }
147     
148     _dim_caracteristic=std::min(dimCaracteristicS, dimCaracteristicT);
149     if (InterpolationOptions::getPrintLevel()>=1)
150       {
151         std::cout << "  - Characteristic size of the source mesh : " << dimCaracteristicS << std::endl;
152         std::cout << "  - Characteristic size of the target mesh: " << dimCaracteristicT << std::endl;
153         std::cout << "InterpolationPlanar::computation of the intersections" << std::endl;
154       }
155     
156     PlanarIntersector<MyMeshType,MatrixType>* intersector=0;
157     std::string meth = InterpolationOptions::filterInterpolationMethod(method);
158     if(meth=="P0P0")
159       {
160         switch (InterpolationOptions::getIntersectionType())
161           {
162           case Triangulation:
163             intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P0>(myMeshT,myMeshS,_dim_caracteristic,
164                                                                                                   InterpolationOptions::getPrecision(),
165                                                                                                   InterpolationOptions::getMaxDistance3DSurfIntersect(),
166                                                                                                   InterpolationOptions::getMedianPlane(),
167                                                                                                   InterpolationOptions::getOrientation(),
168                                                                                                   InterpolationOptions::getPrintLevel());
169             break;
170           case Convex:
171             intersector=new ConvexIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P0>(myMeshT,myMeshS,_dim_caracteristic,
172                                                                                            InterpolationOptions::getPrecision(),
173                                                                                            InterpolationOptions::getMaxDistance3DSurfIntersect(),
174                                                                                            InterpolationOptions::getMedianPlane(),
175                                                                                            InterpolationOptions::getDoRotate(),
176                                                                                            InterpolationOptions::getOrientation(),
177                                                                                            InterpolationOptions::getPrintLevel());
178             break;
179           case Geometric2D:
180             intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P0>(myMeshT, myMeshS, _dim_caracteristic,
181                                                                                                 InterpolationOptions::getMaxDistance3DSurfIntersect(),
182                                                                                                 InterpolationOptions::getMedianPlane(),
183                                                                                                 InterpolationOptions::getPrecision(),
184                                                                                                 InterpolationOptions::getOrientation());
185             break;
186           case PointLocator:
187             intersector=new PointLocator2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P0>(myMeshT, myMeshS, _dim_caracteristic,
188                                                                                                    InterpolationOptions::getMaxDistance3DSurfIntersect(),
189                                                                                                    InterpolationOptions::getMedianPlane(),
190                                                                                                    InterpolationOptions::getPrecision(),
191                                                                                                    InterpolationOptions::getOrientation());
192             break;
193           }
194       }
195     else if(meth=="P0P1")
196       {
197         switch (InterpolationOptions::getIntersectionType())
198           {
199           case Triangulation:
200             intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P1>(myMeshT,myMeshS,_dim_caracteristic,
201                                                                                                   InterpolationOptions::getPrecision(),
202                                                                                                   InterpolationOptions::getMaxDistance3DSurfIntersect(),
203                                                                                                   InterpolationOptions::getMedianPlane(),
204                                                                                                   InterpolationOptions::getOrientation(),
205                                                                                                   InterpolationOptions::getPrintLevel());
206             break;
207           case Convex:
208             intersector=new ConvexIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P1>(myMeshT,myMeshS,_dim_caracteristic,
209                                                                                            InterpolationOptions::getPrecision(),
210                                                                                            InterpolationOptions::getMaxDistance3DSurfIntersect(),
211                                                                                            InterpolationOptions::getMedianPlane(),
212                                                                                            InterpolationOptions::getDoRotate(),
213                                                                                            InterpolationOptions::getOrientation(),
214                                                                                            InterpolationOptions::getPrintLevel());
215             break;
216           case Geometric2D:
217             intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P1>(myMeshT, myMeshS, _dim_caracteristic,
218                                                                                                 InterpolationOptions::getMaxDistance3DSurfIntersect(),
219                                                                                                 InterpolationOptions::getMedianPlane(),
220                                                                                                 InterpolationOptions::getPrecision(),
221                                                                                                 InterpolationOptions::getOrientation());
222             break;
223           case PointLocator:
224             intersector=new PlanarIntersectorP0P1PL<MyMeshType,MatrixType>(myMeshT, myMeshS, _dim_caracteristic,
225                                                                            InterpolationOptions::getMaxDistance3DSurfIntersect(),
226                                                                            InterpolationOptions::getMedianPlane(),
227                                                                            InterpolationOptions::getPrecision(),
228                                                                            InterpolationOptions::getOrientation());
229             break;
230           }
231       }
232     else if(meth=="P1P0")
233       {
234         switch (InterpolationOptions::getIntersectionType())
235           {
236           case Triangulation:
237             intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P0>(myMeshT,myMeshS,_dim_caracteristic,
238                                                                                                   InterpolationOptions::getPrecision(),
239                                                                                                   InterpolationOptions::getMaxDistance3DSurfIntersect(),
240                                                                                                   InterpolationOptions::getMedianPlane(),
241                                                                                                   InterpolationOptions::getOrientation(),
242                                                                                                   InterpolationOptions::getPrintLevel());
243             break;
244           case Convex:
245             intersector=new ConvexIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P0>(myMeshT,myMeshS,_dim_caracteristic,
246                                                                                            InterpolationOptions::getPrecision(),
247                                                                                            InterpolationOptions::getMaxDistance3DSurfIntersect(),
248                                                                                            InterpolationOptions::getMedianPlane(),
249                                                                                            InterpolationOptions::getDoRotate(),
250                                                                                            InterpolationOptions::getOrientation(),
251                                                                                            InterpolationOptions::getPrintLevel());
252             break;
253           case Geometric2D:
254             intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P0>(myMeshT, myMeshS, _dim_caracteristic,
255                                                                                                 InterpolationOptions::getMaxDistance3DSurfIntersect(),
256                                                                                                 InterpolationOptions::getMedianPlane(),
257                                                                                                 InterpolationOptions::getPrecision(),
258                                                                                                 InterpolationOptions::getOrientation());
259             break;
260           case PointLocator:
261             intersector=new PlanarIntersectorP1P0PL<MyMeshType,MatrixType>(myMeshT, myMeshS, _dim_caracteristic,
262                                                                        InterpolationOptions::getMaxDistance3DSurfIntersect(),
263                                                                        InterpolationOptions::getMedianPlane(),
264                                                                        InterpolationOptions::getPrecision(),
265                                                                        InterpolationOptions::getOrientation());
266             break;
267           }
268       }
269     else if(meth=="P1P0Bary")
270     {
271       switch (InterpolationOptions::getIntersectionType())
272       {
273       case Triangulation:
274         intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P0Bary>(myMeshT,myMeshS,_dim_caracteristic,
275                                                                                                   InterpolationOptions::getPrecision(),
276                                                                                                   InterpolationOptions::getMaxDistance3DSurfIntersect(),
277                                                                                                   InterpolationOptions::getMedianPlane(),
278                                                                                                   InterpolationOptions::getOrientation(),
279                                                                                                   InterpolationOptions::getPrintLevel());
280         break;
281       case Convex:
282         intersector=new ConvexIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P0Bary>(myMeshT,myMeshS,_dim_caracteristic,
283                                                                                            InterpolationOptions::getPrecision(),
284                                                                                            InterpolationOptions::getMaxDistance3DSurfIntersect(),
285                                                                                            InterpolationOptions::getMedianPlane(),
286                                                                                            InterpolationOptions::getDoRotate(),
287                                                                                            InterpolationOptions::getOrientation(),
288                                                                                            InterpolationOptions::getPrintLevel());
289         break;
290       case Geometric2D:
291         intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P0Bary>(myMeshT, myMeshS, _dim_caracteristic,
292                                                                                                 InterpolationOptions::getMaxDistance3DSurfIntersect(),
293                                                                                                 InterpolationOptions::getMedianPlane(),
294                                                                                                 InterpolationOptions::getPrecision(),
295                                                                                                 InterpolationOptions::getOrientation());
296         break;
297       case PointLocator:
298         throw INTERP_KERNEL::Exception("Invalid intersector (PointLocator) for P1P0Bary !");
299         break;
300       }
301     }
302     else if(meth=="P1P1")
303       {
304         switch (InterpolationOptions::getIntersectionType())
305           {
306           case Triangulation:
307             intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P1>(myMeshT,myMeshS,_dim_caracteristic,
308                                                                                                   InterpolationOptions::getPrecision(),
309                                                                                                   InterpolationOptions::getMaxDistance3DSurfIntersect(),
310                                                                                                   InterpolationOptions::getMedianPlane(),
311                                                                                                   InterpolationOptions::getOrientation(),
312                                                                                                   InterpolationOptions::getPrintLevel());
313             break;
314           case Convex:
315             intersector=new ConvexIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P1>(myMeshT,myMeshS,_dim_caracteristic,
316                                                                                            InterpolationOptions::getPrecision(),
317                                                                                            InterpolationOptions::getMaxDistance3DSurfIntersect(),
318                                                                                            InterpolationOptions::getMedianPlane(),
319                                                                                            InterpolationOptions::getDoRotate(),
320                                                                                            InterpolationOptions::getOrientation(),
321                                                                                            InterpolationOptions::getPrintLevel());
322             break;
323           case Geometric2D:
324             intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P1>(myMeshT, myMeshS, _dim_caracteristic,
325                                                                                                 InterpolationOptions::getMaxDistance3DSurfIntersect(),
326                                                                                                 InterpolationOptions::getMedianPlane(),
327                                                                                                 InterpolationOptions::getPrecision(),
328                                                                                                 InterpolationOptions::getOrientation());
329             break;
330           case PointLocator:
331             intersector=new PlanarIntersectorP1P1PL<MyMeshType,MatrixType>(myMeshT, myMeshS, _dim_caracteristic,
332                                                                            InterpolationOptions::getMaxDistance3DSurfIntersect(),
333                                                                            InterpolationOptions::getMedianPlane(),
334                                                                            InterpolationOptions::getPrecision(),
335                                                                            InterpolationOptions::getOrientation());
336             break;
337           }
338       }
339     else
340       throw INTERP_KERNEL::Exception("Invalid method specified or intersection type ! Must be in : \"P0P0\" \"P0P1\" \"P1P0\" or \"P1P1\"");
341     /****************************************************************/
342     /* Create a search tree based on the bounding boxes             */
343     /* Instanciate the intersector and initialise the result vector */
344     /****************************************************************/
345  
346     long start_filtering=clock();
347  
348     std::vector<double> bbox;
349     intersector->createBoundingBoxes(myMeshS,bbox); // create the bounding boxes
350     performAdjustmentOfBB(intersector,bbox);
351     const double *bboxPtr=0;
352     if(nbMailleS>0)
353       bboxPtr=&bbox[0];
354     BBTree<SPACEDIM,ConnType> my_tree(bboxPtr, 0, 0,nbMailleS);//creating the search structure 
355
356     long end_filtering=clock();
357
358     result.resize(intersector->getNumberOfRowsOfResMatrix());//on initialise.
359
360     /****************************************************/
361     /* Loop on the target cells - core of the algorithm */
362     /****************************************************/
363     long start_intersection=clock();
364     long nbelem_type=myMeshT.getNumberOfElements();
365     const ConnType *connIndxT=myMeshT.getConnectivityIndexPtr();
366     for(int iT=0; iT<nbelem_type; iT++)
367       {
368         int nb_nodesT=connIndxT[iT+1]-connIndxT[iT];
369         std::vector<int> intersecting_elems;
370         double bb[2*SPACEDIM];
371         intersector->getElemBB(bb,myMeshT,OTT<ConnType,numPol>::indFC(iT),nb_nodesT);
372         my_tree.getIntersectingElems(bb, intersecting_elems);
373         intersector->intersectCells(iT,intersecting_elems,result);
374         counter+=intersecting_elems.size();
375         intersecting_elems.clear();
376       }
377     int ret=intersector->getNumberOfColsOfResMatrix();
378     delete intersector;
379
380     if (InterpolationOptions::getPrintLevel() >=1)
381       {
382         long end_intersection=clock();
383         std::cout << "Filtering time= " << end_filtering-start_filtering << std::endl;
384         std::cout << "Intersection time= " << end_intersection-start_intersection << std::endl;
385         long global_end =clock();    
386         std::cout << "Number of computed intersections = " << counter << std::endl;
387         std::cout << "Global time= " << global_end - global_start << std::endl;
388       }
389     return ret;
390   }
391 }
392
393 #endif