v0.16.0
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | Private Attributes | List of all members
ElasticAdaptiveExample Struct Reference

#include "tutorials/vec-8_elasticity_adaptive/src/ElasticAdaptiveExample.hpp"

Inheritance diagram for ElasticAdaptiveExample:
[legend]
Collaboration diagram for ElasticAdaptiveExample:
[legend]

Public Member Functions

 ElasticAdaptiveExample (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 [Run problem]
 
- Public Member Functions inherited from ElasticExample
 ElasticExample (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 [Run problem]
 

Private Member Functions

MoFEMErrorCode readMesh ()
 [Run problem]
 
MoFEMErrorCode setupAdaptivity ()
 [Read mesh]
 
MoFEMErrorCode resetPipelines ()
 [Set up problem]
 
MoFEMErrorCode computeErrorNorms ()
 [Postprocess results]
 
MoFEMErrorCode outputResults (int ref_iter=-1)
 [Postprocess results]
 
MoFEMErrorCode refineOrder (int ref_level)
 
MoFEMErrorCode computeErrorIndicators ()
 
MoFEMErrorCode refineGeometry ()
 
MoFEMErrorCode calculateGeometryError ()
 Calculate geometry error and save on a tag.
 
MoFEMErrorCode kspSetUpAndSolve (SmartPetscObj< KSP > solver) override
 [Reset pipelines]
 

Private Attributes

int oRder = 2
 
PetscBool refGeom = PETSC_FALSE
 
int refAdaptNum = 0
 
double refAdaptThreshold = 1
 
double refGeomThreshold = 1
 
std::array< double, 2 > meanError = {0.0, 0.0}
 
double errorIndicMean = 0.0
 
int atomTest = 0
 

Additional Inherited Members

- Protected Member Functions inherited from ElasticExample
MoFEMErrorCode readMesh ()
 [Run problem]
 
MoFEMErrorCode setupProblem ()
 [Read mesh]
 
MoFEMErrorCode boundaryCondition ()
 [Set up problem]
 
MoFEMErrorCode assembleSystem ()
 [Boundary condition]
 
MoFEMErrorCode solveSystem ()
 [Solve]
 
MoFEMErrorCode outputResults ()
 [Solve]
 
MoFEMErrorCode checkResults ()
 [Postprocess results]
 
- Protected Attributes inherited from ElasticExample
MoFEM::InterfacemField
 
boost::shared_ptr< MatrixDouble > vectorFieldPtr = nullptr
 

Detailed Description

Definition at line 11 of file ElasticAdaptiveExample.hpp.

Constructor & Destructor Documentation

◆ ElasticAdaptiveExample()

ElasticAdaptiveExample::ElasticAdaptiveExample ( MoFEM::Interface m_field)
inline

Definition at line 13 of file ElasticAdaptiveExample.hpp.

Member Function Documentation

◆ calculateGeometryError()

MoFEMErrorCode ElasticAdaptiveExample::calculateGeometryError ( )
private

Calculate geometry error and save on a tag.

Definition at line 14 of file HighOrderGeometryRef.hpp.

14 {
16 auto simple = mField.getInterface<Simple>();
17
18 double def_val_tag = 0.0;
19 Tag tag_err;
20 CHKERR mField.get_moab().tag_get_handle("GEOMETRY_ERROR", 1, MB_TYPE_DOUBLE,
21 tag_err, MB_TAG_CREAT | MB_TAG_SPARSE,
22 &def_val_tag);
23
24 auto LoCoordsPtr = boost::make_shared<MatrixDouble>();
25 auto *op_ptr = new BoundaryEleOp(NOSPACE, BoundaryEleOp::OPSPACE);
26 op_ptr->doWorkRhsHook = [&](DataOperator *base_op_ptr, int side,
27 EntityType type,
28 EntitiesFieldData::EntData &data) {
30 auto op_ptr = static_cast<BoundaryEleOp *>(base_op_ptr);
31 *LoCoordsPtr = op_ptr->getCoordsAtGaussPts();
33 };
34
35 auto *op_ptr_ho = new BoundaryEleOp(NOSPACE, BoundaryEleOp::OPSPACE);
36 op_ptr_ho->doWorkRhsHook = [&](DataOperator *base_op_ptr, int side,
37 EntityType type,
38 EntitiesFieldData::EntData &data) {
40 auto op_ptr_ho = static_cast<BoundaryEleOp *>(base_op_ptr);
41 auto fe_ent = op_ptr_ho->getFEEntityHandle();
43 MatrixDouble &lo_mat = *LoCoordsPtr;
44 MatrixDouble &ho_mat = op_ptr_ho->getCoordsAtGaussPts();
45 auto t_lo_coords = getFTensor1FromMat<SPACE_DIM>(lo_mat);
46 auto t_ho_coords = getFTensor1FromMat<SPACE_DIM>(ho_mat);
47 auto t_w = op_ptr_ho->getFTensor0IntegrationWeight();
48 double err_int = 0;
49 const auto nb_gauss_pts = op_ptr_ho->getGaussPts().size2();
50 // E = sqrt( int (x-xh)*(x-xh) da ) / face_area
51 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
52 err_int += t_w * ((t_lo_coords(i) - t_ho_coords(i)) *
53 (t_lo_coords(i) - t_ho_coords(i)));
54 ++t_lo_coords;
55 ++t_ho_coords;
56 ++t_w;
57 }
58 const double err_measure = sqrt(err_int) / op_ptr_ho->getMeasure();
59 if (err_measure > std::numeric_limits<float>::epsilon()) {
60 meanError[IndicInds::ERROR_TOT] += err_measure;
62 }
63
64 CHKERR mField.get_moab().tag_set_data(tag_err, &fe_ent, 1, &err_measure);
65 Range adj_tet;
66 CHKERR mField.get_moab().get_adjacencies(&fe_ent, 1, SPACE_DIM, false,
67 adj_tet);
68 if (adj_tet.size() != 1)
71 "There should be only one ent adjacent to the boundary ent");
72 auto tet_ent = *adj_tet.begin();
73 double tet_err_measure = 0;
74 CHKERR mField.get_moab().tag_get_data(tag_err, &tet_ent, 1,
75 &tet_err_measure);
76 if (err_measure > tet_err_measure) {
77 CHKERR mField.get_moab().tag_set_data(tag_err, &tet_ent, 1, &err_measure);
78 }
79
81 };
82
83 auto fe = boost::make_shared<BoundaryEle>(mField);
84 fe->getOpPtrVector().push_back(op_ptr);
85
87 fe->getOpPtrVector(), {NOSPACE}, "GEOMETRY");
88 fe->getOpPtrVector().push_back(op_ptr_ho);
89 auto dm = simple->getDM();
91 DMoFEMLoopFiniteElements(dm, simple->getBoundaryFEName(), fe),
92 "calc metric");
93
95}
std::string type
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
constexpr int SPACE_DIM
BoundaryEle::UserDataOperator BoundaryEleOp
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
@ NOSPACE
Definition definitions.h:83
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ 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.
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
FTensor::Index< 'i', SPACE_DIM > i
UBlasMatrix< double > MatrixDouble
Definition Types.hpp:77
std::array< double, 2 > meanError
MoFEM::Interface & mField
virtual moab::Interface & get_moab()=0
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.

◆ computeErrorIndicators()

MoFEMErrorCode ElasticAdaptiveExample::computeErrorIndicators ( )
private

Definition at line 230 of file AdaptiveOrderRef.hpp.

230 {
232 PipelineManager *pipeline_mng = mField.getInterface<PipelineManager>();
233 auto simple = mField.getInterface<Simple>();
234
235 Tag th_error_ind;
236 CHKERR getTagHandle(mField, "SOLUTION_ERROR", MB_TYPE_DOUBLE, th_error_ind);
237
238 pipeline_mng->getSkeletonRhsFE().reset();
239
240 auto integration_rule = [](int, int, int p_data) { return 2 * p_data + 1; };
241 CHKERR pipeline_mng->setSkeletonRhsIntegrationRule(integration_rule);
242
243 auto op_loop_side =
244 new OpLoopSide<SideEle>(mField, simple->getDomainFEName(), SPACE_DIM);
245
247 op_loop_side->getOpPtrVector(), {H1}, "GEOMETRY");
248
249 // Use HookeOps commonDataFactory to get matStrainPtr and matCauchyStressPtr
250 auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEle>(
251 mField, op_loop_side->getOpPtrVector(), "U", "MAT_ELASTIC", Sev::verbose);
252
253 auto mat_jump_ptr = boost::make_shared<MatrixDouble>();
254 op_loop_side->getOpPtrVector().push_back(new OpCalculateTractionJump(
255 "U", common_ptr->getMatCauchyStress(), mat_jump_ptr));
256
257 auto *op_ptr = new BoundaryEleOp(NOSPACE, BoundaryEleOp::OPSPACE);
258 op_ptr->doWorkRhsHook = [&](DataOperator *base_op_ptr, int side,
259 EntityType type,
260 EntitiesFieldData::EntData &data) {
263 auto op_ptr = static_cast<BoundaryEleOp *>(base_op_ptr);
264 auto fe_ent = op_ptr->getFEEntityHandle();
265
266 auto t_jump = getFTensor1FromMat<SPACE_DIM>(*mat_jump_ptr);
267 auto t_w = op_ptr->getFTensor0IntegrationWeight();
268 double err_int = 0;
269 const auto nb_gauss_pts = op_ptr->getGaussPts().size2();
270 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
271 err_int += t_w * (t_jump(i) * t_jump(i));
272 ++t_jump;
273 ++t_w;
274 }
275 double err_measure = sqrt(err_int);
276 CHKERR mField.get_moab().tag_set_data(th_error_ind, &fe_ent, 1,
277 &err_measure);
278
280 };
281
282 pipeline_mng->getOpSkeletonRhsPipeline().push_back(op_loop_side);
283 pipeline_mng->getOpSkeletonRhsPipeline().push_back(op_ptr);
284
285 Range fe_ents;
286 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM - 1, fe_ents);
287 double zero = 0;
288 CHKERR mField.get_moab().tag_clear_data(th_error_ind, fe_ents, &zero);
289
290 CHKERR DMoFEMLoopFiniteElements(simple->getDM(), simple->getSkeletonFEName(),
291 pipeline_mng->getSkeletonRhsFE());
292
293 pipeline_mng->getSkeletonRhsFE().reset();
294
295 Range domain_ents_part;
296 CHKERR getDomainEntsPart(mField, domain_ents_part);
297
298 ParallelComm *pcomm =
299 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
300 Range empty_range;
301 CHKERR pcomm->reduce_tags(th_error_ind, MPI_SUM, empty_range);
302
303 std::array<double, 3> error_indic_loc = {0.0, 0.0, 0.0};
304
305 for (auto domain_ent : domain_ents_part) {
306 Range face_ents;
307 CHKERR mField.get_moab().get_adjacencies(
308 &domain_ent, 1, SPACE_DIM - 1, true, face_ents, moab::Interface::UNION);
309
310 double err_indic_sum = 0;
311 for (auto face_ent : face_ents) {
312 double err_indic = 0;
313 CHKERR mField.get_moab().tag_get_data(th_error_ind, &face_ent, 1,
314 &err_indic);
315 err_indic_sum += err_indic;
316 }
317 CHKERR mField.get_moab().tag_set_data(th_error_ind, &domain_ent, 1,
318 &err_indic_sum);
319
320 error_indic_loc[IndicInds::ERROR_TOT] += err_indic_sum;
321
322 const EntityHandle *vert_conn;
323 int vert_num;
324 CHKERR mField.get_moab().get_connectivity(domain_ent, vert_conn, vert_num,
325 true);
326 std::vector<double> vpos(3 * vert_num);
327 CHKERR mField.get_moab().get_coords(vert_conn, vert_num, &vpos[0]);
328 double vol = Tools::tetVolume(vpos.data());
329
330 error_indic_loc[IndicInds::ERROR_NORM] += err_indic_sum * vol;
331 }
332
333 CHKERR copyTagOnSkin(mField, "SOLUTION_ERROR", MB_TYPE_DOUBLE);
334
335 error_indic_loc[IndicInds::COUNT_ENTS] =
336 static_cast<double>(domain_ents_part.size());
337
338 std::array<double, 3> error_indic_glob = {0.0, 0.0, 0.0};
339
340 MPI_Allreduce(&error_indic_loc[0], &error_indic_glob[0], 3, MPI_DOUBLE,
341 MPI_SUM, mField.get_comm());
342
343 errorIndicMean = error_indic_glob[IndicInds::ERROR_TOT] /
344 error_indic_glob[IndicInds::COUNT_ENTS];
345
346 MOFEM_LOG("WORLD", Sev::inform) << "Global error indicator (norm): "
347 << error_indic_glob[IndicInds::ERROR_NORM];
348 MOFEM_LOG("WORLD", Sev::inform)
349 << "Global error indicator (mean): " << errorIndicMean;
350
352}
static MoFEMErrorCode getTagHandle(MoFEM::Interface &m_field, const char *name, DataType type, Tag &tag_handle)
static MoFEMErrorCode getDomainEntsPart(MoFEM::Interface &m_field, Range &domain_ents_part)
static MoFEMErrorCode copyTagOnSkin(MoFEM::Interface &m_field, const char *name, DataType type)
#define MYPCOMM_INDEX
default communicator number PCOMM
auto integration_rule
#define MOFEM_LOG(channel, severity)
Log.
virtual MPI_Comm & get_comm() const =0

