27   void parallelepiped_regular_simplex_mesh_
 
   28   (mesh &me, dim_type N, 
const base_node &org,
 
   29    const base_small_vector *ivect, 
const size_type *iref) {
 
   33     if (N >= 5) GMM_WARNING1(
"CAUTION : Simplexification in dimension >= 5 " 
   34                              "has not been tested and the resulting mesh " 
   35                              "should be not conformal");
 
   43     for (i = 0; i < nbpt; ++i) {
 
   45       for (dim_type n = 0; n < N; ++n)
 
   46         gmm::add(gmm::scaled(ivect[n],pararef.points()[i][n]),a);
 
   47       pararef.points()[i] = a;
 
   53     std::vector<size_type> tab1(N+1), tab(N), tab3(nbpt);
 
   55     std::fill(tab.begin(), tab.end(), 0);
 
   56     while (tab[N-1] != iref[N-1]) {
 
   57       for (a = org, i = 0; i < N; i++)
 
   58         gmm::add(gmm::scaled(ivect[i],scalar_type(tab[i])),a);
 
   61       for (i = 0; i < nbpt; i++)
 
   62         tab3[i] = me.add_point(a + pararef.points()[i]);
 
   64       for (i = 0; i < nbs; i++) {
 
   66         for (dim_type l = 0; l <= N; l++)
 
   68           tab1[l] = tab3[(tab2[l]
 
   69                           + (((total & 1) && N != 3) ? (nbpt/2) : 0)) % nbpt];
 
   70         me.add_simplex(N, tab1.begin());
 
   73       for (dim_type l = 0; l < N; l++) {
 
   75         if (l < N-1 && tab[l] >= iref[l]) { total -= tab[l]; tab[l] = 0; }
 
   82   void parallelepiped_regular_prism_mesh_
 
   83   (mesh &me, dim_type N, 
const base_node &org,
 
   84    const base_small_vector *ivect, 
const size_type *iref) {
 
   86     parallelepiped_regular_simplex_mesh_(aux, dim_type(N-1), org, ivect, iref);
 
   87     std::vector<base_node> ptab(2 * N);
 
   89     for (dal::bv_visitor cv(aux.convex_index()); !cv.finished(); ++cv) {
 
   90       std::copy(aux.points_of_convex(cv).begin(),
 
   91                 aux.points_of_convex(cv).end(), ptab.begin());
 
   93       for (
size_type k = 0; k < iref[N-1]; ++k) {
 
   95         for (dim_type j = 0; j < N; ++j) ptab[j+N] = ptab[j] + ivect[N-1];
 
   96         me.add_prism_by_points(N, ptab.begin());
 
   98         std::copy(ptab.begin()+N, ptab.end(), ptab.begin());
 
  103   void parallelepiped_regular_mesh_
 
  104   (mesh &me, dim_type N, 
const base_node &org,
 
  105    const base_small_vector *ivect, 
const size_type *iref, 
bool linear_gt) {
 
  111     for (i = 0; i < nbpt; ++i) {
 
  113       for (dim_type n = 0; n < N; ++n)
 
  114         gmm::add(gmm::scaled(ivect[n],pararef.points()[i][n]),a);
 
  116       pararef.points()[i] = a;
 
  119     std::vector<size_type> tab1(N+1), tab(N), tab3(nbpt);
 
  121     std::fill(tab.begin(), tab.end(), 0);
 
  122     while (tab[N-1] != iref[N-1]) {
 
  123       for (a = org, i = 0; i < N; i++)
 
  124         gmm::add(gmm::scaled(ivect[i], scalar_type(tab[i])),a);
 
  127       for (i = 0; i < nbpt; i++)
 
  128         tab3[i] = me.add_point(a + pararef.points()[i]);
 
  129       me.add_convex(linear_gt ?
 
  130                     bgeot::parallelepiped_linear_geotrans(N) :
 
  131                     bgeot::parallelepiped_geotrans(N, 1), tab3.begin());
 
  133       for (dim_type l = 0; l < N; l++) {
 
  135         if (l < N-1 && tab[l] >= iref[l]) { total -= tab[l]; tab[l] = 0; }
 
  141   void parallelepiped_regular_pyramid_mesh_
 
  142   (mesh &me, 
const base_node &org,
 
  143    const base_small_vector *ivect, 
const size_type *iref) {
 
  147     base_node a = org, barycenter(N);
 
  150     for (i = 0; i < nbpt; ++i) {
 
  152       for (dim_type n = 0; n < N; ++n)
 
  153         gmm::add(gmm::scaled(ivect[n],pararef.points()[i][n]),a);
 
  155       pararef.points()[i] = a;
 
  158     barycenter /= double(nbpt);
 
  160     std::vector<size_type> tab1(N+1), tab(N), tab3(nbpt);
 
  162     std::fill(tab.begin(), tab.end(), 0);
 
  163     while (tab[N-1] != iref[N-1]) {
 
  164       for (a = org, i = 0; i < N; i++)
 
  165         gmm::add(gmm::scaled(ivect[i], scalar_type(tab[i])),a);
 
  168       for (i = 0; i < nbpt; i++)
 
  169         tab3[i] = me.add_point(a + pararef.points()[i]);
 
  170       size_type ib = me.add_point(a + barycenter);
 
  171       me.add_pyramid(tab3[0],tab3[1],tab3[2],tab3[3],ib);
 
  172       me.add_pyramid(tab3[4],tab3[6],tab3[5],tab3[7],ib);
 
  173       me.add_pyramid(tab3[0],tab3[4],tab3[1],tab3[5],ib);
 
  174       me.add_pyramid(tab3[1],tab3[5],tab3[3],tab3[7],ib);
 
  175       me.add_pyramid(tab3[3],tab3[7],tab3[2],tab3[6],ib);
 
  176       me.add_pyramid(tab3[2],tab3[6],tab3[0],tab3[4],ib);
 
  178       for (dim_type l = 0; l < N; l++) {
 
  180         if (l < N-1 && tab[l] >= iref[l]) { total -= tab[l]; tab[l] = 0; }
 
  188   static base_node shake_func(
const base_node& x) {
 
  189     base_node z(x.size());
 
  190     scalar_type c1 = 1., c2 = 1.;
 
  192       c1*=(x[i]*(1.-x[i]));
 
  193       c2*=(.5 - gmm::abs(x[i]-.5));
 
  202   static base_node radial_deformation(
const base_node& x) {
 
  203     GMM_ASSERT1(x.size() == 2, 
"For two-dimensional meshes only. \n");
 
  204     base_node z(x.size());
 
  207     scalar_type r = sqrt( z[0] * z[0] + z[1] * z[1] ) ;
 
  208     scalar_type theta = atan2(z[1], z[0]);
 
  209     if ( r < 0.5 - 1.e-6)
 
  211     theta += 10000. * gmm::sqrt(r) * (0.5 - r) * (0.5 - r) * (0.5 - r) * (0.5 - r) * (0.1 - r) * (0.15 - r)  ;
 
  212     z[0] = r * cos(theta) + 0.5;
 
  213     z[1] = r * sin(theta) + 0.5;
 
  217   static void noise_unit_mesh(mesh& m, std::vector<size_type> nsubdiv,
 
  220     for (dal::bv_visitor ip(m.points().index()); !ip.finished(); ++ip) {
 
  221       bool is_border = 
false;
 
  222       base_node& P = m.points()[ip];
 
  224         if (gmm::abs(P[i]) < 1e-10 || gmm::abs(P[i]-1.) < 1e-10)
 
  229         if (N == 2) P = radial_deformation(P) ;
 
  231           P[i] += 0.*(
double(1)/
double(nsubdiv[i]* pgt->complexity()))
 
  232             * gmm::random(
double());
 
  241     dim_type N = dim_type(nsubdiv.size());
 
  242     base_node org(N); gmm::clear(org);
 
  243     std::vector<base_small_vector> vtab(N);
 
  244     for (dim_type i = 0; i < N; i++) {
 
  245       vtab[i] = base_small_vector(N); gmm::clear(vtab[i]);
 
  246       (vtab[i])[i] = 1. / scalar_type(nsubdiv[i]) * 1.;
 
  249       getfem::parallelepiped_regular_simplex_mesh
 
  250         (msh, N, org, vtab.begin(), nsubdiv.begin());
 
  252       getfem::parallelepiped_regular_mesh
 
  253         (msh, N, org, vtab.begin(), nsubdiv.begin());
 
  255       getfem::parallelepiped_regular_prism_mesh
 
  256         (msh, N, org, vtab.begin(), nsubdiv.begin());
 
  258       getfem::parallelepiped_regular_pyramid_mesh
 
  259         (msh, org, vtab.begin(), nsubdiv.begin());
 
  261       GMM_ASSERT1(
false, 
"cannot build a regular mesh for " 
  267     for (dal::bv_visitor cv(msh.
convex_index()); !cv.finished(); ++cv) {
 
  268       if (pgt == msh.trans_of_convex(cv)) {
 
  270                                msh.points_of_convex(cv).begin());
 
  272         std::vector<base_node> pts(pgt->nb_points());
 
  273         for (
size_type i=0; i < pgt->nb_points(); ++i) {
 
  274           pts[i] = msh.trans_of_convex(cv)->transform
 
  275             (pgt->convex_ref()->points()[i], msh.points_of_convex(cv));
 
  282     if (noised) noise_unit_mesh(m, nsubdiv, pgt);
 
  290     std::stringstream s(st);
 
  291     bgeot::md_param PARAM;
 
  292     PARAM.read_param_file(s);
 
  294     std::string GT = PARAM.string_value(
"GT");
 
  295     GMM_ASSERT1(!GT.empty(), 
"regular mesh : you have at least to " 
  296                 "specify the geometric transformation");
 
  300     base_small_vector org(N); gmm::clear(org);
 
  302     const auto &o = PARAM.array_value(
"ORG");
 
  304       GMM_ASSERT1(o.size() == N,
 
  305                   "ORG parameter should be an array of size " << N);
 
  307         GMM_ASSERT1(o[i].type_of_param() == bgeot::md_param::REAL_VALUE,
 
  308                     "ORG should be a real array.");
 
  309         org[i] = o[i].real();
 
  313     bool noised = (PARAM.int_value(
"NOISED") != 0);
 
  315     std::vector<size_type> nsubdiv(N);
 
  316     gmm::fill(nsubdiv, 2);
 
  317     const auto &ns = PARAM.array_value(
"NSUBDIV");
 
  319       GMM_ASSERT1(ns.size() == N,
 
  320                   "NSUBDIV parameter should be an array of size " << N);
 
  322         GMM_ASSERT1(ns[i].type_of_param() == bgeot::md_param::REAL_VALUE,
 
  323                     "NSUBDIV should be an integer array");
 
  324         nsubdiv[i] = 
size_type(ns[i].real()+0.5);
 
  328     base_small_vector sizes(N);
 
  329     gmm::fill(sizes, 1.0);
 
  331     const auto &si = PARAM.array_value(
"SIZES");
 
  333       GMM_ASSERT1(si.size() == N,
 
  334                   "SIZES parameter should be an array of size " << N);
 
  336         GMM_ASSERT1(si[i].type_of_param() == bgeot::md_param::REAL_VALUE,
 
  337                     "SIZES should be a real array");
 
  338         sizes[i] = si[i].real();
 
  345     for (
size_type i=0; i < N; ++i) M(i,i) = sizes[i];
 
  353     std::stringstream s(st);
 
  354     bgeot::md_param PARAM;
 
  355     PARAM.read_param_file(s);
 
  357     std::string GT = PARAM.string_value(
"GT");
 
  358     GMM_ASSERT1(!GT.empty(), 
"regular ball mesh : you have at least to " 
  359                 "specify the geometric transformation");
 
  363     base_small_vector org(N);
 
  365     const auto &o = PARAM.array_value(
"ORG");
 
  367       GMM_ASSERT1(o.size() == N,
 
  368                   "ORG parameter should be an array of size " << N);
 
  370         GMM_ASSERT1(o[i].type_of_param() == bgeot::md_param::REAL_VALUE,
 
  371                     "ORG should be a real array");
 
  372         org[i] = o[i].real();
 
  377     bool noised = (PARAM.int_value(
"NOISED") != 0);
 
  380     const auto &ns = PARAM.array_value(
"NSUBDIV");
 
  382       GMM_ASSERT1(ns.size() == 2,
 
  383                   "NSUBDIV parameter should be an array of size 2");
 
  385         GMM_ASSERT1(ns[i].type_of_param() == bgeot::md_param::REAL_VALUE,
 
  386                     "NSUBDIV should be an integer array");
 
  391     scalar_type radius(1), core_ratio(M_SQRT1_2);
 
  392     const auto &si = PARAM.array_value(
"SIZES");
 
  394       GMM_ASSERT1(si.size() == 1,
 
  395                   "SIZES parameter should be an array of size 1");
 
  396       GMM_ASSERT1(si[0].type_of_param() == bgeot::md_param::REAL_VALUE,
 
  397                   "SIZES should be a real array");
 
  398       radius = si[0].real();
 
  401     std::vector<size_type> nsubdiv(N);
 
  402     gmm::fill(nsubdiv, nsubdiv0);
 
  404     std::vector<mesh> mm(N);
 
  406       gmm::fill(nsubdiv, nsubdiv0);
 
  407       nsubdiv[i] = nsubdiv1;
 
  412     for (
size_type i=0; i < N; ++i) M(i,i) = core_ratio;
 
  415     scalar_type peel_ratio = scalar_type(1)-core_ratio; 
 
  418       MM(i,i) = peel_ratio;
 
  419       mm[i].transformation(MM);
 
  421       std::vector<base_node> pts(mm[i].points().card(), base_node(N));
 
  423       for (dal::bv_visitor pt(mm[i].points().index()); !pt.finished(); ++pt, ++j) {
 
  424         pts[j] = mm[i].points()[pt];
 
  425         for (
unsigned k=0; k < N; ++k)
 
  426           if (k != i) pts[j][k] += (pts[j][k]/core_ratio) * pts[j][i];
 
  429       for (dal::bv_visitor pt(mm[i].points().index()); !pt.finished(); ++pt, ++j)
 
  430           mm[i].points()[pt] = pts[j];
 
  432       base_small_vector trsl(N);
 
  433       trsl[i] = core_ratio;
 
  434       mm[i].translation(trsl);
 
  435       for (dal::bv_visitor cv(mm[i].convex_index()); !cv.finished(); ++cv)
 
  437                                mm[i].points_of_convex(cv).begin());
 
  440     std::vector<base_node> pts(m.points().card(), base_node(N));
 
  442     for (dal::bv_visitor pt(m.points().index()); !pt.finished(); ++pt, ++j) {
 
  443       pts[j] = m.points()[pt];
 
  444       scalar_type maxcoord(0);
 
  447         if (gmm::abs(pts[j][k]) > maxcoord) {
 
  448           maxcoord = gmm::abs(pts[j][k]);
 
  451       if (maxcoord > 1e-10) {
 
  452         scalar_type l(0), l0(0);
 
  455             scalar_type theta = M_PI_4 * pts[j][k] / maxcoord;
 
  456             scalar_type c0 = std::min(scalar_type(1), maxcoord);
 
  457             pts[j][k] = c0*tan(theta)* maxcoord + (scalar_type(1)-c0)*pts[j][k];
 
  459           l += pts[j][k] * pts[j][k];
 
  463         scalar_type scale(radius);
 
  464         scalar_type c(core_ratio);
 
  465         c *= std::max(scalar_type(0.3),
 
  466                       (scalar_type(1) - sqrt(l0*l0 - scalar_type(1))));
 
  468           scale -= (l - c) / (l0 - c) * (radius - radius/(l/maxcoord));
 
  475     for (dal::bv_visitor pt(m.points().index()); !pt.finished(); ++pt, ++j)
 
  476       m.points()[pt] = pts[j];
 
  479     size_type symmetries(PARAM.int_value(
"SYMMETRIES"));
 
  480     symmetries = std::min(symmetries,N);
 
  482     for (
size_type sym=0; sym < N-symmetries; ++sym) {
 
  486         M(sym,sym0) = scalar_type(-1);
 
  487         M(sym0,sym) = scalar_type(1);
 
  489           if (i != sym && i != sym0) M(i,i) = scalar_type(1);
 
  491         base_matrix M1(M), M2(M);
 
  497       for (dal::bv_visitor cv(m0.
convex_index()); !cv.finished(); ++cv)
 
  499                                m0.points_of_convex(cv).begin());
 
  506     std::stringstream s(st);
 
  507     bgeot::md_param PARAM;
 
  508     PARAM.read_param_file(s);
 
  510     std::string GT = PARAM.string_value(
"GT");
 
  511     GMM_ASSERT1(!GT.empty(), 
"regular ball mesh : you have at least to " 
  512                 "specify the geometric transformation");
 
  516     base_small_vector org(N);
 
  517     const auto &o = PARAM.array_value(
"ORG");
 
  519       GMM_ASSERT1(o.size() == N,
 
  520                   "ORG parameter should be an array of size " << N);
 
  522         GMM_ASSERT1(o[i].type_of_param() == bgeot::md_param::REAL_VALUE,
 
  523                     "ORG should be a real array");
 
  524         org[i] = o[i].real();
 
  529     bool noised = (PARAM.int_value(
"NOISED") != 0);
 
  532     const auto &ns = PARAM.array_value(
"NSUBDIV");
 
  534       GMM_ASSERT1(ns.size() == 2,
 
  535                   "NSUBDIV parameter should be an array of size 2");
 
  537         GMM_ASSERT1(ns[i].type_of_param() == bgeot::md_param::REAL_VALUE,
 
  538                     "NSUBDIV should be an integer array");
 
  543     scalar_type radius(1), thickness(0.5);
 
  544     const auto &si = PARAM.array_value(
"SIZES");
 
  546       GMM_ASSERT1(si.size() == 2,
 
  547                   "SIZES parameter should be an array of size 2");
 
  548       GMM_ASSERT1(si[0].type_of_param() == bgeot::md_param::REAL_VALUE &&
 
  549                   si[1].type_of_param() == bgeot::md_param::REAL_VALUE ,
 
  550                   "SIZES should be a real array");
 
  551       radius = si[0].real();
 
  552       thickness = si[1].real();
 
  555     std::vector<size_type> nsubdiv(N, nsubdiv0);
 
  556     nsubdiv[N-1] = nsubdiv1;
 
  561     std::vector<base_node> pts(m0.points().card(), base_node(N));
 
  563     for (dal::bv_visitor pt(m0.points().index()); !pt.finished(); ++pt, ++j) {
 
  564       pts[j] = m0.points()[pt];
 
  567         pts[j][k] = tan(pts[j][k]*M_PI_4);
 
  568         l += pts[j][k]*pts[j][k];
 
  571       scalar_type r(radius-thickness+thickness*pts[j][N-1]);
 
  578     for (dal::bv_visitor pt(m0.points().index()); !pt.finished(); ++pt, ++j)
 
  579       m0.points()[pt] = pts[j];
 
  580     m0.points().resort();
 
  584       M(i,i+1) = scalar_type(1);
 
  585     M(N-1,0) = scalar_type(1);
 
  589       for (dal::bv_visitor cv(m0.
convex_index()); !cv.finished(); ++cv)
 
  591                                m0.points_of_convex(cv).begin());
 
  594     size_type symmetries(PARAM.int_value(
"SYMMETRIES"));
 
  595     symmetries = std::min(symmetries,N);
 
  597     for (
size_type sym=0; sym < N-symmetries; ++sym) {
 
  601         M(sym,sym0) = scalar_type(-1);
 
  602         M(sym0,sym) = scalar_type(1);
 
  604           if (i != sym && i != sym0) M(i,i) = scalar_type(1);
 
  606         base_matrix M1(M), M2(M);
 
  611       for (dal::bv_visitor cv(m0.
convex_index()); !cv.finished(); ++cv)
 
  613                                m0.points_of_convex(cv).begin());
 
Mesh structure definition.
const dal::bit_vector & convex_index() const
Return the list of valid convex IDs.
size_type nb_convex() const
The total number of convexes in the mesh.
const ind_set & ind_points_of_convex(size_type ic) const
Return a container to the list of points attached to convex ic.
Describe a mesh (collection of convexes (elements) and points).
void transformation(const base_matrix &)
apply the given matrix transformation to each mesh node.
void optimize_structure(bool with_renumbering=true)
Pack the mesh : renumber convexes and nodes such that there is no holes in their numbering.
void copy_from(const mesh &m)
Clone a mesh.
void clear()
Erase the mesh.
void translation(const base_small_vector &)
Apply the given translation to each mesh node.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
size_type add_convex_by_points(bgeot::pgeometric_trans pgt, ITER ipts, const scalar_type tol=scalar_type(0))
Add a convex to the mesh, given a geometric transformation and a list of point coordinates.
pconvex_structure pyramid_QK_structure(dim_type k)
Give a pointer on the 3D pyramid structure for a degree k = 1 or 2.
std::string name_of_geometric_trans(pgeometric_trans p)
Get the string name of a geometric transformation.
pconvex_structure parallelepiped_structure(dim_type nc, dim_type k)
Give a pointer on the structures of a parallelepiped of dimension d.
pconvex_structure prism_P1_structure(dim_type nc)
Give a pointer on the structures of a prism of dimension d.
pconvex_ref parallelepiped_of_reference(dim_type nc, dim_type k)
parallelepiped of reference of dimension nc (and degree 1)
pconvex_structure simplex_structure(dim_type nc)
Give a pointer on the structures of a simplex of dimension d.
pgeometric_trans geometric_trans_descriptor(std::string name)
Get the geometric transformation from its string name.
size_t size_type
used as the common size type in the library
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
GEneric Tool for Finite Element Methods.
void regular_mesh(mesh &m, const std::string &st)
Build a regular mesh parametrized by the string st.
void regular_ball_mesh(mesh &m, const std::string &st)
Build a regular mesh on a ball, parametrized by the string st.
void regular_unit_mesh(mesh &m, std::vector< size_type > nsubdiv, bgeot::pgeometric_trans pgt, bool noised=false)
Build a regular mesh of the unit square/cube/, etc.
void regular_ball_shell_mesh(mesh &m, const std::string &st)
Build a regular mesh on a ball shell, parametrized by the string st.