v0.13.2
Loading...
Searching...
No Matches
poisson_2d_lagrange_multiplier.cpp
Go to the documentation of this file.
1#include <stdlib.h>
4
5using namespace MoFEM;
7
12
13static char help[] = "...\n\n";
14
16public:
18
19 // Declaration of the main function to run analysis
21
22private:
23 // Declaration of other main functions called in runProgram()
31
32 // Function to calculate the Source term
33 static double sourceTermFunction(const double x, const double y,
34 const double z) {
35 return 200 * sin(x * 10.) * cos(y * 10.);
36 // return 1;
37 }
38 // Function to calculate the Boundary term
39 static double boundaryFunction(const double x, const double y,
40 const double z) {
41 return sin(x * 10.) * cos(y * 10.);
42 // return 0;
43 }
44
45 // Main interfaces
48
49 // Field name and approximation order
50 std::string domainField; // displacement field
51 std::string boundaryField; // Lagrange multiplier field
52 int oRder;
53
54 // Object to mark boundary entities for the assembling of domain elements
55 boost::shared_ptr<std::vector<unsigned char>> boundaryMarker;
56
57 // Boundary entities marked for fieldsplit (block) solver - optional
59};
60
62 MoFEM::Interface &m_field)
63 : domainField("U"), boundaryField("L"), mField(m_field) {}
64
67
71
73}
74
77
82
83 int oRder = 3;
84 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-order", &oRder, PETSC_NULL);
87
89
91}
92
95
96 // Get boundary edges marked in block named "BOUNDARY_CONDITION"
97 auto get_ents_on_mesh = [&]() {
98 Range boundary_entities;
100 std::string entity_name = it->getName();
101 if (entity_name.compare(0, 18, "BOUNDARY_CONDITION") == 0) {
102 CHKERR it->getMeshsetIdEntitiesByDimension(mField.get_moab(), 1,
103 boundary_entities, true);
104 }
105 }
106 // Add vertices to boundary entities
107 Range boundary_vertices;
108 CHKERR mField.get_moab().get_connectivity(boundary_entities,
109 boundary_vertices, true);
110 boundary_entities.merge(boundary_vertices);
111
112 // Store entities for fieldsplit (block) solver
113 boundaryEntitiesForFieldsplit = boundary_entities;
114
115 return boundary_entities;
116 };
117
118 auto mark_boundary_dofs = [&](Range &&skin_edges) {
119 auto problem_manager = mField.getInterface<ProblemsManager>();
120 auto marker_ptr = boost::make_shared<std::vector<unsigned char>>();
121 problem_manager->markDofs(simpleInterface->getProblemName(), ROW,
122 skin_edges, *marker_ptr);
123 return marker_ptr;
124 };
125
126 // Get global local vector of marked DOFs. Is global, since is set for all
127 // DOFs on processor. Is local since only DOFs on processor are in the
128 // vector. To access DOFs use local indices.
129 boundaryMarker = mark_boundary_dofs(get_ents_on_mesh());
130
132}
133
136
137 auto pipeline_mng = mField.getInterface<PipelineManager>();
138 auto det_ptr = boost::make_shared<VectorDouble>();
139 auto jac_ptr = boost::make_shared<MatrixDouble>();
140 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
141
142 { // Push operators to the Pipeline that is responsible for calculating LHS of
143 // domain elements
144 pipeline_mng->getOpDomainLhsPipeline().push_back(
145 new OpCalculateHOJac<2>(jac_ptr));
146 pipeline_mng->getOpDomainLhsPipeline().push_back(
147 new OpInvertMatrix<2>(jac_ptr, det_ptr, inv_jac_ptr));
148 pipeline_mng->getOpDomainLhsPipeline().push_back(
149 new OpSetHOInvJacToScalarBases<2>(H1, inv_jac_ptr));
150 pipeline_mng->getOpDomainLhsPipeline().push_back(
152 pipeline_mng->getOpDomainLhsPipeline().push_back(
154 }
155
156 { // Push operators to the Pipeline that is responsible for calculating RHS of
157 // domain elements
158 pipeline_mng->getOpDomainRhsPipeline().push_back(
160 }
161
162 { // Push operators to the Pipeline that is responsible for calculating LHS of
163 // boundary elements (Lagrange multiplier)
164 pipeline_mng->getOpBoundaryLhsPipeline().push_back(
166 pipeline_mng->getOpBoundaryLhsPipeline().push_back(
168 }
169
170 { // Push operators to the Pipeline that is responsible for calculating RHS of
171 // boundary elements (Lagrange multiplier)
172 pipeline_mng->getOpBoundaryRhsPipeline().push_back(
174 }
175
177}
178
181
182 auto pipeline_mng = mField.getInterface<PipelineManager>();
183
184 auto domain_rule_lhs = [](int, int, int p) -> int { return 2 * (p - 1); };
185 auto domain_rule_rhs = [](int, int, int p) -> int { return 2 * (p - 1); };
186 CHKERR pipeline_mng->setDomainLhsIntegrationRule(domain_rule_lhs);
187 CHKERR pipeline_mng->setDomainRhsIntegrationRule(domain_rule_rhs);
188
189 auto boundary_rule_lhs = [](int, int, int p) -> int { return 2 * p; };
190 auto boundary_rule_rhs = [](int, int, int p) -> int { return 2 * p; };
191 CHKERR pipeline_mng->setBoundaryLhsIntegrationRule(boundary_rule_lhs);
192 CHKERR pipeline_mng->setBoundaryLhsIntegrationRule(boundary_rule_rhs);
193
195}
196
199
200 auto pipeline_mng = mField.getInterface<PipelineManager>();
201
202 auto ksp_solver = pipeline_mng->createKSP();
203 CHKERR KSPSetFromOptions(ksp_solver);
204
205 // Create RHS and solution vectors
206 auto dm = simpleInterface->getDM();
207 auto F = createDMVector(dm);
208 auto D = vectorDuplicate(F);
209
210 // Setup fieldsplit (block) solver - optional: yes/no
211 if (1) {
212 PC pc;
213 CHKERR KSPGetPC(ksp_solver, &pc);
214 PetscBool is_pcfs = PETSC_FALSE;
215 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
216
217 // Set up FIELDSPLIT, only when user set -pc_type fieldsplit
218 // Identify the index for boundary entities, remaining will be for domain
219 // Then split the fields for boundary and domain for solving
220 if (is_pcfs == PETSC_TRUE) {
221 IS is_domain, is_boundary;
222 cerr << "Running FIELDSPLIT..." << endl;
223 const MoFEM::Problem *problem_ptr;
224 CHKERR DMMoFEMGetProblemPtr(dm, &problem_ptr);
225 CHKERR mField.getInterface<ISManager>()->isCreateProblemFieldAndRank(
226 problem_ptr->getName(), ROW, domainField, 0, 1, &is_boundary,
228 // CHKERR ISView(is_boundary, PETSC_VIEWER_STDOUT_SELF);
229
230 CHKERR PCFieldSplitSetIS(pc, NULL, is_boundary);
231
232 CHKERR ISDestroy(&is_boundary);
233 }
234 }
235
236 CHKERR KSPSetUp(ksp_solver);
237
238 // Solve the system
239 CHKERR KSPSolve(ksp_solver, F, D);
240
241 // Scatter result data on the mesh
242 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
243 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
244 CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_REVERSE);
245
247}
248
251
252 auto pipeline_mng = mField.getInterface<PipelineManager>();
253 pipeline_mng->getDomainLhsFE().reset();
254 pipeline_mng->getBoundaryLhsFE().reset();
255
256 auto d_ptr = boost::make_shared<VectorDouble>();
257 auto l_ptr = boost::make_shared<VectorDouble>();
258
260
261 auto post_proc_domain_fe = boost::make_shared<PostProcFaceEle>(mField);
262 post_proc_domain_fe->getOpPtrVector().push_back(
264 post_proc_domain_fe->getOpPtrVector().push_back(
265 new OpPPMap(post_proc_domain_fe->getPostProcMesh(),
266 post_proc_domain_fe->getMapGaussPts(), {{domainField, d_ptr}},
267 {}, {}, {}));
268 pipeline_mng->getDomainRhsFE() = post_proc_domain_fe;
269
270 auto post_proc_boundary_fe = boost::make_shared<PostProcEdgeEle>(mField);
271 post_proc_boundary_fe->getOpPtrVector().push_back(
272 new OpCalculateScalarFieldValues(boundaryField, l_ptr));
273 post_proc_boundary_fe->getOpPtrVector().push_back(
274 new OpPPMap(post_proc_boundary_fe->getPostProcMesh(),
275 post_proc_boundary_fe->getMapGaussPts(),
276 {{boundaryField, l_ptr}}, {}, {}, {}));
277 pipeline_mng->getBoundaryRhsFE() = post_proc_boundary_fe;
278
279 CHKERR pipeline_mng->loopFiniteElements();
280 CHKERR post_proc_domain_fe->writeFile("out_result_domain.h5m");
281 CHKERR post_proc_boundary_fe->writeFile("out_result_boundary.h5m");
282
284}
285
288
289 readMesh();
290 setupProblem();
294 solveSystem();
296
298}
299
300int main(int argc, char *argv[]) {
301
302 // Initialisation of MoFEM/PETSc and MOAB data structures
303 const char param_file[] = "param_file.petsc";
305
306 // Error handling
307 try {
308 // Register MoFEM discrete manager in PETSc
309 DMType dm_name = "DMMOFEM";
310 CHKERR DMRegister_MoFEM(dm_name);
311
312 // Create MOAB instance
313 moab::Core mb_instance; // mesh database
314 moab::Interface &moab = mb_instance; // mesh database interface
315
316 // Create MoFEM instance
317 MoFEM::Core core(moab); // finite element database
318 MoFEM::Interface &m_field = core; // finite element interface
319
320 // Run the main analysis
321 Poisson2DLagrangeMultiplier poisson_problem(m_field);
322 CHKERR poisson_problem.runProgram();
323 }
325
326 // Finish work: cleaning memory, getting statistics, etc.
328
329 return 0;
330}
static Index< 'p', 3 > p
std::string param_file
int main()
Definition: adol-c_atom.cpp:46
@ ROW
Definition: definitions.h:123
#define CATCH_ERRORS
Catch errors.
Definition: definitions.h:372
@ AINSWORTH_BERNSTEIN_BEZIER_BASE
Definition: definitions.h:64
@ 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 ...
Definition: definitions.h:346
@ BLOCKSET
Definition: definitions.h:148
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:416
#define CHKERR
Inline error check.
Definition: definitions.h:535
@ 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:509
PetscErrorCode DMMoFEMGetProblemPtr(DM dm, const MoFEM::Problem **problem_ptr)
Get pointer to problem data structure.
Definition: DMMoFEM.cpp:412
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition: DMMoFEM.cpp:47
auto createDMVector(DM dm)
Get smart vector from DM.
Definition: DMMoFEM.hpp:1003
SmartPetscObj< KSP > createKSP(SmartPetscObj< DM > dm=nullptr)
Create KSP (linear) solver.
#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.
double D
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
static char help[]
virtual moab::Interface & get_moab()=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 value at integration points for scalar field.
Post post-proc data at points from hash maps.
Set inverse jacobian to base functions.
Modify integration weights on face to take in account higher-order geometry.
PipelineManager interface.
boost::shared_ptr< FEMethod > & getDomainLhsFE()
keeps basic data about problem
Problem manager is used to build and partition problems.
MoFEMErrorCode markDofs(const std::string problem_name, RowColData rc, const enum MarkOP op, const Range ents, std::vector< unsigned char > &marker) const
Create vector with marked indices.
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 getOptions()
get options
Definition: Simple.cpp:180
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition: Simple.cpp:667
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name)
Load mesh file.
Definition: Simple.cpp:194
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
Definition: Simple.cpp:473
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:282
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
Definition: Simple.cpp:611
const std::string getProblemName() const
Get the Problem Name.
Definition: Simple.hpp:348
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface refernce to pointer of interface.
static double sourceTermFunction(const double x, const double y, const double z)
Poisson2DLagrangeMultiplier(MoFEM::Interface &m_field)
boost::shared_ptr< std::vector< unsigned char > > boundaryMarker
static double boundaryFunction(const double x, const double y, const double z)