27   std::ostream &
operator<<(std::ostream &os, 
const mesh_level_set::zone &z) {
 
   29     for (mesh_level_set::zone::const_iterator it = z.begin();
 
   30          it != z.end(); ++it) {
 
   31       if (it != z.begin()) os << 
", ";
 
   38   std::ostream &
operator<<(std::ostream &os,
const mesh_level_set::zoneset &zs) {
 
   40     for (mesh_level_set::zoneset::const_iterator it = zs.begin(); 
 
   41          it != zs.end(); ++it) {
 
   42       if (it != zs.begin()) os << 
"; ";
 
   53   unsigned long long tprev;
 
   54   unsigned long long acc;
 
   55   unsigned long long tmax;
 
   56   bool running; 
unsigned cnt;
 
   57   Chrono() : acc(0), tmax(0), running(false), cnt(0) {}
 
   58   void tic() { rdtscll(tprev); running = 
true; ++cnt; }
 
   60     if (!running) 
return 0.; running = 
false;
 
   61     unsigned long long t; rdtscll(t);
 
   63     acc += t; tmax = std::max(tmax, t);
 
   64     return double(t)/2.8e9;
 
   66   double total() { 
return double(acc) / 2.8e9; }
 
   67   double max() { 
return double(tmax) / 2.8e9; }
 
   68   double mean() { 
return cnt ? total() / cnt : 0.; }
 
   69   unsigned count() { 
return cnt; }
 
   72   Chrono interpolate_face_chrono;
 
   75   static bool noisy = 
false;
 
   76   void getfem_mesh_level_set_noisy(
void) { noisy = 
true; }
 
   78   void mesh_level_set::clear(
void) {
 
   80     is_adapted_ = 
false; touch();
 
   83   const dal::bit_vector &mesh_level_set::crack_tip_convexes()
 const {
 
   84     return crack_tip_convexes_;
 
   87   void mesh_level_set::init_with_mesh(mesh &me) {
 
   88     GMM_ASSERT1(linked_mesh_ == 0, 
"mesh_level_set already initialized");
 
   90     this->add_dependency(me);
 
   94   mesh_level_set::mesh_level_set(mesh &me)
 
   95   { linked_mesh_ = 0; init_with_mesh(me); }
 
   97   mesh_level_set::mesh_level_set(
void)
 
   98   { linked_mesh_ = 0; is_adapted_ = 
false; }
 
  101   mesh_level_set::~mesh_level_set() {}
 
  104                                mesh &m, dal::bit_vector& ptdone, 
 
  105                                const std::vector<size_type>& ipts,
 
  108                                const std::vector<dal::bit_vector> &constraints,
 
  109                                const std::vector<
const 
  110                                mesher_signed_distance *> &list_constraints) {
 
  111     if (cvs->dim() == 0) 
return;
 
  112     else if (cvs->dim() > 1) {
 
  113       std::vector<size_type> fpts;
 
  114       for (
short_type f=0; f < cvs->nb_faces(); ++f) {
 
  115         fpts.resize(cvs->nb_points_of_face(f));
 
  116         for (
size_type k=0; k < fpts.size(); ++k)
 
  117           fpts[k] = ipts[cvs->ind_points_of_face(f)[k]];
 
  118         interpolate_face(pgt, m,ptdone,fpts,cvs->faces_structure()[f],
 
  119                          nb_vertices, constraints, list_constraints);
 
  124       cout << 
"ipts.size() = " << ipts.size() << endl;
 
  125       cout << 
" nb_vertices = " <<  nb_vertices << endl;
 
  129     for (
size_type i=0; i < ipts.size(); ++i) {
 
  131       if (ipts[i] < nb_vertices) {
 
  133           cout << 
"point " << i << 
" coordinates " 
  134                << m.points()[ipts[i]] << 
" constraints[ipts[i]] = " 
  135                << constraints[ipts[i]] << endl;
 
  136         if (cnt == 0) cts = constraints[ipts[i]];
 
  137         else cts &= constraints[ipts[i]];
 
  142     if (noisy) cout << 
"cts = " << cts << endl;
 
  146       for (
size_type i=0; i < ipts.size(); ++i) {
 
  147         if (ipts[i] >= nb_vertices && !ptdone[ipts[i]]) {
 
  148           base_node P = m.points()[ipts[i]];
 
  151           if (!pure_multi_constraint_projection(list_constraints, P, cts)) {
 
  152             GMM_WARNING1(
"Pure multi has failed in interpolate_face !! " 
  153                          "Original point " << m.points()[ipts[i]]
 
  154                          << 
" projection " << P);
 
  156             if (pgt->convex_ref()->is_in(P) > 1E-8) {
 
  157               GMM_WARNING1(
"Projected point outside the reference convex ! " 
  158                            "Projection canceled. P = " << P);
 
  159             } 
else m.points()[ipts[i]] = P;
 
  161           ptdone[ipts[i]] = 
true;
 
  172     std::vector<dal::bit_vector> constraints_;
 
  173     std::vector<scalar_type> radius_;
 
  174     const std::vector<const mesher_signed_distance*> &list_constraints;
 
  175     scalar_type radius_cv;
 
  177     void clear(
void) { points.
clear(); constraints_.clear();radius_.clear(); }
 
  178     scalar_type radius(
size_type i)
 const { 
return radius_[i]; }
 
  179     const dal::bit_vector &constraints(
size_type i)
 const 
  180     { 
return constraints_[i]; }
 
  181     size_type size(
void)
 const { 
return points.size(); }
 
  182     const base_node &operator[](
size_type i)
 const { 
return points[i]; }
 
  184     size_type add(
const base_node &pt, 
const dal::bit_vector &bv,
 
  189         constraints_.push_back(bv);
 
  190         radius_.push_back(r);
 
  198         for (
size_type i = 0; i < list_constraints.size(); ++i)
 
  199           if (gmm::abs((*(list_constraints[i]))(pt)) < 1E-8*radius_cv)
 
  202         constraints_.push_back(bv);
 
  203         radius_.push_back(r);
 
  211         for (
size_type i = 0; i < list_constraints.size(); ++i)
 
  212           if (gmm::abs((*(list_constraints[i]))(pt)) < 1E-8*radius_cv)
 
  215         constraints_.push_back(bv);
 
  216         scalar_type r = min_curvature_radius_estimate(list_constraints,pt,bv);
 
  217         radius_.push_back(r);
 
  222     dal::bit_vector decimate(
const mesher_signed_distance &ref_element,
 
  223                              scalar_type dmin)
 const {
 
  224       dal::bit_vector retained_points;
 
  229         points_tree.reserve(size());
 
  235             if (!(retained_points.is_in(i)) &&
 
  236                 (constraints(i).card() == nb_co ||
 
  237                  (nb_co == n && constraints(i).card() > n)) &&
 
  238                 ref_element(points[i]) < 1E-8) {
 
  240               scalar_type d = (nb_co == 0) ? (dmin * 1.5)
 
  241                 : std::min(radius(i)*0.25, dmin);
 
  242               base_node min = points[i], max = min;
 
  243               for (
size_type m = 0; m < n; ++m) { min[m]-=d; max[m]+=d; }
 
  245               points_tree.points_in_box(inpts, min, max);
 
  246               for (
size_type j = 0; j < inpts.size(); ++j)
 
  247                 if (retained_points.is_in(inpts[j].i) &&
 
  248                     constraints(inpts[j].i).contains(constraints(i))
 
  249                     && gmm::vect_dist2(points[i], points[inpts[j].i]) < d)
 
  250                   { kept = 
false; 
break; }
 
  252                 if (noisy) cout << 
"kept point : " << points[i] << 
" co = " 
  253                                 << constraints(i) << endl;
 
  254                 retained_points.add(i);
 
  260       return retained_points;
 
  263     point_stock(
const std::vector<const mesher_signed_distance*> &ls,
 
  265       : points(scalar_type(10000000)), list_constraints(ls),
 
  271     dim_type n = pgt->structure()->dim();
 
  272     size_type nbp = pgt->basic_structure()->nb_points();
 
  276         return new_mesher_simplex_ref(n);
 
  282       base_node rmin(n), rmax(n);
 
  283       std::fill(rmax.begin(), rmax.end(), scalar_type(1));
 
  284       return new_mesher_rectangle(rmin, rmax);
 
  290       return new_mesher_prism_ref(n);
 
  293     GMM_ASSERT1(
false, 
"This element is not taken into account. Contact us");
 
  297   struct global_mesh_for_mesh_level_set : 
public mesh {};
 
  298   static mesh& global_mesh() {
 
  302   void mesh_level_set::run_delaunay(std::vector<base_node> &fixed_points,
 
  303                                     gmm::dense_matrix<size_type> &simplexes,
 
  304                                     std::vector<dal::bit_vector> &
 
  306     double t0=gmm::uclock_sec();
 
  307     if (noisy) cout << 
"running delaunay with " << fixed_points.size()
 
  308                     << 
" points.." << std::flush;
 
  309     bgeot::qhull_delaunay(fixed_points, simplexes);
 
  310     if (noisy) cout << 
" -> " << gmm::mat_ncols(simplexes)
 
  311                     << 
" simplexes [" << gmm::uclock_sec()-t0 << 
"sec]\n";
 
  314   static bool intersects(
const mesh_level_set::zone &z1, 
 
  315                          const mesh_level_set::zone &z2) {
 
  316     for (std::set<const std::string *>::const_iterator it = z1.begin(); it != z1.end();
 
  318       if (z2.find(*it) != z2.end()) 
return true;
 
  322   void mesh_level_set::merge_zoneset(zoneset &zones1,
 
  323                                      const zoneset &zones2)
 const {
 
  324     for (std::set<const zone *>::const_iterator it2 = zones2.begin(); 
 
  325          it2 != zones2.end(); ++it2) {
 
  327       for (std::set<const zone *>::iterator it1 = zones1.begin(); 
 
  328            it1 != zones1.end(); ) {
 
  329         if (intersects(z, *(*it1))) {
 
  330           z.insert((*it1)->begin(), (*it1)->end());
 
  335       zones1.insert(&(*(allzones.insert(z).first)));
 
  340   static void add_sub_zones_no_zero(std::string &s, 
 
  341                                     mesh_level_set::zone &z, 
 
  342                                     std::set<std::string> &allsubzones) {
 
  343     size_t i = s.find(
'0');
 
  344     if (i != 
size_t(-1)) {
 
  345       s[i] = 
'+'; add_sub_zones_no_zero(s, z, allsubzones);
 
  346       s[i] = 
'-'; add_sub_zones_no_zero(s, z, allsubzones);
 
  348       z.insert(&(*(allsubzones.insert(s).first)));
 
  352   void mesh_level_set::merge_zoneset(zoneset &zones1,
 
  353                                      const std::string &subz)
 const {
 
  355     zone z; std::string s(subz);
 
  356     add_sub_zones_no_zero(s, z, allsubzones);
 
  358     zs.insert(&(*(allzones.insert(z).first)));
 
  359     merge_zoneset(zones1, zs);
 
  365   void mesh_level_set::find_zones_of_element(
size_type cv,
 
  366                                              std::string &prezone,
 
  367                                              scalar_type radius) {
 
  368     convex_info &cvi = cut_cv[cv];
 
  370     for (dal::bv_visitor i(cvi.pmsh->convex_index()); !i.finished();++i) {
 
  372       if (cvi.pmsh->convex_area_estimate(i) > 1e-8) {
 
  373         std::string subz = prezone;
 
  375         for (
size_type j = 0; j < level_sets.size(); ++j) {
 
  376           if (subz[j] == 
'*' || subz[j] == 
'0') {
 
  377             int s = sub_simplex_is_not_crossed_by(cv, level_sets[j], i,radius);
 
  379             subz[j] = (s < 0) ? 
'-' : ((s > 0) ? 
'+' : 
'0');
 
  382         merge_zoneset(cvi.zones, subz);
 
  385     if (noisy) cout << 
"Number of zones for convex " << cv << 
" : " 
  386                     << cvi.zones.size() << endl;
 
  390   void mesh_level_set::cut_element(
size_type cv,
 
  391                                    const dal::bit_vector &primary,
 
  392                                    const dal::bit_vector &secondary,
 
  393                                    scalar_type radius_cv) {
 
  395     cut_cv[cv] = convex_info();
 
  396     cut_cv[cv].pmsh = std::make_shared<mesh>();
 
  397     if (noisy) cout << 
"cutting element " << cv << endl;
 
  399     pmesher_signed_distance ref_element = new_ref_element(pgt);
 
  400     std::vector<pmesher_signed_distance> mesher_level_sets;
 
  403     size_type nbtotls = primary.card() + secondary.card();
 
  405     GMM_ASSERT1(nbtotls <= 16,
 
  406                 "An element is cut by more than 16 level_set, aborting");
 
  413     scalar_type r0 = 1E+10; 
 
  414     std::vector<const mesher_signed_distance*> list_constraints;
 
  415     point_stock mesh_points(list_constraints, radius_cv);
 
  417     ref_element->register_constraints(list_constraints);
 
  418     size_type nbeltconstraints = list_constraints.size();
 
  419     mesher_level_sets.reserve(nbtotls);
 
  420     for (
size_type ll = 0; ll < level_sets.size(); ++ll) {
 
  423         K = std::max(K, (level_sets[ll])->degree());
 
  424         mesher_level_sets.push_back(level_sets[ll]->mls_of_convex(cv, 0));
 
  425         pmesher_signed_distance mls(mesher_level_sets.back());
 
  426         list_constraints.push_back(mesher_level_sets.back().get());
 
  427         r0 = std::min(r0, curvature_radius_estimate(*mls, X, 
true));
 
  428         GMM_ASSERT1(gmm::abs(r0) >= 1e-13, 
"Something wrong in your level " 
  429                     "set ... curvature radius = " << r0);
 
  431           mesher_level_sets.push_back(level_sets[ll]->mls_of_convex(cv, 1));
 
  432           pmesher_signed_distance mls2(mesher_level_sets.back());
 
  433           list_constraints.push_back(mesher_level_sets.back().get());
 
  434           r0 = std::min(r0, curvature_radius_estimate(*mls2, X, 
true));
 
  442     scalar_type h0 = std::min(1./(K+1), 0.2 * r0), dmin = 0.55;
 
  443     bool h0_is_ok = 
true;
 
  449       scalar_type geps = .001*h0; 
 
  451       std::vector<size_type> gridnx(n);
 
  453         { gridnx[i]=1+(
size_type)(1./h0); nbpt *= gridnx[i]; }
 
  454       base_node P(n), Q(n), V(n);
 
  456       std::vector<size_type> co_v;
 
  460           unsigned p =  unsigned(r % gridnx[k]);
 
  461           P[k] = p * scalar_type(1) / scalar_type(gridnx[k]-1);
 
  464         co.clear(); co_v.resize(0);
 
  465         if ((*ref_element)(P) < geps) {
 
  471             scalar_type d = list_constraints[k]->grad(P, V);
 
  472             if (gmm::vect_norm2(V)*h0*7 > gmm::abs(d))
 
  473               if (try_projection(*(list_constraints[k]), Q, 
true)) {
 
  474                 if (k >= nbeltconstraints
 
  475                     && gmm::vect_dist2(P, Q) < h0 * 3.5) kept = 
true;
 
  476                 if (gmm::vect_dist2(P, Q) < h0 / 1.5) {
 
  477                   co.add(k); co_v.push_back(k); 
 
  478                   if ((*ref_element)(Q) < 1E-8) {
 
  480                       curvature_radius_estimate(*(list_constraints[k]), Q);
 
  481                     r0 = std::min(r0, r);
 
  482                     if (r0 < 4.*h0) { h0 = 0.2 * r0; h0_is_ok = 
false; 
break; }
 
  483                     if (k >= nbeltconstraints || kept) mesh_points.add(Q, r);
 
  488           if (kept) mesh_points.add(P, 1.E10);
 
  496               if (count & (
size_type(1) << j)) nn.add(co_v[j]);
 
  497             if (nn.card() > 1 && nn.card() <= n) {
 
  498               if (noisy) cout << 
"trying set of constraints" << nn << endl;
 
  500               bool ok=pure_multi_constraint_projection(list_constraints,Q,nn);
 
  501               if (ok && (*ref_element)(Q) < 1E-9) {
 
  502                 if (noisy) cout << 
"Intersection point found " << Q << 
" with " 
  510       if (!h0_is_ok) 
continue;
 
  518       if (noisy) cout << 
"dmin = " << dmin << 
" h0 = " << h0 << endl;
 
  519       if (noisy) cout << 
"convex " << cv << endl;
 
  521       dal::bit_vector retained_points
 
  522         = mesh_points.decimate(*ref_element, dmin);
 
  524       bool delaunay_again = 
true;
 
  526       std::vector<base_node> fixed_points;
 
  527       std::vector<dal::bit_vector> fixed_points_constraints;
 
  528       mesh &msh(*(cut_cv[cv].pmsh));
 
  530       mesh_region &ls_border_faces(cut_cv[cv].ls_border_faces);
 
  531       std::vector<base_node> cvpts;
 
  535       while (delaunay_again) {
 
  536         if (++nb_delaunay > 15)
 
  537           { h0_is_ok = 
false; h0 /= 2.0; dmin = 2.*h0; 
break; }
 
  539         fixed_points.resize(0);
 
  540         fixed_points_constraints.resize(0);
 
  543         fixed_points.reserve(retained_points.card());
 
  544         fixed_points_constraints.reserve(retained_points.card());
 
  545         for (dal::bv_visitor i(retained_points); !i.finished(); ++i) {
 
  546           fixed_points.push_back(mesh_points[i]);
 
  547           fixed_points_constraints.push_back(mesh_points.constraints(i));
 
  550         gmm::dense_matrix<size_type> simplexes;
 
  551         run_delaunay(fixed_points, simplexes, fixed_points_constraints);
 
  552         delaunay_again = 
false;
 
  556         for (
size_type i = 0; i <  fixed_points.size(); ++i) {
 
  557           size_type j = msh.add_point(fixed_points[i]);
 
  562         for (
size_type i = 0; i < gmm::mat_ncols(simplexes); ++i) {
 
  563           size_type j = msh.add_convex(bgeot::simplex_geotrans(n,1),
 
  564                                        gmm::vect_const_begin(gmm::mat_col(simplexes, i)));
 
  566           if (msh.convex_quality_estimate(j) < 1E-10) msh.sup_convex(j);
 
  568             std::vector<scalar_type> signs(list_constraints.size());
 
  569             std::vector<size_type> prev_point(list_constraints.size());
 
  571               for (
size_type jj = 0; jj < list_constraints.size(); ++jj) {
 
  573                   (*(list_constraints[jj]))(msh.points_of_convex(j)[ii]);
 
  574                 if (gmm::abs(dd) > radius_cv * 1E-7) {
 
  575                   if (dd * signs[jj] < 0.0) {
 
  576                     if (noisy) cout << 
"Intersection found ... " << jj
 
  577                                     << 
" dd = " << dd << 
" convex quality = " 
  578                                     << msh.convex_quality_estimate(j) << 
"\n";
 
  580                     base_node X = msh.points_of_convex(j)[ii], G;
 
  581                     base_node VV = msh.points_of_convex(j)[prev_point[jj]] - X;
 
  582                     if (dd > 0.) gmm::scale(VV, -1.);
 
  583                     dd = (*(list_constraints[jj])).grad(X, G);
 
  585                     while (gmm::abs(dd) > 1e-16*radius_cv && (++nbit < 20)) { 
 
  587                       if (gmm::abs(nG) < 1E-8) nG = 1E-8;
 
  588                       if (nG < 0) nG = 1.0;
 
  589                       gmm::add(gmm::scaled(VV, -dd / nG), X);
 
  590                       dd = (*(list_constraints[jj])).grad(X, G);
 
  592                     if (gmm::abs(dd) > 1e-16*radius_cv) { 
 
  593                       base_node X1 = msh.points_of_convex(j)[ii];
 
  594                       base_node X2 = msh.points_of_convex(j)[prev_point[jj]], X3;
 
  595                       scalar_type dd1 = (*(list_constraints[jj]))(X1);
 
  596                       scalar_type dd2 = (*(list_constraints[jj]))(X2);
 
  597                       if (dd1 > dd2) { std::swap(dd1, dd2); std::swap(X1, X2); }
 
  598                       while (gmm::abs(dd1) > 1e-15*radius_cv) {
 
  599                         X3 = (X1 + X2) / 2.0;
 
  600                         scalar_type dd3 = (*(list_constraints[jj]))(X3);
 
  601                         if (dd3 == dd1 || dd3 == dd2) 
break;
 
  602                         if (dd3 > 0) { dd2 = dd3; X2 = X3; }
 
  603                         else { dd1 = dd3; X1 = X3; }
 
  609                     if (!(retained_points[kk])) {
 
  610                       retained_points.add(kk);
 
  611                       delaunay_again = 
true;
 
  616                   if (signs[jj] == 0.0) { signs[jj] = dd; prev_point[jj] = ii; }
 
  626       if (!h0_is_ok) 
continue;
 
  630         for (dal::bv_visitor_c j(msh.convex_index()); !j.finished(); ++j) {
 
  632           cvpts.resize(pgt2->nb_points());
 
  633           for (
size_type k=0; k < pgt2->nb_points(); ++k) {
 
  634             cvpts[k] = bgeot::simplex_geotrans(n,1)->transform
 
  635               (pgt2->convex_ref()->points()[k], msh.points_of_convex(j));
 
  640           size_type jj = msh.add_convex_by_points(pgt2, cvpts.begin());
 
  648         char s[512]; snprintf(s, 511, 
"totobefore%d.dx", 
int(cv));
 
  651         exp.exporting_mesh_edges();
 
  657       for (dal::bv_visitor i(msh.convex_index()); !i.finished(); ++i) {
 
  659           const mesh::ind_pt_face_ct &fpts
 
  660             = msh.ind_points_of_face_of_convex(i, f);
 
  662           dal::bit_vector cts; 
bool first = 
true;
 
  663           for (
unsigned k=0; k < fpts.size(); ++k) {
 
  664             if (fpts[k] >= fixed_points_constraints.size()) {
 
  668             if (first) { cts = fixed_points_constraints[fpts[k]]; first=
false; }
 
  669             else cts &= fixed_points_constraints[fpts[k]];
 
  671           for (dal::bv_visitor ii(cts); !ii.finished(); ++ii) {
 
  672             if (ii >= nbeltconstraints)
 
  673               ls_border_faces.add(i, f);
 
  680         dal::bit_vector ptdone;
 
  681         std::vector<size_type> ipts;
 
  685         for (dal::bv_visitor i(msh.convex_index()); !i.finished(); ++i) {
 
  687             const mesh::ind_pt_face_ct &fpts
 
  688               = msh.ind_points_of_face_of_convex(i, f);
 
  689             ipts.assign(fpts.begin(), fpts.end());
 
  691             interpolate_face_chrono.tic();
 
  694             interpolate_face(pgt, msh, ptdone, ipts,
 
  695                              msh.trans_of_convex(i)->structure()
 
  696                              ->faces_structure()[f], fixed_points.size(),
 
  697                              fixed_points_constraints, list_constraints);
 
  699             interpolate_face_chrono.toc();
 
  708         char s[512]; snprintf(s, 511, 
"toto%d.dx", 
int(cv));
 
  711         exp.exporting_mesh_edges();
 
  722       auto new_approx = std::make_shared<approx_integration>(pgt->convex_ref());
 
  723       base_matrix KK(n,n), CS(n,n);
 
  724       base_matrix pc(pgt2->nb_points(), n); 
 
  725       for (dal::bv_visitor i(msh.convex_index()); !i.finished(); ++i) {
 
  726         vectors_to_base_matrix(G, msh.points_of_convex(i));
 
  729         scalar_type sign = 0.0;
 
  730         for (
size_type j = 0; j < pai->nb_points_on_convex(); ++j) {
 
  731           c.set_xref(pai->point(j));
 
  732           pgt2->poly_vector_grad(pai->point(j), pc);
 
  735           if (noisy && J * sign < 0) {
 
  736             cout << 
"CAUTION reversal situation in convex " << i
 
  737                  << 
"sign = " << sign << 
" J = " << J << endl;
 
  738             for (
size_type nip = 0; nip < msh.nb_points_of_convex(i); ++nip)
 
  739               cout << 
"Point " << nip << 
"=" << msh.points_of_convex(i)[nip]
 
  743           if (sign == 0 && gmm::abs(J) > 1E-14) sign = J;
 
  744           new_approx->add_point(c.xreal(), pai->coeff(j) * gmm::abs(J));
 
  751         vectors_to_base_matrix(G, msh.points_of_convex(it.cv()));
 
  754         for (
size_type j = 0; j < pai->nb_points_on_face(it.f()); ++j) {
 
  755           c.set_xref(pai->point_on_face(it.f(), j));
 
  756           new_approx->add_point(c.xreal(), pai->coeff_on_face(it.f(), j)
 
  757                                * gmm::abs(c.J()), it.f() );
 
  760       new_approx->valid_method();
 
  766       scalar_type error = test_integration_error(new_approx, 1);
 
  767       if (noisy) cout << 
" max monomial integration err: " << error << 
"\n";
 
  769         if (noisy) cout << 
"Not Good ! Let us make a finer cut.\n";
 
  770         if (dmin > 3*h0) { dmin /= 2.; }
 
  771         else { h0 /= 2.0; dmin = 2.*h0; }
 
  776       if (h0_is_ok && noisy) { 
 
  777         vectors_to_base_matrix(G, 
linked_mesh().points_of_convex(cv));
 
  778         std::vector<size_type> pts(msh.nb_points());
 
  779         for (
size_type i = 0; i < msh.nb_points(); ++i)
 
  780           pts[i] = global_mesh().add_point(pgt->transform(msh.points()[i], G));
 
  782         for (dal::bv_visitor i(msh.convex_index()); !i.finished(); ++i)
 
  783           global_mesh().
add_convex(msh.trans_of_convex(i), 
 
  784                                    gmm::index_ref_iterator(pts.begin(),
 
  785                                    msh.ind_points_of_convex(i).begin()));
 
  791     cout << 
"Interpolate face: " << interpolate_face_chrono.total()
 
  792          << 
" moyenne: " << interpolate_face_chrono.mean() << 
"\n";
 
  800     for (dal::bv_visitor cv(
linked_mesh().convex_index()); 
 
  801          !cv.finished(); ++cv) {
 
  802       if (is_convex_cut(cv)) {
 
  803         const convex_info &ci = (cut_cv.find(cv))->second;
 
  804         mesh &msh = *(ci.pmsh);
 
  806         vectors_to_base_matrix(G, 
linked_mesh().points_of_convex(cv));
 
  807         std::vector<size_type> pts(msh.
nb_points());
 
  809           pts[i] = m.add_point(pgt->transform(msh.points()[i], G));
 
  813         for (dal::bv_visitor i(msh.
convex_index()); !i.finished(); ++i) {
 
  815                                 gmm::index_ref_iterator(pts.begin(),
 
  819         for (
mr_visitor i(ci.ls_border_faces); !i.finished(); ++i) {
 
  820           m.
region(0).add(ic2[i.cv()], i.f());
 
  832   void mesh_level_set::update_crack_tip_convexes() {
 
  833     crack_tip_convexes_.clear();
 
  835     for (std::map<size_type, convex_info>::const_iterator it = cut_cv.begin(); 
 
  836          it != cut_cv.end(); ++it) {
 
  838       mesh &msh = *(it->second.pmsh);      
 
  840         if (get_level_set(ils)->has_secondary()) {
 
  841           pmesher_signed_distance
 
  842             mesherls0 = get_level_set(ils)->mls_of_convex(cv, 0, 
false);
 
  843           pmesher_signed_distance
 
  844             mesherls1 = get_level_set(ils)->mls_of_convex(cv, 1, 
false);
 
  845           for (dal::bv_visitor ii(msh.
convex_index()); !ii.finished(); ++ii) {
 
  847               if (gmm::abs((*mesherls0)(msh.points_of_convex(ii)[ipt])) < 1E-10
 
  848                   && gmm::abs((*mesherls1)(msh.points_of_convex(ii)[ipt])) < 1E-10) {
 
  849                 crack_tip_convexes_.add(cv);
 
  866     GMM_ASSERT1(linked_mesh_ != 0, 
"Uninitialized mesh_level_set");
 
  869     zones_of_convexes.
clear();
 
  875     for (dal::bv_visitor cv(
linked_mesh().convex_index()); 
 
  876          !cv.finished(); ++cv) {
 
  878       dal::bit_vector prim, sec;
 
  879       find_crossing_level_set(cv, prim, sec, z, radius);
 
  880       zones_of_convexes[cv] = &(*(allsubzones.insert(z).first));
 
  881       if (noisy) cout << 
"element " << cv << 
" cut level sets : " 
  882                       << prim << 
" zone : " << z << endl;
 
  884         cut_element(cv, prim, sec, radius);
 
  885         find_zones_of_element(cv, z, radius);
 
  897     update_crack_tip_convexes();
 
  903   void mesh_level_set::find_level_set_potential_intersections
 
  904   (std::vector<size_type> &icv, std::vector<dal::bit_vector> &ils) {
 
  906     GMM_ASSERT1(linked_mesh_ != 0, 
"Uninitialized mesh_level_set");
 
  908     for (dal::bv_visitor cv(
linked_mesh().convex_index()); 
 
  909          !cv.finished(); ++cv)
 
  910       if (is_convex_cut(cv)) {
 
  912         dal::bit_vector prim, sec;
 
  913         find_crossing_level_set(cv, prim, sec, z, radius);
 
  914         if (prim.card() > 1) {
 
  925   int mesh_level_set::sub_simplex_is_not_crossed_by(
size_type cv,
 
  928                                                     scalar_type radius) {
 
  929     scalar_type EPS = 1e-7 * radius;
 
  931     convex_info &cvi = cut_cv[cv];
 
  936     pmesher_signed_distance mls0 = ls->mls_of_convex(cv, 0), mls1(mls0);
 
  937     if (ls->has_secondary()) mls1 = ls->mls_of_convex(cv, 1);
 
  940     scalar_type d2 = 0, d1 = 1, d0 = 0, d0min = 0;
 
  941     for (
size_type i = 0; i < pgt2->nb_points(); ++i) {
 
  942       d0 = (*mls0)(cvi.pmsh->points_of_convex(sub_cv)[i]);
 
  943       if (i == 0) d0min = gmm::abs(d0);
 
  944       else d0min = std::min(d0min, gmm::abs(d0));
 
  945       if (ls->has_secondary())
 
  946         d1 = std::min(d1, (*mls1)(cvi.pmsh->points_of_convex(sub_cv)[i]));
 
  948       int p2 = ( (d0 < -EPS) ? -1 : ((d0 > EPS) ? +1 : 0));
 
  950       if (gmm::abs(d0) > gmm::abs(d2)) d2 = d0;
 
  951       if (!p2 || p*p2 < 0) is_cut = 
true;
 
  955     if (is_cut && ls->has_secondary() && d1 >= -radius*0.0001) 
return 0;
 
  957     return (d2 < 0.) ? -1 : 1;
 
  960   int mesh_level_set::is_not_crossed_by(
size_type cv, plevel_set ls,
 
  961                                         unsigned lsnum, scalar_type radius) {
 
  962     const mesh_fem &mf = ls->get_mesh_fem();
 
  963     GMM_ASSERT1(!mf.is_reduced(), 
"Internal error");
 
  964     const mesh_fem::ind_dof_ct &dofs = mf.ind_basic_dof_of_element(cv);
 
  965     pfem pf = mf.fem_of_element(cv);
 
  967     scalar_type EPS = 1e-8 * radius;
 
  974     for (mesh_fem::ind_dof_ct::const_iterator it=dofs.begin();
 
  975          it != dofs.end(); ++it) {
 
  976       scalar_type v = ls->values(lsnum)[*it];
 
  977       int p2 = ( (v < -EPS) ? -1 : ((v > EPS) ? +1 : 0));
 
  979       if (!p2 || p*p2 < 0) 
return 0;
 
  982     pmesher_signed_distance mls1 = ls->mls_of_convex(cv, lsnum, 
false);
 
  983     base_node X(pf->dim()), G(pf->dim());
 
  985     scalar_type d = mls1->grad(X, G);
 
  986     if (gmm::vect_norm2(G)*2.5 < gmm::abs(d)) 
return p;
 
  989     pmesher_signed_distance ref_element = new_ref_element(pgt);
 
  992     mesher_intersection mi1(ref_element, mls1);
 
  993     if (!try_projection(mi1, X)) 
return p;
 
  994     if ((*ref_element)(X) > 1E-8) 
return p;
 
  997     pmesher_signed_distance mls2 = ls->mls_of_convex(cv, lsnum, 
true);
 
  998     mesher_intersection mi2(ref_element, mls2);
 
  999     if (!try_projection(mi2, X)) 
return p;
 
 1000     if ((*ref_element)(X) > 1E-8) 
return p;
 
 1005   void mesh_level_set::find_crossing_level_set(
size_type cv,
 
 1006                                                dal::bit_vector &prim,
 
 1007                                                dal::bit_vector &sec,
 
 1009                                                scalar_type radius) {
 
 1010     prim.clear(); sec.clear();
 
 1011     z = std::string(level_sets.size(), 
'*');
 
 1013     for (
size_type k = 0; k < level_sets.size(); ++k, ++lsnum) {
 
 1014       if (noisy) cout << 
"testing cv " << cv << 
" with level set " 
 1016       int s = is_not_crossed_by(cv, level_sets[k], 0, radius);
 
 1018         if (noisy) cout << 
"is cut \n";
 
 1019         if (level_sets[k]->has_secondary()) {
 
 1020           s = is_not_crossed_by(cv, level_sets[k], 1, radius);
 
 1021           if (!s) { sec.add(lsnum); prim.add(lsnum); }
 
 1022           else if (s < 0) prim.add(lsnum); 
else z[k] = 
'0';
 
 1024         else prim.add(lsnum);
 
 1026       else z[k] = (s < 0) ? 
'-' : 
'+';
 
the geotrans_interpolation_context structure is passed as the argument of geometric transformation in...
Balanced tree over a set of points.
void add_point_with_id(const base_node &n, size_type i)
insert a new point, with an associated number.
short_type nb_points_of_convex(size_type ic) const
Return the number of points of convex ic.
const dal::bit_vector & convex_index() const
Return the list of valid convex IDs.
const ind_set & ind_points_of_convex(size_type ic) const
Return a container to the list of points attached to convex ic.
size_type nb_allocated_convex() const
The number of convex indexes from 0 to the index of the last convex.
Store a set of points, identifying points that are nearer than a certain very small distance.
size_type search_node(const base_node &pt, const scalar_type radius=0) const
Search a node in the array.
size_type add_node(const base_node &pt, const scalar_type radius=0, bool remove_duplicated_nodes=true)
Add a point to the array or use an existing point, located within a distance smaller than radius.
void clear(void)
reset the array, remove all points
void clear(void)
Clear and desallocate all the elements.
static T & instance()
Instance from the current thread.
A (quite large) class for exportation of data to IBM OpenDX.
void exporting_mesh_edges(bool with_slice_edge=true)
append edges information (if you want to draw the mesh and are using a refined slice.
void global_cut_mesh(mesh &m) const
fill m with the (non-conformal) "cut" mesh.
size_type nb_level_sets(void) const
Get number of level-sets referenced in this object.
void adapt(void)
do all the work (cut the convexes wrt the levelsets)
mesh & linked_mesh(void) const
Gives a reference to the linked mesh of type mesh.
"iterator" class for regions.
structure used to hold a set of convexes and/or convex faces.
Describe a mesh (collection of convexes (elements) and points).
virtual scalar_type convex_radius_estimate(size_type ic) const
Return an estimate of the convex largest dimension.
size_type nb_points() const
Give the number of geometrical nodes in the mesh.
const mesh_region region(size_type id) const
Return the region of index 'id'.
size_type add_convex(bgeot::pgeometric_trans pgt, ITER ipts)
Add a convex to the mesh.
void clear()
Erase the mesh.
This slicer does nothing.
The output of a getfem::mesh_slicer which has been recorded.
void build(const getfem::mesh &m, const slicer_action &a, size_type nrefine=1)
Build the slice, by applying a slicer_action operation.
Keep informations about a mesh crossed by level-sets.
void copy(const L1 &l1, L2 &l2)
*/
void fill_random(L &l)
fill a vector or matrix with random value (uniform [-1,1]).
void clear(L &l)
clear (fill with zeros) a vector or matrix.
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
strongest_value_type< V1, V2 >::value_type vect_sp(const V1 &v1, const V2 &v2)
*/
void add(const L1 &l1, L2 &l2)
*/
linalg_traits< DenseMatrixLU >::value_type lu_det(const DenseMatrixLU &LU, const Pvector &pvector)
Compute the matrix determinant (via a LU factorization)
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 APIDECL outer_faces_of_mesh(const mesh &m, const dal::bit_vector &cvlst, convex_face_ct &flist)
returns a list of "exterior" faces of a mesh (i.e.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
std::vector< index_node_pair > kdtree_tab_type
store a set of points with associated indexes.
gmm::uint16_type short_type
used as the common short type integer in the library
std::ostream & operator<<(std::ostream &o, const convex_structure &cv)
Print the details of the convex structure cvs to the output stream o.
std::shared_ptr< const convex_structure > pconvex_structure
Pointer on a convex structure description.
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_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
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
GEneric Tool for Finite Element Methods.
pintegration_method classical_approx_im(bgeot::pgeometric_trans pgt, dim_type degree)
try to find an approximate integration method for the geometric transformation pgt which is able to i...
pintegration_method classical_exact_im(bgeot::pgeometric_trans pgt)
return an exact integration method for convex type handled by pgt.