v0.16.3
Loading...
Searching...
No Matches
poisson_2d_dis_galerkin.cpp
Go to the documentation of this file.
1/**
2 * \file poisson_2d_dis_galerkin.cpp
3 * \example mofem/tutorials/scl-11/poisson_2d_dis_galerkin.cpp
4 *
5 * Example of implementation for discontinuous Galerkin.
6 */
7
8#include <MoFEM.hpp>
9using namespace MoFEM;
10
11constexpr int BASE_DIM = 1;
12constexpr int FIELD_DIM = 1;
13constexpr int SPACE_DIM = 2;
14
16
18using DomainEleOp = DomainEle::UserDataOperator;
19
22using BoundaryEleOp = BoundaryEle::UserDataOperator;
25using FaceSideOp = FaceSideEle::UserDataOperator;
26
28
29static double penalty = 1e6;
30static double phi =
31 -1; // 1 - symmetric Nitsche, 0 - nonsymmetric, -1 antisymmetrica
32static double nitsche = 1;
33
35
40
41PetscBool is_test = PETSC_FALSE;
42
43auto u_exact = [](const double x, const double y, const double) {
44 if (is_test)
45 return x * x * y * y;
46 else
47 return cos(2 * x * M_PI) * cos(2 * y * M_PI);
48};
49
50auto u_grad_exact = [](const double x, const double y, const double) {
51 if (is_test)
52 return FTensor::Tensor1<double, 2>{2 * x * y * y, 2 * x * x * y};
53 else
55
56 -2 * M_PI * cos(2 * M_PI * y) * sin(2 * M_PI * x),
57 -2 * M_PI * cos(2 * M_PI * x) * sin(2 * M_PI * y)
58
59 };
60};
61
62auto source = [](const double x, const double y, const double) {
63 if (is_test)
64 return -(2 * x * x + 2 * y * y);
65 else
66 return 8 * M_PI * M_PI * cos(2 * x * M_PI) * cos(2 * y * M_PI);
67};
68
69using namespace MoFEM;
71
72static char help[] = "...\n\n";
73
75public:
77
78 // Declaration of the main function to run analysis
80
81private:
82 // Declaration of other main functions called in runProgram()
91
92 // MoFEM interfaces
95
96 // Field name and approximation order
97 std::string domainField;
98 int oRder;
99};
100
102 : domainField("U"), mField(m_field), oRder(4) {}
103
104//! [Read mesh]
107
110
111 // Only L2 field is set in this example. Two lines bellow forces simple
112 // interface to creat lower dimension (edge) elements, despite that fact that
113 // there is no field spanning on such elements. We need them for DG method.
116
118
120}
121//! [Read mesh]
122
123//! [Setup problem]
126
127 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &oRder, PETSC_NULLPTR);
128 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-penalty", &penalty,
129 PETSC_NULLPTR);
130 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-phi", &phi, PETSC_NULLPTR);
131 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-nitsche", &nitsche,
132 PETSC_NULLPTR);
133 PetscOptionsGetBool(PETSC_NULLPTR, "", "-is_test", &is_test, PETSC_NULLPTR);
134
135 MOFEM_LOG("WORLD", Sev::inform) << "Set order: " << oRder;
136 MOFEM_LOG("WORLD", Sev::inform) << "Set penalty: " << penalty;
137 MOFEM_LOG("WORLD", Sev::inform) << "Set phi: " << phi;
138 MOFEM_LOG("WORLD", Sev::inform) << "Set nitche: " << nitsche;
139 MOFEM_LOG("WORLD", Sev::inform) << "Set test: " << (is_test == PETSC_TRUE);
140
145
146 // This is only for debigging and experimentation, to see boundary and edge
147 // elements.
148 [[maybe_unused]] auto save_shared = [&](auto meshset, std::string prefix) {
150 auto file_name =
151 prefix + "_" +
152 boost::lexical_cast<std::string>(mField.get_comm_rank()) + ".vtk";
153 CHKERR mField.get_moab().write_file(file_name.c_str(), "VTK", "", &meshset,
154 1);
156 };
157
158 // CHKERR save_shared(simpleInterface->getBoundaryMeshSet(), "bdy");
159 // CHKERR save_shared(simpleInterface->getSkeletonMeshSet(), "skel");
160
162}
163//! [Setup problem]
164
165//! [Boundary condition]
170
171//! [Boundary condition]
172
173//! [Assemble system]
176
177 auto pipeline_mng = mField.getInterface<PipelineManager>();
178
179 auto add_base_ops = [&](auto &pipeline) {
180 auto det_ptr = boost::make_shared<VectorDouble>();
181 auto jac_ptr = boost::make_shared<MatrixDouble>();
182 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
183 pipeline.push_back(new OpCalculateHOJacForFace(jac_ptr));
184 pipeline.push_back(new OpInvertMatrix<2>(jac_ptr, det_ptr, inv_jac_ptr));
185 pipeline.push_back(new OpSetInvJacL2ForFace(inv_jac_ptr));
186 };
187
188 add_base_ops(pipeline_mng->getOpDomainLhsPipeline());
189 pipeline_mng->getOpDomainLhsPipeline().push_back(new OpDomainGradGrad(
191 [](const double, const double, const double) { return 1; }));
192 pipeline_mng->getOpDomainRhsPipeline().push_back(
194
195 // Push operators to the Pipeline for Skeleton
196 auto side_fe_ptr = boost::make_shared<FaceSideEle>(mField);
197 add_base_ops(side_fe_ptr->getOpPtrVector());
198 side_fe_ptr->getOpPtrVector().push_back(
200
201 // Push operators to the Pipeline for Skeleton
202 pipeline_mng->getOpSkeletonLhsPipeline().push_back(
203 new OpL2LhsPenalty(side_fe_ptr));
204
205 // Push operators to the Pipeline for Boundary
206 pipeline_mng->getOpBoundaryLhsPipeline().push_back(
207 new OpL2LhsPenalty(side_fe_ptr));
208 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
209 new OpL2BoundaryRhs(side_fe_ptr, u_exact));
210
212}
213//! [Assemble system]
214
215//! [Set integration rules]
218
219 auto rule_lhs = [](int, int, int p) -> int { return 2 * p; };
220 auto rule_rhs = [](int, int, int p) -> int { return 2 * p; };
221 auto rule_2 = [this](int, int, int) { return 2 * oRder; };
222
223 auto pipeline_mng = mField.getInterface<PipelineManager>();
224 CHKERR pipeline_mng->setDomainLhsIntegrationRule(rule_lhs);
225 CHKERR pipeline_mng->setDomainRhsIntegrationRule(rule_rhs);
226
227 CHKERR pipeline_mng->setSkeletonLhsIntegrationRule(rule_2);
228 CHKERR pipeline_mng->setSkeletonRhsIntegrationRule(rule_2);
229 CHKERR pipeline_mng->setBoundaryLhsIntegrationRule(rule_2);
230 CHKERR pipeline_mng->setBoundaryRhsIntegrationRule(rule_2);
231
233}
234//! [Set integration rules]
235
236//! [Solve system]
239
240 auto pipeline_mng = mField.getInterface<PipelineManager>();
241
242 auto ksp_solver = pipeline_mng->createKSP();
243 CHKERR KSPSetFromOptions(ksp_solver);
244 CHKERR KSPSetUp(ksp_solver);
245
246 // Create RHS and solution vectors
247 auto dm = simpleInterface->getDM();
248 auto F = createDMVector(dm);
249 auto D = vectorDuplicate(F);
250
251 CHKERR KSPSolve(ksp_solver, F, D);
253 ksp_solver, "poisson 2d discontinuous Galerkin");
254
255 // Scatter result data on the mesh
256 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
257 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
258 CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_REVERSE);
259
261}
262//! [Solve system]
263
266
267 auto pipeline_mng = mField.getInterface<PipelineManager>();
268
269 auto rule = [](int, int, int p) -> int { return 2 * p; };
270 CHKERR pipeline_mng->setEvaluationIntegrationRule(rule);
271 auto rule_2 = [this](int, int, int) { return 2 * oRder; };
272 auto &evaluation_pipeline = pipeline_mng->getOpEvaluationPipeline();
273
274 auto add_base_ops = [&](auto &pipeline) {
275 auto det_ptr = boost::make_shared<VectorDouble>();
276 auto jac_ptr = boost::make_shared<MatrixDouble>();
277 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
278 pipeline.push_back(new OpCalculateHOJacForFace(jac_ptr));
279 pipeline.push_back(new OpInvertMatrix<2>(jac_ptr, det_ptr, inv_jac_ptr));
280 pipeline.push_back(new OpSetInvJacL2ForFace(inv_jac_ptr));
281 };
282
283 auto u_vals_ptr = boost::make_shared<VectorDouble>();
284 auto u_grad_ptr = boost::make_shared<MatrixDouble>();
285
286 add_base_ops(evaluation_pipeline);
287 evaluation_pipeline.push_back(
289 evaluation_pipeline.push_back(
291
292 enum NORMS { L2 = 0, SEMI_NORM, H1, LAST_NORM };
293 std::array<int, LAST_NORM> error_indices;
294 for (int i = 0; i != LAST_NORM; ++i)
295 error_indices[i] = i;
296 auto l2_vec = createVectorMPI(
297 mField.get_comm(), (!mField.get_comm_rank()) ? LAST_NORM : 0, LAST_NORM);
298
299 auto error_op = new DomainEleOp(domainField, DomainEleOp::OPROW);
300 error_op->doWorkRhsHook = [&](DataOperator *op_ptr, int side, EntityType type,
303 auto o = static_cast<DomainEleOp *>(op_ptr);
304
305 FTensor::Index<'i', 2> i;
306
307 if (const size_t nb_dofs = data.getIndices().size()) {
308
309 const int nb_integration_pts = o->getGaussPts().size2();
310 auto t_w = o->getFTensor0IntegrationWeight();
311 auto t_val = getFTensor0FromVec(*u_vals_ptr);
312 auto t_grad = getFTensor1FromMat<2>(*u_grad_ptr);
313 auto t_coords = o->getFTensor1CoordsAtGaussPts();
314
315 std::array<double, LAST_NORM> error;
316 std::fill(error.begin(), error.end(), 0);
317
318 for (int gg = 0; gg != nb_integration_pts; ++gg) {
319
320 const double alpha = t_w * o->getMeasure();
321 const double diff =
322 t_val - u_exact(t_coords(0), t_coords(1), t_coords(2));
323
324 auto t_exact_grad = u_grad_exact(t_coords(0), t_coords(1), t_coords(2));
325
326 const double diff_grad =
327 (t_grad(i) - t_exact_grad(i)) * (t_grad(i) - t_exact_grad(i));
328
329 error[L2] += alpha * pow(diff, 2);
330 error[SEMI_NORM] += alpha * diff_grad;
331
332 ++t_w;
333 ++t_val;
334 ++t_grad;
335 ++t_coords;
336 }
337
338 error[H1] = error[L2] + error[SEMI_NORM];
339
340 CHKERR VecSetValues(l2_vec, LAST_NORM, error_indices.data(), error.data(),
341 ADD_VALUES);
342 }
343
345 };
346
347 auto side_fe_ptr = boost::make_shared<FaceSideEle>(mField);
348 add_base_ops(side_fe_ptr->getOpPtrVector());
349 side_fe_ptr->getOpPtrVector().push_back(
351 std::array<VectorDouble, 2> side_vals;
352 std::array<double, 2> area_map;
353 std::array<EntityHandle, 2> side_ents = {0, 0};
354
355 auto side_vals_op = new DomainEleOp(domainField, DomainEleOp::OPROW);
356 side_vals_op->doWorkRhsHook = [&](DataOperator *op_ptr, int side,
357 EntityType type,
360 auto o = static_cast<FaceSideOp *>(op_ptr);
361
362 const auto nb_in_loop = o->getFEMethod()->nInTheLoop;
363 area_map[nb_in_loop] = o->getMeasure();
364 side_vals[nb_in_loop] = *u_vals_ptr;
365 side_ents[nb_in_loop] = o->getFEEntityHandle();
366 if (!nb_in_loop) {
367 area_map[1] = 0;
368 side_vals[1].clear();
369 side_ents[1] = 0;
370 }
371
373 };
374 side_fe_ptr->getOpPtrVector().push_back(side_vals_op);
375
376 auto do_work_rhs_error = [&](DataOperator *op_ptr, int side, EntityType type,
379 auto o = static_cast<BoundaryEleOp *>(op_ptr);
380
381 CHKERR o->loopSideFaces("dFE", *side_fe_ptr);
382 const auto in_the_loop = side_fe_ptr->nInTheLoop;
383 if (in_the_loop) {
384 if (auto side_ptr_fe = o->getSidePtrFE()) {
385 if (side_ptr_fe->numeredEntFiniteElementPtr->getEnt() != side_ents[0]) {
387 }
388 }
389 }
390
391#ifndef NDEBUG
392 const std::array<std::string, 2> ele_type_name = {"BOUNDARY", "SKELETON"};
393 MOFEM_LOG("SELF", Sev::noisy)
394 << "do_work_rhs_error in_the_loop " << ele_type_name[in_the_loop];
395#endif
396
397 const double s = o->getMeasure() / (area_map[0] + area_map[1]);
398 const double p = penalty * s;
399
400 std::array<double, LAST_NORM> error;
401 std::fill(error.begin(), error.end(), 0);
402
403 const int nb_integration_pts = o->getGaussPts().size2();
404
405 if (!in_the_loop) {
406 side_vals[1].resize(nb_integration_pts, false);
407 auto t_coords = o->getFTensor1CoordsAtGaussPts();
408 auto t_val_m = getFTensor0FromVec(side_vals[1]);
409 for (size_t gg = 0; gg != nb_integration_pts; ++gg) {
410 t_val_m = u_exact(t_coords(0), t_coords(1), t_coords(2));
411 ++t_coords;
412 ++t_val_m;
413 }
414 }
415
416 auto t_val_p = getFTensor0FromVec(side_vals[0]);
417 auto t_val_m = getFTensor0FromVec(side_vals[1]);
418 auto t_w = o->getFTensor0IntegrationWeight();
419
420 for (size_t gg = 0; gg != nb_integration_pts; ++gg) {
421
422 const double alpha = o->getMeasure() * t_w;
423 const auto diff = t_val_p - t_val_m;
424 error[SEMI_NORM] += alpha * p * diff * diff;
425
426 ++t_w;
427 ++t_val_p;
428 ++t_val_m;
429 }
430
431
432 error[H1] = error[SEMI_NORM];
433 CHKERR VecSetValues(l2_vec, LAST_NORM, error_indices.data(), error.data(),
434 ADD_VALUES);
435
437 };
438
439 auto skeleton_error_op = new BoundaryEleOp(NOSPACE, BoundaryEleOp::OPSPACE);
440 skeleton_error_op->doWorkRhsHook = do_work_rhs_error;
441 auto boundary_error_op = new BoundaryEleOp(NOSPACE, BoundaryEleOp::OPSPACE);
442 boundary_error_op->doWorkRhsHook = do_work_rhs_error;
443
444 evaluation_pipeline.push_back(error_op);
445
446 auto add_side_error_op = [&](const std::string &fe_name, auto error_op) {
447 auto op_loop_side = new OpLoopSide<BoundaryEle>(
448 mField, fe_name, SPACE_DIM - 1, Sev::verbose);
449 op_loop_side->getSideFEPtr()->getRuleHook = rule_2;
450 op_loop_side->getOpPtrVector().push_back(error_op);
451 evaluation_pipeline.push_back(op_loop_side);
452 };
453
454 add_side_error_op(simpleInterface->getSkeletonFEName(), skeleton_error_op);
455 add_side_error_op(simpleInterface->getBoundaryFEName(), boundary_error_op);
456
457 CHKERR pipeline_mng->loopFiniteElementsEvaluation();
458
459 CHKERR VecAssemblyBegin(l2_vec);
460 CHKERR VecAssemblyEnd(l2_vec);
461
462 if (mField.get_comm_rank() == 0) {
463 const double *array;
464 CHKERR VecGetArrayRead(l2_vec, &array);
465 MOFEM_LOG_C("SELF", Sev::inform, "Error Norm L2 %6.4e",
466 std::sqrt(array[L2]));
467 MOFEM_LOG_C("SELF", Sev::inform, "Error Norm Energetic %6.4e",
468 std::sqrt(array[SEMI_NORM]));
469 MOFEM_LOG_C("SELF", Sev::inform, "Error Norm H1 %6.4e",
470 std::sqrt(array[H1]));
471
472 if(is_test) {
473 constexpr double eps = 1e-12;
474 if (std::sqrt(array[H1]) > eps)
475 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID, "Error is too big");
476 }
477
478 CHKERR VecRestoreArrayRead(l2_vec, &array);
479 const MoFEM::Problem *problem_ptr;
481 MOFEM_LOG_C("SELF", Sev::inform, "Nb. DOFs %d",
482 problem_ptr->getNbDofsRow());
483 }
484
486}
487
488//! [Output results]
491
492 auto pipeline_mng = mField.getInterface<PipelineManager>();
493
494 auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
495
496 auto u_ptr = boost::make_shared<VectorDouble>();
497 post_proc_fe->getOpPtrVector().push_back(
499
501
502 post_proc_fe->getOpPtrVector().push_back(
503
504 new OpPPMap(
505
506 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
507
508 {{"U", u_ptr}},
509
510 {},
511
512 {},
513
514 {})
515
516 );
517
518 pipeline_mng->getDomainPostProcFE() = post_proc_fe;
519 CHKERR pipeline_mng->loopFiniteElementsPostProc();
520 CHKERR post_proc_fe->writeFile("out_result.h5m");
521
523}
524//! [Output results]
525
526//! [Run program]
541//! [Run program]
542
543//! [Main]
544int main(int argc, char *argv[]) {
545
546 // Initialisation of MoFEM/PETSc and MOAB data structures
547 const char param_file[] = "param_file.petsc";
548 MoFEM::Core::Initialize(&argc, &argv, param_file, help);
549
550 // Error handling
551 try {
552 // Register MoFEM discrete manager in PETSc
553 DMType dm_name = "DMMOFEM";
554 CHKERR DMRegister_MoFEM(dm_name);
555
556 // Create MOAB instance
557 moab::Core mb_instance; // mesh database
558 moab::Interface &moab = mb_instance; // mesh database interface
559
560 // Create MoFEM instance
561 MoFEM::Core core(moab); // finite element database
562 MoFEM::Interface &m_field = core; // finite element interface
563
564 // Run the main analysis
565 Poisson2DiscontGalerkin poisson_problem(m_field);
566 CHKERR poisson_problem.runProgram();
567 }
569
570 // Finish work: cleaning memory, getting statistics, etc.
572
573 return 0;
574}
575//! [Main]
std::string type
#define MOFEM_LOG_C(channel, severity, format,...)
int main()
static const double eps
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< 1, FIELD_DIM > OpDomainSource
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LOBATTO_BASE
Definition definitions.h:62
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ L2
field with C-1 continuity
Definition definitions.h:88
@ H1
continuous field
Definition definitions.h:85
@ 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.
constexpr auto domainField
@ F
PetscErrorCode DMMoFEMGetProblemPtr(DM dm, const MoFEM::Problem **problem_ptr)
Get pointer to problem data structure.
Definition DMMoFEM.cpp:451
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:543
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1250
SmartPetscObj< KSP > createKSP(SmartPetscObj< DM > dm=nullptr)
Create KSP (linear) solver.
@ PETSC
Standard PETSc assembly.
#define MOFEM_LOG(channel, severity)
Log.
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradGrad< 1, 1, SPACE_DIM > OpDomainGradGrad
Definition helmholtz.cpp:25
double D
PipelineManager::ElementsAndOpsByDim< FE_DIM >::FaceSideEle FaceSideEle
Definition level_set.cpp:41
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)
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
OpCalculateHOJacForFaceImpl< 2 > OpCalculateHOJacForFace
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
static auto getFTensor0FromVec(V &data)
Get tensor rank 0 (scalar) form data vector.
MoFEMErrorCode VecSetValues(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Assemble PETSc vector.
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
auto u_grad_exact
static char help[]
constexpr int SPACE_DIM
static double nitsche
constexpr int FIELD_DIM
constexpr int BASE_DIM
DomainEle::UserDataOperator DomainEleOp
static double penalty
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradGrad< BASE_DIM, FIELD_DIM, SPACE_DIM > OpDomainGradGrad
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< BASE_DIM, FIELD_DIM > OpDomainSource
static double phi
BoundaryEle::UserDataOperator BoundaryEleOp
PetscBool is_test
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
base operator to do operations at Gauss Pt. level
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for double precision scalar field values calculation.
Operator for inverting matrices at integration points.
Element used to execute operators on side of the element.
Post post-proc data at points from hash maps.
Template struct for dimension-specific finite element types.
PipelineManager interface.
MoFEMErrorCode setEvaluationIntegrationRule(RuleHookFun rule)
Set integration rule for domain evaluation finite element.
boost::shared_ptr< FEMethod > & getDomainPostProcFE()
Get domain postprocessing finite element.
MoFEMErrorCode setDomainLhsIntegrationRule(RuleHookFun rule)
Set integration rule for domain left-hand side finite element.
keeps basic data about problem
DofIdx getNbDofsRow() const
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
bool & getAddBoundaryFE()
Get the addBoundaryFE flag.
Definition Simple.hpp:546
const std::string getBoundaryFEName() const
Get the Boundary FE Name.
Definition Simple.hpp:436
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
Definition Simple.cpp:191
const std::string getSkeletonFEName() const
Get the Skeleton FE Name.
Definition Simple.hpp:443
MoFEMErrorCode getOptions()
get options
Definition Simple.cpp:180
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:799
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
Definition Simple.cpp:575
bool & getAddSkeletonFE()
Get the addSkeletonFE flag.
Definition Simple.hpp:536
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.
Operator tp collect data from elements on the side of Edge/Face.
Operator to evaluate Dirichlet boundary conditions using DG.
MoFEMErrorCode boundaryCondition()
[Setup problem]
MoFEMErrorCode checkResults()
[Solve system]
MoFEMErrorCode setupProblem()
[Read mesh]
MoFEMErrorCode setIntegrationRules()
[Assemble system]
MoFEMErrorCode assembleSystem()
[Boundary condition]
Poisson2DiscontGalerkin(MoFEM::Interface &m_field)
MoFEMErrorCode solveSystem()
[Set integration rules]
MoFEMErrorCode readMesh()
[Read mesh]
MoFEMErrorCode outputResults()
[Output results]
MoFEMErrorCode runProgram()
[Output results]