42 #include "libmesh/libmesh_config.h" 43 #include "libmesh/libmesh.h" 44 #include "libmesh/mesh.h" 45 #include "libmesh/mesh_generation.h" 46 #include "libmesh/exodusII_io.h" 47 #include "libmesh/gnuplot_io.h" 48 #include "libmesh/linear_implicit_system.h" 49 #include "libmesh/equation_systems.h" 50 #include "libmesh/fe.h" 51 #include "libmesh/quadrature_gauss.h" 52 #include "libmesh/dof_map.h" 53 #include "libmesh/sparse_matrix.h" 54 #include "libmesh/numeric_vector.h" 55 #include "libmesh/dense_matrix.h" 56 #include "libmesh/dense_submatrix.h" 57 #include "libmesh/dense_vector.h" 58 #include "libmesh/dense_subvector.h" 59 #include "libmesh/perf_log.h" 60 #include "libmesh/elem.h" 61 #include "libmesh/boundary_info.h" 62 #include "libmesh/zero_function.h" 63 #include "libmesh/dirichlet_boundaries.h" 64 #include "libmesh/string_to_enum.h" 65 #include "libmesh/getpot.h" 66 #include "libmesh/solver_configuration.h" 67 #include "libmesh/petsc_linear_solver.h" 68 #include "libmesh/petsc_macro.h" 69 #include "libmesh/enum_solver_package.h" 70 #include "libmesh/tensor_value.h" 71 #include "libmesh/vector_value.h" 72 #include "libmesh/utility.h" 77 #define BOUNDARY_ID_MIN_Z 0 78 #define BOUNDARY_ID_MIN_Y 1 79 #define BOUNDARY_ID_MAX_X 2 80 #define BOUNDARY_ID_MAX_Y 3 81 #define BOUNDARY_ID_MIN_X 4 82 #define BOUNDARY_ID_MAX_Z 5 83 #define NODE_BOUNDARY_ID 10 84 #define EDGE_BOUNDARY_ID 20 89 #ifdef LIBMESH_HAVE_PETSC 97 _petsc_linear_solver(petsc_linear_solver)
103 LibmeshPetscCall2(_petsc_linear_solver.comm(), KSPSetType(_petsc_linear_solver.ksp(),
const_cast<KSPType
>(KSPCG)));
104 LibmeshPetscCall2(_petsc_linear_solver.comm(), PCSetType(_petsc_linear_solver.pc(),
const_cast<PCType
>(PCBJACOBI)));
130 return i == j ? 1. : 0.;
142 const Real poisson_ratio = 0.3;
143 const Real young_modulus = 1.;
146 const Real lambda_1 = (young_modulus*poisson_ratio)/((1.+poisson_ratio)*(1.-2.*poisson_ratio));
147 const Real lambda_2 = young_modulus/(2.*(1.+poisson_ratio));
170 fe->attach_quadrature_rule (&qrule);
174 fe_face->attach_quadrature_rule (&qface);
176 const std::vector<Real> & JxW = fe->get_JxW();
177 const std::vector<std::vector<Real>> & phi = fe->get_phi();
178 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
195 std::vector<dof_id_type> dof_indices;
196 std::vector<std::vector<dof_id_type>> dof_indices_var(3);
200 for (
const auto & elem :
mesh.active_local_element_ptr_range())
203 for (
unsigned int var=0; var<3; var++)
204 dof_map.
dof_indices (elem, dof_indices_var[var], var);
206 const unsigned int n_dofs = dof_indices.size();
207 const unsigned int n_var_dofs = dof_indices_var[0].size();
211 Ke.
resize (n_dofs, n_dofs);
212 for (
unsigned int var_i=0; var_i<3; var_i++)
213 for (
unsigned int var_j=0; var_j<3; var_j++)
214 Ke_var[var_i][var_j].reposition (var_i*n_var_dofs, var_j*n_var_dofs, n_var_dofs, n_var_dofs);
217 for (
unsigned int var=0; var<3; var++)
218 Fe_var[var].reposition (var*n_var_dofs, n_var_dofs);
220 for (
unsigned int qp=0; qp<qrule.n_points(); qp++)
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 for (
unsigned int i=0; i<3; i++)
226 for (
unsigned int j=0; j<3; j++)
227 for (
unsigned int k=0; k<3; k++)
228 for (
unsigned int l=0; l<3; l++)
229 Ke_var[i][k](dof_i,dof_j) +=
234 for (
unsigned int dof_i=0; dof_i<n_var_dofs; dof_i++)
235 for (
unsigned int i=0; i<3; i++)
236 Fe_var[i](dof_i) += JxW[qp] * (f_vec(i) * phi[dof_i][qp]);
242 for (
auto side : elem->side_index_range())
243 if (elem->neighbor_ptr(side) ==
nullptr)
245 const std::vector<std::vector<Real>> & phi_face = fe_face->get_phi();
246 const std::vector<Real> & JxW_face = fe_face->get_JxW();
248 fe_face->reinit(elem, side);
251 for (
unsigned int qp=0; qp<qface.n_points(); qp++)
253 for (
unsigned int dof_i=0; dof_i<n_var_dofs; dof_i++)
254 for (
unsigned int i=0; i<3; i++)
255 Fe_var[i](dof_i) += JxW_face[qp] * (g_vec(i) * phi_face[dof_i][qp]);
274 unsigned int displacement_vars[3];
284 fe->attach_quadrature_rule (&qrule);
286 const std::vector<Real> & JxW = fe->get_JxW();
287 const std::vector<std::vector<Real>> & phi = fe->get_phi();
288 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
293 unsigned int sigma_vars[6];
300 unsigned int vonMises_var = stress_system.
variable_number (
"vonMises");
303 std::vector<std::vector<dof_id_type>> dof_indices_var(system.
n_vars());
304 std::vector<dof_id_type> stress_dof_indices_var;
305 std::vector<dof_id_type> vonmises_dof_indices_var;
307 for (
const auto & elem :
mesh.active_local_element_ptr_range())
309 for (
unsigned int var=0; var<3; var++)
310 dof_map.
dof_indices (elem, dof_indices_var[var], displacement_vars[var]);
312 const unsigned int n_var_dofs = dof_indices_var[0].size();
316 std::vector<TensorValue<Number>> stress_tensor_qp(qrule.n_points());
317 for (
unsigned int qp=0; qp<qrule.n_points(); qp++)
321 for (
unsigned int var_i=0; var_i<3; var_i++)
322 for (
unsigned int var_j=0; var_j<3; var_j++)
323 for (
unsigned int j=0; j<n_var_dofs; j++)
324 grad_u(var_i,var_j) += dphi[j][qp](var_j) * system.
current_solution(dof_indices_var[var_i][j]);
326 for (
unsigned int var_i=0; var_i<3; var_i++)
327 for (
unsigned int var_j=0; var_j<3; var_j++)
328 for (
unsigned int k=0; k<3; k++)
329 for (
unsigned int l=0; l<3; l++)
330 stress_tensor_qp[qp](var_i,var_j) +=
elasticity_tensor(var_i,var_j,k,l) * grad_u(k,l);
333 stress_dof_map.dof_indices (elem, vonmises_dof_indices_var, vonMises_var);
334 std::vector<TensorValue<Number>> elem_sigma_vec(vonmises_dof_indices_var.size());
339 unsigned int stress_var_index = 0;
340 for (
unsigned int var_i=0; var_i<3; var_i++)
341 for (
unsigned int var_j=var_i; var_j<3; var_j++)
343 stress_dof_map.dof_indices (elem, stress_dof_indices_var, sigma_vars[stress_var_index]);
345 const unsigned int n_proj_dofs = stress_dof_indices_var.size();
348 for (
unsigned int qp=0; qp<qrule.n_points(); qp++)
350 for(
unsigned int i=0; i<n_proj_dofs; i++)
351 for(
unsigned int j=0; j<n_proj_dofs; j++)
353 Me(i,j) += JxW[qp]*(phi[i][qp]*phi[j][qp]);
358 for (
unsigned int qp=0; qp<qrule.n_points(); qp++)
359 for(
unsigned int i=0; i<n_proj_dofs; i++)
361 Fe(i) += JxW[qp] * stress_tensor_qp[qp](var_i,var_j) * phi[i][qp];
367 for(
unsigned int index=0; index<n_proj_dofs; index++)
369 dof_id_type dof_index = stress_dof_indices_var[index];
370 if ((stress_system.
solution->first_local_index() <= dof_index) &&
371 (dof_index < stress_system.solution->last_local_index()))
372 stress_system.
solution->set(dof_index, projected_data(index));
374 elem_sigma_vec[index](var_i,var_j) = projected_data(index);
380 for (std::size_t index=0; index<elem_sigma_vec.size(); index++)
382 elem_sigma_vec[index](1,0) = elem_sigma_vec[index](0,1);
383 elem_sigma_vec[index](2,0) = elem_sigma_vec[index](0,2);
384 elem_sigma_vec[index](2,1) = elem_sigma_vec[index](1,2);
387 Number vonMises_value = std::sqrt(0.5*(Utility::pow<2>(elem_sigma_vec[index](0,0) - elem_sigma_vec[index](1,1)) +
388 Utility::pow<2>(elem_sigma_vec[index](1,1) - elem_sigma_vec[index](2,2)) +
389 Utility::pow<2>(elem_sigma_vec[index](2,2) - elem_sigma_vec[index](0,0)) +
390 6.*(Utility::pow<2>(elem_sigma_vec[index](0,1)) +
391 Utility::pow<2>(elem_sigma_vec[index](1,2)) +
392 Utility::pow<2>(elem_sigma_vec[index](2,0)))));
394 dof_id_type dof_index = vonmises_dof_indices_var[index];
396 if ((stress_system.
solution->first_local_index() <= dof_index) &&
397 (dof_index < stress_system.solution->last_local_index()))
398 stress_system.
solution->set(dof_index, vonMises_value);
410 int main (
int argc,
char ** argv)
417 "--enable-petsc, --enable-trilinos, or --enable-eigen");
420 const unsigned int dim = 3;
423 libmesh_example_requires(
dim == LIBMESH_DIM,
"3D support");
426 #ifndef LIBMESH_ENABLE_DIRICHLET 427 libmesh_example_requires(
false,
"--enable-dirichlet");
452 for (
const auto & elem :
mesh.element_ptr_range())
455 side_max_x = 0, side_min_y = 0,
456 side_max_y = 0, side_max_z = 0;
459 found_side_max_x =
false, found_side_max_y =
false,
460 found_side_min_y =
false, found_side_max_z =
false;
462 for (
auto side : elem->side_index_range())
467 found_side_max_x =
true;
473 found_side_min_y =
true;
479 found_side_max_y =
true;
485 found_side_max_z =
true;
492 if (found_side_max_x && found_side_max_y && found_side_max_z)
493 for (
auto n : elem->node_index_range())
494 if (elem->is_node_on_side(n, side_max_x) &&
495 elem->is_node_on_side(n, side_max_y) &&
496 elem->is_node_on_side(n, side_max_z))
503 if (found_side_max_x && found_side_min_y)
504 for (
auto e : elem->edge_index_range())
505 if (elem->is_edge_on_side(e, side_max_x) &&
506 elem->is_edge_on_side(e, side_min_y))
518 #ifdef LIBMESH_HAVE_PETSC 524 petsc_linear_solver->set_solver_configuration(petsc_solver_config);
530 #ifdef LIBMESH_ENABLE_DIRICHLET 543 {u_var, v_var, w_var}, zf,
549 #endif // LIBMESH_ENABLE_DIRICHLET 564 equation_systems.
init();
576 #ifdef LIBMESH_HAVE_EXODUS_API 582 #endif // #ifdef LIBMESH_HAVE_EXODUS_API class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
virtual void configure_solver()
Apply solver options to a particular solver.
T command_line_next(std::string name, T default_value)
Use GetPot's search()/next() functions to get following arguments from the command line...
This is the EquationSystems class.
bool has_boundary_id(const Node *const node, const boundary_id_type id) const
Real elasticity_tensor(unsigned int i, unsigned int j, unsigned int k, unsigned int l)
ConstFunction that simply returns 0.
void assemble()
Assemble the system matrix and right-hand side vector.
void constrain_element_matrix_and_vector(DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
Constrains the element matrix and vector.
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...
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
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]...
const FEType & variable_type(const unsigned int c) const
LinearElasticity(EquationSystems &es_in)
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
NumericVector< Number > * rhs
The system matrix.
This class allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
Order default_quadrature_order() const
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
virtual LinearSolver< Number > * get_linear_solver() const override
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
The libMesh namespace provides an interface to certain functionality in the library.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Abstract base class to be used for system assembly.
virtual void solve() override
Assembles & solves the linear system A*x=b.
const T_sys & get_system(std::string_view name) const
int main(int argc, char **argv)
This is the MeshBase class.
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.
void add_node(const Node *node, const boundary_id_type id)
Add Node node with boundary id id to the boundary information data structures.
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.
PetscSolverConfiguration(PetscLinearSolver< Number > &petsc_linear_solver)
PetscLinearSolver< Number > & _petsc_linear_solver
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh.
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.
This class stores solver configuration data, e.g.
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.
Real elasticity_tensor(unsigned int i, unsigned int j, unsigned int k, unsigned int l)
Evaluate the fourth order tensor (C_ijkl) that relates stress to strain.
void attach_assemble_object(Assembly &assemble)
Register a user object to use in assembling the system matrix and RHS.
virtual void update()
Update the local values to reflect the solution on neighboring processors.
void write_discontinuous_exodusII(const std::string &name, const EquationSystems &es, const std::set< std::string > *system_names=nullptr)
Writes a exodusII file with discontinuous data.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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
void add_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary)
Adds a copy of the specified Dirichlet boundary to the system.
void cholesky_solve(const DenseVector< T2 > &b, DenseVector< T2 > &x)
For symmetric positive definite (SPD) matrices.
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.
Real kronecker_delta(unsigned int i, unsigned int j)
Kronecker delta function.
const DofMap & get_dof_map() const
const SparseMatrix< Number > & get_system_matrix() 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 add_edge(const dof_id_type elem, const unsigned short int edge, const boundary_id_type id)
Add edge edge of element number elem with boundary id id to the boundary information data structure...