◆ computeErrorNorms()

MoFEMErrorCode ElasticAdaptiveExample::computeErrorNorms ( )
private

[Postprocess results]

[Error Norms]

Definition at line 263 of file ElasticAdaptiveExample.hpp.

263 {
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}
MoFEM::VectorFunc analyticalDisplacement
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
MoFEMErrorCode resetPipelines()
[Set up problem]
virtual int get_comm_rank() const =0

◆ kspSetUpAndSolve()

MoFEMErrorCode ElasticAdaptiveExample::kspSetUpAndSolve ( SmartPetscObj< KSP >  solver)
overrideprivatevirtual

[Reset pipelines]

Reimplemented from ElasticExample.

Definition at line 173 of file ElasticAdaptiveExample.hpp.

173 {
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}
@ F
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
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1237
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
double D
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.

◆ outputResults()

MoFEMErrorCode ElasticAdaptiveExample::outputResults ( int  ref_iter = -1)
private

[Postprocess results]

Definition at line 241 of file ElasticAdaptiveExample.hpp.

241 {
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}
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
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)
ElementsAndOps< SPACE_DIM >::SideEle SideEle
Definition plastic.cpp:62

◆ readMesh()

MoFEMErrorCode ElasticAdaptiveExample::readMesh ( )
private

[Run problem]

