libMesh
Loading...
Searching...
No Matches
vector_fe_ex3.C
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18
19
20// <h1>Vector Finite Elements Example 3 - Nedelec Elements</h1>
21// \author Paul Bauman
22// \date 2012
23//
24// This example shows an example of using the Nedelec elements of the
25// first type to solve a model problem in H(curl).
26
27// Basic include files
28#include "libmesh/equation_systems.h"
29#include "libmesh/getpot.h"
30#include "libmesh/exodusII_io.h"
31#include "libmesh/mesh.h"
32#include "libmesh/mesh_generation.h"
33#include "libmesh/mesh_modification.h"
34#include "libmesh/mesh_refinement.h"
35#include "libmesh/exact_solution.h"
36#include "libmesh/string_to_enum.h"
37#include "libmesh/enum_solver_package.h"
38#include "libmesh/enum_norm_type.h"
39#include "libmesh/petsc_macro.h"
40
41// The systems and solvers we may use
42#include "curl_curl_system.h"
43#include "libmesh/diff_solver.h"
44#include "libmesh/steady_solver.h"
45#include "solution_function.h"
46
47// Bring in everything from the libMesh namespace
48using namespace libMesh;
49
50// Define static data member holding (optional) rotation matrix
52
53// The main program.
54int main (int argc, char ** argv)
55{
56 // Initialize libMesh.
57 LibMeshInit init (argc, argv);
58
59 // This example requires a linear solver package.
60 libmesh_example_requires(libMesh::default_solver_package() != INVALID_SOLVER_PACKAGE,
61 "--enable-petsc, --enable-trilinos, or --enable-eigen");
62
63 // Parse the input file
64 GetPot infile("vector_fe_ex3.in");
65
66 // But allow the command line to override it.
67 infile.parse_command_line(argc, argv);
68
69 // hypre AMS requires PETSc 3.12.2 or above with hypre support enabled
70#if PETSC_VERSION_LESS_THAN(3, 12, 2) || !defined(LIBMESH_HAVE_PETSC_HYPRE)
71 libmesh_example_requires(!infile.search("ams"),
72 "PETSc 3.12.2 or above with hypre support enabled");
73#endif
74
75 // Read in parameters from the input file
76 const unsigned int grid_size = infile("grid_size", 2);
77
78 // Skip higher-dimensional examples on a lower-dimensional libMesh build
79 libmesh_example_requires(2 <= LIBMESH_DIM, "2D support");
80
81 // Create a mesh, with dimension to be overridden later, on the
82 // default MPI communicator.
83 Mesh mesh(init.comm());
84
85 // Use the MeshTools::Generation mesh generator to create a uniform
86 // grid on the square [-1,1]^D. We must use at least TRI6 or QUAD8 elements
87 // for the Nedelec triangle or quadrilateral elements, respectively.
88 const std::string elem_str = infile("element_type", std::string("TRI6"));
89
90 libmesh_error_msg_if(elem_str != "TRI6" && elem_str != "TRI7" && elem_str != "QUAD8" && elem_str != "QUAD9",
91 "You selected: " << elem_str <<
92 " but this example must be run with TRI6, TRI7, QUAD8, or QUAD9.");
93
95 grid_size,
96 grid_size,
97 -1., 1.,
98 -1., 1.,
99 Utility::string_to_enum<ElemType>(elem_str));
100
101 // Make sure the code is robust against nodal reorderings.
103
104#ifdef LIBMESH_ENABLE_AMR
105 // Make sure the code is robust against mesh refinements.
106 MeshRefinement mesh_refinement(mesh);
107 mesh_refinement.uniformly_refine(infile("refine", 0));
108#endif
109
110 // Make sure the code is robust against solves on 2d meshes rotated out of
111 // the xy plane. By default, all Euler angles are zero, the rotation matrix
112 // is the identity, and the mesh stays in place.
113 const Real phi = infile("phi", 0.), theta = infile("theta", 0.), psi = infile("psi", 0.);
115
116 // Rotation can leave a mesh's caches unprepared
118
119 // Print information about the mesh to the screen.
121
122 // Create an equation systems object.
123 EquationSystems equation_systems (mesh);
124
125 // Declare the system "CurlCurl" and its variables.
126 CurlCurlSystem & system =
127 equation_systems.add_system<CurlCurlSystem> ("CurlCurl");
128
129 // Set the FE approximation order.
130 const Order order = static_cast<Order>(infile("order", 1u));
131
132 libmesh_error_msg_if(order < FIRST || order > FIFTH,
133 "You selected: " << order <<
134 " but this example must be run with 1 <= order <= 5.");
135
136 system.order(order);
137
138 // This example only implements the steady-state problem
139 system.time_solver = std::make_unique<SteadySolver>(system);
140
141 // Initialize the system
142 equation_systems.init();
143
144 // And the nonlinear solver options
145 DiffSolver & solver = *(system.time_solver->diff_solver().get());
146 solver.quiet = infile("solver_quiet", true);
147 solver.verbose = !solver.quiet;
148 solver.max_nonlinear_iterations = infile("max_nonlinear_iterations", 15);
149 solver.relative_step_tolerance = infile("relative_step_tolerance", 1.e-3);
150 solver.relative_residual_tolerance = infile("relative_residual_tolerance", 1.0e-13);
151 solver.absolute_residual_tolerance = infile("absolute_residual_tolerance", 0.0);
152
153 // And the linear solver options
154 solver.max_linear_iterations = infile("max_linear_iterations", 50000);
155 solver.initial_linear_tolerance = infile("initial_linear_tolerance", 1.e-10);
156
157 // Print information about the system to the screen.
158 equation_systems.print_info();
159
160 // Solve the system.
161 system.solve();
162
163 ExactSolution exact_sol(equation_systems);
164
165 SolutionFunction soln_func(system.variable_number("u"));
166 SolutionGradient soln_grad(system.variable_number("u"));
167
168 // Build FunctionBase* containers to attach to the ExactSolution object.
169 std::vector<FunctionBase<Number> *> sols(1, &soln_func);
170 std::vector<FunctionBase<Gradient> *> grads(1, &soln_grad);
171
172 exact_sol.attach_exact_values(sols);
173 exact_sol.attach_exact_derivs(grads);
174
175 // Use higher quadrature order for more accurate error results
176 int extra_error_quadrature = infile("extra_error_quadrature", 2);
177 exact_sol.extra_quadrature_order(extra_error_quadrature);
178
179 // Compute the error.
180 exact_sol.compute_error("CurlCurl", "u");
181
182 // Print out the error values
183 libMesh::out << "L2-Error is: "
184 << exact_sol.l2_error("CurlCurl", "u")
185 << std::endl;
186 libMesh::out << "HCurl semi-norm error is: "
187 << exact_sol.error_norm("CurlCurl", "u", HCURL_SEMINORM)
188 << std::endl;
189 libMesh::out << "HCurl-Error is: "
190 << exact_sol.hcurl_error("CurlCurl", "u")
191 << std::endl;
192
193#ifdef LIBMESH_HAVE_EXODUS_API
194
195 // We write the file in the ExodusII format.
196 ExodusII_IO(mesh).write_equation_systems("out.e", equation_systems);
197
198#endif // #ifdef LIBMESH_HAVE_EXODUS_API
199
200 // All done.
201 return 0;
202}
static void RM(RealTensor T)
FEMSystem, TimeSolver and NewtonSolver will handle most tasks, but we must specify element residuals.
void order(const Order &order)
This is a generic class that defines a solver to handle ImplicitSystem classes, including NonlinearIm...
Definition diff_solver.h:70
Real absolute_residual_tolerance
The DiffSolver should exit after the residual is reduced to either less than absolute_residual_tolera...
unsigned int max_linear_iterations
Each linear solver step should exit after max_linear_iterations is exceeded.
double initial_linear_tolerance
Any required linear solves will at first be done with this tolerance; the DiffSolver may tighten the ...
bool verbose
The DiffSolver may print a lot more to libMesh::out if verbose is set to true; default is false.
unsigned int max_nonlinear_iterations
The DiffSolver should exit in failure if max_nonlinear_iterations is exceeded and continue_after_max_...
bool quiet
The DiffSolver should not print anything to libMesh::out unless quiet is set to false; default is tru...
std::unique_ptr< TimeSolver > time_solver
A pointer to the solver object we're going to use.
This is the EquationSystems class.
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
virtual void init()
Initialize all the systems.
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.
This class handles the computation of the L2 and/or H1 error for the Systems in the EquationSystems o...
Real l2_error(std::string_view sys_name, std::string_view unknown_name)
Real hcurl_error(std::string_view sys_name, std::string_view unknown_name)
Real error_norm(std::string_view sys_name, std::string_view unknown_name, const FEMNormType &norm)
void attach_exact_values(const std::vector< FunctionBase< Number > * > &f)
Clone and attach arbitrary functors which compute the exact values of the EquationSystems' solutions ...
void compute_error(std::string_view sys_name, std::string_view unknown_name)
Computes and stores the error in the solution value e = u-u_h, the gradient grad(e) = grad(u) - grad(...
void extra_quadrature_order(const int extraorder)
Increases or decreases the order of the quadrature rule used for numerical integration.
void attach_exact_derivs(const std::vector< FunctionBase< Gradient > * > &g)
Clone and attach arbitrary functors which compute the exact gradients of the EquationSystems' solutio...
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition exodusII_io.h:53
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.
virtual void solve() override
Invokes the solver associated with the system.
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition libmesh.h:92
void complete_preparation()
Definition mesh_base.C:874
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
Implements (adaptive) mesh refinement algorithms for a MeshBase.
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition mesh.h:51
unsigned int variable_number(std::string_view var) const
Definition system.C:1398
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
MeshBase & mesh
void build_square(UnstructuredMesh &mesh, const unsigned int nx, const unsigned int ny, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 2D meshes.
RealTensorValue rotate(MeshBase &mesh, const Real phi, const Real theta=0., const Real psi=0.)
Rotates the mesh in 3D space.
void permute_elements(MeshBase &mesh)
Randomly permute the nodal ordering of each element (without twisting the element mapping).
The libMesh namespace provides an interface to certain functionality in the library.
SolverPackage default_solver_package()
Definition libmesh.C:1064
OStreamProxy out
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
int main()