28 inline scalar_type sfloor(scalar_type x)
29 {
return (x >= 0) ? floor(x) : -floor(-x); }
35 scalar_type c1 = c_max, c2 = c_max * scalar_type(base);
36 GMM_ASSERT2(y.size() == s,
"dimension error");
38 base_node::const_iterator itx=x.begin(), itex=x.end(), ity=y.begin();
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);
47 if (ret == 0) {
if (a < b) ret = -1;
else if (a > b) ret = 1; }
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;
65 mesh_precomposite::mesh_precomposite(
const basic_mesh &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]);
73 for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv) {
78 GMM_ASSERT1(pgt->is_linear() && N == P,
"Bad geometric transformation");
80 base_matrix G(P, pgt->nb_points());
81 base_matrix pc(pgt->nb_points() , N);
84 m.points_of_convex(cv, G);
87 pgt->poly_vector_grad(x, pc);
89 gmm::mult(gmm::transposed(pc), gmm::transposed(G), B0);
90 det[cv] = gmm::lu_inverse(B0);
92 orgs[cv] = m.points_of_convex(cv)[0];
96 scalar_type polynomial_composite::eval(
const base_node &pt)
const {
98 std::vector<bool> elt(mp->linked_mesh().nb_convex(),
true);
99 mesh_structure::ind_cv_ct::const_iterator itc, itce;
101 mesh_precomposite::PTAB::const_sorted_iterator
102 it1 = mp->vertexes.sorted_ge(pt), it2 = it1;
105 --it2; i2 = it2.index();
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)
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()));
128 ++it1; i1 = it1.index();
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)
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()));
149 --it2; i2 = it2.index();
152 GMM_ASSERT1(
false,
"Element not found in composite polynomial: " << pt);
157 polynomial_composite::polynomial_composite(
158 const mesh_precomposite &m,
bool lc)
159 : mp(&m), local_coordinate(lc), default_poly(mp->dim(), 0) {}
161 void polynomial_composite::derivative(
short_type k) {
162 if (local_coordinate) {
163 dim_type N = mp->dim();
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);
170 auto &poly = poly_of_subelt(ic);
171 for (dim_type n = 0; n < N; ++n) {
176 if (polytab.find(ic) != polytab.end()) set_poly_of_subelt(ic, P);
180 for (
size_type ic = 0; ic < mp->nb_convex(); ++ic) {
181 auto poly = poly_of_subelt(ic);
183 if (polytab.find(ic) != polytab.end()) set_poly_of_subelt(ic, poly);
188 auto poly_key = std::make_shared<base_poly_key>(poly.
degree(), poly.
dim(), poly);
191 o = std::make_shared<base_poly>(poly);
194 polytab[l] = poly_key;
198 auto it = polytab.find(l);
199 if (it == polytab.end())
return default_poly;
210 const std::vector<base_node> *opt_gt_pts,
212 scalar_type h = 1./k;
213 switch (cvs->dim()) {
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);
223 pm->add_segment(na, nb);
231 scalar_type a = i * h, b = (i+1) * h;
233 scalar_type c = l * h, d = (l+1) * h;
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);
249 pm->add_triangle(nA,nB,nC);
251 pm->add_triangle(nC,nB,nD);
263 scalar_type x = ci*h;
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);
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);
298 if (k > 2 && ci+cj+ck < k-2) {
299 t[7] = pm->add_point(H);
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]);
312 if (k > 2 && ci+cj+ck < k-2) {
313 pm->add_tetrahedron(t[3], t[5], t[7], t[6]);
321 GMM_ASSERT1(
false,
"Sorry, not implemented for simplices of " 322 "dimension " <<
int(cvs->dim()));
326 static void structured_mesh_for_parallelepiped_
328 const std::vector<base_node> *opt_gt_pts,
short_type k, pbasic_mesh pm) {
329 scalar_type h = 1./k;
333 std::vector<size_type> strides(n);
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);
341 while (kcnt[n] == 0) {
344 if (opt_gt) pt = opt_gt->transform(pt, *opt_gt_pts);
345 pids.push_back(pm->add_point(pt));
348 { kcnt[kk]++;
if (kcnt[kk] == k+1) { kcnt[kk] = 0; kk++; }
else break; }
354 std::vector<size_type> ppts(pow2n);
356 while (kcnt[n] == 0) {
357 for (kk = 0; kk < pow2n; ++kk) {
360 pos += kcnt[z]*strides[z];
361 if ((kk & (
size_type(1) << z))) pos += strides[z];
363 ppts[kk] = pids.at(pos);
365 pm->add_convex(parallelepiped_linear_geotrans(n), ppts.begin());
367 while (kk < n && kcnt[kk] == k) { kcnt[kk] = 0; kcnt[++kk]++; }
374 const std::vector<base_node> *opt_gt_pts,
377 dim_type n = cvs->dim();
382 structured_mesh_for_simplex_(cvs,opt_gt,opt_gt_pts,k,pm);
386 structured_mesh_for_parallelepiped_(cvs,opt_gt,opt_gt_pts,k,pm);
389 GMM_ASSERT1(
false,
"Sorry, structured_mesh not implemented for prisms.");
391 GMM_ASSERT1(
false,
"This element is not taken into account. Contact us");
396 static void structured_mesh_of_faces_(pconvex_ref cvr, dim_type f,
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)
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);
413 for (
size_type i=0; i < ipts.size(); ++i)
if (!on_face[ipts[i]])
414 { allin =
false;
break; }
421 facem.
add_convex(m.structure_of_convex(cv)->faces_structure()[ff],
435 std::unique_ptr<basic_mesh> pm;
436 std::vector<std::unique_ptr<mesh_structure>> pfacem;
437 dal::bit_vector nodes_on_edges;
438 std::unique_ptr<mesh_precomposite> pmp;
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"); }
445 typedef std::shared_ptr<const str_mesh_cv__> pstr_mesh_cv__;
455 pbasic_mesh &pm, pmesh_precomposite &pmp,
456 bool force_simplexification) {
460 force_simplexification = force_simplexification || (nbp == n+1);
461 dal::pstatic_stored_object_key
463 k, force_simplexification);
468 psmc = std::dynamic_pointer_cast<
const str_mesh_cv__>(o);
471 auto ppsmc = std::make_shared<str_mesh_cv__>
473 str_mesh_cv__ &smc(*ppsmc);
476 smc.pm = std::make_unique<basic_mesh>();
478 if (force_simplexification) {
487 = simplex_geotrans(cvr->structure()->dim(), 1);
488 for (
size_type j=0; j < cvpts.size(); ++j) {
494 sgt, &cvpts, k, smc.pm.get());
497 structured_mesh_for_convex_(cvr->structure(), 0, 0, k, smc.pm.get());
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]));
505 smc.pmp = std::make_unique<mesh_precomposite>(*(smc.pm));
509 pmp = psmc->pmp.get();
514 pbasic_mesh pm; pmesh_precomposite pmp;
519 const std::vector<std::unique_ptr<mesh_structure>>&
521 dal::pstatic_stored_object_key
526 pstr_mesh_cv__ psmc = std::dynamic_pointer_cast<
const str_mesh_cv__>(o);
529 else GMM_ASSERT1(
false,
530 "call refined_simplex_mesh_for_convex first (or fix me)");
indexed array reference (given a container X, and a set of indexes I, this class provides a pseudo-co...
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.
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
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)
gmm::uint16_type short_type
used as the common short type integer in the library
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.
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