27 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator>;
44 virtual MoFEMErrorCode
setUpSolver(SmartPetscObj<KSP> solver);
79 enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
80 const char *list_bases[LASBASETOPT] = {
"ainsworth",
"demkowicz"};
81 PetscInt choice_base_value = AINSWORTH;
82 CHKERR PetscOptionsGetEList(PETSC_NULLPTR, NULL,
"-base", list_bases,
83 LASBASETOPT, &choice_base_value, PETSC_NULLPTR);
86 switch (choice_base_value) {
90 <<
"Set AINSWORTH_LEGENDRE_BASE for displacements";
95 <<
"Set DEMKOWICZ_JACOBI_BASE for displacements";
106 CHKERR PetscOptionsGetInt(PETSC_NULLPTR,
"",
"-order", &
order, PETSC_NULLPTR);
114 auto project_ho_geometry = [&]() {
115 Projection10NodeCoordsOnField ent_method(
mField,
"GEOMETRY");
118 CHKERR project_ho_geometry();
130 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_X",
132 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Y",
134 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Z",
136 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
137 "REMOVE_ALL",
"U", 0, 3);
138 CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
139 simple->getProblemName(),
"U");
151 CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, A, I, DomainEleOp>(
152 mField, lhs_pipeline,
"U",
"MAT_ELASTIC", Sev::verbose);
154 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, A, I, DomainEleOp>(
155 mField, rhs_pipeline,
"U",
"MAT_ELASTIC", Sev::verbose);
168 auto integration_rule_bc = [](int, int,
int approx_order) {
174 CHKERR pip->setBoundaryRhsIntegrationRule(integration_rule_bc);
175 CHKERR pip->setBoundaryLhsIntegrationRule(integration_rule_bc);
179 pip->getOpDomainLhsPipeline(), {H1},
"GEOMETRY");
181 pip->getOpDomainRhsPipeline(), {H1},
"GEOMETRY");
183 pip->getOpBoundaryRhsPipeline(), {NOSPACE},
"GEOMETRY");
185 pip->getOpBoundaryLhsPipeline(), {NOSPACE},
"GEOMETRY");
189 pip->getOpDomainRhsPipeline());
194 pip->getOpDomainRhsPipeline(),
mField,
"U", Sev::inform);
200 pip->getOpBoundaryRhsPipeline(),
mField,
"U", -1, Sev::inform);
203 pip->getOpBoundaryLhsPipeline(),
mField,
"U", Sev::verbose);
218 BOOST_LOG_SCOPED_THREAD_ATTR(
"Timeline", attrs::timer());
219 MOFEM_LOG(
"TIMER", Sev::inform) <<
"KSPSetUp";
221 MOFEM_LOG(
"TIMER", Sev::inform) <<
"KSPSetUp <= Done";
224 CHKERR KSPGetDM(solver, &dm);
225 auto D = createDMVector(dm);
226 auto F = vectorDuplicate(
D);
228 MOFEM_LOG(
"TIMER", Sev::inform) <<
"KSPSolve";
230 MOFEM_LOG(
"TIMER", Sev::inform) <<
"KSPSolve <= Done";
232 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
233 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
234 CHKERR DMoFEMMeshToLocalVector(dm,
D, INSERT_VALUES, SCATTER_REVERSE);
246 auto solver = pip->createKSP();
248 CHKERR KSPSetFromOptions(solver);
250 auto set_essential_bc = [
this]() {
254 auto dm =
simple->getDM();
255 auto ksp_ctx_ptr = getDMKspCtx(dm);
257 auto pre_proc_rhs = boost::make_shared<FEMethod>();
258 auto post_proc_rhs = boost::make_shared<FEMethod>();
259 auto post_proc_lhs = boost::make_shared<FEMethod>();
261 auto get_pre_proc_hook = [
this, pre_proc_rhs]() {
262 return EssentialPreProc<DisplacementCubitBcData>(
mField, pre_proc_rhs,
265 pre_proc_rhs->preProcessHook = get_pre_proc_hook();
267 auto get_post_proc_hook_rhs = [
this, post_proc_rhs]() {
270 CHKERR EssentialPostProcRhs<DisplacementCubitBcData>(
mField,
271 post_proc_rhs, 1.)();
275 auto get_post_proc_hook_lhs = [
this, post_proc_lhs]() {
278 CHKERR EssentialPostProcLhs<DisplacementCubitBcData>(
mField,
279 post_proc_lhs, 1.)();
283 post_proc_rhs->postProcessHook = get_post_proc_hook_rhs;
284 post_proc_lhs->postProcessHook = get_post_proc_hook_lhs;
286 ksp_ctx_ptr->getPreProcComputeRhs().push_front(pre_proc_rhs);
287 ksp_ctx_ptr->getPostProcComputeRhs().push_back(post_proc_rhs);
288 ksp_ctx_ptr->getPostProcSetOperators().push_back(post_proc_lhs);
292 auto evaluate_field_at_the_point = [&]() {
296 std::array<double, 3> field_eval_coords{0.0, 0.0, 0.0};
298 CHKERR PetscOptionsGetRealArray(NULL, NULL,
"-field_eval_coords",
299 field_eval_coords.data(), &coords_dim,
305 auto field_eval_data =
309 ->buildTree<SPACE_DIM>(field_eval_data,
simple->getDomainFEName());
311 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
312 auto no_rule = [](int, int, int) {
return -1; };
313 auto field_eval_fe_ptr = field_eval_data->feMethodPtr;
314 field_eval_fe_ptr->getRuleHook = no_rule;
316 field_eval_fe_ptr->getOpPtrVector().push_back(
317 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U",
vectorFieldPtr));
320 ->evalFEAtThePoint<SPACE_DIM>(
321 field_eval_coords.data(), 1e-12,
simple->getProblemName(),
322 simple->getDomainFEName(), field_eval_data,
330 <<
"U_X: " << t_disp(0) <<
" U_Y: " << t_disp(1);
333 <<
"U_X: " << t_disp(0) <<
" U_Y: " << t_disp(1)
334 <<
" U_Z: " << t_disp(2);
342 CHKERR set_essential_bc();
344 CHKERR evaluate_field_at_the_point();
368 auto integration_rule = [](int, int,
int p_data) {
return 2 * p_data + 1; };
371 auto &domain_evaluation_pipeline = pip->getOpEvaluationPipeline();
373 if (domain_evaluation_pipeline.empty()) {
375 domain_evaluation_pipeline, {
H1},
"GEOMETRY");
377 auto op_loop_boundary =
new OpLoopSide<BoundaryEle>(
380 auto &boundary_evaluation_pipeline = op_loop_boundary->getOpPtrVector();
383 boundary_evaluation_pipeline, {},
"GEOMETRY");
386 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, A, I, DomainEleOp>(
387 mField, domain_evaluation_pipeline,
"U",
"MAT_ELASTIC", Sev::verbose);
390 domain_evaluation_pipeline,
mField,
"U", Sev::verbose);
393 boundary_evaluation_pipeline,
mField,
"U", -1, Sev::verbose);
394 domain_evaluation_pipeline.push_back(op_loop_boundary);
397 auto dm =
simple->getDM();
398 auto res = createDMVector(dm);
399 CHKERR VecSetDM(res, PETSC_NULLPTR);
401 pip->getEvaluationFE()->f = res;
403 CHKERR VecZeroEntries(res);
405 CHKERR pip->loopFiniteElementsEvaluation();
408 CHKERR VecGhostUpdateBegin(res, ADD_VALUES, SCATTER_REVERSE);
409 CHKERR VecGhostUpdateEnd(res, ADD_VALUES, SCATTER_REVERSE);
410 CHKERR VecAssemblyBegin(res);
411 CHKERR VecAssemblyEnd(res);
413 auto zero_residual_at_constrains = [&]() {
415 auto fe_post_proc_ptr = boost::make_shared<FEMethod>();
416 auto get_post_proc_hook_rhs = [&]() {
418 CHKERR EssentialPreProcReaction<DisplacementCubitBcData>(
419 mField, fe_post_proc_ptr, res)();
420 CHKERR EssentialPostProcRhs<DisplacementCubitBcData>(
421 mField, fe_post_proc_ptr, 0, res)();
424 fe_post_proc_ptr->postProcessHook = get_post_proc_hook_rhs;
425 CHKERR DMoFEMPostProcessFiniteElements(dm, fe_post_proc_ptr.get());
429 CHKERR zero_residual_at_constrains();
432 CHKERR VecNorm(res, NORM_2, &nrm2);
434 MOFEM_LOG_C(
"WORLD", Sev::inform,
"residual = %3.4e\n", nrm2);
437 CHKERR PetscOptionsGetInt(PETSC_NULLPTR,
"",
"-test", &test, PETSC_NULLPTR);
439 auto post_proc_residual = [&](
auto dm,
auto f_res,
auto out_name) {
442 boost::make_shared<PostProcBrokenMeshInMoab<DomainEle>>(
mField);
443 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
444 auto u_vec = boost::make_shared<MatrixDouble>();
445 post_proc_fe->getOpPtrVector().push_back(
446 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_vec, f_res));
447 post_proc_fe->getOpPtrVector().push_back(
451 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
461 CHKERR DMoFEMLoopFiniteElements(dm,
simple->getDomainFEName(),
463 post_proc_fe->writeFile(out_name);
467 CHKERR post_proc_residual(
simple->getDM(), res,
"res.h5m");
469 constexpr double eps = 1e-8;
472 "Residual is not zero");
475 if (!vectorFieldPtr || vectorFieldPtr->size1() == 0) {
477 "atom test %d failed: Field Evaluator did not provide result",
480 auto t_disp = getFTensor1FromMat<SPACE_DIM>(*vectorFieldPtr);
481 double Ux_ref = 0.46;
482 double Uy_ref = -0.03;
483 constexpr double eps = 1e-8;
484 if (fabs(t_disp(0) - Ux_ref) >
eps || fabs(t_disp(1) - Uy_ref) >
eps) {
486 "atom test %d failed: Ux_ref = %3.6e, computed = %3.6e, Uy_ref "
487 "= %3.6e, computed = %3.6e",
488 test, Ux_ref, t_disp(0), Uy_ref, t_disp(1));
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
#define MOFEM_LOG_C(channel, severity, format,...)
void simple(double P1[], double P2[], double P3[], double c[], const int N)
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_ATOM_TEST_INVALID
@ MOFEM_DATA_INCONSISTENCY
#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 ...
#define MOFEM_LOG(channel, severity)
Log.
#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 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)
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
static constexpr int approx_order
virtual MoFEMErrorCode solveSystem()
[Solve]
virtual MoFEMErrorCode outputResults()
[Solve]
virtual MoFEMErrorCode assembleSystem()
virtual MoFEMErrorCode addDomainMaterialOps(Pipeline &lhs_pipeline, Pipeline &rhs_pipeline)
Add constitutive operators to the domain assembly pipelines.
virtual MoFEMErrorCode setupProblem()
[Read mesh]
virtual MoFEMErrorCode kspSetUpAndSolve(SmartPetscObj< KSP > solver)
MoFEMErrorCode runProblem()
[Run problem]
MoFEM::Interface & mField
virtual MoFEMErrorCode boundaryCondition()
[Set up problem]
virtual MoFEMErrorCode checkResults()
[Postprocess results]
boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > Pipeline
virtual ~ElasticExample()=default
virtual MoFEMErrorCode readMesh()
[Run problem]
boost::shared_ptr< MatrixDouble > vectorFieldPtr
ElasticExample(MoFEM::Interface &m_field)
virtual MoFEMErrorCode setUpSolver(SmartPetscObj< KSP > solver)
[Push operators to pipeline]
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Deprecated interface functions.
Post post-proc data at points from hash maps.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
PetscBool do_eval_field
Evaluate field.
ElementsAndOps< SPACE_DIM >::SideEle SideEle
Calculate traction for linear problem.
Implementation of elastic spring bc.
Natural boundary condition applying pressure from fluid.
Implementation of Hookes operator Hookes for linear elastic problems in MoFEM.
Implementation of natural boundary conditions.
Boundary conditions in domain, i.e. body forces.