libMesh
Classes | Functions
systems_of_equations_ex6.C File Reference

Go to the source code of this file.

Classes

class  PetscSolverConfiguration
 
class  LinearElasticity
 

Functions

int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 419 of file systems_of_equations_ex6.C.

420 {
421  // Initialize libMesh and any dependent libraries
422  LibMeshInit init (argc, argv);
423 
424  // This example requires a linear solver package.
425  libmesh_example_requires(libMesh::default_solver_package() != INVALID_SOLVER_PACKAGE,
426  "--enable-petsc, --enable-trilinos, or --enable-eigen");
427 
428  // Initialize the cantilever mesh
429  const unsigned int dim = 3;
430 
431  // Make sure libMesh was compiled for 3D
432  libmesh_example_requires(dim == LIBMESH_DIM, "3D support");
433 
434  // We use Dirichlet boundary conditions here
435 #ifndef LIBMESH_ENABLE_DIRICHLET
436  libmesh_example_requires(false, "--enable-dirichlet");
437 #endif
438 
439  // Create a 3D mesh distributed across the default MPI communicator.
440  Mesh mesh(init.comm(), dim);
442  32,
443  8,
444  4,
445  0., 1.*x_scaling,
446  0., 0.3,
447  0., 0.1,
448  HEX8);
449 
450  // Print information about the mesh to the screen.
451  mesh.print_info();
452 
453  // Let's add some node and edge boundary conditions
454  // Each processor should know about each boundary condition it can
455  // see, so we loop over all elements, not just local elements.
456  for (const auto & elem : mesh.element_ptr_range())
457  {
458  unsigned int
459  side_max_x = 0, side_min_y = 0,
460  side_max_y = 0, side_max_z = 0;
461 
462  bool
463  found_side_max_x = false, found_side_max_y = false,
464  found_side_min_y = false, found_side_max_z = false;
465 
466  for (auto side : elem->side_index_range())
467  {
468  if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MAX_X))
469  {
470  side_max_x = side;
471  found_side_max_x = true;
472  }
473 
474  if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MIN_Y))
475  {
476  side_min_y = side;
477  found_side_min_y = true;
478  }
479 
480  if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MAX_Y))
481  {
482  side_max_y = side;
483  found_side_max_y = true;
484  }
485 
486  if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MAX_Z))
487  {
488  side_max_z = side;
489  found_side_max_z = true;
490  }
491  }
492 
493  // If elem has sides on boundaries
494  // BOUNDARY_ID_MAX_X, BOUNDARY_ID_MAX_Y, BOUNDARY_ID_MAX_Z
495  // then let's set a node boundary condition
496  if (found_side_max_x && found_side_max_y && found_side_max_z)
497  for (auto n : elem->node_index_range())
498  if (elem->is_node_on_side(n, side_max_x) &&
499  elem->is_node_on_side(n, side_max_y) &&
500  elem->is_node_on_side(n, side_max_z))
501  mesh.get_boundary_info().add_node(elem->node_ptr(n), NODE_BOUNDARY_ID);
502 
503 
504  // If elem has sides on boundaries
505  // BOUNDARY_ID_MAX_X and BOUNDARY_ID_MIN_Y
506  // then let's set an edge boundary condition
507  if (found_side_max_x && found_side_min_y)
508  for (auto e : elem->edge_index_range())
509  if (elem->is_edge_on_side(e, side_max_x) &&
510  elem->is_edge_on_side(e, side_min_y))
511  mesh.get_boundary_info().add_edge(elem, e, EDGE_BOUNDARY_ID);
512  }
513 
514  // Create an equation systems object.
515  EquationSystems equation_systems (mesh);
516 
517  // Declare the system and its variables.
518  // Create a system named "Elasticity"
519  LinearImplicitSystem & system =
520  equation_systems.add_system<LinearImplicitSystem> ("Elasticity");
521 
522 #ifdef LIBMESH_HAVE_PETSC
523  // Attach a SolverConfiguration object to system.linear_solver
524  PetscLinearSolver<Number> * petsc_linear_solver =
525  cast_ptr<PetscLinearSolver<Number>*>(system.get_linear_solver());
526  libmesh_assert(petsc_linear_solver);
527  PetscSolverConfiguration petsc_solver_config(*petsc_linear_solver);
528  petsc_linear_solver->set_solver_configuration(petsc_solver_config);
529 #endif
530 
531  LinearElasticity le(equation_systems);
532  system.attach_assemble_object(le);
533 
534 #ifdef LIBMESH_ENABLE_DIRICHLET
535  // Add three displacement variables, u and v, to the system
536  unsigned int u_var = system.add_variable("u", FIRST, LAGRANGE);
537  unsigned int v_var = system.add_variable("v", FIRST, LAGRANGE);
538  unsigned int w_var = system.add_variable("w", FIRST, LAGRANGE);
539 
540  std::set<boundary_id_type> boundary_ids;
541  boundary_ids.insert(BOUNDARY_ID_MIN_X);
542  boundary_ids.insert(NODE_BOUNDARY_ID);
543  boundary_ids.insert(EDGE_BOUNDARY_ID);
544 
545  // Create a vector storing the variable numbers which the BC applies to
546  std::vector<unsigned int> variables;
547  variables.push_back(u_var);
548  variables.push_back(v_var);
549  variables.push_back(w_var);
550 
551  // Create a ZeroFunction to initialize dirichlet_bc
552  ZeroFunction<> zf;
553 
554  // Most DirichletBoundary users will want to supply a "locally
555  // indexed" functor
556  DirichletBoundary dirichlet_bc(boundary_ids, variables, zf,
558 
559  // We must add the Dirichlet boundary condition _before_
560  // we call equation_systems.init()
561  system.get_dof_map().add_dirichlet_boundary(dirichlet_bc);
562 #endif // LIBMESH_ENABLE_DIRICHLET
563 
564  // Also, initialize an ExplicitSystem to store stresses
565  ExplicitSystem & stress_system =
566  equation_systems.add_system<ExplicitSystem> ("StressSystem");
567 
568  stress_system.add_variable("sigma_00", FIRST, L2_LAGRANGE);
569  stress_system.add_variable("sigma_01", FIRST, L2_LAGRANGE);
570  stress_system.add_variable("sigma_02", FIRST, L2_LAGRANGE);
571  stress_system.add_variable("sigma_11", FIRST, L2_LAGRANGE);
572  stress_system.add_variable("sigma_12", FIRST, L2_LAGRANGE);
573  stress_system.add_variable("sigma_22", FIRST, L2_LAGRANGE);
574  stress_system.add_variable("vonMises", FIRST, L2_LAGRANGE);
575 
576  // Initialize the data structures for the equation system.
577  equation_systems.init();
578 
579  // Print information about the system to the screen.
580  equation_systems.print_info();
581 
582  // Solve the system
583  system.solve();
584 
585  // Post-process the solution to compute the stresses
586  le.compute_stresses();
587 
588  // Plot the solution
589 #ifdef LIBMESH_HAVE_EXODUS_API
590 
591  // Use single precision in this case (reduces the size of the exodus file)
592  ExodusII_IO exo_io(mesh, /*single_precision=*/true);
593  exo_io.write_discontinuous_exodusII("displacement_and_stress.exo", equation_systems);
594 
595 #endif // #ifdef LIBMESH_HAVE_EXODUS_API
596 
597  // All done.
598  return 0;
599 }

