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/patch_recovery_error_estimator.h" 65 #include "libmesh/uniform_refinement_estimator.h" 66 #include "libmesh/hp_coarsentest.h" 67 #include "libmesh/hp_singular.h" 68 #include "libmesh/sibling_coupling.h" 69 #include "libmesh/mesh_generation.h" 70 #include "libmesh/mesh_modification.h" 71 #include "libmesh/perf_log.h" 72 #include "libmesh/getpot.h" 73 #include "libmesh/exact_solution.h" 74 #include "libmesh/dof_map.h" 75 #include "libmesh/numeric_vector.h" 76 #include "libmesh/elem.h" 77 #include "libmesh/string_to_enum.h" 78 #include "libmesh/enum_solver_package.h" 79 #include "libmesh/dirichlet_boundaries.h" 80 #include "libmesh/wrapped_function.h" 92 const std::string & system_name);
100 const std::string &);
106 const std::string &);
122 int main(
int argc,
char ** argv)
129 "--enable-petsc, --enable-trilinos, or --enable-eigen");
132 libmesh_example_requires(
sizeof(
Real) > 4,
"--disable-singleprecision");
135 #ifndef LIBMESH_ENABLE_AMR 136 libmesh_example_requires(
false,
"--enable-amr");
140 GetPot input_file(
"adaptivity_ex3.in");
143 input_file.parse_command_line(argc, argv);
146 const unsigned int max_r_steps = input_file(
"max_r_steps", 3);
147 const unsigned int max_r_level = input_file(
"max_r_level", 3);
148 const Real refine_percentage = input_file(
"refine_percentage", 0.5);
149 const Real coarsen_percentage = input_file(
"coarsen_percentage", 0.5);
150 const unsigned int uniform_refine = input_file(
"uniform_refine",0);
151 const std::string refine_type = input_file(
"refinement_type",
"h");
152 const std::string approx_type = input_file(
"approx_type",
"LAGRANGE");
153 const unsigned int approx_order = input_file(
"approx_order", 1);
155 const std::string element_type = input_file(
"element_type",
"tensor");
156 const int extra_error_quadrature = input_file(
"extra_error_quadrature", 0);
157 const int max_linear_iterations = input_file(
"max_linear_iterations", 5000);
159 #ifdef LIBMESH_HAVE_EXODUS_API 160 const bool output_intermediate = input_file(
"output_intermediate",
false);
166 #if !defined(LIBMESH_ENABLE_SECOND_DERIVATIVES) 167 libmesh_example_requires(approx_type !=
"HERMITE",
"--enable-second");
170 dim = input_file(
"dimension", 2);
171 const std::string indicator_type = input_file(
"indicator_type",
"kelly");
173 const bool extrusion = input_file(
"extrusion",
false);
174 const bool complete = input_file(
"complete",
false);
175 libmesh_error_msg_if(extrusion &&
dim < 3,
"Extrusion option is only for 3D meshes");
178 libmesh_example_requires(
dim <= LIBMESH_DIM,
"2D/3D support");
182 std::string approx_name =
"";
183 if (element_type ==
"tensor")
185 if (approx_order == 1)
186 approx_name +=
"linear";
187 else if (approx_order == 2)
188 approx_name +=
"quadratic";
189 else if (approx_order == 3)
190 approx_name +=
"cubic";
191 else if (approx_order == 4)
192 approx_name +=
"quartic";
194 std::string output_file = approx_name;
196 output_file += refine_type;
197 if (uniform_refine == 0)
198 output_file +=
"_adaptive.m";
200 output_file +=
"_uniform.m";
202 std::ofstream
out (output_file.c_str());
203 out <<
"% dofs L2-error H1-error" << std::endl;
204 out <<
"e = [" << std::endl;
224 if (refine_type ==
"hp")
230 else if (
dim == 2 || extrusion ==
true)
236 if (element_type ==
"simplex")
252 else if (approx_order > 1 || refine_type !=
"h")
265 system.
add_variable(
"u", static_cast<Order>(approx_order),
266 Utility::string_to_enum<FEFamily>(approx_type));
268 std::vector<unsigned int> all_vars(1, u_var);
271 for (
unsigned int var_num=1; var_num <
n_vars; ++var_num)
273 std::ostringstream var_name;
274 var_name <<
"u" << var_num;
275 unsigned int next_var =
277 static_cast<Order>(approx_order),
278 Utility::string_to_enum<FEFamily>(approx_type));
279 all_vars.push_back(next_var);
293 equation_systems.init();
296 equation_systems.parameters.set<
unsigned int>(
"linear solver maximum iterations")
297 = max_linear_iterations;
300 equation_systems.parameters.set<
Real>(
"linear solver tolerance") =
304 equation_systems.print_info();
319 << exact_sol.
l2_error(
"Laplace",
"u")
322 << exact_sol.
h1_error(
"Laplace",
"u")
326 for (
unsigned int r_step=0; r_step<max_r_steps; r_step++)
328 libMesh::out <<
"Beginning Solve " << r_step << std::endl;
334 << equation_systems.n_active_dofs()
335 <<
" degrees of freedom." 340 <<
", final residual: " 344 #ifdef LIBMESH_HAVE_EXODUS_API 347 if (output_intermediate)
349 std::ostringstream outfile;
350 outfile <<
"lshaped_" << r_step <<
".e";
354 #endif // #ifdef LIBMESH_HAVE_EXODUS_API 362 libmesh_error_msg(
"NaN solve result");
366 << exact_sol.
l2_error(
"Laplace",
"u")
369 << exact_sol.
h1_error(
"Laplace",
"u")
386 Real mean_disc_error = disc_error.
mean();
388 libMesh::out <<
"Mean discontinuity error = " << mean_disc_error << std::endl;
391 #ifdef LIBMESH_ENABLE_PETSC 392 libmesh_assert_less (mean_disc_error, 1e-14);
397 out << equation_systems.n_active_dofs() <<
" " 398 << exact_sol.
l2_error(
"Laplace",
"u") <<
" " 399 << exact_sol.
h1_error(
"Laplace",
"u") << std::endl;
402 if (r_step+1 != max_r_steps)
406 if (uniform_refine == 0)
413 if (indicator_type ==
"exact")
440 else if (indicator_type ==
"patch")
449 else if (indicator_type ==
"uniform")
459 libmesh_assert_equal_to (indicator_type,
"kelly");
478 std::ostringstream ss;
480 #ifdef LIBMESH_HAVE_EXODUS_API 481 # ifdef LIBMESH_HAVE_NEMESIS_API 482 std::string error_output =
"error_" + ss.str() +
".n";
484 std::string error_output =
"error_" + ss.str() +
".e";
487 std::string error_output =
"error_" + ss.str() +
".gmv";
502 if (refine_type ==
"p")
506 else if (refine_type ==
"matchedhp")
510 else if (refine_type ==
"hp")
517 else if (refine_type ==
"singularhp")
528 libmesh_error_msg_if(refine_type !=
"h",
529 "Unknown refinement_type = " << refine_type);
536 else if (uniform_refine == 1)
538 if (refine_type ==
"h" || refine_type ==
"hp" ||
539 refine_type ==
"matchedhp")
541 if (refine_type ==
"p" || refine_type ==
"hp" ||
542 refine_type ==
"matchedhp")
551 equation_systems.reinit ();
555 #ifdef LIBMESH_HAVE_EXODUS_API 561 #endif // #ifdef LIBMESH_HAVE_EXODUS_API 564 out <<
"];" << std::endl;
565 out <<
"hold on" << std::endl;
566 out <<
"plot(e(:,1), e(:,2), 'bo-');" << std::endl;
567 out <<
"plot(e(:,1), e(:,3), 'ro-');" << std::endl;
570 out <<
"xlabel('dofs');" << std::endl;
571 out <<
"title('" << approx_name <<
" elements');" << std::endl;
572 out <<
"legend('L2-error', 'H1-error');" << std::endl;
577 #endif // #ifndef LIBMESH_ENABLE_AMR 595 const Real y = (
dim > 1) ? p(1) : 0.;
601 Real theta = atan2(y, x);
608 const Real z = (
dim > 2) ? p(2) : 0;
610 return pow(x*x + y*y, 1./3.)*sin(2./3.*theta) + z;
616 const Real z = (
dim > 2) ? p(2) : 0;
618 return cos(x) * exp(y) * (1. - z);
639 const Real y =
dim > 1 ? p(1) : 0.;
644 libmesh_assert_not_equal_to (x, 0.);
647 const Real tt = 2./3.;
648 const Real ot = 1./3.;
651 const Real r2 = x*x + y*y;
655 Real theta = atan2(y, x);
662 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;
666 gradu(1) = tt*y*
pow(r2,-tt)*sin(tt*theta) +
pow(r2,ot)*cos(tt*theta)*tt/(1.+y*y/x/x)*1./x;
673 const Real z = (
dim > 2) ? p(2) : 0;
675 gradu(0) = -sin(x) * exp(y) * (1. - z);
677 gradu(1) = cos(x) * exp(y) * (1. - z);
679 gradu(2) = -cos(x) * exp(y);
696 const std::string & system_name)
701 #ifdef LIBMESH_ENABLE_AMR 704 libmesh_assert_equal_to (system_name,
"Laplace");
710 PerfLog perf_log (
"Matrix Assembly",
false);
729 FEType fe_type = dof_map.variable_type(0);
735 std::unique_ptr<FEBase> fe (
FEBase::build(mesh_dim, fe_type));
736 std::unique_ptr<FEBase> fe_face (
FEBase::build(mesh_dim, fe_type));
743 fe->attach_quadrature_rule (qrule.get());
744 fe_face->attach_quadrature_rule (qface.get());
750 const std::vector<Real> & JxW = fe->get_JxW();
755 const std::vector<Point> & q_point = fe->get_xyz();
758 const std::vector<std::vector<Real>> & phi = fe->get_phi();
762 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
774 std::vector<dof_id_type> dof_indices;
788 for (
const auto & elem :
mesh.active_local_element_ptr_range())
793 perf_log.
push(
"elem init");
799 dof_map.dof_indices (elem, dof_indices);
807 const unsigned int n_dofs =
808 cast_int<unsigned int>(dof_indices.size());
816 Ke.
resize (n_dofs, n_dofs);
823 perf_log.
pop(
"elem init");
831 perf_log.
push (
"Ke");
833 std::vector<dof_id_type> dof_indices_u;
834 dof_map.dof_indices (elem, dof_indices_u, 0);
835 const unsigned int n_u_dofs = dof_indices_u.size();
836 libmesh_assert_equal_to (n_u_dofs, phi.size());
837 libmesh_assert_equal_to (n_u_dofs, dphi.size());
839 for (
unsigned int v=0; v !=
n_vars; ++v)
842 Kuu.
reposition (v*n_u_dofs, v*n_u_dofs, n_u_dofs, n_u_dofs);
844 for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
845 for (
unsigned int i=0; i != n_u_dofs; i++)
846 for (
unsigned int j=0; j != n_u_dofs; j++)
847 Kuu(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]);
855 for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
857 Real x = q_point[qp](0);
860 for (
unsigned int i=0; i != n_u_dofs; ++i)
861 Fu(i) += JxW[qp]*phi[i][qp]*f;
875 LOG_SCOPE_WITH(
"matrix insertion",
"", perf_log);
879 dof_map.heterogenously_constrain_element_matrix_and_vector(Ke, Fe, dof_indices);
887 #endif // #ifdef LIBMESH_ENABLE_AMR class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
This class handles the computation of the L2 and/or H1 error for the Systems in the EquationSystems o...
Wrap a libMesh-style function pointer into a FunctionBase object.
void uniformly_p_refine(unsigned int n=1)
Uniformly p refines the mesh n times.
This is the EquationSystems class.
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false)=0
Interfaces for reading/writing a mesh to/from a file.
void assemble_laplace(EquationSystems &es, const std::string &system_name)
void pop(const char *label, const char *header="")
Pop the event label off the stack, resuming any lower event.
Order
defines an enum for polynomial orders.
This class provides the ability to map between arbitrary, user-defined strings and several data types...
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...
static constexpr Real TOLERANCE
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
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]...
Real & coarsen_fraction()
The coarsen_fraction sets either a desired target or a desired maximum number of elements to flag for...
void extra_quadrature_order(const int extraorder)
Increases or decreases the order of the quadrature rule used for numerical integration.
NumericVector< Number > * rhs
The system matrix.
This class allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
Real & refine_fraction()
The refine_fraction sets either a desired target or a desired maximum number of elements to flag for ...
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
The libMesh namespace provides an interface to certain functionality in the library.
virtual void solve() override
Assembles & solves the linear system A*x=b.
const T_sys & get_system(std::string_view name) const
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...
unsigned int & max_h_level()
The max_h_level is the greatest refinement level an element should reach.
This class measures discontinuities between elements for debugging purposes.
This is the MeshBase class.
Gradient exact_grad(const Point &, const Parameters &, const std::string &, const std::string &)
Defines a dense subvector for use in finite element computations.
std::list< Point > singular_points
This list, to be filled by the user, should include all singular points in the solution.
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.
SolverPackage default_solver_package()
The PerfLog class allows monitoring of specific events.
This class handles the numbering of degrees of freedom on a mesh.
void switch_h_to_p_refinement()
Takes a mesh whose elements are flagged for h refinement and coarsening, and switches those flags to ...
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
void reposition(const unsigned int ioff, const unsigned int n)
Changes the location of the subvector in the parent vector.
void libmesh_ignore(const Args &...)
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.
Real final_linear_residual() const
Implements (adaptive) mesh refinement algorithms for a MeshBase.
int main(int argc, char **argv)
unsigned int n_linear_iterations() const
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.
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(...
Defines a dense submatrix for use in Finite Element-type computations.
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.
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...
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.
void push(const char *label, const char *header="")
Push the event label onto the stack, pausing any active event.
Number exact_solution(const Point &p, const Parameters &, const std::string &, const std::string &)
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.
Real l2_error(std::string_view sys_name, std::string_view unknown_name)
void plot_error(const std::string &filename, const MeshBase &mesh) const
Plots a data file, of a type determined by looking at the file extension in filename, of the error values on the active elements of mesh.
virtual void clear()
Deletes all the element and node data that is currently stored.
virtual void select_refinement(System &system)
This pure virtual function must be redefined in derived classes to take a mesh flagged for h refineme...
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...
Gradient exact_derivative(const Point &p, const Parameters &, const std::string &, const std::string &)
This class implements the Kelly error indicator which is based on the flux jumps between elements...
This class uses the error estimate given by different types of derefinement (h coarsening or p reduct...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
This class adds coupling (for use in send_list construction) between active elements and all descenda...
This class implements an "error estimator" based on the difference between the approximate and exact ...
virtual void all_complete_order()
Calls the range-based version of this function with a range consisting of all elements in the mesh...
This class implements the Patch Recovery error indicator.
bool refine_and_coarsen_elements()
Refines and coarsens user-requested elements.
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().
bool use_unweighted_quadrature_rules
This boolean flag allows you to use "unweighted" quadrature rules (sized to exactly integrate unweigh...
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...
unsigned int mesh_dimension() const
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...
void add_dirichlet_boundary(const DirichletBoundary &dirichlet_boundary)
Adds a copy of the specified Dirichlet boundary to the system.
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.
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 add_p_to_h_refinement()
Takes a mesh whose elements are flagged for h refinement and coarsening, and adds flags to request p ...
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 uses a user-provided list of singularity locations to choose between h refining and p elev...
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 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...
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Real h1_error(std::string_view sys_name, std::string_view unknown_name)
const DofMap & get_dof_map() const
A Point defines a location in LIBMESH_DIM dimensional Real space.
const SparseMatrix< Number > & get_system_matrix() const
virtual Real mean() const override
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.