Go to the documentation of this file.
   38 #include "libmesh/mesh.h" 
   39 #include "libmesh/equation_systems.h" 
   40 #include "libmesh/linear_implicit_system.h" 
   41 #include "libmesh/exodusII_io.h" 
   42 #include "libmesh/fe.h" 
   43 #include "libmesh/quadrature.h" 
   44 #include "libmesh/dense_matrix.h" 
   45 #include "libmesh/dense_vector.h" 
   46 #include "libmesh/sparse_matrix.h" 
   47 #include "libmesh/mesh_generation.h" 
   48 #include "libmesh/mesh_modification.h" 
   49 #include "libmesh/mesh_refinement.h" 
   50 #include "libmesh/error_vector.h" 
   51 #include "libmesh/fourth_error_estimators.h" 
   52 #include "libmesh/getpot.h" 
   53 #include "libmesh/exact_solution.h" 
   54 #include "libmesh/dof_map.h" 
   55 #include "libmesh/numeric_vector.h" 
   56 #include "libmesh/elem.h" 
   57 #include "libmesh/tensor_value.h" 
   58 #include "libmesh/perf_log.h" 
   59 #include "libmesh/string_to_enum.h" 
   60 #include "libmesh/enum_solver_package.h" 
   72                          const std::string & system_name);
 
  103                              const std::string &);
 
  108                              const std::string &);
 
  113                         const std::string &);
 
  118                         const std::string &);
 
  123                         const std::string &);
 
  135                          const std::string &);
 
  140                              const std::string &);
 
  145                         const std::string &);
 
  151 int main(
int argc, 
char ** argv)
 
  158                            "--enable-petsc, --enable-trilinos, or --enable-eigen");
 
  162 #ifdef LIBMESH_DEFAULT_SINGLE_PRECISION 
  163   libmesh_example_requires(
false, 
"double precision");
 
  167 #ifndef LIBMESH_ENABLE_AMR 
  168   libmesh_example_requires(
false, 
"--enable-amr");
 
  172 #ifndef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  173   libmesh_example_requires(
false, 
"--enable-second");
 
  177   GetPot input_file(
"adaptivity_ex4.in");
 
  180   input_file.parse_command_line(argc, argv);
 
  183   const unsigned int max_r_level = input_file(
"max_r_level", 10);
 
  184   const unsigned int max_r_steps = input_file(
"max_r_steps", 4);
 
  185   const std::string approx_type  = input_file(
"approx_type", 
"HERMITE");
 
  186   const std::string approx_order_string = input_file(
"approx_order", 
"THIRD");
 
  187   const unsigned int uniform_refine = input_file(
"uniform_refine", 0);
 
  188   const Real refine_percentage = input_file(
"refine_percentage", 0.5);
 
  189   const Real coarsen_percentage = input_file(
"coarsen_percentage", 0.5);
 
  190   const unsigned int dim = input_file(
"dimension", 2);
 
  191   const unsigned int max_linear_iterations = input_file(
"max_linear_iterations", 10000);
 
  194   libmesh_example_requires(
dim <= LIBMESH_DIM, 
"2D/3D support");
 
  204   std::string output_file = 
"";
 
  207     output_file += 
"1D_";
 
  209     output_file += 
"2D_";
 
  211     output_file += 
"3D_";
 
  213   if (approx_type == 
"HERMITE")
 
  214     output_file += 
"hermite_";
 
  215   else if (approx_type == 
"SECOND")
 
  216     output_file += 
"reducedclough_";
 
  218     output_file += 
"clough_";
 
  220   if (uniform_refine == 0)
 
  221     output_file += 
"adaptive";
 
  223     output_file += 
"uniform";
 
  225 #ifdef LIBMESH_HAVE_EXODUS_API 
  227   std::string exd_file = output_file;
 
  229 #endif // #ifdef LIBMESH_HAVE_EXODUS_API 
  233   std::ofstream 
out (output_file.c_str());
 
  234   out << 
"% dofs     L2-error     H1-error      H2-error\n" 
  270   if (approx_type != 
"HERMITE")
 
  287   Order approx_order = approx_type == 
