v0.16.3
Loading...
Searching...
No Matches
ElasticAdaptiveExample.hpp
Go to the documentation of this file.
1/**
2 * @file ElasticAdaptiveExample.hpp
3 * @brief elastic example with adaptive order refinement
4 *
5 * @copyright Copyright (c) 2026
6 *
7 */
8
9#include <ElasticExample.hpp>
11
13
15
16 MoFEMErrorCode runProblem();
17
18private:
19 MoFEMErrorCode readMesh();
20 MoFEMErrorCode setupAdaptivity();
21 MoFEMErrorCode computeErrorNorms();
22 MoFEMErrorCode outputResults(int ref_iter = -1);
23 MoFEMErrorCode refineOrder(int ref_level);
24 MoFEMErrorCode computeErrorIndicators();
25 MoFEMErrorCode refineGeometry();
26 MoFEMErrorCode calculateGeometryError();
27 MoFEMErrorCode kspSetUpAndSolve(SmartPetscObj<KSP> solver) override;
28
29 int oRder = 2;
30 PetscBool refGeom = PETSC_FALSE;
31 int refAdaptNum = 0;
33 double refGeomThreshold = 1;
34 std::array<double, 2> meanError = {0.0, 0.0};
35 double errorIndicMean = 0.0;
36
37 int atomTest = 0;
38};
39
41
42#include <AdaptiveOrderRef.hpp>
44
45//! [Run problem]
76//! [Run problem]
77
78//! [Read mesh]
81 auto simple = mField.getInterface<Simple>();
82 CHKERR simple->getOptions();
83
84 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-ref_geom", &refGeom,
85 PETSC_NULLPTR);
86
87 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-ref_adapt_num", &refAdaptNum,
88 PETSC_NULLPTR);
89
90 if ((refAdaptNum > 0) && refGeom) {
91 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
92 "Adaptive order and geometry refinement cannot be used together");
93 }
94
95 simple->getAddSkeletonFE() = true;
96 CHKERR simple->loadFile();
97
98 // Add meshsets if config file provided
99 CHKERR mField.getInterface<MeshsetsManager>()->setMeshsetFromFile();
100
101 auto update_ghost_ents = [&]() {
103
104 for (auto m : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
105 std::regex((boost::format("%s(.*)") % "MAT_ELASTIC").str()))
106
107 ) {
108 Range ents;
109 CHKERR mField.get_moab().get_entities_by_handle(m->getMeshset(), ents,
110 true);
111 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(ents);
112 CHKERR mField.get_moab().add_entities(m->getMeshset(), ents);
113 }
114
116 };
117
118 CHKERR update_ghost_ents();
119
121}
122//! [Read mesh]
123
124//! [Set up problem]
127
128 Range domainEntities;
129 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
130 domainEntities);
131 Tag th_order;
132 CHKERR getTagHandle(mField, "ORDER", MB_TYPE_INTEGER, th_order);
133
134 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &oRder, PETSC_NULLPTR);
135 for (auto ent : domainEntities) {
136 CHKERR mField.get_moab().tag_set_data(th_order, &ent, 1, &oRder);
137 }
138
139 CHKERR copyTagOnSkin(mField, "ORDER", MB_TYPE_INTEGER);
140
141 if (refGeom) {
143 CHKERR refineGeometry(); // optional ho refinement
144 }
145
146 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-test", &atomTest,
147 PETSC_NULLPTR);
148
150}
151//! [Set up problem]
152
153// ! [KSP set up]
154MoFEMErrorCode
157
158 MOFEM_LOG_CHANNEL("TIMER");
159 MOFEM_LOG_TAG("TIMER", "timer");
160
161 DM dm;
162 CHKERR KSPGetDM(solver, &dm);
163 auto D = createDMVector(dm);
164 auto F = vectorDuplicate(D);
165
166 CHKERR VecZeroEntries(D);
167 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
168 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
169 CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_REVERSE);
170
171 BOOST_LOG_SCOPED_THREAD_ATTR("Timeline", attrs::timer());
172 MOFEM_LOG("TIMER", Sev::inform) << "KSPSetUp";
173 CHKERR KSPSetUp(solver);
174 MOFEM_LOG("TIMER", Sev::inform) << "KSPSetUp <= Done";
175 MOFEM_LOG("TIMER", Sev::inform) << "KSPSolve";
176 CHKERR KSPSolve(solver, F, D);
177 CHKERR mField.getInterface<TestingInterface>()->checkSolver(
178 solver, "elasticity adaptive");
179 MOFEM_LOG("TIMER", Sev::inform) << "KSPSolve <= Done";
180
181 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
182 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
183 CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_REVERSE);
184
186}
187// ! [KSP set up]
188
190 lame_solution(0.5, 1.0, 2.0, 1.0, 1e3, 0.3);
191
193 [](double x, double y, double z) {
194 return lame_solution.displacement(x, y, z);
195 };
196
197//! [Postprocess results]
198MoFEMErrorCode ElasticAdaptiveExample::outputResults(int ref_iter) {
200 auto simple = mField.getInterface<Simple>();
201
202 std::ostringstream strm;
203 strm << "out_elastic";
204 if (ref_iter >= 0) {
205 strm << "_" << ref_iter;
206 }
207 strm << ".h5m";
208
211 mField, simple->getDM(), simple->getDomainFEName(), strm.str(), {},
212 {"GEOMETRY_ERROR", "SOLUTION_ERROR", "ORDER"}, Sev::verbose);
214}
215//! [Postprocess results]
216
217//! [Error Norms]
219 MOFEM_LOG_CHANNEL("WORLD");
220 auto simple = mField.getInterface<Simple>();
222
223 auto integration_rule = [](int, int, int p_data) { return p_data + 1; };
224 auto evaluation_fe = boost::make_shared<DomainEle>(mField);
225 evaluation_fe->getRuleHook = integration_rule;
226
227 auto &evaluation_pipeline = evaluation_fe->getOpPtrVector();
228 CHKERR AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(evaluation_pipeline,
229 {H1}, "GEOMETRY");
230
231 auto u_ptr = boost::make_shared<MatrixDouble>();
232 evaluation_pipeline.push_back(
233 new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
234
235 auto analytical_disp_ptr = boost::make_shared<MatrixDouble>();
236
237 evaluation_pipeline.push_back(new OpGetTensor1fromFunc<SPACE_DIM, SPACE_DIM>(
238 analytical_disp_ptr, analyticalDisplacement));
239
240 auto normsVec = createVectorMPI(mField.get_comm(),
241 (mField.get_comm_rank() == 0) ? 1 : 0, 1);
242
243 evaluation_pipeline.push_back(new OpCalcNormL2Tensor1<SPACE_DIM>(
244 u_ptr, normsVec, 0, analytical_disp_ptr));
245
246 CHKERR VecZeroEntries(normsVec);
247 CHKERR DMoFEMLoopFiniteElements(simple->getDM(), simple->getDomainFEName(),
248 evaluation_fe);
249 CHKERR VecAssemblyBegin(normsVec);
250 CHKERR VecAssemblyEnd(normsVec);
251
252 if (mField.get_comm_rank() == 0) {
253 const double *norms;
254 CHKERR VecGetArrayRead(normsVec, &norms);
255 MOFEM_TAG_AND_LOG("SELF", Sev::inform, "Errors")
256 << "Displacement error L2 norm: " << std::scientific
257 << std::sqrt(norms[0]);
258
259 if (atomTest == 3 && std::sqrt(norms[0]) > 2.195e-06) {
260 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
261 "atom test failed: displacement error L2 norm is too high: "
262 "%3.6e",
263 std::sqrt(norms[0]));
264 }
265
266 if (atomTest == 4 && std::sqrt(norms[0]) > 1.995e-07) {
267 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
268 "atom test failed: displacement error L2 norm is too high: "
269 "%3.6e",
270 std::sqrt(norms[0]));
271 }
272
273 CHKERR VecRestoreArrayRead(normsVec, &norms);
274 }
275
277}
278//! [Error Norms]
Calculate error indicators.
static MoFEMErrorCode getTagHandle(MoFEM::Interface &m_field, const char *name, DataType type, Tag &tag_handle)
static MoFEMErrorCode copyTagOnSkin(MoFEM::Interface &m_field, const char *name, DataType type)
MoFEM::VectorFunc analyticalDisplacement
const AnalyticalSolutions::HollowCylinderUnderRadialPressure< SPACE_DIM > lame_solution(0.5, 1.0, 2.0, 1.0, 1e3, 0.3)
Implementation of elastic example class.
Higher Order Geometry refinement.
#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
constexpr int SPACE_DIM
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
@ 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
@ 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.
@ F
auto integration_rule
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
double D
MoFEMErrorCode postProcessElasticResults(MoFEM::Interface &mField, SmartPetscObj< DM > dm, const std::string &domain_fe_name, const std::string &out_file_name, std::vector< std::pair< std::string, SmartPetscObj< Vec > > > extra_vectors={}, const std::vector< std::string > &tags_to_transfer={}, const Sev hooke_ops_sev=Sev::verbose)
boost::function< VectorDouble(const double, const double, const double)> VectorFunc
ElementsAndOps< SPACE_DIM >::SideEle SideEle
Definition plastic.cpp:62
FTensor::Index< 'm', 3 > m
Lamé analytical solution for a hollow cylinder under radial pressure with a linear isotropic Hooke ma...
MoFEMErrorCode calculateGeometryError()
Calculate geometry error and save on a tag.
MoFEMErrorCode computeErrorNorms()
[Postprocess results]
ElasticAdaptiveExample(MoFEM::Interface &m_field)
std::array< double, 2 > meanError
MoFEMErrorCode kspSetUpAndSolve(SmartPetscObj< KSP > solver) override
[Set up problem]
MoFEMErrorCode refineOrder(int ref_level)
MoFEMErrorCode computeErrorIndicators()
MoFEMErrorCode runProblem()
[Run problem]
MoFEMErrorCode readMesh()
[Run problem]
MoFEMErrorCode setupAdaptivity()
[Read mesh]
virtual MoFEMErrorCode solveSystem()
[Solve]
virtual MoFEMErrorCode outputResults()
[Solve]
virtual MoFEMErrorCode assembleSystem()
virtual MoFEMErrorCode setupProblem()
[Read mesh]
MoFEM::Interface & mField
virtual MoFEMErrorCode boundaryCondition()
[Set up problem]
virtual MoFEMErrorCode checkResults()
[Postprocess results]
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Deprecated interface functions.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.