GetFEM  5.4.3
bgeot_convex_structure.cc
1 /*===========================================================================
2 
3  Copyright (C) 1999-2020 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, write to the Free Software Foundation,
18  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20 ===========================================================================*/
21 
22 
23 #include "getfem/dal_singleton.h"
27 
28 namespace bgeot {
29 
30  /* ******************************************************************** */
31  /* */
32  /* class convex_structure */
33  /* */
34  /* ******************************************************************** */
35 
36  void convex_structure::add_point_adaptative(short_type i, short_type f) {
37  GMM_ASSERT1(i <= nbpt, "convex_structure::add_point_adaptative: "
38  "internal error");
39  if (i == nbpt) nbpt++;
40  if (f != short_type(-1)) {
41  faces[f].resize(faces[f].size() + 1);
42  (faces[f])[faces[f].size() - 1] = i;
43  }
44  }
45 
46  void convex_structure::init_for_adaptative(pconvex_structure cvs) {
47  *this = *(basic_structure(cvs));
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();
52  nbpt = 0;
53  }
54 
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());
60  for (short_type iff : ftab)
61  for (short_type i : ind_points_of_face(iff))
62  cpt[i]--;
63  convex_ind_ct ind;
64  for (short_type i = 0; i < nb_points(); ++i)
65  if (cpt[i] == 0) ind.push_back(i);
66  it = intersection_points.emplace(ftab, ind).first;
67  }
68  return it->second;
69  }
70 
71  std::ostream &operator <<(std::ostream &o, const convex_structure &cv) {
72  o << "convex structure of dimension " << int(cv.dim()) << " with "
73  << cv.nb_points() << " points and " << cv.nb_faces() << " faces "
74  << endl;
75  // a completer au besoin
76  return o;
77  }
78 
79  // Key type for static storing
80  class convex_structure_key : virtual public dal::static_stored_object_key {
81  int type; // 0 = simplex structure degree K
82  // 1 = polygon (N = nb of points, K = 0)
83  // 2 = dummy (N = dimension, K = nbpt)
84  dim_type N; short_type K; short_type nf;
85  public :
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;
96  return false;
97  }
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;
104  return true;
105  }
106  convex_structure_key(int t, dim_type NN, short_type KK = 0,
107  short_type nnf = 0)
108  : type(t), N(NN), K(KK), nf(nnf) {}
109  };
110 
111  bool operator==(const pconvex_structure &p1, const pconvex_structure &p2){
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);
115  }
116 
117  bool operator!=(const pconvex_structure &p1, const pconvex_structure &p2){
118  return !(p1 == p2);
119  }
120 
121  bool operator==(const pconvex_structure &p1, std::nullptr_t){
122  return p1.get() == nullptr;
123  }
124 
125  bool operator==(std::nullptr_t, const pconvex_structure &p2){
126  return p2 == nullptr;
127  }
128 
129  bool operator!=(const pconvex_structure &p1, std::nullptr_t){
130  return !(p1 == nullptr);
131  }
132 
133  bool operator!=(std::nullptr_t, const pconvex_structure &p2){
134  return !(p2 == nullptr);
135  }
136 
137  /* ******************************************************************** */
138  /* simplex structures */
139  /* ******************************************************************** */
140 
141  class simplex_structure_ : public convex_structure
142  { friend pconvex_structure simplex_structure(dim_type nc); };
143 
144 #ifdef GETFEM_HAVE_QDLIB
145 # include <qd/fpu.h>
146 #endif
147 
149 #ifdef GETFEM_HAVE_QDLIB
150  /* initialisation for QD on intel CPUs */
151  static bool fpu_init = false;
152  if (!fpu_init) {
153  unsigned int old_cw;
154  fpu_fix_start(&old_cw);
155  fpu_init = true;
156  }
157 #endif
158  dal::pstatic_stored_object_key
159  pcsk = std::make_shared<convex_structure_key>(0, nc, 1);
160  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
161  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
162 
163  auto p = std::make_shared<simplex_structure_>();
165  p->Nc = dim_type(nc); p->nbpt = short_type(nc+1);
166  p->nbf = short_type(nc ? nc+1 : 0);
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;
171  for (short_type i = 0; i < p->nbf; i++) {
172  p->dir_points_[i] = i;
173  p->faces_struct[i] = simplex_structure(dim_type(nc-1));
174  p->faces[i].resize(nc);
175  for (short_type j = 0; j < nc; j++)
176  (p->faces[i])[j] = (j >= i) ? short_type(j + 1) : j;
177  }
178  if (nc == 0)
179  dal::add_stored_object(pcsk, pcvs, dal::PERMANENT_STATIC_OBJECT);
180  else
181  dal::add_stored_object(pcsk, pcvs, simplex_structure(dim_type(nc-1)),
182  dal::PERMANENT_STATIC_OBJECT);
183  return pcvs;
184  }
185 
186  /* ******************************************************************** */
187  /* K-simplex structures */
188  /* ******************************************************************** */
189 
190  struct K_simplex_structure_ : public convex_structure {
191 
192  K_simplex_structure_(dim_type NN, short_type KK) {
193  Nc = NN; nbpt = short_type(alpha(Nc, KK)); nbf = short_type(Nc+1);
194  basic_pcvs = simplex_structure(NN);
195  faces_struct.resize(nbf);
196  faces.resize(nbf);
197  dir_points_.resize(Nc+1);
198 
199  for (int i = 0; i < nbf; i++) {
200  if (KK > 0) {
201  faces_struct[i] = simplex_structure(dim_type(Nc-1), KK);
202  faces[i].resize(faces_struct[i]->nb_points());
203  }
204  else {
205  faces_struct[i] = pconvex_structure();
206  faces[i].resize(0);
207  }
208  }
209 
210  base_node c(Nc); c.fill(0.0);
211  std::vector<int> pf(Nc+1); std::fill(pf.begin(), pf.end(), 0);
212  size_type l, sum = 0, pd = 0;
213  if (KK == 0) c.fill(scalar_type(1.0) / scalar_type(Nc+1));
214  else {
215  for (l = 1; l <= Nc; ++l) (faces[l])[(pf[l])++] = 0;
216  dir_points_[pd++] = 0;
217  }
218 
219  for (short_type r = 1; r < nbpt; ++r) {
220  l = 0;
221  c[l] += scalar_type(1.0) / scalar_type(KK); ++sum;
222  while (sum > KK) {
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);
225  ++sum;
226  }
227  for (l = 1; l <= Nc; ++l)
228  if (c[l-1] == scalar_type(0.0)) (faces[l])[(pf[l])++] = r;
229  if (sum == KK) {
230  (faces[0])[(pf[0])++] = r;
231  if (*(std::max_element(c.begin(), c.end())) == scalar_type(1.0))
232  dir_points_[pd++] = r;
233  }
234  }
235  }
236  };
237 
239  if (nc == 0) K = 1;
240  if (K == 1) return simplex_structure(nc);
241  dal::pstatic_stored_object_key
242  pcsk = std::make_shared<convex_structure_key>(0, nc, K);
243  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
244  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
245 
246  pconvex_structure p = std::make_shared<K_simplex_structure_>(nc, K);
247  dal::add_stored_object(pcsk, p, simplex_structure(dim_type(nc-1), K),
248  dal::PERMANENT_STATIC_OBJECT);
249  return p;
250  }
251 
252  /* ******************************************************************** */
253  /* polygon structures */
254  /* ******************************************************************** */
255 
256  struct polygon_structure_ : public convex_structure {
258  };
259 
261  if (nbt <= 1) return simplex_structure(0);
262  if (nbt <= 3) return simplex_structure(dim_type(nbt-1));
263 
264  dal::pstatic_stored_object_key
265  pcsk = std::make_shared<convex_structure_key>(1, dim_type(nbt));
266  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
267  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
268 
269  auto p = std::make_shared<polygon_structure_>();
270  pconvex_structure pcvs(p);
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);
276 
277  for (int i = 0; i < p->nbf; i++) {
278  p->faces_struct[i] = simplex_structure(1);
279  p->faces[i] = std::vector<short_type>(2);
280  for (int j = 0; j < 2; j++)
281  (p->faces[i])[j] = short_type((i+j) % nbt);
282  }
283 
284  p->dir_points_[0] = 0;
285  p->dir_points_[1] = 1;
286  p->dir_points_[2] = short_type(nbt - 1);
287 
289  dal::PERMANENT_STATIC_OBJECT);
290  return pcvs;
291  }
292 
293  /* ******************************************************************** */
294  /* Direct product of convex structures */
295  /* ******************************************************************** */
296 
297  DAL_DOUBLE_KEY(cv_pr_key_, pconvex_structure, pconvex_structure);
298 
299  struct cv_pr_structure_ : public convex_structure {
300  cv_pr_structure_(pconvex_structure cv1, pconvex_structure cv2) {
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());
305  if (basic_structure(cv1) != cv1 || basic_structure(cv2) != cv2)
306  basic_pcvs = convex_product_structure(basic_structure(cv1),
307  basic_structure(cv2));
308  else
309  auto_basic = true;
310  faces_struct.resize(nbf);
311  faces = std::vector< std::vector<short_type> >(nbf);
312 
313  if (cv1->ind_dir_points().size() && cv2->ind_dir_points().size()) {
314  dir_points_ = std::vector<short_type>(Nc + 1);
315 
316  for (int i = 0; i <= cv1->dim(); i++)
317  dir_points_[i]
318  = short_type(cv1->ind_dir_points()[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]
322  = short_type(cv1->ind_dir_points()[0]
323  + cv2->ind_dir_points()[i] * cv1->nb_points());
324  }
325 
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;
329  else
330  faces_struct[i]
331  = (cv1->faces_structure()[i] == pconvex_structure()) ?
333  : convex_product_structure(cv1->faces_structure()[i], cv2);
334 
335  faces[i] = std::vector<short_type>(cv1->nb_points_of_face(i)
336  * cv2->nb_points());
337 
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]
341  = short_type((cv1->ind_points_of_face(i))[j]
342  + l * cv1->nb_points());
343  }
344  }
345  for (short_type i = 0; i < cv2->nb_faces(); i++) {
346  short_type k = cv1->nb_faces();
347  if (cv2->nb_points_of_face(i) == 1)
348  faces_struct[i+k] = cv1;
349  else
350  faces_struct[i+k]
351  = (cv2->faces_structure()[i] == pconvex_structure()) ?
353  : convex_product_structure(cv1, cv2->faces_structure()[i]);
354 
355  faces[i+k] = std::vector<short_type>(cv2->nb_points_of_face(i)
356  * cv1->nb_points());
357 
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]
362  * cv1->nb_points());
363  }
364  }
365  }
366  };
367 
369  pconvex_structure b) {
370 
371  dal::pstatic_stored_object_key pcsk = std::make_shared<cv_pr_key_>(a, b);
372  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
373  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
374  pconvex_structure p = std::make_shared<cv_pr_structure_>(a, b);
375  dal::add_stored_object(pcsk, p, a, b, dal::PERMANENT_STATIC_OBJECT);
376  for (size_type k = 0; k < p->nb_faces(); ++k) {
377  if (exists_stored_object(p->faces_structure()[k]))
378  dal::add_dependency(p, p->faces_structure()[k]);
379  }
380  return p;
381  }
382 
383  /* ******************************************************************** */
384  /* parallelepiped structures. */
385  /* ******************************************************************** */
386 
387  struct parallelepiped_ : virtual public dal::static_stored_object {
389  parallelepiped_()
390  { DAL_STORED_OBJECT_DEBUG_CREATED(this, "parallelepiped structure"); }
391  ~parallelepiped_()
392  { DAL_STORED_OBJECT_DEBUG_DESTROYED(this, "parallelepiped structure"); }
393  };
394 
395  DAL_DOUBLE_KEY(parallelepiped_key_, dim_type, dim_type);
396 
397  pconvex_structure parallelepiped_structure(dim_type nc, dim_type k) {
398  if (nc <= 1)
399  return simplex_structure(nc, k);
400 
401  dal::pstatic_stored_object_key
402  pcsk = std::make_shared<parallelepiped_key_>(nc, k);
403 
404  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
405  if (o)
406  return ((std::dynamic_pointer_cast<const parallelepiped_>(o))->p);
407  else {
408  auto p = std::make_shared<parallelepiped_>();
409  p->p = convex_product_structure(parallelepiped_structure(dim_type(nc-1),k),
410  simplex_structure(1,k));
411  dal::add_stored_object(pcsk, dal::pstatic_stored_object(p), p->p,
412  dal::PERMANENT_STATIC_OBJECT);
413  return p->p;
414  }
415  }
416 
417  /* ******************************************************************** */
418  /* Incomplete Q2 structure for n=2 or 3. */
419  /* ******************************************************************** */
420  /* By Yao Koutsawa <[email protected]> 2012-12-10 */
421 
422  struct Q2_incomplete_structure_ : public convex_structure {
423  friend pconvex_structure Q2_incomplete_structure(dim_type nc);
424  };
425 
426  DAL_SIMPLE_KEY(Q2_incomplete_structure_key_, dim_type);
427 
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);
432  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
433  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
434 
435  auto p = std::make_shared<Q2_incomplete_structure_>();
436  pconvex_structure pcvs(p);
437  p->Nc = nc;
438  p->nbpt = (nc == 2) ? 8 : 20;
439  p->nbf = (nc == 2) ? 4 : 6;
440  p->basic_pcvs = parallelepiped_structure(nc); // k=1
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);
444 
445  if (nc == 2) {
446  // 5--6--7
447  // | |
448  // 3 4
449  // | |
450  // 0--1--2
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};
455 
456  p->dir_points_[0] = 0;
457  p->dir_points_[1] = 2;
458  p->dir_points_[2] = 5;
459  } else {
460  // 17---18---19
461  // /| /|
462  // / 10 / 11
463  // 15 | 16 |
464  // / 5----6/---7
465  // / / / /
466  // 12---13---14 /
467  // | 3 | 4
468  // 8 / 9 /
469  // |/ |/
470  // 0----1----2
471  p->faces[0] = {2,4,7,9,11,14,16,19};
472  p->faces[1] = {0,3,5,8,10,12,15,17};
473 
474  p->faces[2] = {5,6,7,10,11,17,18,19};
475  p->faces[3] = {0,1,2,8,9,12,13,14};
476 
477  p->faces[4] = {12,13,14,15,16,17,18,19};
478  p->faces[5] = {0,1,2,3,4,5,6,7};
479 
480  p->dir_points_[0] = 0;
481  p->dir_points_[1] = 2;
482  p->dir_points_[2] = 5;
483  p->dir_points_[3] = 12;
484  }
485 
486  for (int i = 0; i < p->nbf; i++) {
487  p->faces_struct[i] = (nc == 2) ? simplex_structure(1, 2)
489  }
490 
491  dal::add_stored_object(pcsk, pcvs, parallelepiped_structure(dim_type(nc-1)),
492  dal::PERMANENT_STATIC_OBJECT);
493  return pcvs;
494  }
495 
496 
497 
498  /* ******************************************************************** */
499  /* Pyramidal 3D structure for k=1 or 2. */
500  /* ******************************************************************** */
501 
502  struct pyramid_QK_structure_ : public convex_structure {
503  friend pconvex_structure pyramid_QK_structure(dim_type k);
504  };
505 
506  DAL_SIMPLE_KEY(pyramid_QK_structure_key_, dim_type);
507 
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);
513  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
514  if (o)
515  return std::dynamic_pointer_cast<const convex_structure>(o);
516 
517  auto p = std::make_shared<pyramid_QK_structure_>();
518  pconvex_structure pcvs(p);
519 
520  p->Nc = 3;
521  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
522 
523  if (k == 1) {
524  p->nbpt = 5;
525  p->nbf = 5;
526  p->auto_basic = true;
527  // 4
528  // /|||
529  // / || |
530  // 2-|--|-3
531  // | | | |
532  // || ||
533  // || ||
534  // 0------1
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};
542 
543  p->dir_points_[0] = 0;
544  p->dir_points_[1] = 1;
545  p->dir_points_[2] = 2;
546  p->dir_points_[3] = 4;
547 
548  p->faces_struct[0] = parallelepiped_structure(2);
549  for (int i = 1; i < p->nbf; i++)
550  p->faces_struct[i] = simplex_structure(2);
551 
554  dal::PERMANENT_STATIC_OBJECT);
555 
556  } else {
557  p->nbpt = 14;
558  p->nbf = 5;
559  p->basic_pcvs = pyramid_QK_structure(1);
560  // 13
561  // / |
562  // 11--12
563  // | |
564  // 9---10
565  // / |
566  // 6--7--8
567  // | |
568  // 3 4 5
569  // | |
570  // 0--1--2
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};
578 
579  p->dir_points_[0] = 0;
580  p->dir_points_[1] = 2;
581  p->dir_points_[2] = 6;
582  p->dir_points_[3] = 13;
583 
584  p->faces_struct[0] = parallelepiped_structure(2, 2);
585  for (int i = 1; i < p->nbf; i++)
586  p->faces_struct[i] = simplex_structure(2, 2);
587 
589  simplex_structure(2, 2),
590  dal::PERMANENT_STATIC_OBJECT);
591  }
592  return pcvs;
593  }
594 
595  /* ******************************************************************** */
596  /* Incomplete quadratic pyramidal 3D structure. */
597  /* ******************************************************************** */
598 
599  struct pyramid_Q2_incomplete_structure_ : public convex_structure {
601  };
602 
603  DAL_SIMPLE_KEY(pyramid_Q2_incomplete_structure_key_, dim_type);
604 
606  dal::pstatic_stored_object_key
607  pcsk = std::make_shared<pyramid_Q2_incomplete_structure_key_>(0);
608  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
609  if (o)
610  return std::dynamic_pointer_cast<const convex_structure>(o);
611 
612  auto p = std::make_shared<pyramid_Q2_incomplete_structure_>();
613  pconvex_structure pcvs(p);
614 
615  p->Nc = 3;
616  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
617 
618  p->nbpt = 13;
619  p->nbf = 5;
620  p->basic_pcvs = pyramid_QK_structure(1);
621  // 12
622  // / |
623  // 10--11
624  // | |
625  // 8---9
626  // / |
627  // 5--6--7
628  // | |
629  // 3 4
630  // | |
631  // 0--1--2
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};
639 
640  p->dir_points_[0] = 0;
641  p->dir_points_[1] = 2;
642  p->dir_points_[2] = 5;
643  p->dir_points_[3] = 12;
644 
645  p->faces_struct[0] = Q2_incomplete_structure(2);
646  for (int i = 1; i < p->nbf; i++)
647  p->faces_struct[i] = simplex_structure(2, 2);
648 
650  simplex_structure(2, 2),
651  dal::PERMANENT_STATIC_OBJECT);
652  return pcvs;
653  }
654 
655  /* ******************************************************************** */
656  /* Incomplete quadratic triangular prism 3D structure. */
657  /* ******************************************************************** */
658 
659  struct prism_incomplete_P2_structure_ : public convex_structure {
661  };
662 
663  DAL_SIMPLE_KEY(prism_incomplete_P2_structure_key_, dim_type);
664 
666  dal::pstatic_stored_object_key
667  pcsk = std::make_shared<prism_incomplete_P2_structure_key_>(0);
668  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
669  if (o)
670  return std::dynamic_pointer_cast<const convex_structure>(o);
671 
672  auto p = std::make_shared<prism_incomplete_P2_structure_>();
673  pconvex_structure pcvs(p);
674 
675  p->Nc = 3;
676  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
677 
678  p->nbpt = 15;
679  p->nbf = 5;
680  p->basic_pcvs = prism_P1_structure(3);
681  // 14
682  // /|`
683  // 12 | 13
684  // / 8 `
685  // 9--10--11
686  // | | |
687  // | 5 |
688  // 6 / ` 7
689  // | 3 4 |
690  // |/ `|
691  // 0---1---2
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};
699 
700  p->dir_points_[0] = 0;
701  p->dir_points_[1] = 2;
702  p->dir_points_[2] = 5;
703  p->dir_points_[3] = 9;
704 
705  for (int i = 0; i < 3; i++)
706  p->faces_struct[i] = Q2_incomplete_structure(2);
707  p->faces_struct[3] = simplex_structure(2, 2);
708  p->faces_struct[4] = simplex_structure(2, 2);
709 
710  dal::add_stored_object(pcsk, pcvs, simplex_structure(2, 2),
712  dal::PERMANENT_STATIC_OBJECT);
713  return pcvs;
714  }
715 
716  /* ******************************************************************** */
717  /* Generic dummy convex with n global nodes. */
718  /* ******************************************************************** */
719 
720  struct dummy_structure_ : public convex_structure {
722  short_type);
723  };
724 
726  short_type nf) {
727  dal::pstatic_stored_object_key
728  pcsk = std::make_shared<convex_structure_key>(2, nc, short_type(n), nf);
729  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
730  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
731  auto p = std::make_shared<dummy_structure_>();
732  pconvex_structure pcvs(p);
733  p->Nc = nc; p->nbpt = short_type(n); p->nbf = 0;
734  p->faces_struct.resize(nf);
735  p->faces.resize(nf);
736  for (short_type j = 0; j < nf; ++j) {
737  if (nc == 0)
738  p->faces_struct[j] = simplex_structure(0);
739  else p->faces_struct[j] = generic_dummy_structure(dim_type(nc-1), n, nc);
740  p->faces[j].resize(n);
741  for (short_type k = 0; k < n; ++k) p->faces[j][k] = k;
742  }
743  p->dir_points_.resize(0);
744  p->auto_basic = true;
745  if (nc == 0)
746  dal::add_stored_object(pcsk, pcvs, dal::PERMANENT_STATIC_OBJECT);
747  else
748  dal::add_stored_object(pcsk, pcvs,
749  generic_dummy_structure(dim_type(nc-1), n, nc),
750  dal::PERMANENT_STATIC_OBJECT);
751  return pcvs;
752  }
753 
754 } /* 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:73
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:49
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:47
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.