1 #include "mesh_adaptation.h" 2 #include <deal.II/hp/refinement.h> 6 template <
int dim,
typename real,
typename MeshType>
9 , current_mesh_adaptation_cycle(0)
10 , mesh_adaptation_param(mesh_adaptation_param_input)
11 , pcout(
std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0)
17 template <
int dim,
typename real,
typename MeshType>
20 [[maybe_unused]]
unsigned int expected_size_of_cellwise_errors =
dg->triangulation->n_active_cells();
22 [[maybe_unused]]
unsigned int actual_size_of_cellwise_errors =
cellwise_errors.size();
23 AssertDimension(expected_size_of_cellwise_errors, actual_size_of_cellwise_errors);
31 template <
int dim,
typename real,
typename MeshType>
34 dealii::LinearAlgebra::distributed::Vector<real> old_solution(
dg->solution);
35 dealii::parallel::distributed::SolutionTransfer<dim, dealii::LinearAlgebra::distributed::Vector<real>, dealii::DoFHandler<dim>> solution_transfer(
dg->dof_handler);
36 solution_transfer.prepare_for_coarsening_and_refinement(old_solution);
37 dg->high_order_grid->prepare_for_coarsening_and_refinement();
39 if constexpr(dim == 1 || !std::is_same<MeshType, dealii::parallel::distributed::Triangulation<dim>>::value)
41 dealii::GridRefinement::refine_and_coarsen_fixed_number(*(
dg->high_order_grid->triangulation),
48 dealii::parallel::distributed::GridRefinement::refine_and_coarsen_fixed_number(*(
dg->high_order_grid->triangulation),
59 if(mesh_adaptation_type == MeshAdaptationTypeEnum::h_adaptation){
61 }
else if(mesh_adaptation_type == MeshAdaptationTypeEnum::p_adaptation){
62 dealii::hp::Refinement::p_adaptivity_fixed_number(
dg->dof_handler,
68 dealii::hp::Refinement::force_p_over_h(
dg->dof_handler);
69 }
else if(mesh_adaptation_type == MeshAdaptationTypeEnum::hp_adaptation){
74 dg->high_order_grid->triangulation->execute_coarsening_and_refinement();
75 dg->high_order_grid->execute_coarsening_and_refinement();
77 dg->allocate_system ();
78 dg->solution.zero_out_ghosts();
79 solution_transfer.interpolate(
dg->solution);
80 dg->solution.update_ghost_values();
81 dg->assemble_residual ();
84 template <
int dim,
typename real,
typename MeshType>
87 const auto mapping = (*(
dg->high_order_grid->mapping_fe_field));
88 dealii::hp::MappingCollection<dim> mapping_collection(mapping);
89 const dealii::UpdateFlags update_flags = dealii::update_values | dealii::update_JxW_values;
90 dealii::hp::FEValues<dim,dim> fe_values_collection_volume (mapping_collection,
dg->fe_collection,
dg->volume_quadrature_collection, update_flags);
92 std::vector< real > soln_coeff_high;
93 std::vector<dealii::types::global_dof_index> dof_indices;
95 for (
auto cell :
dg->dof_handler.active_cell_iterators()) {
96 if (!(cell->is_locally_owned() || cell->is_ghost()))
continue;
97 if(!cell->refine_flag_set())
continue;
100 const int i_fele = cell->active_fe_index();
101 const int i_quad = i_fele;
102 const int i_mapp = 0;
104 const dealii::FESystem<dim,dim> &fe_high =
dg->fe_collection[i_fele];
105 const unsigned int degree = fe_high.tensor_degree();
109 pcout<<
"Degree of the current cell is 0. Cannot compute smoothness indicator as we cannot interpolate to a lower polynomial order"<<std::endl;
113 const unsigned int nstate = fe_high.components;
114 const unsigned int n_dofs_high = fe_high.dofs_per_cell;
116 fe_values_collection_volume.reinit (cell, i_quad, i_mapp, i_fele);
117 const dealii::FEValues<dim,dim> &fe_values_volume = fe_values_collection_volume.get_present_fe_values();
119 dof_indices.resize(n_dofs_high);
120 cell->get_dof_indices (dof_indices);
122 soln_coeff_high.resize(n_dofs_high);
123 for (
unsigned int idof=0; idof<n_dofs_high; ++idof) {
124 soln_coeff_high[idof] =
dg->solution[dof_indices[idof]];
128 const unsigned int lower_degree = degree-1;
129 const dealii::FE_DGQLegendre<dim> fe_dgq_lower(lower_degree);
130 const dealii::FESystem<dim,dim> fe_lower(fe_dgq_lower, nstate);
133 const dealii::QGauss<dim> projection_quadrature(degree+5);
134 std::vector< real > soln_coeff_lower = project_function<dim, real>( soln_coeff_high, fe_high, fe_lower, projection_quadrature);
137 const dealii::Quadrature<dim> &quadrature = fe_values_volume.get_quadrature();
138 const std::vector<dealii::Point<dim,real>> &unit_quad_pts = quadrature.get_points();
140 const unsigned int n_quad_pts = quadrature.size();
141 const unsigned int n_dofs_lower = fe_lower.dofs_per_cell;
143 real element_volume = 0.0;
145 real soln_norm = 0.0;
146 std::vector<real> soln_high(nstate);
147 std::vector<real> soln_lower(nstate);
148 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
149 for (
unsigned int s=0; s<nstate; ++s) {
154 for (
unsigned int idof=0; idof<n_dofs_high; ++idof) {
155 const unsigned int istate = fe_high.system_to_component_index(idof).first;
156 soln_high[istate] += soln_coeff_high[idof] * fe_high.shape_value_component(idof,unit_quad_pts[iquad],istate);
159 for (
unsigned int idof=0; idof<n_dofs_lower; ++idof) {
160 const unsigned int istate = fe_lower.system_to_component_index(idof).first;
161 soln_lower[istate] += soln_coeff_lower[idof] * fe_lower.shape_value_component(idof,unit_quad_pts[iquad],istate);
164 element_volume += fe_values_volume.JxW(iquad);
166 for (
unsigned int s=0; s<1; ++s)
168 error += (soln_high[s] - soln_lower[s]) * (soln_high[s] - soln_lower[s]) * fe_values_volume.JxW(iquad);
169 soln_norm += soln_high[s] * soln_high[s] * fe_values_volume.JxW(iquad);
173 if (soln_norm < 1e-12)
178 real smoothness_sensor = error / soln_norm;
180 if(smoothness_sensor < mesh_adaptation_param->hp_smoothness_tolerance)
182 cell->clear_refine_flag();
183 cell->set_future_fe_index(cell->active_fe_index()+1);
void adapt_mesh()
Function to adapt the mesh based on input parameters.
const Parameters::MeshAdaptationParam *const mesh_adaptation_param
Holds parameters of mesh adaptation.
static std::unique_ptr< MeshErrorEstimateBase< dim, real, MeshType > > create_mesh_error(std::shared_ptr< DGBase< dim, real, MeshType > > dg)
Returns pointer of the mesh error's abstract class.
MeshAdaptation(std::shared_ptr< DGBase< dim, real, MeshType > > dg_input, const Parameters::MeshAdaptationParam *const mesh_adaptation_param_input)
Constructor to initialize the class with a pointer to DG.
Files for the baseline physics.
MeshAdaptationType mesh_adaptation_type
Selection of mesh adaptation type.
MeshAdaptationType
Choices for mesh adaptation to be used.
dealii::Vector< real > cellwise_errors
Stores errors in each cell.
std::unique_ptr< MeshErrorEstimateBase< dim, real, MeshType > > mesh_error
Pointer to the error estimator class.
std::shared_ptr< DGBase< dim, real, MeshType > > dg
Pointer to DGBase.
Parameters for Mesh Adaptation.
double h_coarsen_fraction
Fraction of cells to be h-coarsened.
dealii::ConditionalOStream pcout
Parallel std::cout.
void smoothness_sensor_based_hp_refinement()
Decide whether to perform h or p refinement based on a smoothness indicator.
int current_mesh_adaptation_cycle
Stores the current adaptation cycle.
DGBase is independent of the number of state variables.
double refine_fraction
Fraction of cells to be h or p-refined.
void fixed_fraction_isotropic_refinement_and_coarsening()
Performs fixed fraction refinement based on refinement and coarsening fractions.