Welcome to the NetCologne GmbH open source mirroring service!

This machine mirrors various open-source projects. 20 Gbit/s uplink.

If there are any issues or you want another project mirrored, please contact mirror-service -=AT=- netcologne DOT de !

GetFEM: src/bgeot_convex_structure.cc Source File
GetFEM  5.4.4
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  if (KK > 0)
200  for (int i = 0; i < nbf; i++) {
201  faces_struct[i] = simplex_structure(dim_type(Nc-1), KK);
202  faces[i].resize(faces_struct[i]->nb_points());
203  }
204  else
205  for (int i = 0; i < nbf; i++) {
206  faces_struct[i] = pconvex_structure();
207  faces[i].resize(0);
208  }
209 
210  base_node c(Nc);
211  c.fill(0.0);
212  std::vector<int> pf(Nc+1,0);
213  size_type l, sum = 0, pd = 0;
214  if (KK == 0)
215  c.fill(scalar_type(1.0) / scalar_type(Nc+1));
216  else {
217  for (l = 1; l <= Nc; ++l)
218  (faces[l])[(pf[l])++] = 0;
219  dir_points_[pd++] = 0;
220 
221  for (short_type r = 1; r < nbpt; ++r) {
222  l = 0;
223  c[l] += scalar_type(1) / scalar_type(KK);
224  ++sum;
225  while (sum > KK) {
226  sum -= size_type(floor(0.5+(c[l] * KK)));
227  c[l] = 0.0; ++l;
228  c[l] += scalar_type(1) / scalar_type(KK);
229  ++sum;
230  }
231  for (l = 1; l <= Nc; ++l)
232  if (c[l-1] == scalar_type(0.0))
233  (faces[l])[(pf[l])++] = r;
234  if (sum == KK) {
235  (faces[0])[(pf[0])++] = r;
236  if (*(std::max_element(c.begin(), c.end())) == scalar_type(1.0))
237  dir_points_[pd++] = r;
238  }
239  }
240  }
241  }
242  };
243 
245  if (nc == 0) K = 1;
246  if (K == 1) return simplex_structure(nc);
247  dal::pstatic_stored_object_key
248  pcsk = std::make_shared<convex_structure_key>(0, nc, K);
249  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
250  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
251 
252  pconvex_structure p = std::make_shared<K_simplex_structure_>(nc, K);
253  dal::add_stored_object(pcsk, p, simplex_structure(dim_type(nc-1), K),
254  dal::PERMANENT_STATIC_OBJECT);
255  return p;
256  }
257 
258  /* ******************************************************************** */
259  /* polygon structures */
260  /* ******************************************************************** */
261 
262  struct polygon_structure_ : public convex_structure {
264  };
265 
267  if (nbt <= 1) return simplex_structure(0);
268  if (nbt <= 3) return simplex_structure(dim_type(nbt-1));
269 
270  dal::pstatic_stored_object_key
271  pcsk = std::make_shared<convex_structure_key>(1, dim_type(nbt));
272  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
273  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
274 
275  auto p = std::make_shared<polygon_structure_>();
276  pconvex_structure pcvs(p);
277  p->Nc = 2; p->nbpt = nbt; p->nbf = nbt;
278  p->auto_basic = true;
279  p->faces_struct.resize(p->nbf);
280  p->faces = std::vector< std::vector<short_type> >(p->nbf);
281  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
282 
283  for (int i = 0; i < p->nbf; i++) {
284  p->faces_struct[i] = simplex_structure(1);
285  p->faces[i] = std::vector<short_type>(2);
286  for (int j = 0; j < 2; j++)
287  (p->faces[i])[j] = short_type((i+j) % nbt);
288  }
289 
290  p->dir_points_[0] = 0;
291  p->dir_points_[1] = 1;
292  p->dir_points_[2] = short_type(nbt - 1);
293 
295  dal::PERMANENT_STATIC_OBJECT);
296  return pcvs;
297  }
298 
299  /* ******************************************************************** */
300  /* Direct product of convex structures */
301  /* ******************************************************************** */
302 
303  DAL_DOUBLE_KEY(cv_pr_key_, pconvex_structure, pconvex_structure);
304 
305  struct cv_pr_structure_ : public convex_structure {
306  cv_pr_structure_(pconvex_structure cv1, pconvex_structure cv2) {
307  Nc = dim_type(cv1->dim() + cv2->dim());
308  prod_a = cv1; prod_b = cv2;
309  nbpt = short_type(cv1->nb_points() * cv2->nb_points());
310  nbf = short_type(cv1->nb_faces() + cv2->nb_faces());
311  if (basic_structure(cv1) != cv1 || basic_structure(cv2) != cv2)
312  basic_pcvs = convex_product_structure(basic_structure(cv1),
313  basic_structure(cv2));
314  else
315  auto_basic = true;
316  faces_struct.resize(nbf);
317  faces = std::vector< std::vector<short_type> >(nbf);
318 
319  if (cv1->ind_dir_points().size() && cv2->ind_dir_points().size()) {
320  dir_points_ = std::vector<short_type>(Nc + 1);
321 
322  for (int i = 0; i <= cv1->dim(); i++)
323  dir_points_[i]
324  = short_type(cv1->ind_dir_points()[i]
325  + cv2->ind_dir_points()[0] * cv1->nb_points());
326  for (int i = 1; i <= cv2->dim(); i++)
327  dir_points_[cv1->dim()+i]
328  = short_type(cv1->ind_dir_points()[0]
329  + cv2->ind_dir_points()[i] * cv1->nb_points());
330  }
331 
332  for (short_type i = 0; i < cv1->nb_faces(); i++) {
333  if (cv1->nb_points_of_face(i) == 1)
334  faces_struct[i] = cv2;
335  else
336  faces_struct[i]
337  = (cv1->faces_structure()[i] == pconvex_structure()) ?
339  : convex_product_structure(cv1->faces_structure()[i], cv2);
340 
341  faces[i] = std::vector<short_type>(cv1->nb_points_of_face(i)
342  * cv2->nb_points());
343 
344  for (short_type j = 0; j < cv1->nb_points_of_face(i); j++)
345  for (short_type l = 0; l < cv2->nb_points(); l++) {
346  (faces[i])[l*cv1->nb_points_of_face(i)+j]
347  = short_type((cv1->ind_points_of_face(i))[j]
348  + l * cv1->nb_points());
349  }
350  }
351  for (short_type i = 0; i < cv2->nb_faces(); i++) {
352  short_type k = cv1->nb_faces();
353  if (cv2->nb_points_of_face(i) == 1)
354  faces_struct[i+k] = cv1;
355  else
356  faces_struct[i+k]
357  = (cv2->faces_structure()[i] == pconvex_structure()) ?
359  : convex_product_structure(cv1, cv2->faces_structure()[i]);
360 
361  faces[i+k] = std::vector<short_type>(cv2->nb_points_of_face(i)
362  * cv1->nb_points());
363 
364  for (short_type j = 0; j < cv2->nb_points_of_face(i); j++)
365  for (short_type l = 0; l < cv1->nb_points(); l++) {
366  (faces[i+k])[j*cv1->nb_points()+l]
367  = short_type(l + (cv2->ind_points_of_face(i))[j]
368  * cv1->nb_points());
369  }
370  }
371  }
372  };
373 
375  pconvex_structure b) {
376 
377  dal::pstatic_stored_object_key pcsk = std::make_shared<cv_pr_key_>(a, b);
378  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
379  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
380  pconvex_structure p = std::make_shared<cv_pr_structure_>(a, b);
381  dal::add_stored_object(pcsk, p, a, b, dal::PERMANENT_STATIC_OBJECT);
382  for (size_type k = 0; k < p->nb_faces(); ++k) {
383  if (exists_stored_object(p->faces_structure()[k]))
384  dal::add_dependency(p, p->faces_structure()[k]);
385  }
386  return p;
387  }
388 
389  /* ******************************************************************** */
390  /* parallelepiped structures. */
391  /* ******************************************************************** */
392 
393  struct parallelepiped_ : virtual public dal::static_stored_object {
395  parallelepiped_()
396  { DAL_STORED_OBJECT_DEBUG_CREATED(this, "parallelepiped structure"); }
397  ~parallelepiped_()
398  { DAL_STORED_OBJECT_DEBUG_DESTROYED(this, "parallelepiped structure"); }
399  };
400 
401  DAL_DOUBLE_KEY(parallelepiped_key_, dim_type, dim_type);
402 
403  pconvex_structure parallelepiped_structure(dim_type nc, dim_type k) {
404  if (nc <= 1)
405  return simplex_structure(nc, k);
406 
407  dal::pstatic_stored_object_key
408  pcsk = std::make_shared<parallelepiped_key_>(nc, k);
409 
410  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
411  if (o)
412  return ((std::dynamic_pointer_cast<const parallelepiped_>(o))->p);
413  else {
414  auto p = std::make_shared<parallelepiped_>();
415  p->p = convex_product_structure(parallelepiped_structure(dim_type(nc-1),k),
416  simplex_structure(1,k));
417  dal::add_stored_object(pcsk, dal::pstatic_stored_object(p), p->p,
418  dal::PERMANENT_STATIC_OBJECT);
419  return p->p;
420  }
421  }
422 
423  /* ******************************************************************** */
424  /* Incomplete Q2 structure for n=2 or 3. */
425  /* ******************************************************************** */
426  /* By Yao Koutsawa <yao.koutsawa@tudor.lu> 2012-12-10 */
427 
428  struct Q2_incomplete_structure_ : public convex_structure {
429  friend pconvex_structure Q2_incomplete_structure(dim_type nc);
430  };
431 
432  DAL_SIMPLE_KEY(Q2_incomplete_structure_key_, dim_type);
433 
435  GMM_ASSERT1(nc == 2 || nc == 3, "Bad parameter, expected value 2 or 3");
436  dal::pstatic_stored_object_key
437  pcsk = std::make_shared<Q2_incomplete_structure_key_>(nc);
438  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
439  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
440 
441  auto p = std::make_shared<Q2_incomplete_structure_>();
442  pconvex_structure pcvs(p);
443  p->Nc = nc;
444  p->nbpt = (nc == 2) ? 8 : 20;
445  p->nbf = (nc == 2) ? 4 : 6;
446  p->basic_pcvs = parallelepiped_structure(nc); // k=1
447  p->faces_struct.resize(p->nbf);
448  p->faces = std::vector< std::vector<short_type> >(p->nbf);
449  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
450 
451  if (nc == 2) {
452  // 5--6--7
453  // | |
454  // 3 4
455  // | |
456  // 0--1--2
457  p->faces[0] = {2,4,7};
458  p->faces[1] = {0,3,5};
459  p->faces[2] = {5,6,7};
460  p->faces[3] = {0,1,2};
461 
462  p->dir_points_[0] = 0;
463  p->dir_points_[1] = 2;
464  p->dir_points_[2] = 5;
465  } else {
466  // 17---18---19
467  // /| /|
468  // / 10 / 11
469  // 15 | 16 |
470  // / 5----6/---7
471  // / / / /
472  // 12---13---14 /
473  // | 3 | 4
474  // 8 / 9 /
475  // |/ |/
476  // 0----1----2
477  p->faces[0] = {2,4,7,9,11,14,16,19};
478  p->faces[1] = {0,3,5,8,10,12,15,17};
479 
480  p->faces[2] = {5,6,7,10,11,17,18,19};
481  p->faces[3] = {0,1,2,8,9,12,13,14};
482 
483  p->faces[4] = {12,13,14,15,16,17,18,19};
484  p->faces[5] = {0,1,2,3,4,5,6,7};
485 
486  p->dir_points_[0] = 0;
487  p->dir_points_[1] = 2;
488  p->dir_points_[2] = 5;
489  p->dir_points_[3] = 12;
490  }
491 
492  for (int i = 0; i < p->nbf; i++) {
493  p->faces_struct[i] = (nc == 2) ? simplex_structure(1, 2)
495  }
496 
497  dal::add_stored_object(pcsk, pcvs, parallelepiped_structure(dim_type(nc-1)),
498  dal::PERMANENT_STATIC_OBJECT);
499  return pcvs;
500  }
501 
502 
503 
504  /* ******************************************************************** */
505  /* Pyramidal 3D structure for k=1 or 2. */
506  /* ******************************************************************** */
507 
508  struct pyramid_QK_structure_ : public convex_structure {
509  friend pconvex_structure pyramid_QK_structure(dim_type k);
510  };
511 
512  DAL_SIMPLE_KEY(pyramid_QK_structure_key_, dim_type);
513 
515  GMM_ASSERT1(k == 1 || k == 2, "Sorry, pyramidal elements implemented "
516  "only for degree one or two.");
517  dal::pstatic_stored_object_key
518  pcsk = std::make_shared<pyramid_QK_structure_key_>(k);
519  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
520  if (o)
521  return std::dynamic_pointer_cast<const convex_structure>(o);
522 
523  auto p = std::make_shared<pyramid_QK_structure_>();
524  pconvex_structure pcvs(p);
525 
526  p->Nc = 3;
527  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
528 
529  if (k == 1) {
530  p->nbpt = 5;
531  p->nbf = 5;
532  p->auto_basic = true;
533  // 4
534  // /|||
535  // / || |
536  // 2-|--|-3
537  // | | | |
538  // || ||
539  // || ||
540  // 0------1
541  p->faces_struct.resize(p->nbf);
542  p->faces = std::vector< std::vector<short_type> >(p->nbf);
543  p->faces[0] = {0,1,2,3};
544  p->faces[1] = {0,1,4};
545  p->faces[2] = {1,3,4};
546  p->faces[3] = {3,2,4};
547  p->faces[4] = {2,0,4};
548 
549  p->dir_points_[0] = 0;
550  p->dir_points_[1] = 1;
551  p->dir_points_[2] = 2;
552  p->dir_points_[3] = 4;
553 
554  p->faces_struct[0] = parallelepiped_structure(2);
555  for (int i = 1; i < p->nbf; i++)
556  p->faces_struct[i] = simplex_structure(2);
557 
560  dal::PERMANENT_STATIC_OBJECT);
561 
562  } else {
563  p->nbpt = 14;
564  p->nbf = 5;
565  p->basic_pcvs = pyramid_QK_structure(1);
566  // 13
567  // / |
568  // 11--12
569  // | |
570  // 9---10
571  // / |
572  // 6--7--8
573  // | |
574  // 3 4 5
575  // | |
576  // 0--1--2
577  p->faces_struct.resize(p->nbf);
578  p->faces = std::vector< std::vector<short_type> >(p->nbf);
579  p->faces[0] = {0,1,2,3,4,5,6,7,8};
580  p->faces[1] = {0,1,2,9,10,13};
581  p->faces[2] = {2,5,8,10,12,13};
582  p->faces[3] = {8,7,6,12,11,13};
583  p->faces[4] = {6,3,0,11,9,13};
584 
585  p->dir_points_[0] = 0;
586  p->dir_points_[1] = 2;
587  p->dir_points_[2] = 6;
588  p->dir_points_[3] = 13;
589 
590  p->faces_struct[0] = parallelepiped_structure(2, 2);
591  for (int i = 1; i < p->nbf; i++)
592  p->faces_struct[i] = simplex_structure(2, 2);
593 
595  simplex_structure(2, 2),
596  dal::PERMANENT_STATIC_OBJECT);
597  }
598  return pcvs;
599  }
600 
601  /* ******************************************************************** */
602  /* Incomplete quadratic pyramidal 3D structure. */
603  /* ******************************************************************** */
604 
605  struct pyramid_Q2_incomplete_structure_ : public convex_structure {
607  };
608 
609  DAL_SIMPLE_KEY(pyramid_Q2_incomplete_structure_key_, dim_type);
610 
612  dal::pstatic_stored_object_key
613  pcsk = std::make_shared<pyramid_Q2_incomplete_structure_key_>(0);
614  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
615  if (o)
616  return std::dynamic_pointer_cast<const convex_structure>(o);
617 
618  auto p = std::make_shared<pyramid_Q2_incomplete_structure_>();
619  pconvex_structure pcvs(p);
620 
621  p->Nc = 3;
622  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
623 
624  p->nbpt = 13;
625  p->nbf = 5;
626  p->basic_pcvs = pyramid_QK_structure(1);
627  // 12
628  // / |
629  // 10--11
630  // | |
631  // 8---9
632  // / |
633  // 5--6--7
634  // | |
635  // 3 4
636  // | |
637  // 0--1--2
638  p->faces_struct.resize(p->nbf);
639  p->faces = std::vector< std::vector<short_type> >(p->nbf);
640  p->faces[0] = {0,1,2,3,4,5,6,7};
641  p->faces[1] = {0,1,2,8,9,12};
642  p->faces[2] = {2,4,7,9,11,12};
643  p->faces[3] = {7,6,5,11,10,12};
644  p->faces[4] = {5,3,0,10,8,12};
645 
646  p->dir_points_[0] = 0;
647  p->dir_points_[1] = 2;
648  p->dir_points_[2] = 5;
649  p->dir_points_[3] = 12;
650 
651  p->faces_struct[0] = Q2_incomplete_structure(2);
652  for (int i = 1; i < p->nbf; i++)
653  p->faces_struct[i] = simplex_structure(2, 2);
654 
656  simplex_structure(2, 2),
657  dal::PERMANENT_STATIC_OBJECT);
658  return pcvs;
659  }
660 
661  /* ******************************************************************** */
662  /* Incomplete quadratic triangular prism 3D structure. */
663  /* ******************************************************************** */
664 
665  struct prism_incomplete_P2_structure_ : public convex_structure {
667  };
668 
669  DAL_SIMPLE_KEY(prism_incomplete_P2_structure_key_, dim_type);
670 
672  dal::pstatic_stored_object_key
673  pcsk = std::make_shared<prism_incomplete_P2_structure_key_>(0);
674  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
675  if (o)
676  return std::dynamic_pointer_cast<const convex_structure>(o);
677 
678  auto p = std::make_shared<prism_incomplete_P2_structure_>();
679  pconvex_structure pcvs(p);
680 
681  p->Nc = 3;
682  p->dir_points_ = std::vector<short_type>(p->Nc + 1);
683 
684  p->nbpt = 15;
685  p->nbf = 5;
686  p->basic_pcvs = prism_P1_structure(3);
687  // 14
688  // /|`
689  // 12 | 13
690  // / 8 `
691  // 9--10--11
692  // | | |
693  // | 5 |
694  // 6 / ` 7
695  // | 3 4 |
696  // |/ `|
697  // 0---1---2
698  p->faces_struct.resize(p->nbf);
699  p->faces = std::vector< std::vector<short_type> >(p->nbf);
700  p->faces[0] = {2,4,5,7,8,11,13,14};
701  p->faces[1] = {0,3,5,6,8,9,12,14};
702  p->faces[2] = {0,1,2,6,7,9,10,11};
703  p->faces[3] = {9,10,11,12,13,14};
704  p->faces[4] = {0,1,2,3,4,5};
705 
706  p->dir_points_[0] = 0;
707  p->dir_points_[1] = 2;
708  p->dir_points_[2] = 5;
709  p->dir_points_[3] = 9;
710 
711  for (int i = 0; i < 3; i++)
712  p->faces_struct[i] = Q2_incomplete_structure(2);
713  p->faces_struct[3] = simplex_structure(2, 2);
714  p->faces_struct[4] = simplex_structure(2, 2);
715 
716  dal::add_stored_object(pcsk, pcvs, simplex_structure(2, 2),
718  dal::PERMANENT_STATIC_OBJECT);
719  return pcvs;
720  }
721 
722  /* ******************************************************************** */
723  /* Generic dummy convex with n global nodes. */
724  /* ******************************************************************** */
725 
726  struct dummy_structure_ : public convex_structure {
728  short_type);
729  };
730 
732  short_type nf) {
733  dal::pstatic_stored_object_key
734  pcsk = std::make_shared<convex_structure_key>(2, nc, short_type(n), nf);
735  dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
736  if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
737  auto p = std::make_shared<dummy_structure_>();
738  pconvex_structure pcvs(p);
739  p->Nc = nc; p->nbpt = short_type(n); p->nbf = 0;
740  p->faces_struct.resize(nf);
741  p->faces.resize(nf);
742  for (short_type j = 0; j < nf; ++j) {
743  if (nc == 0)
744  p->faces_struct[j] = simplex_structure(0);
745  else p->faces_struct[j] = generic_dummy_structure(dim_type(nc-1), n, nc);
746  p->faces[j].resize(n);
747  for (short_type k = 0; k < n; ++k) p->faces[j][k] = k;
748  }
749  p->dir_points_.resize(0);
750  p->auto_basic = true;
751  if (nc == 0)
752  dal::add_stored_object(pcsk, pcvs, dal::PERMANENT_STATIC_OBJECT);
753  else
754  dal::add_stored_object(pcsk, pcvs,
755  generic_dummy_structure(dim_type(nc-1), n, nc),
756  dal::PERMANENT_STATIC_OBJECT);
757  return pcvs;
758  }
759 
760 } /* 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.