44 class LogarithmGridFunctionCoefficient :
public Coefficient 54 :
u(&u_), obstacle(&obst_), min_val(min_val_) { }
59 class ExponentialGridFunctionCoefficient :
public Coefficient 69 double min_val_=0.0,
double max_val_=1e6)
70 :
u(&u_), obstacle(&obst_), min_val(min_val_), max_val(max_val_) { }
75 int main(
int argc,
char *argv[])
83 bool visualization =
true;
87 "Finite element order (polynomial degree).");
88 args.
AddOption(&ref_levels,
"-r",
"--refs",
89 "Number of h-refinements.");
90 args.
AddOption(&max_it,
"-mi",
"--max-it",
91 "Maximum number of iterations");
93 "Stopping criteria based on the difference between" 94 "successive solution updates");
97 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
99 "Enable or disable GLVis visualization.");
109 const char *mesh_file =
"../data/disc-nurbs.mesh";
110 Mesh mesh(mesh_file, 1, 1);
115 for (
int l = 0; l < ref_levels; l++)
122 int curvature_order = max(order,2);
127 double scale = 2*sqrt(2);
137 cout <<
"Number of H1 finite element unknowns: " 139 cout <<
"Number of L2 finite element unknowns: " 160 auto IC_func = [](
const Vector &x)
164 for (
int i=0; i<x.Size(); i++)
177 u_gf.
MakeRef(&H1fes,x,offsets[0]);
178 delta_psi_gf.
MakeRef(&L2fes,x,offsets[1]);
198 LogarithmGridFunctionCoefficient ln_u(u_gf, obstacle);
208 sol_sock.precision(8);
213 int total_iterations = 0;
214 double increment_u = 0.1;
215 for (k = 0; k < max_it; k++)
220 mfem::out <<
"\nOUTER ITERATION " << k+1 << endl;
223 for ( j = 0; j < 10; j++)
233 ExponentialGridFunctionCoefficient exp_psi(psi_gf, zero);
297 GMRES(A,prec,rhs,x,0,10000,500,1e-12,0.0);
299 u_gf.
MakeRef(&H1fes, x.GetBlock(0), 0);
300 delta_psi_gf.
MakeRef(&L2fes, x.GetBlock(1), 0);
307 delta_psi_gf *= gamma;
308 psi_gf += delta_psi_gf;
312 sol_sock <<
"solution\n" << mesh << u_gf <<
"window_title 'Discrete solution'" 314 mfem::out <<
"Newton_update_size = " << Newton_update_size << endl;
319 if (Newton_update_size < increment_u)
329 mfem::out <<
"Number of Newton iterations = " << j+1 << endl;
330 mfem::out <<
"Increment (|| uₕ - uₕ_prvs||) = " << increment_u << endl;
335 if (increment_u < tol || k == max_it-1)
340 double H1_error = u_gf.
ComputeH1Error(&exact_coef,&exact_grad_coef);
341 mfem::out <<
"H1-error (|| u - uₕᵏ||) = " << H1_error << endl;
345 mfem::out <<
"\n Outer iterations: " << k+1
346 <<
"\n Total iterations: " << total_iterations
354 err_sock.precision(8);
360 err_sock <<
"solution\n" << mesh << error_gf <<
"window_title 'Error'" <<
366 double H1_error = u_gf.
ComputeH1Error(&exact_coef,&exact_grad_coef);
368 ExponentialGridFunctionCoefficient u_alt_cf(psi_gf,obstacle);
373 mfem::out <<
"\n Final L2-error (|| u - uₕ||) = " << L2_error <<
375 mfem::out <<
" Final H1-error (|| u - uₕ||) = " << H1_error << endl;
376 mfem::out <<
" Final L2-error (|| u - ϕ - exp(ψₕ)||) = " << L2_error_alt <<
386 MFEM_ASSERT(
u != NULL,
"grid function is not set");
388 double val =
u->GetValue(T, ip) - obstacle->Eval(T, ip);
389 return max(min_val, log(val));
395 MFEM_ASSERT(
u != NULL,
"grid function is not set");
397 double val =
u->GetValue(T, ip);
398 return min(max_val, max(min_val, exp(val) + obstacle->Eval(T, ip)));
403 double x = pt(0), y = pt(1);
404 double r = sqrt(x*x + y*y);
409 double tmp = sqrt(r0*r0 -
b*
b);
410 double B = tmp +
b*
b/tmp;
419 return sqrt(r0*r0 - r*r);
425 double x = pt(0), y = pt(1);
426 double r = sqrt(x*x + y*y);
428 double a = 0.348982574111686;
429 double A = -0.340129705945858;
437 return sqrt(r0*r0-r*r);
443 double x = pt(0), y = pt(1);
444 double r = sqrt(x*x + y*y);
446 double a = 0.348982574111686;
447 double A = -0.340129705945858;
451 grad(0) = A * x / (r*r);
452 grad(1) = A * y / (r*r);
456 grad(0) = - x / sqrt( r0*r0 - r*r );
457 grad(1) = - y / sqrt( r0*r0 - r*r );
virtual double ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL, const Array< int > *elems=NULL) const
Class for domain integration L(v) := (f, v)
double Eval(ElementTransformation &T, const IntegrationPoint &ip, double t)
Evaluate the coefficient in the element described by T at the point ip at time t. ...
double exact_solution_obstacle(const Vector &pt)
Class for grid function - Vector with associated FE space.
A class to handle Vectors in a block fashion.
A coefficient that is constant across space and time.
void PrintOptions(std::ostream &out) const
Print the options.
int Dimension() const
Dimension of the reference space used within the elements.
void PrintUsage(std::ostream &out) const
Print the usage message.
Scalar coefficient defined as the product of two scalar coefficients or a scalar and a scalar coeffic...
Coefficient defined by a GridFunction. This coefficient is mesh dependent.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
bool Good() const
Return true if the command line options were parsed successfully.
double spherical_obstacle(const Vector &pt)
Data type for Gauss-Seidel smoother of sparse matrix.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
A class to handle Block diagonal preconditioners in a matrix-free implementation. ...
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
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.
Vector coefficient defined as the Gradient of a scalar GridFunction.
int main(int argc, char *argv[])
virtual void MakeRef(FiniteElementSpace *f, double *v)
Make the GridFunction reference external data on a new FiniteElementSpace.
Set the diagonal value to one.
A general vector function coefficient.
virtual int GetTrueVSize() const
Return the number of vector true (conforming) dofs.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
virtual double ComputeH1Error(Coefficient *exsol, VectorCoefficient *exgrad, Coefficient *ell_coef, double Nu, int norm_type) const
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
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...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
Class for integration point with weight.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
int Size() const
Return the logical size of the array.
A general function coefficient.
Arbitrary order H1-conforming (continuous) finite elements.
void GetNodes(Vector &node_coord) const
double u(const Vector &xvec)
void exact_solution_gradient_obstacle(const Vector &pt, Vector &grad)
A class to handle Block systems in a matrix-free implementation.
Scalar coefficient defined as the linear combination of two scalar coefficients or a scalar and a sca...
void SetBlock(int iRow, int iCol, Operator *op, double c=1.0)
Add a block op in the block-entry (iblock, jblock).
int GMRES(const Operator &A, Vector &x, const Vector &b, Solver &M, int &max_iter, int m, double &tol, double atol, int printit)
GMRES method. (tolerances are squared)
void SetDiagonalBlock(int iblock, Operator *op)
Add a square block op in the block-entry (iblock, iblock).
Vector & GetBlock(int i)
Get the i-th vector in the block.
Arbitrary order "L2-conforming" discontinuous finite elements.
double f(const Vector &p)