GCC Code Coverage Report


Directory: ./
File: Core/felisceTools.hpp
Date: 2024-04-14 07:32:34
Exec Total Coverage
Lines: 54 104 51.9%
Branches: 36 140 25.7%

Line Branch Exec Source
1 // ______ ______ _ _ _____ ______
2 // | ____| ____| | (_)/ ____| | ____|
3 // | |__ | |__ | | _| (___ ___| |__
4 // | __| | __| | | | |\___ \ / __| __|
5 // | | | |____| |____| |____) | (__| |____
6 // |_| |______|______|_|_____/ \___|______|
7 // Finite Elements for Life Sciences and Engineering
8 //
9 // License: LGL2.1 License
10 // FELiScE default license: LICENSE in root folder
11 //
12 // Main authors: Sebastien Gilles
13 //
14
15 #ifndef _FELISCE_TOOLS_HPP_
16 #define _FELISCE_TOOLS_HPP_
17
18 // System includes
19 #include <cassert>
20 #include <cmath>
21 #include <iostream>
22 #include <vector>
23 #include <set>
24 #include <unordered_map>
25 #include <sstream>
26 #include <fstream>
27
28 // External includes
29 #include "Core/NoThirdPartyWarning/Mpi/mpi.hpp"
30
31 // Project includes
32 #include "Core/felisce_error.hpp"
33 #include "Core/mpiInfo.hpp"
34
35 namespace felisce {
36 namespace Tools {
37
38 static constexpr double ZeroTolerance = std::numeric_limits<double>::epsilon();
39
40 template<class T,class J>
41 inline bool insideVec(const J& vec, const T& elem) {
42 return find( vec.begin(), vec.end(), elem) != vec.end();
43 }
44
45 //! supposed to work for ublas
46 template< class M>
47 double trace(const M& mat) {
48 double tr(0);
49 for(std::size_t i(0); i<mat.size1(); ++i) {
50 tr+=mat(i,i);
51 }
52 return tr;
53 }
54
55 void allGatherSet( std::set<int> &locCont, std::set<int> &globCont );
56
57 //! Safe comparison between floating-point numbers
58 template<class T>
59 3174 bool equal(T lvalue, T rvalue) {
60 3174 return ( std::fabs( rvalue - lvalue ) <= ZeroTolerance );
61 }
62
63 //! Safe comparison between floating-point numbers
64 template<class T>
65 1008 bool equalTol(T lvalue, T rvalue, double tol) {
66 1008 return ( std::fabs( rvalue - lvalue ) <= tol );
67 }
68
69 //! Safe comparison between floating-point numbers
70 template<class T>
71 bool almostEqual(T lvalue, T rvalue, double rTol) {
72 return ( std::fabs( rvalue - lvalue ) <= rTol * std::max(std::fabs(rvalue),std::fabs(lvalue)) );
73 }
74
75 //! Safe comparison between floating-point numbers
76 template<class T>
77 25 bool notEqual(T lvalue, T rvalue) {
78 25 return ( std::fabs( rvalue - lvalue ) > ZeroTolerance );
79 }
80
81 template< class T>
82 void saveVectorInFile( std::vector<T> v, std::string filename, std::string folder ) {
83 std::stringstream filenameWithFolder;
84 if ( folder[folder.size()-1] != '/') {
85 folder.push_back('/');
86 }
87 filenameWithFolder<<folder<<filename;
88 std::ofstream outputFile( filenameWithFolder.str().c_str(), std::ios::trunc );
89 for ( unsigned int i(0); i<v.size(); i++ ) {
90 outputFile<<v[i]<<std::endl;
91 }
92 outputFile.close();
93 }
94
95 template< class T>
96 bool loadVectorFromFile( std::vector<T> &v, std::string filename, std::string folder ) {
97 std::stringstream filenameWithFolder;
98 if ( folder[folder.size()-1] != '/') {
99 folder.push_back('/');
100 }
101 filenameWithFolder<<folder<<filename;
102 T tmp;
103 std::ifstream inputFile( filenameWithFolder.str().c_str());
104 while ( inputFile >> tmp ) {
105 v.push_back(tmp);
106 }
107 if ( !inputFile.eof() ) {
108 std::cout << "[error reading] "<<filename<<std::endl;
109 return false;
110 }
111 inputFile.close();
112 return true;
113 }
114
115 template< class T>
116 void printVector( std::vector<T> v) {
117 std::cout<< " Printing the std::vector "<<std::endl;
118 for ( unsigned int i(0); i<v.size(); i++ ) {
119 std::cout<<v[i]<<"\t";
120 }
121 std::cout<<std::endl;
122 std::cout<<" End of the std::vector" <<std::endl;
123 }
124 template< class T>
125 void printVector( std::vector<T> v, std::string nameOfTheVector, std::ostream& out=std::cout,bool noEnd=false) {
126 out<< " "<<nameOfTheVector<<" : "<<std::endl;
127 for ( unsigned int i(0); i<v.size(); i++ ) {
128 out<<v[i]<<"\t";
129 }
130 out<<std::endl;
131 if(!noEnd)
132 out<<" End of the "<<nameOfTheVector<<std::endl;
133 }
134
135 template < class T>
136 bool pairComparison(std::pair<int, T > a, std::pair<int, T > b) {
137 return a.first < b.first;
138 }
139
140 template < class T>
141 15570 bool lgPairComparison(std::pair<int, T > a, std::pair<int, T > b) {
142
2/2
✓ Branch 2 taken 7842 times.
✓ Branch 3 taken 7728 times.
15570 if ( a.second.x() < b.second.x() )
143 7842 return true;
144
2/2
✓ Branch 2 taken 7024 times.
✓ Branch 3 taken 704 times.
7728 else if ( a.second.x() > b.second.x() )
145 7024 return false;
146
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 704 times.
704 if ( a.second.y() < b.second.y() )
147 return true;
148
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 704 times.
704 else if ( a.second.y() > b.second.y() )
149 return false;
150
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 704 times.
704 if ( a.second.z() < b.second.z() )
151 return true;
152
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 704 times.
704 else if ( a.second.z() > b.second.z() )
153 return false;
154
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 704 times.
704 if ( a.first < b.first )
155 return true;
156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 704 times.
704 else if ( a.first > b.first )
157 return false;
158 else
159 704 return false;
160 }
161
162 template < class T, class Poin> // This function is meant to be used only with Poin==Point, I used a template only to avoid including geometry/point.hpp which includes felisceTools.hpp as well.
163 // It was not possible to use a forward declaration because you can not call, for instance, the x() method on an incomplete type, but you can do that on a template parameter!
164 16 void allGatherSetPair(
165 std::set<std::pair<int,Poin>,T> &locCont,
166 std::set<std::pair<int,Poin>,T> &globCont
167 )
168 {
169
2/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 double *locContainerAsVec = new double[ 4 * locCont.size()];
170 16 int locCount(0), globCount(0);
171
172
2/2
✓ Branch 3 taken 336 times.
✓ Branch 4 taken 16 times.
352 for ( auto it = locCont.begin(); it != locCont.end(); it++ ) {
173 336 locContainerAsVec[locCount] = static_cast<double>( it->first );
174 336 locCount++;
175 336 locContainerAsVec[locCount] = it->second.x();
176 336 locCount++;
177 336 locContainerAsVec[locCount] = it->second.y();
178 336 locCount++;
179 336 locContainerAsVec[locCount] = it->second.z();
180 336 locCount++;
181 }
182
183
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 MPI_Allreduce(&locCount, &globCount,1,MPI_INT,MPI_SUM,MpiInfo::petscComm());
184
185 16 double globContainerAsVec[globCount];
186
187
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 int displacements[MpiInfo::numProc()];
188
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 int localCountBroadcasted[MpiInfo::numProc()];
189
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 int ones[MpiInfo::numProc()];
190
191
3/4
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
✓ Branch 4 taken 16 times.
80 for ( int proc(0); proc < MpiInfo::numProc(); proc++) {
192 64 localCountBroadcasted[proc]=0;
193 64 displacements[proc] = proc;
194 64 ones[proc] = 1;
195 }
196
197
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 MPI_Allgatherv(&locCount,1,MPI_INT,localCountBroadcasted,ones,displacements,MPI_INT,MpiInfo::petscComm());
198
199 16 displacements[0]=0;
200
3/4
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 16 times.
64 for ( int proc(0); proc < MpiInfo::numProc()-1; proc++) {
201 48 displacements[proc+1] = displacements[proc] + localCountBroadcasted[proc];
202 }
203
204
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 MPI_Allgatherv(locContainerAsVec,locCount,MPI_DOUBLE,globContainerAsVec,localCountBroadcasted,displacements, MPI_DOUBLE,MpiInfo::petscComm());
205
206
2/2
✓ Branch 0 taken 1344 times.
✓ Branch 1 taken 16 times.
1360 for ( int k(0); k< globCount; ) {
207 1344 int theInt = static_cast<int>(round(globContainerAsVec[k]));
208 1344 Poin P(globContainerAsVec[k+1],globContainerAsVec[k+2],globContainerAsVec[k+3]);
209 1344 k=k+4;
210
2/4
✓ Branch 1 taken 1344 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1344 times.
✗ Branch 5 not taken.
1344 globCont.insert( std::make_pair(theInt,P));
211 }
212 32 }
213
214 // this class inherits from the regular std::unordered_map
215 // it is just a decoration of the regular std::unordered_map.
216 // Get who check before accessing the std::unordered_map ( operator[] would have
217 // initialized a new element of the std::unordered_map)
218 // I think it is usefull for small maps and it helps a lot the debugging phase
219 // I added also an Init for readibility
220 // and at operator could be usufull later
221 template <class K, class V>
222 class mapHolder
223 : public std::unordered_map < K , V >
224 {
225 public:
226 // just for readibility
227 572 inline void Init(K key) {this->operator[](key);}
228
229 23229927 inline V& Get(K key) {
230
2/4
✓ Branch 1 taken 11683152 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11683152 times.
✗ Branch 4 not taken.
23229927 if ( this->count(key)>0 )
231
1/2
✓ Branch 1 taken 11683152 times.
✗ Branch 2 not taken.
23229927 return this->operator[](key);
232 std::stringstream err;
233 err<<"accessing a non-existing key: "<<key;
234 FEL_ERROR(err.str().c_str());
235 return this->operator[](key);
236 }
237
238 // only similar to the at of c++11..
239 // while waiting for it..
240 inline const V& At(K key) { return *(this->find(key)); }
241
242 };
243 } // namespace Tools
244 } // namespace felisce
245
246
247 #endif // _FELISCE_TOOLS_HPP_
248