v0.14.0
Loading...
Searching...
No Matches
simple_l2_only.cpp
Go to the documentation of this file.
1/**
2 * \file simple_l2_only.cpp
3 * \ingroup mofem_simple_interface
4 * \example simple_l2_only.cpp
5 *
6 * Test iterating over boundary and skeleton elements only when L2 field is
7 * presents on the domain.
8 *
9 */
10
11#include <MoFEM.hpp>
12using namespace MoFEM;
13
14static char help[] = "...\n\n";
15
16constexpr int SPACE_DIM = 2;
17
18template <int DIM> struct ElementsAndOps {};
19
20template <> struct ElementsAndOps<2> {
22 using DomainEleOp = DomainEle::UserDataOperator;
24 using BoundaryEleOp = BoundaryEle::UserDataOperator;
25};
26
28using DomainEleOp = DomainEle::UserDataOperator;
30using BoundaryEleOp = BoundaryEle::UserDataOperator;
32
33int main(int argc, char *argv[]) {
34
35 // initialize petsc
36 MoFEM::Core::Initialize(&argc, &argv, (char *)0, help);
37
38 try {
39
40 // Create MoAB database
41 moab::Core moab_core;
42 moab::Interface &moab = moab_core;
43
44 // Create MoFEM database and link it to MoAB
45 MoFEM::Core mofem_core(moab);
46 MoFEM::Interface &m_field = mofem_core;
47
48 // Register DM Manager
49 DMType dm_name = "DMMOFEM";
50 CHKERR DMRegister_MoFEM(dm_name);
51
52 // Simple interface
53 Simple *simple_interface;
54 CHKERR m_field.getInterface(simple_interface);
55 {
56
57 // get options from command line
58 CHKERR simple_interface->getOptions();
59 // load mesh file
60 CHKERR simple_interface->loadFile();
61
62 CHKERR simple_interface->addDomainField("FIELD", L2,
64
65 CHKERR simple_interface->addMeshsetField("GLOBAL", NOFIELD, NOBASE, 1);
66 CHKERR simple_interface->addMeshsetField("FIELD", L2,
68
69 // I add vols to meshset, that is to integrate on side of mFE. That make
70 // "FIELD" adjacent to "GLOBAL", and all other "FIELD" adjacent to
71 // "FIELD". That would create dense matrix. In principle you will add only
72 // small subset of "FIELD" entities to "GLOBAL" meshset.
73 Range vols;
74 CHKERR m_field.get_moab().get_entities_by_dimension(0, SPACE_DIM, vols);
75 simple_interface->getMeshsetFiniteElementEntities().push_back(
76 vols); // create one meshset element
77
78 simple_interface->getAddBoundaryFE() = true;
79 simple_interface->getAddSkeletonFE() = true;
80
81 // set fields order
82 CHKERR simple_interface->setFieldOrder("FIELD", 1);
83 // setup problem
84 CHKERR simple_interface->setUp();
85
86 int count_skeleton_fe;
87 int count_side_fe;
88 int count_meshset_fe;
89 int count_meshset_side_fe;
90
91 PipelineManager *pipeline_mng = m_field.getInterface<PipelineManager>();
92
93 // Create OP for side FE
94 auto op_side_fe = new DomainEleOp(NOSPACE, DomainEleOp::OPSPACE);
95 op_side_fe->doWorkRhsHook = [&](DataOperator *op_ptr, int side,
96 EntityType type,
98 auto domain_op = static_cast<DomainEleOp *>(op_ptr);
100
101 MOFEM_LOG("SELF", Sev::verbose)
102 << "Side element name [ " << count_side_fe << " ] "
103 << domain_op->getFEName();
104
105 ++count_side_fe;
106
108 };
109
110 // Create side FE
111 auto side_fe = boost::make_shared<DomainEle>(m_field);
112 side_fe->getOpPtrVector().push_back(op_side_fe);
113
114 // Create boundary FE OP
115
116 auto do_work_rhs = [&](DataOperator *op_ptr, int side, EntityType type,
118 auto bdy_op = static_cast<BoundaryEleOp *>(op_ptr);
120
121 MOFEM_LOG("SELF", Sev::verbose)
122 << "Element name [ " << count_skeleton_fe << " ] "
123 << bdy_op->getFEName();
124
125 CHKERR bdy_op->loopSide(simple_interface->getDomainFEName(),
126 side_fe.get(), SPACE_DIM);
127
128 ++count_skeleton_fe;
129
131 };
132
133 auto op_bdy_fe = new BoundaryEleOp(NOSPACE, DomainEleOp::OPSPACE);
134 op_bdy_fe->doWorkRhsHook = do_work_rhs;
135
136 auto op_skeleton_fe = new BoundaryEleOp(NOSPACE, DomainEleOp::OPSPACE);
137 op_skeleton_fe->doWorkRhsHook = do_work_rhs;
138
139 // create meshset fe
140 auto op_meshset_side_fe = new DomainEleOp(NOSPACE, DomainEleOp::OPSPACE);
141 op_meshset_side_fe->doWorkRhsHook =
142 [&](DataOperator *op_ptr, int side, EntityType type,
144 auto domain_op = static_cast<DomainEleOp *>(op_ptr);
146
147 MOFEM_LOG("SELF", Sev::verbose)
148 << "Side element name [ " << count_side_fe << " ] "
149 << domain_op->getFEName();
150
151 ++count_meshset_side_fe;
152
154 };
155
156 auto meshset_side_fe = boost::make_shared<DomainEle>(m_field);
157 meshset_side_fe->getOpPtrVector().push_back(op_meshset_side_fe);
158
159 auto op_meshset_fe = new ForcesAndSourcesCore::UserDataOperator(
160 "GLOBAL", ForcesAndSourcesCore::UserDataOperator::OPROW);
161 op_meshset_fe->doWorkRhsHook = [&](DataOperator *op_ptr, int side,
162 EntityType type,
165 MOFEM_LOG("SELF", Sev::inform)
166 << "Meshset element name " << data.getIndices();
167
168 CHKERR op_meshset_fe->loopSide(simple_interface->getDomainFEName(),
169 meshset_side_fe.get(), SPACE_DIM, 0,
170 boost::make_shared<Range>(vols));
171
172 ++count_meshset_fe;
174 };
175
176 // Count boundary
177 count_skeleton_fe = 0;
178 count_side_fe = 0;
179 count_meshset_fe = 0;
180 count_meshset_side_fe = 0;
181
182 pipeline_mng->getOpBoundaryRhsPipeline().push_back(op_bdy_fe);
183 pipeline_mng->getOpSkeletonRhsPipeline().push_back(op_skeleton_fe);
184 pipeline_mng->getOpMeshsetRhsPipeline().push_back(op_meshset_fe);
185 pipeline_mng->loopFiniteElements();
186
187 MOFEM_LOG("SELF", Sev::inform)
188 << "Number of elements " << count_skeleton_fe;
189 MOFEM_LOG("SELF", Sev::inform)
190 << "Number of side elements " << count_side_fe;
191 MOFEM_LOG("SELF", Sev::inform)
192 << "Number of meshset elements " << count_meshset_fe;
193 MOFEM_LOG("SELF", Sev::inform)
194 << "Number of meshset side elements " << count_meshset_side_fe;
195
196 if (count_skeleton_fe != 16)
197 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
198 "Wrong numbers of FEs");
199 if (count_side_fe != 24)
200 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
201 "Wrong numbers of side FEs");
202 if (count_meshset_fe != 1)
203 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
204 "Wrong numbers of side FEs");
205 if (count_meshset_side_fe != 8)
206 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
207 "Wrong numbers of side FEs");
208 }
209 }
211
212 // finish work cleaning memory, getting statistics, etc.
214
215 return 0;
216}
int main()
DomainEle::UserDataOperator DomainEleOp
Finire element operator type.
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
[Define dimension]
BoundaryEle::UserDataOperator BoundaryEleOp
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base nme:nme847.
Definition definitions.h:60
@ NOBASE
Definition definitions.h:59
@ L2
field with C-1 continuity
Definition definitions.h:88
@ NOFIELD
scalar or vector of scalars describe (no true field)
Definition definitions.h:84
@ NOSPACE
Definition definitions.h:83
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
MoFEMErrorCode loopFiniteElements(SmartPetscObj< DM > dm=nullptr)
Iterate finite elements.
boost::ptr_deque< UserDataOperator > & getOpBoundaryRhsPipeline()
Get the Op Boundary Rhs Pipeline object.
boost::ptr_deque< UserDataOperator > & getOpSkeletonRhsPipeline()
Get the Op Skeleton Rhs Pipeline object.
#define MOFEM_LOG(channel, severity)
Log.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
static char help[]
constexpr int SPACE_DIM
virtual moab::Interface & get_moab()=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
base operator to do operations at Gauss Pt. level
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
PipelineManager interface.
boost::ptr_deque< UserDataOperator > & getOpMeshsetRhsPipeline()
Get the Op Meshset Rhs Pipeline object.
MoFEM::FaceElementForcesAndSourcesCore FaceEle
MoFEM::EdgeElementForcesAndSourcesCore EdgeEle
Simple interface for fast problem set-up.
Definition Simple.hpp:27
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:264
bool & getAddBoundaryFE()
Get the addSkeletonFE.
Definition Simple.hpp:498
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
Definition Simple.cpp:194
MoFEMErrorCode addMeshsetField(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 meshset field.
Definition Simple.cpp:414
MoFEMErrorCode getOptions()
get options
Definition Simple.cpp:180
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
Definition Simple.cpp:599
auto & getMeshsetFiniteElementEntities()
Get the Domain Fields.
Definition Simple.hpp:443
bool & getAddSkeletonFE()
Get the addSkeletonFE.
Definition Simple.hpp:487
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
Definition Simple.cpp:765
const std::string getDomainFEName() const
Get the Domain FE Name.
Definition Simple.hpp:387
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.