Dear All,

Continuing my previous post:
> I see two other approaches :
>   a)  summing the rows to the assembled global matrix.
In the attachment you have the second version of the
assembly routine  asm_lumped_mass_matrix_v1() where
the lumping is done after assembly.
The only thing I wonder is, if it makes sense to check for
non-zero entries of the matrix and how to set sensibly the
threshold (which here is set arbitrarily to 1e-10).

Regards,

Roman
namespace getfem {
  /** 
      generic lumped mass matrix assembly (on the whole mesh or on the specified
      convex set or boundary) 
      The lumped mass matix is produced by row summation approach.
      @ingroup asm
  */
  template<typename MAT>
  void asm_lumped_mass_matrix(const MAT &M, const mesh_im &mim,
		       const mesh_fem &mf_u1,
		       const mesh_region &rg = mesh_region::all_convexes()) {
    generic_assembly assem;
    int N = mf_u1.nb_dof();
    std::stringstream oss;
    oss << "h=data$1(" << N << "," << N << "," << N << "," << N << ");";
    if (mf_u1.get_qdim() == 1) {
      oss << "Mc=sym(comp(Base(#1).Base(#1)));"
          <<  "M(#1,#1)+=(Mc(i,j).h(:,:,i,j));";
    } else {
      oss << "Mc=sym(comp(vBase(#1).vBase(#1))(:,i,:,i));"
             "M(#1,#1)+=(Mc(i,j).h(:,:,i,j));";
    }
    assem.set(oss.str());
    assem.push_mi(mim);
    assem.push_mf(mf_u1);
    /* vector v stores 4-th order tensor H which action on consistent
     * mass matrix is to produce lumped mass matrix
     */
    gmm::rsvector<double> v(N*N*N*N);
    size_type N2 = N*N;
    size_type N3 = N*N*N;
    for (int i=0; i<N; i++) {
      size_type is = i + N*i + N2*i;
      for (int j=0; j<N; j++) {
         v[is + j*N3] = 1.0;
      }
    }
    assem.push_data(v);
    assem.push_mat(const_cast<MAT &>(M));
    assem.assembly(rg);
  }

  template<typename MAT>
  void asm_lumped_mass_matrix_v1(MAT &M, const mesh_im &mim,
		       const mesh_fem &mf_u1,
		       const mesh_region &rg = mesh_region::all_convexes()) {
    generic_assembly assem;
    if (mf_u1.get_qdim() == 1) {
      assem.set("M+=sym(comp(Base(#1).Base(#1)));");
    } else {
      assem.set("M(#1,#1) +=sym(comp(vBase(#1).vBase(#1))(:,i,:,i));");
    }
    assem.push_mi(mim);
    assem.push_mf(mf_u1);
    assem.push_mat(M);
    assem.assembly(rg);
    for (int i=0; i<gmm::mat_nrows(M); i++) {
      typename MAT::value_type s = typename MAT::value_type(0);
      for (int j=0; j<gmm::mat_nrows(M); j++) {
         if (fabs(M(i,j)) >= 1e-10) {
           s = s+M(i,j);
           M(i,j) = 0.0;
         }
      }
      M(i,i) = s;
    } 
  }

} /* namespace getfem */
_______________________________________________
Getfem-users mailing list
[email protected]
https://mail.gna.org/listinfo/getfem-users

Reply via email to