GetFEM  5.5
getfem_fem_level_set.cc
Go to the documentation of this file.
1 /*===========================================================================
2 
3  Copyright (C) 1999-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 /** \file getfem_fem_level_set.cc
21  \brief an FEM which should be used with getfem::mesh_fem_level_set.
22 */
24 
25 namespace getfem {
26 
27  void fem_level_set::init() {
28  cvr = bfem->ref_convex(0);
29  dim_ = cvr->structure()->dim();
30  is_equiv = true; real_element_defined = true;
31  is_polycomp = is_pol = is_lag = is_standard_fem = false;
32  es_degree = 5; /* humm ... */
33  ntarget_dim = bfem->target_dim();
34 
35  std::stringstream nm;
36  nm << "FEM_LEVEL_SET(" << bfem->debug_name() << ")";
37  debug_name_ = nm.str();
38 
39  ls_index.sup(0, mls.nb_level_sets());
40 
41  common_ls_zones.resize(mls.nb_level_sets());
42  /* fill ls_index .. */
43  for (size_type i=0; i < mls.nb_level_sets(); ++i) {
44  char c = '*';
45  for (size_type k=0; k < bfem->nb_dof(0); ++k) {
46  const mesh_level_set::zoneset *ze = dofzones[k];
47  if (ze) {
48  for (mesh_level_set::zoneset::const_iterator itz = ze->begin();
49  itz != ze->end(); ++itz) {
50  const mesh_level_set::zone *z = *itz;
51  for (mesh_level_set::zone::const_iterator it = z->begin();
52  it != z->end(); ++it) {
53  assert((**it).size() == mls.nb_level_sets());
54  char d = (*(*it))[i];
55  if (c == '*') c = d;
56  else if (c != d) { ls_index.add(i); break; }
57  }
58  }
59  }
60  }
61  common_ls_zones[i] = c;
62  }
63 
64  init_cvs_node();
65  for (size_type k = 0; k < bfem->nb_dof(0); ++k) {
66  if (!dofzones[k]) {
67  add_node(bfem->dof_types()[k], bfem->node_of_dof(0,k));
68  } else {
69  for (size_type j = 0; j < dofzones[k]->size(); ++j) {
70  // cout << " -> +dof: '" << *(*dofzones[k])[j] << "'\n";
71  add_node(xfem_dof(bfem->dof_types()[k], j+xfem_index),
72  bfem->node_of_dof(0,k));
73  }
74  }
75  }
76  }
77 
78  void fem_level_set::base_value(const base_node &, base_tensor &) const
79  { GMM_ASSERT1(false, "No base values, real only element."); }
80  void fem_level_set::grad_base_value(const base_node &,
81  base_tensor &) const
82  { GMM_ASSERT1(false, "No base values, real only element."); }
83  void fem_level_set::hess_base_value(const base_node &,
84  base_tensor &) const
85  { GMM_ASSERT1(false, "No base values, real only element."); }
86 
87  static bool are_zones_compatible_(const std::string a, const std::string b) {
88  if (a.size() != b.size()) return false;
89  for (size_type i = 0; i < a.size(); ++i)
90  if (a[i] != '0' && a[i] != b[i]) return false;
91  return true;
92  }
93 
94  void fem_level_set::find_zone_id(const fem_interpolation_context &c,
95  std::vector<bool> &ids, int side) const {
96  size_type s = 0, cv = c.convex_num();
97  for (size_type i = 0; i < dofzones.size(); ++i)
98  if (dofzones[i]) s += dofzones[i]->size();
99  ids.resize(0); ids.resize(s, false);
100  std::string z(common_ls_zones);
101  base_vector coeff(32);
102 
103  mesher_level_set eval;
104  size_type iclosest = size_type(-1); scalar_type vclosest = 1E100;
105  for (dal::bv_visitor i(ls_index); !i.finished(); ++i) {
106  const level_set *ls = mls.get_level_set(i);
107  const mesh_fem &mf = ls->get_mesh_fem();
108  slice_vector_on_basic_dof_of_element(mf, ls->values(), cv, coeff);
109  eval.init_base(mf.fem_of_element(cv), coeff);
110  eval.set_shift(ls->get_shift()); // Deprecated
111 
112  // mesher_level_set eval = mls.get_level_set(i)->mls_of_convex(cv);
113 
114  scalar_type v = eval(c.xref());
115  if (side != 0) {
116  if (gmm::abs(v) < vclosest) { vclosest = gmm::abs(v); iclosest = i; }
117  }
118  z[size_type(i)] = (v > 0.) ? '+' : '-';
119  }
120 
121  if (side != 0 && iclosest != size_type(-1)) // Forces the side of the
122  // closest level-set (in order to compute jumps).
123  z[iclosest] = (side > 0) ? '+' : '-';
124 
125 
126  unsigned cnt = 0;
127  for (unsigned d = 0; d < dofzones.size(); ++d) {
128  if (!dofzones[d]) continue;
129  for (mesh_level_set::zoneset::const_iterator it = dofzones[d]->begin();
130  it != dofzones[d]->end(); ++it, ++cnt) {
131  ids[cnt] = false;
132  for (mesh_level_set::zone::const_iterator it2 = (*it)->begin();
133  it2 != (*it)->end(); ++it2) {
134  if (are_zones_compatible_(z,*(*it2))) { ids[cnt] = true; break; }
135  }
136  }
137  }
138  }
139 
141  base_tensor &t, bool) const {
142  // bgeot::multi_index mi(2);
143  // mi[1] = target_dim(); mi[0] = short_type(nb_base(0));
144  t.adjust_sizes(nb_base(0), target_dim());
145  base_tensor::iterator it = t.begin();
147  if (c0.have_pfp())
148  c0.set_pfp(fem_precomp(bfem, c0.pfp()->get_ppoint_tab(), c0.pfp()));
149  else c0.set_pf(bfem);
150  base_tensor tt; c0.base_value(tt);
151  base_tensor::const_iterator itf = tt.begin();
152 
153  std::vector<bool> zid;
154  find_zone_id(c, zid, c.xfem_side());
155  for (dim_type q = 0; q < target_dim(); ++q) {
156  unsigned cnt = 0;
157  for (size_type d = 0; d < bfem->nb_dof(0); ++d, ++itf) {
158  if (dofzones[d]) { /* enriched dof ? */
159  for (size_type k = 0; k < dofzones[d]->size(); ++k, ++cnt)
160  *it++ = zid[cnt] ? *itf : 0;
161  } else *it++ = *itf;
162  }
163  }
164  assert(it == t.end());
165  }
166 
168  base_tensor &t, bool) const {
169  // bgeot::multi_index mi(3);
170  // mi[2] = short_type(c.N()); mi[1] = target_dim();
171  // mi[0] = short_type(nb_base(0));
172  t.adjust_sizes(nb_base(0), target_dim(), c.N());
174  if (c0.have_pfp())
175  c0.set_pfp(fem_precomp(bfem, c0.pfp()->get_ppoint_tab(), c0.pfp()));
176  else c0.set_pf(bfem);
177  base_tensor tt; c0.grad_base_value(tt);
178 
179  base_tensor::iterator it = t.begin();
180  base_tensor::const_iterator itf = tt.begin();
181 
182  std::vector<bool> zid;
183  find_zone_id(c, zid, c.xfem_side());
184 
185  for (dim_type i = 0; i < c.N() ; ++i) {
186  for (dim_type q = 0; q < target_dim(); ++q) {
187  unsigned cnt = 0;
188  for (size_type d = 0; d < bfem->nb_dof(0); ++d, ++itf) {
189  if (dofzones[d]) { /* enriched dof ? */
190  for (size_type k = 0; k < dofzones[d]->size(); ++k, ++cnt)
191  *it++ = zid[cnt] ? *itf : 0;
192  } else *it++ = *itf;
193  }
194  }
195  }
196  assert(it == t.end());
197  }
198 
200  base_tensor &t, bool) const {
201  t.adjust_sizes(nb_base(0), target_dim(), gmm::sqr(c.N()));
203  if (c0.have_pfp())
204  c0.set_pfp(fem_precomp(bfem, c0.pfp()->get_ppoint_tab(), c0.pfp()));
205  else c0.set_pf(bfem);
206  base_tensor tt; c0.hess_base_value(tt);
207 
208  base_tensor::iterator it = t.begin();
209  base_tensor::const_iterator itf = tt.begin();
210 
211  std::vector<bool> zid;
212  find_zone_id(c, zid, c.xfem_side());
213 
214  dim_type NNdim = dim_type(gmm::sqr(c.N())*target_dim());
215  for (dim_type ijq = 0; ijq < NNdim ; ++ijq) {
216  unsigned cnt = 0;
217  for (size_type d = 0; d < bfem->nb_dof(0); ++d, ++itf) {
218  if (dofzones[d]) /* enriched dof ? */
219  for (size_type k = 0; k < dofzones[d]->size(); ++k, ++cnt)
220  *it++ = zid[cnt] ? *itf : 0;
221  else
222  *it++ = *itf;
223  }
224  }
225  assert(it == t.end());
226  }
227 
228 
229 } /* end of namespace getfem. */
230 
structure passed as the argument of fem interpolation functions.
Definition: getfem_fem.h:749
void real_hess_base_value(const fem_interpolation_context &c, base_tensor &t, bool=true) const
Give the hessian of all components of the base functions at the current point of the fem_interpolatio...
void real_base_value(const fem_interpolation_context &c, base_tensor &t, bool=true) const
Give the value of all components of the base functions at the current point of the fem_interpolation_...
void base_value(const base_node &x, base_tensor &t) const
Give the value of all components of the base functions at the point x of the reference element.
void real_grad_base_value(const fem_interpolation_context &c, base_tensor &t, bool=true) const
Give the gradient of all components of the base functions at the current point of the fem_interpolati...
void grad_base_value(const base_node &x, base_tensor &t) const
Give the value of all gradients (on ref.
void hess_base_value(const base_node &x, base_tensor &t) const
Give the value of all hessians (on ref.
size_type nb_level_sets(void) const
Get number of level-sets referenced in this object.
FEM associated with getfem::mesh_fem_level_set objects.
pdof_description xfem_dof(pdof_description p, size_type ind)
Description of a special dof for Xfem.
Definition: getfem_fem.cc:433
void add_node(const pdof_description &d, const base_node &pt, const dal::bit_vector &faces)
internal function adding a node to an element for the creation of a finite element method.
Definition: getfem_fem.cc:648
dim_type target_dim() const
dimension of the target space.
Definition: getfem_fem.h:313
bool have_pfp() const
true if a fem_precomp_ has been supplied.
Definition: getfem_fem.h:759
virtual size_type nb_base(size_type cv) const
Number of basis functions.
Definition: getfem_fem.h:298
void hess_base_value(base_tensor &t, bool withM=true) const
fill the tensor with the hessian of the base functions (taken at point this->xref())
Definition: getfem_fem.cc:255
void grad_base_value(base_tensor &t, bool withM=true) const
fill the tensor with the gradient of the base functions (taken at point this->xref())
Definition: getfem_fem.cc:202
void base_value(base_tensor &t, bool withM=true) const
fill the tensor with the values of the base functions (taken at point this->xref())
Definition: getfem_fem.cc:120
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
pfem_precomp pfp() const
get the current fem_precomp_
Definition: getfem_fem.h:793
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:48
GEneric Tool for Finite Element Methods.
void slice_vector_on_basic_dof_of_element(const mesh_fem &mf, const VEC1 &vec, size_type cv, VEC2 &coeff, size_type qmult1=size_type(-1), size_type qmult2=size_type(-1))
Given a mesh_fem.