getfem-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Getfem-commits] (no subject)


From: Yves Renard
Subject: [Getfem-commits] (no subject)
Date: Thu, 25 May 2017 12:21:27 -0400 (EDT)

branch: devel-yves
commit e70af36cc7b1e81379b7638b71e413545c4c0f44
Author: Yves Renard <address@hidden>
Date:   Wed May 24 23:44:44 2017 +0200

    adding pyramidal element, work in progress
---
 doc/sphinx/source/userdoc/appendixA.rst |  72 +++++++++----------
 src/bgeot_convex_ref.cc                 | 110 ++++++++++++++++++++++++-----
 src/bgeot_convex_ref_simplexified.cc    |  16 ++++-
 src/bgeot_convex_structure.cc           | 119 ++++++++++++++++++++++++++++---
 src/bgeot_geometric_trans.cc            |  54 +++++++++++++-
 src/getfem/bgeot_convex_ref.h           |   4 +-
 src/getfem/bgeot_convex_structure.h     |   5 +-
 src/getfem/bgeot_geometric_trans.h      |   3 +-
 src/getfem/bgeot_poly.h                 | 121 ++++++++++++++++++++++++++++++++
 9 files changed, 430 insertions(+), 74 deletions(-)

diff --git a/doc/sphinx/source/userdoc/appendixA.rst 
b/doc/sphinx/source/userdoc/appendixA.rst
index 59a8d6d..af728e4 100644
--- a/doc/sphinx/source/userdoc/appendixA.rst
+++ b/doc/sphinx/source/userdoc/appendixA.rst
@@ -64,8 +64,8 @@ Appendix A. Finite element method list
             :scale: 50
      * - Value of the whole second derivative (hessian) at the node.
        - Scalar product with a certain vector (for instance an edge) for a
-         vectorial elements.
-       - Scalar product with the normal to a face for a vectorial elements.
+         vector elements.
+       - Scalar product with the normal to a face for a vector elements.
      * - .. image:: images/getfemlistsymbols12.png
             :align: center
             :scale: 50
@@ -212,7 +212,7 @@ the classical :math:`P_K` Lagrange element.
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -234,7 +234,7 @@ the classical :math:`P_K` Lagrange element.
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -338,7 +338,7 @@ not to have the same degree on each dimension. An example 
is shown on figure
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -360,7 +360,7 @@ not to have the same degree on each dimension. An example 
is shown on figure
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -382,7 +382,7 @@ not to have the same degree on each dimension. An example 
is shown on figure
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -412,7 +412,7 @@ not to have the same degree on each dimension. An example 
is shown on figure
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -458,7 +458,7 @@ Hierarchical elements with respect to the degree
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -480,7 +480,7 @@ Hierarchical elements with respect to the degree
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -502,7 +502,7 @@ Hierarchical elements with respect to the degree
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -546,7 +546,7 @@ elements. But this tool can also be used to build piecewise 
polynomial elements.
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -581,7 +581,7 @@ Hierarchical composite elements
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -603,7 +603,7 @@ Hierarchical composite elements
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -621,7 +621,7 @@ and ``"FEM_STRUCTURED_COMPOSITE(FEM1, S)"``.
 It is important to use a corresponding composite integration method.
 
 
-Classical vectorial elements
+Classical vector elements
 ----------------------------
 
 Raviart-Thomas of lowest order elements
