GetFEM++  5.3
getfem_mesh_slicers.h
Go to the documentation of this file.
1 /* -*- c++ -*- (enables emacs c++ mode) */
2 /*===========================================================================
3 
4  Copyright (C) 2004-2017 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_slicers.h
33  @author Julien Pommier <Julien.Pommier@insa-toulouse.fr>
34  @date February 2004.
35  @brief Define various mesh slicers.
36 
37  Mesh slices are analogous to a refined P1-discontinuous mesh_fem, a
38  list of nodes/simplexes on which the interpolation is very fast.
39 
40  A slice is built from a mesh, by applying some slicing operations
41  (cut the mesh with a plane, intersect with a sphere, take the
42  boundary faces, etc..).
43 
44  They are used for post-treatment (exportation of results to VTK or OpenDX,
45  etc.)
46 */
47 
48 #ifndef GETFEM_MESH_SLICERS_H
49 #define GETFEM_MESH_SLICERS_H
50 
51 #include <bitset>
52 #include <memory>
53 #include "gmm/gmm_kernel.h"
54 #include "getfem_mesh_fem.h"
55 #include "bgeot_rtree.h"
56 
57 namespace getfem {
58  /** @internal @brief node data in a slice.
59 
60  Contains both real position, and position in the reference
61  convex
62  */
63  struct slice_node {
64  typedef std::bitset<32> faces_ct; /** broken for convexes with more
65  * than 32 faces. */
66  base_node pt, pt_ref;
67  faces_ct faces;
68  slice_node() {}
69  slice_node(const base_node& pt_, const base_node& pt_ref_)
70  : pt(pt_), pt_ref(pt_ref_) {}
71  void swap(slice_node &other) {
72  std::swap(faces,other.faces); pt.swap(other.pt);
73  pt_ref.swap(other.pt_ref);
74  }
75  };
76 
77 
78  /** @internal @brief simplex data in a slice.
79 
80  Just a list of slice_node ids.
81  */
82  struct slice_simplex {
83  std::vector<size_type> inodes;
84  size_type dim() const { return inodes.size()-1; }
85  slice_simplex(size_type n) : inodes(n) {}
86  slice_simplex() : inodes(4) {}
87  bool operator==(const slice_simplex& o) const
88  { return inodes == o.inodes; }
89  bool operator!=(const slice_simplex& o) const
90  { return inodes != o.inodes; }
91  };
92 
93  class slicer_action;
94  class stored_mesh_slice;
95  class mesh_level_set;
96 
97  /** @brief Apply a serie a slicing operations to a mesh.
98 
99  No output is produced by this object, the real output obtained
100  with the side-effect of certain getfem::mesh_slicer objects
101  (such as getfem::slicer_build_stored_mesh_slice).
102  */
103  class mesh_slicer {
104  std::deque<slicer_action*> action; /* pointed actions are not deleted */
105  public:
106  typedef std::vector<slice_node> cs_nodes_ct;
107  typedef std::vector<slice_simplex> cs_simplexes_ct;
108  const mesh& m;
109  const mesh_level_set *mls; // optional
110  size_type cv;
111  short_type face, cv_nbfaces;
112  dim_type cv_dim;
114  /* list of nodes and simplexes for the current convex
115  (including those who are outside of the slice) */
116  cs_nodes_ct nodes;
117  cs_simplexes_ct simplexes;
118  /* indexes of used simplexes and nodes,
119  and index of simplexes who are considered to be in
120  the slice */
121  dal::bit_vector simplex_index, nodes_index, splx_in;
122  size_type fcnt;
123  bgeot::pconvex_ref cvr, prev_cvr;
124  bool discont; // true when mls->is_convex_cut(cv) == true
125 
126  mesh tmp_mesh; // used only when mls != 0
127  bgeot::mesh_structure tmp_mesh_struct; // used only when mls != 0
128  // for faces structure.
129 
130  void pack(); /* not used, indeed */
131  void update_nodes_index();
132  /** mesh_slicer constructor. Use mesh_slicer::exec to build the slice.
133  @param m_ the mesh that is going to be sliced.
134  */
135  mesh_slicer(const mesh& m_);
136  mesh_slicer(const mesh_level_set &mls_);
137  void using_mesh_level_set(const mesh_level_set &mls_);
138  void push_back_action(slicer_action &a) { action.push_back(&a); }
139  void push_front_action(slicer_action &a) { action.push_front(&a); }
140 
141  size_type add_simplex(const slice_simplex& s, bool isin) {
142  size_type i = simplexes.size();
143  simplexes.push_back(s); splx_in[i] = isin; simplex_index.add(i);
144  return i;
145  }
146  void sup_simplex(size_type i) {
147  splx_in.sup(i); simplex_index.sup(i);
148  }
149  size_type dim() {
150  if (nodes.size()) return nodes[0].pt.size();
151  else GMM_ASSERT1(false, "internal_error");
152  }
153  void simplex_orientation(slice_simplex& s);
154  /**@brief build a new mesh_slice.
155  @param nrefine number of refinments for each convex of the original
156  mesh (size_type or a vector indexed by the convex number)
157  @param cvlst the list of convex numbers (or convex faces) of m that
158  will be taken into account for the slice
159  */
160  void exec(size_type nrefine, const mesh_region& cvlst);
161  void exec(const std::vector<short_type> &nrefine,const mesh_region& cvlst);
162  void exec(size_type nrefine = 1);
163  /**
164  @brief build a new mesh slice.
165  @param sms an initial stored_mesh_slice
166  */
167  void exec(const stored_mesh_slice& sms);
168  /**
169  @brief build a new mesh_slice than can be used to interpolate a field
170  on a fixed set of points.
171  @param pts the list of points
172  */
173  void exec(const std::vector<base_node>& pts);
174  private:
175  void exec_(const short_type *pnrefine,
176  int nref_stride,
177  const mesh_region& cvlst);
178  const mesh& refined_simplex_mesh_for_convex_cut_by_level_set
179  (const mesh &cvm, unsigned nrefine);
180  const bgeot::mesh_structure &
181  refined_simplex_mesh_for_convex_faces_cut_by_level_set(short_type f);
182 
183  void update_cv_data(size_type cv_, short_type f_ = short_type(-1));
184  void init_indexes();
185  void apply_slicers();
186  };
187 
188 
189  /* stupid class in order to use any vector type for field data associated
190  to mesh_fems in slices (used for slice deformation and isovalues) */
191  class mesh_slice_cv_dof_data_base {
192  public:
193  const mesh_fem *pmf;
194  virtual void copy(size_type cv, base_vector& coeff) const = 0;
195  virtual scalar_type maxval() const = 0;
196  virtual ~mesh_slice_cv_dof_data_base() {}
197  virtual std::unique_ptr<mesh_slice_cv_dof_data_base> clone() const = 0;
198  };
199 
200  /**
201  Use this structure to specify that the mesh must be deformed before
202  the slicing operation (with a mesh_fem and an associated field).
203  */
204  template<typename VEC> class mesh_slice_cv_dof_data
205  : public mesh_slice_cv_dof_data_base {
206  typedef typename gmm::linalg_traits<VEC>::value_type T;
207  std::vector<T> u;
208  public:
209  mesh_slice_cv_dof_data(const mesh_fem &mf_, const VEC &u_) {
210  pmf=&mf_;
211  gmm::resize(u, mf_.nb_basic_dof());
212  if (mf_.is_reduced())
213  gmm::mult(mf_.extension_matrix(), u_, u);
214  else
215  gmm::copy(u_, u);
216  }
217  virtual void copy(size_type cv, base_vector& coeff) const {
218  coeff.resize(pmf->nb_basic_dof_of_element(cv));
219  const mesh_fem::ind_dof_ct &dof = pmf->ind_basic_dof_of_element(cv);
220  base_vector::iterator out = coeff.begin();
221  for (mesh_fem::ind_dof_ct::iterator it=dof.begin(); it != dof.end();
222  ++it, ++out)
223  *out = u[*it];
224  }
225  scalar_type maxval() const { return gmm::vect_norminf(u); }
226  virtual std::unique_ptr<mesh_slice_cv_dof_data_base> clone() const
227  { return std::make_unique<mesh_slice_cv_dof_data<VEC>>(*this); }
228  };
229 
230 
231  /** @brief generic slicer class.
232 
233  Given a list of slice_simplex/slice_node, it build a news list of
234  slice_simplex/slice_node, indicating which ones are in the slice
235  with the bit_vector splx_in.
236  */
238  public:
239  static const float EPS;
240  virtual void exec(mesh_slicer &ms) = 0;
241  virtual ~slicer_action() {}
242  };
243 
244  /** This slicer does nothing. */
245  class slicer_none : public slicer_action {
246  public:
247  slicer_none() {}
248  void exec(mesh_slicer &/*ms*/) {}
249  static slicer_none& static_instance();
250  };
251 
252  /** Extraction of the boundary of a slice. */
254  slicer_action *A;
255  std::vector<slice_node::faces_ct> convex_faces;
256  bool test_bound(const slice_simplex& s, slice_node::faces_ct& fmask,
257  const mesh_slicer::cs_nodes_ct& nodes) const;
258  void build_from(const mesh& m, const mesh_region& cvflst);
259  public:
260  slicer_boundary(const mesh& m, slicer_action &sA,
261  const mesh_region& fbound);
262  slicer_boundary(const mesh& m,
263  slicer_action &sA = slicer_none::static_instance());
264  void exec(mesh_slicer &ms);
265  };
266 
267  /* Apply a precomputed deformation to the slice nodes */
268  class slicer_apply_deformation : public slicer_action {
269  mesh_slice_cv_dof_data_base *defdata;
270  pfem pf;
271  fem_precomp_pool fprecomp;
272  std::vector<base_node> ref_pts;
273  public:
274  slicer_apply_deformation(mesh_slice_cv_dof_data_base &defdata_)
275  : defdata(&defdata_), pf(0) {
276  if (defdata &&
277  defdata->pmf->get_qdim() != defdata->pmf->linked_mesh().dim())
278  GMM_ASSERT1(false, "wrong Q(=" << int(defdata->pmf->get_qdim())
279  << ") dimension for slice deformation: should be equal to "
280  "the mesh dimension which is "
281  << int(defdata->pmf->linked_mesh().dim()));
282  }
283  void exec(mesh_slicer &ms);
284  };
285 
286  /**
287  Base class for general slices of a mesh (planar, sphere,
288  cylinder,isosurface)
289  */
290  class slicer_volume : public slicer_action {
291  public:
292  enum {VOLIN=-1, VOLBOUND=0, VOLOUT=+1, VOLSPLIT=+2};
293  protected:
294  /**
295  orient defines the kind of slicing :
296  VOLIN -> keep the inside of the volume,
297  VOLBOUND -> its boundary,
298  VOLOUT -> its outside,
299  VOLSPLIT -> keep everything but make split simplexes
300  untils no simplex crosses the boundary
301  */
302  int orient;
303  dal::bit_vector pt_in, pt_bin;
304 
305  /** Overload either 'prepare' or 'test_point'.
306  */
307  virtual void prepare(size_type /*cv*/,
308  const mesh_slicer::cs_nodes_ct& nodes,
309  const dal::bit_vector& nodes_index) {
310  pt_in.clear(); pt_bin.clear();
311  for (dal::bv_visitor i(nodes_index); !i.finished(); ++i) {
312  bool in, bin; test_point(nodes[i].pt, in, bin);
313  if (bin || ((orient > 0) ? !in : in)) pt_in.add(i);
314  if (bin) pt_bin.add(i);
315  }
316  }
317  virtual void test_point(const base_node&, bool& in, bool& bound) const
318  { in=true; bound=true; }
319  /** edge_intersect should always be overloaded */
320  virtual scalar_type
321  edge_intersect(size_type /*i*/, size_type /*j*/,
322  const mesh_slicer::cs_nodes_ct& /*nodes*/) const = 0;
323 
324  slicer_volume(int orient_) : orient(orient_) {}
325 
326  /** Utility function */
327  static scalar_type trinom(scalar_type a, scalar_type b, scalar_type c) {
328  scalar_type delta = b*b - 4*a*c;
329  if (delta < 0.) return 1./EPS;
330  delta = sqrt(delta);
331  scalar_type s1 = (-b - delta) / (2*a);
332  scalar_type s2 = (-b + delta) / (2*a);
333  if (gmm::abs(s1-.5) < gmm::abs(s2-.5)) return s1; else return s2;
334  }
335  void split_simplex(mesh_slicer &ms,
336  slice_simplex s, /* s is NOT a reference, it is on
337  * purpose(push_back in the function)*/
338  size_type sstart, std::bitset<32> spin,
339  std::bitset<32> spbin);
340  public:
341  void exec(mesh_slicer &ms);
342  };
343 
344  /**
345  Slice a mesh with a half-space (or its boundary).
346  */
348  const base_node x0, n; /* normal directed from inside toward outside */
349  void test_point(const base_node& P, bool& in, bool& bound) const {
350  scalar_type s = gmm::vect_sp(P-x0,n);
351  in = (s <= 0); bound = (s*s <= EPS); // gmm::vect_norm2_sqr(P-x0)); No!
352  // do not try to be smart with the boundary check .. easily broken with
353  // slicer_mesh_with_mesh
354  }
355  scalar_type edge_intersect(size_type iA, size_type iB,
356  const mesh_slicer::cs_nodes_ct& nodes) const {
357  const base_node& A=nodes[iA].pt;
358  const base_node& B=nodes[iB].pt;
359  scalar_type s1 = 0., s2 = 0.;
360  for (unsigned i=0; i < A.size(); ++i)
361  { s1 += (A[i] - B[i])*n[i]; s2 += (A[i]-x0[i])*n[i]; }
362  if (gmm::abs(s1) < EPS) return 1./EPS;
363  else return s2/s1;
364  }
365  public:
366  slicer_half_space(base_node x0_, base_node n_, int orient_) :
367  slicer_volume(orient_), x0(x0_), n(n_/gmm::vect_norm2(n_)) {
368  //n *= (1./bgeot::vect_norm2(n));
369  }
370  };
371 
372  /**
373  Slices a mesh with a sphere (or its boundary).
374  */
375  class slicer_sphere : public slicer_volume {
376  base_node x0;
377  scalar_type R;
378  void test_point(const base_node& P, bool& in, bool& bound) const {
379  scalar_type R2 = gmm::vect_dist2_sqr(P,x0);
380  bound = (R2 >= (1-EPS)*R*R && R2 <= (1+EPS)*R*R);
381  in = R2 <= R*R;
382  }
383  scalar_type edge_intersect(size_type iA, size_type iB,
384  const mesh_slicer::cs_nodes_ct& nodes) const {
385  const base_node& A=nodes[iA].pt;
386  const base_node& B=nodes[iB].pt;
387  scalar_type a,b,c; // a*x^2 + b*x + c = 0
388  a = gmm::vect_norm2_sqr(B-A);
389  if (a < EPS) return pt_bin.is_in(iA) ? 0. : 1./EPS;
390  b = 2*gmm::vect_sp(A-x0,B-A);
391  c = gmm::vect_norm2_sqr(A-x0)-R*R;
392  return slicer_volume::trinom(a,b,c);
393  }
394  public:
395  /* orient = -1 => select interior,
396  orient = 0 => select boundary
397  orient = +1 => select exterior */
398  slicer_sphere(base_node x0_, scalar_type R_, int orient_) :
399  slicer_volume(orient_), x0(x0_), R(R_) {}
400  //cerr << "slicer_volume, x0=" << x0 << ", R=" << R << endl; }
401  };
402 
403  /**
404  Slices a mesh with a cylinder (or its boundary).
405  */
407  base_node x0, d;
408  scalar_type R;
409  void test_point(const base_node& P, bool& in, bool& bound) const {
410  base_node N = P;
411  if (2 == N.size()) { /* Add Z coorinate if mesh is 2D */
412  N.push_back(0.0);
413  }
414  N = N-x0;
415  scalar_type axpos = gmm::vect_sp(d, N);
416  scalar_type dist2 = gmm::vect_norm2_sqr(N) - gmm::sqr(axpos);
417  bound = gmm::abs(dist2-R*R) < EPS;
418  in = dist2 < R*R;
419  }
420  scalar_type edge_intersect(size_type iA, size_type iB,
421  const mesh_slicer::cs_nodes_ct& nodes) const {
422  base_node F=nodes[iA].pt;
423  base_node D=nodes[iB].pt-nodes[iA].pt;
424  if (2 == F.size()) {
425  F.push_back(0.0);
426  D.push_back(0.0);
427  }
428  F = F - x0;
429  scalar_type Fd = gmm::vect_sp(F,d);
430  scalar_type Dd = gmm::vect_sp(D,d);
431  scalar_type a = gmm::vect_norm2_sqr(D) - gmm::sqr(Dd);
432  if (a < EPS) return pt_bin.is_in(iA) ? 0. : 1./EPS; assert(a> -EPS);
433  scalar_type b = 2*(gmm::vect_sp(F,D) - Fd*Dd);
434  scalar_type c = gmm::vect_norm2_sqr(F) - gmm::sqr(Fd) - gmm::sqr(R);
435  return slicer_volume::trinom(a,b,c);
436  }
437  public:
438  slicer_cylinder(base_node x0_, base_node x1_,scalar_type R_,int orient_) :
439  slicer_volume(orient_), x0(x0_), d(x1_-x0_), R(R_) {
440  d /= gmm::vect_norm2(d);
441  }
442  };
443 
444 
445  /**
446  Extract an isosurface.
447  */
449  std::unique_ptr<const mesh_slice_cv_dof_data_base> mfU;
450  scalar_type val;
451  scalar_type val_scaling; /* = max(abs(U)) */
452  std::vector<scalar_type> Uval;
453  void prepare(size_type cv, const mesh_slicer::cs_nodes_ct& nodes,
454  const dal::bit_vector& nodes_index);
455  scalar_type edge_intersect(size_type iA, size_type iB,
456  const mesh_slicer::cs_nodes_ct&) const {
457  assert(iA < Uval.size() && iB < Uval.size());
458  if (((Uval[iA] < val) && (Uval[iB] > val)) ||
459  ((Uval[iA] > val) && (Uval[iB] < val)))
460  return (val-Uval[iA])/(Uval[iB]-Uval[iA]);
461  else return 1./EPS;
462  }
463  public:
464  /* orient = -1: u(x) <= val, 0: u(x) == val, +1: u(x) >= val */
465  slicer_isovalues(const mesh_slice_cv_dof_data_base& mfU_,
466  scalar_type val_, int orient_) :
467  slicer_volume(orient_), mfU(mfU_.clone()), val(val_) {
468  GMM_ASSERT1(mfU->pmf->get_qdim() == 1,
469  "can't compute isovalues of a vector field !");
470  val_scaling = mfU->maxval();
471  }
472  };
473 
474  /**
475  Slices a mesh with another mesh. (of same dimension,
476  and whose convex are preferably linear). Note that slicing
477  a refined mesh with a rough mesh should be faster than slicing
478  a rough mesh with a refined mesh.
479  */
481  const mesh& slm;
482  bgeot::rtree tree; /* tree of bounding boxes for slm */
483  protected:
484  virtual void intersection_callback(mesh_slicer &/*ms*/,
485  size_type /*slmcv*/) {}
486  public:
487  slicer_mesh_with_mesh(const mesh&);
488  void exec(mesh_slicer &ms);
489  };
490 
491  /**
492  union of two slices
493  */
494  class slicer_union : public slicer_action {
495  slicer_action *A, *B;
496  public:
497  slicer_union(const slicer_action &sA, const slicer_action &sB) :
498  A(&const_cast<slicer_action&>(sA)), B(&const_cast<slicer_action&>(sB)) {}
499  void exec(mesh_slicer &ms);
500  };
501 
502  /**
503  Build the intersection of two slices
504  */
506  slicer_action *A, *B;
507  public:
508  slicer_intersect(slicer_action &sA, slicer_action &sB) : A(&sA), B(&sB) {}
509  void exec(mesh_slicer &ms);
510  };
511 
512  /**
513  Build the complementary of a slice
514  */
516  slicer_action *A;
517  public:
518  slicer_complementary(slicer_action &sA) : A(&sA) {}
519  void exec(mesh_slicer &ms);
520  };
521 
522  /**
523  Slicer whose side-effect is to compute the area of the
524  slice. Note that if the slice is composed of simplexes of many
525  dimensions, the resulting area is nonsense.
526  */
528  scalar_type a;
529  public:
530  slicer_compute_area() : a(0) {}
531  void exec(mesh_slicer &ms);
532  scalar_type area() const { return a; }
533  };
534 
535  /**
536  Slicer whose side-effect is to build the list of edges
537  (i.e. segments) and store them in a mesh object.
538 
539  Hence all common nodes/edges are eliminated. (this slicer
540  is not useful for anything but visualization of sliced meshes)
541  */
543  mesh& edges_m;
544  dal::bit_vector *pslice_edges;
545  public:
546  /** @param edges_m_ the mesh that will be filled with edges. */
548  : edges_m(edges_m_), pslice_edges(0) {}
549  /** @param edges_m_ the mesh that will be filled with edges.
550  @param bv will contain on output the list of edges numbers
551  (as convex numbers in edges_m_) which where not part of the
552  original mesh, but became apparent when some convex faces were
553  sliced.
554  */
555  slicer_build_edges_mesh(mesh& edges_m_, dal::bit_vector& bv)
556  : edges_m(edges_m_), pslice_edges(&bv) {}
557  void exec(mesh_slicer &ms);
558  };
559 
560  /**
561  Slicer whose side-effect is to build a mesh from the slice
562  simplexes. Hence using slices is a good way to simplexify a
563  mesh, however keep in mind that high order geometric
564  transformation will be simplexified with linear simplexes!
565  */
567  mesh& m;
568  public:
569  slicer_build_mesh(mesh& m_) : m(m_) {}
570  void exec(mesh_slicer &ms);
571  };
572 
573  /**
574  Contract or expand each convex with respect to its gravity center
575  */
576  class slicer_explode : public slicer_action {
577  scalar_type coef;
578  public:
579  /**
580  @param c < 1 => contraction, > 1 -> expansion.
581  */
582  slicer_explode(scalar_type c) : coef(c) {}
583  void exec(mesh_slicer &ms);
584  };
585 
586 }
587 
588 #endif /*GETFEM_MESH_SLICERS_H*/
structure used to hold a set of convexes and/or convex faces.
Slicer whose side-effect is to build a mesh from the slice simplexes.
Slice a mesh with a half-space (or its boundary).
Define the getfem::mesh_fem class.
Extraction of the boundary of a slice.
Describe a mesh (collection of convexes (elements) and points).
Definition: getfem_mesh.h:95
Slices a mesh with another mesh.
Slices a mesh with a sphere (or its boundary).
Contract or expand each convex with respect to its gravity center.
Slicer whose side-effect is to compute the area of the slice.
Base class for general slices of a mesh (planar, sphere, cylinder,isosurface)
const EXTENSION_MATRIX & extension_matrix() const
Return the extension matrix corresponding to reduction applied (RE=I).
static scalar_type trinom(scalar_type a, scalar_type b, scalar_type c)
Utility function.
Apply a serie a slicing operations to a mesh.
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
virtual void prepare(size_type, const mesh_slicer::cs_nodes_ct &nodes, const dal::bit_vector &nodes_index)
Overload either &#39;prepare&#39; or &#39;test_point&#39;.
virtual size_type nb_basic_dof() const
Return the total number of basic degrees of freedom (before the optional reduction).
Use this structure to specify that the mesh must be deformed before the slicing operation (with a mes...
handle a pool (i.e.
Definition: getfem_fem.h:711
Include the base gmm files.
The output of a getfem::mesh_slicer which has been recorded.
bool is_reduced() const
Return true if a reduction matrix is applied to the dofs.
GEneric Tool for Finite Element Methods.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
Definition: getfem_fem.h:239
Describe a finite element method linked to a mesh.
Extract an isosurface.
gmm::uint16_type short_type
used as the common short type integer in the library
Definition: bgeot_config.h:79
Build the intersection of two slices.
This slicer does nothing.
Build the complementary of a slice.
Mesh structure definition.
Slices a mesh with a cylinder (or its boundary).
union of two slices
slicer_build_edges_mesh(mesh &edges_m_, dal::bit_vector &bv)
generic slicer class.
Balanced tree of n-dimensional rectangles.
Definition: bgeot_rtree.h:66
region-tree for window/point search on a set of rectangles.
Slicer whose side-effect is to build the list of edges (i.e.
int orient
orient defines the kind of slicing : VOLIN -> keep the inside of the volume, VOLBOUND -> its boundary...
Keep informations about a mesh crossed by level-sets.
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation