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[])
140 Mpi::Init(argc, argv);
141 int num_procs = Mpi::WorldSize();
142 int myid = Mpi::WorldRank();
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.");
232 Device device(device_config);
233 if (myid == 0) { device.
Print(); }
237 Mesh *mesh =
new Mesh(mesh_file, 1, 1);
244 UserMonitor *pmon = NULL;
247 switch (ode_solver_type)
250 case 2: ode_solver =
new RK2Solver(1.0);
break;
252 case 4: ode_solver =
new RK4Solver;
break;
253 case 6: ode_solver =
new RK6Solver;
break;
257 cout <<
"Unknown ODE solver type: " << ode_solver_type <<
'\n';
274 for (
int lev = 0; lev < ser_ref_levels; lev++)
289 for (
int lev = 0; lev < par_ref_levels; lev++)
302 cout <<
"Number of unknowns: " << global_vSize << endl;
359 ostringstream mesh_name, sol_name;
360 mesh_name <<
"ex9-mesh." << setfill(
'0') << setw(6) << myid;
361 sol_name <<
"ex9-init." << setfill(
'0') << setw(6) << myid;
362 ofstream omesh(mesh_name.str().c_str());
363 omesh.precision(precision);
365 ofstream osol(sol_name.str().c_str());
366 osol.precision(precision);
377 #ifdef MFEM_USE_SIDRE
380 MFEM_ABORT(
"Must build with MFEM_USE_SIDRE=YES for binary output.");
399 sout.
open(vishost, visport);
403 cout <<
"Unable to connect to GLVis server at "
404 << vishost <<
':' << visport << endl;
405 visualization =
false;
408 cout <<
"GLVis visualization disabled.\n";
413 sout <<
"parallel " << num_procs <<
" " << myid <<
"\n";
414 sout.precision(precision);
415 sout <<
"solution\n" << *pmesh << *
u;
419 cout <<
"GLVis visualization paused."
420 <<
" Press space (in the GLVis window) to resume it.\n";
425 sout.precision(precision);
426 pmon =
new UserMonitor(sout,pmesh,u,vis_steps);
438 pode_solver->
Init(*adv,PetscODESolver::ODE_SOLVER_LINEAR);
442 ode_solver->
Init(*adv);
450 for (
int ti = 0; !done; )
454 double dt_real = min(dt, t_final - t);
455 ode_solver->
Step(*U, t, dt_real);
458 done = (t >= t_final - 1e-8*dt);
460 if (done || ti % vis_steps == 0)
464 cout <<
"time step: " << ti <<
", time: " << t << endl;
472 sout <<
"parallel " << num_procs <<
" " << myid <<
"\n";
473 sout <<
"solution\n" << *pmesh << *u << flush;
485 else { ode_solver->
Run(*U, t, dt, t_final); }
491 ostringstream sol_name;
492 sol_name <<
"ex9-final." << setfill(
'0') << setw(6) << myid;
493 ofstream osol(sol_name.str().c_str());
494 osol.precision(precision);
522 const Vector &b_,
bool M_in_lhs)
526 b(b_), comm(M_.ParFESpace()->GetComm()), M_solver(comm), z(M_.Height()),
527 iJacobian(NULL), rJacobian(NULL)
610 Operator::PETSC_MATAIJ : Operator::ANY_TYPE);
617 mfem_error(
"FE_Evolution::GetExplicitGradient(x): Capability not coded!");
627 Operator::PETSC_MATAIJ : Operator::ANY_TYPE);
636 mfem_error(
"FE_Evolution::GetImplicitGradient(x,xp,shift):"
637 " Capability not coded!");
649 for (
int i = 0; i <
dim; i++)
662 case 1: v(0) = 1.0;
break;
663 case 2: v(0) = sqrt(2./3.); v(1) = sqrt(1./3.);
break;
664 case 3: v(0) = sqrt(3./6.); v(1) = sqrt(2./6.); v(2) = sqrt(1./6.);
673 const double w = M_PI/2;
676 case 1: v(0) = 1.0;
break;
677 case 2: v(0) = w*X(1); v(1) = -w*X(0);
break;
678 case 3: v(0) = w*X(1); v(1) = -w*X(0); v(2) = 0.0;
break;
685 const double w = M_PI/2;
686 double d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
690 case 1: v(0) = 1.0;
break;
691 case 2: v(0) = d*w*X(1); v(1) = -d*w*X(0);
break;
692 case 3: v(0) = d*w*X(1); v(1) = -d*w*X(0); v(2) = 0.0;
break;
706 for (
int i = 0; i <
dim; i++)
720 return exp(-40.*pow(X(0)-0.5,2));
724 double rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
727 const double s = (1. + 0.25*cos(2*M_PI*X(2)));
731 return ( erfc(w*(X(0)-cx-rx))*erfc(-w*(X(0)-cx+rx)) *
732 erfc(w*(X(1)-cy-ry))*erfc(-w*(X(1)-cy+ry)) )/16;
738 double x_ = X(0), y_ = X(1), rho, phi;
741 return pow(sin(M_PI*rho),2)*sin(3*phi);
745 const double f = M_PI;
746 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.
virtual void SetPrintLevel(int print_lvl)
Legacy method to set the level of verbosity of the solver output.
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)
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].
void Print(std::ostream &out=mfem::out) const override
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.