v0.14.0
electrostatics.cpp
Go to the documentation of this file.
1 /**
2  * @file Electrostatics.cpp
3  * \example Electrostatics.cpp
4  * */
5 
6 #ifndef EXECUTABLE_DIMENSION
7 #define EXECUTABLE_DIMENSION 3
8 #endif
9 
10 #include <electrostatics.hpp>
11 static char help[] = "...\n\n";
13 public:
15 
16  // Declaration of the main function to run analysis
18 
19 private:
20  // Declaration of other main functions called in runProgram()
30 
31  int oRder = 2; // default order
32  int geomOrder = 1; // default gemoetric order
35  std::string domainField;
36  boost::shared_ptr<std::map<int, BlockData>> permBlockSetsPtr;
37  boost::shared_ptr<std::map<int, BlockData>> intBlockSetsPtr;
38  boost::shared_ptr<std::map<int, BlockData>> electrodeBlockSetsPtr;
39  boost::shared_ptr<DataAtIntegrationPts> commonDataPtr;
40 
41  boost::shared_ptr<ForcesAndSourcesCore> interFaceRhsFe;
42  boost::shared_ptr<ForcesAndSourcesCore> electrodeRhsFe;
43 
44  double aLpha = 0.0; // declaration for total charge on first electrode
45  double bEta = 0.0; // declaration for total charge on second electrode
46  SmartPetscObj<Vec> petscVec; // petsc vector for the charge solution
47  SmartPetscObj<Vec> petscVecEnergy; // petsc vector for the energy solution
48  PetscBool out_skin = PETSC_FALSE; //
49  PetscBool is_partitioned = PETSC_FALSE;
50  enum VecElements { ZERO = 0, ONE = 1, LAST_ELEMENT };
51  int atomTest = 0;
52 };
53 
55  : domainField("POTENTIAL"), mField(m_field) {}
56 
57 //! [Read mesh]
62 
64  true; // create lower dimensional element to ensure sharing of partitioed
65  // entities at the boundaries.
68 }
69 //! [Read mesh]
70 
71 //! [Setup problem]
74 
75  Range domain_ents;
76  CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, domain_ents,
77  true);
78  auto get_ents_by_dim = [&](const auto dim) {
79  if (dim == SPACE_DIM) {
80  return domain_ents;
81  } else {
82  Range ents;
83  if (dim == 0)
84  CHKERR mField.get_moab().get_connectivity(domain_ents, ents, true);
85  else
86  CHKERR mField.get_moab().get_entities_by_dimension(0, dim, ents, true);
87  return ents;
88  }
89  };
90 
91  // Select base for the field based on the element type
92  auto get_base = [&]() {
93  auto domain_ents = get_ents_by_dim(SPACE_DIM);
94  if (domain_ents.empty())
95  CHK_THROW_MESSAGE(MOFEM_NOT_FOUND, "Empty mesh");
96  const auto type = type_from_handle(domain_ents[0]);
97  switch (type) {
98  case MBQUAD:
99  return DEMKOWICZ_JACOBI_BASE;
100  case MBHEX:
101  return DEMKOWICZ_JACOBI_BASE;
102  case MBTRI:
104  case MBTET:
106  default:
107  CHK_THROW_MESSAGE(MOFEM_NOT_FOUND, "Element type is not handled");
108  }
109  return NOBASE;
110  };
111 
112  auto base = get_base();
115 
116  CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-order", &oRder, PETSC_NULL);
117 
118  CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-geom_order", &geomOrder,
119  PETSC_NULL);
120 
121  CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-atom_test", &atomTest,
122  PETSC_NULL);
124  CHKERR simpleInterface->addDataField("GEOMETRY", H1, base, SPACE_DIM);
126 
127  auto project_ho_geometry = [&]() {
128  Projection10NodeCoordsOnField ent_method(mField, "GEOMETRY");
129  return mField.loop_dofs("GEOMETRY", ent_method);
130  };
131 
133  CHKERR project_ho_geometry();
134 
135  commonDataPtr = boost::make_shared<DataAtIntegrationPts>(mField);
136 
137  // gets the map of the permittivity attributes and the block sets
138  permBlockSetsPtr = boost::make_shared<std::map<int, BlockData>>();
139  Range mat_electr_ents; // range of entities with the permittivity
141  if (bit->getName().compare(0, 12, "MAT_ELECTRIC") == 0) {
142  const int id = bit->getMeshsetId();
143  auto &block_data = (*permBlockSetsPtr)[id];
144 
145  CHKERR mField.get_moab().get_entities_by_dimension(
146  bit->getMeshset(), SPACE_DIM, block_data.domainEnts, true);
147  mat_electr_ents.merge(block_data.domainEnts);
148 
149  std::vector<double> attributes;
150  bit->getAttributes(attributes);
151  if (attributes.size() < 1) {
152  SETERRQ1(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
153  " At least one permittivity attributes should be given but "
154  "found %d",
155  attributes.size());
156  }
157  block_data.iD = id; // id of the block
158  block_data.epsPermit = attributes[0]; // permittivity value of the block
159  }
160  }
161 
162  // gets the map of the charge attributes and the block sets
163  intBlockSetsPtr = boost::make_shared<std::map<int, BlockData>>();
164  Range int_electr_ents; // range of entities with the charge
166  if (bit->getName().compare(0, 12, "INT_ELECTRIC") == 0) {
167  const int id = bit->getMeshsetId();
168  auto &block_data = (*intBlockSetsPtr)[id];
169 
170  CHKERR mField.get_moab().get_entities_by_dimension(
171  bit->getMeshset(), SPACE_DIM - 1, block_data.interfaceEnts, true);
172  int_electr_ents.merge(block_data.interfaceEnts);
173 
174  std::vector<double> attributes;
175  bit->getAttributes(attributes);
176  if (attributes.size() < 1) {
177  SETERRQ1(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
178  "At least one charge attributes should be given but found %d",
179  attributes.size());
180  }
181 
182  block_data.iD = id; // id-> block ID
183  block_data.chargeDensity = attributes[0]; // block charge attribute
184  }
185  }
186  // gets the map of the electrode entity range in the block sets
187  electrodeBlockSetsPtr = boost::make_shared<std::map<int, BlockData>>();
188  Range electrode_ents; // range of entities with the electrode
189  int electrodeCount = 0;
191  if (bit->getName().compare(0, 9, "ELECTRODE") == 0) {
192  const int id = bit->getMeshsetId();
193  auto &block_data = (*electrodeBlockSetsPtr)[id];
194  ++electrodeCount;
195 
196  CHKERR mField.get_moab().get_entities_by_dimension(
197  bit->getMeshset(), SPACE_DIM - 1, block_data.electrodeEnts, true);
198  electrode_ents.merge(block_data.electrodeEnts);
199 
200 
201  if (electrodeCount > 2) {
202  SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
203  "Three or more electrode blocksets found");
204  ;
205  }
206  }
207  }
208 
209  // sync entities
210  CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
211  mat_electr_ents);
212  CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
213  int_electr_ents);
214  CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
215  electrode_ents);
216 
217  CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-out_skin", &out_skin,
218  PETSC_NULL);
219  CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-is_partitioned", &is_partitioned,
220  PETSC_NULL);
221  // get the skin entities
222  Skinner skinner(&mField.get_moab());
223  Range skin_tris;
224  CHKERR skinner.find_skin(0, mat_electr_ents, false, skin_tris);
225  Range proc_skin;
226  ParallelComm *pcomm =
227  ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
228  if (is_partitioned) {
229  CHKERR pcomm->filter_pstatus(skin_tris,
230  PSTATUS_SHARED | PSTATUS_MULTISHARED,
231  PSTATUS_NOT, -1, &proc_skin);
232  } else {
233  proc_skin = skin_tris;
234  }
235  // add the skin entities to the field
238  "SKIN");
242  // add the interface entities to the field
243  CHKERR mField.add_finite_element("INTERFACE");
247  CHKERR mField.modify_finite_element_add_field_data("INTERFACE", "GEOMETRY");
248 
250  SPACE_DIM - 1, "INTERFACE");
251  // add the electrode entities to the field
252  CHKERR mField.add_finite_element("ELECTRODE");
256  CHKERR mField.modify_finite_element_add_field_data("ELECTRODE", "GEOMETRY");
257 
259  "ELECTRODE");
260 
261  // sync field entities
262  mField.getInterface<CommInterface>()->synchroniseFieldEntities(domainField);
263  mField.getInterface<CommInterface>()->synchroniseFieldEntities("GEOMETRY");
265  CHKERR simpleInterface->defineProblem(PETSC_TRUE);
270  CHKERR mField.build_finite_elements("INTERFACE");
271  CHKERR mField.build_finite_elements("ELECTRODE");
272 
276 
277  DMType dm_name = "DMMOFEM";
278  CHKERR DMRegister_MoFEM(dm_name);
279 
281  dm = createDM(mField.get_comm(), dm_name);
282 
283  // create dm instance
284  CHKERR DMSetType(dm, dm_name);
285 
287 
288  // initialise petsc vector for required processor
289  int local_size;
290  if (mField.get_comm_rank() == 0) // get_comm_rank() gets processor number
291 
292  local_size = LAST_ELEMENT; // last element gives size of vector
293 
294  else
295  // other processors (e.g. 1, 2, 3, etc.)
296  local_size = 0; // local size of vector is zero on other processors
297 
301 }
302 //! [Setup problem]
303 
304 //! [Boundary condition]
307 
308  auto bc_mng = mField.getInterface<BcManager>();
309 
310  // Remove_BCs_from_blockset name "BOUNDARY_CONDITION";
311  CHKERR bc_mng->removeBlockDOFsOnEntities<BcScalarMeshsetType<BLOCKSET>>(
312  simpleInterface->getProblemName(), "BOUNDARY_CONDITION",
313  std::string(domainField), true);
314 
316 }
317 //! [Boundary condition]
318 
319 //! [Set integration rules]
322 
323  auto rule_lhs = [this](int, int, int p) -> int { return 2 * p + geomOrder -1; };
324  auto rule_rhs = [this](int, int, int p) -> int { return 2 * p + geomOrder -1; };
325 
326  auto pipeline_mng = mField.getInterface<PipelineManager>();
327  CHKERR pipeline_mng->setDomainLhsIntegrationRule(rule_lhs);
328  CHKERR pipeline_mng->setDomainRhsIntegrationRule(rule_rhs);
329 
331 }
332 //! [Set integration rules]
333 
334 //! [Assemble system]
337 
338  auto pipeline_mng = mField.getInterface<PipelineManager>();
339  commonDataPtr = boost::make_shared<DataAtIntegrationPts>(mField);
340 
341  auto add_domain_base_ops = [&](auto &pipeline) {
343  "GEOMETRY");
344 
345  pipeline.push_back(
347  };
348 
349  add_domain_base_ops(pipeline_mng->getOpDomainLhsPipeline());
350  auto epsilon = [&](const double, const double, const double) {
351  return commonDataPtr->blockPermittivity;
352  };
353 
354  { // Push operators to the Pipeline that is responsible for calculating LHS
355  pipeline_mng->getOpDomainLhsPipeline().push_back(
357  }
358 
359  { // Push operators to the Pipeline that is responsible for calculating RHS
360  auto set_values_to_bc_dofs = [&](auto &fe) {
361  auto get_bc_hook = [&]() {
363  return hook;
364  };
365  fe->preProcessHook = get_bc_hook();
366  };
367  // Set essential BC
368  auto calculate_residual_from_set_values_on_bc = [&](auto &pipeline) {
369  using OpInternal =
372 
373  add_domain_base_ops(pipeline_mng->getOpDomainRhsPipeline());
374 
375  auto grad_u_ptr = boost::make_shared<MatrixDouble>();
376  pipeline_mng->getOpDomainRhsPipeline().push_back(
378  grad_u_ptr));
379  auto minus_epsilon = [&](double, double, double) constexpr {
380  return -commonDataPtr->blockPermittivity;
381  };
382  pipeline_mng->getOpDomainRhsPipeline().push_back(
383  new OpInternal(domainField, grad_u_ptr, minus_epsilon));
384  };
385 
386  set_values_to_bc_dofs(pipeline_mng->getDomainRhsFE());
387  calculate_residual_from_set_values_on_bc(
388  pipeline_mng->getOpDomainRhsPipeline());
389 
390  auto bodySourceTerm = [&](const double, const double, const double) {
391  return bodySource;
392  };
393  pipeline_mng->getOpDomainRhsPipeline().push_back(
394  new OpBodySourceVectorb(domainField, bodySourceTerm));
395  }
396 
397  interFaceRhsFe = boost::shared_ptr<ForcesAndSourcesCore>(
399  interFaceRhsFe->getRuleHook = [this](int, int, int p) {
400  return 2 * p + geomOrder -1;
401  };
402 
403  {
404 
406  interFaceRhsFe->getOpPtrVector(), {NOSPACE}, "GEOMETRY");
407 
408  interFaceRhsFe->getOpPtrVector().push_back(
410 
411  auto sIgma = [&](const double, const double, const double) {
412  return commonDataPtr->blockChrgDens;
413  };
414 
415  interFaceRhsFe->getOpPtrVector().push_back(
416  new OpInterfaceRhsVectorF(domainField, sIgma));
417  }
418 
420 }
421 //! [Assemble system]
422 
423 //! [Solve system]
426 
427  auto pipeline_mng = mField.getInterface<PipelineManager>();
428 
429  auto ksp_solver = pipeline_mng->createKSP();
430 
431  boost::shared_ptr<ForcesAndSourcesCore> null; ///< Null element does
432  DM dm;
434 
435  CHKERR DMMoFEMKSPSetComputeRHS(dm, "INTERFACE", interFaceRhsFe, null, null);
436 
437  CHKERR KSPSetFromOptions(ksp_solver);
438 
439  // Create RHS and solution vectors
440  auto F = createDMVector(dm);
441  auto D = vectorDuplicate(F);
442  // Solve the system
443  CHKERR KSPSetUp(ksp_solver);
444  CHKERR KSPSolve(ksp_solver, F, D);
445 
446  CHKERR VecGhostUpdateBegin(F, INSERT_VALUES, SCATTER_FORWARD);
447  CHKERR VecGhostUpdateEnd(F, INSERT_VALUES, SCATTER_FORWARD);
448 
449  double fnorm;
450  CHKERR VecNorm(F, NORM_2, &fnorm);
451  CHKERR PetscPrintf(PETSC_COMM_WORLD, "F norm = %9.8e\n", fnorm);
452 
453  // Scatter result data on the mesh
454  CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
455  CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
456 
457  double dnorm;
458  CHKERR VecNorm(D, NORM_2, &dnorm);
459  CHKERR PetscPrintf(PETSC_COMM_WORLD, "D norm = %9.8e\n", dnorm);
460 
461  CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_REVERSE);
462 
464 }
465 //! [Solve system]
466 
467 //! [Output results]
470  auto pipeline_mng = mField.getInterface<PipelineManager>();
471  pipeline_mng->getDomainRhsFE().reset();
472  pipeline_mng->getBoundaryLhsFE().reset();
473  pipeline_mng->getBoundaryRhsFE().reset(); //
474  pipeline_mng->getDomainLhsFE().reset();
475  auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
476 
477  // lamda function to calculate electric field
478  auto calculate_e_field = [&](auto &pipeline) {
479  auto u_ptr = boost::make_shared<VectorDouble>();
480  auto x_ptr = boost::make_shared<MatrixDouble>();
481  auto grad_u_ptr = boost::make_shared<MatrixDouble>();
482  auto e_field_ptr = boost::make_shared<MatrixDouble>();
483  // add higher order operator
485  "GEOMETRY");
486  // calculate field values
487  pipeline.push_back(new OpCalculateScalarFieldValues(domainField, u_ptr));
488  pipeline.push_back(
489  new OpCalculateVectorFieldValues<SPACE_DIM>("GEOMETRY", x_ptr));
490 
491  // calculate gradient
492  pipeline.push_back(
494  // calculate electric field
495  pipeline.push_back(new OpElectricField(e_field_ptr, grad_u_ptr));
496  return boost::make_tuple(u_ptr, e_field_ptr, x_ptr);
497  };
498 
499  auto [u_ptr, e_field_ptr, x_ptr] =
500  calculate_e_field(post_proc_fe->getOpPtrVector());
501 
502  auto e_field_times_perm_ptr = boost::make_shared<MatrixDouble>();
503  auto energy_density_ptr = boost::make_shared<VectorDouble>();
504 
505  post_proc_fe->getOpPtrVector().push_back(
506  new OpGradTimesPerm(domainField, e_field_ptr, e_field_times_perm_ptr,
508  post_proc_fe->getOpPtrVector().push_back(
509  new OpEnergyDensity(domainField, e_field_ptr, energy_density_ptr,
511 
513  post_proc_fe->getOpPtrVector().push_back(new OpPPMap(
514  post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
515 
516  OpPPMap::DataMapVec{{"POTENTIAL", u_ptr},
517  {"ENERGY_DENSITY", energy_density_ptr}},
519  {"GEOMETRY", x_ptr},
520  {"ELECTRIC_FIELD", e_field_ptr},
521  {"ELECTRIC_DISPLACEMENT", e_field_times_perm_ptr},
522  },
524 
526 
527  );
528 
529  pipeline_mng->getDomainRhsFE() = post_proc_fe;
530  CHKERR pipeline_mng->loopFiniteElements();
531  CHKERR post_proc_fe->writeFile("out.h5m");
532 
533  if (out_skin && SPACE_DIM == 3) {
534 
535  auto post_proc_skin = boost::make_shared<PostProcFaceEle>(mField);
536  auto op_loop_skin = new OpLoopSide<SideEle>(
537  mField, simpleInterface->getDomainFEName(), SPACE_DIM);
538 
539  auto [u_ptr, e_field_ptr, x_ptr] =
540  calculate_e_field(op_loop_skin->getOpPtrVector());
541 
542  op_loop_skin->getOpPtrVector().push_back(
543  new OpGradTimesPerm(domainField, e_field_ptr, e_field_times_perm_ptr,
544  permBlockSetsPtr, commonDataPtr));
545  op_loop_skin->getOpPtrVector().push_back(
546  new OpEnergyDensity(domainField, e_field_ptr, energy_density_ptr,
547  permBlockSetsPtr, commonDataPtr));
548 
549  // push op to boundary element
550  post_proc_skin->getOpPtrVector().push_back(op_loop_skin);
551 
552  post_proc_skin->getOpPtrVector().push_back(new OpPPMap(
553  post_proc_skin->getPostProcMesh(), post_proc_skin->getMapGaussPts(),
554  OpPPMap::DataMapVec{{"POTENTIAL", u_ptr},
555  {"ENERGY_DENSITY", energy_density_ptr}},
556  OpPPMap::DataMapMat{{"ELECTRIC_FIELD", e_field_ptr},
557  {"GEOMETRY", x_ptr},
558  {"ELECTRIC_DISPLACEMENT", e_field_times_perm_ptr}},
560 
561  CHKERR DMoFEMLoopFiniteElements(simpleInterface->getDM(), "SKIN",
562  post_proc_skin);
563  CHKERR post_proc_skin->writeFile("out_skin.h5m");
564  }
566 }
567 //! [Output results]
568 
569 //! [Get Total Energy]
572  auto pip_energy = mField.getInterface<PipelineManager>();
573  pip_energy->getDomainRhsFE().reset();
574  pip_energy->getDomainLhsFE().reset();
575  pip_energy->getBoundaryLhsFE().reset();
576  pip_energy->getBoundaryRhsFE().reset();
577  pip_energy->getOpDomainRhsPipeline().clear();
578  pip_energy->getOpDomainLhsPipeline().clear();
579 
580  // gets the map of the internal domain entity range to get the total energy
581 
582  boost::shared_ptr<std::map<int, BlockData>> intrnlDomnBlckSetPtr =
583  boost::make_shared<std::map<int, BlockData>>();
584  Range internal_domain; // range of entities marked the internal domain
586  if (bit->getName().compare(0, 10, "DOMAIN_INT") == 0) {
587  const int id = bit->getMeshsetId();
588  auto &block_data = (*intrnlDomnBlckSetPtr)[id];
589 
590  CHKERR mField.get_moab().get_entities_by_dimension(
591  bit->getMeshset(), SPACE_DIM, block_data.internalDomainEnts, true);
592  internal_domain.merge(block_data.internalDomainEnts);
593  block_data.iD = id;
594  }
595  }
596  CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
597  internal_domain);
598 
600  pip_energy->getOpDomainRhsPipeline(), {H1}, "GEOMETRY");
601 
602  auto grad_u_ptr = boost::make_shared<MatrixDouble>();
603  auto e_field_ptr = boost::make_shared<MatrixDouble>();
604 
605  pip_energy->getOpDomainRhsPipeline().push_back(
607  pip_energy->getOpDomainRhsPipeline().push_back(
608  new OpElectricField(e_field_ptr, grad_u_ptr));
609 
610  commonDataPtr = boost::make_shared<DataAtIntegrationPts>(mField);
611 
612  pip_energy->getOpDomainRhsPipeline().push_back(
613  new OpTotalEnergy(domainField, grad_u_ptr, permBlockSetsPtr,
614  intrnlDomnBlckSetPtr, commonDataPtr, petscVecEnergy));
615 
616  pip_energy->loopFiniteElements();
617  CHKERR VecAssemblyBegin(petscVecEnergy);
618  CHKERR VecAssemblyEnd(petscVecEnergy);
619 
620  double total_energy = 0.0; // declaration for total energy
621  if (!mField.get_comm_rank()) {
622  const double *array;
623 
624  CHKERR VecGetArrayRead(petscVecEnergy, &array);
625  total_energy = array[ZERO];
626  MOFEM_LOG_CHANNEL("SELF");
627  MOFEM_LOG_C("SELF", Sev::inform, "Total Energy: %6.15f", total_energy);
628  CHKERR VecRestoreArrayRead(petscVecEnergy, &array);
629  }
630 
632 }
633 //! [Get Total Energy]
634 
635 //! [Get Charges]
638  auto op_loop_side = new OpLoopSide<SideEle>(
640 
642  op_loop_side->getOpPtrVector(), {H1}, "GEOMETRY");
643 
644  auto grad_u_ptr_charge = boost::make_shared<MatrixDouble>();
645  auto e_ptr_charge = boost::make_shared<MatrixDouble>();
646 
647  op_loop_side->getOpPtrVector().push_back(
649  grad_u_ptr_charge));
650 
651  op_loop_side->getOpPtrVector().push_back(
652  new OpElectricField(e_ptr_charge, grad_u_ptr_charge));
653  auto d_jump = boost::make_shared<MatrixDouble>();
654  op_loop_side->getOpPtrVector().push_back(new OpElectricDispJump<SPACE_DIM>(
655  domainField, e_ptr_charge, d_jump, commonDataPtr, permBlockSetsPtr));
656 
657  electrodeRhsFe = boost::shared_ptr<ForcesAndSourcesCore>(
659  electrodeRhsFe->getRuleHook = [this](int, int, int p) {
660  return 2 * p + geomOrder -1;
661  };
662 
663  // push all the operators in on the side to the electrodeRhsFe
664  electrodeRhsFe->getOpPtrVector().push_back(op_loop_side);
665 
666  electrodeRhsFe->getOpPtrVector().push_back(new OpElectrodeCharge<SPACE_DIM>(
668  CHKERR VecZeroEntries(petscVec);
670  "ELECTRODE", electrodeRhsFe, 0,
672  CHKERR VecAssemblyBegin(petscVec);
673  CHKERR VecAssemblyEnd(petscVec);
674 
675  if (!mField.get_comm_rank()) {
676  const double *array;
677 
678  CHKERR(VecGetArrayRead(petscVec, &array));
679  double aLpha = array[0]; // Use explicit index instead of ZERO
680  double bEta = array[1]; // Use explicit index instead of ONE
681  MOFEM_LOG_CHANNEL("SELF");
682  MOFEM_LOG_C("SELF", Sev::inform,
683  "CHARGE_ELEC_1: %6.15f , CHARGE_ELEC_2: %6.15f", aLpha, bEta);
684 
685  CHKERR(VecRestoreArrayRead(petscVec, &array));
686  }
687  if (atomTest && !mField.get_comm_rank()) {
688  double cal_charge_elec1;
689  double cal_charge_elec2;
690  double cal_total_energy;
691  const double *c_ptr, *te_ptr;
692 
693  // Get a pointer to the PETSc vector data
694  CHKERR(VecGetArrayRead(petscVec, &c_ptr));
695  CHKERR(VecGetArrayRead(petscVecEnergy, &te_ptr));
696 
697  // Expected charges at the electrodes
698  double ref_charge_elec1;
699  double ref_charge_elec2;
700  // Expected total energy of the system
701  double ref_tot_energy;
702  double tol;
703  cal_charge_elec1 = c_ptr[0]; // Read charge at the first electrode
704  cal_charge_elec2 = c_ptr[1]; // Read charge at the second electrode
705  cal_total_energy = te_ptr[0]; // Read total energy of the system
706  if (std::isnan(cal_charge_elec1) || std::isnan(cal_charge_elec2) ||
707  std::isnan(cal_total_energy)) {
708  SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
709  "Atom test failed! NaN detected in calculated values.");
710  }
711  switch (atomTest) {
712  case 1: // 2D & 3D test
713  // Expected charges at the electrodes
714  ref_charge_elec1 = 50.0;
715  ref_charge_elec2 = -50.0;
716  // Expected total energy of the system
717  ref_tot_energy = 500.0;
718  tol = 1e-10;
719  break;
720  case 2: // wavy 3D test
721  ref_charge_elec1 = 10.00968352472943;
722  ref_charge_elec2 = 0.0; // no electrode
723  ref_tot_energy = 50.5978;
724  tol = 1e-4;
725  break;
726  default:
727  SETERRQ1(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
728  "atom test %d does not exist", atomTest);
729  }
730 
731  // Validate the results
732  if (std::abs(ref_charge_elec1 - cal_charge_elec1) > tol ||
733  std::abs(ref_charge_elec2 - cal_charge_elec2) > tol ||
734  std::abs(ref_tot_energy - cal_total_energy) > tol) {
735  SETERRQ1(
736  PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
737  "atom test %d failed! Calculated values do not match expected values",
738  atomTest);
739  }
740 
741  CHKERR(VecRestoreArrayRead(petscVec,
742  &c_ptr)); // Restore the PETSc vector array
743  CHKERR(VecRestoreArrayRead(petscVecEnergy, &te_ptr));
744  }
745 
747 }
748 //! [Get Charges]
749 
750 //! [Run program]
753 
754  CHKERR readMesh();
764 }
765 //! [Run program]
766 
767 //! [Main]
768 int main(int argc, char *argv[]) {
769  // Initialisation of MoFEM/PETSc and MOAB data structures
770  const char param_file[] = "param_file.petsc";
771  MoFEM::Core::Initialize(&argc, &argv, param_file, help);
772 
773  // Error handling
774  try {
775  // Register MoFEM discrete manager in PETSc
776  DMType dm_name = "DMMOFEM";
777  CHKERR DMRegister_MoFEM(dm_name);
778 
779  // Create MOAB instance
780  moab::Core mb_instance; // mesh database
781  moab::Interface &moab = mb_instance; // mesh database interface
782 
783  // Create MoFEM instance
784  MoFEM::Core core(moab); // finite element database
785  MoFEM::Interface &m_field = core; // finite element interface
786 
787  // Run the main analysis
788  Electrostatics Electrostatics_problem(m_field);
789  CHKERR Electrostatics_problem.runProgram();
790  }
791  CATCH_ERRORS;
792 
793  // Finish work: cleaning memory, getting statistics, etc.
795 
796  return 0;
797 }
798 //! [Main]
MoFEM::UnknownInterface::getInterface
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Definition: UnknownInterface.hpp:93
Electrostatics::readMesh
MoFEMErrorCode readMesh()
[Read mesh]
Definition: electrostatics.cpp:58
MoFEM::PipelineManager::getDomainRhsFE
boost::shared_ptr< FEMethod > & getDomainRhsFE()
Definition: PipelineManager.hpp:455
MYPCOMM_INDEX
#define MYPCOMM_INDEX
default communicator number PCOMM
Definition: definitions.h:228
MoFEM::CoreInterface::loop_dofs
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.
MoFEM::CoreTmp< 0 >
Core (interface) class.
Definition: Core.hpp:82
H1
@ H1
continuous field
Definition: definitions.h:85
MoFEM::DMMoFEMKSPSetComputeRHS
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:637
MOFEM_LOG_CHANNEL
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
Definition: LogManager.hpp:284
Electrostatics::VecElements
VecElements
Definition: electrostatics.cpp:50
Electrostatics::atomTest
int atomTest
Definition: electrostatics.cpp:51
MoFEM::OpPostProcMapInMoab::DataMapVec
std::map< std::string, boost::shared_ptr< VectorDouble > > DataMapVec
Definition: PostProcBrokenMeshInMoabBase.hpp:700
OpBodySourceVectorb
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< BASE_DIM, FIELD_DIM > OpBodySourceVectorb
Definition: electrostatics.hpp:45
MoFEM::CoreInterface::get_comm
virtual MPI_Comm & get_comm() const =0
MoFEM::CoreInterface::modify_finite_element_add_field_row
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
NOBASE
@ NOBASE
Definition: definitions.h:59
CHK_THROW_MESSAGE
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
Definition: definitions.h:609
IntElementForcesAndSourcesCore
intPostProc< SPACE_DIM >::intEle IntElementForcesAndSourcesCore
Definition: electrostatics.hpp:35
Electrostatics::out_skin
PetscBool out_skin
Definition: electrostatics.cpp:48
MoFEM::Simple::buildProblem
MoFEMErrorCode buildProblem()
Build problem.
Definition: Simple.cpp:751
MoFEM::Exceptions::MoFEMErrorCode
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
MoFEM::Simple::addDataField
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 field on domain.
Definition: Simple.cpp:396
OpInterfaceRhsVectorF
FormsIntegrators< IntEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< BASE_DIM, FIELD_DIM > OpInterfaceRhsVectorF
Definition: electrostatics.hpp:43
MoFEM::OpCalculateVectorFieldValues
Get values at integration pts for tensor filed rank 1, i.e. vector field.
Definition: UserDataOperators.hpp:466
OpElectrodeCharge
Definition: electrostatics.hpp:357
MoFEM::CoreInterface::get_comm_rank
virtual int get_comm_rank() const =0
domainField
constexpr auto domainField
Definition: electrostatics.hpp:7
MoFEM::Simple::loadFile
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
Definition: Simple.cpp:194
MoFEM::PETSC
@ PETSC
Definition: FormsIntegrators.hpp:105
MoFEM::PipelineManager
PipelineManager interface.
Definition: PipelineManager.hpp:24
Electrostatics::commonDataPtr
boost::shared_ptr< DataAtIntegrationPts > commonDataPtr
Definition: electrostatics.cpp:39
Electrostatics::permBlockSetsPtr
boost::shared_ptr< std::map< int, BlockData > > permBlockSetsPtr
Definition: electrostatics.cpp:36
MoFEM::DMoFEMMeshToLocalVector
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
MoFEM::Projection10NodeCoordsOnField
Projection of edge entities with one mid-node on hierarchical basis.
Definition: Projection10NodeCoordsOnField.hpp:24
Electrostatics::outputResults
MoFEMErrorCode outputResults()
[Solve system]
Definition: electrostatics.cpp:468
MoFEM::CoreTmp< 0 >::Finalize
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition: Core.cpp:112
Electrostatics::bEta
double bEta
Definition: electrostatics.cpp:45
Electrostatics::petscVecEnergy
SmartPetscObj< Vec > petscVecEnergy
Definition: electrostatics.cpp:47
MoFEM::Simple
Simple interface for fast problem set-up.
Definition: Simple.hpp:27
MoFEM::DMMoFEMAddElement
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
Definition: DMMoFEM.cpp:497
help
static char help[]
Definition: electrostatics.cpp:11
Electrostatics::getTotalEnergy
MoFEMErrorCode getTotalEnergy()
[Output results]
Definition: electrostatics.cpp:570
MoFEM::DeprecatedCoreInterface
Deprecated interface functions.
Definition: DeprecatedCoreInterface.hpp:16
MoFEM::OpCalculateScalarFieldGradient
Get field gradients at integration pts for scalar filed rank 0, i.e. vector field.
Definition: UserDataOperators.hpp:1293
MoFEM::Interface
DeprecatedCoreInterface Interface
Definition: Interface.hpp:2010
MoFEM::Simple::getOptions
MoFEMErrorCode getOptions()
get options
Definition: Simple.cpp:180
OpElectricDispJump
Definition: electrostatics.hpp:300
MoFEM::Simple::getAddSkeletonFE
bool & getAddSkeletonFE()
Get the addSkeletonFE.
Definition: Simple.hpp:487
MoFEM::Simple::getDM
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition: Simple.cpp:829
CHKERR
#define CHKERR
Inline error check.
Definition: definitions.h:548
Electrostatics::mField
MoFEM::Interface & mField
Definition: electrostatics.cpp:33
MoFEM::createDMVector
auto createDMVector(DM dm)
Get smart vector from DM.
Definition: DMMoFEM.hpp:1099
MoFEM::CoreInterface::add_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
electrostatics.hpp
bodySource
const double bodySource
Definition: electrostatics.hpp:11
MoFEM::CoreInterface::get_moab
virtual moab::Interface & get_moab()=0
OpTotalEnergy
Definition: electrostatics.hpp:135
Electrostatics::domainField
std::string domainField
Definition: electrostatics.cpp:35
MoFEM::DMoFEMLoopFiniteElementsUpAndLowRank
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:567
MoFEM::CoreInterface::modify_finite_element_add_field_col
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
Electrostatics::boundaryCondition
MoFEMErrorCode boundaryCondition()
[Setup problem]
Definition: electrostatics.cpp:305
SPACE_DIM
constexpr int SPACE_DIM
Definition: child_and_parent.cpp:16
Electrostatics::electrodeRhsFe
boost::shared_ptr< ForcesAndSourcesCore > electrodeRhsFe
Definition: electrostatics.cpp:42
MoFEM::createDM
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
Definition: PetscSmartObj.hpp:141
OpBlockChargeDensity
Definition: electrostatics.hpp:74
MoFEM::BcManager
Simple interface for fast problem set-up.
Definition: BcManager.hpp:25
Electrostatics::oRder
int oRder
Definition: electrostatics.cpp:31
MoFEM::CoreInterface::build_finite_elements
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
MOFEM_LOG_C
#define MOFEM_LOG_C(channel, severity, format,...)
Definition: LogManager.hpp:311
double
bit
auto bit
set bit
Definition: hanging_node_approx.cpp:75
convert.type
type
Definition: convert.py:64
MoFEM::FormsIntegrators::Assembly
Assembly methods.
Definition: FormsIntegrators.hpp:317
OpPPMap
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
Definition: photon_diffusion.cpp:29
MoFEM::BcScalarMeshsetType
Definition: BcManager.hpp:15
OpDomainLhsMatrixK
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradGrad< BASE_DIM, FIELD_DIM, SPACE_DIM > OpDomainLhsMatrixK
Definition: electrostatics.hpp:40
MoFEM::OpCalculateScalarFieldValues
Get value at integration points for scalar field.
Definition: UserDataOperators.hpp:82
MoFEM::PipelineManager::createKSP
SmartPetscObj< KSP > createKSP(SmartPetscObj< DM > dm=nullptr)
Create KSP (linear) solver.
Definition: PipelineManager.cpp:99
OpGradTimesPerm
Definition: electrostatics.hpp:247
MoFEM::DMRegister_MoFEM
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition: DMMoFEM.cpp:43
OpElectricField
Definition: electrostatics.hpp:406
MoFEM::CoreInterface::get_comm_size
virtual int get_comm_size() const =0
MoFEM::GAUSS
@ GAUSS
Definition: FormsIntegrators.hpp:136
MoFEM::Simple::getDomainFEName
const std::string getDomainFEName() const
Get the Domain FE Name.
Definition: Simple.hpp:387
MoFEM::Simple::addBoundaryField
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:358
Electrostatics::geomOrder
int geomOrder
Definition: electrostatics.cpp:32
MoFEM::type_from_handle
auto type_from_handle(const EntityHandle h)
get type from entity handle
Definition: Templates.hpp:1898
Electrostatics::intBlockSetsPtr
boost::shared_ptr< std::map< int, BlockData > > intBlockSetsPtr
Definition: electrostatics.cpp:37
MoFEM::CoreInterface::add_ents_to_finite_element_by_dim
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
OpEnergyDensity
Definition: electrostatics.hpp:195
MoFEM::CoreInterface::modify_finite_element_add_field_data
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
MoFEM::OpPostProcMapInMoab::DataMapMat
std::map< std::string, boost::shared_ptr< MatrixDouble > > DataMapMat
Definition: PostProcBrokenMeshInMoabBase.hpp:701
MOFEM_NOT_FOUND
@ MOFEM_NOT_FOUND
Definition: definitions.h:33
OpGradTimesTensor
FormsIntegrators< DomainEleOp >::Assembly< A >::LinearForm< I >::OpGradTimesTensor< 1, FIELD_DIM, SPACE_DIM > OpGradTimesTensor
Definition: operators_tests.cpp:48
Electrostatics::is_partitioned
PetscBool is_partitioned
Definition: electrostatics.cpp:49
MoFEM::Simple::setFieldOrder
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
Definition: Simple.cpp:599
MoFEM::Simple::buildFiniteElements
MoFEMErrorCode buildFiniteElements()
Build finite elements.
Definition: Simple.cpp:697
MoFEM::AddHOOps
Add operators pushing bases from local to physical configuration.
Definition: HODataOperators.hpp:415
MoFEM::EssentialPreProc< TemperatureCubitBcData >
Specialization for TemperatureCubitBcData.
Definition: EssentialTemperatureCubitBcData.hpp:91
Range
MoFEM::CoreTmp< 0 >::Initialize
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
MF_ZERO
@ MF_ZERO
Definition: definitions.h:111
MoFEM::vectorDuplicate
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
Definition: PetscSmartObj.hpp:221
CATCH_ERRORS
#define CATCH_ERRORS
Catch errors.
Definition: definitions.h:385
DEMKOWICZ_JACOBI_BASE
@ DEMKOWICZ_JACOBI_BASE
Definition: definitions.h:66
MoFEM::CommInterface
Managing BitRefLevels.
Definition: CommInterface.hpp:21
_IT_CUBITMESHSETS_BY_SET_TYPE_FOR_LOOP_
#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.
Definition: MeshsetsManager.hpp:71
Electrostatics::setIntegrationRules
MoFEMErrorCode setIntegrationRules()
[Boundary condition]
Definition: electrostatics.cpp:320
MoFEM::Core
CoreTmp< 0 > Core
Definition: Core.hpp:1148
main
int main(int argc, char *argv[])
[Run program]
Definition: electrostatics.cpp:768
Electrostatics::simpleInterface
Simple * simpleInterface
Definition: electrostatics.cpp:34
Electrostatics::solveSystem
MoFEMErrorCode solveSystem()
[Assemble system]
Definition: electrostatics.cpp:424
BLOCKSET
@ BLOCKSET
Definition: definitions.h:161
Electrostatics::setupProblem
MoFEMErrorCode setupProblem()
[Read mesh]
Definition: electrostatics.cpp:72
OpBlockPermittivity
Definition: electrostatics.hpp:103
Electrostatics::petscVec
SmartPetscObj< Vec > petscVec
Definition: electrostatics.cpp:46
AINSWORTH_LEGENDRE_BASE
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition: definitions.h:60
MOFEM_DATA_INCONSISTENCY
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
MoFEM::Simple::defineFiniteElements
MoFEMErrorCode defineFiniteElements()
Define finite elements.
Definition: Simple.cpp:474
Electrostatics::ONE
@ ONE
Definition: electrostatics.cpp:50
MoFEM::createVectorMPI
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
Definition: PetscSmartObj.hpp:202
MoFEM::Simple::buildFields
MoFEMErrorCode buildFields()
Build fields.
Definition: Simple.cpp:608
Electrostatics::interFaceRhsFe
boost::shared_ptr< ForcesAndSourcesCore > interFaceRhsFe
Definition: electrostatics.cpp:41
Electrostatics::getElectrodeCharge
MoFEMErrorCode getElectrodeCharge()
[Get Total Energy]
Definition: electrostatics.cpp:636
ReactionDiffusionEquation::D
const double D
diffusivity
Definition: reaction_diffusion.cpp:20
Electrostatics::assembleSystem
MoFEMErrorCode assembleSystem()
[Set integration rules]
Definition: electrostatics.cpp:335
MOFEM_ATOM_TEST_INVALID
@ MOFEM_ATOM_TEST_INVALID
Definition: definitions.h:40
MoFEM::Simple::defineProblem
MoFEMErrorCode defineProblem(const PetscBool is_partitioned=PETSC_TRUE)
define problem
Definition: Simple.cpp:575
Electrostatics::Electrostatics
Electrostatics(MoFEM::Interface &m_field)
Definition: electrostatics.cpp:54
Electrostatics
Definition: electrostatics.cpp:12
MoFEM::SmartPetscObj< Vec >
Electrostatics::electrodeBlockSetsPtr
boost::shared_ptr< std::map< int, BlockData > > electrodeBlockSetsPtr
Definition: electrostatics.cpp:38
Electrostatics::ZERO
@ ZERO
Definition: electrostatics.cpp:50
MoFEM::Simple::setUp
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
Definition: Simple.cpp:765
MoFEM::Simple::getProblemName
const std::string getProblemName() const
Get the Problem Name.
Definition: Simple.hpp:408
MoFEM::DMoFEMLoopFiniteElements
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
convert.int
int
Definition: convert.py:64
MoFEM::PetscOptionsGetInt
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
Definition: DeprecatedPetsc.hpp:142
MoFEMFunctionReturn
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:429
MoFEM::Simple::addDomainField
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:264
Electrostatics::runProgram
MoFEMErrorCode runProgram()
[Get Charges]
Definition: electrostatics.cpp:751
Electrostatics::LAST_ELEMENT
@ LAST_ELEMENT
Definition: electrostatics.cpp:50
Electrostatics::aLpha
double aLpha
Definition: electrostatics.cpp:44
MoFEM::OpLoopSide
Element used to execute operators on side of the element.
Definition: ForcesAndSourcesCore.hpp:1291
MoFEMFunctionBegin
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:359
MOFEM_INVALID_DATA
@ MOFEM_INVALID_DATA
Definition: definitions.h:36
tol
double tol
Definition: mesh_smoothing.cpp:26
F
@ F
Definition: free_surface.cpp:394
MoFEM::OpPostProcMapInMoab
Post post-proc data at points from hash maps.
Definition: PostProcBrokenMeshInMoabBase.hpp:698
MoFEM::PetscOptionsGetBool
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
Definition: DeprecatedPetsc.hpp:182