libMesh
systems_of_equations_ex7.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 // <h1> Systems Example 7 - Large deformation elasticity (St. Venant-Kirchoff material) </h1>
20 // \author Lorenzo Zanon
21 // \author David Knezevic
22 // \date 2014
23 //
24 // In this example, we consider an elastic cantilever beam modeled as a St. Venant-Kirchoff
25 // material (which is an extension of the linear elastic material model to the nonlinear
26 // regime). The implementation presented here uses NonlinearImplicitSystem.
27 //
28 // We formulate the PDE on the reference geometry (\Omega) as opposed to the deformed
29 // geometry (\Omega^deformed). As a result (e.g. see Ciarlet's 3D elasticity book,
30 // Theorem 2.6-2) the PDE is given as follows:
31 //
32 // \int_\Omega F_im Sigma_mj v_i,j = \int_\Omega f_i v_i + \int_\Gamma g_i v_i ds
33 //
34 // where:
35 // * F is the deformation gradient, F = I + du/dx (x here refers to reference coordinates).
36 // * Sigma is the second Piola-Kirchoff stress, which for the St. Venant Kirchoff model is
37 // given by Sigma_ij = C_ijkl E_kl, where E_kl is the strain,
38 // E_kl = 0.5 * (u_k,l + u_l,k + u_m,k u_m,l).
39 // * f is a body load.
40 // * g is a surface traction on the surface \Gamma.
41 //
42 // In this example we only consider a body load (e.g. gravity), hence we set g = 0.
43 
44 // C++ include files that we need
45 #include <iostream>
46 #include <algorithm>
47 #include <cmath>
48 
49 // Various include files needed for the mesh & solver functionality.
50 #include "libmesh/libmesh.h"
51 #include "libmesh/mesh.h"
52 #include "libmesh/mesh_refinement.h"
53 #include "libmesh/exodusII_io.h"
54 #include "libmesh/equation_systems.h"
55 #include "libmesh/fe.h"
56 #include "libmesh/quadrature_gauss.h"
57 #include "libmesh/dof_map.h"
58 #include "libmesh/sparse_matrix.h"
59 #include "libmesh/numeric_vector.h"
60 #include "libmesh/dense_matrix.h"
61 #include "libmesh/dense_vector.h"
62 #include "libmesh/elem.h"
63 #include "libmesh/string_to_enum.h"
64 #include "libmesh/getpot.h"
65 #include "libmesh/mesh_generation.h"
66 #include "libmesh/dirichlet_boundaries.h"
67 #include "libmesh/zero_function.h"
68 #include "libmesh/enum_solver_package.h"
69 
70 // The nonlinear solver and system we will be using
71 #include "libmesh/nonlinear_solver.h"
72 #include "libmesh/nonlinear_implicit_system.h"
73 
74 #define BOUNDARY_ID_MIN_Z 0
75 #define BOUNDARY_ID_MIN_Y 1
76 #define BOUNDARY_ID_MAX_X 2
77 #define BOUNDARY_ID_MAX_Y 3
78 #define BOUNDARY_ID_MIN_X 4
79 #define BOUNDARY_ID_MAX_Z 5
80 
81 using namespace libMesh;
82 
83 
84 
87 {
88 private:
90 
91 public:
92 
94  es(es_in)
95  {}
96 
100  Real kronecker_delta(unsigned int i,
101  unsigned int j)
102  {
103  return i == j ? 1. : 0.;
104  }
105 
109  Real elasticity_tensor(Real young_modulus,
110  Real poisson_ratio,
111  unsigned int i,
112  unsigned int j,
113  unsigned int k,
114  unsigned int l)
115  {
116  // Define the Lame constants
117  const Real lambda_1 = (young_modulus*poisson_ratio)/((1.+poisson_ratio)*(1.-2.*poisson_ratio));
118  const Real lambda_2 = young_modulus/(2.*(1.+poisson_ratio));
119 
120  return lambda_1 * kronecker_delta(i,j) * kronecker_delta(k,l) +
121  lambda_2 * (kronecker_delta(i,k) * kronecker_delta(j,l) + kronecker_delta(i,l) * kronecker_delta(j,k));
122  }
123 
124 
128  virtual void jacobian (const NumericVector<Number> & soln,
129  SparseMatrix<Number> & jacobian,
130  NonlinearImplicitSystem & /*sys*/)
131  {
132  const Real young_modulus = es.parameters.get<Real>("young_modulus");
133  const Real poisson_ratio = es.parameters.get<Real>("poisson_ratio");
134 
135  const MeshBase & mesh = es.get_mesh();
136  const unsigned int dim = mesh.mesh_dimension();
137 
138  NonlinearImplicitSystem & system =
139  es.get_system<NonlinearImplicitSystem>("NonlinearElasticity");
140 
141  const unsigned int u_var = system.variable_number ("u");
142 
143  const DofMap & dof_map = system.get_dof_map();
144 
145  FEType fe_type = dof_map.variable_type(u_var);
146  std::unique_ptr<FEBase> fe (FEBase::build(dim, fe_type));
147  QGauss qrule (dim, fe_type.default_quadrature_order());
148  fe->attach_quadrature_rule (&qrule);
149 
150  std::unique_ptr<FEBase> fe_face (FEBase::build(dim, fe_type));
151  QGauss qface (dim-1, fe_type.default_quadrature_order());
152  fe_face->attach_quadrature_rule (&qface);
153 
154  const std::vector<Real> & JxW = fe->get_JxW();
155  const std::vector<std::vector<Real>> & phi = fe->get_phi();
156  const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
157 
159  DenseSubMatrix<Number> Ke_var[3][3] =
160  {
164  };
165 
166  std::vector<dof_id_type> dof_indices;
167  std::vector<std::vector<dof_id_type>> dof_indices_var(3);
168 
169  jacobian.zero();
170 
171  for (const auto & elem : mesh.active_local_element_ptr_range())
172  {
173  dof_map.dof_indices (elem, dof_indices);
174  for (unsigned int var=0; var<3; var++)
175  dof_map.dof_indices (elem, dof_indices_var[var], var);
176 
177  const unsigned int n_dofs = dof_indices.size();
178  const unsigned int n_var_dofs = dof_indices_var[0].size();
179 
180  fe->reinit (elem);
181 
182  Ke.resize (n_dofs, n_dofs);
183  for (unsigned int var_i=0; var_i<3; var_i++)
184  for (unsigned int var_j=0; var_j<3; var_j++)
185  Ke_var[var_i][var_j].reposition (var_i*n_var_dofs, var_j*n_var_dofs, n_var_dofs, n_var_dofs);
186 
187  for (unsigned int qp=0; qp<qrule.n_points(); qp++)
188  {
189  DenseVector<Number> u_vec(3);
190  DenseMatrix<Number> grad_u(3, 3);
191  for (unsigned int var_i=0; var_i<3; var_i++)
192  {
193  for (unsigned int j=0; j<n_var_dofs; j++)
194  u_vec(var_i) += phi[j][qp]*soln(dof_indices_var[var_i][j]);
195 
196  // Row is variable u1, u2, or u3, column is x, y, or z
197  for (unsigned int var_j=0; var_j<3; var_j++)
198  for (unsigned int j=0; j<n_var_dofs; j++)
199  grad_u(var_i,var_j) += dphi[j][qp](var_j)*soln(dof_indices_var[var_i][j]);
200  }
201 
202  DenseMatrix<Number> strain_tensor(3, 3);
203  for (unsigned int i=0; i<3; i++)
204  for (unsigned int j=0; j<3; j++)
205  {
206  strain_tensor(i,j) += 0.5 * (grad_u(i,j) + grad_u(j,i));
207 
208  for (unsigned int k=0; k<3; k++)
209  strain_tensor(i,j) += 0.5 * grad_u(k,i)*grad_u(k,j);
210  }
211 
212  // Define the deformation gradient
213  DenseMatrix<Number> F(3, 3);
214  F = grad_u;
215  for (unsigned int var=0; var<3; var++)
216  F(var, var) += 1.;
217 
218  DenseMatrix<Number> stress_tensor(3, 3);
219 
220  for (unsigned int i=0; i<3; i++)
221  for (unsigned int j=0; j<3; j++)
222  for (unsigned int k=0; k<3; k++)
223  for (unsigned int l=0; l<3; l++)
224  stress_tensor(i,j) +=
225  elasticity_tensor(young_modulus, poisson_ratio, i, j, k, l) * strain_tensor(k, l);
226 
227  for (unsigned int dof_i=0; dof_i<n_var_dofs; dof_i++)
228  for (unsigned int dof_j=0; dof_j<n_var_dofs; dof_j++)
229  {
230  for (unsigned int i=0; i<3; i++)
231  for (unsigned int j=0; j<3; j++)
232  for (unsigned int m=0; m<3; m++)
233  Ke_var[i][i](dof_i,dof_j) += JxW[qp] *
234  (-dphi[dof_j][qp](m) * stress_tensor(m,j) * dphi[dof_i][qp](j));
235 
236  for (unsigned int i=0; i<3; i++)
237  for (unsigned int j=0; j<3; j++)
238  for (unsigned int k=0; k<3; k++)
239  for (unsigned int l=0; l<3; l++)
240  {
241  Number FxC_ijkl = 0.;
242  for (unsigned int m=0; m<3; m++)
243  FxC_ijkl += F(i,m) * elasticity_tensor(young_modulus, poisson_ratio, m, j, k, l);
244 
245  Ke_var[i][k](dof_i,dof_j) += JxW[qp] *
246  (-0.5 * FxC_ijkl * dphi[dof_j][qp](l) * dphi[dof_i][qp](j));
247 
248  Ke_var[i][l](dof_i,dof_j) += JxW[qp] *
249  (-0.5 * FxC_ijkl * dphi[dof_j][qp](k) * dphi[dof_i][qp](j));
250 
251  for (unsigned int n=0; n<3; n++)
252  Ke_var[i][n](dof_i,dof_j) += JxW[qp] *
253  (-0.5 * FxC_ijkl * (dphi[dof_j][qp](k) * grad_u(n,l) + dphi[dof_j][qp](l) * grad_u(n,k)) * dphi[dof_i][qp](j));
254  }
255  }
256  }
257 
258  dof_map.constrain_element_matrix (Ke, dof_indices);
259  jacobian.add_matrix (Ke, dof_indices);
260  }
261  }
262 
266  virtual void residual (const NumericVector<Number> & soln,
267  NumericVector<Number> & residual,
268  NonlinearImplicitSystem & /*sys*/)
269  {
270  const Real young_modulus = es.parameters.get<Real>("young_modulus");
271  const Real poisson_ratio = es.parameters.get<Real>("poisson_ratio");
272  const Real forcing_magnitude = es.parameters.get<Real>("forcing_magnitude");
273 
274  const MeshBase & mesh = es.get_mesh();
275  const unsigned int dim = mesh.mesh_dimension();
276 
277  NonlinearImplicitSystem & system =
278  es.get_system<NonlinearImplicitSystem>("NonlinearElasticity");
279 
280  const unsigned int u_var = system.variable_number ("u");
281 
282  const DofMap & dof_map = system.get_dof_map();
283 
284  FEType fe_type = dof_map.variable_type(u_var);
285  std::unique_ptr<FEBase> fe (FEBase::build(dim, fe_type));
286  QGauss qrule (dim, fe_type.default_quadrature_order());
287  fe->attach_quadrature_rule (&qrule);
288 
289  std::unique_ptr<FEBase> fe_face (FEBase::build(dim, fe_type));
290  QGauss qface (dim-1, fe_type.default_quadrature_order());
291  fe_face->attach_quadrature_rule (&qface);
292 
293  const std::vector<Real> & JxW = fe->get_JxW();
294  const std::vector<std::vector<Real>> & phi = fe->get_phi();
295  const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
296 
298 
299  DenseSubVector<Number> Re_var[3] =
303 
304  std::vector<dof_id_type> dof_indices;
305  std::vector<std::vector<dof_id_type>> dof_indices_var(3);
306 
307  residual.zero();
308 
309  for (const auto & elem : mesh.active_local_element_ptr_range())
310  {
311  dof_map.dof_indices (elem, dof_indices);
312  for (unsigned int var=0; var<3; var++)
313  dof_map.dof_indices (elem, dof_indices_var[var], var);
314 
315  const unsigned int n_dofs = dof_indices.size();
316  const unsigned int n_var_dofs = dof_indices_var[0].size();
317 
318  fe->reinit (elem);
319 
320  Re.resize (n_dofs);
321  for (unsigned int var=0; var<3; var++)
322  Re_var[var].reposition (var*n_var_dofs, n_var_dofs);
323 
324  for (unsigned int qp=0; qp<qrule.n_points(); qp++)
325  {
326  DenseVector<Number> u_vec(3);
327  DenseMatrix<Number> grad_u(3, 3);
328  for (unsigned int var_i=0; var_i<3; var_i++)
329  {
330  for (unsigned int j=0; j<n_var_dofs; j++)
331  u_vec(var_i) += phi[j][qp]*soln(dof_indices_var[var_i][j]);
332 
333  // Row is variable u, v, or w column is x, y, or z
334  for (unsigned int var_j=0; var_j<3; var_j++)
335  for (unsigned int j=0; j<n_var_dofs; j++)
336  grad_u(var_i,var_j) += dphi[j][qp](var_j)*soln(dof_indices_var[var_i][j]);
337  }
338 
339  DenseMatrix<Number> strain_tensor(3, 3);
340  for (unsigned int i=0; i<3; i++)
341  for (unsigned int j=0; j<3; j++)
342  {
343  strain_tensor(i,j) += 0.5 * (grad_u(i,j) + grad_u(j,i));
344 
345  for (unsigned int k=0; k<3; k++)
346  strain_tensor(i,j) += 0.5 * grad_u(k,i)*grad_u(k,j);
347  }
348 
349  // Define the deformation gradient
350  DenseMatrix<Number> F(3, 3);
351  F = grad_u;
352  for (unsigned int var=0; var<3; var++)
353  F(var, var) += 1.;
354 
355  DenseMatrix<Number> stress_tensor(3, 3);
356 
357  for (unsigned int i=0; i<3; i++)
358  for (unsigned int j=0; j<3; j++)
359  for (unsigned int k=0; k<3; k++)
360  for (unsigned int l=0; l<3; l++)
361  stress_tensor(i,j) +=
362  elasticity_tensor(young_modulus, poisson_ratio, i, j, k, l) * strain_tensor(k,l);
363 
364  DenseVector<Number> f_vec(3);
365  f_vec(0) = 0.;
366  f_vec(1) = 0.;
367  f_vec(2) = -forcing_magnitude;
368 
369  for (unsigned int dof_i=0; dof_i<n_var_dofs; dof_i++)
370  for (unsigned int i=0; i<3; i++)
371  {
372  for (unsigned int j=0; j<3; j++)
373  {
374  Number FxStress_ij = 0.;
375  for (unsigned int m=0; m<3; m++)
376  FxStress_ij += F(i,m) * stress_tensor(m,j);
377 
378  Re_var[i](dof_i) += JxW[qp] * (-FxStress_ij * dphi[dof_i][qp](j));
379  }
380 
381  Re_var[i](dof_i) += JxW[qp] * (f_vec(i) * phi[dof_i][qp]);
382  }
383  }
384 
385  dof_map.constrain_element_vector (Re, dof_indices);
386  residual.add_vector (Re, dof_indices);
387  }
388  }
389 
394  {
395  const Real young_modulus = es.parameters.get<Real>("young_modulus");
396  const Real poisson_ratio = es.parameters.get<Real>("poisson_ratio");
397 
398  const MeshBase & mesh = es.get_mesh();
399  const unsigned int dim = mesh.mesh_dimension();
400 
401  NonlinearImplicitSystem & system =
402  es.get_system<NonlinearImplicitSystem>("NonlinearElasticity");
403 
404  unsigned int displacement_vars[3];
405  displacement_vars[0] = system.variable_number ("u");
406  displacement_vars[1] = system.variable_number ("v");
407  displacement_vars[2] = system.variable_number ("w");
408  const unsigned int u_var = system.variable_number ("u");
409 
410  const DofMap & dof_map = system.get_dof_map();
411  FEType fe_type = dof_map.variable_type(u_var);
412  std::unique_ptr<FEBase> fe (FEBase::build(dim, fe_type));
413  QGauss qrule (dim, fe_type.default_quadrature_order());
414  fe->attach_quadrature_rule (&qrule);
415 
416  const std::vector<Real> & JxW = fe->get_JxW();
417  const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
418 
419  // Also, get a reference to the ExplicitSystem
420  ExplicitSystem & stress_system = es.get_system<ExplicitSystem>("StressSystem");
421  const DofMap & stress_dof_map = stress_system.get_dof_map();
422  unsigned int sigma_vars[6];
423  sigma_vars[0] = stress_system.variable_number ("sigma_00");
424  sigma_vars[1] = stress_system.variable_number ("sigma_01");
425  sigma_vars[2] = stress_system.variable_number ("sigma_02");
426  sigma_vars[3] = stress_system.variable_number ("sigma_11");
427  sigma_vars[4] = stress_system.variable_number ("sigma_12");
428  sigma_vars[5] = stress_system.variable_number ("sigma_22");
429 
430  // Storage for the stress dof indices on each element
431  std::vector<std::vector<dof_id_type>> dof_indices_var(system.n_vars());
432  std::vector<dof_id_type> stress_dof_indices_var;
433 
434  // To store the stress tensor on each element
435  DenseMatrix<Number> elem_avg_stress_tensor(3, 3);
436 
437  for (const auto & elem : mesh.active_local_element_ptr_range())
438  {
439  for (unsigned int var=0; var<3; var++)
440  dof_map.dof_indices (elem, dof_indices_var[var], displacement_vars[var]);
441 
442  const unsigned int n_var_dofs = dof_indices_var[0].size();
443 
444  fe->reinit (elem);
445 
446  // clear the stress tensor
447  elem_avg_stress_tensor.resize(3, 3);
448 
449  for (unsigned int qp=0; qp<qrule.n_points(); qp++)
450  {
451  DenseMatrix<Number> grad_u(3, 3);
452  // Row is variable u1, u2, or u3, column is x, y, or z
453  for (unsigned int var_i=0; var_i<3; var_i++)
454  for (unsigned int var_j=0; var_j<3; var_j++)
455  for (unsigned int j=0; j<n_var_dofs; j++)
456  grad_u(var_i,var_j) += dphi[j][qp](var_j) * system.current_solution(dof_indices_var[var_i][j]);
457 
458  DenseMatrix<Number> strain_tensor(3, 3);
459  for (unsigned int i=0; i<3; i++)
460  for (unsigned int j=0; j<3; j++)
461  {
462  strain_tensor(i,j) += 0.5 * (grad_u(i,j) + grad_u(j,i));
463 
464  for (unsigned int k=0; k<3; k++)
465  strain_tensor(i,j) += 0.5 * grad_u(k,i)*grad_u(k,j);
466  }
467 
468  // Define the deformation gradient
469  DenseMatrix<Number> F(3, 3);
470  F = grad_u;
471  for (unsigned int var=0; var<3; var++)
472  F(var, var) += 1.;
473 
474  DenseMatrix<Number> stress_tensor(3, 3);
475  for (unsigned int i=0; i<3; i++)
476  for (unsigned int j=0; j<3; j++)
477  for (unsigned int k=0; k<3; k++)
478  for (unsigned int l=0; l<3; l++)
479  stress_tensor(i,j) +=
480  elasticity_tensor(young_modulus, poisson_ratio, i, j, k, l) * strain_tensor(k, l);
481 
482  // stress_tensor now holds the second Piola-Kirchoff stress (PK2) at point qp.
483  // However, in this example we want to compute the Cauchy stress which is given by
484  // 1/det(F) * F * PK2 * F^T, hence we now apply this transformation.
485  stress_tensor.scale(1./F.det());
486  stress_tensor.left_multiply(F);
487  stress_tensor.right_multiply_transpose(F);
488 
489  // We want to plot the average Cauchy stress on each element, hence
490  // we integrate stress_tensor
491  elem_avg_stress_tensor.add(JxW[qp], stress_tensor);
492  }
493 
494  // Get the average stress per element by dividing by volume
495  elem_avg_stress_tensor.scale(1./elem->volume());
496 
497  // load elem_sigma data into stress_system
498  unsigned int stress_var_index = 0;
499  for (unsigned int i=0; i<3; i++)
500  for (unsigned int j=i; j<3; j++)
501  {
502  stress_dof_map.dof_indices (elem, stress_dof_indices_var, sigma_vars[stress_var_index]);
503 
504  // We are using CONSTANT MONOMIAL basis functions, hence we only need to get
505  // one dof index per variable
506  dof_id_type dof_index = stress_dof_indices_var[0];
507 
508  if ((stress_system.solution->first_local_index() <= dof_index) &&
509  (dof_index < stress_system.solution->last_local_index()))
510  stress_system.solution->set(dof_index, elem_avg_stress_tensor(i,j));
511 
512  stress_var_index++;
513  }
514  }
515 
516  // Should call close and update when we set vector entries directly
517  stress_system.solution->close();
518  stress_system.update();
519  }
520 
521 };
522 
523 
524 int main (int argc, char ** argv)
525 {
526  LibMeshInit init (argc, argv);
527 
528  // This example requires the PETSc nonlinear solvers
529  libmesh_example_requires(libMesh::default_solver_package() == PETSC_SOLVERS, "--enable-petsc");
530 
531  // We use a 3D domain.
532  libmesh_example_requires(LIBMESH_DIM > 2, "--disable-1D-only --disable-2D-only");
533 
534  // We use Dirichlet boundary conditions here
535 #ifndef LIBMESH_ENABLE_DIRICHLET
536  libmesh_example_requires(false, "--enable-dirichlet");
537 #endif
538 
539  GetPot infile("systems_of_equations_ex7.in");
540  const Real x_length = infile("x_length", 0.);
541  const Real y_length = infile("y_length", 0.);
542  const Real z_length = infile("z_length", 0.);
543  const int n_elem_x = infile("n_elem_x", 0);
544  const int n_elem_y = infile("n_elem_y", 0);
545  const int n_elem_z = infile("n_elem_z", 0);
546  const std::string approx_order = infile("approx_order", "FIRST");
547  const std::string fe_family = infile("fe_family", "LAGRANGE");
548 
549  const Real young_modulus = infile("Young_modulus", 1.0);
550  const Real poisson_ratio = infile("poisson_ratio", 0.3);
551  const Real forcing_magnitude = infile("forcing_magnitude", 0.001);
552 
553  const Real nonlinear_abs_tol = infile("nonlinear_abs_tol", 1.e-8);
554  const Real nonlinear_rel_tol = infile("nonlinear_rel_tol", 1.e-8);
555  const unsigned int nonlinear_max_its = infile("nonlinear_max_its", 50);
556 
557  const unsigned int n_solves = infile("n_solves", 10);
558  const Real force_scaling = infile("force_scaling", 5.0);
559 
560  Mesh mesh(init.comm());
561 
563  n_elem_x,
564  n_elem_y,
565  n_elem_z,
566  0., x_length,
567  0., y_length,
568  0., z_length,
569  HEX27);
570 
571  mesh.print_info();
572 
573  EquationSystems equation_systems (mesh);
574  LargeDeformationElasticity lde(equation_systems);
575 
576  NonlinearImplicitSystem & system =
577  equation_systems.add_system<NonlinearImplicitSystem> ("NonlinearElasticity");
578 
579  unsigned int u_var =
580  system.add_variable("u",
581  Utility::string_to_enum<Order> (approx_order),
582  Utility::string_to_enum<FEFamily>(fe_family));
583 
584  unsigned int v_var =
585  system.add_variable("v",
586  Utility::string_to_enum<Order> (approx_order),
587  Utility::string_to_enum<FEFamily>(fe_family));
588 
589  unsigned int w_var =
590  system.add_variable("w",
591  Utility::string_to_enum<Order> (approx_order),
592  Utility::string_to_enum<FEFamily>(fe_family));
593 
594  // Also, initialize an ExplicitSystem to store stresses
595  ExplicitSystem & stress_system =
596  equation_systems.add_system<ExplicitSystem> ("StressSystem");
597  stress_system.add_variable("sigma_00", CONSTANT, MONOMIAL);
598  stress_system.add_variable("sigma_01", CONSTANT, MONOMIAL);
599  stress_system.add_variable("sigma_02", CONSTANT, MONOMIAL);
600  stress_system.add_variable("sigma_11", CONSTANT, MONOMIAL);
601  stress_system.add_variable("sigma_12", CONSTANT, MONOMIAL);
602  stress_system.add_variable("sigma_22", CONSTANT, MONOMIAL);
603 
604  equation_systems.parameters.set<Real> ("nonlinear solver absolute residual tolerance") = nonlinear_abs_tol;
605  equation_systems.parameters.set<Real> ("nonlinear solver relative residual tolerance") = nonlinear_rel_tol;
606  equation_systems.parameters.set<unsigned int> ("nonlinear solver maximum iterations") = nonlinear_max_its;
607 
608  system.nonlinear_solver->residual_object = &lde;
609  system.nonlinear_solver->jacobian_object = &lde;
610 
611  equation_systems.parameters.set<Real>("young_modulus") = young_modulus;
612  equation_systems.parameters.set<Real>("poisson_ratio") = poisson_ratio;
613  equation_systems.parameters.set<Real>("forcing_magnitude") = forcing_magnitude;
614 
615 #ifdef LIBMESH_ENABLE_DIRICHLET
616  // Attach Dirichlet boundary conditions
617  std::set<boundary_id_type> clamped_boundaries;
618  clamped_boundaries.insert(BOUNDARY_ID_MIN_X);
619 
620  std::vector<unsigned int> uvw;
621  uvw.push_back(u_var);
622  uvw.push_back(v_var);
623  uvw.push_back(w_var);
624 
626 
627  // Most DirichletBoundary users will want to supply a "locally
628  // indexed" functor
630  (DirichletBoundary (clamped_boundaries, uvw, zero,
632 #else
633  libmesh_ignore(u_var, v_var, w_var);
634 #endif // LIBMESH_ENABLE_DIRICHLET
635 
636  equation_systems.init();
637  equation_systems.print_info();
638 
639  // Provide a loop here so that we can do a sequence of solves
640  // where solve n gives a good starting guess for solve n+1.
641  // This "continuation" approach is helpful for solving for
642  // large values of "forcing_magnitude".
643  // Set n_solves and force_scaling in nonlinear_elasticity.in.
644  for (unsigned int count=0; count<n_solves; count++)
645  {
646  Real previous_forcing_magnitude = equation_systems.parameters.get<Real>("forcing_magnitude");
647  equation_systems.parameters.set<Real>("forcing_magnitude") = previous_forcing_magnitude*force_scaling;
648 
649  libMesh::out << "Performing solve "
650  << count
651  << ", forcing_magnitude: "
652  << equation_systems.parameters.get<Real>("forcing_magnitude")
653  << std::endl;
654 
655  system.solve();
656 
657  libMesh::out << "System solved at nonlinear iteration "
658  << system.n_nonlinear_iterations()
659  << " , final nonlinear residual norm: "
660  << system.final_nonlinear_residual()
661  << std::endl
662  << std::endl;
663 
664  libMesh::out << "Computing stresses..." << std::endl;
665 
666  lde.compute_stresses();
667 
668 #ifdef LIBMESH_HAVE_EXODUS_API
669  std::stringstream filename;
670  filename << "solution_" << count << ".exo";
671  ExodusII_IO (mesh).write_equation_systems(filename.str(), equation_systems);
672 #endif
673  }
674 
675  return 0;
676 }
elasticity_tensor
Real elasticity_tensor(unsigned int i, unsigned int j, unsigned int k, unsigned int l)
Definition: assembly.C:40
libMesh::NumericVector::zero
virtual void zero()=0
Set all entries to zero.
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::Number
Real Number
Definition: libmesh_common.h:195
libMesh::System::n_vars
unsigned int n_vars() const
Definition: system.h:2155
libMesh::NonlinearImplicitSystem::final_nonlinear_residual
Real final_nonlinear_residual() const
Definition: nonlinear_implicit_system.h:278
libMesh::Mesh
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
libMesh::EquationSystems::add_system
virtual System & add_system(const std::string &system_type, const std::string &name)
Add the system of type system_type named name to the systems array.
Definition: equation_systems.C:345
libMesh::EquationSystems::get_mesh
const MeshBase & get_mesh() const
Definition: equation_systems.h:637
libMesh::QGauss
This class implements specific orders of Gauss quadrature.
Definition: quadrature_gauss.h:39
libMesh::PETSC_SOLVERS
Definition: enum_solver_package.h:36
libMesh::DofMap::dof_indices
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
Definition: dof_map.C:1967
libMesh::DenseMatrix::right_multiply_transpose
void right_multiply_transpose(const DenseMatrix< T > &A)
Right multiplies by the transpose of the matrix A.
Definition: dense_matrix_impl.h:278
libMesh::DofMap::constrain_element_vector
void constrain_element_vector(DenseVector< Number > &rhs, std::vector< dof_id_type > &dofs, bool asymmetric_constraint_rows=true) const
Constrains the element vector.
Definition: dof_map.h:2030
libMesh::DofMap::add_dirichlet_boundary
void add_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary)
Adds a copy of the specified Dirichlet boundary to the system.
Definition: dof_map_constraints.C:4390
libMesh::MeshBase::active_local_element_ptr_range
virtual SimpleRange< element_iterator > active_local_element_ptr_range()=0
libMesh::DenseSubMatrix
Defines a dense submatrix for use in Finite Element-type computations.
Definition: dense_submatrix.h:45
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::DenseMatrix::add
boostcopy::enable_if_c< ScalarTraits< T2 >::value, void >::type add(const T2 factor, const DenseMatrix< T3 > &mat)
Adds factor times mat to this matrix.
Definition: dense_matrix.h:945
libMesh::EquationSystems::get_system
const T_sys & get_system(const std::string &name) const
Definition: equation_systems.h:757
kronecker_delta
Real kronecker_delta(unsigned int i, unsigned int j)
Definition: assembly.C:34
libMesh::MeshTools::Generation::build_cube
void build_cube(UnstructuredMesh &mesh, const unsigned int nx=0, const unsigned int ny=0, const unsigned int nz=0, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const Real zmin=0., const Real zmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
Builds a (elements) cube.
Definition: mesh_generation.C:298
libMesh::DenseMatrix< Number >
main
int main(int argc, char **argv)
Definition: systems_of_equations_ex7.C:524
libMesh::default_solver_package
SolverPackage default_solver_package()
Definition: libmesh.C:993
mesh
MeshBase & mesh
Definition: mesh_communication.C:1257
libMesh::MeshBase::mesh_dimension
unsigned int mesh_dimension() const
Definition: mesh_base.C:135
libMesh::ExodusII_IO
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition: exodusII_io.h:51
libMesh::NonlinearImplicitSystem
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
Definition: nonlinear_implicit_system.h:54
LargeDeformationElasticity::kronecker_delta
Real kronecker_delta(unsigned int i, unsigned int j)
Kronecker delta function.
Definition: systems_of_equations_ex7.C:100
libMesh::SparseMatrix< Number >
dim
unsigned int dim
Definition: adaptivity_ex3.C:113
libMesh::DenseMatrix::resize
void resize(const unsigned int new_m, const unsigned int new_n)
Resize the matrix.
Definition: dense_matrix.h:822
libMesh::NonlinearImplicitSystem::solve
virtual void solve() override
Assembles & solves the nonlinear system R(x) = 0.
Definition: nonlinear_implicit_system.C:161
libMesh::NumericVector< Number >
libMesh::zero
const Number zero
.
Definition: libmesh.h:243
libMesh::System::current_solution
Number current_solution(const dof_id_type global_dof_number) const
Definition: system.C:194
libMesh::TriangleWrapper::init
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
LargeDeformationElasticity::es
EquationSystems & es
Definition: systems_of_equations_ex7.C:89
libMesh::LOCAL_VARIABLE_ORDER
Definition: dirichlet_boundaries.h:62
libMesh::NumericVector::add_vector
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
Computes , where v is a pointer and each dof_indices[i] specifies where to add value v[i].
Definition: numeric_vector.C:363
libMesh::MeshBase
This is the MeshBase class.
Definition: mesh_base.h:78
libMesh::HEX27
Definition: enum_elem_type.h:49
libMesh::libmesh_ignore
void libmesh_ignore(const Args &...)
Definition: libmesh_common.h:526
libMesh::FEGenericBase::build
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
LargeDeformationElasticity::elasticity_tensor
Real elasticity_tensor(Real young_modulus, Real poisson_ratio, unsigned int i, unsigned int j, unsigned int k, unsigned int l)
Evaluate the fourth order tensor (C_ijkl) that relates stress to strain.
Definition: systems_of_equations_ex7.C:109
libMesh::System::add_variable
unsigned int add_variable(const std::string &var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variable var to the list of variables for this system.
Definition: system.C:1069
libMesh::EquationSystems::init
virtual void init()
Initialize all the systems.
Definition: equation_systems.C:96
libMesh::NonlinearImplicitSystem::n_nonlinear_iterations
unsigned int n_nonlinear_iterations() const
Definition: nonlinear_implicit_system.h:273
LargeDeformationElasticity
Definition: systems_of_equations_ex7.C:85
libMesh::CONSTANT
Definition: enum_order.h:41
libMesh::DofMap::variable_type
const FEType & variable_type(const unsigned int c) const
Definition: dof_map.h:1924
LargeDeformationElasticity::LargeDeformationElasticity
LargeDeformationElasticity(EquationSystems &es_in)
Definition: systems_of_equations_ex7.C:93
libMesh::LibMeshInit
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition: libmesh.h:83
LargeDeformationElasticity::residual
virtual void residual(const NumericVector< Number > &soln, NumericVector< Number > &residual, NonlinearImplicitSystem &)
Evaluate the residual of the nonlinear system.
Definition: systems_of_equations_ex7.C:266
libMesh::ZeroFunction
ConstFunction that simply returns 0.
Definition: zero_function.h:36
libMesh::EquationSystems::print_info
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
Definition: equation_systems.C:1314
libMesh::MONOMIAL
Definition: enum_fe_family.h:39
libMesh::EquationSystems
This is the EquationSystems class.
Definition: equation_systems.h:74
libMesh::Parameters::set
T & set(const std::string &)
Definition: parameters.h:460
libMesh::DenseSubVector< Number >
libMesh::MeshOutput::write_equation_systems
virtual void write_equation_systems(const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
This method implements writing a mesh with data to a specified file where the data is taken from the ...
Definition: mesh_output.C:31
LargeDeformationElasticity::compute_stresses
void compute_stresses()
Compute the Cauchy stress for the current solution.
Definition: systems_of_equations_ex7.C:393
libMesh::NonlinearImplicitSystem::nonlinear_solver
std::unique_ptr< NonlinearSolver< Number > > nonlinear_solver
The NonlinearSolver defines the default interface used to solve the nonlinear_implicit system.
Definition: nonlinear_implicit_system.h:261
libMesh::ExplicitSystem
Manages consistently variables, degrees of freedom, and coefficient vectors for explicit systems.
Definition: explicit_system.h:48
libMesh::DenseVector::resize
void resize(const unsigned int n)
Resize the vector.
Definition: dense_vector.h:355
libMesh::DofMap::constrain_element_matrix
void constrain_element_matrix(DenseMatrix< Number > &matrix, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
Constrains the element matrix.
Definition: dof_map.h:2021
libMesh::System::solution
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1539
libMesh::SparseMatrix::add_matrix
virtual void add_matrix(const DenseMatrix< T > &dm, const std::vector< numeric_index_type > &rows, const std::vector< numeric_index_type > &cols)=0
Add the full matrix dm to the SparseMatrix.
libMesh::DenseMatrix::left_multiply
virtual void left_multiply(const DenseMatrixBase< T > &M2) override
Performs the operation: (*this) <- M2 * (*this)
Definition: dense_matrix_impl.h:58
libMesh::FEType
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:178
libMesh::DofMap
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:176
libMesh::MeshBase::print_info
void print_info(std::ostream &os=libMesh::out) const
Prints relevant information about the mesh.
Definition: mesh_base.C:585
libMesh::DirichletBoundary
This class allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
Definition: dirichlet_boundaries.h:88
libMesh::DenseMatrix::det
T det()
Definition: dense_matrix_impl.h:886
libMesh::NonlinearImplicitSystem::ComputeJacobian
Abstract base class to be used to calculate the Jacobian of a nonlinear system.
Definition: nonlinear_implicit_system.h:103
libMesh::System::variable_number
unsigned short int variable_number(const std::string &var) const
Definition: system.C:1232
libMesh::System::get_dof_map
const DofMap & get_dof_map() const
Definition: system.h:2099
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::FEType::default_quadrature_order
Order default_quadrature_order() const
Definition: fe_type.h:353
LargeDeformationElasticity::jacobian
virtual void jacobian(const NumericVector< Number > &soln, SparseMatrix< Number > &jacobian, NonlinearImplicitSystem &)
Evaluate the Jacobian of the nonlinear system.
Definition: systems_of_equations_ex7.C:128
libMesh::Parameters::get
const T & get(const std::string &) const
Definition: parameters.h:421
libMesh::out
OStreamProxy out
libMesh::NonlinearImplicitSystem::ComputeResidual
Abstract base class to be used to calculate the residual of a nonlinear system.
Definition: nonlinear_implicit_system.h:85
libMesh::System::update
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition: system.C:408
libMesh::SparseMatrix::zero
virtual void zero()=0
Set all entries to 0.
libMesh::DenseMatrix::scale
void scale(const T factor)
Multiplies every element in the matrix by factor.
Definition: dense_matrix.h:913
libMesh::DenseVector< Number >
libMesh::EquationSystems::parameters
Parameters parameters
Data structure holding arbitrary parameters.
Definition: equation_systems.h:557