118 const unsigned int dim =
mesh.mesh_dimension();
128 for (
const auto & elem : range)
135 Patch patch(
mesh.processor_id());
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 =
189 bool is_valid_norm_combo =
216 const FEType & fe_type = dof_map.variable_type (var);
218 const Order element_order = static_cast<Order>
219 (fe_type.order + elem->p_level());
225 std::unique_ptr<QBase> qrule (fe_type.default_quadrature_rule(
dim));
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);
280 DenseMatrix<Number> Kp(matsize,matsize);
281 DenseVector<Number> F, Fx, Fy, Fz, Fxy, Fxz, Fyz;
282 DenseVector<Number> Pu_h, Pu_x_h, Pu_y_h, Pu_z_h, Pu_xy_h, Pu_xz_h, Pu_yz_h;
286 F.resize(matsize); Pu_h.resize(matsize);
293 Fx.resize(matsize); Pu_x_h.resize(matsize);
295 Fy.resize(matsize); Pu_y_h.resize(matsize);
298 Fz.resize(matsize); Pu_z_h.resize(matsize);
303 Fx.resize(matsize); Pu_x_h.resize(matsize);
308 Fy.resize(matsize); Pu_y_h.resize(matsize);
313 Fz.resize(matsize); Pu_z_h.resize(matsize);
320 Fxy.resize(matsize); Pu_xy_h.resize(matsize);
322 Fxz.resize(matsize); Pu_xz_h.resize(matsize);
323 Fyz.resize(matsize); Pu_yz_h.resize(matsize);
332 for (
const auto & e_p : patch)
339 dof_map.dof_indices (e_p, dof_indices, var);
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 const unsigned int m = Kp.m(), n = Kp.n();
357 for (
unsigned int i=0; i<m; i++)
358 for (
unsigned int j=0; j<n; j++)
359 Kp(i,j) += JxW[qp]*psi[i]*psi[j];
368 for (
unsigned int i=0; i<n_dofs; i++)
372 for (
unsigned int i=0; i != psi_size; i++)
373 F(i) = JxW[qp]*u_h*psi[i];
383 for (std::size_t i=0; i<n_dofs; i++)
390 for (
unsigned int i=0; i != psi_size; i++)
392 Fx(i) += JxW[qp]*grad_u_h(0)*psi[i];
394 Fy(i) += JxW[qp]*grad_u_h(1)*psi[i];
397 Fz(i) += JxW[qp]*grad_u_h(2)*psi[i];
407 for (
unsigned int i=0; i<n_dofs; i++)
414 for (
unsigned int i=0; i != psi_size; i++)
416 Fx(i) += JxW[qp]*grad_u_h(0)*psi[i];
426 for (
unsigned int i=0; i<n_dofs; i++)
433 for (
unsigned int i=0; i != psi_size; i++)
435 Fy(i) += JxW[qp]*grad_u_h(1)*psi[i];
438 #endif // LIBMESH_DIM > 1
446 for (
unsigned int i=0; i<n_dofs; i++)
453 for (
unsigned int i=0; i != psi_size; i++)
455 Fz(i) += JxW[qp]*grad_u_h(2)*psi[i];
458 #endif // LIBMESH_DIM > 2
462 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
467 for (
unsigned int i=0; i<n_dofs; i++)
474 for (
unsigned int i=0; i != psi_size; i++)
476 Fx(i) += JxW[qp]*hess_u_h(0,0)*psi[i];
478 Fy(i) += JxW[qp]*hess_u_h(1,1)*psi[i];
479 Fxy(i) += JxW[qp]*hess_u_h(0,1)*psi[i];
482 Fz(i) += JxW[qp]*hess_u_h(2,2)*psi[i];
483 Fxz(i) += JxW[qp]*hess_u_h(0,2)*psi[i];
484 Fyz(i) += JxW[qp]*hess_u_h(1,2)*psi[i];
488 libmesh_error_msg(
"ERROR: --enable-second-derivatives is required \nfor _sobolev_order == 2!");
492 libmesh_error_msg(
"Unsupported error norm type!");
505 Kp.lu_solve(F, Pu_h);
512 Kp.lu_solve (Fx, Pu_x_h);
514 Kp.lu_solve (Fy, Pu_y_h);
517 Kp.lu_solve (Fz, Pu_z_h);
522 Kp.lu_solve (Fx, Pu_x_h);
526 Kp.lu_solve (Fy, Pu_y_h);
530 Kp.lu_solve (Fz, Pu_z_h);
537 Kp.lu_solve(Fxy, Pu_xy_h);
539 Kp.lu_solve(Fxz, Pu_xz_h);
540 Kp.lu_solve(Fyz, Pu_yz_h);
549 Patch::const_iterator patch_re_it;
550 Patch::const_iterator patch_re_end;
553 Patch patch_re(
mesh.processor_id());
558 patch_re_it = patch.begin();
559 patch_re_end = patch.end();
565 patch_re.build_around_element (elem, 0,
569 patch_re_it = patch_re.begin();
570 patch_re_end = patch_re.end();
581 FEMContext femcontext(
system);
585 for (
unsigned int e = 0 ; patch_re_it != patch_re_end; ++patch_re_it, ++e)
590 const Elem * e_p = *patch_re_it;
596 femcontext.pre_fe_reinit(
system, e_p);
611 dof_map.dof_indices (e_p, dof_indices, var);
615 const unsigned int n_dofs =
616 cast_int<unsigned int>(dof_indices.size());
619 Real element_error = 0;
622 static_cast<Order>(fe_type.order + e_p->p_level());
625 QGrid samprule (
dim, qorder);
629 fe->attach_quadrature_rule (&samprule);
632 const unsigned int n_sp =
633 cast_int<unsigned int>(JxW.size());
636 for (
unsigned int sp=0; sp<n_sp; sp++)
640 std::vector<Number> temperr(6,0.0);
648 for (
unsigned int i=0; i<n_dofs; i++)
652 std::vector<Real> psi(
specpoly(
dim, element_order, q_point[sp], matsize));
653 for (
unsigned int i=0; i<matsize; i++)
655 temperr[0] += psi[i]*Pu_h(i);
666 for (
unsigned int i=0; i<n_dofs; i++)
671 std::vector<Real> psi(
specpoly(
dim, element_order, q_point[sp], matsize));
673 for (
unsigned int i=0; i<matsize; i++)
675 temperr[0] += psi[i]*Pu_x_h(i);
677 temperr[1] += psi[i]*Pu_y_h(i);
680 temperr[2] += psi[i]*Pu_z_h(i);
683 temperr[0] -= grad_u_h(0);
685 temperr[1] -= grad_u_h(1);
688 temperr[2] -= grad_u_h(2);
696 for (
unsigned int i=0; i<n_dofs; i++)
701 std::vector<Real> psi(
specpoly(
dim, element_order, q_point[sp], matsize));
702 for (
unsigned int i=0; i<matsize; i++)
704 temperr[0] += psi[i]*Pu_x_h(i);
707 temperr[0] -= grad_u_h(0);
715 for (
unsigned int i=0; i<n_dofs; i++)
720 std::vector<Real> psi(
specpoly(
dim, element_order, q_point[sp], matsize));
721 for (
unsigned int i=0; i<matsize; i++)
723 temperr[1] += psi[i]*Pu_y_h(i);
726 temperr[1] -= grad_u_h(1);
728 #endif // LIBMESH_DIM > 1
735 for (
unsigned int i=0; i<n_dofs; i++)
740 std::vector<Real> psi(
specpoly(
dim, element_order, q_point[sp], matsize));
741 for (
unsigned int i=0; i<matsize; i++)
743 temperr[2] += psi[i]*Pu_z_h(i);
746 temperr[2] -= grad_u_h(2);
748 #endif // LIBMESH_DIM > 2
752 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
756 for (
unsigned int i=0; i<n_dofs; i++)
761 std::vector<Real> psi(
specpoly(
dim, element_order, q_point[sp], matsize));
762 for (
unsigned int i=0; i<matsize; i++)
764 temperr[0] += psi[i]*Pu_x_h(i);
766 temperr[1] += psi[i]*Pu_y_h(i);
767 temperr[3] += psi[i]*Pu_xy_h(i);
770 temperr[2] += psi[i]*Pu_z_h(i);
771 temperr[4] += psi[i]*Pu_xz_h(i);
772 temperr[5] += psi[i]*Pu_yz_h(i);
776 temperr[0] -= hess_u_h(0,0);
778 temperr[1] -= hess_u_h(1,1);
779 temperr[3] -= hess_u_h(0,1);
782 temperr[2] -= hess_u_h(2,2);
783 temperr[4] -= hess_u_h(0,2);
784 temperr[5] -= hess_u_h(1,2);
787 libmesh_error_msg(
"ERROR: --enable-second-derivatives is required \nfor _sobolev_order == 2!");
799 element_error = std::max(element_error,
std::abs(
weight*temperr[0]));
801 for (
unsigned int i=0; i != LIBMESH_DIM; ++i)
802 element_error = std::max(element_error,
std::abs(
weight*temperr[i]));
804 for (
unsigned int i=0; i != 6; ++i)
805 element_error = std::max(element_error,
std::abs(
weight*temperr[i]));
809 for (
unsigned int i=0; i != LIBMESH_DIM; ++i)
819 for (
unsigned int i=0; i != LIBMESH_DIM; ++i)
822 for (
unsigned int i=3; i != 6; ++i)
840 libmesh_error_msg(
"Unsupported error norm type!");
851 Patch::const_iterator patch_re_it;
852 Patch::const_iterator patch_re_end;
855 Patch current_elem_patch(
mesh.processor_id());
860 patch_re_it = patch.begin();
861 patch_re_end = patch.end();
867 current_elem_patch.build_around_element (elem, 0,
871 patch_re_it = current_elem_patch.begin();
872 patch_re_end = current_elem_patch.end();
876 for (
unsigned int i = 0 ; patch_re_it != patch_re_end; ++patch_re_it, ++i)
879 const Elem * e_p = *patch_re_it;
905 (new_error_per_cell[i]);