v0.13.2
Loading...
Searching...
No Matches
hcurl_curl_operator.cpp
Go to the documentation of this file.
1/**
2 * \file hcurl_curl_operator.cpp
3 * \brief Testich curl-curl operator by applying Stokes theorem
4 * \example hcurl_curl_operator.cpp
5 *
6 * Using PipelineManager interface calculate the curl of base functions, and
7 * integral of the vector tangent vector with normal on the boundary. Since the
8 * h-curl space is used, volume integral and boundary integral should give the
9 * same result, as a result, as we are applying Stokes theorem on h-curl space.
10 *
11 */
12
13
14
15#include <MoFEM.hpp>
16
17using namespace MoFEM;
18
19static char help[] = "...\n\n";
20
22
26 "HCURL", UserDataOperator::OPROW),
27 tCurl(t_curl) {}
28
29 MoFEMErrorCode doWork(int side, EntityType type,
31};
32
34
38 "HCURL", UserDataOperator::OPROW),
39 tCurl(t_curl) {}
40
41 MoFEMErrorCode doWork(int side, EntityType type,
43};
44
45int main(int argc, char *argv[]) {
46
47 MoFEM::Core::Initialize(&argc, &argv, (char *)0, help);
48
49 try {
50
51 enum bases { AINSWORTH, DEMKOWICZ, LASTOP };
52
53 const char *list[] = {"ainsworth", "demkowicz"};
54
55 PetscBool flg;
56 PetscInt choise_value = AINSWORTH;
57 CHKERR PetscOptionsGetEList(PETSC_NULL, NULL, "-base", list, LASTOP,
58 &choise_value, &flg);
59 if (flg != PETSC_TRUE) {
60 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "base not set");
61 }
62
63 PetscBool ho_geometry = PETSC_FALSE;
64 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-ho_geometry", &ho_geometry,
65 PETSC_NULL);
66
67 DMType dm_name = "DMMOFEM";
68 CHKERR DMRegister_MoFEM(dm_name);
69
70 // Create MoAB
71 moab::Core mb_instance; ///< database
72 moab::Interface &moab = mb_instance; ///< interface
73
74 // Create MoFEM
75 MoFEM::Core core(moab);
76 MoFEM::Interface &m_field = core;
77
78 Simple *simple_interface = m_field.getInterface<Simple>();
79 PipelineManager *pipeline_mng = m_field.getInterface<PipelineManager>();
80 CHKERR simple_interface->getOptions();
81 CHKERR simple_interface->loadFile("");
82
83 // fields
84 switch (choise_value) {
85 case AINSWORTH:
86 CHKERR simple_interface->addDomainField("HCURL", HCURL,
88 CHKERR simple_interface->addBoundaryField("HCURL", HCURL,
90 break;
91 case DEMKOWICZ:
92 CHKERR simple_interface->addDomainField("HCURL", HCURL,
94 CHKERR simple_interface->addBoundaryField("HCURL", HCURL,
96 break;
97 }
98
99 if (ho_geometry == PETSC_TRUE)
100 CHKERR simple_interface->addDataField("MESH_NODE_POSITIONS", H1,
102
103 constexpr int order = 3;
104 CHKERR simple_interface->setFieldOrder("HCURL", order);
105 // Range ents;
106 // CHKERR moab.get_entities_by_dimension(0, 2, ents, true);
107 // CHKERR simple_interface->setFieldOrder("HCURL", 1, &ents);
108
109 if (ho_geometry == PETSC_TRUE)
110 CHKERR simple_interface->setFieldOrder("MESH_NODE_POSITIONS", 2);
111 CHKERR simple_interface->setUp();
112
113 auto integration_rule = [](int, int, int p_data) { return 2 * p_data; };
114 CHKERR pipeline_mng->setDomainRhsIntegrationRule(integration_rule);
115 CHKERR pipeline_mng->setBoundaryRhsIntegrationRule(integration_rule);
116
118 FTensor::Tensor1<double, 3> t_curl_skin;
119
120 auto material_grad_mat = boost::make_shared<MatrixDouble>();
121 auto material_det_vec = boost::make_shared<VectorDouble>();
122 auto material_inv_grad_mat = boost::make_shared<MatrixDouble>();
123 auto jac_ptr = boost::make_shared<MatrixDouble>();
124 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
125 auto det_ptr = boost::make_shared<VectorDouble>();
126
127 boost::dynamic_pointer_cast<VolumeElementForcesAndSourcesCore>(
128 pipeline_mng->getDomainRhsFE())
129 ->meshPositionsFieldName = "none";
130 boost::dynamic_pointer_cast<PipelineManager::FaceEle>(
131 pipeline_mng->getBoundaryRhsFE())
132 ->meshPositionsFieldName = "none";
133
134 pipeline_mng->getOpDomainRhsPipeline().push_back(
135 new OpCalculateHOJac<3>(jac_ptr));
136 pipeline_mng->getOpDomainRhsPipeline().push_back(
137 new OpInvertMatrix<3>(jac_ptr, det_ptr, inv_jac_ptr));
138 pipeline_mng->getOpDomainRhsPipeline().push_back(
139 new OpSetHOWeights(det_ptr));
140 pipeline_mng->getOpDomainRhsPipeline().push_back(
141 new OpSetHOCovariantPiolaTransform(HCURL, inv_jac_ptr));
142 pipeline_mng->getOpDomainRhsPipeline().push_back(
143 new OpSetHOInvJacVectorBase(HCURL, inv_jac_ptr));
144
145 if (ho_geometry) {
146 pipeline_mng->getOpDomainRhsPipeline().push_back(
147 new OpCalculateVectorFieldGradient<3, 3>("MESH_NODE_POSITIONS",
148 material_grad_mat));
149 pipeline_mng->getOpDomainRhsPipeline().push_back(new OpInvertMatrix<3>(
150 material_grad_mat, material_det_vec, material_inv_grad_mat));
151 pipeline_mng->getOpDomainRhsPipeline().push_back(
152 new OpSetHOWeights(material_det_vec));
153 pipeline_mng->getOpDomainRhsPipeline().push_back(
154 new OpSetHOCovariantPiolaTransform(HCURL, material_inv_grad_mat));
155 pipeline_mng->getOpDomainRhsPipeline().push_back(
156 new OpSetHOInvJacVectorBase(HCURL, material_inv_grad_mat));
157 }
158 pipeline_mng->getOpDomainRhsPipeline().push_back(new OpVolCurl(t_curl_vol));
159
160 if (m_field.check_field("MESH_NODE_POSITIONS"))
161 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
162 new OpGetHONormalsOnFace("MESH_NODE_POSITIONS"));
163 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
165 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
166 new OpFacesRot(t_curl_skin));
167
169 t_curl_vol(i) = 0;
170 t_curl_skin(i) = 0;
171
172 // project geometry form 10 node tets on higher order approx. functions
173 if (ho_geometry == PETSC_TRUE) {
174 Projection10NodeCoordsOnField ent_method(m_field, "MESH_NODE_POSITIONS");
175 CHKERR m_field.loop_dofs("MESH_NODE_POSITIONS", ent_method);
176 }
177
178 // Run pipelines on mesh
179 CHKERR pipeline_mng->loopFiniteElements();
180
181 std::cout.precision(12);
182
183 t_curl_vol(i) -= t_curl_skin(i);
184 double nrm2 = sqrt(t_curl_vol(i) * t_curl_vol(i));
185
186 constexpr double eps = 1e-8;
187 if (fabs(nrm2) > eps)
188 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
189 "Curl operator not passed test\n");
190 }
192
194}
195
199
200 if (data.getFieldData().size() == 0)
202
203 const unsigned int nb_gauss_pts = data.getDiffN().size1();
204 const unsigned int nb_dofs = data.getFieldData().size();
205
206 MatrixDouble curl_mat;
210
211 auto t_curl_base = data.getFTensor2DiffN<3, 3>();
212
213 unsigned int gg = 0;
214 for (; gg < nb_gauss_pts; gg++) {
215 double w = getGaussPts()(3, gg) * getVolume();
217 for (unsigned int dd = 0; dd != nb_dofs; dd++) {
218 t_curl(i) = levi_civita(j, i, k) * t_curl_base(j, k);
219 tCurl(i) += w * t_curl(i);
220 ++t_curl_base;
221 }
222 }
223
225}
226
230
231 int nb_dofs = data.getFieldData().size();
232 if (nb_dofs == 0)
234 int nb_gauss_pts = data.getN().size1();
235
236 auto t_curl_base = data.getFTensor1N<3>();
237
240
241 for (int gg = 0; gg < nb_gauss_pts; gg++) {
242 for (int dd = 0; dd < nb_dofs; dd++) {
243 double w = getGaussPts()(2, gg);
244 const double n0 = getNormalsAtGaussPts(gg)[0];
245 const double n1 = getNormalsAtGaussPts(gg)[1];
246 const double n2 = getNormalsAtGaussPts(gg)[2];
247 if (getFEType() == MBTRI) {
248 w *= 0.5;
249 }
250
251 tCurl(0) += (n1 * t_curl_base(2) - n2 * t_curl_base(1)) * w;
252 tCurl(1) += (n2 * t_curl_base(0) - n0 * t_curl_base(2)) * w;
253 tCurl(2) += (n0 * t_curl_base(1) - n1 * t_curl_base(0)) * w;
254 ++t_curl_base;
255 }
256 }
257
259}
ForcesAndSourcesCore::UserDataOperator UserDataOperator
int main()
Definition: adol-c_atom.cpp:46
static const double eps
#define CATCH_ERRORS
Catch errors.
Definition: definitions.h:372
@ 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()
Definition: definitions.h:447
@ H1
continuous field
Definition: definitions.h:85
@ HCURL
field with continuous tangents
Definition: definitions.h:86
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:346
@ 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()
Definition: definitions.h:416
#define CHKERR
Inline error check.
Definition: definitions.h:535
auto integration_rule
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition: DMMoFEM.cpp:47
virtual bool check_field(const std::string &name) const =0
check if field is in database
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.
static char help[]
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
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)
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)
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 dofs values
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
Get field gradients at integration pts for scalar filed rank 0, i.e. vector field.
Calculate normals at Gauss points of triangle element.
transform Hcurl base fluxes from reference element to physical triangle
Apply covariant (Piola) transfer to Hcurl space for HO geometry.
transform local reference derivatives of shape function to global derivatives if higher order geometr...
Set inverse jacobian to base functions.
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 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 field on domain.
Definition: Simple.cpp:320
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
MoFEMErrorCode getOptions()
get options
Definition: Simple.cpp:180
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name)
Load mesh file.
Definition: Simple.cpp:194
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
Definition: Simple.cpp:476
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:282
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
Definition: Simple.cpp:614
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface refernce to pointer of interface.
OpFacesRot(FTensor::Tensor1< double, 3 > &t_curl)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
FTensor::Tensor1< double, 3 > & tCurl
OpVolCurl(FTensor::Tensor1< double, 3 > &t_curl)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
FTensor::Tensor1< double, 3 > & tCurl