30 #include "libmesh/libmesh.h" 31 #include "libmesh/mesh.h" 32 #include "libmesh/equation_systems.h" 33 #include "libmesh/mesh_generation.h" 34 #include "libmesh/mesh_modification.h" 35 #include "libmesh/elem.h" 36 #include "libmesh/transient_system.h" 37 #include "libmesh/fe.h" 38 #include "libmesh/quadrature_gauss.h" 39 #include "libmesh/dof_map.h" 40 #include "libmesh/sparse_matrix.h" 41 #include "libmesh/dense_matrix.h" 42 #include "libmesh/dense_vector.h" 43 #include "libmesh/dense_submatrix.h" 44 #include "libmesh/dense_subvector.h" 45 #include "libmesh/numeric_vector.h" 46 #include "libmesh/linear_implicit_system.h" 47 #include "libmesh/exodusII_io.h" 48 #include "libmesh/fe_interface.h" 49 #include "libmesh/getpot.h" 50 #include "libmesh/mesh_refinement.h" 51 #include "libmesh/error_vector.h" 52 #include "libmesh/kelly_error_estimator.h" 53 #include "libmesh/discontinuity_measure.h" 54 #include "libmesh/string_to_enum.h" 55 #include "libmesh/exact_solution.h" 56 #include "libmesh/enum_solver_package.h" 57 #include "libmesh/elem_side_builder.h" 72 if (parameters.
get<
bool>(
"singularity"))
74 Real theta = atan2(y, x);
79 return pow(x*x + y*y, 1./3.)*sin(2./3.*theta) + z;
83 return cos(x) * exp(y) * (1. - z);
103 if (parameters.
get<
bool>(
"singularity"))
105 libmesh_assert_not_equal_to (x, 0.);
108 const Real tt = 2./3.;
109 const Real ot = 1./3.;
112 const Real r2 = x*x + y*y;
116 Real theta = atan2(y, x);
123 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;
124 gradu(1) = tt*y*
pow(r2,-tt)*sin(tt*theta) +
pow(r2,ot)*cos(tt*theta)*tt/(1.+y*y/x/x)*1./x;
129 gradu(0) = -sin(x) * exp(y) * (1. - z);
130 gradu(1) = cos(x) * exp(y) * (1. - z);
131 gradu(2) = -cos(x) * exp(y);
142 const std::string & libmesh_dbg_var(system_name))
149 libmesh_assert_equal_to (system_name,
"EllipticDG");
160 std::string refinement_type = es.
parameters.
get<std::string> (
"refinement");
185 fe->attach_quadrature_rule (&qrule);
194 fe_elem_face->attach_quadrature_rule(&qface);
195 fe_neighbor_face->attach_quadrature_rule(&qface);
200 const std::vector<Real> & JxW = fe->get_JxW();
201 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
204 const std::vector<std::vector<Real>> & phi_face = fe_elem_face->get_phi();
205 const std::vector<std::vector<RealGradient>> & dphi_face = fe_elem_face->get_dphi();
206 const std::vector<Real> & JxW_face = fe_elem_face->get_JxW();
207 const std::vector<Point> & qface_normals = fe_elem_face->get_normals();
208 const std::vector<Point> & qface_points = fe_elem_face->get_xyz();
211 const std::vector<std::vector<Real>> & phi_neighbor_face = fe_neighbor_face->get_phi();
212 const std::vector<std::vector<RealGradient>> & dphi_neighbor_face = fe_neighbor_face->get_dphi();
233 std::vector<dof_id_type> dof_indices;
247 for (
const auto & elem :
mesh.active_local_element_ptr_range())
253 dof_map.dof_indices (elem, dof_indices);
254 const unsigned int n_dofs =
255 cast_int<unsigned int>(dof_indices.size());
267 Ke.
resize (n_dofs, n_dofs);
273 for (
unsigned int qp=0; qp<qrule.
n_points(); qp++)
274 for (
unsigned int i=0; i<n_dofs; i++)
275 for (
unsigned int j=0; j<n_dofs; j++)
276 Ke(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]);
283 for (
auto side : elem->side_index_range())
285 if (elem->neighbor_ptr(side) ==
nullptr)
288 fe_elem_face->reinit(elem, side);
291 const auto side_volume = side_builder(*elem, side).volume();
292 const unsigned int elem_b_order =
static_cast<unsigned int> (fe_elem_face->get_order());
293 const Real h_elem = elem->volume()/side_volume * 1./
pow(elem_b_order, 2.);
295 for (
unsigned int qp=0; qp<qface.
n_points(); qp++)
298 for (
unsigned int i=0; i<n_dofs; i++)
301 for (
unsigned int j=0; j<n_dofs; j++)
304 Ke(i,j) += JxW_face[qp] * penalty/h_elem * phi_face[i][qp] * phi_face[j][qp];
309 (phi_face[i][qp] * (dphi_face[j][qp]*qface_normals[qp]) +
310 phi_face[j][qp] * (dphi_face[i][qp]*qface_normals[qp]));
316 Fe(i) += JxW_face[qp] * bc_value * penalty/h_elem * phi_face[i][qp];
319 Fe(i) -= JxW_face[qp] * dphi_face[i][qp] * (bc_value*qface_normals[qp]);
334 const unsigned int elem_id = elem->
id();
335 const unsigned int neighbor_id = neighbor->
id();
342 if ((neighbor->
active() &&
343 (neighbor->
level() == elem->level()) &&
344 (elem_id < neighbor_id)) ||
345 (neighbor->
level() < elem->level()))
347 const Elem & elem_side = side_builder(*elem, side);
350 const unsigned int elem_b_order =
static_cast<unsigned int>(fe_elem_face->get_order());
351 const unsigned int neighbor_b_order =
static_cast<unsigned int>(fe_neighbor_face->get_order());
352 const double side_order = (elem_b_order + neighbor_b_order)/2.;
353 const Real h_elem = (elem->volume()/elem_side.
volume()) * 1./
pow(side_order,2.);
356 std::vector<Point> qface_neighbor_point;
359 std::vector<Point > qface_point;
362 fe_elem_face->reinit(elem, side);
365 qface_point = fe_elem_face->get_xyz();
369 if (refinement_type ==
"p")
370 fe_neighbor_face->side_map (neighbor,
374 qface_neighbor_point);
378 qface_neighbor_point);
381 fe_neighbor_face->reinit(neighbor, &qface_neighbor_point);
386 std::vector<dof_id_type> neighbor_dof_indices;
387 dof_map.dof_indices (neighbor, neighbor_dof_indices);
388 const unsigned int n_neighbor_dofs =
389 cast_int<unsigned int>(neighbor_dof_indices.size());
397 Kne.
resize (n_neighbor_dofs, n_dofs);
398 Ken.
resize (n_dofs, n_neighbor_dofs);
399 Kee.
resize (n_dofs, n_dofs);
400 Knn.
resize (n_neighbor_dofs, n_neighbor_dofs);
406 for (
unsigned int qp=0; qp<qface.
n_points(); qp++)
410 for (
unsigned int i=0; i<n_dofs; i++)
412 for (
unsigned int j=0; j<n_dofs; j++)
417 (phi_face[j][qp]*(qface_normals[qp]*dphi_face[i][qp]) +
418 phi_face[i][qp]*(qface_normals[qp]*dphi_face[j][qp]));
421 Kee(i,j) += JxW_face[qp] * penalty/h_elem * phi_face[j][qp]*phi_face[i][qp];
427 for (
unsigned int i=0; i<n_neighbor_dofs; i++)
429 for (
unsigned int j=0; j<n_neighbor_dofs; j++)
434 (phi_neighbor_face[j][qp]*(qface_normals[qp]*dphi_neighbor_face[i][qp]) +
435 phi_neighbor_face[i][qp]*(qface_normals[qp]*dphi_neighbor_face[j][qp]));
439 JxW_face[qp] * penalty/h_elem * phi_neighbor_face[j][qp]*phi_neighbor_face[i][qp];
445 for (
unsigned int i=0; i<n_neighbor_dofs; i++)
447 for (
unsigned int j=0; j<n_dofs; j++)
452 (phi_neighbor_face[i][qp]*(qface_normals[qp]*dphi_face[j][qp]) -
453 phi_face[j][qp]*(qface_normals[qp]*dphi_neighbor_face[i][qp]));
456 Kne(i,j) -= JxW_face[qp] * penalty/h_elem * phi_face[j][qp]*phi_neighbor_face[i][qp];
462 for (
unsigned int i=0; i<n_dofs; i++)
464 for (
unsigned int j=0; j<n_neighbor_dofs; j++)
469 (phi_neighbor_face[j][qp]*(qface_normals[qp]*dphi_face[i][qp]) -
470 phi_face[i][qp]*(qface_normals[qp]*dphi_neighbor_face[j][qp]));
473 Ken(i,j) -= JxW_face[qp] * penalty/h_elem * phi_face[i][qp]*phi_neighbor_face[j][qp];
481 matrix.
add_matrix(Kne, neighbor_dof_indices, dof_indices);
482 matrix.
add_matrix(Ken, dof_indices, neighbor_dof_indices);
501 int main (
int argc,
char** argv)
507 "--enable-petsc, --enable-trilinos, or --enable-eigen");
510 #ifndef LIBMESH_ENABLE_AMR 511 libmesh_example_requires(
false,
"--enable-amr");
515 GetPot input_file(
"miscellaneous_ex5.in");
518 input_file.parse_command_line(argc, argv);
521 const unsigned int adaptive_refinement_steps = input_file(
"max_adaptive_r_steps", 3);
522 const unsigned int uniform_refinement_steps = input_file(
"uniform_h_r_steps", 3);
523 const Real refine_fraction = input_file(
"refine_fraction", 0.5);
524 const Real coarsen_fraction = input_file(
"coarsen_fraction", 0.);
525 const unsigned int max_h_level = input_file(
"max_h_level", 10);
526 const std::string refinement_type = input_file(
"refinement_type",
"p");
527 Order p_order =
static_cast<Order>(input_file(
"p_order", 1));
528 const std::string element_type = input_file(
"element_type",
"tensor");
529 const Real penalty = input_file(
"ip_penalty", 10.);
530 const bool singularity = input_file(
"singularity",
true);
531 const unsigned int dim = input_file(
"dimension", 3);
532 const std::string fe_family = input_file(
"fe_family",
"MONOMIAL");
535 libmesh_example_requires(
dim <= LIBMESH_DIM,
"2D/3D support");
550 if (element_type ==
"simplex")
560 for (
unsigned int rstep=0; rstep<uniform_refinement_steps; rstep++)
568 equation_system.
parameters.
set<
unsigned int>(
"linear solver maximum iterations") = 1000;
571 equation_system.
parameters.
set<std::string>(
"refinement") = refinement_type;
577 ellipticdg_system.
add_variable (
"u", p_order, Utility::string_to_enum<FEFamily>(fe_family));
583 equation_system.
init();
591 for (
unsigned int rstep=0; rstep<adaptive_refinement_steps; ++rstep)
593 libMesh::out <<
" Beginning Solve " << rstep << std::endl;
597 ellipticdg_system.solve();
601 <<
" degrees of freedom." 605 << ellipticdg_system.n_linear_iterations()
606 <<
", final residual: " 607 << ellipticdg_system.final_linear_residual()
615 << exact_sol.
l2_error(
"EllipticDG",
"u")
619 if (rstep+1 < adaptive_refinement_steps)
633 if (refinement_type ==
"p")
635 if (refinement_type ==
"hp")
647 #ifdef LIBMESH_HAVE_EXODUS_API 651 #endif // #ifndef 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...
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.
Order
defines an enum for polynomial orders.
This class provides the ability to map between arbitrary, user-defined strings and several data types...
static constexpr Real TOLERANCE
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true, const bool extra_checks=true)
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]...
This is the base class from which all geometric element types are derived.
Real & coarsen_fraction()
The coarsen_fraction sets either a desired target or a desired maximum number of elements to flag for...
int main(int argc, char **argv)
NumericVector< Number > * rhs
The system matrix.
Order default_quadrature_order() const
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.
const T_sys & get_system(std::string_view name) const
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.
SolverPackage default_solver_package()
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 ...
Gradient exact_derivative(const Point &p, const Parameters ¶meters, const std::string &, const std::string &)
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.
const T & get(std::string_view) const
Implements (adaptive) mesh refinement algorithms for a MeshBase.
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
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(...
virtual void reinit()
Handle any mesh changes and reinitialize all the systems on the updated mesh.
Number exact_solution(const Point &p, const Parameters ¶meters, const std::string &, const std::string &)
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.
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.
unsigned int n_points() const
Helper for building element sides that minimizes the construction of new elements.
Real l2_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...
const Elem * neighbor_ptr(unsigned int i) const
BasicOStreamProxy & flush()
Flush the associated stream buffer.
unsigned int level() const
void write_discontinuous_exodusII(const std::string &name, const EquationSystems &es, const std::set< std::string > *system_names=nullptr)
Writes a exodusII file with discontinuous data.
const FEType & variable_type(const unsigned int i) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const std::vector< Point > & get_points() const
T & set(const std::string &)
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().
virtual Real volume() const
std::size_t n_active_dofs() const
This class implements specific orders of Gauss quadrature.
unsigned int mesh_dimension() const
Parameters parameters
Data structure holding arbitrary parameters.
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 assemble_ellipticdg(EquationSystems &es, const std::string &libmesh_dbg_var(system_name))
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...
virtual void init()
Initialize all the systems.
virtual dof_id_type n_elem() const =0
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.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
const DofMap & get_dof_map() const
A Point defines a location in LIBMESH_DIM dimensional Real space.
const SparseMatrix< Number > & get_system_matrix() const
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.