v0.16.0
Loading...
Searching...
No Matches
Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
Electrostatics Struct Reference
Collaboration diagram for Electrostatics:
[legend]

Public Member Functions

 Electrostatics (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProgram ()
 [Get Charges]
 

Private Types

enum  VecElements { ZERO = 0 , ONE = 1 , LAST_ELEMENT }
 

Private Member Functions

MoFEMErrorCode readMesh ()
 [Read mesh]
 
MoFEMErrorCode setupProblem ()
 [Read mesh]
 
MoFEMErrorCode boundaryCondition ()
 [Setup problem]
 
MoFEMErrorCode setIntegrationRules ()
 [Boundary condition]
 
MoFEMErrorCode assembleSystem ()
 [Set integration rules]
 
MoFEMErrorCode solveSystem ()
 [Assemble system]
 
MoFEMErrorCode outputResults ()
 [Solve system]
 
MoFEMErrorCode getTotalEnergy ()
 [Output results]
 
MoFEMErrorCode getElectrodeCharge ()
 [Get Total Energy]
 

Private Attributes

int oRder = 2
 
int geomOrder = 1
 
MoFEM::InterfacemField
 
SimplesimpleInterface
 
std::string domainField
 
boost::shared_ptr< std::map< int, BlockData > > permBlockSetsPtr
 
boost::shared_ptr< std::map< int, BlockData > > intBlockSetsPtr
 
boost::shared_ptr< std::map< int, BlockData > > electrodeBlockSetsPtr
 
boost::shared_ptr< DataAtIntegrationPtscommonDataPtr
 
boost::shared_ptr< ForcesAndSourcesCoreinterFaceRhsFe
 
boost::shared_ptr< ForcesAndSourcesCoreelectrodeRhsFe
 
double aLpha = 0.0
 
double bEta = 0.0
 
SmartPetscObj< Vec > petscVec
 
SmartPetscObj< Vec > petscVecEnergy
 
PetscBool out_skin = PETSC_FALSE
 
PetscBool is_partitioned = PETSC_FALSE
 
int atomTest = 0
 

Detailed Description

Examples
mofem/tutorials/scl-12_electrostatics/electrostatics.cpp.

Definition at line 12 of file electrostatics.cpp.

Member Enumeration Documentation

◆ VecElements

Enumerator
ZERO 
ONE 
LAST_ELEMENT 
Examples
mofem/tutorials/scl-12_electrostatics/electrostatics.cpp.

Definition at line 50 of file electrostatics.cpp.

Constructor & Destructor Documentation

◆ Electrostatics()

Electrostatics::Electrostatics ( MoFEM::Interface m_field)
Examples
mofem/tutorials/scl-12_electrostatics/electrostatics.cpp.

Definition at line 54 of file electrostatics.cpp.

55 : domainField("POTENTIAL"), mField(m_field) {}
MoFEM::Interface & mField
std::string domainField

Member Function Documentation

◆ assembleSystem()

MoFEMErrorCode Electrostatics::assembleSystem ( )
private

[Set integration rules]

[Assemble system]

Examples
mofem/tutorials/scl-12_electrostatics/electrostatics.cpp.

Definition at line 338 of file electrostatics.cpp.

338 {
340
341 auto pipeline_mng = mField.getInterface<PipelineManager>();
342 commonDataPtr = boost::make_shared<DataAtIntegrationPts>(mField);
343
344 auto add_domain_base_ops = [&](auto &pipeline) {
346 "GEOMETRY");
347
348 pipeline.push_back(
350 };
351
352 add_domain_base_ops(pipeline_mng->getOpDomainLhsPipeline());
353 auto epsilon = [&](const double, const double, const double) {
354 return commonDataPtr->blockPermittivity;
355 };
356
357 { // Push operators to the Pipeline that is responsible for calculating LHS
358 pipeline_mng->getOpDomainLhsPipeline().push_back(
360 }
361
362 { // Push operators to the Pipeline that is responsible for calculating RHS
363 auto set_values_to_bc_dofs = [&](auto &fe) {
364 auto get_bc_hook = [&]() {
366 return hook;
367 };
368 fe->preProcessHook = get_bc_hook();
369 };
370 // Set essential BC
371 auto calculate_residual_from_set_values_on_bc = [&](auto &pipeline) {
372 using OpInternal =
375
376 add_domain_base_ops(pipeline_mng->getOpDomainRhsPipeline());
377
378 auto grad_u_ptr = boost::make_shared<MatrixDouble>();
379 pipeline_mng->getOpDomainRhsPipeline().push_back(
381 grad_u_ptr));
382 auto minus_epsilon = [&](double, double, double) constexpr {
383 return -commonDataPtr->blockPermittivity;
384 };
385 pipeline_mng->getOpDomainRhsPipeline().push_back(
386 new OpInternal(domainField, grad_u_ptr, minus_epsilon));
387 };
388
389 set_values_to_bc_dofs(pipeline_mng->getDomainRhsFE());
390 calculate_residual_from_set_values_on_bc(
391 pipeline_mng->getOpDomainRhsPipeline());
392
393 auto bodySourceTerm = [&](const double, const double, const double) {
394 return bodySource;
395 };
396 pipeline_mng->getOpDomainRhsPipeline().push_back(
397 new OpBodySourceVectorb(domainField, bodySourceTerm));
398 }
399
400 interFaceRhsFe = boost::shared_ptr<ForcesAndSourcesCore>(
402 interFaceRhsFe->getRuleHook = [this](int, int, int p) {
403 return 2 * p + geomOrder -1;
404 };
405
406 {
407
409 interFaceRhsFe->getOpPtrVector(), {NOSPACE}, "GEOMETRY");
410
411 interFaceRhsFe->getOpPtrVector().push_back(
413
414 auto sIgma = [&](const double, const double, const double) {
415 return commonDataPtr->blockChrgDens;
416 };
417
418 interFaceRhsFe->getOpPtrVector().push_back(
420 }
421
423}
@ 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.
FormsIntegrators< IntEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< BASE_DIM, FIELD_DIM > OpInterfaceRhsVectorF
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradGrad< BASE_DIM, FIELD_DIM, SPACE_DIM > OpDomainLhsMatrixK
intPostProc< SPACE_DIM >::intEle IntElementForcesAndSourcesCore
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< BASE_DIM, FIELD_DIM > OpBodySourceVectorb
const double bodySource
@ GAUSS
Gaussian quadrature integration.
@ PETSC
Standard PETSc assembly.
FormsIntegrators< DomainEleOp >::Assembly< A >::LinearForm< I >::OpGradTimesTensor< 1, FIELD_DIM, SPACE_DIM > OpGradTimesTensor
boost::shared_ptr< ForcesAndSourcesCore > interFaceRhsFe
boost::shared_ptr< std::map< int, BlockData > > intBlockSetsPtr
boost::shared_ptr< DataAtIntegrationPts > commonDataPtr
boost::shared_ptr< std::map< int, BlockData > > permBlockSetsPtr
Add operators pushing bases from local to physical configuration.
Class (Function) to enforce essential constrains.
Definition Essential.hpp:25
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
PipelineManager interface.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.

◆ boundaryCondition()

MoFEMErrorCode Electrostatics::boundaryCondition ( )
private

[Setup problem]

[Boundary condition]

Examples
mofem/tutorials/scl-12_electrostatics/electrostatics.cpp.

Definition at line 308 of file electrostatics.cpp.

308 {
310
311 auto bc_mng = mField.getInterface<BcManager>();
312
313 // Remove_BCs_from_blockset name "BOUNDARY_CONDITION";
315 simpleInterface->getProblemName(), "BOUNDARY_CONDITION",
316 std::string(domainField), true);
317
319}
MoFEMErrorCode removeBlockDOFsOnEntities(const std::string problem_name, const std::string block_name, const std::string field_name, int lo, int hi, bool get_low_dim_ents=true, bool is_distributed_mesh=true)
Remove DOFs from problem based on block entities.
Definition BcManager.cpp:72
Simple * simpleInterface
Boundary condition manager for finite element problem setup.
Template specialization for scalar field boundary conditions.
const std::string getProblemName() const
Get the Problem Name.
Definition Simple.hpp:450

◆ getElectrodeCharge()

MoFEMErrorCode Electrostatics::getElectrodeCharge ( )
private

[Get Total Energy]

[Get Charges]

Examples
mofem/tutorials/scl-12_electrostatics/electrostatics.cpp.

Definition at line 632 of file electrostatics.cpp.

632 {
634 auto op_loop_side = new OpLoopSide<SideEle>(
636
638 op_loop_side->getOpPtrVector(), {H1}, "GEOMETRY");
639
640 auto grad_u_ptr_charge = boost::make_shared<MatrixDouble>();
641 auto e_ptr_charge = boost::make_shared<MatrixDouble>();
642
643 op_loop_side->getOpPtrVector().push_back(
645 grad_u_ptr_charge));
646
647 op_loop_side->getOpPtrVector().push_back(
648 new OpElectricField(e_ptr_charge, grad_u_ptr_charge));
649 auto d_jump = boost::make_shared<MatrixDouble>();
650 op_loop_side->getOpPtrVector().push_back(new OpElectricDispJump<SPACE_DIM>(
651 domainField, e_ptr_charge, d_jump, commonDataPtr, permBlockSetsPtr));
652
653 electrodeRhsFe = boost::shared_ptr<ForcesAndSourcesCore>(
655 electrodeRhsFe->getRuleHook = [this](int, int, int p) {
656 return 2 * p + geomOrder -1;
657 };
658
659 // push all the operators in on the side to the electrodeRhsFe
660 electrodeRhsFe->getOpPtrVector().push_back(op_loop_side);
661
662 electrodeRhsFe->getOpPtrVector().push_back(new OpElectrodeCharge<SPACE_DIM>(
664 CHKERR VecZeroEntries(petscVec);
666 "ELECTRODE", electrodeRhsFe, 0,
668 CHKERR VecAssemblyBegin(petscVec);
669 CHKERR VecAssemblyEnd(petscVec);
670
671 if (!mField.get_comm_rank()) {
672 const double *array;
673
674 CHKERR(VecGetArrayRead(petscVec, &array));
675 double aLpha = array[0]; // Use explicit index instead of ZERO
676 double bEta = array[1]; // Use explicit index instead of ONE
677 MOFEM_LOG_CHANNEL("SELF");
678 MOFEM_LOG_C("SELF", Sev::inform,
679 "CHARGE_ELEC_1: %6.15f , CHARGE_ELEC_2: %6.15f", aLpha, bEta);
680
681 CHKERR(VecRestoreArrayRead(petscVec, &array));
682 }
683 if (atomTest && !mField.get_comm_rank()) {
684 double cal_charge_elec1;
685 double cal_charge_elec2;
686 double cal_total_energy;
687 const double *c_ptr, *te_ptr;
688
689 // Get a pointer to the PETSc vector data
690 CHKERR(VecGetArrayRead(petscVec, &c_ptr));
691 CHKERR(VecGetArrayRead(petscVecEnergy, &te_ptr));
692
693 // Expected charges at the electrodes
694 double ref_charge_elec1;
695 double ref_charge_elec2;
696 // Expected total energy of the system
697 double ref_tot_energy;
698 double tol;
699 cal_charge_elec1 = c_ptr[0]; // Read charge at the first electrode
700 cal_charge_elec2 = c_ptr[1]; // Read charge at the second electrode
701 cal_total_energy = te_ptr[0]; // Read total energy of the system
702 if (std::isnan(cal_charge_elec1) || std::isnan(cal_charge_elec2) ||
703 std::isnan(cal_total_energy)) {
704 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
705 "Atom test failed! NaN detected in calculated values.");
706 }
707 switch (atomTest) {
708 case 1: // 2D & 3D test
709 case 3: // JSON clear-block 2D test
710 // Expected charges at the electrodes
711 ref_charge_elec1 = 50.0;
712 ref_charge_elec2 = -50.0;
713 // Expected total energy of the system
714 ref_tot_energy = 500.0;
715 tol = 1e-10;
716 break;
717 case 2: // wavy 3D test
718 ref_charge_elec1 = 10.00968352472943;
719 ref_charge_elec2 = 0.0; // no electrode
720 ref_tot_energy = 50.5978;
721 tol = 1e-4;
722 break;
723 default:
724 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
725 "atom test %d does not exist", atomTest);
726 }
727
728 // Validate the results
729 if (std::abs(ref_charge_elec1 - cal_charge_elec1) > tol ||
730 std::abs(ref_charge_elec2 - cal_charge_elec2) > tol ||
731 std::abs(ref_tot_energy - cal_total_energy) > tol) {
732 SETERRQ(
733 PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
734 "atom test %d failed! Calculated values do not match expected values",
735 atomTest);
736 }
737
738 CHKERR(VecRestoreArrayRead(petscVec,
739 &c_ptr)); // Restore the PETSc vector array
740 CHKERR(VecRestoreArrayRead(petscVecEnergy, &te_ptr));
741 }
742
744}
#define MOFEM_LOG_C(channel, severity, format,...)
constexpr int SPACE_DIM
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
@ MOFEM_INVALID_DATA
Definition definitions.h:36
PetscErrorCode DMoFEMLoopFiniteElementsUpAndLowRank(DM dm, const char fe_name[], MoFEM::FEMethod *method, int low_rank, int up_rank, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:557
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
double tol
boost::shared_ptr< ForcesAndSourcesCore > electrodeRhsFe
SmartPetscObj< Vec > petscVec
SmartPetscObj< Vec > petscVecEnergy
boost::shared_ptr< std::map< int, BlockData > > electrodeBlockSetsPtr
virtual int get_comm_size() const =0
virtual int get_comm_rank() const =0
Element used to execute operators on side of the element.
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:799
const std::string getDomainFEName() const
Get the Domain FE Name.
Definition Simple.hpp:429

◆ getTotalEnergy()

MoFEMErrorCode Electrostatics::getTotalEnergy ( )
private

[Output results]

[Get Total Energy]

Examples
mofem/tutorials/scl-12_electrostatics/electrostatics.cpp.

Definition at line 569 of file electrostatics.cpp.

569 {
571 auto pip_energy = mField.getInterface<PipelineManager>();
572
573 auto rule = [this](int, int, int p) { return 2 * p + geomOrder - 1; };
574 CHKERR pip_energy->setEvaluationIntegrationRule(rule);
575 auto &evaluation_pipeline = pip_energy->getOpEvaluationPipeline();
576
577 // gets the map of the internal domain entity range to get the total energy
578
579 boost::shared_ptr<std::map<int, BlockData>> intrnlDomnBlckSetPtr =
580 boost::make_shared<std::map<int, BlockData>>();
581 Range internal_domain; // range of entities marked the internal domain
583 if (bit->getName().compare(0, 10, "DOMAIN_INT") == 0) {
584 const int id = bit->getMeshsetId();
585 auto &block_data = (*intrnlDomnBlckSetPtr)[id];
586
587 CHKERR mField.get_moab().get_entities_by_dimension(
588 bit->getMeshset(), SPACE_DIM, block_data.internalDomainEnts, true);
589 internal_domain.merge(block_data.internalDomainEnts);
590 block_data.iD = id;
591 }
592 }
593 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
594 internal_domain);
595
597 {H1}, "GEOMETRY");
598
599 auto grad_u_ptr = boost::make_shared<MatrixDouble>();
600 auto e_field_ptr = boost::make_shared<MatrixDouble>();
601
602 evaluation_pipeline.push_back(
604 evaluation_pipeline.push_back(new OpElectricField(e_field_ptr, grad_u_ptr));
605
606 commonDataPtr = boost::make_shared<DataAtIntegrationPts>(mField);
607
608 evaluation_pipeline.push_back(
610 intrnlDomnBlckSetPtr, commonDataPtr, petscVecEnergy));
611
612 CHKERR pip_energy->loopFiniteElementsEvaluation();
613 CHKERR VecAssemblyBegin(petscVecEnergy);
614 CHKERR VecAssemblyEnd(petscVecEnergy);
615
616 double total_energy = 0.0; // declaration for total energy
617 if (!mField.get_comm_rank()) {
618 const double *array;
619
620 CHKERR VecGetArrayRead(petscVecEnergy, &array);
621 total_energy = array[ZERO];
622 MOFEM_LOG_CHANNEL("SELF");
623 MOFEM_LOG_C("SELF", Sev::inform, "Total Energy: %6.15f", total_energy);
624 CHKERR VecRestoreArrayRead(petscVecEnergy, &array);
625 }
626
628}
@ BLOCKSET
#define _IT_CUBITMESHSETS_BY_SET_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet having a particular BC meshset in a moFEM field.
auto bit
set bit
Managing BitRefLevels.
virtual moab::Interface & get_moab()=0
MoFEMErrorCode setEvaluationIntegrationRule(RuleHookFun rule)
Set integration rule for domain evaluation finite element.

