v0.16.3
Loading...
Searching...
No Matches
Classes | Functions | Variables
simple_elasticity.cpp File Reference
#include <MoFEM.hpp>

Go to the source code of this file.

Classes

struct  OpK
 
struct  OpPressure
 
struct  ApplyDirichletBc
 
struct  VolRule
 Set integration rule to volume elements. More...
 
struct  FaceRule
 Set integration rule to boundary elements. More...
 

Functions

int main (int argc, char *argv[])
 

Variables

static char help []
 

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 390 of file simple_elasticity.cpp.

390 {
391
392 const string default_options = "-ksp_type fgmres \n"
393 "-pc_type lu \n"
394 "-pc_factor_mat_solver_type mumps \n"
395 "-mat_mumps_icntl_20 0 \n"
396 "-ksp_monitor\n";
397
398 string param_file = "param_file.petsc";
399 if (!static_cast<bool>(ifstream(param_file))) {
400 std::ofstream file(param_file.c_str(), std::ios::ate);
401 if (file.is_open()) {
402 file << default_options;
403 file.close();
404 }
405 }
406
407 MoFEM::Core::Initialize(&argc, &argv, param_file.c_str(), help);
408
409 // Create mesh database
410 moab::Core mb_instance; // create database
411 moab::Interface &moab = mb_instance; // create interface to database
412
413 try {
414 // Create MoFEM database and link it to MoAB
415 MoFEM::Core core(moab);
416 MoFEM::Interface &m_field = core;
417
418 CHKERR DMRegister_MoFEM("DMMOFEM");
419
420 // Get command line options
421 int order = 3; // default approximation order
422 PetscOptionsBegin(PETSC_COMM_WORLD, "", "SimpleElasticProblem",
423 "none");
424
425 // Set approximation order
426 CHKERR PetscOptionsInt("-order", "approximation order", "", order, &order,
427 PETSC_NULLPTR);
428
429 PetscOptionsEnd();
430
431 Simple *simple_interface = m_field.getInterface<MoFEM::Simple>();
432
433 CHKERR simple_interface->getOptions();
434 CHKERR simple_interface->loadFile();
435
436 Range fix_faces, pressure_faces, fix_nodes, fix_second_node;
437
438 enum MyBcTypes {
439 FIX_BRICK_FACES = 1,
440 FIX_NODES = 2,
441 BRICK_PRESSURE_FACES = 3,
442 FIX_NODES_Y_DIR = 4
443 };
444
446 EntityHandle meshset = bit->getMeshset();
447 int id = bit->getMeshsetId();
448
449 if (id == FIX_BRICK_FACES) { // brick-faces
450
451 CHKERR m_field.get_moab().get_entities_by_dimension(meshset, 2,
452 fix_faces, true);
453
454 Range adj_ents;
455 CHKERR m_field.get_moab().get_adjacencies(fix_faces, 0, false, adj_ents,
456 moab::Interface::UNION);
457
458 CHKERR m_field.get_moab().get_adjacencies(fix_faces, 1, false, adj_ents,
459 moab::Interface::UNION);
460 fix_faces.merge(adj_ents);
461 } else if (id == FIX_NODES) { // node(s)
462
463 CHKERR m_field.get_moab().get_entities_by_dimension(meshset, 0,
464 fix_nodes, true);
465
466 } else if (id == BRICK_PRESSURE_FACES) { // brick pressure faces
467 CHKERR m_field.get_moab().get_entities_by_dimension(
468 meshset, 2, pressure_faces, true);
469
470 } else if (id ==
471 FIX_NODES_Y_DIR) { // restrained second node in y direction
472 CHKERR m_field.get_moab().get_entities_by_dimension(
473 meshset, 0, fix_second_node, true);
474
475 } else {
476 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY, "Unknown blockset");
477 }
478 }
479
480 CHKERR simple_interface->addDomainField("U", H1, AINSWORTH_LEGENDRE_BASE,
481 3);
482 CHKERR simple_interface->setFieldOrder("U", order);
483
484 CHKERR simple_interface->defineFiniteElements();
485
486 // Add pressure element
487 CHKERR m_field.add_finite_element("PRESSURE");
488 CHKERR m_field.modify_finite_element_add_field_row("PRESSURE", "U");
489 CHKERR m_field.modify_finite_element_add_field_col("PRESSURE", "U");
490 CHKERR m_field.modify_finite_element_add_field_data("PRESSURE", "U");
491
492 CHKERR simple_interface->defineProblem();
493
494 DM dm;
495 CHKERR simple_interface->getDM(&dm);
496
497 CHKERR DMMoFEMAddElement(dm, "PRESSURE");
498 CHKERR DMMoFEMSetIsPartitioned(dm, PETSC_TRUE);
499
500 CHKERR simple_interface->buildFields();
501 CHKERR simple_interface->buildFiniteElements();
502
503 CHKERR m_field.add_ents_to_finite_element_by_dim(pressure_faces, 2,
504 "PRESSURE");
505 CHKERR m_field.build_finite_elements("PRESSURE", &pressure_faces);
506
507 CHKERR simple_interface->buildProblem();
508
509 // Create elements instances
510 boost::shared_ptr<VolumeElementForcesAndSourcesCore> elastic_fe(
512 boost::shared_ptr<FaceElementForcesAndSourcesCore> pressure_fe(
514
515 // Set integration rule to elements instances
516 elastic_fe->getRuleHook = VolRule();
517 pressure_fe->getRuleHook = FaceRule();
518
519 // Add operators to element instances
520 // push operators to elastic_fe
521 elastic_fe->getOpPtrVector().push_back(new OpK());
522 // push operators to pressure_fe
523 pressure_fe->getOpPtrVector().push_back(new OpPressure());
524
525 boost::shared_ptr<FEMethod> fix_dofs_fe(
526 new ApplyDirichletBc(fix_faces, fix_nodes, fix_second_node));
527
528 boost::shared_ptr<FEMethod> null_fe;
529
530 // Set operators for KSP solver
532 dm, simple_interface->getDomainFEName(), elastic_fe, null_fe, null_fe);
533
534 CHKERR DMMoFEMKSPSetComputeRHS(dm, "PRESSURE", pressure_fe, null_fe,
535 null_fe);
536
537 // initialise matrix A used as the global stiffness matrix
538 Mat A;
539
540 // initialise left hand side vector x and right hand side vector f
541 Vec x, f;
542
543 // allocate memory handled by MoFEM discrete manager for matrix A
544 CHKERR DMCreateMatrix(dm, &A);
545
546 // allocate memory handled by MoFEM discrete manager for vector x
547 CHKERR DMCreateGlobalVector(dm, &x);
548
549 // allocate memory handled by MoFEM discrete manager for vector f of the
550 // same size as x
551 CHKERR VecDuplicate(x, &f);
552
553 // precondition matrix A according to fix_dofs_fe and elastic_fe finite
554 // elements
555 elastic_fe->ksp_B = A;
556 fix_dofs_fe->ksp_B = A;
557
558 // precondition the right hand side vector f according to fix_dofs_fe and
559 // elastic_fe finite elements
560 fix_dofs_fe->ksp_f = f;
561 pressure_fe->ksp_f = f;
562
563 CHKERR DMoFEMLoopFiniteElements(dm, simple_interface->getDomainFEName(),
564 elastic_fe);
565
566 CHKERR DMoFEMLoopFiniteElements(dm, "PRESSURE", pressure_fe);
567
568 // This is done because only post processor is implemented in the
569 // ApplyDirichletBc struct
570 CHKERR DMoFEMPostProcessFiniteElements(dm, fix_dofs_fe.get());
571
572 // make available a KSP solver
573 KSP solver;
574
575 // make the solver available for parallel computing by determining its MPI
576 // communicator
577 CHKERR KSPCreate(PETSC_COMM_WORLD, &solver);
578
579 // making available running all options available for KSP solver in running
580 // command
581 CHKERR KSPSetFromOptions(solver);
582
583 // set A matrix with preconditioner
584 CHKERR KSPSetOperators(solver, A, A);
585
586 // set up the solver data strucure for the iterative solver
587 CHKERR KSPSetUp(solver);
588
589 // solve the system of linear equations
590 CHKERR KSPSolve(solver, f, x);
591 // Solver convergence is cheap to check and carries no magic numbers, so
592 // it stands alone rather than waiting on a "-test_nb"/"-test_name"
593 // selector.
594 CHKERR m_field.getInterface<TestingInterface>()->checkSolver(
595 solver, "simple elasticity");
596
597 // destroy solver no needed any more
598 CHKERR KSPDestroy(&solver);
599
600 // make vector x available for parallel computations for visualization
601 // context
602 VecView(x, PETSC_VIEWER_STDOUT_WORLD);
603
604 // save solution in vector x on mesh
605 CHKERR DMoFEMMeshToGlobalVector(dm, x, INSERT_VALUES, SCATTER_REVERSE);
606
607 // Set up post-processor. It is some generic implementation of finite
608 // element
609 auto get_post_proc_ele = [&]() {
610 auto jac_ptr = boost::make_shared<MatrixDouble>();
611 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
612 auto det_ptr = boost::make_shared<VectorDouble>();
613
614 auto post_proc_ele = boost::make_shared<
616 // Add operators to the elements, starting with some generic
617 constexpr int SPACE_DIM = 3;
618 post_proc_ele->getOpPtrVector().push_back(
619 new OpCalculateHOJac<SPACE_DIM>(jac_ptr));
620 post_proc_ele->getOpPtrVector().push_back(
621 new OpInvertMatrix<SPACE_DIM>(jac_ptr, det_ptr, inv_jac_ptr));
622 post_proc_ele->getOpPtrVector().push_back(
623 new OpSetHOInvJacToScalarBases<SPACE_DIM>(H1, inv_jac_ptr));
624
625 auto u_ptr = boost::make_shared<MatrixDouble>();
626 auto grad_ptr = boost::make_shared<MatrixDouble>();
627 post_proc_ele->getOpPtrVector().push_back(
629 post_proc_ele->getOpPtrVector().push_back(
631 grad_ptr));
633
634 post_proc_ele->getOpPtrVector().push_back(
635
636 new OpPPMap(
637
638 post_proc_ele->getPostProcMesh(), post_proc_ele->getMapGaussPts(),
639 {},
640
641 {{"U", u_ptr}},
642
643 {{"GRAD", grad_ptr}},
644
645 {})
646
647 );
648
649 return post_proc_ele;
650 };
651
652 if (auto post_proc = get_post_proc_ele()) {
653 CHKERR DMoFEMLoopFiniteElements(dm, simple_interface->getDomainFEName(),
654 post_proc);
655 // write output
656 CHKERR post_proc->writeFile("out.h5m");
657 }
658
659 {
660 auto testing = m_field.getInterface<TestingInterface>();
661 CHKERR testing->addTestCommandLine("", 1, "max displacement", [&]() {
663 const double x_vec_norm_const = 0.4;
664 // Check norm_1 value
665 double norm_check;
666 // Takes maximal element of the vector, that should be maximal
667 // displacement at the end of the bar
668 CHKERR VecNorm(x, NORM_INFINITY, &norm_check);
669 CHKERR testing->checkValue<TestType::SCALAR>(
670 "max displacement", norm_check, x_vec_norm_const, {0., 1.e-10});
672 });
673 CHKERR testing->runTests();
674 }
675
676 // free memory handled by mofem discrete manager for A, x and f
677 CHKERR MatDestroy(&A);
678 CHKERR VecDestroy(&x);
679 CHKERR VecDestroy(&f);
680
681 // free memory allocated for mofem discrete manager
682 CHKERR DMDestroy(&dm);
683
684 // This is a good reference for the future
685 }
687
688 // finish work cleaning memory, getting statistics, etc
690
691 return 0;
692}
constexpr int SPACE_DIM
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ 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 ...
@ BLOCKSET
@ 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.
constexpr int order
PetscErrorCode DMoFEMMeshToGlobalVector(DM dm, Vec g, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set ghosted vector values on all existing mesh entities
Definition DMMoFEM.cpp:554
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
Definition DMMoFEM.cpp:1142
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
Definition DMMoFEM.cpp:517
PetscErrorCode DMoFEMPostProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
Definition DMMoFEM.cpp:575
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
PetscErrorCode DMMoFEMKSPSetComputeRHS(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set KSP right hand side evaluation function
Definition DMMoFEM.cpp:656
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:605
PetscErrorCode DMMoFEMKSPSetComputeOperators(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
Set KSP operators and push mofem finite element methods.
Definition DMMoFEM.cpp:697
virtual MoFEMErrorCode add_ents_to_finite_element_by_dim(const EntityHandle entities, const int dim, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
#define _IT_CUBITMESHSETS_BY_BCDATA_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet in a moFEM field.
auto bit
set bit
PetscBool testing
const FTensor::Tensor2< T, Dim, Dim > Vec
constexpr AssemblyType A
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
static char help[]
Set integration rule to boundary elements.
virtual moab::Interface & get_moab()=0
Core (interface) class.
Definition Core.hpp:83
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition Core.cpp:68
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition Core.cpp:123
Deprecated interface functions.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for MatrixDouble vector field values calculation.
Operator for inverting matrices at integration points.
Post post-proc data at points from hash maps.
Set inverse jacobian to base functions.
Simple interface for fast problem set-up.
Definition Simple.hpp:27
MoFEMErrorCode buildProblem()
Build problem.
Definition Simple.cpp:721
MoFEMErrorCode addDomainField(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_ZERO, int verb=-1)
Add field on domain.
Definition Simple.cpp:261
MoFEMErrorCode defineFiniteElements()
Define finite elements.
Definition Simple.cpp:471
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
Definition Simple.cpp:191
MoFEMErrorCode buildFiniteElements()
Build finite elements.
Definition Simple.cpp:659
MoFEMErrorCode getOptions()
get options
Definition Simple.cpp:180
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:799
MoFEMErrorCode buildFields()
Build fields.
Definition Simple.cpp:584
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
Definition Simple.cpp:575
MoFEMErrorCode defineProblem(const PetscBool is_partitioned=PETSC_TRUE)
define problem
Definition Simple.cpp:551
const std::string getDomainFEName() const
Get the Domain FE Name.
Definition Simple.hpp:429
virtual MoFEMErrorCode addTestCommandLine(const std::string &prefix, int number, const std::string &name, TestHook hook)=0
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Set integration rule to volume elements.

Variable Documentation

◆ help

char help[]
static
Initial value:
= "-order approximation order\n"
"\n"

Definition at line 13 of file simple_elasticity.cpp.