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: Tue, 27 Aug 2019 14:37:04 -0400 (EDT)

branch: master
commit d962432c90fefebff2e8f44bbd93a1943dcb864e
Author: Yves Renard <address@hidden>
Date:   Tue Aug 20 00:30:25 2019 +0200

    fix poly composite for mixed dimension sub elements
---
 interface/tests/python/demo_laplacian_HHO.py | 49 ++++++++------
 src/bgeot_poly_composite.cc                  | 99 +++++++++++++++++++++++++---
 src/getfem/bgeot_poly_composite.h            | 75 ++-------------------
 src/getfem_HHO.cc                            |  8 +--
 src/getfem_fem.cc                            |  3 +-
 src/getfem_fem_composite.cc                  |  2 -
 src/getfem_integration_composite.cc          |  4 +-
 7 files changed, 129 insertions(+), 111 deletions(-)

diff --git a/interface/tests/python/demo_laplacian_HHO.py 
b/interface/tests/python/demo_laplacian_HHO.py
index f091623..f21b609 100644
--- a/interface/tests/python/demo_laplacian_HHO.py
+++ b/interface/tests/python/demo_laplacian_HHO.py
@@ -31,7 +31,7 @@ import getfem as gf
 import numpy as np
 
 ## Parameters
-NX = 100                           # Mesh parameter.
+NX = 10                            # Mesh parameter.
 Dirichlet_with_multipliers = True  # Dirichlet condition with multipliers
                                    # or penalization
 dirichlet_coefficient = 1e10       # Penalization coefficient
@@ -49,15 +49,17 @@ mfur  = gf.MeshFem(m, 1)
 mfrhs = gf.MeshFem(m, 1)
 
 if (using_HHO):
-  mfu.set_fem(gf.Fem('FEM_HHO(FEM_PK(2,2),FEM_PK(1,2))'))
-  mfgu.set_fem(gf.Fem('FEM_HHO(FEM_PK(2,2),FEM_PK(1,2))'))
+  
mfu.set_fem(gf.Fem('FEM_HHO(FEM_PK_DISCONTINUOUS(2,2,0.1),FEM_PK_DISCONTINUOUS(1,2,0.1))'))
+  mfur.set_fem(gf.Fem('FEM_PK(2,3)'))
 else:
   mfu.set_fem(gf.Fem('FEM_PK(2,2)'))
-  mfgu.set_fem(gf.Fem('FEM_PK(2,2)'))
+  mfur.set_fem(gf.Fem('FEM_PK(2,2)'))
 
-mfur.set_fem(gf.Fem('FEM_PK(2,3)'))
+mfgu.set_fem(gf.Fem('FEM_PK(2,2)'))
 mfrhs.set_fem(gf.Fem('FEM_PK(2,2)'))
 
+print('nbdof : %d' % mfu.nbdof());
+
 #  Integration method used
 mim = gf.MeshIm(m, gf.Integ('IM_TRIANGLE(4)'))
 
@@ -84,7 +86,7 @@ ALL_FACES = 4
 m.set_region(ALL_FACES, all_faces)
 
 # Interpolate the exact solution (Assuming mfu is a Lagrange fem)
-Ue = mfu.eval('y*(y-1)*x*(x-1)+x*x*x*x*x')
+Ue = mfur.eval('y*(y-1)*x*(x-1)+x*x*x*x*x')
 
 # Interpolate the source term
 F1 = mfrhs.eval('-(2*(x*x+y*y)-2*x-2*y+20*x*x*x)')
@@ -105,13 +107,13 @@ if (using_HHO):
   md.add_HHO_reconstructed_gradient('HHO_Grad');
   md.add_HHO_reconstructed_value('HHO_Val');
   md.add_HHO_stabilization('HHO_Stab');
-  md.add_macro('HHO_Val_u', 'Elementary_transformation(u, HHO_Val)')
+  md.add_macro('HHO_Val_u', 'Elementary_transformation(u, HHO_Val, ur)')
   md.add_macro('HHO_Grad_u', 'Elementary_transformation(u, HHO_Grad, Gu)')
   md.add_macro('HHO_Grad_Test_u',
                'Elementary_transformation(Test_u, HHO_Grad, Gu)')
   md.add_macro('HHO_Stab_u', 'Elementary_transformation(u, HHO_Stab)')
   md.add_macro('HHO_Stab_Test_u',
-               'Elementary_transformation(Test_u, HHO_Stab, ur)')
+               'Elementary_transformation(Test_u, HHO_Stab)')
 
 
 # Laplacian term on u
