implemented mirror mesh, still not working for vol. cells
[engrid.git] / src / utilities.h
blob14e04da64dbca3c09e69b4c4100d1bed9701904a
1 #ifndef UTILITIES_H
2 #define UTILITIES_H
4 /** @file utilities.h Contains several utility functions. */
6 #include <QVector>
7 #include <QMap>
8 #include <QObject>
9 #include <QtDebug>
10 #include <QFileDialog>
12 #include <iostream>
13 using namespace std;
15 #include "math/mathvector.h"
16 #include "math/smallsquarematrix.h"
17 #include "math/linsolve.h"
19 #include "vtkUnstructuredGrid.h"
21 #include <complex>
22 using namespace std;
24 /** Restricts value to the CYCLIC [min,max[ range.
25 * Equivalent to min + modulo(value-min, max-min)
26 * @param value value to restrict
27 * @param min minimum
28 * @param max maximum (if value=max, then min will be returned)
30 inline double restrict_to(double value, double min, double max)
32 return value - floor((value - min) / (max - min))*(max - min);
35 /// Converts degrees to radians
36 inline double RadiansFromDegrees(double a_deg)
38 return(a_deg / 180.0*M_PI);
41 /// Converts radians to degrees
42 inline double DegreesFromRadians(double a_rad)
44 return(a_rad / M_PI*180.0);
47 double toDouble(QString str);///< Equivalent of the QString::toDouble function, but it also replaces "," with "."
49 /** Converts a double to a string.
50 * @param x double value to convert
51 * @param separator symbol to use as decimal separator. It is recommended to always use the default: ".".
53 QString toString(double x, QString separator = QObject::tr("."));
55 /// a modulo function which also works for negative numbers
56 inline int modulo(int a, int b)
58 return((a % b + b) % b);
61 /// a modulo function which also works for negative numbers
62 inline double modulo(double a, double b)
64 while (a < 0) a += b;
65 while (a >= b) a -= b;
66 return a;
69 /** Adds a suffix to a filename if it is missing.
70 * @param filename string to which to add the suffix
71 * @param suffix suffix to add. suffix should be of the form 'ext' without the dot!!!
72 * @param remove_old_suffix If true, any previous suffix of filename will be removed. ex: foo.bar -> foo.png
73 * @return the filename with the new suffix
75 QString addSuffix(QString filename, QString suffix, bool remove_old_suffix);
77 ///////////////////////////////////////////
79 /** Transposes a vector of vectors (matrix)
80 * @param in the matrix to transpose
81 * @param nrows the number of rows of the input matrix
82 * @param ncolumns the number of columns of the input matrix
83 * @return the transposed "matrix"
85 template <class T>
86 QVector < QVector <T> > transpose(QVector < QVector <T> > & in, int nrows, int ncolumns)
88 QVector < QVector <T> > out(ncolumns);
89 QVector <T> col(nrows);
90 out.fill(col);
92 for (int i = 0; i < in.size(); i++) {
93 QVector <T> row = in[i];
94 for (int j = 0; j < row.size(); j++) {
95 out[j][i] = in[i][j];
98 return(out);
101 ///////////////////////////////////////////
103 /// ostream operator for QVectors
104 template <class T>
105 ostream &operator<<(ostream &out, QVector<T> const & vector)
107 int N = vector.size();
108 out << "[";
109 for (int i = 0; i < N; ++i) {
110 out << vector.at(i);
111 if (i != N - 1) out << ",";
113 out << "]";
114 return(out);
117 /// ostream operator for QSets
118 template <class T>
119 ostream &operator<<(ostream &out, QSet<T> const & set)
121 out << "[ ";
122 foreach(T value, set) out << value << " ";
123 out << "]";
124 return(out);
127 /// ostream operator for QVectors of QSets
128 template <class T>
129 ostream &operator<<(ostream &out, QVector<QSet<T> > & vector)
131 int N = vector.size();
132 out << "[";
133 for (int i = 0; i < N; ++i) {
134 QSet<T> set = vector.at(i);
135 out << set;
136 if (i != N - 1) out << ",";
138 out << "]";
139 return(out);
142 /// ostream operator for QVectors of QVectors
143 template <class T>
144 ostream &operator<<(ostream &out, QVector<QVector<T> > & vector)
146 int N = vector.size();
147 out << "[";
148 for (int i = 0; i < N; ++i) {
149 QVector<T> subvector = vector.at(i);
150 out << subvector;
151 if (i != N - 1) out << ",";
153 out << "]";
154 return(out);
157 /// ostream operator for QMaps
158 template <class T1, class T2>
159 ostream &operator<<(ostream &out, QMap<T1, T2> & map)
161 QMapIterator<T1, T2> i(map);
162 out << "[";
163 while (i.hasNext()) {
164 i.next();
165 out << " [" << i.key() << ": " << i.value() << "]";
167 out << "]";
168 return(out);
171 /// ostream operator for a QVector of pairs
172 template <class T1, class T2>
173 ostream &operator<<(ostream &out, QVector < pair<T1, T2> > & vector)
175 int N = vector.size();
176 out << "[";
177 for (int i = 0; i < N; ++i) {
178 out << "<";
179 out << vector.at(i).first;
180 out << ",";
181 out << vector.at(i).second;
182 out << ">";
183 if (i != N - 1) out << ",";
185 out << "]";
186 return(out);
189 ////////////////////////////////////////////////////
191 template <class T>
192 QVector <T> Set2Vector(QSet <T> a_set, bool a_sort)
194 QVector <T> l_vector(a_set.size());
195 qCopy(a_set.begin(),a_set.end(),l_vector.begin());
196 if(a_sort) qSort(l_vector.begin(),l_vector.end());
197 return(l_vector);
200 template <class T>
201 QSet <T> Vector2Set(QVector <T> a_vector, bool a_sort)
203 QSet <T> l_set;
204 foreach(T element, a_vector) l_set.insert(element);
205 if(a_sort) qSort(l_set.begin(),l_set.end());
206 return(l_set);
209 template <class T>
210 bool duplicates(QVector <T> a_vector)
212 QSet <T> l_set;
213 foreach(T element, a_vector) l_set.insert(element);
214 return l_set.size()!=a_vector.size();
217 ////////////////////////////////////////////////////
219 Qt::CheckState int2CheckState(int a);///< Converts an integer into a Qt::CheckState: Qt::Unchecked=0, Qt::PartiallyChecked=1, Qt::Checked=2
220 int CheckState2int(Qt::CheckState a);///< Converts a Qt::CheckState into an integer: Qt::Unchecked=0, Qt::PartiallyChecked=1, Qt::Checked=2
222 QString vector2csv(QVector <double> vector);///< Converts a vector into a CSV string
223 QVector <double> csv2vector(QString csv);///< Converts a CSV string into a vector
225 /// V(rotated base) = rotationMatrix_X * V(original base)
226 mat3_t rotationMatrix_X(double a_rad);
228 /// V(rotated base) = rotationMatrix_Y * V(original base)
229 mat3_t rotationMatrix_Y(double a_rad);
231 /// V(rotated base) = rotationMatrix_Z * V(original base)
232 mat3_t rotationMatrix_Z(double a_rad);
234 /// V(rotated base) = rotateRelativeZXZ * V(original base)
235 mat3_t rotateRelativeZXZ(double angle_1_rad, double angle_2_rad, double angle_3_rad);
237 /// V(rotated base) = rotateAbsoluteZXY * V(original base)
238 mat3_t rotateAbsoluteZXY(double angle_1_rad, double angle_2_rad, double angle_3_rad);
240 /// returns the polar angle in radians
241 double getGamma(vec3_t V);
243 /// returns the azimuth angle in radians. returns phi from -pi to pi
244 double getPhi(vec3_t V);
246 /// A version of QFileDialog::getExistingDirectory which allows preselecting a directory
247 QString getDirectory(QWidget * parent = 0, const QString & caption = QString(), const QString & selected = QString());
248 // QString getDirectory( QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), const QString & selected = QString() , Options options = ShowDirsOnly );
251 * Utility function that allows printing selected data from an vtkUnstructuredGrid to any ostream (includes ofstream objects)
252 * @param stream ostream object to print to
253 * @param grid vtkUnstructuredGrid you want to print data from
254 * @param npoints print number of points in the grid
255 * @param ncells print number of cells in the grid
256 * @param points print points in the grid
257 * @param cells print cells in the grid
259 int cout_grid(ostream &stream, vtkUnstructuredGrid *grid, bool npoints=true, bool ncells=true, bool points=false, bool cells=false);
261 ///////////////////////////////////////////
262 int addCell(vtkUnstructuredGrid* a_grid, vtkIdType A, vtkIdType B, vtkIdType C, int bc);
264 ///get number of the shortest side of the cell
265 int getShortestSide(vtkIdType a_id_cell,vtkUnstructuredGrid* a_grid);
266 ///get number of the longest side of the cell
267 int getLongestSide(vtkIdType a_id_cell,vtkUnstructuredGrid* a_grid);
268 //sort sides by length
269 //QVector <vtkIdType> sortSidesByLength(vtkIdType a_id_cell,vtkUnstructuredGrid* a_grid);
271 ///get number of the edge corresponding to node1-node2
272 int getSide(vtkIdType a_id_cell,vtkUnstructuredGrid* a_grid,vtkIdType a_id_node1,vtkIdType a_id_node2);
274 // QSet <int> complementary_bcs(QSet <int> &bcs, vtkUnstructuredGrid *a_grid, QVector <vtkIdType> &a_cells);
275 QString cell2str(vtkIdType id_cell,vtkUnstructuredGrid* grid);
277 ///////////////////////////////////////////
278 ///////////////////////////////////////////
279 pair<vtkIdType,vtkIdType> OrderedPair(vtkIdType a, vtkIdType b);
281 const char* VertexType2Str(char T);
282 char Str2VertexType(QString S);
283 QDebug operator<<(QDebug dbg, const vec3_t &v);
284 QDebug operator<<(QDebug dbg, const vec2_t &v);
286 bool checkVector(vec3_t V);
287 bool checkVector(vec2_t V);
289 /// returns the index of a node in a structured triangle grid
290 inline vtkIdType trigrid_idx(vtkIdType N, int i, int j) {
291 int offset = -i * (i - 2 * N - 1) / 2;
292 return offset + j;
295 /// returns the index of a node in a structured quad grid
296 inline vtkIdType quadgrid_idx(vtkIdType N, int i, int j) {
297 return i*N + j;
300 // solver functions
301 typedef complex<double> dcmplx;
302 QDebug operator<<(QDebug dbg, const dcmplx &c);
303 dcmplx complex_pow(dcmplx base, double power);
304 // x^3 + a x^2 + b x + c = 0
305 int poly_solve_cubic(double a, double b, double c, double * x0, double * x1, double * x2);
306 // a x^2 + b x + c = 0
307 int poly_solve_quadratic(double a, double b, double c, double * x0, double * x1);
309 #endif