18static char help[] =
"mesh smoothing\n\n";
30 Range &output_vertices);
32int main(
int argc,
char *argv[]) {
38 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Mesh cut options",
"none");
39 CHKERR PetscOptionsInt(
"-edges_block_set",
"edges side set",
"",
41 CHKERR PetscOptionsInt(
"-vertex_block_set",
"vertex side set",
"",
43 CHKERR PetscOptionsBool(
"-output_vtk",
"if true outout vtk file",
"",
45 CHKERR PetscOptionsScalar(
"-quality_reduction_tol",
"",
46 "Tolerance of quality reduction",
tol, &
tol,
48 CHKERR PetscOptionsScalar(
"-gamma_factor",
"",
55 moab::Interface &moab = moab_core;
65 Range edges, vertices, fixed_vertex;
108 CHKERR m_field.
get_moab().get_connectivity(edges, vertices,
true);
118 ->synchroniseFieldEntities(
"LAMBDA_EDGE");
123 "EDGE_SLIDING",
"MESH_NODE_POSITIONS");
125 "EDGE_SLIDING",
"MESH_NODE_POSITIONS");
127 "EDGE_SLIDING",
"MESH_NODE_POSITIONS");
146 if (!edges.empty()) {
155 "LAMBDA_SURFACE", verts, 0, 1);
157 CHKERR prb_mng->removeDofsOnEntities(
173 smoothing_cfg.
gamma = 0.0;
177 edges, smoothing_handles);
190 auto hook = [&](SNES snes, Vec x, Vec
F,
191 boost::shared_ptr<CacheTuple> cache_ptr,
200 boost::make_shared<PostProcEleDomain>(*m_field_ptr);
201 auto &pip = post_proc_fe->getOpPtrVector();
202 auto X_ptr = boost::make_shared<MatrixDouble>();
204 "MESH_NODE_POSITIONS", X_ptr));
205 auto res_X_ptr = boost::make_shared<MatrixDouble>();
208 auto lambda_ptr = boost::make_shared<VectorDouble>();
211 auto res_lambda_ptr = boost::make_shared<VectorDouble>();
220 post_proc_fe->getPostProcMesh(),
221 post_proc_fe->getMapGaussPts(),
223 {{
"LAMBDA_SURFACE", lambda_ptr},
224 {
"RES_LAMBDA_SURFACE", res_lambda_ptr}},
226 {{
"MESH_NODE_POSITIONS", X_ptr},
228 {
"RES_MESH_NODE_POSITIONS", res_X_ptr}},
239 CHKERR post_proc_fe->writeFile(
"debug_smoothing.h5m");
244 snes_ctx_ptr->getRhsHook() = hook;
256 "MESH_NODE_POSITIONS", it)) {
257 if (it->get()->getEntType() != MBVERTEX)
260 for(
int dd = 0;dd!=3;++dd)
261 coords[dd] = it->get()->getEntFieldData()[dd];
263 CHKERR m_field_ptr->
get_moab().set_coords(&ent, 1, &*coords.begin());
273 "MESH_NODE_POSITIONS", it)) {
274 if (it->get()->getEntType() != MBVERTEX)
278 CHKERR m_field_ptr->
get_moab().get_coords(&ent, 1, &*coords.begin());
279 for(
int dd = 0;dd!=3;++dd)
280 it->get()->getEntFieldData()[dd] = coords[dd];
290 double min_quality = 0;
292 dm, simple_interface->getDomainFEName(), smoothing_handles, min_quality);
293 PetscPrintf(PETSC_COMM_WORLD,
"Min quality = %4.3f\n", min_quality);
295 double gamma = min_quality > 0 ?
gamma_factor * min_quality
299 double min_quality_p,
eps;
302 min_quality_p = min_quality;
308 dm, simple_interface->getDomainFEName(), smoothing_handles,
311 eps = (min_quality - min_quality_p) / min_quality;
312 PetscPrintf(PETSC_COMM_WORLD,
"Min quality = %4.3f eps = %4.3f\n",
315 double gamma = min_quality > 0 ?
gamma_factor * min_quality
351 Range &output_vertices) {
354 Range fineFeatureTris;
360 "no 3d entities found in the mesh");
363 Skinner skinner(&m_field.
get_moab());
365 CHKERR skinner.find_skin(0, vols,
false, skin_tris);
366 if (skin_tris.empty()) {
368 "no skin triangles found in the mesh");
379 const double fine_planar_cos = std::cos(1e-6);
382 CHKERR m_field.
get_moab().get_adjacencies(skin_tris, 1,
true, skin_edges,
383 moab::Interface::UNION);
385 for (
auto edge : skin_edges) {
387 CHKERR m_field.
get_moab().get_adjacencies(&edge, 1, 2,
false, adj_tris,
388 moab::Interface::UNION);
389 adj_tris = intersect(adj_tris, skin_tris);
390 if (adj_tris.size() != 2) {
396 CHKERR tri_normal(adj_tris[0], n0);
397 CHKERR tri_normal(adj_tris[1], n1);
398 const double dot = n0(
i) * n1(
i);
399 if (std::abs(dot) <= fine_planar_cos) {
400 fineFeatureTris.insert(adj_tris[0]);
401 fineFeatureTris.insert(adj_tris[1]);
402 output_edges.insert(edge);
406 std::map<EntityHandle, std::vector<EntityHandle>> vert_edges;
407 for (
auto edge : output_edges) {
410 CHKERR m_field.
get_moab().get_connectivity(edge, conn, nconn,
false);
413 vert_edges[conn[0]].push_back(edge);
414 vert_edges[conn[1]].push_back(edge);
417 Range straight_edges;
418 for (
auto edge : output_edges) {
421 CHKERR m_field.
get_moab().get_connectivity(edge, conn, nconn,
false);
425 bool keep_edge =
true;
426 for (
int vv = 0; vv < 2; ++vv) {
427 const auto v = conn[vv];
428 const auto it = vert_edges.find(
v);
429 if (it == vert_edges.end()) {
433 const auto &inc_edges = it->second;
434 if (inc_edges.size() > 2) {
438 if (inc_edges.size() == 2) {
439 const auto other_edge =
440 (inc_edges[0] == edge) ? inc_edges[1] : inc_edges[0];
443 CHKERR m_field.
get_moab().get_connectivity(other_edge, conn_other,
445 if (nconn_other != 2) {
450 (conn_other[0] ==
v) ? conn_other[1] : conn_other[0];
452 double pv[3], pa[3], pb[3];
466 a(
i) = t_pa(
i) - t_pv(
i);
467 b(
i) = t_pb(
i) - t_pv(
i);
468 const double na =
a.l2();
469 const double nb = b.
l2();
470 if (na == 0 || nb == 0) {
474 const double dot = (
a(
i) * b(
i)) / (na * nb);
475 if (std::abs(dot) < fine_planar_cos) {
483 straight_edges.insert(edge);
487 output_edges = straight_edges;
488 output_vertices.clear();
489 if (!output_edges.empty()) {
490 std::map<EntityHandle, int> vert_count;
491 for (
auto edge : output_edges) {
494 CHKERR m_field.
get_moab().get_connectivity(edge, conn, nconn,
false);
497 vert_count[conn[0]]++;
498 vert_count[conn[1]]++;
500 Range filtered_edges;
501 for (
auto edge : output_edges) {
504 CHKERR m_field.
get_moab().get_connectivity(edge, conn, nconn,
false);
507 const int d0 = vert_count[conn[0]];
508 const int d1 = vert_count[conn[1]];
509 if (!(d0 == 1 && d1 == 1)) {
510 filtered_edges.insert(edge);
511 for (
int vv = 0; vv < 2; ++vv) {
512 const auto v = conn[vv];
513 auto it = vert_count.find(
v);
514 if (it != vert_count.end() && it->second == 1) {
515 output_vertices.insert(
v);
520 output_edges = filtered_edges;
523 if (!fineFeatureTris.empty())
525 "tri_features_test.vtk", fineFeatureTris);
526 if (!output_edges.empty())
529 if (!output_vertices.empty())
Post-process fields on refined mesh.
#define FTENSOR_INDEX(DIM, I)
#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 ...
@ MOFEM_DATA_INCONSISTENCY
#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 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.
#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.
FTensor::Index< 'i', SPACE_DIM > i
MoFEM::PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::DomainEle Ele
const double v
phase velocity of light in medium (cm/ns)
MoFEMErrorCode updateBarrierGamma(Handles &handles, double gamma)
MoFEMErrorCode evaluateMinQuality(DM dm, const std::string &domain_fe_name, const Handles &handles, double &min_quality)
MoFEMErrorCode createSnes(DM dm, SmartPetscObj< SNES > &snes)
MoFEMErrorCode solveSnes(DM dm, SNES snes, const std::vector< std::string > &zero_vertex_fields={})
MoFEMErrorCode createOperators(MoFEM::Interface &m_field, const Config &cfg, const Range &fixed_vertices, const Range &edge_entities, Handles &handles)
MoFEMErrorCode addToSnesDM(DM dm, const Config &cfg, const Handles &handles)
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
AdolCOps::VolumeLengthQualityType qualityType
std::string geometryField
std::string lambdaEdgeField
std::string meshReferenceField
std::string lambdaSurfaceField
bool enableSurfaceSliding
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.
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 getDM(DM *dm)
Get DM.
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.