libMesh::HPCoarsenTest Class Reference

#include <hp_coarsentest.h>

Inheritance diagram for libMesh::HPCoarsenTest:

Public Member Functions

 HPCoarsenTest ()
 
 HPCoarsenTest (const HPCoarsenTest &)=delete
 
HPCoarsenTestoperator= (const HPCoarsenTest &)=delete
 
 HPCoarsenTest (HPCoarsenTest &&)=default
 
HPCoarsenTestoperator= (HPCoarsenTest &&)=default
 
virtual ~HPCoarsenTest ()=default
 
virtual void select_refinement (System &system) override
 

Public Attributes

Real p_weight
 
std::vector< float > component_scale
 

Protected Member Functions

void add_projection (const System &, const Elem *, unsigned int var)
 

Protected Attributes

const Elemcoarse
 
std::vector< dof_id_typedof_indices
 
std::unique_ptr< FEBasefe
 
std::unique_ptr< FEBasefe_coarse
 
const std::vector< std::vector< Real > > * phi
 
const std::vector< std::vector< Real > > * phi_coarse
 
const std::vector< std::vector< RealGradient > > * dphi
 
const std::vector< std::vector< RealGradient > > * dphi_coarse
 
const std::vector< std::vector< RealTensor > > * d2phi
 
const std::vector< std::vector< RealTensor > > * d2phi_coarse
 
const std::vector< Real > * JxW
 
const std::vector< Point > * xyz_values
 
std::vector< Pointcoarse_qpoints
 
std::unique_ptr< QBaseqrule
 
DenseMatrix< NumberKe
 
DenseVector< NumberFe
 
DenseVector< NumberUc
 
DenseVector< NumberUp
 

Detailed Description

This class uses the error estimate given by different types of derefinement (h coarsening or p reduction) to choose between h refining and p elevation. Currently we assume that a set of elements has already been flagged for h refinement, and we may want to change some of those elements to be flagged for p refinement.

This code is currently experimental and will not produce optimal hp meshes without significant improvement.

Author
Roy H. Stogner
Date
2006

Definition at line 68 of file hp_coarsentest.h.

Constructor & Destructor Documentation

◆ HPCoarsenTest() [1/3]

libMesh::HPCoarsenTest::HPCoarsenTest ( )
inline

Constructor.

Definition at line 75 of file hp_coarsentest.h.

75  : p_weight(1.0)
76  {
77  libmesh_experimental();
78  }

◆ HPCoarsenTest() [2/3]

libMesh::HPCoarsenTest::HPCoarsenTest ( const HPCoarsenTest )
delete

This class cannot be (default) copy constructed/assigned because it has unique_ptr members. Explicitly deleting these functions is the best way to document this fact.

◆ HPCoarsenTest() [3/3]

libMesh::HPCoarsenTest::HPCoarsenTest ( HPCoarsenTest &&  )
default

Defaulted move ctor, move assignment operator, and destructor.

◆ ~HPCoarsenTest()

virtual libMesh::HPCoarsenTest::~HPCoarsenTest ( )
virtualdefault

Member Function Documentation

◆ add_projection()

void libMesh::HPCoarsenTest::add_projection ( const System system,
const Elem elem,
unsigned int  var 
)
protected

The helper function which adds individual fine element data to the coarse element projection

Definition at line 47 of file hp_coarsentest.C.

References libMesh::Elem::active(), libMesh::TypeVector< T >::add_scaled(), libMesh::TypeTensor< T >::add_scaled(), libMesh::C_ONE, libMesh::C_ZERO, libMesh::Elem::child_ref_range(), coarse, coarse_qpoints, libMesh::TypeTensor< T >::contract(), libMesh::System::current_solution(), d2phi, d2phi_coarse, dof_indices, libMesh::DofMap::dof_indices(), dphi, fe, Fe, fe_coarse, libMesh::System::get_dof_map(), libMesh::System::get_mesh(), libMesh::FEInterface::inverse_map(), Ke, libMesh::MeshBase::mesh_dimension(), phi_coarse, qrule, libMesh::DenseVector< T >::resize(), libMesh::DenseMatrix< T >::resize(), libMesh::DenseVector< T >::size(), libMesh::Elem::subactive(), Uc, libMesh::DofMap::variable_type(), xyz_values, libMesh::DenseMatrix< T >::zero(), libMesh::DenseVector< T >::zero(), and libMesh::zero.