◆ outputResults()

MoFEMErrorCode Electrostatics::outputResults ( )
private

[Solve system]

[Output results]

Examples
mofem/tutorials/scl-12_electrostatics/electrostatics.cpp.

Definition at line 471 of file electrostatics.cpp.

471 {
473 auto pipeline_mng = mField.getInterface<PipelineManager>();
474 auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
475
476 // lamda function to calculate electric field
477 auto calculate_e_field = [&](auto &pipeline) {
478 auto u_ptr = boost::make_shared<VectorDouble>();
479 auto x_ptr = boost::make_shared<MatrixDouble>();
480 auto grad_u_ptr = boost::make_shared<MatrixDouble>();
481 auto e_field_ptr = boost::make_shared<MatrixDouble>();
482 // add higher order operator
484 "GEOMETRY");
485 // calculate field values
486 pipeline.push_back(new OpCalculateScalarFieldValues(domainField, u_ptr));
487 pipeline.push_back(
488 new OpCalculateVectorFieldValues<SPACE_DIM>("GEOMETRY", x_ptr));
489
490 // calculate gradient
491 pipeline.push_back(
493 // calculate electric field
494 pipeline.push_back(new OpElectricField(e_field_ptr, grad_u_ptr));
495 return boost::make_tuple(u_ptr, e_field_ptr, x_ptr);
496 };
497
498 auto [u_ptr, e_field_ptr, x_ptr] =
499 calculate_e_field(post_proc_fe->getOpPtrVector());
500
501 auto e_field_times_perm_ptr = boost::make_shared<MatrixDouble>();
502 auto energy_density_ptr = boost::make_shared<VectorDouble>();
503
504 post_proc_fe->getOpPtrVector().push_back(
505 new OpGradTimesPerm(domainField, e_field_ptr, e_field_times_perm_ptr,
507 post_proc_fe->getOpPtrVector().push_back(
508 new OpEnergyDensity(domainField, e_field_ptr, energy_density_ptr,
510
512 post_proc_fe->getOpPtrVector().push_back(new OpPPMap(
513 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
514
515 OpPPMap::DataMapVec{{"POTENTIAL", u_ptr},
516 {"ENERGY_DENSITY", energy_density_ptr}},
518 {"GEOMETRY", x_ptr},
519 {"ELECTRIC_FIELD", e_field_ptr},
520 {"ELECTRIC_DISPLACEMENT", e_field_times_perm_ptr},
521 },
523
525
526 );
527
528 pipeline_mng->getDomainPostProcFE() = post_proc_fe;
529 CHKERR pipeline_mng->loopFiniteElementsPostProc();
530 CHKERR post_proc_fe->writeFile("out.h5m");
531
532 if (out_skin && SPACE_DIM == 3) {
533
534 auto post_proc_skin = boost::make_shared<PostProcFaceEle>(mField);
535 auto op_loop_skin = new OpLoopSide<SideEle>(
537
538 auto [u_ptr, e_field_ptr, x_ptr] =
539 calculate_e_field(op_loop_skin->getOpPtrVector());
540
541 op_loop_skin->getOpPtrVector().push_back(
542 new OpGradTimesPerm(domainField, e_field_ptr, e_field_times_perm_ptr,
544 op_loop_skin->getOpPtrVector().push_back(
545 new OpEnergyDensity(domainField, e_field_ptr, energy_density_ptr,
547
548 // push op to boundary element
549 post_proc_skin->getOpPtrVector().push_back(op_loop_skin);
550
551 post_proc_skin->getOpPtrVector().push_back(new OpPPMap(
552 post_proc_skin->getPostProcMesh(), post_proc_skin->getMapGaussPts(),
553 OpPPMap::DataMapVec{{"POTENTIAL", u_ptr},
554 {"ENERGY_DENSITY", energy_density_ptr}},
555 OpPPMap::DataMapMat{{"ELECTRIC_FIELD", e_field_ptr},
556 {"GEOMETRY", x_ptr},
557 {"ELECTRIC_DISPLACEMENT", e_field_times_perm_ptr}},
559
561 post_proc_skin);
562 CHKERR post_proc_skin->writeFile("out_skin.h5m");
563 }
565}
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
MoFEMErrorCode loopFiniteElementsPostProc(SmartPetscObj< DM > dm=nullptr)
Iterate postprocessing finite elements.
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
Specialization for double precision scalar field values calculation.
Specialization for MatrixDouble vector field values calculation.
Post post-proc data at points from hash maps.
std::map< std::string, ScalarDataPtr > DataMapVec
std::map< std::string, boost::shared_ptr< MatrixDouble > > DataMapMat
boost::shared_ptr< FEMethod > & getDomainPostProcFE()
Get domain postprocessing finite element.

◆ readMesh()

MoFEMErrorCode Electrostatics::readMesh ( )
private

[Read mesh]

Examples
mofem/tutorials/scl-12_electrostatics/electrostatics.cpp.

Definition at line 58 of file electrostatics.cpp.

58 {
62
64 true; // create lower dimensional element to ensure sharing of partitioed
65 // entities at the boundaries.
67 {"permittivity", "charge_density"});
69 CHKERR mField.getInterface<MeshsetsManager>()->setMeshsetFromFile();
71}
static MoFEMErrorCode addCanonicalAttributeNames(const std::vector< std::string > &names)
Interface for managing meshsets containing materials and boundary conditions.
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
bool & getAddSkeletonFE()
Get the addSkeletonFE flag.
Definition Simple.hpp:536

◆ runProgram()

MoFEMErrorCode Electrostatics::runProgram ( )

[Get Charges]

[Run program]

Examples
mofem/tutorials/scl-12_electrostatics/electrostatics.cpp.

Definition at line 748 of file electrostatics.cpp.

748 {
750
761}
MoFEMErrorCode setupProblem()
[Read mesh]
MoFEMErrorCode outputResults()
[Solve system]
MoFEMErrorCode setIntegrationRules()
[Boundary condition]
MoFEMErrorCode getElectrodeCharge()
[Get Total Energy]
MoFEMErrorCode readMesh()
[Read mesh]
MoFEMErrorCode assembleSystem()
[Set integration rules]
MoFEMErrorCode getTotalEnergy()
[Output results]
MoFEMErrorCode boundaryCondition()
[Setup problem]
MoFEMErrorCode solveSystem()
[Assemble system]

◆ setIntegrationRules()

MoFEMErrorCode Electrostatics::setIntegrationRules ( )
private

[Boundary condition]

[Set integration rules]

Examples
mofem/tutorials/scl-12_electrostatics/electrostatics.cpp.

Definition at line 323 of file electrostatics.cpp.

323 {
325
326 auto rule_lhs = [this](int, int, int p) -> int { return 2 * p + geomOrder -1; };
327 auto rule_rhs = [this](int, int, int p) -> int { return 2 * p + geomOrder -1; };
328
329 auto pipeline_mng = mField.getInterface<PipelineManager>();
330 CHKERR pipeline_mng->setDomainLhsIntegrationRule(rule_lhs);
331 CHKERR pipeline_mng->setDomainRhsIntegrationRule(rule_rhs);
332
334}
MoFEMErrorCode setDomainLhsIntegrationRule(RuleHookFun rule)
Set integration rule for domain left-hand side finite element.

◆ setupProblem()

MoFEMErrorCode Electrostatics::setupProblem ( )
private

[Read mesh]

[Setup problem]

Examples
mofem/tutorials/scl-12_electrostatics/electrostatics.cpp.

Definition at line 75 of file electrostatics.cpp.

75 {
77
78 Range domain_ents;
79 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, domain_ents,
80 true);
81 auto get_ents_by_dim = [&](const auto dim) {
82 if (dim == SPACE_DIM) {
83 return domain_ents;
84 } else {
85 Range ents;
86 if (dim == 0)
87 CHKERR mField.get_moab().get_connectivity(domain_ents, ents, true);
88 else
89 CHKERR mField.get_moab().get_entities_by_dimension(0, dim, ents, true);
90 return ents;
91 }
92 };
93
94 // Select base for the field based on the element type
95 auto get_base = [&]() {
96 auto domain_ents = get_ents_by_dim(SPACE_DIM);
97 if (domain_ents.empty())
99 const auto type = type_from_handle(domain_ents[0]);
100 switch (type) {
101 case MBQUAD:
103 case MBHEX:
105 case MBTRI:
107 case MBTET:
109 default:
110 CHK_THROW_MESSAGE(MOFEM_NOT_FOUND, "Element type is not handled");
111 }
112 return NOBASE;
113 };
114
115 auto base = get_base();
118
119 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &oRder, PETSC_NULLPTR);
120
121 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-geom_order", &geomOrder,
122 PETSC_NULLPTR);
123
124 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-atom_test", &atomTest,
125 PETSC_NULLPTR);
127 CHKERR simpleInterface->addDataField("GEOMETRY", H1, base, SPACE_DIM);
129
130 auto project_ho_geometry = [&]() {
131 Projection10NodeCoordsOnField ent_method(mField, "GEOMETRY");
132 return mField.loop_dofs("GEOMETRY", ent_method);
133 };
134
136 CHKERR project_ho_geometry();
137
138 commonDataPtr = boost::make_shared<DataAtIntegrationPts>(mField);
139
140 // gets the map of the permittivity attributes and the block sets
141 permBlockSetsPtr = boost::make_shared<std::map<int, BlockData>>();
142 Range mat_electr_ents; // range of entities with the permittivity
144 if (bit->getName().compare(0, 12, "MAT_ELECTRIC") == 0) {
145 const int id = bit->getMeshsetId();
146 auto &block_data = (*permBlockSetsPtr)[id];
147
148 CHKERR mField.get_moab().get_entities_by_dimension(
149 bit->getMeshset(), SPACE_DIM, block_data.domainEnts, true);
150 mat_electr_ents.merge(block_data.domainEnts);
151
152 std::vector<double> attributes;
153 bit->getAttributes(attributes);
154 if (attributes.size() < 1) {
155 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
156 " At least one permittivity attributes should be given but "
157 "found %zu",
158 attributes.size());
159 }
160 block_data.epsPermit = attributes[0];
161 block_data.iD = id; // id of the block
162 }
163 }
164
165 // gets the map of the charge attributes and the block sets
166 intBlockSetsPtr = boost::make_shared<std::map<int, BlockData>>();
167 Range int_electr_ents; // range of entities with the charge
169 if (bit->getName().compare(0, 12, "INT_ELECTRIC") == 0) {
170 const int id = bit->getMeshsetId();
171 auto &block_data = (*intBlockSetsPtr)[id];
172
173 CHKERR mField.get_moab().get_entities_by_dimension(
174 bit->getMeshset(), SPACE_DIM - 1, block_data.interfaceEnts, true);
175 int_electr_ents.merge(block_data.interfaceEnts);
176
177 std::vector<double> attributes;
178 bit->getAttributes(attributes);
179 if (attributes.size() < 1) {
180 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
181 "At least one charge attributes should be given but found %zu",
182 attributes.size());
183 }
184 block_data.chargeDensity = attributes[0];
185
186 block_data.iD = id; // id-> block ID
187 }
188 }
189 // gets the map of the electrode entity range in the block sets
190 electrodeBlockSetsPtr = boost::make_shared<std::map<int, BlockData>>();
191 Range electrode_ents; // range of entities with the electrode
192 int electrodeCount = 0;
194 if (bit->getName().compare(0, 9, "ELECTRODE") == 0) {
195 const int id = bit->getMeshsetId();
196 auto &block_data = (*electrodeBlockSetsPtr)[id];
197 ++electrodeCount;
198
199 CHKERR mField.get_moab().get_entities_by_dimension(
200 bit->getMeshset(), SPACE_DIM - 1, block_data.electrodeEnts, true);
201 electrode_ents.merge(block_data.electrodeEnts);
202
203
204 if (electrodeCount > 2) {
205 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
206 "Three or more electrode blocksets found");
207 ;
208 }
209 }
210 }
211
212 // sync entities
213 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
214 mat_electr_ents);
215 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
216 int_electr_ents);
217 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
218 electrode_ents);
219
220 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-out_skin", &out_skin,
221 PETSC_NULLPTR);
222 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-is_partitioned", &is_partitioned,
223 PETSC_NULLPTR);
224 // get the skin entities
225 Skinner skinner(&mField.get_moab());
226 Range skin_tris;
227 CHKERR skinner.find_skin(0, mat_electr_ents, false, skin_tris);
228 Range proc_skin;
229 ParallelComm *pcomm =
230 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
231 if (is_partitioned) {
232 CHKERR pcomm->filter_pstatus(skin_tris,
233 PSTATUS_SHARED | PSTATUS_MULTISHARED,
234 PSTATUS_NOT, -1, &proc_skin);
235 } else {
236 proc_skin = skin_tris;
237 }
238 // add the skin entities to the field
241 "SKIN");
245 // add the interface entities to the field
246 CHKERR mField.add_finite_element("INTERFACE");
250 CHKERR mField.modify_finite_element_add_field_data("INTERFACE", "GEOMETRY");
251
253 SPACE_DIM - 1, "INTERFACE");
254 // add the electrode entities to the field
255 CHKERR mField.add_finite_element("ELECTRODE");
259 CHKERR mField.modify_finite_element_add_field_data("ELECTRODE", "GEOMETRY");
260
262 "ELECTRODE");
263
264 // sync field entities
265 mField.getInterface<CommInterface>()->synchroniseFieldEntities(domainField);
266 mField.getInterface<CommInterface>()->synchroniseFieldEntities("GEOMETRY");
275
279
280 DMType dm_name = "DMMOFEM";
281 CHKERR DMRegister_MoFEM(dm_name);
282
284 dm = createDM(mField.get_comm(), dm_name);
285
286 // create dm instance
287 CHKERR DMSetType(dm, dm_name);
288
290
291 // initialise petsc vector for required processor
292 int local_size;
293 if (mField.get_comm_rank() == 0) // get_comm_rank() gets processor number
294
295 local_size = LAST_ELEMENT; // last element gives size of vector
296
297 else
298 // other processors (e.g. 1, 2, 3, etc.)
299 local_size = 0; // local size of vector is zero on other processors
300
304}
std::string type
@ MF_ZERO
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ NOBASE
Definition definitions.h:59
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MYPCOMM_INDEX
default communicator number PCOMM
@ MOFEM_NOT_FOUND
Definition definitions.h:33
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
Definition DMMoFEM.cpp:488
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
virtual MoFEMErrorCode add_ents_to_finite_element_by_dim(const EntityHandle entities, const int dim, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
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.
auto type_from_handle(const EntityHandle h)
get type from entity handle
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)
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
PetscBool is_partitioned
virtual MPI_Comm & get_comm() const =0
Projection of edge entities with one mid-node on hierarchical basis.
MoFEMErrorCode buildProblem()
Build problem.
Definition Simple.cpp:721
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 defineFiniteElements()
Define finite elements.
Definition Simple.cpp:471
MoFEMErrorCode buildFiniteElements()
Build finite elements.
Definition Simple.cpp:659
MoFEMErrorCode addBoundaryField(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 boundary.
Definition Simple.cpp:355
MoFEMErrorCode buildFields()
Build fields.
Definition Simple.cpp:584
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
Definition Simple.cpp:575
MoFEMErrorCode defineProblem(const PetscBool is_partitioned=PETSC_TRUE)
define problem
Definition Simple.cpp:551
MoFEMErrorCode addDataField(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 data field.
Definition Simple.cpp:393
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
Definition Simple.cpp:735
intrusive_ptr for managing petsc objects

◆ solveSystem()

MoFEMErrorCode Electrostatics::solveSystem ( )
private

[Assemble system]

[Solve system]

< Null element does

Examples
mofem/tutorials/scl-12_electrostatics/electrostatics.cpp.

Definition at line 427 of file electrostatics.cpp.

427 {
429
430 auto pipeline_mng = mField.getInterface<PipelineManager>();
431
432 auto ksp_solver = pipeline_mng->createKSP();
433
434 boost::shared_ptr<ForcesAndSourcesCore> null; ///< Null element does
435 DM dm;
437
438 CHKERR DMMoFEMKSPSetComputeRHS(dm, "INTERFACE", interFaceRhsFe, null, null);
439
440 CHKERR KSPSetFromOptions(ksp_solver);
441
442 // Create RHS and solution vectors
443 auto F = createDMVector(dm);
444 auto D = vectorDuplicate(F);
445 // Solve the system
446 CHKERR KSPSetUp(ksp_solver);
447 CHKERR KSPSolve(ksp_solver, F, D);
448
449 CHKERR VecGhostUpdateBegin(F, INSERT_VALUES, SCATTER_FORWARD);
450 CHKERR VecGhostUpdateEnd(F, INSERT_VALUES, SCATTER_FORWARD);
451
452 double fnorm;
453 CHKERR VecNorm(F, NORM_2, &fnorm);
454 CHKERR PetscPrintf(PETSC_COMM_WORLD, "F norm = %9.8e\n", fnorm);
455
456 // Scatter result data on the mesh
457 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
458 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
459
460 double dnorm;
461 CHKERR VecNorm(D, NORM_2, &dnorm);
462 CHKERR PetscPrintf(PETSC_COMM_WORLD, "D norm = %9.8e\n", dnorm);
463
464 CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_REVERSE);
465
467}
@ F
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 DMMoFEMKSPSetComputeRHS(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set KSP right hand side evaluation function
Definition DMMoFEM.cpp:627
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1237
SmartPetscObj< KSP > createKSP(SmartPetscObj< DM > dm=nullptr)
Create KSP (linear) solver.
double D
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.

Member Data Documentation

◆ aLpha

double Electrostatics::aLpha = 0.0
private

◆ atomTest

int Electrostatics::atomTest = 0
private

◆ bEta

double Electrostatics::bEta = 0.0
private

◆ commonDataPtr

boost::shared_ptr<DataAtIntegrationPts> Electrostatics::commonDataPtr
private

◆ domainField

std::string Electrostatics::domainField
private

◆ electrodeBlockSetsPtr

boost::shared_ptr<std::map<int, BlockData> > Electrostatics::electrodeBlockSetsPtr
private

◆ electrodeRhsFe

boost::shared_ptr<ForcesAndSourcesCore> Electrostatics::electrodeRhsFe
private

◆ geomOrder

int Electrostatics::geomOrder = 1
private

◆ intBlockSetsPtr

boost::shared_ptr<std::map<int, BlockData> > Electrostatics::intBlockSetsPtr
private

◆ interFaceRhsFe

boost::shared_ptr<ForcesAndSourcesCore> Electrostatics::interFaceRhsFe
private

◆ is_partitioned

PetscBool Electrostatics::is_partitioned = PETSC_FALSE
private

◆ mField

MoFEM::Interface& Electrostatics::mField
private

◆ oRder

int Electrostatics::oRder = 2
private

◆ out_skin

PetscBool Electrostatics::out_skin = PETSC_FALSE
private

◆ permBlockSetsPtr

boost::shared_ptr<std::map<int, BlockData> > Electrostatics::permBlockSetsPtr
private

◆ petscVec

SmartPetscObj<Vec> Electrostatics::petscVec
private

◆ petscVecEnergy

SmartPetscObj<Vec> Electrostatics::petscVecEnergy
private

◆ simpleInterface

Simple* Electrostatics::simpleInterface
private

The documentation for this struct was generated from the following file: