[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
assemble_ECSW_residual.cpp
1 #include "assemble_ECSW_residual.h"
2 #include <iostream>
3 
4 #include "flow_solver/flow_solver.h"
5 #include "flow_solver/flow_solver_factory.h"
6 
7 namespace PHiLiP {
8 namespace HyperReduction {
9 using Eigen::MatrixXd;
10 
11 template <int dim, int nstate>
13  const PHiLiP::Parameters::AllParameters *const parameters_input,
14  const dealii::ParameterHandler &parameter_handler_input,
15  std::shared_ptr<DGBase<dim,double>> &dg_input,
16  std::shared_ptr<ProperOrthogonalDecomposition::PODBase<dim>> pod,
17  MatrixXd snapshot_parameters_input,
19  Epetra_MpiComm &Comm)
20  : AssembleECSWBase<dim, nstate>(parameters_input, parameter_handler_input, dg_input, pod, snapshot_parameters_input, ode_solver_type, Comm)
21 {
22 }
23 
24 template <int dim, int nstate>
26  this->pcout << "Solve for A and b for the NNLS Problem from POD Snapshots"<< std::endl;
27  MatrixXd snapshotMatrix = this->pod->getSnapshotMatrix();
28  const Epetra_CrsMatrix epetra_pod_basis = this->pod->getPODBasis()->trilinos_matrix();
29  Epetra_CrsMatrix epetra_system_matrix = this->dg->system_matrix.trilinos_matrix();
30 
31  // Get dimensions of the problem
32  int num_snaps_POD = snapshotMatrix.cols(); // Number of snapshots used to build the POD basis
33  int n_reduced_dim_POD = epetra_pod_basis.NumGlobalCols(); // Reduced subspace dimension
34  int N_FOM_dim = epetra_pod_basis.NumGlobalRows(); // Length of solution vector
35  int num_elements_N_e = this->dg->triangulation->n_active_cells(); // Number of elements (equal to N if there is one DOF per cell)
36 
37  // Create empty and temporary C and d structs
38  int training_snaps;
39  // Check if all or a subset of the snapshots will be used for training
41  this->pcout << "LIMITED NUMBER OF SNAPSHOTS"<< std::endl;
43  }
44  else{
45  training_snaps = num_snaps_POD;
46  }
47  const int rank = this->Comm_.MyPID();
48  const int n_quad_pts = this->dg->volume_quadrature_collection[this->all_parameters->flow_solver_param.poly_degree].size();
49  const int length = epetra_system_matrix.NumMyRows()/(nstate*n_quad_pts);
50  int *local_elements = new int[length];
51  int ctr = 0;
52  for (const auto &cell : this->dg->dof_handler.active_cell_iterators())
53  {
54  if (cell->is_locally_owned()){
55  local_elements[ctr] = cell->active_cell_index();
56  ctr +=1;
57  }
58  }
59  Epetra_Map RowMap((n_reduced_dim_POD*training_snaps), (n_reduced_dim_POD*training_snaps), 0, this->Comm_); // Number of rows in residual based training matrix = n * (number of training snapshots)
60  Epetra_Map ColMap(num_elements_N_e, length, local_elements, 0, this->Comm_);
61  Epetra_Map dMap((n_reduced_dim_POD*training_snaps), (rank == 0) ? (n_reduced_dim_POD*training_snaps) : 0, 0, this->Comm_);
62 
63  delete[] local_elements;
64 
65  Epetra_CrsMatrix C_T(Epetra_DataAccess::Copy, ColMap, RowMap, num_elements_N_e);
66  Epetra_Vector d(dMap);
67 
68  // Loop through the given number of training snapshots to find residuals
69  const unsigned int max_dofs_per_cell = this->dg->dof_handler.get_fe_collection().max_dofs_per_cell();
70  std::vector<dealii::types::global_dof_index> current_dofs_indices(max_dofs_per_cell);
71  int row_num = 0;
72  int snap_num = 0;
73  for(auto snap_param : this->snapshot_parameters.rowwise()){
74  this->pcout << "Snapshot Parameter Values" << std::endl;
75  this->pcout << snap_param << std::endl;
76 
77  // Modifiy parameters for snapshot location and create new flow solver
78  Parameters::AllParameters params = this->reinit_params(snap_param);
79  std::unique_ptr<FlowSolver::FlowSolver<dim,nstate>> flow_solver = FlowSolver::FlowSolverFactory<dim,nstate>::select_flow_case(&params, this->parameter_handler);
80  this->dg = flow_solver->dg;
81 
82  // Set solution to snapshot and re-compute the residual/Jacobian
83  this->dg->solution = this->fom_locations[snap_num];
84  const bool compute_dRdW = true;
85  this->dg->assemble_residual(compute_dRdW);
86  Epetra_Vector epetra_right_hand_side(Epetra_DataAccess::Copy, epetra_system_matrix.RowMap(), this->dg->right_hand_side.begin());
87  Epetra_Vector local_rhs = copy_vector_to_all_cores(epetra_right_hand_side);
88 
89  // Compute test basis
90  epetra_system_matrix = this->dg->system_matrix.trilinos_matrix();
91  std::shared_ptr<Epetra_CrsMatrix> epetra_test_basis = this->local_generate_test_basis(epetra_system_matrix, epetra_pod_basis);
92  Epetra_CrsMatrix local_test_basis = copy_matrix_to_all_cores(*epetra_test_basis);
93 
94  // Loop through the elements
95  for (const auto &cell : this->dg->dof_handler.active_cell_iterators())
96  {
97  if (cell->is_locally_owned()){
98  int cell_num = cell->active_cell_index();
99  const int fe_index_curr_cell = cell->active_fe_index();
100  const dealii::FESystem<dim,dim> &current_fe_ref = this->dg->fe_collection[fe_index_curr_cell];
101  const int n_dofs_curr_cell = current_fe_ref.n_dofs_per_cell();
102 
103  current_dofs_indices.resize(n_dofs_curr_cell);
104  cell->get_dof_indices(current_dofs_indices);
105 
106  // Create L_e matrix for current cell
107  const Epetra_SerialComm sComm;
108  Epetra_Map LeRowMap(n_dofs_curr_cell, 0, sComm);
109  Epetra_Map LeColMap(N_FOM_dim, 0, sComm);
110  Epetra_CrsMatrix L_e(Epetra_DataAccess::Copy, LeRowMap, LeColMap, 1);
111  double posOne = 1.0;
112 
113  for(int i = 0; i < n_dofs_curr_cell; i++){
114  const int col = current_dofs_indices[i];
115  L_e.InsertGlobalValues(i, 1, &posOne , &col);
116  }
117  L_e.FillComplete(LeColMap, LeRowMap);
118 
119  // Extract residual contributions of the current cell into global dimension
120  Epetra_Vector local_r(LeRowMap);
121  Epetra_Vector global_r_e(LeColMap);
122  L_e.Multiply(false, local_rhs, local_r);
123  L_e.Multiply(true, local_r, global_r_e);
124 
125  // Find reduced-order representation of contribution
126  Epetra_Map cseRowMap(n_reduced_dim_POD, 0, sComm);
127  Epetra_Vector c_se(cseRowMap);
128 
129  local_test_basis.Multiply(true, global_r_e, c_se);
130  double *c_se_array = new double[n_reduced_dim_POD];
131 
132  c_se.ExtractCopy(c_se_array);
133 
134  // Sub into entries of C and d
135  for (int k = 0; k < n_reduced_dim_POD; ++k){
136  int place = row_num+k;
137  C_T.InsertGlobalValues(cell_num, 1, &c_se_array[k], &place);
138  }
139  delete[] c_se_array;
140  }
141  }
142  row_num+=n_reduced_dim_POD;
143  snap_num+=1;
144 
145  // Check if number of training snapshots has been reached
147  this->pcout << "LIMITED NUMBER OF SNAPSHOTS"<< std::endl;
148  if (snap_num > (this->all_parameters->hyper_reduction_param.num_training_snaps-1)){
149  break;
150  }
151  }
152  }
153 
154  C_T.FillComplete(RowMap, ColMap);
155 
156  Epetra_CrsMatrix C_single = copy_matrix_to_all_cores(C_T);
157  for (int p = 0; p < num_elements_N_e; p++){
158  double *row = new double[C_single.NumGlobalCols()];
159  int *global_cols = new int[C_single.NumGlobalCols()];
160  int numE;
161  C_single.ExtractGlobalRowCopy(p, C_single.NumGlobalCols(), numE , row, global_cols);
162  for (int o = 0; o < dMap.NumMyElements(); o++){
163  int col = dMap.GID(o);
164  d.SumIntoMyValues(1, &row[col], &o);
165  }
166  delete[] row;
167  delete[] global_cols;
168  }
169 
170  // Sub temp C and d into class A and b
171  this->A_T->reinit(C_T);
172  this->b.reinit(dMap.NumMyElements());
173  for(int z = 0 ; z < dMap.NumMyElements() ; z++){
174  this->b(z) = d[z];
175  }
176 }
177 
178 #if PHILIP_DIM==1
180 #endif
181 
182 #if PHILIP_DIM!=1
184 #endif
185 
186 } // HyperReduction namespace
187 } // PHiLiP namespace
const dealii::ParameterHandler & parameter_handler
Parameter handler for storing the .prm file being ran.
std::vector< dealii::LinearAlgebra::distributed::Vector< double > > fom_locations
Vector of parameter-ROMTestLocation pairs.
FlowSolverParam flow_solver_param
Contains the parameters for simulation cases (flow solver test)
MatrixXd snapshot_parameters
Matrix of snapshot parameters.
std::shared_ptr< dealii::TrilinosWrappers::SparseMatrix > A_T
Matrix for the NNLS Problem.
Files for the baseline physics.
Definition: ADTypes.hpp:10
int num_training_snaps
Maximum number of snapshots in the ECSW training.
unsigned int poly_degree
Polynomial order (P) of the basis functions for DG.
Main parameter class that contains the various other sub-parameter classes.
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.
dealii::LinearAlgebra::ReadWriteVector< double > b
RHS Vector for the NNLS Problem.
std::shared_ptr< ProperOrthogonalDecomposition::PODBase< dim > > pod
POD.
Epetra_MpiComm Comm_
Epetra Communicator Object with MPI.
std::shared_ptr< Epetra_CrsMatrix > local_generate_test_basis(Epetra_CrsMatrix &system_matrix, const Epetra_CrsMatrix &pod_basis)
Generate Test Basis from the pod and snapshot info depending on the ode_solve_type (copied from the O...
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
std::shared_ptr< DGBase< dim, double > > dg
dg
dealii::ConditionalOStream pcout
ConditionalOStream.
DGBase is independent of the number of state variables.
Definition: dg_base.hpp:82
HyperReductionParam hyper_reduction_param
Contains parameters for Hyperreduction.
Parameters::AllParameters reinit_params(const RowVectorXd &parameter) const
Reinitialize parameters.
void build_problem() override
Fill entries of A and b.
AssembleECSWRes(const PHiLiP::Parameters::AllParameters *const parameters_input, const dealii::ParameterHandler &parameter_handler_input, std::shared_ptr< DGBase< dim, double >> &dg_input, std::shared_ptr< ProperOrthogonalDecomposition::PODBase< dim >> pod, MatrixXd snapshot_parameters_input, Parameters::ODESolverParam::ODESolverEnum ode_solver_type, Epetra_MpiComm &Comm)
Constructor.