[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
symmetric_KKT_hessian.cpp
1 #include <Epetra_RowMatrixTransposer.h>
2 
3 #include <deal.II/base/conditional_ostream.h>
4 
5 #include <deal.II/distributed/tria.h>
6 #include <deal.II/grid/grid_generator.h>
7 #include <deal.II/grid/grid_tools.h>
8 
9 #include <deal.II/numerics/vector_tools.h>
10 
11 #include "physics/physics_factory.h"
12 #include "parameters/all_parameters.h"
13 #include "dg/dg_factory.hpp"
14 #include "functional/functional.h"
15 
16 #include <deal.II/lac/full_matrix.h>
17 
18 #include <deal.II/lac/solver_bicgstab.h>
19 #include <deal.II/lac/solver_cg.h>
20 #include <deal.II/lac/solver_gmres.h>
21 #include <deal.II/lac/solver_minres.h>
22 
23 #include <deal.II/lac/block_sparsity_pattern.h>
24 
25 #include <deal.II/lac/precondition.h>
26 
27 #include <deal.II/lac/trilinos_block_sparse_matrix.h>
28 #include <deal.II/lac/trilinos_precondition.h>
29 #include <deal.II/lac/trilinos_solver.h>
30 #include <deal.II/lac/trilinos_sparsity_pattern.h>
31 #include <deal.II/lac/trilinos_sparse_matrix.h>
32 
33 #include <deal.II/lac/trilinos_parallel_block_vector.h>
34 #include <deal.II/lac/la_parallel_block_vector.h>
35 
36 
37 #include <deal.II/lac/packaged_operation.h>
38 #include <deal.II/lac/trilinos_linear_operator.h>
39 
40 #include <deal.II/lac/read_write_vector.h>
41 
42 const double STEPSIZE = 1e-7;
43 const double TOLERANCE = 1e-6;
44 
45 #if PHILIP_DIM==1
46  using Triangulation = dealii::Triangulation<PHILIP_DIM>;
47 #else
48  using Triangulation = dealii::parallel::distributed::Triangulation<PHILIP_DIM>;
49 #endif
50 
51 std::pair<unsigned int, double>
53  dealii::TrilinosWrappers::BlockSparseMatrix &matrix_A,
54  dealii::LinearAlgebra::distributed::BlockVector<double> &right_hand_side,
55  dealii::LinearAlgebra::distributed::BlockVector<double> &solution,
57 {
58 
59  {
60  using trilinos_vector_type = dealii::TrilinosWrappers::MPI::Vector;
61  using vector_type = dealii::LinearAlgebra::distributed::Vector<double>;
62 
63 
64  vector_type &_rhs1 = right_hand_side.block(0);
65  vector_type &_rhs2 = right_hand_side.block(1);
66 
67  dealii::IndexSet rhs1_locally_owned = _rhs1.locally_owned_elements();
68  dealii::IndexSet rhs1_ghost = _rhs1.get_partitioner()->ghost_indices();
69  //rhs1_locally_relevant.add_indices(_rhs1.get_partitioner()->ghost_indices());
70  dealii::IndexSet rhs2_locally_owned = _rhs2.locally_owned_elements();
71  dealii::IndexSet rhs2_ghost = _rhs2.get_partitioner()->ghost_indices();
72  //rhs2_locally_relevant.add_indices(_rhs2.get_partitioner()->ghost_indices());
73 
74  trilinos_vector_type rhs1(rhs1_locally_owned);
75  trilinos_vector_type rhs2(rhs2_locally_owned);
76  rhs1_locally_owned.print(std::cout);
77  std::cout << rhs1.size() << std::endl;
78  // trilinos_vector_type rhs1(rhs1_locally_owned, rhs1_ghost);
79  // trilinos_vector_type rhs2(rhs2_locally_owned, rhs2_ghost);
80  trilinos_vector_type soln1(_rhs1.locally_owned_elements());
81  trilinos_vector_type soln2(_rhs2.locally_owned_elements());
82 
83  {
84  dealii::LinearAlgebra::ReadWriteVector<double> rw_vector(rhs1_locally_owned);
85  rw_vector.import(_rhs1, dealii::VectorOperation::insert);
86  rhs1.import(rw_vector, dealii::VectorOperation::insert);
87  }
88  {
89  dealii::LinearAlgebra::ReadWriteVector<double> rw_vector(rhs2_locally_owned);
90  rw_vector.import(_rhs2, dealii::VectorOperation::insert);
91  rhs2.import(rw_vector, dealii::VectorOperation::insert);
92  }
93 
94  //vector_type &soln1 = solution.block(0);
95  //vector_type &soln2 = solution.block(1);
96 
97  using matrix_type = dealii::TrilinosWrappers::SparseMatrix;
98  using payload_type = dealii::TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload;
99 
100 
101  const auto &L11 = matrix_A.block(0,0);
102  const auto &L12 = matrix_A.block(0,1);
103  const auto &L21 = matrix_A.block(1,0);
104  const auto &L22 = matrix_A.block(1,1);
105 
106  const auto op_L11 = dealii::linear_operator<trilinos_vector_type,trilinos_vector_type,payload_type>(L11);
107  const auto op_L12 = dealii::linear_operator<trilinos_vector_type,trilinos_vector_type,payload_type>(L12);
108  const auto op_L21 = dealii::linear_operator<trilinos_vector_type,trilinos_vector_type,payload_type>(L21);
109  const auto op_L22 = dealii::linear_operator<trilinos_vector_type,trilinos_vector_type,payload_type>(L22);
110 
111  dealii::ReductionControl reduction_control_L11(2000, 1.0e-15, 1.0e-12);
112  dealii::SolverGMRES<trilinos_vector_type> solver_L11(reduction_control_L11);
113 
114  dealii::TrilinosWrappers::PreconditionILU preconditioner_L11;
115  //dealii::TrilinosWrappers::PreconditionIdentity preconditioner_L11;
116  preconditioner_L11.initialize(L11);
117  //const dealii::TrilinosWrappers::PreconditionBase &preconditioner_L11_base = preconditioner_L11;
118 
119  const auto op_L11_inv = dealii::inverse_operator(op_L11, solver_L11, preconditioner_L11);
120  const auto op_Schur = op_L22 - op_L21 * op_L11_inv * op_L12;
121 
122  const auto op_preconditioner_L11 = dealii::linear_operator<trilinos_vector_type,trilinos_vector_type,payload_type>(L11,preconditioner_L11);
123  const auto op_approxSchur = op_L22 - op_L21 * op_preconditioner_L11 * op_L12;
124 
125  const trilinos_vector_type schur_rhs = rhs2 - op_L21 * op_L11_inv * rhs1;
126  std::cout << reduction_control_L11.last_step() << " GMRES iterations to solve L11inv*rhs1." << std::endl;
127 
128  // Schur inverse preconditioner
129  // dealii::IterationNumberControl iteration_number_control_aS(300, 1.e-12);
130  // dealii::SolverGMRES<trilinos_vector_type> solver_approxSchur(iteration_number_control_aS);
131  // const auto preconditioner_Schur = dealii::inverse_operator(op_approxSchur, solver_approxSchur, dealii::PreconditionIdentity());
132  // //const auto preconditioner_Schur = dealii::PreconditionIdentity();
133 
134  dealii::TrilinosWrappers::SparseMatrix approxSchur;
135  const auto L11_rows = L11.locally_owned_range_indices();
136  trilinos_vector_type L11_diag_inv(L11_rows);
137  for (auto row = L11_rows.begin(); row != L11_rows.end(); ++row) {
138  L11_diag_inv[*row] = 1.0/L11.diag_element(*row);
139  }
140  L21.mmult(approxSchur, L12, L11_diag_inv);
141  approxSchur *= -1.0;
142  approxSchur.add(1.0,L22);
143  dealii::TrilinosWrappers::PreconditionILU preconditioner_Schur;
144  const unsigned int ilu_fill = 20, overlap = 1;
145  const double ilu_atol = 1e-5, ilu_rtol = 1e-2;
146  preconditioner_Schur.initialize(approxSchur, dealii::TrilinosWrappers::PreconditionILU::AdditionalData(ilu_fill,ilu_atol,ilu_rtol,overlap));
147 
148  // Schur inverse operator
149  dealii::SolverControl solver_control_Schur(2000, 1.e-15,true);
150  //dealii::ReductionControl solver_control_Schur(20000, 1.0e-15, 1.0e-12);
151  dealii::SolverGMRES<trilinos_vector_type> solver_Schur(solver_control_Schur,
152  dealii::SolverGMRES<trilinos_vector_type>::AdditionalData (2000, false, true, false) );
153  const auto op_Schur_inv = dealii::inverse_operator(op_Schur, solver_Schur, preconditioner_Schur);
154 
155  soln2 = op_Schur_inv * schur_rhs;
156  std::cout << solver_control_Schur.last_step() << " GMRES iterations to obtain convergence." << std::endl;
157  soln1 = op_L11_inv * (rhs1 - op_L12 * soln2);
158 
159  {
160  dealii::LinearAlgebra::ReadWriteVector<double> rw_vector;
161  rw_vector.reinit(soln1);
162  solution.block(0).import(rw_vector, dealii::VectorOperation::insert);
163  }
164  {
165  dealii::LinearAlgebra::ReadWriteVector<double> rw_vector;
166  rw_vector.reinit(soln2);
167  solution.block(1).import(rw_vector, dealii::VectorOperation::insert);
168  }
169 
170 
171  // int n_digits = 12;
172  // {
173  // dealii::FullMatrix<double> fullA(matrix_A.block(0,0).m(),matrix_A.block(0,0).n());
174  // fullA.copy_from(matrix_A.block(0,0));
175  // std::cout<<"Block 0,0 matrix:"<<std::endl;
176  // fullA.print_formatted(std::cout, n_digits, true, n_digits+7, "0", 1., 0.);
177  // }
178  // {
179  // dealii::FullMatrix<double> fullA(matrix_A.block(0,1).m(),matrix_A.block(0,1).n());
180  // fullA.copy_from(matrix_A.block(0,1));
181  // std::cout<<"Block 0,1 matrix:"<<std::endl;
182  // fullA.print_formatted(std::cout, n_digits, true, n_digits+7, "0", 1., 0.);
183  // }
184  // {
185  // dealii::FullMatrix<double> fullA(matrix_A.block(1,0).m(),matrix_A.block(1,0).n());
186  // fullA.copy_from(matrix_A.block(1,0));
187  // std::cout<<"Block 1,0 matrix:"<<std::endl;
188  // fullA.print_formatted(std::cout, n_digits, true, n_digits+7, "0", 1., 0.);
189  // }
190  // {
191  // dealii::FullMatrix<double> fullA(matrix_A.block(1,1).m(),matrix_A.block(1,1).n());
192  // fullA.copy_from(matrix_A.block(1,1));
193  // std::cout<<"Block 1,1 matrix:"<<std::endl;
194  // fullA.print_formatted(std::cout, n_digits, true, n_digits+7, "0", 1., 0.);
195  // }
196  // std::cout<<"rhs1:"<<std::endl;
197  // rhs1.print(std::cout, n_digits);
198  // std::cout<<"rhs2:"<<std::endl;
199  // rhs2.print(std::cout, n_digits);
200  // std::cout<<"soln1:"<<std::endl;
201  // soln1.print(std::cout, n_digits);
202  // std::cout<<"soln2:"<<std::endl;
203  // soln2.print(std::cout, n_digits);
204 
205  const trilinos_vector_type r1 = op_L11 * soln1 + op_L12 * soln2 - rhs1;
206  const trilinos_vector_type r2 = op_L21 * soln1 + op_L22 * soln2 - rhs2;
207 
208  std::cout<<"r1 norm: "<<r1.l2_norm()<<std::endl;
209  //r1.print(std::cout, n_digits);
210  std::cout<<"r2 norm: "<<r2.l2_norm()<<std::endl;
211  //r2.print(std::cout, n_digits);
212 
213  }
214  //{
215  // dealii::SolverControl solver_control(std::max<std::size_t>(100000, right_hand_side.size() / 10), 1e-10 * right_hand_side.l2_norm(), true, true);
216  // dealii::SolverGMRES<dealii::LinearAlgebra::distributed::BlockVector<double>> solver(solver_control);
217  // //dealii::PreconditionJacobi<dealii::TrilinosWrappers::BlockSparseMatrix<double>> preconditioner;
218  // //dealii::TrilinosWrappers::PreconditionJacobi<dealii::TrilinosWrappers::BlockSparseMatrix> preconditioner;
219  // //preconditioner.initialize(matrix_A, 1.0);
220  // solver.solve(matrix_A, solution, right_hand_side, dealii::PreconditionIdentity());
221  // dealii::LinearAlgebra::distributed::BlockVector<double> residual(right_hand_side);
222  // matrix_A.vmult(residual, solution);
223  // residual -= right_hand_side;
224  // std::cout << " Iterations required for convergence: "
225  // << solver_control.last_step() << '\n'
226  // << " Max norm of residual: "
227  // << residual.linfty_norm() << '\n';
228 
229  //}
230  return {-1.0, -1.0};
231 }
232 
234 template <int dim, int nspecies, int nstate, typename real>
235 class L2_Norm_Functional : public PHiLiP::Functional<dim, nspecies, nstate, real>
236 {
237  using FadType = Sacado::Fad::DFad<real>;
238  using FadFadType = Sacado::Fad::DFad<FadType>;
239 public:
242  std::shared_ptr<PHiLiP::DGBase<dim,nspecies,real>> dg_input,
243  const bool uses_solution_values = true,
244  const bool uses_solution_gradient = false)
245  : PHiLiP::Functional<dim,nspecies,nstate,real>(dg_input,uses_solution_values,uses_solution_gradient)
246  {}
247 
249  template <typename real2>
252  const dealii::Point<dim,real2> &phys_coord,
253  const std::array<real2,nstate> &soln_at_q,
254  const std::array<dealii::Tensor<1,dim,real2>,nstate> &/*soln_grad_at_q*/) const
255  {
256  real2 l2error = 0;
257 
258  for (int istate=0; istate<nstate; ++istate) {
259  const real2 uexact = physics.manufactured_solution_function->value(phys_coord, istate);
260  l2error += std::pow(soln_at_q[istate] - uexact, 2);
261  }
262 
263  return l2error;
264  }
265 
267 
268  template<typename real2>
271  const unsigned int /*boundary_id*/,
272  const dealii::Point<dim,real2> &phys_coord,
273  const dealii::Tensor<1,dim,real2> &/*normal*/,
274  const std::array<real2,nstate> &soln_at_q,
275  const std::array<dealii::Tensor<1,dim,real2>,nstate> &/*soln_grad_at_q*/) const
276  {
277  real2 l1error = 0;
278  for (int istate=0; istate<nstate; ++istate) {
279  const real2 uexact = physics.manufactured_solution_function->value(phys_coord, istate);
280  l1error += std::abs(soln_at_q[istate] - uexact);
281  }
282  return l1error;
283  }
284 
286 
289  const unsigned int boundary_id,
290  const dealii::Point<dim,real> &phys_coord,
291  const dealii::Tensor<1,dim,real> &normal,
292  const std::array<real,nstate> &soln_at_q,
293  const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_at_q) const override
294  {
295  return evaluate_boundary_integrand<real>(
296  physics,
297  boundary_id,
298  phys_coord,
299  normal,
300  soln_at_q,
301  soln_grad_at_q);
302  }
304 
307  const unsigned int boundary_id,
308  const dealii::Point<dim,FadFadType> &phys_coord,
309  const dealii::Tensor<1,dim,FadFadType> &normal,
310  const std::array<FadFadType,nstate> &soln_at_q,
311  const std::array<dealii::Tensor<1,dim,FadFadType>,nstate> &soln_grad_at_q) const override
312  {
313  return evaluate_boundary_integrand<FadFadType>(
314  physics,
315  boundary_id,
316  phys_coord,
317  normal,
318  soln_at_q,
319  soln_grad_at_q);
320  }
321 
322 
326  const dealii::Point<dim,real> &phys_coord,
327  const std::array<real,nstate> &soln_at_q,
328  const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_at_q) const override
329  {
330  return evaluate_volume_integrand<>(physics, phys_coord, soln_at_q, soln_grad_at_q);
331  }
335  const dealii::Point<dim,FadFadType> &phys_coord,
336  const std::array<FadFadType,nstate> &soln_at_q,
337  const std::array<dealii::Tensor<1,dim,FadFadType>,nstate> &soln_grad_at_q) const override
338  {
339  return evaluate_volume_integrand<>(physics, phys_coord, soln_at_q, soln_grad_at_q);
340  }
341 
342 };
343 
344 
345 template <int dim, int nspecies, int nstate>
347 {
348  dealii::LinearAlgebra::distributed::Vector<double> solution_no_ghost;
349  solution_no_ghost.reinit(dg.locally_owned_dofs, MPI_COMM_WORLD);
350  dealii::VectorTools::interpolate(dg.dof_handler, *physics.manufactured_solution_function, solution_no_ghost);
351  dg.solution = solution_no_ghost;
352 }
353 
354 int main(int argc, char *argv[])
355 {
356 
357  const int dim = PHILIP_DIM;
358  const int nspecies = 1;
359  const int nstate = 1;
360  int fail_bool = false;
361 
362  // Initializing MPI
363  dealii::Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
364  const int this_mpi_process = dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
365  dealii::ConditionalOStream pcout(std::cout, this_mpi_process==0);
366 
367  // Initializing parameter handling
368  dealii::ParameterHandler parameter_handler;
370  PHiLiP::Parameters::AllParameters all_parameters;
371  all_parameters.parse_parameters(parameter_handler);
372 
373  // polynomial order and mesh size
374  const unsigned poly_degree = 1;
375 
376  // creating the grid
377  std::shared_ptr<Triangulation> grid = std::make_shared<Triangulation>(
378 #if PHILIP_DIM!=1
379  MPI_COMM_WORLD,
380 #endif
381  typename dealii::Triangulation<dim>::MeshSmoothing(
382  dealii::Triangulation<dim>::smoothing_on_refinement |
383  dealii::Triangulation<dim>::smoothing_on_coarsening));
384 
385  const unsigned int n_refinements = 2;
386  double left = 0.0;
387  double right = 2.0;
388  const bool colorize = true;
389 
390  dealii::GridGenerator::hyper_cube(*grid, left, right, colorize);
391  grid->refine_global(n_refinements);
392  const double random_factor = 0.2;
393  const bool keep_boundary = false;
394  if (random_factor > 0.0) dealii::GridTools::distort_random (random_factor, *grid, keep_boundary);
395 
396  pcout << "Grid generated and refined" << std::endl;
397 
398  // creating the dg
399  std::shared_ptr < PHiLiP::DGBase<dim, nspecies, double> > dg = PHiLiP::DGFactory<dim,nspecies,double>::create_discontinuous_galerkin(&all_parameters, poly_degree, grid);
400  pcout << "dg created" << std::endl;
401 
402  dg->allocate_system();
403  pcout << "dg allocated" << std::endl;
404 
405  const int n_refine = 2;
406  for (int i=0; i<n_refine;i++) {
407  dg->high_order_grid->prepare_for_coarsening_and_refinement();
408  grid->prepare_coarsening_and_refinement();
409  unsigned int icell = 0;
410  for (auto cell = grid->begin_active(); cell!=grid->end(); ++cell) {
411  icell++;
412  if (!cell->is_locally_owned()) continue;
413  if (icell < grid->n_global_active_cells()/2) {
414  cell->set_refine_flag();
415  }
416  }
417  grid->execute_coarsening_and_refinement();
418  bool mesh_out = (i==n_refine-1);
419  dg->high_order_grid->execute_coarsening_and_refinement(mesh_out);
420  }
421  dg->allocate_system ();
422 
423  // manufactured solution function
424  std::shared_ptr <PHiLiP::Physics::PhysicsBase<dim,nspecies,nstate,double>> physics_double = PHiLiP::Physics::PhysicsFactory<dim, nspecies, nstate, double>::create_Physics(&all_parameters);
425  pcout << "Physics created" << std::endl;
426 
427  // performing the interpolation for the intial conditions
428  initialize_perturbed_solution(*dg, *physics_double);
429  pcout << "solution initialized" << std::endl;
430 
431  // evaluating the derivative (using SACADO)
432  pcout << std::endl << "Starting Hessian AD... " << std::endl;
433  L2_Norm_Functional<dim,nspecies,nstate,double> functional(dg,true,false);
434  const bool compute_dIdW = false, compute_dIdX = false, compute_d2I = true;
435  double functional_value = functional.evaluate_functional(compute_dIdW, compute_dIdX, compute_d2I);
436  (void) functional_value;
437 
438  // Evaluate residual Hessians
439  bool compute_dRdW, compute_dRdX, compute_d2R;
440 
441  pcout << "Evaluating RHS only to use as dual variables..." << std::endl;
442  compute_dRdW = false; compute_dRdX = false, compute_d2R = false;
443  dg->assemble_residual(compute_dRdW, compute_dRdX, compute_d2R);
444  dealii::LinearAlgebra::distributed::Vector<double> dummy_dual(dg->right_hand_side);
445  dg->set_dual(dummy_dual);
446 
447  pcout << "Evaluating RHS with d2R..." << std::endl;
448  compute_dRdW = true; compute_dRdX = false, compute_d2R = false;
449  dg->assemble_residual(compute_dRdW, compute_dRdX, compute_d2R);
450  compute_dRdW = false; compute_dRdX = true, compute_d2R = false;
451  dg->assemble_residual(compute_dRdW, compute_dRdX, compute_d2R);
452  compute_dRdW = false; compute_dRdX = false, compute_d2R = true;
453  dg->assemble_residual(compute_dRdW, compute_dRdX, compute_d2R);
454  dealii::LinearAlgebra::distributed::Vector<double> rhs_d2R(dg->right_hand_side);
455  // pcout << "*******************************************************************************" << std::endl;
456 
457  dealii::TrilinosWrappers::SparseMatrix dRdW_transpose;
458  {
459  Epetra_CrsMatrix *transpose_CrsMatrix;
460  Epetra_RowMatrixTransposer epmt(const_cast<Epetra_CrsMatrix *>(&dg->system_matrix.trilinos_matrix()));
461  epmt.CreateTranspose(false, transpose_CrsMatrix);
462  dRdW_transpose.reinit(*transpose_CrsMatrix);
463  }
464 
465  dealii::TrilinosWrappers::SparseMatrix dRdX_transpose;
466  {
467  Epetra_CrsMatrix *transpose_CrsMatrix;
468  Epetra_RowMatrixTransposer epmt(const_cast<Epetra_CrsMatrix *>(&dg->dRdXv.trilinos_matrix()));
469  epmt.CreateTranspose(false, transpose_CrsMatrix);
470  dRdX_transpose.reinit(*transpose_CrsMatrix);
471  }
472 
473  dealii::TrilinosWrappers::SparseMatrix d2RdXdW;
474  {
475  Epetra_CrsMatrix *transpose_CrsMatrix;
476  Epetra_RowMatrixTransposer epmt(const_cast<Epetra_CrsMatrix *>(&dg->d2RdWdX.trilinos_matrix()));
477  epmt.CreateTranspose(false, transpose_CrsMatrix);
478  d2RdXdW.reinit(*transpose_CrsMatrix);
479  }
480  dealii::TrilinosWrappers::SparseMatrix d2IdXdW;
481  {
482  Epetra_CrsMatrix *transpose_CrsMatrix;
483  Epetra_RowMatrixTransposer epmt(const_cast<Epetra_CrsMatrix *>(&functional.d2IdWdX->trilinos_matrix()));
484  epmt.CreateTranspose(false, transpose_CrsMatrix);
485  d2IdXdW.reinit(*transpose_CrsMatrix);
486  }
487 
488  // Form Lagrangian Hessian
489  functional.d2IdWdW->add(1.0,dg->d2RdWdW);
490  functional.d2IdWdX->add(1.0,dg->d2RdWdX);
491  d2IdXdW.add(1.0,d2RdXdW);
492  functional.d2IdXdX->add(1.0,dg->d2RdXdX);
493 
494 
495  // Block Sparsity pattern
496  // L_ww L_wx R_w^T
497  // L_xw L_xx R_x^T
498  // R_w R_x 0
499  // const unsigned int n_constraints = rhs_only.size();
500  // const unsigned int n_flow_var = dg->dof_handler.n_dofs();
501  // const unsigned int n_geom_var = dg->high_order_grid->dof_handler_grid.n_dofs();
502  //BlockDynamicSparsityPattern dsp(3, 3);
503  //dsp.block(0, 0).reinit(n_flow_var, n_flow_var);
504  //dsp.block(0, 1).reinit(n_flow_var, n_geom_var);
505  //dsp.block(0, 2).reinit(n_flow_var, n_constraints);
506 
507  //dsp.block(1, 0).reinit(n_geom_var, n_flow_var);
508  //dsp.block(1, 1).reinit(n_geom_var, n_geom_var);
509  //dsp.block(1, 2).reinit(n_geom_var, n_constraints);
510 
511  //dsp.block(2, 0).reinit(n_constraints, n_flow_var);
512  //dsp.block(2, 1).reinit(n_constraints, n_geom_var);
513  //dsp.block(2, 2).reinit(n_constraints, n_constraints);
514 
515  dealii::TrilinosWrappers::BlockSparseMatrix kkt_hessian;
516  kkt_hessian.reinit(3,3);
517  kkt_hessian.block(0, 0).copy_from( *functional.d2IdWdW);
518  kkt_hessian.block(0, 1).copy_from( *functional.d2IdWdX);
519  kkt_hessian.block(0, 2).copy_from( dRdW_transpose);
520 
521  kkt_hessian.block(1, 0).copy_from( d2IdXdW);
522  kkt_hessian.block(1, 1).copy_from( *functional.d2IdXdX);
523  kkt_hessian.block(1, 2).copy_from( dRdX_transpose);
524 
525  kkt_hessian.block(2, 0).copy_from( dg->system_matrix);
526  kkt_hessian.block(2, 1).copy_from( dg->dRdXv);
527  dealii::TrilinosWrappers::SparsityPattern zero_sparsity_pattern(dg->locally_owned_dofs, MPI_COMM_WORLD, 0);
528  //dealii::TrilinosWrappers::SparseMatrix zero_block;//(n_constraints, n_constraints, 0);
529  //zero_block.reinit(dg->locally_owned_dofs, zero_sparsity_pattern, MPI_COMM_WORLD);
530  // zero_block.reinit(dg->locally_owned_dofs);
531  // dealii::TrilinosWrappers::SparseMatrix zero_block(dg->locally_owned_dofs);
532  // kkt_hessian.block(2, 2).copy_from( zero_block );
533  zero_sparsity_pattern.compress();
534  kkt_hessian.block(2, 2).reinit(zero_sparsity_pattern);
535 
536  kkt_hessian.collect_sizes();
537 
538  pcout << "kkt_hessian.frobenius_norm() " << kkt_hessian.frobenius_norm() << std::endl;
539 
540  // const int n_mpi_processes = dealii::Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD);
541  // if (n_mpi_processes == 1) {
542  // dealii::FullMatrix<double> fullA(kkt_hessian.m());
543  // fullA.copy_from(kkt_hessian);
544  // pcout<<"d2IdWdW:"<<std::endl;
545  // if (pcout.is_active()) fullA.print_formatted(pcout.get_stream(), 3, true, 10, "0", 1., 0.);
546  // }
547 
548  dealii::LinearAlgebra::distributed::BlockVector<double> block_vector(3);
549  block_vector.block(0) = dg->solution;
550  block_vector.block(1) = dg->high_order_grid->volume_nodes;
551  block_vector.block(2) = dummy_dual;
552  dealii::LinearAlgebra::distributed::BlockVector<double> Hv(3);
553  dealii::LinearAlgebra::distributed::BlockVector<double> Htv(3);
554  Hv.reinit(block_vector);
555  Htv.reinit(block_vector);
556 
557  kkt_hessian.vmult(Hv,block_vector);
558  kkt_hessian.Tvmult(Htv,block_vector);
559 
560  Htv.sadd(-1.0, Hv);
561 
562  const double vector_norm = Hv.l2_norm();
563  const double vector_abs_diff = Htv.l2_norm();
564  const double vector_rel_diff = vector_abs_diff / vector_norm;
565 
566  const double tol = 1e-11;
567  pcout << "Error: "
568  << " vector_abs_diff: " << vector_abs_diff
569  << " vector_rel_diff: " << vector_rel_diff
570  << std::endl
571  << " vector_abs_diff: " << vector_abs_diff
572  << " vector_rel_diff: " << vector_rel_diff
573  << std::endl;
574  if (vector_abs_diff > tol && vector_rel_diff > tol) fail_bool = true;
575 
576  const int n_mpi_processes = dealii::Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD);
577  if (n_mpi_processes == 1) {
578  dealii::FullMatrix<double> fullA(kkt_hessian.m());
579  fullA.copy_from(kkt_hessian);
580  const int n_digits = 8;
581  if (pcout.is_active()) fullA.print_formatted(pcout.get_stream(), n_digits, true, n_digits+7, "0", 1., 0.);
582  }
583 
584  dealii::deallog.depth_console(3);
585  solve_linear (
586  kkt_hessian,
587  Hv, // b
588  Htv, // x
589  all_parameters.linear_solver_param);
590 
591  return fail_bool;
592 }
593 
std::shared_ptr< dealii::TrilinosWrappers::SparseMatrix > d2IdWdW
Sparse matrix for storing the functional partial second derivatives.
Definition: functional.h:124
Sacado::Fad::DFad< FadType > FadFadType
Sacado AD type that allows 2nd derivatives.
Parameters related to the linear solver.
Base class from which Advection, Diffusion, ConvectionDiffusion, and Euler is derived.
Definition: physics.h:34
std::pair< unsigned int, double > solve_linear(const dealii::TrilinosWrappers::SparseMatrix &system_matrix, dealii::LinearAlgebra::distributed::Vector< double > &right_hand_side, dealii::LinearAlgebra::distributed::Vector< double > &solution, const Parameters::LinearSolverParam &param)
std::shared_ptr< dealii::TrilinosWrappers::SparseMatrix > d2IdWdX
Sparse matrix for storing the functional partial second derivatives.
Definition: functional.h:126
real2 evaluate_volume_integrand(const PHiLiP::Physics::PhysicsBase< dim, nspecies, nstate, real2 > &physics, const dealii::Point< dim, real2 > &phys_coord, const std::array< real2, nstate > &soln_at_q, const std::array< dealii::Tensor< 1, dim, real2 >, nstate > &) const
Templated volume integrand.
Functional(std::shared_ptr< PHiLiP::DGBase< dim, nspecies, real, dealii::parallel::distributed::Triangulation< dim > >> _dg, const bool _uses_solution_values=true, const bool _uses_solution_gradient=true)
virtual real evaluate_boundary_integrand(const PHiLiP::Physics::PhysicsBase< dim, nspecies, nstate, real > &physics, const unsigned int boundary_id, const dealii::Point< dim, real > &phys_coord, const dealii::Tensor< 1, dim, real > &normal, const std::array< real, nstate > &soln_at_q, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_at_q) const override
Virtual function for computation of cell boundary functional term.
Files for the baseline physics.
Definition: ADTypes.hpp:10
std::shared_ptr< DGBase< dim, nspecies, real, dealii::parallel::distributed::Triangulation< dim > > > dg
Smart pointer to DGBase.
Definition: functional.h:50
std::shared_ptr< ManufacturedSolutionFunction< dim, nspecies, real > > manufactured_solution_function
Manufactured solution function.
Definition: physics.h:71
real evaluate_volume_integrand(const PHiLiP::Physics::PhysicsBase< dim, nspecies, nstate, real > &physics, const dealii::Point< dim, real > &phys_coord, const std::array< real, nstate > &soln_at_q, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_at_q) const override
non-template functions to override the template classes
Main parameter class that contains the various other sub-parameter classes.
virtual real evaluate_functional(const bool compute_dIdW=false, const bool compute_dIdX=false, const bool compute_d2I=false)
Evaluates the functional derivative with respect to the solution variable.
Definition: functional.cpp:794
dealii::DoFHandler< dim > dof_handler
Finite Element Collection to represent the high-order grid.
Definition: dg_base.hpp:1175
std::shared_ptr< dealii::TrilinosWrappers::SparseMatrix > d2IdXdX
Sparse matrix for storing the functional partial second derivatives.
Definition: functional.h:128
const bool uses_solution_values
Will evaluate solution values at quadrature points.
Definition: functional.h:314
LinearSolverParam linear_solver_param
Contains parameters for linear solver.
dealii::IndexSet locally_owned_dofs
Locally own degrees of freedom.
Definition: dg_base.hpp:398
const bool uses_solution_gradient
Will evaluate solution gradient at quadrature points.
Definition: functional.h:315
static std::shared_ptr< DGBase< dim, nspecies, real, MeshType > > create_discontinuous_galerkin(const Parameters::AllParameters *const parameters_input, const unsigned int degree, const unsigned int max_degree_input, const unsigned int grid_degree_input, const std::shared_ptr< Triangulation > triangulation_input)
Creates a derived object DG, but returns it as DGBase.
Definition: dg_factory.cpp:11
dealii::LinearAlgebra::distributed::Vector< double > solution
Current modal coefficients of the solution.
Definition: dg_base.hpp:409
L2_Norm_Functional(std::shared_ptr< PHiLiP::DGBase< dim, nspecies, real >> dg_input, const bool uses_solution_values=true, const bool uses_solution_gradient=false)
Constructor.
void parse_parameters(dealii::ParameterHandler &prm)
Retrieve parameters from dealii::ParameterHandler.
dealii::ConditionalOStream pcout
Parallel std::cout that only outputs on mpi_rank==0.
Definition: functional.h:317
Sacado::Fad::DFad< real > FadType
Sacado AD type for first derivatives.
static std::shared_ptr< PhysicsBase< dim, nspecies, nstate, real > > create_Physics(const Parameters::AllParameters *const parameters_input, std::shared_ptr< ModelBase< dim, nspecies, nstate, real > > model_input=nullptr)
Factory to return the correct physics given input file.
real2 evaluate_boundary_integrand(const PHiLiP::Physics::PhysicsBase< dim, nspecies, nstate, real2 > &physics, const unsigned int, const dealii::Point< dim, real2 > &phys_coord, const dealii::Tensor< 1, dim, real2 > &, const std::array< real2, nstate > &soln_at_q, const std::array< dealii::Tensor< 1, dim, real2 >, nstate > &) const
Virtual function for computation of cell boundary functional term.
FadFadType evaluate_volume_integrand(const PHiLiP::Physics::PhysicsBase< dim, nspecies, nstate, FadFadType > &physics, const dealii::Point< dim, FadFadType > &phys_coord, const std::array< FadFadType, nstate > &soln_at_q, const std::array< dealii::Tensor< 1, dim, FadFadType >, nstate > &soln_grad_at_q) const override
non-template functions to override the template classes
Functional base class.
Definition: functional.h:43
static void declare_parameters(dealii::ParameterHandler &prm)
Declare parameters that can be set as inputs and set up the default options.
DGBase is independent of the number of state variables.
Definition: dg_base.hpp:82
virtual FadFadType evaluate_boundary_integrand(const PHiLiP::Physics::PhysicsBase< dim, nspecies, nstate, FadFadType > &physics, const unsigned int boundary_id, const dealii::Point< dim, FadFadType > &phys_coord, const dealii::Tensor< 1, dim, FadFadType > &normal, const std::array< FadFadType, nstate > &soln_at_q, const std::array< dealii::Tensor< 1, dim, FadFadType >, nstate > &soln_grad_at_q) const override
Virtual function for Sacado computation of cell boundary functional term and derivatives.