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