v0.14.0
Loading...
Searching...
No Matches
nonlinear_elastic.cpp
Go to the documentation of this file.
1/**
2 * \file nonlinear_elastic.cpp
3 * \example nonlinear_elastic.cpp
4 *
5 * Plane stress elastic dynamic problem
6 *
7 */
8
9#include <MoFEM.hpp>
10#include <MatrixFunction.hpp>
11
12using namespace MoFEM;
13
14constexpr int SPACE_DIM =
15 EXECUTABLE_DIMENSION; //< Space dimension of problem, mesh
16
21using DomainEleOp = DomainEle::UserDataOperator;
22using BoundaryEleOp = BoundaryEle::UserDataOperator;
23
28
32
33template <int DIM> struct PostProcEleByDim;
34
35template <> struct PostProcEleByDim<2> {
39};
40
41template <> struct PostProcEleByDim<3> {
45};
46
51
52#include <HenckyOps.hpp>
53using namespace HenckyOps;
54
55struct Example {
56
57 Example(MoFEM::Interface &m_field) : mField(m_field) {}
58
60
61private:
63
72};
73
74//! [Run problem]
86}
87//! [Run problem]
88
89//! [Read mesh]
93 CHKERR simple->getOptions();
94 char meshFileName[255];
95 CHKERR PetscOptionsGetString(PETSC_NULL, PETSC_NULL, "-file_name",
96 meshFileName, 255, PETSC_NULL);
97 CHKERR simple->loadFile("", meshFileName,
100}
101//! [Read mesh]
102
103//! [Set up problem]
107
108 enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
109 const char *list_bases[LASBASETOPT] = {"ainsworth", "demkowicz"};
110 PetscInt choice_base_value = AINSWORTH;
111 CHKERR PetscOptionsGetEList(PETSC_NULL, NULL, "-base", list_bases,
112 LASBASETOPT, &choice_base_value, PETSC_NULL);
113
115 switch (choice_base_value) {
116 case AINSWORTH:
118 MOFEM_LOG("WORLD", Sev::inform)
119 << "Set AINSWORTH_LEGENDRE_BASE for displacements";
120 break;
121 case DEMKOWICZ:
123 MOFEM_LOG("WORLD", Sev::inform)
124 << "Set DEMKOWICZ_JACOBI_BASE for displacements";
125 break;
126 default:
127 base = LASTBASE;
128 break;
129 }
130
131 // Add field
132 CHKERR simple->addDomainField("U", H1, base, SPACE_DIM);
133 CHKERR simple->addBoundaryField("U", H1, base, SPACE_DIM);
134 int order = 2;
135 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-order", &order, PETSC_NULL);
136 CHKERR simple->setFieldOrder("U", order);
137 CHKERR simple->setUp();
139}
140//! [Set up problem]
141
142//! [Boundary condition]
145 auto *pipeline_mng = mField.getInterface<PipelineManager>();
147 auto bc_mng = mField.getInterface<BcManager>();
148 auto time_scale = boost::make_shared<TimeScale>();
149
150 auto integration_rule = [](int, int, int approx_order) {
151 return 2 * (approx_order - 1);
152 };
153
154 CHKERR pipeline_mng->setDomainRhsIntegrationRule(integration_rule);
155 CHKERR pipeline_mng->setDomainLhsIntegrationRule(integration_rule);
156 CHKERR pipeline_mng->setBoundaryRhsIntegrationRule(integration_rule);
157
159 pipeline_mng->getOpBoundaryRhsPipeline(), mField, "U", {time_scale},
160 "FORCE", Sev::inform);
161
162 //! [Define gravity vector]
164 pipeline_mng->getOpDomainRhsPipeline(), mField, "U", {time_scale},
165 "BODY_FORCE", Sev::inform);
166
167 // Essential BC
168 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_X",
169 "U", 0, 0);
170 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Y",
171 "U", 1, 1);
172 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "REMOVE_Z",
173 "U", 2, 2);
174 CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
175 simple->getProblemName(), "U");
176
177 // Essential MPCs BC
178 CHKERR bc_mng->addBlockDOFsToMPCs(simple->getProblemName(), "U");
179
181}
182//! [Boundary condition]
183
184//! [Push operators to pipeline]
187 auto *simple = mField.getInterface<Simple>();
188 auto *pipeline_mng = mField.getInterface<PipelineManager>();
189
190 auto add_domain_ops_lhs = [&](auto &pip) {
194 mField, pip, "U", "MAT_ELASTIC", Sev::inform);
196 };
197
198 auto add_domain_ops_rhs = [&](auto &pip) {
202 mField, pip, "U", "MAT_ELASTIC", Sev::inform);
204 };
205
206 CHKERR add_domain_ops_lhs(pipeline_mng->getOpDomainLhsPipeline());
207 CHKERR add_domain_ops_rhs(pipeline_mng->getOpDomainRhsPipeline());
208
210}
211//! [Push operators to pipeline]
212
213/**
214 * @brief Monitor solution
215 *
216 * This functions is called by TS solver at the end of each step. It is used
217 * to output results to the hard drive.
218 */
219struct Monitor : public FEMethod {
220 Monitor(SmartPetscObj<DM> dm, boost::shared_ptr<PostProcEleBdy> post_proc)
221 : dM(dm), postProc(post_proc){};
224 constexpr int save_every_nth_step = 1;
225 if (ts_step % save_every_nth_step == 0) {
228 postProc->mField, postProc->getPostProcMesh(), {"U"});
229
230 CHKERR postProc->writeFile(
231 "out_step_" + boost::lexical_cast<std::string>(ts_step) + ".h5m");
232 }
234 }
235
236private:
238 boost::shared_ptr<PostProcEleBdy> postProc;
239};
240
241//! [Solve]
244 auto *simple = mField.getInterface<Simple>();
245 auto *pipeline_mng = mField.getInterface<PipelineManager>();
246
247 auto dm = simple->getDM();
248 auto ts = pipeline_mng->createTSIM();
249
250 // Setup postprocessing
251 auto create_post_proc_fe = [dm, this, simple]() {
252 auto post_proc_ele_domain = [dm, this](auto &pip_domain) {
255 mField, pip_domain, "U", "MAT_ELASTIC", Sev::inform);
256 return common_ptr;
257 };
258
259 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(mField);
260 auto u_ptr = boost::make_shared<MatrixDouble>();
261 post_proc_fe_bdy->getOpPtrVector().push_back(
263 auto op_loop_side =
264 new OpLoopSide<SideEle>(mField, simple->getDomainFEName(), SPACE_DIM);
265 auto common_ptr = post_proc_ele_domain(op_loop_side->getOpPtrVector());
266 post_proc_fe_bdy->getOpPtrVector().push_back(op_loop_side);
267
269
270 post_proc_fe_bdy->getOpPtrVector().push_back(
271
272 new OpPPMap(
273
274 post_proc_fe_bdy->getPostProcMesh(),
275 post_proc_fe_bdy->getMapGaussPts(),
276
277 {},
278
279 {{"U", u_ptr}},
280
281 {{"GRAD", common_ptr->matGradPtr},
282 {"FIRST_PIOLA", common_ptr->getMatFirstPiolaStress()}},
283
284 {}
285
286 )
287
288 );
289 return post_proc_fe_bdy;
290 };
291
292 auto add_extra_finite_elements_to_ksp_solver_pipelines = [&]() {
294
295 auto pre_proc_ptr = boost::make_shared<FEMethod>();
296 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
297 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
298
299 auto time_scale = boost::make_shared<TimeScale>();
300
301 auto get_bc_hook_rhs = [this, pre_proc_ptr, time_scale]() {
304 {time_scale}, false)();
306 };
307
308 pre_proc_ptr->preProcessHook = get_bc_hook_rhs;
309
310 auto get_post_proc_hook_rhs = [this, post_proc_rhs_ptr]() {
313 mField, post_proc_rhs_ptr, nullptr, Sev::verbose)();
315 mField, post_proc_rhs_ptr, 1.)();
316 CHKERR EssentialPostProcRhs<MPCsType>(mField, post_proc_rhs_ptr)();
318 };
319 auto get_post_proc_hook_lhs = [this, post_proc_lhs_ptr]() {
322 mField, post_proc_lhs_ptr, 1.)();
323 CHKERR EssentialPostProcLhs<MPCsType>(mField, post_proc_lhs_ptr)();
325 };
326 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
327 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs;
328
329 // This is low level pushing finite elements (pipelines) to solver
330 auto ts_ctx_ptr = getDMTsCtx(simple->getDM());
331 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
332 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
333 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
334 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
336 };
337
338 // Add extra finite elements to SNES solver pipelines to resolve essential
339 // boundary conditions
340 CHKERR add_extra_finite_elements_to_ksp_solver_pipelines();
341
342 auto create_monitor_fe = [dm](auto &&post_proc_fe) {
343 return boost::make_shared<Monitor>(dm, post_proc_fe);
344 };
345
346 // Set monitor which postprocessing results and saves them to the hard drive
347 boost::shared_ptr<FEMethod> null_fe;
348 auto monitor_ptr = create_monitor_fe(create_post_proc_fe());
349 CHKERR DMMoFEMTSSetMonitor(dm, ts, simple->getDomainFEName(), null_fe,
350 null_fe, monitor_ptr);
351
352 // Set time solver
353 double ftime = 1;
354 CHKERR TSSetDuration(ts, PETSC_DEFAULT, ftime);
355 CHKERR TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
356
357 auto D = createDMVector(simple->getDM());
358
359 CHKERR TSSetSolution(ts, D);
360 CHKERR TSSetFromOptions(ts);
361
362 CHKERR TSSolve(ts, NULL);
363 CHKERR TSGetTime(ts, &ftime);
364
365 PetscInt steps, snesfails, rejects, nonlinits, linits;
366 CHKERR TSGetStepNumber(ts, &steps);
367 CHKERR TSGetSNESFailures(ts, &snesfails);
368 CHKERR TSGetStepRejections(ts, &rejects);
369 CHKERR TSGetSNESIterations(ts, &nonlinits);
370 CHKERR TSGetKSPIterations(ts, &linits);
371 MOFEM_LOG_C("EXAMPLE", Sev::inform,
372 "steps %d (%d rejected, %d SNES fails), ftime %g, nonlinits "
373 "%d, linits %d",
374 steps, rejects, snesfails, ftime, nonlinits, linits);
375
377}
378//! [Solve]
379
380//! [Getting norms]
383
385 auto dm = simple->getDM();
386
387 auto T = createDMVector(simple->getDM());
388 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
389 SCATTER_FORWARD);
390 double nrm2;
391 CHKERR VecNorm(T, NORM_2, &nrm2);
392 MOFEM_LOG("EXAMPLE", Sev::inform) << "Solution norm " << nrm2;
393
394 auto post_proc_norm_fe = boost::make_shared<DomainEle>(mField);
395
396 auto post_proc_norm_rule_hook = [](int, int, int p) -> int { return 2 * p; };
397 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
398
400 post_proc_norm_fe->getOpPtrVector(), {H1});
401
402 enum NORMS { U_NORM_L2 = 0, PIOLA_NORM, LAST_NORM };
403 auto norms_vec =
405 (mField.get_comm_rank() == 0) ? LAST_NORM : 0, LAST_NORM);
406 CHKERR VecZeroEntries(norms_vec);
407
408 auto u_ptr = boost::make_shared<MatrixDouble>();
409 post_proc_norm_fe->getOpPtrVector().push_back(
411
412 post_proc_norm_fe->getOpPtrVector().push_back(
413 new OpCalcNormL2Tensor1<SPACE_DIM>(u_ptr, norms_vec, U_NORM_L2));
414
416 mField, post_proc_norm_fe->getOpPtrVector(), "U", "MAT_ELASTIC",
417 Sev::inform);
418
419 post_proc_norm_fe->getOpPtrVector().push_back(
421 common_ptr->getMatFirstPiolaStress(), norms_vec, PIOLA_NORM));
422
423 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(),
424 post_proc_norm_fe);
425
426 CHKERR VecAssemblyBegin(norms_vec);
427 CHKERR VecAssemblyEnd(norms_vec);
428
429 MOFEM_LOG_CHANNEL("SELF"); // Clear channel from old tags
430 if (mField.get_comm_rank() == 0) {
431 const double *norms;
432 CHKERR VecGetArrayRead(norms_vec, &norms);
433 MOFEM_TAG_AND_LOG("SELF", Sev::inform, "example")
434 << "norm_u: " << std::scientific << std::sqrt(norms[U_NORM_L2]);
435 MOFEM_TAG_AND_LOG("SELF", Sev::inform, "example")
436 << "norm_piola: " << std::scientific << std::sqrt(norms[PIOLA_NORM]);
437 CHKERR VecRestoreArrayRead(norms_vec, &norms);
438 }
439
441}
442//! [Getting norms]
443
444//! [Postprocessing results]
447 PetscInt test_nb = 0;
448 PetscBool test_flg = PETSC_FALSE;
449 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-test", &test_nb, &test_flg);
450
451 if (test_flg) {
453 auto T = createDMVector(simple->getDM());
454 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
455 SCATTER_FORWARD);
456 double nrm2;
457 CHKERR VecNorm(T, NORM_2, &nrm2);
458 MOFEM_LOG("EXAMPLE", Sev::verbose) << "Regression norm " << nrm2;
459 double regression_value = 0;
460 switch (test_nb) {
461 case 1:
462 regression_value = 1.02789;
463 break;
464 case 2:
465 regression_value = 1.8841e+00;
466 break;
467 case 3:
468 regression_value = 1.8841e+00;
469 break;
470 case 4: // just links
471 regression_value = 4.9625e+00;
472 break;
473 case 5: // link master
474 regression_value = 6.6394e+00;
475 break;
476 case 6: // link master swap
477 regression_value = 4.98764e+00;
478 break;
479 case 7: // link Y
480 regression_value = 4.9473e+00;
481 break;
482 case 8: // link_3D_repr
483 regression_value = 2.5749e-01;
484 break;
485
486 default:
487 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID, "Wrong test number.");
488 break;
489 }
490 if (fabs(nrm2 - regression_value) > 1e-2)
491 SETERRQ2(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
492 "Regression test field; wrong norm value. %6.4e != %6.4e", nrm2,
493 regression_value);
494 }
496}
497//! [Postprocessing results]
498
499//! [Check]
503}
504//! [Check]
505
506static char help[] = "...\n\n";
507
508int main(int argc, char *argv[]) {
509
510 // Initialisation of MoFEM/PETSc and MOAB data structures
511 const char param_file[] = "param_file.petsc";
512 MoFEM::Core::Initialize(&argc, &argv, param_file, help);
513
514 // Add logging channel for example
515 auto core_log = logging::core::get();
516 core_log->add_sink(
518 LogManager::setLog("EXAMPLE");
519 MOFEM_LOG_TAG("EXAMPLE", "example");
520
521 try {
522
523 //! [Register MoFEM discrete manager in PETSc]
524 DMType dm_name = "DMMOFEM";
525 CHKERR DMRegister_MoFEM(dm_name);
526 //! [Register MoFEM discrete manager in PETSc
527
528 //! [Create MoAB]
529 moab::Core mb_instance; ///< mesh database
530 moab::Interface &moab = mb_instance; ///< mesh database interface
531 //! [Create MoAB]
532
533 //! [Create MoFEM]
534 MoFEM::Core core(moab); ///< finite element database
535 MoFEM::Interface &m_field = core; ///< finite element database interface
536 //! [Create MoFEM]
537
538 //! [Example]
539 Example ex(m_field);
540 CHKERR ex.runProblem();
541 //! [Example]
542 }
544
546}
#define MOFEM_LOG_C(channel, severity, format,...)
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
int main()
constexpr int SPACE_DIM
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
[Define dimension]
#define CATCH_ERRORS
Catch errors.
FieldApproximationBase
approximation base
Definition definitions.h:58
@ LASTBASE
Definition definitions.h:69
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base nme:nme847.
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
#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.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
constexpr int order
PostProcEleByDim< SPACE_DIM >::PostProcEleBdy PostProcEleBdy
auto integration_rule
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:523
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:586
auto createDMVector(DM dm)
Get smart vector from DM.
Definition DMMoFEM.hpp:1099
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.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
double D
MoFEMErrorCode opFactoryDomainLhs(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< HenckyOps::CommonData > common_ptr, Sev sev)
MoFEMErrorCode opFactoryDomainRhs(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< HenckyOps::CommonData > common_ptr, Sev sev)
auto commonDataFactory(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, std::string block_name, Sev sev, double scale=1)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
PetscErrorCode DMMoFEMTSSetMonitor(DM dm, TS ts, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
Set Monitor To TS solver.
Definition DMMoFEM.cpp:1056
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
Definition DMMoFEM.hpp:1141
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.
PetscErrorCode PetscOptionsGetEList(PetscOptions *, const char pre[], const char name[], const char *const *list, PetscInt next, PetscInt *value, PetscBool *set)
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
int save_every_nth_step
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
#define EXECUTABLE_DIMENSION
Definition plastic.cpp:13
ElementsAndOps< SPACE_DIM >::SideEle SideEle
Definition plastic.cpp:61
static constexpr int approx_order
[Example]
Definition plastic.cpp:213
MoFEMErrorCode boundaryCondition()
MoFEMErrorCode assembleSystem()
MoFEMErrorCode readMesh()
FieldApproximationBase base
Definition plot_base.cpp:68
MoFEMErrorCode checkResults()
MoFEMErrorCode solveSystem()
Example(MoFEM::Interface &m_field)
MoFEMErrorCode runProblem()
MoFEMErrorCode gettingNorms()
[Solve]
MoFEM::Interface & mField
Definition plastic.cpp:223
MoFEMErrorCode setupProblem()
MoFEMErrorCode outputResults()
Add operators pushing bases from local to physical configuration.
Simple interface for fast problem set-up.
Definition BcManager.hpp:25
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:112
Deprecated interface functions.
Definition of the displacement bc data structure.
Definition BCData.hpp:76
Data on single entity (This is passed as argument to DataOperator::doWork)
Class (Function) to enforce essential constrains on the left hand side diagonal.
Definition Essential.hpp:33
Class (Function) to enforce essential constrains on the right hand side diagonal.
Definition Essential.hpp:41
Class (Function) to enforce essential constrains.
Definition Essential.hpp:25
Class (Function) to calculate residual side diagonal.
Definition Essential.hpp:49
structure for User Loop Methods on finite elements
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.
Assembly methods.
Definition Natural.hpp:65
Get norm of input MatrixDouble for Tensor1.
Get norm of input MatrixDouble for Tensor2.
Get values at integration pts for tensor filed rank 1, i.e. vector field.
Element used to execute operators on side of the element.
Post post-proc data at points from hash maps.
PipelineManager interface.
Simple interface for fast problem set-up.
Definition Simple.hpp:27
intrusive_ptr for managing petsc objects
PetscInt ts_step
time step number
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
[Push operators to pipeline]
boost::shared_ptr< PostProcEleBdy > postProc
SmartPetscObj< DM > dM
MoFEMErrorCode postProcess()
function is run at the end of loop
boost::shared_ptr< PostProcEle > postProc
Monitor(SmartPetscObj< DM > dm, boost::shared_ptr< PostProcEleBdy > post_proc)
PipelineManager::ElementsAndOpsByDim< 2 >::FaceSideEle SideEle
PipelineManager::ElementsAndOpsByDim< 3 >::FaceSideEle SideEle
static char help[]
[Check]
constexpr int SPACE_DIM