Salome HOME
4083addb386e95ccde0fe95cf9d4d91c653d4060
[tools/medcoupling.git] / src / INTERP_KERNELTest / PerfTest.cxx
1 // Copyright (C) 2007-2020  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
20 #include "Interpolation3D.hxx"
21 #include "Interpolation3D.txx"
22 #include "MeshTestToolkit.txx"
23 #include "Log.hxx"
24 #include "VectorUtils.hxx"
25 #include "TestInterpKernelUtils.hxx"
26
27 #include "MEDCouplingNormalizedUnstructuredMesh.hxx"
28
29 #include <cassert>
30 #include <string>
31
32 /**
33  * Test program which takes two meshes and calculates their intersection matrix.
34  *
35  * USAGE : PerfTest mesh1 mesh2
36  *         where mesh1 and mesh2 are the names of two meshes located in
37  *         the files mesh1.med, mesh2.med in {$MEDCOUPLING_ROOT_DIR}/share/resources/med/
38  *
39  */
40
41 namespace INTERP_TEST
42 {
43   /**
44    * \brief Specialization of MeshTestToolkit for the purposes of performance testing.
45    *
46    */
47   class PerfTestToolkit : public MeshTestToolkit<3,3>
48   {
49
50   public:
51
52     /**
53      * Calculates the intersection matrix for two meshes.
54      * Outputs the names of the meshes intersected, the number of elements in each mesh,
55      * the number of matrix elements and the number of non-zero matrix elements, etc.
56      * These values help to determine how well the filtering algorithm is working.
57      *
58      * @param  mesh1path   the path to the file containing the source mesh, relative to {$MEDCOUPLING_ROOT_DIR}/share/resources/med/
59      * @param  mesh1       the name of the source mesh
60      * @param  mesh2path   the path to the file containing the target mesh, relative to {$MEDCOUPLING_ROOT_DIR}/share/resources/med/
61      * @param  mesh2       the name of the target mesh
62      * @param  m           intersection matrix in which to store the result of the intersection
63      */
64     void calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m)
65     {
66       LOG(1, std::endl << "=== -> intersecting src = " << mesh1 << ", target = " << mesh2 );
67
68       LOG(5, "Loading " << mesh1 << " from " << mesh1path);
69       MCAuto<MEDFileUMesh> sMeshML=MEDFileUMesh::New(INTERP_TEST::getResourceFile(mesh1path).c_str(),mesh1);
70       MCAuto<MEDCouplingUMesh> sMesh=sMeshML->getMeshAtLevel(0);
71
72
73       LOG(5, "Loading " << mesh2 << " from " << mesh2path);
74       MCAuto<MEDFileUMesh> tMeshML=MEDFileUMesh::New(INTERP_TEST::getResourceFile(mesh2path).c_str(),mesh2);
75       MCAuto<MEDCouplingUMesh> tMesh=tMeshML->getMeshAtLevel(0);
76
77       MEDCouplingNormalizedUnstructuredMesh<3,3> sMesh_wrapper(sMesh);
78       MEDCouplingNormalizedUnstructuredMesh<3,3> tMesh_wrapper(tMesh);
79
80       Interpolation3D interpolator;
81       interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0");
82
83 //      std::pair<int, int> eff = countNumberOfMatrixEntries(m);
84 //      LOG(1, eff.first << " of " << numTargetElems * numSrcElems << " intersections calculated : ratio = "
85 //          << double(eff.first) / double(numTargetElems * numSrcElems));
86       LOG(1, eff.second << " non-zero elements of " << eff.first << " total : filter efficiency = "
87           << double(eff.second) / double(eff.first));
88
89       LOG(1, "Intersection calculation done. " << std::endl );
90
91     }
92
93     /**
94      * Counts the number of elements in an intersection matrix, and the number of these which are non-zero.
95      *
96      * @param m  the intersection matrix
97      * @return  pair<int, int> containing as its first element the number of elements in m and as its second element the
98      *                         number these which are non-zero
99      */
100     std::pair<int,int> countNumberOfMatrixEntries(const IntersectionMatrix& m)
101     {
102
103       int numElems = 0;
104       int numNonZero = 0;
105       for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter)
106         {
107           numElems += iter->size();
108           for(std::map<mcIdType, double>::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2)
109             {
110               if(!INTERP_KERNEL::epsilonEqual(iter2->second, 0.0, VOL_PREC))
111                 {
112                   ++numNonZero;
113                 }
114             }
115         }
116       return std::make_pair(numElems, numNonZero);
117     }
118
119   };
120 }
121
122 /**
123  * Main method of the program.
124  * Intersects the meshes and outputs some information about the calculation as well as the
125  * intersection matrix on std::cout.
126  *
127  * @param argc  number of arguments given to the program (should be 3, the user giving 2 mesh names)
128  * @param argv  vector to the arguments as strings.
129  */
130 int main(int argc, char** argv)
131 {
132   using INTERP_TEST::PerfTestToolkit;
133
134   assert(argc == 3);
135
136   // load meshes
137   const std::string mesh1 = argv[1];
138   const std::string mesh2 = argv[2];
139
140   const std::string mesh1path = mesh1 + ".med";
141   const std::string mesh2path = mesh2 + ".med";
142
143   IntersectionMatrix m;
144
145   PerfTestToolkit testTools;
146
147   testTools.calcIntersectionMatrix(mesh1path.c_str(), mesh1.c_str(), mesh2path.c_str(), mesh2.c_str(), m);
148
149   testTools.dumpIntersectionMatrix(m);
150
151   return 0;
152
153 }
154