v0.16.0
Loading...
Searching...
No Matches
nonlinear_dynamic_elastic.cpp
Go to the documentation of this file.
1/**
2 * \file dynamic_elastic.cpp
3 * \example mofem/tutorials/vec-3_nonlinear_dynamics/nonlinear_dynamic_elastic.cpp
4 *
5 * Plane stress elastic dynamic problem
6 *
7 */
8
9#include <MoFEM.hpp>
10#include <MatrixFunction.hpp>
11using namespace MoFEM;
12
13template <int DIM> struct ElementsAndOps {};
14
15template <> struct ElementsAndOps<2> {
17};
18
19template <> struct ElementsAndOps<3> {
21};
22
23constexpr int SPACE_DIM =
24 EXECUTABLE_DIMENSION; //< Space dimension of problem, mesh
25
28using DomainEleOp = DomainEle::UserDataOperator;
30
35
40 SPACE_DIM>;
41
42constexpr double rho = 1;
43constexpr double omega = 2.4;
44[[maybe_unused]] constexpr double young_modulus = 1;
45[[maybe_unused]] constexpr double poisson_ratio = 0.25;
46
47#include <HenckyOps.hpp>
48using namespace HenckyOps;
49
50struct Example {
51
52 Example(MoFEM::Interface &m_field) : mField(m_field) {}
53
55
56private:
58
66};
67
68//! [Run problem]
79}
80//! [Run problem]
81
82//! [Read mesh]
87 CHKERR simple->loadFile();
89}
90//! [Read mesh]
91
92//! [Set up problem]
96 // Add field
98 SPACE_DIM);
99 CHKERR simple->addDataField("GEOMETRY", H1, AINSWORTH_LEGENDRE_BASE,
100 SPACE_DIM);
101 int order = 2;
102 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &order, PETSC_NULLPTR);
103 CHKERR simple->setFieldOrder("U", order);
104 CHKERR simple->setFieldOrder("GEOMETRY", order);
105 CHKERR simple->setUp();
106
107 auto project_ho_geometry = [&]() {
108 Projection10NodeCoordsOnField ent_method(mField, "GEOMETRY");
109 return mField.loop_dofs("GEOMETRY", ent_method);
110 };
111 CHKERR project_ho_geometry();
112
114}
115//! [Set up problem]
116
117//! [Boundary condition]
120
122 auto bc_mng = mField.getInterface<BcManager>();
123
124 CHKERR bc_mng->removeBlockDOFsOnEntities<DisplacementCubitBcData>(
125 simple->getProblemName(), "U");
126
128}
129//! [Boundary condition]
130
131//! [Push operators to pipeline]
134 auto *pipeline_mng = mField.getInterface<PipelineManager>();
135
136 [[maybe_unused]] auto get_body_force = [this](const double, const double,
137 const double) {
140 t_source(i) = 0.;
141 t_source(0) = 0.1;
142 t_source(1) = 1.;
143 return t_source;
144 };
145
146 auto rho_ptr = boost::make_shared<double>(rho);
147
148 auto add_rho_block = [this, rho_ptr](auto &pip, auto block_name, Sev sev) {
150
151 struct OpMatRhoBlocks : public DomainEleOp {
152 OpMatRhoBlocks(boost::shared_ptr<double> rho_ptr,
153 MoFEM::Interface &m_field, Sev sev,
154 std::vector<const CubitMeshSets *> meshset_vec_ptr)
155 : DomainEleOp(NOSPACE, DomainEleOp::OPSPACE), rhoPtr(rho_ptr) {
156 CHK_THROW_MESSAGE(extractRhoData(m_field, meshset_vec_ptr, sev),
157 "Can not get data from block");
158 }
159
160 MoFEMErrorCode doWork(int side, EntityType type,
162
164
165 for (auto &b : blockData) {
166 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
167 *rhoPtr = b.rho;
169 }
170 }
171
172 *rhoPtr = rho;
173
175 }
176
177 private:
178 struct BlockData {
179 double rho;
180 Range blockEnts;
181 };
182
183 std::vector<BlockData> blockData;
184
186 extractRhoData(MoFEM::Interface &m_field,
187 std::vector<const CubitMeshSets *> meshset_vec_ptr,
188 Sev sev) {
190
191 for (auto m : meshset_vec_ptr) {
192 MOFEM_TAG_AND_LOG("WORLD", sev, "Mat Rho Block") << *m;
193 std::vector<double> block_data;
194 CHKERR m->getAttributes(block_data);
195 if (block_data.size() < 1) {
196 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
197 "Expected that block has two attributes");
198 }
199 auto get_block_ents = [&]() {
200 Range ents;
201 CHKERR
202 m_field.get_moab().get_entities_by_handle(m->meshset, ents, true);
203 return ents;
204 };
205
206 MOFEM_TAG_AND_LOG("WORLD", sev, "Mat Rho Block")
207 << m->getName() << ": ro = " << block_data[0];
208
209 blockData.push_back({block_data[0], get_block_ents()});
210 }
211 MOFEM_LOG_CHANNEL("WORLD");
212 MOFEM_LOG_CHANNEL("WORLD");
214 }
215
216 boost::shared_ptr<double> rhoPtr;
217 };
218
219 pip.push_back(new OpMatRhoBlocks(
220 rho_ptr, mField, sev,
221
222 // Get blockset using regular expression
224
225 (boost::format("%s(.*)") % block_name).str()
226
227 ))
228
229 ));
231 };
232
233 // Get pointer to U_tt shift in domain element
234 auto get_rho = [rho_ptr](const double, const double, const double) {
235 return *rho_ptr;
236 };
237
238 // specific time scaling
239 [[maybe_unused]] auto get_time_scale = [this](const double time) {
240 return sin(time * omega * M_PI);
241 };
242
243 auto apply_lhs = [&](auto &pip) {
246 "GEOMETRY");
247 CHKERR HenckyOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
248 mField, pip, "U", "MAT_ELASTIC", Sev::verbose);
249 CHKERR add_rho_block(pip, "MAT_RHO", Sev::verbose);
250
251 pip.push_back(new OpMass("U", "U", get_rho));
252 static_cast<OpMass &>(pip.back()).feScalingFun =
253 [](const FEMethod *fe_ptr) { return fe_ptr->ts_aa; };
255 };
256
257 auto apply_rhs = [&](auto &pip) {
259
261 pipeline_mng->getOpDomainRhsPipeline(), {H1}, "GEOMETRY");
262 CHKERR HenckyOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
263 mField, pip, "U", "MAT_ELASTIC", Sev::inform);
264 CHKERR add_rho_block(pip, "MAT_RHO", Sev::inform);
265
266 auto mat_acceleration_ptr = boost::make_shared<MatrixDouble>();
267 // Apply inertia
269 "U", mat_acceleration_ptr));
270 pip.push_back(new OpInertiaForce("U", mat_acceleration_ptr, get_rho));
271
273 pip, mField, "U", {},
274 {boost::make_shared<TimeScaleVector<SPACE_DIM>>("-time_vector_file",
275 true)},
276 "BODY_FORCE", Sev::inform);
277
279 };
280
281 CHKERR apply_lhs(pipeline_mng->getOpDomainLhsPipeline());
282 CHKERR apply_rhs(pipeline_mng->getOpDomainRhsPipeline());
283
284 auto integration_rule = [](int, int, int approx_order) {
285 return 2 * approx_order;
286 };
287 CHKERR pipeline_mng->setDomainRhsIntegrationRule(integration_rule);
288 CHKERR pipeline_mng->setDomainLhsIntegrationRule(integration_rule);
289
290 auto get_bc_hook = [&]() {
292 mField, pipeline_mng->getDomainRhsFE(),
293 {boost::make_shared<TimeScale>()});
294 return hook;
295 };
296
297 pipeline_mng->getDomainRhsFE()->preProcessHook = get_bc_hook();
298
300}
301//! [Push operators to pipeline]
302
303/**
304 * @brief Monitor solution
305 *
306 * This functions is called by TS solver at the end of each step. It is used
307 * to output results to the hard drive.
308 */
309struct Monitor : public FEMethod {
310 Monitor(SmartPetscObj<DM> dm, boost::shared_ptr<PostProcEle> post_proc)
311 : dM(dm), postProc(post_proc){};
314 constexpr int save_every_nth_step = 1;
315 if (ts_step % save_every_nth_step == 0) {
317 CHKERR postProc->writeFile(
318 "out_step_" + boost::lexical_cast<std::string>(ts_step) + ".h5m");
319 }
321 }
322
323private:
325 boost::shared_ptr<PostProcEle> postProc;
326};
327
328//! [Solve]
331 auto *simple = mField.getInterface<Simple>();
332 auto *pipeline_mng = mField.getInterface<PipelineManager>();
333
334 auto dm = simple->getDM();
336 ts = pipeline_mng->createTSIM2();
337
338 // Setup postprocessing
339 auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
341 post_proc_fe->getOpPtrVector(), {H1});
342 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
343 mField, post_proc_fe->getOpPtrVector(), "U", "MAT_ELASTIC", Sev::inform);
344
345 auto u_ptr = boost::make_shared<MatrixDouble>();
346 post_proc_fe->getOpPtrVector().push_back(
348 auto X_ptr = boost::make_shared<MatrixDouble>();
349 post_proc_fe->getOpPtrVector().push_back(
350 new OpCalculateVectorFieldValues<SPACE_DIM>("GEOMETRY", X_ptr));
351
353
354 post_proc_fe->getOpPtrVector().push_back(
355
356 new OpPPMap(
357
358 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
359
360 {},
361
362 {{"U", u_ptr}, {"GEOMETRY", X_ptr}},
363
364 {{"GRAD", common_ptr->matGradPtr},
365 {"FIRST_PIOLA", common_ptr->getMatFirstPiolaStress()}},
366
367 {}
368
369 )
370
371 );
372
373 // Add monitor to time solver
374 boost::shared_ptr<FEMethod> null_fe;
375 auto monitor_ptr = boost::make_shared<Monitor>(dm, post_proc_fe);
376 CHKERR DMMoFEMTSSetMonitor(dm, ts, simple->getDomainFEName(), null_fe,
377 null_fe, monitor_ptr);
378
379 double ftime = 1;
380 // CHKERR TSSetMaxTime(ts, ftime);
381 CHKERR TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
382
383 auto T = createDMVector(simple->getDM());
384 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
385 SCATTER_FORWARD);
386 auto TT = vectorDuplicate(T);
387 CHKERR TS2SetSolution(ts, T, TT);
388 auto B = createDMMatrix(dm);
389 CHKERR TSSetI2Jacobian(ts, B, B, PETSC_NULLPTR, PETSC_NULLPTR);
390 CHKERR TSSetFromOptions(ts);
391
392 CHKERR TSSolve(ts, NULL);
393 CHKERR TSGetTime(ts, &ftime);
394
395 PetscInt steps, snesfails, rejects, nonlinits, linits;
396#if PETSC_VERSION_GE(3, 8, 0)
397 CHKERR TSGetStepNumber(ts, &steps);
398#else
399 CHKERR TSGetStepNumber(ts, &steps);
400#endif
401 CHKERR TSGetSNESFailures(ts, &snesfails);
402 CHKERR TSGetStepRejections(ts, &rejects);
403 CHKERR TSGetSNESIterations(ts, &nonlinits);
404 CHKERR TSGetKSPIterations(ts, &linits);
405 MOFEM_LOG_C("EXAMPLE", Sev::inform,
406 "steps %d (%d rejected, %d SNES fails), ftime %g, nonlinits "
407 "%d, linits %d\n",
408 steps, rejects, snesfails, ftime, nonlinits, linits);
409
411}
412//! [Solve]
413
414//! [Postprocess results]
417 PetscBool test_flg = PETSC_FALSE;
418 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test", &test_flg, PETSC_NULLPTR);
419 if (test_flg) {
420 auto *simple = mField.getInterface<Simple>();
421 auto T = createDMVector(simple->getDM());
422 CHKERR DMoFEMMeshToLocalVector(simple->getDM(), T, INSERT_VALUES,
423 SCATTER_FORWARD);
424 double nrm2;
425 CHKERR VecNorm(T, NORM_2, &nrm2);
426 MOFEM_LOG("EXAMPLE", Sev::inform) << "Regression norm " << nrm2;
427 constexpr double regression_value = 0.0194561;
428 if (fabs(nrm2 - regression_value) > 1e-2)
429 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
430 "Regression test failed; wrong norm value.");
431 }
433}
434//! [Postprocess results]
435
436//! [Check]
440}
441//! [Check]
442
443static char help[] = "...\n\n";
444
445int main(int argc, char *argv[]) {
446
447 // Initialisation of MoFEM/PETSc and MOAB data structures
448 const char param_file[] = "param_file.petsc";
449 MoFEM::Core::Initialize(&argc, &argv, param_file, help);
450
451 // Add logging channel for example
452 auto core_log = logging::core::get();
453 core_log->add_sink(
455 LogManager::setLog("EXAMPLE");
456 MOFEM_LOG_TAG("EXAMPLE", "example");
457
458 try {
459
460 //! [Register MoFEM discrete manager in PETSc]
461 DMType dm_name = "DMMOFEM";
462 CHKERR DMRegister_MoFEM(dm_name);
463 //! [Register MoFEM discrete manager in PETSc
464
465 //! [Create MoAB]
466 moab::Core mb_instance; ///< mesh database
467 moab::Interface &moab = mb_instance; ///< mesh database interface
468 //! [Create MoAB]
469
470 //! [Create MoFEM]
471 MoFEM::Core core(moab); ///< finite element database
472 MoFEM::Interface &m_field = core; ///< finite element database interface
473 //! [Create MoFEM]
474
475 //! [Example]
476 Example ex(m_field);
477 CHKERR ex.runProblem();
478 //! [Example]
479 }
481
483}
std::string type
#define MOFEM_LOG_C(channel, severity, format,...)
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
int main()
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ AINSWORTH_BERNSTEIN_BEZIER_BASE
Definition definitions.h:64
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ H1
continuous field
Definition definitions.h:85
@ NOSPACE
Definition definitions.h:83
#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
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr int order
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesVector< 1, SPACE_DIM, SPACE_DIM > OpInertiaForce
constexpr double omega
Save field DOFS on vertices/tags.
auto integration_rule
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
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
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1237
auto createDMMatrix(DM dm)
Get smart matrix from DM.
Definition DMMoFEM.hpp:1194
@ 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.
SeverityLevel
Severity levels.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
FTensor::Index< 'i', SPACE_DIM > i
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
PetscErrorCode DMMoFEMTSSetMonitor(DM dm, TS ts, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
Set Monitor To TS solver.
Definition DMMoFEM.cpp:1046
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)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
constexpr double rho
static char help[]
[Check]
constexpr int SPACE_DIM
constexpr double poisson_ratio
constexpr double omega
constexpr double young_modulus
int save_every_nth_step
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
static constexpr int approx_order
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMass
[Only used with Hooke equation (linear material model)]
Definition seepage.cpp:56
FTensor::Index< 'm', 3 > m
[Example]
Definition plastic.cpp:217
MoFEMErrorCode boundaryCondition()
MoFEMErrorCode assembleSystem()
MoFEMErrorCode readMesh()
MoFEMErrorCode checkResults()
MoFEMErrorCode solveSystem()
Example(MoFEM::Interface &m_field)
MoFEMErrorCode runProblem()
MoFEM::Interface & mField
Reference to MoFEM interface.
Definition plastic.cpp:227
MoFEMErrorCode setupProblem()
MoFEMErrorCode outputResults()
Add operators pushing bases from local to physical configuration.
Boundary condition manager for finite element problem setup.
virtual moab::Interface & get_moab()=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.
Definition of the displacement bc data structure.
Definition BCData.hpp:72
Data on single entity (This is passed as argument to DataOperator::doWork)
Class (Function) to enforce essential constrains.
Definition Essential.hpp:25
Structure for user loop methods on finite elements.
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.
Interface for managing meshsets containing materials and boundary conditions.
Assembly methods.
Definition Natural.hpp:65
Approximate field values for given petsc vector.
Specialization for MatrixDouble vector field values calculation.
Post post-proc data at points from hash maps.
PipelineManager interface.
Projection of edge entities with one mid-node on hierarchical basis.
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
PetscInt ts_step
Current time step number.
PetscReal ts_aa
Shift parameter for U_tt (second time derivative)
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
[Push operators to pipeline]
Monitor(SmartPetscObj< DM > dm, boost::shared_ptr< PostProcEle > post_proc)
SmartPetscObj< DM > dM
MoFEMErrorCode postProcess()
Post-processing function executed at loop completion.
boost::shared_ptr< PostProcEle > postProc
double rho
Definition plastic.cpp:145
#define EXECUTABLE_DIMENSION
Definition plastic.cpp:13
constexpr int SPACE_DIM