33 # if !defined(GETFEM_HAVE_LIBQHULL_R_QHULL_RA_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.");
42 # include <libqhull_r/qhull_ra.h>
45 void qhull_delaunay(
const std::vector<base_node> &pts,
46 gmm::dense_matrix<size_type>& simplexes) {
49 if (pts.size() <= dim) { gmm::resize(simplexes, dim+1, 0);
return; }
50 if (pts.size() == dim+1) {
51 gmm::resize(simplexes, dim+1, 1);
52 for (
size_type i=0; i <= dim; ++i) simplexes(i, 0) = i;
55 std::vector<coordT> Pts(dim * pts.size());
57 gmm::copy(pts[i], gmm::sub_vector(Pts, gmm::sub_interval(i*dim, dim)));
63 char flags[]=
"qhull QJ d Qbb Pp T0";
66 FILE *errfile= stderr;
70 vertexT *vertex, **vertexp;
73 exitcode = qh_new_qhull (qh,
int(dim),
int(pts.size()), &Pts[0], ismalloc,
74 flags, outfile, errfile);
77 FORALLfacets {
if (!facet->upperdelaunay) nbf++; }
78 gmm::resize(simplexes, dim+1, nbf);
82 if (!facet->upperdelaunay) {
84 FOREACHvertex_(facet->vertices) {
85 assert(s < (
unsigned)(dim+1));
86 simplexes(s++,nbf) = qh_pointid(qh, vertex->point);
92 qh_freeqhull(qh, !qh_ALL);
93 qh_memfreeshort(qh, &curlong, &totlong);
94 if (curlong || totlong)
95 cerr <<
"qhull internal warning (main): did not free " << totlong <<
96 " bytes of long memory (" << curlong <<
" pieces)\n";
111 dim_type n = basic_cvs->dim();
112 std::vector<size_type> ipts(n+1);
113 if (basic_cvs->nb_points() == n + 1) {
114 for (
size_type i = 0; i <= n; ++i) ipts[i] = i;
115 m.add_simplex(n, ipts.begin());
119 size_type nb = simplexified_tab(basic_cvs, &tab);
122 for (
size_type i = 0; i <= n; ++i) ipts[i] = *tab++;
123 m.add_simplex(n, ipts.begin());
126 # if defined(GETFEM_HAVE_LIBQHULL_R_QHULL_RA_H)
127 gmm::dense_matrix<size_type> t;
128 qhull_delaunay(cvr->
points(), t);
129 for (
size_type nc = 0; nc < gmm::mat_ncols(t); ++nc) {
130 for (
size_type i = 0; i <= n; ++i) ipts[i] = t(i,nc);
131 m.add_simplex(n, ipts.begin());
142 struct stored_point_tab_key :
virtual public dal::static_stored_object_key {
144 bool compare(
const static_stored_object_key &oo)
const override {
145 const stored_point_tab_key &o
146 =
dynamic_cast<const stored_point_tab_key &
>(oo);
149 if (&x == &y)
return false;
150 std::vector<base_node>::const_iterator it1 = x.begin(), it2 = y.begin();
151 base_node::const_iterator itn1, itn2, itne;
152 for ( ; it1 != x.end() && it2 != y.end() ; ++it1, ++it2) {
153 if ((*it1).size() < (*it2).size())
return true;
154 if ((*it1).size() > (*it2).size())
return false;
155 itn1 = (*it1).begin(); itne = (*it1).end(); itn2 = (*it2).begin();
156 for ( ; itn1 != itne ; ++itn1, ++itn2)
157 if (*itn1 < *itn2)
return true;
158 else if (*itn1 > *itn2)
return false;
160 if (it2 != y.end())
return true;
163 bool equal(
const static_stored_object_key &oo)
const override {
164 auto &o =
dynamic_cast<const stored_point_tab_key &
>(oo);
167 if (&x == &y)
return true;
168 if (x.size() != y.size())
return false;
169 auto it1 = x.begin();
170 auto it2 = y.begin();
171 base_node::const_iterator itn1, itn2, itne;
172 for ( ; it1 != x.end() && it2 != y.end() ; ++it1, ++it2) {
173 if ((*it1).size() != (*it2).size())
return false;
174 itn1 = (*it1).begin(); itne = (*it1).end(); itn2 = (*it2).begin();
175 for ( ; itn1 != itne ; ++itn1, ++itn2)
176 if (*itn1 != *itn2)
return false;
185 dal::pstatic_stored_object_key
186 pk = std::make_shared<stored_point_tab_key>(&spt);
188 if (o)
return std::dynamic_pointer_cast<const stored_point_tab>(o);
189 pstored_point_tab p = std::make_shared<stored_point_tab>(spt);
190 DAL_STORED_OBJECT_DEBUG_CREATED(p.get(),
"Stored point tab");
191 dal::pstatic_stored_object_key
192 psp = std::make_shared<stored_point_tab_key>(p.get());
197 convex_of_reference::convex_of_reference
200 auto_basic(auto_basic_) {
201 DAL_STORED_OBJECT_DEBUG_CREATED(
this,
"convex of refrence");
202 psimplexified_convex = std::make_shared<mesh_structure>();
209 GMM_ASSERT1(auto_basic,
210 "always use simplexified_convex on the basic_convex_ref() "
211 "[this=" << nb_points() <<
", basic="
212 << basic_convex_ref_->nb_points());
213 return psimplexified_convex.get();
217 class convex_of_reference_key :
virtual public dal::static_stored_object_key{
223 bool compare(
const static_stored_object_key &oo)
const override{
224 const convex_of_reference_key &o
225 =
dynamic_cast<const convex_of_reference_key &
>(oo);
226 if (type < o.type)
return true;
227 if (type > o.type)
return false;
228 if (N < o.N)
return true;
229 if (N > o.N)
return false;
230 if (K < o.K)
return true;
231 if (K > o.K)
return false;
232 if (nf < o.nf)
return true;
235 bool equal(
const static_stored_object_key &oo)
const override{
236 auto &o =
dynamic_cast<const convex_of_reference_key &
>(oo);
237 if (type != o.type)
return false;
238 if (N != o.N)
return false;
239 if (K != o.K)
return false;
240 if (nf != o.nf)
return false;
243 convex_of_reference_key(
int t, dim_type NN,
short_type KK = 0,
245 : type(t), N(NN), K(KK), nf(nnf) {}
251 class K_simplex_of_ref_ :
public convex_of_reference {
253 scalar_type is_in(
const base_node &pt)
const {
255 GMM_ASSERT1(pt.size() == cvs->dim(),
256 "K_simplex_of_ref_::is_in: Dimensions mismatch");
257 scalar_type e = -1.0, r = (pt.size() > 0) ? -pt[0] : 0.0;
258 base_node::const_iterator it = pt.begin(), ite = pt.end();
259 for (; it != ite; e += *it, ++it) r = std::max(r, -(*it));
260 return std::max(r, e);
263 scalar_type is_in_face(
short_type f,
const base_node &pt)
const {
266 GMM_ASSERT1(pt.size() == cvs->dim(),
267 "K_simplex_of_ref_::is_in_face: Dimensions mismatch");
268 if (f > 0)
return -pt[f-1];
269 scalar_type e = -1.0;
270 base_node::const_iterator it = pt.begin(), ite = pt.end();
271 for (; it != ite; e += *it, ++it) {};
272 return e / sqrt(scalar_type(pt.size()));
275 void project_into(base_node &pt)
const {
277 GMM_ASSERT1(pt.size() == cvs->dim(),
278 "K_simplex_of_ref_::project_into: Dimensions mismatch");
279 scalar_type sum_coordinates = 0.0;
280 for (
const auto &coord : pt) sum_coordinates += coord;
281 if (sum_coordinates > 1.0) gmm::scale(pt, 1.0 / sum_coordinates);
282 for (
auto &coord : pt) {
283 if (coord < 0.0) coord = 0.0;
284 if (coord > 1.0) coord = 1.0;
287 basic_convex_ref_->project_into(pt);
290 K_simplex_of_ref_(dim_type NN,
short_type KK) :
295 convex<base_node>::points().resize(R);
296 normals_.resize(NN+1);
297 base_node
null(NN);
null.fill(0.0);
298 std::fill(normals_.begin(), normals_.end(),
null);
299 std::fill(convex<base_node>::points().begin(),
300 convex<base_node>::points().end(),
null);
302 normals_[i][i-1] = -1.0;
304 std::fill(normals_[0].begin(), normals_[0].end(),
305 scalar_type(1.0)/sqrt(scalar_type(NN)));
306 base_node c(NN); c.fill(0.0);
310 convex<base_node>::points()[0] = c;
315 convex<base_node>::points()[r] = c;
316 if (KK != 0 && NN > 0) {
317 l = 0; c[l] += 1.0 / scalar_type(KK); sum++;
319 sum -= int(floor(0.5+(c[l] * KK)));
320 c[l] = 0.0; l++;
if (l == NN)
break;
321 c[l] += 1.0 / scalar_type(KK); sum++;
326 ppoints = store_point_tab(convex<base_node>::points());
327 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
332 dal::pstatic_stored_object_key
333 pk = std::make_shared<convex_of_reference_key>(0, nc, K);
335 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
336 pconvex_ref p = std::make_shared<K_simplex_of_ref_>(nc, K);
338 dal::PERMANENT_STATIC_OBJECT);
340 if (p != p1) add_dependency(p, p1);
349 class Q2_incomplete_of_ref_ :
public convex_of_reference {
351 scalar_type is_in(
const base_node& pt)
const
352 {
return basic_convex_ref_->is_in(pt); }
353 scalar_type is_in_face(
short_type f,
const base_node& pt)
const
354 {
return basic_convex_ref_->is_in_face(f, pt); }
356 Q2_incomplete_of_ref_(dim_type nc) :
359 GMM_ASSERT1(nc == 2 || nc == 3,
"Sorry exist only in dimension 2 or 3");
360 convex<base_node>::points().resize(cvs->nb_points());
361 normals_.resize(nc == 2 ? 4: 6);
365 normals_[0] = { 1, 0};
366 normals_[1] = {-1, 0};
367 normals_[2] = { 0, 1};
368 normals_[3] = { 0,-1};
370 convex<base_node>::points()[0] = base_node(0.0, 0.0);
371 convex<base_node>::points()[1] = base_node(0.5, 0.0);
372 convex<base_node>::points()[2] = base_node(1.0, 0.0);
373 convex<base_node>::points()[3] = base_node(0.0, 0.5);
374 convex<base_node>::points()[4] = base_node(1.0, 0.5);
375 convex<base_node>::points()[5] = base_node(0.0, 1.0);
376 convex<base_node>::points()[6] = base_node(0.5, 1.0);
377 convex<base_node>::points()[7] = base_node(1.0, 1.0);
380 normals_[0] = { 1, 0, 0};
381 normals_[1] = {-1, 0, 0};
382 normals_[2] = { 0, 1, 0};
383 normals_[3] = { 0,-1, 0};
384 normals_[4] = { 0, 0, 1};
385 normals_[5] = { 0, 0,-1};
387 convex<base_node>::points()[0] = base_node(0.0, 0.0, 0.0);
388 convex<base_node>::points()[1] = base_node(0.5, 0.0, 0.0);
389 convex<base_node>::points()[2] = base_node(1.0, 0.0, 0.0);
390 convex<base_node>::points()[3] = base_node(0.0, 0.5, 0.0);
391 convex<base_node>::points()[4] = base_node(1.0, 0.5, 0.0);
392 convex<base_node>::points()[5] = base_node(0.0, 1.0, 0.0);
393 convex<base_node>::points()[6] = base_node(0.5, 1.0, 0.0);
394 convex<base_node>::points()[7] = base_node(1.0, 1.0, 0.0);
396 convex<base_node>::points()[8] = base_node(0.0, 0.0, 0.5);
397 convex<base_node>::points()[9] = base_node(1.0, 0.0, 0.5);
398 convex<base_node>::points()[10] = base_node(0.0, 1.0, 0.5);
399 convex<base_node>::points()[11] = base_node(1.0, 1.0, 0.5);
401 convex<base_node>::points()[12] = base_node(0.0, 0.0, 1.0);
402 convex<base_node>::points()[13] = base_node(0.5, 0.0, 1.0);
403 convex<base_node>::points()[14] = base_node(1.0, 0.0, 1.0);
404 convex<base_node>::points()[15] = base_node(0.0, 0.5, 1.0);
405 convex<base_node>::points()[16] = base_node(1.0, 0.5, 1.0);
406 convex<base_node>::points()[17] = base_node(0.0, 1.0, 1.0);
407 convex<base_node>::points()[18] = base_node(0.5, 1.0, 1.0);
408 convex<base_node>::points()[19] = base_node(1.0, 1.0, 1.0);
410 ppoints = store_point_tab(convex<base_node>::points());
415 DAL_SIMPLE_KEY(Q2_incomplete_of_reference_key_, dim_type);
418 dal::pstatic_stored_object_key
419 pk = std::make_shared<Q2_incomplete_of_reference_key_>(nc);
421 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
422 pconvex_ref p = std::make_shared<Q2_incomplete_of_ref_>(nc);
424 dal::PERMANENT_STATIC_OBJECT);
426 if (p != p1) add_dependency(p, p1);
434 class pyramid_QK_of_ref_ :
public convex_of_reference {
436 scalar_type is_in_face(
short_type f,
const base_node& pt)
const {
439 GMM_ASSERT1(pt.size() == 3,
"Dimensions mismatch");
443 return gmm::vect_sp(normals_[f], pt) - sqrt(2.)/2.;
446 scalar_type is_in(
const base_node& pt)
const {
448 scalar_type r = is_in_face(0, pt);
449 for (
short_type f = 1; f < 5; ++f) r = std::max(r, is_in_face(f, pt));
453 void project_into(base_node &pt)
const {
455 GMM_ASSERT1(pt.size() == 3,
"Dimensions mismatch");
456 if (pt[2] < .0) pt[2] = 0.;
458 scalar_type reldist =
gmm::vect_sp(normals_[f], pt)*sqrt(2.);
460 gmm::scale(pt, 1./reldist);
463 basic_convex_ref_->project_into(pt);
467 GMM_ASSERT1(k == 1 || k == 2,
468 "Sorry exist only in degree 1 or 2, not " << k);
470 convex<base_node>::points().resize(cvs->nb_points());
471 normals_.resize(cvs->nb_faces());
474 normals_[0] = { 0., 0., -1.};
475 normals_[1] = { 0.,-1., 1.};
476 normals_[2] = { 1., 0., 1.};
477 normals_[3] = { 0., 1., 1.};
478 normals_[4] = {-1., 0., 1.};
480 for (
size_type i = 0; i < normals_.size(); ++i)
481 gmm::scale(normals_[i], 1. / gmm::vect_norm2(normals_[i]));
484 convex<base_node>::points()[0] = base_node(-1.0, -1.0, 0.0);
485 convex<base_node>::points()[1] = base_node( 1.0, -1.0, 0.0);
486 convex<base_node>::points()[2] = base_node(-1.0, 1.0, 0.0);
487 convex<base_node>::points()[3] = base_node( 1.0, 1.0, 0.0);
488 convex<base_node>::points()[4] = base_node( 0.0, 0.0, 1.0);
490 convex<base_node>::points()[0] = base_node(-1.0, -1.0, 0.0);
491 convex<base_node>::points()[1] = base_node( 0.0, -1.0, 0.0);
492 convex<base_node>::points()[2] = base_node( 1.0, -1.0, 0.0);
493 convex<base_node>::points()[3] = base_node(-1.0, 0.0, 0.0);
494 convex<base_node>::points()[4] = base_node( 0.0, 0.0, 0.0);
495 convex<base_node>::points()[5] = base_node( 1.0, 0.0, 0.0);
496 convex<base_node>::points()[6] = base_node(-1.0, 1.0, 0.0);
497 convex<base_node>::points()[7] = base_node( 0.0, 1.0, 0.0);
498 convex<base_node>::points()[8] = base_node( 1.0, 1.0, 0.0);
499 convex<base_node>::points()[9] = base_node(-0.5, -0.5, 0.5);
500 convex<base_node>::points()[10] = base_node( 0.5, -0.5, 0.5);
501 convex<base_node>::points()[11] = base_node(-0.5, 0.5, 0.5);
502 convex<base_node>::points()[12] = base_node( 0.5, 0.5, 0.5);
503 convex<base_node>::points()[13] = base_node( 0.0, 0.0, 1.0);
505 ppoints = store_point_tab(convex<base_node>::points());
506 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
511 DAL_SIMPLE_KEY(pyramid_QK_reference_key_, dim_type);
514 dal::pstatic_stored_object_key
515 pk = std::make_shared<pyramid_QK_reference_key_>(k);
517 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
518 pconvex_ref p = std::make_shared<pyramid_QK_of_ref_>(k);
520 dal::PERMANENT_STATIC_OBJECT);
522 if (p != p1) add_dependency(p, p1);
531 class pyramid_Q2_incomplete_of_ref_ :
public convex_of_reference {
533 scalar_type is_in(
const base_node& pt)
const
534 {
return basic_convex_ref_->is_in(pt); }
535 scalar_type is_in_face(
short_type f,
const base_node& pt)
const
536 {
return basic_convex_ref_->is_in_face(f, pt); }
539 convex<base_node>::points().resize(cvs->nb_points());
540 normals_.resize(cvs->nb_faces());
543 normals_ = basic_convex_ref_->normals();
545 convex<base_node>::points()[0] = base_node(-1.0, -1.0, 0.0);
546 convex<base_node>::points()[1] = base_node( 0.0, -1.0, 0.0);
547 convex<base_node>::points()[2] = base_node( 1.0, -1.0, 0.0);
548 convex<base_node>::points()[3] = base_node(-1.0, 0.0, 0.0);
549 convex<base_node>::points()[4] = base_node( 1.0, 0.0, 0.0);
550 convex<base_node>::points()[5] = base_node(-1.0, 1.0, 0.0);
551 convex<base_node>::points()[6] = base_node( 0.0, 1.0, 0.0);
552 convex<base_node>::points()[7] = base_node( 1.0, 1.0, 0.0);
553 convex<base_node>::points()[8] = base_node(-0.5, -0.5, 0.5);
554 convex<base_node>::points()[9] = base_node( 0.5, -0.5, 0.5);
555 convex<base_node>::points()[10] = base_node(-0.5, 0.5, 0.5);
556 convex<base_node>::points()[11] = base_node( 0.5, 0.5, 0.5);
557 convex<base_node>::points()[12] = base_node( 0.0, 0.0, 1.0);
559 ppoints = store_point_tab(convex<base_node>::points());
560 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
565 DAL_SIMPLE_KEY(pyramid_Q2_incomplete_reference_key_, dim_type);
568 dal::pstatic_stored_object_key
569 pk = std::make_shared<pyramid_Q2_incomplete_reference_key_>(0);
572 return std::dynamic_pointer_cast<const convex_of_reference>(o);
574 pconvex_ref p = std::make_shared<pyramid_Q2_incomplete_of_ref_>();
576 dal::PERMANENT_STATIC_OBJECT);
578 if (p != p1) add_dependency(p, p1);
588 class prism_incomplete_P2_of_ref_ :
public convex_of_reference {
590 scalar_type is_in(
const base_node& pt)
const
591 {
return basic_convex_ref_->is_in(pt); }
592 scalar_type is_in_face(
short_type f,
const base_node& pt)
const
593 {
return basic_convex_ref_->is_in_face(f, pt); }
596 convex<base_node>::points().resize(cvs->nb_points());
597 normals_.resize(cvs->nb_faces());
600 normals_ = basic_convex_ref_->normals();
602 convex<base_node>::points()[0] = base_node(0.0, 0.0, 0.0);
603 convex<base_node>::points()[1] = base_node(0.5, 0.0, 0.0);
604 convex<base_node>::points()[2] = base_node(1.0, 0.0, 0.0);
605 convex<base_node>::points()[3] = base_node(0.0, 0.5, 0.0);
606 convex<base_node>::points()[4] = base_node(0.5, 0.5, 0.0);
607 convex<base_node>::points()[5] = base_node(0.0, 1.0, 0.0);
608 convex<base_node>::points()[6] = base_node(0.0, 0.0, 0.5);
609 convex<base_node>::points()[7] = base_node(1.0, 0.0, 0.5);
610 convex<base_node>::points()[8] = base_node(0.0, 1.0, 0.5);
611 convex<base_node>::points()[9] = base_node(0.0, 0.0, 1.0);
612 convex<base_node>::points()[10] = base_node(0.5, 0.0, 1.0);
613 convex<base_node>::points()[11] = base_node(1.0, 0.0, 1.0);
614 convex<base_node>::points()[12] = base_node(0.0, 0.5, 1.0);
615 convex<base_node>::points()[13] = base_node(0.5, 0.5, 1.0);
616 convex<base_node>::points()[14] = base_node(0.0, 1.0, 1.0);
618 ppoints = store_point_tab(convex<base_node>::points());
619 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
624 DAL_SIMPLE_KEY(prism_incomplete_P2_reference_key_, dim_type);
627 dal::pstatic_stored_object_key
628 pk = std::make_shared<prism_incomplete_P2_reference_key_>(0);
631 return std::dynamic_pointer_cast<const convex_of_reference>(o);
633 pconvex_ref p = std::make_shared<prism_incomplete_P2_of_ref_>();
635 dal::PERMANENT_STATIC_OBJECT);
637 if (p != p1) add_dependency(p, p1);
647 DAL_DOUBLE_KEY(product_ref_key_, pconvex_ref, pconvex_ref);
649 struct product_ref_ :
public convex_of_reference {
650 pconvex_ref cvr1, cvr2;
652 scalar_type is_in(
const base_node &pt)
const {
653 dim_type n1 = cvr1->structure()->dim(), n2 = cvr2->structure()->dim();
654 base_node pt1(n1), pt2(n2);
655 GMM_ASSERT1(pt.size() == cvs->dim(),
656 "product_ref_::is_in: Dimension does not match");
657 std::copy(pt.begin(), pt.begin()+n1, pt1.begin());
658 std::copy(pt.begin()+n1, pt.end(), pt2.begin());
659 return std::max(cvr1->is_in(pt1), cvr2->is_in(pt2));
662 scalar_type is_in_face(
short_type f,
const base_node &pt)
const {
665 dim_type n1 = cvr1->structure()->dim(), n2 = cvr2->structure()->dim();
666 base_node pt1(n1), pt2(n2);
667 GMM_ASSERT1(pt.size() == cvs->dim(),
"Dimensions mismatch");
668 std::copy(pt.begin(), pt.begin()+n1, pt1.begin());
669 std::copy(pt.begin()+n1, pt.end(), pt2.begin());
670 if (f < cvr1->structure()->nb_faces())
return cvr1->is_in_face(f, pt1);
671 else return cvr2->is_in_face(
short_type(f - cvr1->structure()->nb_faces()), pt2);
674 void project_into(base_node &pt)
const {
676 GMM_ASSERT1(pt.size() == cvs->dim(),
"Dimensions mismatch");
677 dim_type n1 = cvr1->structure()->dim(), n2 = cvr2->structure()->dim();
678 base_node pt1(n1), pt2(n2);
679 std::copy(pt.begin(), pt.begin()+n1, pt1.begin());
680 std::copy(pt.begin()+n1, pt.end(), pt2.begin());
681 cvr1->project_into(pt1);
682 cvr2->project_into(pt2);
683 std::copy(pt1.begin(), pt1.end(), pt.begin());
684 std::copy(pt2.begin(), pt2.end(), pt.begin()+n1);
686 basic_convex_ref_->project_into(pt);
689 product_ref_(pconvex_ref a, pconvex_ref b) :
691 convex_direct_product(*a, *b).structure(),
694 if (a->structure()->dim() < b->structure()->dim())
695 GMM_WARNING1(
"Illegal convex: swap your operands: dim(cv1)=" <<
696 int(a->structure()->dim()) <<
" < dim(cv2)=" <<
697 int(b->structure()->dim()));
699 *((convex<base_node> *)(
this)) = convex_direct_product(*a, *b);
700 normals_.resize(cvs->nb_faces());
701 base_small_vector
null(cvs->dim());
null.fill(0.0);
702 std::fill(normals_.begin(), normals_.end(),
null);
703 for (
size_type r = 0; r < cvr1->structure()->nb_faces(); r++)
704 std::copy(cvr1->normals()[r].begin(), cvr1->normals()[r].end(),
705 normals_[r].begin());
706 for (
size_type r = 0; r < cvr2->structure()->nb_faces(); r++)
707 std::copy(cvr2->normals()[r].begin(), cvr2->normals()[r].end(),
708 normals_[r+cvr1->structure()->nb_faces()].begin()
709 + cvr1->structure()->dim());
710 ppoints = store_point_tab(convex<base_node>::points());
715 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
721 dal::pstatic_stored_object_key
722 pk = std::make_shared<product_ref_key_>(a, b);
725 return std::dynamic_pointer_cast<const convex_of_reference>(o);
727 pconvex_ref p = std::make_shared<product_ref_>(a, b);
731 p->pspt(), dal::PERMANENT_STATIC_OBJECT);
733 if (p != p1) add_dependency(p, p1);
751 class equilateral_simplex_of_ref_ :
public convex_of_reference {
754 scalar_type is_in(
const base_node &pt)
const {
755 GMM_ASSERT1(pt.size() == cvs->dim(),
"Dimension does not match");
757 for (
size_type f = 0; f < normals().size(); ++f) {
758 const base_node &x0 = (f ? convex<base_node>::points()[f-1]
759 : convex<base_node>::points().back());
760 scalar_type v = gmm::vect_sp(pt-x0, normals()[f]);
761 if (f == 0) d = v;
else d = std::max(d,v);
766 scalar_type is_in_face(
short_type f,
const base_node &pt)
const {
767 GMM_ASSERT1(pt.size() == cvs->dim(),
"Dimension does not match");
768 const base_node &x0 = (f ? convex<base_node>::points()[f-1]
769 : convex<base_node>::points().back());
773 void project_into(base_node &pt)
const {
774 dim_type N = cvs->dim();
775 GMM_ASSERT1(pt.size() == N,
"Dimension does not match");
776 base_node G(N); G.fill(0.);
777 for (
const base_node &x : convex<base_node>::points())
779 gmm::scale(G, scalar_type(1)/scalar_type(N+1));
783 pt = G + r_inscr/r*(pt-G);
788 equilateral_simplex_of_ref_(
size_type N) :
792 r_inscr = scalar_type(1)/sqrt(scalar_type(2*N)*scalar_type(N+1));
795 convex<base_node>::points().resize(N+1);
796 normals_.resize(N+1);
797 base_node G(N); G.fill(0.);
799 convex<base_node>::points()[i].resize(N);
801 std::copy(prev->convex<base_node>::points()[i].begin(),
802 prev->convex<base_node>::points()[i].end(),
803 convex<base_node>::points()[i].begin());
804 convex<base_node>::points()[i][N-1] = 0.;
806 convex<base_node>::points()[i] = scalar_type(1)/scalar_type(N) * G;
807 convex<base_node>::points()[i][N-1]
808 = sqrt(1. - gmm::vect_norm2_sqr(convex<base_node>::points()[i]));
810 G += convex<base_node>::points()[i];
812 gmm::scale(G, scalar_type(1)/scalar_type(N+1));
814 normals_[f] = G - convex<base_node>::points()[f];
815 gmm::scale(normals_[f], 1/gmm::vect_norm2(normals_[f]));
817 ppoints = store_point_tab(convex<base_node>::points());
818 if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
824 dal::pstatic_stored_object_key
825 pk = std::make_shared<convex_of_reference_key>(1, nc);
827 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
828 pconvex_ref p = std::make_shared<equilateral_simplex_of_ref_>(nc);
830 dal::PERMANENT_STATIC_OBJECT);
837 class generic_dummy_ :
public convex_of_reference {
839 scalar_type is_in(
const base_node &)
const
840 { GMM_ASSERT1(
false,
"Information not available here"); }
841 scalar_type is_in_face(
short_type,
const base_node &)
const
842 { GMM_ASSERT1(
false,
"Information not available here"); }
843 void project_into(base_node &)
const
844 { GMM_ASSERT1(
false,
"Operation not available here"); }
849 convex<base_node>::points().resize(n);
852 std::fill(P.begin(), P.end(), scalar_type(1)/scalar_type(20));
853 std::fill(convex<base_node>::points().begin(), convex<base_node>::points().end(), P);
854 ppoints = store_point_tab(convex<base_node>::points());
860 dal::pstatic_stored_object_key
861 pk = std::make_shared<convex_of_reference_key>(2, nc,
short_type(n), nf);
863 if (o)
return std::dynamic_pointer_cast<const convex_of_reference>(o);
864 pconvex_ref p = std::make_shared<generic_dummy_>(nc, n, nf);
866 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.