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");
301 base_small_vector org(N); gmm::clear(org);
303 const std::vector<bgeot::md_param::param_value> &o
304 = PARAM.array_value(
"ORG");
306 GMM_ASSERT1(o.size() == N,
"ORG parameter should be an array of size " 309 GMM_ASSERT1(o[i].type_of_param() == bgeot::md_param::REAL_VALUE,
310 "ORG should be a real array.");
311 org[i] = o[i].real();
315 bool noised = (PARAM.int_value(
"NOISED") != 0);
317 std::vector<size_type> nsubdiv(N);
318 gmm::fill(nsubdiv, 2);
319 const std::vector<bgeot::md_param::param_value> &ns
320 = PARAM.array_value(
"NSUBDIV");
322 GMM_ASSERT1(ns.size() == N,
323 "NSUBDIV parameter should be an array of size " << N);
325 GMM_ASSERT1(ns[i].type_of_param() == bgeot::md_param::REAL_VALUE,
326 "NSUBDIV should be an integer array.");
327 nsubdiv[i] =
size_type(ns[i].real()+0.5);
331 base_small_vector sizes(N);
332 gmm::fill(sizes, 1.0);
334 const std::vector<bgeot::md_param::param_value> &si
335 = PARAM.array_value(
"SIZES");
337 GMM_ASSERT1(si.size() == N,
338 "SIZES parameter should be an array of size " << N);
340 GMM_ASSERT1(si[i].type_of_param() == bgeot::md_param::REAL_VALUE,
341 "SIZES should be a real array.");
342 sizes[i] = si[i].real();
349 for (
size_type i=0; i < N; ++i) M(i,i) = sizes[i];
357 std::stringstream s(st);
358 bgeot::md_param PARAM;
359 PARAM.read_param_file(s);
361 std::string GT = PARAM.string_value(
"GT");
362 GMM_ASSERT1(!GT.empty(),
"regular ball mesh : you have at least to " 363 "specify the geometric transformation");
368 base_small_vector org(N);
370 const std::vector<bgeot::md_param::param_value> &o
371 = PARAM.array_value(
"ORG");
373 GMM_ASSERT1(o.size() == N,
"ORG parameter should be an array of size " 376 GMM_ASSERT1(o[i].type_of_param() == bgeot::md_param::REAL_VALUE,
377 "ORG should be a real array.");
378 org[i] = o[i].real();
383 bool noised = (PARAM.int_value(
"NOISED") != 0);
386 const std::vector<bgeot::md_param::param_value> &ns
387 = PARAM.array_value(
"NSUBDIV");
389 GMM_ASSERT1(ns.size() == 2,
390 "NSUBDIV parameter should be an array of size " << 2);
392 GMM_ASSERT1(ns[i].type_of_param() == bgeot::md_param::REAL_VALUE,
393 "NSUBDIV should be an integer array.");
398 scalar_type radius(1), core_ratio(M_SQRT1_2);
399 const std::vector<bgeot::md_param::param_value> &si
400 = PARAM.array_value(
"SIZES");
402 GMM_ASSERT1(si.size() == 1,
403 "SIZES parameter should be an array of size " << 1);
404 GMM_ASSERT1(si[0].type_of_param() == bgeot::md_param::REAL_VALUE,
405 "SIZES should be a real array.");
406 radius = si[0].real();
410 std::vector<size_type> nsubdiv(N);
411 gmm::fill(nsubdiv, nsubdiv0);
413 std::vector<mesh> mm(N);
415 gmm::fill(nsubdiv, nsubdiv0);
416 nsubdiv[i] = nsubdiv1;
421 for (
size_type i=0; i < N; ++i) M(i,i) = core_ratio;
424 scalar_type peel_ratio = scalar_type(1)-core_ratio;
427 MM(i,i) = peel_ratio;
428 mm[i].transformation(MM);
430 std::vector<base_node> pts(mm[i].points().card(), base_node(N));
432 for (dal::bv_visitor pt(mm[i].points().index()); !pt.finished(); ++pt, ++j) {
433 pts[j] = mm[i].points()[pt];
434 for (
unsigned k=0; k < N; ++k)
435 if (k != i) pts[j][k] += (pts[j][k]/core_ratio) * pts[j][i];
438 for (dal::bv_visitor pt(mm[i].points().index()); !pt.finished(); ++pt, ++j)
439 mm[i].points()[pt] = pts[j];
441 base_small_vector trsl(N);
442 trsl[i] = core_ratio;
443 mm[i].translation(trsl);
444 for (dal::bv_visitor cv(mm[i].convex_index()); !cv.finished(); ++cv)
448 std::vector<base_node> pts(m.points().card(), base_node(N));
450 for (dal::bv_visitor pt(m.points().index()); !pt.finished(); ++pt, ++j) {
451 pts[j] = m.points()[pt];
452 scalar_type maxcoord(0);
455 if (gmm::abs(pts[j][k]) > maxcoord) {
456 maxcoord = gmm::abs(pts[j][k]);
459 if (maxcoord > 1e-10) {
460 scalar_type l(0), l0(0);
463 scalar_type theta = M_PI_4 * pts[j][k] / maxcoord;
464 scalar_type c0 = std::min(scalar_type(1), maxcoord);
465 pts[j][k] = c0*tan(theta)* maxcoord + (scalar_type(1)-c0)*pts[j][k];
467 l += pts[j][k] * pts[j][k];
471 scalar_type scale(radius);
472 scalar_type c(core_ratio);
473 c *= std::max(scalar_type(0.3),
474 (scalar_type(1) - sqrt(l0*l0 - scalar_type(1))));
476 scale -= (l - c) / (l0 - c) * (radius - radius/(l/maxcoord));
483 for (dal::bv_visitor pt(m.points().index()); !pt.finished(); ++pt, ++j)
484 m.points()[pt] = pts[j];
487 size_type symmetries(PARAM.int_value(
"SYMMETRIES"));
488 symmetries = std::min(symmetries,N);
490 for (
size_type sym=0; sym < N-symmetries; ++sym) {
494 M(sym,sym0) = scalar_type(-1);
495 M(sym0,sym) = scalar_type(1);
497 if (i != sym && i != sym0) M(i,i) = scalar_type(1);
499 base_matrix M1(M), M2(M);
505 for (dal::bv_visitor cv(m0.
convex_index()); !cv.finished(); ++cv)
void optimize_structure(bool with_renumbering=true)
Pack the mesh : renumber convexes and nodes such that there is no holes in their numbering.
pconvex_structure prism_P1_structure(dim_type nc)
Give a pointer on the structures of a prism of dimension d.
Describe a mesh (collection of convexes (elements) and points).
void clear()
Erase the mesh.
pgeometric_trans geometric_trans_descriptor(std::string name)
Get the geometric transformation from its string name.
void regular_mesh(mesh &m, const std::string &st)
Build a regular mesh parametrized by the string st.
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
pconvex_structure pyramid_QK_structure(dim_type k)
Give a pointer on the 3D pyramid structure for a degree k = 1 or 2.
void copy_from(const mesh &m)
Clone a mesh.
GEneric Tool for Finite Element Methods.
void clear(L &l)
clear (fill with zeros) a vector or matrix.
pconvex_structure parallelepiped_structure(dim_type nc, dim_type k)
Give a pointer on the structures of a parallelepiped of dimension d.
std::string name_of_geometric_trans(pgeometric_trans p)
Get the string name of a geometric transformation.
pconvex_structure simplex_structure(dim_type nc)
Give a pointer on the structures of a simplex of dimension d.
pconvex_ref parallelepiped_of_reference(dim_type nc, dim_type k)
parallelepiped of reference of dimension nc (and degree 1)
void translation(const base_small_vector &)
Apply the given translation to each mesh node.
Mesh structure definition.
const ind_cv_ct & ind_points_of_convex(size_type ic) const
Return a container to the list of points attached to convex ic.
void transformation(const base_matrix &)
apply the given matrix transformation to each mesh node.
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.
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.
const dal::bit_vector & convex_index() const
Return the list of valid convex IDs.
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation