v0.14.0
Loading...
Searching...
No Matches
uniform_mesh_refinement.cpp
Go to the documentation of this file.
1/** \file uniform_mesh_refinement.cpp
2
3 \brief Uniformly refine mesh
4
5*/
6
7#include <MoFEM.hpp>
8using namespace MoFEM;
9
10static char help[] = "Uniform mesh refinement\n\n"
11
12 "Usage example:\n"
13
14 "$ ./uniform_mesh_refinement -my_file mesh.h5m "
15 "-output_file refined_mesh.h5m"
16
17 "\n\n";
18
19int main(int argc, char *argv[]) {
20
21 MoFEM::Core::Initialize(&argc, &argv, (char *)0, help);
22
23 try {
24
25 // global variables
26 char mesh_file_name[255];
27 char mesh_out_file[255] = "out.h5m";
28 int dim = 3;
29 int nb_levels = 1;
30 PetscBool shift = PETSC_TRUE;
31 PetscBool flg_file = PETSC_FALSE;
32 PetscBool debug = PETSC_FALSE;
33
34 ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "", "none", "none");
35 CHKERRQ(ierr);
36
37 CHKERR PetscOptionsString("-my_file", "mesh file name", "", "mesh.h5m",
38 mesh_file_name, 255, &flg_file);
39 if (flg_file != PETSC_TRUE)
40 CHKERR PetscOptionsString("-file_name", "mesh file name", "", "mesh.h5m",
41 mesh_file_name, 255, &flg_file);
42 CHKERR PetscOptionsString("-output_file", "output mesh file name", "",
43 "mesh.h5m", mesh_out_file, 255, PETSC_NULL);
44 CHKERR PetscOptionsInt("-dim", "entities dim", "", dim, &dim, PETSC_NULL);
45 CHKERR PetscOptionsInt("-nb_levels", "number of refinement levels", "",
46 nb_levels, &nb_levels, PETSC_NULL);
47 CHKERR PetscOptionsBool("-shift",
48 "shift bits, squash entities of refined elements",
49 "", shift, &shift, PETSC_NULL);
50 CHKERR PetscOptionsBool("-debug",
51 "write additional files with bit ref levels", "",
52 debug, &debug, PETSC_NULL);
53
54 ierr = PetscOptionsEnd();
55 CHKERRQ(ierr);
56
57 moab::Core mb_instance;
58 moab::Interface &moab = mb_instance;
59 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab, MYPCOMM_INDEX);
60 if (pcomm == NULL)
61 pcomm = new ParallelComm(&moab, PETSC_COMM_WORLD);
62
63 const char *option;
64 option = "";
65 CHKERR moab.load_file(mesh_file_name, 0, option);
66
67 // Create MoFEM database
68 MoFEM::Core core(moab);
69 MoFEM::Interface &m_field = core;
70
71 if (flg_file != PETSC_TRUE) {
72 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
73 "*** ERROR -my_file (-file_name) (mesh file needed)");
74 }
75
76 BitRefManager *bit_ref_manager;
77 CHKERR m_field.getInterface(bit_ref_manager);
78
79 auto bit = [](auto l) { return BitRefLevel().set(l); };
80
81 CHKERR bit_ref_manager->setBitRefLevelByDim(0, dim, bit(0));
82
83 for (auto l = 0; l != nb_levels; ++l) {
84 Range ents;
85 CHKERR bit_ref_manager->getEntitiesByDimAndRefLevel(
86 bit(l), BitRefLevel().set(), dim, ents);
87
88 Range edges;
89 CHKERR moab.get_adjacencies(ents, 1, true, edges, moab::Interface::UNION);
90
91 EntityHandle meshset_ref_edges;
92 CHKERR moab.create_meshset(MESHSET_SET, meshset_ref_edges);
93 CHKERR moab.add_entities(meshset_ref_edges, edges);
94
95 MeshRefinement *refine = m_field.getInterface<MeshRefinement>();
96
97 CHKERR refine->addVerticesInTheMiddleOfEdges(meshset_ref_edges,
98 bit(l + 1));
99 if (dim == 3) {
100 CHKERR refine->refineTets(ents, bit(l + 1));
101 } else if (dim == 2) {
102 CHKERR refine->refineTris(ents, bit(l + 1));
103 } else {
104 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
105 "Refinement implemented only for three and two dimensions");
106 }
107
108 auto update_meshsets = [&]() {
110 // update cubit meshsets
111 for (_IT_CUBITMESHSETS_FOR_LOOP_(m_field, ciit)) {
112 EntityHandle cubit_meshset = ciit->meshset;
114 cubit_meshset, bit(l + 1), cubit_meshset, MBMAXTYPE, true);
115 }
117 };
118
119 auto update_partition_sets = [&]() {
121
122 ParallelComm *pcomm = ParallelComm::get_pcomm(
123 &m_field.get_moab(), m_field.get_basic_entity_data_ptr()->pcommID);
124 Tag part_tag = pcomm->part_tag();
125
126 Range r_tagged_sets;
127 CHKERR m_field.get_moab().get_entities_by_type_and_tag(
128 0, MBENTITYSET, &part_tag, NULL, 1, r_tagged_sets,
129 moab::Interface::UNION);
130
131 std::vector<EntityHandle> tagged_sets(r_tagged_sets.size());
132 std::copy(r_tagged_sets.begin(), r_tagged_sets.end(),
133 tagged_sets.begin());
134
135 auto order_tagged_sets = [&]() {
137 std::vector<int> parts(tagged_sets.size());
138 CHKERR m_field.get_moab().tag_get_data(
139 part_tag, &*tagged_sets.begin(), tagged_sets.size(),
140 &*parts.begin());
141 map<int, EntityHandle> m_tagged_sets;
142 for (int p = 0; p != tagged_sets.size(); ++p) {
143 m_tagged_sets[parts[p]] = tagged_sets[p];
144 }
145 for (int p = 0; p != tagged_sets.size(); ++p) {
146 tagged_sets[p] = m_tagged_sets.at(p);
147 }
149 };
150
151 auto add_children = [&]() {
153 std::vector<Range> part_ents(tagged_sets.size());
154
155 for (int p = 0; p != tagged_sets.size(); ++p) {
156 Range ents;
157 CHKERR moab.get_entities_by_dimension(tagged_sets[p], dim, ents,
158 true);
159 CHKERR bit_ref_manager->filterEntitiesByRefLevel(
160 bit(l), BitRefLevel().set(), ents);
161
162 Range children;
163 CHKERR bit_ref_manager->updateRangeByChildren(ents, children);
164 children = children.subset_by_dimension(dim);
165 CHKERR bit_ref_manager->filterEntitiesByRefLevel(
166 bit(l + 1), BitRefLevel().set(), children);
167
168 Range adj;
169 for (auto d = 1; d != dim; ++d) {
170 CHKERR moab.get_adjacencies(children.subset_by_dimension(dim), d,
171 false, adj, moab::Interface::UNION);
172 }
173
174 part_ents[p].merge(children);
175 part_ents[p].merge(adj);
176 }
177
178 for (int p = 1; p != tagged_sets.size(); ++p) {
179 for (int pp = 0; pp != p; pp++) {
180 part_ents[p] = subtract(part_ents[p], part_ents[pp]);
181 }
182 }
183
184 for (int p = 0; p != tagged_sets.size(); ++p) {
185 CHKERR moab.add_entities(tagged_sets[p], part_ents[p]);
186 CHKERR moab.tag_clear_data(part_tag, part_ents[p], &p);
187 }
188
189 if (debug) {
190
191 auto save_range = [&](const std::string name, const Range &r) {
193 auto meshset_ptr = get_temp_meshset_ptr(m_field.get_moab());
194 CHKERR m_field.get_moab().add_entities(*meshset_ptr, r);
195 CHKERR m_field.get_moab().write_file(name.c_str(), "VTK", "",
196 meshset_ptr->get_ptr(), 1);
198 };
199
200 for (int p = 0; p != tagged_sets.size(); ++p) {
201 MOFEM_LOG("WORLD", Sev::inform)
202 << "Write part " << p << " level " << l;
203 Range ents;
204 CHKERR m_field.get_moab().get_entities_by_handle(tagged_sets[p],
205 ents, true);
206 CHKERR bit_ref_manager->filterEntitiesByRefLevel(
207 bit(l + 1), BitRefLevel().set(), ents);
208 CHKERR save_range("part" + boost::lexical_cast<std::string>(p) +
209 "_" + boost::lexical_cast<std::string>(l) +
210 ".vtk",
211 ents);
212 }
213 }
214
216 };
217
218 CHKERR order_tagged_sets();
219 CHKERR add_children();
220
222 };
223
224 CHKERR update_partition_sets();
225 CHKERR update_meshsets();
226
227 CHKERR moab.delete_entities(&meshset_ref_edges, 1);
228 }
229
230 if (debug) {
231 for (int l = 0; l <= nb_levels; ++l) {
232 MOFEM_LOG("WORLD", Sev::inform) << "Write level " << l;
233 CHKERR bit_ref_manager->writeBitLevel(
234 bit(l), BitRefLevel().set(),
235 ("level" + boost::lexical_cast<std::string>(l) + ".vtk").c_str(),
236 "VTK", "");
237 }
238 }
239
240 if (shift == PETSC_TRUE) {
241 MOFEM_LOG("WORLD", Sev::inform) << "Shift bits";
242 CHKERR core.getInterface<BitRefManager>()->shiftRightBitRef(
243 nb_levels, BitRefLevel().set(), VERBOSE);
244 }
245
246 CHKERR moab.write_file(mesh_out_file);
247 }
249
251 CHKERRQ(ierr);
252
253 return 0;
254}
int main()
@ 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 ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
MoFEMErrorCode updateMeshsetByEntitiesChildren(const EntityHandle parent, const BitRefLevel &parent_bit, const BitRefLevel &parent_mask, const BitRefLevel &child_bit, const BitRefLevel &child_mask, const EntityHandle child, EntityType child_type, const bool recursive=false, int verb=0)
Get child entities form meshset containing parent entities.
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 setBitRefLevelByDim(const EntityHandle meshset, const int dim, const BitRefLevel bit, int verb=QUIET) const
Set the Bit Ref Level By Dim object.
MoFEMErrorCode updateRangeByChildren(const Range &parent, Range &child, MoFEMTypes bh=MF_ZERO)
Update range by childrens.
#define MOFEM_LOG(channel, severity)
Log.
#define _IT_CUBITMESHSETS_FOR_LOOP_(MESHSET_MANAGER, IT)
Iterator that loops over all the Cubit MeshSets in a moFEM field.
auto bit
set bit
constexpr int nb_levels
Definition level_set.cpp:58
FTensor::Index< 'l', 3 > l
char mesh_file_name[255]
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition Types.hpp:40
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
static const bool debug
auto get_temp_meshset_ptr(moab::Interface &moab)
Create smart pointer to temporary meshset.
Managing BitRefLevels.
MoFEMErrorCode filterEntitiesByRefLevel(const BitRefLevel bit, const BitRefLevel mask, Range &ents, int verb=QUIET) const
filter entities by bit ref level
MoFEMErrorCode writeBitLevel(const BitRefLevel bit, const BitRefLevel mask, const char *file_name, const char *file_type, const char *options, const bool check_for_empty=true) const
Write bit ref level to file.
virtual moab::Interface & get_moab()=0
virtual boost::shared_ptr< BasicEntityData > & get_basic_entity_data_ptr()=0
Get pointer to basic entity data.
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:112
Deprecated interface functions.
Mesh refinement interface.
MoFEMErrorCode refineTets(const EntityHandle meshset, const BitRefLevel &bit, int verb=QUIET, const bool debug=false)
refine TET in the meshset
MoFEMErrorCode addVerticesInTheMiddleOfEdges(const EntityHandle meshset, const BitRefLevel &bit, const bool recursive=false, int verb=QUIET, EntityHandle start_v=0)
make vertices in the middle of edges in meshset and add them to refinement levels defined by bit
MoFEMErrorCode refineTris(const EntityHandle meshset, const BitRefLevel &bit, int verb=QUIET, const bool debug=false)
refine triangles in the meshset
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
auto save_range
static char help[]