"SECOND" ? 
SECOND :
 
  288     Utility::string_to_enum<Order>(approx_order_string);
 
  293   if (approx_type == 
"HERMITE")
 
  295   else if (approx_type == 
"SECOND")
 
  297   else if (approx_type == 
"CLOUGH")
 
  300     libmesh_error_msg(
"Invalid approx_type = " << approx_type);
 
  307   equation_systems.
init();
 
  311     (
"linear solver maximum iterations") = max_linear_iterations;
 
  331   for (
unsigned int r_step=0; r_step<max_r_steps; r_step++)
 
  336       libMesh::out << 
"Beginning Solve " << r_step << std::endl;
 
  343                    << 
", final residual: " 
  354                    << zero_sol.
l2_error(
"Biharmonic", 
"u")
 
  357                    << zero_sol.
h1_error(
"Biharmonic", 
"u")
 
  360                    << zero_sol.
h2_error(
"Biharmonic", 
"u")
 
  364                    << exact_sol.
l2_error(
"Biharmonic", 
"u")
 
  367                    << exact_sol.
h1_error(
"Biharmonic", 
"u")
 
  370                    << exact_sol.
h2_error(
"Biharmonic", 
"u")
 
  376           << exact_sol.
l2_error(
"Biharmonic", 
"u") << 
" " 
  377           << exact_sol.
h1_error(
"Biharmonic", 
"u") << 
" " 
  378           << exact_sol.
h2_error(
"Biharmonic", 
"u") << std::endl;
 
  381       if (r_step+1 != max_r_steps)
 
  385           if (uniform_refine == 0)
 
  415           equation_systems.
reinit ();
 
  419 #ifdef LIBMESH_HAVE_EXODUS_API 
  424 #endif // #ifdef LIBMESH_HAVE_EXODUS_API 
  429       << 
"loglog(e(:,1), e(:,2), 'bo-');\n" 
  430       << 
"loglog(e(:,1), e(:,3), 'ro-');\n" 
  431       << 
"loglog(e(:,1), e(:,4), 'go-');\n" 
  432       << 
"xlabel('log(dofs)');\n" 
  433       << 
"ylabel('log(error)');\n" 
  434       << 
"title('C1 " << approx_type << 
" elements');\n" 
  435       << 
