omega_h
Reliable mesh adaptation
Omega_h_mesh.hpp
1 #ifndef OMEGA_H_MESH_HPP
2 #define OMEGA_H_MESH_HPP
3 
4 #include <Omega_h_adj.hpp>
5 #include <Omega_h_comm.hpp>
6 #include <Omega_h_dist.hpp>
7 #include <Omega_h_library.hpp>
8 #include <Omega_h_tag.hpp>
9 #include <array>
10 #include <map>
11 #include <set>
12 #include <string>
13 #include <vector>
14 
15 namespace Omega_h {
16 
17 namespace inertia {
18 struct Rib;
19 }
20 
21 struct ClassPair {
22  inline ClassPair() = default;
23  inline ClassPair(Int t_dim, LO t_id) : dim(t_dim), id(t_id) {}
24  Int dim;
25  LO id;
26  OMEGA_H_INLINE bool operator<(ClassPair const& other) const {
27  if (dim != other.dim) return dim < other.dim;
28  if (id != other.id) return id < other.id;
29  return false;
30  }
31 };
32 
33 using ClassSets = std::map<std::string, std::vector<ClassPair>>;
34 
35 class Mesh {
36  public:
37  Mesh();
38  Mesh(Library* library);
39  void set_library(Library* library);
40  void set_comm(CommPtr const& comm);
41  void set_family(Omega_h_Family family);
42  void set_matched(I8 is_matched);
43  virtual void set_dim(Int dim_in);
44  void set_verts(LO nverts_in);
45  void set_ents(Int ent_dim, Adj down);
46  void set_parents(Int ent_dim, Parents parents);
47  Library* library() const;
48  CommPtr comm() const;
49  Omega_h_Parting parting() const;
50  virtual inline Int dim() const {
51  OMEGA_H_CHECK(0 <= dim_ && dim_ <= 3);
52  return dim_;
53  }
54  inline Omega_h_Family family() const { return family_; }
55  inline I8 is_matched() const { return matched_; }
56  LO nents(Int ent_dim) const;
57  LO nelems() const;
58  LO nregions() const;
59  LO nfaces() const;
60  LO nedges() const;
61  LO nverts() const;
62  GO nglobal_ents(Int dim);
63  template <typename T>
64  void add_tag(Int dim, std::string const& name, Int ncomps);
65  template <typename T>
66  void add_tag(Int dim, std::string const& name, Int ncomps, ArrayType array_type);
67  template <typename T>
68  void add_tag(Int dim, std::string const& name, Int ncomps, Read<T> array,
69  bool internal = false, ArrayType array_type = ArrayType::VectorND);
70  template <typename T>
71  void set_tag(
72  Int dim, std::string const& name, Read<T> array, bool internal = false, ArrayType array_type = ArrayType::VectorND);
73  TagBase const* get_tagbase(Int dim, std::string const& name) const;
74  template <typename T>
75  Tag<T> const* get_tag(Int dim, std::string const& name) const;
76  template <typename T>
77  Read<T> get_array(Int dim, std::string const& name) const;
78  void remove_tag(Int dim, std::string const& name);
79  bool has_tag(Int dim, std::string const& name) const;
80  [[nodiscard]] Int ntags(Int dim) const;
81  [[nodiscard]] Int nrctags(Int dim) const;
82  TagBase const* get_tag(Int dim, Int i) const;
83  bool has_ents(Int dim) const;
84  bool has_adj(Int from, Int to) const;
85  Adj get_adj(Int from, Int to) const;
86  Adj ask_down(Int from, Int to);
87  LOs ask_verts_of(Int dim);
88  LOs ask_elem_verts();
89  Adj ask_up(Int from, Int to);
90  Graph ask_star(Int dim);
91  Graph ask_dual();
92 
100  Adj ask_revClass(Int edim, LOs class_ids);
101 
106  Adj ask_revClass(Int edim);
107 
119  Adj ask_revClass_downAdj(Int from, Int to);
120 
125  bool has_revClass(Int edim) const;
126 
132  template <typename T>
133  void add_rcField(
134  LOs class_ids, Int ent_dim, std::string const& name, Int ncomps);
135 
139  template <typename T>
140  void set_rcField_array(Int ent_dim, std::string const& name, Read<T> array);
141 
145  void remove_rcField(Int ent_dim, std::string const& name);
146 
147  [[nodiscard]] Adj get_revClass(Int edim) const;
148 
154  template <typename T>
155  void add_rcField(Int ent_dim, std::string const& name, Int ncomps);
156 
157  template <typename T>
158  [[nodiscard]] Read<T> get_rcField_array(
159  Int ent_dim, std::string const& name) const;
160  void reduce_rcField(Int ent_dim, std::string const& name, Omega_h_Op op);
161  template <typename T>
162  void add_rcField(
163  Int ent_dim, std::string const& name, Int ncomps, Read<T> array);
164  void sync_rcField(Int ent_dim, std::string const& name);
165  [[nodiscard]] bool has_rcField(Int ent_dim, std::string const& name) const;
166 
167  template <typename T>
168  void set_rc_from_mesh_array(Int ent_dim, Int ncomps, LOs class_ids,
169  std::string const& name, Read<T> array);
170  friend class ScopedChangeRCFieldsToMesh;
171 
184  [[nodiscard]] Graph get_vtx_patches(Int minPatchSize, Int tgtDim = -1);
185 
186 
187  private:
188  bool change_all_rcFieldsToMesh();
189  bool change_all_rcFieldsTorc();
190  template <typename T>
191  void change_tagTorc(Int ent_dim, Int ncomps, std::string const& name,
192  LOs class_ids, bool remove = true);
193  template <typename T>
194  void change_tagToMesh(Int ent_dim, Int ncomps, std::string const& name,
195  LOs class_ids, bool remove = true);
196 // Don't use these functions... they need to be public for OOMEGA_H_LAMBDA
197  public:
198  template <typename T>
199  [[nodiscard]] Read<T> get_rc_mesh_array(
200  Int ent_dim, Int ncomps, std::string const& name, LOs class_ids);
201 
202  template <typename T>
203  [[nodiscard]] Read<T> get_rc_array_from_mesh_array(Int ent_dim, Int ncomps,
204  std::string const& name, LOs class_ids, Read<T> mesh_array);
205 
206  template <typename T>
207  [[nodiscard]] std::unique_ptr<Tag<T>> get_rc_mesh_tag_from_rc_tag(
208  Int dim, Tag<T> const*);
209 
210  template <typename T>
211  [[nodiscard]] Read<T> get_rc_array(Int dim, std::string const& name) const;
212 
213  template <typename T>
214  [[nodiscard]] Read<T> get_rc_mesh_array_from_rc_array(
215  Int ent_dim, Int ncomps, LOs class_ids, Read<T> rc_field);
216 
217  public:
218  typedef std::shared_ptr<const TagBase> TagPtr;
219  typedef std::shared_ptr<const Adj> AdjPtr;
220  typedef std::shared_ptr<const Dist> DistPtr;
221  typedef std::shared_ptr<const inertia::Rib> RibPtr;
222  typedef std::shared_ptr<const Parents> ParentPtr;
223  typedef std::shared_ptr<const Children> ChildrenPtr;
224 
225  private:
226  typedef std::vector<TagPtr> TagVector;
227  typedef TagVector::iterator TagIter;
228  typedef TagVector::const_iterator TagCIter;
229  struct TagIterResult {
230  bool had_tag;
231  Mesh::TagIter it;
232  };
233  struct TagCIterResult {
234  bool had_tag;
235  Mesh::TagCIter it;
236  };
237  TagIter tag_iter(Int dim, std::string const& name);
238  TagCIter tag_iter(Int dim, std::string const& name) const;
239  TagIterResult rc_tag_iter(Int dim, std::string const& name);
240  TagCIterResult rc_tag_iter(Int dim, std::string const& name) const;
241  void check_dim(Int dim) const;
242  void check_dim2(Int dim) const;
243  void add_adj(Int from, Int to, Adj adj);
244  Adj derive_adj(Int from, Int to);
245  Adj ask_adj(Int from, Int to);
246  void react_to_set_tag(Int dim, std::string const& name);
247  Omega_h_Family family_;
248  I8 matched_ = -1;
249  CommPtr comm_;
250  Int parting_;
251  Int nghost_layers_;
252  LO nents_[DIMS];
253  TagVector tags_[DIMS];
254  // rc field tags stored in "rc" format
255  TagVector rc_field_tags_[DIMS];
256  AdjPtr adjs_[DIMS][DIMS];
257  Remotes owners_[DIMS];
258  DistPtr dists_[DIMS];
259  RibPtr rib_hints_;
260  ParentPtr parents_[DIMS];
261  ChildrenPtr children_[DIMS][DIMS];
262  Library* library_;
263  Remotes match_owners_[DIMS];
264  LOs model_ents_[DIMS];
265  LOs model_matches_[DIMS - 1];
266 
267  AdjPtr revClass_[DIMS];
268 
269  void add_rcField(Int ent_dim, std::string const& name, TagPtr tag);
270 
271 protected:
272  Int dim_;
273 
274  public:
275  void add_coords(Reals array);
276  Reals coords() const;
277  void set_coords(Reals const& array);
278  Read<GO> globals(Int dim) const;
279  Reals ask_lengths();
280  Reals ask_qualities();
282  Reals ask_sizes();
283  Bytes ask_levels(Int dim);
284  Bytes ask_leaves(Int dim);
285  Parents ask_parents(Int child_dim);
286  Children ask_children(Int parent_dim, Int child_dim);
287  bool has_any_parents() const;
288  void set_owners(Int dim, Remotes owners);
289  Remotes ask_owners(Int dim);
290  Read<I8> owned(Int dim);
291  Dist ask_dist(Int dim);
292  Int nghost_layers() const;
293  void set_parting(Omega_h_Parting parting_in, Int nlayers, bool verbose);
294  void set_parting(Omega_h_Parting parting_in, bool verbose = false);
295  void balance(bool predictive = false);
296  void balance(Reals weights);
305  void migrate(Remotes& owners);
306  Graph ask_graph(Int from, Int to);
307  template <typename T>
308  Read<T> sync_array(Int ent_dim, Read<T> a, Int width);
309  template <typename T>
310  Future<T> isync_array(Int ent_dim, Read<T> a, Int width);
311  template <typename T>
312  Read<T> sync_subset_array(
313  Int ent_dim, Read<T> a_data, LOs a2e, T default_val, Int width);
314  template <typename T>
315  Read<T> reduce_array(Int ent_dim, Read<T> a, Int width, Omega_h_Op op);
316  template <typename T>
317  Read<T> owned_array(Int ent_dim, Read<T> a, Int width);
318  template <typename T>
319  Read<T> owned_subset_array(
320  Int ent_dim, Read<T> a_data, LOs a2e, T default_val, Int width);
321  void sync_tag(Int dim, std::string const& name);
322  void reduce_tag(Int dim, std::string const& name, Omega_h_Op op);
323  bool operator==(Mesh& other);
324  Real min_quality();
325  Real max_length();
326  bool could_be_shared(Int ent_dim) const;
327  bool owners_have_all_upward(Int ent_dim) const;
328  bool have_all_upward() const;
329  Mesh copy_meta() const;
330  RibPtr rib_hints() const;
331  void set_rib_hints(RibPtr hints);
332  Real imbalance(Int ent_dim = -1) const;
333  Adj derive_revClass(Int edim, I8 should_sort = -1);
334 
335  void set_model_ents(Int ent_dim, LOs Ids);
336  void set_model_matches(Int ent_dim, LOs matches);
337  LOs get_model_ents(Int ent_dim);
338  LOs get_model_matches(Int ent_dim);
339  void set_match_owners(Int dim, Remotes owners);
340  Remotes ask_match_owners(Int dim);
341  c_Remotes matches_[DIMS];
342  void set_matches(Int dim, c_Remotes matches);
343  c_Remotes get_matches(Int dim);
344  void swap_root_owner(Int dim);
345  void sync_tag_matched(Int dim, std::string const& name);
346  template <typename T>
347  Read<T> sync_array_matched(Int ent_dim, Read<T> a, Int width);
348  Real ghosted_ratio(Int ent_dim);
349  LO nents_owned(Int ent_dim);
350  std::string string(int verbose = 0);
351 
352  virtual ~Mesh() = default;
353 
361  ClassSets class_sets;
362  [[nodiscard]] const TagVector& get_rc_tags(Int dim) const {
363  return rc_field_tags_[dim];
364  }
365  [[nodiscard]] std::unique_ptr<TagBase> get_rc_mesh_tag_from_rc_tag(
366  Int dim, TagBase const*);
367 };
368 
370  public:
371  // [[nodiscard]] // should be nodiscard when c++17 turned on
372  explicit ScopedChangeRCFieldsToMesh(Mesh& mesh) : mesh_(mesh) {
373  changed_here_ = mesh_.change_all_rcFieldsToMesh();
374  }
376  if (changed_here_) {
377  mesh_.change_all_rcFieldsTorc();
378  }
379  }
380  [[nodiscard]] bool did_conversion() const noexcept { return changed_here_; }
381 
382  private:
383  Mesh& mesh_;
384  bool changed_here_;
385 };
386 
387 bool can_print(Mesh* mesh);
388 
389 Real repro_sum_owned(Mesh* mesh, Int dim, Reals a);
390 
391 Reals average_field(Mesh* mesh, Int dim, LOs a2e, Int ncomps, Reals v2x);
392 Reals average_field(Mesh* mesh, Int dim, Int ncomps, Reals v2x);
393 
394 using TagSet = std::array<std::set<std::string>, DIMS>;
395 
396 void get_all_dim_tags(Mesh* mesh, Int dim, TagSet* tags);
397 TagSet get_all_mesh_tags(Mesh* mesh);
398 void ask_for_mesh_tags(Mesh* mesh, TagSet const& tags);
399 
400 void reorder_by_hilbert(Mesh* mesh);
401 void reorder_by_globals(Mesh* mesh);
402 
403 LOs ents_on_closure(
404  Mesh* mesh, std::set<std::string> const& class_names, Int ent_dim);
405 
406 LOs nodes_on_closure(
407  Mesh* mesh, std::set<std::string> const& class_names, Graph nodes2ents[4]);
408 
409 bool is_rc_tag(std::string const& name);
410 
411 void assign(Mesh& a, Mesh const& b);
412 
413 #define OMEGA_H_EXPL_INST_DECL(T) \
414  extern template Tag<T> const* Mesh::get_tag<T>( \
415  Int dim, std::string const& name) const; \
416  extern template Read<T> Mesh::get_array<T>(Int dim, std::string const& name) \
417  const; \
418  extern template void Mesh::add_tag<T>( \
419  Int dim, std::string const& name, Int ncomps); \
420  extern template void Mesh::add_tag<T>( \
421  Int dim, std::string const& name, Int ncomps, ArrayType array_type); \
422  extern template void Mesh::add_tag<T>(Int dim, std::string const& name, \
423  Int ncomps, Read<T> array, bool internal, ArrayType array_type); \
424  extern template void Mesh::set_tag(Int dim, std::string const& name, \
425  Read<T> array, bool internal, ArrayType array_type); \
426  extern template Read<T> Mesh::sync_array(Int ent_dim, Read<T> a, Int width); \
427  extern template Future<T> Mesh::isync_array( \
428  Int ent_dim, Read<T> a, Int width); \
429  extern template Read<T> Mesh::owned_array( \
430  Int ent_dim, Read<T> a, Int width); \
431  extern template Read<T> Mesh::sync_subset_array( \
432  Int ent_dim, Read<T> a_data, LOs a2e, T default_val, Int width); \
433  extern template Read<T> Mesh::owned_subset_array( \
434  Int ent_dim, Read<T> a_data, LOs a2e, T default_val, Int width); \
435  extern template Read<T> Mesh::reduce_array( \
436  Int ent_dim, Read<T> a, Int width, Omega_h_Op op); \
437  extern template void Mesh::change_tagTorc<T>( \
438  Int ent_dim, Int ncomps, std::string const& name, LOs class_ids, bool); \
439  extern template void Mesh::change_tagToMesh<T>( \
440  Int ent_dim, Int ncomps, std::string const& name, LOs class_ids, bool); \
441  extern template Read<T> Mesh::get_rc_mesh_array( \
442  Int ent_dim, Int ncomps, std::string const& name, LOs class_ids); \
443  extern template Read<T> Mesh::get_rc_array_from_mesh_array(Int ent_dim, \
444  Int ncomps, std::string const& name, LOs class_ids, Read<T> mesh_array); \
445  extern template Read<T> Mesh::get_rcField_array<T>( \
446  Int dim, std::string const& name) const; \
447  extern template void Mesh::add_rcField<T>( \
448  Int dim, std::string const& name, Int ncomps); \
449  extern template void Mesh::add_rcField<T>( \
450  LOs class_ids, Int dim, std::string const& name, Int ncomps); \
451  extern template void Mesh::add_rcField<T>( \
452  Int dim, std::string const& name, Int ncomps, Read<T> array); \
453  extern template void Mesh::set_rcField_array( \
454  Int dim, std::string const& name, Read<T> array); \
455  extern template void Mesh::set_rc_from_mesh_array(Int ent_dim, Int ncomps, \
456  LOs class_ids, std::string const& name, Read<T> array); \
457  extern template std::unique_ptr<Tag<T>> Mesh::get_rc_mesh_tag_from_rc_tag( \
458  Int, Tag<T> const*); \
459  extern template Read<T> Mesh::get_rc_array(Int dim, std::string const& name) \
460  const; \
461  extern template Read<T> Mesh::get_rc_mesh_array_from_rc_array( \
462  Int ent_dim, Int ncomps, LOs class_ids, Read<T> rc_field);
463 OMEGA_H_EXPL_INST_DECL(I8)
464 OMEGA_H_EXPL_INST_DECL(I32)
465 OMEGA_H_EXPL_INST_DECL(I64)
466 OMEGA_H_EXPL_INST_DECL(Real)
467 #undef OMEGA_H_EXPL_INST_DECL
468 
469 } // namespace Omega_h
470 
471 #endif
472 
an MPI distributor object which encapsulates the idea of a communication pattern between lots of smal...
Definition: Omega_h_dist.hpp:119
Abstraction for asynchronous communication.
Definition: Omega_h_future.hpp:19
Definition: Omega_h_library.hpp:10
Definition: Omega_h_mesh.hpp:35
void add_rcField(LOs class_ids, Int ent_dim, std::string const &name, Int ncomps)
Definition: Omega_h_rcFields.cpp:356
Adj ask_revClass_downAdj(Int from, Int to)
Definition: Omega_h_rcFields.cpp:496
Graph get_vtx_patches(Int minPatchSize, Int tgtDim=-1)
form a patch of at least minPatchSize elements surrounding each mesh vertex
Definition: Omega_h_patches.cpp:133
Reals ask_sizes()
Definition: Omega_h_mesh.cpp:445
bool has_revClass(Int edim) const
Definition: Omega_h_rcFields.cpp:62
void migrate(Remotes &owners)
Definition: Omega_h_mesh.cpp:652
ClassSets class_sets
Definition: Omega_h_mesh.hpp:361
void set_rcField_array(Int ent_dim, std::string const &name, Read< T > array)
Definition: Omega_h_rcFields.cpp:397
void remove_rcField(Int ent_dim, std::string const &name)
Definition: Omega_h_rcFields.cpp:388
Adj ask_revClass(Int edim, LOs class_ids)
Definition: Omega_h_rcFields.cpp:154
Definition: Omega_h_array.hpp:89
Definition: Omega_h_mesh.hpp:369
Definition: Omega_h_tag.hpp:31
Definition: Omega_h_tag.hpp:53
Definition: amr_mpi_test.cpp:6
Definition: Omega_h_adj.hpp:11
Definition: Omega_h_adj.hpp:30
Definition: Omega_h_mesh.hpp:21
directed graph (as defined by graph theory) in compressed row format
Definition: Omega_h_graph.hpp:22
Definition: Omega_h_adj.hpp:22
Definition: Omega_h_remotes.hpp:9
Definition: Omega_h_remotes.hpp:23