v0.16.0
Loading...
Searching...
No Matches
approx_sphere.cpp
Go to the documentation of this file.
1/**
2 * \file approx_sphere.cpp
3 * \example mofem/tutorials/vec-4_shallow_wave/approx_sphere.cpp
4 *
5 */
6
7#include <MoFEM.hpp>
8
9using namespace MoFEM;
10
11static char help[] = "...\n\n";
12
13#include <MoFEM.hpp>
14
15constexpr int FM_DIM = 2;
16
17template <int DIM> struct ElementsAndOps {};
18
19template <> struct ElementsAndOps<2> {
21};
22
24using DomainEleOp = DomainEle::UserDataOperator;
26
29
30constexpr double a = 1;
31constexpr double a2 = a * a;
32[[maybe_unused]] constexpr double a4 = a2 * a2;
33
34constexpr double A = 6371220;
35
39
40auto res_J = [](const double x, const double y, const double z) {
41 const double res = (x * x + y * y + z * z - a2);
42 return res;
43};
44
45auto res_J_dx = [](const double x, const double y, const double z) {
46 const double res = res_J(x, y, z);
47 return FTensor::Tensor1<double, 3>{res * (2 * x), res * (2 * y),
48 res * (2 * z)};
49};
50
51auto lhs_J_dx2 = [](const double x, const double y, const double z) {
52 const double res = res_J(x, y, z);
54
55 (res * 2 + (4 * x * x)),
56 (4 * y * x),
57 (4 * z * x),
58
59 (4 * x * y),
60 (2 * res + (4 * y * y)),
61 (4 * z * y),
62
63 (4 * x * z),
64 (4 * y * z),
65 (2 * res + (4 * z * z))};
66};
67
68struct OpRhs : public AssemblyDomainEleOp {
69
70 OpRhs(const std::string field_name, boost::shared_ptr<MatrixDouble> x_ptr,
71 boost::shared_ptr<MatrixDouble> dot_x_ptr)
73 xPtr(x_ptr), xDotPtr(dot_x_ptr) {}
74
77
78 auto t_w = getFTensor0IntegrationWeight();
79 auto t_row_base = row_data.getFTensor0N();
80
81 auto t_x0 = getFTensor1CoordsAtGaussPts();
82 auto t_x = getFTensor1FromMat<3>(*xPtr);
83 auto t_dot_x = getFTensor1FromMat<3>(*xDotPtr);
84 auto t_normal = getFTensor1NormalsAtGaussPts();
85
86 for (int gg = 0; gg != nbIntegrationPts; gg++) {
87
88 constexpr auto t_kd = FTensor::Kronecker_Delta<double>();
89 FTensor::Tensor1<double, 3> t_n{t_x0(0), t_x0(1), t_x0(2)};
90 t_n.normalize();
92 t_P(i, j) = t_n(i) * t_n(j);
93 t_Q(i, j) = t_kd(i, j) - t_P(i, j);
94
95 auto t_J_res = res_J_dx(t_x(0), t_x(1), t_x(2));
96
97 const double alpha = t_w;
98 auto t_nf = getFTensor1FromArray<3, 3>(locF);
99 double l = std::sqrt(t_normal(i) * t_normal(i));
100
102 t_res(i) =
103 alpha * l * ((t_P(i, k) * t_J_res(k) + t_Q(i, k) * t_dot_x(k)));
104
105 int rr = 0;
106 for (; rr != nbRows / 3; ++rr) {
107
108 t_nf(j) += t_row_base * t_res(j);
109
110 ++t_row_base;
111 ++t_nf;
112 }
113 for (; rr < nbRowBaseFunctions; ++rr) {
114 ++t_row_base;
115 }
116
117 ++t_w;
118 ++t_x;
119 ++t_dot_x;
120 ++t_x0;
121 ++t_normal;
122 }
123
125 }
126
127private:
128 boost::shared_ptr<MatrixDouble> xPtr;
129 boost::shared_ptr<MatrixDouble> xDotPtr;
130};
131
132struct OpLhs : public AssemblyDomainEleOp {
133
134 OpLhs(const std::string field_name, boost::shared_ptr<MatrixDouble> x_ptr,
135 boost::shared_ptr<MatrixDouble> dot_x_ptr)
137 AssemblyDomainEleOp::OPROWCOL),
138 xPtr(x_ptr), xDotPtr(dot_x_ptr) {
139 this->sYmm = false;
140 }
141
143 EntitiesFieldData::EntData &col_data) {
145
146 auto t_w = getFTensor0IntegrationWeight();
147 auto t_row_base = row_data.getFTensor0N();
148
149 auto t_x0 = getFTensor1CoordsAtGaussPts();
150 auto t_x = getFTensor1FromMat<3>(*xPtr);
151 auto t_normal = getFTensor1NormalsAtGaussPts();
152
153 auto get_t_mat = [&](const int rr) {
155 &locMat(rr + 0, 0), &locMat(rr + 0, 1), &locMat(rr + 0, 2),
156
157 &locMat(rr + 1, 0), &locMat(rr + 1, 1), &locMat(rr + 1, 2),
158
159 &locMat(rr + 2, 0), &locMat(rr + 2, 1), &locMat(rr + 2, 2)};
160 };
161
162 const double ts_a = getTSa();
163
164 for (int gg = 0; gg != nbIntegrationPts; gg++) {
165
166 constexpr auto t_kd = FTensor::Kronecker_Delta<double>();
167 FTensor::Tensor1<double, 3> t_n{t_x0(0), t_x0(1), t_x0(2)};
168 t_n.normalize();
170 t_P(i, j) = t_n(i) * t_n(j);
171 t_Q(i, j) = t_kd(i, j) - t_P(i, j);
172
173 auto t_J_lhs = lhs_J_dx2(t_x(0), t_x(1), t_x(2));
174 double l = std::sqrt(t_normal(i) * t_normal(i));
175
176 const double alpha = t_w;
178 t_lhs(i, j) =
179 (alpha * l) * (t_P(i, k) * t_J_lhs(k, j) + t_Q(i, j) * ts_a);
180
181 int rr = 0;
182 for (; rr != nbRows / 3; rr++) {
183
184 auto t_col_base = col_data.getFTensor0N(gg, 0);
185 auto t_mat = get_t_mat(3 * rr);
186
187 for (int cc = 0; cc != nbCols / 3; cc++) {
188
189 const double rc = t_row_base * t_col_base;
190 t_mat(i, j) += rc * t_lhs(i, j);
191
192 ++t_col_base;
193 ++t_mat;
194 }
195 ++t_row_base;
196 }
197
198 for (; rr < nbRowBaseFunctions; ++rr)
199 ++t_row_base;
200
201 ++t_w;
202 ++t_x;
203 ++t_x0;
204 ++t_normal;
205 }
206
208 }
209
210private:
211 boost::shared_ptr<MatrixDouble> xPtr;
212 boost::shared_ptr<MatrixDouble> xDotPtr;
213};
214
215struct OpError : public DomainEleOp {
216
217 OpError(const std::string field_name, boost::shared_ptr<MatrixDouble> x_ptr)
219 xPtr(x_ptr) {
220
221 std::fill(&doEntities[MBEDGE], &doEntities[MBMAXTYPE], false);
222 }
223
224 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
225
227
228 auto t_w = getFTensor0IntegrationWeight();
229 auto t_x = getFTensor1FromMat<3>(*xPtr);
230 auto t_normal = getFTensor1NormalsAtGaussPts();
231 auto nb_integration_pts = getGaussPts().size2();
232
233 double error = 0;
234
235 for (int gg = 0; gg != nb_integration_pts; gg++) {
236
237 double l = std::sqrt(t_normal(i) * t_normal(i));
238 error += t_w * l * std::abs((t_x(i) * t_x(i) - A * A));
239
240 ++t_w;
241 ++t_x;
242 ++t_normal;
243 }
244
245 CHKERR VecSetValue(errorVec, 0, error, ADD_VALUES);
246
248 }
249
251
252private:
253 boost::shared_ptr<MatrixDouble> xPtr;
254};
255
257
274
275//! [Run programme]
286//! [Run programme]
287
292
293//! [Read mesh]
301//! [Read mesh]
302
303//! [Set up problem]
306
309 CHKERR simple->addDataField("HO_POSITIONS", H1, AINSWORTH_LEGENDRE_BASE, 3);
310
311 int order = 3;
312 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &order, PETSC_NULLPTR);
313 CHKERR simple->setFieldOrder("HO_POSITIONS", order);
314 CHKERR simple->setUp();
315
317}
318//! [Set up problem]
319
320//! [Push operators to pipeline]
324
325 auto integration_rule = [](int, int, int approx_order) {
326 return 3 * approx_order;
327 };
330
331 auto x_ptr = boost::make_shared<MatrixDouble>();
332 auto dot_x_ptr = boost::make_shared<MatrixDouble>();
333 auto det_ptr = boost::make_shared<VectorDouble>();
334 auto jac_ptr = boost::make_shared<MatrixDouble>();
335 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
336
337 auto def_ops = [&](auto &pipeline) {
338 pipeline.push_back(
339 new OpCalculateVectorFieldValues<3>("HO_POSITIONS", x_ptr));
340 pipeline.push_back(
341 new OpCalculateVectorFieldValuesDot<3>("HO_POSITIONS", dot_x_ptr));
342 };
343
344 def_ops(pipeline_mng->getOpDomainRhsPipeline());
345 def_ops(pipeline_mng->getOpDomainLhsPipeline());
346
347 pipeline_mng->getOpDomainRhsPipeline().push_back(
348 new OpRhs("HO_POSITIONS", x_ptr, dot_x_ptr));
349 pipeline_mng->getOpDomainLhsPipeline().push_back(
350 new OpLhs("HO_POSITIONS", x_ptr, dot_x_ptr));
351
353}
354//! [Push operators to pipeline]
355
356//! [Solve]
359
360 // Project HO geometry from mesh
361 Projection10NodeCoordsOnField ent_method_material(mField, "HO_POSITIONS");
362 CHKERR mField.loop_dofs("HO_POSITIONS", ent_method_material);
363
364 auto *simple = mField.getInterface<Simple>();
365 auto *pipeline_mng = mField.getInterface<PipelineManager>();
366
367 auto dm = simple->getDM();
369 ts = pipeline_mng->createTSIM();
370
371 double ftime = 1;
372 CHKERR TSSetMaxSteps(ts, 1);
373 CHKERR TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
374
375 auto T = createDMVector(simple->getDM());
376 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
377 SCATTER_FORWARD);
378 CHKERR TSSetSolution(ts, T);
379 CHKERR TSSetFromOptions(ts);
380
381 CHKERR TSSolve(ts, NULL);
382 CHKERR TSGetTime(ts, &ftime);
383
384 CHKERR mField.getInterface<FieldBlas>()->fieldScale(A, "HO_POSITIONS");
385
387}
388
389//! [Solve]
392
393 auto x_ptr = boost::make_shared<MatrixDouble>();
394 auto det_ptr = boost::make_shared<VectorDouble>();
395 auto jac_ptr = boost::make_shared<MatrixDouble>();
396 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
397
399 auto dm = simple->getDM();
400
401 auto post_proc_fe =
402 boost::make_shared<PostProcBrokenMeshInMoab<DomainEle>>(mField);
403
404 post_proc_fe->getOpPtrVector().push_back(
405 new OpCalculateVectorFieldValues<3>("HO_POSITIONS", x_ptr));
406
408
409 post_proc_fe->getOpPtrVector().push_back(
410
411 new OpPPMap(post_proc_fe->getPostProcMesh(),
412 post_proc_fe->getMapGaussPts(),
413
414 {},
415
416 {{"HO_POSITIONS", x_ptr}},
417
418 {}, {}
419
420 )
421
422 );
423
424 CHKERR DMoFEMLoopFiniteElements(dm, "dFE", post_proc_fe);
425 CHKERR post_proc_fe->writeFile("out_approx.h5m");
426
427 auto error_fe = boost::make_shared<DomainEle>(mField);
428
429 error_fe->getOpPtrVector().push_back(
430 new OpGetHONormalsOnFace("HO_POSITIONS"));
431 error_fe->getOpPtrVector().push_back(
432 new OpCalculateVectorFieldValues<3>("HO_POSITIONS", x_ptr));
433 error_fe->getOpPtrVector().push_back(new OpError("HO_POSITIONS", x_ptr));
434
435 error_fe->preProcessHook = [&]() {
437 MOFEM_LOG("EXAMPLE", Sev::inform) << "Create vec ";
439 mField.get_comm(), (!mField.get_comm_rank()) ? 1 : 0, 1);
440 VecZeroEntries(OpError::errorVec);
442 };
443
444 error_fe->postProcessHook = [&]() {
446 CHKERR VecAssemblyBegin(OpError::errorVec);
447 CHKERR VecAssemblyEnd(OpError::errorVec);
448 double error2;
449 CHKERR VecSum(OpError::errorVec, &error2);
450 MOFEM_LOG("EXAMPLE", Sev::inform)
451 << "Error " << std::sqrt(error2 / (4 * M_PI * A * A));
452 OpError::errorVec.reset();
454 };
455
456 CHKERR DMoFEMLoopFiniteElements(dm, "dFE", error_fe);
457
458 CHKERR simple->deleteDM();
459 CHKERR simple->deleteFiniteElements();
460 if (mField.get_comm_size() > 1)
461 CHKERR mField.get_moab().write_file("out_ho_mesh.h5m", "MOAB",
462 "PARALLEL=WRITE_PART");
463 else
464 CHKERR mField.get_moab().write_file("out_ho_mesh.h5m");
466}
467//! [Postprocess results]
468
469int main(int argc, char *argv[]) {
470
471 // Initialisation of MoFEM/PETSc and MOAB data structures
472 const char param_file[] = "param_file.petsc";
473 MoFEM::Core::Initialize(&argc, &argv, param_file, help);
474
475 auto core_log = logging::core::get();
476 core_log->add_sink(
478 LogManager::setLog("EXAMPLE");
479 MOFEM_LOG_TAG("EXAMPLE", "example");
480
481 try {
482
483 //! [Register MoFEM discrete manager in PETSc]
484 DMType dm_name = "DMMOFEM";
485 CHKERR DMRegister_MoFEM(dm_name);
486 //! [Register MoFEM discrete manager in PETSc
487
488 //! [Create MoAB]
489 moab::Core mb_instance; ///< mesh database
490 moab::Interface &moab = mb_instance; ///< mesh database interface
491 //! [Create MoAB]
492
493 //! [Create MoFEM]
494 MoFEM::Core core(moab); ///< finite element database
495 MoFEM::Interface &m_field = core; ///< finite element database insterface
496 //! [Create MoFEM]
497
498 //! [ApproxSphere]
499 ApproxSphere ex(m_field);
500 CHKERR ex.runProblem();
501 //! [ApproxSphere]
502 }
504
506}
std::string type
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
int main()
constexpr double a2
constexpr double a
static char help[]
constexpr double a4
constexpr double A
auto lhs_J_dx2
constexpr int FM_DIM
FTensor::Index< 'j', 3 > j
FTensor::Index< 'i', 3 > i
auto res_J_dx
auto res_J
FTensor::Index< 'k', 3 > k
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
Kronecker Delta class.
Tensor1< T, Tensor_Dim > normalize()
#define CATCH_ERRORS
Catch errors.
@ 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()
@ 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 ...
#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
constexpr auto t_kd
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:514
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
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:576
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1237
boost::ptr_deque< UserDataOperator > & getOpDomainLhsPipeline()
Get the Op Domain Lhs Pipeline object.
boost::ptr_deque< UserDataOperator > & getOpDomainRhsPipeline()
Get the Op Domain Rhs Pipeline object.
@ PETSC
Standard PETSc assembly.
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
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< 'l', 3 > l
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
constexpr auto field_name
static constexpr int approx_order
MoFEMErrorCode readMesh()
[Read mesh]
MoFEMErrorCode solveSystem()
[Push operators to pipeline]
MoFEM::Interface & mField
MoFEMErrorCode setupProblem()
[Read mesh]
ApproxSphere(MoFEM::Interface &m_field)
MoFEMErrorCode runProblem()
[Run programme]
MoFEMErrorCode setOPs()
[Set up problem]
MoFEMErrorCode getOptions()
[Run programme]
MoFEMErrorCode outputResults()
[Solve]
virtual int get_comm_size() const =0
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =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.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
Basic algebra on fields.
Definition FieldBlas.hpp:21
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
Approximate field values for given petsc vector.
Specialization for MatrixDouble vector field values calculation.
Calculate normal vectors at Gauss points of face elements.
Post post-proc data at points from hash maps.
PipelineManager interface.
MoFEMErrorCode setDomainRhsIntegrationRule(RuleHookFun rule)
Set integration rule for domain right-hand side finite element.
MoFEMErrorCode setDomainLhsIntegrationRule(RuleHookFun rule)
Set integration rule for domain left-hand side finite element.
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 getOptions()
get options
Definition Simple.cpp:180
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:799
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
OpError(const std::string field_name, boost::shared_ptr< MatrixDouble > x_ptr)
static SmartPetscObj< Vec > errorVec
boost::shared_ptr< MatrixDouble > xPtr
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
boost::shared_ptr< MatrixDouble > xPtr
boost::shared_ptr< MatrixDouble > xDotPtr
OpLhs(const std::string field_name, boost::shared_ptr< MatrixDouble > x_ptr, boost::shared_ptr< MatrixDouble > dot_x_ptr)
boost::shared_ptr< MatrixDouble > xPtr
boost::shared_ptr< MatrixDouble > xDotPtr
OpRhs(const std::string field_name, boost::shared_ptr< MatrixDouble > x_ptr, boost::shared_ptr< MatrixDouble > dot_x_ptr)
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data)