56 int main(
int argc,
char *argv[])
60 MPI_Init(&argc, &argv);
61 MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
62 MPI_Comm_rank(MPI_COMM_WORLD, &myid);
65 const char *mesh_file =
"../data/beam-hex.mesh";
68 bool static_cond =
false;
70 const char *device_config =
"cpu";
71 bool visualization = 1;
74 args.
AddOption(&mesh_file,
"-m",
"--mesh",
77 "Finite element order (polynomial degree).");
78 args.
AddOption(&prob,
"-p",
"--problem-type",
79 "Choose between 0: grad, 1: curl, 2: div");
80 args.
AddOption(&static_cond,
"-sc",
"--static-condensation",
"-no-sc",
81 "--no-static-condensation",
"Enable static condensation.");
82 args.
AddOption(&pa,
"-pa",
"--partial-assembly",
"-no-pa",
83 "--no-partial-assembly",
"Enable Partial Assembly.");
84 args.
AddOption(&device_config,
"-d",
"--device",
85 "Device configuration string, see Device::Configure().");
86 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
88 "Enable or disable GLVis visualization.");
108 Device device(device_config);
109 if (myid == 0) { device.
Print(); }
114 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
123 int ref_levels = (int)floor(log(1000./mesh->
GetNE())/log(2.)/
dim);
124 for (
int l = 0; l < ref_levels; l++)
138 int par_ref_levels = 1;
139 for (
int l = 0; l < par_ref_levels; l++)
177 cout <<
"Number of Nedelec finite element unknowns: " << test_size << endl;
178 cout <<
"Number of H1 finite element unknowns: " << trial_size << endl;
182 cout <<
"Number of Nedelec finite element unknowns: " << trial_size << endl;
183 cout <<
"Number of Raviart-Thomas finite element unknowns: " << test_size <<
188 cout <<
"Number of Raviart-Thomas finite element unknowns: "
189 << trial_size << endl;
190 cout <<
"Number of L2 finite element unknowns: " << test_size << endl;
265 a_mixed.
Mult(gftrial, b);
334 dlo.
Mult(gftrial, discreteInterpolant);
358 double errInterp = discreteInterpolant.
ComputeL2Error(gradp_coef);
363 cout <<
"\n Solution of (E_h,v) = (grad p_h,v) for E_h and v in H(curl)"
364 ": || E_h - grad p ||_{L_2} = " << errSol <<
'\n' << endl;
365 cout <<
" Gradient interpolant E_h = grad p_h in H(curl): || E_h - grad"
366 " p ||_{L_2} = " << errInterp <<
'\n' << endl;
367 cout <<
" Projection E_h of exact grad p in H(curl): || E_h - grad p "
368 "||_{L_2} = " << errProj <<
'\n' << endl;
374 double errInterp = discreteInterpolant.
ComputeL2Error(curlv_coef);
379 cout <<
"\n Solution of (E_h,w) = (curl v_h,w) for E_h and w in "
380 "H(div): || E_h - curl v ||_{L_2} = " << errSol <<
'\n' << endl;
381 cout <<
" Curl interpolant E_h = curl v_h in H(div): || E_h - curl v "
382 "||_{L_2} = " << errInterp <<
'\n' << endl;
383 cout <<
" Projection E_h of exact curl v in H(div): || E_h - curl v "
384 "||_{L_2} = " << errProj <<
'\n' << endl;
389 int order_quad = max(2, 2*order+1);
391 for (
int i=0; i < Geometry::NumGeom; ++i)
397 double errInterp = discreteInterpolant.
ComputeL2Error(divgradp_coef, irs);
402 cout <<
"\n Solution of (f_h,q) = (div v_h,q) for f_h and q in L_2: "
403 "|| f_h - div v ||_{L_2} = " << errSol <<
'\n' << endl;
404 cout <<
" Divergence interpolant f_h = div v_h in L_2: || f_h - div v"
405 " ||_{L_2} = " << errInterp <<
'\n' << endl;
406 cout <<
" Projection f_h of exact div v in L_2: || f_h - div v "
407 "||_{L_2} = " << errProj <<
'\n' << endl;
414 ostringstream mesh_name, sol_name;
415 mesh_name <<
"mesh." << setfill(
'0') << setw(6) << myid;
416 sol_name <<
"sol." << setfill(
'0') << setw(6) << myid;
418 ofstream mesh_ofs(mesh_name.str().c_str());
419 mesh_ofs.precision(8);
420 pmesh->
Print(mesh_ofs);
422 ofstream sol_ofs(sol_name.str().c_str());
423 sol_ofs.precision(8);
433 sol_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
434 sol_sock.precision(8);
435 sol_sock <<
"solution\n" << *pmesh << x << flush;
452 return sin(x(0)) * sin(x(1)) * sin(x(2));
456 return sin(x(0)) * sin(x(1));
466 f(0) = cos(x(0)) * sin(x(1)) * sin(x(2));
467 f(1) = sin(x(0)) * cos(x(1)) * sin(x(2));
468 f(2) = sin(x(0)) * sin(x(1)) * cos(x(2));
472 f(0) = cos(x(0)) * sin(x(1));
473 f(1) = sin(x(0)) * cos(x(1));
474 if (x.
Size() == 3) {
f(2) = 0.0; }
482 return -3.0 * sin(x(0)) * sin(x(1)) * sin(x(2));
486 return -2.0 * sin(x(0)) * sin(x(1));
496 v(0) = sin(
kappa * x(1));
497 v(1) = sin(
kappa * x(2));
498 v(2) = sin(
kappa * x(0));
502 v(0) = sin(
kappa * x(1));
503 v(1) = sin(
kappa * x(0));
504 if (x.
Size() == 3) { v(2) = 0.0; }
Conjugate gradient method.
Class for an integration rule - an Array of IntegrationPoint.
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
void SetFromTrueVector()
Shortcut for calling SetFromTrueDofs() with GetTrueVector() as argument.
A coefficient that is constant across space and time.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
virtual void ReorientTetMesh()
See the remarks for the serial version in mesh.hpp.
Pointer to an Operator of a specified type.
int Size() const
Returns the size of the vector.
int GetNE() const
Returns number of elements.
virtual void Save(std::ostream &out) const
void Print(std::ostream &out=mfem::out)
Print the configuration of the MFEM virtual device object.
Abstract parallel finite element space.
virtual void ProjectCoefficient(Coefficient &coeff)
int main(int argc, char *argv[])
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0)
Computes y = alpha * A * x + beta * y.
void SetPrintLevel(int print_lvl)
void AddDomainInterpolator(DiscreteInterpolator *di)
Adds a domain interpolator. Assumes ownership of di.
virtual int GetTrueVSize() const
Return the number of local vector true dofs.
void SetTrueVector()
Shortcut for calling GetTrueDofs() with GetTrueVector() as argument.
void SetPrintLevel(int print_lvl)
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 ...
void curlv_exact(const Vector &x, Vector &cv)
Jacobi preconditioner in hypre.
Jacobi smoothing for a given bilinear form (no matrix necessary).
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
void SetMaxIter(int max_it)
HYPRE_Int GlobalTrueVSize() const
virtual void Print(std::ostream &out=mfem::out) const
void v_exact(const Vector &x, Vector &v)
void PrintUsage(std::ostream &out) const
Print the usage message.
void SetMaxIter(int max_iter)
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
double p_exact(const Vector &x)
A general vector function coefficient.
int SpaceDimension() const
void SetRelTol(double rtol)
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
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...
virtual double ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL) const
void SetPreconditioner(HypreSolver &precond)
Set the hypre solver to be used as a preconditioner.
void PrintOptions(std::ostream &out) const
Print the options.
HypreParVector * GetTrueDofs() const
Returns the true dofs in a new HypreParVector.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
A general function coefficient.
Arbitrary order H(curl)-conforming Nedelec finite elements.
double div_gradp_exact(const Vector &x)
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
Arbitrary order H1-conforming (continuous) finite elements.
Class for parallel grid function.
The MFEM Device class abstracts hardware devices such as GPUs, as well as programming models such as ...
Wrapper for hypre's ParCSR matrix class.
virtual void Assemble(int skip_zeros=1)
Construct the internal matrix representation of the discrete linear operator.
virtual void Mult(const HypreParVector &b, HypreParVector &x) const
Solve Ax=b with hypre's PCG.
Class for parallel meshes.
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Arbitrary order "L2-conforming" discontinuous finite elements.
double f(const Vector &p)
void gradp_exact(const Vector &, Vector &)
bool Good() const
Return true if the command line options were parsed successfully.