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