@@ -644,7 +644,7 @@ Raviart-Thomas of lowest order elements
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -666,7 +666,7 @@ Raviart-Thomas of lowest order elements
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -699,7 +699,7 @@ Nedelec (or Whitney) edge elements
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -739,7 +739,7 @@ following values of :math:`K`: :math:`1, 2, 3, 4, 5, 6, 7, 
8, 9, 10, 11, 12, 13,
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -784,7 +784,7 @@ is still diagonal.
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -817,7 +817,7 @@ Lagrange element with an additional bubble function
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -862,7 +862,7 @@ Elements with additional bubble functions
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -893,7 +893,7 @@ Elements with additional bubble functions
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -924,7 +924,7 @@ Elements with additional bubble functions
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -955,7 +955,7 @@ Elements with additional bubble functions
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -988,7 +988,7 @@ Non-conforming :math:`P_1` element
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -1042,7 +1042,7 @@ Idem for the two couples :math:`(\widehat{\varphi}_5`, 
:math:`\widehat{\varphi}_
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -1078,7 +1078,7 @@ fourth order problems, despite the fact that it is not 
:math:`{\cal C}^1`.
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -1144,7 +1144,7 @@ transformations (for instance to treat curved boundaries).
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -1185,7 +1185,7 @@ and 9, 10, 11 for the normal derivatives on face 0, 1, 2 
respectively.
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -1218,7 +1218,7 @@ assumed to be polynomial of degree one on each edge (see 
figure
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -1256,7 +1256,7 @@ to use a ``"IM_QUADC1_COMPOSITE"`` integration method 
with this finite element.
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -1290,7 +1290,7 @@ assumed to be polynomial of degree one on each edge (see 
figure
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -1339,7 +1339,7 @@ Elements with additional bubble functions
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -1370,7 +1370,7 @@ Elements with additional bubble functions
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
@@ -1434,7 +1434,7 @@ the corresponding vertex. Idem on the other vertices.
        - dimension
        - d.o.f. number
        - class
-       - vectorial
+       - vector
        - :math:`\tau`-equivalent
        - Polynomial
 
diff --git a/src/bgeot_convex_ref.cc b/src/bgeot_convex_ref.cc
index a468ff8..38536ab 100644
--- a/src/bgeot_convex_ref.cc
+++ b/src/bgeot_convex_ref.cc
@@ -134,19 +134,19 @@ namespace bgeot {
   class K_simplex_of_ref_ : public convex_of_reference {
   public :
     scalar_type is_in(const base_node &pt) const {
-      // return a negative or null number if pt is in the convex
+      // return a negative number if pt is in the convex
       GMM_ASSERT1(pt.size() == cvs->dim(),
-                  "K_simplex_of_ref_::is_in: Dimension does not match");
+                  "K_simplex_of_ref_::is_in: Dimensions mismatch");
       scalar_type e = -1.0, r = (pt.size() > 0) ? -pt[0] : 0.0;
       base_node::const_iterator it = pt.begin(), ite = pt.end();
       for (; it != ite; e += *it, ++it) r = std::max(r, -(*it));
       return std::max(r, e);
     }
     scalar_type is_in_face(short_type f, const base_node &pt) const {
-      // return a null number if pt is in the face of the convex
+      // return zero if pt is in the face of the convex
       // negative if the point is on the side of the face where the element is
       GMM_ASSERT1(pt.size() == cvs->dim(),
-                  "K_simplex_of_ref_::is_in_face: Dimension does not match");
+                  "K_simplex_of_ref_::is_in_face: Dimensions mismatch");
       if (f > 0) return -pt[f-1];
       scalar_type e = -1.0;
       base_node::const_iterator it = pt.begin(), ite = pt.end();
@@ -295,6 +295,90 @@ namespace bgeot {
     return p;
   }
 
+  /* ******************************************************************** */
+  /*    Pyramidal element of reference.                                   */
+  /* ******************************************************************** */
+
+  class pyramid_of_ref_ : public convex_of_reference {
+  public :
+    scalar_type is_in_face(short_type f, const base_node& pt) const {
+      // return zero if pt is in the face of the convex
+      // negative if the point is on the side of the face where the element is
+      GMM_ASSERT1(pt.size() == 3, "Dimensions mismatch");
+      if (f == 0)
+       return -pt[2];
+      else
+       return gmm::vect_sp(normals_[f], pt) - sqrt(2.)/2.;
+    }
+    scalar_type is_in(const base_node& pt) const {
+      // return a negative number if pt is in the convex
+      scalar_type r = is_in_face(0, pt);
+      for (short_type i = 1; i < 5; ++i) r = std::max(r, is_in_face(i, pt));
+      return r;
+    }
+    
+    pyramid_of_ref_(dim_type k) {
+      GMM_ASSERT1(k == 1 || k == 2, "Sorry exist only in degree 2 or 3");
+
+      cvs = pyramidal_structure(k);
+      convex<base_node>::points().resize(cvs->nb_points());
+      normals_.resize(cvs->nb_faces());
+      if (k == 1)
+       auto_basic = true;
+      else
+       basic_convex_ref_ = pyramidal_element_of_reference(1);
+
+      sc(normals_[0]) =  0., 0., 1.;
+      sc(normals_[1]) =  0.,-1., 1.;
+      sc(normals_[2]) =  1., 0., 1.;
+      sc(normals_[3]) =  0., 1., 1.;
+      sc(normals_[4]) = -1., 0., 1.;
+
+      for (size_type i = 0; i < normals_.size(); ++i)
+       gmm::scale(normals_[i], 1. / gmm::vect_norm2(normals_[i]));
+      
+      if (k==1) {
+        convex<base_node>::points()[0]  = base_node(-1.0, -1.0, 0.0);
+        convex<base_node>::points()[1]  = base_node( 1.0, -1.0, 0.0);
+        convex<base_node>::points()[2]  = base_node(-1.0,  1.0, 0.0);
+        convex<base_node>::points()[3]  = base_node( 1.0,  1.0, 0.0);
+        convex<base_node>::points()[4]  = base_node( 0.0,  0.0, 1.0);
+      } else if (k==2) {
+        convex<base_node>::points()[0]  = base_node(-1.0, -1.0, 0.0);
+        convex<base_node>::points()[1]  = base_node( 0.0, -1.0, 0.0);
+        convex<base_node>::points()[2]  = base_node( 1.0, -1.0, 0.0);
+        convex<base_node>::points()[3]  = base_node(-1.0,  0.0, 0.0);
+        convex<base_node>::points()[4]  = base_node( 0.0,  0.0, 0.0);
+        convex<base_node>::points()[5]  = base_node( 1.0,  0.0, 0.0);
+        convex<base_node>::points()[6]  = base_node(-1.0,  1.0, 0.0);
+        convex<base_node>::points()[7]  = base_node( 0.0,  1.0, 0.0);
+        convex<base_node>::points()[8]  = base_node( 1.0,  1.0, 0.0);
+        convex<base_node>::points()[9]  = base_node(-0.5, -0.5, 0.5);
+        convex<base_node>::points()[10] = base_node( 0.5, -0.5, 0.5);
+        convex<base_node>::points()[11] = base_node(-0.5,  0.5, 0.5);
+        convex<base_node>::points()[12] = base_node( 0.5,  0.5, 0.5);
+        convex<base_node>::points()[13] = base_node( 0.0,  0.0, 1.0);
+      }
+      ppoints = store_point_tab(convex<base_node>::points());
+    }
+  };
+  
+  
+  DAL_SIMPLE_KEY(pyramidal_reference_key_, dim_type);
+  
+  pconvex_ref pyramidal_element_of_reference(dim_type k) {
+     dal::pstatic_stored_object_key
+      pk = std::make_shared<pyramidal_reference_key_>(k);
+    dal::pstatic_stored_object o = dal::search_stored_object(pk);
+    if (o) return std::dynamic_pointer_cast<const convex_of_reference>(o);
+    pconvex_ref p = std::make_shared<pyramid_of_ref_>(k);
+    dal::add_stored_object(pk, p, p->structure(), p->pspt(),
+                           dal::PERMANENT_STATIC_OBJECT);
+    pconvex_ref p1 = basic_convex_ref(p);
+    if (p != p1) add_dependency(p, p1); 
+    return p;
+  }
+
 
   /* ******************************************************************** */
   /*    Products.                                                         */
@@ -370,20 +454,10 @@ namespace bgeot {
     return p;
   }
 
-  struct parallelepiped_of_reference_tab
-    : public dal::dynamic_array<pconvex_ref> {};
-
-  pconvex_ref parallelepiped_of_reference(dim_type nc) {
-    parallelepiped_of_reference_tab &tab
-      = dal::singleton<parallelepiped_of_reference_tab>::instance();
-    static dim_type ncd = 1;
-    if (nc <= 1) return simplex_of_reference(nc);
-    if (nc > ncd) { 
-      tab[nc] = convex_ref_product(parallelepiped_of_reference(dim_type(nc-1)),
-                                   simplex_of_reference(1));
-      ncd = nc;
-    }
-    return tab[nc];
+  pconvex_ref parallelepiped_of_reference(dim_type nc, dim_type k) {
+    if (nc <= 1) return simplex_of_reference(nc,k);
+    return convex_ref_product(parallelepiped_of_reference(dim_type(nc-1),k),
+                             simplex_of_reference(k));
   }
 
   pconvex_ref prism_of_reference(dim_type nc) {
diff --git a/src/bgeot_convex_ref_simplexified.cc 
b/src/bgeot_convex_ref_simplexified.cc
index e297e9a..94292bb 100644
--- a/src/bgeot_convex_ref_simplexified.cc
+++ b/src/bgeot_convex_ref_simplexified.cc
@@ -23,7 +23,7 @@
 #include "getfem/bgeot_convex_ref.h"
 
 
- namespace bgeot {
+namespace bgeot {
 
 
   static size_type simplexified_parallelepiped_2[6] = {
@@ -250,9 +250,14 @@
   };
 
   static size_type simplexified_prism_6_nb = 6;
+ 
+  static size_type simplexified_pyramid[30] = {
+     0, 1, 2, 4, 3, 2, 1, 4
+  };
 
-
-
+  static size_type simplexified_pyramid_nb = 3;
+   
+  
   size_type simplexified_tab(pconvex_structure cvs,
                              size_type **tab) {
     if (cvs == parallelepiped_structure(2)) {
@@ -300,6 +305,11 @@
       return simplexified_prism_6_nb;
     }
 
+    if (cvs == pyramidal_structure(1)) {
+      *tab = simplexified_pyramid;
+      return simplexified_pyramid_nb;
+    }
+
     GMM_ASSERT1(false, "No simplexification for this element");
   }
 
diff --git a/src/bgeot_convex_structure.cc b/src/bgeot_convex_structure.cc
index 40fcd51..c96f210 100644
--- a/src/bgeot_convex_structure.cc
+++ b/src/bgeot_convex_structure.cc
@@ -28,9 +28,9 @@
 namespace bgeot {
 
   /* ******************************************************************** */
-  /*                                                                          
*/
+  /*                                                                      */
   /* class   convex_structure                                             */
-  /*                                                                          
*/
+  /*                                                                      */
   /* ******************************************************************** */
 
   void convex_structure::add_point_adaptative(short_type i, short_type f) {
@@ -358,26 +358,25 @@ namespace bgeot {
     { DAL_STORED_OBJECT_DEBUG_DESTROYED(this, "parallelepiped structure"); }
   };
 
-  DAL_SIMPLE_KEY(parallelepiped_key_, dim_type);
+  DAL_DOUBLE_KEY(parallelepiped_key_, dim_type, dim_type);
 
-  pconvex_structure parallelepiped_structure(dim_type nc) {
-    if (nc <= 1) return simplex_structure(nc);
+  pconvex_structure parallelepiped_structure(dim_type nc, dim_type k) {
+    if (nc <= 1) return simplex_structure(nc, k);
     dal::pstatic_stored_object_key
-      pcsk = std::make_shared<parallelepiped_key_>(nc);
+      pcsk = std::make_shared<parallelepiped_key_>(nc, k);
 
     dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
     if (o) return ((std::dynamic_pointer_cast<const parallelepiped_>(o))->p);
     auto p = std::make_shared<parallelepiped_>();
-    p->p = convex_product_structure(parallelepiped_structure(dim_type(nc-1)),
-                                    simplex_structure(1));
+    p->p = convex_product_structure(parallelepiped_structure(dim_type(nc-1),k),
+                                    simplex_structure(1,k));
     dal::add_stored_object(pcsk, dal::pstatic_stored_object(p), p->p,
                            dal::PERMANENT_STATIC_OBJECT);
     return p->p;
   }
 
-
   /* ******************************************************************** */
-  /*        Incomplete Q2 structure for n=2 or 3.                             
*/
+  /*        Incomplete Q2 structure for n=2 or 3.                         */
   /* ******************************************************************** */
   /* By Yao Koutsawa  <address@hidden> 2012-12-10                  */
 
@@ -456,8 +455,106 @@ namespace bgeot {
   }
 
 
+
+  /* ******************************************************************** */
+  /*        Pyramidal 3D structure for k=1 or 2.                          */
+  /* ******************************************************************** */
+
+  struct pyramidal_structure_ : public convex_structure {
+    friend pconvex_structure pyramidal_structure(dim_type k);
+  };
+
+  DAL_SIMPLE_KEY(pyramidal_structure_key_, dim_type);
+
+  pconvex_structure pyramidal_structure(dim_type k) {
+    GMM_ASSERT1(k == 1 || k == 2, "Sorry, pyramidal elements implemented "
+               "only for degree one or two.");
+    dal::pstatic_stored_object_key
+      pcsk = std::make_shared<pyramidal_structure_key_>(k);
+    dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
+    if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
+
+    auto p = std::make_shared<pyramidal_structure_>();
+    pconvex_structure pcvs(p);
+    
+    p->Nc = 3;
+    p->dir_points_ = std::vector<short_type>(p->Nc + 1);
+    
+
+    if (k == 2) {
+      p->nbpt = 5;
+      p->nbf = 5;
+      p->auto_basic = true;
+      //    4 
+      //   /|||
+      //  / || |
+      // 2-|--|-3
+      // | |  | |
+      // ||    ||
+      // ||    ||
+      // 0------1
+      p->faces_struct.resize(p->nbf);
+      p->faces = std::vector< std::vector<short_type> >(p->nbf);
+      sc(p->faces[0]) = 0,1,2,3;
+      sc(p->faces[1]) = 0,1,4;
+      sc(p->faces[2]) = 1,3,4;
+      sc(p->faces[3]) = 3,2,4;
+      sc(p->faces[4]) = 2,0,4;
+
+      p->dir_points_[0] = 0;
+      p->dir_points_[1] = 1;
+      p->dir_points_[2] = 2;
+      p->dir_points_[3] = 4;
+
+      p->faces_struct[0] = parallelepiped_structure(2);
+      for (int i = 1; i < p->nbf; i++)
+       p->faces_struct[i] = simplex_structure(2);
+
+      dal::add_stored_object(pcsk, pcvs, parallelepiped_structure(2),
+                            simplex_structure(2),
+                            dal::PERMANENT_STATIC_OBJECT);
+      
+    } else {
+      p->nbpt = 14;
+      p->nbf = 5;
+      p->basic_pcvs = pyramidal_structure(1);
+      //    13
+      //   /  |
+      //  11--12
+      //  |   |
+      //  9---10
+      //  /    |
+      // 6--7--8
+      // |     |
+      // 3  4  5
+      // |     |
+      // 0--1--2
+      p->faces_struct.resize(p->nbf);
+      p->faces = std::vector< std::vector<short_type> >(p->nbf);
+      sc(p->faces[0]) = 0,1,2,3,4,5,6,7,8;
+      sc(p->faces[1]) = 0,1,2,9,10,13;
+      sc(p->faces[2]) = 2,5,8,10,12,13;
+      sc(p->faces[3]) = 8,7,6,12,11,13;
+      sc(p->faces[4]) = 6,3,0,11,9,13;
+
+      p->dir_points_[0] = 0;
+      p->dir_points_[1] = 2;
+      p->dir_points_[2] = 6;
+      p->dir_points_[3] = 13;
+
+      p->faces_struct[0] = parallelepiped_structure(2, 2);
+      for (int i = 1; i < p->nbf; i++)
+       p->faces_struct[i] = simplex_structure(2, 2);
+
+      dal::add_stored_object(pcsk, pcvs, parallelepiped_structure(2, 2),
+                            simplex_structure(2, 2),
+                            dal::PERMANENT_STATIC_OBJECT);
+    }
+    return pcvs;
+  }
+  
   /* ******************************************************************** */
-  /*        Generic dummy convex with n global nodes.                         
*/
+  /*        Generic dummy convex with n global nodes.                     */
   /* ******************************************************************** */
 
   struct dummy_structure_ : public convex_structure {
diff --git a/src/bgeot_geometric_trans.cc b/src/bgeot_geometric_trans.cc
index d83e27c..4a4db84 100644
--- a/src/bgeot_geometric_trans.cc
+++ b/src/bgeot_geometric_trans.cc
@@ -461,17 +461,18 @@ namespace bgeot {
     return P;
   }
 
-  void geometric_trans::fill_standard_vertices(void) {
+  void geometric_trans::fill_standard_vertices() {
     vertices_.resize(0);
     for (size_type ip = 0; ip < nb_points(); ++ip) {
       bool vertex = true;
       for (size_type i = 0; i < cvr->points()[ip].size(); ++i)
         if (gmm::abs(cvr->points()[ip][i]) > 1e-10
-            && gmm::abs(cvr->points()[ip][i]-1.0) > 1e-10)
+            && gmm::abs(cvr->points()[ip][i]-1.0) > 1e-10
+           && gmm::abs(cvr->points()[ip][i]+1.0) > 1e-10)
           { vertex = false; break; }
       if (vertex) vertices_.push_back(ip);
     }
-    assert(vertices_.size() >= dim());
+    assert(vertices_.size() > dim());
   }
 
   /* ******************************************************************** */
@@ -539,6 +540,7 @@ namespace bgeot {
 
   typedef igeometric_trans<base_poly> poly_geometric_trans;
   typedef igeometric_trans<polynomial_composite> comppoly_geometric_trans;
+  typedef igeometric_trans<base_rational_fraction> fraction_geometric_trans;
 
   /* ******************************************************************** */
   /* transformation on simplex.                                           */
@@ -820,6 +822,51 @@ namespace bgeot {
     return geometric_trans_descriptor(name.str());
   }
 
+  /* ******************************************************************** */
+  /*   Pyramidal geometric transformation of order k=1 or 2.             */
+  /* ******************************************************************** */
+
+  struct pyramidal_trans_: public fraction_geometric_trans  {
+    pyramidal_trans_(short_type k) {
+      cvr = pyramidal_element_of_reference(k);
+      size_type R = cvr->structure()->nb_points();
+      is_lin = false;
+      complexity_ = k;
+      trans.resize(R);
+
+      if (k == 1) {
+       base_rational_fraction Q(read_base_poly(3, "xy"),    // Q = xy/(1-z)
+                                read_base_poly(3, "1-z"));
+       trans[0] = (read_base_poly(3, "1-x-y-z") + Q)*0.25;
+       trans[1] = (read_base_poly(3, "1+x-y-z") - Q)*0.25;
+       trans[2] = (read_base_poly(3, "1+x+y-z") + Q)*0.25;
+       trans[3] = (read_base_poly(3, "1-x+y-z") - Q)*0.25;
+       trans[4] = read_base_poly(3, "z");
+      } else if (k == 2) {
+        // ... to be implemented
+       GMM_ASSERT1(false, "to be done");
+      }
+      fill_standard_vertices();
+    }
+  };
+  
+  static pgeometric_trans
+    pyramidal_gt(gt_param_list& params,
+                     std::vector<dal::pstatic_stored_object> &dependencies) {
+    GMM_ASSERT1(params.size() == 1, "Bad number of parameters : "
+               << params.size() << " should be 1.");
+    GMM_ASSERT1(params[0].type() == 0, "Bad type of parameters");
+    int k = int(::floor(params[0].num() + 0.01));
+    
+    dependencies.push_back(pyramidal_element_of_reference(dim_type(k)));
+    return std::make_shared<pyramidal_trans_>(dim_type(k));
+  }
+  
+  pgeometric_trans pyramidal_geotrans(short_type k) {
+    std::stringstream name;
+    name << "GT_PYRAMID(" << k << ")";
+    return geometric_trans_descriptor(name.str());
+  }
 
   /* ******************************************************************** */
   /*    Misc function.                                                    */
@@ -899,6 +946,7 @@ namespace bgeot {
       add_suffix("LINEAR_PRODUCT", linear_product_gt);
       add_suffix("LINEAR_QK", linear_qk);
       add_suffix("Q2_INCOMPLETE", Q2_incomplete_gt);
+      add_suffix("PYRAMID", pyramidal_gt);
     }
   };
 
diff --git a/src/getfem/bgeot_convex_ref.h b/src/getfem/bgeot_convex_ref.h
index b7dfd4a..8834afe 100644
--- a/src/getfem/bgeot_convex_ref.h
+++ b/src/getfem/bgeot_convex_ref.h
@@ -139,7 +139,7 @@ namespace bgeot {
   /** returns a simplex of reference of dimension nc and degree k */
   pconvex_ref simplex_of_reference(dim_type nc, short_type k = 1);
   /** parallelepiped of reference of dimension nc (and degree 1) */
-  pconvex_ref parallelepiped_of_reference(dim_type nc);
+  pconvex_ref parallelepiped_of_reference(dim_type nc, dim_type k = 1);
   /** prism of reference of dimension nc (and degree 1) */
   pconvex_ref prism_of_reference(dim_type nc);
   /** incomplete Q2 quadrilateral/hexahedral of reference of dimension
@@ -149,6 +149,8 @@ namespace bgeot {
   /** tensorial product of two convex ref.
       in order to ensure unicity, it is required the a->dim() >= b->dim()
   */
+  /** Pyramidal element of reference of degree k (k = 1 or 2 only) */
+  pconvex_ref pyramidal_element_of_reference(dim_type k);
   pconvex_ref convex_ref_product(pconvex_ref a, pconvex_ref b);
   /** equilateral simplex (degree 1). used only for mesh quality estimations
    */
diff --git a/src/getfem/bgeot_convex_structure.h 
b/src/getfem/bgeot_convex_structure.h
index b4f5c0a..0dcb509 100644
--- a/src/getfem/bgeot_convex_structure.h
+++ b/src/getfem/bgeot_convex_structure.h
@@ -174,7 +174,7 @@ namespace bgeot {
   /// Give a pointer on the structures of a simplex of dimension d.
   pconvex_structure simplex_structure(dim_type d);
   /// Give a pointer on the structures of a parallelepiped of dimension d.
-  pconvex_structure parallelepiped_structure(dim_type d);
+  pconvex_structure parallelepiped_structure(dim_type d, dim_type k = 1);
   /// Give a pointer on the structures of a polygon with n vertex.
   pconvex_structure polygon_structure(short_type);
   /** Give a pointer on the structures of a incomplete Q2
@@ -193,6 +193,9 @@ namespace bgeot {
     return convex_product_structure(simplex_structure(dim_type(nc-1)),
                                     simplex_structure(1));
   }
+  /// Give a pointer on the 3D pyramid structure for a degree k = 1 or 2.
+  pconvex_structure pyramidal_structure(short_type k);
+  
 
   /** Simplex structure with the Lagrange grid of degree k.
       @param n the simplex dimension.
diff --git a/src/getfem/bgeot_geometric_trans.h 
b/src/getfem/bgeot_geometric_trans.h
index 6f6988c..06ce13f 100644
--- a/src/getfem/bgeot_geometric_trans.h
+++ b/src/getfem/bgeot_geometric_trans.h
@@ -111,7 +111,7 @@ namespace bgeot {
     size_type complexity_; /* either the degree or the refinement of the
                             *  transformation */
 
-    void fill_standard_vertices(void);
+    void fill_standard_vertices();
   public :
 
     /// Dimension of the reference element.
@@ -221,6 +221,7 @@ namespace bgeot {
   pgeometric_trans APIDECL linear_product_geotrans(pgeometric_trans pg1,
                                            pgeometric_trans pg2);
   pgeometric_trans APIDECL Q2_incomplete_geotrans(dim_type nc);
+  pgeometric_trans APIDECL pyramidal_geotrans(short_type k);
 
   /**
      Get the geometric transformation from its string name.
diff --git a/src/getfem/bgeot_poly.h b/src/getfem/bgeot_poly.h
index f70bd4d..57da803 100644
--- a/src/getfem/bgeot_poly.h
+++ b/src/getfem/bgeot_poly.h
@@ -625,6 +625,127 @@ namespace bgeot
   /** read a base_poly on the string s. */
   base_poly read_base_poly(short_type n, const std::string &s);
 
+
+  /**********************************************************************/
+  /* A class for rational fractions                                     */
+  /**********************************************************************/
+
+  template<typename T> class rational_fraction : public std::vector<T> {
+  protected :
+    
+    polynomial<T> numerator_, denominator_;
+    
+  public :
+
+    const polynomial<T> &numerator() const { return numerator_; }
+    const polynomial<T> &denominator() const { return denominator_; }
+
+    short_type dim(void) const { return numerator_.dim(); }
+    
+    /// Add Q to P. P contains the result.
+    rational_fraction &operator +=(const rational_fraction &Q) {
+      numerator_ = numerator_*Q.denominator() + Q.numerator()*denominator_;
+      denominator_ *= Q.denominator();
+      return *this;
+    }
+    /// Subtract Q from P. P contains the result.
+    rational_fraction &operator -=(const rational_fraction &Q) {
+      numerator_ = numerator_*Q.denominator() - Q.numerator()*denominator_;
+      denominator_ *= Q.denominator();
+      return *this;
+    }
+    /// Add Q to P.
+    rational_fraction operator +(const rational_fraction &Q) const
+    { rational_fraction R = *this; R += Q; return R; }
+    /// Subtract Q from P.
+    rational_fraction operator -(const rational_fraction &Q) const
+    { rational_fraction R = *this; R -= Q; return R; }
+    /// Add Q to P.
+    rational_fraction operator +(const polynomial<T> &Q) const
+    { rational_fraction R(numerator_+Q*denominator_, denominator_); return R; }
+    /// Subtract Q from P.
+    rational_fraction operator -(const polynomial<T> &Q) const
+    { rational_fraction R(numerator_-Q*denominator_, denominator_); return R; }
+    rational_fraction operator -(void) const
+    { numerator_ = -numerator_; }
+    /// Multiply P with Q. P contains the result.
+    rational_fraction &operator *=(const rational_fraction &Q)
+    { numerator_*=Q.numerator(); denominator_*=Q.denominator(); return *this; }
+    /// Divide P by Q. P contains the result.
+    rational_fraction &operator /=(const rational_fraction &Q)
+    { numerator_*=Q.denominator(); denominator_*=Q.numerator(); return *this; }
+    /// Multiply P with Q. 
+    rational_fraction operator *(const rational_fraction &Q) const
+    { rational_fraction R = *this; R *= Q; return R; }
+    /// Divide P by Q. 
+    rational_fraction operator /(const rational_fraction &Q) const
+    { rational_fraction R = *this; R /= Q; return R; }
+    /// Multiply P with the scalar a. P contains the result.
+    rational_fraction &operator *=(const T &e)
+    { numerator_ *= e; return *this; }
+    /// Multiply P with the scalar a.
+    rational_fraction operator *(const T &e) const
+    { rational_fraction R = *this; R *= e; return R; }
+    /// Divide P with the scalar a. P contains the result.
+    rational_fraction &operator /=(const T &e)
+    { denominator_ *= e; return *this; }
+    /// Divide P with the scalar a.
+    rational_fraction operator /(const T &e) const
+    { rational_fraction res = *this; res /= e; return res; }   
+    /// operator ==.
+    bool operator ==(const rational_fraction &Q) const
+    { return  (numerator_==Q.numerator() && denominator_==Q.denominator()); }
+    /// operator !=.
+    bool operator !=(const rational_fraction  &Q) const
+    { return !(operator ==(*this,Q)); }   
+    /// Derivative of P with respect to the variable k. P contains the result.
+    void derivative(short_type k) {
+      polynomial<T> der_num = numerator_;   der_num.derivative(k);
+      polynomial<T> der_den = denominator_; der_den.derivative(k);
+      numerator_ = der_num * denominator_ - der_den * numerator_;
+      denominator_ =  denominator_ * denominator_;
+    }
+    /// Makes P = 1.
+    void one() { numerator_.one(); denominator_.one(); }
+    void clear() { numerator_.clear(); denominator_.one(); }
+    template <typename ITER> T eval(const ITER &it) const {
+      T a = numerator_.eval(it);
+      if (a != T(0)) a /= denominator_.eval(it);
+      return a;
+    }
+    /// Constructor.
+    rational_fraction()
+      : numerator_(1,0), denominator_(1,0) { clear(); }
+    /// Constructor.
+    rational_fraction(short_type dim_)
+      : numerator_(dim_,0), denominator_(dim_,0)  { clear(); }
+    /// Constructor
+    rational_fraction(const polynomial<T> &numer)
+      : numerator_(numer), denominator_(numer.dim(),0) { denominator_.one(); }
+    /// Constructor
+    rational_fraction(const polynomial<T> &numer, const polynomial<T> &denom)
+      : numerator_(numer), denominator_(denom)
+    { GMM_ASSERT1(numer.dim() == denom.dim(), "Dimensions mismatch"); }
+  };
+
+  /// Add Q to P.
+  template<typename T>
+  rational_fraction<T> operator +(const polynomial<T> &P,
+                                 const rational_fraction<T> &Q) {
+    rational_fraction<T> R(P*Q.denominator()+Q.numerator(), Q.denominator());
+    return R;
+  }
+  /// Subtract Q from P.
+  template<typename T>
+  rational_fraction<T> operator -(const polynomial<T> &P,
+                                 const rational_fraction<T> &Q) {
+    rational_fraction<T> R(P*Q.denominator()-Q.numerator(), Q.denominator());
+    return R;
+  }
+  
+
+  typedef rational_fraction<opt_long_scalar_type> base_rational_fraction;
+
 }  /* end of namespace bgeot.                                           */
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]