v0.15.0
Loading...
Searching...
No Matches
Poisson2DNonhomogeneous Struct Reference
Collaboration diagram for Poisson2DNonhomogeneous:
[legend]

Public Member Functions

 Poisson2DNonhomogeneous (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProgram ()
 [Check]
 

Private Types

enum  NORMS { NORM = 0 , LAST_NORM }
 

Private Member Functions

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

Static Private Member Functions

static double sourceTermFunction (const double x, const double y, const double z)
 
static double boundaryFunction (const double x, const double y, const double z)
 

Private Attributes

MoFEM::InterfacemField
 
SimplesimpleInterface
 
std::string domainField
 
int oRder
 
boost::shared_ptr< std::vector< unsigned char > > boundaryMarker
 
Range boundaryEntitiesForFieldsplit
 
int atom_test = 0
 

Detailed Description

Definition at line 10 of file poisson_2d_nonhomogeneous.cpp.

Member Enumeration Documentation

◆ NORMS

Constructor & Destructor Documentation

◆ Poisson2DNonhomogeneous()

Poisson2DNonhomogeneous::Poisson2DNonhomogeneous ( MoFEM::Interface & m_field)

Definition at line 57 of file poisson_2d_nonhomogeneous.cpp.

Member Function Documentation

◆ assembleSystem()

MoFEMErrorCode Poisson2DNonhomogeneous::assembleSystem ( )
private

[Boundary condition]

[Assemble system]

Definition at line 143 of file poisson_2d_nonhomogeneous.cpp.

143 {
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}
#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< BoundaryEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesScalar< 1 > OpBoundaryRhs
FormsIntegrators< BoundaryEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, 1 > OpBoundaryLhs
Add operators pushing bases from local to physical configuration.
Set indices on entities on finite element.
PipelineManager interface.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
static double boundaryFunction(const double x, const double y, const double z)
static double sourceTermFunction(const double x, const double y, const double z)
boost::shared_ptr< std::vector< unsigned char > > boundaryMarker

◆ boundaryCondition()

MoFEMErrorCode Poisson2DNonhomogeneous::boundaryCondition ( )
private

[Setup problem]

[Boundary condition]

Definition at line 125 of file poisson_2d_nonhomogeneous.cpp.

125 {
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}
Simple interface for fast problem set-up.
Definition BcManager.hpp:29
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.
const std::string getProblemName() const
Get the Problem Name.
Definition Simple.hpp:410

◆ boundaryFunction()

static double Poisson2DNonhomogeneous::boundaryFunction ( const double x,
const double y,
const double z )
inlinestaticprivate

Definition at line 34 of file poisson_2d_nonhomogeneous.cpp.

35 {
36 return cos(x * M_PI) * cos(y * M_PI);
37 // return 0;
38 }

◆ checkResults()

MoFEMErrorCode Poisson2DNonhomogeneous::checkResults ( )
private

[Output results]

[Check]

Definition at line 297 of file poisson_2d_nonhomogeneous.cpp.

297 {
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 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
348 "atom test %d does not exist", atom_test);
349 }
350 if (cal_norm > ref_norm) {
351 SETERRQ(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}
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
@ MOFEM_INVALID_DATA
Definition definitions.h:36
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
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
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.
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:800
const std::string getDomainFEName() const
Get the Domain FE Name.
Definition Simple.hpp:389

◆ outputResults()

MoFEMErrorCode Poisson2DNonhomogeneous::outputResults ( )
private

[Solve system]

[Output results]

Definition at line 266 of file poisson_2d_nonhomogeneous.cpp.

266 {
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}
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
Post post-proc data at points from hash maps.
boost::shared_ptr< FEMethod > & getDomainLhsFE()

◆ readMesh()

MoFEMErrorCode Poisson2DNonhomogeneous::readMesh ( )
private

[Read mesh]

Definition at line 60 of file poisson_2d_nonhomogeneous.cpp.

60 {
62
66
68}
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

◆ runProgram()

MoFEMErrorCode Poisson2DNonhomogeneous::runProgram ( )

[Check]

[Run program]

Definition at line 363 of file poisson_2d_nonhomogeneous.cpp.

363 {
365
374
376}
MoFEMErrorCode solveSystem()
[Set integration rules]
MoFEMErrorCode setIntegrationRules()
[Assemble system]
MoFEMErrorCode setupProblem()
[Read mesh]
MoFEMErrorCode boundaryCondition()
[Setup problem]
MoFEMErrorCode checkResults()
[Output results]
MoFEMErrorCode outputResults()
[Solve system]
MoFEMErrorCode readMesh()
[Read mesh]
MoFEMErrorCode assembleSystem()
[Boundary condition]

◆ setIntegrationRules()

MoFEMErrorCode Poisson2DNonhomogeneous::setIntegrationRules ( )
private

[Assemble system]

[Set integration rules]

Definition at line 195 of file poisson_2d_nonhomogeneous.cpp.

195 {
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}
MoFEMErrorCode setDomainLhsIntegrationRule(RuleHookFun rule)

◆ setupProblem()

MoFEMErrorCode Poisson2DNonhomogeneous::setupProblem ( )
private

[Read mesh]

[Setup problem]

Definition at line 72 of file poisson_2d_nonhomogeneous.cpp.

72 {
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_NULLPTR, "", "-atom_test", &atom_test,
114 PETSC_NULLPTR);
115 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &oRder, PETSC_NULLPTR);
117
119
121}
@ 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
@ H1
continuous field
Definition definitions.h:85
@ MOFEM_NOT_FOUND
Definition definitions.h:33
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)
constexpr int SPACE_DIM
virtual moab::Interface & get_moab()=0
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 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 setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
Definition Simple.cpp:575
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
Definition Simple.cpp:736

