[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
anisotropic_mesh_adaptation_cases.cpp
1 #include <stdlib.h>
2 #include <iostream>
3 #include "anisotropic_mesh_adaptation_cases.h"
4 #include "flow_solver/flow_solver_factory.h"
5 #include "mesh/mesh_adaptation/anisotropic_mesh_adaptation.h"
6 #include "mesh/mesh_adaptation/fe_values_shape_hessian.h"
7 #include <deal.II/grid/grid_in.h>
8 
9 namespace PHiLiP {
10 namespace Tests {
11 
12 template <int dim, int nstate>
14  const Parameters::AllParameters *const parameters_input,
15  const dealii::ParameterHandler &parameter_handler_input)
16  : TestsBase::TestsBase(parameters_input)
17  , parameter_handler(parameter_handler_input)
18 {}
19 
20 template <int dim, int nstate>
22 {
23  const auto mapping = (*(dg.high_order_grid->mapping_fe_field));
24  dealii::hp::MappingCollection<dim> mapping_collection(mapping);
25  const dealii::UpdateFlags update_flags = dealii::update_jacobian_pushed_forward_grads | dealii::update_inverse_jacobians;
26  dealii::hp::FEValues<dim,dim> fe_values_collection_volume (mapping_collection, dg.fe_collection, dg.volume_quadrature_collection, update_flags);
27 
28  dealii::MappingQGeneric<dim, dim> mapping2(dg.high_order_grid->dof_handler_grid.get_fe().degree);
29  dealii::hp::MappingCollection<dim> mapping_collection2(mapping2);
30  dealii::hp::FEValues<dim,dim> fe_values_collection_volume2 (mapping_collection2, dg.fe_collection, dg.volume_quadrature_collection, dealii::update_hessians);
31 
32  PHiLiP::FEValuesShapeHessian<dim> fe_values_shape_hessian;
33  for(const auto &cell : dg.dof_handler.active_cell_iterators())
34  {
35  if(! cell->is_locally_owned()) {continue;}
36 
37  const unsigned int i_fele = cell->active_fe_index();
38  const unsigned int i_quad = i_fele;
39  const unsigned int i_mapp = 0;
40  fe_values_collection_volume.reinit(cell, i_quad, i_mapp, i_fele);
41  fe_values_collection_volume2.reinit(cell, i_quad, i_mapp, i_fele);
42  const dealii::FEValues<dim,dim> &fe_values_volume = fe_values_collection_volume.get_present_fe_values();
43  const dealii::FEValues<dim,dim> &fe_values_volume2 = fe_values_collection_volume2.get_present_fe_values();
44 
45  const unsigned int n_dofs_cell = fe_values_volume.dofs_per_cell;
46  const unsigned int n_quad_pts = fe_values_volume.n_quadrature_points;
47  for(unsigned int iquad = 0; iquad < n_quad_pts; ++iquad)
48  {
49  fe_values_shape_hessian.reinit(fe_values_volume, iquad);
50 
51  for(unsigned int idof = 0; idof < n_dofs_cell; ++idof)
52  {
53  const unsigned int istate = fe_values_volume.get_fe().system_to_component_index(idof).first;
54  dealii::Tensor<2,dim,double> shape_hessian_dealii = fe_values_volume2.shape_hessian_component(idof, iquad, istate);
55 
56  dealii::Tensor<2,dim,double> shape_hessian_philip = fe_values_shape_hessian.shape_hessian_component(idof, iquad, istate, fe_values_volume.get_fe());
57 
58  dealii::Tensor<2,dim,double> shape_hessian_diff = shape_hessian_dealii;
59  shape_hessian_diff -= shape_hessian_philip;
60 
61  if(shape_hessian_diff.norm() > 1.0e-8)
62  {
63  std::cout<<"Dealii's FEValues shape_hessian = "<<shape_hessian_dealii<<std::endl;
64  std::cout<<"PHiLiP's FEValues shape_hessian = "<<shape_hessian_philip<<std::endl;
65  std::cout<<"Frobenius norm of diff = "<<shape_hessian_diff.norm()<<std::endl;
66  std::cout<<"Aborting.."<<std::endl<<std::flush;
67  std::abort();
68  }
69  } // idof
70  } // iquad
71  } // cell loop ends
72 
73  pcout<<"PHiLiP's physical shape hessian matches that computed by dealii."<<std::endl;
74 }
75 
76 template <int dim, int nstate>
78 {
79  std::shared_ptr< Functional<dim, nstate, double> > functional
80  = FunctionalFactory<dim,nstate,double>::create_Functional(dg->all_parameters->functional_param, dg);
81  return (functional->evaluate_functional());
82 }
83 
84 template <int dim, int nstate>
86 {
88 
89  std::unique_ptr<FlowSolver::FlowSolver<dim,nstate>> flow_solver = FlowSolver::FlowSolverFactory<dim,nstate>::select_flow_case(&param, parameter_handler);
90  const bool use_goal_oriented_approach = param.mesh_adaptation_param.use_goal_oriented_mesh_adaptation;
91  const double complexity = param.mesh_adaptation_param.mesh_complexity_anisotropic_adaptation;
92  const double normLp = param.mesh_adaptation_param.norm_Lp_anisotropic_adaptation;
93 
94  std::unique_ptr<AnisotropicMeshAdaptation<dim, nstate, double>> anisotropic_mesh_adaptation =
95  std::make_unique<AnisotropicMeshAdaptation<dim, nstate, double>> (flow_solver->dg, normLp, complexity, use_goal_oriented_approach);
96 
97  flow_solver->run();
98  const double functional_initial = evaluate_functional(flow_solver->dg);
99  const unsigned int n_adaptation_cycles = param.mesh_adaptation_param.total_mesh_adaptation_cycles;
100 
101  for(unsigned int cycle = 0; cycle < n_adaptation_cycles; ++cycle)
102  {
103  anisotropic_mesh_adaptation->adapt_mesh();
104  flow_solver->run();
105  }
106  const double functional_final = evaluate_functional(flow_solver->dg);
107 
108  verify_fe_values_shape_hessian(*(flow_solver->dg));
109 
110  const dealii::Point<dim> coordinates_of_highest_refined_cell = flow_solver->dg->coordinates_of_highest_refined_cell(false);
111 
112  pcout<<"Coordinates of highest refined cell = "<<coordinates_of_highest_refined_cell<<std::endl;
113 
114  dealii::Point<dim> expected_coordinates_of_highest_refined_cell;
115  for(unsigned int i=0; i < dim; ++i) {
116  expected_coordinates_of_highest_refined_cell[i] = 0.5;
117  }
118  const double distance_val = expected_coordinates_of_highest_refined_cell.distance(coordinates_of_highest_refined_cell);
119  pcout<<"Distance to the expected coordinates of the highest refined cell = "<<distance_val<<std::endl;
120 
121  int test_val = 0;
122  if(distance_val < 0.1) {return test_val;}// within a ball of radius 0.1
123  else
124  { // Check if functional error has decreased.
125  const double functional_exact = 0.5625;
126  const double error_initial = abs(functional_initial-functional_exact);
127  const double error_final = abs(functional_final-functional_exact);
128 
129  if( !(error_final < error_initial) ) {
130  pcout<<"Functional error has not decreased after adaptation. Test failed."<<std::endl;
131  pcout<<"error_initial = "<<error_initial<<std::endl;
132  pcout<<"error_final = "<<error_final<<std::endl;
133  test_val++;
134  }
135  }
136 
137  return test_val;
138 }
139 
140 //#if PHILIP_DIM==1
141 //template class AnisotropicMeshAdaptationCases <PHILIP_DIM,PHILIP_DIM>;
142 //#endif
143 
144 #if PHILIP_DIM==2
147 #endif
148 } // namespace Tests
149 } // namespace PHiLiP
150 
dealii::Tensor< 2, dim, double > shape_hessian_component(const unsigned int idof, const unsigned int iquad, const unsigned int istate, const dealii::FESystem< dim, dim > &fe_ref) const
Evaluates hessian of shape functions w.r.t. phyical quadrature points.
int total_mesh_adaptation_cycles
Total/maximum number of mesh adaptation cycles while solving a problem.
Files for the baseline physics.
Definition: ADTypes.hpp:10
Main parameter class that contains the various other sub-parameter classes.
MeshAdaptationParam mesh_adaptation_param
Constains parameters for mesh adaptation.
void reinit(const dealii::FEValues< dim, dim > &fe_values_volume, const unsigned int iquad)
Store inverse jacobian and 3rd order tensors which will be the same for a combination of cell/physica...
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.
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
Definition: tests.h:20
const dealii::ParameterHandler & parameter_handler
Parameter handler.
double norm_Lp_anisotropic_adaptation
Lp norm w.r.t. which the optimization is performed in the continuous mesh framework.
std::shared_ptr< HighOrderGrid< dim, real, MeshType > > high_order_grid
High order grid that will provide the MappingFEField.
Definition: dg_base.hpp:655
Class to evaluate hessians of shape functions w.r.t. physical quadrature points.
static std::shared_ptr< Functional< dim, nstate, real, MeshType > > create_Functional(PHiLiP::Parameters::AllParameters const *const param, std::shared_ptr< PHiLiP::DGBase< dim, real, MeshType > > dg)
Create standard functional object from constant parameter file.
dealii::DoFHandler< dim > dof_handler
Finite Element Collection to represent the high-order grid.
Definition: dg_base.hpp:652
double evaluate_functional(std::shared_ptr< DGBase< dim, double >> dg) const
Evaluates .
bool use_goal_oriented_mesh_adaptation
Flag to use goal oriented mesh adaptation.
dealii::ConditionalOStream pcout
ConditionalOStream.
Definition: tests.h:45
AnisotropicMeshAdaptationCases(const Parameters::AllParameters *const parameters_input, const dealii::ParameterHandler &parameter_handler_input)
Constructor.
double mesh_complexity_anisotropic_adaptation
Continuous equivalent of number of vertices/elements. Used in anisotropic mesh adaptation.
DGBase is independent of the number of state variables.
Definition: dg_base.hpp:82
void verify_fe_values_shape_hessian(const DGBase< dim, double > &dg) const
Checks PHiLiP::FEValuesShapeHessian for MappingFEField with dealii&#39;s shape hessian for MappingQGeneri...
dealii::hp::QCollection< dim > volume_quadrature_collection
Finite Element Collection to represent the high-order grid.
Definition: dg_base.hpp:608
const dealii::hp::FECollection< dim > fe_collection
Finite Element Collection for p-finite-element to represent the solution.
Definition: dg_base.hpp:597
Base class of all the tests.
Definition: tests.h:17
int run_test() const
Runs the test related to anisotropic mesh adaptation.