46int main(
int argc,
char *argv[])
51 const char *mesh_file =
"../../data/star.mesh";
52 const char *device_config =
"cpu";
56 bool use_saddle_point =
false;
58 bool use_lor_ams =
false;
59 bool use_hybridization =
false;
62 args.
AddOption(&device_config,
"-d",
"--device",
63 "Device configuration string, see Device::Configure().");
64 args.
AddOption(&mesh_file,
"-m",
"--mesh",
"Mesh file to use.");
65 args.
AddOption(&ser_ref,
"-rs",
"--serial-refine",
66 "Number of times to refine the mesh in serial.");
67 args.
AddOption(&par_ref,
"-rp",
"--parallel-refine",
68 "Number of times to refine the mesh in parallel.");
69 args.
AddOption(&order,
"-o",
"--order",
"Polynomial degree.");
71 "-sp",
"--saddle-point",
"-no-sp",
"--no-saddle-point",
72 "Enable or disable saddle-point solver.");
73 args.
AddOption(&use_ams,
"-ams",
"--ams",
"-no-ams",
"--no-ams",
74 "Enable or disable AMS solver.");
75 args.
AddOption(&use_lor_ams,
"-lor",
"--lor-ams",
"-no-lor",
"--no-lor-ams",
76 "Enable or disable LOR-AMS solver.");
78 "-hb",
"--hybridization",
"-no-hb",
"--no-hybridization",
79 "Enable or disable hybridization solver.");
82 if (!use_saddle_point && !use_ams && !use_lor_ams && !use_hybridization)
84 if (
Mpi::Root()) { cout <<
"No solver enabled. Exiting.\n"; }
88 Device device(device_config);
93 MFEM_VERIFY(
dim == 2 ||
dim == 3,
"Spatial dimension must be 2 or 3.");
107 b.UseFastAssembly(
true);
119 if (use_saddle_point)
121 if (
Mpi::Root()) { cout <<
"\nSaddle point solver... " << flush; }
129 mesh, fes_rt, fes_l2, alpha_coeff, beta_coeff, ess_rt_dofs,
130 HdivSaddlePointSolver::Mode::GRAD_DIV);
141 saddle_point_solver.
SetBC(X_block.GetBlock(1));
144 saddle_point_solver.
Mult(B_block, X_block);
148 cout <<
"Done.\nIterations: "
153 X_block.SyncToBlocks();
156 if (
Mpi::Root()) { cout <<
"L2 error: " << error << endl; }
161 if (
Mpi::Root()) { cout <<
"\nAMS solver... " << flush; }
173 a.FormLinearSystem(ess_rt_dofs, x,
b, A, X, B);
176 std::unique_ptr<Solver> prec;
177 if (
dim == 2) { prec.reset(
new HypreAMS(Ah, &fes_rt)); }
178 else { prec.reset(
new HypreADS(Ah, &fes_rt)); }
183 if (
Mpi::Root()) { cout <<
"L2 error: " << error << endl; }
197 if (
Mpi::Root()) { cout <<
"\nLOR-AMS solver... " << flush; }
201 a.SetAssemblyLevel(AssemblyLevel::PARTIAL);
211 a.FormLinearSystem(ess_rt_dofs, x_lor, b_lor, A, X, B);
213 std::unique_ptr<Solver> prec;
218 a.RecoverFEMSolution(X, b_lor, x_lor);
220 if (
Mpi::Root()) { cout <<
"L2 error: " << error << endl; }
223 if (use_hybridization)
225 if (
Mpi::Root()) { cout <<
"\nHybridization solver... " << flush; }
241 a.FormLinearSystem(ess_rt_dofs, x,
b, A, X, B);
247 a.RecoverFEMSolution(X,
b, x);
249 if (
Mpi::Root()) { cout <<
"L2 error: " << error << endl; }
259 ParMesh mesh(MPI_COMM_WORLD, serial_mesh);
@ GaussLobatto
Closed type.
@ GaussLegendre
Open type.
@ IntegratedGLL
Integrated GLL indicator functions.
A class to handle Vectors in a block fashion.
void SyncFromBlocks() const
Synchronize the memory location flags (i.e. the memory validity flags) of the big/monolithic block-ve...
Vector & GetBlock(int i)
Get the i-th vector in the block.
Conjugate gradient method.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
virtual void Mult(const Vector &b, Vector &x) const
Iterative solution of the linear system using the Conjugate Gradient method.
A coefficient that is constant across space and time.
The MFEM Device class abstracts hardware devices such as GPUs, as well as programming models such as ...
void Print(std::ostream &out=mfem::out)
Print the configuration of the MFEM virtual device object.
for Raviart-Thomas elements
void GetBoundaryTrueDofs(Array< int > &boundary_dofs, int component=-1)
Get a list of all boundary true dofs, boundary_dofs. For spaces with 'vdim' > 1, the 'component' para...
Solve the H(div) saddle-point system using MINRES with matrix-free block-diagonal preconditioning.
const Array< int > & GetOffsets() const
Return the offsets of the block system.
void Mult(const Vector &b, Vector &x) const override
Solve the linear system for L2 (scalar) and RT (flux) unknowns.
void SetBC(const Vector &x_rt)
Sets the Dirichlet boundary conditions at the RT essential DOFs.
int GetNumIterations() const
Get the number of MINRES iterations.
The Auxiliary-space Divergence Solver in hypre.
The Auxiliary-space Maxwell Solver in hypre.
The BoomerAMG solver in hypre.
void SetPrintLevel(int print_level)
Wrapper for hypre's ParCSR matrix class.
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
void SetRelTol(real_t rtol)
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
int GetNumIterations() const
Returns the number of iterations taken during the last call to Mult()
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
void SetMaxIter(int max_it)
void SetAbsTol(real_t atol)
Arbitrary order "L2-conforming" discontinuous finite elements.
Represents a solver of type SolverType created using the low-order refined version of the given Bilin...
void Clear()
Clear the contents of the Mesh.
int Dimension() const
Dimension of the reference space used within the elements.
static Mesh LoadFromFile(const std::string &filename, int generate_edges=0, int refine=1, bool fix_orientation=true)
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
static bool Root()
Return true if the rank in MPI_COMM_WORLD is zero.
static void Init(int &argc, char **&argv, int required=default_thread_required, int *provided=nullptr)
Singleton creation with Mpi::Init(argc, argv).
Pointer to an Operator of a specified type.
OpType * As() const
Return the Operator pointer statically cast to a specified OpType. Similar to the method Get().
void ParseCheck(std::ostream &out=mfem::out)
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...
Abstract parallel finite element space.
Class for parallel grid function.
real_t ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL, const Array< int > *elems=NULL) const override
void SetFromTrueDofs(const Vector &tv) override
Set the GridFunction from the given true-dof vector.
void ProjectCoefficient(Coefficient &coeff) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
void ParallelProject(Vector &tv) const
Returns the vector restricted to the true dofs.
Class for parallel meshes.
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
double RealTime()
Return the number of real seconds elapsed since the stopwatch was started.
void Start()
Start the stopwatch. The elapsed time is not cleared.
void Clear()
Clear the elapsed time on the stopwatch and restart it if it's running.
for VectorFiniteElements (Nedelec, Raviart-Thomas)
A general vector function coefficient.
void SolveCG(Operator &A, Solver &P, const Vector &B, Vector &X)
ParMesh LoadParMesh(const char *mesh_file, int ser_ref=0, int par_ref=0)
void u_vec(const Vector &xvec, Vector &u)
std::function< void(const Vector &, Vector &)> f_vec(bool grad_div_problem)