61 int main(
int argc,
char *argv[])
64 Mpi::Init(argc, argv);
69 const char *mesh_file =
"../data/periodic-square.mesh";
70 int ser_ref_levels = 0;
71 int par_ref_levels = 1;
73 int ode_solver_type = 4;
77 bool visualization =
true;
81 cout.precision(precision);
83 OptionsParser args(argc, argv);
84 args.AddOption(&mesh_file,
"-m",
"--mesh",
86 args.AddOption(&
problem,
"-p",
"--problem",
87 "Problem setup to use. See options in velocity_function().");
88 args.AddOption(&ser_ref_levels,
"-rs",
"--refine-serial",
89 "Number of times to refine the mesh uniformly before parallel"
90 " partitioning, -1 for auto.");
91 args.AddOption(&par_ref_levels,
"-rp",
"--refine-parallel",
92 "Number of times to refine the mesh uniformly after parallel"
94 args.AddOption(&order,
"-o",
"--order",
95 "Order (degree) of the finite elements.");
96 args.AddOption(&ode_solver_type,
"-s",
"--ode-solver",
97 "ODE solver: 1 - Forward Euler,\n\t"
98 " 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
99 args.AddOption(&t_final,
"-tf",
"--t-final",
100 "Final time; start time is 0.");
101 args.AddOption(&dt,
"-dt",
"--time-step",
102 "Time step. Positive number skips CFL timestep calculation.");
103 args.AddOption(&cfl,
"-c",
"--cfl-number",
104 "CFL number for timestep calculation.");
105 args.AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
106 "--no-visualization",
107 "Enable or disable GLVis visualization.");
108 args.AddOption(&vis_steps,
"-vs",
"--visualization-steps",
109 "Visualize every n-th timestep.");
114 if (Mpi::Root()) { args.PrintUsage(cout); }
117 if (Mpi::Root()) { args.PrintOptions(cout); }
121 Mesh mesh(mesh_file, 1, 1);
122 const int dim = mesh.Dimension();
124 MFEM_ASSERT(dim == 2,
"Need a two-dimensional mesh for the problem definition");
128 ODESolver *ode_solver = NULL;
129 switch (ode_solver_type)
131 case 1: ode_solver =
new ForwardEulerSolver;
break;
132 case 2: ode_solver =
new RK2Solver(1.0);
break;
133 case 3: ode_solver =
new RK3SSPSolver;
break;
134 case 4: ode_solver =
new RK4Solver;
break;
135 case 6: ode_solver =
new RK6Solver;
break;
139 cout <<
"Unknown ODE solver type: " << ode_solver_type <<
'\n';
147 for (
int lev = 0; lev < ser_ref_levels; lev++)
149 mesh.UniformRefinement();
155 ParMesh pmesh(MPI_COMM_WORLD, mesh);
157 for (
int lev = 0; lev < par_ref_levels; lev++)
159 pmesh.UniformRefinement();
166 ParFiniteElementSpace fes(&pmesh, &fec);
168 ParFiniteElementSpace dfes(&pmesh, &fec, dim, Ordering::byNODES);
170 ParFiniteElementSpace vfes(&pmesh, &fec,
num_equation, Ordering::byNODES);
173 MFEM_ASSERT(fes.GetOrdering() == Ordering::byNODES,
"");
178 cout <<
"Number of unknowns: " << glob_size << endl;
187 for (
int k = 0; k <=
num_equation; k++) { offsets[k] = k * vfes.GetNDofs(); }
188 BlockVector u_block(offsets);
191 ParGridFunction mom(&dfes, u_block.GetData() + offsets[1]);
195 ParGridFunction sol(&vfes, u_block.GetData());
196 sol.ProjectCoefficient(u0);
200 ostringstream mesh_name;
201 mesh_name <<
"vortex-mesh." << setfill(
'0')
202 << setw(6) << Mpi::WorldRank();
203 ofstream mesh_ofs(mesh_name.str().c_str());
204 mesh_ofs.precision(precision);
209 ParGridFunction uk(&fes, u_block.GetBlock(k));
210 ostringstream sol_name;
211 sol_name <<
"vortex-" << k <<
"-init."
212 << setfill(
'0') << setw(6) << Mpi::WorldRank();
213 ofstream sol_ofs(sol_name.str().c_str());
214 sol_ofs.precision(precision);
221 MixedBilinearForm Aflux(&dfes, &fes);
225 ParNonlinearForm A(&vfes);
241 MPI_Barrier(pmesh.GetComm());
242 sout.open(vishost, visport);
247 cout <<
"Unable to connect to GLVis server at "
248 << vishost <<
':' << visport << endl;
250 visualization =
false;
253 cout <<
"GLVis visualization disabled.\n";
258 sout <<
"parallel " << Mpi::WorldSize()
259 <<
" " << Mpi::WorldRank() <<
"\n";
260 sout.precision(precision);
261 sout <<
"solution\n" << pmesh << mom;
266 cout <<
"GLVis visualization paused."
267 <<
" Press space (in the GLVis window) to resume it.\n";
276 double my_hmin = pmesh.GetElementSize(0, 1);
277 for (
int i = 1; i < pmesh.GetNE(); i++)
279 my_hmin = min(pmesh.GetElementSize(i, 1), my_hmin);
282 MPI_Allreduce(&my_hmin, &hmin, 1, MPI_DOUBLE, MPI_MIN, pmesh.GetComm());
291 ode_solver->Init(euler);
298 Vector z(sol.Size());
302 double all_max_char_speed;
304 1, MPI_DOUBLE, MPI_MAX, pmesh.GetComm());
312 for (
int ti = 0; !done; )
314 double dt_real = min(dt, t_final - t);
316 ode_solver->Step(sol, t, dt_real);
321 double all_max_char_speed;
323 1, MPI_DOUBLE, MPI_MAX, pmesh.GetComm());
330 done = (t >= t_final - 1e-8*dt);
331 if (done || ti % vis_steps == 0)
335 cout <<
"time step: " << ti <<
", time: " << t << endl;
339 MPI_Barrier(pmesh.GetComm());
340 sout <<
"parallel " << Mpi::WorldSize()
341 <<
" " << Mpi::WorldRank() <<
"\n";
342 sout <<
"solution\n" << pmesh << mom << flush;
357 ParGridFunction uk(&fes, u_block.GetBlock(k));
358 ostringstream sol_name;
359 sol_name <<
"vortex-" << k <<
"-final."
360 << setfill(
'0') << setw(6) << Mpi::WorldRank();
361 ofstream sol_ofs(sol_name.str().c_str());
362 sol_ofs.precision(precision);
369 const double error = sol.ComputeLpError(2, u0);
372 cout <<
"Solution error: " << error << endl;
void Stop()
Stop the stopwatch.
const double specific_heat_ratio
void Start()
Start the stopwatch. The elapsed time is not cleared.
L2_FECollection DG_FECollection
Declare an alternative name for L2_FECollection = DG_FECollection.
void InitialCondition(const Vector &x, Vector &y)
const double gas_constant
void Clear()
Clear the elapsed time on the stopwatch and restart it if it's running.