GetFEM  5.5
getfem_mesh_slice.h
Go to the documentation of this file.
1 /* -*- c++ -*- (enables emacs c++ mode) */
2 /*===========================================================================
3 
4  Copyright (C) 2003-2026 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, see https://www.gnu.org/licenses/.
19 
20  As a special exception, you may use this file as it is a part of a free
21  software library without restriction. Specifically, if other files
22  instantiate templates or use macros or inline functions from this file,
23  or you compile this file and link it with other files to produce an
24  executable, this file does not by itself cause the resulting executable
25  to be covered by the GNU Lesser General Public License. This exception
26  does not however invalidate any other reasons why the executable file
27  might be covered by the GNU Lesser General Public License.
28 
29 ===========================================================================*/
30 
31 /**@file getfem_mesh_slice.h
32  @author Julien Pommier <Julien.Pommier@insa-toulouse.fr>
33  @date May 2003.
34  @brief Define the class getfem::stored_mesh_slice.
35  */
36 #ifndef GETFEM_MESH_SLICE_H
37 #define GETFEM_MESH_SLICE_H
38 
39 #include "getfem_mesh_slicers.h"
40 
41 namespace getfem {
42  class slicer_build_stored_mesh_slice;
43 
44  /** The output of a getfem::mesh_slicer which has been recorded.
45  @see getfem::slicer_build_stored_mesh_slice */
47  protected:
48  /* nodes lists and simplexes lists for each convex of the original mesh */
49  struct convex_slice {
50  size_type cv_num;
51  dim_type cv_dim;
52  dim_type fcnt, cv_nbfaces; // number of faces of the convex
53  // (fcnt also counts the faces created by
54  // the slicing of the convex)
55  bool discont; // when true, it is assumed that the interpolated data
56  // inside the convex may be discontinuous
57  // (for ex. levelset discont function)
58  mesh_slicer::cs_nodes_ct nodes;
59  mesh_slicer::cs_simplexes_ct simplexes;
60  size_type global_points_count;
61  };
62  typedef std::deque<convex_slice> cvlst_ct;
63 
64  struct merged_node_t {
65  const slice_node *P;
66  unsigned pos; /* [0..nb_points()-1] */
67  };
68  /* these three arrays allow the association of a global point
69  number to a merged point number, and of a merged point to a
70  list of global points */
71  mutable std::vector<merged_node_t> merged_nodes; /* size = points_cnt */
72  mutable std::vector<size_type> merged_nodes_idx; /* size = merged pts + 1*/
73  mutable std::vector<size_type> to_merged_index; /* size = points_cnt */
74  mutable bool merged_nodes_available;
75 
76  /* keep track of the original mesh (hence it should not be destroyed
77  * before the slice) */
78  const mesh *poriginal_mesh;
79  std::vector<size_type> simplex_cnt; // count simplexes of dim 0,1,...,dim
80  size_type points_cnt;
81  cvlst_ct cvlst;
82  size_type dim_;
83  std::vector<size_type> cv2pos; // convex id -> pos in cvlst
84  friend class slicer_build_stored_mesh_slice;
85  friend class mesh_slicer;
86  public:
87  stored_mesh_slice() : poriginal_mesh(0), points_cnt(0), dim_(size_type(-1))
88  { }
89  /** Shortcut constructor to simplexify a mesh with refinement. */
90  explicit stored_mesh_slice(const getfem::mesh& m, size_type nrefine = 1)
91  : poriginal_mesh(0), points_cnt(0), dim_(size_type(-1)) {
92  this->build(m, slicer_none(), nrefine);
93  };
94  virtual ~stored_mesh_slice() {}
95  /** return the number of convexes of the original mesh referenced
96  in the slice */
97  size_type nb_convex() const { return cvlst.size(); }
98  /** return the original convex number of the 'ic'th convex
99  referenced in the slice */
100  size_type convex_num(size_type ic) const { return cvlst[ic].cv_num; }
101  /** return the position ic of the referenced convex in the slice convexes
102  list cvlist, corresponding to the original convex number cv*/
103  size_type convex_pos(size_type cv) const { return cv2pos[cv]; }
104  /** change the slice dimension (append zeros or truncate node coordinates..) */
105  void set_dim(size_type newdim);
106  /** return the slice dimension */
107  size_type dim() const { return dim_; }
108  /** return a pointer to the original mesh */
109  const mesh& linked_mesh() const { return *poriginal_mesh; }
110  /** return the simplex count, in an array.
111  @param c contains the number of simplexes of dimension 0, 1, ... dim().
112  */
113  void nb_simplexes(std::vector<size_type>& c) const { c = simplex_cnt; }
114  /** Return the number of simplexes of dimension sdim */
115  size_type nb_simplexes(size_type sdim) const { return simplex_cnt[sdim]; }
116  /** Return the number of nodes in the slice */
117  size_type nb_points() const { return points_cnt; }
118  /** Return the list of nodes for the 'ic'th convex of the slice. */
119  const mesh_slicer::cs_nodes_ct& nodes(size_type ic) const { return cvlst[ic].nodes; }
120  mesh_slicer::cs_nodes_ct& nodes(size_type ic) { return cvlst[ic].nodes; }
121 
122  /** Return the list of simplexes for the 'ic'th convex of the slice. */
123  const mesh_slicer::cs_simplexes_ct& simplexes(size_type ic) const { return cvlst[ic].simplexes; }
124  size_type memsize() const;
125  void clear() {
126  poriginal_mesh = 0;
127  cvlst.clear();
128  points_cnt = 0;
129  dim_ = size_type(-1);
130  gmm::fill(cv2pos, size_type(-1));
131  simplex_cnt.clear();
132  clear_merged_nodes();
133  }
134  /** @brief merge with another mesh slice. */
135  void merge(const stored_mesh_slice& sl);
136 
137  /** @brief build a list of merged nodes.
138 
139  build a list of merged nodes, i.e. nodes which have the same
140  geometrical location but were extracted from two different
141  convexes will be considered as one same node. Use for
142  exportation purposes, as VTK and OpenDX do not like
143  'discontinuous' meshes
144  */
145  void merge_nodes() const;
146 
147  /** @brief Return the number of merged nodes in slice. */
149  { return merged_nodes_idx.size() - 1; }
150 
151  /** @brief Return the physical position of the merged node.
152  @param i_merged should be 0 <= i_merged < nb_merged_nodes()
153  */
154  const base_node merged_point(size_type i_merged) const
155  { return merged_nodes[merged_nodes_idx[i_merged]].P->pt; }
156 
157  size_type merged_index(size_type ic, size_type ipt) const
158  { return to_merged_index[global_index(ic,ipt)]; }
159  size_type global_index(size_type ic, size_type ipt) const
160  { return cvlst[ic].global_points_count+ipt; }
161 
162  /** @brief Return the number of nodes that were merged
163  to form the merged one.
164  @param i_merged index of the merged node:
165  0 <= i_merged < nb_merged_nodes()
166  */
168  { return merged_nodes_idx[i_merged+1] - merged_nodes_idx[i_merged]; }
169 
170  std::vector<merged_node_t>::const_iterator
171  merged_point_nodes(size_type i_merged) const {
172  return merged_nodes.begin() + merged_nodes_idx[i_merged];
173  }
174 
175  void clear_merged_nodes() const;
176 
177  /** @brief Extract the list of mesh edges.
178 
179  extract the list of mesh edges into 'edges' (size = 2* number
180  of edges). 'slice_edges' indicates which one were created
181  after slicing. The from_merged_nodes flag may be used if you
182  want to use (and merge common edges according to) the merged
183  points
184  */
185  void get_edges(std::vector<size_type> &edges,
186  dal::bit_vector &slice_edges,
187  bool from_merged_nodes) const;
188 
189  void set_convex(size_type cv, bgeot::pconvex_ref cvr,
190  mesh_slicer::cs_nodes_ct cv_nodes,
191  mesh_slicer::cs_simplexes_ct cv_simplexes,
192  dim_type fcnt, const dal::bit_vector& splx_in,
193  bool discont);
194 
195  /** Build the slice, by applying a slicer_action operation. */
196  void build(const getfem::mesh& m, const slicer_action &a,
197  size_type nrefine = 1) { build(m,&a,0,0,nrefine); }
198  /** Build the slice, by applying two slicer_action operations. */
199  void build(const getfem::mesh& m, const slicer_action &a,
200  const slicer_action &b,
201  size_type nrefine = 1) { build(m,&a,&b,0,nrefine); }
202  /** Build the slice, by applying three slicer_action operations. */
203  void build(const getfem::mesh& m, const slicer_action &a,
204  const slicer_action &b, const slicer_action &c,
205  size_type nrefine = 1) { build(m,&a,&b,&c,nrefine); }
206  void build(const getfem::mesh& m, const slicer_action *a,
207  const slicer_action *b, const slicer_action *c,
208  size_type nrefine);
209 
210  /** @brief Apply the listed slicer_action(s) to the slice object.
211  the stored_mesh_slice is not modified. This can be used to build a
212  new stored_mesh_slice from a stored_mesh_slice.
213  */
214  void replay(slicer_action &a) const { replay(&a,0,0); }
215  void replay(slicer_action &a, slicer_action &b) const
216  { replay(&a, &b, 0); }
217  void replay(slicer_action &a, slicer_action &b, slicer_action &c) const
218  { replay(&a, &b, &c); }
219  void replay(slicer_action *a, slicer_action *b, slicer_action *c) const;
220 
221  /** @brief Save a slice content to a text file.
222  */
223  void write_to_file(std::ostream &os) const;
224  void write_to_file(const std::string &fname, bool with_mesh=false) const;
225  /** @brief Read a slice from a file.
226  */
227  void read_from_file(std::istream &ist, const getfem::mesh &m);
228  void read_from_file(const std::string &fname, const getfem::mesh &m);
229 
230 
231  /** @brief Interpolation of a mesh_fem on a slice.
232 
233  The mesh_fem and the slice must share the same mesh, of course.
234 
235  @param mf the mesh_fem
236 
237  @param U a vector whose dimension is a multiple of
238  mf.nb_dof(), the field to be interpolated.
239 
240  @param V on output, a vector corresponding to the interpolated
241  field on the slice (values given on each node of the slice).
242  */
243  template<typename V1, typename V2> void
244  interpolate(const getfem::mesh_fem &mf, const V1& UU, V2& V) const {
245  typedef typename gmm::linalg_traits<V2>::value_type T;
246  std::vector<base_node> refpts;
247  std::vector<std::vector<T> > coeff;
248  base_matrix G;
249  size_type qdim = mf.get_qdim();
250  size_type qqdim = gmm::vect_size(UU) / mf.nb_dof();
251  size_type pos = 0;
252  coeff.resize(qqdim);
253  std::vector<T> U(mf.nb_basic_dof()*qqdim);
254  mf.extend_vector(UU, U);
255 
256  gmm::clear(V);
257  for (size_type i=0; i < nb_convex(); ++i) {
258  size_type cv = convex_num(i);
259  refpts.resize(nodes(i).size());
260  for (size_type j=0; j < refpts.size(); ++j)
261  refpts[j] = nodes(i)[j].pt_ref;
262  if (!mf.convex_index().is_in(cv)) {
263  pos += refpts.size() * qdim * qqdim;
264  continue;
265  }
266 
267  pfem pf = mf.fem_of_element(cv);
268  if (pf->need_G())
269  bgeot::vectors_to_base_matrix(G,
270  mf.linked_mesh().points_of_convex(cv));
271  fem_precomp_pool fppool;
272  pfem_precomp pfp = fppool(pf, store_point_tab(refpts));
273 
274  mesh_fem::ind_dof_ct dof = mf.ind_basic_dof_of_element(cv);
275  for (size_type qq=0; qq < qqdim; ++qq) {
276  coeff[qq].resize(mf.nb_basic_dof_of_element(cv));
277  typename std::vector<T>::iterator cit = coeff[qq].begin();
278  for (mesh_fem::ind_dof_ct::const_iterator it=dof.begin();
279  it != dof.end(); ++it, ++cit)
280  *cit = U[(*it)*qqdim+qq];
281  }
282  fem_interpolation_context ctx(mf.linked_mesh().trans_of_convex(cv),
283  pfp, 0, G, cv, short_type(-1));
284  for (size_type j=0; j < refpts.size(); ++j) {
285  ctx.set_ii(j);
286  for (size_type qq = 0; qq < qqdim; ++qq) {
287  typename gmm::sub_vector_type<V2*,
288  gmm::sub_interval>::vector_type dest =
289  gmm::sub_vector(V,gmm::sub_interval(pos,qdim));
290  pf->interpolation(ctx,coeff[qq],dest,dim_type(qdim));
291  pos += qdim;
292  }
293  }
294  }
295  GMM_ASSERT1(pos == V.size(), "bad dimensions");
296  }
297  };
298 
299  /** @brief a getfem::mesh_slicer whose side effect is to build a
300  stored_mesh_slice object.
301  */
303  stored_mesh_slice &sl;
304  public:
306  GMM_ASSERT1(sl.cvlst.size() == 0,
307  "the stored_mesh_slice already contains data");
308  }
309  void exec(mesh_slicer& ms);
310  };
311 
312  std::ostream& operator<<(std::ostream& o, const stored_mesh_slice& m);
313 }
314 
315 #endif /*GETFEM_MESH_SLICE_H*/
void set_ii(size_type ii__)
change the current point (assuming a geotrans_precomp_ is used)
base class for static stored objects
structure passed as the argument of fem interpolation functions.
Definition: getfem_fem.h:749
handle a pool (i.e.
Definition: getfem_fem.h:716
Describe a finite element method linked to a mesh.
virtual ind_dof_ct ind_basic_dof_of_element(size_type cv) const
Give an array of the dof numbers a of convex.
virtual dim_type get_qdim() const
Return the Q dimension.
virtual size_type nb_dof() const
Return the total number of degrees of freedom.
const mesh & linked_mesh() const
Return a reference to the underlying mesh.
virtual size_type nb_basic_dof() const
Return the total number of basic degrees of freedom (before the optional reduction).
virtual pfem fem_of_element(size_type cv) const
Return the basic fem associated with an element (if no fem is associated, the function will crash!...
const dal::bit_vector & convex_index() const
Get the set of convexes where a finite element has been assigned.
virtual size_type nb_basic_dof_of_element(size_type cv) const
Return the number of degrees of freedom attached to a given convex.
Apply a serie a slicing operations to a mesh.
Describe a mesh (collection of convexes (elements) and points).
Definition: getfem_mesh.h:98
void clear()
Erase the mesh.
Definition: getfem_mesh.cc:272
generic slicer class.
a getfem::mesh_slicer whose side effect is to build a stored_mesh_slice object.
This slicer does nothing.
The output of a getfem::mesh_slicer which has been recorded.
size_type convex_pos(size_type cv) const
return the position ic of the referenced convex in the slice convexes list cvlist,...
size_type merged_point_cnt(size_type i_merged) const
Return the number of nodes that were merged to form the merged one.
size_type dim() const
return the slice dimension
void nb_simplexes(std::vector< size_type > &c) const
return the simplex count, in an array.
void replay(slicer_action &a) const
Apply the listed slicer_action(s) to the slice object.
void build(const getfem::mesh &m, const slicer_action &a, const slicer_action &b, const slicer_action &c, size_type nrefine=1)
Build the slice, by applying three slicer_action operations.
const base_node merged_point(size_type i_merged) const
Return the physical position of the merged node.
void set_dim(size_type newdim)
change the slice dimension (append zeros or truncate node coordinates..)
const mesh_slicer::cs_nodes_ct & nodes(size_type ic) const
Return the list of nodes for the 'ic'th convex of the slice.
const mesh_slicer::cs_simplexes_ct & simplexes(size_type ic) const
Return the list of simplexes for the 'ic'th convex of the slice.
void build(const getfem::mesh &m, const slicer_action &a, const slicer_action &b, size_type nrefine=1)
Build the slice, by applying two slicer_action operations.
void merge(const stored_mesh_slice &sl)
merge with another mesh slice.
const mesh & linked_mesh() const
return a pointer to the original mesh
stored_mesh_slice(const getfem::mesh &m, size_type nrefine=1)
Shortcut constructor to simplexify a mesh with refinement.
void write_to_file(std::ostream &os) const
Save a slice content to a text file.
size_type nb_points() const
Return the number of nodes in the slice.
size_type nb_simplexes(size_type sdim) const
Return the number of simplexes of dimension sdim.
size_type nb_convex() const
return the number of convexes of the original mesh referenced in the slice
void read_from_file(std::istream &ist, const getfem::mesh &m)
Read a slice from a file.
void merge_nodes() const
build a list of merged nodes.
void get_edges(std::vector< size_type > &edges, dal::bit_vector &slice_edges, bool from_merged_nodes) const
Extract the list of mesh edges.
void interpolate(const getfem::mesh_fem &mf, const V1 &UU, V2 &V) const
Interpolation of a mesh_fem on a slice.
size_type nb_merged_nodes() const
Return the number of merged nodes in slice.
size_type convex_num(size_type ic) const
return the original convex number of the 'ic'th convex referenced in the slice
void build(const getfem::mesh &m, const slicer_action &a, size_type nrefine=1)
Build the slice, by applying a slicer_action operation.
Define various mesh slicers.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
Definition: getfem_fem.h:243
gmm::uint16_type short_type
used as the common short type integer in the library
Definition: bgeot_config.h:72
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:48
GEneric Tool for Finite Element Methods.