v0.13.1
boundary_marker.cpp
Go to the documentation of this file.
1/**
2 * \file boundary_marker.cpp
3 * \example boundary_marker.cpp
4 *
5 * Mark skin entities, i.e. boundary, next check DOFs if are properly marked
6 * when accessed form user data operator.
7 *
8 */
9
10#include <MoFEM.hpp>
11
12using namespace MoFEM;
13
14static char help[] = "...\n\n";
15
18
19struct OpFace : public FaceEleOp {
21 const std::vector<unsigned char> &mArker;
22
23 OpFace(const Range &skin_ents, const std::vector<unsigned char> &marker)
24 : FaceEleOp("FIELD1", OPROW), skinEnts(skin_ents), mArker(marker) {}
25
29
30 const int nb_dofs = data.getIndices().size();
31 if (nb_dofs == 0)
33
34 // This function takes entities on DOFs, and check if those entities are
35 // contained in the range. Note it is local element vector, which is used
36 // to validate of global local vector.
37 auto get_boundary_marker_directly_from_range = [&]() {
38 std::vector<unsigned char> ents_marker_used_for_testing;
39 ents_marker_used_for_testing.resize(data.getLocalIndices().size(),0);
40 switch (type) {
41 case MBVERTEX: {
42 for (size_t side = 0; side != getNumberOfNodesOnElement(); ++side) {
43 EntityHandle ent = getSideEntity(side, MBVERTEX);
44 ents_marker_used_for_testing[3 * side + 0] =
45 skinEnts.find(ent) != skinEnts.end() ? 1 : 0;
46 ents_marker_used_for_testing[3 * side + 2] =
47 ents_marker_used_for_testing[3 * side + 0];
48 }
49 break;
50 }
51 default: {
52 EntityHandle ent = getSideEntity(side, type);
53 bool is_on_boundary = skinEnts.find(ent) != skinEnts.end();
54 for (size_t dof = 0; dof != nb_dofs; ++dof)
55 if ((dof % 3) != 1)
56 ents_marker_used_for_testing[dof] = is_on_boundary ? 1 : 0;
57 }
58 };
59 return ents_marker_used_for_testing;
60 };
61
62 auto test_marker = get_boundary_marker_directly_from_range();
63 for (size_t n = 0; n != nb_dofs; ++n) {
64 const size_t local_index = data.getLocalIndices()[n];
65 if (test_marker[n] != mArker[local_index])
66 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
67 "Wrong boundary marker");
68 }
69
71 }
72};
73
74int main(int argc, char *argv[]) {
75
76 MoFEM::Core::Initialize(&argc, &argv, (char *)0, help);
77
78 try {
79
80 moab::Core mb_instance;
81 moab::Interface &moab = mb_instance;
82
83 // Create MoFEM instance
84 MoFEM::Core core(moab);
85 MoFEM::Interface &m_field = core;
86
87 int order = 4;
88 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-order", &order, PETSC_NULL);
89
90 DMType dm_name = "DMMOFEM";
91 CHKERR DMRegister_MoFEM(dm_name);
92
93 auto *simple_interface = m_field.getInterface<Simple>();
94 CHKERR simple_interface->getOptions();
95 CHKERR simple_interface->loadFile("");
96 CHKERR simple_interface->addDomainField("FIELD1", H1,
98 CHKERR simple_interface->setFieldOrder("FIELD1", order);
99 CHKERR simple_interface->setUp();
100
101 auto get_ents_on_mesh_skin = [&]() {
102 Range faces;
103 CHKERR m_field.get_moab().get_entities_by_type(0, MBTRI, faces);
104 Skinner skin(&m_field.get_moab());
105 Range skin_edges;
106 CHKERR skin.find_skin(0, faces, false, skin_edges);
107 Range skin_verts;
108 CHKERR moab.get_connectivity(skin_edges, skin_verts, true);
109 skin_edges.merge(skin_verts);
110 return skin_edges;
111 };
112
113 auto mark_boundary_dofs = [&](Range &skin_edges) {
114 auto problem_manager = m_field.getInterface<ProblemsManager>();
115 std::vector<unsigned char> marker;
116 problem_manager->markDofs(simple_interface->getProblemName(), ROW,
117 ProblemsManager::OR, skin_edges, marker);
118 // Unset coefficient 1, e.g. u_y
119 problem_manager->modifyMarkDofs(simple_interface->getProblemName(), ROW,
120 "FIELD1", 1, 1, ProblemsManager::AND, 0,
121 marker);
122 return marker;
123 };
124
125 auto skin_ents = get_ents_on_mesh_skin();
126
127 // Get global local vector of marked DOFs. Is global, since is set for all
128 // DOFs on processor. Is local since only DOFs on processor are in the
129 // vector. To access DOFs use local indices.
130 auto marker = mark_boundary_dofs(skin_ents);
131
132 boost::shared_ptr<FaceEle> fe(new FaceEle(m_field));
133 fe->getOpPtrVector().push_back(new OpFace(skin_ents, marker));
134
135 auto dm = simple_interface->getDM();
136 CHKERR DMoFEMLoopFiniteElements(dm, simple_interface->getDomainFEName(),
137 fe);
138 }
140
142}
int main(int argc, char *argv[])
static char help[]
MoFEM::FaceElementForcesAndSourcesCore FaceEle
@ ROW
Definition: definitions.h:123
#define CATCH_ERRORS
Catch errors.
Definition: definitions.h:372
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition: definitions.h:60
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:447
@ 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 ...
Definition: definitions.h:346
@ MOFEM_ATOM_TEST_INVALID
Definition: definitions.h:40
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:416
#define CHKERR
Inline error check.
Definition: definitions.h:535
FTensor::Index< 'n', SPACE_DIM > n
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition: DMMMoFEM.cpp:47
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition: DMMMoFEM.cpp:533
auto marker
set bit to marker
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
implementation of Data Operators for Forces and Sources
Definition: MoFEM.hpp:24
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
CoreTmp< 0 > Core
Definition: Core.hpp:1086
DeprecatedCoreInterface Interface
Definition: Interface.hpp:1955
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
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
const VectorInt & getLocalIndices() const
get local indices of dofs on entity
const VectorInt & getIndices() const
Get global indices of dofs on entity.
int getNumberOfNodesOnElement() const
Get the number of nodes on finite element.
EntityHandle getSideEntity(const int side_number, const EntityType type)
Get the side entity.
@ OPROW
operator doWork function is executed on FE rows
Problem manager is used to build and partition problems.
Simple interface for fast problem set-up.
Definition: Simple.hpp:26
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface refernce to pointer of interface.
OpFace(const Range &skin_ents, const std::vector< unsigned char > &marker)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
const std::vector< unsigned char > & mArker
const Range & skinEnts