@@ -133,7 +135,7 @@ md.add_normal_source_term_brick(mim, 'u', 'NeumannData',
                                 NEUMANN_BOUNDARY_NUM)
 
 # Dirichlet condition on the left.
-md.add_initialized_fem_data("DirichletData", mfu, Ue)
+md.add_initialized_fem_data("DirichletData", mfur, Ue)
 
 if (Dirichlet_with_multipliers):
   md.add_Dirichlet_condition_with_multipliers(mim, 'u', mfu,
@@ -155,7 +157,7 @@ else:
   md.add_Dirichlet_condition_with_penalization(mim, 'u', dirichlet_coefficient,
                                                DIRICHLET_BOUNDARY_NUM2,
                                                'DirichletData')
-gf.memstats()
+# gf.memstats()
 # md.listvar()
 # md.listbricks()
 
@@ -165,25 +167,32 @@ md.solve()
 # Main unknown
 U = md.variable('u')
 if (using_HHO):
-  L2error = gf.asm('generic', mim, 0, 'sqr(HHO_Val_u-Ue)',
-                   -1, md, 'Ue', 0, mfu, Ue)
+  L2error = gf.asm('generic', mim, 0, 'sqr(u-Ue)',
+                   -1, md, 'Ue', 0, mfur, Ue)
   H1error = gf.asm('generic', mim, 0, 'Norm_sqr(Grad_u-Grad_Ue)',
-                   -1, md, 'Ue', 0, mfu, Ue)
+                   -1, md, 'Ue', 0, mfur, Ue)
   H1error = np.sqrt(L2error + H1error)
   L2error = np.sqrt(L2error)
+  print('Error in L2 norm (without reconstruction): %g' % L2error)
+  print('Error in H1 norm (without reconstruction): %g' % H1error)
+  L2error = gf.asm('generic', mim, 0, 'sqr(HHO_Val_u-Ue)',
+                   -1, md, 'Ue', 0, mfur, Ue)
+  H1error = gf.asm('generic', mim, 0, 'Norm_sqr(HHO_Grad_u-Grad_Ue)',
+                   -1, md, 'Ue', 0, mfur, Ue)
+  H1error = np.sqrt(L2error + H1error)
+  L2error = np.sqrt(L2error)
+  print('Error in L2 norm (with reconstruction): %g' % L2error)
+  print('Error in H1 norm (with reconstruction): %g' % H1error)
 else :
   L2error = gf.compute(mfu, U-Ue, 'L2 norm', mim)
   H1error = gf.compute(mfu, U-Ue, 'H1 norm', mim)
-print('Error in L2 norm : ', L2error)
-print('Error in H1 norm : ', H1error)
-
-
+  print('Error in L2 norm : %g' % L2error)
+  print('Error in H1 norm : %g' % H1error)
 
-# Calculer l'erreur sur la reconstruction, aussi.
 
 # Export data
-mfu.export_to_pos('laplacian.pos', Ue,'Exact solution',
-                                    U,'Computed solution')
+# mfur.export_to_pos('laplacian_e.pos', Ue, 'Exact solution')
+mfu.export_to_pos('laplacian.pos', U, 'Computed solution')
 print('You can view the solution with (for example):')
 print('gmsh laplacian.pos')
 
