37 #ifndef MFEM_USE_PETSC
38 #error This example requires that MFEM is built with MFEM_USE_PETSC=YES
85 virtual void ExplicitMult(
const Vector &x,
Vector &y)
const;
117 MPI_Comm_size(pmesh->GetComm(),&num_procs);
118 MPI_Comm_rank(pmesh->GetComm(),&myid);
119 sout <<
"parallel " << num_procs <<
" " << myid <<
"\n";
120 sout <<
"solution\n" << *pmesh << *
u;
121 if (pause) { sout <<
"pause\n"; }
128 cout <<
"GLVis visualization paused."
129 <<
" Press space (in the GLVis window) to resume it.\n";
137 int main(
int argc,
char *argv[])
141 MPI_Init(&argc, &argv);
142 MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
143 MPI_Comm_rank(MPI_COMM_WORLD, &myid);
147 const char *mesh_file =
"../../data/periodic-hexagon.mesh";
148 int ser_ref_levels = 2;
149 int par_ref_levels = 0;
154 const char *device_config =
"cpu";
155 int ode_solver_type = 4;
156 double t_final = 10.0;
158 bool visualization =
true;
162 bool use_petsc =
true;
163 bool implicit =
false;
164 bool use_step =
true;
165 const char *petscrc_file =
"";
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(&ser_ref_levels,
"-rs",
"--refine-serial",
176 "Number of times to refine the mesh uniformly in serial.");
177 args.
AddOption(&par_ref_levels,
"-rp",
"--refine-parallel",
178 "Number of times to refine the mesh uniformly in parallel.");
180 "Order (degree) of the finite elements.");
181 args.
AddOption(&pa,
"-pa",
"--partial-assembly",
"-no-pa",
182 "--no-partial-assembly",
"Enable Partial Assembly.");
183 args.
AddOption(&ea,
"-ea",
"--element-assembly",
"-no-ea",
184 "--no-element-assembly",
"Enable Element Assembly.");
185 args.
AddOption(&fa,
"-fa",
"--full-assembly",
"-no-fa",
186 "--no-full-assembly",
"Enable Full Assembly.");
187 args.
AddOption(&device_config,
"-d",
"--device",
188 "Device configuration string, see Device::Configure().");
189 args.
AddOption(&ode_solver_type,
"-s",
"--ode-solver",
190 "ODE solver: 1 - Forward Euler,\n\t"
191 " 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
192 args.
AddOption(&t_final,
"-tf",
"--t-final",
193 "Final time; start time is 0.");
194 args.
AddOption(&dt,
"-dt",
"--time-step",
196 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
197 "--no-visualization",
198 "Enable or disable GLVis visualization.");
199 args.
AddOption(&visit,
"-visit",
"--visit-datafiles",
"-no-visit",
200 "--no-visit-datafiles",
201 "Save data files for VisIt (visit.llnl.gov) visualization.");
202 args.
AddOption(&binary,
"-binary",
"--binary-datafiles",
"-ascii",
204 "Use binary (Sidre) or ascii format for VisIt data files.");
205 args.
AddOption(&vis_steps,
"-vs",
"--visualization-steps",
206 "Visualize every n-th timestep.");
207 args.
AddOption(&use_petsc,
"-usepetsc",
"--usepetsc",
"-no-petsc",
209 "Use or not PETSc to solve the ODE system.");
210 args.
AddOption(&petscrc_file,
"-petscopts",
"--petscopts",
211 "PetscOptions file to use.");
212 args.
AddOption(&use_step,
"-usestep",
"--usestep",
"-no-step",
214 "Use the Step() or Run() method to solve the ODE system.");
215 args.
AddOption(&implicit,
"-implicit",
"--implicit",
"-no-implicit",
217 "Use or not an implicit method in PETSc to solve the ODE system.");
233 Device device(device_config);
234 if (myid == 0) { device.
Print(); }
238 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
245 UserMonitor *pmon = NULL;
248 switch (ode_solver_type)
251 case 2: ode_solver =
new RK2Solver(1.0);
break;
253 case 4: ode_solver =
new RK4Solver;
break;
254 case 6: ode_solver =
new RK6Solver;
break;
258 cout <<
"Unknown ODE solver type: " << ode_solver_type <<
'\n';
276 for (
int lev = 0; lev < ser_ref_levels; lev++)
291 for (
int lev = 0; lev < par_ref_levels; lev++)
304 cout <<
"Number of unknowns: " << global_vSize << endl;
361 ostringstream mesh_name, sol_name;
362 mesh_name <<
"ex9-mesh." << setfill(
'0') << setw(6) << myid;
363 sol_name <<
"ex9-init." << setfill(
'0') << setw(6) << myid;
364 ofstream omesh(mesh_name.str().c_str());
365 omesh.precision(precision);
367 ofstream osol(sol_name.str().c_str());
368 osol.precision(precision);
379 #ifdef MFEM_USE_SIDRE
382 MFEM_ABORT(
"Must build with MFEM_USE_SIDRE=YES for binary output.");
401 sout.
open(vishost, visport);
405 cout <<
"Unable to connect to GLVis server at "
406 << vishost <<
':' << visport << endl;
407 visualization =
false;
410 cout <<
"GLVis visualization disabled.\n";
415 sout <<
"parallel " << num_procs <<
" " << myid <<
"\n";
416 sout.precision(precision);
417 sout <<
"solution\n" << *pmesh << *
u;
421 cout <<
"GLVis visualization paused."
422 <<
" Press space (in the GLVis window) to resume it.\n";
427 sout.precision(precision);
428 pmon =
new UserMonitor(sout,pmesh,u,vis_steps);
440 pode_solver->
Init(*adv,PetscODESolver::ODE_SOLVER_LINEAR);
444 ode_solver->
Init(*adv);
452 for (
int ti = 0; !done; )
456 double dt_real = min(dt, t_final - t);
457 ode_solver->
Step(*U, t, dt_real);
460 done = (t >= t_final - 1e-8*dt);
462 if (done || ti % vis_steps == 0)
466 cout <<
"time step: " << ti <<
", time: " << t << endl;
474 sout <<
"parallel " << num_procs <<
" " << myid <<
"\n";
475 sout <<
"solution\n" << *pmesh << *u << flush;
487 else { ode_solver->
Run(*U, t, dt, t_final); }
493 ostringstream sol_name;
494 sol_name <<
"ex9-final." << setfill(
'0') << setw(6) << myid;
495 ofstream osol(sol_name.str().c_str());
496 osol.precision(precision);
525 const Vector &b_,
bool M_in_lhs)
529 b(b_), comm(M_.ParFESpace()->GetComm()), M_solver(comm), z(M_.Height()),
530 iJacobian(NULL), rJacobian(NULL)
613 Operator::PETSC_MATAIJ : Operator::ANY_TYPE);
620 mfem_error(
"FE_Evolution::GetExplicitGradient(x): Capability not coded!");
630 Operator::PETSC_MATAIJ : Operator::ANY_TYPE);
639 mfem_error(
"FE_Evolution::GetImplicitGradient(x,xp,shift):"
640 " Capability not coded!");
652 for (
int i = 0; i <
dim; i++)
665 case 1: v(0) = 1.0;
break;
666 case 2: v(0) = sqrt(2./3.); v(1) = sqrt(1./3.);
break;
667 case 3: v(0) = sqrt(3./6.); v(1) = sqrt(2./6.); v(2) = sqrt(1./6.);
676 const double w = M_PI/2;
679 case 1: v(0) = 1.0;
break;
680 case 2: v(0) = w*X(1); v(1) = -w*X(0);
break;
681 case 3: v(0) = w*X(1); v(1) = -w*X(0); v(2) = 0.0;
break;
688 const double w = M_PI/2;
689 double d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
693 case 1: v(0) = 1.0;
break;
694 case 2: v(0) = d*w*X(1); v(1) = -d*w*X(0);
break;
695 case 3: v(0) = d*w*X(1); v(1) = -d*w*X(0); v(2) = 0.0;
break;
709 for (
int i = 0; i <
dim; i++)
723 return exp(-40.*pow(X(0)-0.5,2));
727 double rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
730 const double s = (1. + 0.25*cos(2*M_PI*X(2)));
734 return ( erfc(w*(X(0)-cx-rx))*erfc(-w*(X(0)-cx+rx)) *
735 erfc(w*(X(1)-cy-ry))*erfc(-w*(X(1)-cy+ry)) )/16;
741 double x_ = X(0), y_ = X(1), rho, phi;
744 return pow(sin(M_PI*rho),2)*sin(3*phi);
748 const double f = M_PI;
749 return sin(f*X(0))*sin(f*X(1));
virtual void ImplicitMult(const Vector &x, const Vector &xp, Vector &y) const
Perform the action of the implicit part of the operator, F: y = F(x, k, t) where t is the current tim...
void SetPrecision(int prec)
Set the precision (number of digits) used for the text output of doubles.
Conjugate gradient method.
AssemblyLevel
Enumeration defining the assembly level for bilinear and nonlinear form classes derived from Operator...
bool isImplicit() const
True if type is IMPLICIT or HOMOGENEOUS.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
virtual void Mult(const Vector &b, Vector &x) const
Operator application: y=A(x).
Wrapper for PETSc's matrix class.
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 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.
void SetMonitor(PetscSolverMonitor *ctx)
Sets user-defined monitoring routine.
Abstract class for PETSc's ODE solvers.
Data collection with Sidre routines following the Conduit mesh blueprint specification.
virtual void Init(TimeDependentOperator &f_, enum PetscODESolver::Type type)
Initialize the ODE solver.
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void SetPrintLevel(int print_lvl)
Abstract class for monitoring PETSc's solvers.
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.
Jacobi smoothing for a given bilinear form (no matrix necessary).
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
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)
virtual void Print(std::ostream &out=mfem::out) const
Parallel smoothers in hypre.
bool isExplicit() const
True if type is EXPLICIT.
void PrintUsage(std::ostream &out) const
Print the usage message.
void SetTime(double t)
Set physical time (for time-dependent simulations)
A general vector function coefficient.
Wrapper for hypre's parallel vector class.
Type
Enumeration defining IDs for some classes derived from Operator.
The classical explicit forth-order Runge-Kutta method, RK4.
void SetAbsTol(double atol)
void SetRelTol(double rtol)
void velocity_function(const Vector &x, Vector &v)
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 Operator & GetExplicitGradient(const Vector &x) const
Return an Operator representing dG/dx at the given point x and the currently set time.
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.
virtual Operator & GetImplicitGradient(const Vector &x, const Vector &xp, double shift) const
Return an Operator representing (dF/dk shift + dF/dx) at the given x, k, and the currently set time...
void MFEMInitializePetsc()
Convenience functions to initialize/finalize PETSc.
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)
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 Run(Vector &x, double &t, double &dt, double tf)
Perform time integration from time t [in] to time tf [in].
double u(const Vector &xvec)
Class for parallel grid function.
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.
Class for parallel meshes.
virtual void ExplicitMult(const Vector &x, Vector &y) const
Perform the action of the explicit part of the operator, G: y = G(x, t) where t is the current time...
virtual void Init(TimeDependentOperator &f_)
Associate a TimeDependentOperator with the ODE solver.
double inflow_function(const Vector &x)
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.