54 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);
63 bool verbose = (myid == 0);
66 const char *mesh_file =
"../data/star.mesh";
69 bool par_format =
false;
71 const char *device_config =
"cpu";
72 bool visualization = 1;
76 args.
AddOption(&mesh_file,
"-m",
"--mesh",
78 args.
AddOption(&ref_levels,
"-r",
"--refine",
79 "Number of times to refine the mesh uniformly.");
81 "Finite element order (polynomial degree).");
82 args.
AddOption(&par_format,
"-pf",
"--parallel-format",
"-sf",
84 "Format to use when saving the results for VisIt.");
85 args.
AddOption(&pa,
"-pa",
"--partial-assembly",
"-no-pa",
86 "--no-partial-assembly",
"Enable Partial Assembly.");
87 args.
AddOption(&device_config,
"-d",
"--device",
88 "Device configuration string, see Device::Configure().");
89 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
91 "Enable or disable GLVis visualization.");
92 args.
AddOption(&adios2,
"-adios2",
"--adios2-streams",
"-no-adios2",
93 "--no-adios2-streams",
94 "Save data using adios2 streams.");
112 Device device(device_config);
113 if (myid == 0) { device.
Print(); }
118 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
126 if (ref_levels == -1)
128 ref_levels = (int)floor(log(10000./mesh->
GetNE())/log(2.)/
dim);
131 for (
int l = 0; l < ref_levels; l++)
143 int par_ref_levels = 2;
144 for (
int l = 0; l < par_ref_levels; l++)
163 std::cout <<
"***********************************************************\n";
164 std::cout <<
"dim(R) = " << dimR <<
"\n";
165 std::cout <<
"dim(W) = " << dimW <<
"\n";
166 std::cout <<
"dim(R+W) = " << dimR + dimW <<
"\n";
167 std::cout <<
"***********************************************************\n";
176 block_offsets[0] = 0;
177 block_offsets[1] = R_space->
GetVSize();
178 block_offsets[2] = W_space->
GetVSize();
182 block_trueOffsets[0] = 0;
183 block_trueOffsets[1] = R_space->
TrueVSize();
184 block_trueOffsets[2] = W_space->
TrueVSize();
200 BlockVector x(block_offsets, mt), rhs(block_offsets, mt);
201 BlockVector trueX(block_trueOffsets, mt), trueRhs(block_trueOffsets, mt);
292 for (
int i=0; i<Md_PA.
Size(); ++i)
294 invMd(i) = 1.0 / Md_host[i];
329 int maxIter(pa ? 1000 : 500);
343 solver.
Mult(trueRhs, trueX);
344 if (device.
IsEnabled()) { trueX.HostRead(); }
351 <<
" iterations with a residual norm of " << solver.
GetFinalNorm() <<
".\n";
354 <<
" iterations. Residual norm is " << solver.
GetFinalNorm() <<
".\n";
355 std::cout <<
"MINRES solver took " << chrono.
RealTime() <<
"s. \n";
363 u->
MakeRef(R_space, x.GetBlock(0), 0);
364 p->
MakeRef(W_space, x.GetBlock(1), 0);
368 int order_quad = max(2, 2*order+1);
370 for (
int i=0; i < Geometry::NumGeom; ++i)
382 std::cout <<
"|| u_h - u_ex || / || u_ex || = " << err_u / norm_u <<
"\n";
383 std::cout <<
"|| p_h - p_ex || / || p_ex || = " << err_p / norm_p <<
"\n";
389 ostringstream mesh_name, u_name, p_name;
390 mesh_name <<
"mesh." << setfill(
'0') << setw(6) << myid;
391 u_name <<
"sol_u." << setfill(
'0') << setw(6) << myid;
392 p_name <<
"sol_p." << setfill(
'0') << setw(6) << myid;
394 ofstream mesh_ofs(mesh_name.str().c_str());
395 mesh_ofs.precision(8);
396 pmesh->
Print(mesh_ofs);
398 ofstream u_ofs(u_name.str().c_str());
402 ofstream p_ofs(p_name.str().c_str());
412 DataCollection::SERIAL_FORMAT :
413 DataCollection::PARALLEL_FORMAT);
430 #ifdef MFEM_USE_ADIOS2
433 std::string postfix(mesh_file);
434 postfix.erase(0, std::string(
"../data/").size() );
435 postfix +=
"_o" + std::to_string(order);
436 const std::string collection_name =
"ex5-p_" + postfix +
".bp";
454 u_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
456 u_sock <<
"solution\n" << *pmesh << *u <<
"window_title 'Velocity'"
462 p_sock <<
"parallel " << num_procs <<
" " << myid <<
"\n";
464 p_sock <<
"solution\n" << *pmesh << *p <<
"window_title 'Pressure'"
507 u(0) = - exp(xi)*sin(yi)*cos(zi);
508 u(1) = - exp(xi)*cos(yi)*cos(zi);
512 u(2) = exp(xi)*sin(yi)*sin(zi);
528 return exp(xi)*sin(yi)*cos(zi);
Class for domain integration L(v) := (f, v)
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
Class for an integration rule - an Array of IntegrationPoint.
int GetNumIterations() const
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
void fFun(const Vector &x, Vector &f)
A class to handle Vectors in a block fashion.
void SetDataFormat(VTKFormat fmt)
A coefficient that is constant across space and time.
void SetSize(int s)
Resize the vector to size s.
Helper class for ParaView visualization data.
int TrueVSize() const
Obsolete, kept for backward compatibility.
Pointer to an Operator of a specified type.
HYPRE_BigInt GlobalTrueVSize() const
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
void Print(std::ostream &out=mfem::out)
Print the configuration of the MFEM virtual device object.
Abstract parallel finite element space.
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
void SyncAliasMemory(const Vector &v) const
Update the alias memory location of the vector to match v.
static bool IsEnabled()
Return true if any backend other than Backend::CPU is enabled.
HypreParMatrix * ParMult(const HypreParMatrix *A, const HypreParMatrix *B, bool own_matrix)
double GetFinalNorm() const
virtual int GetTrueVSize() const
Return the number of local vector true dofs.
void Stop()
Stop the stopwatch.
virtual void MakeRef(FiniteElementSpace *f, double *v)
Make the ParGridFunction reference external data on a new FiniteElementSpace.
HYPRE_BigInt * GetRowStarts() const
Return the parallel row partitioning array.
The BoomerAMG solver in hypre.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void SetPrintLevel(int print_lvl)
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
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. ...
Jacobi preconditioner in hypre.
Jacobi smoothing for a given bilinear form (no matrix necessary).
double f_natural(const Vector &x)
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
static MemoryType GetMemoryType()
(DEPRECATED) Equivalent to GetDeviceMemoryType().
Data collection with VisIt I/O routines.
void SetMaxIter(int max_it)
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 SetHighOrderOutput(bool high_order_output_)
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
Print the usage message.
void SetTime(double t)
Set physical time (for time-dependent simulations)
virtual const double * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
Operator * Ptr() const
Access the underlying Operator pointer.
void Start()
Clear the elapsed time and start the stopwatch.
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
A general vector function coefficient.
Wrapper for hypre's parallel vector class.
void SetAbsTol(double atol)
double p(const Vector &x, double t)
void SetRelTol(double rtol)
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
MemoryType
Memory types supported by MFEM.
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.
double ComputeGlobalLpNorm(double p, Coefficient &coeff, ParMesh &pmesh, const IntegrationRule *irs[])
Compute the global Lp norm of a function f. .
void Distribute(const Vector *tv)
The transpose of a given operator. Switches the roles of the methods Mult() and MultTranspose().
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)
virtual double ComputeL2Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL) const
HYPRE_BigInt GetGlobalNumRows() const
Return the global number of rows.
void InvScaleRows(const Vector &s)
Scale the local row i by 1./s(i)
void PrintOptions(std::ostream &out) const
Print the options.
void SetLevelsOfDetail(int levels_of_detail_)
for VectorFiniteElements (Nedelec, Raviart-Thomas)
A general function coefficient.
void SetLevelsOfDetail(const int levels_of_detail) noexcept
virtual void Save() override
double u(const Vector &xvec)
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.
A class to handle Block systems in a matrix-free implementation.
Class for parallel meshes.
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
void SetPrefixPath(const std::string &prefix)
Set the path where the DataCollection will be saved.
void Clear()
Clear the elapsed time on the stopwatch and restart it if it's running.
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)
bool Good() const
Return true if the command line options were parsed successfully.