1 // Copyright (C) 2007-2019 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
20 #ifndef __INTERPOLATIONCURVE_TXX__
21 #define __INTERPOLATIONCURVE_TXX__
23 #include "InterpolationCurve.hxx"
24 #include "InterpolationOptions.hxx"
25 #include "CurveIntersectorP0P0.txx"
26 #include "CurveIntersectorP1P0.txx"
27 #include "CurveIntersectorP0P1.txx"
28 #include "CurveIntersectorP1P1.txx"
29 #include "CurveIntersectorP1P1PL.txx"
34 namespace INTERP_KERNEL
37 * \defgroup interpolationCurve InterpolationCurve
39 * \class InterpolationCurve
40 * \brief Class used to compute the coefficients of the interpolation matrix between
41 * two local meshes in two dimensions.
43 template<class RealCurve>
44 InterpolationCurve<RealCurve>::InterpolationCurve()
48 template<class RealCurve>
49 InterpolationCurve<RealCurve>::InterpolationCurve (const InterpolationOptions& io)
50 :Interpolation< InterpolationCurve<RealCurve> >(io)
54 /** \brief Main function to interpolate 1D meshes.
55 \details The algorithm proceeds in two steps: first a filtering process reduces the number of pairs of elements for which the
56 * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the
57 * volume of intersection is calculated by an object of type IntersectorPlanar for the remaining pairs, and entered into the
58 * intersection matrix.
60 * The matrix is partially sparse : it is a vector of maps of integer - double pairs.
61 * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless
62 * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements
63 * which have a non-zero intersection volume with the target element. The vector has indices running from
64 * 0 to (#target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however,
65 * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j].
68 * @param myMeshS Planar source mesh
69 * @Param myMeshT Planar target mesh
70 * @return vector containing for each element i of the source mesh, a map giving for each element j
71 * of the target mesh which i intersects, the area of the intersection
74 template<class RealCurve>
75 template<class MyMeshType, class MatrixType>
76 int InterpolationCurve<RealCurve>::interpolateMeshes (const MyMeshType& myMeshS,
77 const MyMeshType& myMeshT,
79 const std::string& method)
81 static const int SPACEDIM=MyMeshType::MY_SPACEDIM;
82 typedef typename MyMeshType::MyConnType ConnType;
83 static const NumberingPolicy numPol = MyMeshType::My_numPol;
85 long global_start = clock();
88 long nbMailleS = myMeshS.getNumberOfElements();
89 long nbMailleT = myMeshT.getNumberOfElements();
91 CurveIntersector<MyMeshType,MatrixType>* intersector=0;
94 switch (InterpolationOptions::getIntersectionType())
98 intersector = new CurveIntersectorP0P0<MyMeshType,MatrixType>(myMeshT, myMeshS,
99 InterpolationOptions::getPrecision(),
100 InterpolationOptions::getBoundingBoxAdjustmentAbs(),
101 InterpolationOptions::getMedianPlane(),
102 InterpolationOptions::getPrintLevel());
106 throw INTERP_KERNEL::Exception("For P0P0 in 1D or 2D curve only Triangulation supported for the moment !");
109 else if(method=="P0P1")
111 switch (InterpolationOptions::getIntersectionType())
115 intersector = new CurveIntersectorP0P1<MyMeshType,MatrixType>(myMeshT, myMeshS,
116 InterpolationOptions::getPrecision(),
117 InterpolationOptions::getBoundingBoxAdjustmentAbs(),
118 InterpolationOptions::getMedianPlane(),
119 InterpolationOptions::getPrintLevel());
123 throw INTERP_KERNEL::Exception("For P0P1 in 1D or 2D curve only Triangulation supported for the moment !");
126 else if(method=="P1P0")
128 switch (InterpolationOptions::getIntersectionType())
132 intersector = new CurveIntersectorP1P0<MyMeshType,MatrixType>(myMeshT, myMeshS,
133 InterpolationOptions::getPrecision(),
134 InterpolationOptions::getBoundingBoxAdjustmentAbs(),
135 InterpolationOptions::getMedianPlane(),
136 InterpolationOptions::getPrintLevel());
140 throw INTERP_KERNEL::Exception("For P1P0 in 1D or 2D curve only Triangulation supported for the moment !");
143 else if(method=="P1P1")
145 switch (InterpolationOptions::getIntersectionType())
148 intersector = new CurveIntersectorP1P1<MyMeshType,MatrixType>
150 InterpolationOptions::getPrecision(),
151 InterpolationOptions::getBoundingBoxAdjustmentAbs(),
152 InterpolationOptions::getMedianPlane(),
153 InterpolationOptions::getPrintLevel());
156 intersector = new CurveIntersectorP1P1PL<MyMeshType,MatrixType>
158 InterpolationOptions::getPrecision(),
159 InterpolationOptions::getBoundingBoxAdjustmentAbs(),
160 InterpolationOptions::getMedianPlane(),
161 InterpolationOptions::getPrintLevel());
164 throw INTERP_KERNEL::Exception("For P1P1 in 1D or 2D curve only Triangulation and PointLocator supported !");
168 throw INTERP_KERNEL::Exception("Invalid method specified ! Must be in : \"P0P0\" \"P0P1\" \"P1P0\" or \"P1P1\"");
169 /****************************************************************/
170 /* Create a search tree based on the bounding boxes */
171 /* Instantiate the intersector and initialise the result vector */
172 /****************************************************************/
174 long start_filtering=clock();
176 std::vector<double> bbox;
177 intersector->createBoundingBoxes(myMeshS,bbox); // create the bounding boxes
178 intersector->adjustBoundingBoxes(bbox, InterpolationOptions::getBoundingBoxAdjustmentAbs());
179 BBTree<SPACEDIM,ConnType> my_tree(&bbox[0], 0, 0, nbMailleS);//creating the search structure
181 long end_filtering = clock();
183 result.resize(intersector->getNumberOfRowsOfResMatrix());//on initialise.
185 /****************************************************/
186 /* Loop on the target cells - core of the algorithm */
187 /****************************************************/
188 long start_intersection = clock();
189 const ConnType *connIndxT = myMeshT.getConnectivityIndexPtr();
190 for(int iT=0; iT<nbMailleT; iT++)
192 int nb_nodesT = connIndxT[iT+1] - connIndxT[iT];
193 std::vector<int> intersecting_elems;
194 double bb[2*SPACEDIM];
195 intersector->getElemBB(bb,myMeshT,OTT<ConnType,numPol>::indFC(iT),nb_nodesT);
196 my_tree.getIntersectingElems(bb, intersecting_elems);
197 intersector->intersectCells(iT,intersecting_elems,result);
198 counter += intersecting_elems.size();
200 int ret = intersector->getNumberOfColsOfResMatrix();
203 if (InterpolationOptions::getPrintLevel() >= 1)
205 long end_intersection=clock();
206 std::cout << "Filtering time= " << end_filtering-start_filtering << std::endl;
207 std::cout << "Intersection time= " << end_intersection-start_intersection << std::endl;
208 long global_end =clock();
209 std::cout << "Number of computed intersections = " << counter << std::endl;
210 std::cout << "Global time= " << global_end - global_start << std::endl;