v0.15.0
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 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);
252
253 // Scatter result data on the mesh
254 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
255 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
256 CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_REVERSE);
257
259}
260//! [Solve system]
261
264
265 auto pipeline_mng = mField.getInterface<PipelineManager>();
266 pipeline_mng->getDomainRhsFE().reset();
267 pipeline_mng->getDomainLhsFE().reset();
268 pipeline_mng->getSkeletonRhsFE().reset();
269 pipeline_mng->getSkeletonLhsFE().reset();
270 pipeline_mng->getBoundaryRhsFE().reset();
271 pipeline_mng->getBoundaryLhsFE().reset();
272
273 auto rule = [](int, int, int p) -> int { return 2 * p; };
274 CHKERR pipeline_mng->setDomainRhsIntegrationRule(rule);
275 auto rule_2 = [this](int, int, int) { return 2 * oRder; };
276 CHKERR pipeline_mng->setSkeletonRhsIntegrationRule(rule_2);
277
278 auto add_base_ops = [&](auto &pipeline) {
279 auto det_ptr = boost::make_shared<VectorDouble>();
280 auto jac_ptr = boost::make_shared<MatrixDouble>();
281 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
282 pipeline.push_back(new OpCalculateHOJacForFace(jac_ptr));
283 pipeline.push_back(new OpInvertMatrix<2>(jac_ptr, det_ptr, inv_jac_ptr));
284 pipeline.push_back(new OpSetInvJacL2ForFace(inv_jac_ptr));
285 };
286
287 auto u_vals_ptr = boost::make_shared<VectorDouble>();
288 auto u_grad_ptr = boost::make_shared<MatrixDouble>();
289
290 add_base_ops(pipeline_mng->getOpDomainRhsPipeline());
291 pipeline_mng->getOpDomainRhsPipeline().push_back(
293 pipeline_mng->getOpDomainRhsPipeline().push_back(
295
296 enum NORMS { L2 = 0, SEMI_NORM, H1, LAST_NORM };
297 std::array<int, LAST_NORM> error_indices;
298 for (int i = 0; i != LAST_NORM; ++i)
299 error_indices[i] = i;
300 auto l2_vec = createVectorMPI(
301 mField.get_comm(), (!mField.get_comm_rank()) ? LAST_NORM : 0, LAST_NORM);
302
303 auto error_op = new DomainEleOp(domainField, DomainEleOp::OPROW);
304 error_op->doWorkRhsHook = [&](DataOperator *op_ptr, int side, EntityType type,
307 auto o = static_cast<DomainEleOp *>(op_ptr);
308
309 FTensor::Index<'i', 2> i;
310
311 if (const size_t nb_dofs = data.getIndices().size()) {
312
313 const int nb_integration_pts = o->getGaussPts().size2();
314 auto t_w = o->getFTensor0IntegrationWeight();
315 auto t_val = getFTensor0FromVec(*u_vals_ptr);
316 auto t_grad = getFTensor1FromMat<2>(*u_grad_ptr);
317 auto t_coords = o->getFTensor1CoordsAtGaussPts();
318
319 std::array<double, LAST_NORM> error;
320 std::fill(error.begin(), error.end(), 0);
321
322 for (int gg = 0; gg != nb_integration_pts; ++gg) {
323
324 const double alpha = t_w * o->getMeasure();
325 const double diff =
326 t_val - u_exact(t_coords(0), t_coords(1), t_coords(2));
327
328 auto t_exact_grad = u_grad_exact(t_coords(0), t_coords(1), t_coords(2));
329
330 const double diff_grad =
331 (t_grad(i) - t_exact_grad(i)) * (t_grad(i) - t_exact_grad(i));
332
333 error[L2] += alpha * pow(diff, 2);
334 error[SEMI_NORM] += alpha * diff_grad;
335
336 ++t_w;
337 ++t_val;
338 ++t_grad;
339 ++t_coords;
340 }
341
342 error[H1] = error[L2] + error[SEMI_NORM];
343
344 CHKERR VecSetValues(l2_vec, LAST_NORM, error_indices.data(), error.data(),
345 ADD_VALUES);
346 }
347
349 };
350
351 auto side_fe_ptr = boost::make_shared<FaceSideEle>(mField);
352 add_base_ops(side_fe_ptr->getOpPtrVector());
353 side_fe_ptr->getOpPtrVector().push_back(
355 std::array<VectorDouble, 2> side_vals;
356 std::array<double, 2> area_map;
357
358 auto side_vals_op = new DomainEleOp(domainField, DomainEleOp::OPROW);
359 side_vals_op->doWorkRhsHook = [&](DataOperator *op_ptr, int side,
360 EntityType type,
363 auto o = static_cast<FaceSideOp *>(op_ptr);
364
365 const auto nb_in_loop = o->getFEMethod()->nInTheLoop;
366 area_map[nb_in_loop] = o->getMeasure();
367 side_vals[nb_in_loop] = *u_vals_ptr;
368 if (!nb_in_loop) {
369 area_map[1] = 0;
370 side_vals[1].clear();
371 }
372
374 };
375 side_fe_ptr->getOpPtrVector().push_back(side_vals_op);
376
377 auto do_work_rhs_error = [&](DataOperator *op_ptr, int side, EntityType type,
380 auto o = static_cast<BoundaryEleOp *>(op_ptr);
381
382 CHKERR o->loopSideFaces("dFE", *side_fe_ptr);
383 const auto in_the_loop = side_fe_ptr->nInTheLoop;
384
385#ifndef NDEBUG
386 const std::array<std::string, 2> ele_type_name = {"BOUNDARY", "SKELETON"};
387 MOFEM_LOG("SELF", Sev::noisy)
388 << "do_work_rhs_error in_the_loop " << ele_type_name[in_the_loop];
389#endif
390
391 const double s = o->getMeasure() / (area_map[0] + area_map[1]);
392 const double p = penalty * s;
393
394 std::array<double, LAST_NORM> error;
395 std::fill(error.begin(), error.end(), 0);
396
397 const int nb_integration_pts = o->getGaussPts().size2();
398
399 if (!in_the_loop) {
400 side_vals[1].resize(nb_integration_pts, false);
401 auto t_coords = o->getFTensor1CoordsAtGaussPts();
402 auto t_val_m = getFTensor0FromVec(side_vals[1]);
403 for (size_t gg = 0; gg != nb_integration_pts; ++gg) {
404 t_val_m = u_exact(t_coords(0), t_coords(1), t_coords(2));
405 ++t_coords;
406 ++t_val_m;
407 }
408 }
409
410 auto t_val_p = getFTensor0FromVec(side_vals[0]);
411 auto t_val_m = getFTensor0FromVec(side_vals[1]);
412 auto t_w = o->getFTensor0IntegrationWeight();
413
414 for (size_t gg = 0; gg != nb_integration_pts; ++gg) {
415
416 const double alpha = o->getMeasure() * t_w;
417 const auto diff = t_val_p - t_val_m;
418 error[SEMI_NORM] += alpha * p * diff * diff;
419
420 ++t_w;
421 ++t_val_p;
422 ++t_val_m;
423 }
424
425
426 error[H1] = error[SEMI_NORM];
427 CHKERR VecSetValues(l2_vec, LAST_NORM, error_indices.data(), error.data(),
428 ADD_VALUES);
429
431 };
432
433 auto skeleton_error_op = new BoundaryEleOp(NOSPACE, BoundaryEleOp::OPSPACE);
434 skeleton_error_op->doWorkRhsHook = do_work_rhs_error;
435 auto boundary_error_op = new BoundaryEleOp(NOSPACE, BoundaryEleOp::OPSPACE);
436 boundary_error_op->doWorkRhsHook = do_work_rhs_error;
437
438 pipeline_mng->getOpDomainRhsPipeline().push_back(error_op);
439 pipeline_mng->getOpSkeletonLhsPipeline().push_back(skeleton_error_op);
440 pipeline_mng->getOpBoundaryRhsPipeline().push_back(boundary_error_op);
441
442 CHKERR pipeline_mng->loopFiniteElements();
443
444 CHKERR VecAssemblyBegin(l2_vec);
445 CHKERR VecAssemblyEnd(l2_vec);
446
447 if (mField.get_comm_rank() == 0) {
448 const double *array;
449 CHKERR VecGetArrayRead(l2_vec, &array);
450 MOFEM_LOG_C("SELF", Sev::inform, "Error Norm L2 %6.4e",
451 std::sqrt(array[L2]));
452 MOFEM_LOG_C("SELF", Sev::inform, "Error Norm Energetic %6.4e",
453 std::sqrt(array[SEMI_NORM]));
454 MOFEM_LOG_C("SELF", Sev::inform, "Error Norm H1 %6.4e",
455 std::sqrt(array[H1]));
456
457 if(is_test) {
458 constexpr double eps = 1e-12;
459 if (std::sqrt(array[H1]) > eps)
460 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID, "Error is too big");
461 }
462
463 CHKERR VecRestoreArrayRead(l2_vec, &array);
464 const MoFEM::Problem *problem_ptr;
466 MOFEM_LOG_C("SELF", Sev::inform, "Nb. DOFs %d",
467 problem_ptr->getNbDofsRow());
468 }
469
470
471
473}
474
475//! [Output results]
478
479 auto pipeline_mng = mField.getInterface<PipelineManager>();
480 pipeline_mng->getDomainLhsFE().reset();
481 pipeline_mng->getSkeletonRhsFE().reset();
482 pipeline_mng->getSkeletonLhsFE().reset();
483 pipeline_mng->getBoundaryRhsFE().reset();
484 pipeline_mng->getBoundaryLhsFE().reset();
485
486 auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
487
488 auto u_ptr = boost::make_shared<VectorDouble>();
489 post_proc_fe->getOpPtrVector().push_back(
491
493
494 post_proc_fe->getOpPtrVector().push_back(
495
496 new OpPPMap(
497
498 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
499
500 {{"U", u_ptr}},
501
502 {},
503
504 {},
505
506 {})
507
508 );
509
510 pipeline_mng->getDomainRhsFE() = post_proc_fe;
511 CHKERR pipeline_mng->loopFiniteElements();
512 CHKERR post_proc_fe->writeFile("out_result.h5m");
513
515}
516//! [Output results]
517
518//! [Run program]
533//! [Run program]
534
535//! [Main]
536int main(int argc, char *argv[]) {
537
538 // Initialisation of MoFEM/PETSc and MOAB data structures
539 const char param_file[] = "param_file.petsc";
540 MoFEM::Core::Initialize(&argc, &argv, param_file, help);
541
542 // Error handling
543 try {
544 // Register MoFEM discrete manager in PETSc
545 DMType dm_name = "DMMOFEM";
546 CHKERR DMRegister_MoFEM(dm_name);
547
548 // Create MOAB instance
549 moab::Core mb_instance; // mesh database
550 moab::Interface &moab = mb_instance; // mesh database interface
551
552 // Create MoFEM instance
553 MoFEM::Core core(moab); // finite element database
554 MoFEM::Interface &m_field = core; // finite element interface
555
556 // Run the main analysis
557 Poisson2DiscontGalerkin poisson_problem(m_field);
558 CHKERR poisson_problem.runProgram();
559 }
561
562 // Finish work: cleaning memory, getting statistics, etc.
564
565 return 0;
566}
567//! [Main]
#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
@ 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 DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:514
PetscErrorCode DMMoFEMGetProblemPtr(DM dm, const MoFEM::Problem **problem_ptr)
Get pointer to problem data structure.
Definition DMMoFEM.cpp:422
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
auto createDMVector(DM dm)
Get smart vector from DM.
Definition DMMoFEM.hpp:1234
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(ublas::vector< T, A > &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: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:118
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.
Post post-proc data at points from hash maps.
Template struct for dimension-specific finite element types.
PipelineManager interface.
boost::shared_ptr< FEMethod > & getDomainRhsFE()
Get domain right-hand side finite element.
boost::shared_ptr< FEMethod > & getDomainLhsFE()
Get domain left-hand side 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
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
Definition Simple.cpp:191
MoFEMErrorCode getOptions()
get options
Definition Simple.cpp:180
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:800
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:736
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]