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"
71 #include "libmesh/nonlinear_solver.h"
72 #include "libmesh/nonlinear_implicit_system.h"
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
103 return i == j ? 1. : 0.;
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));
148 fe->attach_quadrature_rule (&qrule);
152 fe_face->attach_quadrature_rule (&qface);
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();
166 std::vector<dof_id_type> dof_indices;
167 std::vector<std::vector<dof_id_type>> dof_indices_var(3);
174 for (
unsigned int var=0; var<3; var++)
175 dof_map.
dof_indices (elem, dof_indices_var[var], var);
177 const unsigned int n_dofs = dof_indices.size();
178 const unsigned int n_var_dofs = dof_indices_var[0].size();
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);
187 for (
unsigned int qp=0; qp<qrule.n_points(); qp++)
191 for (
unsigned int var_i=0; var_i<3; var_i++)
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]);
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]);
203 for (
unsigned int i=0; i<3; i++)
204 for (
unsigned int j=0; j<3; j++)
206 strain_tensor(i,j) += 0.5 * (grad_u(i,j) + grad_u(j,i));
208 for (
unsigned int k=0; k<3; k++)
209 strain_tensor(i,j) += 0.5 * grad_u(k,i)*grad_u(k,j);
215 for (
unsigned int var=0; var<3; var++)
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);
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++)
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));
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++)
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);
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));
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));
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));
287 fe->attach_quadrature_rule (&qrule);
291 fe_face->attach_quadrature_rule (&qface);
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();
304 std::vector<dof_id_type> dof_indices;
305 std::vector<std::vector<dof_id_type>> dof_indices_var(3);
312 for (
unsigned int var=0; var<3; var++)
313 dof_map.
dof_indices (elem, dof_indices_var[var], var);
315 const unsigned int n_dofs = dof_indices.size();
316 const unsigned int n_var_dofs = dof_indices_var[0].size();
321 for (
unsigned int var=0; var<3; var++)
322 Re_var[var].reposition (var*n_var_dofs, n_var_dofs);
324 for (
unsigned int qp=0; qp<qrule.n_points(); qp++)
328 for (
unsigned int var_i=0; var_i<3; var_i++)
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]);
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]);
340 for (
unsigned int i=0; i<3; i++)
341 for (
unsigned int j=0; j<3; j++)
343 strain_tensor(i,j) += 0.5 * (grad_u(i,j) + grad_u(j,i));
345 for (
unsigned int k=0; k<3; k++)
346 strain_tensor(i,j) += 0.5 * grad_u(k,i)*grad_u(k,j);
352 for (
unsigned int var=0; var<3; var++)
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);
367 f_vec(2) = -forcing_magnitude;
369 for (
unsigned int dof_i=0; dof_i<n_var_dofs; dof_i++)
370 for (
unsigned int i=0; i<3; i++)
372 for (
unsigned int j=0; j<3; j++)
375 for (
unsigned int m=0; m<3; m++)
376 FxStress_ij += F(i,m) * stress_tensor(m,j);
378 Re_var[i](dof_i) += JxW[qp] * (-FxStress_ij * dphi[dof_i][qp](j));
381 Re_var[i](dof_i) += JxW[qp] * (f_vec(i) * phi[dof_i][qp]);
404 unsigned int displacement_vars[3];
414 fe->attach_quadrature_rule (&qrule);
416 const std::vector<Real> & JxW = fe->get_JxW();
417 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
422 unsigned int sigma_vars[6];
431 std::vector<std::vector<dof_id_type>> dof_indices_var(system.
n_vars());
432 std::vector<dof_id_type> stress_dof_indices_var;
439 for (
unsigned int var=0; var<3; var++)
440 dof_map.
dof_indices (elem, dof_indices_var[var], displacement_vars[var]);
442 const unsigned int n_var_dofs = dof_indices_var[0].size();
447 elem_avg_stress_tensor.
resize(3, 3);
449 for (
unsigned int qp=0; qp<qrule.n_points(); qp++)
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]);
459 for (
unsigned int i=0; i<3; i++)
460 for (
unsigned int j=0; j<3; j++)
462 strain_tensor(i,j) += 0.5 * (grad_u(i,j) + grad_u(j,i));
464 for (
unsigned int k=0; k<3; k++)
465 strain_tensor(i,j) += 0.5 * grad_u(k,i)*grad_u(k,j);
471 for (
unsigned int var=0; var<3; var++)
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);
491 elem_avg_stress_tensor.
add(JxW[qp], stress_tensor);
495 elem_avg_stress_tensor.
scale(1./elem->volume());
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++)
502 stress_dof_map.dof_indices (elem, stress_dof_indices_var, sigma_vars[stress_var_index]);
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));
524 int main (
int argc,
char ** argv)
532 libmesh_example_requires(LIBMESH_DIM > 2,
"--disable-1D-only --disable-2D-only");
535 #ifndef LIBMESH_ENABLE_DIRICHLET
536 libmesh_example_requires(
false,
"--enable-dirichlet");
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");
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);
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);
557 const unsigned int n_solves = infile(
"n_solves", 10);
558 const Real force_scaling = infile(
"force_scaling", 5.0);
581 Utility::string_to_enum<Order> (approx_order),
582 Utility::string_to_enum<FEFamily>(fe_family));
586 Utility::string_to_enum<Order> (approx_order),
587 Utility::string_to_enum<FEFamily>(fe_family));
591 Utility::string_to_enum<Order> (approx_order),
592 Utility::string_to_enum<FEFamily>(fe_family));
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;
615 #ifdef LIBMESH_ENABLE_DIRICHLET
617 std::set<boundary_id_type> clamped_boundaries;
618 clamped_boundaries.insert(BOUNDARY_ID_MIN_X);
620 std::vector<unsigned int> uvw;
621 uvw.push_back(u_var);
622 uvw.push_back(v_var);
623 uvw.push_back(w_var);
634 #endif // LIBMESH_ENABLE_DIRICHLET
636 equation_systems.
init();
644 for (
unsigned int count=0; count<n_solves; count++)
647 equation_systems.
parameters.
set<
Real>(
"forcing_magnitude") = previous_forcing_magnitude*force_scaling;
651 <<
", forcing_magnitude: "
659 <<
" , final nonlinear residual norm: "
668 #ifdef LIBMESH_HAVE_EXODUS_API
669 std::stringstream filename;
670 filename <<
"solution_" << count <<
".exo";