80int main(
int argc,
char *argv[])
83 int ser_ref_levels = 2;
88 bool visualization =
true;
97 args.
AddOption(&h1,
"-h1",
"--continuous",
"-dg",
"--discontinuous",
98 "Select continuous \"H1\" or discontinuous \"DG\" basis.");
100 "Finite element order (polynomial degree) or -1 for"
101 " isoparametric space.");
103 "One of the two DG penalty parameters, typically +1/-1."
104 " See the documentation of class DGDiffusionIntegrator.");
106 "One of the two DG penalty parameters, should be positive."
107 " Negative values are replaced with (order+1)^2.");
108 args.
AddOption(&ser_ref_levels,
"-rs",
"--refine-serial",
109 "Number of times to refine the mesh uniformly in serial.");
110 args.
AddOption(&mat_val,
"-mat",
"--material-value",
111 "Constant value for material coefficient "
112 "in the Laplace operator.");
113 args.
AddOption(&dbc_val,
"-dbc",
"--dirichlet-value",
114 "Constant value for Dirichlet Boundary Condition.");
115 args.
AddOption(&nbc_val,
"-nbc",
"--neumann-value",
116 "Constant value for Neumann Boundary Condition.");
117 args.
AddOption(&rbc_a_val,
"-rbc-a",
"--robin-a-value",
118 "Constant 'a' value for Robin Boundary Condition: "
119 "du/dn + a * u = b.");
120 args.
AddOption(&rbc_b_val,
"-rbc-b",
"--robin-b-value",
121 "Constant 'b' value for Robin Boundary Condition: "
122 "du/dn + a * u = b.");
124 "Radius of holes in the mesh.");
125 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
126 "--no-visualization",
127 "Enable or disable GLVis visualization.");
134 if (
kappa < 0 && !h1)
136 kappa = (order+1)*(order+1);
142 mfem::out <<
"Hole radius too small, resetting to 0.01.\n";
147 mfem::out <<
"Hole radius too large, resetting to 0.49.\n";
163 mfem::out <<
"Number of finite element unknowns: " << size << endl;
173 nbc_bdr = 0; nbc_bdr[0] = 1;
174 rbc_bdr = 0; rbc_bdr[1] = 1;
175 dbc_bdr = 0; dbc_bdr[2] = 1;
240 u.ProjectBdrCoefficient(dbcCoef, dbc_bdr);
268 a.FormLinearSystem(ess_tdof_list,
u,
b, A, X, B);
270#ifndef MFEM_USE_SUITESPARSE
278 PCG(*A, M, B, X, 1, 500, 1e-12, 0.0);
282 GMRES(*A, M, B, X, 1, 500, 10, 1e-12, 0.0);
289 umf_solver.
Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
291 umf_solver.
Mult(B, X);
296 a.RecoverFEMSolution(X,
b,
u);
300 <<
"Verifying boundary conditions" << endl
301 <<
"=============================" << endl;
307 bool hom_dbc = (dbc_val == 0.0);
308 error /= hom_dbc ? 1.0 : fabs(dbc_val);
309 mfem::out <<
"Average of solution on Gamma_dbc:\t"
311 << (hom_dbc ?
"absolute" :
"relative")
312 <<
" error " << error << endl;
319 bool hom_nbc = (nbc_val == 0.0);
320 error /= hom_nbc ? 1.0 : fabs(nbc_val);
321 mfem::out <<
"Average of n.Grad(u) on Gamma_nbc:\t"
323 << (hom_nbc ?
"absolute" :
"relative")
324 <<
" error " << error << endl;
336 mfem::out <<
"Average of n.Grad(u) on Gamma_nbc0:\t"
338 << (hom_nbc ?
"absolute" :
"relative")
339 <<
" error " << error << endl;
347 bool hom_rbc = (rbc_b_val == 0.0);
348 error /= hom_rbc ? 1.0 : fabs(rbc_b_val);
349 mfem::out <<
"Average of n.Grad(u)+a*u on Gamma_rbc:\t"
351 << (hom_rbc ?
"absolute" :
"relative")
352 <<
" error " << error << endl;
358 ofstream mesh_ofs(
"refined.mesh");
359 mesh_ofs.precision(8);
360 mesh->
Print(mesh_ofs);
361 ofstream sol_ofs(
"sol.gf");
362 sol_ofs.precision(8);
369 string title_str = h1 ?
"H1" :
"DG";
373 sol_sock.precision(8);
374 sol_sock <<
"solution\n" << *mesh <<
u
375 <<
"window_title '" << title_str <<
" Solution'"
376 <<
" keys 'mmc'" << flush;
390 real_t d = 4.0 *
a * (M_SQRT2 - 2.0 *
a) * (1.0 - 2.0 * v);
392 real_t v0 = (1.0 + M_SQRT2) * (M_SQRT2 *
a - 2.0 * v) *
393 ((4.0 - 3 * M_SQRT2) *
a +
394 (8.0 * (M_SQRT2 - 1.0) *
a - 2.0) * v) / d;
396 real_t r = 2.0 * ((M_SQRT2 - 1.0) *
a *
a * (1.0 - 4.0 *v) +
397 2.0 * (1.0 + M_SQRT2 *
398 (1.0 + 2.0 * (2.0 *
a - M_SQRT2 - 1.0) *
a)) * v * v
405 <<
u <<
" " << v <<
" " << r <<
" " << v0 <<
" " <<
t
416 if (
u[1] > 0.5 - tol ||
u[1] < -0.5 + tol)
421 if (
u[0] > 1.0 - tol ||
u[0] < -1.0 + tol || fabs(
u[0]) < tol)
429 if (
u[1] > fabs(
u[0] - 0.5))
435 if (
u[1] < -fabs(
u[0] - 0.5))
442 if (
u[0] - 0.5 > fabs(
u[1]))
448 if (
u[0] - 0.5 < -fabs(
u[1]))
458 if (
u[1] > fabs(
u[0] + 0.5))
464 if (
u[1] < -fabs(
u[0] + 0.5))
471 if (
u[0] + 0.5 > fabs(
u[1]))
477 if (
u[0] + 0.5 < -fabs(
u[1]))
490 Mesh * mesh =
new Mesh(2, 29, 16, 24, 2);
494 for (
int i=0; i<2; i++)
497 vi[0] = o + 0; vi[1] = o + 3; vi[2] = o + 4; vi[3] = o + 1;
500 vi[0] = o + 1; vi[1] = o + 4; vi[2] = o + 5; vi[3] = o + 2;
503 vi[0] = o + 5; vi[1] = o + 8; vi[2] = o + 9; vi[3] = o + 2;
506 vi[0] = o + 8; vi[1] = o + 12; vi[2] = o + 15; vi[3] = o + 9;
509 vi[0] = o + 11; vi[1] = o + 14; vi[2] = o + 15; vi[3] = o + 12;
512 vi[0] = o + 10; vi[1] = o + 13; vi[2] = o + 14; vi[3] = o + 11;
515 vi[0] = o + 6; vi[1] = o + 13; vi[2] = o + 10; vi[3] = o + 7;
518 vi[0] = o + 0; vi[1] = o + 6; vi[2] = o + 7; vi[3] = o + 3;
532 for (
int i=0; i<2; i++)
535 vi[0] = o + 7; vi[1] = o + 3; mesh->
AddBdrSegment(vi, 3 + i);
536 vi[0] = o + 10; vi[1] = o + 7; mesh->
AddBdrSegment(vi, 3 + i);
537 vi[0] = o + 11; vi[1] = o + 10; mesh->
AddBdrSegment(vi, 3 + i);
538 vi[0] = o + 12; vi[1] = o + 11; mesh->
AddBdrSegment(vi, 3 + i);
539 vi[0] = o + 8; vi[1] = o + 12; mesh->
AddBdrSegment(vi, 3 + i);
540 vi[0] = o + 5; vi[1] = o + 8; mesh->
AddBdrSegment(vi, 3 + i);
541 vi[0] = o + 4; vi[1] = o + 5; mesh->
AddBdrSegment(vi, 3 + i);
542 vi[0] = o + 3; vi[1] = o + 4; mesh->
AddBdrSegment(vi, 3 + i);
548 d[0] = -1.0; d[1] = -0.5; mesh->
AddVertex(d);
549 d[0] = -1.0; d[1] = 0.0; mesh->
AddVertex(d);
550 d[0] = -1.0; d[1] = 0.5; mesh->
AddVertex(d);
553 d[0] = -0.5 -
a; d[1] = 0.0; mesh->
AddVertex(d);
556 d[0] = -0.5; d[1] = -0.5; mesh->
AddVertex(d);
559 d[0] = -0.5; d[1] = 0.5; mesh->
AddVertex(d);
562 d[0] = -0.5 +
a; d[1] = 0.0; mesh->
AddVertex(d);
565 d[0] = 0.0; d[1] = -0.5; mesh->
AddVertex(d);
566 d[0] = 0.0; d[1] = 0.0; mesh->
AddVertex(d);
567 d[0] = 0.0; d[1] = 0.5; mesh->
AddVertex(d);
570 d[0] = 0.5 -
a; d[1] = 0.0; mesh->
AddVertex(d);
573 d[0] = 0.5; d[1] = -0.5; mesh->
AddVertex(d);
576 d[0] = 0.5; d[1] = 0.5; mesh->
AddVertex(d);
579 d[0] = 0.5 +
a; d[1] = 0.0; mesh->
AddVertex(d);
582 d[0] = 1.0; d[1] = -0.5; mesh->
AddVertex(d);
583 d[0] = 1.0; d[1] = 0.0; mesh->
AddVertex(d);
584 d[0] = 1.0; d[1] = 0.5; mesh->
AddVertex(d);
593 for (
int i = 0; i < v2v.
Size() - 3; i++)
598 v2v[v2v.
Size() - 3] = 0;
599 v2v[v2v.
Size() - 2] = 1;
600 v2v[v2v.
Size() - 1] = 2;
603 for (
int i = 0; i < mesh->
GetNE(); i++)
608 for (
int j = 0; j < nv; j++)
614 for (
int i = 0; i < mesh->
GetNBE(); i++)
619 for (
int j = 0; j < nv; j++)
629 for (
int l = 0; l < ref; l++)
647 const bool a_is_zero =
alpha == 0.0;
648 const bool b_is_zero =
beta == 0.0;
651 MFEM_ASSERT(fes.
GetVDim() == 1,
"");
653 Vector shape, loc_dofs, w_nor;
656 for (
int i = 0; i < mesh.
GetNBE(); i++)
661 if (FTr ==
nullptr) {
continue; }
665 const int int_order = 2*fe.
GetOrder() + 3;
698 val +=
beta * (shape * loc_dofs);
702 nrm += ip.
weight * face_weight;
705 avg += val * ip.
weight * face_weight;
709 error += (val*val) * ip.
weight * face_weight;
714 if (std::abs(nrm) > 0.0)
722 error = (error >= 0.0) ? sqrt(error) : -sqrt(-error);
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
int Size() const
Return the logical size of the array.
Class for boundary integration .
A coefficient that is constant across space and time.
Data type dense matrix using column-major storage.
real_t InnerProduct(const real_t *x, const real_t *y) const
Compute y^t A x.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Abstract data type element.
virtual void GetVertices(Array< int > &v) const =0
Get the indices defining the vertices.
virtual int GetNVertices() const =0
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
DofTransformation * GetElementDofs(int elem, Array< int > &dofs) const
Returns indices of degrees of freedom of element 'elem'. The returned indices are offsets into an ldo...
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1) const
Get a list of essential true dofs, ess_tdof_list, corresponding to the boundary attributes marked in ...
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
Mesh * GetMesh() const
Returns the mesh.
int GetVDim() const
Returns vector dimension.
Abstract class for all finite elements.
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
void CalcPhysDShape(ElementTransformation &Trans, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in physical space at the poi...
int GetMapType() const
Returns the FiniteElement::MapType of the element describing how reference functions are mapped to ph...
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const =0
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Data type for Gauss-Seidel smoother of sparse matrix.
Class for grid function - Vector with associated FE space.
FiniteElementSpace * FESpace()
Arbitrary order H1-conforming (continuous) finite elements.
Class for integration point with weight.
Class for an integration rule - an Array of IntegrationPoint.
int GetNPoints() const
Returns the number of the points in the integration rule.
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
int AddQuad(int v1, int v2, int v3, int v4, int attr=1)
Adds a quadrilateral to the mesh given by 4 vertices v1 through v4.
int GetBdrAttribute(int i) const
Return the attribute of boundary element i.
const Element * GetElement(int i) const
Return pointer to the i'th element object.
void FinalizeTopology(bool generate_bdr=true)
Finalize the construction of the secondary topology (connectivity) data of a Mesh.
virtual void Print(std::ostream &os=mfem::out, const std::string &comments="") const
int AddVertex(real_t x, real_t y=0.0, real_t z=0.0)
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
int AddBdrSegment(int v1, int v2, int attr=1)
FaceElementTransformations * GetBdrFaceTransformations(int BdrElemNo)
Builds the transformation defining the given boundary face.
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
int GetNBE() const
Returns number of boundary elements.
virtual void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1)
Set the curvature of the mesh nodes using the given polynomial degree.
void Transform(void(*f)(const Vector &, Vector &))
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
void RemoveInternalBoundaries()
void RemoveUnusedVertices()
Remove unused vertices and rebuild mesh connectivity.
Pointer to an Operator of a specified type.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
bool Good() const
Return true if the command line options were parsed successfully.
Scalar coefficient defined as the product of two scalar coefficients or a scalar and a scalar coeffic...
Direct sparse solver using UMFPACK.
virtual void SetOperator(const Operator &op)
Factorize the given Operator op which must be a SparseMatrix.
real_t Control[UMFPACK_CONTROL]
virtual void Mult(const Vector &b, Vector &x) const
Direct solution of the linear system using UMFPACK.
real_t Norml2() const
Returns the l2 norm of the vector.
void SetSize(int s)
Resize the vector to size s.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
real_t sigma(const Vector &x)
void n4Vec(const Vector &x, Vector &n)
void trans(const Vector &u, Vector &x)
real_t IntegrateBC(const GridFunction &sol, const Array< int > &bdr_marker, real_t alpha, real_t beta, real_t gamma, real_t &error)
void quad_trans(real_t u, real_t v, real_t &x, real_t &y, bool log=false)
Mesh * GenerateSerialMesh(int ref)
void CalcOrtho(const DenseMatrix &J, Vector &n)
real_t u(const Vector &xvec)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
int GMRES(const Operator &A, Vector &x, const Vector &b, Solver &M, int &max_iter, int m, real_t &tol, real_t atol, int printit)
GMRES method. (tolerances are squared)
void PCG(const Operator &A, Solver &B, const Vector &b, Vector &x, int print_iter, int max_num_iter, real_t RTOLERANCE, real_t ATOLERANCE)
Preconditioned conjugate gradient method. (tolerances are squared)
L2_FECollection DG_FECollection
Declare an alternative name for L2_FECollection = DG_FECollection.
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)