"legend('L2-error', 'H1-error', 'H2-error');\n";
 
  439 #endif // #ifndef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  440 #endif // #ifndef LIBMESH_ENABLE_AMR 
  454   return 256.*(x-x*x)*(x-x*x);
 
  470   gradu(0) = 256.*2.*(x-x*x)*(1-2*x);
 
  488   hessu(0,0) = 256.*2.*(1-6.*x+6.*x*x);
 
  498   return 256. * 2. * 12.;
 
  512   return 256.*(x-x*x)*(x-x*x)*(y-y*y)*(y-y*y);
 
  529   gradu(0) = 256.*2.*(x-x*x)*(1-2*x)*(y-y*y)*(y-y*y);
 
  530   gradu(1) = 256.*2.*(x-x*x)*(x-x*x)*(y-y*y)*(1-2*y);
 
  549   hessu(0,0) = 256.*2.*(1-6.*x+6.*x*x)*(y-y*y)*(y-y*y);
 
  550   hessu(0,1) = 256.*4.*(x-x*x)*(1.-2.*x)*(y-y*y)*(1.-2.*y);
 
  551   hessu(1,1) = 256.*2.*(x-x*x)*(x-x*x)*(1.-6.*y+6.*y*y);
 
  554   hessu(1,0) = hessu(0,1);
 
  567   return 256. * 8. * (3.*((y-y*y)*(y-y*y)+(x-x*x)*(x-x*x))
 
  568                       + (1.-6.*x+6.*x*x)*(1.-6.*y+6.*y*y));
 
  584   return 4096.*(x-x*x)*(x-x*x)*(y-y*y)*(y-y*y)*(z-z*z)*(z-z*z);
 
  601   gradu(0) = 4096.*2.*(x-x*x)*(1.-2.*x)*(y-y*y)*(y-y*y)*(z-z*z)*(z-z*z);
 
  602   gradu(1) = 4096.*2.*(x-x*x)*(x-x*x)*(y-y*y)*(1.-2.*y)*(z-z*z)*(z-z*z);
 
  603   gradu(2) = 4096.*2.*(x-x*x)*(x-x*x)*(y-y*y)*(y-y*y)*(z-z*z)*(1.-2.*z);
 
  623   hessu(0,0) = 4096.*(2.-12.*x+12.*x*x)*(y-y*y)*(y-y*y)*(z-z*z)*(z-z*z);
 
  624   hessu(0,1) = 4096.*4.*(x-x*x)*(1.-2.*x)*(y-y*y)*(1.-2.*y)*(z-z*z)*(z-z*z);
 
  625   hessu(0,2) = 4096.*4.*(x-x*x)*(1.-2.*x)*(y-y*y)*(y-y*y)*(z-z*z)*(1.-2.*z);
 
  626   hessu(1,1) = 4096.*(x-x*x)*(x-x*x)*(2.-12.*y+12.*y*y)*(z-z*z)*(z-z*z);
 
  627   hessu(1,2) = 4096.*4.*(x-x*x)*(x-x*x)*(y-y*y)*(1.-2.*y)*(z-z*z)*(1.-2.*z);
 
  628   hessu(2,2) = 4096.*(x-x*x)*(x-x*x)*(y-y*y)*(y-y*y)*(2.-12.*z+12.*z*z);
 
  631   hessu(1,0) = hessu(0,1);
 
  632   hessu(2,0) = hessu(0,2);
 
  633   hessu(2,1) = hessu(1,2);
 
  648   return 4096. * 8. * (3.*((y-y*y)*(y-y*y)*(x-x*x)*(x-x*x) +
 
  649                            (z-z*z)*(z-z*z)*(x-x*x)*(x-x*x) +
 
  650                            (z-z*z)*(z-z*z)*(y-y*y)*(y-y*y)) +
 
  651                        (1.-6.*x+6.*x*x)*(1.-6.*y+6.*y*y)*(z-z*z)*(z-z*z) +
 
  652                        (1.-6.*x+6.*x*x)*(1.-6.*z+6.*z*z)*(y-y*y)*(y-y*y) +
 
  653                        (1.-6.*y+6.*y*y)*(1.-6.*z+6.*z*z)*(x-x*x)*(x-x*x));
 
  664                          const std::string & system_name)
 
  669 #ifdef LIBMESH_ENABLE_AMR 
  670 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  674   libmesh_assert_equal_to (system_name, 
"Biharmonic");
 
  680   PerfLog perf_log (
"Matrix Assembly", 
false);
 
  699   FEType fe_type = dof_map.variable_type(0);
 
  713   fe->attach_quadrature_rule (qrule.get());
 
  727   fe_face->attach_quadrature_rule (qface.get());
 
  733   const std::vector<Real> & JxW = fe->get_JxW();
 
  738   const std::vector<Point> & q_point = fe->get_xyz();
 
  741   const std::vector<std::vector<Real>> & phi = fe->get_phi();
 
  746   const std::vector<std::vector<RealTensor>> & d2phi = fe->get_d2phi();
 
  750   std::vector<Real> shape_laplacian;
 
  762   std::vector<dof_id_type> dof_indices;
 
  772       perf_log.
push(
"elem init");
 
  778       dof_map.dof_indices (elem, dof_indices);
 
  786       const unsigned int n_dofs =
 
  787         cast_int<unsigned int>(dof_indices.size());
 
  788       libmesh_assert_equal_to (n_dofs, phi.size());
 
  792       Ke.
resize (n_dofs, n_dofs);
 
  797       shape_laplacian.resize(n_dofs);
 
  802       perf_log.
pop(
"elem init");
 
  813       perf_log.
