GetFEM++  5.3
bgeot_convex_structure.cc
1 /*===========================================================================
2 
3  Copyright (C) 1999-2017 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  virtual bool compare(const static_stored_object_key &oo) const {
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  convex_structure_key(int t, dim_type NN, short_type KK = 0,
99  short_type nnf = 0)
100  : type(t), N(NN), K(KK), nf(nnf) {}
101  };
102 
103  /* ******************************************************************** */
104  /* simplex structures */
105  /* ******************************************************************** */
106 
107  class simplex_structure_ : public convex_structure
108  { friend pconvex_structure simplex_structure(dim_type nc); };
109 
110 #ifdef GETFEM_HAVE_QDLIB
111 # include <qd/fpu.h>
112 #endif
113 
115 #ifdef GETFEM_HAVE_QDLIB
116  /* initialisation for QD on intel CPUs */
117  static bool fpu_init = false;
118  if (!fpu_init) {
119  unsigned int old_cw;
120  fpu_fix_start(&old_cw);
121  fpu_init = true;
122  }
123 #endif
124  dal::pstatic_stored_object_key
125  pcsk = std::make_shared<convex_structure_key>(0, nc, 1);
126  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
127  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
128 
129  auto p = std::make_shared<simplex_structure_>();
131  p->Nc = dim_type(nc); p->nbpt = short_type(nc+1);
132  p->nbf = short_type(nc ? nc+1 : 0);
133  p->faces_struct.resize(p->nbf);
134  p->faces.resize(p->nbf);
135  p->dir_points_.resize(p->Nc + 1);
136  p->auto_basic = true;
137  for (short_type i = 0; i < p->nbf; i++) {
138  p->dir_points_[i] = i;
139  p->faces_struct[i] = simplex_structure(dim_type(nc-1));
140  p->faces[i].resize(nc);
141  for (short_type j = 0; j < nc; j++)
142  (p->faces[i])[j] = (j >= i) ? short_type(j + 1) : j;
143  }
144  if (nc == 0)
145  dal::add_stored_object(pcsk, pcvs, dal::PERMANENT_STATIC_OBJECT);
146  else
147  dal::add_stored_object(pcsk, pcvs, simplex_structure(dim_type(nc-1)),
148  dal::PERMANENT_STATIC_OBJECT);
149  return pcvs;
150  }
151 
152  /* ******************************************************************** */
153  /* K-simplex structures */
154  /* ******************************************************************** */
155 
156  struct K_simplex_structure_ : public convex_structure {
157 
158  K_simplex_structure_(dim_type NN, short_type KK) {
159  Nc = NN; nbpt = short_type(alpha(Nc, KK)); nbf = short_type(Nc+1);
160  basic_pcvs = simplex_structure(NN);
161  faces_struct.resize(nbf);
162  faces.resize(nbf);
163  dir_points_.resize(Nc+1);
164 
165  for (int i = 0; i < nbf; i++) {
166  if (KK > 0) {
167  faces_struct[i] = simplex_structure(dim_type(Nc-1), KK);
168  faces[i].resize(faces_struct[i]->nb_points());
169  }
170  else {
171  faces_struct[i] = pconvex_structure();
172  faces[i].resize(0);
173  }
174  }
175 
176  base_node c(Nc); c.fill(0.0);
177  std::vector<int> pf(Nc+1); std::fill(pf.begin(), pf.end(), 0);
178  size_type l, sum = 0, pd = 0;
179  if (KK == 0) c.fill(scalar_type(1.0) / scalar_type(Nc+1));
180  else {
181  for (l = 1; l <= Nc; ++l) (faces[l])[(pf[l])++] = 0;
182  dir_points_[pd++] = 0;
183  }
184 
185  for (short_type r = 1; r < nbpt; ++r) {
186  l = 0;
187  c[l] += scalar_type(1.0) / scalar_type(KK); ++sum;
188  while (sum > KK) {
189  sum -= size_type(floor(0.5+(c[l] * KK)));
190  c[l] = 0.0; ++l; c[l] += scalar_type(1.0) / scalar_type(KK);
191  ++sum;
192  }
193  for (l = 1; l <= Nc; ++l)
194  if (c[l-1] == scalar_type(0.0)) (faces[l])[(pf[l])++] = r;
195  if (sum == KK) {
196  (faces[0])[(pf[0])++] = r;
197  if (*(std::max_element(c.begin(), c.end())) == scalar_type(1.0))
198  dir_points_[pd++] = r;
199  }
200  }
201  }
202  };
203 
205  if (nc == 0) K = 1;
206  if (K == 1) return simplex_structure(nc);
207  dal::pstatic_stored_object_key
208  pcsk = std::make_shared<convex_structure_key>(0, nc, K);
209  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
210  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
211 
212  pconvex_structure p = std::make_shared<K_simplex_structure_>(nc, K);
213  dal::add_stored_object(pcsk, p, simplex_structure(dim_type(nc-1), K),
214  dal::PERMANENT_STATIC_OBJECT);
215  return p;
216  }
217 
218  /* ******************************************************************** */
219  /* polygon structures */
220  /* ******************************************************************** */
221 
222  struct polygon_structure_ : public convex_structure {
224  };
225 
227  if (nbt <= 1) return simplex_structure(0);
228  if (nbt <= 3) return simplex_structure(dim_type(nbt-1));
229 
230  dal::pstatic_stored_object_key
231  pcsk = std::make_shared<convex_structure_key>(1, dim_type(nbt));
232  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
233  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
234 
235  auto p = std::make_shared<polygon_structure_>();
236  pconvex_structure pcvs(p);
237  p->Nc = 2; p->nbpt = nbt; p->nbf = nbt;
238  p->auto_basic = true;
239  p->faces_struct.resize(p->nbf);
240  p->faces = std::vector< std::vector<short_type> >(p->nbf);
241  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
242 
243  for (int i = 0; i < p->nbf; i++) {
244  p->faces_struct[i] = simplex_structure(1);
245  p->faces[i] = std::vector<short_type>(2);
246  for (int j = 0; j < 2; j++)
247  (p->faces[i])[j] = short_type((i+j) % nbt);
248  }
249 
250  p->dir_points_[0] = 0;
251  p->dir_points_[1] = 1;
252  p->dir_points_[2] = short_type(nbt - 1);
253 
255  dal::PERMANENT_STATIC_OBJECT);
256  return pcvs;
257  }
258 
259  /* ******************************************************************** */
260  /* Direct product of convex structures */
261  /* ******************************************************************** */
262 
263  DAL_DOUBLE_KEY(cv_pr_key_, pconvex_structure, pconvex_structure);
264 
265  struct cv_pr_structure_ : public convex_structure {
266  cv_pr_structure_(pconvex_structure cv1, pconvex_structure cv2) {
267  Nc = dim_type(cv1->dim() + cv2->dim());
268  prod_a = cv1; prod_b = cv2;
269  nbpt = short_type(cv1->nb_points() * cv2->nb_points());
270  nbf = short_type(cv1->nb_faces() + cv2->nb_faces());
271  if (basic_structure(cv1) != cv1 || basic_structure(cv2) != cv2)
272  basic_pcvs = convex_product_structure(basic_structure(cv1),
273  basic_structure(cv2));
274  else
275  auto_basic = true;
276  faces_struct.resize(nbf);
277  faces = std::vector< std::vector<short_type> >(nbf);
278 
279  if (cv1->ind_dir_points().size() && cv2->ind_dir_points().size()) {
280  dir_points_ = std::vector<short_type>(Nc + 1);
281 
282  for (int i = 0; i <= cv1->dim(); i++)
283  dir_points_[i]
284  = short_type(cv1->ind_dir_points()[i]
285  + cv2->ind_dir_points()[0] * cv1->nb_points());
286  for (int i = 1; i <= cv2->dim(); i++)
287  dir_points_[cv1->dim()+i]
288  = short_type(cv1->ind_dir_points()[0]
289  + cv2->ind_dir_points()[i] * cv1->nb_points());
290  }
291 
292  for (short_type i = 0; i < cv1->nb_faces(); i++) {
293  if (cv1->nb_points_of_face(i) == 1)
294  faces_struct[i] = cv2;
295  else
296  faces_struct[i]
297  = (cv1->faces_structure()[i] == pconvex_structure()) ?
299  : convex_product_structure(cv1->faces_structure()[i], cv2);
300 
301  faces[i] = std::vector<short_type>(cv1->nb_points_of_face(i)
302  * cv2->nb_points());
303 
304  for (short_type j = 0; j < cv1->nb_points_of_face(i); j++)
305  for (short_type l = 0; l < cv2->nb_points(); l++) {
306  (faces[i])[l*cv1->nb_points_of_face(i)+j]
307  = short_type((cv1->ind_points_of_face(i))[j]
308  + l * cv1->nb_points());
309  }
310  }
311  for (short_type i = 0; i < cv2->nb_faces(); i++) {
312  short_type k = cv1->nb_faces();
313  if (cv2->nb_points_of_face(i) == 1)
314  faces_struct[i+k] = cv1;
315  else
316  faces_struct[i+k]
317  = (cv2->faces_structure()[i] == pconvex_structure()) ?
319  : convex_product_structure(cv1, cv2->faces_structure()[i]);
320 
321  faces[i+k] = std::vector<short_type>(cv2->nb_points_of_face(i)
322  * cv1->nb_points());
323 
324  for (short_type j = 0; j < cv2->nb_points_of_face(i); j++)
325  for (short_type l = 0; l < cv1->nb_points(); l++) {
326  (faces[i+k])[j*cv1->nb_points()+l]
327  = short_type(l + (cv2->ind_points_of_face(i))[j]
328  * cv1->nb_points());
329  }
330  }
331  }
332  };
333 
335  pconvex_structure b) {
336 
337  dal::pstatic_stored_object_key pcsk = std::make_shared<cv_pr_key_>(a, b);
338  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
339  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
340  pconvex_structure p = std::make_shared<cv_pr_structure_>(a, b);
341  dal::add_stored_object(pcsk, p, a, b, dal::PERMANENT_STATIC_OBJECT);
342  for (size_type k = 0; k < p->nb_faces(); ++k) {
343  if (exists_stored_object(p->faces_structure()[k]))
344  dal::add_dependency(p, p->faces_structure()[k]);
345  }
346  return p;
347  }
348 
349  /* ******************************************************************** */
350  /* parallelepiped structures. */
351  /* ******************************************************************** */
352 
353  struct parallelepiped_ : virtual public dal::static_stored_object {
355  parallelepiped_()
356  { DAL_STORED_OBJECT_DEBUG_CREATED(this, "parallelepiped structure"); }
357  ~parallelepiped_()
358  { DAL_STORED_OBJECT_DEBUG_DESTROYED(this, "parallelepiped structure"); }
359  };
360 
361  DAL_DOUBLE_KEY(parallelepiped_key_, dim_type, dim_type);
362 
363  pconvex_structure parallelepiped_structure(dim_type nc, dim_type k) {
364  if (nc <= 1)
365  return simplex_structure(nc, k);
366 
367  dal::pstatic_stored_object_key
368  pcsk = std::make_shared<parallelepiped_key_>(nc, k);
369 
370  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
371  if (o)
372  return ((std::dynamic_pointer_cast<const parallelepiped_>(o))->p);
373  else {
374  auto p = std::make_shared<parallelepiped_>();
375  p->p = convex_product_structure(parallelepiped_structure(dim_type(nc-1),k),
376  simplex_structure(1,k));
377  dal::add_stored_object(pcsk, dal::pstatic_stored_object(p), p->p,
378  dal::PERMANENT_STATIC_OBJECT);
379  return p->p;
380  }
381  }
382 
383  /* ******************************************************************** */
384  /* Incomplete Q2 structure for n=2 or 3. */
385  /* ******************************************************************** */
386  /* By Yao Koutsawa <yao.koutsawa@tudor.lu> 2012-12-10 */
387 
388  struct Q2_incomplete_structure_ : public convex_structure {
389  friend pconvex_structure Q2_incomplete_structure(dim_type nc);
390  };
391 
392  DAL_SIMPLE_KEY(Q2_incomplete_structure_key_, dim_type);
393 
395  GMM_ASSERT1(nc == 2 || nc == 3, "Bad parameter, expected value 2 or 3");
396  dal::pstatic_stored_object_key
397  pcsk = std::make_shared<Q2_incomplete_structure_key_>(nc);
398  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
399  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
400 
401  auto p = std::make_shared<Q2_incomplete_structure_>();
402  pconvex_structure pcvs(p);
403  p->Nc = nc;
404  p->nbpt = (nc == 2) ? 8 : 20;
405  p->nbf = (nc == 2) ? 4 : 6;
406  p->basic_pcvs = parallelepiped_structure(nc); // k=1
407  p->faces_struct.resize(p->nbf);
408  p->faces = std::vector< std::vector<short_type> >(p->nbf);
409  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
410 
411  if (nc == 2) {
412  // 5--6--7
413  // | |
414  // 3 4
415  // | |
416  // 0--1--2
417  p->faces[0] = {2,4,7};
418  p->faces[1] = {0,3,5};
419  p->faces[2] = {5,6,7};
420  p->faces[3] = {0,1,2};
421 
422  p->dir_points_[0] = 0;
423  p->dir_points_[1] = 2;
424  p->dir_points_[2] = 5;
425  } else {
426  // 17---18---19
427  // /| /|
428  // / 10 / 11
429  // 15 | 16 |
430  // / 5----6/---7
431  // / / / /
432  // 12---13---14 /
433  // | 3 | 4
434  // 8 / 9 /
435  // |/ |/
436  // 0----1----2
437  p->faces[0] = {2,4,7,9,11,14,16,19};
438  p->faces[1] = {0,3,5,8,10,12,15,17};
439 
440  p->faces[2] = {5,6,7,10,11,17,18,19};
441  p->faces[3] = {0,1,2,8,9,12,13,14};
442 
443  p->faces[4] = {12,13,14,15,16,17,18,19};
444  p->faces[5] = {0,1,2,3,4,5,6,7};
445 
446  p->dir_points_[0] = 0;
447  p->dir_points_[1] = 2;
448  p->dir_points_[2] = 5;
449  p->dir_points_[3] = 12;
450  }
451 
452  for (int i = 0; i < p->nbf; i++) {
453  p->faces_struct[i] = (nc == 2) ? simplex_structure(1, 2)
455  }
456 
457  dal::add_stored_object(pcsk, pcvs, parallelepiped_structure(dim_type(nc-1)),
458  dal::PERMANENT_STATIC_OBJECT);
459  return pcvs;
460  }
461 
462 
463 
464  /* ******************************************************************** */
465  /* Pyramidal 3D structure for k=1 or 2. */
466  /* ******************************************************************** */
467 
468  struct pyramid_QK_structure_ : public convex_structure {
469  friend pconvex_structure pyramid_QK_structure(dim_type k);
470  };
471 
472  DAL_SIMPLE_KEY(pyramid_QK_structure_key_, dim_type);
473 
475  GMM_ASSERT1(k == 1 || k == 2, "Sorry, pyramidal elements implemented "
476  "only for degree one or two.");
477  dal::pstatic_stored_object_key
478  pcsk = std::make_shared<pyramid_QK_structure_key_>(k);
479  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
480  if (o)
481  return std::dynamic_pointer_cast<const convex_structure>(o);
482 
483  auto p = std::make_shared<pyramid_QK_structure_>();
484  pconvex_structure pcvs(p);
485 
486  p->Nc = 3;
487  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
488 
489  if (k == 1) {
490  p->nbpt = 5;
491  p->nbf = 5;
492  p->auto_basic = true;
493  // 4
494  // /|||
495  // / || |
496  // 2-|--|-3
497  // | | | |
498  // || ||
499  // || ||
500  // 0------1
501  p->faces_struct.resize(p->nbf);
502  p->faces = std::vector< std::vector<short_type> >(p->nbf);
503  p->faces[0] = {0,1,2,3};
504  p->faces[1] = {0,1,4};
505  p->faces[2] = {1,3,4};
506  p->faces[3] = {3,2,4};
507  p->faces[4] = {2,0,4};
508 
509  p->dir_points_[0] = 0;
510  p->dir_points_[1] = 1;
511  p->dir_points_[2] = 2;
512  p->dir_points_[3] = 4;
513 
514  p->faces_struct[0] = parallelepiped_structure(2);
515  for (int i = 1; i < p->nbf; i++)
516  p->faces_struct[i] = simplex_structure(2);
517 
520  dal::PERMANENT_STATIC_OBJECT);
521 
522  } else {
523  p->nbpt = 14;
524  p->nbf = 5;
525  p->basic_pcvs = pyramid_QK_structure(1);
526  // 13
527  // / |
528  // 11--12
529  // | |
530  // 9---10
531  // / |
532  // 6--7--8
533  // | |
534  // 3 4 5
535  // | |
536  // 0--1--2
537  p->faces_struct.resize(p->nbf);
538  p->faces = std::vector< std::vector<short_type> >(p->nbf);
539  p->faces[0] = {0,1,2,3,4,5,6,7,8};
540  p->faces[1] = {0,1,2,9,10,13};
541  p->faces[2] = {2,5,8,10,12,13};
542  p->faces[3] = {8,7,6,12,11,13};
543  p->faces[4] = {6,3,0,11,9,13};
544 
545  p->dir_points_[0] = 0;
546  p->dir_points_[1] = 2;
547  p->dir_points_[2] = 6;
548  p->dir_points_[3] = 13;
549 
550  p->faces_struct[0] = parallelepiped_structure(2, 2);
551  for (int i = 1; i < p->nbf; i++)
552  p->faces_struct[i] = simplex_structure(2, 2);
553 
555  simplex_structure(2, 2),
556  dal::PERMANENT_STATIC_OBJECT);
557  }
558  return pcvs;
559  }
560 
561  /* ******************************************************************** */
562  /* Incomplete quadratic pyramidal 3D structure. */
563  /* ******************************************************************** */
564 
565  struct pyramid_Q2_incomplete_structure_ : public convex_structure {
567  };
568 
569  DAL_SIMPLE_KEY(pyramid_Q2_incomplete_structure_key_, dim_type);
570 
572  dal::pstatic_stored_object_key
573  pcsk = std::make_shared<pyramid_Q2_incomplete_structure_key_>(0);
574  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
575  if (o)
576  return std::dynamic_pointer_cast<const convex_structure>(o);
577 
578  auto p = std::make_shared<pyramid_Q2_incomplete_structure_>();
579  pconvex_structure pcvs(p);
580 
581  p->Nc = 3;
582  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
583 
584  p->nbpt = 13;
585  p->nbf = 5;
586  p->basic_pcvs = pyramid_QK_structure(1);
587  // 12
588  // / |
589  // 10--11
590  // | |
591  // 8---9
592  // / |
593  // 5--6--7
594  // | |
595  // 3 4
596  // | |
597  // 0--1--2
598  p->faces_struct.resize(p->nbf);
599  p->faces = std::vector< std::vector<short_type> >(p->nbf);
600  p->faces[0] = {0,1,2,3,4,5,6,7};
601  p->faces[1] = {0,1,2,8,9,12};
602  p->faces[2] = {2,4,7,9,11,12};
603  p->faces[3] = {7,6,5,11,10,12};
604  p->faces[4] = {5,3,0,10,8,12};
605 
606  p->dir_points_[0] = 0;
607  p->dir_points_[1] = 2;
608  p->dir_points_[2] = 5;
609  p->dir_points_[3] = 12;
610 
611  p->faces_struct[0] = Q2_incomplete_structure(2);
612  for (int i = 1; i < p->nbf; i++)
613  p->faces_struct[i] = simplex_structure(2, 2);
614 
616  simplex_structure(2, 2),
617  dal::PERMANENT_STATIC_OBJECT);
618  return pcvs;
619  }
620 
621  /* ******************************************************************** */
622  /* Incomplete quadratic triangular prism 3D structure. */
623  /* ******************************************************************** */
624 
625  struct prism_incomplete_P2_structure_ : public convex_structure {
627  };
628 
629  DAL_SIMPLE_KEY(prism_incomplete_P2_structure_key_, dim_type);
630 
632  dal::pstatic_stored_object_key
633  pcsk = std::make_shared<prism_incomplete_P2_structure_key_>(0);
634  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
635  if (o)
636  return std::dynamic_pointer_cast<const convex_structure>(o);
637 
638  auto p = std::make_shared<prism_incomplete_P2_structure_>();
639  pconvex_structure pcvs(p);
640 
641  p->Nc = 3;
642  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
643 
644  p->nbpt = 15;
645  p->nbf = 5;
646  p->basic_pcvs = prism_P1_structure(3);
647  // 14
648  // /|`
649  // 12 | 13
650  // / 8 `
651  // 9--10--11
652  // | | |
653  // | 5 |
654  // 6 / ` 7
655  // | 3 4 |
656  // |/ `|
657  // 0---1---2
658  p->faces_struct.resize(p->nbf);
659  p->faces = std::vector< std::vector<short_type> >(p->nbf);
660  p->faces[0] = {2,4,5,7,8,11,13,14};
661  p->faces[1] = {0,3,5,6,8,9,12,14};
662  p->faces[2] = {0,1,2,6,7,9,10,11};
663  p->faces[3] = {9,10,11,12,13,14};
664  p->faces[4] = {0,1,2,3,4,5};
665 
666  p->dir_points_[0] = 0;
667  p->dir_points_[1] = 2;
668  p->dir_points_[2] = 5;
669  p->dir_points_[3] = 9;
670 
671  for (int i = 0; i < 3; i++)
672  p->faces_struct[i] = Q2_incomplete_structure(2);
673  p->faces_struct[3] = simplex_structure(2, 2);
674  p->faces_struct[4] = simplex_structure(2, 2);
675 
676  dal::add_stored_object(pcsk, pcvs, simplex_structure(2, 2),
678  dal::PERMANENT_STATIC_OBJECT);
679  return pcvs;
680  }
681 
682  /* ******************************************************************** */
683  /* Generic dummy convex with n global nodes. */
684  /* ******************************************************************** */
685 
686  struct dummy_structure_ : public convex_structure {
688  short_type);
689  };
690 
692  short_type nf) {
693  dal::pstatic_stored_object_key
694  pcsk = std::make_shared<convex_structure_key>(2, nc, short_type(n), nf);
695  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
696  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
697  auto p = std::make_shared<dummy_structure_>();
698  pconvex_structure pcvs(p);
699  p->Nc = nc; p->nbpt = short_type(n); p->nbf = 0;
700  p->faces_struct.resize(nf);
701  p->faces.resize(nf);
702  for (short_type j = 0; j < nf; ++j) {
703  if (nc == 0)
704  p->faces_struct[j] = simplex_structure(0);
705  else p->faces_struct[j] = generic_dummy_structure(dim_type(nc-1), n, nc);
706  p->faces[j].resize(n);
707  for (short_type k = 0; k < n; ++k) p->faces[j][k] = k;
708  }
709  p->dir_points_.resize(0);
710  p->auto_basic = true;
711  if (nc == 0)
712  dal::add_stored_object(pcsk, pcvs, dal::PERMANENT_STATIC_OBJECT);
713  else
714  dal::add_stored_object(pcsk, pcvs,
715  generic_dummy_structure(dim_type(nc-1), n, nc),
716  dal::PERMANENT_STATIC_OBJECT);
717  return pcvs;
718  }
719 
720 } /* end of namespace bgeot. */
friend pconvex_structure basic_structure(pconvex_structure cv)
Original structure (if concerned)
base class for static stored objects
Stores interdependent getfem objects.
container for small vectors of POD (Plain Old Data) types.
std::ostream & operator<<(std::ostream &o, const convex_structure &cv)
Print the details of the convex structure cvs to the output stream o.
Definition of convex structures.
pconvex_structure prism_P1_structure(dim_type nc)
Give a pointer on the structures of a prism of dimension d.
pstatic_stored_object search_stored_object(pstatic_stored_object_key k)
Gives a pointer to an object from a key pointer.
std::shared_ptr< const convex_structure > pconvex_structure
Pointer on a convex structure description.
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
pconvex_structure pyramid_QK_structure(dim_type k)
Give a pointer on the 3D pyramid structure for a degree k = 1 or 2.
void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o, permanence perm)
Add an object with two optional dependencies.
pconvex_structure prism_incomplete_P2_structure()
Give a pointer on the 3D quadratic incomplete prism structure.
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 ...
A simple singleton implementation.
short_type nb_points() const
Number of vertices.
void add_dependency(pstatic_stored_object o1, pstatic_stored_object o2)
Add a dependency, object o1 will depend on object o2.
Structure of a convex.
gmm::uint16_type short_type
used as the common short type integer in the library
Definition: bgeot_config.h:79
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.
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...
convenient initialization of vectors via overload of "operator,".
pconvex_structure simplex_structure(dim_type nc)
Give a pointer on the structures of a simplex of dimension d.
dim_type dim() const
Dimension of the convex.
short_type nb_faces() const
Number of faces.
const convex_ind_ct & ind_points_of_face(short_type i) const
Give an array of the indexes of the vertices of a face.
Basic Geometric Tools.
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.
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
pconvex_structure polygon_structure(short_type nbt)
Give a pointer on the structures of a polygon with n vertex.
pconvex_structure pyramid_Q2_incomplete_structure()
Give a pointer on the 3D quadratic incomplete pyramid structure.