1 #include <Epetra_RowMatrixTransposer.h> 6 #include <deal.II/distributed/tria.h> 7 #include <deal.II/distributed/grid_refinement.h> 9 #include <deal.II/grid/grid_generator.h> 10 #include <deal.II/grid/grid_tools.h> 12 #include <deal.II/numerics/vector_tools.h> 14 #include <deal.II/lac/solver_bicgstab.h> 15 #include <deal.II/lac/solver_cg.h> 16 #include <deal.II/lac/solver_gmres.h> 17 #include <deal.II/lac/solver_minres.h> 19 #include <deal.II/lac/full_matrix.h> 21 #include <deal.II/lac/trilinos_block_sparse_matrix.h> 22 #include <deal.II/lac/trilinos_precondition.h> 23 #include <deal.II/lac/trilinos_solver.h> 24 #include <deal.II/lac/trilinos_sparsity_pattern.h> 25 #include <deal.II/lac/trilinos_sparse_matrix.h> 27 #include <deal.II/lac/trilinos_parallel_block_vector.h> 28 #include <deal.II/lac/la_parallel_block_vector.h> 29 #include <deal.II/lac/read_write_vector.h> 31 #include <deal.II/lac/packaged_operation.h> 32 #include <deal.II/lac/trilinos_linear_operator.h> 34 #include "optimization_inverse_manufactured.h" 36 #include "physics/physics_factory.h" 37 #include "physics/physics.h" 38 #include "dg/dg_factory.hpp" 39 #include "ode_solver/ode_solver_factory.h" 41 #include "functional/target_functional.h" 42 #include "functional/adjoint.h" 44 #include "linear_solver/linear_solver.h" 46 #include "testing/full_space_optimization.h" 53 #define AMPLITUDE_OPT 0.1 55 #define HESSIAN_DIAG 1e0 59 dealii::Point<dim> reverse_deformation(dealii::Point<dim> point) {
60 dealii::Point<dim> new_point = point;
61 const double amplitude = AMPLITUDE_OPT;
62 double denom = amplitude;
64 denom *= std::sin(2.0*dealii::numbers::PI*point[1]);
67 denom *= std::sin(2.0*dealii::numbers::PI*point[2]);
70 new_point[0] /= denom;
74 dealii::Point<dim> target_deformation(dealii::Point<dim> point) {
75 const double amplitude = AMPLITUDE_OPT;
76 dealii::Tensor<1,dim,double> disp;
80 disp[0] *= std::sin(2.0*dealii::numbers::PI*point[1]);
83 disp[0] *= std::sin(2.0*dealii::numbers::PI*point[2]);
247 template <
int dim,
int nstate,
typename real>
264 const dealii::LinearAlgebra::distributed::Vector<real> &
target_solution,
271 template <
typename real2>
274 const dealii::Point<dim,real2> &,
275 const std::array<real2,nstate> &,
276 const std::array<real,nstate> &,
277 const std::array<dealii::Tensor<1,dim,real2>,nstate> &,
278 const std::array<dealii::Tensor<1,dim,real2>,nstate> &)
const 288 const dealii::Point<dim,real> &phys_coord,
289 const std::array<real,nstate> &soln_at_q,
290 const std::array<real,nstate> &target_soln_at_q,
291 const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_at_q,
292 const std::array<dealii::Tensor<1,dim,real>,nstate> &target_soln_grad_at_q)
const override 294 return evaluate_volume_integrand<>(physics, phys_coord, soln_at_q, target_soln_at_q, soln_grad_at_q, target_soln_grad_at_q);
299 const dealii::Point<dim,FadFadType> &phys_coord,
300 const std::array<FadFadType,nstate> &soln_at_q,
301 const std::array<real,nstate> &target_soln_at_q,
302 const std::array<dealii::Tensor<1,dim,FadFadType>,nstate> &soln_grad_at_q,
303 const std::array<dealii::Tensor<1,dim,FadFadType>,nstate> &target_soln_grad_at_q)
const override 305 return evaluate_volume_integrand<>(physics, phys_coord, soln_at_q, target_soln_at_q, soln_grad_at_q, target_soln_grad_at_q);
309 template <
int dim,
int nstate>
315 template <
int dim,
int nstate>
318 dealii::LinearAlgebra::distributed::Vector<double> solution_no_ghost;
324 template<
int dim,
int nstate>
328 const double amplitude = AMPLITUDE_OPT;
329 const int poly_degree = 1;
330 int fail_bool =
false;
331 pcout <<
" Running optimization case... " << std::endl;
337 const unsigned int initial_n_cells = 4;
340 using Triangulation = dealii::Triangulation<dim>;
342 using Triangulation = dealii::parallel::distributed::Triangulation<dim>;
345 std::shared_ptr <Triangulation> grid = std::make_shared<Triangulation> (
349 typename dealii::Triangulation<dim>::MeshSmoothing(
350 dealii::Triangulation<dim>::smoothing_on_refinement |
351 dealii::Triangulation<dim>::smoothing_on_coarsening));
353 dealii::GridGenerator::subdivided_hyper_cube(*grid, initial_n_cells);
354 for (
auto cell = grid->begin_active(); cell != grid->end(); ++cell) {
356 cell->set_material_id(9002);
357 for (
unsigned int face=0; face<dealii::GeometryInfo<dim>::faces_per_cell; ++face) {
358 if (cell->face(face)->at_boundary()) cell->face(face)->set_boundary_id (1000);
364 dg->allocate_system ();
366 std::shared_ptr<HighOrderGrid<dim,double>> high_order_grid = dg->high_order_grid;
368 high_order_grid->prepare_for_coarsening_and_refinement();
370 high_order_grid->execute_coarsening_and_refinement();
371 high_order_grid->output_results_vtk(high_order_grid->nth_refinement++);
377 std::vector<dealii::Tensor<1,dim,double>> point_displacements(high_order_grid->locally_relevant_surface_points.size());
378 const unsigned int n_locally_relevant_surface_nodes = dim * high_order_grid->locally_relevant_surface_points.size();
379 std::vector<dealii::types::global_dof_index> surface_node_global_indices(n_locally_relevant_surface_nodes);
380 std::vector<double> surface_node_displacements(n_locally_relevant_surface_nodes);
382 auto displacement = point_displacements.begin();
383 auto point = high_order_grid->locally_relevant_surface_points.begin();
384 auto point_end = high_order_grid->locally_relevant_surface_points.end();
385 for (;point != point_end; ++point, ++displacement) {
386 (*displacement)[0] = amplitude * (*point)[0];
388 (*displacement)[0] *= std::sin(2.0*dealii::numbers::PI*(*point)[1]);
391 (*displacement)[0] *= std::sin(2.0*dealii::numbers::PI*(*point)[2]);
395 for (
unsigned int ipoint=0; ipoint<point_displacements.size(); ++ipoint) {
396 for (
unsigned int d=0;d<dim;++d) {
397 const std::pair<unsigned int, unsigned int> point_axis = std::make_pair(ipoint,d);
398 const dealii::types::global_dof_index global_index = high_order_grid->point_and_axis_to_global_index[point_axis];
399 surface_node_global_indices[inode] = global_index;
400 surface_node_displacements[inode] = point_displacements[ipoint][d];
405 const auto initial_grid = high_order_grid->volume_nodes;
409 using VectorType = dealii::LinearAlgebra::distributed::Vector<double>;
410 std::function<dealii::Point<dim>(dealii::Point<dim>)> target_transformation = target_deformation<dim>;
411 VectorType surface_node_displacements_vector = high_order_grid->transform_surface_nodes(target_transformation);
412 surface_node_displacements_vector -= high_order_grid->surface_nodes;
413 surface_node_displacements_vector.update_ghost_values();
425 high_order_grid->volume_nodes += volume_displacements;
426 high_order_grid->volume_nodes.update_ghost_values();
427 high_order_grid->update_surface_nodes();
441 initialize_perturbed_solution(*dg, *physics_double);
442 dg->output_results_vtk(999);
443 high_order_grid->output_results_vtk(high_order_grid->nth_refinement++);
445 ode_solver->steady_state();
448 const auto target_solution = dg->solution;
449 const auto target_nodes = high_order_grid->volume_nodes;
451 pcout <<
"Target grid: " << std::endl;
452 dg->output_results_vtk(9999);
453 high_order_grid->output_results_vtk(9999);
459 auto displacement = point_displacements.begin();
460 auto point = high_order_grid->locally_relevant_surface_points.begin();
461 auto point_end = high_order_grid->locally_relevant_surface_points.end();
462 for (;point != point_end; ++point, ++displacement) {
463 if ((*point)[0] > 0.5 && (*point)[1] > 1e-10 && (*point)[1] < 1-1e-10) {
464 const double final_location = 1.0;
465 const double current_location = (*point)[0];
466 (*displacement)[0] = final_location - current_location;
473 for (
unsigned int ipoint=0; ipoint<point_displacements.size(); ++ipoint) {
474 for (
unsigned int d=0;d<dim;++d) {
475 const std::pair<unsigned int, unsigned int> point_axis = std::make_pair(ipoint,d);
476 const dealii::types::global_dof_index global_index = high_order_grid->point_and_axis_to_global_index[point_axis];
477 surface_node_global_indices[inode] = global_index;
478 surface_node_displacements[inode] = point_displacements[ipoint][d];
495 high_order_grid->volume_nodes = initial_grid;
496 high_order_grid->volume_nodes.update_ghost_values();
497 high_order_grid->update_surface_nodes();
498 pcout <<
"Initial grid: " << std::endl;
499 dg->output_results_vtk(9998);
500 high_order_grid->output_results_vtk(9998);
503 ode_solver->steady_state();
506 auto error_vector = dg->solution;
507 error_vector -= target_solution;
508 const double l2_vector_error = error_vector.l2_norm();
511 bool compute_dIdW =
false, compute_dIdX =
false, compute_d2I =
true;
512 const double current_l2_error = inverse_target_functional.
evaluate_functional(compute_dIdW, compute_dIdX, compute_d2I);
513 pcout <<
"Vector l2_norm of the coefficients: " << l2_vector_error << std::endl;
514 pcout <<
"Functional l2_norm : " << current_l2_error << std::endl;
516 pcout <<
"*************************************************************" << std::endl;
517 pcout <<
"Starting design... " << std::endl;
518 pcout <<
"Number of state variables: " << dg->dof_handler.n_dofs() << std::endl;
519 pcout <<
"Number of mesh volume_nodes: " << high_order_grid->dof_handler_grid.n_dofs() << std::endl;
520 pcout <<
"Number of constraints: " << dg->dof_handler.n_dofs() << std::endl;
522 const dealii::IndexSet surface_locally_owned_indexset = high_order_grid->surface_nodes.locally_owned_elements();
523 dealii::TrilinosWrappers::SparseMatrix dRdXs;
524 dealii::TrilinosWrappers::SparseMatrix d2LdWdXs;
525 dealii::TrilinosWrappers::SparseMatrix d2LdXsdXs;
530 dIdXs.reinit(dg->high_order_grid->surface_nodes);
532 auto grad_lagrangian = dIdXs;
535 dealii::LinearAlgebra::distributed::BlockVector<double> kkt_rhs(3);
536 pcout <<
"Evaluating KKT right-hand side: dIdW, dIdX, d2I, Residual..." << std::endl;
537 compute_dIdW =
true, compute_dIdX =
true, compute_d2I =
true;
538 (void) inverse_target_functional.
evaluate_functional(compute_dIdW, compute_dIdX, compute_d2I);
539 bool compute_dRdW =
false, compute_dRdX =
false, compute_d2R =
false;
540 dg->assemble_residual(compute_dRdW, compute_dRdX, compute_d2R);
541 for (
unsigned int isurf = 0; isurf < dg->high_order_grid->surface_nodes.size(); ++isurf) {
542 const auto scalar_product = meshmover.
dXvdXs[isurf] * inverse_target_functional.
dIdX;
543 if (dIdXs.locally_owned_elements().is_element(isurf)) {
544 dIdXs[isurf] = scalar_product;
547 dIdXs.update_ghost_values();
549 kkt_rhs.block(0) = inverse_target_functional.
dIdw;
550 kkt_rhs.block(1) = dIdXs;
551 kkt_rhs.block(2) = dg->right_hand_side;
554 dealii::LinearAlgebra::distributed::BlockVector<double> kkt_soln(3), p4inv_kkt_rhs(3);
555 kkt_soln.reinit(kkt_rhs);
556 p4inv_kkt_rhs.reinit(kkt_rhs);
558 auto mesh_error = target_nodes;
559 mesh_error -= high_order_grid->volume_nodes;
562 double current_kkt_norm = kkt_rhs.l2_norm();
563 double current_constraint_satisfaction = kkt_rhs.block(2).l2_norm();
564 double current_mesh_error = mesh_error.l2_norm();
565 pcout << std::scientific << std::setprecision(5);
566 pcout <<
"*************************************************************" << std::endl;
567 pcout <<
"Initial design " << std::endl;
568 pcout <<
"*************************************************************" << std::endl;
569 pcout <<
"Current functional: " << current_functional << std::endl;
570 pcout <<
"Constraint satisfaction: " << current_constraint_satisfaction << std::endl;
571 pcout <<
"l2norm(Current mesh - optimal mesh): " << current_mesh_error << std::endl;
572 pcout <<
"Current KKT norm: " << current_kkt_norm << std::endl;
575 const unsigned int n_des_var = high_order_grid->surface_nodes.size();
576 dealii::FullMatrix<double> Hessian_inverse = dealii::IdentityMatrix(n_des_var);
577 const double diagonal_hessian = HESSIAN_DIAG;
578 Hessian_inverse *= 1.0/diagonal_hessian;
579 dealii::Vector<double> oldg(n_des_var), currentg(n_des_var), searchD(n_des_var);
581 const bool use_BFGS =
true;
582 const unsigned int bfgs_max_history = n_des_var;
583 const unsigned int n_max_design = 1000;
584 const double kkt_tolerance = 1e-10;
587 dg->set_dual(kkt_soln.block(2));
589 std::list<VectorType> bfgs_search_s;
590 std::list<VectorType> bfgs_dgrad_y;
591 std::list<double> bfgs_denom_rho;
596 ode_solver->steady_state();
602 pcout <<
"Evaluating KKT right-hand side: dIdW, dIdX, Residual..." << std::endl;
603 bool compute_dIdW =
true, compute_dIdX =
true, compute_d2I =
false;
604 (void) inverse_target_functional.
evaluate_functional(compute_dIdW, compute_dIdX, compute_d2I);
605 compute_dRdW =
false, compute_dRdX =
false, compute_d2R =
false;
606 dg->assemble_residual(compute_dRdW, compute_dRdX, compute_d2R);
607 for (
unsigned int isurf = 0; isurf < dg->high_order_grid->surface_nodes.size(); ++isurf) {
609 const auto scalar_product = meshmover.
dXvdXs[isurf] * inverse_target_functional.
dIdX;
610 if (dIdXs.locally_owned_elements().is_element(isurf)) {
613 const unsigned int surface_index = high_order_grid->surface_to_volume_indices[isurf];
614 const unsigned int component = high_order_grid->global_index_to_point_and_axis[surface_index].second;
615 if (component != 0) dIdXs[isurf] = 0.0;
616 else dIdXs[isurf] = scalar_product;
619 dIdXs.update_ghost_values();
622 pcout <<
"Evaluating dRdW..." << std::endl;
623 compute_dRdW =
true, compute_dRdX =
false, compute_d2R =
false;
624 dg->assemble_residual(compute_dRdW, compute_dRdX, compute_d2R);
625 pcout <<
"Evaluating dRdX..." << std::endl;
626 compute_dRdW =
false; compute_dRdX =
true, compute_d2R =
false;
627 dg->assemble_residual(compute_dRdW, compute_dRdX, compute_d2R);
631 dealii::SparsityPattern sparsity_pattern_dRdXs = dg->get_dRdXs_sparsity_pattern ();
632 const dealii::IndexSet &row_parallel_partitioning_dRdXs = dg->locally_owned_dofs;
633 const dealii::IndexSet &col_parallel_partitioning_dRdXs = surface_locally_owned_indexset;
634 dRdXs.reinit(row_parallel_partitioning_dRdXs, col_parallel_partitioning_dRdXs, sparsity_pattern_dRdXs, mpi_communicator);
636 for (
unsigned int isurf = 0; isurf < high_order_grid->surface_nodes.size(); ++isurf) {
637 VectorType dRdXs_i(dg->solution);
638 dg->dRdXv.vmult(dRdXs_i,meshmover.
dXvdXs[isurf]);
639 for (
unsigned int irow = 0; irow < dg->dof_handler.n_dofs(); ++irow) {
640 if (dg->locally_owned_dofs.is_element(irow)) {
641 dRdXs.add(irow, isurf, dRdXs_i[irow]);
645 dRdXs.compress(dealii::VectorOperation::add);
648 auto dRdW_T = transpose_trilinos_matrix(dg->system_matrix);
651 solve_linear (dRdW_T, inverse_target_functional.
dIdw, dg->dual, linear_solver_param);
653 grad_lagrangian = dIdXs;
654 grad_lagrangian *= -1.0;
655 dRdXs.Tvmult_add(grad_lagrangian, dg->dual);
656 grad_lagrangian *= -1.0;
658 for (
unsigned int i_design = 0; i_design < n_max_design && current_kkt_norm > kkt_tolerance; i_design++) {
661 auto search_direction = grad_lagrangian;
662 if (use_BFGS && bfgs_search_s.size() > 0) {
663 search_direction = LBFGS(grad_lagrangian, bfgs_search_s, bfgs_dgrad_y, bfgs_denom_rho);
664 auto descent = search_direction * grad_lagrangian;
666 search_direction = grad_lagrangian;
667 bfgs_search_s.pop_front();
668 bfgs_dgrad_y.pop_front();
669 bfgs_denom_rho.pop_front();
672 search_direction *= -1.0;
673 pcout <<
"Gradient magnitude = " << grad_lagrangian.l2_norm() <<
" Search direction magnitude = " << search_direction.l2_norm() << std::endl;
674 for (
unsigned int isurf = 0; isurf < dg->high_order_grid->surface_nodes.size(); ++isurf) {
675 if (search_direction.locally_owned_elements().is_element(isurf)) {
677 const unsigned int surface_index = high_order_grid->surface_to_volume_indices[isurf];
678 const unsigned int component = high_order_grid->global_index_to_point_and_axis[surface_index].second;
679 if (component != 0) search_direction[isurf] = 0.0;
683 const auto old_solution = dg->solution;
684 const auto old_volume_nodes = high_order_grid->volume_nodes;
685 const auto old_surface_nodes = high_order_grid->surface_nodes;
686 const auto old_functional = current_functional;
689 double step_length = 1.0;
690 const unsigned int max_linesearch = 80;
691 unsigned int i_linesearch = 0;
692 for (; i_linesearch < max_linesearch; i_linesearch++) {
694 surface_node_displacements_vector = search_direction;
695 surface_node_displacements_vector *= step_length;
698 const auto disp_norm = surface_node_displacements_vector.l2_norm();
699 if (disp_norm > 1e-2) {
700 pcout <<
"Displacement of " << disp_norm <<
" too large. Reducing step length" << std::endl;
705 high_order_grid->volume_nodes += volume_displacements;
706 high_order_grid->volume_nodes.update_ghost_values();
707 high_order_grid->update_surface_nodes();
709 ode_solver->steady_state();
713 pcout <<
"Linesearch " << i_linesearch+1
714 << std::scientific << std::setprecision(15)
715 <<
" step = " << step_length
716 <<
" Old functional = " << old_functional
717 <<
" New functional = " << current_functional << std::endl;
718 pcout << std::fixed << std::setprecision(6);
720 const double wolfe_c = 1e-4;
721 double old_func_plus = search_direction*grad_lagrangian;
722 old_func_plus *= wolfe_c * step_length;
723 old_func_plus += old_functional;
725 if (current_functional < old_func_plus)
break;
728 dg->solution = old_solution;
729 high_order_grid->volume_nodes = old_volume_nodes;
730 high_order_grid->volume_nodes.update_ghost_values();
731 high_order_grid->update_surface_nodes();
734 if (i_linesearch == max_linesearch)
return 1;
740 pcout <<
"Evaluating KKT right-hand side: dIdW, dIdX, Residual..." << std::endl;
741 bool compute_dIdW =
true, compute_dIdX =
true, compute_d2I =
false;
742 (void) inverse_target_functional.
evaluate_functional(compute_dIdW, compute_dIdX, compute_d2I);
743 compute_dRdW =
false, compute_dRdX =
false, compute_d2R =
false;
744 dg->assemble_residual(compute_dRdW, compute_dRdX, compute_d2R);
745 for (
unsigned int isurf = 0; isurf < dg->high_order_grid->surface_nodes.size(); ++isurf) {
746 const auto scalar_product = meshmover.
dXvdXs[isurf] * inverse_target_functional.
dIdX;
747 if (dIdXs.locally_owned_elements().is_element(isurf)) {
749 const unsigned int surface_index = high_order_grid->surface_to_volume_indices[isurf];
750 const unsigned int component = high_order_grid->global_index_to_point_and_axis[surface_index].second;
751 if (component != 0) dIdXs[isurf] = 0.0;
752 else dIdXs[isurf] = scalar_product;
755 dIdXs.update_ghost_values();
758 pcout <<
"Evaluating dRdW..." << std::endl;
759 compute_dRdW =
true, compute_dRdX =
false, compute_d2R =
false;
760 dg->assemble_residual(compute_dRdW, compute_dRdX, compute_d2R);
761 pcout <<
"Evaluating dRdX..." << std::endl;
762 compute_dRdW =
false; compute_dRdX =
true, compute_d2R =
false;
763 dg->assemble_residual(compute_dRdW, compute_dRdX, compute_d2R);
767 dealii::SparsityPattern sparsity_pattern_dRdXs = dg->get_dRdXs_sparsity_pattern ();
768 const dealii::IndexSet &row_parallel_partitioning_dRdXs = dg->locally_owned_dofs;
769 const dealii::IndexSet &col_parallel_partitioning_dRdXs = surface_locally_owned_indexset;
770 dRdXs.reinit(row_parallel_partitioning_dRdXs, col_parallel_partitioning_dRdXs, sparsity_pattern_dRdXs, mpi_communicator);
772 for (
unsigned int isurf = 0; isurf < high_order_grid->surface_nodes.size(); ++isurf) {
773 VectorType dRdXs_i(dg->solution);
774 dg->dRdXv.vmult(dRdXs_i,meshmover.
dXvdXs[isurf]);
775 for (
unsigned int irow = 0; irow < dg->dof_handler.n_dofs(); ++irow) {
776 if (dg->locally_owned_dofs.is_element(irow)) {
777 dRdXs.add(irow, isurf, dRdXs_i[irow]);
781 dRdXs.compress(dealii::VectorOperation::add);
784 auto dRdW_T = transpose_trilinos_matrix(dg->system_matrix);
787 solve_linear (dRdW_T, inverse_target_functional.
dIdw, dg->dual, linear_solver_param);
789 const auto old_grad_lagrangian = grad_lagrangian;
790 grad_lagrangian = dIdXs;
791 grad_lagrangian *= -1.0;
792 dRdXs.Tvmult_add(grad_lagrangian, dg->dual);
793 grad_lagrangian *= -1.0;
797 auto s = search_direction;
799 const auto y = grad_lagrangian - old_grad_lagrangian;
800 const double curvature = s*y;
801 if (curvature > 0 && bfgs_max_history > 0) {
802 bfgs_denom_rho.push_front(1.0/curvature);
803 bfgs_search_s.push_front(s);
804 bfgs_dgrad_y.push_front(y);
807 if (bfgs_search_s.size() > bfgs_max_history) {
808 bfgs_search_s.pop_back();
809 bfgs_dgrad_y.pop_back();
810 bfgs_denom_rho.pop_back();
815 dg->output_results_vtk(high_order_grid->nth_refinement);
816 high_order_grid->output_results_vtk(high_order_grid->nth_refinement++);
818 mesh_error = target_nodes;
819 mesh_error -= high_order_grid->volume_nodes;
820 current_kkt_norm = grad_lagrangian.l2_norm();
821 current_constraint_satisfaction = dg->right_hand_side.l2_norm();
822 current_mesh_error = mesh_error.l2_norm();
823 pcout << std::scientific << std::setprecision(5);
824 pcout <<
"*************************************************************" << std::endl;
825 pcout <<
"Design iteration " << i_design+1 << std::endl;
826 pcout <<
"Current functional: " << current_functional << std::endl;
827 pcout <<
"Constraint satisfaction: " << current_constraint_satisfaction << std::endl;
828 pcout <<
"l2norm(Current mesh - optimal mesh): " << current_mesh_error << std::endl;
829 pcout <<
"Current KKT norm: " << current_kkt_norm << std::endl;
1070 pcout << std::endl << std::endl << std::endl << std::endl;
1072 high_order_grid->volume_nodes = target_nodes;
1073 high_order_grid->volume_nodes.update_ghost_values();
1074 high_order_grid->update_surface_nodes();
1076 ode_solver->steady_state();
1078 pcout <<
"Nodes at target volume_nodes should have zero functional l2 error : " << zero_l2_error << std::endl;
1079 if (zero_l2_error > 1e-10)
return 1;
1081 if (current_kkt_norm > kkt_tolerance)
return 1;
const bool uses_solution_gradient
Will evaluate solution gradient at quadrature points.
dealii::LinearAlgebra::distributed::Vector< real > dIdX
Vector for storing the derivatives with respect to each grid DoF.
TargetFunctional base class.
Parameters related to the linear solver.
const bool uses_solution_values
Will evaluate solution values at quadrature points.
dealii::LinearAlgebra::distributed::Vector< real > dIdw
Vector for storing the derivatives with respect to each solution DoF.
Base class from which Advection, Diffusion, ConvectionDiffusion, and Euler is derived.
const MPI_Comm mpi_communicator
MPI communicator.
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 ¶m)
Files for the baseline physics.
virtual real evaluate_functional(const bool compute_dIdW=false, const bool compute_dIdX=false, const bool compute_d2I=false) override
Evaluates the functional derivative with respect to the solution variable.
Main parameter class that contains the various other sub-parameter classes.
dealii::LinearAlgebra::distributed::Vector< double > solution
Current modal coefficients of the solution.
dealii::IndexSet locally_owned_dofs
Locally own degrees of freedom.
Sacado::Fad::DFad< real > FadType
Sacado AD type for first derivatives.
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
static std::shared_ptr< DGBase< dim, 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.
LinearSolverParam linear_solver_param
Contains parameters for linear solver.
const dealii::LinearAlgebra::distributed::Vector< real > target_solution
Solution used to evaluate target functional.
FadFadType evaluate_volume_integrand(const PHiLiP::Physics::PhysicsBase< dim, nstate, FadFadType > &physics, const dealii::Point< dim, FadFadType > &phys_coord, const std::array< FadFadType, nstate > &soln_at_q, const std::array< real, nstate > &target_soln_at_q, const std::array< dealii::Tensor< 1, dim, FadFadType >, nstate > &soln_grad_at_q, const std::array< dealii::Tensor< 1, dim, FadFadType >, nstate > &target_soln_grad_at_q) const override
non-template functions to override the template classes
real2 evaluate_volume_integrand(const PHiLiP::Physics::PhysicsBase< dim, nstate, real2 > &, const dealii::Point< dim, real2 > &, const std::array< real2, nstate > &, const std::array< real, nstate > &, const std::array< dealii::Tensor< 1, dim, real2 >, nstate > &, const std::array< dealii::Tensor< 1, dim, real2 >, nstate > &) const
Zero out the default inverse target volume functional.
VectorType get_volume_displacements()
real current_functional_value
Store the functional value from the last time evaluate_functional() was called.
static std::shared_ptr< PhysicsBase< dim, nstate, real > > create_Physics(const Parameters::AllParameters *const parameters_input, std::shared_ptr< ModelBase< dim, nstate, real > > model_input=nullptr)
Factory to return the correct physics given input file.
dealii::DoFHandler< dim > dof_handler
Finite Element Collection to represent the high-order grid.
Sacado::Fad::DFad< FadType > FadFadType
Sacado AD type that allows 2nd derivatives.
OptimizationInverseManufactured(const Parameters::AllParameters *const parameters_input)
Constructor.
int run_test() const override
Grid convergence on Euler Gaussian Bump.
dealii::ConditionalOStream pcout
ConditionalOStream.
Performs grid convergence for various polynomial degrees.
DGBase is independent of the number of state variables.
std::shared_ptr< ManufacturedSolutionFunction< dim, real > > manufactured_solution_function
Manufactured solution function.
static std::shared_ptr< ODESolverBase< dim, real, MeshType > > create_ODESolver(std::shared_ptr< DGBase< dim, real, MeshType > > dg_input)
Creates either implicit or explicit ODE solver based on parameter value(no POD basis given) ...
Base class of all the tests.
std::vector< dealii::LinearAlgebra::distributed::Vector< double > > dXvdXs
real evaluate_volume_integrand(const PHiLiP::Physics::PhysicsBase< dim, nstate, real > &physics, const dealii::Point< dim, real > &phys_coord, const std::array< real, nstate > &soln_at_q, const std::array< real, nstate > &target_soln_at_q, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_at_q, const std::array< dealii::Tensor< 1, dim, real >, nstate > &target_soln_grad_at_q) const override
non-template functions to override the template classes
BoundaryInverseTarget(std::shared_ptr< DGBase< dim, real >> dg_input, const dealii::LinearAlgebra::distributed::Vector< real > &target_solution, const bool uses_solution_values=true, const bool uses_solution_gradient=true)
Constructor.