v0.16.0
Loading...
Searching...
No Matches
Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
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

Enumerator
NORM 
LAST_NORM 

Definition at line 54 of file poisson_2d_nonhomogeneous.cpp.

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.
Add operators pushing bases from local to physical configuration.
Set indices on entities on finite element.
Unset 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}
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 DOFs on block entities for boundary conditions.
Boundary condition manager for finite element problem setup.
const std::string getProblemName() const
Get the Problem Name.
Definition Simple.hpp:450

◆ 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 293 of file poisson_2d_nonhomogeneous.cpp.

293 {
295
296 auto check_result_fe_ptr = boost::make_shared<FaceEle>(mField);
297 auto petscVec =
299 (mField.get_comm_rank() == 0) ? LAST_NORM : 0, LAST_NORM);
300
302 check_result_fe_ptr->getOpPtrVector(), {H1})),
303 "Apply transform");
304
305 check_result_fe_ptr->getRuleHook = [](int, int, int p) { return 2 * p; };
306 auto analyticalFunction = [&](double x, double y, double z) {
307 return cos(x * M_PI) * cos(y * M_PI);
308 };
309
310 auto u_ptr = boost::make_shared<VectorDouble>();
311
312 check_result_fe_ptr->getOpPtrVector().push_back(
314 auto mValFuncPtr = boost::make_shared<VectorDouble>();
315 check_result_fe_ptr->getOpPtrVector().push_back(
316 new OpGetTensor0fromFunc(mValFuncPtr, analyticalFunction));
317 check_result_fe_ptr->getOpPtrVector().push_back(
318 new OpCalcNormL2Tensor0(u_ptr, petscVec, NORM, mValFuncPtr));
319 CHKERR VecZeroEntries(petscVec);
322 check_result_fe_ptr);
323 CHKERR VecAssemblyBegin(petscVec);
324 CHKERR VecAssemblyEnd(petscVec);
325 MOFEM_LOG_CHANNEL("SELF"); // Clear channel from old tags
326 if (mField.get_comm_rank() == 0) {
327 const double *norms;
328 CHKERR VecGetArrayRead(petscVec, &norms);
329 MOFEM_TAG_AND_LOG("SELF", Sev::inform, "Errors")
330 << "NORM: " << std::sqrt(norms[NORM]);
331 CHKERR VecRestoreArrayRead(petscVec, &norms);
332 }
333 if (atom_test && !mField.get_comm_rank()) {
334 const double *t_ptr;
335 CHKERR VecGetArrayRead(petscVec, &t_ptr);
336 double ref_norm = 1.4e-04;
337 double cal_norm;
338 switch (atom_test) {
339 case 1: // 2D
340 cal_norm = sqrt(t_ptr[0]);
341 break;
342 default:
343 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
344 "atom test %d does not exist", atom_test);
345 }
346 if (cal_norm > ref_norm) {
347 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
348 "atom test %d failed! Calculated Norm %3.16e is greater than "
349 "reference Norm %3.16e",
350 atom_test, cal_norm, ref_norm);
351 }
352 CHKERR VecRestoreArrayRead(petscVec, &t_ptr);
353 }
355}
#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.
Specialization for double precision scalar field values calculation.
Get values from scalar function at integration points and save them to VectorDouble for Tensor0.
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:799
const std::string getDomainFEName() const
Get the Domain FE Name.
Definition Simple.hpp:429

◆ 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
271 auto d_ptr = boost::make_shared<VectorDouble>();
272 auto l_ptr = boost::make_shared<VectorDouble>();
273
275
276 auto post_proc_fe = boost::make_shared<PostProcFaceEle>(mField);
277
278 post_proc_fe->getOpPtrVector().push_back(
280 post_proc_fe->getOpPtrVector().push_back(new OpPPMap(
281 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
282 {{domainField, d_ptr}}, {}, {}, {}));
283 pipeline_mng->getDomainPostProcFE() = post_proc_fe;
284
285 CHKERR pipeline_mng->loopFiniteElementsPostProc();
286 CHKERR post_proc_fe->writeFile("out_result.h5m");
287
289}
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
Post post-proc data at points from hash maps.

◆ 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 359 of file poisson_2d_nonhomogeneous.cpp.

359 {
361
370
372}
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)
Set integration rule for domain left-hand side finite element.

◆ 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}
std::string type
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
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:735

◆ 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 DMMoFEMGetProblemPtr(DM dm, const MoFEM::Problem **problem_ptr)
Get pointer to problem data structure.
Definition DMMoFEM.cpp:422
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
Definition DMMoFEM.cpp:514
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1237
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: