[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
rom_test_location.cpp
1 #include "rom_test_location.h"
2 #include <iostream>
3 #include <filesystem>
4 #include <deal.II/base/conditional_ostream.h>
5 #include <deal.II/lac/trilinos_sparse_matrix.h>
6 #include "parameters/all_parameters.h"
7 #include "pod_basis_base.h"
8 #include "reduced_order_solution.h"
9 #include "linear_solver/linear_solver.h"
10 #include <Epetra_Vector.h>
11 #include <EpetraExt_MatrixMatrix.h>
12 #include <Epetra_LinearProblem.h>
13 #include "Amesos.h"
14 #include <Amesos_Lapack.h>
15 #include "flow_solver/flow_solver.h"
16 #include "flow_solver/flow_solver_factory.h"
17 #include <deal.II/base/parameter_handler.h>
18 
19 namespace PHiLiP {
20 namespace ProperOrthogonalDecomposition {
21 
22 template <int dim, int nstate>
23 ROMTestLocation<dim, nstate>::ROMTestLocation(const RowVectorXd& parameter, std::unique_ptr<ROMSolution<dim, nstate>> rom_solution)
24  : TestLocationBase<dim, nstate>(parameter, std::move(rom_solution))
25 {
26 }
27 
28 template <int dim, int nstate>
30 
31  this->pcout << "Computing adjoint-based error estimate between initial ROM and updated ROM..." << std::endl;
32 
33  dealii::ParameterHandler dummy_handler;
34  std::unique_ptr<FlowSolver::FlowSolver<dim,nstate>> flow_solver = FlowSolver::FlowSolverFactory<dim,nstate>::select_flow_case(&this->rom_solution->params, dummy_handler);
35  flow_solver->dg->solution = this->rom_solution->solution;
36  const bool compute_dRdW = true;
37  flow_solver->dg->assemble_residual(compute_dRdW);
38 
39  const Epetra_CrsMatrix epetra_pod_basis = pod_updated->getPODBasis()->trilinos_matrix();
40  const Epetra_CrsMatrix epetra_system_matrix_transpose = flow_solver->dg->system_matrix_transpose.trilinos_matrix();
41 
42  Epetra_CrsMatrix epetra_petrov_galerkin_basis(Epetra_DataAccess::Copy, epetra_system_matrix_transpose.DomainMap(), pod_updated->getPODBasis()->n());
43  EpetraExt::MatrixMatrix::Multiply(epetra_system_matrix_transpose, true, epetra_pod_basis, false, epetra_petrov_galerkin_basis, true);
44 
45  Epetra_Vector epetra_gradient(epetra_pod_basis.RowMap());
46 
47  // Iterate over local indices and copy manually
48  for (unsigned int i = 0; i < this->rom_solution->gradient.local_size(); ++i){
49  epetra_gradient.ReplaceMyValue(static_cast<int>(i), 0, this->rom_solution->gradient.local_element(i));
50  }
51 
52  Epetra_Vector epetra_reduced_gradient(epetra_pod_basis.DomainMap());
53 
54  epetra_pod_basis.Multiply(true, epetra_gradient, epetra_reduced_gradient);
55 
56  Epetra_CrsMatrix epetra_reduced_jacobian_transpose(Epetra_DataAccess::Copy, epetra_petrov_galerkin_basis.DomainMap(), pod_updated->getPODBasis()->n());
57  EpetraExt::MatrixMatrix::Multiply(epetra_petrov_galerkin_basis, true, epetra_petrov_galerkin_basis, false, epetra_reduced_jacobian_transpose);
58 
59  Epetra_Vector epetra_reduced_adjoint(epetra_reduced_jacobian_transpose.DomainMap());
60  epetra_reduced_gradient.Scale(-1);
61  if (this->rom_solution->params.reduced_order_param.residual_error_bool == true){
62  epetra_reduced_adjoint.PutScalar(0);
63  }
64  else{
65  Epetra_LinearProblem linearProblem(&epetra_reduced_jacobian_transpose, &epetra_reduced_adjoint, &epetra_reduced_gradient);
66 
67  Amesos_Lapack Solver(linearProblem);
68 
69  Teuchos::ParameterList List;
70  Solver.SetParameters(List);
71  Solver.SymbolicFactorization();
72  Solver.NumericFactorization();
73  Solver.Solve();
74  }
75 
76  Epetra_Vector epetra_reduced_residual(epetra_petrov_galerkin_basis.DomainMap());
77  Epetra_Vector epetra_residual(Epetra_DataAccess::Copy, epetra_petrov_galerkin_basis.RangeMap(), const_cast<double *>(flow_solver->dg->right_hand_side.begin()));
78  epetra_petrov_galerkin_basis.Multiply(true, epetra_residual, epetra_reduced_residual);
79 
80  //Compute dual weighted residual
82  epetra_reduced_adjoint.Dot(epetra_reduced_residual, &this->initial_rom_to_final_rom_error);
84 
85  this->pcout << "Parameter: " << this->parameter << ". Error estimate between initial ROM and updated ROM: " << this->initial_rom_to_final_rom_error << std::endl;
86 }
87 
88 #if PHILIP_DIM==1
90 #endif
91 
92 #if PHILIP_DIM!=1
94 #endif
95 
96 }
97 }
ROMTestLocation(const RowVectorXd &parameter, std::unique_ptr< ROMSolution< dim, nstate >> rom_solution)
Constructor.
Base class for a ROM/HROM point, differences would be in the second DWR error indicator.
Files for the baseline physics.
Definition: ADTypes.hpp:10
Class to compute and store adjoint-based error estimates.
dealii::ConditionalOStream pcout
ConditionalOStream.
static std::unique_ptr< FlowSolver< dim, nstate > > select_flow_case(const Parameters::AllParameters *const parameters_input, const dealii::ParameterHandler &parameter_handler_input)
Factory to return the correct flow solver given input file.
double initial_rom_to_final_rom_error
Error from initial ROM to final ROM.
std::unique_ptr< ROMSolution< dim, nstate > > rom_solution
ROM solution.
Class to hold information about the reduced-order solution.
void compute_initial_rom_to_final_rom_error(std::shared_ptr< ProperOrthogonalDecomposition::PODBase< dim >> pod_updated) override
Compute error between initial ROM and final ROM.