32 # if !defined(GETFEM_HAVE_LIBQHULL_R_QHULL_RA_H)
33 void qhull_delaunay(
const std::vector<base_node> &,
34 gmm::dense_matrix<size_type>&) {
35 GMM_ASSERT1(
false,
"Qhull header files not installed. "
36 "Install qhull library and reinstall GetFEM library.");
41 # include <libqhull_r/qhull_ra.h>
44 void qhull_delaunay(
const std::vector<base_node> &pts,
45 gmm::dense_matrix<size_type>& simplexes) {
48 if (pts.size() <= dim) { gmm::resize(simplexes, dim+1, 0);
return; }
49 if (pts.size() == dim+1) {
50 gmm::resize(simplexes, dim+1, 1);
51 for (
size_type i=0; i <= dim; ++i) simplexes(i, 0) = i;
54 std::vector<coordT> Pts(dim * pts.size());
56 gmm::copy(pts[i], gmm::sub_vector(Pts, gmm::sub_interval(i*dim, dim)));
62 char flags[]=
"qhull QJ d Qbb Pp T0";
65 FILE *errfile= stderr;
69 vertexT *vertex, **vertexp;
72 exitcode = qh_new_qhull (qh,
int(dim),
int(pts.size()), &Pts[0], ismalloc,
73 flags, outfile, errfile);
76 FORALLfacets {
if (!facet->upperdelaunay) nbf++; }
77 gmm::resize(simplexes, dim+1, nbf);
81 if (!facet->upperdelaunay) {
83 FOREACHvertex_(facet->vertices) {
84 assert(s < (
unsigned)(dim+1));
85 simplexes(s++,nbf) = qh_pointid(qh, vertex->point);
91 qh_freeqhull(qh, !qh_ALL);
92 qh_memfreeshort(qh, &curlong, &totlong);
93 if (curlong || totlong)
94 cerr <<
"qhull internal warning (main): did not free " << totlong <<
95 " bytes of long memory (" << curlong <<
" pieces)\n";
110 dim_type n = basic_cvs->dim();
111 std::vector<size_type> ipts(n+1);
112 if (basic_cvs->nb_points() == n + 1) {
113 for (
size_type i = 0; i <= n; ++i) ipts[i] = i;
114 m.add_simplex(n, ipts.begin());
118 size_type nb = simplexified_tab(basic_cvs, &tab);
121 for (
size_type i = 0; i <= n; ++i) ipts[i] = *tab++;
122 m.add_simplex(n, ipts.begin());
125 # if defined(GETFEM_HAVE_LIBQHULL_R_QHULL_RA_H)
126 gmm::dense_matrix<size_type> t;
127 qhull_delaunay(cvr->
points(), t);
128 for (
size_type nc = 0; nc < gmm::mat_ncols(t); ++nc) {
129 for (
size_type i = 0; i <= n; ++i) ipts[i] = t(i,nc);
130 m.add_simplex(n, ipts.begin());
141 struct stored_point_tab_key :
virtual public dal::static_stored_object_key {
143 bool compare(
const static_stored_object_key &oo)
const override {
144 const stored_point_tab_key &o
145 =
dynamic_cast<const stored_point_tab_key &
>(oo);
148 if (&x == &y)
return false;
149 std::vector<base_node>::const_iterator it1 = x.begin(), it2 = y.begin();
150 base_node::const_iterator itn1, itn2, itne;
151 for ( ; it1 != x.end() && it2 != y.end() ; ++it1, ++it2) {
152 if ((*it1).size() < (*it2).size())
return true;
153 if ((*it1).size() > (*it2).size())
return false;
154 itn1 = (*it1).begin(); itne = (*it1).end(); itn2 = (*it2).begin();
155 for ( ; itn1 != itne ; ++itn1, ++itn2)
156 if (*itn1 < *itn2)
return true;
157 else if (*itn1 > *itn2)
return false;
159 if (it2 != y.end())
return true;
162 bool equal(
const static_stored_object_key &oo)
const override {
163 auto &o =
dynamic_cast<const stored_point_tab_key &
>(oo);
166 if (&x == &y)
return true;
167 if (x.size() != y.size())
return false;
168 auto it1 = x.begin();
169 auto it2 = y.begin();
170 base_node::const_iterator itn1, itn2, itne;
171 for ( ; it1 != x.end() && it2 != y.end() ; ++it1, ++it2) {
172 if ((*it1).size() != (*it2).size())
return false;
173 itn1 = (*it1).begin(); itne = (*it1).end(); itn2 = (*it2).begin();
174 for ( ; itn1 != itne ; ++itn1, ++itn2)
175 if (*itn1 != *itn2)
return false;
184 dal::pstatic_stored_object_key
185 pk = std::make_shared<stored_point_tab_key>(&spt);
187 if (o)
return std::dynamic_pointer_cast<const stored_point_tab>(o);
188 pstored_point_tab p = std::make_shared<stored_point_tab>(spt);
189 DAL_STORED_OBJECT_DEBUG_CREATED(p.get(),
"Stored point tab");
190 dal::pstatic_stored_object_key
191 psp = std::make_shared<stored_point_tab_key>(p.get());
196 convex_of_reference::convex_of_reference
199 auto_basic(auto_basic_) {
200 DAL_STORED_OBJECT_DEBUG_CREATED(
this,
"convex of refrence");
201 psimplexified_convex = std::make_shared<mesh_structure>();
208 GMM_ASSERT1(auto_basic,
209 "always use simplexified_convex on the basic_convex_ref() "
210 "[this=" << nb_points() <<
", basic="
211 << basic_convex_ref_->nb_points());
212 return psimplexified_convex.get();
216 class convex_of_reference_key :
virtual public dal::static_stored_object_key{
222 bool compare(
const static_stored_object_key &oo)
const override{
223 const convex_of_reference_key &o
224 =
dynamic_cast<const convex_of_reference_key &
>(oo);
225 if (type < o.type)
return true;
226 if (type > o.type)
return false;
227 if (N < o.N)
return true;
228 if (N > o.N)
return false;
229 if (K < o.K)
return true;
230 if (K > o.K)
return false;
231 if (nf < o.nf)
return true;
234 bool equal(
const static_stored_object_key &oo)
const override{
235 auto &o =
dynamic_cast<const convex_of_reference_key &
>(oo);
236 if (type != o.type)
return false;
237 if (N != o.N)
return false;
238 if (K != o.K)
return false;
239 if (nf != o.nf)
return false;
242 convex_of_reference_key(
int t, dim_type NN,
short_type KK = 0,
244 : type(t), N(NN), K(KK), nf(nnf) {}
250 class K_simplex_of_ref_ :
public convex_of_reference {
252 scalar_type is_in(
const base_node &pt)
const {
254 GMM_ASSERT1(pt.size() == cvs->dim(),
255 "K_simplex_of_ref_::is_in: Dimensions mismatch");
256 scalar_type e = -1.0, r = (pt.size() > 0) ? -pt[0] : 0.0;
257 base_node::const_iterator it = pt.begin(), ite = pt.end();
258 for (; it != ite; e += *it, ++it) r = std::max(r, -(*it));
259 return std::max(r, e);
262 scalar_type is_in_face(
short_type f,
const base_node &pt)
const {
265 GMM_ASSERT1(pt.size() == cvs->dim(),
266 "K_simplex_of_ref_::is_in_face: Dimensions mismatch");
267 if (f > 0)
return -pt[f-1];
268 scalar_type e = -1.0;
269 base_node::const_iterator it = pt.begin(), ite = pt.end();
270 for (; it != ite; e += *it, ++it) {};
271 return e / sqrt(scalar_type(pt.size()));
274 void project_into(base_node &pt)
const {
276 GMM_ASSERT1(pt.size() == cvs->dim(),
277 "K_simplex_of_ref_::project_into: Dimensions mismatch");
278 scalar_type sum_coordinates = 0.0;
279 for (
const auto &coord : pt) sum_coordinates += coord;
280 if (sum_coordinates > 1.0) gmm::scale(pt, 1.0 / sum_coordinates);
281 for (
auto &coord : pt) {
282 if (coord < 0.0) coord = 0.0;
283 if (coord > 1.0) coord = 1.0;
286 basic_convex_ref_->project_into(pt);
289 K_simplex_of_ref_(dim_type NN,
short_type KK) :
294 convex<base_node>::points().resize(R);
295 normals_.resize(NN+1);
296 base_node
null(NN);
null.fill(0.0);
297 std::fill(normals_.begin(), normals_.end(),
null);
298 std::fill(convex<base_node>::points().begin(),
299 convex<base_node>::points().end(),
null);
301 normals_[i][i-1] = -1.0;
303 std::fill(normals_[0].begin(), normals_[0].end(),
304 scalar_type(1.0)/sqrt(scalar_type(NN)));
305 base_node c(NN); c.fill(0.0);
309 convex<base_node>::points()[0] = c;
314 convex<base_node>::points()[r] = c;
315 if (KK != 0 && NN > 0) {
316 l = 0; c[l] += 1.0 / scalar_type(KK); sum++;
318 sum -= int(floor(0.5+(c[l] * KK)));
319 c[l] = 0.0; l++;
if (l == NN)
break;
320 c[l] += 1.0 / scalar_type(KK); sum++;
325 ppoints = store_point_tab(convex<base_node>::points());
326 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
331 dal::pstatic_stored_object_key
332 pk = std::make_shared<convex_of_reference_key>(0, nc, K);
334 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
335 pconvex_ref p = std::make_shared<K_simplex_of_ref_>(nc, K);
337 dal::PERMANENT_STATIC_OBJECT);
339 if (p != p1) add_dependency(p, p1);
348 class Q2_incomplete_of_ref_ :
public convex_of_reference {
350 scalar_type is_in(
const base_node& pt)
const
351 {
return basic_convex_ref_->is_in(pt); }
352 scalar_type is_in_face(
short_type f,
const base_node& pt)
const
353 {
return basic_convex_ref_->is_in_face(f, pt); }
355 Q2_incomplete_of_ref_(dim_type nc) :
358 GMM_ASSERT1(nc == 2 || nc == 3,
"Sorry exist only in dimension 2 or 3");
359 convex<base_node>::points().resize(cvs->nb_points());
360 normals_.resize(nc == 2 ? 4: 6);
364 normals_[0] = { 1, 0};
365 normals_[1] = {-1, 0};
366 normals_[2] = { 0, 1};
367 normals_[3] = { 0,-1};
369 convex<base_node>::points()[0] = base_node(0.0, 0.0);
370 convex<base_node>::points()[1] = base_node(0.5, 0.0);
371 convex<base_node>::points()[2] = base_node(1.0, 0.0);
372 convex<base_node>::points()[3] = base_node(0.0, 0.5);
373 convex<base_node>::points()[4] = base_node(1.0, 0.5);
374 convex<base_node>::points()[5] = base_node(0.0, 1.0);
375 convex<base_node>::points()[6] = base_node(0.5, 1.0);
376 convex<base_node>::points()[7] = base_node(1.0, 1.0);
379 normals_[0] = { 1, 0, 0};
380 normals_[1] = {-1, 0, 0};
381 normals_[2] = { 0, 1, 0};
382 normals_[3] = { 0,-1, 0};
383 normals_[4] = { 0, 0, 1};
384 normals_[5] = { 0, 0,-1};
386 convex<base_node>::points()[0] = base_node(0.0, 0.0, 0.0);
387 convex<base_node>::points()[1] = base_node(0.5, 0.0, 0.0);
388 convex<base_node>::points()[2] = base_node(1.0, 0.0, 0.0);
389 convex<base_node>::points()[3] = base_node(0.0, 0.5, 0.0);
390 convex<base_node>::points()[4] = base_node(1.0, 0.5, 0.0);
391 convex<base_node>::points()[5] = base_node(0.0, 1.0, 0.0);
392 convex<base_node>::points()[6] = base_node(0.5, 1.0, 0.0);
393 convex<base_node>::points()[7] = base_node(1.0, 1.0, 0.0);
395 convex<base_node>::points()[8] = base_node(0.0, 0.0, 0.5);
396 convex<base_node>::points()[9] = base_node(1.0, 0.0, 0.5);
397 convex<base_node>::points()[10] = base_node(0.0, 1.0, 0.5);
398 convex<base_node>::points()[11] = base_node(1.0, 1.0, 0.5);
400 convex<base_node>::points()[12] = base_node(0.0, 0.0, 1.0);
401 convex<base_node>::points()[13] = base_node(0.5, 0.0, 1.0);
402 convex<base_node>::points()[14] = base_node(1.0, 0.0, 1.0);
403 convex<base_node>::points()[15] = base_node(0.0, 0.5, 1.0);
404 convex<base_node>::points()[16] = base_node(1.0, 0.5, 1.0);
405 convex<base_node>::points()[17] = base_node(0.0, 1.0, 1.0);
406 convex<base_node>::points()[18] = base_node(0.5, 1.0, 1.0);
407 convex<base_node>::points()[19] = base_node(1.0, 1.0, 1.0);
409 ppoints = store_point_tab(convex<base_node>::points());
414 DAL_SIMPLE_KEY(Q2_incomplete_of_reference_key_, dim_type);
417 dal::pstatic_stored_object_key
418 pk = std::make_shared<Q2_incomplete_of_reference_key_>(nc);
420 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
421 pconvex_ref p = std::make_shared<Q2_incomplete_of_ref_>(nc);
423 dal::PERMANENT_STATIC_OBJECT);
425 if (p != p1) add_dependency(p, p1);
433 class pyramid_QK_of_ref_ :
public convex_of_reference {
435 scalar_type is_in_face(
short_type f,
const base_node& pt)
const {
438 GMM_ASSERT1(pt.size() == 3,
"Dimensions mismatch");
442 return gmm::vect_sp(normals_[f], pt) - sqrt(2.)/2.;
445 scalar_type is_in(
const base_node& pt)
const {
447 scalar_type r = is_in_face(0, pt);
448 for (
short_type f = 1; f < 5; ++f) r = std::max(r, is_in_face(f, pt));
452 void project_into(base_node &pt)
const {
454 GMM_ASSERT1(pt.size() == 3,
"Dimensions mismatch");
455 if (pt[2] < .0) pt[2] = 0.;
457 scalar_type reldist =
gmm::vect_sp(normals_[f], pt)*sqrt(2.);
459 gmm::scale(pt, 1./reldist);
462 basic_convex_ref_->project_into(pt);
466 GMM_ASSERT1(k == 1 || k == 2,
467 "Sorry exist only in degree 1 or 2, not " << k);
469 convex<base_node>::points().resize(cvs->nb_points());
470 normals_.resize(cvs->nb_faces());
473 normals_[0] = { 0., 0., -1.};
474 normals_[1] = { 0.,-1., 1.};
475 normals_[2] = { 1., 0., 1.};
476 normals_[3] = { 0., 1., 1.};
477 normals_[4] = {-1., 0., 1.};
479 for (
size_type i = 0; i < normals_.size(); ++i)
480 gmm::scale(normals_[i], 1. / gmm::vect_norm2(normals_[i]));
483 convex<base_node>::points()[0] = base_node(-1.0, -1.0, 0.0);
484 convex<base_node>::points()[1] = base_node( 1.0, -1.0, 0.0);
485 convex<base_node>::points()[2] = base_node(-1.0, 1.0, 0.0);
486 convex<base_node>::points()[3] = base_node( 1.0, 1.0, 0.0);
487 convex<base_node>::points()[4] = base_node( 0.0, 0.0, 1.0);
489 convex<base_node>::points()[0] = base_node(-1.0, -1.0, 0.0);
490 convex<base_node>::points()[1] = base_node( 0.0, -1.0, 0.0);
491 convex<base_node>::points()[2] = base_node( 1.0, -1.0, 0.0);
492 convex<base_node>::points()[3] = base_node(-1.0, 0.0, 0.0);
493 convex<base_node>::points()[4] = base_node( 0.0, 0.0, 0.0);
494 convex<base_node>::points()[5] = base_node( 1.0, 0.0, 0.0);
495 convex<base_node>::points()[6] = base_node(-1.0, 1.0, 0.0);
496 convex<base_node>::points()[7] = base_node( 0.0, 1.0, 0.0);
497 convex<base_node>::points()[8] = base_node( 1.0, 1.0, 0.0);
498 convex<base_node>::points()[9] = base_node(-0.5, -0.5, 0.5);
499 convex<base_node>::points()[10] = base_node( 0.5, -0.5, 0.5);
500 convex<base_node>::points()[11] = base_node(-0.5, 0.5, 0.5);
501 convex<base_node>::points()[12] = base_node( 0.5, 0.5, 0.5);
502 convex<base_node>::points()[13] = base_node( 0.0, 0.0, 1.0);
504 ppoints = store_point_tab(convex<base_node>::points());
505 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
510 DAL_SIMPLE_KEY(pyramid_QK_reference_key_, dim_type);
513 dal::pstatic_stored_object_key
514 pk = std::make_shared<pyramid_QK_reference_key_>(k);
516 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
517 pconvex_ref p = std::make_shared<pyramid_QK_of_ref_>(k);
519 dal::PERMANENT_STATIC_OBJECT);
521 if (p != p1) add_dependency(p, p1);
530 class pyramid_Q2_incomplete_of_ref_ :
public convex_of_reference {
532 scalar_type is_in(
const base_node& pt)
const
533 {
return basic_convex_ref_->is_in(pt); }
534 scalar_type is_in_face(
short_type f,
const base_node& pt)
const
535 {
return basic_convex_ref_->is_in_face(f, pt); }
538 convex<base_node>::points().resize(cvs->nb_points());
539 normals_.resize(cvs->nb_faces());
542 normals_ = basic_convex_ref_->normals();
544 convex<base_node>::points()[0] = base_node(-1.0, -1.0, 0.0);
545 convex<base_node>::points()[1] = base_node( 0.0, -1.0, 0.0);
546 convex<base_node>::points()[2] = base_node( 1.0, -1.0, 0.0);
547 convex<base_node>::points()[3] = base_node(-1.0, 0.0, 0.0);
548 convex<base_node>::points()[4] = base_node( 1.0, 0.0, 0.0);
549 convex<base_node>::points()[5] = base_node(-1.0, 1.0, 0.0);
550 convex<base_node>::points()[6] = base_node( 0.0, 1.0, 0.0);
551 convex<base_node>::points()[7] = base_node( 1.0, 1.0, 0.0);
552 convex<base_node>::points()[8] = base_node(-0.5, -0.5, 0.5);
553 convex<base_node>::points()[9] = base_node( 0.5, -0.5, 0.5);
554 convex<base_node>::points()[10] = base_node(-0.5, 0.5, 0.5);
555 convex<base_node>::points()[11] = base_node( 0.5, 0.5, 0.5);
556 convex<base_node>::points()[12] = base_node( 0.0, 0.0, 1.0);
558 ppoints = store_point_tab(convex<base_node>::points());
559 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
564 DAL_SIMPLE_KEY(pyramid_Q2_incomplete_reference_key_, dim_type);
567 dal::pstatic_stored_object_key
568 pk = std::make_shared<pyramid_Q2_incomplete_reference_key_>(0);
571 return std::dynamic_pointer_cast<const convex_of_reference>(o);
573 pconvex_ref p = std::make_shared<pyramid_Q2_incomplete_of_ref_>();
575 dal::PERMANENT_STATIC_OBJECT);
577 if (p != p1) add_dependency(p, p1);
587 class prism_incomplete_P2_of_ref_ :
public convex_of_reference {
589 scalar_type is_in(
const base_node& pt)
const
590 {
return basic_convex_ref_->is_in(pt); }
591 scalar_type is_in_face(
short_type f,
const base_node& pt)
const
592 {
return basic_convex_ref_->is_in_face(f, pt); }
595 convex<base_node>::points().resize(cvs->nb_points());
596 normals_.resize(cvs->nb_faces());
599 normals_ = basic_convex_ref_->normals();
601 convex<base_node>::points()[0] = base_node(0.0, 0.0, 0.0);
602 convex<base_node>::points()[1] = base_node(0.5, 0.0, 0.0);
603 convex<base_node>::points()[2] = base_node(1.0, 0.0, 0.0);
604 convex<base_node>::points()[3] = base_node(0.0, 0.5, 0.0);
605 convex<base_node>::points()[4] = base_node(0.5, 0.5, 0.0);
606 convex<base_node>::points()[5] = base_node(0.0, 1.0, 0.0);
607 convex<base_node>::points()[6] = base_node(0.0, 0.0, 0.5);
608 convex<base_node>::points()[7] = base_node(1.0, 0.0, 0.5);
609 convex<base_node>::points()[8] = base_node(0.0, 1.0, 0.5);
610 convex<base_node>::points()[9] = base_node(0.0, 0.0, 1.0);
611 convex<base_node>::points()[10] = base_node(0.5, 0.0, 1.0);
612 convex<base_node>::points()[11] = base_node(1.0, 0.0, 1.0);
613 convex<base_node>::points()[12] = base_node(0.0, 0.5, 1.0);
614 convex<base_node>::points()[13] = base_node(0.5, 0.5, 1.0);
615 convex<base_node>::points()[14] = base_node(0.0, 1.0, 1.0);
617 ppoints = store_point_tab(convex<base_node>::points());
618 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
623 DAL_SIMPLE_KEY(prism_incomplete_P2_reference_key_, dim_type);
626 dal::pstatic_stored_object_key
627 pk = std::make_shared<prism_incomplete_P2_reference_key_>(0);
630 return std::dynamic_pointer_cast<const convex_of_reference>(o);
632 pconvex_ref p = std::make_shared<prism_incomplete_P2_of_ref_>();
634 dal::PERMANENT_STATIC_OBJECT);
636 if (p != p1) add_dependency(p, p1);
646 DAL_DOUBLE_KEY(product_ref_key_, pconvex_ref, pconvex_ref);
648 struct product_ref_ :
public convex_of_reference {
649 pconvex_ref cvr1, cvr2;
651 scalar_type is_in(
const base_node &pt)
const {
652 dim_type n1 = cvr1->structure()->dim(), n2 = cvr2->structure()->dim();
653 base_node pt1(n1), pt2(n2);
654 GMM_ASSERT1(pt.size() == cvs->dim(),
655 "product_ref_::is_in: Dimension does not match");
656 std::copy(pt.begin(), pt.begin()+n1, pt1.begin());
657 std::copy(pt.begin()+n1, pt.end(), pt2.begin());
658 return std::max(cvr1->is_in(pt1), cvr2->is_in(pt2));
661 scalar_type is_in_face(
short_type f,
const base_node &pt)
const {
664 dim_type n1 = cvr1->structure()->dim(), n2 = cvr2->structure()->dim();
665 base_node pt1(n1), pt2(n2);
666 GMM_ASSERT1(pt.size() == cvs->dim(),
"Dimensions mismatch");
667 std::copy(pt.begin(), pt.begin()+n1, pt1.begin());
668 std::copy(pt.begin()+n1, pt.end(), pt2.begin());
669 if (f < cvr1->structure()->nb_faces())
return cvr1->is_in_face(f, pt1);
670 else return cvr2->is_in_face(
short_type(f - cvr1->structure()->nb_faces()), pt2);
673 void project_into(base_node &pt)
const {
675 GMM_ASSERT1(pt.size() == cvs->dim(),
"Dimensions mismatch");
676 dim_type n1 = cvr1->structure()->dim(), n2 = cvr2->structure()->dim();
677 base_node pt1(n1), pt2(n2);
678 std::copy(pt.begin(), pt.begin()+n1, pt1.begin());
679 std::copy(pt.begin()+n1, pt.end(), pt2.begin());
680 cvr1->project_into(pt1);
681 cvr2->project_into(pt2);
682 std::copy(pt1.begin(), pt1.end(), pt.begin());
683 std::copy(pt2.begin(), pt2.end(), pt.begin()+n1);
685 basic_convex_ref_->project_into(pt);
688 product_ref_(pconvex_ref a, pconvex_ref b) :
690 convex_direct_product(*a, *b).structure(),
693 if (a->structure()->dim() < b->structure()->dim())
694 GMM_WARNING1(
"Illegal convex: swap your operands: dim(cv1)=" <<
695 int(a->structure()->dim()) <<
" < dim(cv2)=" <<
696 int(b->structure()->dim()));
698 *((convex<base_node> *)(
this)) = convex_direct_product(*a, *b);
699 normals_.resize(cvs->nb_faces());
700 base_small_vector
null(cvs->dim());
null.fill(0.0);
701 std::fill(normals_.begin(), normals_.end(),
null);
702 for (
size_type r = 0; r < cvr1->structure()->nb_faces(); r++)
703 std::copy(cvr1->normals()[r].begin(), cvr1->normals()[r].end(),
704 normals_[r].begin());
705 for (
size_type r = 0; r < cvr2->structure()->nb_faces(); r++)
706 std::copy(cvr2->normals()[r].begin(), cvr2->normals()[r].end(),
707 normals_[r+cvr1->structure()->nb_faces()].begin()
708 + cvr1->structure()->dim());
709 ppoints = store_point_tab(convex<base_node>::points());
714 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
720 dal::pstatic_stored_object_key
721 pk = std::make_shared<product_ref_key_>(a, b);
724 return std::dynamic_pointer_cast<const convex_of_reference>(o);
726 pconvex_ref p = std::make_shared<product_ref_>(a, b);
730 p->pspt(), dal::PERMANENT_STATIC_OBJECT);
732 if (p != p1) add_dependency(p, p1);
750 class equilateral_simplex_of_ref_ :
public convex_of_reference {
753 scalar_type is_in(
const base_node &pt)
const {
754 GMM_ASSERT1(pt.size() == cvs->dim(),
"Dimension does not match");
756 for (
size_type f = 0; f < normals().size(); ++f) {
757 const base_node &x0 = (f ? convex<base_node>::points()[f-1]
758 : convex<base_node>::points().back());
759 scalar_type v = gmm::vect_sp(pt-x0, normals()[f]);
760 if (f == 0) d = v;
else d = std::max(d,v);
765 scalar_type is_in_face(
short_type f,
const base_node &pt)
const {
766 GMM_ASSERT1(pt.size() == cvs->dim(),
"Dimension does not match");
767 const base_node &x0 = (f ? convex<base_node>::points()[f-1]
768 : convex<base_node>::points().back());
772 void project_into(base_node &pt)
const {
773 dim_type N = cvs->dim();
774 GMM_ASSERT1(pt.size() == N,
"Dimension does not match");
775 base_node G(N); G.fill(0.);
776 for (
const base_node &x : convex<base_node>::points())
778 gmm::scale(G, scalar_type(1)/scalar_type(N+1));
782 pt = G + r_inscr/r*(pt-G);
787 equilateral_simplex_of_ref_(
size_type N) :
791 r_inscr = scalar_type(1)/sqrt(scalar_type(2*N)*scalar_type(N+1));
794 convex<base_node>::points().resize(N+1);
795 normals_.resize(N+1);
796 base_node G(N); G.fill(0.);
798 convex<base_node>::points()[i].resize(N);
800 std::copy(prev->convex<base_node>::points()[i].begin(),
801 prev->convex<base_node>::points()[i].end(),
802 convex<base_node>::points()[i].begin());
803 convex<base_node>::points()[i][N-1] = 0.;
805 convex<base_node>::points()[i] = scalar_type(1)/scalar_type(N) * G;
806 convex<base_node>::points()[i][N-1]
807 = sqrt(1. - gmm::vect_norm2_sqr(convex<base_node>::points()[i]));
809 G += convex<base_node>::points()[i];
811 gmm::scale(G, scalar_type(1)/scalar_type(N+1));
813 normals_[f] = G - convex<base_node>::points()[f];
814 gmm::scale(normals_[f], 1/gmm::vect_norm2(normals_[f]));
816 ppoints = store_point_tab(convex<base_node>::points());
817 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
823 dal::pstatic_stored_object_key
824 pk = std::make_shared<convex_of_reference_key>(1, nc);
826 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
827 pconvex_ref p = std::make_shared<equilateral_simplex_of_ref_>(nc);
829 dal::PERMANENT_STATIC_OBJECT);
836 class generic_dummy_ :
public convex_of_reference {
838 scalar_type is_in(
const base_node &)
const
839 { GMM_ASSERT1(
false,
"Information not available here"); }
840 scalar_type is_in_face(
short_type,
const base_node &)
const
841 { GMM_ASSERT1(
false,
"Information not available here"); }
842 void project_into(base_node &)
const
843 { GMM_ASSERT1(
false,
"Operation not available here"); }
848 convex<base_node>::points().resize(n);
851 std::fill(P.begin(), P.end(), scalar_type(1)/scalar_type(20));
852 std::fill(convex<base_node>::points().begin(), convex<base_node>::points().end(), P);
853 ppoints = store_point_tab(convex<base_node>::points());
859 dal::pstatic_stored_object_key
860 pk = std::make_shared<convex_of_reference_key>(2, nc,
short_type(n), nf);
862 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
863 pconvex_ref p = std::make_shared<generic_dummy_>(nc, n, nf);
865 dal::PERMANENT_STATIC_OBJECT);
convenient initialization of vectors via overload of "operator,".
Mesh structure definition.
Base class for reference convexes.
const stored_point_tab & points() const
return the vertices of the reference convex.
const mesh_structure * simplexified_convex() const
return a mesh structure composed of simplexes whose union is the reference convex.
const std::vector< base_small_vector > & normals() const
return the normal vector for each face.
Mesh structure definition.
void clear()
erase the mesh
A simple singleton implementation.
strongest_value_type< V1, V2 >::value_type vect_sp(const V1 &v1, const V2 &v2)
*/
pconvex_structure prism_incomplete_P2_structure()
Give a pointer on the 3D quadratic incomplete prism structure.
pconvex_ref convex_ref_product(pconvex_ref a, pconvex_ref b)
tensorial product of two convex ref.
pconvex_structure pyramid_Q2_incomplete_structure()
Give a pointer on the 3D quadratic incomplete pyramid structure.
gmm::uint16_type short_type
used as the common short type integer in the library
pconvex_structure pyramid_QK_structure(dim_type k)
Give a pointer on the 3D pyramid structure for a degree k = 1 or 2.
pconvex_ref equilateral_simplex_of_reference(dim_type nc)
equilateral simplex (degree 1).
pconvex_ref pyramid_QK_of_reference(dim_type k)
pyramidal element of reference of degree k (k = 1 or 2 only)
pconvex_ref simplex_of_reference(dim_type nc, short_type K)
returns a simplex of reference of dimension nc and degree k
std::shared_ptr< const convex_structure > pconvex_structure
Pointer on a convex structure description.
pconvex_structure generic_dummy_structure(dim_type nc, size_type n, short_type nf)
Generic convex with n global nodes.
pconvex_ref pyramid_Q2_incomplete_of_reference()
incomplete quadratic pyramidal element of reference (13-node)
pconvex_ref prism_incomplete_P2_of_reference()
incomplete quadratic prism element of reference (15-node)
pconvex_structure Q2_incomplete_structure(dim_type nc)
Give a pointer on the structures of a incomplete Q2 quadrilateral/hexahedral of dimension d = 2 or 3.
pconvex_ref parallelepiped_of_reference(dim_type nc, dim_type k)
parallelepiped of reference of dimension nc (and degree 1)
pconvex_ref generic_dummy_convex_ref(dim_type nc, size_type n, short_type nf)
generic convex with n global nodes
pconvex_structure simplex_structure(dim_type nc)
Give a pointer on the structures of a simplex of dimension d.
size_t size_type
used as the common size type in the library
pconvex_ref Q2_incomplete_of_reference(dim_type nc)
incomplete Q2 quadrilateral/hexahedral of reference of dimension d = 2 or 3
pconvex_structure convex_product_structure(pconvex_structure a, pconvex_structure b)
Give a pointer on the structures of a convex which is the direct product of the convexes represented ...
pconvex_structure basic_structure(pconvex_structure cv)
Original structure (if concerned)
pconvex_ref basic_convex_ref(pconvex_ref cvr)
return the associated order 1 reference convex.
pconvex_ref prism_of_reference(dim_type nc)
prism of reference of dimension nc (and degree 1)
void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o, permanence perm)
Add an object with two optional dependencies.
pstatic_stored_object search_stored_object(pstatic_stored_object_key k)
Gives a pointer to an object from a key pointer.