49#include "libmesh/mesh.h"
50#include "libmesh/equation_systems.h"
51#include "libmesh/linear_implicit_system.h"
52#include "libmesh/exodusII_io.h"
53#include "libmesh/tecplot_io.h"
54#include "libmesh/fe.h"
55#include "libmesh/quadrature_gauss.h"
56#include "libmesh/dense_matrix.h"
57#include "libmesh/dense_vector.h"
58#include "libmesh/sparse_matrix.h"
59#include "libmesh/mesh_refinement.h"
60#include "libmesh/error_vector.h"
61#include "libmesh/discontinuity_measure.h"
62#include "libmesh/exact_error_estimator.h"
63#include "libmesh/kelly_error_estimator.h"
64#include "libmesh/smoothness_estimator.h"
65#include "libmesh/patch_recovery_error_estimator.h"
66#include "libmesh/uniform_refinement_estimator.h"
67#include "libmesh/hp_coarsentest.h"
68#include "libmesh/hp_singular.h"
69#include "libmesh/sibling_coupling.h"
70#include "libmesh/mesh_generation.h"
71#include "libmesh/mesh_modification.h"
72#include "libmesh/perf_log.h"
73#include "libmesh/getpot.h"
74#include "libmesh/exact_solution.h"
75#include "libmesh/dof_map.h"
76#include "libmesh/numeric_vector.h"
77#include "libmesh/elem.h"
78#include "libmesh/string_to_enum.h"
79#include "libmesh/enum_solver_package.h"
80#include "libmesh/dirichlet_boundaries.h"
81#include "libmesh/wrapped_function.h"
93 const std::string & system_name);
101 const std::string &);
107 const std::string &);
123int main(
int argc,
char ** argv)
130 "--enable-petsc, --enable-trilinos, or --enable-eigen");
133 libmesh_example_requires(
sizeof(
Real) > 4,
"--disable-singleprecision");
136#ifndef LIBMESH_ENABLE_AMR
137 libmesh_example_requires(
false,
"--enable-amr");
141 GetPot input_file(
"adaptivity_ex3.in");
144 input_file.parse_command_line(argc, argv);
147 const unsigned int max_r_steps = input_file(
"max_r_steps", 3);
148 const unsigned int max_r_level = input_file(
"max_r_level", 3);
149 const Real refine_percentage = input_file(
"refine_percentage", 0.5);
150 const Real coarsen_percentage = input_file(
"coarsen_percentage", 0.5);
151 const unsigned int uniform_refine = input_file(
"uniform_refine",0);
152 const std::string refine_type = input_file(
"refinement_type",
"h");
153 const std::string approx_type = input_file(
"approx_type",
"LAGRANGE");
154 const unsigned int approx_order = input_file(
"approx_order", 1);
156 const std::string element_type = input_file(
"element_type",
"tensor");
157 const int extra_error_quadrature = input_file(
"extra_error_quadrature", 0);
158 const int max_linear_iterations = input_file(
"max_linear_iterations", 5000);
160#ifdef LIBMESH_HAVE_EXODUS_API
161 const bool output_intermediate = input_file(
"output_intermediate",
false);
167#if !defined(LIBMESH_ENABLE_SECOND_DERIVATIVES)
168 libmesh_example_requires(approx_type !=
"HERMITE",
"--enable-second");
171 dim = input_file(
"dimension", 2);
172 const std::string indicator_type = input_file(
"indicator_type",
"kelly");
174 const bool extrusion = input_file(
"extrusion",
false);
175 const bool complete = input_file(
"complete",
false);
176 libmesh_error_msg_if(extrusion &&
dim < 3,
"Extrusion option is only for 3D meshes");
179 libmesh_example_requires(
dim <= LIBMESH_DIM,
"2D/3D support");
183 std::string approx_name =
"";
184 if (element_type ==
"tensor")
186 if (approx_order == 1)
187 approx_name +=
"linear";
188 else if (approx_order == 2)
189 approx_name +=
"quadratic";
190 else if (approx_order == 3)
191 approx_name +=
"cubic";
192 else if (approx_order == 4)
193 approx_name +=
"quartic";
195 std::string output_file = approx_name;
197 output_file += refine_type;
198 if (uniform_refine == 0)
199 output_file +=
"_adaptive.m";
201 output_file +=
"_uniform.m";
203 std::ofstream
out (output_file.c_str());
204 out <<
"% dofs L2-error H1-error" << std::endl;
205 out <<
"e = [" << std::endl;
225 if (refine_type ==
"hp")
231 else if (
dim == 2 || extrusion ==
true)
237 if (element_type ==
"simplex")
253 else if (approx_order > 1 || refine_type !=
"h")
267 Utility::string_to_enum<FEFamily>(approx_type));
269 std::vector<unsigned int> all_vars(1, u_var);
272 for (
unsigned int var_num=1; var_num <
n_vars; ++var_num)
274 std::ostringstream var_name;
275 var_name <<
"u" << var_num;
276 unsigned int next_var =
278 static_cast<Order>(approx_order),
279 Utility::string_to_enum<FEFamily>(approx_type));
280 all_vars.push_back(next_var);
294 equation_systems.
init();
297 equation_systems.
parameters.
set<
unsigned int>(
"linear solver maximum iterations")
298 = max_linear_iterations;
320 << exact_sol.
l2_error(
"Laplace",
"u")
323 << exact_sol.
h1_error(
"Laplace",
"u")
327 for (
unsigned int r_step=0; r_step<max_r_steps; r_step++)
329 libMesh::out <<
"Beginning Solve " << r_step << std::endl;
336 <<
" degrees of freedom."
341 <<
", final residual: "
345#ifdef LIBMESH_HAVE_EXODUS_API
348 if (output_intermediate)
350 std::ostringstream outfile;
351 outfile <<
"lshaped_" << r_step <<
".e";
363 libmesh_error_msg(
"NaN solve result");
367 << exact_sol.
l2_error(
"Laplace",
"u")
370 << exact_sol.
h1_error(
"Laplace",
"u")
387 Real mean_disc_error = disc_error.
mean();
389 libMesh::out <<
"Mean discontinuity error = " << mean_disc_error << std::endl;
392#ifdef LIBMESH_ENABLE_PETSC
393 libmesh_assert_less (mean_disc_error, 1e-14);
399 << exact_sol.
l2_error(
"Laplace",
"u") <<
" "
400 << exact_sol.
h1_error(
"Laplace",
"u") << std::endl;
403 if (r_step+1 != max_r_steps)
407 if (uniform_refine == 0)
414 if (indicator_type ==
"exact")
441 else if (indicator_type ==
"patch")
450 else if (indicator_type ==
"uniform")
460 libmesh_assert_equal_to (indicator_type,
"kelly");
479 std::ostringstream ss;
481#ifdef LIBMESH_HAVE_EXODUS_API
482# ifdef LIBMESH_HAVE_NEMESIS_API
483 std::string error_output =
"error_" + ss.str() +
".n";
484 std::string smoothness_output =
"smoothness_" + ss.str() +
".n";
486 std::string error_output =
"error_" + ss.str() +
".e";
487 std::string smoothness_output =
"smoothness_" + ss.str() +
".e";
490 std::string error_output =
"error_" + ss.str() +
".gmv";
491 std::string smoothness_output =
"smoothness_" + ss.str() +
".gmv";
495 if (refine_type ==
"hp")
500 std::string data_type =
"smoothness";
515 if (refine_type ==
"p")
519 else if (refine_type ==
"matchedhp")
523 else if (refine_type ==
"hp")
530 else if (refine_type ==
"singularhp")
541 libmesh_error_msg_if(refine_type !=
"h",
542 "Unknown refinement_type = " << refine_type);
549 else if (uniform_refine == 1)
551 if (refine_type ==
"h" || refine_type ==
"hp" ||
552 refine_type ==
"matchedhp")
554 if (refine_type ==
"p" || refine_type ==
"hp" ||
555 refine_type ==
"matchedhp")
564 equation_systems.
reinit ();
568#ifdef LIBMESH_HAVE_EXODUS_API
577 out <<
"];" << std::endl;
578 out <<
"hold on" << std::endl;
579 out <<
"plot(e(:,1), e(:,2), 'bo-');" << std::endl;
580 out <<
"plot(e(:,1), e(:,3), 'ro-');" << std::endl;
583 out <<
"xlabel('dofs');" << std::endl;
584 out <<
"title('" << approx_name <<
" elements');" << std::endl;
585 out <<
"legend('L2-error', 'H1-error');" << std::endl;
608 const Real y = (
dim > 1) ? p(1) : 0.;
614 Real theta = atan2(y, x);
621 const Real z = (
dim > 2) ? p(2) : 0;
623 return pow(x*x + y*y, 1./3.)*sin(2./3.*theta) + z;
629 const Real z = (
dim > 2) ? p(2) : 0;
631 return cos(x) * exp(y) * (1. - z);
652 const Real y =
dim > 1 ? p(1) : 0.;
657 libmesh_assert_not_equal_to (x, 0.);
660 const Real tt = 2./3.;
661 const Real ot = 1./3.;
664 const Real r2 = x*x + y*y;
668 Real theta = atan2(y, x);
675 gradu(0) = tt*x*pow(r2,-tt)*sin(tt*theta) - pow(r2,ot)*cos(tt*theta)*tt/(1.+y*y/x/x)*y/x/x;
679 gradu(1) = tt*y*pow(r2,-tt)*sin(tt*theta) + pow(r2,ot)*cos(tt*theta)*tt/(1.+y*y/x/x)*1./x;
686 const Real z = (
dim > 2) ? p(2) : 0;
688 gradu(0) = -sin(x) * exp(y) * (1. - z);
690 gradu(1) = cos(x) * exp(y) * (1. - z);
692 gradu(2) = -cos(x) * exp(y);
709 const std::string & system_name)
714#ifdef LIBMESH_ENABLE_AMR
717 libmesh_assert_equal_to (system_name,
"Laplace");
723 PerfLog perf_log (
"Matrix Assembly",
false);
742 FEType fe_type = dof_map.variable_type(0);
748 std::unique_ptr<FEBase> fe (
FEBase::build(mesh_dim, fe_type));
749 std::unique_ptr<FEBase> fe_face (
FEBase::build(mesh_dim, fe_type));
756 fe->attach_quadrature_rule (qrule.get());
757 fe_face->attach_quadrature_rule (qface.get());
763 const std::vector<Real> & JxW = fe->get_JxW();
768 const std::vector<Point> & q_point = fe->get_xyz();
771 const std::vector<std::vector<Real>> & phi = fe->get_phi();
775 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
787 std::vector<dof_id_type> dof_indices;
801 for (
const auto & elem :
mesh.active_local_element_ptr_range())
806 perf_log.
push(
"elem init");
812 dof_map.dof_indices (elem, dof_indices);
820 const unsigned int n_dofs =
821 cast_int<unsigned int>(dof_indices.size());
829 Ke.
resize (n_dofs, n_dofs);
836 perf_log.
pop(
"elem init");
844 perf_log.
push (
"Ke");
846 std::vector<dof_id_type> dof_indices_u;
847 dof_map.dof_indices (elem, dof_indices_u, 0);
848 const unsigned int n_u_dofs = dof_indices_u.size();
849 libmesh_assert_equal_to (n_u_dofs, phi.size());
850 libmesh_assert_equal_to (n_u_dofs, dphi.size());
852 for (
unsigned int v=0; v !=
n_vars; ++v)
855 Kuu.
reposition (v*n_u_dofs, v*n_u_dofs, n_u_dofs, n_u_dofs);
857 for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
858 for (
unsigned int i=0; i != n_u_dofs; i++)
859 for (
unsigned int j=0; j != n_u_dofs; j++)
860 Kuu(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]);
868 for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
870 Real x = q_point[qp](0);
873 for (
unsigned int i=0; i != n_u_dofs; ++i)
874 Fu(i) += JxW[qp]*phi[i][qp]*f;
888 LOG_SCOPE_WITH(
"matrix insertion",
"", perf_log);
892 dof_map.heterogenously_constrain_element_matrix_and_vector(Ke, Fe, dof_indices);
void assemble_laplace(EquationSystems &es, const std::string &system_name)
Gradient(* exact_derivative)(const Point &p, const Parameters &, const std::string &, const std::string &)
Number(* exact_solution)(const Point &p, const Parameters &, const std::string &, const std::string &)
Defines a dense matrix for use in Finite Element-type computations.
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
Defines a dense submatrix for use in Finite Element-type computations.
void reposition(const unsigned int ioff, const unsigned int joff, const unsigned int new_m, const unsigned int new_n)
Changes the location of the submatrix in the parent matrix.
Defines a dense subvector for use in finite element computations.
void reposition(const unsigned int ioff, const unsigned int n)
Changes the location of the subvector in the parent vector.
Defines a dense vector for use in Finite Element-type computations.
void resize(const unsigned int n)
Resize the vector.
This class allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
This class measures discontinuities between elements for debugging purposes.
This class handles the numbering of degrees of freedom on a mesh.
void add_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary)
Adds a copy of the specified Dirichlet boundary to the system.
void add_algebraic_ghosting_functor(GhostingFunctor &evaluable_functor, bool to_mesh=true)
Adds a functor which can specify algebraic ghosting requirements for use with distributed vectors.
This is the EquationSystems class.
virtual void reinit()
Handle any mesh changes and reinitialize all the systems on the updated mesh.
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
std::size_t n_active_dofs() const
const MeshBase & get_mesh() const
Parameters parameters
Data structure holding arbitrary parameters.
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.
const T_sys & get_system(std::string_view name) const
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
virtual Real mean() const override
void plot_error(const std::string &filename, const MeshBase &mesh, const std::string &data_type="error") const
Plots a data file, of a type determined by looking at the file extension in filename,...
This class implements an "error estimator" based on the difference between the approximate and exact ...
virtual void estimate_error(const System &system, ErrorVector &error_per_cell, const NumericVector< Number > *solution_vector=nullptr, bool estimate_parent_error=false) override
This function uses the exact solution function to estimate the error on each cell.
void attach_exact_deriv(unsigned int sys_num, FunctionBase< Gradient > *g)
Clone and attach an arbitrary functor which computes the exact gradient of the system sys_num solutio...
void attach_exact_value(unsigned int sys_num, FunctionBase< Number > *f)
Clone and attach an arbitrary functor which computes the exact value of the system sys_num solution a...
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 h1_error(std::string_view sys_name, std::string_view unknown_name)
void attach_exact_deriv(unsigned int sys_num, FunctionBase< Gradient > *g)
Clone and attach an arbitrary functor which computes the exact gradient of the system sys_num solutio...
void attach_exact_value(unsigned int sys_num, FunctionBase< Number > *f)
Clone and attach an arbitrary functor which computes the exact value of the system sys_num solution a...
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.
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
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.
NumericVector< Number > * rhs
The system matrix.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
This class uses the error estimate given by different types of derefinement (h coarsening or p reduct...
virtual void select_refinement(System &system) override
This pure virtual function must be redefined in derived classes to take a mesh flagged for h refineme...
This class uses a user-provided list of singularity locations to choose between h refining and p elev...
std::list< Point > singular_points
This list, to be filled by the user, should include all singular points in the solution.
virtual void select_refinement(System &system)
This pure virtual function must be redefined in derived classes to take a mesh flagged for h refineme...
const SparseMatrix< Number > & get_system_matrix() const
bool use_unweighted_quadrature_rules
This boolean flag allows you to use "unweighted" quadrature rules (sized to exactly integrate unweigh...
virtual void estimate_error(const System &system, ErrorVector &error_per_cell, const NumericVector< Number > *solution_vector=nullptr, bool estimate_parent_error=false) override
This function uses the derived class's jump error estimate formula to estimate the error on each cell...
This class implements the Kelly error indicator which is based on the flux jumps between elements.
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
Real final_linear_residual() const
virtual void solve() override
Assembles & solves the linear system A*x=b.
unsigned int n_linear_iterations() const
This is the MeshBase class.
unsigned int mesh_dimension() const
void all_second_order(const bool full_ordered=true)
Calls the range-based version of this function with a range consisting of all elements in the mesh.
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false, bool skip_detect_interior_parents=false)=0
Interfaces for reading/writing a mesh to/from a file.
virtual void clear()
Deletes all the element and node data that is currently stored.
virtual void all_complete_order()
Calls the range-based version of this function with a range consisting of all elements in the mesh.
Implements (adaptive) mesh refinement algorithms for a MeshBase.
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
void switch_h_to_p_refinement()
Takes a mesh whose elements are flagged for h refinement and coarsening, and switches those flags to ...
void flag_elements_by_error_fraction(const ErrorVector &error_per_cell, const Real refine_fraction=0.3, const Real coarsen_fraction=0.0, const unsigned int max_level=libMesh::invalid_uint)
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell.
unsigned int & max_h_level()
The max_h_level is the greatest refinement level an element should reach.
void add_p_to_h_refinement()
Takes a mesh whose elements are flagged for h refinement and coarsening, and adds flags to request p ...
bool refine_and_coarsen_elements()
Refines and coarsens user-requested elements.
Real & refine_fraction()
The refine_fraction sets either a desired target or a desired maximum number of elements to flag for ...
void uniformly_p_refine(unsigned int n=1)
Uniformly p refines the mesh n times.
Real & coarsen_fraction()
The coarsen_fraction sets either a desired target or a desired maximum number of elements to flag for...
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
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].
This class provides the ability to map between arbitrary, user-defined strings and several data types...
T & set(const std::string &)
This class implements the Patch Recovery error indicator.
virtual void estimate_error(const System &system, ErrorVector &error_per_cell, const NumericVector< Number > *solution_vector=nullptr, bool estimate_parent_error=false) override
This function uses the Patch Recovery error estimate to estimate the error on each cell.
The PerfLog class allows monitoring of specific events.
void pop(const char *label, const char *header="")
Pop the event label off the stack, resuming any lower event.
void push(const char *label, const char *header="")
Push the event label onto the stack, pausing any active event.
A Point defines a location in LIBMESH_DIM dimensional Real space.
This class adds coupling (for use in send_list construction) between active elements and all descenda...
This class implements the Smoothness estimate.
virtual void estimate_smoothness(const System &system, ErrorVector &smoothness_per_cell, const NumericVector< Number > *solution_vector=nullptr)
This function uses the Legendre expansion of solution to estimate coefficient decay to quantify the s...
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.
void attach_assemble_function(void fptr(EquationSystems &es, const std::string &name))
Register a user function to use in assembling the system matrix and RHS.
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.
const DofMap & get_dof_map() const
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
Wrap a libMesh-style function pointer into a FunctionBase object.
Gradient exact_grad(const Point &, const Parameters &, const std::string &, const std::string &)
The libMesh namespace provides an interface to certain functionality in the library.
void libmesh_ignore(const Args &...)
SolverPackage default_solver_package()
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real