[Read mesh]

Definition at line 81 of file ElasticAdaptiveExample.hpp.

81 {
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}
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)
FTensor::Index< 'm', 3 > m

◆ refineGeometry()

MoFEMErrorCode ElasticAdaptiveExample::refineGeometry ( )
private

Definition at line 97 of file HighOrderGeometryRef.hpp.

97 {
99 auto simple = mField.getInterface<Simple>();
100
101 CHKERR PetscOptionsGetReal(PETSC_NULLPTR, "", "-ref_geom_threshold",
102 &refGeomThreshold, PETSC_NULLPTR);
103
104 if (Tag tag_err = 0; mField.get_moab().tag_get_handle(
105 "GEOMETRY_ERROR", tag_err) == MB_SUCCESS) {
106
107 std::array<double, 2> mean_error_glob = {0.0, 0.0};
108 MPI_Allreduce(&meanError[0], &mean_error_glob[0], 2, MPI_DOUBLE, MPI_SUM,
109 mField.get_comm());
110 if (mean_error_glob[IndicInds::COUNT_ENTS] > 0) {
111 refGeomThreshold *= (mean_error_glob[IndicInds::ERROR_TOT] /
112 mean_error_glob[IndicInds::COUNT_ENTS]);
113 }
114
115 MOFEM_LOG("WORLD", Sev::inform)
116 << "Geometry refinement threshold = " << refGeomThreshold;
117
118 auto get_ents_to_refine = [&]() {
119 Range outer_ref_ents;
120
121 auto *op_ptr_ref = new BoundaryEleOp(NOSPACE, BoundaryEleOp::OPSPACE);
122 op_ptr_ref->doWorkRhsHook = [&](DataOperator *base_op_ptr, int side,
123 EntityType type,
124 EntitiesFieldData::EntData &data) {
126 auto op_ptr_ref = static_cast<BoundaryEleOp *>(base_op_ptr);
127 auto fe_ent = op_ptr_ref->getFEEntityHandle();
128 double err_measure = 0;
129 CHKERR mField.get_moab().tag_get_data(tag_err, &fe_ent, 1,
130 &err_measure);
131 if (err_measure > refGeomThreshold)
132 outer_ref_ents.insert(fe_ent);
133
135 };
136
137 auto fe = boost::make_shared<BoundaryEle>(mField);
138 fe->getOpPtrVector().push_back(op_ptr_ref);
139 auto dm = simple->getDM();
141 DMoFEMLoopFiniteElements(dm, simple->getBoundaryFEName(), fe),
142 "ref ents");
143 return outer_ref_ents;
144 };
145
146 auto ents_to_ref = get_ents_to_refine();
147
148 Range all_domain_ents;
149 CHKERR mField.get_moab().get_entities_by_handle(simple->getMeshset(),
150 all_domain_ents);
151 Range all_boundary_ents;
152 CHKERR mField.get_moab().get_entities_by_handle(
153 simple->getBoundaryMeshSet(), all_boundary_ents);
154
155 Range tets_to_refine[2];
156 CHKERR mField.get_moab().get_adjacencies(ents_to_ref, SPACE_DIM, false,
157 tets_to_refine[1],
158 moab::Interface::UNION);
159 Range ent_conn;
160 CHKERR mField.get_moab().get_adjacencies(tets_to_refine[1], SPACE_DIM - 1,
161 true, ent_conn,
162 moab::Interface::UNION);
163 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(ent_conn);
164
165 CHKERR mField.get_moab().get_adjacencies(
166 ent_conn, SPACE_DIM, true, tets_to_refine[0], moab::Interface::UNION);
167 tets_to_refine[0] = subtract(tets_to_refine[0], tets_to_refine[1]);
168
169#ifndef NDEBUG
170 CHKERR CutMeshInterface::SaveData(mField.get_moab())(
171 "ents_to_refine_ho_2.vtk", tets_to_refine[0]);
172 CHKERR CutMeshInterface::SaveData(mField.get_moab())(
173 "ents_to_refine_ho_3.vtk", tets_to_refine[1]);
174#endif
175
176 for (int i = 0; i < 2; ++i) {
177 Range ents_to_refine;
178 ents_to_refine.merge(tets_to_refine[i]);
179 for (int d = 1; d < SPACE_DIM; ++d) {
180 Range lower_dim_ents;
181 CHKERR mField.get_moab().get_adjacencies(
182 tets_to_refine[i], d, true, lower_dim_ents, moab::Interface::UNION);
183 ents_to_refine.merge(lower_dim_ents);
184 }
185 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
186 ents_to_refine);
187
188 CHKERR simple->setFieldOrder("U", oRder + i + 1, &ents_to_refine);
189 }
190
191 CHKERR mField.getInterface<CommInterface>()->synchroniseFieldEntities("U");
192 CHKERR simple->reSetUp();
193
194 // save order on tags (volumes and boundary)
195 int orders[] = {oRder, oRder + 1, oRder + 2};
196 Tag tag_order;
197
198 CHKERR getTagHandle(mField, "ORDER", MB_TYPE_INTEGER, tag_order);
199
200 for (int i = 0; i < 2; ++i) {
201 Range adj_faces;
202 CHKERR mField.get_moab().get_adjacencies(tets_to_refine[i], SPACE_DIM - 1,
203 true, adj_faces,
204 moab::Interface::UNION);
205 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
206 adj_faces);
207
208 adj_faces = intersect(adj_faces, all_boundary_ents);
209 CHKERR mField.get_moab().tag_clear_data(tag_order, tets_to_refine[i],
210 &orders[i + 1]);
211 CHKERR mField.get_moab().tag_clear_data(tag_order, adj_faces,
212 &orders[i + 1]);
213 }
214 }
216}
PetscErrorCode PetscOptionsGetReal(PetscOptions *, const char pre[], const char name[], PetscReal *dval, PetscBool *set)

