46int main(
int argc,
char *argv[])
53 string mesh_file =
"../../data/ref-cube.mesh";
58 int assembly_type_int = 3;
61 int refine_serial = 3;
62 int refine_parallel = 0;
64 int geometric_levels = 1;
73 string device_config =
"cpu";
74 bool use_monitor =
false;
75 bool visualization =
true;
78 args.
AddOption(&mesh_file,
"-m",
"--mesh",
81 "Finite element order (polynomial degree)");
82 args.
AddOption(&geometric_levels,
"-gl",
"--geometric-levels",
83 "Number of geometric refinements (levels) done prior to order"
85 args.
AddOption(&order_levels,
"-ol",
"--order-levels",
86 "Number of order refinements (levels). "
87 "Finest level in the hierarchy has order 2^{or}.");
88 args.
AddOption((
int*)&solver_type,
"-s",
"--solver",
89 "Solvers to be considered:"
90 "\n\t0: Stationary Linear Iteration"
91 "\n\t1: Preconditioned Conjugate Gradient");
92 args.
AddOption((
int*)&integrator_type,
"-i",
"--integrator",
93 "Integrators to be considered:"
94 "\n\t0: MassIntegrator"
95 "\n\t1: DiffusionIntegrator");
96 args.
AddOption(&assembly_type_int,
"-a",
"--assembly",
97 "Assembly level to be considered:"
103 args.
AddOption(&refine_serial,
"-rs",
"--refine-serial",
104 "Number of serial refinements");
105 args.
AddOption(&refine_parallel,
"-rp",
"--refine-parallel",
106 "Number of parallel refinements");
107 args.
AddOption(&rel_tol,
"-t",
"--tolerance",
108 "Relative tolerance for the iterative solver");
109 args.
AddOption(&max_iter,
"-ni",
"--iterations",
110 "Maximum number of iterations");
111 args.
AddOption(&eps_y,
"-Ky",
"--Kershaw-y",
112 "Kershaw transform factor, eps_y in (0,1]");
113 args.
AddOption(&eps_z,
"-Kz",
"--Kershaw-z",
114 "Kershaw transform factor, eps_z in (0,1]");
115 args.
AddOption(&
freq,
"-f",
"--frequency",
"Set the frequency for the exact"
117 args.
AddOption(&device_config,
"-d",
"--device",
118 "Device configuration string, see Device::Configure().");
119 args.
AddOption(&use_monitor,
"-mon",
"--monitor",
"-no-mon",
121 "Enable or disable Data Monitor.");
122 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
123 "--no-visualization",
124 "Enable or disable GLVis visualization.");
127 MFEM_VERIFY((0 <= solver_type) && (solver_type <
num_solvers),
128 "invalid solver type: " << solver_type);
129 MFEM_VERIFY((0 <= integrator_type) && (integrator_type <
num_integrators),
130 "invalid integrator type: " << integrator_type);
131 MFEM_VERIFY((0 <= assembly_type_int) && (assembly_type_int < 6),
132 "invalid assembly type: " << assembly_type_int);
133 MFEM_VERIFY(geometric_levels >= 0,
134 "geometric_levels needs to be non-negative");
135 MFEM_VERIFY(order_levels >= 0,
"order_levels needs to be non-negative");
136 MFEM_VERIFY((0.0 <= eps_y) && (eps_y <= 1.0),
"eps_y must be in [0,1]");
137 MFEM_VERIFY((0.0 <= eps_z) && (eps_z <= 1.0),
"eps_z must be in [0,1]");
141 ostringstream file_name;
144 file_name <<
"MGABS-"
145 <<
"G" << geometric_levels
146 <<
"O" << order_levels
148 <<
"I" << (int) integrator_type
149 <<
"S" << (
int) solver_type
150 <<
"A" << assembly_type_int
154 string assembly_description;
155 switch (assembly_type_int)
158 assembly_type = AssemblyLevel::LEGACY;
159 assembly_description =
"Using Legacy type of assembly level...";
162 assembly_type = AssemblyLevel::FULL;
163 assembly_description =
"Using Full type of assembly level...";
166 assembly_type = AssemblyLevel::ELEMENT;
167 assembly_description =
"Using Element type of assembly level...";
170 assembly_type = AssemblyLevel::PARTIAL;
171 assembly_description =
"Using Partial type of assembly level...";
174 assembly_type = AssemblyLevel::NONE;
175 assembly_description =
"Using matrix-free type of assembly level...";
178 MFEM_ABORT(
"Unsupported option!");
181 Device device(device_config);
186 Mesh *serial_mesh =
new Mesh(mesh_file);
187 for (
int ls = 0; ls < refine_serial; ls++)
197 for (
int lp = 0; lp < refine_parallel; lp++)
205 bool cond_z = (
dim < 3) ?
true : (eps_z != 0.0);
206 if (eps_y != 0.0 && cond_z)
208 if (
dim < 3) { eps_z = 0.0; }
219 switch (integrator_type)
227 mfem_error(
"Maxwell integrator not supported in this miniapp!");
229 mfem_error(
"Invalid integrator type! Check FiniteElementCollection");
236 mfem::out <<
"Warning! Polynomial order provided. "
237 <<
"Ignoring order level..." << endl;
251 for (
int lg = 0; lg < geometric_levels; ++lg)
255 for (
int lo = 0; lo < order_levels; ++lo)
257 switch (integrator_type)
265 "FiniteElementCollection for order refinements...");
273 mfem::out <<
"Number of unknowns: " << sys_size << endl;
274 mfem::out << assembly_description << endl;
301 switch (integrator_type)
315 mfem_error(
"Invalid integrator type! Check ParLinearForm");
317 b->AddDomainIntegrator(lfi);
328 mg->SetCycleType(Multigrid::CycleType::VCYCLE, 1, 1);
329 mg->FormFineLinearSystem(x, *
b, A, X, B);
342 solver =
new CGSolver(MPI_COMM_WORLD);
367 mg->RecoverFineFEMSolution(X, *
b, x);
376 sol_sock.precision(8);
377 sol_sock <<
"solution\n"
385 switch (integrator_type)
392 mfem_error(
"Invalid integrator type! Check ComputeL2Error");
396 mfem::out <<
"\n|| u_h - u ||_{L^2} = " << error <<
"\n" << endl;
404 if (monitor) {
delete monitor; }
405 if (scalar_u) {
delete scalar_u; }
406 if (scalar_f) {
delete scalar_f; }
407 for (
int level = 0; level < fec_array.
Size(); ++level)
409 delete fec_array[level];
411 delete fes_hierarchy;
Abs-L(1)-Jacobi custom general geometric multigrid method.
Custom monitor that prints a csv-formatted file.
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.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
T & Last()
Return the last element in the array.
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 &os=mfem::out)
Print the configuration of the MFEM virtual device object.
Class for domain integration .
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
A general function coefficient.
Arbitrary order H1-conforming (continuous) finite elements.
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Abstract base class for iterative solver.
void SetRelTol(real_t rtol)
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
void SetMaxIter(int max_it)
void SetMonitor(IterativeSolverMonitor &m)
An alias of SetController() for backward compatibility.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
int Dimension() const
Dimension of the reference space used within the elements.
void Transform(std::function< void(const Vector &, Vector &)> f)
int SpaceDimension() const
Dimension of the physical space containing the mesh.
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
static bool Root()
Return true if the rank in MPI_COMM_WORLD is zero.
static int WorldRank()
Return the MPI rank in MPI_COMM_WORLD.
static int WorldSize()
Return the size of MPI_COMM_WORLD.
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.
void SetOperatorOwner(bool own=true)
Set the ownership flag for the held Operator.
Operator * Ptr() const
Access the underlying Operator pointer.
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
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...
void AddUniformlyRefinedLevel(int dim=1, int ordering=Ordering::byVDIM) override
Adds one level to the hierarchy by uniformly refining the mesh on the previous level.
void AddOrderRefinedLevel(FiniteElementCollection *fec, int dim=1, int ordering=Ordering::byVDIM) override
Adds one level to the hierarchy by using a different finite element order defined through FiniteEleme...
const ParFiniteElementSpace & GetFinestFESpace() const override
Returns the finite element space at the finest level.
Abstract parallel finite element space.
HYPRE_BigInt GlobalTrueVSize() const
ParMesh * GetParMesh() const
Class for parallel grid function.
real_t ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL, const Array< int > *elems=NULL) const override
Returns ||u_ex - u_h||_L2 in parallel for H1 or L2 elements.
void ProjectBdrCoefficient(Coefficient *coeff[], VectorCoefficient *vcoeff, const Array< int > &attr)
Class for parallel meshes.
Stationary linear iteration: x <- x + B (b - A x)
virtual void SetOperator(const Operator &op)=0
Set/update the solver for the given operator.
real_t diffusion_source(const Vector &x)
real_t diffusion_solution(const Vector &x)
void mfem_error(const char *msg)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
AssemblyLevel
Enumeration defining the assembly level for bilinear and nonlinear form classes derived from Operator...