Referenced by select_refinement().

50 {
51  // If we have children, we need to add their projections instead
52  if (!elem->active())
53  {
54  libmesh_assert(!elem->subactive());
55  for (auto & child : elem->child_ref_range())
56  this->add_projection(system, &child, var);
57  return;
58  }
59 
60  // The DofMap for this system
61  const DofMap & dof_map = system.get_dof_map();
62 
63  // The type of finite element to use for this variable
64  const FEType & fe_type = dof_map.variable_type (var);
65 
66  const FEContinuity cont = fe->get_continuity();
67 
68  fe->reinit(elem);
69 
70  dof_map.dof_indices(elem, dof_indices, var);
71 
72  const unsigned int n_dofs =
73  cast_int<unsigned int>(dof_indices.size());
74 
75  FEInterface::inverse_map (system.get_mesh().mesh_dimension(),
76  fe_type, coarse, *xyz_values, coarse_qpoints);
77 
78  fe_coarse->reinit(coarse, &coarse_qpoints);
79 
80  const unsigned int n_coarse_dofs =
81  cast_int<unsigned int>(phi_coarse->size());
82 
83  if (Uc.size() == 0)
84  {
85  Ke.resize(n_coarse_dofs, n_coarse_dofs);
86  Ke.zero();
87  Fe.resize(n_coarse_dofs);
88  Fe.zero();
89  Uc.resize(n_coarse_dofs);
90  Uc.zero();
91  }
92  libmesh_assert_equal_to (Uc.size(), phi_coarse->size());
93 
94  // Loop over the quadrature points
95  for (unsigned int qp=0; qp<qrule->n_points(); qp++)
96  {
97  // The solution value at the quadrature point
98  Number val = libMesh::zero;
99  Gradient grad;
100  Tensor hess;
101 
102  for (unsigned int i=0; i != n_dofs; i++)
103  {
104  dof_id_type dof_num = dof_indices[i];
105  val += (*phi)[i][qp] *
106  system.current_solution(dof_num);
107  if (cont == C_ZERO || cont == C_ONE)
108  grad.add_scaled((*dphi)[i][qp],system.current_solution(dof_num));
109  if (cont == C_ONE)
110  hess.add_scaled((*d2phi)[i][qp], system.current_solution(dof_num));
111  }
112 
113  // The projection matrix and vector
114  for (unsigned int i=0; i != Fe.size(); ++i)
115  {
116  Fe(i) += (*JxW)[qp] *
117  (*phi_coarse)[i][qp]*val;
118  if (cont == C_ZERO || cont == C_ONE)
119  Fe(i) += (*JxW)[qp] *
120  (grad*(*dphi_coarse)[i][qp]);
121  if (cont == C_ONE)
122  Fe(i) += (*JxW)[qp] *
123  hess.contract((*d2phi_coarse)[i][qp]);
124 
125  for (unsigned int j=0; j != Fe.size(); ++j)
126  {
127  Ke(i,j) += (*JxW)[qp] *
128  (*phi_coarse)[i][qp]*(*phi_coarse)[j][qp];
129  if (cont == C_ZERO || cont == C_ONE)
130  Ke(i,j) += (*JxW)[qp] *
131  (*dphi_coarse)[i][qp]*(*dphi_coarse)[j][qp];
132  if (cont == C_ONE)
133  Ke(i,j) += (*JxW)[qp] *
134  ((*d2phi_coarse)[i][qp].contract((*d2phi_coarse)[j][qp]));
135  }
136  }
137  }
138 }
virtual unsigned int size() const override
Definition: dense_vector.h:92
void add_projection(const System &, const Elem *, unsigned int var)
DenseVector< Number > Fe
std::unique_ptr< FEBase > fe_coarse
const std::vector< std::vector< Real > > * phi_coarse
void resize(const unsigned int n)
Definition: dense_vector.h:355
const Number zero
Definition: libmesh.h:239
const std::vector< Point > * xyz_values
DenseVector< Number > Uc
NumberVectorValue Gradient
static Point inverse_map(const unsigned int dim, const FEType &fe_t, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
Definition: fe_interface.C:590
std::unique_ptr< FEBase > fe
NumberTensorValue Tensor
virtual void zero() override
Definition: dense_matrix.h:808
void resize(const unsigned int new_m, const unsigned int new_n)
Definition: dense_matrix.h:792
const std::vector< std::vector< RealTensor > > * d2phi_coarse
const std::vector< std::vector< RealTensor > > * d2phi
const std::vector< std::vector< RealGradient > > * dphi
std::vector< dof_id_type > dof_indices
std::vector< Point > coarse_qpoints
std::unique_ptr< QBase > qrule
virtual void zero() override
Definition: dense_vector.h:379
uint8_t dof_id_type
Definition: id_types.h:64
DenseMatrix< Number > Ke

◆ operator=() [1/2]

HPCoarsenTest& libMesh::HPCoarsenTest::operator= ( const HPCoarsenTest )
delete

◆ operator=() [2/2]

HPCoarsenTest& libMesh::HPCoarsenTest::operator= ( HPCoarsenTest &&  )
default

◆ select_refinement()

void libMesh::HPCoarsenTest::select_refinement ( System system)
overridevirtual

This pure virtual function must be redefined in derived classes to take a mesh flagged for h refinement and potentially change the desired refinement type.

Implements libMesh::HPSelector.

Definition at line 140 of file hp_coarsentest.C.

References add_projection(), libMesh::TypeVector< T >::add_scaled(), libMesh::TypeTensor< T >::add_scaled(), libMesh::FEGenericBase< OutputType >::build(), libMesh::C_ONE, libMesh::C_ZERO, libMesh::DenseMatrix< T >::cholesky_solve(), coarse, coarse_qpoints, libMesh::HPSelector::component_scale, libMesh::TypeTensor< T >::contract(), libMesh::System::current_solution(), d2phi, d2phi_coarse, libMesh::FEType::default_quadrature_rule(), libMesh::DISCONTINUOUS, libMesh::Elem::DO_NOTHING, dof_indices, libMesh::DofMap::dof_indices(), libMesh::DofObject::dof_number(), dphi, dphi_coarse, libMesh::ErrorVectorReal, fe, Fe, fe_coarse, libMesh::System::get_dof_map(), libMesh::System::get_mesh(), libMesh::FEInterface::inverse_map(), JxW, Ke, libMesh::MeshRefinement::make_flags_parallel_consistent(), std::max(), mesh, libMesh::FEInterface::n_dofs(), n_nodes, n_vars, libMesh::System::n_vars(), libMesh::TensorTools::norm_sq(), libMesh::TypeVector< T >::norm_sq(), libMesh::TypeTensor< T >::norm_sq(), libMesh::System::number(), libMesh::FEType::order, libMesh::Elem::p_level(), p_weight, libMesh::Elem::parent(), phi, phi_coarse, qrule, libMesh::Real, libMesh::Elem::REFINE, libMesh::DenseVector< T >::resize(), libMesh::DenseMatrix< T >::resize(), libMesh::DenseVector< T >::size(), libMesh::TypeVector< T >::subtract_scaled(), libMesh::TypeTensor< T >::subtract_scaled(), Uc, Up, libMesh::DofMap::variable_type(), xyz_values, libMesh::DenseMatrix< T >::zero(), libMesh::DenseVector< T >::zero(), and libMesh::zero.

141 {
142  LOG_SCOPE("select_refinement()", "HPCoarsenTest");
143 
144  // The current mesh
145  MeshBase & mesh = system.get_mesh();
146 
147  // The dimensionality of the mesh
148  const unsigned int dim = mesh.mesh_dimension();
149 
150  // The number of variables in the system
151  const unsigned int n_vars = system.n_vars();
152 
153  // The DofMap for this system
154  const DofMap & dof_map = system.get_dof_map();
155 
156  // The system number (for doing bad hackery)
157  const unsigned int sys_num = system.number();
158 
159  // Check for a valid component_scale
160  if (!component_scale.empty())
161  {
162  if (component_scale.size() != n_vars)
163  libmesh_error_msg("ERROR: component_scale is the wrong size:\n" \
164  << " component_scale.size()=" \
165  << component_scale.size() \
166  << "\n n_vars=" \
167  << n_vars);
168  }
169  else
170  {
171  // No specified scaling. Scale all variables by one.
172  component_scale.resize (n_vars, 1.0);
173  }
174 
175  // Resize the error_per_cell vectors to handle
176  // the number of elements, initialize them to 0.
177  std::vector<ErrorVectorReal> h_error_per_cell(mesh.max_elem_id(), 0.);
178  std::vector<ErrorVectorReal> p_error_per_cell(mesh.max_elem_id(), 0.);
179 
180  // Loop over all the variables in the system
181  for (unsigned int var=0; var<n_vars; var++)
182  {
183  // Possibly skip this variable
184  if (!component_scale.empty())
185  if (component_scale[var] == 0.0) continue;
186 
187  // The type of finite element to use for this variable
188  const FEType & fe_type = dof_map.variable_type (var);
189 
190  // Finite element objects for a fine (and probably a coarse)
191  // element will be needed
192  fe = FEBase::build (dim, fe_type);
193  fe_coarse = FEBase::build (dim, fe_type);
194 
195  // Any cached coarse element results have expired
196  coarse = nullptr;
197  unsigned int cached_coarse_p_level = 0;
198 
199  const FEContinuity cont = fe->get_continuity();
200  libmesh_assert (cont == DISCONTINUOUS || cont == C_ZERO ||
201  cont == C_ONE);
202 
203  // Build an appropriate quadrature rule
204  qrule = fe_type.default_quadrature_rule(dim);
205 
206  // Tell the refined finite element about the quadrature
207  // rule. The coarse finite element need not know about it
208  fe->attach_quadrature_rule (qrule.get());
209 
210  // We will always do the integration
211  // on the fine elements. Get their Jacobian values, etc..
212  JxW = &(fe->get_JxW());
213  xyz_values = &(fe->get_xyz());
214 
215  // The shape functions
216  phi = &(fe->get_phi());
217  phi_coarse = &(fe_coarse->get_phi());
218 
219  // The shape function derivatives
220  if (cont == C_ZERO || cont == C_ONE)
221  {
222  dphi = &(fe->get_dphi());
223  dphi_coarse = &(fe_coarse->get_dphi());
224  }
225 
226  // The shape function second derivatives
227  if (cont == C_ONE)
228  {
229 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
230  d2phi = &(fe->get_d2phi());
231  d2phi_coarse = &(fe_coarse->get_d2phi());
232 #else
233  libmesh_error_msg("Minimization of H2 error without second derivatives is not possible.");
234 #endif
235  }
236 
237  // Iterate over all the active elements in the mesh
238  // that live on this processor.
239  for (const auto & elem : mesh.active_local_element_ptr_range())
240  {
241  // We're only checking elements that are already flagged for h
242  // refinement
243  if (elem->refinement_flag() != Elem::REFINE)
244  continue;
245 
246  const dof_id_type e_id = elem->id();
247 
248  // Find the projection onto the parent element,
249  // if necessary
250  if (elem->parent() &&
251  (coarse != elem->parent() ||
252  cached_coarse_p_level != elem->p_level()))
253  {
254  Uc.resize(0);
255 
256  coarse = elem->parent();
257  cached_coarse_p_level = elem->p_level();
258 
259  unsigned int old_parent_level = coarse->p_level();
260  (const_cast<Elem *>(coarse))->hack_p_level(elem->p_level());
261 
262  this->add_projection(system, coarse, var);
263 
264  (const_cast<Elem *>(coarse))->hack_p_level(old_parent_level);
265 
266  // Solve the h-coarsening projection problem
268  }
269 
270  fe->reinit(elem);
271 
272  // Get the DOF indices for the fine element
273  dof_map.dof_indices (elem, dof_indices, var);
274 
275  // The number of quadrature points
276  const unsigned int n_qp = qrule->n_points();
277 
278  // The number of DOFS on the fine element
279  const unsigned int n_dofs =
280  cast_int<unsigned int>(dof_indices.size());
281 
282  // The number of nodes on the fine element
283  const unsigned int n_nodes = elem->n_nodes();
284 
285  // The average element value (used as an ugly hack
286  // when we have nothing p-coarsened to compare to)
287  // Real average_val = 0.;
288  Number average_val = 0.;
289 
290  // Calculate this variable's contribution to the p
291  // refinement error
292 
293  if (elem->p_level() == 0)
294  {
295  unsigned int n_vertices = 0;
296  for (unsigned int n = 0; n != n_nodes; ++n)
297  if (elem->is_vertex(n))
298  {
299  n_vertices++;
300  const Node & node = elem->node_ref(n);
301  average_val += system.current_solution
302  (node.dof_number(sys_num,var,0));
303  }
304  average_val /= n_vertices;
305  }
306  else
307  {
308  unsigned int old_elem_level = elem->p_level();
309  (const_cast<Elem *>(elem))->hack_p_level(old_elem_level - 1);
310 
311  fe_coarse->reinit(elem, &(qrule->get_points()));
312 
313  const unsigned int n_coarse_dofs =
314  cast_int<unsigned int>(phi_coarse->size());
315 
316  (const_cast<Elem *>(elem))->hack_p_level(old_elem_level);
317 
318  Ke.resize(n_coarse_dofs, n_coarse_dofs);
319  Ke.zero();
320  Fe.resize(n_coarse_dofs);
321  Fe.zero();
322 
323  // Loop over the quadrature points
324  for (unsigned int qp=0; qp<qrule->n_points(); qp++)
325  {
326  // The solution value at the quadrature point
327  Number val = libMesh::zero;
328  Gradient grad;
329  Tensor hess;
330 
331  for (unsigned int i=0; i != n_dofs; i++)
332  {
333  dof_id_type dof_num = dof_indices[i];
334  val += (*phi)[i][qp] *
335  system.current_solution(dof_num);
336  if (cont == C_ZERO || cont == C_ONE)
337  grad.add_scaled((*dphi)[i][qp], system.current_solution(dof_num));
338  if (cont == C_ONE)
339  hess.add_scaled((*d2phi)[i][qp], system.current_solution(dof_num));
340  }
341 
342  // The projection matrix and vector
343  for (unsigned int i=0; i != Fe.size(); ++i)
344  {
345  Fe(i) += (*JxW)[qp] *
346  (*phi_coarse)[i][qp]*val;
347  if (cont == C_ZERO || cont == C_ONE)
348  Fe(i) += (*JxW)[qp] *
349  grad * (*dphi_coarse)[i][qp];
350  if (cont == C_ONE)
351  Fe(i) += (*JxW)[qp] *
352  hess.contract((*d2phi_coarse)[i][qp]);
353 
354  for (unsigned int j=0; j != Fe.size(); ++j)
355  {
356  Ke(i,j) += (*JxW)[qp] *
357  (*phi_coarse)[i][qp]*(*phi_coarse)[j][qp];
358  if (cont == C_ZERO || cont == C_ONE)
359  Ke(i,j) += (*JxW)[qp] *
360  (*dphi_coarse)[i][qp]*(*dphi_coarse)[j][qp];
361  if (cont == C_ONE)
362  Ke(i,j) += (*JxW)[qp] *
363  ((*d2phi_coarse)[i][qp].contract((*d2phi_coarse)[j][qp]));
364  }
365  }
366  }
367 
368  // Solve the p-coarsening projection problem
370  }
371 
372  // loop over the integration points on the fine element
373  for (unsigned int qp=0; qp<n_qp; qp++)
374  {
375  Number value_error = 0.;
376  Gradient grad_error;
377  Tensor hessian_error;
378  for (unsigned int i=0; i<n_dofs; i++)
379  {
380  const dof_id_type dof_num = dof_indices[i];
381  value_error += (*phi)[i][qp] *
382  system.current_solution(dof_num);
383  if (cont == C_ZERO || cont == C_ONE)
384  grad_error.add_scaled((*dphi)[i][qp], system.current_solution(dof_num));
385  if (cont == C_ONE)
386  hessian_error.add_scaled((*d2phi)[i][qp], system.current_solution(dof_num));
387  }
388  if (elem->p_level() == 0)
389  {
390  value_error -= average_val;
391  }
392  else
393  {
394  for (unsigned int i=0; i<Up.size(); i++)
395  {
396  value_error -= (*phi_coarse)[i][qp] * Up(i);
397  if (cont == C_ZERO || cont == C_ONE)
398  grad_error.subtract_scaled((*dphi_coarse)[i][qp], Up(i));
399  if (cont == C_ONE)
400  hessian_error.subtract_scaled((*d2phi_coarse)[i][qp], Up(i));
401  }
402  }
403 
404  p_error_per_cell[e_id] += static_cast<ErrorVectorReal>
405  (component_scale[var] *
406  (*JxW)[qp] * TensorTools::norm_sq(value_error));
407  if (cont == C_ZERO || cont == C_ONE)
408  p_error_per_cell[e_id] += static_cast<ErrorVectorReal>
409  (component_scale[var] *
410  (*JxW)[qp] * grad_error.norm_sq());
411  if (cont == C_ONE)
412  p_error_per_cell[e_id] += static_cast<ErrorVectorReal>
413  (component_scale[var] *
414  (*JxW)[qp] * hessian_error.norm_sq());
415  }
416 
417  // Calculate this variable's contribution to the h
418  // refinement error
419 
420  if (!elem->parent())
421  {
422  // For now, we'll always start with an h refinement
423  h_error_per_cell[e_id] =
425  }
426  else
427  {
428  FEInterface::inverse_map (dim, fe_type, coarse,
430 
431  unsigned int old_parent_level = coarse->p_level();
432  (const_cast<Elem *>(coarse))->hack_p_level(elem->p_level());
433 
434  fe_coarse->reinit(coarse, &coarse_qpoints);
435 
436  (const_cast<Elem *>(coarse))->hack_p_level(old_parent_level);
437 
438  // The number of DOFS on the coarse element
439  unsigned int n_coarse_dofs =
440  cast_int<unsigned int>(phi_coarse->size());
441 
442  // Loop over the quadrature points
443  for (unsigned int qp=0; qp<n_qp; qp++)
444  {
445  // The solution difference at the quadrature point
446  Number value_error = libMesh::zero;
447  Gradient grad_error;
448  Tensor hessian_error;
449 
450  for (unsigned int i=0; i != n_dofs; ++i)
451  {
452  const dof_id_type dof_num = dof_indices[i];
453  value_error += (*phi)[i][qp] *
454  system.current_solution(dof_num);
455  if (cont == C_ZERO || cont == C_ONE)
456  grad_error.add_scaled((*dphi)[i][qp], system.current_solution(dof_num));
457  if (cont == C_ONE)
458  hessian_error.add_scaled((*d2phi)[i][qp], system.current_solution(dof_num));
459  }
460 
461  for (unsigned int i=0; i != n_coarse_dofs; ++i)
462  {
463  value_error -= (*phi_coarse)[i][qp] * Uc(i);
464  if (cont == C_ZERO || cont == C_ONE)
465  grad_error.subtract_scaled((*dphi_coarse)[i][qp], Uc(i));
466  if (cont == C_ONE)
467  hessian_error.subtract_scaled((*d2phi_coarse)[i][qp], Uc(i));
468  }
469 
470  h_error_per_cell[e_id] += static_cast<ErrorVectorReal>
471  (component_scale[var] *
472  (*JxW)[qp] * TensorTools::norm_sq(value_error));
473  if (cont == C_ZERO || cont == C_ONE)
474  h_error_per_cell[e_id] += static_cast<ErrorVectorReal>
475  (component_scale[var] *
476  (*JxW)[qp] * grad_error.norm_sq());
477  if (cont == C_ONE)
478  h_error_per_cell[e_id] += static_cast<ErrorVectorReal>
479  (component_scale[var] *
480  (*JxW)[qp] * hessian_error.norm_sq());
481  }
482 
483  }
484  }
485  }
486 
487  // Now that we've got our approximations for p_error and h_error, let's see
488  // if we want to switch any h refinement flags to p refinement
489 
490  // Iterate over all the active elements in the mesh
491  // that live on this processor.
492  for (auto & elem : mesh.active_local_element_ptr_range())
493  {
494  // We're only checking elements that are already flagged for h
495  // refinement
496  if (elem->refinement_flag() != Elem::REFINE)
497  continue;
498 
499  const dof_id_type e_id = elem->id();
500 
501  unsigned int dofs_per_elem = 0, dofs_per_p_elem = 0;
502 
503  // Loop over all the variables in the system
504  for (unsigned int var=0; var<n_vars; var++)
505  {
506  // The type of finite element to use for this variable
507  const FEType & fe_type = dof_map.variable_type (var);
508 
509  // FIXME: we're overestimating the number of DOFs added by h
510  // refinement
511  FEType elem_fe_type = fe_type;
512  elem_fe_type.order =
513  static_cast<Order>(fe_type.order + elem->p_level());
514  dofs_per_elem +=
515  FEInterface::n_dofs(dim, elem_fe_type, elem->type());
516 
517  elem_fe_type.order =
518  static_cast<Order>(fe_type.order + elem->p_level() + 1);
519  dofs_per_p_elem +=
520  FEInterface::n_dofs(dim, elem_fe_type, elem->type());
521  }
522 
523  const unsigned int new_h_dofs = dofs_per_elem *
524  (elem->n_children() - 1);
525 
526  const unsigned int new_p_dofs = dofs_per_p_elem -
527  dofs_per_elem;
528 
529  /*
530  libMesh::err << "Cell " << e_id << ": h = " << elem->hmax()
531  << ", p = " << elem->p_level() + 1 << "," << std::endl
532  << " h_error = " << h_error_per_cell[e_id]
533  << ", p_error = " << p_error_per_cell[e_id] << std::endl
534  << " new_h_dofs = " << new_h_dofs
535  << ", new_p_dofs = " << new_p_dofs << std::endl;
536  */
537  const Real p_value =
538  std::sqrt(p_error_per_cell[e_id]) * p_weight / new_p_dofs;
539  const Real h_value =
540  std::sqrt(h_error_per_cell[e_id]) /
541  static_cast<Real>(new_h_dofs);
542  if (p_value > h_value)
543  {
544  elem->set_p_refinement_flag(Elem::REFINE);
545  elem->set_refinement_flag(Elem::DO_NOTHING);
546  }
547  }
548 
549  // libMesh::MeshRefinement will now assume that users have set
550  // refinement flags consistently on all processors, but all we've
551  // done so far is set refinement flags on local elements. Let's
552  // make sure that flags on geometrically ghosted elements are all
553  // set to whatever their owners decided.
554  MeshRefinement(mesh).make_flags_parallel_consistent();
555 }
virtual unsigned int size() const override
Definition: dense_vector.h:92
const std::vector< std::vector< Real > > * phi
const Elem * parent() const
Definition: elem.h:2479
std::vector< float > component_scale
Definition: hp_selector.h:82
void add_projection(const System &, const Elem *, unsigned int var)
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:454
DenseVector< Number > Fe
std::unique_ptr< FEBase > fe_coarse
const std::vector< std::vector< Real > > * phi_coarse
void resize(const unsigned int n)
Definition: dense_vector.h:355
MeshBase & mesh
const std::vector< std::vector< RealGradient > > * dphi_coarse
unsigned int p_level() const
Definition: elem.h:2555
const unsigned int n_vars
Definition: tecplot_io.C:69
const Number zero
Definition: libmesh.h:239
const std::vector< Point > * xyz_values
long double max(long double a, double b)
DIE A HORRIBLE DEATH HERE typedef float ErrorVectorReal
DenseVector< Number > Uc
const std::vector< Real > * JxW
const dof_id_type n_nodes
Definition: tecplot_io.C:68
NumberVectorValue Gradient
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
static Point inverse_map(const unsigned int dim, const FEType &fe_t, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
Definition: fe_interface.C:590
DenseVector< Number > Up
std::unique_ptr< FEBase > fe
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
NumberTensorValue Tensor
virtual void zero() override
Definition: dense_matrix.h:808
void resize(const unsigned int new_m, const unsigned int new_n)
Definition: dense_matrix.h:792
const std::vector< std::vector< RealTensor > > * d2phi_coarse
const std::vector< std::vector< RealTensor > > * d2phi
void cholesky_solve(const DenseVector< T2 > &b, DenseVector< T2 > &x)
const std::vector< std::vector< RealGradient > > * dphi
std::vector< dof_id_type > dof_indices
std::vector< Point > coarse_qpoints
std::unique_ptr< QBase > qrule
virtual void zero() override
Definition: dense_vector.h:379
uint8_t dof_id_type
Definition: id_types.h:64
DenseMatrix< Number > Ke

Member Data Documentation

◆ coarse

const Elem* libMesh::HPCoarsenTest::coarse
protected

The coarse element on which a solution projection is cached

Definition at line 119 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

◆ coarse_qpoints

std::vector<Point> libMesh::HPCoarsenTest::coarse_qpoints
protected

Definition at line 147 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

◆ component_scale

std::vector<float> libMesh::HPSelector::component_scale
inherited

This vector can be used to "scale" certain variables in a system. If the mask is not empty, the consideration given to each component's h and p error estimates will be scaled by component_scale[c].

Definition at line 82 of file hp_selector.h.

Referenced by select_refinement().

◆ d2phi

const std::vector<std::vector<RealTensor> >* libMesh::HPCoarsenTest::d2phi
protected

Definition at line 136 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

◆ d2phi_coarse

const std::vector<std::vector<RealTensor> > * libMesh::HPCoarsenTest::d2phi_coarse
protected

Definition at line 136 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

◆ dof_indices

std::vector<dof_id_type> libMesh::HPCoarsenTest::dof_indices
protected

Global DOF indices for fine elements

Definition at line 124 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

◆ dphi

const std::vector<std::vector<RealGradient> >* libMesh::HPCoarsenTest::dphi
protected

Definition at line 135 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

◆ dphi_coarse

const std::vector<std::vector<RealGradient> > * libMesh::HPCoarsenTest::dphi_coarse
protected

Definition at line 135 of file hp_coarsentest.h.

Referenced by select_refinement().

◆ fe

std::unique_ptr<FEBase> libMesh::HPCoarsenTest::fe
protected

The finite element objects for fine and coarse elements

Definition at line 129 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

◆ Fe

DenseVector<Number> libMesh::HPCoarsenTest::Fe
protected

Definition at line 158 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

◆ fe_coarse

std::unique_ptr<FEBase> libMesh::HPCoarsenTest::fe_coarse
protected

Definition at line 129 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

◆ JxW

const std::vector<Real>* libMesh::HPCoarsenTest::JxW
protected

Mapping jacobians

Definition at line 141 of file hp_coarsentest.h.

Referenced by select_refinement().

◆ Ke

DenseMatrix<Number> libMesh::HPCoarsenTest::Ke
protected

Linear system for projections

Definition at line 157 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

◆ p_weight

Real libMesh::HPCoarsenTest::p_weight

Because the coarsening test seems to always choose p refinement, we're providing an option to make h refinement more likely

Definition at line 107 of file hp_coarsentest.h.

Referenced by select_refinement().

◆ phi

const std::vector<std::vector<Real> >* libMesh::HPCoarsenTest::phi
protected

The shape functions and their derivatives

Definition at line 134 of file hp_coarsentest.h.

Referenced by select_refinement().

◆ phi_coarse

const std::vector<std::vector<Real> > * libMesh::HPCoarsenTest::phi_coarse
protected

Definition at line 134 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

◆ qrule

std::unique_ptr<QBase> libMesh::HPCoarsenTest::qrule
protected

The quadrature rule for the fine element

Definition at line 152 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

◆ Uc

DenseVector<Number> libMesh::HPCoarsenTest::Uc
protected

Coefficients for projected coarse and projected p-derefined solutions

Definition at line 163 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().

◆ Up

DenseVector<Number> libMesh::HPCoarsenTest::Up
protected

Definition at line 164 of file hp_coarsentest.h.

Referenced by select_refinement().

◆ xyz_values

const std::vector<Point>* libMesh::HPCoarsenTest::xyz_values
protected

Quadrature locations

Definition at line 146 of file hp_coarsentest.h.

Referenced by add_projection(), and select_refinement().


The documentation for this class was generated from the following files: