29 {
30
32
33 try {
34
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,
44 PETSC_NULLPTR);
45 CHKERR PetscOptionsScalar(
"-gamma_factor",
"",
47 PETSC_NULLPTR);
48 PetscOptionsEnd();
49
50
51 moab::Core moab_core;
52 moab::Interface &moab = moab_core;
53
56
58
59
60
62
63
64 {
65
67
69
70
71
74
77
78
80 1);
82 1);
83
86
87
89
90 } else {
93
99 true);
101 "LAMBDA_EDGE");
103 ->synchroniseFieldEntities("LAMBDA_EDGE");
105
108 "EDGE_SLIDING", "MESH_NODE_POSITIONS");
110 "EDGE_SLIDING", "MESH_NODE_POSITIONS");
112 "EDGE_SLIDING", "MESH_NODE_POSITIONS");
114 "LAMBDA_EDGE");
116 "LAMBDA_EDGE");
118 "LAMBDA_EDGE");
120 "EDGE_SLIDING");
122 }
123 }
124
130
131
142 "LAMBDA_SURFACE", verts, 0, 1);
144 CHKERR prb_mng->removeDofsOnEntities(
146 0, 3);
147 }
148 }
149 }
150
151 struct ElementsAndOperators {
152
155 double *minQualityPtr;
156
159 &minQualityVec);
160 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
161 ierr = VecGetArray(minQualityVec, &minQualityPtr);
162 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
163 }
164
165 virtual ~ElementsAndOperators() {
166 ierr = VecRestoreArray(minQualityVec, &minQualityPtr);
167 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
168 ierr = VecDestroy(&minQualityVec);
169 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
170 }
171
172 double getMinQuality() const { return *minQualityPtr; }
173
174 enum Tags {
175 SMOOTHING_TAG = 1,
176 SURFACE_CONSTRAINS_TAG,
177 EDGE_CONSTRAINS_TAG
178 };
179
180 boost::shared_ptr<Smoother> smootherFe;
181 boost::shared_ptr<Smoother::MyVolumeFE>
182 feSmootherRhs;
183 boost::shared_ptr<Smoother::MyVolumeFE>
184 feSmootherLhs;
185 boost::shared_ptr<VolumeLengthQuality<double> > volumeLengthDouble;
186 boost::shared_ptr<VolumeLengthQuality<adouble> > volumeLengthAdouble;
187
188 boost::shared_ptr<SurfaceSlidingConstrains> surfaceConstrain;
189 boost::shared_ptr<SurfaceSlidingConstrains::DriverElementOrientation>
190 skinOrientation;
191 boost::shared_ptr<EdgeSlidingConstrains> edgeConstrain;
192
193 boost::shared_ptr<MoFEM::VolumeElementForcesAndSourcesCore> minQualityFe;
194
196 double *minQualityPtr;
197 MinQualityOp(double *min_quality_ptr)
200 minQualityPtr(min_quality_ptr) {}
204 if (type != MBVERTEX)
207 *minQualityPtr = fmin(*minQualityPtr, q);
209 }
210 };
211
214 smootherFe = boost::shared_ptr<Smoother>(
new Smoother(mField));
215 volumeLengthAdouble = boost::shared_ptr<VolumeLengthQuality<adouble> >(
217 volumeLengthDouble = boost::shared_ptr<VolumeLengthQuality<double> >(
219
222 smootherFe->setOfBlocks[0].tEts.merge(tets);
223
224 smootherFe->setOfBlocks[0].materialDoublePtr = volumeLengthDouble;
225 smootherFe->setOfBlocks[0].materialAdoublePtr = volumeLengthAdouble;
226
227
228 smootherFe->commonData.spatialPositions = "MESH_NODE_POSITIONS";
229 smootherFe->commonData.meshPositions = "NONE";
230
231 smootherFe->feRhs.meshPositionsFieldName = "NONE";
232 smootherFe->feLhs.meshPositionsFieldName = "NONE";
233 smootherFe->feRhs.addToRule = 0;
234 smootherFe->feLhs.addToRule = 0;
235
236 feSmootherRhs = smootherFe->feRhsPtr;
237 feSmootherLhs = smootherFe->feLhsPtr;
238
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));
249
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"));
261
262 minQualityFe =
263 boost::shared_ptr<MoFEM::VolumeElementForcesAndSourcesCore>(
265 minQualityFe->getOpPtrVector().push_back(
266 new MinQualityOp(minQualityPtr));
267
273 }
276 CHKERR prb_mng->removeDofsOnEntities(simple_interface->getProblemName(),
277 "MESH_NODE_POSITIONS",
278 fixed_vertex, 0, 3);
279 CHKERR prb_mng->removeDofsOnEntities(simple_interface->getProblemName(),
280 "LAMBDA_SURFACE",
281 fixed_vertex, 0, 1);
285 CHKERR prb_mng->removeDofsOnEntities(
286 simple_interface->getProblemName(), "LAMBDA_EDGE", fixed_vertex,
287 0, 1);
288 }
289
291 }
292
295 skinOrientation = boost::shared_ptr<
298 surfaceConstrain = boost::shared_ptr<SurfaceSlidingConstrains>(
299 skinOrientation,
301 surfaceConstrain->setOperators(SURFACE_CONSTRAINS_TAG, "LAMBDA_SURFACE",
302 "MESH_NODE_POSITIONS");
303
310 true);
311
316 CHKERR skin.find_skin(0, tets,
false, skin_faces);
317
318 edgeConstrain = boost::shared_ptr<EdgeSlidingConstrains>(
320 CHKERR edgeConstrain->setOperators(EDGE_CONSTRAINS_TAG, edges,
321 skin_faces, "LAMBDA_EDGE",
322 "MESH_NODE_POSITIONS");
323
324
325
326 }
328 }
329
332 boost::shared_ptr<ForcesAndSourcesCore> null;
333
335 null);
337 surfaceConstrain->feRhsPtr, null, null);
340 edgeConstrain->feRhsPtr, null, null);
341
343 null);
345 surfaceConstrain->feLhsPtr, null, null);
348 edgeConstrain->feLhsPtr, null, null);
349
350
351
352
353
355 }
356
359 *minQualityPtr = 1;
361 CHKERR VecMin(minQualityVec, PETSC_NULLPTR, minQualityPtr);
363 }
364 };
365
366 ElementsAndOperators elements_and_operators(m_field);
367 CHKERR elements_and_operators.createSmoothingFE();
368 CHKERR elements_and_operators.createConstrians();
369
370 DM dm;
371 CHKERR simple_interface->getDM(&dm);
372 CHKERR elements_and_operators.addFEtoDM(dm);
373
374 struct Solve {
375
378
379
381 CHKERR DMCreateGlobalVector(dm, &
F);
382
383
385
386 CHKERR zeroLambdaFields(dm);
388
389
390 SNES solver;
391 CHKERR SNESCreate(PETSC_COMM_WORLD, &solver);
392 CHKERR SNESSetFromOptions(solver);
393 CHKERR SNESSetDM(solver, dm);
394
396
397 auto hook = [&](SNES snes,
Vec x,
Vec F,
398 boost::shared_ptr<CacheTuple> cache_ptr,
401
404
406 auto post_proc_fe =
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>();
416 pip.push_back(
418 auto res_lambda_ptr = boost::make_shared<VectorDouble>();
421
423 pip.push_back(
424
426
427 post_proc_fe->getPostProcMesh(),
428 post_proc_fe->getMapGaussPts(),
429
430 {{"LAMBDA_SURFACE", lambda_ptr},
431 {"RES_LAMBDA_SURFACE", res_lambda_ptr}},
432
433 {{"MESH_NODE_POSITIONS", X_ptr},
434
435 {"RES_MESH_NODE_POSITIONS", res_X_ptr}},
436
437 {},
438
439 {}
440
441 )
442
443 );
444
446 CHKERR post_proc_fe->writeFile(
"debug_smoothing.h5m");
448 };
449
451 snes_ctx_ptr->getRhsHook() = hook;
452
453
454
455
457
458
459
461
462 CHKERR SNESDestroy(&solver);
465
467 }
468
474 "MESH_NODE_POSITIONS", it)) {
475 if (it->get()->getEntType() != MBVERTEX)
476 continue;
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());
482 }
484 }
485
491 "MESH_NODE_POSITIONS", it)) {
492 if (it->get()->getEntType() != MBVERTEX)
493 continue;
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];
499 }
501 }
502
503 private:
509 0, MBVERTEX, "LAMBDA_SURFACE");
511 }
512
513 };
514
517
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);
521
522 double gamma = min_quality > 0 ?
gamma_factor * min_quality
524 elements_and_operators.volumeLengthDouble->gAmma = gamma;
525 elements_and_operators.volumeLengthAdouble->gAmma = gamma;
526
527 double min_quality_p,
eps;
528 do {
529
530 min_quality_p = min_quality;
531
533
535 CHKERR elements_and_operators.calcuteMinQuality(dm);
536 min_quality = elements_and_operators.getMinQuality();
537
538 eps = (min_quality - min_quality_p) / min_quality;
539 PetscPrintf(PETSC_COMM_WORLD, "Min quality = %4.3f eps = %4.3f\n",
541
542 double gamma = min_quality > 0 ?
gamma_factor * min_quality
544 elements_and_operators.volumeLengthDouble->gAmma = gamma;
545 elements_and_operators.volumeLengthAdouble->gAmma = gamma;
546
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
570 "");
571 }
573
575}
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
PostProcEleByDim< SPACE_DIM >::PostProcEleDomain PostProcEleDomain
PetscErrorCode DMMoFEMSNESSetFunction(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set SNES residual evaluation function
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
PetscErrorCode DMMoFEMSNESSetJacobian(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set SNES Jacobian evaluation function
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
PetscErrorCode DMoFEMGetInterfacePtr(DM dm, MoFEM::Interface **m_field_ptr)
Get pointer to MoFEM::Interface.
PetscErrorCode DMoFEMMeshToGlobalVector(DM dm, Vec g, InsertMode mode, ScatterMode scatter_mode)
set ghosted vector values on all existing mesh entities
#define _IT_GET_ENT_FIELD_BY_NAME_FOR_LOOP_(MFIELD, NAME, IT)
loop over all dofs from a moFEM field and particular field
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode add_ents_to_finite_element_by_type(const EntityHandle entities, const EntityType type, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
virtual MoFEMErrorCode set_field_order(const EntityHandle meshset, const EntityType type, const std::string &name, const ApproximationOrder order, int verb=DEFAULT_VERBOSITY)=0
Set order approximation of the entities in the field.
virtual MoFEMErrorCode add_ents_to_field_by_type(const Range &ents, const EntityType type, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
bool checkMeshset(const int ms_id, const CubitBCType cubit_bc_type) const
Check for CUBIT meshset by ID and type.
MoFEM::PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::DomainEle Ele
const FTensor::Tensor2< T, Dim, Dim > Vec
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
VectorBoundedArray< double, 3 > VectorDouble3
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
implementation of Data Operators for Forces and Sources
static PetscErrorCode solve(Mat mat, Vec x, Vec y)
auto getInterfacePtr(DM dm)
Get the Interface Ptr object.
auto getDMSnesCtx(DM dm)
Get SNES context data structure used by DM.
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
virtual int get_comm_size() const =0
virtual moab::Interface & get_moab()=0
virtual MoFEMErrorCode add_field(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_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
const VectorDouble & getFieldData() const
Get DOF values on entity.
structure to get information from mofem into EntitiesFieldData
Interface for managing meshsets containing materials and boundary conditions.
Specialization for double precision scalar field values calculation.
Specialization for double precision vector field values calculation.
Post post-proc data at points from hash maps.
Template struct for dimension-specific finite element types.
Problem manager is used to build and partition problems.
Simple interface for fast problem set-up.
MoFEMErrorCode buildProblem()
Build problem.
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.
const std::string getBoundaryFEName() const
Get the Boundary FE Name.
MoFEMErrorCode defineFiniteElements()
Define finite elements.
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
MoFEMErrorCode buildFiniteElements()
Build finite elements.
MoFEMErrorCode addBoundaryField(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 boundary.
std::vector< std::string > & getOtherFiniteElements()
Get the Other Finite Elements.
MoFEMErrorCode getOptions()
get options
MoFEMErrorCode buildFields()
Build fields.
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
MoFEMErrorCode defineProblem(const PetscBool is_partitioned=PETSC_TRUE)
define problem
const std::string getProblemName() const
Get the Problem Name.
const std::string getDomainFEName() const
Get the Domain FE Name.
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Volume finite element base.
Class implemented by user to detect face orientation.
Shape preserving constrains, i.e. nodes sliding on body surface.
constexpr bool fix_edge_blocks