76 #if MFEM_HYPRE_VERSION >= 21800
81 class AIR_prec :
public Solver
92 AIR_prec(
int blocksize_) : AIR_solver(NULL), blocksize(blocksize_) { }
100 MFEM_VERIFY(A != NULL,
"AIR_prec requires a HypreParMatrix.")
107 AIR_solver->SetAdvectiveOptions(1, "", "FA");
108 AIR_solver->SetPrintLevel(0);
109 AIR_solver->SetMaxLevels(50);
117 BlockInverseScaleJob::RHS_ONLY);
118 AIR_solver->Mult(z_s, y);
129 class DG_Solver :
public Solver
144 linear_solver(M.GetComm()),
151 BlockILU::Reordering::MINIMUM_DISCARDED_FILL);
155 #if MFEM_HYPRE_VERSION >= 21800
156 prec =
new AIR_prec(block_size);
158 MFEM_ABORT(
"Must have MFEM_HYPRE_VERSION >= 21800 to use AIR.\n");
161 linear_solver.iterative_mode =
false;
162 linear_solver.SetRelTol(1e-9);
163 linear_solver.SetAbsTol(0.0);
164 linear_solver.SetMaxIter(100);
165 linear_solver.SetPrintLevel(0);
166 linear_solver.SetPreconditioner(*prec);
171 void SetTimeStep(
double dt_)
178 A =
Add(-dt, K, 0.0, K);
181 A_diag.
Add(1.0, M_diag);
183 linear_solver.SetOperator(*A);
187 void SetOperator(
const Operator &op)
189 linear_solver.SetOperator(op);
194 linear_solver.Mult(x, y);
217 DG_Solver *dg_solver;
226 virtual void ImplicitSolve(
const double dt,
const Vector &x,
Vector &k);
232 int main(
int argc,
char *argv[])
241 const char *mesh_file =
"../data/periodic-hexagon.mesh";
242 int ser_ref_levels = 2;
243 int par_ref_levels = 0;
248 const char *device_config =
"cpu";
249 int ode_solver_type = 4;
250 double t_final = 10.0;
252 bool visualization =
true;
254 bool paraview =
false;
258 #if MFEM_HYPRE_VERSION >= 21800
264 cout.precision(precision);
267 args.
AddOption(&mesh_file,
"-m",
"--mesh",
268 "Mesh file to use.");
270 "Problem setup to use. See options in velocity_function().");
271 args.
AddOption(&ser_ref_levels,
"-rs",
"--refine-serial",
272 "Number of times to refine the mesh uniformly in serial.");
273 args.
AddOption(&par_ref_levels,
"-rp",
"--refine-parallel",
274 "Number of times to refine the mesh uniformly in parallel.");
276 "Order (degree) of the finite elements.");
277 args.
AddOption(&pa,
"-pa",
"--partial-assembly",
"-no-pa",
278 "--no-partial-assembly",
"Enable Partial Assembly.");
279 args.
AddOption(&ea,
"-ea",
"--element-assembly",
"-no-ea",
280 "--no-element-assembly",
"Enable Element Assembly.");
281 args.
AddOption(&fa,
"-fa",
"--full-assembly",
"-no-fa",
282 "--no-full-assembly",
"Enable Full Assembly.");
283 args.
AddOption(&device_config,
"-d",
"--device",
284 "Device configuration string, see Device::Configure().");
285 args.
AddOption(&ode_solver_type,
"-s",
"--ode-solver",
286 "ODE solver: 1 - Forward Euler,\n\t"
287 " 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6,\n\t"
288 " 11 - Backward Euler,\n\t"
289 " 12 - SDIRK23 (L-stable), 13 - SDIRK33,\n\t"
290 " 22 - Implicit Midpoint Method,\n\t"
291 " 23 - SDIRK23 (A-stable), 24 - SDIRK34");
292 args.
AddOption(&t_final,
"-tf",
"--t-final",
293 "Final time; start time is 0.");
294 args.
AddOption(&dt,
"-dt",
"--time-step",
296 args.
AddOption((
int *)&prec_type,
"-pt",
"--prec-type",
"Preconditioner for "
297 "implicit solves. 0 for ILU, 1 for pAIR-AMG.");
298 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
299 "--no-visualization",
300 "Enable or disable GLVis visualization.");
301 args.
AddOption(&visit,
"-visit",
"--visit-datafiles",
"-no-visit",
302 "--no-visit-datafiles",
303 "Save data files for VisIt (visit.llnl.gov) visualization.");
304 args.
AddOption(¶view,
"-paraview",
"--paraview-datafiles",
"-no-paraview",
305 "--no-paraview-datafiles",
306 "Save data files for ParaView (paraview.org) visualization.");
307 args.
AddOption(&adios2,
"-adios2",
"--adios2-streams",
"-no-adios2",
308 "--no-adios2-streams",
309 "Save data using adios2 streams.");
310 args.
AddOption(&binary,
"-binary",
"--binary-datafiles",
"-ascii",
312 "Use binary (Sidre) or ascii format for VisIt data files.");
313 args.
AddOption(&vis_steps,
"-vs",
"--visualization-steps",
314 "Visualize every n-th timestep.");
329 Device device(device_config);
334 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
340 switch (ode_solver_type)
344 case 2: ode_solver =
new RK2Solver(1.0);
break;
346 case 4: ode_solver =
new RK4Solver;
break;
347 case 6: ode_solver =
new RK6Solver;
break;
359 cout <<
"Unknown ODE solver type: " << ode_solver_type <<
'\n';
369 for (
int lev = 0; lev < ser_ref_levels; lev++)
384 for (
int lev = 0; lev < par_ref_levels; lev++)
397 cout <<
"Number of unknowns: " << global_vSize << endl;
426 constexpr
double alpha = -1.0;
455 ostringstream mesh_name, sol_name;
456 mesh_name <<
"ex9-mesh." << setfill(
'0') << setw(6) << myid;
457 sol_name <<
"ex9-init." << setfill(
'0') << setw(6) << myid;
458 ofstream omesh(mesh_name.str().c_str());
459 omesh.precision(precision);
461 ofstream osol(sol_name.str().c_str());
462 osol.precision(precision);
473 #ifdef MFEM_USE_SIDRE
476 MFEM_ABORT(
"Must build with MFEM_USE_SIDRE=YES for binary output.");
508 #ifdef MFEM_USE_ADIOS2
512 std::string postfix(mesh_file);
513 postfix.erase(0, std::string(
"../data/").size() );
514 postfix +=
"_o" + std::to_string(order);
515 const std::string collection_name =
"ex9-p-" + postfix +
".bp";
519 adios2_dc->
SetParameter(
"SubStreams", std::to_string(num_procs/2) );
533 sout.
open(vishost, visport);
537 cout <<
"Unable to connect to GLVis server at "
538 << vishost <<
':' << visport << endl;
539 visualization =
false;
542 cout <<
"GLVis visualization disabled.\n";
547 sout <<
"parallel " << num_procs <<
" " << myid <<
"\n";
548 sout.precision(precision);
549 sout <<
"solution\n" << *pmesh << *
u;
553 cout <<
"GLVis visualization paused."
554 <<
" Press space (in the GLVis window) to resume it.\n";
565 ode_solver->
Init(adv);
568 for (
int ti = 0; !done; )
570 double dt_real = min(dt, t_final - t);
571 ode_solver->
Step(*U, t, dt_real);
574 done = (t >= t_final - 1e-8*dt);
576 if (done || ti % vis_steps == 0)
580 cout <<
"time step: " << ti <<
", time: " << t << endl;
589 sout <<
"parallel " << num_procs <<
" " << myid <<
"\n";
590 sout <<
"solution\n" << *pmesh << *u << flush;
607 #ifdef MFEM_USE_ADIOS2
623 ostringstream sol_name;
624 sol_name <<
"ex9-final." << setfill(
'0') << setw(6) << myid;
625 ofstream osol(sol_name.str().c_str());
626 osol.precision(precision);
641 #ifdef MFEM_USE_ADIOS2
657 M_solver(M_.ParFESpace()->GetComm()),
681 dg_solver =
new DG_Solver(M_mat, K_mat, *M_.
FESpace(), prec_type);
705 dg_solver->SetTimeStep(dt);
706 dg_solver->Mult(z, k);
731 for (
int i = 0; i <
dim; i++)
744 case 1: v(0) = 1.0;
break;
745 case 2: v(0) = sqrt(2./3.); v(1) = sqrt(1./3.);
break;
746 case 3: v(0) = sqrt(3./6.); v(1) = sqrt(2./6.); v(2) = sqrt(1./6.);
755 const double w = M_PI/2;
758 case 1: v(0) = 1.0;
break;
759 case 2: v(0) = w*X(1); v(1) = -w*X(0);
break;
760 case 3: v(0) = w*X(1); v(1) = -w*X(0); v(2) = 0.0;
break;
767 const double w = M_PI/2;
768 double d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
772 case 1: v(0) = 1.0;
break;
773 case 2: v(0) = d*w*X(1); v(1) = -d*w*X(0);
break;
774 case 3: v(0) = d*w*X(1); v(1) = -d*w*X(0); v(2) = 0.0;
break;
788 for (
int i = 0; i <
dim; i++)
802 return exp(-40.*pow(X(0)-0.5,2));
806 double rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
809 const double s = (1. + 0.25*cos(2*M_PI*X(2)));
813 return ( erfc(w*(X(0)-cx-rx))*erfc(-w*(X(0)-cx+rx)) *
814 erfc(w*(X(1)-cy-ry))*erfc(-w*(X(1)-cy+ry)) )/16;
820 double x_ = X(0), y_ = X(1), rho, phi;
823 return pow(sin(M_PI*rho),2)*sin(3*phi);
827 const double f = M_PI;
828 return sin(f*X(0))*sin(f*X(1));
int WorldSize() const
Return MPI_COMM_WORLD's size.
void SetPrecision(int prec)
Set the precision (number of digits) used for the text output of doubles.
void Add(const int i, const int j, const double a)
Conjugate gradient method.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
void SetDataFormat(VTKFormat fmt)
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Helper class for ParaView visualization data.
Base abstract class for first order time dependent operators.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void GetBoundingBox(Vector &min, Vector &max, int ref=2)
Returns the minimum and maximum corners of the mesh bounding box.
Pointer to an Operator of a specified type.
virtual void Step(Vector &x, double &t, double &dt)=0
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in]...
HYPRE_BigInt GlobalTrueVSize() const
int Size() const
Returns the size of the vector.
Abstract class for solving systems of ODEs: dx/dt = f(x,t)
virtual void Save(std::ostream &out) const
void Print(std::ostream &out=mfem::out)
Print the configuration of the MFEM virtual device object.
virtual void SetTime(const double t_)
Set the current time.
Abstract parallel finite element space.
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
void BlockInverseScale(const HypreParMatrix *A, HypreParMatrix *C, const Vector *b, HypreParVector *d, int blocksize, BlockInverseScaleJob job)
Backward Euler ODE solver. L-stable.
Data collection with Sidre routines following the Conduit mesh blueprint specification.
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
The BoomerAMG solver in hypre.
A simple convenience class that calls MPI_Init() at construction and MPI_Finalize() at destruction...
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void SetPrintLevel(int print_lvl)
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
virtual void Save()
Save the collection to disk.
Jacobi smoothing for a given bilinear form (no matrix necessary).
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Data collection with VisIt I/O routines.
void SetMaxIter(int max_it)
virtual void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1)
bool Root() const
Return true if WorldRank() == 0.
virtual void Print(std::ostream &out=mfem::out) const
void SetParameter(const std::string key, const std::string value) noexcept
Parallel smoothers in hypre.
void SetHighOrderOutput(bool high_order_output_)
void PrintUsage(std::ostream &out) const
Print the usage message.
void SetTime(double t)
Set physical time (for time-dependent simulations)
A general vector function coefficient.
Wrapper for hypre's parallel vector class.
The classical explicit forth-order Runge-Kutta method, RK4.
void SetAbsTol(double atol)
virtual void ImplicitSolve(const double dt, const Vector &x, Vector &k)
Solve the equation: k = f(x + dt k, t), for the unknown k at the current time t.
void SetRelTol(double rtol)
int WorldRank() const
Return MPI_COMM_WORLD's rank.
void velocity_function(const Vector &x, Vector &v)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
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...
Third-order, strong stability preserving (SSP) Runge-Kutta method.
virtual void Mult(const Vector &x, Vector &y) const
Perform the action of the operator: y = k = f(x, t), where k solves the algebraic equation F(x...
Implicit midpoint method. A-stable, not L-stable.
FE_Evolution(FiniteElementSpace &vfes_, Operator &A_, SparseMatrix &Aflux_)
NURBSExtension * NURBSext
Optional NURBS mesh extension.
void GetDiag(Vector &d) const
Returns the Diagonal of A.
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
void PrintOptions(std::ostream &out) const
Print the options.
HypreParVector * GetTrueDofs() const
Returns the true dofs in a new HypreParVector.
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
double u0_function(const Vector &x)
void SetLevelsOfDetail(int levels_of_detail_)
virtual void SetOperator(const Operator &op)
Also calls SetOperator for the preconditioner if there is one.
A general function coefficient.
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
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 ...
The classical forward Euler method.
Wrapper for hypre's ParCSR matrix class.
Class for parallel meshes.
virtual void Init(TimeDependentOperator &f_)
Associate a TimeDependentOperator with the ODE solver.
void SetPrefixPath(const std::string &prefix)
Set the path where the DataCollection will be saved.
double inflow_function(const Vector &x)
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.