Loading...
Searching...
No Matches
EigenFunctions.H
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ██╗████████╗██╗ ██╗ █████╗ ██████╗ █████╗ ███████╗██╗ ██╗
3 ██║╚══██╔══╝██║ ██║██╔══██╗██╔════╝██╔══██╗ ██╔════╝██║ ██║
4 ██║ ██║ ███████║███████║██║ ███████║█████╗█████╗ ██║ ██║
5 ██║ ██║ ██╔══██║██╔══██║██║ ██╔══██║╚════╝██╔══╝ ╚██╗ ██╔╝
6 ██║ ██║ ██║ ██║██║ ██║╚██████╗██║ ██║ ██║ ╚████╔╝
7 ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═══╝
8
9 * In real Time Highly Advanced Computational Applications for Finite Volumes
10 * Copyright (C) 2017 by the ITHACA-FV authors
11-------------------------------------------------------------------------------
12License
13 This file is part of ITHACA-FV
14 ITHACA-FV is free software: you can redistribute it and/or modify
15 it under the terms of the GNU Lesser General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18 ITHACA-FV is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU Lesser General Public License for more details.
22 You should have received a copy of the GNU Lesser General Public License
23 along with ITHACA-FV. If not, see <http://www.gnu.org/licenses/>.
24Class
25 EigenFunctions
26Description
27 Set of routines to manipulate Eigen c++ objects
28SourceFiles
29 EigenFunctions.C
30\*---------------------------------------------------------------------------*/
31
36
37#ifndef EigenFunctions_H
38#define EigenFunctions_H
39#include <mutex>
40#pragma GCC diagnostic push
41#pragma GCC diagnostic ignored "-Wold-style-cast"
42#include <Eigen/Eigen>
43#include <unsupported/Eigen/SparseExtra>
44#include <unsupported/Eigen/CXX11/Tensor>
45#pragma GCC diagnostic pop
46#include "fvCFD.H"
47
48
49// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
50
51
52/*---------------------------------------------------------------------------*\
53 Namespace EigenFunctions Declaration
54\*---------------------------------------------------------------------------*/
55
56
58namespace EigenFunctions
59{
60//--------------------------------------------------------------------------
69template <typename T>
70Eigen::SparseMatrix<T> vectorize(Eigen::SparseMatrix<T>& Matrix);
71
72//--------------------------------------------------------------------------
83template <typename T>
84T max(Eigen::SparseMatrix<T>& mat, label& ind_row, label& ind_col);
85
86//--------------------------------------------------------------------------
97template <typename T>
98T min(Eigen::SparseMatrix<T>& mat, label& ind_row, label& ind_col);
99
100//--------------------------------------------------------------------------
106void sortEigenvalues(Eigen::VectorXd& eigenvalues,
107 Eigen::MatrixXd& eigenvectors);
108
109//--------------------------------------------------------------------------
121template <typename T>
122Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> innerProduct(
123 List <Eigen::SparseMatrix<T>>& A, List <Eigen::SparseMatrix<T>>& B);
124
125//--------------------------------------------------------------------------
137template <typename T>
138Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> innerProduct(
139 List <Eigen::SparseMatrix<T>>& A, Eigen::SparseMatrix<T>& B);
140
141//--------------------------------------------------------------------------
154template <typename T>
155T innerProduct(Eigen::SparseMatrix<T>& A, Eigen::SparseMatrix<T>& B);
156
157//--------------------------------------------------------------------------
171template <typename T>
172Eigen::SparseMatrix<T> MVproduct(List<Eigen::SparseMatrix<T>>& A,
173 Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>& C);
174
175//--------------------------------------------------------------------------
189template <typename T>
190Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> MVproduct(
191 const std::vector< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>& A,
192 Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>& C);
193
194//--------------------------------------------------------------------------
208template <typename T>
209List<Eigen::SparseMatrix<T>> MMproduct(List<Eigen::SparseMatrix<T>>& A,
210 Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>& C);
211
212//--------------------------------------------------------------------------
221template <typename T>
222T condNumber(Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& A);
223
224//--------------------------------------------------------------------------
235Eigen::VectorXd ExpSpaced(double first, double last, int n);
236
237//--------------------------------------------------------------------------
246template <typename T>
247Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> vectorTensorProduct(
248 const Eigen::Matrix<T, Eigen::Dynamic, 1>& g,
249 const Eigen::Tensor<T, 3 >& c,
250 const Eigen::Matrix<T, Eigen::Dynamic, 1>& a);
251
252};
253
254template <typename T>
255Eigen::SparseMatrix<T> EigenFunctions::vectorize(Eigen::SparseMatrix<T>& Matrix)
256{
257 typedef Eigen::Triplet<double> Trip;
258 std::vector<Trip> tripletList;
259 tripletList.reserve(Matrix.nonZeros());
260 Eigen::SparseMatrix<T> vec;
261 vec.resize(1, Matrix.size());
262 vec.reserve(Matrix.nonZeros());
263
264 for (label k = 0; k < Matrix.outerSize(); ++k)
265 {
266 for (Eigen::SparseMatrix<double>::InnerIterator it(Matrix, k); it; ++it)
267 {
268 tripletList.push_back(Trip(0, it.row() + it.col()*Matrix.rows(), it.value()));
269 }
270 }
271
272 vec.setFromTriplets(tripletList.begin(), tripletList.end());
273}
274
275template <typename T>
276T EigenFunctions::max(Eigen::SparseMatrix<T>& mat, label& ind_row,
277 label& ind_col)
278{
279 label i = 0;
280 T max = 0;
281
282 for (label k = 0; k < mat.outerSize(); ++k)
283 {
284 for (typename Eigen::SparseMatrix<T>::InnerIterator it(mat, k); it; ++it)
285 {
286 if (max < it.value() || i == 0)
287 {
288 max = it.value();
289 ind_row = it.row();
290 ind_col = it.col();
291 i++;
292 }
293 }
294 }
295
296 return max;
297}
298
299template <typename T>
300T EigenFunctions::min(Eigen::SparseMatrix<T>& mat, label& ind_row,
301 label& ind_col)
302{
303 label i = 0;
304 T min = 0;
305
306 for (label k = 0; k < mat.outerSize(); ++k)
307 {
308 for (typename Eigen::SparseMatrix<T>::InnerIterator it(mat, k); it; ++it)
309 {
310 if (min > it.value() || i == 0)
311 {
312 min = it.value();
313 ind_row = it.row();
314 ind_col = it.col();
315 i++;
316 }
317 }
318 }
319
320 return min;
321}
322
323template <typename T>
324Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> EigenFunctions::innerProduct(
325 List <Eigen::SparseMatrix<T>>& A, List <Eigen::SparseMatrix<T>>& B)
326{
327 label rows = A.size();
328 label cols = B.size();
329 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> out;
330 out.resize(rows, cols);
331
332 for (label i = 0; i < rows; i++)
333 {
334 for (label j = 0; j < cols; j++)
335 {
336 out(i, j) = innerProduct(A[i], B[j]);
337 }
338 }
339
340 return out;
341}
342
343template <typename T>
344Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> EigenFunctions::innerProduct(
345 List<Eigen::SparseMatrix<T>>& A, Eigen::SparseMatrix<T>& B)
346{
347 label rows = A.size();
348 label cols = 1;
349 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> out;
350 out.resize(rows, cols);
351
352 for (label i = 0; i < rows; i++)
353 {
354 out(i, 0) = innerProduct(A[i], B);
355 }
356
357 return out;
358}
359
360template <typename T>
361T EigenFunctions::innerProduct(Eigen::SparseMatrix<T>& A,
362 Eigen::SparseMatrix<T>& B)
363{
364 T res = 0;
365
366 for (label k = 0; k < A.cols(); k++)
367 {
368 res += A.col(k).dot(B.col(k));
369 }
370
371 return res;
372}
373
374template <typename T>
375Eigen::SparseMatrix<T> EigenFunctions::MVproduct(List<Eigen::SparseMatrix<T>>& A
376 , Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>& C)
377{
378 Eigen::SparseMatrix<T> out;
379 out = A[0] * C(0);
380
381 for (label i = 1; i < A.size(); i++)
382 {
383 out += A[i] * C(i);
384 }
385
386 return out;
387}
388
389template <typename T>
390Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> EigenFunctions::MVproduct(
391 const std::vector< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>& A,
392 Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>& C)
393{
394 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> out;
395 out = A[0] * C(0);
396
397 for (label i = 1; i < A.size(); i++)
398 {
399 out += A[i] * C(i);
400 }
401
402 return out;
403}
404
405
406
407template <typename T>
408List<Eigen::SparseMatrix<T>> EigenFunctions::MMproduct(
409 List<Eigen::SparseMatrix<T>>& A,
410 Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>& C)
411{
412 List<Eigen::SparseMatrix<T>> out;
413 out.resize(C.cols());
414 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> col;
415
416 for (label i = 0; i < C.cols(); i++)
417 {
418 col = C.col(i);
419 out[i] = MVproduct(A, col);
420 }
421
422 return out;
423}
424
425template <typename T>
426T EigenFunctions::condNumber(Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>&
427 A)
428{
429 Eigen::JacobiSVD<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>> svd(A);
430 T cond = svd.singularValues()(0) / svd.singularValues()(
431 svd.singularValues().size() - 1);
432 return cond;
433}
434
435// Additional Eigen Functions
436namespace Eigen
437{
438using namespace Eigen;
439
440template<typename VectorType>
441bool saveMarketVector (const VectorType& vec, const std::string& filename,
442 label prec, std::_Ios_Fmtflags outytpe = std::ios_base::scientific)
443{
444 typedef typename VectorType::Scalar Scalar;
445 std::ofstream out(filename.c_str(), std::ios::out);
446
447 if (!out)
448 {
449 return false;
450 }
451
452 out.flags(outytpe);
453 out.precision(prec);
454
455 if (internal::is_same<Scalar, std::complex<float>>::value
456 || internal::is_same<Scalar, std::complex<double>>::value)
457 {
458 out << "%%MatrixMarket matrix array complex general\n";
459 }
460 else
461 {
462 out << "%%MatrixMarket matrix array real general\n";
463 }
464
465 out << vec.size() << " " << 1 << "\n";
466
467 for (label i = 0; i < vec.size(); i++)
468 {
469 internal::putVectorElt(vec(i), out);
470 }
471
472 out.close();
473 return true;
474}
475
476template<typename VectorType>
477Matrix<VectorType, Dynamic, Dynamic> SliceFromTensor(
478 Eigen::Tensor<VectorType, 3>& tensor, label dim, label index1)
479{
480 Eigen::Tensor<VectorType, 2> t2 = tensor.chip(index1, dim);
481 Matrix<VectorType, Dynamic, Dynamic> m = Eigen::Map<Eigen::Matrix<
482 VectorType, /* scalar element type */
483 Eigen::Dynamic, /* num_rows is a run-time value */
484 Eigen::Dynamic, /* num_cols is a run-time value */
485 Eigen::ColMajor /* tensorflow::Tensor is always row-major */>>(
486 t2.data(), /* ptr to data */
487 t2.dimensions()[0], /* num_rows */
488 t2.dimensions()[1] /* num_cols */);
489 return m;
490}
491
492template<typename VectorType>
493Matrix<VectorType, Dynamic, Dynamic> SliceFromTensor(
494 const Eigen::Tensor<VectorType, 3>& tensor, label dim, label index1)
495{
496 Eigen::Tensor<VectorType, 2> t2 = tensor.chip(index1, dim);
497 Matrix<VectorType, Dynamic, Dynamic> m = Eigen::Map<Eigen::Matrix<
498 VectorType, /* scalar element type */
499 Eigen::Dynamic, /* num_rows is a run-time value */
500 Eigen::Dynamic, /* num_cols is a run-time value */
501 Eigen::ColMajor /* tensorflow::Tensor is always row-major */>>(
502 t2.data(), /* ptr to data */
503 t2.dimensions()[0], /* num_rows */
504 t2.dimensions()[1] /* num_cols */);
505 return m;
506}
507
508}
509
510
511
512
513
514#endif
515
516
volScalarField & T
Definition createT.H:46
volScalarField & A
Namespace to perform operation on Eigen objects.
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > vectorTensorProduct(const Eigen::Matrix< T, Eigen::Dynamic, 1 > &g, const Eigen::Tensor< T, 3 > &c, const Eigen::Matrix< T, Eigen::Dynamic, 1 > &a)
A function that computes the product of g.T c a, where c is a third dim tensor.
Eigen::SparseMatrix< T > MVproduct(List< Eigen::SparseMatrix< T > > &A, Eigen::DenseBase< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > > &C)
Sparse Matrix-Vector product between a list of sparse matrices and a vector of coefficients.
T max(Eigen::SparseMatrix< T > &mat, label &ind_row, label &ind_col)
Find the maximum of a sparse Matrix (Useful for DEIM)
Eigen::VectorXd ExpSpaced(double first, double last, int n)
Returns exponentially spaced vector.
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > innerProduct(List< Eigen::SparseMatrix< T > > &A, List< Eigen::SparseMatrix< T > > &B)
Perform Frobenius inner Product between two list of sparse matrices A and B.
Eigen::SparseMatrix< T > vectorize(Eigen::SparseMatrix< T > &Matrix)
Vectorize a Sparse Matrix.
void sortEigenvalues(Eigen::VectorXd &eigenvalues, Eigen::MatrixXd &eigenvectors)
sort eigenvalues
T condNumber(Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &A)
Conditioning number of a dense matrix.
List< Eigen::SparseMatrix< T > > MMproduct(List< Eigen::SparseMatrix< T > > &A, Eigen::DenseBase< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > > &C)
Sparse Matrix - Dense Matrix product between a list of sparse matrices and a dense matrix.
T min(Eigen::SparseMatrix< T > &mat, label &ind_row, label &ind_col)
Find the minimum of a sparse Matrix (Useful for DEIM)
bool saveMarketVector(const VectorType &vec, const std::string &filename, label prec, std::_Ios_Fmtflags outytpe=std::ios_base::scientific)
Matrix< VectorType, Dynamic, Dynamic > SliceFromTensor(Eigen::Tensor< VectorType, 3 > &tensor, label dim, label index1)
singVal col(i)
Info<< endl;Info<< "*********************************************************"<< endl;Info<< "Performing test for the parameterized BC inverse solver"<< endl;Info<< endl;word outputFolder="./ITHACAoutput/parameterizedBCtest_RBFparameter/";volScalarField gTrueField=example_paramBC.list2Field(example_paramBC.gTrue);ITHACAstream::exportSolution(gTrueField, "1", outputFolder, "gTrue");Eigen::VectorXd rbfWidth=EigenFunctions::ExpSpaced(0.001, 100, rbfWidthTest_size);ITHACAstream::exportMatrix(rbfWidth, "rbfShapeParameters", "eigen", outputFolder);Eigen::VectorXd residualNorms;residualNorms.resize(rbfWidthTest_size);Eigen::VectorXd heatFluxL2norm(rbfWidthTest_size);Eigen::VectorXd heatFluxLinfNorm=heatFluxL2norm;Eigen::VectorXd condNumber=heatFluxL2norm;Eigen::MatrixXd singVal;for(int i=0;i< rbfWidthTest_size;i++){ Info<< "*********************************************************"<< endl;Info<< "RBF parameter "<< rbfWidth(i)<< endl;Info<< "Test "<< i+1<< endl;Info<< endl;example_paramBC.set_gParametrized("rbf", rbfWidth(i));example_paramBC.parameterizedBCoffline(1);example_paramBC.parameterizedBC("fullPivLU");volScalarField gParametrizedField=example_paramBC.list2Field(example_paramBC.g);ITHACAstream::exportSolution(gParametrizedField, std::to_string(i+1), outputFolder, "gParametrized");volScalarField &T(example_paramBC._T());ITHACAstream::exportSolution(T, std::to_string(i+1), outputFolder, "T");residualNorms(i)=Foam::sqrt(example_paramBC.residual.squaredNorm());Eigen::MatrixXd A=example_paramBC.Theta.transpose() *example_paramBC.Theta;Eigen::JacobiSVD< Eigen::MatrixXd > svd(A, Eigen::ComputeThinU|Eigen::ComputeThinV)
dimensionedVector & g
label i
Definition pEqn.H:46