60int main(
int argc,
char *argv[])
70 const real_t specific_heat_ratio = 1.4;
71 const real_t gas_constant = 1.0;
73 string mesh_file =
"";
74 int IntOrderOffset = 1;
75 int ser_ref_levels = 0;
76 int par_ref_levels = 1;
78 int ode_solver_type = 4;
82 bool visualization =
true;
83 bool preassembleWeakDiv =
true;
87 cout.precision(precision);
90 args.
AddOption(&mesh_file,
"-m",
"--mesh",
91 "Mesh file to use. If not provided, then a periodic square"
92 " mesh will be used.");
94 "Problem setup to use. See EulerInitialCondition().");
95 args.
AddOption(&ser_ref_levels,
"-rs",
"--serial-refine",
96 "Number of times to refine the serial mesh uniformly.");
97 args.
AddOption(&par_ref_levels,
"-rp",
"--parallel-refine",
98 "Number of times to refine the parallel mesh uniformly.");
100 "Order (degree) of the finite elements.");
101 args.
AddOption(&ode_solver_type,
"-s",
"--ode-solver",
102 "ODE solver: 1 - Forward Euler,\n\t"
103 " 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
104 args.
AddOption(&t_final,
"-tf",
"--t-final",
"Final time; start time is 0.");
105 args.
AddOption(&dt,
"-dt",
"--time-step",
106 "Time step. Positive number skips CFL timestep calculation.");
107 args.
AddOption(&cfl,
"-c",
"--cfl-number",
108 "CFL number for timestep calculation.");
109 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
110 "--no-visualization",
111 "Enable or disable GLVis visualization.");
112 args.
AddOption(&preassembleWeakDiv,
"-ea",
"--element-assembly-divergence",
113 "-mf",
"--matrix-free-divergence",
114 "Weak divergence assembly level\n"
115 " ea - Element assembly with interpolated F\n"
116 " mf - Nonlinear assembly in matrix-free manner");
117 args.
AddOption(&vis_steps,
"-vs",
"--visualization-steps",
118 "Visualize every n-th timestep.");
125 const int num_equations =
dim + 2;
130 for (
int lev = 0; lev < ser_ref_levels; lev++)
144 for (
int lev = 0; lev < par_ref_levels; lev++)
152 switch (ode_solver_type)
155 case 2: ode_solver =
new RK2Solver(1.0);
break;
157 case 4: ode_solver =
new RK4Solver;
break;
158 case 6: ode_solver =
new RK6Solver;
break;
160 cout <<
"Unknown ODE solver type: " << ode_solver_type <<
'\n';
180 cout <<
"Number of unknowns: " << glob_size << endl;
196 ostringstream mesh_name;
197 mesh_name <<
"euler-mesh." << setfill(
'0') << setw(6) <<
Mpi::WorldRank();
198 ofstream mesh_ofs(mesh_name.str().c_str());
199 mesh_ofs.precision(precision);
202 for (
int k = 0; k < num_equations; k++)
205 ostringstream sol_name;
206 sol_name <<
"euler-" << k <<
"-init." << setfill(
'0') << setw(6)
208 ofstream sol_ofs(sol_name.str().c_str());
209 sol_ofs.precision(precision);
218 vfes, std::unique_ptr<HyperbolicFormIntegrator>(
232 visualization =
false;
235 cout <<
"Unable to connect to GLVis server at " <<
vishost <<
':'
237 cout <<
"GLVis visualization disabled.\n";
242 sout.precision(precision);
244 sout <<
"parallel " << numProcs <<
" " << myRank <<
"\n";
245 sout <<
"solution\n" << pmesh << mom;
246 sout <<
"window_title 'momentum, t = 0'\n";
247 sout <<
"view 0 0\n";
248 sout <<
"keys jlm\n";
253 cout <<
"GLVis visualization paused."
254 <<
" Press space (in the GLVis window) to resume it.\n";
267 for (
int i = 0; i < pmesh.
GetNE(); i++)
283 dt = cfl * hmin / max_char_speed / (2 * order + 1);
293 ode_solver->
Init(euler);
297 for (
int ti = 0; !done;)
299 real_t dt_real = min(dt, t_final -
t);
301 ode_solver->
Step(sol,
t, dt_real);
308 dt = cfl * hmin / max_char_speed / (2 * order + 1);
312 done = (
t >= t_final - 1e-8 * dt);
313 if (done || ti % vis_steps == 0)
317 cout <<
"time step: " << ti <<
", time: " <<
t << endl;
321 sout <<
"window_title 'momentum, t = " <<
t <<
"'\n";
322 sout <<
"parallel " << numProcs <<
" " << myRank <<
"\n";
323 sout <<
"solution\n" << pmesh << mom << flush;
337 ostringstream mesh_name;
338 mesh_name <<
"euler-mesh-final." << setfill(
'0') << setw(6)
340 ofstream mesh_ofs(mesh_name.str().c_str());
341 mesh_ofs.precision(precision);
344 for (
int k = 0; k < num_equations; k++)
347 ostringstream sol_name;
348 sol_name <<
"euler-" << k <<
"-final." << setfill(
'0') << setw(6)
350 ofstream sol_ofs(sol_name.str().c_str());
351 sol_ofs.precision(precision);
360 cout <<
"Solution error: " << error << endl;
Time dependent DG operator for hyperbolic conservation laws.
void Mult(const Vector &x, Vector &y) const override
Apply nonlinear form to obtain M⁻¹(DIVF + JUMP HAT(F))
int GetNDofs() const
Returns number of degrees of freedom. This is the number of Local Degrees of Freedom.
Ordering::Type GetOrdering() const
Return the ordering method.
The classical forward Euler method.
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Arbitrary order "L2-conforming" discontinuous finite elements.
void Clear()
Clear the contents of the Mesh.
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
real_t GetElementSize(int i, int type=0)
Get the size of the i-th element relative to the perfect reference element.
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).
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].
void ParseCheck(std::ostream &out=mfem::out)
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...
Abstract parallel finite element space.
HYPRE_BigInt GlobalTrueVSize() const
Class for parallel grid function.
real_t ComputeLpError(const real_t p, Coefficient &exsol, Coefficient *weight=NULL, const IntegrationRule *irs[]=NULL, const Array< int > *elems=NULL) const override
void ProjectCoefficient(Coefficient &coeff) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Class for parallel meshes.
Third-order, strong stability preserving (SSP) Runge-Kutta method.
The classical explicit forth-order Runge-Kutta method, RK4.
Rusanov flux, also known as local Lax-Friedrichs, F̂ n = ½(F(u⁺,x)n + F(u⁻,x)n) - ½λ(u⁺ - u⁻) where λ...
double RealTime()
Return the number of real seconds elapsed since the stopwatch was started.
void Start()
Start the stopwatch. The elapsed time is not cleared.
void Stop()
Stop the stopwatch.
void Clear()
Clear the elapsed time on the stopwatch and restart it if it's running.
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.
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
real_t infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
Mesh EulerMesh(const int problem)
VectorFunctionCoefficient EulerInitialCondition(const int problem, const real_t specific_heat_ratio, const real_t gas_constant)
Helper struct to convert a C++ type to an MPI type.