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"
71 if (parameters.
get<
bool>(
"singularity"))
73 Real theta = atan2(y, x);
78 return pow(x*x + y*y, 1./3.)*sin(2./3.*theta) + z;
82 return cos(x) * exp(y) * (1. - z);
102 if (parameters.
get<
bool>(
"singularity"))
104 libmesh_assert_not_equal_to (x, 0.);
107 const Real tt = 2./3.;
108 const Real ot = 1./3.;
111 const Real r2 = x*x + y*y;
115 Real theta = atan2(y, x);
122 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;
123 gradu(1) = tt*y*
pow(r2,-tt)*sin(tt*theta) +
pow(r2,ot)*cos(tt*theta)*tt/(1.+y*y/x/x)*1./x;
128 gradu(0) = -sin(x) * exp(y) * (1. - z);
129 gradu(1) = cos(x) * exp(y) * (1. - z);
130 gradu(2) = -cos(x) * exp(y);
141 const std::string & libmesh_dbg_var(system_name))
148 libmesh_assert_equal_to (system_name,
"EllipticDG");
159 std::string refinement_type = es.
parameters.
get<std::string> (
"refinement");
184 fe->attach_quadrature_rule (&qrule);
193 fe_elem_face->attach_quadrature_rule(&qface);
194 fe_neighbor_face->attach_quadrature_rule(&qface);
199 const std::vector<Real> & JxW = fe->get_JxW();
200 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
203 const std::vector<std::vector<Real>> & phi_face = fe_elem_face->get_phi();
204 const std::vector<std::vector<RealGradient>> & dphi_face = fe_elem_face->get_dphi();
205 const std::vector<Real> & JxW_face = fe_elem_face->get_JxW();
206 const std::vector<Point> & qface_normals = fe_elem_face->get_normals();
207 const std::vector<Point> & qface_points = fe_elem_face->get_xyz();
210 const std::vector<std::vector<Real>> & phi_neighbor_face = fe_neighbor_face->get_phi();
211 const std::vector<std::vector<RealGradient>> & dphi_neighbor_face = fe_neighbor_face->get_dphi();
232 std::vector<dof_id_type> dof_indices;
243 dof_map.dof_indices (elem, dof_indices);
244 const unsigned int n_dofs =
245 cast_int<unsigned int>(dof_indices.size());
257 Ke.
resize (n_dofs, n_dofs);
263 for (
unsigned int qp=0; qp<qrule.
n_points(); qp++)
264 for (
unsigned int i=0; i<n_dofs; i++)
265 for (
unsigned int j=0; j<n_dofs; j++)
266 Ke(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]);
273 for (
auto side : elem->side_index_range())
275 if (elem->neighbor_ptr(side) ==
nullptr)
278 fe_elem_face->reinit(elem, side);
280 std::unique_ptr<const Elem> elem_side (elem->build_side_ptr(side));
282 const unsigned int elem_b_order = static_cast<unsigned int> (fe_elem_face->get_order());
283 const Real h_elem = elem->volume()/elem_side->volume() * 1./
pow(elem_b_order, 2.);
285 for (
unsigned int qp=0; qp<qface.
n_points(); qp++)
288 for (
unsigned int i=0; i<n_dofs; i++)
291 for (
unsigned int j=0; j<n_dofs; j++)
294 Ke(i,j) += JxW_face[qp] * penalty/h_elem * phi_face[i][qp] * phi_face[j][qp];
299 (phi_face[i][qp] * (dphi_face[j][qp]*qface_normals[qp]) +
300 phi_face[j][qp] * (dphi_face[i][qp]*qface_normals[qp]));
306 Fe(i) += JxW_face[qp] * bc_value * penalty/h_elem * phi_face[i][qp];
309 Fe(i) -= JxW_face[qp] * dphi_face[i][qp] * (bc_value*qface_normals[qp]);
324 const unsigned int elem_id = elem->
id();
325 const unsigned int neighbor_id = neighbor->
id();
332 if ((neighbor->
active() &&
333 (neighbor->
level() == elem->level()) &&
334 (elem_id < neighbor_id)) ||
335 (neighbor->
level() < elem->level()))
338 std::unique_ptr<const Elem> elem_side (elem->build_side_ptr(side));
341 const unsigned int elem_b_order = static_cast<unsigned int>(fe_elem_face->get_order());
342 const unsigned int neighbor_b_order = static_cast<unsigned int>(fe_neighbor_face->get_order());
343 const double side_order = (elem_b_order + neighbor_b_order)/2.;
344 const Real h_elem = (elem->volume()/elem_side->volume()) * 1./
pow(side_order,2.);
347 std::vector<Point> qface_neighbor_point;
350 std::vector<Point > qface_point;
353 fe_elem_face->reinit(elem, side);
356 qface_point = fe_elem_face->get_xyz();
360 if (refinement_type ==
"p")
361 fe_neighbor_face->side_map (neighbor,
365 qface_neighbor_point);
369 qface_neighbor_point);
372 fe_neighbor_face->reinit(neighbor, &qface_neighbor_point);
377 std::vector<dof_id_type> neighbor_dof_indices;
378 dof_map.dof_indices (neighbor, neighbor_dof_indices);
379 const unsigned int n_neighbor_dofs =
380 cast_int<unsigned int>(neighbor_dof_indices.size());
388 Kne.
resize (n_neighbor_dofs, n_dofs);
389 Ken.
resize (n_dofs, n_neighbor_dofs);
390 Kee.
resize (n_dofs, n_dofs);
391 Knn.
resize (n_neighbor_dofs, n_neighbor_dofs);
397 for (
unsigned int qp=0; qp<qface.
n_points(); qp++)
401 for (
unsigned int i=0; i<n_dofs; i++)
403 for (
unsigned int j=0; j<n_dofs; j++)
408 (phi_face[j][qp]*(qface_normals[qp]*dphi_face[i][qp]) +
409 phi_face[i][qp]*(qface_normals[qp]*dphi_face[j][qp]));
412 Kee(i,j) += JxW_face[qp] * penalty/h_elem * phi_face[j][qp]*phi_face[i][qp];
418 for (
unsigned int i=0; i<n_neighbor_dofs; i++)
420 for (
unsigned int j=0; j<n_neighbor_dofs; j++)
425 (phi_neighbor_face[j][qp]*(qface_normals[qp]*dphi_neighbor_face[i][qp]) +
426 phi_neighbor_face[i][qp]*(qface_normals[qp]*dphi_neighbor_face[j][qp]));
430 JxW_face[qp] * penalty/h_elem * phi_neighbor_face[j][qp]*phi_neighbor_face[i][qp];
436 for (
unsigned int i=0; i<n_neighbor_dofs; i++)
438 for (
unsigned int j=0; j<n_dofs; j++)
443 (phi_neighbor_face[i][qp]*(qface_normals[qp]*dphi_face[j][qp]) -
444 phi_face[j][qp]*(qface_normals[qp]*dphi_neighbor_face[i][qp]));
447 Kne(i,j) -= JxW_face[qp] * penalty/h_elem * phi_face[j][qp]*phi_neighbor_face[i][qp];
453 for (
unsigned int i=0; i<n_dofs; i++)
455 for (
unsigned int j=0; j<n_neighbor_dofs; j++)
460 (phi_neighbor_face[j][qp]*(qface_normals[qp]*dphi_face[i][qp]) -
461 phi_face[i][qp]*(qface_normals[qp]*dphi_neighbor_face[j][qp]));
464 Ken(i,j) -= JxW_face[qp] * penalty/h_elem * phi_face[i][qp]*phi_neighbor_face[j][qp];
472 ellipticdg_system.
matrix->
add_matrix(Kne, neighbor_dof_indices, dof_indices);
473 ellipticdg_system.
matrix->
add_matrix(Ken, dof_indices, neighbor_dof_indices);
492 int main (
int argc,
char** argv)
498 "--enable-petsc, --enable-trilinos, or --enable-eigen");
501 #ifndef LIBMESH_ENABLE_AMR
502 libmesh_example_requires(
false,
"--enable-amr");
506 GetPot input_file(
"miscellaneous_ex5.in");
509 const unsigned int adaptive_refinement_steps = input_file(
"max_adaptive_r_steps", 3);
510 const unsigned int uniform_refinement_steps = input_file(
"uniform_h_r_steps", 3);
511 const Real refine_fraction = input_file(
"refine_fraction", 0.5);
512 const Real coarsen_fraction = input_file(
"coarsen_fraction", 0.);
513 const unsigned int max_h_level = input_file(
"max_h_level", 10);
514 const std::string refinement_type = input_file(
"refinement_type",
"p");
515 Order p_order = static_cast<Order>(input_file(
"p_order", 1));
516 const std::string element_type = input_file(
"element_type",
"tensor");
517 const Real penalty = input_file(
"ip_penalty", 10.);
518 const bool singularity = input_file(
"singularity",
true);
519 const unsigned int dim = input_file(
"dimension", 3);
522 libmesh_example_requires(
dim <= LIBMESH_DIM,
"2D/3D support");
537 if (element_type ==
"simplex")
547 for (
unsigned int rstep=0; rstep<uniform_refinement_steps; rstep++)
555 equation_system.
parameters.
set<
unsigned int>(
"linear solver maximum iterations") = 1000;
558 equation_system.
parameters.
set<std::string>(
"refinement") = refinement_type;
568 std::string(
"MONOMIAL"));
570 if (fe_str !=
"MONOMIAL" || fe_str !=
"XYZ")
571 libmesh_error_msg(
"Error: This example must be run with MONOMIAL or XYZ element types.");
573 ellipticdg_system.add_variable (
"u", p_order, Utility::string_to_enum<FEFamily>(fe_str));
576 ellipticdg_system.add_variable (
"u", p_order,
MONOMIAL);
582 equation_system.
init();
590 for (
unsigned int rstep=0; rstep<adaptive_refinement_steps; ++rstep)
592 libMesh::out <<
" Beginning Solve " << rstep << std::endl;
596 ellipticdg_system.solve();
600 <<
" degrees of freedom."
604 << ellipticdg_system.n_linear_iterations()
605 <<
", final residual: "
606 << ellipticdg_system.final_linear_residual()
614 << exact_sol.
l2_error(
"EllipticDG",
"u")
618 if (rstep+1 < adaptive_refinement_steps)
632 if (refinement_type ==
"p")
634 if (refinement_type ==
"hp")
646 #ifdef LIBMESH_HAVE_EXODUS_API
650 #endif // #ifndef LIBMESH_ENABLE_AMR