GetFEM++  5.3
getfem_error_estimate.cc
1 /*===========================================================================
2 
3  Copyright (C) 2013-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 
25 #include <getfem/getfem_mesher.h>
26 
27 namespace getfem {
28 
29 #ifdef EXPERIMENTAL_PURPOSE_ONLY
30 
31 
32  void error_estimate_nitsche(const mesh_im & mim,
33  const mesh_fem &mf_u,
34  const base_vector &U,
35  int GAMMAC,
36  int GAMMAN,
37  scalar_type lambda,
38  scalar_type mu,
39  scalar_type gamma0,
40  scalar_type f_coeff,
41  scalar_type vertical_force,
42  base_vector &ERR) {
43 
44 
45 
46 
47  // static double lambda, mu;
48  const mesh &m = mf_u.linked_mesh();
49  size_type N = m.dim();
50  size_type qdim = mf_u.get_qdim();
51  gmm::clear(ERR);
52  std::vector<scalar_type> coeff1, coeff2;
53  base_matrix grad1(qdim, N), grad2(qdim, N), E(N, N), S1(N, N), S2(N, N);
54  base_matrix hess1(qdim, N*N);
55  base_matrix G1, G2;
57  base_node xref2(N);
58  base_small_vector up(N), jump(N), U1(N), sig(N), sigt(N);
59  //scalar_type young_modulus = mu*(3*lambda + 2*mu)/(lambda+mu);
60  scalar_type Pr, scal, sign, Un ;
61  scalar_type eta1 = 0, eta2 = 0, eta3 = 0, eta4 = 0;
62  scalar_type force_coeff= f_coeff; // inutile pour l'instant
63  force_coeff =0;
64 
65  //vertical force
66 
67  base_small_vector F(N);
68  for (unsigned ii=0; ii < N-1; ++ii)
69  F[ii]=0;
70  F[N-1]=-vertical_force;
71 
72  GMM_ASSERT1(!mf_u.is_reduced(), "To be adapted");
73 
74  for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv) {
75 
76  bgeot::pgeometric_trans pgt1 = m.trans_of_convex(cv);
77  getfem::papprox_integration pai1 =
78  get_approx_im_or_fail(mim.int_method_of_element(cv));
79  getfem::pfem pf1 = mf_u.fem_of_element(cv);
80  scalar_type radius = m.convex_radius_estimate(cv);
81  m.points_of_convex(cv, G1);
82  coeff1.resize(mf_u.nb_basic_dof_of_element(cv));
83  gmm::copy(gmm::sub_vector(U, gmm::sub_index(mf_u.ind_basic_dof_of_element(cv))), coeff1);
84  getfem::fem_interpolation_context ctx1(pgt1, pf1, base_node(N), G1, cv);
85 
86  // Residual on the element
87 
88  for (unsigned ii=0; ii < pai1->nb_points_on_convex(); ++ii) {
89  base_small_vector res(N);
90  ctx1.set_xref(pai1->point(ii));
91  pf1->interpolation_hess(ctx1, coeff1, hess1, dim_type(qdim));
92 
93  for (size_type i = 0; i < N; ++i)
94  for (size_type j = 0; j < N; ++j)
95  res[i] += (lambda + mu) * hess1(j, i*N+j) + mu * hess1(i, j*N+j)+F[i];
96 
97  ERR[cv] += radius*radius*ctx1.J()*pai1->coeff(ii)*gmm::vect_norm2_sqr(res); //norme carrée
98  eta1 += (radius*radius*ctx1.J()*pai1->coeff(ii)*gmm::vect_norm2_sqr(res));
99  }
100  //if (ERR[cv] > 100)
101  //cout << "Erreur en résidu sur element " << cv << " : " << ERR[cv] << endl;
102 
103 
104  // jump of the stress between the element ant its neighbours.
105 
106  for (short_type f1=0; f1 < m.structure_of_convex(cv)->nb_faces(); ++f1) {
107 
108  size_type cvn = m.neighbour_of_convex(cv, f1);
109  if (cvn == size_type(-1)) continue;
110 
111  bgeot::pgeometric_trans pgt2 = m.trans_of_convex(cvn);
112  getfem::pfem pf2 = mf_u.fem_of_element(cvn);
113  m.points_of_convex(cvn, G2);
114  coeff2.resize(mf_u.nb_basic_dof_of_element(cvn));
115  gmm::copy(gmm::sub_vector(U, gmm::sub_index(mf_u.ind_basic_dof_of_element(cvn))), coeff2);
116  getfem::fem_interpolation_context ctx2(pgt2, pf2, base_node(N), G2, cvn);
117  gic.init(m.points_of_convex(cvn), pgt2);
118  for (unsigned ii=0; ii < pai1->nb_points_on_face(f1); ++ii) {
119 
120  ctx1.set_xref(pai1->point_on_face(f1, ii));
121  gmm::mult(ctx1.B(), pgt1->normals()[f1], up);
122  scalar_type norm = gmm::vect_norm2(up);
123  up /= norm;
124  scalar_type coefficient = pai1->coeff_on_face(f1, ii) * ctx1.J() * norm;
125  pf1->interpolation_grad(ctx1, coeff1, grad1, dim_type(qdim));
126  gmm::copy(grad1, E); gmm::add(gmm::transposed(grad1), E);
127  gmm::scale(E, 0.5);
128  scalar_type trace = gmm::mat_trace(E);
129  gmm::copy(gmm::identity_matrix(), S1);
130  gmm::scale(S1, lambda * trace);
131  gmm::add(gmm::scaled(E, 2*mu), S1);
132  bool converged;
133  gic.invert(ctx1.xreal(), xref2, converged);
134  GMM_ASSERT1(converged, "geometric transformation not well inverted ... !");
135  ctx2.set_xref(xref2);
136  pf2->interpolation_grad(ctx2, coeff2, grad2, dim_type(qdim));
137  gmm::copy(grad2, E); gmm::add(gmm::transposed(grad2), E);
138  gmm::scale(E, 0.5);
139  trace = gmm::mat_trace(E);
140  gmm::copy(gmm::identity_matrix(), S2);
141  gmm::scale(S2, lambda * trace);
142  gmm::add(gmm::scaled(E, 2*mu), S2);
143  gmm::mult(S1, up, jump);
144  gmm::mult_add(S2, gmm::scaled(up, -1.0), jump);
145 
146  ERR[cv] +=radius * coefficient * gmm::vect_norm2_sqr(jump);
147  eta2 += (radius * coefficient * gmm::vect_norm2_sqr(jump));
148 
149 
150  }
151 
152 
153  }
154 
155 
156  };
157 
158 
159  {
160 
161  int bnum = GAMMAN;
162 
163  getfem::mesh_region region = m.region(bnum);
164  for (getfem::mr_visitor v(region,m); !v.finished(); ++v) {
165 
166  bgeot::pgeometric_trans pgt1 = m.trans_of_convex(v.cv());
167  getfem::papprox_integration pai1 =
168  get_approx_im_or_fail(mim.int_method_of_element(v.cv()));
169  getfem::pfem pf1 = mf_u.fem_of_element(v.cv());
170  scalar_type radius = m.convex_radius_estimate(v.cv());
171 
172  m.points_of_convex(v.cv(), G1);
173 
174  coeff1.resize(mf_u.nb_basic_dof_of_element(v.cv()));
175  gmm::copy(gmm::sub_vector(U, gmm::sub_index(mf_u.ind_basic_dof_of_element(v.cv()))), coeff1);
176 
177  getfem::fem_interpolation_context ctx1(pgt1, pf1, base_node(N), G1, v.cv());
178 
179  short_type f = v.f();
180 
181  for (unsigned ii=0; ii < pai1->nb_points_on_face(f); ++ii) {
182 
183  ctx1.set_xref(pai1->point_on_face(f, ii));
184  gmm::mult(ctx1.B(), pgt1->normals()[f], up);
185  scalar_type norm = gmm::vect_norm2(up);
186  up /= norm;
187  scalar_type coefficient = pai1->coeff_on_face(f, ii) * ctx1.J() * norm;
188  pf1->interpolation_grad(ctx1, coeff1, grad1, dim_type(qdim));
189  gmm::copy(grad1, E); gmm::add(gmm::transposed(grad1), E);
190  gmm::scale(E, 0.5);
191  scalar_type trace = gmm::mat_trace(E);
192  gmm::copy(gmm::identity_matrix(), S1);
193  gmm::scale(S1, lambda * trace);
194  gmm::add(gmm::scaled(E, 2*mu), S1);
195  gmm::mult(S1, up, jump);
196 
197  ERR[v.cv()] +=radius * coefficient * gmm::vect_norm2_sqr(jump);
198  eta2 += (radius * coefficient * gmm::vect_norm2_sqr(jump));
199  }
200  //cout << "Erreur en neumann sur " << v.cv() << " ERR[v.cv()] = " << ERR[v.cv()]-eee << endl;
201 
202  //if (ERR[v.cv()] > 100)
203  // cout << "Erreur en neumann sur element " << v.cv() << " : " << ERR[v.cv()] << endl;
204 
205  }
206 
207  };
208 
209 
210  {
211  int bnum = GAMMAC;
212 
213  getfem::mesh_region region = m.region(bnum);
214  for (getfem::mr_visitor v(region, m); !v.finished(); ++v) {
215 
216  bgeot::pgeometric_trans pgt1 = m.trans_of_convex(v.cv());
217  getfem::papprox_integration pai1 =
218  get_approx_im_or_fail(mim.int_method_of_element(v.cv()));
219  getfem::pfem pf1 = mf_u.fem_of_element(v.cv());
220 
221  m.points_of_convex(v.cv(), G1);
222 
223  coeff1.resize(mf_u.nb_basic_dof_of_element(v.cv()));
224  gmm::copy(gmm::sub_vector(U, gmm::sub_index(mf_u.ind_basic_dof_of_element(v.cv()))), coeff1);
225 
226  getfem::fem_interpolation_context ctx1(pgt1, pf1, base_node(N), G1, v.cv());
227 
228  // computation of h for gamma = gamma0*h
229  //scalar_type emax, emin, gamma;
230  //gmm::condition_number(ctx1.K(),emax,emin);
231  //gamma = gamma0 * emax * sqrt(scalar_type(N));
232  // Test autre gamma
233  scalar_type radius = m.convex_radius_estimate(v.cv());
234  scalar_type gamma=radius*gamma0;
235  short_type f = v.f();
236  for (unsigned ii=0; ii < pai1->nb_points_on_face(f); ++ii) {
237 
238  ctx1.set_xref(pai1->point_on_face(f, ii));
239  gmm::mult(ctx1.B(), pgt1->normals()[f], up);
240  scalar_type norm = gmm::vect_norm2(up);
241  up /= norm;
242  scalar_type coefficient = pai1->coeff_on_face(f, ii) * ctx1.J() * norm;
243  pf1->interpolation_grad(ctx1, coeff1, grad1, dim_type(qdim));
244  pf1->interpolation(ctx1, coeff1, U1, dim_type(qdim));
245  gmm::copy(grad1, E); gmm::add(gmm::transposed(grad1), E);
246  gmm::scale(E, 0.5);
247  scalar_type trace = gmm::mat_trace(E);
248  gmm::copy(gmm::identity_matrix(), S1);
249  gmm::scale(S1, lambda * trace);
250  gmm::add(gmm::scaled(E, 2*mu), S1);
251  gmm::mult(S1, up, sig); // sig = sigma(u)n
252  sign = gmm::vect_sp(sig,up);// sign = sigma_n(u)
253  Un = gmm::vect_sp(U1,up);// un = u_n
254  scal = Un-gamma*sign;
255  if (scal<0)
256  Pr = sign;
257  else
258  Pr = (scal/gamma + sign);
259  ERR[v.cv()] += coefficient*radius*Pr*Pr;
260  eta4 += coefficient*radius* Pr*Pr;
261 
262  gmm::copy(up,sigt);
263  gmm::scale(sigt, - sign);
264  gmm::add(sig,sigt);
265  ERR[v.cv()] += coefficient *radius*gmm::vect_norm2_sqr(sigt);
266  eta3 += coefficient *radius*gmm::vect_norm2_sqr(sigt);
267  }
268  // cout << "Erreur en contact sur " << v.cv() << " ERR[v.cv()] = " << ERR[v.cv()]-ee << endl;
269 
270  // if (ERR[v.cv()] > 100)
271  // cout << "Erreur en contact sur element " << v.cv() << " : " << ERR[v.cv()] << endl;
272 
273  }
274 
275  }
276 
277  cout << "eta1, eta2, eta3, eta4 = " << endl;
278  cout << sqrt(eta1) << endl;
279  cout << sqrt(eta2) << endl;
280  cout << sqrt(eta3) << endl;
281  cout << sqrt(eta4) << endl;
282  cout << sqrt(eta1+eta2+eta3+eta4) << endl;
283 
284  }
285 
286 #endif
287 
288 }
289 
structure used to hold a set of convexes and/or convex faces.
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2_sqr(const V &v)
squared Euclidean norm of a vector.
Definition: gmm_blas.h:544
An experimental mesher.
does the inversion of the geometric transformation for a given convex
Definition of a posteriori error estimates.
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
Definition: gmm_blas.h:557
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
bool invert(const base_node &n, base_node &n_ref, scalar_type IN_EPS=1e-12)
given the node on the real element, returns the node on the reference element (even if it is outside ...
structure passed as the argument of fem interpolation functions.
Definition: getfem_fem.h:741
"iterator" class for regions.
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
Comomon tools for unilateral contact and Coulomb friction bricks.
linalg_traits< M >::value_type mat_trace(const M &m)
Trace of a matrix.
Definition: gmm_blas.h:528
void mult_add(const L1 &l1, const L2 &l2, L3 &l3)
*/
Definition: gmm_blas.h:1779
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation