libMesh
Loading...
Searching...
No Matches
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 410 of file systems_of_equations_ex6.C.

411{
412 // Initialize libMesh and any dependent libraries
413 LibMeshInit init (argc, argv);
414
415 // This example requires a linear solver package.
416 libmesh_example_requires(libMesh::default_solver_package() != INVALID_SOLVER_PACKAGE,
417 "--enable-petsc, --enable-trilinos, or --enable-eigen");
418
419 // Initialize the cantilever mesh
420 const unsigned int dim = 3;
421
422 // Make sure libMesh was compiled for 3D
423 libmesh_example_requires(dim == LIBMESH_DIM, "3D support");
424
425 // We use Dirichlet boundary conditions here
426#ifndef LIBMESH_ENABLE_DIRICHLET
427 libmesh_example_requires(false, "--enable-dirichlet");
428#endif
429
430 // Get the mesh size from the command line.
431 const int nx = libMesh::command_line_next("-nx", 32),
432 ny = libMesh::command_line_next("-ny", 8),
433 nz = libMesh::command_line_next("-nz", 4);
434
435 // Create a 3D mesh distributed across the default MPI communicator.
436 Mesh mesh(init.comm(), dim);
438 nx,
439 ny,
440 nz,
441 0., 1.*x_scaling,
442 0., 0.3,
443 0., 0.1,
444 HEX8);
445
446 // Print information about the mesh to the screen.
448
449 // Let's add some node and edge boundary conditions
450 // Each processor should know about each boundary condition it can
451 // see, so we loop over all elements, not just local elements.
452 for (const auto & elem : mesh.element_ptr_range())
453 {
454 unsigned int
455 side_max_x = 0, side_min_y = 0,
456 side_max_y = 0, side_max_z = 0;
457
458 bool
459 found_side_max_x = false, found_side_max_y = false,
460 found_side_min_y = false, found_side_max_z = false;
461
462 for (auto side : elem->side_index_range())
463 {
464 if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MAX_X))
465 {
466 side_max_x = side;
467 found_side_max_x = true;
468 }
469
470 if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MIN_Y))
471 {
472 side_min_y = side;
473 found_side_min_y = true;
474 }
475
476 if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MAX_Y))
477 {
478 side_max_y = side;
479 found_side_max_y = true;
480 }
481
482 if (mesh.get_boundary_info().has_boundary_id(elem, side, BOUNDARY_ID_MAX_Z))
483 {
484 side_max_z = side;
485 found_side_max_z = true;
486 }
487 }
488
489 // If elem has sides on boundaries
490 // BOUNDARY_ID_MAX_X, BOUNDARY_ID_MAX_Y, BOUNDARY_ID_MAX_Z
491 // then let's set a node boundary condition
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))
497 mesh.get_boundary_info().add_node(elem->node_ptr(n), NODE_BOUNDARY_ID);
498
499
500 // If elem has sides on boundaries
501 // BOUNDARY_ID_MAX_X and BOUNDARY_ID_MIN_Y
502 // then let's set an edge boundary condition
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))
507 mesh.get_boundary_info().add_edge(elem, e, EDGE_BOUNDARY_ID);
508 }
509
510 // We're all done adding to the boundary_info; let's make sure its
511 // caches know about it.
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 // Create a ZeroFunction to initialize dirichlet_bc
542
543 // Most DirichletBoundary users will want to supply a "locally
544 // indexed" functor
545 DirichletBoundary dirichlet_bc({BOUNDARY_ID_MIN_X, NODE_BOUNDARY_ID,
546 EDGE_BOUNDARY_ID},
547 {u_var, v_var, w_var}, zf,
549
550 // We must add the Dirichlet boundary condition _before_
551 // we call equation_systems.init()
552 system.get_dof_map().add_dirichlet_boundary(dirichlet_bc);
553#endif // LIBMESH_ENABLE_DIRICHLET
554
555 // Also, initialize an ExplicitSystem to store stresses
556 ExplicitSystem & stress_system =
557 equation_systems.add_system<ExplicitSystem> ("StressSystem");
558
559 stress_system.add_variable("sigma_00", FIRST, L2_LAGRANGE);
560 stress_system.add_variable("sigma_01", FIRST, L2_LAGRANGE);
561 stress_system.add_variable("sigma_02", FIRST, L2_LAGRANGE);
562 stress_system.add_variable("sigma_11", FIRST, L2_LAGRANGE);
563 stress_system.add_variable("sigma_12", FIRST, L2_LAGRANGE);
564 stress_system.add_variable("sigma_22", FIRST, L2_LAGRANGE);
565 stress_system.add_variable("vonMises", FIRST, L2_LAGRANGE);
566
567 // Initialize the data structures for the equation system.
568 equation_systems.init();
569
570 // Print information about the system to the screen.
571 equation_systems.print_info();
572
573 // Solve the system
574 system.solve();
575
576 // Post-process the solution to compute the stresses
577 le.compute_stresses();
578
579 // Plot the solution
580#ifdef LIBMESH_HAVE_EXODUS_API
581
582 // Use single precision in this case (reduces the size of the exodus file)
583 ExodusII_IO exo_io(mesh, /*single_precision=*/true);
584 exo_io.write_discontinuous_exodusII("displacement_and_stress.exo", equation_systems);
585
586#endif // #ifdef LIBMESH_HAVE_EXODUS_API
587
588 // All done.
589 return 0;
590}
unsigned int dim
bool has_boundary_id(const Node *const node, const boundary_id_type id) const
void regenerate_id_sets()
Clears and regenerates the cached sets of ids.
This class allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
void add_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary)
Adds a copy of the specified Dirichlet boundary to the system.
This is the EquationSystems class.
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition exodusII_io.h:53
Manages consistently variables, degrees of freedom, and coefficient vectors for explicit systems.
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition libmesh.h:92
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
virtual LinearSolver< Number > * get_linear_solver() const override
virtual void solve() override
Assembles & solves the linear system A*x=b.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition mesh_base.h:170
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
This class provides an interface to PETSc iterative solvers that is compatible with the libMesh Linea...
void attach_assemble_object(Assembly &assemble)
Register a user object to use in assembling the system matrix and RHS.
Definition system.C:1976
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
const DofMap & get_dof_map() const
Definition system.h:2417
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.
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
SolverPackage default_solver_package()
Definition libmesh.C:1064
libmesh_assert(ctx)
T command_line_next(std::string name, T default_value)
Use GetPot's search()/next() functions to get following arguments from the command line.
Definition libmesh.C:1025

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(), libMesh::command_line_next(), LinearElasticity::compute_stresses(), libMesh::default_solver_package(), dim, 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::EquationSystems::init(), libMesh::INVALID_SOLVER_PACKAGE, libMesh::L2_LAGRANGE, libMesh::LAGRANGE, libMesh::libmesh_assert(), libMesh::LOCAL_VARIABLE_ORDER, main(), mesh, libMesh::EquationSystems::print_info(), libMesh::MeshBase::print_info(), libMesh::BoundaryInfo::regenerate_id_sets(), libMesh::LinearImplicitSystem::solve(), and libMesh::ExodusII_IO::write_discontinuous_exodusII().