29int main(
int argc,
char *argv[]) {
35 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Mesh cut options",
"none");
36 CHKERR PetscOptionsInt(
"-edges_block_set",
"edges side set",
"",
38 CHKERR PetscOptionsInt(
"-vertex_block_set",
"vertex side set",
"",
40 CHKERR PetscOptionsBool(
"-output_vtk",
"if true outout vtk file",
"",
42 CHKERR PetscOptionsScalar(
"-quality_reduction_tol",
"",
43 "Tolerance of quality reduction",
tol, &
tol,
45 CHKERR PetscOptionsScalar(
"-gamma_factor",
"",
52 moab::Interface &moab = moab_core;
103 ->synchroniseFieldEntities(
"LAMBDA_EDGE");
108 "EDGE_SLIDING",
"MESH_NODE_POSITIONS");
110 "EDGE_SLIDING",
"MESH_NODE_POSITIONS");
112 "EDGE_SLIDING",
"MESH_NODE_POSITIONS");
142 "LAMBDA_SURFACE", verts, 0, 1);
144 CHKERR prb_mng->removeDofsOnEntities(
151 struct ElementsAndOperators {
155 double *minQualityPtr;
160 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
161 ierr = VecGetArray(minQualityVec, &minQualityPtr);
162 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
165 virtual ~ElementsAndOperators() {
166 ierr = VecRestoreArray(minQualityVec, &minQualityPtr);
167 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
168 ierr = VecDestroy(&minQualityVec);
169 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
172 double getMinQuality()
const {
return *minQualityPtr; }
176 SURFACE_CONSTRAINS_TAG,
180 boost::shared_ptr<Smoother> smootherFe;
181 boost::shared_ptr<Smoother::MyVolumeFE>
183 boost::shared_ptr<Smoother::MyVolumeFE>
185 boost::shared_ptr<VolumeLengthQuality<double> > volumeLengthDouble;
186 boost::shared_ptr<VolumeLengthQuality<adouble> > volumeLengthAdouble;
188 boost::shared_ptr<SurfaceSlidingConstrains> surfaceConstrain;
189 boost::shared_ptr<SurfaceSlidingConstrains::DriverElementOrientation>
191 boost::shared_ptr<EdgeSlidingConstrains> edgeConstrain;
193 boost::shared_ptr<MoFEM::VolumeElementForcesAndSourcesCore> minQualityFe;
196 double *minQualityPtr;
197 MinQualityOp(
double *min_quality_ptr)
200 minQualityPtr(min_quality_ptr) {}
204 if (type != MBVERTEX)
207 *minQualityPtr = fmin(*minQualityPtr, q);
214 smootherFe = boost::shared_ptr<Smoother>(
new Smoother(mField));
215 volumeLengthAdouble = boost::shared_ptr<VolumeLengthQuality<adouble> >(
217 volumeLengthDouble = boost::shared_ptr<VolumeLengthQuality<double> >(
222 smootherFe->setOfBlocks[0].tEts.merge(tets);
224 smootherFe->setOfBlocks[0].materialDoublePtr = volumeLengthDouble;
225 smootherFe->setOfBlocks[0].materialAdoublePtr = volumeLengthAdouble;
228 smootherFe->commonData.spatialPositions =
"MESH_NODE_POSITIONS";
229 smootherFe->commonData.meshPositions =
"NONE";
231 smootherFe->feRhs.meshPositionsFieldName =
"NONE";
232 smootherFe->feLhs.meshPositionsFieldName =
"NONE";
233 smootherFe->feRhs.addToRule = 0;
234 smootherFe->feLhs.addToRule = 0;
236 feSmootherRhs = smootherFe->feRhsPtr;
237 feSmootherLhs = smootherFe->feLhsPtr;
239 feSmootherRhs->getOpPtrVector().push_back(
241 "MESH_NODE_POSITIONS", smootherFe->commonData));
242 feSmootherRhs->getOpPtrVector().push_back(
244 "MESH_NODE_POSITIONS", smootherFe->setOfBlocks.at(0),
245 smootherFe->commonData, SMOOTHING_TAG,
false));
247 "MESH_NODE_POSITIONS", smootherFe->setOfBlocks[0],
248 smootherFe->commonData, smootherFe->smootherData));
250 feSmootherLhs->getOpPtrVector().push_back(
252 "MESH_NODE_POSITIONS", smootherFe->commonData));
253 feSmootherLhs->getOpPtrVector().push_back(
255 "MESH_NODE_POSITIONS", smootherFe->setOfBlocks.at(0),
256 smootherFe->commonData, SMOOTHING_TAG,
true));
258 "MESH_NODE_POSITIONS",
"MESH_NODE_POSITIONS",
259 smootherFe->setOfBlocks.at(0), smootherFe->commonData,
260 smootherFe->smootherData,
"LAMBDA_CRACKFRONT_AREA_TANGENT"));
263 boost::shared_ptr<MoFEM::VolumeElementForcesAndSourcesCore>(
265 minQualityFe->getOpPtrVector().push_back(
266 new MinQualityOp(minQualityPtr));
276 CHKERR prb_mng->removeDofsOnEntities(simple_interface->getProblemName(),
277 "MESH_NODE_POSITIONS",
279 CHKERR prb_mng->removeDofsOnEntities(simple_interface->getProblemName(),
285 CHKERR prb_mng->removeDofsOnEntities(
286 simple_interface->getProblemName(),
"LAMBDA_EDGE", fixed_vertex,
295 skinOrientation = boost::shared_ptr<
298 surfaceConstrain = boost::shared_ptr<SurfaceSlidingConstrains>(
301 surfaceConstrain->setOperators(SURFACE_CONSTRAINS_TAG,
"LAMBDA_SURFACE",
302 "MESH_NODE_POSITIONS");
316 CHKERR skin.find_skin(0, tets,
false, skin_faces);
318 edgeConstrain = boost::shared_ptr<EdgeSlidingConstrains>(
320 CHKERR edgeConstrain->setOperators(EDGE_CONSTRAINS_TAG, edges,
321 skin_faces,
"LAMBDA_EDGE",
322 "MESH_NODE_POSITIONS");
332 boost::shared_ptr<ForcesAndSourcesCore> null;
337 surfaceConstrain->feRhsPtr, null, null);
340 edgeConstrain->feRhsPtr, null, null);
345 surfaceConstrain->feLhsPtr, null, null);
348 edgeConstrain->feLhsPtr, null, null);
361 CHKERR VecMin(minQualityVec, PETSC_NULLPTR, minQualityPtr);
366 ElementsAndOperators elements_and_operators(m_field);
367 CHKERR elements_and_operators.createSmoothingFE();
368 CHKERR elements_and_operators.createConstrians();
372 CHKERR elements_and_operators.addFEtoDM(dm);
381 CHKERR DMCreateGlobalVector(dm, &
F);
386 CHKERR zeroLambdaFields(dm);
391 CHKERR SNESCreate(PETSC_COMM_WORLD, &solver);
392 CHKERR SNESSetFromOptions(solver);
393 CHKERR SNESSetDM(solver, dm);
397 auto hook = [&](SNES snes, Vec x, Vec
F,
398 boost::shared_ptr<CacheTuple> cache_ptr,
407 boost::make_shared<PostProcEleDomain>(*m_field_ptr);
408 auto &pip = post_proc_fe->getOpPtrVector();
409 auto X_ptr = boost::make_shared<MatrixDouble>();
411 "MESH_NODE_POSITIONS", X_ptr));
412 auto res_X_ptr = boost::make_shared<MatrixDouble>();
415 auto lambda_ptr = boost::make_shared<VectorDouble>();
418 auto res_lambda_ptr = boost::make_shared<VectorDouble>();
427 post_proc_fe->getPostProcMesh(),
428 post_proc_fe->getMapGaussPts(),
430 {{
"LAMBDA_SURFACE", lambda_ptr},
431 {
"RES_LAMBDA_SURFACE", res_lambda_ptr}},
433 {{
"MESH_NODE_POSITIONS", X_ptr},
435 {
"RES_MESH_NODE_POSITIONS", res_X_ptr}},
446 CHKERR post_proc_fe->writeFile(
"debug_smoothing.h5m");
451 snes_ctx_ptr->getRhsHook() = hook;
462 CHKERR SNESDestroy(&solver);
474 "MESH_NODE_POSITIONS", it)) {
475 if (it->get()->getEntType() != MBVERTEX)
478 for(
int dd = 0;dd!=3;++dd)
479 coords[dd] = it->get()->getEntFieldData()[dd];
481 CHKERR m_field_ptr->
get_moab().set_coords(&ent, 1, &*coords.begin());
491 "MESH_NODE_POSITIONS", it)) {
492 if (it->get()->getEntType() != MBVERTEX)
496 CHKERR m_field_ptr->
get_moab().get_coords(&ent, 1, &*coords.begin());
497 for(
int dd = 0;dd!=3;++dd)
498 it->get()->getEntFieldData()[dd] = coords[dd];
509 0, MBVERTEX,
"LAMBDA_SURFACE");
518 CHKERR elements_and_operators.calcuteMinQuality(dm);
519 double min_quality = elements_and_operators.getMinQuality();
520 PetscPrintf(PETSC_COMM_WORLD,
"Min quality = %4.3f\n", min_quality);
522 double gamma = min_quality > 0 ?
gamma_factor * min_quality
524 elements_and_operators.volumeLengthDouble->gAmma = gamma;
525 elements_and_operators.volumeLengthAdouble->gAmma = gamma;
527 double min_quality_p,
eps;
530 min_quality_p = min_quality;
535 CHKERR elements_and_operators.calcuteMinQuality(dm);
536 min_quality = elements_and_operators.getMinQuality();
538 eps = (min_quality - min_quality_p) / min_quality;
539 PetscPrintf(PETSC_COMM_WORLD,
"Min quality = %4.3f eps = %4.3f\n",
542 double gamma = min_quality > 0 ?
gamma_factor * min_quality
544 elements_and_operators.volumeLengthDouble->gAmma = gamma;
545 elements_and_operators.volumeLengthAdouble->gAmma = gamma;