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[])
79 int num_procs = Mpi::WorldSize();
80 int myid = Mpi::WorldRank();
89 bool visualization =
true;
93 "Finite element order (polynomial degree).");
94 args.
AddOption(&ref_levels,
"-r",
"--refs",
95 "Number of h-refinements.");
96 args.
AddOption(&max_it,
"-mi",
"--max-it",
97 "Maximum number of iterations");
99 "Stopping criteria based on the difference between" 100 "successive solution updates");
103 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
104 "--no-visualization",
105 "Enable or disable GLVis visualization.");
121 const char *mesh_file =
"../data/disc-nurbs.mesh";
122 Mesh mesh(mesh_file, 1, 1);
127 for (
int l = 0; l < ref_levels; l++)
134 int curvature_order = max(order,2);
139 double scale = 2*sqrt(2);
142 ParMesh pmesh(MPI_COMM_WORLD, mesh);
153 MPI_Allreduce(MPI_IN_PLACE, &num_dofs_H1, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
155 MPI_Allreduce(MPI_IN_PLACE, &num_dofs_L2, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
158 cout <<
"Number of H1 finite element unknowns: " 159 << num_dofs_H1 << endl;
160 cout <<
"Number of L2 finite element unknowns: " 161 << num_dofs_L2 << endl;
180 tx = 0.0; trhs = 0.0;
193 auto IC_func = [](
const Vector &x)
197 for (
int i=0; i<x.Size(); i++)
209 u_gf.
MakeRef(&H1fes,x,offsets[0]);
210 delta_psi_gf.
MakeRef(&L2fes,x,offsets[1]);
230 LogarithmGridFunctionCoefficient ln_u(u_gf, obstacle);
240 sol_sock.precision(8);
245 int total_iterations = 0;
246 double increment_u = 0.1;
247 for (k = 0; k < max_it; k++)
254 mfem::out <<
"\nOUTER ITERATION " << k+1 << endl;
258 for ( j = 0; j < 10; j++)
268 ExponentialGridFunctionCoefficient exp_psi(psi_gf, zero);
290 A00, tx.GetBlock(0), trhs.
GetBlock(0));
299 A10, tx.GetBlock(0), trhs.
GetBlock(1));
353 delta_psi_gf *= gamma;
354 psi_gf += delta_psi_gf;
358 sol_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
359 sol_sock <<
"solution\n" << pmesh << u_gf <<
"window_title 'Discrete solution'" 365 mfem::out <<
"Newton_update_size = " << Newton_update_size << endl;
370 if (Newton_update_size < increment_u)
382 mfem::out <<
"Number of Newton iterations = " << j+1 << endl;
383 mfem::out <<
"Increment (|| uₕ - uₕ_prvs||) = " << increment_u << endl;
389 if (increment_u < tol || k == max_it-1)
394 double H1_error = u_gf.
ComputeH1Error(&exact_coef,&exact_grad_coef);
397 mfem::out <<
"H1-error (|| u - uₕᵏ||) = " << H1_error << endl;
404 mfem::out <<
"\n Outer iterations: " << k+1
405 <<
"\n Total iterations: " << total_iterations
406 <<
"\n Total dofs: " << num_dofs_H1 + num_dofs_L2
414 err_sock.precision(8);
420 err_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
421 err_sock <<
"solution\n" << pmesh << error_gf <<
"window_title 'Error'" <<
427 double H1_error = u_gf.
ComputeH1Error(&exact_coef,&exact_grad_coef);
429 ExponentialGridFunctionCoefficient u_alt_cf(psi_gf,obstacle);
436 mfem::out <<
"\n Final L2-error (|| u - uₕ||) = " << L2_error <<
438 mfem::out <<
" Final H1-error (|| u - uₕ||) = " << H1_error << endl;
439 mfem::out <<
" Final L2-error (|| u - ϕ - exp(ψₕ)||) = " << L2_error_alt <<
450 MFEM_ASSERT(
u != NULL,
"grid function is not set");
452 double val =
u->GetValue(T, ip) - obstacle->Eval(T, ip);
453 return max(min_val, log(val));
459 MFEM_ASSERT(
u != NULL,
"grid function is not set");
461 double val =
u->GetValue(T, ip);
462 return min(max_val, max(min_val, exp(val) + obstacle->Eval(T, ip)));
467 double x = pt(0), y = pt(1);
468 double r = sqrt(x*x + y*y);
473 double tmp = sqrt(r0*r0 -
b*
b);
474 double B = tmp +
b*
b/tmp;
483 return sqrt(r0*r0 - r*r);
489 double x = pt(0), y = pt(1);
490 double r = sqrt(x*x + y*y);
492 double a = 0.348982574111686;
493 double A = -0.340129705945858;
501 return sqrt(r0*r0-r*r);
507 double x = pt(0), y = pt(1);
508 double r = sqrt(x*x + y*y);
510 double a = 0.348982574111686;
511 double A = -0.340129705945858;
515 grad(0) = A * x / (r*r);
516 grad(1) = A * y / (r*r);
520 grad(0) = - x / sqrt( r0*r0 - r*r );
521 grad(1) = - y / sqrt( r0*r0 - r*r );
Class for domain integration L(v) := (f, v)
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1)
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. ...
int main(int argc, char *argv[])
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.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
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.
Abstract parallel finite element space.
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
virtual void SetOperator(const Operator &op) override
Also calls SetOperator for the preconditioner if there is one.
virtual void MakeRef(FiniteElementSpace *f, double *v)
Make the ParGridFunction reference external data on a new FiniteElementSpace.
double spherical_obstacle(const Vector &pt)
The BoomerAMG solver in hypre.
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
virtual void SetFromTrueDofs(const Vector &tv)
Set the GridFunction from the given true-dof vector.
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 *)
void SetPrintLevel(int print_level)
void SetMaxIter(int max_it)
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.
void SetKDim(int dim)
Set the number of iteration to perform between restarts, default is 50.
Parallel smoothers in hypre.
virtual double ComputeH1Error(Coefficient *exsol, VectorCoefficient *exgrad, Coefficient *ell_coef, double Nu, int norm_type) const
Set the diagonal value to one.
virtual double ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL, const Array< int > *elems=NULL) const
A general vector function coefficient.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void SetRelTol(double rtol)
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
double exact_solution_obstacle(const Vector &pt)
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 PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
void exact_solution_gradient_obstacle(const Vector &pt, Vector &grad)
HypreParMatrix * Transpose() const
Returns the transpose of *this.
virtual int GetTrueVSize() const
Return the number of local vector true dofs.
Class for integration point with weight.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
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.
void Clear()
Clear the contents of the Mesh.
A general function coefficient.
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Arbitrary order H1-conforming (continuous) finite elements.
void GetNodes(Vector &node_coord) const
double u(const Vector &xvec)
Class for parallel grid function.
Wrapper for hypre's ParCSR matrix class.
A class to handle Block systems in a matrix-free implementation.
Class for parallel meshes.
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).
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)