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" 73 #include "libmesh/nonlinear_solver.h" 74 #include "libmesh/nonlinear_implicit_system.h" 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 105 return i == j ? 1. : 0.;
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));
150 fe->attach_quadrature_rule (&qrule);
154 fe_face->attach_quadrature_rule (&qface);
156 const std::vector<Real> & JxW = fe->get_JxW();
157 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
167 std::vector<dof_id_type> dof_indices;
168 std::vector<std::vector<dof_id_type>> dof_indices_var(3);
172 for (
const auto & elem :
mesh.active_local_element_ptr_range())
175 for (
unsigned int var=0; var<3; var++)
176 dof_map.
dof_indices (elem, dof_indices_var[var], var);
178 const unsigned int n_dofs = dof_indices.size();
179 const unsigned int n_var_dofs = dof_indices_var[0].size();
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);
188 for (
unsigned int qp=0; qp<qrule.n_points(); qp++)
191 for (
unsigned int var_i=0; var_i<3; var_i++)
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]);
200 for (
unsigned int i=0; i<3; i++)
201 for (
unsigned int j=0; j<3; j++)
203 strain_tensor(i,j) += 0.5 * (grad_u(i,j) + grad_u(j,i));
205 for (
unsigned int k=0; k<3; k++)
206 strain_tensor(i,j) += 0.5 * grad_u(k,i)*grad_u(k,j);
211 for (
unsigned int var=0; var<3; var++)
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);
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++)
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));
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++)
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);
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));
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));
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));
283 fe->attach_quadrature_rule (&qrule);
287 fe_face->attach_quadrature_rule (&qface);
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();
300 std::vector<dof_id_type> dof_indices;
301 std::vector<std::vector<dof_id_type>> dof_indices_var(3);
305 for (
const auto & elem :
mesh.active_local_element_ptr_range())
308 for (
unsigned int var=0; var<3; var++)
309 dof_map.
dof_indices (elem, dof_indices_var[var], var);
311 const unsigned int n_dofs = dof_indices.size();
312 const unsigned int n_var_dofs = dof_indices_var[0].size();
317 for (
unsigned int var=0; var<3; var++)
318 Re_var[var].reposition (var*n_var_dofs, n_var_dofs);
320 for (
unsigned int qp=0; qp<qrule.n_points(); qp++)
323 for (
unsigned int var_i=0; var_i<3; var_i++)
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]);
332 for (
unsigned int i=0; i<3; i++)
333 for (
unsigned int j=0; j<3; j++)
335 strain_tensor(i,j) += 0.5 * (grad_u(i,j) + grad_u(j,i));
337 for (
unsigned int k=0; k<3; k++)
338 strain_tensor(i,j) += 0.5 * grad_u(k,i)*grad_u(k,j);
343 for (
unsigned int var=0; var<3; var++)
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);
357 for (
unsigned int dof_i=0; dof_i<n_var_dofs; dof_i++)
358 for (
unsigned int i=0; i<3; i++)
360 for (
unsigned int j=0; j<3; j++)
363 for (
unsigned int m=0; m<3; m++)
364 FxStress_ij += F(i,m) * stress_tensor(m,j);
366 Re_var[i](dof_i) += JxW[qp] * (-FxStress_ij * dphi[dof_i][qp](j));
369 Re_var[i](dof_i) += JxW[qp] * (f_vec(i) * phi[dof_i][qp]);
392 unsigned int displacement_vars[] = {
402 fe->attach_quadrature_rule (&qrule);
404 const std::vector<Real> & JxW = fe->get_JxW();
405 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
410 unsigned int sigma_vars[] = {
419 std::vector<std::vector<dof_id_type>> dof_indices_var(system.
n_vars());
420 std::vector<dof_id_type> stress_dof_indices_var;
425 for (
const auto & elem :
mesh.active_local_element_ptr_range())
427 for (
unsigned int var=0; var<3; var++)
428 dof_map.
dof_indices (elem, dof_indices_var[var], displacement_vars[var]);
430 const unsigned int n_var_dofs = dof_indices_var[0].size();
435 elem_avg_stress_tensor.
zero();
437 for (
unsigned int qp=0; qp<qrule.n_points(); qp++)
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]);
447 for (
unsigned int i=0; i<3; i++)
448 for (
unsigned int j=0; j<3; j++)
450 strain_tensor(i,j) += 0.5 * (grad_u(i,j) + grad_u(j,i));
452 for (
unsigned int k=0; k<3; k++)
453 strain_tensor(i,j) += 0.5 * grad_u(k,i)*grad_u(k,j);
458 for (
unsigned int var=0; var<3; var++)
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);
472 stress_tensor = 1. / F.
det() * F * stress_tensor * F.
transpose();
476 elem_avg_stress_tensor.
add_scaled(stress_tensor, JxW[qp]);
480 elem_avg_stress_tensor /= elem->volume();
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++)
487 stress_dof_map.dof_indices (elem, stress_dof_indices_var, sigma_vars[stress_var_index]);
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));
509 int main (
int argc,
char ** argv)
517 libmesh_example_requires(LIBMESH_DIM > 2,
"--disable-1D-only --disable-2D-only");
520 #ifndef LIBMESH_ENABLE_DIRICHLET 521 libmesh_example_requires(
false,
"--enable-dirichlet");
524 GetPot infile(
"systems_of_equations_ex7.in");
526 infile.parse_command_line(argc,argv);
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");
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);
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);
545 const unsigned int n_solves = infile(
"n_solves", 10);
546 const Real force_scaling = infile(
"force_scaling", 5.0);
570 Utility::string_to_enum<Order> (approx_order),
571 Utility::string_to_enum<FEFamily>(fe_family));
575 Utility::string_to_enum<Order> (approx_order),
576 Utility::string_to_enum<FEFamily>(fe_family));
580 Utility::string_to_enum<Order> (approx_order),
581 Utility::string_to_enum<FEFamily>(fe_family));
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;
604 #ifdef LIBMESH_ENABLE_DIRICHLET 613 #endif // LIBMESH_ENABLE_DIRICHLET 616 equation_systems.
init();
624 for (
unsigned int count=0; count<n_solves; count++)
627 equation_systems.
parameters.
set<
Real>(
"forcing_magnitude") = previous_forcing_magnitude*force_scaling;
631 <<
", forcing_magnitude: " 639 <<
" , final nonlinear residual norm: " 648 #ifdef LIBMESH_HAVE_EXODUS_API 649 std::stringstream filename;
650 filename <<
"solution_" << count <<
".exo";
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
This is the EquationSystems class.
std::unique_ptr< NonlinearSolver< Number > > nonlinear_solver
The NonlinearSolver defines the default interface used to solve the nonlinear_implicit system...
Real elasticity_tensor(unsigned int i, unsigned int j, unsigned int k, unsigned int l)
ConstFunction that simply returns 0.
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Real kronecker_delta(unsigned int i, unsigned int j)
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
TypeTensor< T > transpose() const
void resize(const unsigned int n)
Resize the 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]...
void zero()
Set all entries of the tensor to 0.
const FEType & variable_type(const unsigned int c) const
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
This class allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
Order default_quadrature_order() const
unsigned int n_nonlinear_iterations() const
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
The libMesh namespace provides an interface to certain functionality in the library.
const T_sys & get_system(std::string_view name) const
This is the MeshBase class.
virtual void zero()=0
Set all entries to zero.
Number current_solution(const dof_id_type global_dof_number) const
unsigned int variable_number(std::string_view var) const
Defines a dense subvector for use in finite element computations.
SolverPackage default_solver_package()
This class handles the numbering of degrees of freedom on a mesh.
Abstract base class to be used to calculate the residual of a nonlinear system.
void libmesh_ignore(const Args &...)
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.
const T & get(std::string_view) const
Real final_nonlinear_residual() const
virtual void zero()=0
Set all entries to 0.
Abstract base class to be used to calculate the Jacobian of a nonlinear system.
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.
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh.
int main(int argc, char **argv)
Defines a dense submatrix for use in Finite Element-type computations.
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
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.
void add_scaled(const TypeTensor< T2 > &, const T &)
Add a scaled tensor to this tensor without creating a temporary.
void prefer_hash_table_matrix_assembly(bool preference)
Sets whether to use hash table matrix assembly if the matrix sub-classes support it.
virtual void solve() override
Assembles & solves the nonlinear system R(x) = 0.
virtual void update()
Update the local values to reflect the solution on neighboring processors.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void constrain_element_vector(DenseVector< Number > &rhs, std::vector< dof_id_type > &dofs, bool asymmetric_constraint_rows=true) const
Constrains the element vector.
T & set(const std::string &)
const MeshBase & get_mesh() const
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
This class implements specific orders of Gauss quadrature.
unsigned int mesh_dimension() const
Parameters parameters
Data structure holding arbitrary parameters.
void add_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary)
Adds a copy of the specified Dirichlet boundary to the system.
virtual void init()
Initialize all the systems.
unsigned int n_vars() const
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.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
const DofMap & get_dof_map() const
Manages consistently variables, degrees of freedom, and coefficient vectors for explicit systems...
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
void constrain_element_matrix(DenseMatrix< Number > &matrix, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
Constrains the element matrix.