284 {
285
287
288 try {
289
290 DMType dm_name = "DMMOFEM";
292
293 moab::Core mb_instance;
294 moab::Interface &moab = mb_instance;
295
296
297 auto core_log = logging::core::get();
298 core_log->add_sink(
302
303
306
310
311 simple->getAddBoundaryFE() =
true;
312
314
315
316 enum bases {
317 AINSWORTH,
318 AINSWORTH_LOBATTO,
319 DEMKOWICZ,
320 BERNSTEIN,
321 LASBASETOP
322 };
323 const char *list_bases[] = {"ainsworth", "ainsworth_lobatto", "demkowicz",
324 "bernstein"};
325 PetscBool flg;
326 PetscInt choice_base_value = AINSWORTH;
328 LASBASETOP, &choice_base_value, &flg);
329
330 if (flg != PETSC_TRUE)
333 if (choice_base_value == AINSWORTH)
335 if (choice_base_value == AINSWORTH_LOBATTO)
337 else if (choice_base_value == DEMKOWICZ)
339 else if (choice_base_value == BERNSTEIN)
341
342 enum spaces { H1SPACE, L2SPACE, LASBASETSPACE };
343 const char *list_spaces[] = {"h1", "l2"};
344 PetscInt choice_space_value = H1SPACE;
346 LASBASETSPACE, &choice_space_value, &flg);
347 if (flg != PETSC_TRUE)
350 if (choice_space_value == H1SPACE)
352 else if (choice_space_value == L2SPACE)
354
356 PETSC_NULLPTR);
357
358 CHKERR simple->addDomainField(
"FIELD1", space, base, 1);
360
362 CHKERR moab.get_entities_by_dimension(0, 1, edges);
363 CHKERR moab.get_entities_by_dimension(0, 2, faces);
364
365 if (choice_base_value != BERNSTEIN) {
367
369 for (auto e : edges) {
371 rise_order.insert(e);
372 }
374 }
375
376 for (auto f : faces) {
378 rise_order.insert(f);
379 }
381 }
382
384 for (auto e : rise_order) {
386 rise_twice.insert(e);
387 }
389 }
390
392
394 }
395
397
398 auto volume_adj = [](moab::Interface &moab,
const Field &field,
400 std::vector<EntityHandle> &adjacency) {
402 EntityHandle fe_ent = fe.getEnt();
403 switch (field.getSpace()) {
405 CHKERR moab.get_connectivity(&fe_ent, 1, adjacency,
true);
407 CHKERR moab.get_adjacencies(&fe_ent, 1, 1,
false, adjacency,
408 moab::Interface::UNION);
411 CHKERR moab.get_adjacencies(&fe_ent, 1, 2,
false, adjacency,
412 moab::Interface::UNION);
413 adjacency.push_back(fe_ent);
414
415 for (auto ent : adjacency)
416 fe.getSideNumberPtr(ent);
417 break;
419 CHKERR moab.get_entities_by_handle(field.getMeshset(), adjacency,
420 false);
421 for (auto ent : adjacency) {
423 .insert(
424 boost::shared_ptr<SideNumber>(
new SideNumber(ent, -1, 0, 0)));
425 }
426 } break;
427 default:
429 "this field is not implemented for TRI finite element");
430 }
431
433 };
434
436 simple->getDomainFEName(), MBTET, volume_adj);
438 simple->getDomainFEName(), MBHEX, volume_adj);
439
444
445 auto dm =
simple->getDM();
446
449
450 auto assemble_matrices_and_vectors = [&]() {
452
455
457 pipeline_mng->getOpDomainLhsPipeline(), {space});
459 pipeline_mng->getOpDomainRhsPipeline(), {space});
460
463
464 pipeline_mng->getOpDomainLhsPipeline().push_back(
466 pipeline_mng->getOpDomainLhsPipeline().push_back(
new OpMass(
467 "FIELD1", "FIELD1", [](double, double, double) { return 1.; }));
468 pipeline_mng->getOpDomainLhsPipeline().push_back(
470
471 pipeline_mng->getOpDomainRhsPipeline().push_back(
472 new OpSource("FIELD1", ApproxFunctions::fUn));
473
475 return 2 * p_data + 1;
476 };
479
481 };
482
483 auto solve_problem = [&] {
485 auto solver = pipeline_mng->createKSP();
486 CHKERR KSPSetFromOptions(solver);
488
489 auto dm =
simple->getDM();
492
494 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
495 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
497
499 };
500
501 auto check_solution = [&] {
503
504 auto ptr_values = boost::make_shared<VectorDouble>();
505 auto ptr_diff_vals = boost::make_shared<MatrixDouble>();
506
508 pipeline_mng->getOpEvaluationPipeline(), {space});
509
510 pipeline_mng->getOpEvaluationPipeline().push_back(
512 pipeline_mng->getOpEvaluationPipeline().push_back(
514 pipeline_mng->getOpEvaluationPipeline().push_back(
516 ptr_diff_vals));
518 vals, diff_vals, ptr_values, ptr_diff_vals, true));
519
520 CHKERR pipeline_mng->loopFiniteElementsEvaluation();
521
523 };
524
525 auto post_proc = [&] {
527
529
530 auto get_domain_post_proc_fe = [&](auto post_proc_mesh_ptr) {
531 auto post_proc_fe =
532 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<DomainEle>>(
533 m_field, post_proc_mesh_ptr);
534
536 post_proc_fe->getOpPtrVector(), {space});
537
538 auto ptr_values = boost::make_shared<VectorDouble>();
539 auto ptr_diff_vals = boost::make_shared<MatrixDouble>();
540
541 post_proc_fe->getOpPtrVector().push_back(
543 post_proc_fe->getOpPtrVector().push_back(
545 ptr_diff_vals));
546
547 post_proc_fe->getOpPtrVector().push_back(
548
550
551 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
552
553 {{"FIELD1", ptr_values}},
554
555 {{"FIELD1_GRAD", ptr_diff_vals}},
556
557 {}, {})
558
559 );
560 return post_proc_fe;
561 };
562
563 auto get_bdy_post_proc_fe = [&](auto post_proc_mesh_ptr) {
564 auto bdy_post_proc_fe =
565 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<BoundaryEle>>(
566 m_field, post_proc_mesh_ptr);
567
570 boost::make_shared<
572
573 auto ptr_values = boost::make_shared<VectorDouble>();
574 auto ptr_diff_vals = boost::make_shared<MatrixDouble>();
575
576
578 op_loop_side->getOpPtrVector(), {space});
579 op_loop_side->getOpPtrVector().push_back(
581 op_loop_side->getOpPtrVector().push_back(
583 ptr_diff_vals));
584
585 bdy_post_proc_fe->getOpPtrVector().push_back(op_loop_side);
586
587 bdy_post_proc_fe->getOpPtrVector().push_back(
588
590
591 bdy_post_proc_fe->getPostProcMesh(),
592 bdy_post_proc_fe->getMapGaussPts(),
593
594 {{"FIELD1", ptr_values}},
595
596 {{"FIELD1_GRAD", ptr_diff_vals}},
597
598 {}, {})
599
600 );
601
602 return bdy_post_proc_fe;
603 };
604
605 auto post_proc_mesh_ptr = boost::make_shared<moab::Core>();
606 auto post_proc_begin =
607 boost::make_shared<PostProcBrokenMeshInMoabBaseBegin>(
608 m_field, post_proc_mesh_ptr);
609 auto post_proc_end =
610 boost::make_shared<PostProcBrokenMeshInMoabBaseEnd>(
611 m_field, post_proc_mesh_ptr);
612 auto domain_post_proc_fe = get_domain_post_proc_fe(post_proc_mesh_ptr);
613 auto bdy_post_proc_fe = get_bdy_post_proc_fe(post_proc_mesh_ptr);
614
617 domain_post_proc_fe);
619 bdy_post_proc_fe);
621 CHKERR post_proc_end->writeFile(
"out_post_proc.h5m");
622
624 };
625
626 CHKERR assemble_matrices_and_vectors();
630 }
632
634}
void simple(double P1[], double P2[], double P3[], double c[], const int N)
#define CATCH_ERRORS
Catch errors.
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
@ AINSWORTH_BERNSTEIN_BEZIER_BASE
FieldSpace
approximation spaces
@ L2
field with C-1 continuity
@ NOFIELD
scalar or vector of scalars describe (no true field)
@ HCURL
field with continuous tangents
@ HDIV
field with continuous normal traction
#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.
PetscErrorCode DMoFEMPostProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
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
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
PetscErrorCode DMoFEMPreProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
multi_index_container< boost::shared_ptr< SideNumber >, indexed_by< ordered_unique< member< SideNumber, EntityHandle, &SideNumber::ent > >, ordered_non_unique< composite_key< SideNumber, const_mem_fun< SideNumber, EntityType, &SideNumber::getEntType >, member< SideNumber, signed char, &SideNumber::side_number > > > > > SideNumber_multiIndex
SideNumber_multiIndex for SideNumber.
virtual MoFEMErrorCode modify_finite_element_adjacency_table(const std::string &fe_name, const EntityType type, ElementAdjacencyFunct function)=0
modify finite element table, only for advanced user
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
FTensor::Index< 'i', SPACE_DIM > i
OpSchurAssembleBase * createOpSchurAssembleEnd(std::vector< std::string > fields_name, std::vector< boost::shared_ptr< Range > > field_ents, SmartPetscObj< AO > ao, SmartPetscObj< Mat > schur, bool sym_schur, bool symm_op)
Construct a new Op Schur Assemble End object.
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
PetscErrorCode PetscOptionsGetEList(PetscOptions *, const char pre[], const char name[], const char *const *list, PetscInt next, PetscInt *value, PetscBool *set)
OpSchurAssembleBase * createOpSchurAssembleBegin()
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMass
[Only used with Hooke equation (linear material model)]
Add operators pushing bases from local to physical configuration.
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Deprecated interface functions.
Finite element data for entity.
Field data structure for finite element approximation.
std::map< EntityHandle, std::vector< boost::weak_ptr< NumeredEntFiniteElement > > > AdjCache
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.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for double precision scalar field values calculation.
Element used to execute operators on side of the element.
Post post-proc data at points from hash maps.
PipelineManager interface.
keeps information about side number for the finite element
Simple interface for fast problem set-up.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.