◆ solveSystem()

MoFEMErrorCode Poisson2DNonhomogeneous::solveSystem ( )
private

[Set integration rules]

[Solve system]

Definition at line 215 of file poisson_2d_nonhomogeneous.cpp.

215 {
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 const MoFEM::Problem *problem_ptr;
240 CHKERR DMMoFEMGetProblemPtr(dm, &problem_ptr);
241 IS is_boundary;
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}
@ ROW
@ 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:514
PetscErrorCode DMMoFEMGetProblemPtr(DM dm, const MoFEM::Problem **problem_ptr)
Get pointer to problem data structure.
Definition DMMoFEM.cpp:422
auto createDMVector(DM dm)
Get smart vector from DM.
Definition DMMoFEM.hpp:1102
SmartPetscObj< KSP > createKSP(SmartPetscObj< DM > dm=nullptr)
Create KSP (linear) solver.
double D
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
Section manager is used to create indexes and sections.
Definition ISManager.hpp:23
keeps basic data about problem

◆ sourceTermFunction()

static double Poisson2DNonhomogeneous::sourceTermFunction ( const double x,
const double y,
const double z )
inlinestaticprivate

Definition at line 29 of file poisson_2d_nonhomogeneous.cpp.

30 {
31 return 2. * M_PI * M_PI * cos(x * M_PI) * cos(y * M_PI);
32 }

Member Data Documentation

◆ atom_test

int Poisson2DNonhomogeneous::atom_test = 0
private

Definition at line 53 of file poisson_2d_nonhomogeneous.cpp.

◆ boundaryEntitiesForFieldsplit

Range Poisson2DNonhomogeneous::boundaryEntitiesForFieldsplit
private

Definition at line 52 of file poisson_2d_nonhomogeneous.cpp.

◆ boundaryMarker

boost::shared_ptr<std::vector<unsigned char> > Poisson2DNonhomogeneous::boundaryMarker
private

Definition at line 49 of file poisson_2d_nonhomogeneous.cpp.

◆ domainField

std::string Poisson2DNonhomogeneous::domainField
private

Definition at line 45 of file poisson_2d_nonhomogeneous.cpp.

◆ mField

MoFEM::Interface& Poisson2DNonhomogeneous::mField
private

Definition at line 41 of file poisson_2d_nonhomogeneous.cpp.

◆ oRder

int Poisson2DNonhomogeneous::oRder
private

Definition at line 46 of file poisson_2d_nonhomogeneous.cpp.

◆ simpleInterface

Simple* Poisson2DNonhomogeneous::simpleInterface
private

Definition at line 42 of file poisson_2d_nonhomogeneous.cpp.


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