60 LOG_SCOPE(
"estimate_error()",
"WeightedPatchRecoveryErrorEstimator");
67 error_per_cell.resize (
mesh.max_elem_id());
68 std::fill (error_per_cell.begin(), error_per_cell.end(), 0.);
72 if (solution_vector && solution_vector != system.
solution.get())
77 newsol->
swap(*sys.solution);
85 mesh.active_local_elements_end(),
100 if (solution_vector && solution_vector != system.
solution.get())
105 newsol->
swap(*sys.solution);
118 const unsigned int dim =
mesh.mesh_dimension();
128 for (
const auto & elem : range)
153 std::vector<Real> new_error_per_cell(1, 0.);
155 new_error_per_cell.resize(patch.size(), 0.);
159 for (
unsigned int var=0; var<
n_vars; var++)
161 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 163 bool is_valid_norm_type =
173 libmesh_assert (is_valid_norm_type);
189 bool is_valid_norm_combo =
208 libmesh_assert (is_valid_norm_combo);
218 const Order element_order =
static_cast<Order> 219 (fe_type.
order + elem->p_level());
228 fe->attach_quadrature_rule (qrule.get());
231 const std::vector<Real> & JxW = fe->get_JxW();
232 const std::vector<Point> & q_point = fe->get_xyz();
238 const std::vector<std::vector<Real>> * phi =
nullptr;
246 phi = &(fe->get_phi());
248 const std::vector<std::vector<RealGradient>> * dphi =
nullptr;
254 dphi = &(fe->get_dphi());
256 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 257 const std::vector<std::vector<RealTensor>> * d2phi =
nullptr;
260 d2phi = &(fe->get_d2phi());
264 std::vector<dof_id_type> dof_indices;
268 unsigned int matsize = element_order + 1;
271 matsize *= (element_order + 2);
276 matsize *= (element_order + 3);
307 libmesh_assert(LIBMESH_DIM > 1);
312 libmesh_assert(LIBMESH_DIM > 2);
332 for (
const auto & e_p : patch)
340 libmesh_assert (dof_indices.size() == phi->size());
342 const unsigned int n_dofs =
343 cast_int<unsigned int>(dof_indices.size());
344 const unsigned int n_qp = qrule->n_points();
348 for (
unsigned int qp=0; qp<n_qp; qp++)
351 std::vector<Real> psi(
specpoly(dim, element_order, q_point[qp], matsize));
353 const unsigned int psi_size = cast_int<unsigned int>(psi.size());
356 for (
unsigned int i=0; i<Kp.
m(); i++)
357 for (
unsigned int j=0; j<Kp.
n(); j++)
358 Kp(i,j) += JxW[qp]*psi[i]*psi[j];
367 for (
unsigned int i=0; i<n_dofs; i++)
371 for (
unsigned int i=0; i != psi_size; i++)
372 F(i) = JxW[qp]*u_h*psi[i];
382 for (std::size_t i=0; i<n_dofs; i++)
389 for (
unsigned int i=0; i != psi_size; i++)
391 Fx(i) += JxW[qp]*grad_u_h(0)*psi[i];
393 Fy(i) += JxW[qp]*grad_u_h(1)*psi[i];
396 Fz(i) += JxW[qp]*grad_u_h(2)*psi[i];
406 for (
unsigned int i=0; i<n_dofs; i++)
413 for (
unsigned int i=0; i != psi_size; i++)
415 Fx(i) += JxW[qp]*grad_u_h(0)*psi[i];
424 for (
unsigned int i=0; i<n_dofs; i++)
431 for (
unsigned int i=0; i != psi_size; i++)
433 Fy(i) += JxW[qp]*grad_u_h(1)*psi[i];
442 for (
unsigned int i=0; i<n_dofs; i++)
449 for (
unsigned int i=0; i != psi_size; i++)
451 Fz(i) += JxW[qp]*grad_u_h(2)*psi[i];
457 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 462 for (
unsigned int i=0; i<n_dofs; i++)
469 for (
unsigned int i=0; i != psi_size; i++)
471 Fx(i) += JxW[qp]*hess_u_h(0,0)*psi[i];
473 Fy(i) += JxW[qp]*hess_u_h(1,1)*psi[i];
474 Fxy(i) += JxW[qp]*hess_u_h(0,1)*psi[i];
477 Fz(i) += JxW[qp]*hess_u_h(2,2)*psi[i];
478 Fxz(i) += JxW[qp]*hess_u_h(0,2)*psi[i];
479 Fyz(i) += JxW[qp]*hess_u_h(1,2)*psi[i];
483 libmesh_error_msg(
"ERROR: --enable-second-derivatives is required \nfor _sobolev_order == 2!");
487 libmesh_error_msg(
"Unsupported error norm type!");
544 Patch::const_iterator patch_re_it;
545 Patch::const_iterator patch_re_end;
553 patch_re_it = patch.begin();
554 patch_re_end = patch.end();
564 patch_re_it = patch_re.begin();
565 patch_re_end = patch_re.end();
580 for (
unsigned int e = 0 ; patch_re_it != patch_re_end; ++patch_re_it, ++e)
585 const Elem * e_p = *patch_re_it;
592 Elem * e_p_cast =
const_cast<Elem *
>(*patch_re_it);
611 libmesh_assert (dof_indices.size() == phi->size());
614 const unsigned int n_dofs =
615 cast_int<unsigned int>(dof_indices.size());
618 Real element_error = 0;
624 QGrid samprule (dim, qorder);
628 fe->attach_quadrature_rule (&samprule);
631 const unsigned int n_sp =
632 cast_int<unsigned int>(JxW.size());
635 for (
unsigned int sp=0; sp<n_sp; sp++)
639 std::vector<Number> temperr(6,0.0);
647 for (
unsigned int i=0; i<n_dofs; i++)
651 std::vector<Real> psi(
specpoly(dim, element_order, q_point[sp], matsize));
652 for (
unsigned int i=0; i<matsize; i++)
654 temperr[0] += psi[i]*Pu_h(i);
665 for (
unsigned int i=0; i<n_dofs; i++)
670 std::vector<Real> psi(
specpoly(dim, element_order, q_point[sp], matsize));
672 for (
unsigned int i=0; i<matsize; i++)
674 temperr[0] += psi[i]*Pu_x_h(i);
676 temperr[1] += psi[i]*Pu_y_h(i);
679 temperr[2] += psi[i]*Pu_z_h(i);
682 temperr[0] -= grad_u_h(0);
684 temperr[1] -= grad_u_h(1);
687 temperr[2] -= grad_u_h(2);
695 for (
unsigned int i=0; i<n_dofs; i++)
700 std::vector<Real> psi(
specpoly(dim, element_order, q_point[sp], matsize));
701 for (
unsigned int i=0; i<matsize; i++)
703 temperr[0] += psi[i]*Pu_x_h(i);
706 temperr[0] -= grad_u_h(0);
713 for (
unsigned int i=0; i<n_dofs; i++)
718 std::vector<Real> psi(
specpoly(dim, element_order, q_point[sp], matsize));
719 for (
unsigned int i=0; i<matsize; i++)
721 temperr[1] += psi[i]*Pu_y_h(i);
724 temperr[1] -= grad_u_h(1);
731 for (
unsigned int i=0; i<n_dofs; i++)
736 std::vector<Real> psi(
specpoly(dim, element_order, q_point[sp], matsize));
737 for (
unsigned int i=0; i<matsize; i++)
739 temperr[2] += psi[i]*Pu_z_h(i);
742 temperr[2] -= grad_u_h(2);
747 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 751 for (
unsigned int i=0; i<n_dofs; i++)
756 std::vector<Real> psi(
specpoly(dim, element_order, q_point[sp], matsize));
757 for (
unsigned int i=0; i<matsize; i++)
759 temperr[0] += psi[i]*Pu_x_h(i);
761 temperr[1] += psi[i]*Pu_y_h(i);
762 temperr[3] += psi[i]*Pu_xy_h(i);
765 temperr[2] += psi[i]*Pu_z_h(i);
766 temperr[4] += psi[i]*Pu_xz_h(i);
767 temperr[5] += psi[i]*Pu_yz_h(i);
771 temperr[0] -= hess_u_h(0,0);
773 temperr[1] -= hess_u_h(1,1);
774 temperr[3] -= hess_u_h(0,1);
777 temperr[2] -= hess_u_h(2,2);
778 temperr[4] -= hess_u_h(0,2);
779 temperr[5] -= hess_u_h(1,2);
782 libmesh_error_msg(
"ERROR: --enable-second-derivatives is required \nfor _sobolev_order == 2!");
796 for (
unsigned int i=0; i != LIBMESH_DIM; ++i)
799 for (
unsigned int i=0; i != 6; ++i)
804 for (
unsigned int i=0; i != LIBMESH_DIM; ++i)
814 for (
unsigned int i=0; i != LIBMESH_DIM; ++i)
817 for (
unsigned int i=3; i != 6; ++i)
835 libmesh_error_msg(
"Unsupported error norm type!");
846 Patch::const_iterator patch_re_it;
847 Patch::const_iterator patch_re_end;
850 Patch current_elem_patch(
mesh.processor_id());
855 patch_re_it = patch.begin();
856 patch_re_end = patch.end();
866 patch_re_it = current_elem_patch.begin();
867 patch_re_end = current_elem_patch.end();
871 for (
unsigned int i = 0 ; patch_re_it != patch_re_end; ++patch_re_it, ++i)
874 const Elem * e_p = *patch_re_it;
890 (std::sqrt(new_error_per_cell[i]));
900 (new_error_per_cell[i]);
Manages the family, order, etc. parameters for a given FE.
virtual void pre_fe_reinit(const System &, const Elem *e)
void operator()(const ConstElemRange &range) const
virtual void estimate_error(const System &system, ErrorVector &error_per_cell, const NumericVector< Number > *solution_vector=nullptr, bool estimate_parent_error=false) override
Patch::PMF patch_growth_strategy
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
void parallel_for(const Range &range, const Body &body)
void add_scaled(const TypeTensor< T2 > &, const T)
void add_scaled(const TypeVector< T2 > &, const T)
void resize(const unsigned int n)
const FEType & variable_type(const unsigned int c) const
friend class EstimateError
The base class for all geometric element types.
const Parallel::Communicator & comm() const
unsigned int p_level() const
Utility class for defining generic ranges for threading.
const unsigned int n_vars
virtual ErrorEstimatorType type() const override
long double max(long double a, double b)
const MeshBase & get_mesh() const
DIE A HORRIBLE DEATH HERE typedef float ErrorVectorReal
void build_around_element(const Elem *elem, const unsigned int target_patch_size=10, PMF patchtype=&Patch::add_local_face_neighbors)
StoredRange< MeshBase::const_element_iterator, const Elem * > ConstElemRange
Number current_solution(const dof_id_type global_dof_number) const
Manages the degrees of freedom (DOFs) in a simulation.
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
Manages consistently variables, degrees of freedom, and coefficient vectors.
FEMNormType type(unsigned int var) const
std::unique_ptr< NumericVector< Number > > solution
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
void reduce_error(std::vector< ErrorVectorReal > &error_per_cell, const Parallel::Communicator &comm) const
unsigned int target_patch_size
static std::vector< Real > specpoly(const unsigned int dim, const Order order, const Point p, const unsigned int matsize)
Implements grid-based quadrature rules suitable for non-smooth functions.
Real weight_sq(unsigned int var) const
Real weight(unsigned int var) const
void lu_solve(const DenseVector< T > &b, DenseVector< T > &x)
ErrorVector & error_per_cell
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void swap(NumericVector< T > &v)
const WeightedPatchRecoveryErrorEstimator & error_estimator
std::vector< FEMFunctionBase< Number > * > weight_functions
unsigned int n_vars() const
const DofMap & get_dof_map() const