GetFEM  5.5
getfem_partial_mesh_fem.cc
1 /*===========================================================================
2 
3  Copyright (C) 2006-2026 Yves Renard
4 
5  This file is a part of GetFEM
6 
7  GetFEM is free software; you can redistribute it and/or modify it
8  under the terms of the GNU Lesser General Public License as published
9  by the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version along with the GCC Runtime Library
11  Exception either version 3.1 or (at your option) any later version.
12  This program is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15  License and GCC Runtime Library Exception for more details.
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program. If not, see https://www.gnu.org/licenses/.
18 
19 ===========================================================================*/
20 
22 
23 namespace getfem {
24 
25 
26  void partial_mesh_fem::clear(void)
27  { mesh_fem::clear(); is_adapted = false; }
28 
29  partial_mesh_fem::partial_mesh_fem(const mesh_fem &mef)
30  : mesh_fem(mef.linked_mesh()), mf(mef)
31  { is_adapted = false; }
32 
33  static getfem::mesh void_mesh__;
34 
35  partial_mesh_fem::partial_mesh_fem(const mesh_fem *mef)
36  : mesh_fem(*(mef ? &(mef->linked_mesh()) : &(void_mesh__))), mf(*mef)
37  { is_adapted = false; }
38 
39  DAL_SIMPLE_KEY(special_partialmf_key, pfem);
40  void partial_mesh_fem::adapt(const dal::bit_vector &kept_dofs,
41  const dal::bit_vector &rejected_elt) {
42  mf.context_check();
43 
44  if (!(mi.is_equal(mf.get_qdims()))) {
45  mi = mf.get_qdims();
46  Qdim = mf.get_qdim();
47  dof_enumeration_made = false; touch(); v_num = act_counter();
48  }
49 
50  fe_convex = mf.convex_index();
51  fe_convex.setminus(rejected_elt);
52 
53  gmm::row_matrix<gmm::rsvector<scalar_type> >
54  RR(kept_dofs.card(), mf.nb_dof());
55  size_type j = 0;
56  for (dal::bv_visitor i(kept_dofs); !i.finished(); ++i, ++j)
57  RR(j, i) = scalar_type(1);
58 
59  R_ = REDUCTION_MATRIX(kept_dofs.card(), mf.nb_basic_dof());
60  E_ = EXTENSION_MATRIX(mf.nb_basic_dof(), kept_dofs.card());
61 
62  if (mf.is_reduced()) {
63  gmm::row_matrix<gmm::rsvector<scalar_type> >
64  A(kept_dofs.card(), mf.nb_basic_dof());
65  gmm::mult(RR, mf.reduction_matrix(), A);
66  gmm::copy(A, R_);
67  gmm::row_matrix<gmm::rsvector<scalar_type> >
68  B(mf.nb_basic_dof(), kept_dofs.card());
69  gmm::mult(mf.extension_matrix(), gmm::transposed(RR), B);
70  gmm::copy(B, E_);
71  }
72  else {
73  gmm::copy(RR, R_); gmm::copy(gmm::transposed(RR), E_);
74  }
75  use_reduction = true;
76 
77  is_adapted = true; touch(); v_num = act_counter();
78  }
79 
80  // invalid function for a mesh change.
81  // dal::bit_vector partial_mesh_fem::retrieve_kept_dofs() const
82  // {
83  // base_vector full(nb_basic_dof());
84  // for (size_type i = 0; i < full.size(); ++i) full[i] = i;
85  // base_vector reduced(nb_dof());
86  //
87  // if (R_.ncols() > 0) gmm::mult(R_, full, reduced);
88  // else reduced = full;
89  //
90  // dal::bit_vector kept_dofs;
91  // for (size_type i=0; i < reduced.size(); ++i) kept_dofs.add(reduced[i]);
92  //
93  // return kept_dofs;
94  // }
95 
96  void partial_mesh_fem::write_to_file(std::ostream &ost) const
97  { context_check(); mf.context_check();
98  gmm::stream_standard_locale sl(ost);
99  ost << '\n' << "BEGIN MESH_FEM" << '\n' << '\n';
100  mf.write_basic_to_file(ost);
101  write_reduction_matrices_to_file(ost);
102  ost << "END MESH_FEM" << '\n';
103  }
104 
105  void partial_mesh_fem::write_to_file(const std::string &name,
106  bool with_mesh) const {
107  std::ofstream o(name.c_str());
108  GMM_ASSERT1(o, "impossible to open file '" << name << "'");
109  o << "% GETFEM MESH_FEM FILE " << '\n';
110  o << "% GETFEM VERSION " << GETFEM_VERSION << '\n' << '\n' << '\n';
111  if (with_mesh) mf.linked_mesh().write_to_file(o);
112  write_to_file(o);
113  }
114 
115  dal::bit_vector select_dofs_from_im(const mesh_fem &mf, const mesh_im &mim,
116  unsigned P) {
117  const mesh &m = mf.linked_mesh();
118  unsigned N = m.dim();
119  if (P == unsigned(-1)) P = N;
120  base_matrix G;
121  bgeot::pgeometric_trans pgt_old = 0;
122  bgeot::pgeotrans_precomp pgp2 = 0;
123  getfem::pfem pf_old = 0;
124  getfem::pfem_precomp pfp = 0;
125  pintegration_method pim1 = 0;
126 
127  std::vector<scalar_type> areas(mf.nb_basic_dof());
128  std::vector<scalar_type> area_supports(mf.nb_basic_dof());
129  dal::bit_vector kept_dofs;
130 
131  for (dal::bv_visitor cv(mim.convex_index()); !cv.finished(); ++cv) {
132  m.points_of_convex(cv, G);
133  bgeot::pgeometric_trans pgt = m.trans_of_convex(cv);
134  pintegration_method pim = mim.int_method_of_element(cv);
135  if (pim == im_none()) continue;
136  getfem::pfem pf = mf.fem_of_element(cv);
137  GMM_ASSERT1(pim->type() == IM_APPROX,
138  "Works only with approximate integration");
139  papprox_integration pai2= pim->approx_method();
140  static papprox_integration pai2_old = 0;
141  if (pgt_old != pgt || pai2 != pai2_old) {
142  pim1 = getfem::classical_approx_im(pgt, 2);
143  pgp2 = bgeot::geotrans_precomp(pgt, pai2->pintegration_points(),pim);
144  }
145  if (pai2 != pai2_old || pf != pf_old) {
146  pf_old = pf;
147  pfp = getfem::fem_precomp(pf, pai2->pintegration_points(), pim);
148  }
149  pai2_old = pai2;
150  pgt_old = pgt;
151 
153  scalar_type area1 = convex_area_estimate(pgt, G, pim1);
154 
155  size_type tdim = mf.get_qdim() / pf->target_dim();
156 
157  for (size_type i = 0; i < pai2->nb_points_on_convex(); ++i) {
158  for (unsigned d = 0; d < pf->nb_dof(cv); ++d) {
159  for (size_type j = 0; j < tdim; ++j) {
160  if (i == 0)
161  areas[mf.ind_basic_dof_of_element(cv)[d*tdim+j]] += area1;
162  c2.set_ii(i);
163  area_supports[mf.ind_basic_dof_of_element(cv)[d*tdim+j]]
164  += pai2->coeff(i) * c2.J() * gmm::sqr(pfp->val(i)[d]);
165  }
166  // * ((gmm::abs(pfp->val(i)[d]) < 1e-10) ? 0.0 : 1.0);
167  }
168  }
169  }
170 
171 
172  std::vector<scalar_type> areas2(mf.nb_dof());
173  std::vector<scalar_type> area_supports2(mf.nb_dof());
174 
175  if (mf.is_reduced()) {
176  gmm::mult(gmm::transposed(mf.extension_matrix()), areas, areas2);
177  gmm::mult(gmm::transposed(mf.extension_matrix()), area_supports,
178  area_supports2);
179  }
180  else {
181  gmm::copy(areas, areas2);
182  gmm::copy(area_supports, area_supports2);
183  }
184 
185  for (size_type i = 0; i < mf.nb_dof(); ++i) {
186  if (area_supports2[i] > pow(1e-14 * areas2[i], scalar_type(P) / N))
187  kept_dofs.add(i);
188  }
189 
190  return kept_dofs;
191  }
192 
193 
194 
195 } /* end of namespace getfem. */
196 
the geotrans_interpolation_context structure is passed as the argument of geometric transformation in...
void set_ii(size_type ii__)
change the current point (assuming a geotrans_precomp_ is used)
scalar_type J() const
get the Jacobian of the geometric trans (taken at point xref() )
Describe a finite element method linked to a mesh.
virtual ind_dof_ct ind_basic_dof_of_element(size_type cv) const
Give an array of the dof numbers a of convex.
virtual dim_type get_qdim() const
Return the Q dimension.
virtual size_type nb_dof() const
Return the total number of degrees of freedom.
const mesh & linked_mesh() const
Return a reference to the underlying mesh.
const EXTENSION_MATRIX & extension_matrix() const
Return the extension matrix corresponding to reduction applied (RE=I).
virtual size_type nb_basic_dof() const
Return the total number of basic degrees of freedom (before the optional reduction).
virtual pfem fem_of_element(size_type cv) const
Return the basic fem associated with an element (if no fem is associated, the function will crash!...
bool is_reduced() const
Return true if a reduction matrix is applied to the dofs.
Describe an integration method linked to a mesh.
virtual pintegration_method int_method_of_element(size_type cv) const
return the integration method associated with an element (in no integration is associated,...
const dal::bit_vector & convex_index(void) const
Get the set of convexes where an integration method has been assigned.
Describe a mesh (collection of convexes (elements) and points).
Definition: getfem_mesh.h:98
a subclass of getfem::mesh_fem which allows to eliminate a number of dof of the original mesh_fem.
scalar_type APIDECL convex_area_estimate(bgeot::pgeometric_trans pgt, const base_matrix &pts, pintegration_method pim)
rough estimate of the convex area.
Definition: getfem_mesh.cc:744
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
Definition: getfem_fem.h:243
pfem_precomp fem_precomp(pfem pf, bgeot::pstored_point_tab pspt, dal::pstatic_stored_object dep)
Handles precomputations for FEM.
Definition: getfem_fem.cc:4760
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:48
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
GEneric Tool for Finite Element Methods.
dal::bit_vector select_dofs_from_im(const mesh_fem &mf, const mesh_im &mim, unsigned P=unsigned(-1))
Return a selection of dof who contribute significantly to the mass-matrix that would be computed with...
pintegration_method classical_approx_im(bgeot::pgeometric_trans pgt, dim_type degree)
try to find an approximate integration method for the geometric transformation pgt which is able to i...
pintegration_method im_none(void)
return IM_NONE