v0.16.0
Loading...
Searching...
No Matches
eigen_elastic.cpp
Go to the documentation of this file.
1/**
2 * \file eigen_elastic.cpp
3 * \example mofem/tutorials/vec-1_eigen_elasticity/eigen_elastic.cpp
4 *
5 * Calculate natural frequencies in 2d and 3d problems.
6 *
7 */
8
9#include <MoFEM.hpp>
10#undef EPS
11#include <slepceps.h>
12
13using namespace MoFEM;
14
15//! [Operators_definition]
16template <int DIM> struct ElementsAndOps {};
17
18template <> struct ElementsAndOps<2> {
20};
21
22template <> struct ElementsAndOps<3> {
24};
25
26constexpr int SPACE_DIM =
27 EXECUTABLE_DIMENSION; //< Space dimension of problem, mesh
28
30using DomainEleOp = DomainEle::UserDataOperator;
32
35 GAUSS>::OpGradSymTensorGrad<1, SPACE_DIM, SPACE_DIM, 0>;
38//! [Operators_definition]
39
40//! [Physical_parameters]
41double rho = 7829e-9; // density in kg/mm^3
42double young_modulus = 2.07e8; // Young's modulus E in [kPa]
43double poisson_ratio = 0.33;
44
47//! [Physical_parameters]
48
49int order = 2;
50
51//! [Create Example_struct]
52struct Example {
53
54 Example(MoFEM::Interface &m_field) : mField(m_field) {}
55
57
58private:
60
69
70 boost::shared_ptr<MatrixDouble> matDPtr;
71
75
76 std::array<SmartPetscObj<Vec>, 6> rigidBodyMotion;
77};
78//! [Create Example_struct]
79
80//! [Create common data]
83
84 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-rho", &rho, PETSC_NULLPTR);
85 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-young_modulus",
86 &young_modulus, PETSC_NULLPTR);
87 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-poisson_ratio",
88 &poisson_ratio, PETSC_NULLPTR);
89
90 bulk_modulus_K = young_modulus / (3 * (1 - 2 * poisson_ratio));
92
93 auto set_matrial_stiffens = [&]() {
100 auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(*matDPtr);
101
102 const double A = (SPACE_DIM == 2)
103 ? 2 * shear_modulus_G /
104 (bulk_modulus_K + (4. / 3.) * shear_modulus_G)
105 : 1; // 2D plane strain or 3D
106 t_D(i, j, k, l) = 2 * shear_modulus_G * ((t_kd(i, k) ^ t_kd(j, l)) / 4.) +
107 A * (bulk_modulus_K - (2. / 3.) * shear_modulus_G) *
108 t_kd(i, j) * t_kd(k, l);
109
111 };
112
113 matDPtr = boost::make_shared<MatrixDouble>();
114
115 constexpr auto size_symm = (SPACE_DIM * (SPACE_DIM + 1)) / 2;
116 matDPtr->resize(1, size_symm * size_symm);
117
118 CHKERR set_matrial_stiffens();
119
121}
122//! [Create common data]
123
124//! [Run problem]
136}
137//! [Run problem]
138
139//! [Read mesh]
143
144 MOFEM_LOG("EXAMPLE", Sev::inform)
145 << "Read mesh for problem in " << EXECUTABLE_DIMENSION;
147 CHKERR simple->loadFile();
149}
150//! [Read mesh]
151
152//! [Set up problem]
154 auto *simple = mField.getInterface<Simple>();
156 // Add field
158 SPACE_DIM);
159 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &order, PETSC_NULLPTR);
160 CHKERR simple->setFieldOrder("U", order);
161 CHKERR simple->setUp();
163}
164//! [Set up problem]
165
166//! [Boundary condition]
168 auto *simple = mField.getInterface<Simple>();
170
172 for (int n = 1; n != 6; ++n)
174
175 // Create space of vectors or rigid motion
176 auto problem_ptr = mField.get_problem(simple->getProblemName());
177 auto dofs = problem_ptr->getNumeredRowDofsPtr();
178
179 // Get all vertices
180 auto lo_uid =
181 DofEntity::getUniqueIdCalculate(0, get_id_for_min_type<MBVERTEX>());
182
183 auto hi = dofs->upper_bound(lo_uid);
184 std::array<double, 3> coords;
185
186 for (auto lo = dofs->lower_bound(lo_uid); lo != hi; ++lo) {
187
188 if ((*lo)->getPart() == mField.get_comm_rank()) {
189
190 auto ent = (*lo)->getEnt();
191 CHKERR mField.get_moab().get_coords(&ent, 1, coords.data());
192
193 if ((*lo)->getDofCoeffIdx() == 0) {
194 CHKERR VecSetValue(rigidBodyMotion[0], (*lo)->getPetscGlobalDofIdx(), 1,
195 INSERT_VALUES);
196 CHKERR VecSetValue(rigidBodyMotion[3], (*lo)->getPetscGlobalDofIdx(),
197 -coords[1], INSERT_VALUES);
198 if (SPACE_DIM == 3)
199 CHKERR VecSetValue(rigidBodyMotion[4], (*lo)->getPetscGlobalDofIdx(),
200 -coords[2], INSERT_VALUES);
201
202 } else if ((*lo)->getDofCoeffIdx() == 1) {
203 CHKERR VecSetValue(rigidBodyMotion[1], (*lo)->getPetscGlobalDofIdx(), 1,
204 INSERT_VALUES);
205 CHKERR VecSetValue(rigidBodyMotion[3], (*lo)->getPetscGlobalDofIdx(),
206 coords[0], INSERT_VALUES);
207 if (SPACE_DIM == 3)
208 CHKERR VecSetValue(rigidBodyMotion[5], (*lo)->getPetscGlobalDofIdx(),
209 -coords[2], INSERT_VALUES);
210
211 } else if ((*lo)->getDofCoeffIdx() == 2) {
212 if (SPACE_DIM == 3) {
213 CHKERR VecSetValue(rigidBodyMotion[2], (*lo)->getPetscGlobalDofIdx(),
214 1, INSERT_VALUES);
215 CHKERR VecSetValue(rigidBodyMotion[4], (*lo)->getPetscGlobalDofIdx(),
216 coords[0], INSERT_VALUES);
217 CHKERR VecSetValue(rigidBodyMotion[5], (*lo)->getPetscGlobalDofIdx(),
218 coords[1], INSERT_VALUES);
219 }
220 }
221 }
222 }
223
224 for (int n = 0; n != rigidBodyMotion.size(); ++n) {
225 CHKERR VecAssemblyBegin(rigidBodyMotion[n]);
226 CHKERR VecAssemblyEnd(rigidBodyMotion[n]);
227 CHKERR VecGhostUpdateBegin(rigidBodyMotion[n], INSERT_VALUES,
228 SCATTER_FORWARD);
229 CHKERR VecGhostUpdateEnd(rigidBodyMotion[n], INSERT_VALUES,
230 SCATTER_FORWARD);
231 }
232
234}
235//! [Boundary condition]
236
237//! [Assemble system]
240 auto *simple = mField.getInterface<Simple>();
241 auto *pipeline_mng = mField.getInterface<PipelineManager>();
242
243 auto dm = simple->getDM();
245 M = matDuplicate(K, MAT_SHARE_NONZERO_PATTERN);
246
247 auto calculate_stiffness_matrix = [&]() {
249 pipeline_mng->getDomainLhsFE().reset();
250
252 pipeline_mng->getOpDomainLhsPipeline(), {H1});
253
254 pipeline_mng->getOpDomainLhsPipeline().push_back(
255 new OpDomainGradGrad("U", "U", matDPtr));
256
257 auto integration_rule = [](int, int, int approx_order) {
258 return 2 * (approx_order - 1);
259 };
260
261 CHKERR pipeline_mng->setDomainLhsIntegrationRule(integration_rule);
262 pipeline_mng->getDomainLhsFE()->B = K;
263 CHKERR MatZeroEntries(K);
264 CHKERR pipeline_mng->loopFiniteElements();
265 CHKERR MatAssemblyBegin(K, MAT_FINAL_ASSEMBLY);
266 CHKERR MatAssemblyEnd(K, MAT_FINAL_ASSEMBLY);
268 };
269
270 auto calculate_mass_matrix = [&]() {
272 pipeline_mng->getDomainLhsFE().reset();
273
275 pipeline_mng->getOpDomainLhsPipeline(), {H1});
276
277 auto get_rho = [](const double, const double, const double) { return rho; };
278 pipeline_mng->getOpDomainLhsPipeline().push_back(
279 new OpDomainMass("U", "U", get_rho));
280
281 auto integration_rule = [](int, int, int approx_order) {
282 return 2 * approx_order;
283 };
284 CHKERR pipeline_mng->setDomainLhsIntegrationRule(integration_rule);
285 CHKERR MatZeroEntries(M);
286 pipeline_mng->getDomainLhsFE()->B = M;
287 CHKERR pipeline_mng->loopFiniteElements();
288 CHKERR MatAssemblyBegin(M, MAT_FINAL_ASSEMBLY);
289 CHKERR MatAssemblyEnd(M, MAT_FINAL_ASSEMBLY);
291 };
292
293 CHKERR calculate_stiffness_matrix();
294 CHKERR calculate_mass_matrix();
295
297}
298//! [Assemble system]
299
300//! [Solve]
303
304 auto create_eps = [](MPI_Comm comm) {
305 EPS eps;
306 CHKERR EPSCreate(comm, &eps);
307 return SmartPetscObj<EPS>(eps);
308 };
309
310 auto deflate_vectors = [&]() {
312 // Deflate vectors
313 std::array<Vec, 6> deflate_vectors;
314 for (int n = 0; n != 6; ++n) {
315 deflate_vectors[n] = rigidBodyMotion[n];
316 }
317 CHKERR EPSSetDeflationSpace(ePS, 6, &deflate_vectors[0]);
319 };
320
321 auto print_info = [&]() {
323 ST st;
324 EPSType type;
325 PetscReal tol;
326 PetscInt nev, maxit, its;
327 // Optional: Get some information from the solver and display it
328 CHKERR EPSGetIterationNumber(ePS, &its);
329 MOFEM_LOG_C("EXAMPLE", Sev::inform,
330 " Number of iterations of the method: %d", its);
331 CHKERR EPSGetST(ePS, &st);
332 CHKERR EPSGetType(ePS, &type);
333 MOFEM_LOG_C("EXAMPLE", Sev::inform, " Solution method: %s", type);
334 CHKERR EPSGetDimensions(ePS, &nev, NULL, NULL);
335 MOFEM_LOG_C("EXAMPLE", Sev::inform, " Number of requested eigenvalues: %d",
336 nev);
337 CHKERR EPSGetTolerances(ePS, &tol, &maxit);
338 MOFEM_LOG_C("EXAMPLE", Sev::inform,
339 " Stopping condition: tol=%.4g, maxit=%d", (double)tol, maxit);
340
341 PetscScalar eigr, eigi;
342 for (int nn = 0; nn < nev; nn++) {
343 CHKERR EPSGetEigenpair(ePS, nn, &eigr, &eigi, PETSC_NULLPTR,
344 PETSC_NULLPTR);
345 MOFEM_LOG_C("EXAMPLE", Sev::inform,
346 " ncov = %d eigr = %.4g eigi = %.4g (inv eigr = %.4g)", nn,
347 eigr, eigi, 1. / eigr);
348 }
349
351 };
352
353 auto setup_eps = [&]() {
355 CHKERR EPSSetProblemType(ePS, EPS_GHEP);
356 CHKERR EPSSetWhichEigenpairs(ePS, EPS_SMALLEST_MAGNITUDE);
357 CHKERR EPSSetFromOptions(ePS);
359 };
360
361 // Create eigensolver context
362 ePS = create_eps(mField.get_comm());
363 CHKERR EPSSetOperators(ePS, K, M);
364
365 // Setup eps
366 CHKERR setup_eps();
367
368 // Deflate vectors
369 CHKERR deflate_vectors();
370
371 // Solve problem
372 CHKERR EPSSolve(ePS);
373
374 // Print info
375 CHKERR print_info();
376
378}
379//! [Solve]
380
381//! [Postprocess results]
384 auto *pipeline_mng = mField.getInterface<PipelineManager>();
385 auto *simple = mField.getInterface<Simple>();
386
387 auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
388
390 post_proc_fe->getOpPtrVector(), {H1});
391
392 auto u_ptr = boost::make_shared<MatrixDouble>();
393 auto grad_ptr = boost::make_shared<MatrixDouble>();
394 auto strain_ptr = boost::make_shared<MatrixDouble>();
395 auto stress_ptr = boost::make_shared<MatrixDouble>();
396
397 post_proc_fe->getOpPtrVector().push_back(
399 post_proc_fe->getOpPtrVector().push_back(
401 post_proc_fe->getOpPtrVector().push_back(
402 new OpSymmetrizeTensor<SPACE_DIM>(grad_ptr, strain_ptr));
403 post_proc_fe->getOpPtrVector().push_back(
405 strain_ptr, stress_ptr, matDPtr));
406
408
409 post_proc_fe->getOpPtrVector().push_back(
410
411 new OpPPMap(
412 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
413
415
416 OpPPMap::DataMapMat{{"U", u_ptr}},
417
419
420 OpPPMap::DataMapMat{{"STRAIN", strain_ptr}, {"STRESS", stress_ptr}}
421
422 )
423
424 );
425
426 pipeline_mng->getDomainPostProcFE() = post_proc_fe;
427
428 auto dm = simple->getDM();
429 auto D = createDMVector(dm);
430
431 PetscInt nev;
432 CHKERR EPSGetDimensions(ePS, &nev, NULL, NULL);
433 PetscScalar eigr, eigi, nrm2r;
434 for (int nn = 0; nn < nev; nn++) {
435 CHKERR EPSGetEigenpair(ePS, nn, &eigr, &eigi, D, PETSC_NULLPTR);
436 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
437 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
438 CHKERR VecNorm(D, NORM_2, &nrm2r);
439 MOFEM_LOG_C("EXAMPLE", Sev::inform,
440 " ncov = %d omega2 = %.8g omega = %.8g frequency = %.8g", nn,
441 eigr, std::sqrt(std::abs(eigr)),
442 std::sqrt(std::abs(eigr)) / (2 * M_PI));
443 CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_REVERSE);
444 CHKERR pipeline_mng->loopFiniteElementsPostProc();
445 post_proc_fe->writeFile("out_eig_" + boost::lexical_cast<std::string>(nn) +
446 ".h5m");
447 }
448
450}
451//! [Postprocess results]
452
453//! [Check]
456 PetscBool test_flg = PETSC_FALSE;
457 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test", &test_flg,
458 PETSC_NULLPTR);
459 if (test_flg) {
460 PetscScalar eigr, eigi;
461 CHKERR EPSGetEigenpair(ePS, 0, &eigr, &eigi, PETSC_NULLPTR, PETSC_NULLPTR);
462 constexpr double regression_value = 12579658;
463 if (fabs(eigr - regression_value) > 1)
464 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
465 "Regression test faileed; wrong eigen value.");
466 }
468}
469//! [Check]
470
471static char help[] = "...\n\n";
472
473//! [Main]
474int main(int argc, char *argv[]) {
475
476 // Initialisation of MoFEM/PETSc and MOAB data structures
477 const char param_file[] = "param_file.petsc";
478 SlepcInitialize(&argc, &argv, param_file, help);
479 MoFEM::Core::Initialize(&argc, &argv, param_file, help);
480
481 // Add logging channel for example
482 auto core_log = logging::core::get();
483 core_log->add_sink(
485 LogManager::setLog("EXAMPLE");
486 MOFEM_LOG_TAG("EXAMPLE", "example");
487
488 try {
489
490 //! [Register MoFEM discrete manager in PETSc]
491 DMType dm_name = "DMMOFEM";
492 CHKERR DMRegister_MoFEM(dm_name);
493 //! [Register MoFEM discrete manager in PETSc
494
495 //! [Create MoAB]
496 moab::Core mb_instance; ///< mesh database
497 moab::Interface &moab = mb_instance; ///< mesh database interface
498 //! [Create MoAB]
499
500 //! [Create MoFEM]
501 MoFEM::Core core(moab); ///< finite element database
502 MoFEM::Interface &m_field = core; ///< finite element database insterface
503 //! [Create MoFEM]
504
505 //! [Example]
506 Example ex(m_field);
507 CHKERR ex.runProblem();
508 //! [Example]
509 }
511
512 SlepcFinalize();
514}
515//! [Main]
std::string type
#define MOFEM_LOG_C(channel, severity, format,...)
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
int main()
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, FIELD_DIM > OpDomainMass
Kronecker Delta class symmetric.
#define CATCH_ERRORS
Catch errors.
@ 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 ...
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr int order
double bulk_modulus_K
double shear_modulus_G
double young_modulus
static char help[]
[Check]
double rho
[Operators_definition]
constexpr int SPACE_DIM
double poisson_ratio
int order
[Physical_parameters]
double bulk_modulus_K
double shear_modulus_G
auto integration_rule
constexpr auto t_kd
PetscErrorCode DMCreateMatrix_MoFEM(DM dm, Mat *M)
Definition DMMoFEM.cpp:1188
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
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1237
virtual const Problem * get_problem(const std::string problem_name) const =0
Get the problem object.
@ GAUSS
Gaussian quadrature integration.
@ PETSC
Standard PETSc assembly.
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
FTensor::Index< 'i', SPACE_DIM > i
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradGrad< 1, 1, SPACE_DIM > OpDomainGradGrad
Definition helmholtz.cpp:25
double D
const double n
refractive index of diffusive medium
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
double tol
const double eps
Definition HenckyOps.hpp:13
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
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)
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
SmartPetscObj< Mat > matDuplicate(Mat mat, MatDuplicateOption op)
constexpr AssemblyType A
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
static constexpr int approx_order
[Operators_definition]
[Example]
Definition plastic.cpp:217
MoFEMErrorCode boundaryCondition()
MoFEMErrorCode assembleSystem()
MoFEMErrorCode readMesh()
MoFEMErrorCode checkResults()
MoFEMErrorCode solveSystem()
MoFEMErrorCode createCommonData()
boost::shared_ptr< MatrixDouble > matDPtr
std::array< SmartPetscObj< Vec >, 6 > rigidBodyMotion
Example(MoFEM::Interface &m_field)
SmartPetscObj< Mat > M
MoFEMErrorCode runProblem()
SmartPetscObj< EPS > ePS
SmartPetscObj< Mat > K
MoFEM::Interface & mField
Reference to MoFEM interface.
Definition plastic.cpp:227
MoFEMErrorCode setupProblem()
MoFEMErrorCode outputResults()
Add operators pushing bases from local to physical configuration.
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:83
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition Core.cpp:68
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition Core.cpp:123
Deprecated interface functions.
static UId getUniqueIdCalculate(const DofIdx dof, UId ent_uid)
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for MatrixDouble vector field values calculation.
Post post-proc data at points from hash maps.
std::map< std::string, ScalarDataPtr > DataMapVec
std::map< std::string, boost::shared_ptr< MatrixDouble > > DataMapMat
Operator for symmetrizing tensor fields.
PipelineManager interface.
auto & getNumeredRowDofsPtr() const
get access to numeredRowDofsPtr storing DOFs on rows
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:261
MoFEMErrorCode getOptions()
get options
Definition Simple.cpp:180
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
double young_modulus
Young modulus.
Definition plastic.cpp:126
double rho
Definition plastic.cpp:145
#define EXECUTABLE_DIMENSION
Definition plastic.cpp:13
double poisson_ratio
Poisson ratio.
Definition plastic.cpp:127
constexpr auto size_symm
Definition plastic.cpp:42
constexpr int SPACE_DIM