6#ifndef EXECUTABLE_DIMENSION
7#define EXECUTABLE_DIMENSION 3
11static char help[] =
"...\n\n";
67 {
"permittivity",
"charge_density"});
81 auto get_ents_by_dim = [&](
const auto dim) {
95 auto get_base = [&]() {
96 auto domain_ents = get_ents_by_dim(
SPACE_DIM);
97 if (domain_ents.empty())
115 auto base = get_base();
130 auto project_ho_geometry = [&]() {
136 CHKERR project_ho_geometry();
142 Range mat_electr_ents;
144 if (
bit->getName().compare(0, 12,
"MAT_ELECTRIC") == 0) {
145 const int id =
bit->getMeshsetId();
146 auto &block_data = (*permBlockSetsPtr)[id];
149 bit->getMeshset(),
SPACE_DIM, block_data.domainEnts,
true);
150 mat_electr_ents.merge(block_data.domainEnts);
152 std::vector<double> attributes;
153 bit->getAttributes(attributes);
154 if (attributes.size() < 1) {
156 " At least one permittivity attributes should be given but "
160 block_data.epsPermit = attributes[0];
167 Range int_electr_ents;
169 if (
bit->getName().compare(0, 12,
"INT_ELECTRIC") == 0) {
170 const int id =
bit->getMeshsetId();
171 auto &block_data = (*intBlockSetsPtr)[id];
174 bit->getMeshset(),
SPACE_DIM - 1, block_data.interfaceEnts,
true);
175 int_electr_ents.merge(block_data.interfaceEnts);
177 std::vector<double> attributes;
178 bit->getAttributes(attributes);
179 if (attributes.size() < 1) {
181 "At least one charge attributes should be given but found %zu",
184 block_data.chargeDensity = attributes[0];
191 Range electrode_ents;
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];
200 bit->getMeshset(),
SPACE_DIM - 1, block_data.electrodeEnts,
true);
201 electrode_ents.merge(block_data.electrodeEnts);
204 if (electrodeCount > 2) {
206 "Three or more electrode blocksets found");
227 CHKERR skinner.find_skin(0, mat_electr_ents,
false, skin_tris);
229 ParallelComm *pcomm =
232 CHKERR pcomm->filter_pstatus(skin_tris,
233 PSTATUS_SHARED | PSTATUS_MULTISHARED,
234 PSTATUS_NOT, -1, &proc_skin);
236 proc_skin = skin_tris;
280 DMType dm_name =
"DMMOFEM";
287 CHKERR DMSetType(dm, dm_name);
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; };
331 CHKERR pipeline_mng->setDomainRhsIntegrationRule(rule_rhs);
344 auto add_domain_base_ops = [&](
auto &pipeline) {
352 add_domain_base_ops(pipeline_mng->getOpDomainLhsPipeline());
358 pipeline_mng->getOpDomainLhsPipeline().push_back(
363 auto set_values_to_bc_dofs = [&](
auto &fe) {
364 auto get_bc_hook = [&]() {
368 fe->preProcessHook = get_bc_hook();
371 auto calculate_residual_from_set_values_on_bc = [&](
auto &pipeline) {
376 add_domain_base_ops(pipeline_mng->getOpDomainRhsPipeline());
378 auto grad_u_ptr = boost::make_shared<MatrixDouble>();
379 pipeline_mng->getOpDomainRhsPipeline().push_back(
385 pipeline_mng->getOpDomainRhsPipeline().push_back(
386 new OpInternal(
domainField, grad_u_ptr, minus_epsilon));
389 set_values_to_bc_dofs(pipeline_mng->getDomainRhsFE());
390 calculate_residual_from_set_values_on_bc(
391 pipeline_mng->getOpDomainRhsPipeline());
396 pipeline_mng->getOpDomainRhsPipeline().push_back(
432 auto ksp_solver = pipeline_mng->
createKSP();
434 boost::shared_ptr<ForcesAndSourcesCore> null;
440 CHKERR KSPSetFromOptions(ksp_solver);
446 CHKERR KSPSetUp(ksp_solver);
451 CHKERR VecGhostUpdateBegin(
F, INSERT_VALUES, SCATTER_FORWARD);
452 CHKERR VecGhostUpdateEnd(
F, INSERT_VALUES, SCATTER_FORWARD);
455 CHKERR VecNorm(
F, NORM_2, &fnorm);
456 CHKERR PetscPrintf(PETSC_COMM_WORLD,
"F norm = %9.8e\n", fnorm);
459 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
460 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
463 CHKERR VecNorm(
D, NORM_2, &dnorm);
464 CHKERR PetscPrintf(PETSC_COMM_WORLD,
"D norm = %9.8e\n", dnorm);
476 auto post_proc_fe = boost::make_shared<PostProcEle>(
mField);
479 auto calculate_e_field = [&](
auto &pipeline) {
480 auto u_ptr = boost::make_shared<VectorDouble>();
481 auto x_ptr = boost::make_shared<MatrixDouble>();
482 auto grad_u_ptr = boost::make_shared<MatrixDouble>();
483 auto e_field_ptr = boost::make_shared<MatrixDouble>();
497 return boost::make_tuple(u_ptr, e_field_ptr, x_ptr);
500 auto [u_ptr, e_field_ptr, x_ptr] =
501 calculate_e_field(post_proc_fe->getOpPtrVector());
503 auto e_field_times_perm_ptr = boost::make_shared<MatrixDouble>();
504 auto energy_density_ptr = boost::make_shared<VectorDouble>();
506 post_proc_fe->getOpPtrVector().push_back(
509 post_proc_fe->getOpPtrVector().push_back(
514 post_proc_fe->getOpPtrVector().push_back(
new OpPPMap(
515 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
518 {
"ENERGY_DENSITY", energy_density_ptr}},
521 {
"ELECTRIC_FIELD", e_field_ptr},
522 {
"ELECTRIC_DISPLACEMENT", e_field_times_perm_ptr},
531 CHKERR pipeline_mng->loopFiniteElementsPostProc();
532 CHKERR post_proc_fe->writeFile(
"out.h5m");
536 auto post_proc_skin = boost::make_shared<PostProcFaceEle>(mField);
538 mField, simpleInterface->getDomainFEName(),
SPACE_DIM);
540 auto [u_ptr, e_field_ptr, x_ptr] =
541 calculate_e_field(op_loop_skin->getOpPtrVector());
543 op_loop_skin->getOpPtrVector().push_back(
545 permBlockSetsPtr, commonDataPtr));
546 op_loop_skin->getOpPtrVector().push_back(
548 permBlockSetsPtr, commonDataPtr));
551 post_proc_skin->getOpPtrVector().push_back(op_loop_skin);
553 post_proc_skin->getOpPtrVector().push_back(
new OpPPMap(
554 post_proc_skin->getPostProcMesh(), post_proc_skin->getMapGaussPts(),
556 {
"ENERGY_DENSITY", energy_density_ptr}},
559 {
"ELECTRIC_DISPLACEMENT", e_field_times_perm_ptr}},
564 CHKERR post_proc_skin->writeFile(
"out_skin.h5m");
575 auto rule = [
this](int, int,
int p) {
return 2 * p +
geomOrder - 1; };
577 auto &evaluation_pipeline = pip_energy->getOpEvaluationPipeline();
581 boost::shared_ptr<std::map<int, BlockData>> intrnlDomnBlckSetPtr =
582 boost::make_shared<std::map<int, BlockData>>();
583 Range internal_domain;
585 if (
bit->getName().compare(0, 10,
"DOMAIN_INT") == 0) {
586 const int id =
bit->getMeshsetId();
587 auto &block_data = (*intrnlDomnBlckSetPtr)[id];
590 bit->getMeshset(),
SPACE_DIM, block_data.internalDomainEnts,
true);
591 internal_domain.merge(block_data.internalDomainEnts);
601 auto grad_u_ptr = boost::make_shared<MatrixDouble>();
602 auto e_field_ptr = boost::make_shared<MatrixDouble>();
604 evaluation_pipeline.push_back(
606 evaluation_pipeline.push_back(
new OpElectricField(e_field_ptr, grad_u_ptr));
610 evaluation_pipeline.push_back(
614 CHKERR pip_energy->loopFiniteElementsEvaluation();
618 double total_energy = 0.0;
623 total_energy = array[
ZERO];
625 MOFEM_LOG_C(
"SELF", Sev::inform,
"Total Energy: %6.15f", total_energy);
640 op_loop_side->getOpPtrVector(), {H1},
"GEOMETRY");
642 auto grad_u_ptr_charge = boost::make_shared<MatrixDouble>();
643 auto e_ptr_charge = boost::make_shared<MatrixDouble>();
645 op_loop_side->getOpPtrVector().push_back(
649 op_loop_side->getOpPtrVector().push_back(
651 auto d_jump = boost::make_shared<MatrixDouble>();
677 double aLpha = array[0];
678 double bEta = array[1];
681 "CHARGE_ELEC_1: %6.15f , CHARGE_ELEC_2: %6.15f",
aLpha,
bEta);
686 double cal_charge_elec1;
687 double cal_charge_elec2;
688 double cal_total_energy;
689 const double *c_ptr, *te_ptr;
696 double ref_charge_elec1;
697 double ref_charge_elec2;
699 double ref_tot_energy;
701 cal_charge_elec1 = c_ptr[0];
702 cal_charge_elec2 = c_ptr[1];
703 cal_total_energy = te_ptr[0];
704 if (std::isnan(cal_charge_elec1) || std::isnan(cal_charge_elec2) ||
705 std::isnan(cal_total_energy)) {
707 "Atom test failed! NaN detected in calculated values.");
713 ref_charge_elec1 = 50.0;
714 ref_charge_elec2 = -50.0;
716 ref_tot_energy = 500.0;
720 ref_charge_elec1 = 10.00968352472943;
721 ref_charge_elec2 = 0.0;
722 ref_tot_energy = 50.5978;
727 "atom test %d does not exist",
atomTest);
731 if (std::abs(ref_charge_elec1 - cal_charge_elec1) >
tol ||
732 std::abs(ref_charge_elec2 - cal_charge_elec2) >
tol ||
733 std::abs(ref_tot_energy - cal_total_energy) >
tol) {
736 "atom test %d failed! Calculated values do not match expected values",
767int main(
int argc,
char *argv[]) {
769 const char param_file[] =
"param_file.petsc";
775 DMType dm_name =
"DMMOFEM";
779 moab::Core mb_instance;
780 moab::Interface &moab = mb_instance;
#define MOFEM_LOG_C(channel, severity, format,...)
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MYPCOMM_INDEX
default communicator number PCOMM
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_ATOM_TEST_INVALID
@ MOFEM_DATA_INCONSISTENCY
#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
constexpr auto domainField
intPostProc< SPACE_DIM >::intEle IntElementForcesAndSourcesCore
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< BASE_DIM, FIELD_DIM > OpBodySourceVectorb
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
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 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
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 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.
SmartPetscObj< KSP > createKSP(SmartPetscObj< DM > dm=nullptr)
Create KSP (linear) solver.
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
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
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.
#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.
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.
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
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)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
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.
FormsIntegrators< DomainEleOp >::Assembly< A >::LinearForm< I >::OpGradTimesTensor< 1, FIELD_DIM, SPACE_DIM > OpGradTimesTensor
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
boost::shared_ptr< ForcesAndSourcesCore > electrodeRhsFe
boost::shared_ptr< ForcesAndSourcesCore > interFaceRhsFe
boost::shared_ptr< std::map< int, BlockData > > intBlockSetsPtr
SmartPetscObj< Vec > petscVec
boost::shared_ptr< DataAtIntegrationPts > commonDataPtr
MoFEM::Interface & mField
MoFEMErrorCode runProgram()
[Get Charges]
MoFEMErrorCode setupProblem()
[Read mesh]
MoFEMErrorCode outputResults()
[Solve system]
MoFEMErrorCode setIntegrationRules()
[Boundary condition]
Electrostatics(MoFEM::Interface &m_field)
MoFEMErrorCode getElectrodeCharge()
[Get Total Energy]
MoFEMErrorCode readMesh()
[Read mesh]
SmartPetscObj< Vec > petscVecEnergy
boost::shared_ptr< std::map< int, BlockData > > permBlockSetsPtr
MoFEMErrorCode assembleSystem()
[Set integration rules]
boost::shared_ptr< std::map< int, BlockData > > electrodeBlockSetsPtr
MoFEMErrorCode getTotalEnergy()
[Output results]
MoFEMErrorCode boundaryCondition()
[Setup problem]
MoFEMErrorCode solveSystem()
[Assemble system]
Add operators pushing bases from local to physical configuration.
Boundary condition manager for finite element problem setup.
Template specialization for scalar field boundary conditions.
virtual int get_comm_size() const =0
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
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.
Class (Function) to enforce essential constrains.
static MoFEMErrorCode addCanonicalAttributeNames(const std::vector< std::string > &names)
Interface for managing meshsets containing materials and boundary conditions.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for double precision scalar field values calculation.
Specialization for MatrixDouble vector field values calculation.
Element used to execute operators on side of the element.
Post post-proc data at points from hash maps.
std::map< std::string, ScalarDataPtr > DataMapVec
std::map< std::string, boost::shared_ptr< MatrixDouble > > DataMapMat
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.
Projection of edge entities with one mid-node on hierarchical basis.
Simple interface for fast problem set-up.
MoFEMErrorCode buildProblem()
Build problem.
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.
MoFEMErrorCode defineFiniteElements()
Define finite elements.
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
MoFEMErrorCode buildFiniteElements()
Build finite elements.
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.
MoFEMErrorCode getOptions()
get options
MoFEMErrorCode getDM(DM *dm)
Get DM.
MoFEMErrorCode buildFields()
Build fields.
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
MoFEMErrorCode defineProblem(const PetscBool is_partitioned=PETSC_TRUE)
define problem
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.
bool & getAddSkeletonFE()
Get the addSkeletonFE flag.
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
const std::string getProblemName() const
Get the Problem Name.
const std::string getDomainFEName() const
Get the Domain FE Name.
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.