push (
"Ke");
 
  815       for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  817           for (
unsigned int i=0; i != n_dofs; i++)
 
  819               shape_laplacian[i] = d2phi[i][qp](0,0);
 
  821                 shape_laplacian[i] += d2phi[i][qp](1,1);
 
  823                 shape_laplacian[i] += d2phi[i][qp](2,2);
 
  825           for (
unsigned int i=0; i != n_dofs; i++)
 
  826             for (
unsigned int j=0; j != n_dofs; j++)
 
  828                 shape_laplacian[i]*shape_laplacian[j];
 
  845         LOG_SCOPE_WITH(
"BCs", 
"", perf_log);
 
  848         const Real penalty = 1e10;
 
  849         const Real penalty2 = 1e10;
 
  854         for (
auto s : elem->side_index_range())
 
  855           if (elem->neighbor_ptr(s) == 
nullptr)
 
  859               const std::vector<std::vector<Real>> & phi_face =
 
  864               const std::vector<std::vector<RealGradient>> & dphi_face =
 
  869               const std::vector<Real> & JxW_face = fe_face->get_JxW();
 
  874               const std::vector<Point> & qface_point = fe_face->get_xyz();
 
  875               const std::vector<Point> & face_normals = fe_face->get_normals();
 
  879               fe_face->reinit(elem, s);
 
  881               libmesh_assert_equal_to (n_dofs, phi_face.size());
 
  884               for (
unsigned int qp=0; qp<qface->n_points(); qp++)
 
  899                   for (
unsigned int i=0; i != n_dofs; i++)
 
  900                     for (
unsigned int j=0; j != n_dofs; j++)
 
  901                       Ke(i,j) += JxW_face[qp] *
 
  902                         (penalty * phi_face[i][qp] *
 
  903                          phi_face[j][qp] + penalty2
 
  904                          * (dphi_face[i][qp] *
 
  911                   for (
unsigned int i=0; i != n_dofs; i++)
 
  912                     Fe(i) += JxW_face[qp] *
 
  913                       (penalty * 
value * phi_face[i][qp]
 
  915                        (flux * face_normals[qp])
 
  917                           * face_normals[qp]));
 
  923       for (
unsigned int qp=0; qp<qrule->n_points(); qp++)
 
  924         for (
unsigned int i=0; i != n_dofs; i++)
 
  933       LOG_SCOPE_WITH(
"matrix insertion", 
"", perf_log);
 
  935       dof_map.constrain_element_matrix_and_vector(Ke, Fe, dof_indices);
 
  946 #endif // #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  947 #endif // #ifdef LIBMESH_ENABLE_AMR 
  
This class handles the computation of the L2 and/or H1 error for the Systems in the EquationSystems o...
 
Number forcing_function_1D(const Point &p)
 
bool refine_and_coarsen_elements()
Refines and coarsens user-requested elements.
 
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
 
Tensor exact_1D_hessian(const Point &p, const Parameters &, const std::string &, const std::string &)
 
Gradient exact_3D_derivative(const Point &p, const Parameters &, const std::string &, const std::string &)
 
Number exact_2D_solution(const Point &p, const Parameters &, const std::string &, const std::string &)
 
virtual System & add_system(const std::string &system_type, const std::string &name)
Add the system of type system_type named name to the systems array.
 
const MeshBase & get_mesh() const
 
Number(* exact_solution)(const Point &p, const Parameters &, const std::string &, const std::string &)
 
Tensor exact_2D_hessian(const Point &p, const Parameters &, const std::string &, const std::string &)
 
NumericVector< Number > * rhs
The system matrix.
 
virtual void all_second_order(const bool full_ordered=true)=0
Converts a (conforming, non-refined) mesh with linear elements into a mesh with second-order elements...
 
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 is an error indicator based on laplacian jumps between elements.
 
virtual SimpleRange< element_iterator > active_local_element_ptr_range()=0
 
The libMesh namespace provides an interface to certain functionality in the library.
 
const T_sys & get_system(const std::string &name) const
 
Real h1_error(const std::string &sys_name, const std::string &unknown_name)
 
static const Real TOLERANCE
 
virtual void solve() override
Assembles & solves the linear system A*x=b.
 
SolverPackage default_solver_package()
 
Number forcing_function_3D(const Point &p)
 
unsigned int mesh_dimension() const
 
Real h2_error(const std::string &sys_name, const std::string &unknown_name)
 
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
 
void resize(const unsigned int new_m, const unsigned int new_n)
Resize the matrix.
 
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
 
Implements (adaptive) mesh refinement algorithms for a MeshBase.
 
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 attach_assemble_function(void fptr(EquationSystems &es, const std::string &name))
Register a user function to use in assembling the system matrix and RHS.
 
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 is the MeshBase class.
 
int main(int argc, char **argv)
 
Tensor(* exact_hessian)(const Point &p, const Parameters &, const std::string &, const std::string &)
 
Number exact_3D_solution(const Point &p, const Parameters &, const std::string &, const std::string &)
 
std::size_t n_active_dofs() const
 
Gradient exact_1D_derivative(const Point &p, const Parameters &, const std::string &, const std::string &)
 
void pop(const char *label, const char *header="")
Pop the event label off the stack, resuming any lower event.
 
void attach_exact_hessian(unsigned int sys_num, FunctionBase< Tensor > *h)
Clone and attach an arbitrary functor which computes the exact second derivatives of the system sys_n...
 
void flag_elements_by_elem_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 libmesh_ignore(const Args &...)
 
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
 
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.
 
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
 
The PerfLog class allows monitoring of specific events.
 
virtual void init()
Initialize all the systems.
 
A Point defines a location in LIBMESH_DIM dimensional Real space.
 
SparseMatrix< Number > * matrix
The system matrix.
 
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
 
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
 
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
 
Real l2_error(const std::string &sys_name, const std::string &unknown_name)
 
Number(* forcing_function)(const Point &p)
 
Number exact_1D_solution(const Point &p, const Parameters &, const std::string &, const std::string &)
 
unsigned int & max_h_level()
The max_h_level is the greatest refinement level an element should reach.
 
void compute_error(const std::string &sys_name, const std::string &unknown_name)
Computes and stores the error in the solution value e = u-u_h, the gradient grad(e) = grad(u) - grad(...
 
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
 
This is the EquationSystems class.
 
T & set(const std::string &)
 
unsigned int n_linear_iterations() const
 
virtual void write_equation_systems(const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
This method implements writing a mesh with data to a specified file where the data is taken from the ...
 
void resize(const unsigned int n)
Resize the vector.
 
Gradient exact_2D_derivative(const Point &p, const Parameters &, const std::string &, const std::string &)
 
virtual void reinit()
Handle any mesh changes and reinitialize all the systems on the updated mesh.
 
Real & coarsen_fraction()
The coarsen_fraction sets either a desired target or a desired maximum number of elements to flag for...
 
NumberVectorValue Gradient
 
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 & refine_fraction()
The refine_fraction sets either a desired target or a desired maximum number of elements to flag for ...
 
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
 
This class handles the numbering of degrees of freedom on a mesh.
 
void print_info(std::ostream &os=libMesh::out) const
Prints relevant information about the mesh.
 
virtual Real mean() const override
 
bool use_unweighted_quadrature_rules
This boolean flag allows you to use "unweighted" quadrature rules (sized to exactly integrate unweigh...
 
void push(const char *label, const char *header="")
Push the event label onto the stack, pausing any active event.
 
Real final_linear_residual() const
 
Number forcing_function_2D(const Point &p)
 
const DofMap & get_dof_map() const
 
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
 
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
 
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 uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
 
Gradient(* exact_derivative)(const Point &p, const Parameters &, const std::string &, const std::string &)
 
Tensor exact_3D_hessian(const Point &p, const Parameters &, const std::string &, const std::string &)
 
virtual Real variance() const override
 
void assemble_biharmonic(EquationSystems &es, const std::string &system_name)
 
This class provides the ability to map between arbitrary, user-defined strings and several data types...
 
Parameters parameters
Data structure holding arbitrary parameters.