References libMesh::DofMap::add_dirichlet_boundary(), libMesh::BoundaryInfo::add_edge(), libMesh::BoundaryInfo::add_node(), libMesh::EquationSystems::add_system(), libMesh::System::add_variable(), libMesh::System::attach_assemble_object(), libMesh::MeshTools::Generation::build_cube(), LinearElasticity::compute_stresses(), libMesh::default_solver_package(), dim, libMesh::MeshBase::element_ptr_range(), libMesh::FIRST, libMesh::MeshBase::get_boundary_info(), libMesh::System::get_dof_map(), libMesh::LinearImplicitSystem::get_linear_solver(), libMesh::BoundaryInfo::has_boundary_id(), libMesh::HEX8, libMesh::TriangleWrapper::init(), libMesh::EquationSystems::init(), libMesh::INVALID_SOLVER_PACKAGE, libMesh::L2_LAGRANGE, libMesh::LAGRANGE, libMesh::libmesh_assert(), libMesh::LOCAL_VARIABLE_ORDER, mesh, libMesh::EquationSystems::print_info(), libMesh::MeshBase::print_info(), libMesh::LinearImplicitSystem::solve(), and libMesh::ExodusII_IO::write_discontinuous_exodusII().

libMesh::Mesh
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
libMesh::MeshBase::get_boundary_info
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:132
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::HEX8
Definition: enum_elem_type.h:47
libMesh::BoundaryInfo::add_node
void add_node(const Node *node, const boundary_id_type id)
Add Node node with boundary id id to the boundary information data structures.
Definition: boundary_info.C:636
LinearElasticity
Definition: systems_of_equations_ex6.C:114
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::LinearImplicitSystem::solve
virtual void solve() override
Assembles & solves the linear system A*x=b.
Definition: linear_implicit_system.C:108
libMesh::default_solver_package
SolverPackage default_solver_package()
Definition: libmesh.C:993
mesh
MeshBase & mesh
Definition: mesh_communication.C:1257
libMesh::ExodusII_IO
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition: exodusII_io.h:51
PetscSolverConfiguration
Definition: systems_of_equations_ex6.C:89
dim
unsigned int dim
Definition: adaptivity_ex3.C:113
libMesh::TriangleWrapper::init
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
libMesh::MeshBase::element_ptr_range
virtual SimpleRange< element_iterator > element_ptr_range()=0
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::LOCAL_VARIABLE_ORDER
Definition: dirichlet_boundaries.h:62
libMesh::LinearImplicitSystem::get_linear_solver
virtual LinearSolver< Number > * get_linear_solver() const override
Definition: linear_implicit_system.C:353
libMesh::INVALID_SOLVER_PACKAGE
Definition: enum_solver_package.h:43
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::PetscLinearSolver< Number >
libMesh::LibMeshInit
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition: libmesh.h:83
libMesh::ZeroFunction
ConstFunction that simply returns 0.
Definition: zero_function.h:36
libMesh::EquationSystems
This is the EquationSystems class.
Definition: equation_systems.h:74
libMesh::ExplicitSystem
Manages consistently variables, degrees of freedom, and coefficient vectors for explicit systems.
Definition: explicit_system.h:48
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::BoundaryInfo::add_edge
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.
Definition: boundary_info.C:707
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::L2_LAGRANGE
Definition: enum_fe_family.h:41
libMesh::System::get_dof_map
const DofMap & get_dof_map() const
Definition: system.h:2099
libMesh::System::attach_assemble_object
void attach_assemble_object(Assembly &assemble)
Register a user object to use in assembling the system matrix and RHS.
Definition: system.C:1774
libMesh::LAGRANGE
Definition: enum_fe_family.h:36
libMesh::LinearImplicitSystem
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
Definition: linear_implicit_system.h:55
libMesh::BoundaryInfo::has_boundary_id
bool has_boundary_id(const Node *const node, const boundary_id_type id) const
Definition: boundary_info.C:972
libMesh::FIRST
Definition: enum_order.h:42