◆ refineOrder()

MoFEMErrorCode ElasticAdaptiveExample::refineOrder ( int  ref_level)
private

Definition at line 147 of file AdaptiveOrderRef.hpp.

147 {
149 auto simple = mField.getInterface<Simple>();
150 auto comm = mField.getInterface<CommInterface>();
151
152 CHKERR PetscOptionsGetReal(PETSC_NULLPTR, "", "-ref_adapt_threshold",
153 &refAdaptThreshold, PETSC_NULLPTR);
154
155 Tag th_error_ind, th_order;
156 CHKERR getTagHandle(mField, "SOLUTION_ERROR", MB_TYPE_DOUBLE, th_error_ind);
157 CHKERR getTagHandle(mField, "ORDER", MB_TYPE_INTEGER, th_order);
158
159 std::vector<Range> refinement_levels(ref_level + 2);
160
161 Range domain_ents_part;
162 CHKERR getDomainEntsPart(mField, domain_ents_part);
163
164 for (auto ent : domain_ents_part) {
165 double err_indic = 0;
166 CHKERR mField.get_moab().tag_get_data(th_error_ind, &ent, 1, &err_indic);
167 int order;
168 CHKERR mField.get_moab().tag_get_data(th_order, &ent, 1, &order);
169
170 if (err_indic > refAdaptThreshold * errorIndicMean) {
171 order += 1;
172 refinement_levels[order - oRder].insert(ent);
173 }
174 }
175
176 for (int ll = refinement_levels.size() - 1; ll > 1; ll--) {
177 CHKERR comm->synchroniseEntities(refinement_levels[ll]);
178
179 Range face_ents;
180 CHKERR mField.get_moab().get_adjacencies(refinement_levels[ll],
181 SPACE_DIM - 1, true, face_ents,
182 moab::Interface::UNION);
183 Range tets;
184 CHKERR mField.get_moab().get_adjacencies(face_ents, SPACE_DIM, true, tets,
185 moab::Interface::UNION);
186 tets = subtract(tets, refinement_levels[ll]);
187 refinement_levels[ll - 1].merge(tets);
188 }
189
190 for (int ll = 1; ll < refinement_levels.size(); ll++) {
191
192 if (oRder + ll > 8) {
193 MOFEM_LOG("WORLD", Sev::warning)
194 << "setting approximation order higher than 8 is not currently "
195 "supported"
196 << endl;
197 } else {
198
199 for (auto ent : refinement_levels[ll]) {
200 int order = oRder + ll;
201 CHKERR mField.get_moab().tag_set_data(th_order, &ent, 1, &order);
202 }
203
204 Range ents_to_refine;
205 ents_to_refine.merge(refinement_levels[ll]);
206 for (int d = 1; d < SPACE_DIM; ++d) {
207 Range lower_dim_ents;
208 CHKERR mField.get_moab().get_adjacencies(refinement_levels[ll], d, true,
209 lower_dim_ents,
210 moab::Interface::UNION);
211 ents_to_refine.merge(lower_dim_ents);
212 }
213
214 CHKERR comm->synchroniseEntities(ents_to_refine);
215
216 CHKERR simple->setFieldOrder("U", oRder + ll, &ents_to_refine);
217 }
218 }
219
220 CHKERR copyTagOnSkin(mField, "ORDER", MB_TYPE_INTEGER);
221
222 CHKERR comm->synchroniseFieldEntities("U");
223 CHKERR simple->reSetUp();
224
226
228}
constexpr int order
MoFEMErrorCode boundaryCondition()
[Set up problem]

