48 #ifndef GETFEM_MESH_SLICERS_H 49 #define GETFEM_MESH_SLICERS_H 64 typedef std::bitset<32> faces_ct;
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);
82 struct slice_simplex {
83 std::vector<size_type> inodes;
84 size_type dim()
const {
return inodes.size()-1; }
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; }
94 class stored_mesh_slice;
104 std::deque<slicer_action*> action;
106 typedef std::vector<slice_node> cs_nodes_ct;
107 typedef std::vector<slice_simplex> cs_simplexes_ct;
117 cs_simplexes_ct simplexes;
121 dal::bit_vector simplex_index, nodes_index, splx_in;
123 bgeot::pconvex_ref cvr, prev_cvr;
131 void update_nodes_index();
138 void push_back_action(
slicer_action &a) { action.push_back(&a); }
139 void push_front_action(
slicer_action &a) { action.push_front(&a); }
141 size_type add_simplex(
const slice_simplex& s,
bool isin) {
143 simplexes.push_back(s); splx_in[i] = isin; simplex_index.add(i);
147 splx_in.sup(i); simplex_index.sup(i);
150 if (nodes.size())
return nodes[0].pt.size();
151 else GMM_ASSERT1(
false,
"internal_error");
153 void simplex_orientation(slice_simplex& s);
161 void exec(
const std::vector<short_type> &nrefine,
const mesh_region& cvlst);
173 void exec(
const std::vector<base_node>& pts);
178 const mesh& refined_simplex_mesh_for_convex_cut_by_level_set
179 (
const mesh &cvm,
unsigned nrefine);
181 refined_simplex_mesh_for_convex_faces_cut_by_level_set(
short_type f);
185 void apply_slicers();
191 class mesh_slice_cv_dof_data_base {
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;
205 :
public mesh_slice_cv_dof_data_base {
206 typedef typename gmm::linalg_traits<VEC>::value_type T;
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();
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); }
239 static const float EPS;
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;
269 mesh_slice_cv_dof_data_base *defdata;
272 std::vector<base_node> ref_pts;
274 slicer_apply_deformation(mesh_slice_cv_dof_data_base &defdata_)
275 : defdata(&defdata_), pf(0) {
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()));
292 enum {VOLIN=-1, VOLBOUND=0, VOLOUT=+1, VOLSPLIT=+2};
303 dal::bit_vector pt_in, pt_bin;
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);
317 virtual void test_point(
const base_node&,
bool& in,
bool& bound)
const 318 { in=
true; bound=
true; }
322 const mesh_slicer::cs_nodes_ct& )
const = 0;
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;
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;
339 std::bitset<32> spbin);
348 const base_node x0, n;
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);
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;
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);
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;
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;
409 void test_point(
const base_node& P,
bool& in,
bool& bound)
const {
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;
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;
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);
438 slicer_cylinder(base_node x0_, base_node x1_,scalar_type R_,
int orient_) :
440 d /= gmm::vect_norm2(d);
449 std::unique_ptr<const mesh_slice_cv_dof_data_base> mfU;
451 scalar_type val_scaling;
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);
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]);
466 scalar_type val_,
int orient_) :
468 GMM_ASSERT1(mfU->pmf->get_qdim() == 1,
469 "can't compute isovalues of a vector field !");
470 val_scaling = mfU->maxval();
498 A(&const_cast<slicer_action&>(sA)), B(&const_cast<slicer_action&>(sB)) {}
532 scalar_type area()
const {
return a; }
544 dal::bit_vector *pslice_edges;
548 : edges_m(edges_m_), pslice_edges(0) {}
556 : edges_m(edges_m_), pslice_edges(&bv) {}
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).
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
virtual void prepare(size_type, const mesh_slicer::cs_nodes_ct &nodes, const dal::bit_vector &nodes_index)
Overload either 'prepare' or 'test_point'.
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...
Include the base gmm files.
slicer_build_edges_mesh(mesh &edges_m_)
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
Describe a finite element method linked to a mesh.
gmm::uint16_type short_type
used as the common short type integer in the library
Build the intersection of two slices.
This slicer does nothing.
Build the complementary of a slice.
slicer_explode(scalar_type c)
Mesh structure definition.
Slices a mesh with a cylinder (or its boundary).
slicer_build_edges_mesh(mesh &edges_m_, dal::bit_vector &bv)
Balanced tree of n-dimensional rectangles.
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