GetFEM++  5.3
bgeot_poly_composite.cc
1 /*===========================================================================
2 
3  Copyright (C) 2002-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 #include "getfem/dal_singleton.h"
25 
26 namespace bgeot {
27 
28  inline scalar_type sfloor(scalar_type x)
29  { return (x >= 0) ? floor(x) : -floor(-x); }
30 
31 
33  const base_node &y) const {
34  size_type s = x.size();
35  scalar_type c1 = c_max, c2 = c_max * scalar_type(base);
36  GMM_ASSERT2(y.size() == s, "dimension error");
37 
38  base_node::const_iterator itx=x.begin(), itex=x.end(), ity=y.begin();
39  int ret = 0;
40  for (; itx != itex; ++itx, ++ity) {
41  long a = long(sfloor((*itx) * c1)), b = long(sfloor((*ity) * c1));
42  if ((scalar_type(gmm::abs(a)) > scalar_type(base))
43  || (scalar_type(gmm::abs(b)) > scalar_type(base))) {
44  exp_max++; c_max /= scalar_type(base);
45  return (*this)(x,y);
46  }
47  if (ret == 0) { if (a < b) ret = -1; else if (a > b) ret = 1; }
48  }
49  if (ret) return ret;
50 
51  for (int e = exp_max; e >= exp_min; --e, c1 *= scalar_type(base),
52  c2 *= scalar_type(base)) {
53  itx = x.begin(), itex = x.end(), ity = y.begin();
54  for (; itx != itex; ++itx, ++ity) {
55  int a = int(sfloor(((*itx) * c2) - sfloor((*itx) * c1)
56  * scalar_type(base)));
57  int b = int(sfloor(((*ity) * c2) - sfloor((*ity) * c1)
58  * scalar_type(base)));
59  if (a < b) return -1; else if (a > b) return 1;
60  }
61  }
62  return 0;
63  }
64 
65  mesh_precomposite::mesh_precomposite(const basic_mesh &m) {
66  msh = &m;
67  det.resize(m.nb_convex());
68  orgs.resize(m.nb_convex());
69  gtrans.resize(m.nb_convex());
70  for (size_type i = 0; i <= m.points().index().last_true(); ++i) {
71  vertexes.add(m.points()[i]);
72  }
73  for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv) {
74 
75  pgeometric_trans pgt = m.trans_of_convex(cv);
76  size_type N = pgt->structure()->dim();
77  size_type P = m.dim();
78  GMM_ASSERT1(pgt->is_linear() && N == P, "Bad geometric transformation");
79 
80  base_matrix G(P, pgt->nb_points());
81  base_matrix pc(pgt->nb_points() , N);
82  base_matrix B0(N, P);
83 
84  m.points_of_convex(cv, G);
85 
86  base_node x(N); gmm::clear(x);
87  pgt->poly_vector_grad(x, pc);
88 
89  gmm::mult(gmm::transposed(pc), gmm::transposed(G), B0);
90  det[cv] = gmm::lu_inverse(B0);
91  gtrans[cv] = B0;
92  orgs[cv] = m.points_of_convex(cv)[0];
93  }
94  }
95 
96  scalar_type polynomial_composite::eval(const base_node &pt) const {
97  base_node p0(mp->dim()), p1(mp->dim());
98  std::vector<bool> elt(mp->linked_mesh().nb_convex(), true);
99  mesh_structure::ind_cv_ct::const_iterator itc, itce;
100 
101  mesh_precomposite::PTAB::const_sorted_iterator
102  it1 = mp->vertexes.sorted_ge(pt), it2 = it1;
103  size_type i1 = it1.index(), i2;
104 
105  --it2; i2 = it2.index();
106 
107 
108  while (i1 != size_type(-1) || i2 != size_type(-1))
109  {
110  if (i1 != size_type(-1))
111  {
112  const mesh_structure::ind_cv_ct &tc
113  = mp->linked_mesh().convex_to_point(i1);
114  itc = tc.begin(); itce = tc.end();
115  for (; itc != itce; ++itc)
116  {
117  size_type ii = *itc;
118  if (elt[ii])
119  {
120  elt[ii] = false;
121  p0 = pt; p0 -= mp->orgs[ii];
122  gmm::mult(gmm::transposed(mp->gtrans[ii]), p0, p1);
123  if (mp->trans_of_convex(ii)->convex_ref()->is_in(p1) < 1E-10) {
124  return to_scalar(poly_of_subelt(ii).eval(local_coordinate ? p1.begin() : pt.begin()));
125  }
126  }
127  }
128  ++it1; i1 = it1.index();
129  }
130 
131  if (i2 != size_type(-1))
132  {
133  const mesh_structure::ind_cv_ct &tc
134  = mp->linked_mesh().convex_to_point(i2);
135  itc = tc.begin(); itce = tc.end();
136  for (; itc != itce; ++itc)
137  {
138  size_type ii = *itc;
139  if (elt[ii])
140  {
141  elt[ii] = false;
142  p0 = pt; p0 -= mp->orgs[ii];
143  gmm::mult(gmm::transposed(mp->gtrans[ii]), p0, p1);
144  if (mp->trans_of_convex(ii)->convex_ref()->is_in(p1) < 1E-10) {
145  return to_scalar(poly_of_subelt(ii).eval(local_coordinate ? p1.begin() : pt.begin()));
146  }
147  }
148  }
149  --it2; i2 = it2.index();
150  }
151  }
152  GMM_ASSERT1(false, "Element not found in composite polynomial: " << pt);
153  }
154 
155  DAL_TRIPLE_KEY(base_poly_key, short_type, short_type, std::vector<opt_long_scalar_type>);
156 
157  polynomial_composite::polynomial_composite(
158  const mesh_precomposite &m, bool lc)
159  : mp(&m), local_coordinate(lc), default_poly(mp->dim(), 0) {}
160 
161  void polynomial_composite::derivative(short_type k) {
162  if (local_coordinate) {
163  dim_type N = mp->dim();
164  base_poly P(N, 0), Q;
165  base_vector e(N), f(N);
166  for (size_type ic = 0; ic < mp->nb_convex(); ++ic) {
167  gmm::clear(e); e[k] = 1.0;
168  gmm::mult(gmm::transposed(mp->gtrans[ic]), e, f);
169  P.clear();
170  auto &poly = poly_of_subelt(ic);
171  for (dim_type n = 0; n < N; ++n) {
172  Q = poly;
173  Q.derivative(n);
174  P += Q * f[n];
175  }
176  if (polytab.find(ic) != polytab.end()) set_poly_of_subelt(ic, P);
177  }
178  }
179  else
180  for (size_type ic = 0; ic < mp->nb_convex(); ++ic) {
181  auto poly = poly_of_subelt(ic);
182  poly.derivative(k);
183  if (polytab.find(ic) != polytab.end()) set_poly_of_subelt(ic, poly);
184  }
185  }
186 
187  void polynomial_composite::set_poly_of_subelt(size_type l, const base_poly &poly) {
188  auto poly_key = std::make_shared<base_poly_key>(poly.degree(), poly.dim(), poly);
189  auto o = dal::search_stored_object(poly_key);
190  if (!o) {
191  o = std::make_shared<base_poly>(poly);
192  dal::add_stored_object(poly_key, o);
193  }
194  polytab[l] = poly_key;
195  }
196 
197  const base_poly &polynomial_composite::poly_of_subelt(size_type l) const {
198  auto it = polytab.find(l);
199  if (it == polytab.end()) return default_poly;
200  return dynamic_cast<const base_poly &>(*dal::search_stored_object(it->second));
201  }
202 
203 
204  /* build a regularly refined mesh for a simplex of dimension <= 3.
205  All simplexes have the same orientation as the original simplex.
206  */
207  static void
208  structured_mesh_for_simplex_(pconvex_structure cvs,
209  pgeometric_trans opt_gt,
210  const std::vector<base_node> *opt_gt_pts,
211  short_type k, pbasic_mesh pm) {
212  scalar_type h = 1./k;
213  switch (cvs->dim()) {
214  case 1 :
215  {
216  base_node a(1), b(1);
217  for (short_type i = 0; i < k; ++i) {
218  a[0] = i * h; b[0] = (i+1) * h;
219  if (opt_gt) a = opt_gt->transform(a, *opt_gt_pts);
220  if (opt_gt) b = opt_gt->transform(b, *opt_gt_pts);
221  size_type na = pm->add_point(a);
222  size_type nb = pm->add_point(b);
223  pm->add_segment(na, nb);
224  }
225  }
226  break;
227  case 2 :
228  {
229  base_node A(2),B(2),C(2),D(2);
230  for (short_type i = 0; i < k; ++i) {
231  scalar_type a = i * h, b = (i+1) * h;
232  for (short_type l = 0; l+i < k; ++l) {
233  scalar_type c = l * h, d = (l+1) * h;
234  A[0] = a; A[1] = c;
235  B[0] = b; B[1] = c;
236  C[0] = a; C[1] = d;
237  D[0] = b; D[1] = d;
238  if (opt_gt) {
239  A = opt_gt->transform(A, *opt_gt_pts);
240  B = opt_gt->transform(B, *opt_gt_pts);
241  C = opt_gt->transform(C, *opt_gt_pts);
242  D = opt_gt->transform(D, *opt_gt_pts);
243  }
244  /* add triangle with correct orientation (det [B-A;C-A] > 0) */
245  size_type nA = pm->add_point(A);
246  size_type nB = pm->add_point(B);
247  size_type nC = pm->add_point(C);
248  size_type nD = pm->add_point(D);
249  pm->add_triangle(nA,nB,nC);
250  if (l+i+1 < k)
251  pm->add_triangle(nC,nB,nD);
252  }
253  }
254  }
255  break;
256  case 3 :
257  {
258  /* based on decompositions of small cubes
259  the number of tetrahedrons is k^3
260  */
261  base_node A,B,C,D,E,F,G,H;
262  for (short_type ci = 0; ci < k; ci++) {
263  scalar_type x = ci*h;
264  for (short_type cj = 0; cj < k-ci; cj++) {
265  scalar_type y=cj*h;
266  for (short_type ck = 0; ck < k-ci-cj; ck++) {
267  scalar_type z=ck*h;
268 
269  A = {x, y, z};
270  B = {x+h, y, z};
271  C = {x, y+h, z};
272  D = {x+h, y+h, z};
273  E = {x, y, z+h};
274  F = {x+h, y, z+h};
275  G = {x, y+h, z+h};
276  H = {x+h, y+h, z+h};
277  if (opt_gt) {
278  A = opt_gt->transform(A, *opt_gt_pts);
279  B = opt_gt->transform(B, *opt_gt_pts);
280  C = opt_gt->transform(C, *opt_gt_pts);
281  D = opt_gt->transform(D, *opt_gt_pts);
282  E = opt_gt->transform(E, *opt_gt_pts);
283  F = opt_gt->transform(F, *opt_gt_pts);
284  G = opt_gt->transform(G, *opt_gt_pts);
285  H = opt_gt->transform(H, *opt_gt_pts);
286  }
287  size_type t[8];
288  t[0] = pm->add_point(A);
289  t[1] = pm->add_point(B);
290  t[2] = pm->add_point(C);
291  t[4] = pm->add_point(E);
292  t[3] = t[5] = t[6] = t[7] = size_type(-1);
293  if (k > 1 && ci+cj+ck < k-1) {
294  t[3] = pm->add_point(D);
295  t[5] = pm->add_point(F);
296  t[6] = pm->add_point(G);
297  }
298  if (k > 2 && ci+cj+ck < k-2) {
299  t[7] = pm->add_point(H);
300  }
301  /**
302  Note that the orientation of each tetrahedron is the same
303  (det > 0)
304  */
305  pm->add_tetrahedron(t[0], t[1], t[2], t[4]);
306  if (k > 1 && ci+cj+ck < k-1) {
307  pm->add_tetrahedron(t[1], t[2], t[4], t[5]);
308  pm->add_tetrahedron(t[6], t[4], t[2], t[5]);
309  pm->add_tetrahedron(t[2], t[3], t[5], t[1]);
310  pm->add_tetrahedron(t[2], t[5], t[3], t[6]);
311  }
312  if (k > 2 && ci+cj+ck < k-2) {
313  pm->add_tetrahedron(t[3], t[5], t[7], t[6]);
314  }
315  }
316  }
317  }
318  }
319  break;
320  default :
321  GMM_ASSERT1(false, "Sorry, not implemented for simplices of "
322  "dimension " << int(cvs->dim()));
323  }
324  }
325 
326  static void structured_mesh_for_parallelepiped_
327  (pconvex_structure cvs, pgeometric_trans opt_gt,
328  const std::vector<base_node> *opt_gt_pts, short_type k, pbasic_mesh pm) {
329  scalar_type h = 1./k;
330  size_type n = cvs->dim();
331  size_type pow2n = (size_type(1) << n);
332  size_type powkn = 1; for (size_type i=0; i < n; ++i) powkn *= k;
333  std::vector<size_type> strides(n);
334  size_type nbpts = 1;
335  for (size_type i=0; i < n; ++i) { strides[i] = nbpts; nbpts *= (k+1); }
336  std::vector<short_type> kcnt; kcnt.resize(n+1,0);
337  std::vector<size_type> pids; pids.reserve(nbpts);
338  base_node pt(n);
339  size_type kk;
340  /* insert nodes and fill pids with their numbers */
341  while (kcnt[n] == 0) {
342  for (size_type z = 0; z < n; ++z)
343  pt[z] = h*kcnt[z];
344  if (opt_gt) pt = opt_gt->transform(pt, *opt_gt_pts);
345  pids.push_back(pm->add_point(pt));
346  kk=0;
347  while (kk <= n)
348  { kcnt[kk]++; if (kcnt[kk] == k+1) { kcnt[kk] = 0; kk++; } else break; }
349  }
350 
351  /*
352  insert convexes using node ids stored in 'pids'
353  */
354  std::vector<size_type> ppts(pow2n);
355  kcnt[n] = 0;
356  while (kcnt[n] == 0) {
357  for (kk = 0; kk < pow2n; ++kk) {
358  size_type pos = 0;
359  for (size_type z = 0; z < n; ++z) {
360  pos += kcnt[z]*strides[z];
361  if ((kk & (size_type(1) << z))) pos += strides[z];
362  }
363  ppts[kk] = pids.at(pos);
364  }
365  pm->add_convex(parallelepiped_linear_geotrans(n), ppts.begin());
366  kcnt[(kk = 0)]++;
367  while (kk < n && kcnt[kk] == k) { kcnt[kk] = 0; kcnt[++kk]++; }
368  }
369  }
370 
371  static void
372  structured_mesh_for_convex_(pconvex_structure cvs,
373  pgeometric_trans opt_gt,
374  const std::vector<base_node> *opt_gt_pts,
375  short_type k, pbasic_mesh pm) {
376  size_type nbp = basic_structure(cvs)->nb_points();
377  dim_type n = cvs->dim();
378  /* Identifying simplexes. */
379  if (nbp == size_type(n+1) &&
381  // smc.pm->write_to_file(cout);
382  structured_mesh_for_simplex_(cvs,opt_gt,opt_gt_pts,k,pm);
383  /* Identifying parallelepipeds. */
384  } else if (nbp == (size_type(1) << n) &&
386  structured_mesh_for_parallelepiped_(cvs,opt_gt,opt_gt_pts,k,pm);
387  } else if (nbp == size_type(2 * n) &&
388  basic_structure(cvs) == prism_P1_structure(n)) {
389  GMM_ASSERT1(false, "Sorry, structured_mesh not implemented for prisms.");
390  } else {
391  GMM_ASSERT1(false, "This element is not taken into account. Contact us");
392  }
393  }
394 
395  /* extract the mesh_structure on faces */
396  static void structured_mesh_of_faces_(pconvex_ref cvr, dim_type f,
397  const basic_mesh &m,
398  mesh_structure &facem) {
399  facem.clear();
400  dal::bit_vector on_face;
401  for (size_type i = 0; i < m.nb_max_points(); ++i) {
402  if (m.is_point_valid(i)) {
403  if (gmm::abs(cvr->is_in_face(f, m.points()[i])) < 1e-12)
404  on_face.add(i);
405  }
406  }
407  //cerr << "on_face=" << on_face << endl;
408  for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv) {
409  for (short_type ff=0; ff < m.structure_of_convex(cv)->nb_faces(); ++ff) {
411  ipts=m.ind_points_of_face_of_convex(cv,ff);
412  bool allin = true;
413  for (size_type i=0; i < ipts.size(); ++i) if (!on_face[ipts[i]])
414  { allin = false; break; }
415  if (allin) {
416  /* cerr << "ajout de la face " << ff << " du convexe " << cv << ":";
417  for (size_type i=0; i < ipts.size(); ++i)
418  cerr << on_face[ipts[i]] << "/" << ipts[i] << " ";
419  cerr << endl;
420  */
421  facem.add_convex(m.structure_of_convex(cv)->faces_structure()[ff],
422  ipts.begin());
423  }
424  }
425  }
426  }
427 
428  DAL_TRIPLE_KEY(str_mesh_key, pconvex_structure, short_type, bool);
429 
430  struct str_mesh_cv__ : virtual public dal::static_stored_object {
431  pconvex_structure cvs;
432  short_type n;
433  bool simplex_mesh; /* true if the convex has been splited into simplexes,
434  which were refined */
435  std::unique_ptr<basic_mesh> pm;
436  std::vector<std::unique_ptr<mesh_structure>> pfacem; /* array of mesh_structures for faces */
437  dal::bit_vector nodes_on_edges;
438  std::unique_ptr<mesh_precomposite> pmp;
439  str_mesh_cv__(pconvex_structure c, short_type k, bool smesh_) :
440  cvs(c), n(k), simplex_mesh(smesh_)
441  { DAL_STORED_OBJECT_DEBUG_CREATED(this, "cv mesh"); }
442  ~str_mesh_cv__() { DAL_STORED_OBJECT_DEBUG_DESTROYED(this,"cv mesh"); }
443  };
444 
445  typedef std::shared_ptr<const str_mesh_cv__> pstr_mesh_cv__;
446 
447  /**
448  * This function returns a mesh in pm which contains a refinement of the convex
449  * cvr if force_simplexification is false, refined convexes have the same
450  * basic_structure than cvr, if it is set to true, the cvr is decomposed
451  * into simplexes which are then refined.
452  * TODO: move it into another file and separate the pmesh_precomposite part ?
453  **/
454  void structured_mesh_for_convex(pconvex_ref cvr, short_type k,
455  pbasic_mesh &pm, pmesh_precomposite &pmp,
456  bool force_simplexification) {
457  size_type n = cvr->structure()->dim();
458  size_type nbp = basic_structure(cvr->structure())->nb_points();
459 
460  force_simplexification = force_simplexification || (nbp == n+1);
461  dal::pstatic_stored_object_key
462  pk = std::make_shared<str_mesh_key>(basic_structure(cvr->structure()),
463  k, force_simplexification);
464 
465  dal::pstatic_stored_object o = dal::search_stored_object(pk);
466  pstr_mesh_cv__ psmc;
467  if (o)
468  psmc = std::dynamic_pointer_cast<const str_mesh_cv__>(o);
469  else {
470 
471  auto ppsmc = std::make_shared<str_mesh_cv__>
472  (basic_structure(cvr->structure()), k, force_simplexification);
473  str_mesh_cv__ &smc(*ppsmc);
474  psmc = ppsmc;
475 
476  smc.pm = std::make_unique<basic_mesh>();
477 
478  if (force_simplexification) {
479  // cout << "cvr = " << int(cvr->structure()->dim()) << " : "
480  // << cvr->structure()->nb_points() << endl;
481  const mesh_structure* splx_mesh
482  = basic_convex_ref(cvr)->simplexified_convex();
483  /* splx_mesh is correctly oriented */
484  for (size_type ic=0; ic < splx_mesh->nb_convex(); ++ic) {
485  std::vector<base_node> cvpts(splx_mesh->nb_points_of_convex(ic));
486  pgeometric_trans sgt
487  = simplex_geotrans(cvr->structure()->dim(), 1);
488  for (size_type j=0; j < cvpts.size(); ++j) {
489  size_type ip = splx_mesh->ind_points_of_convex(ic)[j];
490  cvpts[j] = basic_convex_ref(cvr)->points()[ip];
491  //cerr << "cvpts[" << j << "]=" << cvpts[j] << endl;
492  }
493  structured_mesh_for_convex_(splx_mesh->structure_of_convex(ic),
494  sgt, &cvpts, k, smc.pm.get());
495  }
496  } else {
497  structured_mesh_for_convex_(cvr->structure(), 0, 0, k, smc.pm.get());
498  }
499  smc.pfacem.resize(cvr->structure()->nb_faces());
500  for (dim_type f=0; f < cvr->structure()->nb_faces(); ++f) {
501  smc.pfacem[f] = std::make_unique<mesh_structure>();
502  structured_mesh_of_faces_(cvr, f, *(smc.pm), *(smc.pfacem[f]));
503  }
504 
505  smc.pmp = std::make_unique<mesh_precomposite>(*(smc.pm));
506  dal::add_stored_object(pk, psmc, basic_structure(cvr->structure()));
507  }
508  pm = psmc->pm.get();
509  pmp = psmc->pmp.get();
510  }
511 
512  const basic_mesh *
514  pbasic_mesh pm; pmesh_precomposite pmp;
515  structured_mesh_for_convex(cvr, k, pm, pmp, true);
516  return pm;
517  }
518 
519  const std::vector<std::unique_ptr<mesh_structure>>&
521  dal::pstatic_stored_object_key
522  pk = std::make_shared<str_mesh_key>(basic_structure(cvr->structure()),
523  k, true);
524  dal::pstatic_stored_object o = dal::search_stored_object(pk);
525  if (o) {
526  pstr_mesh_cv__ psmc = std::dynamic_pointer_cast<const str_mesh_cv__>(o);
527  return psmc->pfacem;
528  }
529  else GMM_ASSERT1(false,
530  "call refined_simplex_mesh_for_convex first (or fix me)");
531  }
532 
533 } /* end of namespace getfem. */
indexed array reference (given a container X, and a set of indexes I, this class provides a pseudo-co...
Definition: gmm_ref.h:289
pconvex_ref basic_convex_ref(pconvex_ref cvr)
return the associated order 1 reference convex.
short_type nb_points_of_convex(size_type ic) const
Return the number of points of convex ic.
base class for static stored objects
Handle composite polynomials.
const basic_mesh * refined_simplex_mesh_for_convex(pconvex_ref cvr, short_type k)
simplexify a convex_ref.
pconvex_structure prism_P1_structure(dim_type nc)
Give a pointer on the structures of a prism of dimension d.
pconvex_structure structure_of_convex(size_type ic) const
Return the pconvex_structure of the convex ic.
void clear()
erase the mesh
pstatic_stored_object search_stored_object(pstatic_stored_object_key k)
Gives a pointer to an object from a key pointer.
const std::vector< std::unique_ptr< mesh_structure > > & refined_simplex_mesh_for_convex_faces(pconvex_ref cvr, short_type k)
simplexify the faces of a convex_ref
void derivative(short_type k)
Derivative of P with respect to the variable k. P contains the result.
Definition: bgeot_poly.h:421
std::shared_ptr< const convex_structure > pconvex_structure
Pointer on a convex structure description.
size_type nb_convex() const
The total number of convexes in the mesh.
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o, permanence perm)
Add an object with two optional dependencies.
void structured_mesh_for_convex(pconvex_ref cvr, short_type k, pbasic_mesh &pm, pmesh_precomposite &pmp, bool force_simplexification)
This function returns a mesh in pm which contains a refinement of the convex cvr if force_simplexific...
int operator()(const base_node &x, const base_node &y) const
comparaison function
A simple singleton implementation.
short_type dim() const
Gives the dimension (number of variables)
Definition: bgeot_poly.h:199
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.
size_type add_convex(pconvex_structure cs, ITER ipts, bool *present=0)
Insert a new convex in the mesh_structure.
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.
pconvex_structure basic_structure(pconvex_structure cv)
Original structure (if concerned)
Mesh structure definition.
short_type degree() const
Gives the degree of the polynomial.
Definition: bgeot_poly.h:193
Basic Geometric Tools.
const ind_cv_ct & ind_points_of_convex(size_type ic) const
Return a container to the list of points attached to convex ic.
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation