v0.15.0
Loading...
Searching...
No Matches
Functions | Variables
mesh_cut.cpp File Reference

test for mesh cut interface More...

#include <MoFEM.hpp>

Go to the source code of this file.

Functions

int main (int argc, char *argv[])
 

Variables

static char help [] = "mesh cutting\n\n"
 

Detailed Description

test for mesh cut interface

Definition in file mesh_cut.cpp.

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 16 of file mesh_cut.cpp.

16 {
17
18 MoFEM::Core::Initialize(&argc, &argv, (char *)0, help);
19
20 try {
21
22 PetscBool flg_myfile = PETSC_TRUE;
23 PetscBool flg_surf_file = PETSC_FALSE;
24 char mesh_file_name[255];
25 char mesh_surf_name[255];
26 int surface_side_set = 200;
27 PetscBool flg_vol_block_set;
28 int vol_block_set = 1;
29 int edges_block_set = 1;
30 int vertex_block_set = 2;
31 PetscBool flg_shift;
32 double shift[] = {0, 0, 0};
33 int nmax = 3;
34 int fraction_level = 2;
35 PetscBool squash_bits = PETSC_TRUE;
36 PetscBool set_coords = PETSC_TRUE;
37 PetscBool output_vtk = PETSC_TRUE;
38 int create_surface_side_set = 201;
39 PetscBool flg_create_surface_side_set;
40 int nb_ref_cut = 0;
41 int nb_ref_trim = 0;
42 PetscBool flg_tol;
43 double tol[] = {1e-2, 2e-1, 2e-1};
44 int nmax_tol = 3;
45 int restricted_side_set = 205;
46 PetscBool debug = PETSC_FALSE;
47
48 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Mesh cut options", "none");
49 CHKERR PetscOptionsString("-my_file", "mesh file name", "", "mesh.h5m",
51 CHKERR PetscOptionsString("-my_surface", "cut mesh file name", "", "mesh.h5m",
52 mesh_surf_name, 255, &flg_surf_file);
53 CHKERR PetscOptionsInt("-surface_side_set", "surface side set", "",
54 surface_side_set, &surface_side_set, PETSC_NULLPTR);
55 CHKERR PetscOptionsInt("-vol_block_set", "volume side set", "",
56 vol_block_set, &vol_block_set, &flg_vol_block_set);
57 CHKERR PetscOptionsInt("-edges_block_set", "edges block set", "",
58 edges_block_set, &edges_block_set, PETSC_NULLPTR);
59 CHKERR PetscOptionsInt("-vertex_block_set", "vertex block set", "",
60 vertex_block_set, &vertex_block_set, PETSC_NULLPTR);
61 CHKERR PetscOptionsRealArray("-shift", "shift surface by vector", "", shift,
62 &nmax, &flg_shift);
63 CHKERR PetscOptionsInt("-fraction_level", "fraction of merges merged", "",
64 fraction_level, &fraction_level, PETSC_NULLPTR);
65 CHKERR PetscOptionsBool("-squash_bits", "true to squash bits at the end",
66 "", squash_bits, &squash_bits, PETSC_NULLPTR);
67 CHKERR PetscOptionsBool("-set_coords", "true to set coords at the end", "",
68 set_coords, &set_coords, PETSC_NULLPTR);
69 CHKERR PetscOptionsBool("-output_vtk", "if true outout vtk file", "",
70 output_vtk, &output_vtk, PETSC_NULLPTR);
71 CHKERR PetscOptionsInt("-create_side_set", "crete side set", "",
72 create_surface_side_set, &create_surface_side_set,
73 &flg_create_surface_side_set);
74 CHKERR PetscOptionsInt("-nb_ref_cut", "nb refinements befor cut", "",
75 nb_ref_cut, &nb_ref_cut, PETSC_NULLPTR);
76 CHKERR PetscOptionsInt("-nb_ref_trim", "nb refinements befor trim", "",
77 nb_ref_trim, &nb_ref_trim, PETSC_NULLPTR);
78
79 CHKERR PetscOptionsInt("-restricted_side_set", "sideset for constrained surface", "",
80 restricted_side_set, &restricted_side_set, PETSC_NULLPTR);
81
82 CHKERR PetscOptionsRealArray(
83 "-tol", "tolerances tolCut, tolCutClose, tolTrim, tolTrimClose", "",
84 tol, &nmax_tol, &flg_tol);
85 CHKERR PetscOptionsBool("-debug", "debug (produces many VTK files)", "",
86 debug, &debug, PETSC_NULLPTR);
87 PetscOptionsEnd();
88
89 if (flg_myfile != PETSC_TRUE) {
90 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
91 "*** ERROR -my_file (MESH FILE NEEDED)");
92 }
93 if (flg_shift && nmax != 3) {
94 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA, "three values expected");
95 }
96
97 if (flg_tol && nmax_tol != 3)
98 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA, "four values expected");
99
100 moab::Core mb_instance;
101 moab::Interface &moab = mb_instance;
102 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab, MYPCOMM_INDEX);
103 if (pcomm == NULL)
104 pcomm = new ParallelComm(&moab, PETSC_COMM_WORLD);
105
106 const char *option;
107 option = "";
108 CHKERR moab.load_file(mesh_file_name, 0, option);
109
110 MoFEM::Core core(moab);
111 MoFEM::CoreInterface &m_field =
112 *(core.getInterface<MoFEM::CoreInterface>());
113
114 // get cut mesh interface
115 CutMeshInterface *cut_mesh;
116 CHKERR m_field.getInterface(cut_mesh);
117 // get meshset manager interface
118 MeshsetsManager *meshset_manager;
119 CHKERR m_field.getInterface(meshset_manager);
120 // get bit ref manager interface
121 BitRefManager *bit_ref_manager;
122 CHKERR m_field.getInterface(bit_ref_manager);
123
125 (core.getInterface<MeshsetsManager &, 0>()), SIDESET, it)) {
126 cout << *it << endl;
127 }
128
129 CHKERR bit_ref_manager->setBitRefLevelByDim(0, 3, BitRefLevel().set(0));
130
132 EntityHandle def_set;
133 if (flg_surf_file) {
134 CHKERR moab.create_meshset(MESHSET_SET, def_set);
135 CHKERR moab.load_file(mesh_surf_name, &def_set, option);
136 CHKERR moab.get_entities_by_dimension(def_set, 2, surface, false);
137
138 if (surface.empty()) {
139 MOFEM_LOG("WORLD", Sev::warning)
140 << "The surface triangles not found. Using the skin.";
141 Skinner skin(&moab);
142 Range ents; // skin faces from 3d ents
143 CHKERR moab.get_entities_by_dimension(def_set, 3, ents, false);
144 CHKERR skin.find_skin(def_set, ents, false, surface);
145 // CHKERR moab.delete_entities(&def_set, 1);
146 // CHKERR moab.delete_entities(ents);
147 }
148
149 CHKERR meshset_manager->addMeshset(SIDESET, surface_side_set);
150 CHKERR meshset_manager->addEntitiesToMeshset(
151 SIDESET, surface_side_set, surface);
152 } else if (meshset_manager->checkMeshset(surface_side_set, SIDESET)) {
153 CHKERR meshset_manager->getEntitiesByDimension(surface_side_set, SIDESET,
154 2, surface, true);
155 }
156
157 if (surface.empty())
158 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID, "No surface to cut");
159
160 // Set surface entities. If surface entities are from existing side set,
161 // copy those entities and do other geometrical transformations, like shift
162 // scale or Stretch, rotate.
163 if (meshset_manager->checkMeshset(surface_side_set, SIDESET))
164 CHKERR cut_mesh->copySurface(surface, NULL, shift);
165 else
166 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
167 "Side set not found %d", surface_side_set);
168
169 // Get geometric corner nodes and corner edges
170 Range fixed_edges, corner_nodes;
171 if (meshset_manager->checkMeshset(edges_block_set, BLOCKSET))
173 1, fixed_edges, true);
174 if (meshset_manager->checkMeshset(edges_block_set, SIDESET))
176 1, fixed_edges, true);
177 if (meshset_manager->checkMeshset(vertex_block_set, BLOCKSET))
178 CHKERR meshset_manager->getEntitiesByDimension(
179 vertex_block_set, BLOCKSET, 0, corner_nodes, true);
180
181
182 Range tets;
183 if (flg_vol_block_set) {
184 if (meshset_manager->checkMeshset(vol_block_set, BLOCKSET))
185 CHKERR meshset_manager->getEntitiesByDimension(vol_block_set, BLOCKSET,
186 3, tets, true);
187 else
188 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
189 "Block set %d not found", vol_block_set);
190 } else
191 CHKERR moab.get_entities_by_dimension(0, 3, tets, false);
192 int start_bit = 0;
193 if (type_from_handle(tets[0]) == MBHEX) {
194
195 start_bit = 1;
196 MeshRefinement hex_refine(core);
197
198 CHKERR cut_mesh->setVolume(tets);
199 CHKERR cut_mesh->buildTree();
200 CHKERR cut_mesh->createSurfaceLevelSets();
201 CHKERR cut_mesh->findEdgesToCut(tets);
202 Range const &cut_edges = cut_mesh->getCutEdges();
203 Range intersect_vols;
204
205 CHKERR m_field.get_moab().get_adjacencies(
206 cut_edges, 3, false, intersect_vols, moab::Interface::UNION);
207 Range intersect_adj;
208 CHKERR m_field.get_moab().get_adjacencies(
209 intersect_vols, 2, false, intersect_adj, moab::Interface::UNION);
210 CHKERR m_field.get_moab().get_adjacencies(
211 intersect_adj, 3, false, intersect_vols, moab::Interface::UNION);
212 MOFEM_LOG_C("WORLD", Sev::inform, "Refine %d hexes to tets",
213 intersect_vols.size());
214 CHKERR hex_refine.refineHexToTets(intersect_vols,
215 BitRefLevel().set(start_bit));
216
217 Range level1;
218 CHKERR bit_ref_manager->getEntitiesByDimAndRefLevel(BitRefLevel().set(start_bit), BitRefLevel().set(), 3, level1);
219 tets = level1;
220 }
221
222 if (meshset_manager->checkMeshset(restricted_side_set, SIDESET)) {
223 Range restriced_surface;
224 CHKERR meshset_manager->getEntitiesByDimension(
225 restricted_side_set, SIDESET, 2, restriced_surface, true);
226 cut_mesh->setConstrainSurface(restriced_surface);
227 }
228
229 CHKERR cut_mesh->setVolume(tets);
230 CHKERR cut_mesh->makeFront(true);
231
232 // Build tree, it is used to ask geometrical queries, i.e. to find edges to
233 // cut or trim.
234 CHKERR cut_mesh->buildTree();
235
236 // Refine mesh
237 MOFEM_LOG_C("WORLD", Sev::inform,
238 "Refine mesh %d times before cut and %d times before trim",
239 nb_ref_cut, nb_ref_trim);
240 CHKERR cut_mesh->refineMesh(start_bit, nb_ref_cut, nb_ref_trim,
241 &fixed_edges, VERBOSE, false);
242 auto shift_after_ref = [&]() {
244 BitRefLevel mask;
245 mask.set(start_bit);
246 for (int ll = start_bit + 1; ll != start_bit + nb_ref_cut + nb_ref_trim + 1; ++ll)
247 mask.set(ll);
248 CHKERR core.getInterface<BitRefManager>()->shiftRightBitRef(
249 start_bit + nb_ref_cut + nb_ref_trim, mask, VERBOSE);
251 };
252 CHKERR shift_after_ref();
253
254 // Create tag storing nodal positions
255 double def_position[] = {0, 0, 0};
256 Tag th;
257 CHKERR moab.tag_get_handle("POSITION", 3, MB_TYPE_DOUBLE, th,
258 MB_TAG_CREAT | MB_TAG_SPARSE, def_position);
259 // Set tag values with coordinates of nodes
260 CHKERR cut_mesh->setTagData(th, start_bit);
261
262 int first_bit = start_bit + 1;
263
264 // Cut mesh, trim surface and merge bad edges
265 MOFEM_LOG_C("WORLD", Sev::inform,
266 "Cut mesh, trim surface and merge bad edges on %d levels",
267 fraction_level);
268 CHKERR cut_mesh->cutTrimAndMerge(first_bit, fraction_level, th, tol[0],
269 tol[1], tol[2], fixed_edges,
270 corner_nodes, true, false);
271
272 // Set coordinates for tag data
273 if (set_coords)
274 CHKERR cut_mesh->setCoords(th);
275
276 // Add tets from last level to block
277 if (flg_vol_block_set) {
278 EntityHandle meshset;
279 CHKERR meshset_manager->getMeshset(vol_block_set, BLOCKSET, meshset);
280 CHKERR bit_ref_manager->getEntitiesByTypeAndRefLevel(
281 BitRefLevel().set(first_bit), BitRefLevel().set(), MBTET, meshset);
282 }
283
284 // Shift bits
285 if (squash_bits) {
286 BitRefLevel shift_mask;
287 for (int ll = start_bit; ll != first_bit + start_bit; ++ll)
288 shift_mask.set(ll);
289 CHKERR core.getInterface<BitRefManager>()->shiftRightBitRef(
290 first_bit - 1, shift_mask, VERBOSE);
291 }
292
293 Range surface_verts;
294 CHKERR moab.get_connectivity(cut_mesh->getSurface(), surface_verts);
295 Range surface_edges;
296 CHKERR moab.get_adjacencies(cut_mesh->getSurface(), 1, false, surface_edges,
297 moab::Interface::UNION);
298 CHKERR moab.delete_entities(cut_mesh->getSurface());
299 CHKERR moab.delete_entities(surface_edges);
300 CHKERR moab.delete_entities(surface_verts);
301
302 if (flg_create_surface_side_set) {
303 // Check is meshset is there
304 if (!core.getInterface<MeshsetsManager>()->checkMeshset(
305 create_surface_side_set, SIDESET))
306 CHKERR meshset_manager->addMeshset(SIDESET, create_surface_side_set);
307 else
308 MOFEM_LOG_C("WORLD", Sev::warning,
309 "Warning >>> sideset %d is on the mesh",
310 create_surface_side_set);
311
312 CHKERR meshset_manager->addEntitiesToMeshset(
313 SIDESET, create_surface_side_set, cut_mesh->getMergedSurfaces());
314 }
315
316 CHKERR moab.write_file("out.h5m");
317
318 if (output_vtk) {
319 EntityHandle meshset;
320 CHKERR moab.create_meshset(MESHSET_SET, meshset);
321 if (flg_vol_block_set) {
322 Range ents;
323 meshset_manager->getEntitiesByDimension(vol_block_set, BLOCKSET, 3,
324 ents, true);
325 CHKERR moab.add_entities(meshset, ents);
326 } else {
328 CHKERR bit_ref_manager->getEntitiesByDimAndRefLevel(
329 bit, BitRefLevel().set(), 3, meshset);
330 }
331 CHKERR moab.add_entities(meshset, cut_mesh->getMergedSurfaces());
332 CHKERR moab.write_file("out.vtk", "VTK", "", &meshset, 1);
333 CHKERR moab.delete_entities(&meshset, 1);
334 }
335 }
337
339
340 return 0;
341}
#define MOFEM_LOG_C(channel, severity, format,...)
@ VERBOSE
#define CATCH_ERRORS
Catch errors.
#define MYPCOMM_INDEX
default communicator number PCOMM
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ SIDESET
@ BLOCKSET
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_INVALID_DATA
Definition definitions.h:36
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
MoFEMErrorCode getEntitiesByDimAndRefLevel(const BitRefLevel bit, const BitRefLevel mask, const int dim, const EntityHandle meshset, int verb=0) const
add all ents from ref level given by bit to meshset
MoFEMErrorCode getEntitiesByTypeAndRefLevel(const BitRefLevel bit, const BitRefLevel mask, const EntityType type, const EntityHandle meshset, int verb=0) const
add all ents from ref level given by bit to meshset
MoFEMErrorCode setBitRefLevelByDim(const EntityHandle meshset, const int dim, const BitRefLevel bit, int verb=QUIET) const
Set the Bit Ref Level By Dim object.
#define MOFEM_LOG(channel, severity)
Log.
MoFEMErrorCode getMeshset(const int ms_id, const unsigned int cubit_bc_type, EntityHandle &meshset) const
get meshset from CUBIT Id and CUBIT type
MoFEMErrorCode addEntitiesToMeshset(const CubitBCType cubit_bc_type, const int ms_id, const Range &ents)
Add entities to CUBIT meshset.
bool checkMeshset(const int ms_id, const CubitBCType cubit_bc_type) const
Check for CUBIT meshset by ID and type.
MoFEMErrorCode addMeshset(const CubitBCType cubit_bc_type, const int ms_id, const std::string name="")
Add CUBIT meshset to manager.
MoFEMErrorCode getEntitiesByDimension(const int ms_id, const unsigned int cubit_bc_type, const int dimension, Range &entities, const bool recursive=true) const
get entities from CUBIT/meshset of a particular entity dimension
#define _IT_CUBITMESHSETS_BY_SET_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet having a particular BC meshset in a moFEM field.
auto bit
set bit
constexpr int start_bit
Definition level_set.cpp:60
static char help[]
Definition mesh_cut.cpp:14
double tol
PetscBool output_vtk
PetscBool flg_myfile
int vertex_block_set
int edges_block_set
char mesh_file_name[255]
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition Types.hpp:40
auto type_from_handle(const EntityHandle h)
get type from entity handle
static const bool debug
Managing BitRefLevels.
virtual moab::Interface & get_moab()=0
Core (interface) class.
Definition Core.hpp:82
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition Core.cpp:72
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition Core.cpp:118
Interface to cut meshes.
MoFEMErrorCode copySurface(const Range surface, Tag th=NULL, double *shift=NULL, double *origin=NULL, double *transform=NULL, const std::string save_mesh="")
copy surface entities
const Range & getCutEdges() const
MoFEMErrorCode setCoords(Tag th, const BitRefLevel bit=BitRefLevel(), const BitRefLevel mask=BitRefLevel().set())
set coords from tag
MoFEMErrorCode findEdgesToCut(Range vol, int verb=QUIET, const bool debug=false)
find edges to cut
const Range & getMergedSurfaces() const
MoFEMErrorCode buildTree()
build tree
const Range & getSurface() const
MoFEMErrorCode setConstrainSurface(const Range surf)
Set the constrain surface object.
MoFEMErrorCode setVolume(const Range volume)
set volume entities
MoFEMErrorCode setTagData(Tag th, const BitRefLevel bit=BitRefLevel())
set coords to tag
MoFEMErrorCode cutTrimAndMerge(int &first_bit, const int fraction_level, Tag th, const double tol_geometry, const double tol_cut_close, const double tol_trim_close, Range &fixed_edges, Range &corner_nodes, const bool update_meshsets=false, const bool debug=false)
Cut, trim and merge.
MoFEMErrorCode makeFront(const bool debug=false)
Create front from the surface.
MoFEMErrorCode refineMesh(const int init_bit_level, const int surf_levels, const int front_levels, Range *fixed_edges=nullptr, int verb=QUIET, const bool debug=false)
Refine and set level sets.
MoFEMErrorCode createSurfaceLevelSets(int verb=QUIET, const bool debug=false)
Calculate distance from mesh nodes to cut surface.
Mesh refinement interface.
Interface for managing meshsets containing materials and boundary conditions.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.

Variable Documentation

◆ help

char help[] = "mesh cutting\n\n"
static

Definition at line 14 of file mesh_cut.cpp.