166 auto integration_rule_bc = [](int, int,
int approx_order) {
172 CHKERR pip->setBoundaryRhsIntegrationRule(integration_rule_bc);
173 CHKERR pip->setBoundaryLhsIntegrationRule(integration_rule_bc);
176 CHKERR AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
177 pip->getOpDomainLhsPipeline(), {H1},
"GEOMETRY");
178 CHKERR AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
179 pip->getOpDomainRhsPipeline(), {H1},
"GEOMETRY");
180 CHKERR AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
181 pip->getOpBoundaryRhsPipeline(), {NOSPACE},
"GEOMETRY");
182 CHKERR AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
183 pip->getOpBoundaryLhsPipeline(), {NOSPACE},
"GEOMETRY");
187 pip->getOpDomainRhsPipeline());
192 pip->getOpDomainRhsPipeline(),
mField,
"U", Sev::inform);
198 pip->getOpBoundaryRhsPipeline(),
mField,
"U", -1, Sev::inform);
201 pip->getOpBoundaryLhsPipeline(),
mField,
"U", Sev::verbose);
245 auto solver = pip->createKSP();
247 CHKERR KSPSetFromOptions(solver);
249 auto set_essential_bc = [
this]() {
253 auto dm =
simple->getDM();
254 auto ksp_ctx_ptr = getDMKspCtx(dm);
256 auto pre_proc_rhs = boost::make_shared<FEMethod>();
257 auto post_proc_rhs = boost::make_shared<FEMethod>();
258 auto post_proc_lhs = boost::make_shared<FEMethod>();
260 auto get_pre_proc_hook = [
this, pre_proc_rhs]() {
261 return EssentialPreProc<DisplacementCubitBcData>(
mField, pre_proc_rhs,
264 pre_proc_rhs->preProcessHook = get_pre_proc_hook();
266 auto get_post_proc_hook_rhs = [
this, post_proc_rhs]() {
269 CHKERR EssentialPostProcRhs<DisplacementCubitBcData>(
mField,
270 post_proc_rhs, 1.)();
274 auto get_post_proc_hook_lhs = [
this, post_proc_lhs]() {
277 CHKERR EssentialPostProcLhs<DisplacementCubitBcData>(
mField,
278 post_proc_lhs, 1.)();
282 post_proc_rhs->postProcessHook = get_post_proc_hook_rhs;
283 post_proc_lhs->postProcessHook = get_post_proc_hook_lhs;
285 ksp_ctx_ptr->getPreProcComputeRhs().push_front(pre_proc_rhs);
286 ksp_ctx_ptr->getPostProcComputeRhs().push_back(post_proc_rhs);
287 ksp_ctx_ptr->getPostProcSetOperators().push_back(post_proc_lhs);
291 CHKERR set_essential_bc();
302 auto evaluate_field_at_the_point = [&]() {
306 std::array<double, 3> field_eval_coords{0.0, 0.0, 0.0};
308 CHKERR PetscOptionsGetRealArray(NULL, NULL,
"-field_eval_coords",
309 field_eval_coords.data(), &coords_dim,
314 auto vector_field_ptr = boost::make_shared<MatrixDouble>();
315 auto field_eval_data =
319 ->buildTree<SPACE_DIM>(field_eval_data,
simple->getDomainFEName());
321 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
322 auto no_rule = [](int, int, int) {
return -1; };
323 auto field_eval_fe_ptr = field_eval_data->feMethodPtr;
324 field_eval_fe_ptr->getRuleHook = no_rule;
326 field_eval_fe_ptr->getOpPtrVector().push_back(
327 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", vector_field_ptr));
330 ->evalFEAtThePoint<SPACE_DIM>(
331 field_eval_coords.data(), 1e-12,
simple->getProblemName(),
332 simple->getDomainFEName(), field_eval_data,
336 if (vector_field_ptr->size1()) {
337 auto t_disp = getFTensor1FromMat<SPACE_DIM>(*vector_field_ptr);
340 <<
"U_X: " << t_disp(0) <<
" U_Y: " << t_disp(1);
343 <<
"U_X: " << t_disp(0) <<
" U_Y: " << t_disp(1)
344 <<
" U_Z: " << t_disp(2);
352 CHKERR evaluate_field_at_the_point();
371 auto integration_rule = [](int, int,
int p_data) {
return 2 * p_data + 1; };
374 auto &domain_evaluation_pipeline = pip->getOpEvaluationPipeline();
376 if (domain_evaluation_pipeline.empty()) {
377 CHKERR AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
378 domain_evaluation_pipeline, {
H1},
"GEOMETRY");
380 auto op_loop_boundary =
new OpLoopSide<BoundaryEle>(
383 auto &boundary_evaluation_pipeline = op_loop_boundary->getOpPtrVector();
385 CHKERR AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
386 boundary_evaluation_pipeline, {},
"GEOMETRY");
389 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, A, I, DomainEleOp>(
390 m_field, domain_evaluation_pipeline,
"U",
"MAT_ELASTIC",
394 domain_evaluation_pipeline, m_field,
"U", Sev::verbose);
397 boundary_evaluation_pipeline, m_field,
"U", -1, Sev::verbose);
398 domain_evaluation_pipeline.push_back(op_loop_boundary);
401 auto dm =
simple->getDM();
402 auto res = createDMVector(dm);
403 CHKERR VecSetDM(res, PETSC_NULLPTR);
405 pip->getEvaluationFE()->f = res;
407 CHKERR VecZeroEntries(res);
409 CHKERR pip->loopFiniteElementsEvaluation();
410 pip->getEvaluationFE()->f = PETSC_NULLPTR;
412 CHKERR VecGhostUpdateBegin(res, ADD_VALUES, SCATTER_REVERSE);
413 CHKERR VecGhostUpdateEnd(res, ADD_VALUES, SCATTER_REVERSE);
414 CHKERR VecAssemblyBegin(res);
415 CHKERR VecAssemblyEnd(res);
417 auto zero_residual_at_constrains = [&]() {
419 auto fe_post_proc_ptr = boost::make_shared<FEMethod>();
420 auto get_post_proc_hook_rhs = [&]() {
422 CHKERR EssentialPreProcReaction<DisplacementCubitBcData>(
423 m_field, fe_post_proc_ptr, res)();
424 CHKERR EssentialPostProcRhs<DisplacementCubitBcData>(
425 m_field, fe_post_proc_ptr, 0, res)();
428 fe_post_proc_ptr->postProcessHook = get_post_proc_hook_rhs;
429 CHKERR DMoFEMPostProcessFiniteElements(dm, fe_post_proc_ptr.get());
433 CHKERR zero_residual_at_constrains();
436 CHKERR VecNorm(res.get(), NORM_2, &nrm2);
438 MOFEM_LOG_C(
"WORLD", Sev::inform,
"residual = %3.4e\n", nrm2);
439 CHKERR testing->checkValue<TestType::SCALAR>(
"residual norm", nrm2, 0.,
447 auto displacement_ptr = boost::make_shared<MatrixDouble>();
448 bool point_found =
false;
450 simple->getProblemName(),
simple->getDomainFEName(), {4.5, 2.5, 0.},
451 [displacement_ptr](
auto &pipeline) {
453 pipeline.push_back(
new OpCalculateVectorFieldValues<SPACE_DIM>(
454 "U", displacement_ptr));
457 1e-12, &point_found);
458 const int local_found = point_found;
460 CHKERR MPI_Allreduce(&local_found, &found, 1, MPI_INT, MPI_SUM,
comm);
462 "point found on mesh", found ? 0. : 1., 0., {0., 0.});
464 double error_x = 0, error_y = 0;
466 using DL = DataLayoutTraits<DataLayout::GaussByCoeffs>;
468 MatrixSizeHelper<GetFTensor1FromMatType<
SPACE_DIM, -1, DL>, DL>::get(
469 *displacement_ptr, 1)();
470 error_x = std::abs(t_disp(0) - 0.46);
471 error_y = std::abs(t_disp(1) + 0.03);
473 CHKERR testing->checkError<TestType::POINTWISE>(
"U_X at point", error_x,
475 CHKERR testing->checkError<TestType::POINTWISE>(
"U_Y at point", error_y,
480 CHKERR testing->addTestCommandLine(
"", 1,
"residual is zero",
481 check_residual_is_zero);
483 "", 2,
"point displacement",
484 [check_residual_is_zero, check_point_displacement]() {
486 CHKERR check_residual_is_zero();
487 CHKERR check_point_displacement();
Boundary conditions in domain, i.e. body forces.
MoFEMErrorCode postProcessElasticResults(MoFEM::Interface &mField, SmartPetscObj< DM > dm, const std::string &domain_fe_name, const std::string &out_file_name, std::vector< std::pair< std::string, SmartPetscObj< Vec > > > extra_vectors={}, const std::vector< std::string > &tags_to_transfer={}, const Sev hooke_ops_sev=Sev::verbose)