diff --git a/src/bgeot_poly_composite.cc b/src/bgeot_poly_composite.cc
index 716d71f..5c02fad 100644
--- a/src/bgeot_poly_composite.cc
+++ b/src/bgeot_poly_composite.cc
@@ -68,12 +68,10 @@ namespace bgeot {
 
   void mesh_precomposite::initialise(const basic_mesh &m) {
     msh = &m;
-    det.resize(m.nb_convex());
-    orgs.resize(m.nb_convex());
-    gtrans.resize(m.nb_convex());
-    for (size_type i = 0; i <= m.points().index().last_true(); ++i) {
+    det.resize(m.nb_convex()); orgs.resize(m.nb_convex());
+    gtrans.resize(m.nb_convex()); gtransinv.resize(m.nb_convex());
+    for (size_type i = 0; i <= m.points().index().last_true(); ++i)
       vertices.add(m.points()[i]);
-    }
 
     base_node min, max;
     for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv) {
@@ -88,11 +86,12 @@ namespace bgeot {
       
       m.points_of_convex(cv, G);
       bgeot::geotrans_interpolation_context ctx(pgt, X, G);
-      gtrans[cv] = ctx.B();
+      gtrans[cv] = ctx.K();
+      gtransinv[cv] = ctx.B();
       det[cv] = ctx.J();
       
       auto points_of_convex = m.points_of_convex(cv);
-      orgs[cv] = points_of_convex[0];
+      orgs[cv] = pgt->transform(X, G);
       bounding_box(min, max, points_of_convex);
       box_to_convexes_map[box_tree.add_box(min, max)].push_back(cv);
     }
@@ -111,14 +110,94 @@ namespace bgeot {
       default_polys[i] = base_poly(i, 0.);
   }
 
+  static void mult_diff_transposed(const base_matrix &M, const base_node &p,
+                                   const base_node &p1, base_node &p2) {
+    for (dim_type d = 0; d < p2.size(); ++d) {
+      p2[d] = 0;
+      auto col = mat_col(M, d);
+      for (dim_type i = 0; i < p1.size(); ++i)
+        p2[d] += col[i] * (p[i] - p1[i]);
+    }
+  }
+
+  scalar_type polynomial_composite::eval(const base_node &p,
+                                         size_type l) const {
+    if (l != size_type(-1)) {
+      if (!local_coordinate) return poly_of_subelt(l).eval(p.begin());
+      base_node p1(gmm::mat_ncols(mp->gtransinv[l]));
+      mult_diff_transposed(mp->gtransinv[l], p, mp->orgs[l], p1);
+      return poly_of_subelt(l).eval(p1.begin());
+    }
+
+    auto dim = mp->dim();
+    base_node p1_stored, p1, p2(dim);
+    size_type cv_stored(-1);
+
+    auto &box_tree = mp->box_tree;
+    rtree::pbox_set box_list;
+    box_tree.find_boxes_at_point(p, box_list);
+    
+    while (box_list.size()) {
+      auto pmax_box = *box_list.begin();
+      
+      if (box_list.size() > 1) {
+        auto max_rate = -1.0;
+        for (auto &&pbox : box_list) {
+          auto box_rate = 1.0;
+          for (size_type i = 0; i < dim; ++i) {
+            auto h = pbox->max->at(i) - pbox->min->at(i);
+            if (h > 0) {
+              auto rate = std::min(pbox->max->at(i) - p[i],
+                                   p[i] - pbox->min->at(i)) / h;
+              box_rate = std::min(rate, box_rate);
+            }
+          }
+          if (box_rate > max_rate) { pmax_box = pbox; max_rate = box_rate; }
+        }
+      }
+      
+      for (auto cv : mp->box_to_convexes_map.at(pmax_box->id)) {
+        dim_type elt_dim = dim_type(gmm::mat_ncols(mp->gtransinv[cv]));
+        p1.resize(elt_dim);
+        mult_diff_transposed(mp->gtransinv[cv], p, mp->orgs[cv], p1);
+        scalar_type ddist(0);
+
+        if (elt_dim < dim) {
+          p2 = mp->orgs[cv]; gmm::mult_add(mp->gtrans[cv], p1, p2);
+          ddist = gmm::vect_dist2(p2, p);
+        }
+        if (mp->trans_of_convex(cv)->convex_ref()->is_in(p1) < 1E-9
+            && ddist < 1E-9) {
+          if (!faces_first || elt_dim < dim) {
+            scalar_type res = 
to_scalar(poly_of_subelt(cv).eval(local_coordinate
+                                                     ? p1.begin() : 
p.begin()));
+            return res;
+          }
+          p1_stored = p1; cv_stored = cv;
+        }
+      }
+        
+      if (box_list.size() == 1) break;
+      box_list.erase(pmax_box);
+    }
+    if (cv_stored != size_type(-1)) {
+      scalar_type res =
+        to_scalar(poly_of_subelt(cv_stored).eval(local_coordinate
+                                              ? p1_stored.begin(): p.begin()));
+      return res;
+    }
+    GMM_ASSERT1(false, "Element not found in composite polynomial: " << p);
+  }
+  
+
   void polynomial_composite::derivative(short_type k) {
     if (local_coordinate) {
       dim_type P = mp->dim();
       base_vector e(P), f(P); e[k] = 1.0;
       for (size_type ic = 0; ic < mp->nb_convex(); ++ic) {
-        dim_type N = dim_type(gmm::mat_ncols(mp->gtrans[ic]));
+        dim_type N = dim_type(gmm::mat_ncols(mp->gtransinv[ic]));
         f.resize(N);
-        gmm::mult(gmm::transposed(mp->gtrans[ic]), e, f);
+        gmm::mult(gmm::transposed(mp->gtransinv[ic]), e, f);
         base_poly Der(N, 0), Q;
         if (polytab.find(ic) != polytab.end()) {
           auto &poly = poly_of_subelt(ic);
@@ -156,7 +235,7 @@ namespace bgeot {
     auto it = polytab.find(l);
     if (it == polytab.end()) {
       if (local_coordinate)
-        return default_polys[gmm::mat_ncols(mp->gtrans[l])];
+        return default_polys[gmm::mat_ncols(mp->gtransinv[l])];
       else
         return default_polys[mp->dim()];
     }
diff --git a/src/getfem/bgeot_poly_composite.h 
b/src/getfem/bgeot_poly_composite.h
index 744a8c7..92f2d7a 100644
--- a/src/getfem/bgeot_poly_composite.h
+++ b/src/getfem/bgeot_poly_composite.h
@@ -77,7 +77,7 @@ namespace bgeot {
     PTAB vertices;
     rtree box_tree;
     std::map<size_type, std::vector<size_type>> box_to_convexes_map;
-    std::vector<base_matrix> gtrans;
+    std::vector<base_matrix> gtrans, gtransinv;
     std::vector<scalar_type> det;
     std::vector<base_node> orgs;
     
@@ -112,6 +112,7 @@ namespace bgeot {
     std::vector<base_poly> default_polys;
 
   public :
+    scalar_type eval(const base_node &p, size_type l) const;
 
     template <class ITER> scalar_type eval(const ITER &it,
                                            size_type l = -1) const;
@@ -138,76 +139,10 @@ namespace bgeot {
   }
 
   template <class ITER>
-  void mult_diff_transposed(
-    const base_matrix &M, const ITER &it, const base_node &p1, base_node &p2) {
-    for (dim_type d = 0; d < p2.size(); ++d) {
-      p2[d] = 0;
-      auto col = mat_col(M, d);
-      for (dim_type i = 0; i < p1.size(); ++i)
-        p2[d] += col[i] * (*(it + i) - p1[i]);
-    }
-  }
-
-  template <class ITER>
   scalar_type polynomial_composite::eval(const ITER &it, size_type l) const {
-
-    if (l != size_type(-1)) {
-      if (!local_coordinate) return poly_of_subelt(l).eval(it);
-      base_node p(gmm::mat_ncols(mp->gtrans[l]));
-      // std::copy(it, it + mp->dim(), p.begin());
-      mult_diff_transposed(mp->gtrans[l], it, mp->orgs[l], p);
-      return poly_of_subelt(l).eval(p.begin());
-    }
-
-    auto dim = mp->dim();
-    base_node p0(dim), p1_stored, p1;
-    size_type cv_stored(-1);
-    std::copy(it, it + mp->dim(), p0.begin());
-
-    auto &box_tree = mp->box_tree;
-    rtree::pbox_set box_list;
-    box_tree.find_boxes_at_point(p0, box_list);
-    
-    while (box_list.size()) {
-      auto pmax_box = *box_list.begin();
-      
-      if (box_list.size() > 1) {
-        auto max_rate = -1.0;
-        for (auto &&pbox : box_list) {
-          auto box_rate = 1.0;
-          for (size_type i = 0; i < dim; ++i) {
-            auto h = pbox->max->at(i) - pbox->min->at(i);
-            if (h > 0) {
-              auto rate = std::min(pbox->max->at(i) - p0[i],
-                                   p0[i] - pbox->min->at(i)) / h;
-              box_rate = std::min(rate, box_rate);
-            }
-          }
-          if (box_rate > max_rate) { pmax_box = pbox; max_rate = box_rate; }
-        }
-      }
-      
-      for (auto cv : mp->box_to_convexes_map.at(pmax_box->id)) {
-        cout << "cv = " << cv << endl;
-        p1.resize(gmm::mat_ncols(mp->gtrans[cv]));
-        mult_diff_transposed(mp->gtrans[cv], it, mp->orgs[cv], p1);
-        cout << "p1 = " << p1 << endl;
-        if (mp->trans_of_convex(cv)->convex_ref()->is_in(p1) < 1E-10) {
-          if (!faces_first || mp->trans_of_convex(cv)->structure()->dim() < 
dim)
-            return to_scalar(poly_of_subelt(cv).eval(local_coordinate
-                                                     ? p1.begin() : it));
-          p1_stored = p1; cv_stored = cv;
-        }
-      }
-        
-      if (box_list.size() == 1) break;
-      box_list.erase(pmax_box);
-    }
-    if (cv_stored != size_type(-1))
-      return to_scalar(poly_of_subelt(cv_stored).eval(local_coordinate
-                                                      ? p1_stored.begin(): 
it));
-    GMM_ASSERT1(false, "Element not found in composite polynomial: "
-                << base_node(*it, *it + mp->dim()));
+    base_node p(mp->dim());
+    std::copy(it, it+mp->dim(), p.begin());
+    return eval(p,l);
   }
 
   void structured_mesh_for_convex(pconvex_ref cvr, short_type k,
diff --git a/src/getfem_HHO.cc b/src/getfem_HHO.cc
index 2274741..c9d26a8 100644
--- a/src/getfem_HHO.cc
+++ b/src/getfem_HHO.cc
@@ -50,7 +50,7 @@ namespace getfem {
       // inside the element whose gradient is to be reconstructed,
       // "v_{dT}" is the field on the boundary of T and "n" is the outward
       // unit normal.
-      
+
       // Obtaining the fem descriptors
       pfem pf1 = mf1.fem_of_element(cv);
       pfem pf2 = mf2.fem_of_element(cv);
@@ -142,7 +142,7 @@ namespace getfem {
               }
         }
       }
-      
+
       if (pf2->target_dim() == 1) {
         gmm::sub_slice I(0, ndof2/(N*Q), N*Q);
         gmm::lu_inverse(gmm::sub_matrix(M2, I, I));
@@ -152,10 +152,8 @@ namespace getfem {
         }
       } else { gmm::copy(M2, M2inv); gmm::lu_inverse(M2inv); }
       
-      
       gmm::mult(M2inv, M1, M);
       gmm::clean(M, gmm::vect_norminf(M.as_vector()) * 1E-13);
-      // cout << "M = " << M << endl;
     }
   };
 
@@ -321,7 +319,7 @@ namespace getfem {
       // inside the element whose gradient is to be reconstructed,
       // "v_{dT}" is the field on the boundary of T and "n" is the outward
       // unit normal.
-      
+
       // Obtaining the fem descriptors
       pfem pf1 = mf1.fem_of_element(cv);
       pfem pf2 = mf2.fem_of_element(cv);
diff --git a/src/getfem_fem.cc b/src/getfem_fem.cc
index 38e1e04..fc05256 100644
--- a/src/getfem_fem.cc
+++ b/src/getfem_fem.cc
@@ -3836,9 +3836,8 @@ namespace getfem {
           base_poly S(1,2);
           S[0] = -alpha * G[d] / (1-alpha);
           S[1] = 1. / (1-alpha);
-          for (size_type j=0; j < nb_base(0); ++j) {
+          for (size_type j=0; j < nb_base(0); ++j)
             base_[j] = bgeot::poly_substitute_var(base_[j],S,d);
-          }
         }
       }
     }
diff --git a/src/getfem_fem_composite.cc b/src/getfem_fem_composite.cc
index 74022f6..ccc75c2 100644
--- a/src/getfem_fem_composite.cc
+++ b/src/getfem_fem_composite.cc
@@ -122,7 +122,6 @@ namespace getfem {
     std::vector<pdof_description> dofd(mf.nb_basic_dof());
     
     for (dal::bv_visitor cv(mf.convex_index()); !cv.finished(); ++cv) {
-      cout << "set poly of cv " << cv << endl;
       pfem pf1 = mf.fem_of_element(cv);
       if (!pf1->is_lagrange()) p->is_lagrange() = false;
       if (!(pf1->is_equivalent())) p->is_equivalent() = false;
@@ -134,7 +133,6 @@ namespace getfem {
       for (size_type k = 0; k < pf->nb_dof(cv); ++k) {
        size_type igl = mf.ind_basic_dof_of_element(cv)[k];
        base_poly fu = pf->base()[k];
-        cout << "adding " << fu << " : " << fu.dim() << endl;
        base[igl].set_poly_of_subelt(cv, fu);
        dofd[igl] = pf->dof_types()[k];
       }
diff --git a/src/getfem_integration_composite.cc 
b/src/getfem_integration_composite.cc
index 3da1f7b..b02042a 100644
--- a/src/getfem_integration_composite.cc
+++ b/src/getfem_integration_composite.cc
@@ -57,8 +57,8 @@ namespace getfem {
            { f2 = f3; break;}
        }
        if (f2 != short_type(-1)) {
-         w.resize(gmm::mat_nrows(mp.gtrans[cv]));
-         gmm::mult(mp.gtrans[cv], pgt->normals()[f], w);
+         w.resize(gmm::mat_nrows(mp.gtransinv[cv]));
+         gmm::mult(mp.gtransinv[cv], pgt->normals()[f], w);
          scalar_type coeff_mul = gmm::abs(gmm::vect_norm2(w) * mp.det[cv]);
          for (size_type j = 0; j < pai->nb_points_on_face(f); ++j) {
            base_node pt = pgt->transform



reply via email to

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