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
80 linear_solver(M.GetComm()),
82 BlockILU::Reordering::MINIMUM_DISCARDED_FILL),
85 linear_solver.iterative_mode =
false;
86 linear_solver.SetRelTol(1e-9);
87 linear_solver.SetAbsTol(0.0);
88 linear_solver.SetMaxIter(100);
89 linear_solver.SetPrintLevel(0);
90 linear_solver.SetPreconditioner(prec);
95 void SetTimeStep(
double dt_)
102 A =
Add(-dt, K, 0.0, K);
105 A_diag.
Add(1.0, M_diag);
107 linear_solver.SetOperator(*A);
111 void SetOperator(
const Operator &op)
113 linear_solver.SetOperator(op);
118 linear_solver.Mult(x, y);
139 DG_Solver *dg_solver;
147 virtual void ImplicitSolve(
const double dt,
const Vector &x,
Vector &k);
153 int main(
int argc,
char *argv[])
156 Mpi::Init(argc, argv);
157 int num_procs = Mpi::WorldSize();
158 int myid = Mpi::WorldRank();
163 const char *mesh_file =
"../../data/periodic-hexagon.mesh";
164 int ser_ref_levels = 2;
165 int par_ref_levels = 0;
170 const char *device_config =
"cpu";
171 int ode_solver_type = 7;
172 double t_final = 10.0;
174 bool visualization =
false;
176 bool paraview =
false;
182 const double reltol = 1e-2, abstol = 1e-2;
185 cout.precision(precision);
188 args.
AddOption(&mesh_file,
"-m",
"--mesh",
189 "Mesh file to use.");
191 "Problem setup to use. See options in velocity_function().");
192 args.
AddOption(&ser_ref_levels,
"-rs",
"--refine-serial",
193 "Number of times to refine the mesh uniformly in serial.");
194 args.
AddOption(&par_ref_levels,
"-rp",
"--refine-parallel",
195 "Number of times to refine the mesh uniformly in parallel.");
197 "Order (degree) of the finite elements.");
198 args.
AddOption(&pa,
"-pa",
"--partial-assembly",
"-no-pa",
199 "--no-partial-assembly",
"Enable Partial Assembly.");
200 args.
AddOption(&ea,
"-ea",
"--element-assembly",
"-no-ea",
201 "--no-element-assembly",
"Enable Element Assembly.");
202 args.
AddOption(&fa,
"-fa",
"--full-assembly",
"-no-fa",
203 "--no-full-assembly",
"Enable Full Assembly.");
204 args.
AddOption(&device_config,
"-d",
"--device",
205 "Device configuration string, see Device::Configure().");
206 args.
AddOption(&ode_solver_type,
"-s",
"--ode-solver",
208 "1 - Forward Euler,\n\t"
213 "7 - CVODE (adaptive order implicit Adams),\n\t"
214 "8 - ARKODE default (4th order) explicit,\n\t"
216 args.
AddOption(&t_final,
"-tf",
"--t-final",
217 "Final time; start time is 0.");
218 args.
AddOption(&dt,
"-dt",
"--time-step",
220 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
221 "--no-visualization",
222 "Enable or disable GLVis visualization.");
223 args.
AddOption(&visit,
"-visit",
"--visit-datafiles",
"-no-visit",
224 "--no-visit-datafiles",
225 "Save data files for VisIt (visit.llnl.gov) visualization.");
226 args.
AddOption(¶view,
"-paraview",
"--paraview-datafiles",
"-no-paraview",
227 "--no-paraview-datafiles",
228 "Save data files for ParaView (paraview.org) visualization.");
229 args.
AddOption(&adios2,
"-adios2",
"--adios2-streams",
"-no-adios2",
230 "--no-adios2-streams",
231 "Save data using adios2 streams.");
232 args.
AddOption(&binary,
"-binary",
"--binary-datafiles",
"-ascii",
234 "Use binary (Sidre) or ascii format for VisIt data files.");
235 args.
AddOption(&vis_steps,
"-vs",
"--visualization-steps",
236 "Visualize every n-th timestep.");
252 if (ode_solver_type < 1 || ode_solver_type > 9)
256 cout <<
"Unknown ODE solver type: " << ode_solver_type <<
'\n';
261 Device device(device_config);
262 if (myid == 0) { device.
Print(); }
266 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
273 for (
int lev = 0; lev < ser_ref_levels; lev++)
288 for (
int lev = 0; lev < par_ref_levels; lev++)
301 cout <<
"Number of unknowns: " << global_vSize << endl;
357 ostringstream mesh_name, sol_name;
358 mesh_name <<
"ex9-mesh." << setfill(
'0') << setw(6) << myid;
359 sol_name <<
"ex9-init." << setfill(
'0') << setw(6) << myid;
360 ofstream omesh(mesh_name.str().c_str());
361 omesh.precision(precision);
363 ofstream osol(sol_name.str().c_str());
364 osol.precision(precision);
375 #ifdef MFEM_USE_SIDRE
378 MFEM_ABORT(
"Must build with MFEM_USE_SIDRE=YES for binary output.");
410 #ifdef MFEM_USE_ADIOS2
414 std::string postfix(mesh_file);
415 postfix.erase(0, std::string(
"../data/").size() );
416 postfix +=
"_o" + std::to_string(order);
417 const std::string collection_name =
"ex9-p-" + postfix +
".bp";
421 adios2_dc->
SetParameter(
"SubStreams", std::to_string(num_procs/2) );
434 sout.
open(vishost, visport);
438 cout <<
"Unable to connect to GLVis server at "
439 << vishost <<
':' << visport << endl;
440 visualization =
false;
443 cout <<
"GLVis visualization disabled.\n";
448 sout <<
"parallel " << num_procs <<
" " << myid <<
"\n";
449 sout.precision(precision);
450 sout <<
"solution\n" << *pmesh << *
u;
454 cout <<
"GLVis visualization paused."
455 <<
" Press space (in the GLVis window) to resume it.\n";
470 switch (ode_solver_type)
473 case 2: ode_solver =
new RK2Solver(1.0);
break;
475 case 4: ode_solver =
new RK4Solver;
break;
476 case 6: ode_solver =
new RK6Solver;
break;
483 ode_solver = cvode;
break;
486 arkode =
new ARKStepSolver(MPI_COMM_WORLD, ARKStepSolver::EXPLICIT);
490 if (ode_solver_type == 9) { arkode->
SetERKTableNum(FEHLBERG_13_7_8); }
491 ode_solver = arkode;
break;
495 if (ode_solver_type < 7) { ode_solver->
Init(adv); }
500 for (
int ti = 0; !done; )
502 double dt_real = min(dt, t_final - t);
503 ode_solver->
Step(*U, t, dt_real);
506 done = (t >= t_final - 1e-8*dt);
508 if (done || ti % vis_steps == 0)
512 cout <<
"time step: " << ti <<
", time: " << t << endl;
523 sout <<
"parallel " << num_procs <<
" " << myid <<
"\n";
524 sout <<
"solution\n" << *pmesh << *u << flush;
541 #ifdef MFEM_USE_ADIOS2
557 ostringstream sol_name;
558 sol_name <<
"ex9-final." << setfill(
'0') << setw(6) << myid;
559 ofstream osol(sol_name.str().c_str());
560 osol.precision(precision);
575 #ifdef MFEM_USE_ADIOS2
592 M_solver(M_.ParFESpace()->GetComm()),
616 dg_solver =
new DG_Solver(M_mat, K_mat, *M_.
FESpace());
636 dg_solver->SetTimeStep(dt);
637 dg_solver->Mult(z, k);
662 for (
int i = 0; i <
dim; i++)
675 case 1: v(0) = 1.0;
break;
676 case 2: v(0) =
sqrt(2./3.); v(1) =
sqrt(1./3.);
break;
677 case 3: v(0) =
sqrt(3./6.); v(1) =
sqrt(2./6.); v(2) =
sqrt(1./6.);
686 const double w = M_PI/2;
689 case 1: v(0) = 1.0;
break;
690 case 2: v(0) = w*X(1); v(1) = -w*X(0);
break;
691 case 3: v(0) = w*X(1); v(1) = -w*X(0); v(2) = 0.0;
break;
698 const double w = M_PI/2;
699 double d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
703 case 1: v(0) = 1.0;
break;
704 case 2: v(0) = d*w*X(1); v(1) = -d*w*X(0);
break;
705 case 3: v(0) = d*w*X(1); v(1) = -d*w*X(0); v(2) = 0.0;
break;
719 for (
int i = 0; i <
dim; i++)
733 return exp(-40.*
pow(X(0)-0.5,2));
737 double rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
740 const double s = (1. + 0.25*
cos(2*M_PI*X(2)));
744 return ( erfc(w*(X(0)-cx-rx))*erfc(-w*(X(0)-cx+rx)) *
745 erfc(w*(X(1)-cy-ry))*erfc(-w*(X(1)-cy+ry)) )/16;
751 double x_ = X(0), y_ = X(1), rho, phi;
758 const double f = M_PI;
759 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.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
void SetSStolerances(double reltol, double abstol)
Set the scalar relative and scalar absolute tolerances.
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)
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 SetMaxStep(double dt_max)
Set the maximum time step.
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.
FDualNumber< tbase > exp(const FDualNumber< tbase > &f)
exp([dual number])
Interface to ARKode's ARKStep module – additive Runge-Kutta methods.
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.
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)
void SetMaxStep(double dt_max)
Set the maximum time step.
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)
void Add(const int i, const int j, const double val)
FDualNumber< tbase > cos(const FDualNumber< tbase > &f)
cos([dual number])
FDualNumber< tbase > pow(const FDualNumber< tbase > &a, const FDualNumber< tbase > &b)
pow([dual number],[dual number])
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)
FDualNumber< tbase > sin(const FDualNumber< tbase > &f)
sin([dual number])
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...
FE_Evolution(FiniteElementSpace &vfes_, Operator &A_, SparseMatrix &Aflux_)
NURBSExtension * NURBSext
Optional NURBS mesh extension.
void GetDiag(Vector &d) const
Returns the Diagonal of A.
void PrintInfo() const
Print various ARKStep statistics.
FDualNumber< tbase > sqrt(const FDualNumber< tbase > &f)
sqrt([dual number])
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
void PrintInfo() const
Print various CVODE statistics.
void Print(std::ostream &out=mfem::out) const override
double u(const Vector &xvec)
Class for parallel grid function.
void SetERKTableNum(int table_num)
Choose a specific Butcher table for an explicit RK method.
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.
void Init(TimeDependentOperator &f_)
Initialize ARKode: calls ARKStepCreate() to create the ARKStep memory and set some defaults...
Class for parallel meshes.
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)
bool Good() const
Return true if the command line options were parsed successfully.