[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
pod_basis_online.cpp
1 #include "pod_basis_online.h"
2 #include <iostream>
3 #include <filesystem>
4 #include <deal.II/numerics/vector_tools.h>
5 #include <deal.II/lac/full_matrix.h>
6 #include <deal.II/lac/trilinos_sparse_matrix.h>
7 #include <deal.II/lac/vector_operation.h>
8 #include <deal.II/lac/la_parallel_vector.h>
9 #include <Teuchos_DefaultMpiComm.hpp>
10 #include <Epetra_CrsMatrix.h>
11 #include <Epetra_Map.h>
12 #include <eigen/Eigen/SVD>
13 
14 namespace PHiLiP {
15 namespace ProperOrthogonalDecomposition {
16 
17 template<int dim>
18 OnlinePOD<dim>::OnlinePOD(std::shared_ptr<dealii::TrilinosWrappers::SparseMatrix> _system_matrix)
19  : basis(std::make_shared<dealii::TrilinosWrappers::SparseMatrix>())
20  , system_matrix(_system_matrix)
21  , mpi_communicator(MPI_COMM_WORLD)
22  , mpi_rank(dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD))
23  , pcout(std::cout, mpi_rank==0)
24 {
25 }
26 
27 template <int dim>
28 void OnlinePOD<dim>::addSnapshot(dealii::LinearAlgebra::distributed::Vector<double> snapshot) {
29  pcout << "Adding new snapshot to snapshot matrix..." << std::endl;
30  dealii::LinearAlgebra::ReadWriteVector<double> read_snapshot(snapshot.size());
31  read_snapshot.import(snapshot, dealii::VectorOperation::values::insert);
32  VectorXd eigen_snapshot(snapshot.size());
33  for(unsigned int i = 0 ; i < snapshot.size() ; i++){
34  eigen_snapshot(i) = read_snapshot(i);
35  }
36  snapshotMatrix.conservativeResize(snapshot.size(), snapshotMatrix.cols()+1);
37  snapshotMatrix.col(snapshotMatrix.cols()-1) = eigen_snapshot;
38 
39  //Copy snapshot matrix to dealii Lapack matrix for easy printing to file
40  dealiiSnapshotMatrix.reinit(snapshotMatrix.rows(), snapshotMatrix.cols());
41  for (unsigned int m = 0; m < snapshotMatrix.rows(); m++) {
42  for (unsigned int n = 0; n < snapshotMatrix.cols(); n++) {
43  dealiiSnapshotMatrix.set(m, n, snapshotMatrix(m, n));
44  }
45  }
46 }
47 
48 template <int dim>
50  pcout << "Computing POD basis..." << std::endl;
51 
52  VectorXd reference_state = snapshotMatrix.rowwise().mean();
53 
54  referenceState.reinit(reference_state.size());
55  for(unsigned int i = 0 ; i < reference_state.size() ; i++){
56  referenceState(i) = reference_state(i);
57  }
58 
59  MatrixXd snapshotMatrixCentered = snapshotMatrix.colwise() - reference_state;
60 
61  Eigen::BDCSVD<MatrixXd, Eigen::DecompositionOptions::ComputeThinU> svd(snapshotMatrixCentered);
62  MatrixXd pod_basis = svd.matrixU();
63 
64  const Epetra_CrsMatrix epetra_system_matrix = system_matrix->trilinos_matrix();
65  Epetra_Map system_matrix_map = epetra_system_matrix.RowMap();
66  Epetra_CrsMatrix epetra_basis(Epetra_DataAccess::Copy, system_matrix_map, pod_basis.cols());
67 
68  const int numMyElements = system_matrix_map.NumMyElements(); //Number of elements on the calling processor
69 
70  for (int localRow = 0; localRow < numMyElements; ++localRow){
71  const int globalRow = system_matrix_map.GID(localRow);
72  for(int n = 0 ; n < pod_basis.cols() ; n++){
73  epetra_basis.InsertGlobalValues(globalRow, 1, &pod_basis(globalRow, n), &n);
74  }
75  }
76 
77  Epetra_MpiComm epetra_comm(MPI_COMM_WORLD);
78  Epetra_Map domain_map((int)pod_basis.cols(), 0, epetra_comm);
79 
80  epetra_basis.FillComplete(domain_map, system_matrix_map);
81 
82  basis->reinit(epetra_basis);
83 
84  pcout << "Done computing POD basis. Basis now has " << basis->n() << " columns." << std::endl;
85 }
86 
87 template <int dim>
88 std::shared_ptr<dealii::TrilinosWrappers::SparseMatrix> OnlinePOD<dim>::getPODBasis() {
89  return basis;
90 }
91 
92 template <int dim>
93 dealii::LinearAlgebra::ReadWriteVector<double> OnlinePOD<dim>::getReferenceState() {
94  return referenceState;
95 }
96 
97 template <int dim>
99  return snapshotMatrix;
100 }
101 
102 template class OnlinePOD <PHILIP_DIM>;
103 
104 }
105 }
Class for Online Proper Orthogonal Decomposition basis. This class takes snapshots on the fly and com...
dealii::LinearAlgebra::ReadWriteVector< double > getReferenceState() override
Function to get POD reference state.
std::shared_ptr< dealii::TrilinosWrappers::SparseMatrix > getPODBasis() override
Function to get POD basis for all derived classes.
dealii::LinearAlgebra::ReadWriteVector< double > referenceState
Reference state.
void addSnapshot(dealii::LinearAlgebra::distributed::Vector< double > snapshot)
Add snapshot.
Files for the baseline physics.
Definition: ADTypes.hpp:10
MatrixXd getSnapshotMatrix() override
Function to get snapshot matrix used to build POD basis.
OnlinePOD(std::shared_ptr< dealii::TrilinosWrappers::SparseMatrix > _system_matrix)
Constructor.
std::shared_ptr< dealii::TrilinosWrappers::SparseMatrix > system_matrix
For sparsity pattern of system matrix.
std::shared_ptr< dealii::TrilinosWrappers::SparseMatrix > basis
POD basis.
dealii::LAPACKFullMatrix< double > dealiiSnapshotMatrix
LAPACK matrix of snapshots for nice printing.
MatrixXd snapshotMatrix
Matrix containing snapshots.
dealii::ConditionalOStream pcout
ConditionalOStream.
void computeBasis()
Compute new POD basis from snapshots.