6 #ifndef EXECUTABLE_DIMENSION
7 #define EXECUTABLE_DIMENSION 3
11 static char help[] =
"...\n\n";
78 auto get_ents_by_dim = [&](
const auto dim) {
92 auto get_base = [&]() {
93 auto domain_ents = get_ents_by_dim(
SPACE_DIM);
94 if (domain_ents.empty())
112 auto base = get_base();
125 Range mat_electr_ents;
127 if (
bit->getName().compare(0, 12,
"MAT_ELECTRIC") == 0) {
128 const int id =
bit->getMeshsetId();
129 auto &block_data = (*permBlockSetsPtr)[id];
132 bit->getMeshset(),
SPACE_DIM, block_data.domainEnts,
true);
133 mat_electr_ents.merge(block_data.domainEnts);
135 std::vector<double> attributes;
136 bit->getAttributes(attributes);
137 if (attributes.size() < 1) {
139 " At least one permittivity attributes should be given but "
144 block_data.epsPermit = attributes[0];
150 Range int_electr_ents;
152 if (
bit->getName().compare(0, 12,
"INT_ELECTRIC") == 0) {
153 const int id =
bit->getMeshsetId();
154 auto &block_data = (*intBlockSetsPtr)[id];
157 bit->getMeshset(),
SPACE_DIM - 1, block_data.interfaceEnts,
true);
158 int_electr_ents.merge(block_data.interfaceEnts);
160 std::vector<double> attributes;
161 bit->getAttributes(attributes);
162 if (attributes.size() < 1) {
164 "At least one charge attributes should be given but found %d",
169 block_data.chargeDensity = attributes[0];
174 Range electrode_ents;
175 int electrodeCount = 0;
177 if (
bit->getName().compare(0, 9,
"ELECTRODE") == 0) {
178 const int id =
bit->getMeshsetId();
179 auto &block_data = (*electrodeBlockSetsPtr)[id];
183 bit->getMeshset(),
SPACE_DIM - 1, block_data.electrodeEnts,
true);
184 electrode_ents.merge(block_data.electrodeEnts);
186 auto print_range_on_procs = [&](
const std::string &name,
int meshsetId,
187 const Range &range) {
189 << name <<
" in meshID: " <<
id <<
" with range "
190 << block_data.electrodeEnts <<
" on proc ["
194 print_range_on_procs(
bit->getName(),
id, electrode_ents);
195 if (electrodeCount > 2) {
197 "Three or more electrode blocksets found");
218 CHKERR skinner.find_skin(0, mat_electr_ents,
false, skin_tris);
220 ParallelComm *pcomm =
223 CHKERR pcomm->filter_pstatus(skin_tris,
224 PSTATUS_SHARED | PSTATUS_MULTISHARED,
225 PSTATUS_NOT, -1, &proc_skin);
227 proc_skin = skin_tris;
266 DMType dm_name =
"DMMOFEM";
273 CHKERR DMSetType(dm, dm_name);
312 auto rule_lhs = [](
int,
int,
int p) ->
int {
return 2 * p; };
313 auto rule_rhs = [](
int,
int,
int p) ->
int {
return p; };
316 CHKERR pipeline_mng->setDomainLhsIntegrationRule(rule_lhs);
317 CHKERR pipeline_mng->setDomainRhsIntegrationRule(rule_rhs);
330 auto add_base_ops = [&](
auto &pipeline) {
337 add_base_ops(pipeline_mng->getOpDomainLhsPipeline());
343 pipeline_mng->getOpDomainLhsPipeline().push_back(
348 auto set_values_to_bc_dofs = [&](
auto &fe) {
349 auto get_bc_hook = [&]() {
353 fe->preProcessHook = get_bc_hook();
356 auto calculate_residual_from_set_values_on_bc = [&](
auto &pipeline) {
361 auto grad_u_ptr = boost::make_shared<MatrixDouble>();
362 pipeline_mng->getOpDomainRhsPipeline().push_back(
366 add_base_ops(pipeline_mng->getOpDomainRhsPipeline());
371 pipeline_mng->getOpDomainRhsPipeline().push_back(
372 new OpInternal(
domainField, grad_u_ptr, minus_epsilon));
375 set_values_to_bc_dofs(pipeline_mng->getDomainRhsFE());
376 calculate_residual_from_set_values_on_bc(
377 pipeline_mng->getOpDomainRhsPipeline());
381 pipeline_mng->getOpDomainRhsPipeline().push_back(
411 auto ksp_solver = pipeline_mng->
createKSP();
413 boost::shared_ptr<ForcesAndSourcesCore>
null;
417 CHKERR KSPSetFromOptions(ksp_solver);
418 CHKERR KSPSetUp(ksp_solver);
427 CHKERR VecGhostUpdateBegin(
F, INSERT_VALUES, SCATTER_FORWARD);
428 CHKERR VecGhostUpdateEnd(
F, INSERT_VALUES, SCATTER_FORWARD);
431 CHKERR VecNorm(
F, NORM_2, &fnorm);
432 CHKERR PetscPrintf(PETSC_COMM_WORLD,
"F norm = %9.8e\n", fnorm);
435 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
436 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
439 CHKERR VecNorm(
D, NORM_2, &dnorm);
440 CHKERR PetscPrintf(PETSC_COMM_WORLD,
"D norm = %9.8e\n", dnorm);
453 pipeline_mng->getBoundaryLhsFE().reset();
454 pipeline_mng->getBoundaryRhsFE().reset();
455 pipeline_mng->getDomainLhsFE().reset();
456 auto post_proc_fe = boost::make_shared<PostProcEle>(
mField);
457 auto u_ptr = boost::make_shared<VectorDouble>();
458 auto grad_u_ptr = boost::make_shared<MatrixDouble>();
459 auto e_field_ptr = boost::make_shared<MatrixDouble>();
461 auto add_efield_ops = [&](
auto &pipeline) {
473 add_efield_ops(post_proc_fe->getOpPtrVector());
475 auto e_field_times_perm_ptr = boost::make_shared<MatrixDouble>();
476 auto energy_density_ptr = boost::make_shared<VectorDouble>();
478 post_proc_fe->getOpPtrVector().push_back(
481 post_proc_fe->getOpPtrVector().push_back(
486 post_proc_fe->getOpPtrVector().push_back(
new OpPPMap(
487 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
490 {
"ENERGY_DENSITY", energy_density_ptr}},
492 {
"ELECTRIC_FIELD", e_field_ptr},
493 {
"ELECTRIC_DISPLACEMENT", e_field_times_perm_ptr},
501 pipeline_mng->getDomainRhsFE() = post_proc_fe;
502 CHKERR pipeline_mng->loopFiniteElements();
503 CHKERR post_proc_fe->writeFile(
"out.h5m");
506 auto post_proc_skin = boost::make_shared<PostProcFaceEle>(mField);
508 mField, simpleInterface->getDomainFEName(),
SPACE_DIM);
510 add_efield_ops(op_loop_skin->getOpPtrVector());
512 op_loop_skin->getOpPtrVector().push_back(
514 permBlockSetsPtr, commonDataPtr));
515 op_loop_skin->getOpPtrVector().push_back(
517 permBlockSetsPtr, commonDataPtr));
520 post_proc_skin->getOpPtrVector().push_back(op_loop_skin);
522 post_proc_skin->getOpPtrVector().push_back(
new OpPPMap(
523 post_proc_skin->getPostProcMesh(), post_proc_skin->getMapGaussPts(),
525 {
"ENERGY_DENSITY", energy_density_ptr}},
527 {
"ELECTRIC_DISPLACEMENT", e_field_times_perm_ptr}},
532 CHKERR post_proc_skin->writeFile(
"out_skin.h5m");
543 pip_energy->getDomainLhsFE().reset();
544 pip_energy->getBoundaryLhsFE().reset();
545 pip_energy->getBoundaryRhsFE().reset();
546 pip_energy->getOpDomainRhsPipeline().clear();
547 pip_energy->getOpDomainLhsPipeline().clear();
551 boost::shared_ptr<std::map<int, BlockData>> intrnlDomnBlckSetPtr =
552 boost::make_shared<std::map<int, BlockData>>();
553 Range internal_domain;
555 if (
bit->getName().compare(0, 10,
"DOMAIN_INT") == 0) {
556 const int id =
bit->getMeshsetId();
557 auto &block_data = (*intrnlDomnBlckSetPtr)[id];
560 bit->getMeshset(),
SPACE_DIM, block_data.internalDomainEnts,
true);
561 internal_domain.merge(block_data.internalDomainEnts);
569 pip_energy->getOpDomainRhsPipeline(), {H1});
572 auto grad_u_ptr = boost::make_shared<MatrixDouble>();
573 auto e_field_ptr = boost::make_shared<MatrixDouble>();
575 pip_energy->getOpDomainRhsPipeline().push_back(
577 pip_energy->getOpDomainRhsPipeline().push_back(
582 pip_energy->getOpDomainRhsPipeline().push_back(
586 pip_energy->loopFiniteElements();
590 double total_energy = 0.0;
595 total_energy = array[
ZERO];
597 MOFEM_LOG_C(
"SELF", Sev::inform,
"Total Energy: %6.15f", total_energy);
612 op_loop_side->getOpPtrVector(), {H1});
614 auto grad_u_ptr_charge = boost::make_shared<MatrixDouble>();
615 auto e_ptr_charge = boost::make_shared<MatrixDouble>();
617 op_loop_side->getOpPtrVector().push_back(
621 op_loop_side->getOpPtrVector().push_back(
623 auto d_jump = boost::make_shared<MatrixDouble>();
647 double aLpha = array[0];
648 double bEta = array[1];
651 "CHARGE_ELEC_1: %6.15f , CHARGE_ELEC_2: %6.15f",
aLpha,
bEta);
657 double cal_charge_elec1;
658 double cal_charge_elec2;
659 double cal_total_energy;
660 const double *c_ptr, *te_ptr;
667 double ref_charge_elec1 = 50.0;
668 double ref_charge_elec2 = -50.0;
670 double ref_tot_energy = 500.0;
674 cal_charge_elec1 = c_ptr[0];
675 cal_charge_elec2 = c_ptr[1];
676 cal_total_energy = te_ptr[0];
680 "atom test %d does not exist",
atomTest);
684 if (std::abs(ref_charge_elec1 - cal_charge_elec1) > 1e-10 ||
685 std::abs(ref_charge_elec2 - cal_charge_elec2) > 1e-10 ||
686 std::abs(ref_tot_energy - cal_total_energy) > 1e-10) {
689 "atom test %d failed! Calculated values do not match expected values",
720 int main(
int argc,
char *argv[]) {
722 const char param_file[] =
"param_file.petsc";
728 DMType dm_name =
"DMMOFEM";