[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
grid_refinement_fixed_fraction.cpp
1 #include <deal.II/dofs/dof_tools.h>
2 
3 #include <deal.II/grid/grid_refinement.h>
4 #include <deal.II/distributed/grid_refinement.h>
5 
6 #include "grid_refinement/reconstruct_poly.h"
7 
8 #include "grid_refinement_fixed_fraction.h"
9 
10 namespace PHiLiP {
11 
12 namespace GridRefinement {
13 
14 template <int dim, int nstate, typename real, typename MeshType>
16 {
18  RefinementTypeEnum refinement_type = this->grid_refinement_param.refinement_type;
19 
20  // compute the error indicator, stored in this->indicator
21  error_indicator();
22 
23  // computing the smoothness_indicator only for the hp case
24  if(refinement_type == RefinementTypeEnum::hp){
25  smoothness_indicator();
26  }
27 
28  // setting up the solution transfer
29  dealii::IndexSet locally_owned_dofs, locally_relevant_dofs;
30  locally_owned_dofs = this->dg->dof_handler.locally_owned_dofs();
31  dealii::DoFTools::extract_locally_relevant_dofs(this->dg->dof_handler, locally_relevant_dofs);
32 
33  dealii::LinearAlgebra::distributed::Vector<double> solution_old(this->dg->solution);
34  solution_old.update_ghost_values();
35 
36  using VectorType = typename dealii::LinearAlgebra::distributed::Vector<double>;
37  using DoFHandlerType = typename dealii::DoFHandler<dim>;
38  using SolutionTransfer = typename MeshTypeHelper<MeshType>::template SolutionTransfer<dim,VectorType,DoFHandlerType>;
39 
40  SolutionTransfer solution_transfer(this->dg->dof_handler);
41  solution_transfer.prepare_for_coarsening_and_refinement(solution_old);
42 
43  this->dg->high_order_grid->prepare_for_coarsening_and_refinement();
44  this->dg->triangulation->prepare_coarsening_and_refinement();
45 
46  // performing the refinement
47  if(refinement_type == RefinementTypeEnum::h){
48  refine_grid_h();
49  }else if(refinement_type == RefinementTypeEnum::p){
50  refine_grid_p();
51  }else if(refinement_type == RefinementTypeEnum::hp){
52  refine_grid_hp();
53  }
54 
55  // optionally uncomment to flag all boundaries for refinement
56  // refine_boundary_h();
57 
58  std::cout << "Checking for aniso option" << std::endl;
59 
60  // check for anisotropic h-adaptation
61  if(this->grid_refinement_param.anisotropic){
62  std::cout << "beginning anistropic flagging" << std::endl;
63  anisotropic_h();
64  }
65 
66  this->tria->execute_coarsening_and_refinement();
67  this->dg->high_order_grid->execute_coarsening_and_refinement();
68 
69  // transfering the solution from solution_old
70  this->dg->allocate_system();
71  this->dg->solution.zero_out_ghosts();
72 
73  if constexpr (std::is_same_v<typename dealii::SolutionTransfer<dim,VectorType,DoFHandlerType>,
74  decltype(solution_transfer)>){
75  solution_transfer.interpolate(solution_old, this->dg->solution);
76  }else{
77  solution_transfer.interpolate(this->dg->solution);
78  }
79 
80  this->dg->solution.update_ghost_values();
81 
82  // increase the count
83  this->iteration++;
84 }
85 
86 template <int dim, int nstate, typename real, typename MeshType>
88 {
89  // Performing the call for refinement
90 // #if PHILIP_DIM==1
91  dealii::GridRefinement::refine_and_coarsen_fixed_number(
92  *(this->tria),
93  this->indicator,
94  this->grid_refinement_param.refinement_fraction,
95  this->grid_refinement_param.coarsening_fraction);
96 // #else
97 // dealii::parallel::distributed::GridRefinement::refine_and_coarsen_fixed_number(
98 // *(this->tria),
99 // this->indicator,
100 // this->grid_refinement_param.refinement_fraction,
101 // this->grid_refinement_param.coarsening_fraction);
102 // #endif
103 }
104 
105 template <int dim, int nstate, typename real, typename MeshType>
107 {
108  // flags cells using refine_grid_h, then loop over and replace any h refinement flags with a polynomial enrichment
109  refine_grid_h();
110  for(auto cell = this->dg->dof_handler.begin_active(); cell != this->dg->dof_handler.end(); ++cell)
111  if(cell->is_locally_owned())
112  if(cell->refine_flag_set()){
113  cell->clear_refine_flag();
114  if(cell->active_fe_index()+1 <= this->dg->max_degree)
115  cell->set_active_fe_index(cell->active_fe_index()+1);
116  }
117 }
118 
119 template <int dim, int nstate, typename real, typename MeshType>
121 {
122  // TODO: Same idea as above, except the switch in refine_grid_p
123  // now has to meet some tolerance, e.g. smoothness, jump
124  // will need to implement the choice between different methods here
125  // will start with an h_refinement call and then looping over flags
126  refine_grid_h();
127  for(auto cell = this->dg->dof_handler.begin_active(); cell != this->dg->dof_handler.end(); ++cell)
128  if(cell->is_locally_owned() && cell->active_fe_index()+1 <= this->dg->max_degree)
129  if(cell->refine_flag_set()){
130 
131  // perform the h/p decision making
132  assert(0); // NOT YET IMPLEMENTED
133  bool perform_p_refinement_instead = true;
134 
135  if(perform_p_refinement_instead)
136  {
137  cell->clear_refine_flag();
138  cell->set_active_fe_index(cell->active_fe_index()+1);
139  }
140  }
141 }
142 
143 template <int dim, int nstate, typename real, typename MeshType>
145 {
146  // setting refinement flag on all boundary cells of the dof_handler
147  for(auto cell = this->dg->dof_handler.begin_active(); cell != this->dg->dof_handler.end(); ++cell){
148  if(!cell->is_locally_owned()) continue;
149 
150  // looping over the faces to check if any are at the boundary
151  for(unsigned int face = 0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face){
152  if(cell->face(face)->at_boundary()){
153  cell->set_refine_flag();
154  break;
155  }
156  }
157  }
158 }
159 
160 template <int dim, int nstate, typename real, typename MeshType>
162 {
163  // reads the options and determines the proper smoothness indicator
164  smoothness.reinit(this->tria->n_active_cells());
165 
166  // NOT IMPLEMENTED
167  // cannot assert(0) as its still callled by the output function
168 
169  // placeholder function for future added hp-refinement threshold function
170 }
171 
172 template <int dim, int nstate, typename real, typename MeshType>
174 {
175  using AnisoIndicator = typename PHiLiP::Parameters::GridRefinementParam::AnisoIndicator;
176  AnisoIndicator aniso_indicator = this->grid_refinement_param.anisotropic_indicator;
177 
178  // selecting the anisotropic method to be used
179  if(aniso_indicator == AnisoIndicator::jump_based){
180  anisotropic_h_jump_based();
181  }else if(aniso_indicator == AnisoIndicator::reconstruction_based){
182  anisotropic_h_reconstruction_based();
183  }
184 }
185 
186 // based on dealii step-30
187 template <int dim, int nstate, typename real, typename MeshType>
189 {
190  const dealii::hp::MappingCollection<dim> mapping_collection(*(this->dg->high_order_grid->mapping_fe_field));
191  const dealii::hp::FECollection<dim> fe_collection(this->dg->fe_collection);
192  const dealii::hp::QCollection<dim-1> face_quadrature_collection(this->dg->face_quadrature_collection);
193 
194  dealii::hp::FEFaceValues<dim,dim> fe_values_collection_face_int(
195  mapping_collection,
196  fe_collection,
197  face_quadrature_collection,
198  this->face_update_flags);
199  dealii::hp::FEFaceValues<dim,dim> fe_values_collection_face_ext(
200  mapping_collection,
201  fe_collection,
202  face_quadrature_collection,
203  this->neighbor_face_update_flags);
204  dealii::hp::FESubfaceValues<dim,dim> fe_values_collection_subface(
205  mapping_collection,
206  fe_collection,
207  face_quadrature_collection,
208  this->face_update_flags);
209 
210  const dealii::LinearAlgebra::distributed::Vector<real> solution(this->dg->solution);
211  solution.update_ghost_values();
212 
213  real anisotropic_threshold_ratio = this->grid_refinement_param.anisotropic_threshold_ratio;
214 
215  for(auto cell = this->dg->dof_handler.begin_active(); cell != this->dg->dof_handler.end(); ++cell){
216  if(!(cell->is_locally_owned()) || !(cell->refine_flag_set())) continue;
217 
218  dealii::Point<dim> jump;
219  dealii::Point<dim> area;
220 
221  const unsigned int mapping_index = 0;
222  const unsigned int fe_index = cell->active_fe_index();
223  const unsigned int quad_index = fe_index;
224 
225  for(unsigned int iface = 0; iface < dealii::GeometryInfo<dim>::faces_per_cell; ++iface){
226  if(cell->face(iface)->at_boundary()) continue;
227 
228  const auto face = cell->face(iface);
229 
230  Assert(cell->neighbor(iface).state() == dealii::IteratorState::valid,
231  dealii::ExcInternalError());
232  const auto neig = cell->neighbor(iface);
233 
234  if(face->has_children()){
235  unsigned int neig2 = cell->neighbor_face_no(iface);
236  for(unsigned int subface = 0; subface < face->number_of_children(); ++subface){
237  const auto neig_child = cell->neighbor_child_on_subface(iface, subface);
238  Assert(!neig_child->has_children(), dealii::ExcInternalError());
239 
240  fe_values_collection_subface.reinit(cell,iface,subface,quad_index,mapping_index,fe_index);
241  const dealii::FESubfaceValues<dim,dim> &fe_int_subface = fe_values_collection_subface.get_present_fe_values();
242  std::vector<real> u_face(fe_int_subface.n_quadrature_points);
243  fe_int_subface.get_function_values(solution,u_face);
244 
245  fe_values_collection_face_ext.reinit(neig_child,neig2,quad_index,mapping_index,fe_index);
246  const dealii::FEFaceValues<dim,dim> &fe_ext_face = fe_values_collection_face_ext.get_present_fe_values();
247  std::vector<real> u_neig(fe_ext_face.n_quadrature_points);
248  fe_ext_face.get_function_values(solution,u_neig);
249 
250  const std::vector<real> &JxW = fe_int_subface.get_JxW_values();
251  for(unsigned int iquad = 0; iquad < fe_int_subface.n_quadrature_points; ++iquad){
252  jump[iface/2] += abs(u_face[iquad] - u_neig[iquad]) * JxW[iquad];
253  area[iface/2] += JxW[iquad];
254  }
255  }
256  }else{
257  if(!cell->neighbor_is_coarser(iface)){
258  unsigned int neig2 = cell->neighbor_of_neighbor(iface);
259 
260  fe_values_collection_face_int.reinit(cell,iface,quad_index,mapping_index,fe_index);
261  const dealii::FEFaceValues<dim,dim> &fe_int_face = fe_values_collection_face_int.get_present_fe_values();
262  std::vector<real> u_face(fe_int_face.n_quadrature_points);
263  fe_int_face.get_function_values(solution,u_face);
264 
265  fe_values_collection_face_ext.reinit(neig,neig2,quad_index,mapping_index,fe_index);
266  const dealii::FEFaceValues<dim,dim> &fe_ext_face = fe_values_collection_face_ext.get_present_fe_values();
267  std::vector<real> u_neig(fe_ext_face.n_quadrature_points);
268  fe_ext_face.get_function_values(solution,u_neig);
269 
270  const std::vector<real> &JxW = fe_int_face.get_JxW_values();
271  for(unsigned int iquad = 0; iquad < fe_int_face.n_quadrature_points; ++iquad){
272  jump[iface/2] += abs(u_face[iquad] - u_neig[iquad]) * JxW[iquad];
273  area[iface/2] += JxW[iquad];
274  }
275  }else{
276  std::pair<unsigned int, unsigned int> neig_face_subface = cell->neighbor_of_coarser_neighbor(iface);
277  Assert(neig_face_subface.first < dealii::GeometryInfo<dim>::faces_per_cell,
278  dealii::ExcInternalError());
279  Assert(neig_face_subface.second < neig->face(neig_face_subface.first)->number_of_children(),
280  dealii::ExcInternalError());
281  Assert(neig->neighbor_child_on_subface(neig_face_subface.first, neig_face_subface.second) == cell,
282  dealii::ExcInternalError());
283 
284  fe_values_collection_face_int.reinit(cell,iface,quad_index,mapping_index,fe_index);
285  const dealii::FEFaceValues<dim,dim> &fe_int_face = fe_values_collection_face_int.get_present_fe_values();
286  std::vector<real> u_face(fe_int_face.n_quadrature_points);
287  fe_int_face.get_function_values(solution,u_face);
288 
289  fe_values_collection_subface.reinit(neig,neig_face_subface.first,neig_face_subface.second,quad_index,mapping_index,fe_index);
290  const dealii::FESubfaceValues<dim,dim> &fe_ext_subface = fe_values_collection_subface.get_present_fe_values();
291  std::vector<real> u_neig(fe_ext_subface.n_quadrature_points);
292  fe_ext_subface.get_function_values(solution,u_neig);
293 
294  const std::vector<real> &JxW = fe_int_face.get_JxW_values();
295  for(unsigned int iquad = 0; iquad < fe_int_face.n_quadrature_points; ++iquad){
296  jump[iface/2] += abs(u_face[iquad] - u_neig[iquad]) * JxW[iquad];
297  area[iface/2] += JxW[iquad];
298  }
299  }
300  }
301  }
302 
303  std::array<real,dim> average_jumps;
304  real sum_of_average_jumps = 0.0;
305 
306  for(unsigned int i = 0; i < dim; ++i){
307  average_jumps[i] = jump[i]/area[i];
308  sum_of_average_jumps += average_jumps[i];
309  }
310 
311  for(unsigned int i = 0; i < dim; ++i)
312  if(average_jumps[i] > anisotropic_threshold_ratio * (sum_of_average_jumps - average_jumps[i]))
313  cell->set_refine_flag(dealii::RefinementCase<dim>::cut_axis(i));
314  }
315 }
316 
317 template <int dim, int nstate, typename real, typename MeshType>
319 {
320  // mapping
321  const dealii::hp::MappingCollection<dim> mapping_collection(*(this->dg->high_order_grid->mapping_fe_field));
322 
323  // using p+1 reconstruction
324  const unsigned int rel_order = 1;
325 
326  // generating object to reconstruct derivatives
327  ReconstructPoly<dim,nstate,real> reconstruct_poly(
328  this->dg->dof_handler,
329  mapping_collection,
330  this->dg->fe_collection,
331  this->dg->volume_quadrature_collection,
332  this->volume_update_flags);
333 
334  // call to reconstruct the derivatives
335  reconstruct_poly.reconstruct_chord_derivative(
336  this->dg->solution,
337  rel_order);
338 
339  // controls degree of anisotropy required to flag cell for cut in x
340  real anisotropic_threshold_ratio = this->grid_refinement_param.anisotropic_threshold_ratio;
341 
342  // looping over flagged cells to compute anisotropic indicators
343  for(auto cell = this->dg->dof_handler.begin_active(); cell != this->dg->dof_handler.end(); ++cell){
344  if(!(cell->is_locally_owned()) || !(cell->refine_flag_set())) continue;
345 
346  // vector of chord and midface positions
347  std::array<std::pair<dealii::Tensor<1,dim,real>, dealii::Tensor<1,dim,real>>,dim> chord_nodes;
348  std::array<dealii::Tensor<1,dim,real>,dim> chord_vec;
349 
350  // computing the chord associated with each
351  for(unsigned int vertex = 0; vertex < dealii::GeometryInfo<dim>::vertices_per_cell; ++vertex)
352  for(unsigned int i = 0; i < dim; ++i)
353  if(vertex % (unsigned int)pow(2,i) == 0){
354  chord_nodes[i].first += cell->vertex(vertex);
355  }else{
356  chord_nodes[i].second += cell->vertex(vertex);
357  }
358 
359  // averaging the nodes to get the coord
360  for(unsigned int i = 0; i < dim; ++i){
361  chord_nodes[i].first /= pow(2,dim-1);
362  chord_nodes[i].second /= pow(2,dim-1);
363  }
364 
365  // computing the vectors
366  for(unsigned int i = 0; i < dim; ++i){
367  chord_vec[i] = chord_nodes[i].second - chord_nodes[i].first;
368  }
369 
370  // computing the indicator scaled to the chord length
371  dealii::Tensor<1,dim,real> indicator;
372  for(unsigned int i = 0; i < dim; ++i)
373  indicator[i] += reconstruct_poly.derivative_value[cell->active_cell_index()][i] * pow(chord_vec[i].norm(), cell->active_fe_index()+rel_order);
374 
375  real sum = 0.0;
376  for(unsigned int i = 0; i < dim; ++i)
377  sum += indicator[i];
378 
379  // checking if it meets the criteria for anisotropy
380  // equivalent to the form used in jump_based indicator
381  for(unsigned int i = 0; i < dim; ++i)
382  if(indicator[i] / sum > anisotropic_threshold_ratio/(1.0 + anisotropic_threshold_ratio))
383  cell->set_refine_flag(dealii::RefinementCase<dim>::cut_axis(i));
384  }
385 }
386 
387 template <int dim, int nstate, typename real, typename MeshType>
389 {
390  // different cases depending on indicator types
392  if(this->error_indicator_type == ErrorIndicatorEnum::error_based){
393  error_indicator_error();
394  }else if(this->error_indicator_type == ErrorIndicatorEnum::hessian_based){
395  error_indicator_hessian();
396  }else if(this->error_indicator_type == ErrorIndicatorEnum::residual_based){
397  error_indicator_residual();
398  }else if(this->error_indicator_type == ErrorIndicatorEnum::adjoint_based){
399  error_indicator_adjoint();
400  }else{
401  std::cout << "Warning: error_indicator_type not recognized." << std::endl;
402  }
403 }
404 
405 template <int dim, int nstate, typename real, typename MeshType>
407 {
408  // TODO: update this to work with p-adaptive schemes (will need proper fe_values for each p)
409  // see dg.cpp
410  // const auto mapping = (*(high_order_grid.mapping_fe_field));
411  // dealii::hp::MappingCollection<dim> mapping_collection(mapping);
412  // dealii::hp::FEValues<dim,dim> fe_values_collection(mapping_collection, fe_collection, this->dg->volume_quadrature_collection, this->dg->volume_update_flags);
413 
414  // use manufactured solution to measure the cell-wise error (overintegrate)
415  int overintegrate = 10;
416  int poly_degree = this->dg->get_max_fe_degree();
417  dealii::QGauss<dim> quadrature(this->dg->max_degree+overintegrate);
418  dealii::FEValues<dim,dim> fe_values(*(this->dg->high_order_grid->mapping_fe_field), this->dg->fe_collection[poly_degree], quadrature,
419  dealii::update_values | dealii::update_JxW_values | dealii::update_quadrature_points);
420 
421  const unsigned int n_quad_pts = fe_values.n_quadrature_points;
422  std::array<double,nstate> soln_at_q;
423 
424  // norm to use
425  double norm_Lq = this->grid_refinement_param.norm_Lq;
426 
427  // storing the result in
428  std::vector<dealii::types::global_dof_index> dofs_indices(fe_values.dofs_per_cell);
429  this->indicator.reinit(this->tria->n_active_cells());
430  for(auto cell = this->dg->dof_handler.begin_active(); cell != this->dg->dof_handler.end(); ++cell){
431  if(!cell->is_locally_owned()) continue;
432 
433  fe_values.reinit(cell);
434  cell->get_dof_indices(dofs_indices);
435 
436  double cell_error = 0;
437  for(unsigned int iquad = 0; iquad < n_quad_pts; ++iquad){
438  std::fill(soln_at_q.begin(), soln_at_q.end(), 0);
439  for(unsigned int idof = 0; idof < fe_values.dofs_per_cell; ++idof){
440  const unsigned int istate = fe_values.get_fe().system_to_component_index(idof).first;
441  soln_at_q[istate] += this->dg->solution[dofs_indices[idof]] * fe_values.shape_value_component(idof,iquad,istate);
442  }
443 
444  const dealii::Point<dim> qpoint = (fe_values.quadrature_point(iquad));
445 
446  for(int istate = 0; istate < nstate; ++istate){
447  const double uexact = this->physics->manufactured_solution_function->value(qpoint,istate);
448  cell_error += pow(abs(soln_at_q[istate] - uexact), norm_Lq) * fe_values.JxW(iquad);
449  }
450  }
451  this->indicator[cell->active_cell_index()] = cell_error;
452  }
453 
454 }
455 
456 template <int dim, int nstate, typename real, typename MeshType>
458 {
459  // TODO: Feature based, should use the reconstructed next mode as an indicator
460 
461  // mapping
462  const dealii::hp::MappingCollection<dim> mapping_collection(*(this->dg->high_order_grid->mapping_fe_field));
463 
464  // using p+1 reconstruction
465  const unsigned int rel_order = 1;
466 
467  // call to the function to reconstruct the derivatives onto A
468  ReconstructPoly<dim,nstate,real> reconstruct_poly(
469  this->dg->dof_handler,
470  mapping_collection,
471  this->dg->fe_collection,
472  this->dg->volume_quadrature_collection,
473  this->volume_update_flags);
474 
475  reconstruct_poly.reconstruct_directional_derivative(
476  this->dg->solution,
477  rel_order);
478 
479  // looping over the vector and taking the product of the eigenvalues as the size measure
480  this->indicator.reinit(this->tria->n_active_cells());
481  for(auto cell = this->dg->dof_handler.begin_active(); cell < this->dg->dof_handler.end(); ++cell)
482  if(cell->is_locally_owned()){
483  // using an averaging scheme
484  // error indicator should relate to the cell-size to the power of p+1
485  // this->indicator[cell->active_cell_index()] = pow(cell->measure(), (cell->active_fe_index()+rel_order)/dim);
486  // for(unsigned int d = 0; d < dim; ++d)
487  // this->indicator[cell->active_cell_index()] *= A[cell->active_cell_index()][d];
488 
489  // using max value of the derivative
490  this->indicator[cell->active_cell_index()] = 0.0;
491  for(unsigned int d = 0; d < dim; ++d){
492 
493  // getting derivative value
494  real derivative_value = reconstruct_poly.derivative_value[cell->active_cell_index()][d];
495 
496  // check and update
497  if(this->indicator[cell->active_cell_index()] < derivative_value)
498  this->indicator[cell->active_cell_index()] = derivative_value;
499 
500  }
501 
502  this->indicator[cell->active_cell_index()] *= pow(cell->measure(), (cell->active_fe_index()+rel_order)/dim);
503  }
504 }
505 
506 template <int dim, int nstate, typename real, typename MeshType>
508 {
509  // NOT IMPLEMENTED
510  assert(0);
511 
512  // // projecting the solution to a finer (p) space
513  // // this->coarse_to_fine();
514 
515  // // compute the residual and take the Lq norm of each cell
516  // // TODO: get polynomial orders and corresponding FE_degree
517  // int overintegrate = 10;
518  // int poly_degree = 1;
519  // dealii::QGauss<dim> quadrature(this->dg->max_degree+overintegrate);
520  // dealii::FEValues<dim,dim> fe_values(*(this->dg->high_order_grid.mapping_fe_field), this->dg->fe_collection[poly_degree], quadrature,
521  // dealii::update_values | dealii::update_JxW_values | dealii::update_quadrature_points);
522 
523  // const unsigned int n_quad_pts = fe_values.n_quadrature_points;
524  // std::array<double,nstate> soln_at_q;
525 
526  // // norm to use
527  // double norm_Lq = this->grid_refinement_param.norm_Lq;
528 
529  // // storing the result in
530  // std::vector<dealii::types::global_dof_index> dofs_indices(fe_values.dofs_per_cell);
531  // this->indicator.reinit(this->tria->n_active_cells());
532  // for(auto cell = this->dg->dof_handler.begin_active(); cell != this->dg->dof_handler.end(); ++cell){
533  // if(!cell->is_locally_owned()) continue;
534 
535  // fe_values.reinit(cell);
536  // cell->get_dof_indices(dofs_indices);
537 
538  // double cell_error = 0;
539  // for(unsigned int iquad = 0; iquad < n_quad_pts; ++iquad){
540  // std::fill(soln_at_q.begin(), soln_at_q.end(), 0);
541  // for(unsigned int idof = 0; idof < fe_values.dofs_per_cell; ++idof){
542  // const unsigned int istate = fe_values.get_fe().system_to_component_index(idof).first;
543  // soln_at_q[istate] += this->dg->right_hand_side[dofs_indices[idof]] * fe_values.shape_value_component(idof,iquad,istate);
544  // }
545 
546  // for(int istate = 0; istate < nstate; ++istate)
547  // cell_error += pow(abs(soln_at_q[istate]), norm_Lq) * fe_values.JxW(iquad);
548  // }
549  // this->indicator[cell->active_cell_index()] = cell_error;
550  // }
551 
552  // // and projecting it back to the original space
553  // // this->fine_to_coarse();
554 }
555 
556 template <int dim, int nstate, typename real, typename MeshType>
558 {
559  // evaluating the functional derivatives and adjoint
561  this->adjoint->fine_grid_adjoint();
562 
563  // reinitializing the error indicator vector
564  this->indicator.reinit(this->adjoint->dg->triangulation->n_active_cells());
565  this->indicator = this->adjoint->dual_weighted_residual();
566 
567  // return to the coarse grid
569 }
570 
571 template <int dim, int nstate, typename real, typename MeshType>
572 std::vector< std::pair<dealii::Vector<real>, std::string> > GridRefinement_FixedFraction<dim,nstate,real,MeshType>::output_results_vtk_method()
573 {
574  std::vector< std::pair<dealii::Vector<real>, std::string> > data_out_vector;
575 
576  // error indicator for adaptation
577  error_indicator();
578  data_out_vector.push_back(
579  std::make_pair(
580  indicator,
581  "error_indicator"));
582 
583  smoothness_indicator();
584  data_out_vector.push_back(
585  std::make_pair(
586  indicator,
587  "smoothness_indicator"));
588 
589  return data_out_vector;
590 }
591 
592 // dealii::Triangulation<PHILIP_DIM>
598 
599 // dealii::parallel::shared::Triangulation<PHILIP_DIM>
605 
606 #if PHILIP_DIM != 1
607 // dealii::parallel::distributed::Triangulation<PHILIP_DIM>
613 #endif
614 
615 } // namespace GridRefinement
616 
617 } // namespace PHiLiP
void reconstruct_chord_derivative(const dealii::LinearAlgebra::distributed::Vector< real > &solution, const unsigned int rel_order)
Construct directional derivatives along the chords of the cell.
Polynomial Reconstruction Class.
ErrorIndicator
Types of error indicator to be used in the grid refinement.
void refine_grid() override
Perform call to the grid refinement object of choice.
Adjoint class.
Definition: adjoint.h:39
void error_indicator_error()
Compute error indicator based on Lq norm relative to exact manufactured solution. ...
void error_indicator()
Performs call to proper error indcator function based on type of error_indicator parameter.
void anisotropic_h_jump_based()
Sets anisotropic refinement flags for cells based on discontinuity between neighbors.
Files for the baseline physics.
Definition: ADTypes.hpp:10
void anisotropic_h_reconstruction_based()
Sets anisotropic refinement flags for cells based on directional derivatives reconstructed along the ...
void refine_grid_hp()
(NOT IMPLEMENTED) Based on error and smoothness indicator, perform fixed-fraction flagging and decisi...
void error_indicator_adjoint()
Compute error indicator for goal-oriented approach using a dual-weighted residual.
AnisoIndicator
Control of anisotropic splitting indicator to be used in fixed-fraction methods.
void reconstruct_directional_derivative(const dealii::LinearAlgebra::distributed::Vector< real > &solution, const unsigned int rel_order)
Construct the set of largest perpendicular directional derivatives.
std::vector< std::array< real, dim > > derivative_value
Derivative values.
void refine_grid_p()
Based on error indicator, performs fixed-fraction flagging for polynomial order enrichment.
void smoothness_indicator()
(NOT IMPLEMENTED) Computes smoothness indicator for -refinement decisions
void anisotropic_h()
Performs anisotropic adaptation of the mesh.
RefinementType
Controls the type of refinement to be performed.
std::vector< std::pair< dealii::Vector< real >, std::string > > output_results_vtk_method() override
Output refinement method dependent results.
void error_indicator_hessian()
Compute error indicator based on reconstructed directional derivatives.
void error_indicator_residual()
(NOT IMPLEMENTED) Compute error indicator based on fine grid residual distribution ...
void refine_boundary_h()
Flags the domain boundaries for refinement.
real1 norm(const dealii::Tensor< 1, dim, real1 > x)
Returns norm of dealii::Tensor<1,dim,real>
void refine_grid_h()
Based on error indicator, performs fixed-fraction flagging for element splitting. ...