43#ifndef MFEM_USE_SUNDIALS
44#error This example requires that MFEM is built with MFEM_USE_SUNDIALS=YES
66class DG_Solver :
public Solver
78 BlockILU::Reordering::MINIMUM_DISCARDED_FILL),
89 void SetTimeStep(
double dt_)
104 void SetOperator(
const Operator &op)
111 linear_solver.
Mult(x, y);
127 DG_Solver *dg_solver;
135 virtual void ImplicitSolve(
const double dt,
const Vector &x,
Vector &k);
137 virtual ~FE_Evolution();
141int main(
int argc,
char *argv[])
148 const char *mesh_file =
"../../data/periodic-hexagon.mesh";
154 const char *device_config =
"cpu";
155 int ode_solver_type = 7;
156 double t_final = 10.0;
158 bool visualization =
false;
160 bool paraview =
false;
165 const double reltol = 1e-2, abstol = 1e-2;
168 cout.precision(precision);
171 args.
AddOption(&mesh_file,
"-m",
"--mesh",
172 "Mesh file to use.");
174 "Problem setup to use. See options in velocity_function().");
175 args.
AddOption(&ref_levels,
"-r",
"--refine",
176 "Number of times to refine the mesh uniformly.");
178 "Order (degree) of the finite elements.");
179 args.
AddOption(&pa,
"-pa",
"--partial-assembly",
"-no-pa",
180 "--no-partial-assembly",
"Enable Partial Assembly.");
181 args.
AddOption(&ea,
"-ea",
"--element-assembly",
"-no-ea",
182 "--no-element-assembly",
"Enable Element Assembly.");
183 args.
AddOption(&fa,
"-fa",
"--full-assembly",
"-no-fa",
184 "--no-full-assembly",
"Enable Full Assembly.");
185 args.
AddOption(&device_config,
"-d",
"--device",
186 "Device configuration string, see Device::Configure().");
187 args.
AddOption(&ode_solver_type,
"-s",
"--ode-solver",
189 "1 - Forward Euler,\n\t"
194 "7 - CVODE (adaptive order implicit Adams),\n\t"
195 "8 - ARKODE default (4th order) explicit,\n\t"
197 args.
AddOption(&t_final,
"-tf",
"--t-final",
198 "Final time; start time is 0.");
199 args.
AddOption(&dt,
"-dt",
"--time-step",
201 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
202 "--no-visualization",
203 "Enable or disable GLVis visualization.");
204 args.
AddOption(&visit,
"-visit",
"--visit-datafiles",
"-no-visit",
205 "--no-visit-datafiles",
206 "Save data files for VisIt (visit.llnl.gov) visualization.");
207 args.
AddOption(¶view,
"-paraview",
"--paraview-datafiles",
"-no-paraview",
208 "--no-paraview-datafiles",
209 "Save data files for ParaView (paraview.org) visualization.");
210 args.
AddOption(&binary,
"-binary",
"--binary-datafiles",
"-ascii",
212 "Use binary (Sidre) or ascii format for VisIt data files.");
213 args.
AddOption(&vis_steps,
"-vs",
"--visualization-steps",
214 "Visualize every n-th timestep.");
222 if (ode_solver_type < 1 || ode_solver_type > 9)
224 cout <<
"Unknown ODE solver type: " << ode_solver_type <<
'\n';
229 Device device(device_config);
234 Mesh mesh(mesh_file, 1, 1);
241 for (
int lev = 0; lev < ref_levels; lev++)
256 cout <<
"Number of unknowns: " << fes.
GetVSize() << endl;
283 constexpr double alpha = -1.0;
291 b.AddBdrFaceIntegrator(
305 u.ProjectCoefficient(u0);
308 ofstream omesh(
"ex9.mesh");
309 omesh.precision(precision);
311 ofstream osol(
"ex9-init.gf");
312 osol.precision(precision);
326 MFEM_ABORT(
"Must build with MFEM_USE_SIDRE=YES for binary output.");
362 cout <<
"Unable to connect to GLVis server at "
364 visualization =
false;
365 cout <<
"GLVis visualization disabled.\n";
369 sout.precision(precision);
370 sout <<
"solution\n" << mesh <<
u;
373 cout <<
"GLVis visualization paused."
374 <<
" Press space (in the GLVis window) to resume it.\n";
380 FE_Evolution adv(m, k,
b);
389 switch (ode_solver_type)
392 case 2: ode_solver =
new RK2Solver(1.0);
break;
394 case 4: ode_solver =
new RK4Solver;
break;
395 case 6: ode_solver =
new RK6Solver;
break;
402 ode_solver = cvode;
break;
409 ode_solver = arkode;
break;
416 ode_solver = arkode;
break;
420 if (ode_solver_type < 7) { ode_solver->
Init(adv); }
425 for (
int ti = 0; !done; )
427 double dt_real = min(dt, t_final -
t);
428 ode_solver->
Step(
u,
t, dt_real);
431 done = (
t >= t_final - 1e-8*dt);
433 if (done || ti % vis_steps == 0)
435 cout <<
"time step: " << ti <<
", time: " <<
t << endl;
441 sout <<
"solution\n" << mesh <<
u << flush;
463 ofstream osol(
"ex9-final.gf");
464 osol.precision(precision);
480 M(M_), K(K_),
b(b_), z(height)
483 if (M.GetAssemblyLevel() == AssemblyLevel::LEGACY)
486 M_solver.SetOperator(M.SpMat());
487 dg_solver =
new DG_Solver(M.SpMat(), K.SpMat(), *M.FESpace());
492 M_solver.SetOperator(M);
495 M_solver.SetPreconditioner(*M_prec);
496 M_solver.iterative_mode =
false;
497 M_solver.SetRelTol(1e-9);
498 M_solver.SetAbsTol(0.0);
499 M_solver.SetMaxIter(100);
500 M_solver.SetPrintLevel(0);
503void FE_Evolution::Mult(
const Vector &x,
Vector &y)
const
511void FE_Evolution::ImplicitSolve(
const double dt,
const Vector &x,
Vector &k)
513 MFEM_VERIFY(dg_solver != NULL,
514 "Implicit time integration is not supported with partial assembly");
517 dg_solver->SetTimeStep(dt);
518 dg_solver->Mult(z, k);
521FE_Evolution::~FE_Evolution()
534 for (
int i = 0; i <
dim; i++)
547 case 1: v(0) = 1.0;
break;
548 case 2: v(0) = sqrt(2./3.); v(1) = sqrt(1./3.);
break;
549 case 3: v(0) = sqrt(3./6.); v(1) = sqrt(2./6.); v(2) = sqrt(1./6.);
558 const double w = M_PI/2;
561 case 1: v(0) = 1.0;
break;
562 case 2: v(0) = w*X(1); v(1) = -w*X(0);
break;
563 case 3: v(0) = w*X(1); v(1) = -w*X(0); v(2) = 0.0;
break;
570 const double w = M_PI/2;
571 double d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
575 case 1: v(0) = 1.0;
break;
576 case 2: v(0) = d*w*X(1); v(1) = -d*w*X(0);
break;
577 case 3: v(0) = d*w*X(1); v(1) = -d*w*X(0); v(2) = 0.0;
break;
591 for (
int i = 0; i <
dim; i++)
605 return exp(-40.*pow(X(0)-0.5,2));
609 double rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
612 const double s = (1. + 0.25*cos(2*M_PI*X(2)));
616 return ( erfc(w*(X(0)-cx-rx))*erfc(-w*(X(0)-cx+rx)) *
617 erfc(w*(X(1)-cy-ry))*erfc(-w*(X(1)-cy+ry)) )/16;
623 double x_ = X(0), y_ = X(1), rho, phi;
626 return pow(sin(M_PI*rho),2)*sin(3*phi);
630 const double f = M_PI;
631 return sin(
f*X(0))*sin(
f*X(1));
Interface to ARKode's ARKStep module – additive Runge-Kutta methods.
void SetMaxStep(double dt_max)
Set the maximum time step.
void PrintInfo() const
Print various ARKStep statistics.
void Init(TimeDependentOperator &f_)
Initialize ARKode: calls ARKStepCreate() to create the ARKStep memory and set some defaults.
void SetOrder(int order)
Chooses integration order for all explicit / implicit / IMEX methods.
@ EXPLICIT
Explicit RK method.
void SetERKTableNum(ARKODE_ERKTableID table_id)
Choose a specific Butcher table for an explicit RK method.
void SetSStolerances(double reltol, double abstol)
Set the scalar relative and scalar absolute tolerances.
@ GaussLobatto
Closed type.
Conjugate gradient method.
virtual void Mult(const Vector &b, Vector &x) const
Iterative solution of the linear system using the Conjugate Gradient method.
Interface to the CVODE library – linear multi-step methods.
void SetSStolerances(double reltol, double abstol)
Set the scalar relative and scalar absolute tolerances.
void SetMaxStep(double dt_max)
Set the maximum time step.
void Init(TimeDependentOperator &f_)
Initialize CVODE: calls CVodeCreate() to create the CVODE memory and set some defaults.
void PrintInfo() const
Print various CVODE statistics.
void UseSundialsLinearSolver()
Attach SUNDIALS GMRES linear solver to CVODE.
Data type for scaled Jacobi-type smoother of sparse matrix.
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 &out=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...
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
int GetDof() const
Returns the number of degrees of freedom in the finite element.
The classical forward Euler method.
A general function coefficient.
virtual void Mult(const Vector &b, Vector &x) const
Iterative solution of the linear system using the GMRES method.
Class for grid function - Vector with associated FE space.
virtual 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.
virtual void Print(std::ostream &os=mfem::out, const std::string &comments="") const
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)
Set the curvature of the mesh nodes using the given polynomial degree.
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Abstract class for solving systems of ODEs: dx/dt = f(x,t)
virtual void Init(TimeDependentOperator &f_)
Associate a TimeDependentOperator with the ODE solver.
virtual void Step(Vector &x, real_t &t, real_t &dt)=0
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Jacobi smoothing for a given bilinear form (no matrix necessary).
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.
Helper class for ParaView visualization data.
void SetHighOrderOutput(bool high_order_output_)
void SetLevelsOfDetail(int levels_of_detail_)
virtual void Save() override
void SetDataFormat(VTKFormat fmt)
Third-order, strong stability preserving (SSP) Runge-Kutta method.
The classical explicit forth-order Runge-Kutta method, RK4.
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.
Base abstract class for first order time dependent operators.
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.
Data collection with VisIt I/O routines.
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
real_t u(const Vector &xvec)
std::function< real_t(const Vector &)> f(real_t mass_coeff)
void velocity_function(const Vector &x, Vector &v)
double u0_function(const Vector &x)
double inflow_function(const Vector &x)
constexpr ARKODE_ERKTableID ARKODE_FEHLBERG_13_7_8