◆ resetPipelines()

MoFEMErrorCode ElasticAdaptiveExample::resetPipelines ( )
private

[Set up problem]

[Reset pipelines]

Definition at line 156 of file ElasticAdaptiveExample.hpp.

156 {
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}

◆ runProblem()

MoFEMErrorCode ElasticAdaptiveExample::runProblem ( )

[Run problem]

Definition at line 46 of file ElasticAdaptiveExample.hpp.

46 {
54 if (atomTest == 3)
57
58 if (refAdaptNum > 0) {
61 } else {
63 }
64
65 for (int it = 0; it < refAdaptNum; ++it) {
66 CHKERR refineOrder(it + 1);
71 if (it == refAdaptNum - 1 && atomTest == 4)
74 CHKERR outputResults(it + 1);
75 }
77}
MoFEMErrorCode computeErrorNorms()
[Postprocess results]
MoFEMErrorCode refineOrder(int ref_level)
MoFEMErrorCode computeErrorIndicators()
MoFEMErrorCode readMesh()
[Run problem]
MoFEMErrorCode setupAdaptivity()
[Read mesh]
MoFEMErrorCode solveSystem()
[Solve]
MoFEMErrorCode outputResults()
[Solve]
MoFEMErrorCode assembleSystem()
[Boundary condition]
MoFEMErrorCode setupProblem()
[Read mesh]
MoFEMErrorCode checkResults()
[Postprocess results]

