35 #ifndef MFEM_USE_PETSC
36 #error This example requires that MFEM is built with MFEM_USE_PETSC=YES
49 int main(
int argc,
char *argv[])
55 MPI_Init(&argc, &argv);
56 MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
57 MPI_Comm_rank(MPI_COMM_WORLD, &myid);
58 bool verbose = (myid == 0);
61 const char *mesh_file =
"../../data/star.mesh";
63 bool par_format =
false;
64 bool visualization = 1;
65 bool use_petsc =
true;
66 bool use_nonoverlapping =
false;
67 const char *petscrc_file =
"";
70 args.
AddOption(&mesh_file,
"-m",
"--mesh",
73 "Finite element order (polynomial degree).");
74 args.
AddOption(&par_format,
"-pf",
"--parallel-format",
"-sf",
76 "Format to use when saving the results for VisIt.");
77 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
79 "Enable or disable GLVis visualization.");
80 args.
AddOption(&use_petsc,
"-usepetsc",
"--usepetsc",
"-no-petsc",
82 "Use or not PETSc to solve the linear system.");
83 args.
AddOption(&petscrc_file,
"-petscopts",
"--petscopts",
84 "PetscOptions file to use.");
85 args.
AddOption(&use_nonoverlapping,
"-nonoverlapping",
"--nonoverlapping",
86 "-no-nonoverlapping",
"--no-nonoverlapping",
87 "Use or not the block diagonal PETSc's matrix format "
88 "for non-overlapping domain decomposition.");
104 if (use_petsc) { PetscInitialize(NULL,NULL,petscrc_file,NULL); }
109 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
118 (int)floor(log(10000./mesh->
GetNE())/log(2.)/
dim);
119 for (
int l = 0; l < ref_levels; l++)
131 int par_ref_levels = 2;
132 for (
int l = 0; l < par_ref_levels; l++)
151 std::cout <<
"***********************************************************\n";
152 std::cout <<
"dim(R) = " << dimR <<
"\n";
153 std::cout <<
"dim(W) = " << dimW <<
"\n";
154 std::cout <<
"dim(R+W) = " << dimR + dimW <<
"\n";
155 std::cout <<
"***********************************************************\n";
164 block_offsets[0] = 0;
165 block_offsets[1] = R_space->
GetVSize();
166 block_offsets[2] = W_space->
GetVSize();
170 block_trueOffsets[0] = 0;
171 block_trueOffsets[1] = R_space->
TrueVSize();
172 block_trueOffsets[2] = W_space->
TrueVSize();
188 BlockVector trueX(block_trueOffsets), trueRhs(block_trueOffsets);
217 !use_petsc ? Operator::Hypre_ParCSR :
218 (use_nonoverlapping ? Operator::PETSC_MATIS : Operator::PETSC_MATAIJ);
225 if (!use_petsc) { Mh.Get(M); }
227 Mh.SetOperatorOwner(
false);
245 if (!use_petsc) { BT = B->Transpose(); }
246 else { pBT = pB->Transpose(); };
267 use_nonoverlapping ? Operator::PETSC_MATIS :
268 Operator::PETSC_MATAIJ);
299 invS->iterative_mode =
false;
307 if (use_nonoverlapping)
331 MFEM_ABORT(
"Need to know the boundary dofs");
367 solver.
Mult(trueRhs, trueX);
373 <<
" iterations with a residual norm of "
378 std::cout <<
"MINRES did not converge in "
380 <<
" iterations. Residual norm is "
383 std::cout <<
"MINRES solver took " << chrono.
RealTime() <<
"s. \n";
389 std::string solvertype;
391 if (use_nonoverlapping)
400 solvertype =
"MINRES";
408 solver->
Mult(trueRhs, trueX);
413 std::cout << solvertype <<
" converged in "
415 <<
" iterations with a residual norm of "
420 std::cout << solvertype <<
" did not converge in "
422 <<
" iterations. Residual norm is "
425 std::cout << solvertype <<
" solver took "
437 u->
MakeRef(R_space, x.GetBlock(0), 0);
438 p->
MakeRef(W_space, x.GetBlock(1), 0);
442 int order_quad = max(2, 2*order+1);
444 for (
int i=0; i < Geometry::NumGeom; ++i)
456 std::cout <<
"|| u_h - u_ex || / || u_ex || = " << err_u / norm_u <<
"\n";
457 std::cout <<
"|| p_h - p_ex || / || p_ex || = " << err_p / norm_p <<
"\n";
463 ostringstream mesh_name, u_name, p_name;
464 mesh_name <<
"mesh." << setfill(
'0') << setw(6) << myid;
465 u_name <<
"sol_u." << setfill(
'0') << setw(6) << myid;
466 p_name <<
"sol_p." << setfill(
'0') << setw(6) << myid;
468 ofstream mesh_ofs(mesh_name.str().c_str());
469 mesh_ofs.precision(8);
470 pmesh->
Print(mesh_ofs);
472 ofstream u_ofs(u_name.str().c_str());
476 ofstream p_ofs(p_name.str().c_str());
486 DataCollection::SERIAL_FORMAT :
487 DataCollection::PARALLEL_FORMAT);
493 char vishost[] =
"localhost";
496 u_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
498 u_sock <<
"solution\n" << *pmesh << *u <<
"window_title 'Velocity'"
504 p_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
506 p_sock <<
"solution\n" << *pmesh << *p <<
"window_title 'Pressure'"
538 if (use_petsc) { PetscFinalize(); }
556 u(0) = - exp(xi)*sin(yi)*cos(zi);
557 u(1) = - exp(xi)*cos(yi)*cos(zi);
561 u(2) = exp(xi)*sin(yi)*sin(zi);
577 return exp(xi)*sin(yi)*cos(zi);
int Size() const
Logical size of the array.
void SetPreconditioner(Solver &precond)
Sets the solver to perform preconditioning.
void SetPrintLevel(int plev)
Class for domain integration L(v) := (f, v)
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
virtual void GetEssentialTrueDofs(const Array< int > &bdr_attr_is_ess, Array< int > &ess_tdof_list, int component=-1)
Class for an integration rule - an Array of IntegrationPoint.
int GetNumIterations() const
Abstract class for PETSc's preconditioners.
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
void fFun(const Vector &x, Vector &f)
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
Subclass constant coefficient.
Wrapper for PETSc's matrix class.
Abstract class for PETSc's linear solvers.
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()
Save the collection and a VisIt root file.
virtual void Save(std::ostream &out) const
Abstract parallel finite element space.
void SetRelTol(double tol)
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
void SetMaxIter(int max_iter)
int main(int argc, char *argv[])
HypreParMatrix * ParMult(const HypreParMatrix *A, const HypreParMatrix *B)
Returns the matrix A * B.
double GetFinalNorm() const
virtual void MakeRef(FiniteElementSpace *f, double *v)
Make the ParGridFunction reference external data on a new FiniteElementSpace.
The BoomerAMG solver in hypre.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
HYPRE_Int GetGlobalNumRows() const
void SetPrintLevel(int print_lvl)
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
A class to handle Block diagonal preconditioners in a matrix-free implementation. ...
Jacobi preconditioner in hypre.
double f_natural(const Vector &x)
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Auxiliary class for BDDC customization.
MPI_Comm GetComm() const
Get the associated MPI communicator.
Data collection with VisIt I/O routines.
void SetMaxIter(int max_it)
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
HYPRE_Int GlobalTrueVSize() const
virtual void Print(std::ostream &out=mfem::out) const
virtual void SetFormat(int fmt)
Set the desired output mesh and data format.
double pFun_ex(const Vector &x)
HypreParMatrix * Transpose() const
Returns the transpose of *this.
void GetDiag(Vector &diag) const
Get the local diagonal of the matrix.
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
void PrintUsage(std::ostream &out) const
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
Wrapper for hypre's parallel vector class.
Type
Enumeration defining IDs for some classes derived from Operator.
void SetAbsTol(double atol)
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void SetRelTol(double rtol)
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)
void PartialSum()
Partial Sum.
double ComputeGlobalLpNorm(double p, Coefficient &coeff, ParMesh &pmesh, const IntegrationRule *irs[])
void Distribute(const Vector *tv)
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection and update the root file.
void uFun_ex(const Vector &x, Vector &u)
double gFun(const Vector &x)
void SetOperatorOwner(bool own=true)
Set the ownership flag for the held Operator.
virtual double ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL) const
void InvScaleRows(const Vector &s)
Scale the local row i by 1./s(i)
void SetAbsTol(double tol)
void PrintOptions(std::ostream &out) const
Abstract class for hypre's solvers and preconditioners.
for VectorFiniteElements (Nedelec, Raviart-Thomas)
class for C-function coefficient
void Get(OpType *&A) const
Return the Operator pointer statically cast to a given OpType.
HYPRE_Int * GetRowStarts() const
Class for parallel grid function.
void SetNatBdrDofs(const Array< int > *natdofs, bool loc=false)
Specify dofs on the natural boundary.
Wrapper for hypre's ParCSR matrix class.
A class to handle Block systems in a matrix-free implementation.
virtual void Mult(const Vector &b, Vector &x) const
Application of the solver.
Class for parallel meshes.
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Integrator for (Q u, v) for VectorFiniteElements.
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.