78#if MFEM_HYPRE_VERSION >= 21800
83class AIR_prec :
public Solver
94 AIR_prec(
int blocksize_) : AIR_solver(NULL), blocksize(blocksize_) { }
96 void SetOperator(
const Operator &op)
override
102 MFEM_VERIFY(A != NULL,
"AIR_prec requires a HypreParMatrix.")
109 AIR_solver->SetAdvectiveOptions(1, "", "FA");
110 AIR_solver->SetPrintLevel(0);
111 AIR_solver->SetMaxLevels(50);
119 BlockInverseScaleJob::RHS_ONLY);
120 AIR_solver->Mult(z_s, y);
131class DG_Solver :
public Solver
146 linear_solver(M.GetComm()),
153 BlockILU::Reordering::MINIMUM_DISCARDED_FILL);
157#if MFEM_HYPRE_VERSION >= 21800
158 prec =
new AIR_prec(block_size);
160 MFEM_ABORT(
"Must have MFEM_HYPRE_VERSION >= 21800 to use AIR.\n");
173 void SetTimeStep(
real_t dt_)
180 A =
Add(-dt, K, 0.0, K);
183 A_diag.
Add(1.0, M_diag);
189 void SetOperator(
const Operator &op)
override
196 linear_solver.
Mult(x, y);
199 ~DG_Solver()
override
219 DG_Solver *dg_solver;
230 ~FE_Evolution()
override;
234int main(
int argc,
char *argv[])
244 const char *mesh_file =
"../data/periodic-hexagon.mesh";
245 int ser_ref_levels = 2;
246 int par_ref_levels = 0;
251 const char *device_config =
"cpu";
252 int ode_solver_type = 4;
255 bool visualization =
true;
257 bool paraview =
false;
261 bool solve_implicit_state =
false;
262#if MFEM_HYPRE_VERSION >= 21800
268 cout.precision(precision);
271 args.
AddOption(&mesh_file,
"-m",
"--mesh",
272 "Mesh file to use.");
274 "Problem setup to use. See options in velocity_function().");
275 args.
AddOption(&ser_ref_levels,
"-rs",
"--refine-serial",
276 "Number of times to refine the mesh uniformly in serial.");
277 args.
AddOption(&par_ref_levels,
"-rp",
"--refine-parallel",
278 "Number of times to refine the mesh uniformly in parallel.");
280 "Order (degree) of the finite elements.");
281 args.
AddOption(&pa,
"-pa",
"--partial-assembly",
"-no-pa",
282 "--no-partial-assembly",
"Enable Partial Assembly.");
283 args.
AddOption(&ea,
"-ea",
"--element-assembly",
"-no-ea",
284 "--no-element-assembly",
"Enable Element Assembly.");
285 args.
AddOption(&fa,
"-fa",
"--full-assembly",
"-no-fa",
286 "--no-full-assembly",
"Enable Full Assembly.");
287 args.
AddOption(&device_config,
"-d",
"--device",
288 "Device configuration string, see Device::Configure().");
289 args.
AddOption(&ode_solver_type,
"-s",
"--ode-solver",
291 args.
AddOption(&t_final,
"-tf",
"--t-final",
292 "Final time; start time is 0.");
293 args.
AddOption(&dt,
"-dt",
"--time-step",
295 args.
AddOption(&solve_implicit_state,
"-imp-state",
"--implicit-state",
296 "-imp-slope",
"--implicit-slope",
297 "Implicitly solve for stage state or slope.");
298 args.
AddOption((
int *)&prec_type,
"-pt",
"--prec-type",
"Preconditioner for "
299 "implicit solves. 0 for ILU, 1 for pAIR-AMG.");
300 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
301 "--no-visualization",
302 "Enable or disable GLVis visualization.");
303 args.
AddOption(&visit,
"-visit",
"--visit-datafiles",
"-no-visit",
304 "--no-visit-datafiles",
305 "Save data files for VisIt (visit.llnl.gov) visualization.");
306 args.
AddOption(¶view,
"-paraview",
"--paraview-datafiles",
"-no-paraview",
307 "--no-paraview-datafiles",
308 "Save data files for ParaView (paraview.org) visualization.");
309 args.
AddOption(&adios2,
"-adios2",
"--adios2-streams",
"-no-adios2",
310 "--no-adios2-streams",
311 "Save data using adios2 streams.");
312 args.
AddOption(&binary,
"-binary",
"--binary-datafiles",
"-ascii",
314 "Use binary (Sidre) or ascii format for VisIt data files.");
315 args.
AddOption(&vis_steps,
"-vs",
"--visualization-steps",
316 "Visualize every n-th timestep.");
331 Device device(device_config);
336 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
347 for (
int lev = 0; lev < ser_ref_levels; lev++)
362 for (
int lev = 0; lev < par_ref_levels; lev++)
375 cout <<
"Number of unknowns: " << global_vSize << endl;
412 b->AddBdrFaceIntegrator(
429 u->ProjectCoefficient(u0);
433 ostringstream mesh_name, sol_name;
434 mesh_name <<
"ex9-mesh." << setfill(
'0') << setw(6) << myid;
435 sol_name <<
"ex9-init." << setfill(
'0') << setw(6) << myid;
436 ofstream omesh(mesh_name.str().c_str());
437 omesh.precision(precision);
439 ofstream osol(sol_name.str().c_str());
440 osol.precision(precision);
454 MFEM_ABORT(
"Must build with MFEM_USE_SIDRE=YES for binary output.");
486#ifdef MFEM_USE_ADIOS2
490 std::string postfix(mesh_file);
491 postfix.erase(0, std::string(
"../data/").size() );
492 postfix +=
"_o" + std::to_string(order);
493 const std::string collection_name =
"ex9-p-" + postfix +
".bp";
497 adios2_dc->
SetParameter(
"SubStreams", std::to_string(num_procs/2) );
516 cout <<
"Unable to connect to GLVis server at "
517 <<
vishost <<
':' << visport << endl;
519 visualization =
false;
522 cout <<
"GLVis visualization disabled.\n";
527 sout <<
"parallel " << num_procs <<
" " << myid <<
"\n";
528 sout.precision(precision);
529 sout <<
"solution\n" << *pmesh << *
u;
534 cout <<
"GLVis visualization paused."
535 <<
" Press space (in the GLVis window) to resume it.\n";
543 FE_Evolution adv(*m, *k, *B, prec_type);
545 ImplicitVariableType imp_var = solve_implicit_state ?
546 ImplicitVariableType::STATE
547 : ImplicitVariableType::SLOPE;
551 ode_solver->Init(adv);
552 ode_solver->SetImplicitVariableType(imp_var);
555 for (
int ti = 0; !done; )
557 real_t dt_real = min(dt, t_final - t);
558 ode_solver->Step(*U, t, dt_real);
561 done = (t >= t_final - 1e-8*dt);
563 if (done || ti % vis_steps == 0)
567 cout <<
"time step: " << ti <<
", time: " << t << endl;
576 sout <<
"parallel " << num_procs <<
" " << myid <<
"\n";
577 sout <<
"solution\n" << *pmesh << *
u << flush;
594#ifdef MFEM_USE_ADIOS2
610 ostringstream sol_name;
611 sol_name <<
"ex9-final." << setfill(
'0') << setw(6) << myid;
612 ofstream osol(sol_name.str().c_str());
613 osol.precision(precision);
627#ifdef MFEM_USE_ADIOS2
643 M_solver(M_.ParFESpace()->GetComm()),
657 M_solver.SetOperator(*M);
667 dg_solver =
new DG_Solver(M_mat, K_mat, *M_.
FESpace(), prec_type);
675 M_solver.SetPreconditioner(*M_prec);
676 M_solver.iterative_mode =
false;
677 M_solver.SetRelTol(1e-9);
678 M_solver.SetAbsTol(0.0);
679 M_solver.SetMaxIter(100);
680 M_solver.SetPrintLevel(0);
703 dg_solver->SetTimeStep(dt);
704 dg_solver->Mult(z, k);
707void FE_Evolution::Mult(
const Vector &x,
Vector &y)
const
715FE_Evolution::~FE_Evolution()
729 for (
int i = 0; i <
dim; i++)
742 case 1: v(0) = 1.0;
break;
743 case 2: v(0) = sqrt(2./3.); v(1) = sqrt(1./3.);
break;
744 case 3: v(0) = sqrt(3./6.); v(1) = sqrt(2./6.); v(2) = sqrt(1./6.);
756 case 1: v(0) = 1.0;
break;
757 case 2: v(0) = w*X(1); v(1) = -w*X(0);
break;
758 case 3: v(0) = w*X(1); v(1) = -w*X(0); v(2) = 0.0;
break;
766 real_t d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
770 case 1: v(0) = 1.0;
break;
771 case 2: v(0) = d*w*X(1); v(1) = -d*w*X(0);
break;
772 case 3: v(0) = d*w*X(1); v(1) = -d*w*X(0); v(2) = 0.0;
break;
786 for (
int i = 0; i <
dim; i++)
800 return exp(-40.*pow(X(0)-0.5,2));
804 real_t rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
807 const real_t s = (1. + 0.25*cos(2*M_PI*X(2)));
811 return ( std::erfc(w*(X(0)-cx-rx))*std::erfc(-w*(X(0)-cx+rx)) *
812 std::erfc(w*(X(1)-cy-ry))*std::erfc(-w*(X(1)-cy+ry)) )/16;
818 real_t x_ = X(0), y_ = X(1), rho, phi;
819 rho = std::hypot(x_, y_);
821 return pow(sin(M_PI*rho),2)*sin(3*phi);
826 return sin(
f*X(0))*sin(
f*X(1));
void SetParameter(const std::string key, const std::string value) noexcept
@ GaussLobatto
Closed type.
Conjugate gradient method.
void Mult(const Vector &b, Vector &x) const override
Iterative solution of the linear system using the Conjugate Gradient method.
void SetPrecision(int prec)
Set the precision (number of digits) used for the text output of doubles.
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
void SetTime(real_t t)
Set physical time (for time-dependent simulations)
void SetPrefixPath(const std::string &prefix)
Set the path where the DataCollection will be saved.
virtual void Save()
Save the collection to disk.
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 FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
const FiniteElement * GetTypicalFE() const
Return GetFE(0) if the local mesh is not empty; otherwise return a typical FE based on the Geometry t...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
A general function coefficient.
void Mult(const Vector &b, Vector &x) const override
Iterative solution of the linear system using the GMRES method.
The BoomerAMG solver in hypre.
Wrapper for hypre's ParCSR matrix class.
void GetDiag(Vector &diag) const
Get the local diagonal of the matrix.
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, real_t alpha=1.0, real_t beta=0.0) const
Computes y = alpha * A * x + beta * y.
Wrapper for hypre's parallel vector class.
Parallel smoothers in hypre.
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
void SetOperator(const Operator &op) override
Also calls SetOperator for the preconditioner if there is one.
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 SetAbsTol(real_t atol)
Arbitrary order "L2-conforming" discontinuous finite elements.
NURBSExtension * NURBSext
Optional NURBS mesh extension.
void GetBoundingBox(Vector &min, Vector &max, int ref=2)
Returns the minimum and maximum corners of the mesh bounding box.
int Dimension() const
Dimension of the reference space used within the elements.
virtual void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1, int pyr_type=1)
Set the curvature of the mesh nodes using the given polynomial degree.
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).
static MFEM_EXPORT std::string Types
static MFEM_EXPORT std::unique_ptr< ODESolver > Select(const int ode_solver_type)
Pointer to an Operator of a specified type.
Jacobi smoothing for a given bilinear form (no matrix necessary).
int width
Dimension of the input / number of columns in the matrix.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int height
Dimension of the output / number of rows in the matrix.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
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...
bool Good() const
Return true if the command line options were parsed successfully.
Abstract parallel finite element space.
HYPRE_BigInt GlobalTrueVSize() const
Class for parallel grid function.
Class for parallel meshes.
void Print(std::ostream &out=mfem::out, const std::string &comments="") const override
void SetLevelsOfDetail(int levels_of_detail_)
Set the refinement level.
void SetHighOrderOutput(bool high_order_output_)
Sets whether or not to output the data as high-order elements (false by default).
void SetDataFormat(VTKFormat fmt)
Set the data format for the ParaView output files.
Writer for ParaView visualization (PVD and VTU format)
Data collection with Sidre routines following the Conduit mesh blueprint specification.
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
void Add(const int i, const int j, const real_t val)
Base abstract class for first order time dependent operators.
virtual bool ImplicitVarTypeIsState() const
Returns true if implicit variable is STATE and false otherwise. Used by ODESolver to identify the sta...
virtual void SetTime(const real_t t_)
Set the current time.
A general vector function coefficient.
int Size() const
Returns the size of the vector.
Vector & Add(const real_t a, const Vector &Va)
(*this) += a * Va
Data collection with VisIt I/O routines.
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
const int * ess_tdof_list
void velocity_function(const Vector &x, Vector &v)
real_t inflow_function(const Vector &x)
real_t u0_function(const Vector &x)
int GetTrueVSize(const FieldDescriptor &f)
Get the true dof size of a field descriptor.
real_t u(const Vector &xvec)
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
void BlockInverseScale(const HypreParMatrix *A, HypreParMatrix *C, const Vector *b, HypreParVector *d, int blocksize, BlockInverseScaleJob job)
std::function< real_t(const Vector &)> f(real_t mass_coeff)
void Add(const DenseMatrix &A, const DenseMatrix &B, real_t alpha, DenseMatrix &C)
C = A + alpha*B.
MFEM_HOST_DEVICE Complex exp(const Complex &q)
void velocity_function(const Vector &x, Vector &v)
double u0_function(const Vector &x)
double inflow_function(const Vector &x)