33 # ifndef GETFEM_HAVE_LIBQHULL_QHULL_A_H
34 void qhull_delaunay(
const std::vector<base_node> &,
35 gmm::dense_matrix<size_type>&) {
36 GMM_ASSERT1(
false,
"Qhull header files not installed. "
37 "Install qhull library and reinstall GetFEM library.");
43 # include <libqhull/qhull_a.h>
56 void qhull_delaunay(
const std::vector<base_node> &pts,
57 gmm::dense_matrix<size_type>& simplexes) {
60 if (pts.size() <= dim) { gmm::resize(simplexes, dim+1, 0);
return; }
61 if (pts.size() == dim+1) {
62 gmm::resize(simplexes, dim+1, 1);
63 for (
size_type i=0; i <= dim; ++i) simplexes(i, 0) = i;
66 std::vector<coordT> Pts(dim * pts.size());
68 gmm::copy(pts[i], gmm::sub_vector(Pts, gmm::sub_interval(i*dim, dim)));
74 char flags[]=
"qhull QJ d Qbb Pp T0";
77 FILE *errfile= stderr;
81 vertexT *vertex, **vertexp;
82 exitcode = qh_new_qhull (
int(dim),
int(pts.size()), &Pts[0], ismalloc,
83 flags, outfile, errfile);
86 FORALLfacets {
if (!facet->upperdelaunay) nbf++; }
87 gmm::resize(simplexes, dim+1, nbf);
91 if (!facet->upperdelaunay) {
93 FOREACHvertex_(facet->vertices) {
94 assert(s < (
unsigned)(dim+1));
95 simplexes(s++,nbf) = qh_pointid(vertex->point);
101 qh_freeqhull(!qh_ALL);
102 qh_memfreeshort (&curlong, &totlong);
103 if (curlong || totlong)
104 cerr <<
"qhull internal warning (main): did not free " << totlong <<
105 " bytes of long memory (" << curlong <<
" pieces)\n";
120 dim_type n = basic_cvs->dim();
121 std::vector<size_type> ipts(n+1);
122 if (basic_cvs->nb_points() == n + 1) {
123 for (
size_type i = 0; i <= n; ++i) ipts[i] = i;
124 m.add_simplex(n, ipts.begin());
128 size_type nb = simplexified_tab(basic_cvs, &tab);
131 for (
size_type i = 0; i <= n; ++i) ipts[i] = *tab++;
132 m.add_simplex(n, ipts.begin());
135 # ifdef GETFEM_HAVE_LIBQHULL_QHULL_A_H
136 gmm::dense_matrix<size_type> t;
137 qhull_delaunay(cvr->
points(), t);
138 for (
size_type nc = 0; nc < gmm::mat_ncols(t); ++nc) {
139 for (
size_type i = 0; i <= n; ++i) ipts[i] = t(i,nc);
140 m.add_simplex(n, ipts.begin());
151 struct stored_point_tab_key :
virtual public dal::static_stored_object_key {
153 bool compare(
const static_stored_object_key &oo)
const override {
154 const stored_point_tab_key &o
155 =
dynamic_cast<const stored_point_tab_key &
>(oo);
158 if (&x == &y)
return false;
159 std::vector<base_node>::const_iterator it1 = x.begin(), it2 = y.begin();
160 base_node::const_iterator itn1, itn2, itne;
161 for ( ; it1 != x.end() && it2 != y.end() ; ++it1, ++it2) {
162 if ((*it1).size() < (*it2).size())
return true;
163 if ((*it1).size() > (*it2).size())
return false;
164 itn1 = (*it1).begin(); itne = (*it1).end(); itn2 = (*it2).begin();
165 for ( ; itn1 != itne ; ++itn1, ++itn2)
166 if (*itn1 < *itn2)
return true;
167 else if (*itn1 > *itn2)
return false;
169 if (it2 != y.end())
return true;
172 bool equal(
const static_stored_object_key &oo)
const override {
173 auto &o =
dynamic_cast<const stored_point_tab_key &
>(oo);
176 if (&x == &y)
return true;
177 if (x.size() != y.size())
return false;
178 auto it1 = x.begin();
179 auto it2 = y.begin();
180 base_node::const_iterator itn1, itn2, itne;
181 for ( ; it1 != x.end() && it2 != y.end() ; ++it1, ++it2) {
182 if ((*it1).size() != (*it2).size())
return false;
183 itn1 = (*it1).begin(); itne = (*it1).end(); itn2 = (*it2).begin();
184 for ( ; itn1 != itne ; ++itn1, ++itn2)
185 if (*itn1 != *itn2)
return false;
194 dal::pstatic_stored_object_key
195 pk = std::make_shared<stored_point_tab_key>(&spt);
197 if (o)
return std::dynamic_pointer_cast<const stored_point_tab>(o);
198 pstored_point_tab p = std::make_shared<stored_point_tab>(spt);
199 DAL_STORED_OBJECT_DEBUG_CREATED(p.get(),
"Stored point tab");
200 dal::pstatic_stored_object_key
201 psp = std::make_shared<stored_point_tab_key>(p.get());
206 convex_of_reference::convex_of_reference
209 auto_basic(auto_basic_) {
210 DAL_STORED_OBJECT_DEBUG_CREATED(
this,
"convex of refrence");
211 psimplexified_convex = std::make_shared<mesh_structure>();
218 GMM_ASSERT1(auto_basic,
219 "always use simplexified_convex on the basic_convex_ref() "
220 "[this=" << nb_points() <<
", basic="
221 << basic_convex_ref_->nb_points());
222 return psimplexified_convex.get();
226 class convex_of_reference_key :
virtual public dal::static_stored_object_key{
232 bool compare(
const static_stored_object_key &oo)
const override{
233 const convex_of_reference_key &o
234 =
dynamic_cast<const convex_of_reference_key &
>(oo);
235 if (type < o.type)
return true;
236 if (type > o.type)
return false;
237 if (N < o.N)
return true;
238 if (N > o.N)
return false;
239 if (K < o.K)
return true;
240 if (K > o.K)
return false;
241 if (nf < o.nf)
return true;
244 bool equal(
const static_stored_object_key &oo)
const override{
245 auto &o =
dynamic_cast<const convex_of_reference_key &
>(oo);
246 if (type != o.type)
return false;
247 if (N != o.N)
return false;
248 if (K != o.K)
return false;
249 if (nf != o.nf)
return false;
252 convex_of_reference_key(
int t, dim_type NN,
short_type KK = 0,
254 : type(t), N(NN), K(KK), nf(nnf) {}
260 class K_simplex_of_ref_ :
public convex_of_reference {
262 scalar_type is_in(
const base_node &pt)
const {
264 GMM_ASSERT1(pt.size() == cvs->dim(),
265 "K_simplex_of_ref_::is_in: Dimensions mismatch");
266 scalar_type e = -1.0, r = (pt.size() > 0) ? -pt[0] : 0.0;
267 base_node::const_iterator it = pt.begin(), ite = pt.end();
268 for (; it != ite; e += *it, ++it) r = std::max(r, -(*it));
269 return std::max(r, e);
272 scalar_type is_in_face(
short_type f,
const base_node &pt)
const {
275 GMM_ASSERT1(pt.size() == cvs->dim(),
276 "K_simplex_of_ref_::is_in_face: Dimensions mismatch");
277 if (f > 0)
return -pt[f-1];
278 scalar_type e = -1.0;
279 base_node::const_iterator it = pt.begin(), ite = pt.end();
280 for (; it != ite; e += *it, ++it) {};
281 return e / sqrt(scalar_type(pt.size()));
284 void project_into(base_node &pt)
const {
286 GMM_ASSERT1(pt.size() == cvs->dim(),
287 "K_simplex_of_ref_::project_into: Dimensions mismatch");
288 scalar_type sum_coordinates = 0.0;
289 for (
const auto &coord : pt) sum_coordinates += coord;
290 if (sum_coordinates > 1.0) gmm::scale(pt, 1.0 / sum_coordinates);
291 for (
auto &coord : pt) {
292 if (coord < 0.0) coord = 0.0;
293 if (coord > 1.0) coord = 1.0;
296 basic_convex_ref_->project_into(pt);
299 K_simplex_of_ref_(dim_type NN,
short_type KK) :
304 convex<base_node>::points().resize(R);
305 normals_.resize(NN+1);
306 base_node
null(NN);
null.fill(0.0);
307 std::fill(normals_.begin(), normals_.end(),
null);
308 std::fill(convex<base_node>::points().begin(),
309 convex<base_node>::points().end(),
null);
311 normals_[i][i-1] = -1.0;
313 std::fill(normals_[0].begin(), normals_[0].end(),
314 scalar_type(1.0)/sqrt(scalar_type(NN)));
315 base_node c(NN); c.fill(0.0);
319 convex<base_node>::points()[0] = c;
324 convex<base_node>::points()[r] = c;
325 if (KK != 0 && NN > 0) {
326 l = 0; c[l] += 1.0 / scalar_type(KK); sum++;
328 sum -= int(floor(0.5+(c[l] * KK)));
329 c[l] = 0.0; l++;
if (l == NN)
break;
330 c[l] += 1.0 / scalar_type(KK); sum++;
335 ppoints = store_point_tab(convex<base_node>::points());
336 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
341 dal::pstatic_stored_object_key
342 pk = std::make_shared<convex_of_reference_key>(0, nc, K);
344 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
345 pconvex_ref p = std::make_shared<K_simplex_of_ref_>(nc, K);
347 dal::PERMANENT_STATIC_OBJECT);
349 if (p != p1) add_dependency(p, p1);
358 class Q2_incomplete_of_ref_ :
public convex_of_reference {
360 scalar_type is_in(
const base_node& pt)
const
361 {
return basic_convex_ref_->is_in(pt); }
362 scalar_type is_in_face(
short_type f,
const base_node& pt)
const
363 {
return basic_convex_ref_->is_in_face(f, pt); }
365 Q2_incomplete_of_ref_(dim_type nc) :
368 GMM_ASSERT1(nc == 2 || nc == 3,
"Sorry exist only in dimension 2 or 3");
369 convex<base_node>::points().resize(cvs->nb_points());
370 normals_.resize(nc == 2 ? 4: 6);
374 normals_[0] = { 1, 0};
375 normals_[1] = {-1, 0};
376 normals_[2] = { 0, 1};
377 normals_[3] = { 0,-1};
379 convex<base_node>::points()[0] = base_node(0.0, 0.0);
380 convex<base_node>::points()[1] = base_node(0.5, 0.0);
381 convex<base_node>::points()[2] = base_node(1.0, 0.0);
382 convex<base_node>::points()[3] = base_node(0.0, 0.5);
383 convex<base_node>::points()[4] = base_node(1.0, 0.5);
384 convex<base_node>::points()[5] = base_node(0.0, 1.0);
385 convex<base_node>::points()[6] = base_node(0.5, 1.0);
386 convex<base_node>::points()[7] = base_node(1.0, 1.0);
389 normals_[0] = { 1, 0, 0};
390 normals_[1] = {-1, 0, 0};
391 normals_[2] = { 0, 1, 0};
392 normals_[3] = { 0,-1, 0};
393 normals_[4] = { 0, 0, 1};
394 normals_[5] = { 0, 0,-1};
396 convex<base_node>::points()[0] = base_node(0.0, 0.0, 0.0);
397 convex<base_node>::points()[1] = base_node(0.5, 0.0, 0.0);
398 convex<base_node>::points()[2] = base_node(1.0, 0.0, 0.0);
399 convex<base_node>::points()[3] = base_node(0.0, 0.5, 0.0);
400 convex<base_node>::points()[4] = base_node(1.0, 0.5, 0.0);
401 convex<base_node>::points()[5] = base_node(0.0, 1.0, 0.0);
402 convex<base_node>::points()[6] = base_node(0.5, 1.0, 0.0);
403 convex<base_node>::points()[7] = base_node(1.0, 1.0, 0.0);
405 convex<base_node>::points()[8] = base_node(0.0, 0.0, 0.5);
406 convex<base_node>::points()[9] = base_node(1.0, 0.0, 0.5);
407 convex<base_node>::points()[10] = base_node(0.0, 1.0, 0.5);
408 convex<base_node>::points()[11] = base_node(1.0, 1.0, 0.5);
410 convex<base_node>::points()[12] = base_node(0.0, 0.0, 1.0);
411 convex<base_node>::points()[13] = base_node(0.5, 0.0, 1.0);
412 convex<base_node>::points()[14] = base_node(1.0, 0.0, 1.0);
413 convex<base_node>::points()[15] = base_node(0.0, 0.5, 1.0);
414 convex<base_node>::points()[16] = base_node(1.0, 0.5, 1.0);
415 convex<base_node>::points()[17] = base_node(0.0, 1.0, 1.0);
416 convex<base_node>::points()[18] = base_node(0.5, 1.0, 1.0);
417 convex<base_node>::points()[19] = base_node(1.0, 1.0, 1.0);
419 ppoints = store_point_tab(convex<base_node>::points());
424 DAL_SIMPLE_KEY(Q2_incomplete_of_reference_key_, dim_type);
427 dal::pstatic_stored_object_key
428 pk = std::make_shared<Q2_incomplete_of_reference_key_>(nc);
430 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
431 pconvex_ref p = std::make_shared<Q2_incomplete_of_ref_>(nc);
433 dal::PERMANENT_STATIC_OBJECT);
435 if (p != p1) add_dependency(p, p1);
443 class pyramid_QK_of_ref_ :
public convex_of_reference {
445 scalar_type is_in_face(
short_type f,
const base_node& pt)
const {
448 GMM_ASSERT1(pt.size() == 3,
"Dimensions mismatch");
452 return gmm::vect_sp(normals_[f], pt) - sqrt(2.)/2.;
455 scalar_type is_in(
const base_node& pt)
const {
457 scalar_type r = is_in_face(0, pt);
458 for (
short_type f = 1; f < 5; ++f) r = std::max(r, is_in_face(f, pt));
462 void project_into(base_node &pt)
const {
464 GMM_ASSERT1(pt.size() == 3,
"Dimensions mismatch");
465 if (pt[2] < .0) pt[2] = 0.;
467 scalar_type reldist = gmm::vect_sp(normals_[f], pt)*sqrt(2.);
469 gmm::scale(pt, 1./reldist);
472 basic_convex_ref_->project_into(pt);
476 GMM_ASSERT1(k == 1 || k == 2,
477 "Sorry exist only in degree 1 or 2, not " << k);
479 convex<base_node>::points().resize(cvs->nb_points());
480 normals_.resize(cvs->nb_faces());
483 normals_[0] = { 0., 0., -1.};
484 normals_[1] = { 0.,-1., 1.};
485 normals_[2] = { 1., 0., 1.};
486 normals_[3] = { 0., 1., 1.};
487 normals_[4] = {-1., 0., 1.};
489 for (
size_type i = 0; i < normals_.size(); ++i)
490 gmm::scale(normals_[i], 1. / gmm::vect_norm2(normals_[i]));
493 convex<base_node>::points()[0] = base_node(-1.0, -1.0, 0.0);
494 convex<base_node>::points()[1] = base_node( 1.0, -1.0, 0.0);
495 convex<base_node>::points()[2] = base_node(-1.0, 1.0, 0.0);
496 convex<base_node>::points()[3] = base_node( 1.0, 1.0, 0.0);
497 convex<base_node>::points()[4] = base_node( 0.0, 0.0, 1.0);
499 convex<base_node>::points()[0] = base_node(-1.0, -1.0, 0.0);
500 convex<base_node>::points()[1] = base_node( 0.0, -1.0, 0.0);
501 convex<base_node>::points()[2] = base_node( 1.0, -1.0, 0.0);
502 convex<base_node>::points()[3] = base_node(-1.0, 0.0, 0.0);
503 convex<base_node>::points()[4] = base_node( 0.0, 0.0, 0.0);
504 convex<base_node>::points()[5] = base_node( 1.0, 0.0, 0.0);
505 convex<base_node>::points()[6] = base_node(-1.0, 1.0, 0.0);
506 convex<base_node>::points()[7] = base_node( 0.0, 1.0, 0.0);
507 convex<base_node>::points()[8] = base_node( 1.0, 1.0, 0.0);
508 convex<base_node>::points()[9] = base_node(-0.5, -0.5, 0.5);
509 convex<base_node>::points()[10] = base_node( 0.5, -0.5, 0.5);
510 convex<base_node>::points()[11] = base_node(-0.5, 0.5, 0.5);
511 convex<base_node>::points()[12] = base_node( 0.5, 0.5, 0.5);
512 convex<base_node>::points()[13] = base_node( 0.0, 0.0, 1.0);
514 ppoints = store_point_tab(convex<base_node>::points());
515 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
520 DAL_SIMPLE_KEY(pyramid_QK_reference_key_, dim_type);
523 dal::pstatic_stored_object_key
524 pk = std::make_shared<pyramid_QK_reference_key_>(k);
526 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
527 pconvex_ref p = std::make_shared<pyramid_QK_of_ref_>(k);
529 dal::PERMANENT_STATIC_OBJECT);
531 if (p != p1) add_dependency(p, p1);
540 class pyramid_Q2_incomplete_of_ref_ :
public convex_of_reference {
542 scalar_type is_in(
const base_node& pt)
const
543 {
return basic_convex_ref_->is_in(pt); }
544 scalar_type is_in_face(
short_type f,
const base_node& pt)
const
545 {
return basic_convex_ref_->is_in_face(f, pt); }
548 convex<base_node>::points().resize(cvs->nb_points());
549 normals_.resize(cvs->nb_faces());
552 normals_ = basic_convex_ref_->normals();
554 convex<base_node>::points()[0] = base_node(-1.0, -1.0, 0.0);
555 convex<base_node>::points()[1] = base_node( 0.0, -1.0, 0.0);
556 convex<base_node>::points()[2] = base_node( 1.0, -1.0, 0.0);
557 convex<base_node>::points()[3] = base_node(-1.0, 0.0, 0.0);
558 convex<base_node>::points()[4] = base_node( 1.0, 0.0, 0.0);
559 convex<base_node>::points()[5] = base_node(-1.0, 1.0, 0.0);
560 convex<base_node>::points()[6] = base_node( 0.0, 1.0, 0.0);
561 convex<base_node>::points()[7] = base_node( 1.0, 1.0, 0.0);
562 convex<base_node>::points()[8] = base_node(-0.5, -0.5, 0.5);
563 convex<base_node>::points()[9] = base_node( 0.5, -0.5, 0.5);
564 convex<base_node>::points()[10] = base_node(-0.5, 0.5, 0.5);
565 convex<base_node>::points()[11] = base_node( 0.5, 0.5, 0.5);
566 convex<base_node>::points()[12] = base_node( 0.0, 0.0, 1.0);
568 ppoints = store_point_tab(convex<base_node>::points());
569 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
574 DAL_SIMPLE_KEY(pyramid_Q2_incomplete_reference_key_, dim_type);
577 dal::pstatic_stored_object_key
578 pk = std::make_shared<pyramid_Q2_incomplete_reference_key_>(0);
581 return std::dynamic_pointer_cast<const convex_of_reference>(o);
583 pconvex_ref p = std::make_shared<pyramid_Q2_incomplete_of_ref_>();
585 dal::PERMANENT_STATIC_OBJECT);
587 if (p != p1) add_dependency(p, p1);
597 class prism_incomplete_P2_of_ref_ :
public convex_of_reference {
599 scalar_type is_in(
const base_node& pt)
const
600 {
return basic_convex_ref_->is_in(pt); }
601 scalar_type is_in_face(
short_type f,
const base_node& pt)
const
602 {
return basic_convex_ref_->is_in_face(f, pt); }
605 convex<base_node>::points().resize(cvs->nb_points());
606 normals_.resize(cvs->nb_faces());
609 normals_ = basic_convex_ref_->normals();
611 convex<base_node>::points()[0] = base_node(0.0, 0.0, 0.0);
612 convex<base_node>::points()[1] = base_node(0.5, 0.0, 0.0);
613 convex<base_node>::points()[2] = base_node(1.0, 0.0, 0.0);
614 convex<base_node>::points()[3] = base_node(0.0, 0.5, 0.0);
615 convex<base_node>::points()[4] = base_node(0.5, 0.5, 0.0);
616 convex<base_node>::points()[5] = base_node(0.0, 1.0, 0.0);
617 convex<base_node>::points()[6] = base_node(0.0, 0.0, 0.5);
618 convex<base_node>::points()[7] = base_node(1.0, 0.0, 0.5);
619 convex<base_node>::points()[8] = base_node(0.0, 1.0, 0.5);
620 convex<base_node>::points()[9] = base_node(0.0, 0.0, 1.0);
621 convex<base_node>::points()[10] = base_node(0.5, 0.0, 1.0);
622 convex<base_node>::points()[11] = base_node(1.0, 0.0, 1.0);
623 convex<base_node>::points()[12] = base_node(0.0, 0.5, 1.0);
624 convex<base_node>::points()[13] = base_node(0.5, 0.5, 1.0);
625 convex<base_node>::points()[14] = base_node(0.0, 1.0, 1.0);
627 ppoints = store_point_tab(convex<base_node>::points());
628 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
633 DAL_SIMPLE_KEY(prism_incomplete_P2_reference_key_, dim_type);
636 dal::pstatic_stored_object_key
637 pk = std::make_shared<prism_incomplete_P2_reference_key_>(0);
640 return std::dynamic_pointer_cast<const convex_of_reference>(o);
642 pconvex_ref p = std::make_shared<prism_incomplete_P2_of_ref_>();
644 dal::PERMANENT_STATIC_OBJECT);
646 if (p != p1) add_dependency(p, p1);
656 DAL_DOUBLE_KEY(product_ref_key_, pconvex_ref, pconvex_ref);
658 struct product_ref_ :
public convex_of_reference {
659 pconvex_ref cvr1, cvr2;
661 scalar_type is_in(
const base_node &pt)
const {
662 dim_type n1 = cvr1->structure()->dim(), n2 = cvr2->structure()->dim();
663 base_node pt1(n1), pt2(n2);
664 GMM_ASSERT1(pt.size() == cvs->dim(),
665 "product_ref_::is_in: Dimension does not match");
666 std::copy(pt.begin(), pt.begin()+n1, pt1.begin());
667 std::copy(pt.begin()+n1, pt.end(), pt2.begin());
668 return std::max(cvr1->is_in(pt1), cvr2->is_in(pt2));
671 scalar_type is_in_face(
short_type f,
const base_node &pt)
const {
674 dim_type n1 = cvr1->structure()->dim(), n2 = cvr2->structure()->dim();
675 base_node pt1(n1), pt2(n2);
676 GMM_ASSERT1(pt.size() == cvs->dim(),
"Dimensions mismatch");
677 std::copy(pt.begin(), pt.begin()+n1, pt1.begin());
678 std::copy(pt.begin()+n1, pt.end(), pt2.begin());
679 if (f < cvr1->structure()->nb_faces())
return cvr1->is_in_face(f, pt1);
680 else return cvr2->is_in_face(
short_type(f - cvr1->structure()->nb_faces()), pt2);
683 void project_into(base_node &pt)
const {
685 GMM_ASSERT1(pt.size() == cvs->dim(),
"Dimensions mismatch");
686 dim_type n1 = cvr1->structure()->dim(), n2 = cvr2->structure()->dim();
687 base_node pt1(n1), pt2(n2);
688 std::copy(pt.begin(), pt.begin()+n1, pt1.begin());
689 std::copy(pt.begin()+n1, pt.end(), pt2.begin());
690 cvr1->project_into(pt1);
691 cvr2->project_into(pt2);
692 std::copy(pt1.begin(), pt1.end(), pt.begin());
693 std::copy(pt2.begin(), pt2.end(), pt.begin()+n1);
695 basic_convex_ref_->project_into(pt);
698 product_ref_(pconvex_ref a, pconvex_ref b) :
700 convex_direct_product(*a, *b).structure(),
703 if (a->structure()->dim() < b->structure()->dim())
704 GMM_WARNING1(
"Illegal convex: swap your operands: dim(cv1)=" <<
705 int(a->structure()->dim()) <<
" < dim(cv2)=" <<
706 int(b->structure()->dim()));
708 *((convex<base_node> *)(
this)) = convex_direct_product(*a, *b);
709 normals_.resize(cvs->nb_faces());
710 base_small_vector
null(cvs->dim());
null.fill(0.0);
711 std::fill(normals_.begin(), normals_.end(),
null);
712 for (
size_type r = 0; r < cvr1->structure()->nb_faces(); r++)
713 std::copy(cvr1->normals()[r].begin(), cvr1->normals()[r].end(),
714 normals_[r].begin());
715 for (
size_type r = 0; r < cvr2->structure()->nb_faces(); r++)
716 std::copy(cvr2->normals()[r].begin(), cvr2->normals()[r].end(),
717 normals_[r+cvr1->structure()->nb_faces()].begin()
718 + cvr1->structure()->dim());
719 ppoints = store_point_tab(convex<base_node>::points());
724 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
730 dal::pstatic_stored_object_key
731 pk = std::make_shared<product_ref_key_>(a, b);
734 return std::dynamic_pointer_cast<const convex_of_reference>(o);
736 pconvex_ref p = std::make_shared<product_ref_>(a, b);
740 p->pspt(), dal::PERMANENT_STATIC_OBJECT);
742 if (p != p1) add_dependency(p, p1);
760 class equilateral_simplex_of_ref_ :
public convex_of_reference {
763 scalar_type is_in(
const base_node &pt)
const {
764 GMM_ASSERT1(pt.size() == cvs->dim(),
"Dimension does not match");
766 for (
size_type f = 0; f < normals().size(); ++f) {
767 const base_node &x0 = (f ? convex<base_node>::points()[f-1]
768 : convex<base_node>::points().back());
769 scalar_type v = gmm::vect_sp(pt-x0, normals()[f]);
770 if (f == 0) d = v;
else d = std::max(d,v);
775 scalar_type is_in_face(
short_type f,
const base_node &pt)
const {
776 GMM_ASSERT1(pt.size() == cvs->dim(),
"Dimension does not match");
777 const base_node &x0 = (f ? convex<base_node>::points()[f-1]
778 : convex<base_node>::points().back());
779 return gmm::vect_sp(pt-x0,
normals()[f]);
782 void project_into(base_node &pt)
const {
783 dim_type N = cvs->dim();
784 GMM_ASSERT1(pt.size() == N,
"Dimension does not match");
785 base_node G(N); G.fill(0.);
786 for (
const base_node &x : convex<base_node>::points())
788 gmm::scale(G, scalar_type(1)/scalar_type(N+1));
790 scalar_type r = gmm::vect_sp(pt-G,
normals()[f]);
792 pt = G + r_inscr/r*(pt-G);
797 equilateral_simplex_of_ref_(
size_type N) :
801 r_inscr = scalar_type(1)/sqrt(scalar_type(2*N)*scalar_type(N+1));
804 convex<base_node>::points().resize(N+1);
805 normals_.resize(N+1);
806 base_node G(N); G.fill(0.);
808 convex<base_node>::points()[i].resize(N);
810 std::copy(prev->convex<base_node>::points()[i].begin(),
811 prev->convex<base_node>::points()[i].end(),
812 convex<base_node>::points()[i].begin());
813 convex<base_node>::points()[i][N-1] = 0.;
815 convex<base_node>::points()[i] = scalar_type(1)/scalar_type(N) * G;
816 convex<base_node>::points()[i][N-1]
817 = sqrt(1. - gmm::vect_norm2_sqr(convex<base_node>::points()[i]));
819 G += convex<base_node>::points()[i];
821 gmm::scale(G, scalar_type(1)/scalar_type(N+1));
823 normals_[f] = G - convex<base_node>::points()[f];
824 gmm::scale(normals_[f], 1/gmm::vect_norm2(normals_[f]));
826 ppoints = store_point_tab(convex<base_node>::points());
827 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
833 dal::pstatic_stored_object_key
834 pk = std::make_shared<convex_of_reference_key>(1, nc);
836 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
837 pconvex_ref p = std::make_shared<equilateral_simplex_of_ref_>(nc);
839 dal::PERMANENT_STATIC_OBJECT);
846 class generic_dummy_ :
public convex_of_reference {
848 scalar_type is_in(
const base_node &)
const
849 { GMM_ASSERT1(
false,
"Information not available here"); }
850 scalar_type is_in_face(
short_type,
const base_node &)
const
851 { GMM_ASSERT1(
false,
"Information not available here"); }
852 void project_into(base_node &)
const
853 { GMM_ASSERT1(
false,
"Operation not available here"); }
858 convex<base_node>::points().resize(n);
861 std::fill(P.begin(), P.end(), scalar_type(1)/scalar_type(20));
862 std::fill(convex<base_node>::points().begin(), convex<base_node>::points().end(), P);
863 ppoints = store_point_tab(convex<base_node>::points());
869 dal::pstatic_stored_object_key
870 pk = std::make_shared<convex_of_reference_key>(2, nc,
short_type(n), nf);
872 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
873 pconvex_ref p = std::make_shared<generic_dummy_>(nc, n, nf);
875 dal::PERMANENT_STATIC_OBJECT);