v0.16.0
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>
10
12
14
15 MoFEMErrorCode runProblem();
16
17private:
18 MoFEMErrorCode readMesh();
19 MoFEMErrorCode setupAdaptivity();
20 MoFEMErrorCode resetPipelines();
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]
78//! [Run problem]
79
80//! [Read mesh]
83 auto simple = mField.getInterface<Simple>();
84 CHKERR simple->getOptions();
85
86 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-ref_geom", &refGeom,
87 PETSC_NULLPTR);
88
89 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-ref_adapt_num", &refAdaptNum,
90 PETSC_NULLPTR);
91
92 if ((refAdaptNum > 0) && refGeom) {
93 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
94 "Adaptive order and geometry refinement cannot be used together");
95 }
96
97 simple->getAddSkeletonFE() = true;
98 CHKERR simple->loadFile();
99
100 // Add meshsets if config file provided
101 CHKERR mField.getInterface<MeshsetsManager>()->setMeshsetFromFile();
102
103 auto update_ghost_ents = [&]() {
105
106 for (auto m : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
107 std::regex((boost::format("%s(.*)") % "MAT_ELASTIC").str()))
108
109 ) {
110 Range ents;
111 CHKERR mField.get_moab().get_entities_by_handle(m->getMeshset(), ents,
112 true);
113 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(ents);
114 CHKERR mField.get_moab().add_entities(m->getMeshset(), ents);
115 }
116
118 };
119
120 CHKERR update_ghost_ents();
121
123}
124//! [Read mesh]
125
126//! [Set up problem]
129
130 Range domainEntities;
131 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
132 domainEntities);
133 Tag th_order;
134 CHKERR getTagHandle(mField, "ORDER", MB_TYPE_INTEGER, th_order);
135
136 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &oRder, PETSC_NULLPTR);
137 for (auto ent : domainEntities) {
138 CHKERR mField.get_moab().tag_set_data(th_order, &ent, 1, &oRder);
139 }
140
141 CHKERR copyTagOnSkin(mField, "ORDER", MB_TYPE_INTEGER);
142
143 if (refGeom) {
145 CHKERR refineGeometry(); // optional ho refinement
146 }
147
148 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-test", &atomTest,
149 PETSC_NULLPTR);
150
152}
153//! [Set up problem]
154
155//! [Reset pipelines]
158 auto pip = mField.getInterface<PipelineManager>();
159
160 pip->getDomainLhsFE().reset();
161 pip->getDomainRhsFE().reset();
162 pip->getBoundaryRhsFE().reset();
163 pip->getBoundaryLhsFE().reset();
164 pip->getSkeletonLhsFE().reset();
165 pip->getSkeletonRhsFE().reset();
166
168}
169//! [Reset pipelines]
170
171// ! [KSP set up]
172MoFEMErrorCode
175
176 MOFEM_LOG_CHANNEL("TIMER");
177 MOFEM_LOG_TAG("TIMER", "timer");
178
179 DM dm;
180 CHKERR KSPGetDM(solver, &dm);
181 auto D = createDMVector(dm);
182 auto F = vectorDuplicate(D);
183
184 CHKERR VecZeroEntries(D);
185 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
186 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
187 CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_REVERSE);
188
189 BOOST_LOG_SCOPED_THREAD_ATTR("Timeline", attrs::timer());
190 MOFEM_LOG("TIMER", Sev::inform) << "KSPSetUp";
191 CHKERR KSPSetUp(solver);
192 MOFEM_LOG("TIMER", Sev::inform) << "KSPSetUp <= Done";
193 MOFEM_LOG("TIMER", Sev::inform) << "KSPSolve";
194 CHKERR KSPSolve(solver, F, D);
195 MOFEM_LOG("TIMER", Sev::inform) << "KSPSolve <= Done";
196
197 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
198 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
199 CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_REVERSE);
200
202}
203// ! [KSP set up]
204
205inline auto sqr = [](double v) { return v * v; };
206
207inline MoFEM::VectorFunc analyticalDisplacement = [](double x, double y,
208 double z) {
209 double E = 1e3;
210 double nu = 0.3;
211
212 double r = std::sqrt(x * x + y * y);
213
214 double a = 0.5;
215 double b = 1.0;
216
217 double pa = 2;
218 double pb = 1;
219
220 double A = (pa * sqr(a) - pb * sqr(b)) / (sqr(b) - sqr(a));
221 double B = sqr(a) * sqr(b) * (pa - pb) / (sqr(b) - sqr(a));
222
223 VectorDouble u;
224 u.resize(SPACE_DIM);
225 std::vector<double> v_u;
226
227 double u_r = (1. + nu) / E * ((1. - 2. * nu) * A * r + B / r);
228
229 if (SPACE_DIM == 2)
230 v_u = {u_r / r * x, u_r / r * y};
231 else
232 v_u = {u_r / r * x, u_r / r * y, 0.0};
233
234 for (int i = 0; i < SPACE_DIM; ++i)
235 u(i) = v_u[i];
236
237 return u;
238};
239
240//! [Postprocess results]
241MoFEMErrorCode ElasticAdaptiveExample::outputResults(int ref_iter) {
243 auto simple = mField.getInterface<Simple>();
244
246
247 std::ostringstream strm;
248 strm << "out_elastic";
249 if (ref_iter >= 0) {
250 strm << "_" << ref_iter;
251 }
252 strm << ".h5m";
253
256 mField, simple->getDM(), simple->getDomainFEName(), strm.str(), {},
257 {"GEOMETRY_ERROR", "SOLUTION_ERROR", "ORDER"}, Sev::verbose);
259}
260//! [Postprocess results]
261
262//! [Error Norms]
264 MOFEM_LOG_CHANNEL("WORLD");
265 auto pip = mField.getInterface<PipelineManager>();
267
269
270 auto integration_rule = [](int, int, int p_data) { return p_data + 1; };
271 CHKERR pip->setDomainRhsIntegrationRule(integration_rule);
272
274 pip->getOpDomainRhsPipeline(), {H1}, "GEOMETRY");
275
276 auto u_ptr = boost::make_shared<MatrixDouble>();
277 pip->getOpDomainRhsPipeline().push_back(
278 new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
279
280 auto analytical_disp_ptr = boost::make_shared<MatrixDouble>();
281
282 pip->getOpDomainRhsPipeline().push_back(
283 new OpGetTensor1fromFunc<SPACE_DIM, SPACE_DIM>(analytical_disp_ptr,
285
286 auto normsVec = createVectorMPI(mField.get_comm(),
287 (mField.get_comm_rank() == 0) ? 1 : 0, 1);
288
289 pip->getOpDomainRhsPipeline().push_back(new OpCalcNormL2Tensor1<SPACE_DIM>(
290 u_ptr, normsVec, 0, analytical_disp_ptr));
291
292 CHKERR VecZeroEntries(normsVec);
293 CHKERR pip->loopFiniteElements();
294 CHKERR VecAssemblyBegin(normsVec);
295 CHKERR VecAssemblyEnd(normsVec);
296
297 if (mField.get_comm_rank() == 0) {
298 const double *norms;
299 CHKERR VecGetArrayRead(normsVec, &norms);
300 MOFEM_TAG_AND_LOG("SELF", Sev::inform, "Errors")
301 << "Displacement error L2 norm: " << std::scientific
302 << std::sqrt(norms[0]);
303
304 if (atomTest == 3 && std::sqrt(norms[0]) > 2.195e-06) {
305 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
306 "atom test failed: displacement error L2 norm is too high: "
307 "%3.6e",
308 std::sqrt(norms[0]));
309 }
310
311 if (atomTest == 4 && std::sqrt(norms[0]) > 1.995e-07) {
312 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
313 "atom test failed: displacement error L2 norm is too high: "
314 "%3.6e",
315 std::sqrt(norms[0]));
316 }
317
318 CHKERR VecRestoreArrayRead(normsVec, &norms);
319 }
320
322}
323//! [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
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 double a
constexpr int SPACE_DIM
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
#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.
FTensor::Index< 'i', SPACE_DIM > i
double D
const double v
phase velocity of light in medium (cm/ns)
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
constexpr AssemblyType A
FTensor::Index< 'm', 3 > m
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
[Reset pipelines]
MoFEMErrorCode refineOrder(int ref_level)
MoFEMErrorCode computeErrorIndicators()
MoFEMErrorCode resetPipelines()
[Set up problem]
MoFEMErrorCode runProblem()
[Run problem]
MoFEMErrorCode readMesh()
[Run problem]
MoFEMErrorCode setupAdaptivity()
[Read mesh]
MoFEMErrorCode solveSystem()
[Solve]
MoFEMErrorCode outputResults()
[Solve]
MoFEMErrorCode assembleSystem()
[Boundary condition]
MoFEMErrorCode setupProblem()
[Read mesh]
MoFEM::Interface & mField
MoFEMErrorCode boundaryCondition()
[Set up problem]
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.
ElementsAndOps< SPACE_DIM >::SideEle SideEle
Definition plastic.cpp:62