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) {}
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()));
283 void exec(mesh_slicer &ms);
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;
324 slicer_volume(
int orient_) :
orient(orient_) {}
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;
434 scalar_type b = 2*(gmm::vect_sp(F,D) - Fd*Dd);
435 scalar_type c = gmm::vect_norm2_sqr(F) - gmm::sqr(Fd) - gmm::sqr(R);
439 slicer_cylinder(base_node x0_, base_node x1_,scalar_type R_,
int orient_) :
441 d /= gmm::vect_norm2(d);
450 std::unique_ptr<const mesh_slice_cv_dof_data_base> mfU;
452 scalar_type val_scaling;
453 std::vector<scalar_type> Uval;
454 void prepare(
size_type cv,
const mesh_slicer::cs_nodes_ct& nodes,
455 const dal::bit_vector& nodes_index);
457 const mesh_slicer::cs_nodes_ct&)
const {
458 assert(iA < Uval.size() && iB < Uval.size());
459 if (((Uval[iA] < val) && (Uval[iB] > val)) ||
460 ((Uval[iA] > val) && (Uval[iB] < val)))
461 return (val-Uval[iA])/(Uval[iB]-Uval[iA]);
467 scalar_type val_,
int orient_) :
469 GMM_ASSERT1(mfU->pmf->get_qdim() == 1,
470 "can't compute isovalues of a vector field !");
471 val_scaling = mfU->maxval();
533 scalar_type area()
const {
return a; }
545 dal::bit_vector *pslice_edges;
549 : edges_m(edges_m_), pslice_edges(0) {}
557 : edges_m(edges_m_), pslice_edges(&bv) {}