GetFEM++  5.3
getfem_mesh_region.h
Go to the documentation of this file.
1 /* -*- c++ -*- (enables emacs c++ mode) */
2 /*===========================================================================
3 
4  Copyright (C) 2005-2017 Yves Renard, Julien Pommier
5 
6  This file is a part of GetFEM++
7 
8  GetFEM++ is free software; you can redistribute it and/or modify it
9  under the terms of the GNU Lesser General Public License as published
10  by the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version along with the GCC Runtime Library
12  Exception either version 3.1 or (at your option) any later version.
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16  License and GCC Runtime Library Exception for more details.
17  You should have received a copy of the GNU Lesser General Public License
18  along with this program; if not, write to the Free Software Foundation,
19  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 
21  As a special exception, you may use this file as it is a part of a free
22  software library without restriction. Specifically, if other files
23  instantiate templates or use macros or inline functions from this file,
24  or you compile this file and link it with other files to produce an
25  executable, this file does not by itself cause the resulting executable
26  to be covered by the GNU Lesser General Public License. This exception
27  does not however invalidate any other reasons why the executable file
28  might be covered by the GNU Lesser General Public License.
29 
30 ===========================================================================*/
31 
32 /**@file getfem_mesh_region.h
33 @author Yves Renard, Julien Pommier
34 @date 2005.
35 @brief region objects (set of convexes and/or convex faces)
36 */
37 
38 #ifndef GETFEM_MESH_REGION
39 #define GETFEM_MESH_REGION
40 
41 #include <bitset>
42 #include <iostream>
43 #include "dal_bit_vector.h"
44 #include "bgeot_convex_structure.h"
45 #include "getfem_config.h"
46 
47 // #if __cplusplus > 199711L
48 // #include <unordered_map>
49 // #elif defined(GETFEM_HAVE_BOOST) && BOOST_VERSION >= 103600
50 // #include <boost/unordered_map.hpp>
51 // #else
52 #include <map>
53 // #endif
54 
55 // #ifdef GETFEM_HAVE_BOOST
56 // #include <boost/shared_ptr.hpp>
57 // #endif
58 
59 
60 namespace getfem {
61  class mesh;
62 
63  /** structure used to hold a set of convexes and/or convex faces.
64  @see mesh::region
65  */
66  class APIDECL mesh_region {
67  public:
68  typedef std::bitset<MAX_FACES_PER_CV+1> face_bitset;
69 
70  // #if __cplusplus > 199711L
71  // typedef std::unordered_map<size_type,face_bitset> map_t;
72  // #elif defined(GETFEM_HAVE_BOOST) && BOOST_VERSION >= 103600
73  // typedef boost::unordered_map<size_type,face_bitset> map_t;
74  // #else
75  typedef std::map<size_type,face_bitset> map_t;
76  // #endif
77 
78  private:
79 
80  typedef map_t::const_iterator const_iterator;
81 
82  struct impl {
83  mutable map_t m;
84  mutable omp_distribute<dal::bit_vector> index_;
85  };
86 
87  // #ifdef GETFEM_HAVE_BOOST
88  //need to use boost smart pointer, cause it's reference
89  //counting is thread safe
90  // boost::shared_ptr<impl> p; /* the real region data */
91  // #else
92  std::shared_ptr<impl> p; /* the real region data */
93  // #endif
94 
95  size_type id_; /* used temporarily when the
96  mesh_region(size_type) constructor is used */
97 
98  size_type type_; //optional type of the region
99  omp_distribute<bool> partitioning_allowed; /** specifies that in
100  multithreaded code only a partition of the
101  region is visible in index() and size() methods,
102  as well as during iteration with mr_visitor */
103  mesh *parent_mesh; /* used for mesh_region "extracted" from
104  a mesh (to provide feedback) */
105 
106 
107  //cashing iterators for paritions
108  mutable omp_distribute<const_iterator> itbegin;
109  mutable omp_distribute<const_iterator> itend;
110  mutable omp_distribute<bool> index_updated;
111  void update_partition_iterators() const;
112 
113  impl &wp() { return *p.get(); }
114  const impl &rp() const { return *p.get(); }
115  void clean();
116  /** tells the owner mesh that the region is valid */
117  void touch_parent_mesh();
118 
119  /**when running while multithreaded, gives the iterator
120  for the beginning of the region partition for the current thread*/
121  const_iterator partition_begin( ) const;
122 
123  /**when running while multithreaded, gives the iterator
124  for the end of the region partition for the current thread*/
125  const_iterator partition_end ( ) const;
126 
127  /**begin iterator of the region depending if its partitioned or not*/
128  const_iterator begin( ) const;
129 
130  /**end iteratorof the region depending if its partitioned or not*/
131  const_iterator end ( ) const;
132 
133  /**number of region entries before partitining*/
134  size_type unpartitioned_size() const;
135 
136  public:
137  mesh_region(const mesh_region &other);
138  mesh_region();
139  /** a mesh_region can be built from a integer parameter
140  (a region number in a mesh),
141  but it won't be usable until 'from_mesh(m)' has been called
142  Note that these regions are read-only, this constructor is
143  mostly used for backward-compatibility.
144  */
145  mesh_region(size_type id__);
146 
147  /** internal constructor. You should used m.region(id) instead. */
148  mesh_region(mesh& m, size_type id__, size_type type = size_type(-1));
149  /** build a mesh_region from a convex list stored in a bit_vector. */
150  mesh_region(const dal::bit_vector &bv);
151 
152  /** provide a default value for the mesh_region parameters of assembly
153  procedures etc. */
155  return mesh_region(size_type(-1));
156  }
157  /** return the intersection of two mesh regions */
158  static mesh_region intersection(const mesh_region& a,
159  const mesh_region& b);
160  /** return the union of two mesh_regions */
161  static mesh_region merge(const mesh_region &a,
162  const mesh_region &b);
163  /** subtract the second region from the first one */
164  static mesh_region subtract(const mesh_region &a,
165  const mesh_region &b);
166  /** Test if the region is a boundary of a list of faces of elements of
167  region `rg`. Return 0 if not, -1 if only partially, 1 if the region
168  contains only some faces which are all faces of elements of `rg`. */
169  int region_is_faces_of(const getfem::mesh& m1,
170  const mesh_region &rg2,
171  const getfem::mesh& m2) const;
172 
173  size_type id() const { return id_; }
174 
175  size_type get_type() const { return type_; }
176 
177  void set_type(size_type type) { type_ = type; }
178 
179  /** In multithreaded part of the program makes only a partition of the
180  region visible in the index() and size() operations, as well as during
181  iterations with mr_visitor. This is a default behaviour*/
182  void allow_partitioning();
183 
184  /** Return the bounding box [Pmin - Pmax] of the mesh_region. */
185  void bounding_box(base_node& Pmin, base_node& Pmax) const;
186 
187  /** Disregard partitioning, which means being able to see the whole region
188  in multirheaded code. Can be used, for instance, for contact problems
189  where master region is partitioned, while the slave region is not*/
190  void prohibit_partitioning();
191 
192  bool is_partitioning_allowed() const;
193 
194  /** Extract the next region number
195  that does not yet exists in the mesh*/
196  static size_type free_region_id(const getfem::mesh& m);
197 
198 
199  /** For regions which have been built with just a number 'id',
200  from_mesh(m) sets the current region to 'm.region(id)'.
201  (works only once)
202  */
203  const mesh_region& from_mesh(const mesh &m) const;
204 
205  mesh_region& operator=(const mesh_region &mr);
206 
207  bool compare(const mesh &m1, const mesh_region &mr, const mesh &m2) const;
208 
209  face_bitset operator[](size_t cv) const;
210 
211  /** Index of the region convexes, or the convexes from the partition on the
212  current thread. */
213  const dal::bit_vector& index() const;
214  void add(const dal::bit_vector &bv);
215  void add(size_type cv, short_type f = short_type(-1));
216  void sup(size_type cv, short_type f = short_type(-1));
217  void sup_all(size_type cv);
218  void clear();
219  void swap_convex(size_type cv1, size_type cv2);
220  bool is_in(size_type cv, short_type f = short_type(-1)) const;
221  bool is_in(size_type cv, short_type f, const mesh &m) const;
222 
223  /** Region size, or the size of the region partition on the current
224  thread if the region is partitioned*/
225  size_type size() const;
226 
227  /** Number of convexes in the region, or on the partition on the current
228  thread*/
229  size_type nb_convex() const { return index().card();}
230  bool is_empty() const;
231  /** Return true if the region do contain only convex faces */
232  bool is_only_faces() const;
233  bool is_boundary() const { return is_only_faces(); }
234  /** Return true if the region do not contain any convex face */
235  bool is_only_convexes() const;
236  face_bitset faces_of_convex(size_type cv) const;
237  face_bitset and_mask() const;
238  face_bitset or_mask() const;
239  void error_if_not_faces() const;
240  void error_if_not_convexes() const;
241  void error_if_not_homogeneous() const;
242  const mesh *get_parent_mesh(void) const { return parent_mesh; }
243  void set_parent_mesh(mesh *pm) { parent_mesh = pm; }
244 
245 
246 
247  /** "iterator" class for regions. Usage similar to bv_visitor:
248  for (mr_visitor i(region); !i.finished(); ++i) {
249  ...
250  }
251  */
252  class visitor {
253 
254  typedef mesh_region::map_t::const_iterator const_iterator;
255  bool whole_mesh;
256  dal::bit_const_iterator itb, iteb;
257  const_iterator it, ite;
258  face_bitset c;
259  size_type cv_;
260  short_type f_;
261  bool finished_;
262 #if GETFEM_PARA_LEVEL > 1
263  std::unique_ptr<mesh_region> mpi_rg;
264 #endif
265  void init(const mesh_region &s);
266  void init(const dal::bit_vector &s);
267 
268  public:
269  visitor(const mesh_region &s);
270  visitor(const mesh_region &s, const mesh &m,
271  bool intersect_with_mpi = false);
272  size_type cv() const { return cv_; }
273  size_type is_face() const { return f_ != 0; }
274  short_type f() const { return short_type(f_-1); }
275 
276  bool next();
277  bool operator++() { return next(); }
278 
279  bool finished() const { return finished_; }
280 
281  bool next_face()
282  {
283  if (whole_mesh) return false;
284  if (c.none()) return false;
285  do { ++f_; } while (!c.test(f_));
286  c.set(f_,0);
287  return true;
288  }
289  };
290 
291  friend std::ostream & operator <<(std::ostream &os, const mesh_region &w);
292  };
293 
295 
296  /* Dummy mesh_region for default parameter of functions. */
297  const mesh_region &dummy_mesh_region();
298 
299 }
300 
301 
302 #endif
structure used to hold a set of convexes and/or convex faces.
static mesh_region all_convexes()
provide a default value for the mesh_region parameters of assembly procedures etc.
Provide a dynamic bit container.
specialization for bool, to circumvent the shortcommings of standards library specialization for std:...
Definition: getfem_omp.h:220
Definition of convex structures.
Describe a mesh (collection of convexes (elements) and points).
Definition: getfem_mesh.h:95
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
"iterator" class for regions.
GEneric Tool for Finite Element Methods.
gmm::uint16_type short_type
used as the common short type integer in the library
Definition: bgeot_config.h:79
size_type nb_convex() const
Number of convexes in the region, or on the partition on the current thread.
defines and typedefs for namespace getfem