v0.14.0
Loading...
Searching...
No Matches
poisson_2d_nonhomogeneous.cpp
Go to the documentation of this file.
2
3using namespace MoFEM;
5
6constexpr int SPACE_DIM = 2;
9static char help[] = "...\n\n";
11public:
13
14 // Declaration of the main function to run analysis
16
17private:
18 // Declaration of other main functions called in runProgram()
27
28 // Function to calculate the Source term
29 static double sourceTermFunction(const double x, const double y,
30 const double z) {
31 return 2. * M_PI * M_PI * cos(x * M_PI) * cos(y * M_PI);
32 }
33 // Function to calculate the Boundary term
34 static double boundaryFunction(const double x, const double y,
35 const double z) {
36 return cos(x * M_PI) * cos(y * M_PI);
37 // return 0;
38 }
39
40 // Main interfaces
43
44 // Field name and approximation order
45 std::string domainField;
46 int oRder;
47
48 // Object to mark boundary entities for the assembling of domain elements
49 boost::shared_ptr<std::vector<unsigned char>> boundaryMarker;
50
51 // Boundary entities marked for fieldsplit (block) solver - optional
53 int atom_test = 0;
54 enum NORMS { NORM = 0, LAST_NORM };
55};
56
59//! [Read mesh]
69//! [Read mesh]
70
71//! [Setup problem]
74 Range domain_ents;
75 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, domain_ents,
76 true);
77 auto get_ents_by_dim = [&](const auto dim) {
78 if (dim == SPACE_DIM) {
79 return domain_ents;
80 } else {
81 Range ents;
82 if (dim == 0)
83 CHKERR mField.get_moab().get_connectivity(domain_ents, ents, true);
84 else
85 CHKERR mField.get_moab().get_entities_by_dimension(0, dim, ents, true);
86 return ents;
87 }
88 };
89 // Select base
90 auto get_base = [&]() {
91 auto domain_ents = get_ents_by_dim(SPACE_DIM);
92 if (domain_ents.empty())
94 const auto type = type_from_handle(domain_ents[0]);
95 switch (type) {
96 case MBQUAD:
98 case MBHEX:
100 case MBTRI:
102 case MBTET:
104 default:
105 CHK_THROW_MESSAGE(MOFEM_NOT_FOUND, "Element type not handled");
106 }
107 return NOBASE;
108 };
109 auto base = get_base();
112 int oRder = 3;
113 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-atom_test", &atom_test,
114 PETSC_NULL);
115 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-order", &oRder, PETSC_NULL);
117
119
121}
122//! [Setup problem]
123
124//! [Boundary condition]
127
128 auto bc_mng = mField.getInterface<BcManager>();
130 "BOUNDARY_CONDITION", domainField, 0, 1,
131 true);
132 // merge markers from all blocksets "BOUNDARY_CONDITION"
133 boundaryMarker = bc_mng->getMergedBlocksMarker({"BOUNDARY_CONDITION"});
134 // get entities on blocksets "BOUNDARY_CONDITION"
136 bc_mng->getMergedBlocksRange({"BOUNDARY_CONDITION"});
137
139}
140//! [Boundary condition]
141
142//! [Assemble system]
145
146 auto pipeline_mng = mField.getInterface<PipelineManager>();
147
148 { // Push operators to the Pipeline that is responsible for calculating LHS of
149 // domain elements
151 pipeline_mng->getOpDomainLhsPipeline(), {H1});
152 pipeline_mng->getOpDomainLhsPipeline().push_back(
154 pipeline_mng->getOpDomainLhsPipeline().push_back(
156 pipeline_mng->getOpDomainLhsPipeline().push_back(
158 }
159
160 { // Push operators to the Pipeline that is responsible for calculating RHS of
161 // domain elements
162 pipeline_mng->getOpDomainRhsPipeline().push_back(
164 pipeline_mng->getOpDomainRhsPipeline().push_back(
166 pipeline_mng->getOpDomainRhsPipeline().push_back(
168 }
169
170 { // Push operators to the Pipeline that is responsible for calculating LHS of
171 // boundary elements
172 pipeline_mng->getOpBoundaryLhsPipeline().push_back(
173 new OpSetBc(domainField, false, boundaryMarker));
174 pipeline_mng->getOpBoundaryLhsPipeline().push_back(
176 pipeline_mng->getOpBoundaryLhsPipeline().push_back(
178 }
179
180 { // Push operators to the Pipeline that is responsible for calculating RHS of
181 // boundary elements
182 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
183 new OpSetBc(domainField, false, boundaryMarker));
184 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
186 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
188 }
189
191}
192//! [Assemble system]
193
194//! [Set integration rules]
197
198 auto pipeline_mng = mField.getInterface<PipelineManager>();
199
200 auto domain_rule_lhs = [](int, int, int p) -> int { return 2 * (p - 1); };
201 auto domain_rule_rhs = [](int, int, int p) -> int { return 2 * (p - 1); };
202 CHKERR pipeline_mng->setDomainLhsIntegrationRule(domain_rule_lhs);
203 CHKERR pipeline_mng->setDomainRhsIntegrationRule(domain_rule_rhs);
204
205 auto boundary_rule_lhs = [](int, int, int p) -> int { return 2 * p; };
206 auto boundary_rule_rhs = [](int, int, int p) -> int { return 2 * p; };
207 CHKERR pipeline_mng->setBoundaryLhsIntegrationRule(boundary_rule_lhs);
208 CHKERR pipeline_mng->setBoundaryLhsIntegrationRule(boundary_rule_rhs);
209
211}
212//! [Set integration rules]
213
214//! [Solve system]
217
218 auto pipeline_mng = mField.getInterface<PipelineManager>();
219
220 auto ksp_solver = pipeline_mng->createKSP();
221 CHKERR KSPSetFromOptions(ksp_solver);
222
223 // Create RHS and solution vectors
224 auto dm = simpleInterface->getDM();
225 auto F = createDMVector(dm);
226 auto D = vectorDuplicate(F);
227
228 // Setup fieldsplit (block) solver - optional: yes/no
229 if (1) {
230 PC pc;
231 CHKERR KSPGetPC(ksp_solver, &pc);
232 PetscBool is_pcfs = PETSC_FALSE;
233 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
234
235 // Set up FIELDSPLIT, only when user set -pc_type fieldsplit
236 // Identify the index for boundary entities, remaining will be for domain
237 // Then split the fields for boundary and domain for solving
238 if (is_pcfs == PETSC_TRUE) {
239 IS is_domain, is_boundary;
240 const MoFEM::Problem *problem_ptr;
241 CHKERR DMMoFEMGetProblemPtr(dm, &problem_ptr);
242 CHKERR mField.getInterface<ISManager>()->isCreateProblemFieldAndRank(
243 problem_ptr->getName(), ROW, domainField, 0, 1, &is_boundary,
245 // CHKERR ISView(is_boundary, PETSC_VIEWER_STDOUT_SELF);
246 CHKERR PCFieldSplitSetIS(pc, NULL, is_boundary);
247 CHKERR ISDestroy(&is_boundary);
248 }
249 }
250
251 CHKERR KSPSetUp(ksp_solver);
252
253 // Solve the system
254 CHKERR KSPSolve(ksp_solver, F, D);
255
256 // Scatter result data on the mesh
257 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
258 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
259 CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_REVERSE);
260
262}
263//! [Solve system]
264
265//! [Output results]
268
269 auto pipeline_mng = mField.getInterface<PipelineManager>();
270 pipeline_mng->getDomainLhsFE().reset();
271 pipeline_mng->getBoundaryLhsFE().reset();
272 pipeline_mng->getDomainRhsFE().reset();
273 pipeline_mng->getBoundaryRhsFE().reset();
274
275 auto d_ptr = boost::make_shared<VectorDouble>();
276 auto l_ptr = boost::make_shared<VectorDouble>();
277
279
280 auto post_proc_fe = boost::make_shared<PostProcFaceEle>(mField);
281
282 post_proc_fe->getOpPtrVector().push_back(
284 post_proc_fe->getOpPtrVector().push_back(new OpPPMap(
285 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
286 {{domainField, d_ptr}}, {}, {}, {}));
287 pipeline_mng->getDomainRhsFE() = post_proc_fe;
288
289 CHKERR pipeline_mng->loopFiniteElements();
290 CHKERR post_proc_fe->writeFile("out_result.h5m");
291
293}
294//! [Output results]
295
296//! [Check]
299
300 auto check_result_fe_ptr = boost::make_shared<FaceEle>(mField);
301 auto petscVec =
303 (mField.get_comm_rank() == 0) ? LAST_NORM : 0, LAST_NORM);
304
306 check_result_fe_ptr->getOpPtrVector(), {H1})),
307 "Apply transform");
308
309 check_result_fe_ptr->getRuleHook = [](int, int, int p) { return 2 * p; };
310 auto analyticalFunction = [&](double x, double y, double z) {
311 return cos(x * M_PI) * cos(y * M_PI);
312 };
313
314 auto u_ptr = boost::make_shared<VectorDouble>();
315
316 check_result_fe_ptr->getOpPtrVector().push_back(
318 auto mValFuncPtr = boost::make_shared<VectorDouble>();
319 check_result_fe_ptr->getOpPtrVector().push_back(
320 new OpGetTensor0fromFunc(mValFuncPtr, analyticalFunction));
321 check_result_fe_ptr->getOpPtrVector().push_back(
322 new OpCalcNormL2Tensor0(u_ptr, petscVec, NORM, mValFuncPtr));
323 CHKERR VecZeroEntries(petscVec);
326 check_result_fe_ptr);
327 CHKERR VecAssemblyBegin(petscVec);
328 CHKERR VecAssemblyEnd(petscVec);
329 MOFEM_LOG_CHANNEL("SELF"); // Clear channel from old tags
330 if (mField.get_comm_rank() == 0) {
331 const double *norms;
332 CHKERR VecGetArrayRead(petscVec, &norms);
333 MOFEM_TAG_AND_LOG("SELF", Sev::inform, "Errors")
334 << "NORM: " << std::sqrt(norms[NORM]);
335 CHKERR VecRestoreArrayRead(petscVec, &norms);
336 }
337 if (atom_test && !mField.get_comm_rank()) {
338 const double *t_ptr;
339 CHKERR VecGetArrayRead(petscVec, &t_ptr);
340 double ref_norm = 1.4e-04;
341 double cal_norm;
342 switch (atom_test) {
343 case 1: // 2D
344 cal_norm = sqrt(t_ptr[0]);
345 break;
346 default:
347 SETERRQ1(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
348 "atom test %d does not exist", atom_test);
349 }
350 if (cal_norm > ref_norm) {
351 SETERRQ3(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
352 "atom test %d failed! Calculated Norm %3.16e is greater than "
353 "reference Norm %3.16e",
354 atom_test, cal_norm, ref_norm);
355 }
356 CHKERR VecRestoreArrayRead(petscVec, &t_ptr);
357 }
359}
360//! [Check]
361
362//! [Run program]
377//! [Run program]
378
379int main(int argc, char *argv[]) {
380
381 // Initialisation of MoFEM/PETSc and MOAB data structures
382 const char param_file[] = "param_file.petsc";
383 MoFEM::Core::Initialize(&argc, &argv, param_file, help);
384
385 // Error handling
386 try {
387 // Register MoFEM discrete manager in PETSc
388 DMType dm_name = "DMMOFEM";
389 CHKERR DMRegister_MoFEM(dm_name);
390
391 // Create MOAB instance
392 moab::Core mb_instance; // mesh database
393 moab::Interface &moab = mb_instance; // mesh database interface
394
395 // Create MoFEM instance
396 MoFEM::Core core(moab); // finite element database
397 MoFEM::Interface &m_field = core; // finite element interface
398
399 // Run the main analysis
400 Poisson2DNonhomogeneous poisson_problem(m_field);
401 CHKERR poisson_problem.runProgram();
402 }
404
405 // Finish work: cleaning memory, getting statistics, etc.
407
408 return 0;
409}
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
int main()
@ ROW
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base nme:nme847.
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.
@ 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 ...
@ MOFEM_NOT_FOUND
Definition definitions.h:33
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
@ MOFEM_INVALID_DATA
Definition definitions.h:36
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr auto domainField
@ F
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
PetscErrorCode DMMoFEMGetProblemPtr(DM dm, const MoFEM::Problem **problem_ptr)
Get pointer to problem data structure.
Definition DMMoFEM.cpp:426
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
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
auto createDMVector(DM dm)
Get smart vector from DM.
Definition DMMoFEM.hpp:1099
SmartPetscObj< KSP > createKSP(SmartPetscObj< DM > dm=nullptr)
Create KSP (linear) solver.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
double D
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
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)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
FormsIntegrators< BoundaryEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesScalar< 1 > OpBoundaryRhs
FormsIntegrators< BoundaryEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, 1 > OpBoundaryLhs
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
static char help[]
constexpr int SPACE_DIM
Add operators pushing bases from local to physical configuration.
Simple interface for fast problem set-up.
Definition BcManager.hpp:25
MoFEMErrorCode pushMarkDOFsOnEntities(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)
Mark block DOFs.
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Core (interface) class.
Definition Core.hpp:82
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
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition Core.cpp:112
Deprecated interface functions.
Section manager is used to create indexes and sections.
Definition ISManager.hpp:23
Get norm of input VectorDouble for Tensor0.
Get value at integration points for scalar field.
Get values from scalar function at integration points and save them to VectorDouble for Tensor0.
Post post-proc data at points from hash maps.
Set indices on entities on finite element.
PipelineManager interface.
boost::shared_ptr< FEMethod > & getDomainLhsFE()
MoFEMErrorCode setDomainLhsIntegrationRule(RuleHookFun rule)
keeps basic data about problem
Simple interface for fast problem set-up.
Definition Simple.hpp:27
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
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
Definition Simple.cpp:194
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
MoFEMErrorCode getOptions()
get options
Definition Simple.cpp:180
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:829
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
Definition Simple.cpp:599
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
Definition Simple.cpp:765
const std::string getProblemName() const
Get the Problem Name.
Definition Simple.hpp:408
const std::string getDomainFEName() const
Get the Domain FE Name.
Definition Simple.hpp:387
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
static double boundaryFunction(const double x, const double y, const double z)
Poisson2DNonhomogeneous(MoFEM::Interface &m_field)
MoFEMErrorCode solveSystem()
[Set integration rules]
MoFEMErrorCode setIntegrationRules()
[Assemble system]
static double sourceTermFunction(const double x, const double y, const double z)
MoFEMErrorCode setupProblem()
[Read mesh]
MoFEMErrorCode boundaryCondition()
[Setup problem]
MoFEMErrorCode checkResults()
[Output results]
boost::shared_ptr< std::vector< unsigned char > > boundaryMarker
MoFEMErrorCode outputResults()
[Solve system]
MoFEMErrorCode readMesh()
[Read mesh]
MoFEMErrorCode assembleSystem()
[Boundary condition]