v0.16.0
Loading...
Searching...
No Matches
hdiv_divergence_operator.cpp
Go to the documentation of this file.
1/**
2 * \file hdiv_divergence_operator.cpp
3 * \example mofem/atom_tests/hdiv_divergence_operator.cpp
4 *
5 * Using PipelineManager interface calculate the divergence of base functions,
6 * and integral of flux on the boundary. Since the h-div space is used, volume
7 * integral and boundary integral should give the same result.
8 */
9
10
11
12#include <MoFEM.hpp>
13
14using namespace MoFEM;
15
16static char help[] = "...\n\n";
17
30
33
34 double &dIv;
35 OpFacesFluxes(double &div)
37 "HDIV", UserDataOperator::OPROW),
38 dIv(div) {}
39
40 MoFEMErrorCode doWork(int side, EntityType type,
42};
43
44int main(int argc, char *argv[]) {
45
46 MoFEM::Core::Initialize(&argc, &argv, (char *)0, help);
47
48 try {
49
50 enum bases { AINSWORTH, DEMKOWICZ, LASTOP };
51
52 const char *list[] = {"ainsworth", "demkowicz"};
53
54 PetscBool flg;
55 PetscInt choice_value = AINSWORTH;
56 CHKERR PetscOptionsGetEList(PETSC_NULLPTR, NULL, "-base", list, LASTOP,
57 &choice_value, &flg);
58 if (flg != PETSC_TRUE) {
59 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "base not set");
60 }
61
62 PetscBool ho_geometry = PETSC_FALSE;
63 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-ho_geometry", &ho_geometry,
64 PETSC_NULLPTR);
65
66 PetscInt ho_choice_value = AINSWORTH;
67 CHKERR PetscOptionsGetEList(PETSC_NULLPTR, NULL, "-ho_base", list, LASTOP,
68 &ho_choice_value, &flg);
69
70 DMType dm_name = "DMMOFEM";
71 CHKERR DMRegister_MoFEM(dm_name);
72
73 // Create MoAB
74 moab::Core mb_instance; ///< database
75 moab::Interface &moab = mb_instance; ///< interface
76
77 // Create MoFEM
78 MoFEM::Core core(moab);
79 MoFEM::Interface &m_field = core;
80
81 Simple *simple_interface = m_field.getInterface<Simple>();
82 PipelineManager *pipeline_mng = m_field.getInterface<PipelineManager>();
83 CHKERR simple_interface->getOptions();
84 CHKERR simple_interface->loadFile("");
85
86 // fields
87 switch (choice_value) {
88 case AINSWORTH:
89 CHKERR simple_interface->addDomainField("HDIV", HDIV,
91 CHKERR simple_interface->addBoundaryField("HDIV", HDIV,
93 break;
94 case DEMKOWICZ:
95 CHKERR simple_interface->addDomainField("HDIV", HDIV,
97 CHKERR simple_interface->addBoundaryField("HDIV", HDIV,
99 break;
100 }
101
102 if (ho_geometry == PETSC_TRUE) {
103 switch (ho_choice_value) {
104 case AINSWORTH:
105 CHKERR simple_interface->addDataField("MESH_NODE_POSITIONS", H1,
107 case DEMKOWICZ:
108 CHKERR simple_interface->addDataField("MESH_NODE_POSITIONS", H1,
110 }
111 }
112
113 constexpr int order = 3;
114 CHKERR simple_interface->setFieldOrder("HDIV", order);
115 if (ho_geometry == PETSC_TRUE)
116 CHKERR simple_interface->setFieldOrder("MESH_NODE_POSITIONS", 2);
117 CHKERR simple_interface->setUp();
118
119 auto integration_rule = [](int, int, int p_data) { return 2 * p_data; };
120 CHKERR pipeline_mng->setDomainRhsIntegrationRule(integration_rule);
121 CHKERR pipeline_mng->setBoundaryRhsIntegrationRule(integration_rule);
122
123 double divergence_vol = 0;
124 double divergence_skin = 0;
125
126 if (m_field.check_field("MESH_NODE_POSITIONS")) {
127 CHKERR AddHOOps<3, 3, 3>::add(pipeline_mng->getOpDomainRhsPipeline(),
128 {HDIV}, "MESH_NODE_POSITIONS");
129 CHKERR AddHOOps<2, 3, 3>::add(pipeline_mng->getOpBoundaryRhsPipeline(),
130 {HDIV}, "MESH_NODE_POSITIONS");
131 } else {
132 CHKERR AddHOOps<3, 3, 3>::add(pipeline_mng->getOpDomainRhsPipeline(),
133 {HDIV});
134 CHKERR AddHOOps<2, 3, 3>::add(pipeline_mng->getOpBoundaryRhsPipeline(),
135 {HDIV});
136 }
137
138 // domain
139 pipeline_mng->getOpDomainRhsPipeline().push_back(
140 new OpVolDivergence(divergence_vol));
141 // boundary
142 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
143 new OpFacesFluxes(divergence_skin));
144
145 // project geometry form 10 node tets on higher order approx. functions
146 if (ho_geometry == PETSC_TRUE) {
147 Projection10NodeCoordsOnField ent_method(m_field, "MESH_NODE_POSITIONS");
148 CHKERR m_field.loop_dofs("MESH_NODE_POSITIONS", ent_method);
149 }
150 CHKERR pipeline_mng->loopFiniteElements();
151
152 MOFEM_LOG("WORLD", Sev::inform)
153 << "divergence_vol " << std::setprecision(12) << divergence_vol;
154 MOFEM_LOG("WORLD", Sev::inform)
155 << "divergence_skin " << std::setprecision(12) << divergence_skin;
156
157 constexpr double eps = 1e-8;
158 const double error = divergence_skin - divergence_vol;
159 if (fabs(error) > eps)
160 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
161 "invalid surface flux or divergence or both error = %3.4e",
162 error);
163 }
165
167}
168
170OpVolDivergence::doWork(int side, EntityType type,
173
174 if (CN::Dimension(type) < 2)
176
177 if (data.getFieldData().size() == 0)
179
180 int nb_gauss_pts = data.getDiffN().size1();
181 int nb_dofs = data.getFieldData().size();
182
183 VectorDouble div_vec;
184 div_vec.resize(nb_dofs, 0);
185
186 FTensor::Index<'i', 3> i;
187 auto t_base_diff_hdiv = data.getFTensor2DiffN<3, 3>();
188
189 for (size_t gg = 0; gg < nb_gauss_pts; gg++) {
190 for (size_t dd = 0; dd != div_vec.size(); dd++) {
191 double w = getGaussPts()(3, gg) * getVolume();
192 dIv += t_base_diff_hdiv(i, i) * w;
193 ++t_base_diff_hdiv;
194 }
195 }
196
198}
199
203
204 if (CN::Dimension(type) != 2)
206
207 int nb_gauss_pts = data.getN().size1();
208 int nb_dofs = data.getFieldData().size();
209
210 for (int gg = 0; gg < nb_gauss_pts; gg++) {
211 for (int dd = 0; dd < nb_dofs; dd++) {
212
213 double w = getGaussPts()(2, gg);
214 const double n0 = getNormalsAtGaussPts(gg)[0];
215 const double n1 = getNormalsAtGaussPts(gg)[1];
216 const double n2 = getNormalsAtGaussPts(gg)[2];
217 if (getFEType() == MBTRI) {
218 w *= 0.5;
219 }
220
221 dIv += (n0 * data.getVectorN<3>(gg)(dd, 0) +
222 n1 * data.getVectorN<3>(gg)(dd, 1) +
223 n2 * data.getVectorN<3>(gg)(dd, 2)) *
224 w;
225 }
226 }
227
229}
std::string type
int main()
static const double eps
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ H1
continuous field
Definition definitions.h:85
@ HDIV
field with continuous normal traction
Definition definitions.h:87
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_IMPOSSIBLE_CASE
Definition definitions.h:35
@ 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.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
constexpr int order
auto integration_rule
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
virtual bool check_field(const std::string &name) const =0
check if field is in database
#define MOFEM_LOG(channel, severity)
Log.
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.
FTensor::Index< 'i', SPACE_DIM > i
static char help[]
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
PetscErrorCode PetscOptionsGetEList(PetscOptions *, const char pre[], const char name[], const char *const *list, PetscInt next, PetscInt *value, PetscBool *set)
Add operators pushing bases from local to physical configuration.
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.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor2< FTensor::PackPtr< double *, Tensor_Dim0 *Tensor_Dim1 >, Tensor_Dim0, Tensor_Dim1 > getFTensor2DiffN(FieldApproximationBase base)
Get derivatives of base functions for Hdiv space.
MatrixDouble & getDiffN(const FieldApproximationBase base)
get derivatives of base functions
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
const VectorDouble & getFieldData() const
Get DOF values on entity.
const MatrixAdaptor getVectorN(const FieldApproximationBase base, const int gg)
get Hdiv of base functions at Gauss pts
PipelineManager interface.
Projection of edge entities with one mid-node on hierarchical basis.
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:261
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
Definition Simple.cpp:191
MoFEMErrorCode addBoundaryField(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 boundary.
Definition Simple.cpp:355
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:575
MoFEMErrorCode addDataField(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 data field.
Definition Simple.cpp:393
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
Definition Simple.cpp:735
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)