v0.14.0
Loading...
Searching...
No Matches
elastic.cpp
Go to the documentation of this file.
1/**
2 * @file elastic.cpp
3 * @brief elastic example
4 * @version 0.13.2
5 * @date 2022-09-19
6 *
7 * @copyright Copyright (c) 2022
8 *
9 */
10
11#include <MoFEM.hpp>
12
13using namespace MoFEM;
14
15constexpr int BASE_DIM = 1; //< Dimension of the base functions
16
17//! [Define dimension]
18constexpr int SPACE_DIM =
19 EXECUTABLE_DIMENSION; //< Space dimension of problem, mesh
20//! [Define dimension]
22 ? AssemblyType::BLOCK_SCHUR
23 : AssemblyType::PETSC; //< selected assembly type
24
25constexpr IntegrationType I =
26 IntegrationType::GAUSS; //< selected integration type
27
28//! [Define entities]
33using DomainEleOp = DomainEle::UserDataOperator;
34using BoundaryEleOp = BoundaryEle::UserDataOperator;
35//! [Define entities]
36
37//! [OpK]
39 I>::OpGradSymTensorGrad<BASE_DIM, SPACE_DIM, SPACE_DIM, 0>;
40//! [OpK]
41//! [OpInternalForce]
43 I>::OpGradTimesSymTensor<BASE_DIM, SPACE_DIM, SPACE_DIM>;
44//! [OpInternalForce]
45struct DomainBCs {};
46struct BoundaryBCs {};
47
54
55template <int DIM> struct PostProcEleByDim;
56
57template <> struct PostProcEleByDim<2> {
61};
62
63template <> struct PostProcEleByDim<3> {
67};
68
72
73#include <ElasticSpring.hpp>
74#include <FluidLevel.hpp>
75#include <CalculateTraction.hpp>
76#include <NaturalDomainBC.hpp>
77#include <NaturalBoundaryBC.hpp>
78
79constexpr double young_modulus = 1;
80constexpr double poisson_ratio = 0.3;
81constexpr double bulk_modulus_K = young_modulus / (3 * (1 - 2 * poisson_ratio));
82constexpr double shear_modulus_G = young_modulus / (2 * (1 + poisson_ratio));
83
84PetscBool is_plane_strain = PETSC_FALSE;
85
86struct Example {
87
88 Example(MoFEM::Interface &m_field) : mField(m_field) {}
89
91
92private:
94
95 PetscBool doEvalField;
96 std::array<double, SPACE_DIM> fieldEvalCoords;
97 boost::shared_ptr<FieldEvaluatorInterface::SetPtsData> fieldEvalData;
98 boost::shared_ptr<MatrixDouble> vectorFieldPtr;
99
107
109 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
110 std::string field_name, std::string block_name,
111 boost::shared_ptr<MatrixDouble> mat_D_Ptr, Sev sev);
112};
113
115 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
116 std::string field_name, std::string block_name,
117 boost::shared_ptr<MatrixDouble> mat_D_Ptr, Sev sev) {
119
120 struct OpMatBlocks : public DomainEleOp {
121 OpMatBlocks(std::string field_name, boost::shared_ptr<MatrixDouble> m,
122 double bulk_modulus_K, double shear_modulus_G,
123 MoFEM::Interface &m_field, Sev sev,
124 std::vector<const CubitMeshSets *> meshset_vec_ptr)
125 : DomainEleOp(field_name, DomainEleOp::OPROW), matDPtr(m),
126 bulkModulusKDefault(bulk_modulus_K),
127 shearModulusGDefault(shear_modulus_G) {
128 std::fill(&(doEntities[MBEDGE]), &(doEntities[MBMAXTYPE]), false);
129 CHK_THROW_MESSAGE(extractBlockData(m_field, meshset_vec_ptr, sev),
130 "Can not get data from block");
131 }
132
133 MoFEMErrorCode doWork(int side, EntityType type,
136
137 for (auto &b : blockData) {
138
139 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
140 CHKERR getMatDPtr(matDPtr, b.bulkModulusK, b.shearModulusG);
142 }
143 }
144
145 CHKERR getMatDPtr(matDPtr, bulkModulusKDefault, shearModulusGDefault);
147 }
148
149 private:
150 boost::shared_ptr<MatrixDouble> matDPtr;
151
152 struct BlockData {
153 double bulkModulusK;
154 double shearModulusG;
155 Range blockEnts;
156 };
157
158 double bulkModulusKDefault;
159 double shearModulusGDefault;
160 std::vector<BlockData> blockData;
161
163 extractBlockData(MoFEM::Interface &m_field,
164 std::vector<const CubitMeshSets *> meshset_vec_ptr,
165 Sev sev) {
167
168 for (auto m : meshset_vec_ptr) {
169 MOFEM_TAG_AND_LOG("WORLD", sev, "MatBlock") << *m;
170 std::vector<double> block_data;
171 CHKERR m->getAttributes(block_data);
172 if (block_data.size() < 2) {
173 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
174 "Expected that block has two attributes");
175 }
176 auto get_block_ents = [&]() {
177 Range ents;
178 CHKERR
179 m_field.get_moab().get_entities_by_handle(m->meshset, ents, true);
180 return ents;
181 };
182
183 double young_modulus = block_data[0];
184 double poisson_ratio = block_data[1];
185 double bulk_modulus_K = young_modulus / (3 * (1 - 2 * poisson_ratio));
186 double shear_modulus_G = young_modulus / (2 * (1 + poisson_ratio));
187
188 MOFEM_TAG_AND_LOG("WORLD", sev, "MatBlock")
189 << "E = " << young_modulus << " nu = " << poisson_ratio;
190
191 blockData.push_back(
192 {bulk_modulus_K, shear_modulus_G, get_block_ents()});
193 }
194 MOFEM_LOG_CHANNEL("WORLD");
196 }
197
198 MoFEMErrorCode getMatDPtr(boost::shared_ptr<MatrixDouble> mat_D_ptr,
199 double bulk_modulus_K, double shear_modulus_G) {
201 //! [Calculate elasticity tensor]
202 auto set_material_stiffness = [&]() {
208 double A = 1.;
209 if (SPACE_DIM == 2 && !is_plane_strain) {
210 A = 2 * shear_modulus_G /
211 (bulk_modulus_K + (4. / 3.) * shear_modulus_G);
212 }
214 t_D(i, j, k, l) =
215 2 * shear_modulus_G * ((t_kd(i, k) ^ t_kd(j, l)) / 4.) +
216 A * (bulk_modulus_K - (2. / 3.) * shear_modulus_G) * t_kd(i, j) *
217 t_kd(k, l);
218 };
219 //! [Calculate elasticity tensor]
220 constexpr auto size_symm = (SPACE_DIM * (SPACE_DIM + 1)) / 2;
221 mat_D_ptr->resize(size_symm * size_symm, 1);
222 set_material_stiffness();
224 }
225 };
226
227 pipeline.push_back(new OpMatBlocks(
229
230 // Get blockset using regular expression
232
233 (boost::format("%s(.*)") % block_name).str()
234
235 ))
236
237 ));
238
240}
241
242//! [Run problem]
253}
254//! [Run problem]
255
256//! [Read mesh]
260 CHKERR simple->getOptions();
261 CHKERR simple->loadFile();
263}
264//! [Read mesh]
265
266//! [Set up problem]
270
271 enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
272 const char *list_bases[LASBASETOPT] = {"ainsworth", "demkowicz"};
273 PetscInt choice_base_value = AINSWORTH;
274 CHKERR PetscOptionsGetEList(PETSC_NULL, NULL, "-base", list_bases,
275 LASBASETOPT, &choice_base_value, PETSC_NULL);
276
278 switch (choice_base_value) {
279 case AINSWORTH:
281 MOFEM_LOG("WORLD", Sev::inform)
282 << "Set AINSWORTH_LEGENDRE_BASE for displacements";
283 break;
284 case DEMKOWICZ:
286 MOFEM_LOG("WORLD", Sev::inform)
287 << "Set DEMKOWICZ_JACOBI_BASE for displacements";
288 break;
289 default:
290 base = LASTBASE;
291 break;
292 }
293
294 // Add field
295 CHKERR simple->addDomainField("U", H1, base, SPACE_DIM);
296 CHKERR simple->addBoundaryField("U", H1, base, SPACE_DIM);
297 int order = 3;
298 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-order", &order, PETSC_NULL);
299
300 CHKERR simple->addDataField("GEOMETRY", H1, base, SPACE_DIM);
301
302 CHKERR simple->setFieldOrder("U", order);
303 CHKERR simple->setFieldOrder("GEOMETRY", 2);
304 CHKERR simple->setUp();
305
306 auto project_ho_geometry = [&]() {
307 Projection10NodeCoordsOnField ent_method(mField, "GEOMETRY");
308 return mField.loop_dofs("GEOMETRY", ent_method);
309 };
310 CHKERR project_ho_geometry();
311
312 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-plane_strain", &is_plane_strain,
313 PETSC_NULL);
314
315 int coords_dim = SPACE_DIM;
316 CHKERR PetscOptionsGetRealArray(NULL, NULL, "-field_eval_coords",
317 fieldEvalCoords.data(), &coords_dim,
318 &doEvalField);
319
320 if (doEvalField) {
321 vectorFieldPtr = boost::make_shared<MatrixDouble>();
323 mField.getInterface<FieldEvaluatorInterface>()->getData<DomainEle>();
324
325 if constexpr (SPACE_DIM == 3) {
327 fieldEvalData, simple->getDomainFEName());
328 } else {
330 fieldEvalData, simple->getDomainFEName());
331 }
332
333 fieldEvalData->setEvalPoints(fieldEvalCoords.data(), 1);
334 auto no_rule = [](int, int, int) { return -1; };
335 auto field_eval_fe_ptr = fieldEvalData->feMethodPtr.lock();
336 field_eval_fe_ptr->getRuleHook = no_rule;
337
338 field_eval_fe_ptr->getOpPtrVector().push_back(
340 }
341
343}
344//! [Set up problem]
345
346//! [Boundary condition]
349 auto pip = mField.getInterface<PipelineManager>();
351 auto bc_mng = mField.getInterface<BcManager>();
352
353 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_X",
354 "U", 0, 0);
355 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Y",
356 "U", 1, 1);
357 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Z",
358 "U", 2, 2);
359 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
360 "REMOVE_ALL", "U", 0, 3);
361 CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
362 simple->getProblemName(), "U");
363
364 // adding MPCs
365 CHKERR bc_mng->addBlockDOFsToMPCs(simple->getProblemName(), "U");
366
368}
369//! [Boundary condition]
370
371//! [Push operators to pipeline]
374 auto pip = mField.getInterface<PipelineManager>();
376 auto bc_mng = mField.getInterface<BcManager>();
377
378 //! [Integration rule]
379 auto integration_rule = [](int, int, int approx_order) {
380 return 2 * approx_order + 1;
381 };
382
383 auto integration_rule_bc = [](int, int, int approx_order) {
384 return 2 * approx_order + 1;
385 };
386
387 CHKERR pip->setDomainRhsIntegrationRule(integration_rule);
388 CHKERR pip->setDomainLhsIntegrationRule(integration_rule);
389 CHKERR pip->setBoundaryRhsIntegrationRule(integration_rule_bc);
390 CHKERR pip->setBoundaryLhsIntegrationRule(integration_rule_bc);
391 //! [Integration rule]
392
394 pip->getOpDomainLhsPipeline(), {H1}, "GEOMETRY");
396 pip->getOpDomainRhsPipeline(), {H1}, "GEOMETRY");
398 pip->getOpBoundaryRhsPipeline(), {NOSPACE}, "GEOMETRY");
400 pip->getOpBoundaryLhsPipeline(), {NOSPACE}, "GEOMETRY");
401
402 //! [Push domain stiffness matrix to pipeline]
403 auto mat_D_ptr = boost::make_shared<MatrixDouble>();
404
405 // Assemble domain stiffness matrix
406 CHKERR addMatBlockOps(pip->getOpDomainLhsPipeline(), "U", "MAT_ELASTIC",
407 mat_D_ptr, Sev::verbose);
408 pip->getOpDomainLhsPipeline().push_back(new OpK("U", "U", mat_D_ptr));
409 //! [Push domain stiffness matrix to pipeline]
410
411 //! [Push Internal forces]
412 auto mat_grad_ptr = boost::make_shared<MatrixDouble>();
413 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
414 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
415 pip->getOpDomainRhsPipeline().push_back(
417 mat_grad_ptr));
418 CHKERR addMatBlockOps(pip->getOpDomainRhsPipeline(), "U", "MAT_ELASTIC",
419 mat_D_ptr, Sev::inform);
420 pip->getOpDomainRhsPipeline().push_back(
421 new OpSymmetrizeTensor<SPACE_DIM>(mat_grad_ptr, mat_strain_ptr));
422 pip->getOpDomainRhsPipeline().push_back(
424 mat_strain_ptr, mat_stress_ptr, mat_D_ptr));
425
426 pip->getOpDomainRhsPipeline().push_back(
427 new OpInternalForce("U", mat_stress_ptr,
428 [](double, double, double) constexpr { return -1; }));
429 //! [Push Internal forces]
430
431 //! [Push Body forces]
433 pip->getOpDomainRhsPipeline(), mField, "U", Sev::inform);
434 //! [Push Body forces]
435
436 //! [Push natural boundary conditions]
437 // Add force boundary condition
439 pip->getOpBoundaryRhsPipeline(), mField, "U", -1, Sev::inform);
440 // Add case for mix type of BCs
442 pip->getOpBoundaryLhsPipeline(), mField, "U", Sev::verbose);
443 //! [Push natural boundary conditions]
445}
446//! [Push operators to pipeline]
447
448struct SetUpSchur {
449 static boost::shared_ptr<SetUpSchur>
452
453protected:
454 SetUpSchur() = default;
455};
456
457//! [Solve]
461 auto pip = mField.getInterface<PipelineManager>();
462 auto solver = pip->createKSP();
463 CHKERR KSPSetFromOptions(solver);
464
465 auto dm = simple->getDM();
466 auto D = createDMVector(dm);
467 auto F = vectorDuplicate(D);
468
469 auto set_essential_bc = [&]() {
471 // This is low level pushing finite elements (pipelines) to solver
472 auto ksp_ctx_ptr = getDMKspCtx(dm);
473
474 auto pre_proc_rhs = boost::make_shared<FEMethod>();
475 auto post_proc_rhs = boost::make_shared<FEMethod>();
476 auto post_proc_lhs = boost::make_shared<FEMethod>();
477
478 auto get_pre_proc_hook = [&]() {
480 {});
481 };
482 pre_proc_rhs->preProcessHook = get_pre_proc_hook();
483
484 auto get_post_proc_hook_rhs = [this, post_proc_rhs]() {
486
488 post_proc_rhs, 1.)();
489 CHKERR EssentialPostProcRhs<MPCsType>(mField, post_proc_rhs, 1.)();
491 };
492
493 auto get_post_proc_hook_lhs = [this, post_proc_lhs]() {
495
497 post_proc_lhs, 1.)();
500 };
501
502 post_proc_rhs->postProcessHook = get_post_proc_hook_rhs;
503 post_proc_lhs->postProcessHook = get_post_proc_hook_lhs;
504
505 ksp_ctx_ptr->getPreProcComputeRhs().push_front(pre_proc_rhs);
506 ksp_ctx_ptr->getPostProcComputeRhs().push_back(post_proc_rhs);
507 ksp_ctx_ptr->getPostProcSetOperators().push_back(post_proc_lhs);
509 };
510
511 auto setup_and_solve = [&]() {
513 BOOST_LOG_SCOPED_THREAD_ATTR("Timeline", attrs::timer());
514 MOFEM_LOG("TIMER", Sev::inform) << "KSPSetUp";
515 CHKERR KSPSetUp(solver);
516 MOFEM_LOG("TIMER", Sev::inform) << "KSPSetUp <= Done";
517 MOFEM_LOG("TIMER", Sev::inform) << "KSPSolve";
518 CHKERR KSPSolve(solver, F, D);
519 MOFEM_LOG("TIMER", Sev::inform) << "KSPSolve <= Done";
521 };
522
523 MOFEM_LOG_CHANNEL("TIMER");
524 MOFEM_LOG_TAG("TIMER", "timer");
525
526 CHKERR set_essential_bc();
527
528 if (A == AssemblyType::BLOCK_SCHUR || A == AssemblyType::SCHUR) {
529 auto schur_ptr = SetUpSchur::createSetUpSchur(mField);
530 CHKERR schur_ptr->setUp(solver);
531 CHKERR setup_and_solve();
532 } else {
533 CHKERR setup_and_solve();
534 }
535
536 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
537 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
538 CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_REVERSE);
539
540 if (doEvalField) {
541 if constexpr (SPACE_DIM == 3) {
542 CHKERR mField.getInterface<FieldEvaluatorInterface>()->evalFEAtThePoint3D(
543 fieldEvalCoords.data(), 1e-12, simple->getProblemName(),
544 simple->getDomainFEName(), fieldEvalData, mField.get_comm_rank(),
545 mField.get_comm_rank(), nullptr, MF_EXIST, QUIET);
546 } else {
547 CHKERR mField.getInterface<FieldEvaluatorInterface>()->evalFEAtThePoint2D(
548 fieldEvalCoords.data(), 1e-12, simple->getProblemName(),
549 simple->getDomainFEName(), fieldEvalData, mField.get_comm_rank(),
550 mField.get_comm_rank(), nullptr, MF_EXIST, QUIET);
551 }
552
553 if (vectorFieldPtr->size1()) {
555 if constexpr (SPACE_DIM == 2)
556 MOFEM_LOG("FieldEvaluator", Sev::inform)
557 << "U_X: " << t_disp(0) << " U_Y: " << t_disp(1);
558 else
559 MOFEM_LOG("FieldEvaluator", Sev::inform)
560 << "U_X: " << t_disp(0) << " U_Y: " << t_disp(1)
561 << " U_Z: " << t_disp(2);
562 }
563
565 }
566
568}
569//! [Solve]
570
571//! [Postprocess results]
575 auto pip = mField.getInterface<PipelineManager>();
576 auto det_ptr = boost::make_shared<VectorDouble>();
577 auto jac_ptr = boost::make_shared<MatrixDouble>();
578 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
579 //! [Postprocess clean]
580 pip->getDomainRhsFE().reset();
581 pip->getDomainLhsFE().reset();
582 pip->getBoundaryRhsFE().reset();
583 pip->getBoundaryLhsFE().reset();
584 //! [Postprocess clean]
585
586 //! [Postprocess initialise]
587 auto post_proc_mesh = boost::make_shared<moab::Core>();
588 auto post_proc_begin = boost::make_shared<PostProcBrokenMeshInMoabBaseBegin>(
589 mField, post_proc_mesh);
590 auto post_proc_end = boost::make_shared<PostProcBrokenMeshInMoabBaseEnd>(
591 mField, post_proc_mesh);
592 //! [Postprocess initialise]
593
594 auto calculate_stress_ops = [&](auto &pip) {
596 auto mat_grad_ptr = boost::make_shared<MatrixDouble>();
597 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
598 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
600 "U", mat_grad_ptr));
601 auto mat_D_ptr = boost::make_shared<MatrixDouble>();
602 CHKERR addMatBlockOps(pip, "U", "MAT_ELASTIC", mat_D_ptr, Sev::verbose);
603 pip.push_back(
604 new OpSymmetrizeTensor<SPACE_DIM>(mat_grad_ptr, mat_strain_ptr));
606 mat_strain_ptr, mat_stress_ptr, mat_D_ptr));
607 auto u_ptr = boost::make_shared<MatrixDouble>();
608 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
609 auto x_ptr = boost::make_shared<MatrixDouble>();
610 pip.push_back(
611 new OpCalculateVectorFieldValues<SPACE_DIM>("GEOMETRY", x_ptr));
612 return boost::make_tuple(u_ptr, x_ptr, mat_strain_ptr, mat_stress_ptr);
613 };
614
615 auto get_tag_id_on_pmesh = [&](bool post_proc_skin)
616 {
617 int def_val_int = 0;
618 Tag tag_mat;
619 CHKERR mField.get_moab().tag_get_handle(
620 "MAT_ELASTIC", 1, MB_TYPE_INTEGER, tag_mat,
621 MB_TAG_CREAT | MB_TAG_SPARSE, &def_val_int);
622 auto meshset_vec_ptr =
623 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
624 std::regex((boost::format("%s(.*)") % "MAT_ELASTIC").str()));
625
626 Range skin_ents;
627 std::unique_ptr<Skinner> skin_ptr;
628 if (post_proc_skin) {
629 skin_ptr = std::make_unique<Skinner>(&mField.get_moab());
630 auto boundary_meshset = simple->getBoundaryMeshSet();
631 CHKERR mField.get_moab().get_entities_by_handle(boundary_meshset,
632 skin_ents, true);
633 }
634
635 for (auto m : meshset_vec_ptr) {
636 Range ents_3d;
637 CHKERR mField.get_moab().get_entities_by_handle(m->getMeshset(), ents_3d,
638 true);
639 int const id = m->getMeshsetId();
640 ents_3d = ents_3d.subset_by_dimension(SPACE_DIM);
641 if (post_proc_skin) {
642 Range skin_faces;
643 CHKERR skin_ptr->find_skin(0, ents_3d, false, skin_faces);
644 ents_3d = intersect(skin_ents, skin_faces);
645 }
646 CHKERR mField.get_moab().tag_clear_data(tag_mat, ents_3d, &id);
647 }
648
649 return tag_mat;
650 };
651
652 auto post_proc_domain = [&](auto post_proc_mesh) {
653 auto post_proc_fe =
654 boost::make_shared<PostProcEleDomain>(mField, post_proc_mesh);
656
657 auto [u_ptr, x_ptr, mat_strain_ptr, mat_stress_ptr] =
658 calculate_stress_ops(post_proc_fe->getOpPtrVector());
659
660 post_proc_fe->getOpPtrVector().push_back(
661
662 new OpPPMap(
663
664 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
665
666 {},
667
668 {{"U", u_ptr}, {"GEOMETRY", x_ptr}},
669
670 {},
671
672 {{"STRAIN", mat_strain_ptr}, {"STRESS", mat_stress_ptr}}
673
674 )
675
676 );
677
678 post_proc_fe->setTagsToTransfer({get_tag_id_on_pmesh(false)});
679 return post_proc_fe;
680 };
681
682 auto post_proc_boundary = [&](auto post_proc_mesh) {
683 auto post_proc_fe =
684 boost::make_shared<PostProcEleBdy>(mField, post_proc_mesh);
686 post_proc_fe->getOpPtrVector(), {}, "GEOMETRY");
687 auto op_loop_side =
688 new OpLoopSide<SideEle>(mField, simple->getDomainFEName(), SPACE_DIM);
689 // push ops to side element, through op_loop_side operator
690 auto [u_ptr, x_ptr, mat_strain_ptr, mat_stress_ptr] =
691 calculate_stress_ops(op_loop_side->getOpPtrVector());
692 post_proc_fe->getOpPtrVector().push_back(op_loop_side);
693 auto mat_traction_ptr = boost::make_shared<MatrixDouble>();
694 post_proc_fe->getOpPtrVector().push_back(
695 new ElasticExample::OpCalculateTraction(mat_stress_ptr,
696 mat_traction_ptr));
697
699
700 post_proc_fe->getOpPtrVector().push_back(
701
702 new OpPPMap(
703
704 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
705
706 {},
707
708 {{"U", u_ptr}, {"GEOMETRY", x_ptr}, {"T", mat_traction_ptr}},
709
710 {},
711
712 {{"STRAIN", mat_strain_ptr}, {"STRESS", mat_stress_ptr}}
713
714 )
715
716 );
717
718 post_proc_fe->setTagsToTransfer({get_tag_id_on_pmesh(true)});
719 return post_proc_fe;
720 };
721
722 PetscBool post_proc_skin_only = PETSC_FALSE;
723 if (SPACE_DIM == 3) {
724 post_proc_skin_only = PETSC_TRUE;
725 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-post_proc_skin_only",
726 &post_proc_skin_only, PETSC_NULL);
727 }
728 if (post_proc_skin_only == PETSC_FALSE) {
729 pip->getDomainRhsFE() = post_proc_domain(post_proc_mesh);
730 } else {
731 pip->getBoundaryRhsFE() = post_proc_boundary(post_proc_mesh);
732 }
733
735 post_proc_begin->getFEMethod());
736 CHKERR pip->loopFiniteElements();
738 post_proc_end->getFEMethod());
739
740 CHKERR post_proc_end->writeFile("out_elastic.h5m");
742}
743//! [Postprocess results]
744
745//! [Check]
747 MOFEM_LOG_CHANNEL("WORLD");
749 auto pip = mField.getInterface<PipelineManager>();
751 pip->getDomainRhsFE().reset();
752 pip->getDomainLhsFE().reset();
753 pip->getBoundaryRhsFE().reset();
754 pip->getBoundaryLhsFE().reset();
755
756 auto integration_rule = [](int, int, int p_data) { return 2 * p_data + 1; };
757 CHKERR pip->setDomainRhsIntegrationRule(integration_rule);
758 CHKERR pip->setBoundaryRhsIntegrationRule(integration_rule);
759
761 pip->getOpDomainRhsPipeline(), {H1}, "GEOMETRY");
763 pip->getOpBoundaryRhsPipeline(), {}, "GEOMETRY");
764
765 auto mat_grad_ptr = boost::make_shared<MatrixDouble>();
766 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
767 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
768
769 pip->getOpDomainRhsPipeline().push_back(
771 mat_grad_ptr));
772 pip->getOpDomainRhsPipeline().push_back(
773 new OpSymmetrizeTensor<SPACE_DIM>(mat_grad_ptr, mat_strain_ptr));
774
775 auto mat_D_ptr = boost::make_shared<MatrixDouble>();
776 CHKERR addMatBlockOps(pip->getOpDomainRhsPipeline(), "U", "MAT_ELASTIC",
777 mat_D_ptr, Sev::verbose);
778 pip->getOpDomainRhsPipeline().push_back(
780 mat_strain_ptr, mat_stress_ptr, mat_D_ptr));
781
782 pip->getOpDomainRhsPipeline().push_back(
783 new OpInternalForce("U", mat_stress_ptr));
784
785 pip->getOpBoundaryRhsPipeline().push_back(
787 mat_strain_ptr, mat_stress_ptr, mat_D_ptr));
789 pip->getOpDomainRhsPipeline(), mField, "U", Sev::verbose);
791 pip->getOpBoundaryRhsPipeline(), mField, "U", -1, Sev::verbose);
792
793 auto dm = simple->getDM();
794 auto res = createDMVector(dm);
795 CHKERR VecSetDM(res, PETSC_NULL);
796
797 pip->getDomainRhsFE()->f = res;
798 pip->getBoundaryRhsFE()->f = res;
799
800 CHKERR VecZeroEntries(res);
801
802 CHKERR mField.getInterface<FieldBlas>()->fieldScale(-1, "U");
803 CHKERR pip->loopFiniteElements();
804 CHKERR mField.getInterface<FieldBlas>()->fieldScale(-1, "U");
805
806 CHKERR VecGhostUpdateBegin(res, ADD_VALUES, SCATTER_REVERSE);
807 CHKERR VecGhostUpdateEnd(res, ADD_VALUES, SCATTER_REVERSE);
808 CHKERR VecAssemblyBegin(res);
809 CHKERR VecAssemblyEnd(res);
810
811 auto zero_residual_at_constrains = [&]() {
813 auto fe_post_proc_ptr = boost::make_shared<FEMethod>();
814 auto get_post_proc_hook_rhs = [&]() {
817 mField, fe_post_proc_ptr, res)();
819 mField, fe_post_proc_ptr, 0, res)();
820 CHKERR EssentialPostProcRhs<MPCsType>(mField, fe_post_proc_ptr, 0, res)();
822 };
823 fe_post_proc_ptr->postProcessHook = get_post_proc_hook_rhs;
824 CHKERR DMoFEMPostProcessFiniteElements(dm, fe_post_proc_ptr.get());
826 };
827
828 CHKERR zero_residual_at_constrains();
829
830 double nrm2;
831 CHKERR VecNorm(res, NORM_2, &nrm2);
832 MOFEM_LOG_CHANNEL("WORLD");
833 MOFEM_LOG_C("WORLD", Sev::inform, "residual = %3.4e\n", nrm2);
834
835 PetscBool test = PETSC_FALSE;
836 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-test", &test, PETSC_NULL);
837 if (test == PETSC_TRUE) {
838
839 auto post_proc_residual = [&](auto dm, auto f_res, auto out_name) {
841 auto post_proc_fe =
842 boost::make_shared<PostProcBrokenMeshInMoab<DomainEle>>(mField);
844 auto u_vec = boost::make_shared<MatrixDouble>();
845 post_proc_fe->getOpPtrVector().push_back(
846 new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_vec, f_res));
847 post_proc_fe->getOpPtrVector().push_back(
848
849 new OpPPMap(
850
851 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
852
853 {},
854
855 {{"RES", u_vec}},
856
857 {}, {})
858
859 );
860
861 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(),
862 post_proc_fe);
863 post_proc_fe->writeFile(out_name);
865 };
866
867 CHKERR post_proc_residual(simple->getDM(), res, "res.h5m");
868
869 constexpr double eps = 1e-8;
870 if (nrm2 > eps)
871 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
872 "Residual is not zero");
873 }
874
876}
877//! [Check]
878
879static char help[] = "...\n\n";
880
881int main(int argc, char *argv[]) {
882
883 // Initialisation of MoFEM/PETSc and MOAB data structures
884 const char param_file[] = "param_file.petsc";
885 MoFEM::Core::Initialize(&argc, &argv, param_file, help);
886
887 auto core_log = logging::core::get();
888 core_log->add_sink(
890
891 core_log->add_sink(
893 LogManager::setLog("FieldEvaluator");
894 MOFEM_LOG_TAG("FieldEvaluator", "field_eval");
895
896 try {
897
898 //! [Register MoFEM discrete manager in PETSc]
899 DMType dm_name = "DMMOFEM";
900 CHKERR DMRegister_MoFEM(dm_name);
901 DMType dm_name_mg = "DMMOFEM_MG";
903 //! [Register MoFEM discrete manager in PETSc
904
905 //! [Create MoAB]
906 moab::Core mb_instance; ///< mesh database
907 moab::Interface &moab = mb_instance; ///< mesh database interface
908 //! [Create MoAB]
909
910 //! [Create MoFEM]
911 MoFEM::Core core(moab); ///< finite element database
912 MoFEM::Interface &m_field = core; ///< finite element database interface
913 //! [Create MoFEM]
914
915 //! [Example]
916 Example ex(m_field);
917 CHKERR ex.runProblem();
918 //! [Example]
919 }
921
923}
924
925struct SetUpSchurImpl : public SetUpSchur {
926
928 if (S) {
931 "Is expected that schur matrix is not allocated. This is "
932 "possible only is PC is set up twice");
933 }
934 }
935 virtual ~SetUpSchurImpl() = default;
936
938
939private:
945
947
949
954};
955
959 auto pip = mField.getInterface<PipelineManager>();
960 PC pc;
961 CHKERR KSPGetPC(solver, &pc);
962 PetscBool is_pcfs = PETSC_FALSE;
963 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
964 if (is_pcfs) {
965 if (S) {
968 "Is expected that schur matrix is not allocated. This is "
969 "possible only is PC is set up twice");
970 }
973
974 // Add data to DM storage
976 CHKERR MatSetDM(S, PETSC_NULL);
977 CHKERR MatSetBlockSize(S, SPACE_DIM);
978 CHKERR MatSetOption(S, MAT_SYMMETRIC, PETSC_TRUE);
979
981 CHKERR setPC(pc);
982
983 if constexpr (A == AssemblyType::BLOCK_SCHUR) {
984 // Set DM to use shell block matrix
985 DM solver_dm;
986 CHKERR KSPGetDM(solver, &solver_dm);
987 CHKERR DMSetMatType(solver_dm, MATSHELL);
988 }
989 CHKERR KSPSetUp(solver);
991
992 } else {
993 pip->getOpBoundaryLhsPipeline().push_front(createOpSchurAssembleBegin());
994 pip->getOpBoundaryLhsPipeline().push_back(createOpSchurAssembleEnd({}, {}));
995 pip->getOpDomainLhsPipeline().push_front(createOpSchurAssembleBegin());
996 pip->getOpDomainLhsPipeline().push_back(createOpSchurAssembleEnd({}, {}));
997 }
999}
1000
1003 auto simple = mField.getInterface<Simple>();
1004 CHKERR mField.get_moab().get_entities_by_dimension(simple->getMeshset(),
1006 CHKERR mField.get_moab().get_entities_by_handle(simple->getMeshset(),
1007 subEnts);
1008 subEnts = subtract(subEnts, volEnts);
1010};
1011
1014 auto simple = mField.getInterface<Simple>();
1015
1016 auto create_dm = [&](const char *name, auto &ents, auto dm_type) {
1017 auto dm = createDM(mField.get_comm(), dm_type);
1018 auto create_dm_imp = [&]() {
1020 CHKERR DMMoFEMCreateSubDM(dm, simple->getDM(), name);
1021 CHKERR DMMoFEMSetSquareProblem(dm, PETSC_TRUE);
1022 CHKERR DMMoFEMAddElement(dm, simple->getDomainFEName());
1023 auto sub_ents_ptr = boost::make_shared<Range>(ents);
1024 CHKERR DMMoFEMAddSubFieldRow(dm, "U", sub_ents_ptr);
1025 CHKERR DMMoFEMAddSubFieldCol(dm, "U", sub_ents_ptr);
1026 CHKERR DMSetUp(dm);
1028 };
1029 CHK_THROW_MESSAGE(create_dm_imp(),
1030 "Error in creating schurDM. It is possible that schurDM is "
1031 "already created");
1032 return dm;
1033 };
1034
1035 schurDM = create_dm("SCHUR", subEnts, "DMMOFEM_MG");
1036 blockDM = create_dm("BLOCK", volEnts, "DMMOFEM");
1037
1038 if constexpr (A == AssemblyType::BLOCK_SCHUR) {
1039
1040 auto get_nested_mat_data = [&]() -> boost::shared_ptr<NestSchurData> {
1041 auto block_mat_data =
1043
1044 {{
1045
1046 simple->getDomainFEName(),
1047
1048 {{"U", "U"}
1049
1050 }}}
1051
1052 );
1053
1055
1056 {schurDM, blockDM}, block_mat_data,
1057
1058 {"U"}, {boost::make_shared<Range>(volEnts)}
1059
1060 );
1061 };
1062
1063 auto nested_mat_data = get_nested_mat_data();
1064
1065 CHKERR DMMoFEMSetNestSchurData(simple->getDM(), nested_mat_data);
1066 }
1067
1069}
1070
1073 auto simple = mField.getInterface<Simple>();
1074 auto pip = mField.getInterface<PipelineManager>();
1075
1076 // Boundary
1077 auto dm_is = getDMSubData(schurDM)->getSmartRowIs();
1078 auto ao_up = createAOMappingIS(dm_is, PETSC_NULL);
1079 pip->getOpBoundaryLhsPipeline().push_front(createOpSchurAssembleBegin());
1080 pip->getOpBoundaryLhsPipeline().push_back(createOpSchurAssembleEnd(
1081 {"U"}, {boost::make_shared<Range>(volEnts)}, ao_up, S, true, true));
1082 // Domain
1083 pip->getOpDomainLhsPipeline().push_front(createOpSchurAssembleBegin());
1084 pip->getOpDomainLhsPipeline().push_back(createOpSchurAssembleEnd(
1085 {"U"}, {boost::make_shared<Range>(volEnts)}, ao_up, S, true, true));
1086
1087 auto pre_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
1088 auto post_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
1089
1090 pre_proc_schur_lhs_ptr->preProcessHook = [this]() {
1092 if (S) {
1093 CHKERR MatZeroEntries(S);
1094 }
1095 MOFEM_LOG("TIMER", Sev::inform) << "Lhs Assemble Begin";
1097 };
1098
1099 post_proc_schur_lhs_ptr->postProcessHook = [this, post_proc_schur_lhs_ptr,
1100 ao_up]() {
1102 CHKERR MatAssemblyBegin(S, MAT_FINAL_ASSEMBLY);
1103 CHKERR MatAssemblyEnd(S, MAT_FINAL_ASSEMBLY);
1105 mField, post_proc_schur_lhs_ptr, 1, S, ao_up)();
1106 MOFEM_LOG("TIMER", Sev::inform) << "Lhs Assemble End";
1108 };
1109
1110 auto ksp_ctx_ptr = getDMKspCtx(simple->getDM());
1111 ksp_ctx_ptr->getPreProcSetOperators().push_front(pre_proc_schur_lhs_ptr);
1112 ksp_ctx_ptr->getPostProcSetOperators().push_back(post_proc_schur_lhs_ptr);
1113
1115}
1116
1119 auto simple = mField.getInterface<Simple>();
1120 SmartPetscObj<IS> vol_is;
1121 mField.getInterface<ISManager>()->isCreateProblemFieldAndRank(
1122 simple->getProblemName(), ROW, "U", 0, SPACE_DIM, vol_is, &volEnts);
1123 CHKERR PCFieldSplitSetIS(pc, NULL, vol_is);
1124 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER, S);
1126}
1127
1130
1131 auto get_pc = [](auto ksp) {
1132 PC pc_raw;
1133 CHKERR KSPGetPC(ksp, &pc_raw);
1134 return SmartPetscObj<PC>(pc_raw, true); // bump reference
1135 };
1136
1137 if constexpr (A == AssemblyType::BLOCK_SCHUR) {
1138 auto simple = mField.getInterface<Simple>();
1139 auto A = createDMBlockMat(simple->getDM());
1140 auto P = createDMNestSchurMat(simple->getDM());
1141 CHKERR PCSetOperators(pc, A, P);
1142
1143 KSP *subksp;
1144 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULL, &subksp);
1145 CHKERR setSchurA00MatSolvePC(get_pc(subksp[0]));
1146
1147 auto set_pc_p_mg = [](auto dm, auto pc, auto S) {
1149 CHKERR PCSetDM(pc, dm);
1150 PetscBool same = PETSC_FALSE;
1151 PetscObjectTypeCompare((PetscObject)pc, PCMG, &same);
1152 if (same) {
1154 pc, createPCMGSetUpViaApproxOrdersCtx(dm, S, true));
1155 CHKERR PCSetFromOptions(pc);
1156 }
1158 };
1159
1160 CHKERR set_pc_p_mg(schurDM, get_pc(subksp[1]), S);
1161
1162 CHKERR PetscFree(subksp);
1163 }
1165}
1166
1167boost::shared_ptr<SetUpSchur>
1169 return boost::shared_ptr<SetUpSchur>(new SetUpSchurImpl(m_field));
1170}
Calculate traction for linear problem.
Implementation of elastic spring bc.
Natural boundary condition applying pressure from fluid.
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
#define MOFEM_LOG_C(channel, severity, format,...)
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
Implementation of natural boundary conditions.
Boundary conditions in domain, i.e. body forces.
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
int main()
static const double eps
DomainEle::UserDataOperator DomainEleOp
Finire element operator type.
constexpr int SPACE_DIM
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
[Define dimension]
Kronecker Delta class symmetric.
#define SCHUR_ASSEMBLE
Definition contact.cpp:18
@ QUIET
@ ROW
#define CATCH_ERRORS
Catch errors.
@ MF_EXIST
FieldApproximationBase
approximation base
Definition definitions.h:58
@ LASTBASE
Definition definitions.h:69
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base nme:nme847.
Definition definitions.h:60
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ H1
continuous field
Definition definitions.h:85
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
constexpr int order
PostProcEleByDim< SPACE_DIM >::PostProcEleDomain PostProcEleDomain
PostProcEleByDim< SPACE_DIM >::PostProcEleBdy PostProcEleBdy
double bulk_modulus_K
double shear_modulus_G
static char help[]
[Check]
Definition elastic.cpp:879
PetscBool is_plane_strain
Definition elastic.cpp:84
FormsIntegrators< DomainEleOp >::Assembly< A >::LinearForm< I >::OpGradTimesSymTensor< BASE_DIM, SPACE_DIM, SPACE_DIM > OpInternalForce
Definition elastic.cpp:42
constexpr int SPACE_DIM
[Define dimension]
Definition elastic.cpp:18
constexpr double poisson_ratio
Definition elastic.cpp:80
constexpr int BASE_DIM
Definition elastic.cpp:15
constexpr double shear_modulus_G
Definition elastic.cpp:82
constexpr IntegrationType I
Definition elastic.cpp:25
constexpr double bulk_modulus_K
Definition elastic.cpp:81
FormsIntegrators< DomainEleOp >::Assembly< A >::BiLinearForm< I >::OpGradSymTensorGrad< BASE_DIM, SPACE_DIM, SPACE_DIM, 0 > OpK
[Define entities]
Definition elastic.cpp:38
constexpr double young_modulus
Definition elastic.cpp:79
@ F
auto integration_rule
constexpr auto t_kd
PetscErrorCode DMMoFEMCreateSubDM(DM subdm, DM dm, const char problem_name[])
Must be called by user to set Sub DM MoFEM data structures.
Definition DMMoFEM.cpp:215
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
Definition DMMoFEM.cpp:497
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
Definition DMMoFEM.cpp:456
PetscErrorCode DMoFEMPostProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
Definition DMMoFEM.cpp:556
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:523
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
Definition DMMoFEM.cpp:238
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
MoFEMErrorCode DMRegister_MGViaApproxOrders(const char sname[])
Register DM for Multi-Grid via approximation orders.
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:586
auto createDMVector(DM dm)
Get smart vector from DM.
Definition DMMoFEM.hpp:1099
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
Definition DMMoFEM.cpp:280
auto createDMMatrix(DM dm)
Get smart matrix from DM.
Definition DMMoFEM.hpp:1056
PetscErrorCode DMoFEMPreProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
Definition DMMoFEM.cpp:546
IntegrationType
Form integrator integration types.
AssemblyType
[Storage and set boundary conditions]
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
SeverityLevel
Severity levels.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
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 getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
FTensor::Index< 'i', SPACE_DIM > i
double D
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
OpSchurAssembleBase * createOpSchurAssembleEnd(std::vector< std::string > fields_name, std::vector< boost::shared_ptr< Range > > field_ents, SmartPetscObj< AO > ao, SmartPetscObj< Mat > schur, bool sym_schur, bool symm_op)
Construct a new Op Schur Assemble End object.
Definition Schur.cpp:2186
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
MoFEMErrorCode setSchurA00MatSolvePC(SmartPetscObj< PC > pc)
Set PC for A00 block.
Definition Schur.cpp:2223
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
boost::shared_ptr< PCMGSetUpViaApproxOrdersCtx > createPCMGSetUpViaApproxOrdersCtx(DM dm, Mat A, bool use_shell_mat)
createPCMGSetUpViaApproxOrdersCtx
PetscErrorCode PetscOptionsGetRealArray(PetscOptions *, const char pre[], const char name[], PetscReal dval[], PetscInt *nmax, PetscBool *set)
static FTensor::Ddg< FTensor::PackPtr< T *, 1 >, Tensor_Dim01, Tensor_Dim23 > getFTensor4DdgFromMat(ublas::matrix< T, L, A > &data)
Get symmetric tensor rank 4 on first two and last indices from form data matrix.
auto getDMKspCtx(DM dm)
Get KSP context data structure used by DM.
Definition DMMoFEM.hpp:1113
auto getDMSubData(DM dm)
Get sub problem data structure.
Definition DMMoFEM.hpp:1157
FTensor::Tensor1< FTensor::PackPtr< T *, S >, Tensor_Dim > getFTensor1FromMat(ublas::matrix< T, L, A > &data)
Get tensor rank 1 (vector) form data matrix.
MoFEMErrorCode PCMGSetUpViaApproxOrders(PC pc, boost::shared_ptr< PCMGSetUpViaApproxOrdersCtx > ctx, int verb)
Function build MG structure.
boost::shared_ptr< BlockStructure > createBlockMatStructure(DM dm, SchurFEOpsFEandFields schur_fe_op_vec)
Create a Mat Diag Blocks object.
Definition Schur.cpp:1009
boost::shared_ptr< NestSchurData > createSchurNestedMatrixStruture(std::pair< SmartPetscObj< DM >, SmartPetscObj< DM > > dms, boost::shared_ptr< BlockStructure > block_mat_data_ptr, std::vector< std::string > fields_names, std::vector< boost::shared_ptr< Range > > field_ents, bool add_preconditioner_block)
Get the Schur Nest Mat Array object.
Definition Schur.cpp:1944
auto createAOMappingIS(IS isapp, IS ispetsc)
Creates an application mapping using two index sets.
PetscErrorCode PetscOptionsGetEList(PetscOptions *, const char pre[], const char name[], const char *const *list, PetscInt next, PetscInt *value, PetscBool *set)
MoFEMErrorCode DMMoFEMSetNestSchurData(DM dm, boost::shared_ptr< NestSchurData >)
Definition DMMoFEM.cpp:1562
auto createDMNestSchurMat(DM dm)
Definition DMMoFEM.hpp:1083
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
OpSchurAssembleBase * createOpSchurAssembleBegin()
Definition Schur.cpp:2181
auto createDMBlockMat(DM dm)
Definition DMMoFEM.hpp:1076
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
double young_modulus
Young modulus.
Definition plastic.cpp:121
#define EXECUTABLE_DIMENSION
Definition plastic.cpp:13
double poisson_ratio
Poisson ratio.
Definition plastic.cpp:122
constexpr auto size_symm
Definition plastic.cpp:42
ElementsAndOps< SPACE_DIM >::SideEle SideEle
Definition plastic.cpp:61
constexpr auto field_name
static constexpr int approx_order
FTensor::Index< 'm', 3 > m
[OpInternalForce]
Definition elastic.cpp:45
[Example]
Definition plastic.cpp:213
MoFEMErrorCode boundaryCondition()
MoFEMErrorCode assembleSystem()
MoFEMErrorCode readMesh()
PetscBool doEvalField
Definition elastic.cpp:95
FieldApproximationBase base
Definition plot_base.cpp:68
MoFEMErrorCode checkResults()
MoFEMErrorCode solveSystem()
Example(MoFEM::Interface &m_field)
Definition elastic.cpp:88
MoFEMErrorCode runProblem()
MoFEM::Interface & mField
Definition plastic.cpp:223
std::array< double, SPACE_DIM > fieldEvalCoords
Definition elastic.cpp:96
MoFEMErrorCode setupProblem()
MoFEMErrorCode outputResults()
MoFEMErrorCode addMatBlockOps(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string field_name, std::string block_name, boost::shared_ptr< MatrixDouble > mat_D_Ptr, Sev sev)
Definition elastic.cpp:114
boost::shared_ptr< MatrixDouble > vectorFieldPtr
Definition elastic.cpp:98
boost::shared_ptr< FieldEvaluatorInterface::SetPtsData > fieldEvalData
Definition elastic.cpp:97
Add operators pushing bases from local to physical configuration.
Simple interface for fast problem set-up.
Definition BcManager.hpp:25
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Core (interface) class.
Definition Core.hpp:82
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition Core.cpp:72
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition Core.cpp:112
Deprecated interface functions.
Definition of the displacement bc data structure.
Definition BCData.hpp:76
Data on single entity (This is passed as argument to DataOperator::doWork)
Class (Function) to enforce essential constrains on the left hand side diagonal.
Definition Essential.hpp:33
Class (Function) to enforce essential constrains on the right hand side diagonal.
Definition Essential.hpp:41
Class (Function) to enforce essential constrains.
Definition Essential.hpp:25
Class (Function) to calculate residual side diagonal.
Definition Essential.hpp:49
Basic algebra on fields.
Definition FieldBlas.hpp:21
Field evaluator interface.
Section manager is used to create indexes and sections.
Definition ISManager.hpp:23
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
static boost::shared_ptr< std::ostream > getStrmSync()
Get the strm sync object.
Interface for managing meshsets containing materials and boundary conditions.
Assembly methods.
Definition Natural.hpp:65
Get field gradients at integration pts for scalar filed rank 0, i.e. vector field.
Get values at integration pts for tensor filed rank 1, i.e. vector field.
Element used to execute operators on side of the element.
Post post-proc data at points from hash maps.
PipelineManager interface.
Projection of edge entities with one mid-node on hierarchical basis.
Simple interface for fast problem set-up.
Definition Simple.hpp:27
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
PipelineManager::ElementsAndOpsByDim< 3 >::FaceSideEle SideEle
[Push operators to pipeline]
SetUpSchur()=default
virtual MoFEMErrorCode setUp(SmartPetscObj< KSP > solver)=0
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field)
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field)
MoFEMErrorCode setUp(SmartPetscObj< KSP > solver)
virtual ~SetUpSchurImpl()=default
SmartPetscObj< Mat > S
MoFEMErrorCode createSubDM()
MoFEMErrorCode setDiagonalPC(PC pc)
SetUpSchurImpl(MoFEM::Interface &m_field)
Definition elastic.cpp:927
SmartPetscObj< DM > schurDM
Definition contact.cpp:1004
MoFEMErrorCode setEntities()
Definition elastic.cpp:1001
MoFEMErrorCode setUp(SmartPetscObj< KSP >)
SmartPetscObj< DM > blockDM
Definition contact.cpp:1005
MoFEMErrorCode setPC(PC pc)
MoFEMErrorCode setOperator()
MoFEM::Interface & mField
PetscBool is_plane_strain