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>&
256 Matrix)
257{
258 typedef Eigen::Triplet<double> Trip;
259 std::vector<Trip> tripletList;
260 tripletList.reserve(Matrix.nonZeros());
261 Eigen::SparseMatrix<T> vec;
262 vec.resize(1, Matrix.size());
263 vec.reserve(Matrix.nonZeros());
264
265 for (label k = 0; k < Matrix.outerSize(); ++k)
266 {
267 for (Eigen::SparseMatrix<double>::InnerIterator it(Matrix, k); it; ++it)
268 {
269 tripletList.push_back(Trip(0, it.row() + it.col() * Matrix.rows(), it.value()));
270 }
271 }
272
273 vec.setFromTriplets(tripletList.begin(), tripletList.end());
274}
275
276template <typename T>
277T EigenFunctions::max(Eigen::SparseMatrix<T>& mat, label& ind_row,
278 label& ind_col)
279{
280 label i = 0;
281 T max = 0;
282
283 for (label k = 0; k < mat.outerSize(); ++k)
284 {
285 for (typename Eigen::SparseMatrix<T>::InnerIterator it(mat, k); it; ++it)
286 {
287 if (max < it.value() || i == 0)
288 {
289 max = it.value();
290 ind_row = it.row();
291 ind_col = it.col();
292 i++;
293 }
294 }
295 }
296
297 return max;
298}
299
300template <typename T>
301T EigenFunctions::min(Eigen::SparseMatrix<T>& mat, label& ind_row,
302 label& ind_col)
303{
304 label i = 0;
305 T min = 0;
306
307 for (label k = 0; k < mat.outerSize(); ++k)
308 {
309 for (typename Eigen::SparseMatrix<T>::InnerIterator it(mat, k); it; ++it)
310 {
311 if (min > it.value() || i == 0)
312 {
313 min = it.value();
314 ind_row = it.row();
315 ind_col = it.col();
316 i++;
317 }
318 }
319 }
320
321 return min;
322}
323
324template <typename T>
325Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> EigenFunctions::innerProduct(
326 List <Eigen::SparseMatrix<T >> & A, List <Eigen::SparseMatrix<T >>& B)
327{
328 label rows = A.size();
329 label cols = B.size();
330 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> out;
331 out.resize(rows, cols);
332
333 for (label i = 0; i < rows; i++)
334 {
335 for (label j = 0; j < cols; j++)
336 {
337 out(i, j) = innerProduct(A[i], B[j]);
338 }
339 }
340
341 return out;
342}
343
344template <typename T>
345Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> EigenFunctions::innerProduct(
346 List<Eigen::SparseMatrix<T >> & A, Eigen::SparseMatrix<T>& B)
347{
348 label rows = A.size();
349 label cols = 1;
350 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> out;
351 out.resize(rows, cols);
352
353 for (label i = 0; i < rows; i++)
354 {
355 out(i, 0) = innerProduct(A[i], B);
356 }
357
358 return out;
359}
360
361template <typename T>
362T EigenFunctions::innerProduct(Eigen::SparseMatrix<T>& A,
363 Eigen::SparseMatrix<T>& B)
364{
365 T res = 0;
366
367 for (label k = 0; k < A.cols(); k++)
368 {
369 res += A.col(k).dot(B.col(k));
370 }
371
372 return res;
373}
374
375template <typename T>
376Eigen::SparseMatrix<T> EigenFunctions::MVproduct(List<Eigen::SparseMatrix<T >> &
377 A
378 , Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >>& C)
379{
380 Eigen::SparseMatrix<T> out;
381 out = A[0] * C(0);
382
383 for (label i = 1; i < A.size(); i++)
384 {
385 out += A[i] * C(i);
386 }
387
388 return out;
389}
390
391template <typename T>
392Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> EigenFunctions::MVproduct(
393 const std::vector< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >> & A,
394 Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >>& C)
395{
396 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> out;
397 out = A[0] * C(0);
398
399 for (label i = 1; i < A.size(); i++)
400 {
401 out += A[i] * C(i);
402 }
403
404 return out;
405}
406
407
408
409template <typename T>
410List<Eigen::SparseMatrix<T >> EigenFunctions::MMproduct(
411 List<Eigen::SparseMatrix<T >>& A,
412 Eigen::DenseBase<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >> & C)
413{
414 List<Eigen::SparseMatrix<T >> out;
415 out.resize(C.cols());
416 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> col;
417
418 for (label i = 0; i < C.cols(); i++)
419 {
420 col = C.col(i);
421 out[i] = MVproduct(A, col);
422 }
423 return out;
424}
425
426template <typename T>
427T EigenFunctions::condNumber(Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>&
428 A)
429{
430 Eigen::JacobiSVD<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic >> svd(A);
431 T cond = svd.singularValues()(0) / svd.singularValues()(
432 svd.singularValues().size() - 1);
433 return cond;
434}
435
436// Additional Eigen Functions
437namespace Eigen
438{
439using namespace Eigen;
440
441template<typename VectorType>
442bool saveMarketVector (const VectorType & vec, const std::string & filename,
443 label prec, std::_Ios_Fmtflags outytpe = std::ios_base::scientific)
444{
445 typedef typename VectorType::Scalar Scalar;
446 std::ofstream out(filename.c_str(), std::ios::out);
447
448 if (!out)
449 {
450 return false;
451 }
452
453 out.flags(outytpe);
454 out.precision(prec);
455
456 if (internal::is_same<Scalar, std::complex<float >>::value
457 || internal::is_same<Scalar, std::complex<double >>::value)
458 {
459 out << "%%MatrixMarket matrix array complex general\n";
460 }
461 else
462 {
463 out << "%%MatrixMarket matrix array real general\n";
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 out.close();
472 return true;
473}
474
475template<typename VectorType>
476Matrix<VectorType, Dynamic, Dynamic> SliceFromTensor(
477 Eigen::Tensor<VectorType, 3>& tensor, label dim, label index1)
478{
479 Eigen::Tensor<VectorType, 2> t2 = tensor.chip(index1, dim);
480 Matrix<VectorType, Dynamic, Dynamic> m = Eigen::Map<Eigen::Matrix<
481 VectorType, /* scalar element type */
482 Eigen::Dynamic, /* num_rows is a run-time value */
483 Eigen::Dynamic, /* num_cols is a run-time value */
484 Eigen::ColMajor /* tensorflow::Tensor is always row-major */ >> (
485 t2.data(), /* ptr to data */
486 t2.dimensions()[0], /* num_rows */
487 t2.dimensions()[1] /* num_cols */);
488 return m;
489}
490
491template<typename VectorType>
492Matrix<VectorType, Dynamic, Dynamic> SliceFromTensor(
493 const Eigen::Tensor<VectorType, 3>& tensor, label dim, label index1)
494{
495 Eigen::Tensor<VectorType, 2> t2 = tensor.chip(index1, dim);
496 Matrix<VectorType, Dynamic, Dynamic> m = Eigen::Map<Eigen::Matrix<
497 VectorType, /* scalar element type */
498 Eigen::Dynamic, /* num_rows is a run-time value */
499 Eigen::Dynamic, /* num_cols is a run-time value */
500 Eigen::ColMajor /* tensorflow::Tensor is always row-major */ >> (
501 t2.data(), /* ptr to data */
502 t2.dimensions()[0], /* num_rows */
503 t2.dimensions()[1] /* num_cols */);
504 return m;
505}
506
507}
508
509
510
511
512
513#endif
514
515
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)
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)
singVal col(i)
dimensionedVector & g
label i
Definition pEqn.H:46