◆ setupAdaptivity()

MoFEMErrorCode ElasticAdaptiveExample::setupAdaptivity ( )
private

[Read mesh]

[Set up problem]

Definition at line 127 of file ElasticAdaptiveExample.hpp.

127 {
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}
MoFEMErrorCode calculateGeometryError()
Calculate geometry error and save on a tag.

Member Data Documentation

◆ atomTest

int ElasticAdaptiveExample::atomTest = 0
private

Definition at line 37 of file ElasticAdaptiveExample.hpp.

◆ errorIndicMean

double ElasticAdaptiveExample::errorIndicMean = 0.0
private

Definition at line 35 of file ElasticAdaptiveExample.hpp.

◆ meanError

std::array<double, 2> ElasticAdaptiveExample::meanError = {0.0, 0.0}
private

Definition at line 34 of file ElasticAdaptiveExample.hpp.

34{0.0, 0.0};

◆ oRder

int ElasticAdaptiveExample::oRder = 2
private

Definition at line 29 of file ElasticAdaptiveExample.hpp.

◆ refAdaptNum

int ElasticAdaptiveExample::refAdaptNum = 0
private

Definition at line 31 of file ElasticAdaptiveExample.hpp.

◆ refAdaptThreshold

double ElasticAdaptiveExample::refAdaptThreshold = 1
private

Definition at line 32 of file ElasticAdaptiveExample.hpp.

◆ refGeom

PetscBool ElasticAdaptiveExample::refGeom = PETSC_FALSE
private

Definition at line 30 of file ElasticAdaptiveExample.hpp.

◆ refGeomThreshold

double ElasticAdaptiveExample::refGeomThreshold = 1
private

Definition at line 33 of file ElasticAdaptiveExample.hpp.


The documentation for this struct was generated from the following files: