libMesh
Loading...
Searching...
No Matches
systems_of_equations_ex7.C
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 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#include "libmesh/vector_value.h"
70#include "libmesh/tensor_value.h"
71
72// The nonlinear solver and system we will be using
73#include "libmesh/nonlinear_solver.h"
74#include "libmesh/nonlinear_implicit_system.h"
75
76#define BOUNDARY_ID_MIN_Z 0
77#define BOUNDARY_ID_MIN_Y 1
78#define BOUNDARY_ID_MAX_X 2
79#define BOUNDARY_ID_MAX_Y 3
80#define BOUNDARY_ID_MIN_X 4
81#define BOUNDARY_ID_MAX_Z 5
82
83using namespace libMesh;
84
85
86
89{
90private:
92
93public:
94
96 es(es_in)
97 {}
98
102 Real kronecker_delta(unsigned int i,
103 unsigned int j)
104 {
105 return i == j ? 1. : 0.;
106 }
107
112 Real poisson_ratio,
113 unsigned int i,
114 unsigned int j,
115 unsigned int k,
116 unsigned int l)
117 {
118 // Define the Lame constants
119 const Real lambda_1 = (young_modulus*poisson_ratio)/((1.+poisson_ratio)*(1.-2.*poisson_ratio));
120 const Real lambda_2 = young_modulus/(2.*(1.+poisson_ratio));
121
122 return lambda_1 * kronecker_delta(i,j) * kronecker_delta(k,l) +
123 lambda_2 * (kronecker_delta(i,k) * kronecker_delta(j,l) + kronecker_delta(i,l) * kronecker_delta(j,k));
124 }
125
126
130 virtual void jacobian (const NumericVector<Number> & soln,
132 NonlinearImplicitSystem & /*sys*/)
133 {
134 const Real young_modulus = es.parameters.get<Real>("young_modulus");
135 const Real poisson_ratio = es.parameters.get<Real>("poisson_ratio");
136
137 const MeshBase & mesh = es.get_mesh();
138 const unsigned int dim = mesh.mesh_dimension();
139
140 NonlinearImplicitSystem & system =
141 es.get_system<NonlinearImplicitSystem>("NonlinearElasticity");
142
143 const unsigned int u_var = system.variable_number ("u");
144
145 const DofMap & dof_map = system.get_dof_map();
146
147 FEType fe_type = dof_map.variable_type(u_var);
148 std::unique_ptr<FEBase> fe (FEBase::build(dim, fe_type));
149 QGauss qrule (dim, fe_type.default_quadrature_order());
150 fe->attach_quadrature_rule (&qrule);
151
152 std::unique_ptr<FEBase> fe_face (FEBase::build(dim, fe_type));
153 QGauss qface (dim-1, fe_type.default_quadrature_order());
154 fe_face->attach_quadrature_rule (&qface);
155
156 const std::vector<Real> & JxW = fe->get_JxW();
157 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
158
160 DenseSubMatrix<Number> Ke_var[3][3] =
161 {
165 };
166
167 std::vector<dof_id_type> dof_indices;
168 std::vector<std::vector<dof_id_type>> dof_indices_var(3);
169
170 jacobian.zero();
171
172 for (const auto & elem : mesh.active_local_element_ptr_range())
173 {
174 dof_map.dof_indices (elem, dof_indices);
175 for (unsigned int var=0; var<3; var++)
176 dof_map.dof_indices (elem, dof_indices_var[var], var);
177
178 const unsigned int n_dofs = dof_indices.size();
179 const unsigned int n_var_dofs = dof_indices_var[0].size();
180
181 fe->reinit (elem);
182
183 Ke.resize (n_dofs, n_dofs);
184 for (unsigned int var_i=0; var_i<3; var_i++)
185 for (unsigned int var_j=0; var_j<3; var_j++)
186 Ke_var[var_i][var_j].reposition (var_i*n_var_dofs, var_j*n_var_dofs, n_var_dofs, n_var_dofs);
187
188 for (unsigned int qp=0; qp<qrule.n_points(); qp++)
189 {
190 TensorValue<Number> grad_u;
191 for (unsigned int var_i=0; var_i<3; var_i++)
192 {
193 // Row is variable u1, u2, or u3, column is x, y, or z
194 for (unsigned int var_j=0; var_j<3; var_j++)
195 for (unsigned int j=0; j<n_var_dofs; j++)
196 grad_u(var_i,var_j) += dphi[j][qp](var_j)*soln(dof_indices_var[var_i][j]);
197 }
198
199 TensorValue<Number> strain_tensor;
200 for (unsigned int i=0; i<3; i++)
201 for (unsigned int j=0; j<3; j++)
202 {
203 strain_tensor(i,j) += 0.5 * (grad_u(i,j) + grad_u(j,i));
204
205 for (unsigned int k=0; k<3; k++)
206 strain_tensor(i,j) += 0.5 * grad_u(k,i)*grad_u(k,j);
207 }
208
209 // Define the deformation gradient
210 auto F = grad_u;
211 for (unsigned int var=0; var<3; var++)
212 F(var, var) += 1.;
213
214 TensorValue<Number> stress_tensor;
215
216 for (unsigned int i=0; i<3; i++)
217 for (unsigned int j=0; j<3; j++)
218 for (unsigned int k=0; k<3; k++)
219 for (unsigned int l=0; l<3; l++)
220 stress_tensor(i,j) +=
221 elasticity_tensor(young_modulus, poisson_ratio, i, j, k, l) * strain_tensor(k, l);
222
223 for (unsigned int dof_i=0; dof_i<n_var_dofs; dof_i++)
224 for (unsigned int dof_j=0; dof_j<n_var_dofs; dof_j++)
225 {
226 for (unsigned int i=0; i<3; i++)
227 for (unsigned int j=0; j<3; j++)
228 for (unsigned int m=0; m<3; m++)
229 Ke_var[i][i](dof_i,dof_j) += JxW[qp] *
230 (-dphi[dof_j][qp](m) * stress_tensor(m,j) * dphi[dof_i][qp](j));
231
232 for (unsigned int i=0; i<3; i++)
233 for (unsigned int j=0; j<3; j++)
234 for (unsigned int k=0; k<3; k++)
235 for (unsigned int l=0; l<3; l++)
236 {
237 Number FxC_ijkl = 0.;
238 for (unsigned int m=0; m<3; m++)
239 FxC_ijkl += F(i,m) * elasticity_tensor(young_modulus, poisson_ratio, m, j, k, l);
240
241 Ke_var[i][k](dof_i,dof_j) += JxW[qp] *
242 (-0.5 * FxC_ijkl * dphi[dof_j][qp](l) * dphi[dof_i][qp](j));
243
244 Ke_var[i][l](dof_i,dof_j) += JxW[qp] *
245 (-0.5 * FxC_ijkl * dphi[dof_j][qp](k) * dphi[dof_i][qp](j));
246
247 for (unsigned int n=0; n<3; n++)
248 Ke_var[i][n](dof_i,dof_j) += JxW[qp] *
249 (-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));
250 }
251 }
252 }
253
254 dof_map.constrain_element_matrix (Ke, dof_indices);
255 jacobian.add_matrix (Ke, dof_indices);
256 }
257 }
258
262 virtual void residual (const NumericVector<Number> & soln,
264 NonlinearImplicitSystem & /*sys*/)
265 {
266 const Real young_modulus = es.parameters.get<Real>("young_modulus");
267 const Real poisson_ratio = es.parameters.get<Real>("poisson_ratio");
268 const Real forcing_magnitude = es.parameters.get<Real>("forcing_magnitude");
269
270 const MeshBase & mesh = es.get_mesh();
271 const unsigned int dim = mesh.mesh_dimension();
272
273 NonlinearImplicitSystem & system =
274 es.get_system<NonlinearImplicitSystem>("NonlinearElasticity");
275
276 const unsigned int u_var = system.variable_number ("u");
277
278 const DofMap & dof_map = system.get_dof_map();
279
280 FEType fe_type = dof_map.variable_type(u_var);
281 std::unique_ptr<FEBase> fe (FEBase::build(dim, fe_type));
282 QGauss qrule (dim, fe_type.default_quadrature_order());
283 fe->attach_quadrature_rule (&qrule);
284
285 std::unique_ptr<FEBase> fe_face (FEBase::build(dim, fe_type));
286 QGauss qface (dim-1, fe_type.default_quadrature_order());
287 fe_face->attach_quadrature_rule (&qface);
288
289 const std::vector<Real> & JxW = fe->get_JxW();
290 const std::vector<std::vector<Real>> & phi = fe->get_phi();
291 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
292
294
295 DenseSubVector<Number> Re_var[3] =
299
300 std::vector<dof_id_type> dof_indices;
301 std::vector<std::vector<dof_id_type>> dof_indices_var(3);
302
303 residual.zero();
304
305 for (const auto & elem : mesh.active_local_element_ptr_range())
306 {
307 dof_map.dof_indices (elem, dof_indices);
308 for (unsigned int var=0; var<3; var++)
309 dof_map.dof_indices (elem, dof_indices_var[var], var);
310
311 const unsigned int n_dofs = dof_indices.size();
312 const unsigned int n_var_dofs = dof_indices_var[0].size();
313
314 fe->reinit (elem);
315
316 Re.resize (n_dofs);
317 for (unsigned int var=0; var<3; var++)
318 Re_var[var].reposition (var*n_var_dofs, n_var_dofs);
319
320 for (unsigned int qp=0; qp<qrule.n_points(); qp++)
321 {
322 TensorValue<Number> grad_u;
323 for (unsigned int var_i=0; var_i<3; var_i++)
324 {
325 // Row is variable u, v, or w column is x, y, or z
326 for (unsigned int var_j=0; var_j<3; var_j++)
327 for (unsigned int j=0; j<n_var_dofs; j++)
328 grad_u(var_i,var_j) += dphi[j][qp](var_j)*soln(dof_indices_var[var_i][j]);
329 }
330
331 TensorValue<Number> strain_tensor;
332 for (unsigned int i=0; i<3; i++)
333 for (unsigned int j=0; j<3; j++)
334 {
335 strain_tensor(i,j) += 0.5 * (grad_u(i,j) + grad_u(j,i));
336
337 for (unsigned int k=0; k<3; k++)
338 strain_tensor(i,j) += 0.5 * grad_u(k,i)*grad_u(k,j);
339 }
340
341 // Define the deformation gradient
342 auto F = grad_u;
343 for (unsigned int var=0; var<3; var++)
344 F(var, var) += 1.;
345
346 TensorValue<Number> stress_tensor;
347
348 for (unsigned int i=0; i<3; i++)
349 for (unsigned int j=0; j<3; j++)
350 for (unsigned int k=0; k<3; k++)
351 for (unsigned int l=0; l<3; l++)
352 stress_tensor(i,j) +=
353 elasticity_tensor(young_modulus, poisson_ratio, i, j, k, l) * strain_tensor(k,l);
354
355 VectorValue<Number> f_vec(0., 0., -forcing_magnitude);
356
357 for (unsigned int dof_i=0; dof_i<n_var_dofs; dof_i++)
358 for (unsigned int i=0; i<3; i++)
359 {
360 for (unsigned int j=0; j<3; j++)
361 {
362 Number FxStress_ij = 0.;
363 for (unsigned int m=0; m<3; m++)
364 FxStress_ij += F(i,m) * stress_tensor(m,j);
365
366 Re_var[i](dof_i) += JxW[qp] * (-FxStress_ij * dphi[dof_i][qp](j));
367 }
368
369 Re_var[i](dof_i) += JxW[qp] * (f_vec(i) * phi[dof_i][qp]);
370 }
371 }
372
373 dof_map.constrain_element_vector (Re, dof_indices);
374 residual.add_vector (Re, dof_indices);
375 }
376 }
377
382 {
383 const Real young_modulus = es.parameters.get<Real>("young_modulus");
384 const Real poisson_ratio = es.parameters.get<Real>("poisson_ratio");
385
386 const MeshBase & mesh = es.get_mesh();
387 const unsigned int dim = mesh.mesh_dimension();
388
389 NonlinearImplicitSystem & system =
390 es.get_system<NonlinearImplicitSystem>("NonlinearElasticity");
391
392 unsigned int displacement_vars[] = {
393 system.variable_number ("u"),
394 system.variable_number ("v"),
395 system.variable_number ("w")};
396 const unsigned int u_var = system.variable_number ("u");
397
398 const DofMap & dof_map = system.get_dof_map();
399 FEType fe_type = dof_map.variable_type(u_var);
400 std::unique_ptr<FEBase> fe (FEBase::build(dim, fe_type));
401 QGauss qrule (dim, fe_type.default_quadrature_order());
402 fe->attach_quadrature_rule (&qrule);
403
404 const std::vector<Real> & JxW = fe->get_JxW();
405 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
406
407 // Also, get a reference to the ExplicitSystem
408 ExplicitSystem & stress_system = es.get_system<ExplicitSystem>("StressSystem");
409 const DofMap & stress_dof_map = stress_system.get_dof_map();
410 unsigned int sigma_vars[] = {
411 stress_system.variable_number ("sigma_00"),
412 stress_system.variable_number ("sigma_01"),
413 stress_system.variable_number ("sigma_02"),
414 stress_system.variable_number ("sigma_11"),
415 stress_system.variable_number ("sigma_12"),
416 stress_system.variable_number ("sigma_22")};
417
418 // Storage for the stress dof indices on each element
419 std::vector<std::vector<dof_id_type>> dof_indices_var(system.n_vars());
420 std::vector<dof_id_type> stress_dof_indices_var;
421
422 // To store the stress tensor on each element
423 TensorValue<Number> elem_avg_stress_tensor;
424
425 for (const auto & elem : mesh.active_local_element_ptr_range())
426 {
427 for (unsigned int var=0; var<3; var++)
428 dof_map.dof_indices (elem, dof_indices_var[var], displacement_vars[var]);
429
430 const unsigned int n_var_dofs = dof_indices_var[0].size();
431
432 fe->reinit (elem);
433
434 // clear the stress tensor
435 elem_avg_stress_tensor.zero();
436
437 for (unsigned int qp=0; qp<qrule.n_points(); qp++)
438 {
439 TensorValue<Number> grad_u;
440 // Row is variable u1, u2, or u3, column is x, y, or z
441 for (unsigned int var_i=0; var_i<3; var_i++)
442 for (unsigned int var_j=0; var_j<3; var_j++)
443 for (unsigned int j=0; j<n_var_dofs; j++)
444 grad_u(var_i,var_j) += dphi[j][qp](var_j) * system.current_solution(dof_indices_var[var_i][j]);
445
446 TensorValue<Number> strain_tensor;
447 for (unsigned int i=0; i<3; i++)
448 for (unsigned int j=0; j<3; j++)
449 {
450 strain_tensor(i,j) += 0.5 * (grad_u(i,j) + grad_u(j,i));
451
452 for (unsigned int k=0; k<3; k++)
453 strain_tensor(i,j) += 0.5 * grad_u(k,i)*grad_u(k,j);
454 }
455
456 // Define the deformation gradient
457 auto F = grad_u;
458 for (unsigned int var=0; var<3; var++)
459 F(var, var) += 1.;
460
461 TensorValue<Number> stress_tensor;
462 for (unsigned int i=0; i<3; i++)
463 for (unsigned int j=0; j<3; j++)
464 for (unsigned int k=0; k<3; k++)
465 for (unsigned int l=0; l<3; l++)
466 stress_tensor(i,j) +=
467 elasticity_tensor(young_modulus, poisson_ratio, i, j, k, l) * strain_tensor(k, l);
468
469 // stress_tensor now holds the second Piola-Kirchoff stress (PK2) at point qp.
470 // However, in this example we want to compute the Cauchy stress which is given by
471 // 1/det(F) * F * PK2 * F^T, hence we now apply this transformation.
472 stress_tensor = 1. / F.det() * F * stress_tensor * F.transpose();
473
474 // We want to plot the average Cauchy stress on each element, hence
475 // we integrate stress_tensor
476 elem_avg_stress_tensor.add_scaled(stress_tensor, JxW[qp]);
477 }
478
479 // Get the average stress per element by dividing by volume
480 elem_avg_stress_tensor /= elem->volume();
481
482 // load elem_sigma data into stress_system
483 unsigned int stress_var_index = 0;
484 for (unsigned int i=0; i<3; i++)
485 for (unsigned int j=i; j<3; j++)
486 {
487 stress_dof_map.dof_indices (elem, stress_dof_indices_var, sigma_vars[stress_var_index]);
488
489 // We are using CONSTANT MONOMIAL basis functions, hence we only need to get
490 // one dof index per variable
491 dof_id_type dof_index = stress_dof_indices_var[0];
492
493 if ((stress_system.solution->first_local_index() <= dof_index) &&
494 (dof_index < stress_system.solution->last_local_index()))
495 stress_system.solution->set(dof_index, elem_avg_stress_tensor(i,j));
496
497 stress_var_index++;
498 }
499 }
500
501 // Should call close and update when we set vector entries directly
502 stress_system.solution->close();
503 stress_system.update();
504 }
505
506};
507
508
509int main (int argc, char ** argv)
510{
511 LibMeshInit init (argc, argv);
512
513 // This example requires the PETSc nonlinear solvers
514 libmesh_example_requires(libMesh::default_solver_package() == PETSC_SOLVERS, "--enable-petsc");
515
516 // We use a 3D domain.
517 libmesh_example_requires(LIBMESH_DIM > 2, "--disable-1D-only --disable-2D-only");
518
519 // We use Dirichlet boundary conditions here
520#ifndef LIBMESH_ENABLE_DIRICHLET
521 libmesh_example_requires(false, "--enable-dirichlet");
522#endif
523
524 GetPot infile("systems_of_equations_ex7.in");
525
526 infile.parse_command_line(argc,argv);
527
528 const Real x_length = infile("x_length", 0.);
529 const Real y_length = infile("y_length", 0.);
530 const Real z_length = infile("z_length", 0.);
531 const int n_elem_x = infile("n_elem_x", 0);
532 const int n_elem_y = infile("n_elem_y", 0);
533 const int n_elem_z = infile("n_elem_z", 0);
534 const std::string approx_order = infile("approx_order", "FIRST");
535 const std::string fe_family = infile("fe_family", "LAGRANGE");
536
537 const Real young_modulus = infile("Young_modulus", 1.0);
538 const Real poisson_ratio = infile("poisson_ratio", 0.3);
539 const Real forcing_magnitude = infile("forcing_magnitude", 0.001);
540
541 const Real nonlinear_abs_tol = infile("nonlinear_abs_tol", 1.e-8);
542 const Real nonlinear_rel_tol = infile("nonlinear_rel_tol", 1.e-8);
543 const unsigned int nonlinear_max_its = infile("nonlinear_max_its", 50);
544
545 const unsigned int n_solves = infile("n_solves", 10);
546 const Real force_scaling = infile("force_scaling", 5.0);
547
548 Mesh mesh(init.comm());
549
551 n_elem_x,
552 n_elem_y,
553 n_elem_z,
554 0., x_length,
555 0., y_length,
556 0., z_length,
557 HEX27);
558
560
561 EquationSystems equation_systems (mesh);
562 LargeDeformationElasticity lde(equation_systems);
563
564 NonlinearImplicitSystem & system =
565 equation_systems.add_system<NonlinearImplicitSystem> ("NonlinearElasticity");
567
568 unsigned int u_var =
569 system.add_variable("u",
570 Utility::string_to_enum<Order> (approx_order),
571 Utility::string_to_enum<FEFamily>(fe_family));
572
573 unsigned int v_var =
574 system.add_variable("v",
575 Utility::string_to_enum<Order> (approx_order),
576 Utility::string_to_enum<FEFamily>(fe_family));
577
578 unsigned int w_var =
579 system.add_variable("w",
580 Utility::string_to_enum<Order> (approx_order),
581 Utility::string_to_enum<FEFamily>(fe_family));
582
583 // Also, initialize an ExplicitSystem to store stresses
584 ExplicitSystem & stress_system =
585 equation_systems.add_system<ExplicitSystem> ("StressSystem");
586 stress_system.add_variable("sigma_00", CONSTANT, MONOMIAL);
587 stress_system.add_variable("sigma_01", CONSTANT, MONOMIAL);
588 stress_system.add_variable("sigma_02", CONSTANT, MONOMIAL);
589 stress_system.add_variable("sigma_11", CONSTANT, MONOMIAL);
590 stress_system.add_variable("sigma_12", CONSTANT, MONOMIAL);
591 stress_system.add_variable("sigma_22", CONSTANT, MONOMIAL);
592
593 equation_systems.parameters.set<Real> ("nonlinear solver absolute residual tolerance") = nonlinear_abs_tol;
594 equation_systems.parameters.set<Real> ("nonlinear solver relative residual tolerance") = nonlinear_rel_tol;
595 equation_systems.parameters.set<unsigned int> ("nonlinear solver maximum iterations") = nonlinear_max_its;
596
597 system.nonlinear_solver->residual_object = &lde;
598 system.nonlinear_solver->jacobian_object = &lde;
599
600 equation_systems.parameters.set<Real>("young_modulus") = young_modulus;
601 equation_systems.parameters.set<Real>("poisson_ratio") = poisson_ratio;
602 equation_systems.parameters.set<Real>("forcing_magnitude") = forcing_magnitude;
603
604#ifdef LIBMESH_ENABLE_DIRICHLET
605 // Attach Dirichlet (Clamped) boundary conditions
607
608 // Most DirichletBoundary users will want to supply a "locally
609 // indexed" functor
611 (DirichletBoundary ({BOUNDARY_ID_MIN_X}, {u_var, v_var, w_var},
613#endif // LIBMESH_ENABLE_DIRICHLET
614 libmesh_ignore(u_var, v_var, w_var);
615
616 equation_systems.init();
617 equation_systems.print_info();
618
619 // Provide a loop here so that we can do a sequence of solves
620 // where solve n gives a good starting guess for solve n+1.
621 // This "continuation" approach is helpful for solving for
622 // large values of "forcing_magnitude".
623 // Set n_solves and force_scaling in nonlinear_elasticity.in.
624 for (unsigned int count=0; count<n_solves; count++)
625 {
626 Real previous_forcing_magnitude = equation_systems.parameters.get<Real>("forcing_magnitude");
627 equation_systems.parameters.set<Real>("forcing_magnitude") = previous_forcing_magnitude*force_scaling;
628
629 libMesh::out << "Performing solve "
630 << count
631 << ", forcing_magnitude: "
632 << equation_systems.parameters.get<Real>("forcing_magnitude")
633 << std::endl;
634
635 system.solve();
636
637 libMesh::out << "System solved at nonlinear iteration "
638 << system.n_nonlinear_iterations()
639 << " , final nonlinear residual norm: "
640 << system.final_nonlinear_residual()
641 << std::endl
642 << std::endl;
643
644 libMesh::out << "Computing stresses..." << std::endl;
645
646 lde.compute_stresses();
647
648#ifdef LIBMESH_HAVE_EXODUS_API
649 std::stringstream filename;
650 filename << "solution_" << count << ".exo";
651 ExodusII_IO (mesh).write_equation_systems(filename.str(), equation_systems);
652#endif
653 }
654
655 return 0;
656}
unsigned int dim
virtual void residual(const NumericVector< Number > &soln, NumericVector< Number > &residual, NonlinearImplicitSystem &)
Evaluate the residual of the nonlinear system.
LargeDeformationElasticity(EquationSystems &es_in)
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.
virtual void jacobian(const NumericVector< Number > &soln, SparseMatrix< Number > &jacobian, NonlinearImplicitSystem &)
Evaluate the Jacobian of the nonlinear system.
void compute_stresses()
Compute the Cauchy stress for the current solution.
Real kronecker_delta(unsigned int i, unsigned int j)
Kronecker delta function.
Defines a dense matrix for use in Finite Element-type computations.
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
Defines a dense submatrix for use in Finite Element-type computations.
Defines a dense subvector for use in finite element computations.
Defines a dense vector for use in Finite Element-type computations.
void resize(const unsigned int n)
Resize the vector.
This class allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
This class handles the numbering of degrees of freedom on a mesh.
Definition dof_map.h:181
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition dof_map.C:2201
void add_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary)
Adds a copy of the specified Dirichlet boundary to the system.
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:2485
const FEType & variable_type(const unsigned int i) const
Definition dof_map.h:2388
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:2494
This is the EquationSystems class.
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
const MeshBase & get_mesh() const
Parameters parameters
Data structure holding arbitrary parameters.
virtual void init()
Initialize all the systems.
virtual System & add_system(std::string_view system_type, std::string_view name)
Add the system of type system_type named name to the systems array.
const T_sys & get_system(std::string_view name) const
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition exodusII_io.h:53
virtual void write_equation_systems(const std::string &fname, const EquationSystems &es, const std::set< std::string > *system_names=nullptr) override
Writes out the solution for no specific time or timestep.
Manages consistently variables, degrees of freedom, and coefficient vectors for explicit systems.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition fe_type.h:197
Order default_quadrature_order() const
Definition fe_type.h:415
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition libmesh.h:92
This is the MeshBase class.
Definition mesh_base.h:81
unsigned int mesh_dimension() const
Definition mesh_base.C:430
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh.
Definition mesh_base.C:1755
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition mesh.h:51
Abstract base class to be used to calculate the Jacobian of a nonlinear system.
Abstract base class to be used to calculate the residual of a nonlinear system.
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
virtual void solve() override
Assembles & solves the nonlinear system R(x) = 0.
std::unique_ptr< NonlinearSolver< Number > > nonlinear_solver
The NonlinearSolver defines the default interface used to solve the nonlinear_implicit system.
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
T & set(const std::string &)
Definition parameters.h:494
const T & get(std::string_view) const
Definition parameters.h:451
unsigned int n_points() const
Definition quadrature.h:131
This class implements specific orders of Gauss quadrature.
Generic sparse matrix.
Number current_solution(const dof_id_type global_dof_number) const
Definition system.C:162
unsigned int add_variable(std::string_view 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:1344
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition system.h:1655
void prefer_hash_table_matrix_assembly(bool preference)
Sets whether to use hash table matrix assembly if the matrix sub-classes support it.
Definition system.h:2667
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition system.C:498
unsigned int variable_number(std::string_view var) const
Definition system.C:1398
unsigned int n_vars() const
Definition system.C:2674
const DofMap & get_dof_map() const
Definition system.h:2417
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
void add_scaled(const TypeTensor< T2 > &, const T &)
Add a scaled tensor to this tensor without creating a temporary.
void zero()
Set all entries of the tensor to 0.
TypeTensor< T > transpose() const
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
ConstFunction that simply returns 0.
MeshBase & mesh
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.
The libMesh namespace provides an interface to certain functionality in the library.
void libmesh_ignore(const Args &...)
SolverPackage default_solver_package()
Definition libmesh.C:1064
OStreamProxy out
const Number zero
.
Definition libmesh.h:297
uint8_t dof_id_type
Definition id_types.h:67
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
int main()