GetFEM++  5.3
getfem_mesh_fem_product.cc
1 /*===========================================================================
2 
3  Copyright (C) 1999-2017 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, write to the Free Software Foundation,
18  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20 ===========================================================================*/
21 
22 
24 
25 namespace getfem {
26 
27  void fem_product::init() {
28 
29  GMM_ASSERT1(pfems[0]->target_dim() == 1, "To be done");
30  GMM_ASSERT1(pfems[1]->target_dim() == 1,
31  "The second finite element should be scalar");
32 
33  cvr = pfems[0]->ref_convex(cv);
34  dim_ = cvr->structure()->dim();
35  is_equiv = real_element_defined = true;
36  is_polycomp = is_pol = is_lag = is_standard_fem = false;
37  es_degree = 5; /* humm ... */
38  ntarget_dim = 1;
39  std::stringstream nm;
40  nm << "FEM_PRODUCT(" << pfems[0]->debug_name() << ","
41  << pfems[1]->debug_name() << "," << cv << ")";
42  debug_name_ = nm.str();
43 
44  init_cvs_node();
45  for (dal::bv_visitor i(enriched_dof1); !i.finished(); ++i) {
46  for (size_type j = 0; j < pfems[1]->nb_dof(cv); ++j)
47  add_node(xfem_dof(pfems[0]->dof_types()[i], xfem_index+j),
48  pfems[0]->node_of_dof(cv,i));
49  }
50  }
51 
52  void fem_product::base_value(const base_node &,
53  base_tensor &) const
54  { GMM_ASSERT1(false, "No base values, real only element."); }
55  void fem_product::grad_base_value(const base_node &,
56  base_tensor &) const
57  { GMM_ASSERT1(false, "No base values, real only element."); }
58  void fem_product::hess_base_value(const base_node &,
59  base_tensor &) const
60  { GMM_ASSERT1(false, "No base values, real only element."); }
61 
62  void fem_product::real_base_value(const fem_interpolation_context &c,
63  base_tensor &t, bool) const {
64  bgeot::multi_index mi(2);
65  mi[1] = target_dim(); mi[0] = short_type(nb_dof(0));
66  t.adjust_sizes(mi);
67  base_tensor::iterator it = t.begin(), itf;
68 
69  fem_interpolation_context c0 = c;
70  std::vector<base_tensor> val_e(2);
71  for (size_type k = 0; k < 2; ++k) {
72  if (c0.have_pfp()) {
73  c0.set_pfp(fem_precomp(pfems[k], c0.pfp()->get_ppoint_tab(),
74  c0.pfp()));
75  } else { c0.set_pf(pfems[k]); }
76  c0.base_value(val_e[k]);
77  }
78 
79  assert(target_dim() == 1);
80  for (dal::bv_visitor i(enriched_dof1); !i.finished(); ++i) {
81  itf = val_e[1].begin();
82  scalar_type e = val_e[0][i];
83  for (size_type j = 0; j < pfems[1]->nb_dof(cv); ++j)
84  *it++ = *itf++ * e;
85  }
86  assert(it == t.end());
87  }
88 
89  void fem_product::real_grad_base_value(const fem_interpolation_context &c,
90  base_tensor &t, bool) const {
91  bgeot::multi_index mi(3);
92  mi[2] = short_type(c.N()); mi[1] = target_dim();
93  mi[0] = short_type(nb_dof(0));
94  t.adjust_sizes(mi);
95  base_tensor::iterator it = t.begin();
96 
97  fem_interpolation_context c0 = c;
98  std::vector<base_tensor> grad_e(2), val_e(2);
99  for (size_type k = 0; k < 2; ++k) {
100  if (c0.have_pfp()) {
101  c0.set_pfp(fem_precomp(pfems[k], c0.pfp()->get_ppoint_tab(),
102  c0.pfp()));
103  } else { c0.set_pf(pfems[k]); }
104  c0.grad_base_value(grad_e[k]);
105  c0.base_value(val_e[k]);
106  }
107 
108  assert(target_dim() == 1);
109  for (dim_type k = 0; k < c.N() ; ++k) {
110  for (dal::bv_visitor i(enriched_dof1); !i.finished(); ++i) {
111  size_type posg0 = k * pfems[0]->nb_dof(cv);
112  size_type posg1 = k * pfems[1]->nb_dof(cv);
113  for (size_type j = 0; j < pfems[1]->nb_dof(cv); ++j)
114  *it++ = grad_e[0][i + posg0] * val_e[1][j]
115  + grad_e[1][j + posg1] * val_e[0][i];
116  }
117  }
118  assert(it == t.end());
119  }
120 
121  void fem_product::real_hess_base_value(const fem_interpolation_context &c,
122  base_tensor &t, bool) const {
123  t.adjust_sizes(nb_dof(0), target_dim(), gmm::sqr(c.N()));
124  base_tensor::iterator it = t.begin();
125 
126  fem_interpolation_context c0 = c;
127  std::vector<base_tensor> hess_e(2), grad_e(2), val_e(2);
128  for (size_type k = 0; k < 2; ++k) {
129  if (c0.have_pfp()) {
130  c0.set_pfp(fem_precomp(pfems[k], c0.pfp()->get_ppoint_tab(),
131  c0.pfp()));
132  } else { c0.set_pf(pfems[k]); }
133  c0.hess_base_value(hess_e[k]);
134  c0.grad_base_value(grad_e[k]);
135  c0.base_value(val_e[k]);
136  }
137 
138  assert(target_dim() == 1);
139  for (dim_type k0 = 0; k0 < c.N(); ++k0) {
140  for (dim_type k1 = 0; k1 < c.N() ; ++k1) {
141  for (dal::bv_visitor i(enriched_dof1); !i.finished(); ++i) {
142  size_type posh0 = (k0*c.N()+k1) * pfems[0]->nb_dof(cv);
143  size_type posh1 = (k0*c.N()+k1) * pfems[1]->nb_dof(cv);
144  size_type posg00 = k0 * pfems[0]->nb_dof(cv);
145  size_type posg01 = k1 * pfems[0]->nb_dof(cv);
146  size_type posg10 = k0 * pfems[1]->nb_dof(cv);
147  size_type posg11 = k1 * pfems[1]->nb_dof(cv);
148  for (size_type j = 0; j < pfems[1]->nb_dof(cv); ++j) {
149  *it++ = hess_e[0][i + posh0] * val_e[1][j] +
150  hess_e[1][j + posh1] * val_e[0][i] +
151  grad_e[0][i + posg00] * grad_e[1][j + posg11] +
152  grad_e[0][i + posg01] * grad_e[1][j + posg10];
153  }
154  }
155  }
156  }
157  assert(it == t.end());
158  }
159 
160  void mesh_fem_product::clear_build_methods() {
161  for (size_type i = 0; i < build_methods.size(); ++i)
162  del_stored_object(build_methods[i]);
163  build_methods.clear();
164  }
165  void mesh_fem_product::clear(void) {
166  mesh_fem::clear();
167  clear_build_methods();
168  is_adapted = false;
169  }
170 
171  DAL_SIMPLE_KEY(special_mflproduct_key, pfem);
172 
173  void mesh_fem_product::adapt(void) {
174  context_check();
175  clear();
176 
177  GMM_ASSERT1(!mf1.is_reduced() && !mf2.is_reduced(),
178  "Sorry, mesh_fem_product not defined for reduced mesh_fems");
179 
180  for (dal::bv_visitor cv(linked_mesh().convex_index()); !cv.finished();
181  ++cv) {
182  dal::bit_vector local_enriched_dof;
183  for (size_type i = 0; i < mf1.nb_basic_dof_of_element(cv); ++i)
184  if (enriched_dof.is_in(mf1.ind_basic_dof_of_element(cv)[i]))
185  local_enriched_dof.add(i);
186  if (local_enriched_dof.card() > 0) {
187  pfem pf = std::make_shared<fem_product>
188  (mf1.fem_of_element(cv), mf2.fem_of_element(cv), cv,
189  xfem_index, local_enriched_dof);
190  dal::pstatic_stored_object_key
191  pk = std::make_shared<special_mflproduct_key>(pf);
192  dal::add_stored_object(pk, pf, pf->ref_convex(0), pf->node_tab(0));
193  build_methods.push_back(pf);
194  set_finite_element(cv, pf);
195  }
196  }
197  is_adapted = true; touch();
198  }
199 
200 
201 } /* end of namespace getfem. */
202 
void del_stored_object(const pstatic_stored_object &o, bool ignore_unstored)
Delete an object and the object which depend on it.
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o, permanence perm)
Add an object with two optional dependencies.
GEneric Tool for Finite Element Methods.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
Definition: getfem_fem.h:239
void clear(L &l)
clear (fill with zeros) a vector or matrix.
Definition: gmm_blas.h:59
gmm::uint16_type short_type
used as the common short type integer in the library
Definition: bgeot_config.h:79
pfem_precomp fem_precomp(pfem pf, bgeot::pstored_point_tab pspt, dal::pstatic_stored_object dep)
Handles precomputations for FEM.
Definition: getfem_fem.cc:4051
A kind of product of two mesh_fems. Specific for Xfem enrichment.
pdof_description xfem_dof(pdof_description p, size_type ind)
Description of a special dof for Xfem.
Definition: getfem_fem.cc:428