]> SALOME platform Git repositories - tools/medcoupling.git/blob - src/INTERP_KERNEL/Interpolation2D1D.txx
Salome HOME
e84d07dec7238add8ee7636a470c526231371b4e
[tools/medcoupling.git] / src / INTERP_KERNEL / Interpolation2D1D.txx
1 // Copyright (C) 2007-2012  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 __INTERPOLATION2D1D_TXX__
20 #define __INTERPOLATION2D1D_TXX__
21
22 #include "Interpolation2D1D.hxx"
23
24 namespace INTERP_KERNEL
25 {
26
27   /** \brief Main function to interpolate triangular or quadrangular meshes.
28       \details  The algorithm proceeds in two steps: first a filtering process reduces the number of pairs of elements for which the
29       * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the
30       * volume of intersection is calculated by an object of type IntersectorPlanar for the remaining pairs, and entered into the
31       * intersection matrix.
32       *
33       * The matrix is partially sparse : it is a vector of maps of integer - double pairs.
34       * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless
35       * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements
36       * which have a non-zero intersection volume with the target element. The vector has indices running from
37       * 0 to (#target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however,
38       * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j].
39       *
40
41       * @param myMeshS  Planar source mesh
42       * @Param myMeshT  Planar target mesh
43       * @return            vector containing for each element i of the source mesh, a map giving for each element j
44       *                    of the target mesh which i intersects, the area of the intersection
45       *
46       */
47   template<class MyMeshType, class MatrixType>
48   int Interpolation2D1D::interpolateMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, MatrixType& result, const char *method)
49   {
50     static const int SPACEDIM=MyMeshType::MY_SPACEDIM;
51     typedef typename MyMeshType::MyConnType ConnType;
52     static const NumberingPolicy numPol=MyMeshType::My_numPol;
53
54     long global_start =clock();
55     int counter=0;
56     /***********************************************************/
57     /* Check both meshes are made of triangles and quadrangles */
58     /***********************************************************/
59
60     long nbMailleS=myMeshS.getNumberOfElements();
61
62     /**************************************************/
63     /* Search the characteristic size of the meshes   */
64     /**************************************************/
65
66     int printLevel = InterpolationOptions::getPrintLevel();
67     _dim_caracteristic = CalculateCharacteristicSizeOfMeshes(myMeshS, myMeshT, printLevel);
68     if (printLevel>=1)
69       {
70         std::cout << "Interpolation2D1D::computation of the intersections" << std::endl;
71       }
72
73     PlanarIntersector<MyMeshType,MatrixType>* intersector=0;
74     std::string meth = InterpolationOptions::filterInterpolationMethod(method);
75     if(meth=="P0P0")
76       {
77         switch (InterpolationOptions::getIntersectionType())
78           {
79           case Geometric2D:
80             intersector=new Geometric2DIntersector<MyMeshType,MatrixType,Planar2D1DIntersectorP0P0>(myMeshT, myMeshS, _dim_caracteristic,
81                                                                                                     InterpolationOptions::getMaxDistance3DSurfIntersect(),
82                                                                                                     InterpolationOptions::getMedianPlane(),
83                                                                                                     InterpolationOptions::getPrecision(),
84                                                                                                     InterpolationOptions::getOrientation());
85             break;
86           default:
87             throw INTERP_KERNEL::Exception("Invalid intersection type ! Must be : Geometric2D");
88           }
89       }
90     else
91       throw INTERP_KERNEL::Exception("Invalid method specified or intersection type ! Must be : \"P0P0\"");
92
93     /****************************************************************/
94     /* Create a search tree based on the bounding boxes             */
95     /* Instanciate the intersector and initialise the result vector */
96     /****************************************************************/
97
98     long start_filtering=clock();
99
100     std::vector<double> bbox;
101     intersector->createBoundingBoxes(myMeshS,bbox); // create the bounding boxes
102     const double *bboxPtr=0;
103     if(nbMailleS>0)
104       bboxPtr=&bbox[0];
105     BBTree<SPACEDIM,ConnType> my_tree(bboxPtr, 0, 0,nbMailleS, -getPrecision());//creating the search structure
106
107     long end_filtering=clock();
108
109     result.resize(intersector->getNumberOfRowsOfResMatrix());//on initialise.
110
111     /****************************************************/
112     /* Loop on the target cells - core of the algorithm */
113     /****************************************************/
114     long start_intersection=clock();
115     long nbelem_type=myMeshT.getNumberOfElements();
116     const ConnType *connIndxT=myMeshT.getConnectivityIndexPtr();
117     for(int iT=0; iT<nbelem_type; iT++)
118       {
119         int nb_nodesT=connIndxT[iT+1]-connIndxT[iT];
120         std::vector<int> intersecting_elems;
121         double bb[2*SPACEDIM];
122         intersector->getElemBB(bb,myMeshT,OTT<ConnType,numPol>::indFC(iT),nb_nodesT);
123         my_tree.getIntersectingElems(bb, intersecting_elems);
124         intersector->intersectCells(iT,intersecting_elems,result);
125         counter+=intersecting_elems.size();
126         intersecting_elems.clear();
127       }
128     int ret=intersector->getNumberOfColsOfResMatrix();
129
130     const DuplicateFacesType& intersectFaces = *intersector->getIntersectFaces();
131     DuplicateFacesType::const_iterator iter;
132     for (iter = intersectFaces.begin(); iter != intersectFaces.end(); ++iter)
133       {
134         if (iter->second.size() > 1)
135           {
136             _duplicate_faces.insert(std::make_pair(iter->first, iter->second));
137           }
138       }
139
140     delete intersector;
141
142     if (InterpolationOptions::getPrintLevel() >=1)
143       {
144         long end_intersection=clock();
145         std::cout << "Filtering time= " << end_filtering-start_filtering << std::endl;
146         std::cout << "Intersection time= " << end_intersection-start_intersection << std::endl;
147         long global_end =clock();
148         std::cout << "Number of computed intersections = " << counter << std::endl;
149         std::cout << "Global time= " << global_end - global_start << std::endl;
150       }
151     return ret;
152   }
153
154 }
155 #endif