266 pipeline_mng->getDomainLhsFE().reset();
267 pipeline_mng->getSkeletonRhsFE().reset();
268 pipeline_mng->getSkeletonLhsFE().reset();
269 pipeline_mng->getBoundaryRhsFE().reset();
270 pipeline_mng->getBoundaryLhsFE().reset();
272 auto rule = [](
int,
int,
int p) ->
int {
return 2 * p; };
273 CHKERR pipeline_mng->setDomainRhsIntegrationRule(rule);
275 CHKERR pipeline_mng->setSkeletonRhsIntegrationRule(rule_2);
277 auto add_base_ops = [&](
auto &pipeline) {
278 auto det_ptr = boost::make_shared<VectorDouble>();
279 auto jac_ptr = boost::make_shared<MatrixDouble>();
280 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
286 auto u_vals_ptr = boost::make_shared<VectorDouble>();
287 auto u_grad_ptr = boost::make_shared<MatrixDouble>();
289 add_base_ops(pipeline_mng->getOpDomainRhsPipeline());
290 pipeline_mng->getOpDomainRhsPipeline().push_back(
292 pipeline_mng->getOpDomainRhsPipeline().push_back(
295 enum NORMS {
L2 = 0, SEMI_NORM,
H1, LAST_NORM };
296 std::array<int, LAST_NORM> error_indices;
297 for (
int i = 0;
i != LAST_NORM; ++
i)
298 error_indices[
i] =
i;
303 error_op->doWorkRhsHook = [&](
DataOperator *op_ptr,
int side, EntityType
type,
310 if (
const size_t nb_dofs = data.getIndices().size()) {
312 const int nb_integration_pts = o->getGaussPts().size2();
313 auto t_w = o->getFTensor0IntegrationWeight();
315 auto t_grad = getFTensor1FromMat<2>(*u_grad_ptr);
316 auto t_coords = o->getFTensor1CoordsAtGaussPts();
318 std::array<double, LAST_NORM> error;
319 std::fill(error.begin(), error.end(), 0);
321 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
323 const double alpha = t_w * o->getMeasure();
325 t_val -
u_exact(t_coords(0), t_coords(1), t_coords(2));
327 auto t_exact_grad =
u_grad_exact(t_coords(0), t_coords(1), t_coords(2));
329 const double diff_grad =
330 (t_grad(
i) - t_exact_grad(
i)) * (t_grad(
i) - t_exact_grad(
i));
332 error[
L2] += alpha * pow(diff, 2);
333 error[SEMI_NORM] += alpha * diff_grad;
341 error[
H1] = error[
L2] + error[SEMI_NORM];
350 auto side_fe_ptr = boost::make_shared<FaceSideEle>(
mField);
351 add_base_ops(side_fe_ptr->getOpPtrVector());
352 side_fe_ptr->getOpPtrVector().push_back(
354 std::array<VectorDouble, 2> side_vals;
355 std::array<double, 2> area_map;
358 side_vals_op->doWorkRhsHook = [&](
DataOperator *op_ptr,
int side,
364 const auto nb_in_loop = o->getFEMethod()->nInTheLoop;
365 area_map[nb_in_loop] = o->getMeasure();
366 side_vals[nb_in_loop] = *u_vals_ptr;
369 side_vals[1].clear();
374 side_fe_ptr->getOpPtrVector().push_back(side_vals_op);
376 auto do_work_rhs_error = [&](
DataOperator *op_ptr,
int side, EntityType
type,
381 CHKERR o->loopSideFaces(
"dFE", *side_fe_ptr);
382 const auto in_the_loop = side_fe_ptr->nInTheLoop;
385 const std::array<std::string, 2> ele_type_name = {
"BOUNDARY",
"SKELETON"};
387 <<
"do_work_rhs_error in_the_loop " << ele_type_name[in_the_loop];
390 const double s = o->getMeasure() / (area_map[0] + area_map[1]);
393 constexpr std::array<int, 2> sign_array{1, -1};
395 std::array<double, LAST_NORM> error;
396 std::fill(error.begin(), error.end(), 0);
398 const int nb_integration_pts = o->getGaussPts().size2();
401 side_vals[1].resize(nb_integration_pts,
false);
402 auto t_coords = o->getFTensor1CoordsAtGaussPts();
404 for (
size_t gg = 0; gg != nb_integration_pts; ++gg) {
405 t_val_m =
u_exact(t_coords(0), t_coords(1), t_coords(2));
413 auto t_w = o->getFTensor0IntegrationWeight();
415 for (
size_t gg = 0; gg != nb_integration_pts; ++gg) {
417 const double alpha = o->getMeasure() * t_w;
418 const auto diff = t_val_p - t_val_m;
419 error[SEMI_NORM] += alpha * p * diff * diff;
427 error[
H1] = error[SEMI_NORM];
435 skeleton_error_op->doWorkRhsHook = do_work_rhs_error;
437 boundary_error_op->doWorkRhsHook = do_work_rhs_error;
439 pipeline_mng->getOpDomainRhsPipeline().push_back(error_op);
440 pipeline_mng->getOpSkeletonLhsPipeline().push_back(skeleton_error_op);
441 pipeline_mng->getOpBoundaryRhsPipeline().push_back(boundary_error_op);
443 CHKERR pipeline_mng->loopFiniteElements();
445 CHKERR VecAssemblyBegin(l2_vec);
446 CHKERR VecAssemblyEnd(l2_vec);
450 CHKERR VecGetArrayRead(l2_vec, &array);
451 MOFEM_LOG_C(
"SELF", Sev::inform,
"Error Norm L2 %6.4e",
452 std::sqrt(array[
L2]));
453 MOFEM_LOG_C(
"SELF", Sev::inform,
"Error Norm Energetic %6.4e",
454 std::sqrt(array[SEMI_NORM]));
455 MOFEM_LOG_C(
"SELF", Sev::inform,
"Error Norm H1 %6.4e",
456 std::sqrt(array[
H1]));
459 constexpr
double eps = 1e-12;
460 if (std::sqrt(array[
H1]) >
eps)
464 CHKERR VecRestoreArrayRead(l2_vec, &array);