GetFEM  5.5
bgeot_convex_structure.cc
1 /*===========================================================================
2 
3  Copyright (C) 1999-2026 Yves Renard
4 
5  This file is a part of GetFEM
6 
7  GetFEM is free software; you can redistribute it and/or modify it
8  under the terms of the GNU Lesser General Public License as published
9  by the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version along with the GCC Runtime Library
11  Exception either version 3.1 or (at your option) any later version.
12  This program is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15  License and GCC Runtime Library Exception for more details.
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program. If not, see https://www.gnu.org/licenses/.
18 
19 ===========================================================================*/
20 
21 
22 #include "getfem/dal_singleton.h"
26 
27 namespace bgeot {
28 
29  /* ******************************************************************** */
30  /* */
31  /* class convex_structure */
32  /* */
33  /* ******************************************************************** */
34 
35  void convex_structure::add_point_adaptative(short_type i, short_type f) {
36  GMM_ASSERT1(i <= nbpt, "convex_structure::add_point_adaptative: "
37  "internal error");
38  if (i == nbpt) nbpt++;
39  if (f != short_type(-1)) {
40  faces[f].resize(faces[f].size() + 1);
41  (faces[f])[faces[f].size() - 1] = i;
42  }
43  }
44 
45  void convex_structure::init_for_adaptative(pconvex_structure cvs) {
46  *this = *(basic_structure(cvs));
47  std::fill(faces_struct.begin(),faces_struct.end(),
49  std::fill(faces.begin(),faces.end(), convex_ind_ct());
50  dir_points_ = convex_ind_ct();
51  nbpt = 0;
52  }
53 
55  (const std::vector<short_type> &ftab) const {
56  auto it = intersection_points.find(ftab);
57  if (it == intersection_points.end()) {
58  std::vector<size_type> cpt(nb_points(), ftab.size());
59  for (short_type iff : ftab)
60  for (short_type i : ind_points_of_face(iff))
61  cpt[i]--;
62  convex_ind_ct ind;
63  for (short_type i = 0; i < nb_points(); ++i)
64  if (cpt[i] == 0) ind.push_back(i);
65  it = intersection_points.emplace(ftab, ind).first;
66  }
67  return it->second;
68  }
69 
70  std::ostream &operator <<(std::ostream &o, const convex_structure &cv) {
71  o << "convex structure of dimension " << int(cv.dim()) << " with "
72  << cv.nb_points() << " points and " << cv.nb_faces() << " faces "
73  << endl;
74  // a completer au besoin
75  return o;
76  }
77 
78  // Key type for static storing
79  class convex_structure_key : virtual public dal::static_stored_object_key {
80  int type; // 0 = simplex structure degree K
81  // 1 = polygon (N = nb of points, K = 0)
82  // 2 = dummy (N = dimension, K = nbpt)
83  dim_type N; short_type K; short_type nf;
84  public :
85  bool compare(const static_stored_object_key &oo) const override{
86  const convex_structure_key &o
87  = dynamic_cast<const convex_structure_key &>(oo);
88  if (type < o.type) return true;
89  if (type > o.type) return false;
90  if (N < o.N) return true;
91  if (N > o.N) return false;
92  if (K < o.K) return true;
93  if (K > o.K) return false;
94  if (nf < o.nf) return true;
95  return false;
96  }
97  bool equal(const static_stored_object_key &oo) const override{
98  auto &o = dynamic_cast<const convex_structure_key &>(oo);
99  if (type != o.type) return false;
100  if (N != o.N) return false;
101  if (K != o.K) return false;
102  if (nf != o.nf) return false;
103  return true;
104  }
105  convex_structure_key(int t, dim_type NN, short_type KK = 0,
106  short_type nnf = 0)
107  : type(t), N(NN), K(KK), nf(nnf) {}
108  };
109 
110  bool operator==(const pconvex_structure &p1, const pconvex_structure &p2){
111  if (!p1 || !p2) return p1.get() == p2.get();
112  if (p1.get() == p2.get()) return true;
113  else return *dal::key_of_stored_object(p1) == *dal::key_of_stored_object(p2);
114  }
115 
116  bool operator!=(const pconvex_structure &p1, const pconvex_structure &p2){
117  return !(p1 == p2);
118  }
119 
120  bool operator==(const pconvex_structure &p1, std::nullptr_t){
121  return p1.get() == nullptr;
122  }
123 
124  bool operator==(std::nullptr_t, const pconvex_structure &p2){
125  return p2 == nullptr;
126  }
127 
128  bool operator!=(const pconvex_structure &p1, std::nullptr_t){
129  return !(p1 == nullptr);
130  }
131 
132  bool operator!=(std::nullptr_t, const pconvex_structure &p2){
133  return !(p2 == nullptr);
134  }
135 
136  /* ******************************************************************** */
137  /* simplex structures */
138  /* ******************************************************************** */
139 
140  class simplex_structure_ : public convex_structure
141  { friend pconvex_structure simplex_structure(dim_type nc); };
142 
143 #ifdef GETFEM_HAVE_QDLIB
144 # include <qd/fpu.h>
145 #endif
146 
148 #ifdef GETFEM_HAVE_QDLIB
149  /* initialisation for QD on intel CPUs */
150  static bool fpu_init = false;
151  if (!fpu_init) {
152  unsigned int old_cw;
153  fpu_fix_start(&old_cw);
154  fpu_init = true;
155  }
156 #endif
157  dal::pstatic_stored_object_key
158  pcsk = std::make_shared<convex_structure_key>(0, nc, 1);
159  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
160  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
161 
162  auto p = std::make_shared<simplex_structure_>();
164  p->Nc = dim_type(nc); p->nbpt = short_type(nc+1);
165  p->nbf = short_type(nc ? nc+1 : 0);
166  p->faces_struct.resize(p->nbf);
167  p->faces.resize(p->nbf);
168  p->dir_points_.resize(p->Nc + 1);
169  p->auto_basic = true;
170  for (short_type i = 0; i < p->nbf; i++) {
171  p->dir_points_[i] = i;
172  p->faces_struct[i] = simplex_structure(dim_type(nc-1));
173  p->faces[i].resize(nc);
174  for (short_type j = 0; j < nc; j++)
175  (p->faces[i])[j] = (j >= i) ? short_type(j + 1) : j;
176  }
177  if (nc == 0)
178  dal::add_stored_object(pcsk, pcvs, dal::PERMANENT_STATIC_OBJECT);
179  else
180  dal::add_stored_object(pcsk, pcvs, simplex_structure(dim_type(nc-1)),
181  dal::PERMANENT_STATIC_OBJECT);
182  return pcvs;
183  }
184 
185  /* ******************************************************************** */
186  /* K-simplex structures */
187  /* ******************************************************************** */
188 
189  struct K_simplex_structure_ : public convex_structure {
190 
191  K_simplex_structure_(dim_type NN, short_type KK) {
192  Nc = NN; nbpt = short_type(alpha(Nc, KK)); nbf = short_type(Nc+1);
193  basic_pcvs = simplex_structure(NN);
194  faces_struct.resize(nbf);
195  faces.resize(nbf);
196  dir_points_.resize(Nc+1);
197 
198  if (KK > 0)
199  for (int i = 0; i < nbf; i++) {
200  faces_struct[i] = simplex_structure(dim_type(Nc-1), KK);
201  faces[i].resize(faces_struct[i]->nb_points());
202  }
203  else
204  for (int i = 0; i < nbf; i++) {
205  faces_struct[i] = pconvex_structure();
206  faces[i].resize(0);
207  }
208 
209  base_node c(Nc);
210  c.fill(0.0);
211  std::vector<int> pf(Nc+1,0);
212  size_type l, sum = 0, pd = 0;
213  if (KK == 0)
214  c.fill(scalar_type(1.0) / scalar_type(Nc+1));
215  else {
216  for (l = 1; l <= Nc; ++l)
217  (faces[l])[(pf[l])++] = 0;
218  dir_points_[pd++] = 0;
219 
220  for (short_type r = 1; r < nbpt; ++r) {
221  l = 0;
222  c[l] += scalar_type(1) / scalar_type(KK);
223  ++sum;
224  while (sum > KK) {
225  sum -= size_type(floor(0.5+(c[l] * KK)));
226  c[l] = 0.0; ++l;
227  c[l] += scalar_type(1) / scalar_type(KK);
228  ++sum;
229  }
230  for (l = 1; l <= Nc; ++l)
231  if (c[l-1] == scalar_type(0.0))
232  (faces[l])[(pf[l])++] = r;
233  if (sum == KK) {
234  (faces[0])[(pf[0])++] = r;
235  if (*(std::max_element(c.begin(), c.end())) == scalar_type(1.0))
236  dir_points_[pd++] = r;
237  }
238  }
239  }
240  }
241  };
242 
244  if (nc == 0) K = 1;
245  if (K == 1) return simplex_structure(nc);
246  dal::pstatic_stored_object_key
247  pcsk = std::make_shared<convex_structure_key>(0, nc, K);
248  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
249  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
250 
251  pconvex_structure p = std::make_shared<K_simplex_structure_>(nc, K);
252  dal::add_stored_object(pcsk, p, simplex_structure(dim_type(nc-1), K),
253  dal::PERMANENT_STATIC_OBJECT);
254  return p;
255  }
256 
257  /* ******************************************************************** */
258  /* polygon structures */
259  /* ******************************************************************** */
260 
261  struct polygon_structure_ : public convex_structure {
263  };
264 
266  if (nbt <= 1) return simplex_structure(0);
267  if (nbt <= 3) return simplex_structure(dim_type(nbt-1));
268 
269  dal::pstatic_stored_object_key
270  pcsk = std::make_shared<convex_structure_key>(1, dim_type(nbt));
271  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
272  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
273 
274  auto p = std::make_shared<polygon_structure_>();
275  pconvex_structure pcvs(p);
276  p->Nc = 2; p->nbpt = nbt; p->nbf = nbt;
277  p->auto_basic = true;
278  p->faces_struct.resize(p->nbf);
279  p->faces = std::vector< std::vector<short_type> >(p->nbf);
280  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
281 
282  for (int i = 0; i < p->nbf; i++) {
283  p->faces_struct[i] = simplex_structure(1);
284  p->faces[i] = std::vector<short_type>(2);
285  for (int j = 0; j < 2; j++)
286  (p->faces[i])[j] = short_type((i+j) % nbt);
287  }
288 
289  p->dir_points_[0] = 0;
290  p->dir_points_[1] = 1;
291  p->dir_points_[2] = short_type(nbt - 1);
292 
294  dal::PERMANENT_STATIC_OBJECT);
295  return pcvs;
296  }
297 
298  /* ******************************************************************** */
299  /* Direct product of convex structures */
300  /* ******************************************************************** */
301 
302  DAL_DOUBLE_KEY(cv_pr_key_, pconvex_structure, pconvex_structure);
303 
304  struct cv_pr_structure_ : public convex_structure {
305  cv_pr_structure_(pconvex_structure cv1, pconvex_structure cv2) {
306  Nc = dim_type(cv1->dim() + cv2->dim());
307  prod_a = cv1; prod_b = cv2;
308  nbpt = short_type(cv1->nb_points() * cv2->nb_points());
309  nbf = short_type(cv1->nb_faces() + cv2->nb_faces());
310  if (basic_structure(cv1) != cv1 || basic_structure(cv2) != cv2)
311  basic_pcvs = convex_product_structure(basic_structure(cv1),
312  basic_structure(cv2));
313  else
314  auto_basic = true;
315  faces_struct.resize(nbf);
316  faces = std::vector< std::vector<short_type> >(nbf);
317 
318  if (cv1->ind_dir_points().size() && cv2->ind_dir_points().size()) {
319  dir_points_ = std::vector<short_type>(Nc + 1);
320 
321  for (int i = 0; i <= cv1->dim(); i++)
322  dir_points_[i]
323  = short_type(cv1->ind_dir_points()[i]
324  + cv2->ind_dir_points()[0] * cv1->nb_points());
325  for (int i = 1; i <= cv2->dim(); i++)
326  dir_points_[cv1->dim()+i]
327  = short_type(cv1->ind_dir_points()[0]
328  + cv2->ind_dir_points()[i] * cv1->nb_points());
329  }
330 
331  for (short_type i = 0; i < cv1->nb_faces(); i++) {
332  if (cv1->nb_points_of_face(i) == 1)
333  faces_struct[i] = cv2;
334  else
335  faces_struct[i]
336  = (cv1->faces_structure()[i] == pconvex_structure()) ?
338  : convex_product_structure(cv1->faces_structure()[i], cv2);
339 
340  faces[i] = std::vector<short_type>(cv1->nb_points_of_face(i)
341  * cv2->nb_points());
342 
343  for (short_type j = 0; j < cv1->nb_points_of_face(i); j++)
344  for (short_type l = 0; l < cv2->nb_points(); l++) {
345  (faces[i])[l*cv1->nb_points_of_face(i)+j]
346  = short_type((cv1->ind_points_of_face(i))[j]
347  + l * cv1->nb_points());
348  }
349  }
350  for (short_type i = 0; i < cv2->nb_faces(); i++) {
351  short_type k = cv1->nb_faces();
352  if (cv2->nb_points_of_face(i) == 1)
353  faces_struct[i+k] = cv1;
354  else
355  faces_struct[i+k]
356  = (cv2->faces_structure()[i] == pconvex_structure()) ?
358  : convex_product_structure(cv1, cv2->faces_structure()[i]);
359 
360  faces[i+k] = std::vector<short_type>(cv2->nb_points_of_face(i)
361  * cv1->nb_points());
362 
363  for (short_type j = 0; j < cv2->nb_points_of_face(i); j++)
364  for (short_type l = 0; l < cv1->nb_points(); l++) {
365  (faces[i+k])[j*cv1->nb_points()+l]
366  = short_type(l + (cv2->ind_points_of_face(i))[j]
367  * cv1->nb_points());
368  }
369  }
370  }
371  };
372 
374  pconvex_structure b) {
375 
376  dal::pstatic_stored_object_key pcsk = std::make_shared<cv_pr_key_>(a, b);
377  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
378  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
379  pconvex_structure p = std::make_shared<cv_pr_structure_>(a, b);
380  dal::add_stored_object(pcsk, p, a, b, dal::PERMANENT_STATIC_OBJECT);
381  for (size_type k = 0; k < p->nb_faces(); ++k) {
382  if (exists_stored_object(p->faces_structure()[k]))
383  dal::add_dependency(p, p->faces_structure()[k]);
384  }
385  return p;
386  }
387 
388  /* ******************************************************************** */
389  /* parallelepiped structures. */
390  /* ******************************************************************** */
391 
392  struct parallelepiped_ : virtual public dal::static_stored_object {
394  parallelepiped_()
395  { DAL_STORED_OBJECT_DEBUG_CREATED(this, "parallelepiped structure"); }
396  ~parallelepiped_()
397  { DAL_STORED_OBJECT_DEBUG_DESTROYED(this, "parallelepiped structure"); }
398  };
399 
400  DAL_DOUBLE_KEY(parallelepiped_key_, dim_type, dim_type);
401 
402  pconvex_structure parallelepiped_structure(dim_type nc, dim_type k) {
403  if (nc <= 1)
404  return simplex_structure(nc, k);
405 
406  dal::pstatic_stored_object_key
407  pcsk = std::make_shared<parallelepiped_key_>(nc, k);
408 
409  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
410  if (o)
411  return ((std::dynamic_pointer_cast<const parallelepiped_>(o))->p);
412  else {
413  auto p = std::make_shared<parallelepiped_>();
414  p->p = convex_product_structure(parallelepiped_structure(dim_type(nc-1),k),
415  simplex_structure(1,k));
416  dal::add_stored_object(pcsk, dal::pstatic_stored_object(p), p->p,
417  dal::PERMANENT_STATIC_OBJECT);
418  return p->p;
419  }
420  }
421 
422  /* ******************************************************************** */
423  /* Incomplete Q2 structure for n=2 or 3. */
424  /* ******************************************************************** */
425  /* By Yao Koutsawa <yao.koutsawa@tudor.lu> 2012-12-10 */
426 
427  struct Q2_incomplete_structure_ : public convex_structure {
428  friend pconvex_structure Q2_incomplete_structure(dim_type nc);
429  };
430 
431  DAL_SIMPLE_KEY(Q2_incomplete_structure_key_, dim_type);
432 
434  GMM_ASSERT1(nc == 2 || nc == 3, "Bad parameter, expected value 2 or 3");
435  dal::pstatic_stored_object_key
436  pcsk = std::make_shared<Q2_incomplete_structure_key_>(nc);
437  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
438  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
439 
440  auto p = std::make_shared<Q2_incomplete_structure_>();
441  pconvex_structure pcvs(p);
442  p->Nc = nc;
443  p->nbpt = (nc == 2) ? 8 : 20;
444  p->nbf = (nc == 2) ? 4 : 6;
445  p->basic_pcvs = parallelepiped_structure(nc); // k=1
446  p->faces_struct.resize(p->nbf);
447  p->faces = std::vector< std::vector<short_type> >(p->nbf);
448  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
449 
450  if (nc == 2) {
451  // 5--6--7
452  // | |
453  // 3 4
454  // | |
455  // 0--1--2
456  p->faces[0] = {2,4,7};
457  p->faces[1] = {0,3,5};
458  p->faces[2] = {5,6,7};
459  p->faces[3] = {0,1,2};
460 
461  p->dir_points_[0] = 0;
462  p->dir_points_[1] = 2;
463  p->dir_points_[2] = 5;
464  } else {
465  // 17---18---19
466  // /| /|
467  // / 10 / 11
468  // 15 | 16 |
469  // / 5----6/---7
470  // / / / /
471  // 12---13---14 /
472  // | 3 | 4
473  // 8 / 9 /
474  // |/ |/
475  // 0----1----2
476  p->faces[0] = {2,4,7,9,11,14,16,19};
477  p->faces[1] = {0,3,5,8,10,12,15,17};
478 
479  p->faces[2] = {5,6,7,10,11,17,18,19};
480  p->faces[3] = {0,1,2,8,9,12,13,14};
481 
482  p->faces[4] = {12,13,14,15,16,17,18,19};
483  p->faces[5] = {0,1,2,3,4,5,6,7};
484 
485  p->dir_points_[0] = 0;
486  p->dir_points_[1] = 2;
487  p->dir_points_[2] = 5;
488  p->dir_points_[3] = 12;
489  }
490 
491  for (int i = 0; i < p->nbf; i++) {
492  p->faces_struct[i] = (nc == 2) ? simplex_structure(1, 2)
494  }
495 
496  dal::add_stored_object(pcsk, pcvs, parallelepiped_structure(dim_type(nc-1)),
497  dal::PERMANENT_STATIC_OBJECT);
498  return pcvs;
499  }
500 
501 
502 
503  /* ******************************************************************** */
504  /* Pyramidal 3D structure for k=1 or 2. */
505  /* ******************************************************************** */
506 
507  struct pyramid_QK_structure_ : public convex_structure {
508  friend pconvex_structure pyramid_QK_structure(dim_type k);
509  };
510 
511  DAL_SIMPLE_KEY(pyramid_QK_structure_key_, dim_type);
512 
514  GMM_ASSERT1(k == 1 || k == 2, "Sorry, pyramidal elements implemented "
515  "only for degree one or two.");
516  dal::pstatic_stored_object_key
517  pcsk = std::make_shared<pyramid_QK_structure_key_>(k);
518  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
519  if (o)
520  return std::dynamic_pointer_cast<const convex_structure>(o);
521 
522  auto p = std::make_shared<pyramid_QK_structure_>();
523  pconvex_structure pcvs(p);
524 
525  p->Nc = 3;
526  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
527 
528  if (k == 1) {
529  p->nbpt = 5;
530  p->nbf = 5;
531  p->auto_basic = true;
532  // 4
533  // /|||
534  // / || |
535  // 2-|--|-3
536  // | | | |
537  // || ||
538  // || ||
539  // 0------1
540  p->faces_struct.resize(p->nbf);
541  p->faces = std::vector< std::vector<short_type> >(p->nbf);
542  p->faces[0] = {0,1,2,3};
543  p->faces[1] = {0,1,4};
544  p->faces[2] = {1,3,4};
545  p->faces[3] = {3,2,4};
546  p->faces[4] = {2,0,4};
547 
548  p->dir_points_[0] = 0;
549  p->dir_points_[1] = 1;
550  p->dir_points_[2] = 2;
551  p->dir_points_[3] = 4;
552 
553  p->faces_struct[0] = parallelepiped_structure(2);
554  for (int i = 1; i < p->nbf; i++)
555  p->faces_struct[i] = simplex_structure(2);
556 
559  dal::PERMANENT_STATIC_OBJECT);
560 
561  } else {
562  p->nbpt = 14;
563  p->nbf = 5;
564  p->basic_pcvs = pyramid_QK_structure(1);
565  // 13
566  // / |
567  // 11--12
568  // | |
569  // 9---10
570  // / |
571  // 6--7--8
572  // | |
573  // 3 4 5
574  // | |
575  // 0--1--2
576  p->faces_struct.resize(p->nbf);
577  p->faces = std::vector< std::vector<short_type> >(p->nbf);
578  p->faces[0] = {0,1,2,3,4,5,6,7,8};
579  p->faces[1] = {0,1,2,9,10,13};
580  p->faces[2] = {2,5,8,10,12,13};
581  p->faces[3] = {8,7,6,12,11,13};
582  p->faces[4] = {6,3,0,11,9,13};
583 
584  p->dir_points_[0] = 0;
585  p->dir_points_[1] = 2;
586  p->dir_points_[2] = 6;
587  p->dir_points_[3] = 13;
588 
589  p->faces_struct[0] = parallelepiped_structure(2, 2);
590  for (int i = 1; i < p->nbf; i++)
591  p->faces_struct[i] = simplex_structure(2, 2);
592 
594  simplex_structure(2, 2),
595  dal::PERMANENT_STATIC_OBJECT);
596  }
597  return pcvs;
598  }
599 
600  /* ******************************************************************** */
601  /* Incomplete quadratic pyramidal 3D structure. */
602  /* ******************************************************************** */
603 
604  struct pyramid_Q2_incomplete_structure_ : public convex_structure {
606  };
607 
608  DAL_SIMPLE_KEY(pyramid_Q2_incomplete_structure_key_, dim_type);
609 
611  dal::pstatic_stored_object_key
612  pcsk = std::make_shared<pyramid_Q2_incomplete_structure_key_>(0);
613  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
614  if (o)
615  return std::dynamic_pointer_cast<const convex_structure>(o);
616 
617  auto p = std::make_shared<pyramid_Q2_incomplete_structure_>();
618  pconvex_structure pcvs(p);
619 
620  p->Nc = 3;
621  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
622 
623  p->nbpt = 13;
624  p->nbf = 5;
625  p->basic_pcvs = pyramid_QK_structure(1);
626  // 12
627  // / |
628  // 10--11
629  // | |
630  // 8---9
631  // / |
632  // 5--6--7
633  // | |
634  // 3 4
635  // | |
636  // 0--1--2
637  p->faces_struct.resize(p->nbf);
638  p->faces = std::vector< std::vector<short_type> >(p->nbf);
639  p->faces[0] = {0,1,2,3,4,5,6,7};
640  p->faces[1] = {0,1,2,8,9,12};
641  p->faces[2] = {2,4,7,9,11,12};
642  p->faces[3] = {7,6,5,11,10,12};
643  p->faces[4] = {5,3,0,10,8,12};
644 
645  p->dir_points_[0] = 0;
646  p->dir_points_[1] = 2;
647  p->dir_points_[2] = 5;
648  p->dir_points_[3] = 12;
649 
650  p->faces_struct[0] = Q2_incomplete_structure(2);
651  for (int i = 1; i < p->nbf; i++)
652  p->faces_struct[i] = simplex_structure(2, 2);
653 
655  simplex_structure(2, 2),
656  dal::PERMANENT_STATIC_OBJECT);
657  return pcvs;
658  }
659 
660  /* ******************************************************************** */
661  /* Incomplete quadratic triangular prism 3D structure. */
662  /* ******************************************************************** */
663 
664  struct prism_incomplete_P2_structure_ : public convex_structure {
666  };
667 
668  DAL_SIMPLE_KEY(prism_incomplete_P2_structure_key_, dim_type);
669 
671  dal::pstatic_stored_object_key
672  pcsk = std::make_shared<prism_incomplete_P2_structure_key_>(0);
673  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
674  if (o)
675  return std::dynamic_pointer_cast<const convex_structure>(o);
676 
677  auto p = std::make_shared<prism_incomplete_P2_structure_>();
678  pconvex_structure pcvs(p);
679 
680  p->Nc = 3;
681  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
682 
683  p->nbpt = 15;
684  p->nbf = 5;
685  p->basic_pcvs = prism_P1_structure(3);
686  // 14
687  // /|`
688  // 12 | 13
689  // / 8 `
690  // 9--10--11
691  // | | |
692  // | 5 |
693  // 6 / ` 7
694  // | 3 4 |
695  // |/ `|
696  // 0---1---2
697  p->faces_struct.resize(p->nbf);
698  p->faces = std::vector< std::vector<short_type> >(p->nbf);
699  p->faces[0] = {2,4,5,7,8,11,13,14};
700  p->faces[1] = {0,3,5,6,8,9,12,14};
701  p->faces[2] = {0,1,2,6,7,9,10,11};
702  p->faces[3] = {9,10,11,12,13,14};
703  p->faces[4] = {0,1,2,3,4,5};
704 
705  p->dir_points_[0] = 0;
706  p->dir_points_[1] = 2;
707  p->dir_points_[2] = 5;
708  p->dir_points_[3] = 9;
709 
710  for (int i = 0; i < 3; i++)
711  p->faces_struct[i] = Q2_incomplete_structure(2);
712  p->faces_struct[3] = simplex_structure(2, 2);
713  p->faces_struct[4] = simplex_structure(2, 2);
714 
715  dal::add_stored_object(pcsk, pcvs, simplex_structure(2, 2),
717  dal::PERMANENT_STATIC_OBJECT);
718  return pcvs;
719  }
720 
721  /* ******************************************************************** */
722  /* Generic dummy convex with n global nodes. */
723  /* ******************************************************************** */
724 
725  struct dummy_structure_ : public convex_structure {
727  short_type);
728  };
729 
731  short_type nf) {
732  dal::pstatic_stored_object_key
733  pcsk = std::make_shared<convex_structure_key>(2, nc, short_type(n), nf);
734  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
735  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
736  auto p = std::make_shared<dummy_structure_>();
737  pconvex_structure pcvs(p);
738  p->Nc = nc; p->nbpt = short_type(n); p->nbf = 0;
739  p->faces_struct.resize(nf);
740  p->faces.resize(nf);
741  for (short_type j = 0; j < nf; ++j) {
742  if (nc == 0)
743  p->faces_struct[j] = simplex_structure(0);
744  else p->faces_struct[j] = generic_dummy_structure(dim_type(nc-1), n, nc);
745  p->faces[j].resize(n);
746  for (short_type k = 0; k < n; ++k) p->faces[j][k] = k;
747  }
748  p->dir_points_.resize(0);
749  p->auto_basic = true;
750  if (nc == 0)
751  dal::add_stored_object(pcsk, pcvs, dal::PERMANENT_STATIC_OBJECT);
752  else
753  dal::add_stored_object(pcsk, pcvs,
754  generic_dummy_structure(dim_type(nc-1), n, nc),
755  dal::PERMANENT_STATIC_OBJECT);
756  return pcvs;
757  }
758 
759 } /* end of namespace bgeot. */
convenient initialization of vectors via overload of "operator,".
Definition of convex structures.
Structure of a convex.
const convex_ind_ct & ind_points_of_face(short_type i) const
Give an array of the indexes of the vertices of a face.
dim_type dim() const
Dimension of the convex.
const convex_ind_ct & ind_common_points_of_faces(const std::vector< short_type > &ftab) const
Give an array of the indexes of the vertices at the intersection of a set of faces.
friend pconvex_structure basic_structure(pconvex_structure cv)
Original structure (if concerned)
short_type nb_points() const
Number of vertices.
short_type nb_faces() const
Number of faces.
base class for static stored objects
A simple singleton implementation.
Stores interdependent getfem objects.
Basic Geometric Tools.
pconvex_structure prism_incomplete_P2_structure()
Give a pointer on the 3D quadratic incomplete prism structure.
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
Definition: bgeot_config.h:72
pconvex_structure pyramid_QK_structure(dim_type k)
Give a pointer on the 3D pyramid structure for a degree k = 1 or 2.
std::ostream & operator<<(std::ostream &o, const convex_structure &cv)
Print the details of the convex structure cvs to the output stream o.
std::shared_ptr< const convex_structure > pconvex_structure
Pointer on a convex structure description.
pconvex_structure parallelepiped_structure(dim_type nc, dim_type k)
Give a pointer on the structures of a parallelepiped of dimension d.
pconvex_structure generic_dummy_structure(dim_type nc, size_type n, short_type nf)
Generic convex with n global nodes.
bool operator==(const pconvex_structure &p1, const pconvex_structure &p2)
Stored objects must be compared by keys, because there is a possibility that they are duplicated in s...
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_structure prism_P1_structure(dim_type nc)
Give a pointer on the structures of a prism of dimension d.
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
Definition: bgeot_poly.h:48
pconvex_structure polygon_structure(short_type nbt)
Give a pointer on the structures of a polygon with n vertex.
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)
size_type alpha(short_type n, short_type d)
Return the value of which is the number of monomials of a polynomial of variables and degree .
Definition: bgeot_poly.cc:46
void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o, permanence perm)
Add an object with two optional dependencies.
void add_dependency(pstatic_stored_object o1, pstatic_stored_object o2)
Add a dependency, object o1 will depend on object o2.
pstatic_stored_object search_stored_object(pstatic_stored_object_key k)
Gives a pointer to an object from a key pointer.