67 target_patch_size(20),
68 patch_growth_strategy(&
Patch::add_local_face_neighbors),
79 const unsigned int matsize)
81 std::vector<Real> psi;
83 unsigned int npows = order+1;
84 std::vector<Real> xpow(npows,1.), ypow, zpow;
88 xpow[i] = xpow[i-1] * x;
93 ypow.resize(npows,1.);
95 ypow[i] = ypow[i-1] * y;
100 zpow.resize(npows,1.);
102 zpow[i] = zpow[i-1] * z;
107 for (
unsigned int poly_deg=0; poly_deg <= static_cast<unsigned int>(order) ; poly_deg++)
115 for (
int xexp=poly_deg; xexp >= 0; xexp--)
116 for (
int yexp=poly_deg-xexp; yexp >= 0; yexp--)
118 int zexp = poly_deg - xexp - yexp;
119 psi.push_back(xpow[xexp]*ypow[yexp]*zpow[zexp]);
127 for (
int xexp=poly_deg; xexp >= 0; xexp--)
129 int yexp = poly_deg - xexp;
130 psi.push_back(xpow[xexp]*ypow[yexp]);
139 psi.push_back(xpow[xexp]);
144 libmesh_error_msg(
"Invalid dimension dim " << dim);
158 LOG_SCOPE(
"estimate_error()",
"PatchRecoveryErrorEstimator");
165 error_per_cell.resize (
mesh.max_elem_id());
166 std::fill (error_per_cell.begin(), error_per_cell.end(), 0.);
170 if (solution_vector && solution_vector != system.
solution.get())
175 newsol->
swap(*sys.solution);
183 mesh.active_local_elements_end(),
198 if (solution_vector && solution_vector != system.
solution.get())
203 newsol->
swap(*sys.solution);
216 const unsigned int dim =
mesh.mesh_dimension();
226 for (
const auto & elem : range)
251 std::vector<Real> new_error_per_cell(1, 0.);
253 new_error_per_cell.resize(patch.size(), 0.);
257 for (
unsigned int var=0; var<
n_vars; var++)
259 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 261 bool is_valid_norm_type =
271 libmesh_assert (is_valid_norm_type);
288 bool is_valid_norm_combo =
307 libmesh_assert (is_valid_norm_combo);
317 const Order element_order =
static_cast<Order> 318 (fe_type.
order + elem->p_level());
327 fe->attach_quadrature_rule (qrule.get());
330 const std::vector<Real> & JxW = fe->get_JxW();
331 const std::vector<Point> & q_point = fe->get_xyz();
337 const std::vector<std::vector<Real>> * phi =
nullptr;
345 phi = &(fe->get_phi());
347 const std::vector<std::vector<RealGradient>> * dphi =
nullptr;
353 dphi = &(fe->get_dphi());
355 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 356 const std::vector<std::vector<RealTensor>> * d2phi =
nullptr;
359 d2phi = &(fe->get_d2phi());
363 std::vector<dof_id_type> dof_indices;
367 unsigned int matsize = element_order + 1;
370 matsize *= (element_order + 2);
375 matsize *= (element_order + 3);
406 libmesh_assert_greater (LIBMESH_DIM, 1);
411 libmesh_assert_greater (LIBMESH_DIM, 2);
430 for (
const auto & e_p : patch)
438 libmesh_assert_equal_to (dof_indices.size(), phi->size());
440 const unsigned int n_dofs =
441 cast_int<unsigned int>(dof_indices.size());
442 const unsigned int n_qp = qrule->n_points();
446 for (
unsigned int qp=0; qp<n_qp; qp++)
449 std::vector<Real> psi(
specpoly(dim, element_order, q_point[qp], matsize));
451 const unsigned int psi_size = cast_int<unsigned int>(psi.size());
454 for (
unsigned int i=0; i<Kp.
m(); i++)
455 for (
unsigned int j=0; j<Kp.
n(); j++)
456 Kp(i,j) += JxW[qp]*psi[i]*psi[j];
465 for (
unsigned int i=0; i<n_dofs; i++)
469 for (
unsigned int i=0; i != psi_size; i++)
470 F(i) += JxW[qp]*u_h*psi[i];
480 for (
unsigned int i=0; i<n_dofs; i++)
485 for (
unsigned int i=0; i != psi_size; i++)
487 Fx(i) += JxW[qp]*grad_u_h(0)*psi[i];
489 Fy(i) += JxW[qp]*grad_u_h(1)*psi[i];
492 Fz(i) += JxW[qp]*grad_u_h(2)*psi[i];
502 for (
unsigned int i=0; i<n_dofs; i++)
507 for (
unsigned int i=0; i != psi_size; i++)
509 Fx(i) += JxW[qp]*grad_u_h(0)*psi[i];
518 for (
unsigned int i=0; i<n_dofs; i++)
523 for (
unsigned int i=0; i != psi_size; i++)
525 Fy(i) += JxW[qp]*grad_u_h(1)*psi[i];
534 for (
unsigned int i=0; i<n_dofs; i++)
539 for (
unsigned int i=0; i != psi_size; i++)
541 Fz(i) += JxW[qp]*grad_u_h(2)*psi[i];
547 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 552 for (
unsigned int i=0; i<n_dofs; i++)
557 for (
unsigned int i=0; i != psi_size; i++)
559 Fx(i) += JxW[qp]*hess_u_h(0,0)*psi[i];
561 Fy(i) += JxW[qp]*hess_u_h(1,1)*psi[i];
562 Fxy(i) += JxW[qp]*hess_u_h(0,1)*psi[i];
565 Fz(i) += JxW[qp]*hess_u_h(2,2)*psi[i];
566 Fxz(i) += JxW[qp]*hess_u_h(0,2)*psi[i];
567 Fyz(i) += JxW[qp]*hess_u_h(1,2)*psi[i];
571 libmesh_error_msg(
"ERROR: --enable-second-derivatives is required \nfor _sobolev_order == 2!");
575 libmesh_error_msg(
"Unsupported error norm type!");
632 Patch::const_iterator patch_re_it;
633 Patch::const_iterator patch_re_end;
641 patch_re_it = patch.begin();
642 patch_re_end = patch.end();
652 patch_re_it = patch_re.begin();
653 patch_re_end = patch_re.end();
663 for (
unsigned int e = 0 ; patch_re_it != patch_re_end; ++patch_re_it, ++e)
668 const Elem * e_p = *patch_re_it;
687 libmesh_assert_equal_to (dof_indices.size(), phi->size());
690 const unsigned int n_dofs =
691 cast_int<unsigned int>(dof_indices.size());
694 Real element_error = 0;
700 QGrid samprule (dim, qorder);
704 fe->attach_quadrature_rule (&samprule);
707 const unsigned int n_sp =
708 cast_int<unsigned int>(JxW.size());
711 for (
unsigned int sp=0; sp<n_sp; sp++)
715 std::vector<Number> temperr(6,0.0);
723 for (
unsigned int i=0; i<n_dofs; i++)
727 std::vector<Real> psi(
specpoly(dim, element_order, q_point[sp], matsize));
728 for (
unsigned int i=0; i<matsize; i++)
730 temperr[0] += psi[i]*Pu_h(i);
741 for (
unsigned int i=0; i<n_dofs; i++)
746 std::vector<Real> psi(
specpoly(dim, element_order, q_point[sp], matsize));
748 for (
unsigned int i=0; i<matsize; i++)
750 temperr[0] += psi[i]*Pu_x_h(i);
752 temperr[1] += psi[i]*Pu_y_h(i);
755 temperr[2] += psi[i]*Pu_z_h(i);
758 temperr[0] -= grad_u_h(0);
760 temperr[1] -= grad_u_h(1);
763 temperr[2] -= grad_u_h(2);
771 for (
unsigned int i=0; i<n_dofs; i++)
776 std::vector<Real> psi(
specpoly(dim, element_order, q_point[sp], matsize));
777 for (
unsigned int i=0; i<matsize; i++)
779 temperr[0] += psi[i]*Pu_x_h(i);
782 temperr[0] -= grad_u_h(0);
789 for (
unsigned int i=0; i<n_dofs; i++)
794 std::vector<Real> psi(
specpoly(dim, element_order, q_point[sp], matsize));
795 for (
unsigned int i=0; i<matsize; i++)
797 temperr[1] += psi[i]*Pu_y_h(i);
800 temperr[1] -= grad_u_h(1);
807 for (
unsigned int i=0; i<n_dofs; i++)
812 std::vector<Real> psi(
specpoly(dim, element_order, q_point[sp], matsize));
813 for (
unsigned int i=0; i<matsize; i++)
815 temperr[2] += psi[i]*Pu_z_h(i);
818 temperr[2] -= grad_u_h(2);
823 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 827 for (
unsigned int i=0; i<n_dofs; i++)
832 std::vector<Real> psi(
specpoly(dim, element_order, q_point[sp], matsize));
833 for (
unsigned int i=0; i<matsize; i++)
835 temperr[0] += psi[i]*Pu_x_h(i);
837 temperr[1] += psi[i]*Pu_y_h(i);
838 temperr[3] += psi[i]*Pu_xy_h(i);
841 temperr[2] += psi[i]*Pu_z_h(i);
842 temperr[4] += psi[i]*Pu_xz_h(i);
843 temperr[5] += psi[i]*Pu_yz_h(i);
847 temperr[0] -= hess_u_h(0,0);
849 temperr[1] -= hess_u_h(1,1);
850 temperr[3] -= hess_u_h(0,1);
853 temperr[2] -= hess_u_h(2,2);
854 temperr[4] -= hess_u_h(0,2);
855 temperr[5] -= hess_u_h(1,2);
858 libmesh_error_msg(
"ERROR: --enable-second-derivatives is required \nfor _sobolev_order == 2!");
868 for (
unsigned int i=0; i != LIBMESH_DIM; ++i)
871 for (
unsigned int i=0; i != 6; ++i)
876 for (
unsigned int i=0; i != LIBMESH_DIM; ++i)
886 for (
unsigned int i=0; i != LIBMESH_DIM; ++i)
889 for (
unsigned int i=3; i != 6; ++i)
907 libmesh_error_msg(
"Unsupported error norm type!");
918 Patch::const_iterator patch_re_it;
919 Patch::const_iterator patch_re_end;
922 Patch current_elem_patch(
mesh.processor_id());
927 patch_re_it = patch.begin();
928 patch_re_end = patch.end();
938 patch_re_it = current_elem_patch.begin();
939 patch_re_end = current_elem_patch.end();
943 for (
unsigned int i = 0 ; patch_re_it != patch_re_end; ++patch_re_it, ++i)
946 const Elem * e_p = *patch_re_it;
Manages the family, order, etc. parameters for a given FE.
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
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
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)
virtual void estimate_error(const System &system, ErrorVector &error_per_cell, const NumericVector< Number > *solution_vector=nullptr, bool estimate_parent_error=false) override
void reduce_error(std::vector< ErrorVectorReal > &error_per_cell, const Parallel::Communicator &comm) const
unsigned int target_patch_size
const PatchRecoveryErrorEstimator & error_estimator
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.
void operator()(const ConstElemRange &range) const
Real weight_sq(unsigned int var) const
ErrorVector & error_per_cell
Real weight(unsigned int var) const
void lu_solve(const DenseVector< T > &b, DenseVector< T > &x)
void set_patch_reuse(bool)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void swap(NumericVector< T > &v)
PatchRecoveryErrorEstimator()
virtual ErrorEstimatorType type() const override
friend class EstimateError
unsigned int n_vars() const
const DofMap & get_dof_map() const
A geometric point in (x,y,z) space.