33 # if !defined(GETFEM_HAVE_LIBQHULL_R_QHULL_RA_H) 
   34   void qhull_delaunay(
const std::vector<base_node> &,
 
   35                 gmm::dense_matrix<size_type>&) {
 
   36     GMM_ASSERT1(
false, 
"Qhull header files not installed. " 
   37                 "Install qhull library and reinstall GetFEM library.");
 
   42 # include <libqhull_r/qhull_ra.h> 
   45   void qhull_delaunay(
const std::vector<base_node> &pts,
 
   46                       gmm::dense_matrix<size_type>& simplexes) {
 
   49     if (pts.size() <= dim) { gmm::resize(simplexes, dim+1, 0); 
return; }
 
   50     if (pts.size() == dim+1) {
 
   51       gmm::resize(simplexes, dim+1, 1);
 
   52       for (
size_type i=0; i <= dim; ++i) simplexes(i, 0) = i;
 
   55     std::vector<coordT> Pts(dim * pts.size());
 
   57       gmm::copy(pts[i], gmm::sub_vector(Pts, gmm::sub_interval(i*dim, dim)));
 
   63     char flags[]= 
"qhull QJ d Qbb Pp T0"; 
 
   66     FILE *errfile= stderr;    
 
   70     vertexT *vertex, **vertexp;
 
   73     exitcode = qh_new_qhull (qh, 
int(dim), 
int(pts.size()), &Pts[0], ismalloc,
 
   74                              flags, outfile, errfile);
 
   77       FORALLfacets { 
if (!facet->upperdelaunay) nbf++; }
 
   78       gmm::resize(simplexes, dim+1, nbf);
 
   82         if (!facet->upperdelaunay) {
 
   84           FOREACHvertex_(facet->vertices) {
 
   85             assert(s < (
unsigned)(dim+1));
 
   86             simplexes(s++,nbf) = qh_pointid(qh, vertex->point);
 
   92     qh_freeqhull(qh, !qh_ALL);
 
   93     qh_memfreeshort(qh, &curlong, &totlong);
 
   94     if (curlong || totlong)
 
   95       cerr << 
"qhull internal warning (main): did not free " << totlong <<
 
   96         " bytes of long memory (" << curlong << 
" pieces)\n";
 
  111     dim_type n = basic_cvs->dim();
 
  112     std::vector<size_type> ipts(n+1);
 
  113     if (basic_cvs->nb_points() == n + 1) {
 
  114       for (
size_type i = 0; i <= n; ++i) ipts[i] = i;
 
  115       m.add_simplex(n, ipts.begin());
 
  119       size_type nb = simplexified_tab(basic_cvs, &tab);
 
  122           for (
size_type i = 0; i <= n; ++i) ipts[i] = *tab++;
 
  123           m.add_simplex(n, ipts.begin());
 
  126 #       if defined(GETFEM_HAVE_LIBQHULL_R_QHULL_RA_H) 
  127         gmm::dense_matrix<size_type> t;
 
  128         qhull_delaunay(cvr->
points(), t);
 
  129         for (
size_type nc = 0; nc < gmm::mat_ncols(t); ++nc) {
 
  130           for (
size_type i = 0; i <= n; ++i) ipts[i] = t(i,nc);
 
  131           m.add_simplex(n, ipts.begin());
 
  142   struct stored_point_tab_key : 
virtual public dal::static_stored_object_key  {
 
  144     bool compare(
const static_stored_object_key &oo)
 const override {
 
  145       const stored_point_tab_key &o
 
  146         = 
dynamic_cast<const stored_point_tab_key &
>(oo);
 
  149       if (&x == &y) 
return false;
 
  150       std::vector<base_node>::const_iterator it1 = x.begin(), it2 = y.begin();
 
  151       base_node::const_iterator itn1, itn2, itne;
 
  152       for ( ; it1 != x.end() && it2 != y.end() ; ++it1, ++it2) {
 
  153         if ((*it1).size() < (*it2).size()) 
return true;
 
  154         if ((*it1).size() > (*it2).size()) 
return false;
 
  155         itn1 = (*it1).begin(); itne = (*it1).end(); itn2 = (*it2).begin();
 
  156         for ( ; itn1 != itne ; ++itn1, ++itn2)
 
  157           if (*itn1 < *itn2) 
return true;
 
  158           else if (*itn1 > *itn2) 
return false;
 
  160       if (it2 != y.end()) 
return true;
 
  163     bool equal(
const static_stored_object_key &oo)
 const override {
 
  164       auto &o = 
dynamic_cast<const stored_point_tab_key &
>(oo);
 
  167       if (&x == &y) 
return true;
 
  168       if (x.size() != y.size()) 
return false;
 
  169       auto it1 = x.begin();
 
  170       auto it2 = y.begin();
 
  171       base_node::const_iterator itn1, itn2, itne;
 
  172       for ( ; it1 != x.end() && it2 != y.end() ; ++it1, ++it2) {
 
  173         if ((*it1).size() != (*it2).size()) 
return false;
 
  174         itn1 = (*it1).begin(); itne = (*it1).end(); itn2 = (*it2).begin();
 
  175         for ( ; itn1 != itne ; ++itn1, ++itn2)
 
  176           if (*itn1 != *itn2) 
return false;
 
  185     dal::pstatic_stored_object_key
 
  186       pk = std::make_shared<stored_point_tab_key>(&spt);
 
  188     if (o) 
return std::dynamic_pointer_cast<const stored_point_tab>(o);
 
  189     pstored_point_tab p = std::make_shared<stored_point_tab>(spt);
 
  190     DAL_STORED_OBJECT_DEBUG_CREATED(p.get(), 
"Stored point tab");
 
  191     dal::pstatic_stored_object_key
 
  192       psp = std::make_shared<stored_point_tab_key>(p.get());
 
  197   convex_of_reference::convex_of_reference
 
  200     auto_basic(auto_basic_) {
 
  201     DAL_STORED_OBJECT_DEBUG_CREATED(
this, 
"convex of refrence");
 
  202     psimplexified_convex = std::make_shared<mesh_structure>();
 
  209     GMM_ASSERT1(auto_basic,
 
  210                 "always use simplexified_convex on the basic_convex_ref() " 
  211                 "[this=" << nb_points() << 
", basic=" 
  212                 << basic_convex_ref_->nb_points());
 
  213     return psimplexified_convex.get();
 
  217   class convex_of_reference_key : 
virtual public dal::static_stored_object_key{
 
  223     bool compare(
const static_stored_object_key &oo)
 const override{
 
  224       const convex_of_reference_key &o
 
  225         = 
dynamic_cast<const convex_of_reference_key &
>(oo);
 
  226       if (type < o.type) 
return true;
 
  227       if (type > o.type) 
return false;
 
  228       if (N < o.N) 
return true;
 
  229       if (N > o.N) 
return false;
 
  230       if (K < o.K) 
return true;
 
  231       if (K > o.K) 
return false;
 
  232       if (nf < o.nf) 
return true;
 
  235     bool equal(
const static_stored_object_key &oo)
 const override{
 
  236       auto &o = 
dynamic_cast<const convex_of_reference_key &
>(oo);
 
  237       if (type != o.type) 
return false;
 
  238       if (N != o.N) 
return false;
 
  239       if (K != o.K) 
return false;
 
  240       if (nf != o.nf) 
return false;
 
  243     convex_of_reference_key(
int t, dim_type NN, 
short_type KK = 0,
 
  245       : type(t), N(NN), K(KK), nf(nnf) {}
 
  251   class K_simplex_of_ref_ : 
public convex_of_reference {
 
  253     scalar_type is_in(
const base_node &pt)
 const {
 
  255       GMM_ASSERT1(pt.size() == cvs->dim(),
 
  256                   "K_simplex_of_ref_::is_in: Dimensions mismatch");
 
  257       scalar_type e = -1.0, r = (pt.size() > 0) ? -pt[0] : 0.0;
 
  258       base_node::const_iterator it = pt.begin(), ite = pt.end();
 
  259       for (; it != ite; e += *it, ++it) r = std::max(r, -(*it));
 
  260       return std::max(r, e);
 
  263     scalar_type is_in_face(
short_type f, 
const base_node &pt)
 const {
 
  266       GMM_ASSERT1(pt.size() == cvs->dim(),
 
  267                   "K_simplex_of_ref_::is_in_face: Dimensions mismatch");
 
  268       if (f > 0) 
return -pt[f-1];
 
  269       scalar_type e = -1.0;
 
  270       base_node::const_iterator it = pt.begin(), ite = pt.end();
 
  271       for (; it != ite; e += *it, ++it) {};
 
  272       return e / sqrt(scalar_type(pt.size()));
 
  275     void project_into(base_node &pt)
 const {
 
  277         GMM_ASSERT1(pt.size() == cvs->dim(),
 
  278                     "K_simplex_of_ref_::project_into: Dimensions mismatch");
 
  279         scalar_type sum_coordinates = 0.0;
 
  280         for (
const auto &coord : pt) sum_coordinates += coord;
 
  281         if (sum_coordinates > 1.0) gmm::scale(pt, 1.0 / sum_coordinates);
 
  282         for (
auto &coord : pt) {
 
  283           if (coord < 0.0) coord = 0.0;
 
  284           if (coord > 1.0) coord = 1.0;
 
  287         basic_convex_ref_->project_into(pt);
 
  290     K_simplex_of_ref_(dim_type NN, 
short_type KK) :
 
  295       convex<base_node>::points().resize(R);
 
  296       normals_.resize(NN+1);
 
  297       base_node 
null(NN); 
null.fill(0.0);
 
  298       std::fill(normals_.begin(), normals_.end(), 
null);
 
  299       std::fill(convex<base_node>::points().begin(),
 
  300                 convex<base_node>::points().end(), 
null);
 
  302         normals_[i][i-1] = -1.0;
 
  304         std::fill(normals_[0].begin(), normals_[0].end(),
 
  305                   scalar_type(1.0)/sqrt(scalar_type(NN)));
 
  306       base_node c(NN);  c.fill(0.0);
 
  310         convex<base_node>::points()[0] = c;
 
  315           convex<base_node>::points()[r] = c;
 
  316           if (KK != 0 && NN > 0) {
 
  317             l = 0; c[l] += 1.0 / scalar_type(KK); sum++;
 
  319               sum -= int(floor(0.5+(c[l] * KK)));
 
  320               c[l] = 0.0; l++; 
if (l == NN) 
break;
 
  321               c[l] += 1.0 / scalar_type(KK); sum++;
 
  326       ppoints = store_point_tab(convex<base_node>::points());
 
  327       if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
 
  332     dal::pstatic_stored_object_key
 
  333       pk = std::make_shared<convex_of_reference_key>(0, nc, K);
 
  335     if (o) 
return std::dynamic_pointer_cast<const convex_of_reference>(o);
 
  336     pconvex_ref p = std::make_shared<K_simplex_of_ref_>(nc, K);
 
  338                            dal::PERMANENT_STATIC_OBJECT);
 
  340     if (p != p1) add_dependency(p, p1);
 
  349   class Q2_incomplete_of_ref_ : 
public convex_of_reference {
 
  351     scalar_type is_in(
const base_node& pt)
 const 
  352     { 
return basic_convex_ref_->is_in(pt); }
 
  353     scalar_type is_in_face(
short_type f, 
const base_node& pt)
 const 
  354     { 
return basic_convex_ref_->is_in_face(f, pt); }
 
  356     Q2_incomplete_of_ref_(dim_type nc) :
 
  359       GMM_ASSERT1(nc == 2 || nc == 3, 
"Sorry exist only in dimension 2 or 3");
 
  360       convex<base_node>::points().resize(cvs->nb_points());
 
  361       normals_.resize(nc == 2 ? 4: 6);
 
  365         normals_[0] = { 1, 0};
 
  366         normals_[1] = {-1, 0};
 
  367         normals_[2] = { 0, 1};
 
  368         normals_[3] = { 0,-1};
 
  370         convex<base_node>::points()[0] = base_node(0.0, 0.0);
 
  371         convex<base_node>::points()[1] = base_node(0.5, 0.0);
 
  372         convex<base_node>::points()[2] = base_node(1.0, 0.0);
 
  373         convex<base_node>::points()[3] = base_node(0.0, 0.5);
 
  374         convex<base_node>::points()[4] = base_node(1.0, 0.5);
 
  375         convex<base_node>::points()[5] = base_node(0.0, 1.0);
 
  376         convex<base_node>::points()[6] = base_node(0.5, 1.0);
 
  377         convex<base_node>::points()[7] = base_node(1.0, 1.0);
 
  380         normals_[0] = { 1, 0, 0};
 
  381         normals_[1] = {-1, 0, 0};
 
  382         normals_[2] = { 0, 1, 0};
 
  383         normals_[3] = { 0,-1, 0};
 
  384         normals_[4] = { 0, 0, 1};
 
  385         normals_[5] = { 0, 0,-1};
 
  387         convex<base_node>::points()[0] = base_node(0.0, 0.0, 0.0);
 
  388         convex<base_node>::points()[1] = base_node(0.5, 0.0, 0.0);
 
  389         convex<base_node>::points()[2] = base_node(1.0, 0.0, 0.0);
 
  390         convex<base_node>::points()[3] = base_node(0.0, 0.5, 0.0);
 
  391         convex<base_node>::points()[4] = base_node(1.0, 0.5, 0.0);
 
  392         convex<base_node>::points()[5] = base_node(0.0, 1.0, 0.0);
 
  393         convex<base_node>::points()[6] = base_node(0.5, 1.0, 0.0);
 
  394         convex<base_node>::points()[7] = base_node(1.0, 1.0, 0.0);
 
  396         convex<base_node>::points()[8] = base_node(0.0, 0.0, 0.5);
 
  397         convex<base_node>::points()[9] = base_node(1.0, 0.0, 0.5);
 
  398         convex<base_node>::points()[10] = base_node(0.0, 1.0, 0.5);
 
  399         convex<base_node>::points()[11] = base_node(1.0, 1.0, 0.5);
 
  401         convex<base_node>::points()[12] = base_node(0.0, 0.0, 1.0);
 
  402         convex<base_node>::points()[13] = base_node(0.5, 0.0, 1.0);
 
  403         convex<base_node>::points()[14] = base_node(1.0, 0.0, 1.0);
 
  404         convex<base_node>::points()[15] = base_node(0.0, 0.5, 1.0);
 
  405         convex<base_node>::points()[16] = base_node(1.0, 0.5, 1.0);
 
  406         convex<base_node>::points()[17] = base_node(0.0, 1.0, 1.0);
 
  407         convex<base_node>::points()[18] = base_node(0.5, 1.0, 1.0);
 
  408         convex<base_node>::points()[19] = base_node(1.0, 1.0, 1.0);
 
  410       ppoints = store_point_tab(convex<base_node>::points());
 
  415   DAL_SIMPLE_KEY(Q2_incomplete_of_reference_key_, dim_type);
 
  418      dal::pstatic_stored_object_key
 
  419       pk = std::make_shared<Q2_incomplete_of_reference_key_>(nc);
 
  421     if (o) 
return std::dynamic_pointer_cast<const convex_of_reference>(o);
 
  422     pconvex_ref p = std::make_shared<Q2_incomplete_of_ref_>(nc);
 
  424                            dal::PERMANENT_STATIC_OBJECT);
 
  426     if (p != p1) add_dependency(p, p1);
 
  434   class pyramid_QK_of_ref_ : 
public convex_of_reference {
 
  436     scalar_type is_in_face(
short_type f, 
const base_node& pt)
 const {
 
  439       GMM_ASSERT1(pt.size() == 3, 
"Dimensions mismatch");
 
  443         return gmm::vect_sp(normals_[f], pt) - sqrt(2.)/2.;
 
  446     scalar_type is_in(
const base_node& pt)
 const {
 
  448       scalar_type r = is_in_face(0, pt);
 
  449       for (
short_type f = 1; f < 5; ++f) r = std::max(r, is_in_face(f, pt));
 
  453     void project_into(base_node &pt)
 const {
 
  455         GMM_ASSERT1(pt.size() == 3, 
"Dimensions mismatch");
 
  456         if (pt[2] < .0) pt[2] = 0.;
 
  458           scalar_type reldist = 
gmm::vect_sp(normals_[f], pt)*sqrt(2.);
 
  460             gmm::scale(pt, 1./reldist);
 
  463         basic_convex_ref_->project_into(pt);
 
  467       GMM_ASSERT1(k == 1 || k == 2,
 
  468                   "Sorry exist only in degree 1 or 2, not " << k);
 
  470       convex<base_node>::points().resize(cvs->nb_points());
 
  471       normals_.resize(cvs->nb_faces());
 
  474       normals_[0] = { 0., 0., -1.};
 
  475       normals_[1] = { 0.,-1.,  1.};
 
  476       normals_[2] = { 1., 0.,  1.};
 
  477       normals_[3] = { 0., 1.,  1.};
 
  478       normals_[4] = {-1., 0.,  1.};
 
  480       for (
size_type i = 0; i < normals_.size(); ++i)
 
  481         gmm::scale(normals_[i], 1. / gmm::vect_norm2(normals_[i]));
 
  484         convex<base_node>::points()[0]  = base_node(-1.0, -1.0, 0.0);
 
  485         convex<base_node>::points()[1]  = base_node( 1.0, -1.0, 0.0);
 
  486         convex<base_node>::points()[2]  = base_node(-1.0,  1.0, 0.0);
 
  487         convex<base_node>::points()[3]  = base_node( 1.0,  1.0, 0.0);
 
  488         convex<base_node>::points()[4]  = base_node( 0.0,  0.0, 1.0);
 
  490         convex<base_node>::points()[0]  = base_node(-1.0, -1.0, 0.0);
 
  491         convex<base_node>::points()[1]  = base_node( 0.0, -1.0, 0.0);
 
  492         convex<base_node>::points()[2]  = base_node( 1.0, -1.0, 0.0);
 
  493         convex<base_node>::points()[3]  = base_node(-1.0,  0.0, 0.0);
 
  494         convex<base_node>::points()[4]  = base_node( 0.0,  0.0, 0.0);
 
  495         convex<base_node>::points()[5]  = base_node( 1.0,  0.0, 0.0);
 
  496         convex<base_node>::points()[6]  = base_node(-1.0,  1.0, 0.0);
 
  497         convex<base_node>::points()[7]  = base_node( 0.0,  1.0, 0.0);
 
  498         convex<base_node>::points()[8]  = base_node( 1.0,  1.0, 0.0);
 
  499         convex<base_node>::points()[9]  = base_node(-0.5, -0.5, 0.5);
 
  500         convex<base_node>::points()[10] = base_node( 0.5, -0.5, 0.5);
 
  501         convex<base_node>::points()[11] = base_node(-0.5,  0.5, 0.5);
 
  502         convex<base_node>::points()[12] = base_node( 0.5,  0.5, 0.5);
 
  503         convex<base_node>::points()[13] = base_node( 0.0,  0.0, 1.0);
 
  505       ppoints = store_point_tab(convex<base_node>::points());
 
  506       if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
 
  511   DAL_SIMPLE_KEY(pyramid_QK_reference_key_, dim_type);
 
  514      dal::pstatic_stored_object_key
 
  515       pk = std::make_shared<pyramid_QK_reference_key_>(k);
 
  517     if (o) 
return std::dynamic_pointer_cast<const convex_of_reference>(o);
 
  518     pconvex_ref p = std::make_shared<pyramid_QK_of_ref_>(k);
 
  520                            dal::PERMANENT_STATIC_OBJECT);
 
  522     if (p != p1) add_dependency(p, p1);
 
  531   class pyramid_Q2_incomplete_of_ref_ : 
public convex_of_reference {
 
  533     scalar_type is_in(
const base_node& pt)
 const 
  534     { 
return basic_convex_ref_->is_in(pt); }
 
  535     scalar_type is_in_face(
short_type f, 
const base_node& pt)
 const 
  536     { 
return basic_convex_ref_->is_in_face(f, pt); }
 
  539       convex<base_node>::points().resize(cvs->nb_points());
 
  540       normals_.resize(cvs->nb_faces());
 
  543       normals_ = basic_convex_ref_->normals();
 
  545       convex<base_node>::points()[0]  = base_node(-1.0, -1.0, 0.0);
 
  546       convex<base_node>::points()[1]  = base_node( 0.0, -1.0, 0.0);
 
  547       convex<base_node>::points()[2]  = base_node( 1.0, -1.0, 0.0);
 
  548       convex<base_node>::points()[3]  = base_node(-1.0,  0.0, 0.0);
 
  549       convex<base_node>::points()[4]  = base_node( 1.0,  0.0, 0.0);
 
  550       convex<base_node>::points()[5]  = base_node(-1.0,  1.0, 0.0);
 
  551       convex<base_node>::points()[6]  = base_node( 0.0,  1.0, 0.0);
 
  552       convex<base_node>::points()[7]  = base_node( 1.0,  1.0, 0.0);
 
  553       convex<base_node>::points()[8]  = base_node(-0.5, -0.5, 0.5);
 
  554       convex<base_node>::points()[9]  = base_node( 0.5, -0.5, 0.5);
 
  555       convex<base_node>::points()[10] = base_node(-0.5,  0.5, 0.5);
 
  556       convex<base_node>::points()[11] = base_node( 0.5,  0.5, 0.5);
 
  557       convex<base_node>::points()[12] = base_node( 0.0,  0.0, 1.0);
 
  559       ppoints = store_point_tab(convex<base_node>::points());
 
  560       if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
 
  565   DAL_SIMPLE_KEY(pyramid_Q2_incomplete_reference_key_, dim_type);
 
  568     dal::pstatic_stored_object_key
 
  569       pk = std::make_shared<pyramid_Q2_incomplete_reference_key_>(0);
 
  572       return std::dynamic_pointer_cast<const convex_of_reference>(o);
 
  574       pconvex_ref p = std::make_shared<pyramid_Q2_incomplete_of_ref_>();
 
  576                              dal::PERMANENT_STATIC_OBJECT);
 
  578       if (p != p1) add_dependency(p, p1);
 
  588   class prism_incomplete_P2_of_ref_ : 
public convex_of_reference {
 
  590     scalar_type is_in(
const base_node& pt)
 const 
  591     { 
return basic_convex_ref_->is_in(pt); }
 
  592     scalar_type is_in_face(
short_type f, 
const base_node& pt)
 const 
  593     { 
return basic_convex_ref_->is_in_face(f, pt); }
 
  596       convex<base_node>::points().resize(cvs->nb_points());
 
  597       normals_.resize(cvs->nb_faces());
 
  600       normals_ = basic_convex_ref_->normals();
 
  602       convex<base_node>::points()[0]  = base_node(0.0, 0.0, 0.0);
 
  603       convex<base_node>::points()[1]  = base_node(0.5, 0.0, 0.0);
 
  604       convex<base_node>::points()[2]  = base_node(1.0, 0.0, 0.0);
 
  605       convex<base_node>::points()[3]  = base_node(0.0, 0.5, 0.0);
 
  606       convex<base_node>::points()[4]  = base_node(0.5, 0.5, 0.0);
 
  607       convex<base_node>::points()[5]  = base_node(0.0, 1.0, 0.0);
 
  608       convex<base_node>::points()[6]  = base_node(0.0, 0.0, 0.5);
 
  609       convex<base_node>::points()[7]  = base_node(1.0, 0.0, 0.5);
 
  610       convex<base_node>::points()[8]  = base_node(0.0, 1.0, 0.5);
 
  611       convex<base_node>::points()[9]  = base_node(0.0, 0.0, 1.0);
 
  612       convex<base_node>::points()[10] = base_node(0.5, 0.0, 1.0);
 
  613       convex<base_node>::points()[11] = base_node(1.0, 0.0, 1.0);
 
  614       convex<base_node>::points()[12] = base_node(0.0, 0.5, 1.0);
 
  615       convex<base_node>::points()[13] = base_node(0.5, 0.5, 1.0);
 
  616       convex<base_node>::points()[14] = base_node(0.0, 1.0, 1.0);
 
  618       ppoints = store_point_tab(convex<base_node>::points());
 
  619       if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
 
  624   DAL_SIMPLE_KEY(prism_incomplete_P2_reference_key_, dim_type);
 
  627     dal::pstatic_stored_object_key
 
  628       pk = std::make_shared<prism_incomplete_P2_reference_key_>(0);
 
  631       return std::dynamic_pointer_cast<const convex_of_reference>(o);
 
  633       pconvex_ref p = std::make_shared<prism_incomplete_P2_of_ref_>();
 
  635                              dal::PERMANENT_STATIC_OBJECT);
 
  637       if (p != p1) add_dependency(p, p1);
 
  647   DAL_DOUBLE_KEY(product_ref_key_, pconvex_ref, pconvex_ref);
 
  649   struct product_ref_ : 
public convex_of_reference {
 
  650     pconvex_ref cvr1, cvr2;
 
  652     scalar_type is_in(
const base_node &pt)
 const {
 
  653       dim_type n1 = cvr1->structure()->dim(), n2 = cvr2->structure()->dim();
 
  654       base_node pt1(n1), pt2(n2);
 
  655       GMM_ASSERT1(pt.size() == cvs->dim(),
 
  656                   "product_ref_::is_in: Dimension does not match");
 
  657       std::copy(pt.begin(), pt.begin()+n1, pt1.begin());
 
  658       std::copy(pt.begin()+n1,   pt.end(), pt2.begin());
 
  659       return std::max(cvr1->is_in(pt1), cvr2->is_in(pt2));
 
  662     scalar_type is_in_face(
short_type f, 
const base_node &pt)
 const {
 
  665       dim_type n1 = cvr1->structure()->dim(), n2 = cvr2->structure()->dim();
 
  666       base_node pt1(n1), pt2(n2);
 
  667       GMM_ASSERT1(pt.size() == cvs->dim(), 
"Dimensions mismatch");
 
  668       std::copy(pt.begin(), pt.begin()+n1, pt1.begin());
 
  669       std::copy(pt.begin()+n1,   pt.end(), pt2.begin());
 
  670       if (f < cvr1->structure()->nb_faces()) 
return cvr1->is_in_face(f, pt1);
 
  671       else return cvr2->is_in_face(
short_type(f - cvr1->structure()->nb_faces()), pt2);
 
  674     void project_into(base_node &pt)
 const {
 
  676         GMM_ASSERT1(pt.size() == cvs->dim(), 
"Dimensions mismatch");
 
  677         dim_type n1 = cvr1->structure()->dim(), n2 = cvr2->structure()->dim();
 
  678         base_node pt1(n1), pt2(n2);
 
  679         std::copy(pt.begin(), pt.begin()+n1, pt1.begin());
 
  680         std::copy(pt.begin()+n1,   pt.end(), pt2.begin());
 
  681         cvr1->project_into(pt1);
 
  682         cvr2->project_into(pt2);
 
  683         std::copy(pt1.begin(), pt1.end(), pt.begin());
 
  684         std::copy(pt2.begin(), pt2.end(), pt.begin()+n1);
 
  686         basic_convex_ref_->project_into(pt);
 
  689     product_ref_(pconvex_ref a, pconvex_ref b) :
 
  691         convex_direct_product(*a, *b).structure(),
 
  694       if (a->structure()->dim() < b->structure()->dim())
 
  695         GMM_WARNING1(
"Illegal convex: swap your operands: dim(cv1)=" <<
 
  696                     int(a->structure()->dim()) << 
" < dim(cv2)=" <<
 
  697                     int(b->structure()->dim()));
 
  699       *((convex<base_node> *)(
this)) = convex_direct_product(*a, *b);
 
  700       normals_.resize(cvs->nb_faces());
 
  701       base_small_vector 
null(cvs->dim()); 
null.fill(0.0);
 
  702       std::fill(normals_.begin(), normals_.end(), 
null);
 
  703       for (
size_type r = 0; r < cvr1->structure()->nb_faces(); r++)
 
  704         std::copy(cvr1->normals()[r].begin(), cvr1->normals()[r].end(),
 
  705                   normals_[r].begin());
 
  706       for (
size_type r = 0; r < cvr2->structure()->nb_faces(); r++)
 
  707         std::copy(cvr2->normals()[r].begin(), cvr2->normals()[r].end(),
 
  708                   normals_[r+cvr1->structure()->nb_faces()].begin()
 
  709                   + cvr1->structure()->dim());
 
  710       ppoints = store_point_tab(convex<base_node>::points());
 
  715       if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
 
  721     dal::pstatic_stored_object_key
 
  722       pk = std::make_shared<product_ref_key_>(a, b);
 
  725       return std::dynamic_pointer_cast<const convex_of_reference>(o);
 
  727       pconvex_ref p = std::make_shared<product_ref_>(a, b);
 
  731                              p->pspt(), dal::PERMANENT_STATIC_OBJECT);
 
  733       if (p != p1) add_dependency(p, p1);
 
  751   class equilateral_simplex_of_ref_ : 
public convex_of_reference {
 
  754     scalar_type is_in(
const base_node &pt)
 const {
 
  755       GMM_ASSERT1(pt.size() == cvs->dim(), 
"Dimension does not match");
 
  757       for (
size_type f = 0; f < normals().size(); ++f) {
 
  758         const base_node &x0 = (f ? convex<base_node>::points()[f-1]
 
  759                                : convex<base_node>::points().back());
 
  760         scalar_type v = gmm::vect_sp(pt-x0, normals()[f]);
 
  761         if (f == 0) d = v; 
else d = std::max(d,v);
 
  766     scalar_type is_in_face(
short_type f, 
const base_node &pt)
 const {
 
  767       GMM_ASSERT1(pt.size() == cvs->dim(), 
"Dimension does not match");
 
  768       const base_node &x0 = (f ? convex<base_node>::points()[f-1]
 
  769                              : convex<base_node>::points().back());
 
  773     void project_into(base_node &pt)
 const {
 
  774       dim_type N = cvs->dim();
 
  775       GMM_ASSERT1(pt.size() == N, 
"Dimension does not match");
 
  776       base_node G(N); G.fill(0.);
 
  777       for (
const base_node &x : convex<base_node>::points())
 
  779       gmm::scale(G, scalar_type(1)/scalar_type(N+1));
 
  783           pt = G + r_inscr/r*(pt-G);
 
  788     equilateral_simplex_of_ref_(
size_type N) :
 
  792       r_inscr = scalar_type(1)/sqrt(scalar_type(2*N)*scalar_type(N+1));
 
  795       convex<base_node>::points().resize(N+1);
 
  796       normals_.resize(N+1);
 
  797       base_node G(N); G.fill(0.);
 
  799         convex<base_node>::points()[i].resize(N);
 
  801           std::copy(prev->convex<base_node>::points()[i].begin(),
 
  802                     prev->convex<base_node>::points()[i].end(),
 
  803                     convex<base_node>::points()[i].begin());
 
  804           convex<base_node>::points()[i][N-1] = 0.;
 
  806           convex<base_node>::points()[i] = scalar_type(1)/scalar_type(N) * G;
 
  807           convex<base_node>::points()[i][N-1]
 
  808             = sqrt(1. - gmm::vect_norm2_sqr(convex<base_node>::points()[i]));
 
  810         G += convex<base_node>::points()[i];
 
  812       gmm::scale(G, scalar_type(1)/scalar_type(N+1));
 
  814         normals_[f] = G - convex<base_node>::points()[f];
 
  815         gmm::scale(normals_[f], 1/gmm::vect_norm2(normals_[f]));
 
  817       ppoints = store_point_tab(convex<base_node>::points());
 
  818       if (auto_basic) simplexify_convex(
this, *psimplexified_convex);
 
  824      dal::pstatic_stored_object_key
 
  825       pk = std::make_shared<convex_of_reference_key>(1, nc);
 
  827     if (o) 
return std::dynamic_pointer_cast<const convex_of_reference>(o);
 
  828     pconvex_ref p = std::make_shared<equilateral_simplex_of_ref_>(nc);
 
  830                            dal::PERMANENT_STATIC_OBJECT);
 
  837   class generic_dummy_ : 
public convex_of_reference {
 
  839     scalar_type is_in(
const base_node &)
 const 
  840     { GMM_ASSERT1(
false, 
"Information not available here"); }
 
  841     scalar_type is_in_face(
short_type, 
const base_node &)
 const 
  842     { GMM_ASSERT1(
false, 
"Information not available here"); }
 
  843     void project_into(base_node &)
 const 
  844     { GMM_ASSERT1(
false, 
"Operation not available here"); }
 
  849       convex<base_node>::points().resize(n);
 
  852       std::fill(P.begin(), P.end(), scalar_type(1)/scalar_type(20));
 
  853       std::fill(convex<base_node>::points().begin(), convex<base_node>::points().end(), P);
 
  854       ppoints = store_point_tab(convex<base_node>::points());
 
  860     dal::pstatic_stored_object_key
 
  861       pk = std::make_shared<convex_of_reference_key>(2, nc, 
short_type(n), nf);
 
  863     if (o) 
return std::dynamic_pointer_cast<const convex_of_reference>(o);
 
  864     pconvex_ref p = std::make_shared<generic_dummy_>(nc, n, nf);
 
  866                            dal::PERMANENT_STATIC_OBJECT);
 
convenient initialization of vectors via overload of "operator,".
Mesh structure definition.
Base class for reference convexes.
const stored_point_tab & points() const
return the vertices of the reference convex.
const mesh_structure * simplexified_convex() const
return a mesh structure composed of simplexes whose union is the reference convex.
const std::vector< base_small_vector > & normals() const
return the normal vector for each face.
Mesh structure definition.
void clear()
erase the mesh
A simple singleton implementation.
strongest_value_type< V1, V2 >::value_type vect_sp(const V1 &v1, const V2 &v2)
*/
pconvex_structure prism_incomplete_P2_structure()
Give a pointer on the 3D quadratic incomplete prism structure.
pconvex_ref convex_ref_product(pconvex_ref a, pconvex_ref b)
tensorial product of two convex ref.
pconvex_structure pyramid_Q2_incomplete_structure()
Give a pointer on the 3D quadratic incomplete pyramid structure.
gmm::uint16_type short_type
used as the common short type integer 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.
pconvex_ref equilateral_simplex_of_reference(dim_type nc)
equilateral simplex (degree 1).
pconvex_ref pyramid_QK_of_reference(dim_type k)
pyramidal element of reference of degree k (k = 1 or 2 only)
pconvex_ref simplex_of_reference(dim_type nc, short_type K)
returns a simplex of reference of dimension nc and degree k
std::shared_ptr< const convex_structure > pconvex_structure
Pointer on a convex structure description.
pconvex_structure generic_dummy_structure(dim_type nc, size_type n, short_type nf)
Generic convex with n global nodes.
pconvex_ref pyramid_Q2_incomplete_of_reference()
incomplete quadratic pyramidal element of reference (13-node)
pconvex_ref prism_incomplete_P2_of_reference()
incomplete quadratic prism element of reference (15-node)
pconvex_structure Q2_incomplete_structure(dim_type nc)
Give a pointer on the structures of a incomplete Q2 quadrilateral/hexahedral of dimension d = 2 or 3.
pconvex_ref parallelepiped_of_reference(dim_type nc, dim_type k)
parallelepiped of reference of dimension nc (and degree 1)
pconvex_ref generic_dummy_convex_ref(dim_type nc, size_type n, short_type nf)
generic convex with n global nodes
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_ref Q2_incomplete_of_reference(dim_type nc)
incomplete Q2 quadrilateral/hexahedral of reference of dimension d = 2 or 3
pconvex_structure convex_product_structure(pconvex_structure a, pconvex_structure b)
Give a pointer on the structures of a convex which is the direct product of the convexes represented ...
pconvex_structure basic_structure(pconvex_structure cv)
Original structure (if concerned)
pconvex_ref basic_convex_ref(pconvex_ref cvr)
return the associated order 1 reference convex.
pconvex_ref prism_of_reference(dim_type nc)
prism of reference of dimension nc (and degree 1)
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.