37 GMM_ASSERT1(i <= nbpt,
"convex_structure::add_point_adaptative: "
39 if (i == nbpt) nbpt++;
41 faces[f].resize(faces[f].size() + 1);
42 (faces[f])[faces[f].size() - 1] = i;
48 std::fill(faces_struct.begin(),faces_struct.end(),
50 std::fill(faces.begin(),faces.end(), convex_ind_ct());
51 dir_points_ = convex_ind_ct();
56 (
const std::vector<short_type> &ftab)
const {
57 auto it = intersection_points.find(ftab);
58 if (it == intersection_points.end()) {
59 std::vector<size_type> cpt(nb_points(), ftab.size());
65 if (cpt[i] == 0) ind.push_back(i);
66 it = intersection_points.emplace(ftab, ind).first;
72 o <<
"convex structure of dimension " << int(cv.
dim()) <<
" with "
80 class convex_structure_key :
virtual public dal::static_stored_object_key {
86 bool compare(
const static_stored_object_key &oo)
const override{
87 const convex_structure_key &o
88 =
dynamic_cast<const convex_structure_key &
>(oo);
89 if (type < o.type)
return true;
90 if (type > o.type)
return false;
91 if (N < o.N)
return true;
92 if (N > o.N)
return false;
93 if (K < o.K)
return true;
94 if (K > o.K)
return false;
95 if (nf < o.nf)
return true;
98 bool equal(
const static_stored_object_key &oo)
const override{
99 auto &o =
dynamic_cast<const convex_structure_key &
>(oo);
100 if (type != o.type)
return false;
101 if (N != o.N)
return false;
102 if (K != o.K)
return false;
103 if (nf != o.nf)
return false;
106 convex_structure_key(
int t, dim_type NN,
short_type KK = 0,
108 : type(t), N(NN), K(KK), nf(nnf) {}
112 if (!p1 || !p2)
return p1.get() == p2.get();
113 if (p1.get() == p2.get())
return true;
114 else return *dal::key_of_stored_object(p1) == *dal::key_of_stored_object(p2);
122 return p1.get() ==
nullptr;
126 return p2 ==
nullptr;
130 return !(p1 ==
nullptr);
134 return !(p2 ==
nullptr);
141 class simplex_structure_ :
public convex_structure
144 #ifdef GETFEM_HAVE_QDLIB
149 #ifdef GETFEM_HAVE_QDLIB
151 static bool fpu_init =
false;
154 fpu_fix_start(&old_cw);
158 dal::pstatic_stored_object_key
159 pcsk = std::make_shared<convex_structure_key>(0, nc, 1);
161 if (o)
return std::dynamic_pointer_cast<const convex_structure>(o);
163 auto p = std::make_shared<simplex_structure_>();
165 p->Nc = dim_type(nc); p->nbpt =
short_type(nc+1);
167 p->faces_struct.resize(p->nbf);
168 p->faces.resize(p->nbf);
169 p->dir_points_.resize(p->Nc + 1);
170 p->auto_basic =
true;
172 p->dir_points_[i] = i;
174 p->faces[i].resize(nc);
176 (p->faces[i])[j] = (j >= i) ?
short_type(j + 1) : j;
182 dal::PERMANENT_STATIC_OBJECT);
190 struct K_simplex_structure_ :
public convex_structure {
192 K_simplex_structure_(dim_type NN,
short_type KK) {
195 faces_struct.resize(nbf);
197 dir_points_.resize(Nc+1);
199 for (
int i = 0; i < nbf; i++) {
202 faces[i].resize(faces_struct[i]->nb_points());
210 base_node c(Nc); c.fill(0.0);
211 std::vector<int> pf(Nc+1); std::fill(pf.begin(), pf.end(), 0);
213 if (KK == 0) c.fill(scalar_type(1.0) / scalar_type(Nc+1));
215 for (l = 1; l <= Nc; ++l) (faces[l])[(pf[l])++] = 0;
216 dir_points_[pd++] = 0;
221 c[l] += scalar_type(1.0) / scalar_type(KK); ++sum;
223 sum -=
size_type(floor(0.5+(c[l] * KK)));
224 c[l] = 0.0; ++l; c[l] += scalar_type(1.0) / scalar_type(KK);
227 for (l = 1; l <= Nc; ++l)
228 if (c[l-1] == scalar_type(0.0)) (faces[l])[(pf[l])++] = r;
230 (faces[0])[(pf[0])++] = r;
231 if (*(std::max_element(c.begin(), c.end())) == scalar_type(1.0))
232 dir_points_[pd++] = r;
241 dal::pstatic_stored_object_key
242 pcsk = std::make_shared<convex_structure_key>(0, nc, K);
244 if (o)
return std::dynamic_pointer_cast<const convex_structure>(o);
248 dal::PERMANENT_STATIC_OBJECT);
256 struct polygon_structure_ :
public convex_structure {
264 dal::pstatic_stored_object_key
265 pcsk = std::make_shared<convex_structure_key>(1, dim_type(nbt));
267 if (o)
return std::dynamic_pointer_cast<const convex_structure>(o);
269 auto p = std::make_shared<polygon_structure_>();
271 p->Nc = 2; p->nbpt = nbt; p->nbf = nbt;
272 p->auto_basic =
true;
273 p->faces_struct.resize(p->nbf);
274 p->faces = std::vector< std::vector<short_type> >(p->nbf);
275 p->dir_points_ = std::vector<short_type>(p->Nc + 1);
277 for (
int i = 0; i < p->nbf; i++) {
279 p->faces[i] = std::vector<short_type>(2);
280 for (
int j = 0; j < 2; j++)
284 p->dir_points_[0] = 0;
285 p->dir_points_[1] = 1;
289 dal::PERMANENT_STATIC_OBJECT);
299 struct cv_pr_structure_ :
public convex_structure {
301 Nc = dim_type(cv1->dim() + cv2->dim());
302 prod_a = cv1; prod_b = cv2;
303 nbpt =
short_type(cv1->nb_points() * cv2->nb_points());
304 nbf =
short_type(cv1->nb_faces() + cv2->nb_faces());
310 faces_struct.resize(nbf);
311 faces = std::vector< std::vector<short_type> >(nbf);
313 if (cv1->ind_dir_points().size() && cv2->ind_dir_points().size()) {
314 dir_points_ = std::vector<short_type>(Nc + 1);
316 for (
int i = 0; i <= cv1->dim(); i++)
319 + cv2->ind_dir_points()[0] * cv1->nb_points());
320 for (
int i = 1; i <= cv2->dim(); i++)
321 dir_points_[cv1->dim()+i]
323 + cv2->ind_dir_points()[i] * cv1->nb_points());
326 for (
short_type i = 0; i < cv1->nb_faces(); i++) {
327 if (cv1->nb_points_of_face(i) == 1)
328 faces_struct[i] = cv2;
335 faces[i] = std::vector<short_type>(cv1->nb_points_of_face(i)
338 for (
short_type j = 0; j < cv1->nb_points_of_face(i); j++)
339 for (
short_type l = 0; l < cv2->nb_points(); l++) {
340 (faces[i])[l*cv1->nb_points_of_face(i)+j]
342 + l * cv1->nb_points());
345 for (
short_type i = 0; i < cv2->nb_faces(); i++) {
347 if (cv2->nb_points_of_face(i) == 1)
348 faces_struct[i+k] = cv1;
355 faces[i+k] = std::vector<short_type>(cv2->nb_points_of_face(i)
358 for (
short_type j = 0; j < cv2->nb_points_of_face(i); j++)
359 for (
short_type l = 0; l < cv1->nb_points(); l++) {
360 (faces[i+k])[j*cv1->nb_points()+l]
361 =
short_type(l + (cv2->ind_points_of_face(i))[j]
371 dal::pstatic_stored_object_key pcsk = std::make_shared<cv_pr_key_>(a, b);
373 if (o)
return std::dynamic_pointer_cast<const convex_structure>(o);
376 for (
size_type k = 0; k < p->nb_faces(); ++k) {
377 if (exists_stored_object(p->faces_structure()[k]))
390 { DAL_STORED_OBJECT_DEBUG_CREATED(
this,
"parallelepiped structure"); }
392 { DAL_STORED_OBJECT_DEBUG_DESTROYED(
this,
"parallelepiped structure"); }
395 DAL_DOUBLE_KEY(parallelepiped_key_, dim_type, dim_type);
401 dal::pstatic_stored_object_key
402 pcsk = std::make_shared<parallelepiped_key_>(nc, k);
406 return ((std::dynamic_pointer_cast<const parallelepiped_>(o))->p);
408 auto p = std::make_shared<parallelepiped_>();
412 dal::PERMANENT_STATIC_OBJECT);
422 struct Q2_incomplete_structure_ :
public convex_structure {
426 DAL_SIMPLE_KEY(Q2_incomplete_structure_key_, dim_type);
429 GMM_ASSERT1(nc == 2 || nc == 3,
"Bad parameter, expected value 2 or 3");
430 dal::pstatic_stored_object_key
431 pcsk = std::make_shared<Q2_incomplete_structure_key_>(nc);
433 if (o)
return std::dynamic_pointer_cast<const convex_structure>(o);
435 auto p = std::make_shared<Q2_incomplete_structure_>();
438 p->nbpt = (nc == 2) ? 8 : 20;
439 p->nbf = (nc == 2) ? 4 : 6;
441 p->faces_struct.resize(p->nbf);
442 p->faces = std::vector< std::vector<short_type> >(p->nbf);
443 p->dir_points_ = std::vector<short_type>(p->Nc + 1);
451 p->faces[0] = {2,4,7};
452 p->faces[1] = {0,3,5};
453 p->faces[2] = {5,6,7};
454 p->faces[3] = {0,1,2};
456 p->dir_points_[0] = 0;
457 p->dir_points_[1] = 2;
458 p->dir_points_[2] = 5;
471 p->faces[0] = {2,4,7,9,11,14,16,19};
472 p->faces[1] = {0,3,5,8,10,12,15,17};
474 p->faces[2] = {5,6,7,10,11,17,18,19};
475 p->faces[3] = {0,1,2,8,9,12,13,14};
477 p->faces[4] = {12,13,14,15,16,17,18,19};
478 p->faces[5] = {0,1,2,3,4,5,6,7};
480 p->dir_points_[0] = 0;
481 p->dir_points_[1] = 2;
482 p->dir_points_[2] = 5;
483 p->dir_points_[3] = 12;
486 for (
int i = 0; i < p->nbf; i++) {
492 dal::PERMANENT_STATIC_OBJECT);
502 struct pyramid_QK_structure_ :
public convex_structure {
506 DAL_SIMPLE_KEY(pyramid_QK_structure_key_, dim_type);
509 GMM_ASSERT1(k == 1 || k == 2,
"Sorry, pyramidal elements implemented "
510 "only for degree one or two.");
511 dal::pstatic_stored_object_key
512 pcsk = std::make_shared<pyramid_QK_structure_key_>(k);
515 return std::dynamic_pointer_cast<const convex_structure>(o);
517 auto p = std::make_shared<pyramid_QK_structure_>();
521 p->dir_points_ = std::vector<short_type>(p->Nc + 1);
526 p->auto_basic =
true;
535 p->faces_struct.resize(p->nbf);
536 p->faces = std::vector< std::vector<short_type> >(p->nbf);
537 p->faces[0] = {0,1,2,3};
538 p->faces[1] = {0,1,4};
539 p->faces[2] = {1,3,4};
540 p->faces[3] = {3,2,4};
541 p->faces[4] = {2,0,4};
543 p->dir_points_[0] = 0;
544 p->dir_points_[1] = 1;
545 p->dir_points_[2] = 2;
546 p->dir_points_[3] = 4;
549 for (
int i = 1; i < p->nbf; i++)
554 dal::PERMANENT_STATIC_OBJECT);
571 p->faces_struct.resize(p->nbf);
572 p->faces = std::vector< std::vector<short_type> >(p->nbf);
573 p->faces[0] = {0,1,2,3,4,5,6,7,8};
574 p->faces[1] = {0,1,2,9,10,13};
575 p->faces[2] = {2,5,8,10,12,13};
576 p->faces[3] = {8,7,6,12,11,13};
577 p->faces[4] = {6,3,0,11,9,13};
579 p->dir_points_[0] = 0;
580 p->dir_points_[1] = 2;
581 p->dir_points_[2] = 6;
582 p->dir_points_[3] = 13;
585 for (
int i = 1; i < p->nbf; i++)
590 dal::PERMANENT_STATIC_OBJECT);
599 struct pyramid_Q2_incomplete_structure_ :
public convex_structure {
603 DAL_SIMPLE_KEY(pyramid_Q2_incomplete_structure_key_, dim_type);
606 dal::pstatic_stored_object_key
607 pcsk = std::make_shared<pyramid_Q2_incomplete_structure_key_>(0);
610 return std::dynamic_pointer_cast<const convex_structure>(o);
612 auto p = std::make_shared<pyramid_Q2_incomplete_structure_>();
616 p->dir_points_ = std::vector<short_type>(p->Nc + 1);
632 p->faces_struct.resize(p->nbf);
633 p->faces = std::vector< std::vector<short_type> >(p->nbf);
634 p->faces[0] = {0,1,2,3,4,5,6,7};
635 p->faces[1] = {0,1,2,8,9,12};
636 p->faces[2] = {2,4,7,9,11,12};
637 p->faces[3] = {7,6,5,11,10,12};
638 p->faces[4] = {5,3,0,10,8,12};
640 p->dir_points_[0] = 0;
641 p->dir_points_[1] = 2;
642 p->dir_points_[2] = 5;
643 p->dir_points_[3] = 12;
646 for (
int i = 1; i < p->nbf; i++)
651 dal::PERMANENT_STATIC_OBJECT);
659 struct prism_incomplete_P2_structure_ :
public convex_structure {
663 DAL_SIMPLE_KEY(prism_incomplete_P2_structure_key_, dim_type);
666 dal::pstatic_stored_object_key
667 pcsk = std::make_shared<prism_incomplete_P2_structure_key_>(0);
670 return std::dynamic_pointer_cast<const convex_structure>(o);
672 auto p = std::make_shared<prism_incomplete_P2_structure_>();
676 p->dir_points_ = std::vector<short_type>(p->Nc + 1);
692 p->faces_struct.resize(p->nbf);
693 p->faces = std::vector< std::vector<short_type> >(p->nbf);
694 p->faces[0] = {2,4,5,7,8,11,13,14};
695 p->faces[1] = {0,3,5,6,8,9,12,14};
696 p->faces[2] = {0,1,2,6,7,9,10,11};
697 p->faces[3] = {9,10,11,12,13,14};
698 p->faces[4] = {0,1,2,3,4,5};
700 p->dir_points_[0] = 0;
701 p->dir_points_[1] = 2;
702 p->dir_points_[2] = 5;
703 p->dir_points_[3] = 9;
705 for (
int i = 0; i < 3; i++)
712 dal::PERMANENT_STATIC_OBJECT);
720 struct dummy_structure_ :
public convex_structure {
727 dal::pstatic_stored_object_key
728 pcsk = std::make_shared<convex_structure_key>(2, nc,
short_type(n), nf);
730 if (o)
return std::dynamic_pointer_cast<const convex_structure>(o);
731 auto p = std::make_shared<dummy_structure_>();
733 p->Nc = nc; p->nbpt =
short_type(n); p->nbf = 0;
734 p->faces_struct.resize(nf);
740 p->faces[j].resize(n);
741 for (
short_type k = 0; k < n; ++k) p->faces[j][k] = k;
743 p->dir_points_.resize(0);
744 p->auto_basic =
true;
750 dal::PERMANENT_STATIC_OBJECT);