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) : box_tree{1e-13} {
 
   69   void mesh_precomposite::initialise(
const basic_mesh &m) {
 
   71     det.resize(m.nb_convex()); orgs.resize(m.nb_convex());
 
   72     gtrans.resize(m.nb_convex()); gtransinv.resize(m.nb_convex());
 
   73     for (
size_type i = 0; i <= m.points().index().last_true(); ++i)
 
   74       vertices.add(m.points()[i]);
 
   77     for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv) {
 
   82       GMM_ASSERT1(pgt->is_linear(), 
"Bad geometric transformation");
 
   84       base_matrix G(P, pgt->nb_points());
 
   87       m.points_of_convex(cv, G);
 
   90       gtransinv[cv] = ctx.B();
 
   93       auto points_of_convex = m.points_of_convex(cv);
 
   94       orgs[cv] = pgt->transform(X, G);
 
   95       bounding_box(min, max, points_of_convex);
 
   96       box_to_convexes_map[box_tree.add_box(min, max)].push_back(cv);
 
   99     box_tree.build_tree();
 
  103                  std::vector<opt_long_scalar_type>);
 
  105   polynomial_composite::polynomial_composite(
const mesh_precomposite &m,
 
  107     : mp(&m), local_coordinate(lc), faces_first(ff),
 
  108       default_polys(mp->dim()+1) {
 
  109     for (dim_type i = 0; i <= mp->dim(); ++i)
 
  110       default_polys[i] = base_poly(i, 0.);
 
  113   static void mult_diff_transposed(
const base_matrix &M, 
const base_node &p,
 
  114                                    const base_node &p1, base_node &p2) {
 
  115     for (dim_type d = 0; d < p2.size(); ++d) {
 
  117       auto col = mat_col(M, d);
 
  118       for (dim_type i = 0; i < p1.size(); ++i)
 
  119         p2[d] += col[i] * (p[i] - p1[i]);
 
  123   scalar_type polynomial_composite::eval(
const base_node &p,
 
  126       if (!local_coordinate) 
return poly_of_subelt(l).eval(p.begin());
 
  127       base_node p1(gmm::mat_ncols(mp->gtransinv[l]));
 
  128       mult_diff_transposed(mp->gtransinv[l], p, mp->orgs[l], p1);
 
  129       return poly_of_subelt(l).eval(p1.begin());
 
  132     auto dim = mp->dim();
 
  133     base_node p1_stored, p1, p2(dim);
 
  136     auto &box_tree = mp->box_tree;
 
  137     rtree::pbox_set box_list;
 
  138     box_tree.find_boxes_at_point(p, box_list);
 
  140     while (box_list.size()) {
 
  141       auto pmax_box = *box_list.begin();
 
  143       if (box_list.size() > 1) {
 
  144         auto max_rate = -1.0;
 
  145         for (
auto &&pbox : box_list) {
 
  148             auto h = pbox->max->at(i) - pbox->min->at(i);
 
  150               auto rate = std::min(pbox->max->at(i) - p[i],
 
  151                                    p[i] - pbox->min->at(i)) / h;
 
  152               box_rate = std::min(rate, box_rate);
 
  155           if (box_rate > max_rate) { pmax_box = pbox; max_rate = box_rate; }
 
  159       for (
auto cv : mp->box_to_convexes_map.at(pmax_box->id)) {
 
  160         dim_type elt_dim = dim_type(gmm::mat_ncols(mp->gtransinv[cv]));
 
  162         mult_diff_transposed(mp->gtransinv[cv], p, mp->orgs[cv], p1);
 
  163         scalar_type ddist(0);
 
  169         if (mp->trans_of_convex(cv)->convex_ref()->is_in(p1) < 1E-9
 
  171           if (!faces_first || elt_dim < dim) {
 
  172             scalar_type res = to_scalar(poly_of_subelt(cv).eval(local_coordinate
 
  173                                                      ? p1.begin() : p.begin()));
 
  176           p1_stored = p1; cv_stored = cv;
 
  180       if (box_list.size() == 1) 
break;
 
  181       box_list.erase(pmax_box);
 
  185         to_scalar(poly_of_subelt(cv_stored).eval(local_coordinate
 
  186                                               ? p1_stored.begin(): p.begin()));
 
  189     GMM_ASSERT1(
false, 
"Element not found in composite polynomial: " << p);
 
  193   void polynomial_composite::derivative(
short_type k) {
 
  194     if (local_coordinate) {
 
  195       dim_type P = mp->dim();
 
  196       base_vector e(P), f(P); e[k] = 1.0;
 
  197       for (
size_type ic = 0; ic < mp->nb_convex(); ++ic) {
 
  198         dim_type N = dim_type(gmm::mat_ncols(mp->gtransinv[ic]));
 
  200         gmm::mult(gmm::transposed(mp->gtransinv[ic]), e, f);
 
  201         base_poly Der(N, 0), Q;
 
  202         if (polytab.find(ic) != polytab.end()) {
 
  203           auto &poly = poly_of_subelt(ic);
 
  204           for (dim_type n = 0; n < N; ++n) {
 
  209           if (Der.is_zero()) polytab.erase(ic); 
else set_poly_of_subelt(ic,Der);
 
  214     for (
size_type ic = 0; ic < mp->nb_convex(); ++ic) {
 
  215       auto poly = poly_of_subelt(ic);
 
  217       if (polytab.find(ic) != polytab.end()) set_poly_of_subelt(ic, poly);
 
  221   void polynomial_composite::set_poly_of_subelt(
size_type l,
 
  222                                                 const base_poly &poly) {
 
  224       std::make_shared<base_poly_key>(poly.degree(), poly.dim(), poly);
 
  225     pstored_base_poly o(std::dynamic_pointer_cast<const stored_base_poly>
 
  228       o = std::make_shared<stored_base_poly>(poly);
 
  234   const base_poly &polynomial_composite::poly_of_subelt(
size_type l)
 const {
 
  235     auto it = polytab.find(l);
 
  236     if (it == polytab.end()) {
 
  237       if (local_coordinate)
 
  238         return default_polys[gmm::mat_ncols(mp->gtransinv[l])];
 
  240         return default_polys[mp->dim()];
 
  242     return *(it->second);
 
  252                                const std::vector<base_node> *opt_gt_pts,
 
  254       scalar_type h = 1./k;
 
  255       switch (cvs->dim()) {
 
  258           base_node a(1), b(1);
 
  260             a[0] = i * h; b[0] = (i+1) * h;
 
  261             if (opt_gt) a = opt_gt->transform(a, *opt_gt_pts);
 
  262             if (opt_gt) b = opt_gt->transform(b, *opt_gt_pts);
 
  265             pm->add_segment(na, nb);
 
  271           base_node A(2),B(2),C(2),D(2);
 
  273             scalar_type a = i * h, b = (i+1) * h;
 
  275               scalar_type c = l * h, d = (l+1) * h;
 
  281                 A = opt_gt->transform(A, *opt_gt_pts);
 
  282                 B = opt_gt->transform(B, *opt_gt_pts);
 
  283                 C = opt_gt->transform(C, *opt_gt_pts);
 
  284                 D = opt_gt->transform(D, *opt_gt_pts);
 
  291               pm->add_triangle(nA,nB,nC);
 
  293                 pm->add_triangle(nC,nB,nD);
 
  303           base_node A,B,C,D,E,F,G,H;
 
  305             scalar_type x = ci*h;
 
  320                   A = opt_gt->transform(A, *opt_gt_pts);
 
  321                   B = opt_gt->transform(B, *opt_gt_pts);
 
  322                   C = opt_gt->transform(C, *opt_gt_pts);
 
  323                   D = opt_gt->transform(D, *opt_gt_pts);
 
  324                   E = opt_gt->transform(E, *opt_gt_pts);
 
  325                   F = opt_gt->transform(F, *opt_gt_pts);
 
  326                   G = opt_gt->transform(G, *opt_gt_pts);
 
  327                   H = opt_gt->transform(H, *opt_gt_pts);
 
  330                 t[0] = pm->add_point(A);
 
  331                 t[1] = pm->add_point(B);
 
  332                 t[2] = pm->add_point(C);
 
  333                 t[4] = pm->add_point(E);
 
  334                 t[3] = t[5] = t[6] = t[7] = 
size_type(-1);
 
  335                 if (k > 1 && ci+cj+ck < k-1) {
 
  336                   t[3] = pm->add_point(D);
 
  337                   t[5] = pm->add_point(F);
 
  338                   t[6] = pm->add_point(G);
 
  340                 if (k > 2 && ci+cj+ck < k-2) {
 
  341                   t[7] = pm->add_point(H);
 
  347                 pm->add_tetrahedron(t[0], t[1], t[2], t[4]);
 
  348                 if (k > 1 && ci+cj+ck < k-1) {
 
  349                   pm->add_tetrahedron(t[1], t[2], t[4], t[5]);
 
  350                   pm->add_tetrahedron(t[6], t[4], t[2], t[5]);
 
  351                   pm->add_tetrahedron(t[2], t[3], t[5], t[1]);
 
  352                   pm->add_tetrahedron(t[2], t[5], t[3], t[6]);
 
  354                 if (k > 2 && ci+cj+ck < k-2) {
 
  355                   pm->add_tetrahedron(t[3], t[5], t[7], t[6]);
 
  363         GMM_ASSERT1(
false, 
"Sorry, not implemented for simplices of " 
  364           "dimension " << 
int(cvs->dim()));
 
  368   static void structured_mesh_for_parallelepiped_
 
  370     const std::vector<base_node> *opt_gt_pts, 
short_type k, pbasic_mesh pm) {
 
  371       scalar_type h = 1./k;
 
  375       std::vector<size_type> strides(n);
 
  377       for (
size_type i=0; i < n; ++i) { strides[i] = nbpts; nbpts *= (k+1); }
 
  378       std::vector<short_type> kcnt; kcnt.resize(n+1,0);
 
  379       std::vector<size_type> pids; pids.reserve(nbpts);
 
  383       while (kcnt[n] == 0) {
 
  386         if (opt_gt) pt = opt_gt->transform(pt, *opt_gt_pts);
 
  387         pids.push_back(pm->add_point(pt));
 
  390         { kcnt[kk]++; 
if (kcnt[kk] == k+1) { kcnt[kk] = 0; kk++; } 
else break; }
 
  396       std::vector<size_type> ppts(pow2n);
 
  398       while (kcnt[n] == 0) {
 
  399         for (kk = 0; kk < pow2n; ++kk) {
 
  402             pos += kcnt[z]*strides[z];
 
  403             if ((kk & (
size_type(1) << z))) pos += strides[z];
 
  405           ppts[kk] = pids.at(pos);
 
  407         pm->add_convex(parallelepiped_linear_geotrans(n), ppts.begin());
 
  409         while (kk < n && kcnt[kk] == k) { kcnt[kk] = 0; kcnt[++kk]++; }
 
  416                               const std::vector<base_node> *opt_gt_pts,
 
  419       dim_type n = cvs->dim();
 
  425           structured_mesh_for_simplex_(cvs,opt_gt,opt_gt_pts,k,pm);
 
  430           structured_mesh_for_parallelepiped_(cvs,opt_gt,opt_gt_pts,k,pm);
 
  434           GMM_ASSERT1(
false, 
"Sorry, structured_mesh not implemented for prisms.");
 
  436         GMM_ASSERT1(
false, 
"This element is not taken into account. Contact us");
 
  441   static void structured_mesh_of_faces_(pconvex_ref cvr, dim_type f,
 
  443     mesh_structure &facem) {
 
  445       dal::bit_vector on_face;
 
  446       for (
size_type i = 0; i < m.nb_max_points(); ++i) {
 
  447         if (m.is_point_valid(i)) {
 
  448           if (gmm::abs(cvr->is_in_face(f, m.points()[i])) < 1e-12)
 
  453       for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv) {
 
  454         for (
short_type ff=0; ff < m.structure_of_convex(cv)->nb_faces(); ++ff) {
 
  455           mesh_structure::ind_pt_face_ct
 
  456             ipts=m.ind_points_of_face_of_convex(cv,ff);
 
  458           for (
size_type i=0; i < ipts.size(); ++i) 
if (!on_face[ipts[i]])
 
  459           { allin = 
false; 
break; }
 
  466             facem.add_convex(m.structure_of_convex(cv)->faces_structure()[ff],
 
  480     std::unique_ptr<basic_mesh> pm;
 
  481     std::vector<std::unique_ptr<mesh_structure>> pfacem; 
 
  482     dal::bit_vector nodes_on_edges;
 
  483     std::unique_ptr<mesh_precomposite> pmp;
 
  485       cvs(c), n(k), simplex_mesh(smesh_)
 
  486     { DAL_STORED_OBJECT_DEBUG_CREATED(
this, 
"cv mesh"); }
 
  487     ~str_mesh_cv__() { DAL_STORED_OBJECT_DEBUG_DESTROYED(
this,
"cv mesh"); }
 
  490   typedef std::shared_ptr<const str_mesh_cv__> pstr_mesh_cv__;
 
  500                                   pbasic_mesh &pm, pmesh_precomposite &pmp,
 
  501                                   bool force_simplexification) {
 
  505     force_simplexification = force_simplexification || (nbp == n+1);
 
  506     dal::pstatic_stored_object_key
 
  508                                           k, force_simplexification);
 
  510     dal::pstatic_stored_object o = dal::search_stored_object_on_all_threads(pk);
 
  513       psmc = std::dynamic_pointer_cast<const str_mesh_cv__>(o);
 
  516       auto ppsmc = std::make_shared<str_mesh_cv__>
 
  518       str_mesh_cv__ &smc(*ppsmc);
 
  521       smc.pm = std::make_unique<basic_mesh>();
 
  523       if (force_simplexification) {
 
  532             = simplex_geotrans(cvr->structure()->dim(), 1);
 
  533           for (
size_type j=0; j < cvpts.size(); ++j) {
 
  539                                       sgt, &cvpts, k, smc.pm.get());
 
  542         structured_mesh_for_convex_(cvr->structure(), 0, 0, k, smc.pm.get());
 
  544       smc.pfacem.resize(cvr->structure()->nb_faces());
 
  545       for (dim_type f=0; f < cvr->structure()->nb_faces(); ++f) {
 
  546         smc.pfacem[f] = std::make_unique<mesh_structure>();
 
  547         structured_mesh_of_faces_(cvr, f, *(smc.pm), *(smc.pfacem[f]));
 
  550       smc.pmp = std::make_unique<mesh_precomposite>(*(smc.pm));
 
  554     pmp = psmc->pmp.get();
 
  559       pbasic_mesh pm; pmesh_precomposite pmp;
 
  564   const std::vector<std::unique_ptr<mesh_structure>>&
 
  566     dal::pstatic_stored_object_key
 
  571       pstr_mesh_cv__ psmc = std::dynamic_pointer_cast<const str_mesh_cv__>(o);
 
  574     else GMM_ASSERT1(
false,
 
  575                      "call refined_simplex_mesh_for_convex first (or fix me)");
 
convenient initialization of vectors via overload of "operator,".
 
Handle composite polynomials.
 
the geotrans_interpolation_context structure is passed as the argument of geometric transformation in...
 
Mesh structure definition.
 
short_type nb_points_of_convex(size_type ic) const
Return the number of points of convex ic.
 
size_type nb_convex() const
The total number of convexes in the mesh.
 
pconvex_structure structure_of_convex(size_type ic) const
Return the pconvex_structure of the convex ic.
 
const ind_set & ind_points_of_convex(size_type ic) const
Return a container to the list of points attached to convex ic.
 
base class for static stored objects
 
A simple singleton implementation.
 
void mult_add(const L1 &l1, const L2 &l2, L3 &l3)
*/
 
number_traits< typename linalg_traits< V1 >::value_type >::magnitude_type vect_dist2(const V1 &v1, const V2 &v2)
Euclidean distance between two vectors.
 
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
 
gmm::uint16_type short_type
used as the common short type integer in the library
 
const basic_mesh * refined_simplex_mesh_for_convex(pconvex_ref cvr, short_type k)
simplexify a convex_ref.
 
std::shared_ptr< const convex_structure > pconvex_structure
Pointer on a convex structure description.
 
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...
 
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.
 
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
 
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
 
pconvex_structure basic_structure(pconvex_structure cv)
Original structure (if concerned)
 
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
 
pconvex_ref basic_convex_ref(pconvex_ref cvr)
return the associated order 1 reference convex.
 
void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o, permanence perm)
Add an object with two optional dependencies.
 
pstatic_stored_object search_stored_object(pstatic_stored_object_key k)
Gives a pointer to an object from a key pointer.
 
int operator()(const base_node &x, const base_node &y) const
comparaison function