43 #ifndef MFEM_USE_SUNDIALS 44 #error This example requires that MFEM is built with MFEM_USE_SUNDIALS=YES 66 class 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);
141 int 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);
323 #ifdef MFEM_USE_SIDRE 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";
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);
482 if (M.GetAssemblyLevel() == AssemblyLevel::LEGACY)
486 dg_solver =
new DG_Solver(M.SpMat(), K.SpMat(), *M.FESpace());
491 M_solver.SetOperator(M);
494 M_solver.SetPreconditioner(*M_prec);
495 M_solver.iterative_mode =
false;
496 M_solver.SetRelTol(1e-9);
497 M_solver.SetAbsTol(0.0);
498 M_solver.SetMaxIter(100);
499 M_solver.SetPrintLevel(0);
512 MFEM_VERIFY(dg_solver != NULL,
513 "Implicit time integration is not supported with partial assembly");
516 dg_solver->SetTimeStep(dt);
517 dg_solver->Mult(z, k);
533 for (
int i = 0; i <
dim; i++)
546 case 1: v(0) = 1.0;
break;
547 case 2: v(0) = sqrt(2./3.); v(1) = sqrt(1./3.);
break;
548 case 3: v(0) = sqrt(3./6.); v(1) = sqrt(2./6.); v(2) = sqrt(1./6.);
557 const double w = M_PI/2;
560 case 1: v(0) = 1.0;
break;
561 case 2: v(0) = w*X(1); v(1) = -w*X(0);
break;
562 case 3: v(0) = w*X(1); v(1) = -w*X(0); v(2) = 0.0;
break;
569 const double w = M_PI/2;
570 double d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
574 case 1: v(0) = 1.0;
break;
575 case 2: v(0) = d*w*X(1); v(1) = -d*w*X(0);
break;
576 case 3: v(0) = d*w*X(1); v(1) = -d*w*X(0); v(2) = 0.0;
break;
590 for (
int i = 0; i <
dim; i++)
604 return exp(-40.*pow(X(0)-0.5,2));
608 double rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
611 const double s = (1. + 0.25*cos(2*M_PI*X(2)));
615 return ( erfc(w*(X(0)-cx-rx))*erfc(-w*(X(0)-cx+rx)) *
616 erfc(w*(X(1)-cy-ry))*erfc(-w*(X(1)-cy+ry)) )/16;
622 double x_ = X(0), y_ = X(1), rho, phi;
625 return pow(sin(M_PI*rho),2)*sin(3*phi);
629 const double f = M_PI;
630 return sin(
f*X(0))*sin(
f*X(1));
void SetPrecision(int prec)
Set the precision (number of digits) used for the text output of doubles.
void Init(TimeDependentOperator &f_)
Initialize CVODE: calls CVodeCreate() to create the CVODE memory and set some defaults.
Conjugate gradient method.
Class for grid function - Vector with associated FE space.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
Data type for scaled Jacobi-type smoother of sparse matrix.
void SetSStolerances(double reltol, double abstol)
Set the scalar relative and scalar absolute tolerances.
void SetDataFormat(VTKFormat fmt)
void PrintOptions(std::ostream &out) const
Print the options.
int Dimension() const
Dimension of the reference space used within the elements.
Helper class for ParaView visualization data.
void SetERKTableNum(ARKODE_ERKTableID table_id)
Choose a specific Butcher table for an explicit RK method.
void PrintUsage(std::ostream &out) const
Print the usage message.
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)
void GetBoundingBox(Vector &min, Vector &max, int ref=2)
Returns the minimum and maximum corners of the mesh bounding box.
virtual void SetOperator(const Operator &a)
Set/update the solver for the given operator.
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]...
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
int Size() const
Returns the size of the vector.
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Abstract class for solving systems of ODEs: dx/dt = f(x,t)
void SetMaxStep(double dt_max)
Set the maximum time step.
void SetOrder(int order)
Chooses integration order for all explicit / implicit / IMEX methods.
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.
bool Good() const
Return true if the command line options were parsed successfully.
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
virtual void SetOperator(const Operator &op) override
Also calls SetOperator for the preconditioner if there is one.
Interface to ARKode's ARKStep module – additive Runge-Kutta methods.
Data collection with Sidre routines following the Conduit mesh blueprint specification.
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
virtual void Save()
Save the collection to disk.
Interface to the CVODE library – linear multi-step methods.
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)
Set the curvature of the mesh nodes using the given polynomial degree.
void SetMaxStep(double dt_max)
Set the maximum time step.
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...
void SetHighOrderOutput(bool high_order_output_)
void PrintInfo() const
Print various ARKStep statistics.
void SetTime(double t)
Set physical time (for time-dependent simulations)
A general vector function coefficient.
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)
void PrintInfo() const
Print various CVODE statistics.
void velocity_function(const Vector &x, Vector &v)
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
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.
int GetDof() const
Returns the number of degrees of freedom in the finite element.
constexpr ARKODE_ERKTableID ARKODE_FEHLBERG_13_7_8
FE_Evolution(FiniteElementSpace &vfes_, Operator &A_, SparseMatrix &Aflux_)
NURBSExtension * NURBSext
Optional NURBS mesh extension.
int main(int argc, char *argv[])
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
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_)
A general function coefficient.
virtual void Print(std::ostream &os=mfem::out) const
virtual void SetPreconditioner(Solver &pr)
This should be called before SetOperator.
virtual void Save() override
double u(const Vector &xvec)
The MFEM Device class abstracts hardware devices such as GPUs, as well as programming models such as ...
The classical forward Euler method.
void Init(TimeDependentOperator &f_)
Initialize ARKode: calls ARKStepCreate() to create the ARKStep memory and set some defaults...
void SetSStolerances(double reltol, double abstol)
Set the scalar relative and scalar absolute tolerances.
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)
void UseSundialsLinearSolver()
Attach SUNDIALS GMRES linear solver to CVODE.
Arbitrary order "L2-conforming" discontinuous finite elements.
double f(const Vector &p)