getfem-commits
[Top][All Lists]
Advanced

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

[Getfem-commits] (no subject)


From: Konstantinos Poulios
Subject: [Getfem-commits] (no subject)
Date: Sun, 11 Nov 2018 07:38:22 -0500 (EST)

branch: fix-project-into-element
commit 5e91d088ce074a4af5d15172b2737b7bbc9e6c49
Author: Konstantinos Poulios <address@hidden>
Date:   Sat Sep 8 22:29:18 2018 +0200

    Fix projected_fem
---
 src/getfem_projected_fem.cc | 86 +++++++++++++++++++++++++++++----------------
 1 file changed, 55 insertions(+), 31 deletions(-)

diff --git a/src/getfem_projected_fem.cc b/src/getfem_projected_fem.cc
index 0050b0b..20266b9 100644
--- a/src/getfem_projected_fem.cc
+++ b/src/getfem_projected_fem.cc
@@ -34,11 +34,12 @@ namespace getfem {
    *   pt  : the point to be projected
    * Output:
    *   proj_ref: the projected point in the reference element
+   *   proj    : the projected point in the real element
   */
   void projection_on_convex_face
     (const bgeot::pgeometric_trans pgt, const base_matrix &G_cv,
      const short_type fc, const base_node &pt,
-     base_node &proj_ref) {
+     base_node &proj_ref, base_node &proj) {
 
     size_type N = gmm::mat_nrows(G_cv); // dimension of the target space
     size_type P = pgt->dim();           // dimension of the reference element 
space
@@ -65,8 +66,8 @@ namespace getfem {
     }
 
     proj_ref.resize(P);
+    proj.resize(N);
 
-    base_node proj(N); // the projected point in the real element
     base_node vres(P); // residual vector
     scalar_type res= 1.;
 
@@ -105,6 +106,9 @@ namespace getfem {
     }
     GMM_ASSERT1( res <= EPS,
                 "Iterative pojection on convex face did not converge");
+    pgt->project_into_reference_convex(proj_ref);
+    pgt->poly_vector_val(proj_ref, ind_pts_fc, val);
+    gmm::mult(G_fc, val, proj);
   }
 
 
@@ -260,8 +264,8 @@ namespace getfem {
 
     size_type cv_sel = size_type(-1);
     short_type fc_sel = short_type(-1);
-    scalar_type is_in_sel(1e10);
-    base_node proj_ref, proj_ref_sel;
+    scalar_type dist_sel(1e10);
+    base_node proj_ref, proj_ref_sel, proj, proj_sel;
     const getfem::mesh::ind_cv_ct cvs = mf_source.convex_to_basic_dof(ipt.i);
     for (size_type i=0; i < cvs.size(); ++i) {
       size_type cv = cvs[i];
@@ -271,9 +275,11 @@ namespace getfem {
         gic = bgeot::geotrans_inv_convex(mf_source.linked_mesh().convex(cv), 
pgt);
         gic.invert(pt, proj_ref, gt_invertible);
         if (gt_invertible) {
-          scalar_type is_in = pgt->convex_ref()->is_in(proj_ref);
-          if (is_in < is_in_sel) {
-            is_in_sel = is_in;
+          pgt->project_into_reference_convex(proj_ref);
+          proj = pgt->transform(proj_ref, 
mf_source.linked_mesh().points_of_convex(cv));
+          scalar_type dist = gmm::vect_dist2(pt, proj);
+          if (dist < dist_sel) {
+            dist_sel = dist;
             cv_sel = cv;
             fc_sel = short_type(-1);
             proj_ref_sel = proj_ref;
@@ -287,24 +293,28 @@ namespace getfem {
           short_type nbf = mf_source.linked_mesh().nb_faces_of_convex(cv);
           for (short_type f = 0; f < nbf; ++f) {
             if (faces.test(f)) {
-              projection_on_convex_face(pgt, G, f, pt, proj_ref);
-              scalar_type is_in = pgt->convex_ref()->is_in(proj_ref);
-              if (is_in < is_in_sel) {
-                is_in_sel = is_in;
+              projection_on_convex_face(pgt, G, f, pt, proj_ref, proj);
+              scalar_type dist = gmm::vect_dist2(pt, proj);
+              if (dist < dist_sel) {
+                dist_sel = dist;
                 cv_sel = cv;
                 fc_sel = f;
                 proj_ref_sel = proj_ref;
+                proj_sel = proj;
               }
             }
           }
         }
       }
     }
-    if (cv_sel != size_type(-1) && is_in_sel < 0.05) {  //FIXME
-        cv_proj = cv_sel;
-        fc_proj = fc_sel;
-        ptr_proj = proj_ref_sel;
-        return true;
+    if (cv_sel != size_type(-1)) {
+      scalar_type elm_size = 
mf_source.linked_mesh().convex_radius_estimate(cv_sel);
+      if (dist_sel < 0.05*elm_size) {  //FIXME
+          cv_proj = cv_sel;
+          fc_proj = fc_sel;
+          ptr_proj = proj_ref_sel;
+          return true;
+      }
     }
     return false;
   }
@@ -321,6 +331,7 @@ namespace getfem {
 
     elements.clear();
     ind_dof.resize(mf_source.nb_basic_dof());
+    std::fill(ind_dof.begin(), ind_dof.end(), size_type(-1));
     size_type max_dof = 0;
     if (rg_target.id() != mesh_region::all_convexes().id() &&
         rg_target.is_empty()) {
@@ -351,13 +362,13 @@ namespace getfem {
       bgeot::pgeometric_trans pgt = 
mim_target.linked_mesh().trans_of_convex(cv);
       bgeot::pgeotrans_precomp pgp =
         bgeot::geotrans_precomp(pgt, pai->pintegration_points(), 0);
-      dal::bit_vector dofs;
       size_type last_cv = size_type(-1); // refers to the source mesh
       short_type last_f = short_type(-1); // refers to the source mesh
       size_type nb_pts = i.is_face() ? pai->nb_points_on_face(f) : 
pai->nb_points();
       size_type start_pt = i.is_face() ? pai->ind_first_point_on_face(f) : 0;
       elt_projection_data &e = elements[cv];
       base_node gpt(N);
+      dal::bit_vector new_dofs;
       for (size_type k = 0; k < nb_pts; ++k) {
         pgp->transform(mim_target.linked_mesh().points_of_convex(cv),
                        start_pt + k, gpt);
@@ -382,7 +393,7 @@ namespace getfem {
             for (size_type loc_dof = 0; loc_dof < nbdof; ++loc_dof) {
               size_type dof = 
mf_source.ind_basic_dof_of_element(gppd.cv)[loc_dof];
               if (!(blocked_dofs[dof]))
-                dofs.add(dof);
+                new_dofs.add(dof);
             }
           }
           else { // convex face
@@ -390,20 +401,29 @@ namespace getfem {
             for (size_type loc_dof = 0; loc_dof < nbdof; ++loc_dof) {
               size_type dof = 
mf_source.ind_basic_dof_of_face_of_element(gppd.cv, gppd.f)[loc_dof];
               if (!(blocked_dofs[dof]))
-                dofs.add(dof);
+                new_dofs.add(dof);
             }
           }
           last_cv = gppd.cv;
           last_f = gppd.f;
         }
       }
-      e.nb_dof = dofs.card();
+
+      size_type cnt(0);
+      dal::bit_vector old_dofs;
+      for (const size_type dof : e.inddof) {
+        old_dofs.add(dof);
+        ind_dof[dof] = cnt++;
+      }
+      for (dal::bv_visitor dof(new_dofs); !dof.finished(); ++dof)
+        if (!(old_dofs[dof])) {
+          ind_dof[dof] = cnt++;
+          e.inddof.push_back(dof);
+        }
+
       e.pim = pim;
-      e.inddof.resize(dofs.card());
-      max_dof = std::max(max_dof, dofs.card());
-      size_type cnt = 0;
-      for (dal::bv_visitor dof(dofs); !dof.finished(); ++dof)
-        { e.inddof[cnt] = dof; ind_dof[dof] = cnt++; }
+      e.nb_dof = e.inddof.size();
+      max_dof = std::max(max_dof, e.nb_dof);
       for (size_type k = 0; k < nb_pts; ++k) {
         gausspt_projection_data &gppd = e.gausspt[start_pt + k];
         if (gppd.iflags) {
@@ -411,8 +431,8 @@ namespace getfem {
             size_type nbdof = mf_source.nb_basic_dof_of_element(gppd.cv);
             for (size_type loc_dof = 0; loc_dof < nbdof; ++loc_dof) {
               size_type dof = 
mf_source.ind_basic_dof_of_element(gppd.cv)[loc_dof];
-              gppd.local_dof[loc_dof] = dofs.is_in(dof) ? ind_dof[dof]
-                                                        : size_type(-1);
+              gppd.local_dof[loc_dof] = new_dofs.is_in(dof) ? ind_dof[dof]
+                                                            : size_type(-1);
             }
           }
           else { // convex face
@@ -424,8 +444,8 @@ namespace getfem {
               for (size_type loc_dof = 0; loc_dof < nbdof; ++loc_dof) { // 
local dof with respect to the source convex face
                 size_type dof = 
mf_source.ind_basic_dof_of_face_of_element(gppd.cv, gppd.f)[loc_dof];
                 size_type loc_dof2 = ind_pts_fc[loc_dof]; // local dof with 
respect to the source convex
-                gppd.local_dof[loc_dof2] = dofs.is_in(dof) ? ind_dof[dof]
-                                                           : size_type(-1);
+                gppd.local_dof[loc_dof2] = new_dofs.is_in(dof) ? ind_dof[dof]
+                                                               : size_type(-1);
               }
             else
               for (size_type ii = 0; ii < nbdof/rdim; ++ii)
@@ -433,12 +453,16 @@ namespace getfem {
                   size_type loc_dof = ii*rdim + jj; // local dof with respect 
to the source convex face
                   size_type dof = 
mf_source.ind_basic_dof_of_face_of_element(gppd.cv, gppd.f)[loc_dof];
                   size_type loc_dof2 = ind_pts_fc[ii]*rdim + jj; // local dof 
with respect to the source convex
-                  gppd.local_dof[loc_dof2] = dofs.is_in(dof) ? ind_dof[dof]
-                                                             : size_type(-1);
+                  gppd.local_dof[loc_dof2] = new_dofs.is_in(dof) ? ind_dof[dof]
+                                                                 : 
size_type(-1);
                 }
           }
         }
       }
+
+      for (const size_type dof : e.inddof)
+        ind_dof[dof] = size_type(-1);
+
     }
     /** setup global dofs, with dummy coordinates */
     base_node P(dim()); gmm::fill(P,1./20);



reply via email to

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