72 enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
73 const char *list_bases[LASBASETOPT] = {
"ainsworth",
"demkowicz"};
74 PetscInt choice_base_value = AINSWORTH;
75 CHKERR PetscOptionsGetEList(PETSC_NULLPTR, NULL,
"-base", list_bases,
76 LASBASETOPT, &choice_base_value, PETSC_NULLPTR);
79 switch (choice_base_value) {
83 <<
"Set AINSWORTH_LEGENDRE_BASE for displacements";
88 <<
"Set DEMKOWICZ_JACOBI_BASE for displacements";
99 CHKERR PetscOptionsGetInt(PETSC_NULLPTR,
"",
"-order", &
order, PETSC_NULLPTR);
107 auto project_ho_geometry = [&]() {
108 Projection10NodeCoordsOnField ent_method(
mField,
"GEOMETRY");
111 CHKERR project_ho_geometry();
148 auto integration_rule_bc = [](int, int,
int approx_order) {
154 CHKERR pip->setBoundaryRhsIntegrationRule(integration_rule_bc);
155 CHKERR pip->setBoundaryLhsIntegrationRule(integration_rule_bc);
159 pip->getOpDomainLhsPipeline(), {H1},
"GEOMETRY");
161 pip->getOpDomainRhsPipeline(), {H1},
"GEOMETRY");
163 pip->getOpBoundaryRhsPipeline(), {NOSPACE},
"GEOMETRY");
165 pip->getOpBoundaryLhsPipeline(), {NOSPACE},
"GEOMETRY");
169 CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, A, I, DomainEleOp>(
170 mField, pip->getOpDomainLhsPipeline(),
"U",
"MAT_ELASTIC", Sev::verbose);
174 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, A, I, DomainEleOp>(
175 mField, pip->getOpDomainRhsPipeline(),
"U",
"MAT_ELASTIC", Sev::verbose);
179 pip->getOpDomainRhsPipeline(),
mField,
"U", Sev::inform);
185 pip->getOpBoundaryRhsPipeline(),
mField,
"U", -1, Sev::inform);
188 pip->getOpBoundaryLhsPipeline(),
mField,
"U", Sev::verbose);
231 auto solver = pip->createKSP();
233 CHKERR KSPSetFromOptions(solver);
235 auto set_essential_bc = [
this]() {
239 auto dm =
simple->getDM();
240 auto ksp_ctx_ptr = getDMKspCtx(dm);
242 auto pre_proc_rhs = boost::make_shared<FEMethod>();
243 auto post_proc_rhs = boost::make_shared<FEMethod>();
244 auto post_proc_lhs = boost::make_shared<FEMethod>();
246 auto get_pre_proc_hook = [
this, pre_proc_rhs]() {
247 return EssentialPreProc<DisplacementCubitBcData>(
mField, pre_proc_rhs,
250 pre_proc_rhs->preProcessHook = get_pre_proc_hook();
252 auto get_post_proc_hook_rhs = [
this, post_proc_rhs]() {
255 CHKERR EssentialPostProcRhs<DisplacementCubitBcData>(
mField,
256 post_proc_rhs, 1.)();
260 auto get_post_proc_hook_lhs = [
this, post_proc_lhs]() {
263 CHKERR EssentialPostProcLhs<DisplacementCubitBcData>(
mField,
264 post_proc_lhs, 1.)();
268 post_proc_rhs->postProcessHook = get_post_proc_hook_rhs;
269 post_proc_lhs->postProcessHook = get_post_proc_hook_lhs;
271 ksp_ctx_ptr->getPreProcComputeRhs().push_front(pre_proc_rhs);
272 ksp_ctx_ptr->getPostProcComputeRhs().push_back(post_proc_rhs);
273 ksp_ctx_ptr->getPostProcSetOperators().push_back(post_proc_lhs);
277 auto evaluate_field_at_the_point = [&]() {
281 std::array<double, 3> field_eval_coords{0.0, 0.0, 0.0};
283 CHKERR PetscOptionsGetRealArray(NULL, NULL,
"-field_eval_coords",
284 field_eval_coords.data(), &coords_dim,
290 auto field_eval_data =
294 ->buildTree<SPACE_DIM>(field_eval_data,
simple->getDomainFEName());
296 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
297 auto no_rule = [](int, int, int) {
return -1; };
298 auto field_eval_fe_ptr = field_eval_data->feMethodPtr;
299 field_eval_fe_ptr->getRuleHook = no_rule;
301 field_eval_fe_ptr->getOpPtrVector().push_back(
302 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U",
vectorFieldPtr));
305 ->evalFEAtThePoint<SPACE_DIM>(
306 field_eval_coords.data(), 1e-12,
simple->getProblemName(),
307 simple->getDomainFEName(), field_eval_data,
315 <<
"U_X: " << t_disp(0) <<
" U_Y: " << t_disp(1);
318 <<
"U_X: " << t_disp(0) <<
" U_Y: " << t_disp(1)
319 <<
" U_Z: " << t_disp(2);
327 CHKERR set_essential_bc();
329 CHKERR evaluate_field_at_the_point();
353 auto integration_rule = [](int, int,
int p_data) {
return 2 * p_data + 1; };
356 auto &domain_evaluation_pipeline = pip->getOpEvaluationPipeline();
358 if (domain_evaluation_pipeline.empty()) {
360 domain_evaluation_pipeline, {
H1},
"GEOMETRY");
362 auto op_loop_boundary =
new OpLoopSide<BoundaryEle>(
365 auto &boundary_evaluation_pipeline = op_loop_boundary->getOpPtrVector();
368 boundary_evaluation_pipeline, {},
"GEOMETRY");
371 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, A, I, DomainEleOp>(
372 mField, domain_evaluation_pipeline,
"U",
"MAT_ELASTIC", Sev::verbose);
375 domain_evaluation_pipeline,
mField,
"U", Sev::verbose);
378 boundary_evaluation_pipeline,
mField,
"U", -1, Sev::verbose);
379 domain_evaluation_pipeline.push_back(op_loop_boundary);
382 auto dm =
simple->getDM();
383 auto res = createDMVector(dm);
384 CHKERR VecSetDM(res, PETSC_NULLPTR);
386 pip->getEvaluationFE()->f = res;
388 CHKERR VecZeroEntries(res);
390 CHKERR pip->loopFiniteElementsEvaluation();
393 CHKERR VecGhostUpdateBegin(res, ADD_VALUES, SCATTER_REVERSE);
394 CHKERR VecGhostUpdateEnd(res, ADD_VALUES, SCATTER_REVERSE);
395 CHKERR VecAssemblyBegin(res);
396 CHKERR VecAssemblyEnd(res);
398 auto zero_residual_at_constrains = [&]() {
400 auto fe_post_proc_ptr = boost::make_shared<FEMethod>();
401 auto get_post_proc_hook_rhs = [&]() {
403 CHKERR EssentialPreProcReaction<DisplacementCubitBcData>(
404 mField, fe_post_proc_ptr, res)();
405 CHKERR EssentialPostProcRhs<DisplacementCubitBcData>(
406 mField, fe_post_proc_ptr, 0, res)();
409 fe_post_proc_ptr->postProcessHook = get_post_proc_hook_rhs;
410 CHKERR DMoFEMPostProcessFiniteElements(dm, fe_post_proc_ptr.get());
414 CHKERR zero_residual_at_constrains();
417 CHKERR VecNorm(res, NORM_2, &nrm2);
419 MOFEM_LOG_C(
"WORLD", Sev::inform,
"residual = %3.4e\n", nrm2);
422 CHKERR PetscOptionsGetInt(PETSC_NULLPTR,
"",
"-test", &test, PETSC_NULLPTR);
424 auto post_proc_residual = [&](
auto dm,
auto f_res,
auto out_name) {
427 boost::make_shared<PostProcBrokenMeshInMoab<DomainEle>>(
mField);
428 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
429 auto u_vec = boost::make_shared<MatrixDouble>();
430 post_proc_fe->getOpPtrVector().push_back(
431 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_vec, f_res));
432 post_proc_fe->getOpPtrVector().push_back(
436 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
446 CHKERR DMoFEMLoopFiniteElements(dm,
simple->getDomainFEName(),
448 post_proc_fe->writeFile(out_name);
452 CHKERR post_proc_residual(
simple->getDM(), res,
"res.h5m");
454 constexpr double eps = 1e-8;
457 "Residual is not zero");
460 if (!vectorFieldPtr || vectorFieldPtr->size1() == 0) {
462 "atom test %d failed: Field Evaluator did not provide result",
465 auto t_disp = getFTensor1FromMat<SPACE_DIM>(*vectorFieldPtr);
466 double Ux_ref = 0.46;
467 double Uy_ref = -0.03;
468 constexpr double eps = 1e-8;
469 if (fabs(t_disp(0) - Ux_ref) >
eps || fabs(t_disp(1) - Uy_ref) >
eps) {
471 "atom test %d failed: Ux_ref = %3.6e, computed = %3.6e, Uy_ref "
472 "= %3.6e, computed = %3.6e",
473 test, Ux_ref, t_disp(0), Uy_ref, t_disp(1));
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
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)
Post post-proc data at points from hash maps.
Boundary conditions in domain, i.e. body forces.