72 std::unique_ptr<BilinearForm> K;
75 std::unique_ptr<HypreParMatrix> T;
89 const Type &ode_expression_type);
92 void SetConductionTensor(
const Vector &
u);
114 int SUNImplicitSetup(
const Vector &
u,
const Vector &fu,
int jok,
int *jcur,
124 int SUNMassSetup()
override;
144int main(
int argc,
char *argv[])
154 const char *mesh_file =
"../../data/star.mesh";
155 int ser_ref_levels = 2;
156 int par_ref_levels = 1;
158 int ode_solver_type = 9;
163 bool visualization =
true;
168 const real_t reltol = 1e-4, abstol = 1e-4;
171 cout.precision(precision);
174 args.
AddOption(&mesh_file,
"-m",
"--mesh",
175 "Mesh file to use.");
176 args.
AddOption(&ser_ref_levels,
"-rs",
"--refine-serial",
177 "Number of times to refine the mesh uniformly in serial.");
178 args.
AddOption(&par_ref_levels,
"-rp",
"--refine-parallel",
179 "Number of times to refine the mesh uniformly in parallel.");
181 "Order (degree) of the finite elements.");
182 args.
AddOption(&ode_solver_type,
"-s",
"--ode-solver",
184 "1 - Forward Euler,\n\t"
188 "5 - Backward Euler,\n\t"
191 "8 - CVODE (implicit Adams),\n\t"
192 "9 - CVODE (implicit BDF),\n\t"
193 "10 - ARKODE (default explicit),\n\t"
194 "11 - ARKODE (explicit Fehlberg-6-4-5),\n\t"
195 "12 - ARKODE (default implicit),\n\t"
196 "13 - ARKODE (default explicit with MFEM mass solve),\n\t"
197 "14 - ARKODE (explicit Fehlberg-6-4-5 with MFEM mass solve),\n\t"
198 "15 - ARKODE (default implicit with MFEM mass solve).");
199 args.
AddOption(&t_final,
"-tf",
"--t-final",
200 "Final time; start time is 0.");
201 args.
AddOption(&dt,
"-dt",
"--time-step",
204 "Alpha coefficient.");
206 "Kappa coefficient offset.");
207 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
208 "--no-visualization",
209 "Enable or disable GLVis visualization.");
210 args.
AddOption(&visit,
"-visit",
"--visit-datafiles",
"-no-visit",
211 "--no-visit-datafiles",
212 "Save data files for VisIt (visit.llnl.gov) visualization.");
213 args.
AddOption(&vis_steps,
"-vs",
"--visualization-steps",
214 "Visualize every n-th timestep.");
227 bool use_mass_solver = ode_solver_type >= 13;
233 std::unique_ptr<ParMesh> pmesh;
235 std::unique_ptr<Mesh> mesh(
new Mesh(mesh_file, 1, 1));
240 for (
int lev = 0; lev < ser_ref_levels; lev++)
242 mesh->UniformRefinement();
247 pmesh = std::make_unique<ParMesh>(MPI_COMM_WORLD, *mesh);
249 for (
int lev = 0; lev < par_ref_levels; lev++)
251 pmesh->UniformRefinement();
256 int dim = pmesh->Dimension();
263 cout <<
"Number of temperature unknowns: " << fe_size << endl;
285 ConductionOperator oper(fespace,
alpha,
kappa,
u, ode_expression_type);
289 ostringstream mesh_name, sol_name;
290 mesh_name <<
"ex16-mesh." << setfill(
'0') << setw(6) << myid;
291 sol_name <<
"ex16-init." << setfill(
'0') << setw(6) << myid;
292 ofstream omesh(mesh_name.str().c_str());
293 omesh.precision(precision);
295 ofstream osol(sol_name.str().c_str());
296 osol.precision(precision);
315 sout <<
"parallel " << num_procs <<
" " << myid << endl;
316 int good = sout.good(), all_good;
317 MPI_Allreduce(&good, &all_good, 1, MPI_INT, MPI_MIN, pmesh->GetComm());
321 visualization =
false;
324 cout <<
"Unable to connect to GLVis server at "
325 <<
vishost <<
':' << visport << endl;
326 cout <<
"GLVis visualization disabled.\n";
331 sout.precision(precision);
332 sout <<
"solution\n" << *pmesh << u_gf;
337 cout <<
"GLVis visualization paused."
338 <<
" Press space (in the GLVis window) to resume it.\n";
345 std::unique_ptr<ODESolver> ode_solver;
346 switch (ode_solver_type)
349 case 1: ode_solver = std::make_unique<ForwardEulerSolver>();
break;
350 case 2: ode_solver = std::make_unique<RK2Solver>(0.5);
break;
351 case 3: ode_solver = std::make_unique<RK3SSPSolver>();
break;
352 case 4: ode_solver = std::make_unique<RK4Solver>();
break;
354 case 5: ode_solver = std::make_unique<BackwardEulerSolver>();
break;
355 case 6: ode_solver = std::make_unique<SDIRK23Solver>(2);
break;
356 case 7: ode_solver = std::make_unique<SDIRK33Solver>();
break;
361 int cvode_solver_type;
362 if (ode_solver_type == 8)
364 cvode_solver_type = CV_ADAMS;
368 cvode_solver_type = CV_BDF;
370 std::unique_ptr<CVODESolver> cvode(
371 new CVODESolver(MPI_COMM_WORLD, cvode_solver_type));
373 cvode->SetSStolerances(reltol, abstol);
374 cvode->SetMaxStep(dt);
375 ode_solver = std::move(cvode);
387 if (ode_solver_type == 12 || ode_solver_type == 15)
395 std::unique_ptr<ARKStepSolver> arkode(
398 arkode->SetSStolerances(reltol, abstol);
399 arkode->SetMaxStep(dt);
400 if (ode_solver_type == 11 || ode_solver_type == 14)
406 arkode->UseMFEMMassLinearSolver(SUNFALSE);
408 ode_solver = std::move(arkode);
412 cout <<
"Unknown ODE solver type: " << ode_solver_type <<
'\n';
417 if (ode_solver_type < 8) { ode_solver->Init(oper); }
423 cvode->SetStepMode(CV_ONE_STEP);
427 arkode->SetStepMode(ARK_ONE_STEP);
434 cout <<
"Integrating the ODE ..." << endl;
439 bool last_step =
false;
440 for (
int ti = 1; !last_step; ti++)
442 real_t dt_real = min(dt, t_final - t);
449 ode_solver->Step(
u, t, dt_real);
451 last_step = (t >= t_final - 1e-8*dt);
453 if (last_step || (ti % vis_steps) == 0)
457 cout <<
"step " << ti <<
", t = " << t << endl;
471 sout <<
"parallel " << num_procs <<
" " << myid <<
"\n";
472 sout <<
"solution\n" << *pmesh << u_gf << flush;
482 oper.SetConductionTensor(
u);
492 u_gf.
Save(
"ex16-final", precision);
500 const Type &ode_expression_type)
503 M_solver(fes.GetComm()), T_solver(fes.GetComm()), z(height)
506 const real_t rel_tol = 1e-8;
510 M.FormSystemMatrix(ess_tdof_list, Mmat);
512 M_solver.iterative_mode =
false;
513 M_solver.SetRelTol(rel_tol);
514 M_solver.SetAbsTol(0.0);
515 M_solver.SetMaxIter(100);
516 M_solver.SetPrintLevel(0);
518 M_solver.SetPreconditioner(M_prec);
519 M_solver.SetOperator(Mmat);
521 T_solver.iterative_mode =
false;
522 T_solver.SetRelTol(rel_tol);
523 T_solver.SetAbsTol(0.0);
524 T_solver.SetMaxIter(100);
525 T_solver.SetPrintLevel(0);
526 T_solver.SetPreconditioner(T_prec);
528 SetConductionTensor(
u);
531void ConductionOperator::SetConductionTensor(
const Vector &
u)
535 u_alpha_gf.SetFromTrueDofs(
u);
536 for (
int i = 0; i < u_alpha_gf.Size(); i++)
542 K = std::make_unique<ParBilinearForm>(&fespace);
548void ConductionOperator::ExplicitMult(
const Vector &
u,
Vector &v)
const
555void ConductionOperator::Mult(
const Vector &
u,
Vector &k)
const
562void ConductionOperator::ImplicitSolve(
const real_t gam,
const Vector &
u,
567 T = std::unique_ptr<HypreParMatrix>(
Add(1.0, Mmat, gam, Kmat));
572int ConductionOperator::SUNImplicitSetup(
const Vector &
u,
const Vector &fu,
573 int jok,
int *jcur,
real_t gam)
576 T = std::unique_ptr<HypreParMatrix>(
Add(1.0, Mmat, gam, Kmat));
582int ConductionOperator::SUNImplicitSolve(
const Vector &r,
Vector &dk,
593 T_solver.
Mult(z, dk);
597 T_solver.
Mult(r, dk);
605 return SUNLS_CONV_FAIL;
609int ConductionOperator::SUNMassSetup()
626 return SUNLS_CONV_FAIL;
630int ConductionOperator::SUNMassMult(
const Vector &x,
Vector &v)
Interface to ARKode's ARKStep module – additive Runge-Kutta methods.
Type
Types of ARKODE solvers.
@ IMPLICIT
Implicit RK method.
@ EXPLICIT
Explicit RK method.
Conjugate gradient method.
void Mult(const Vector &b, Vector &x) const override
Iterative solution of the linear system using the Conjugate Gradient method.
void SetOperator(const Operator &op) override
Set/update the solver for the given operator.
Interface to the CVODE library – linear multi-step methods.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
void SetTime(real_t t)
Set physical time (for time-dependent simulations)
A general function coefficient.
Coefficient defined by a GridFunction. This coefficient is mesh dependent.
Arbitrary order H1-conforming (continuous) finite elements.
Wrapper for hypre's ParCSR matrix class.
Parallel smoothers in hypre.
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
void SetRelTol(real_t rtol)
bool GetConverged() const
Returns true if the last call to Mult() converged successfully.
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).
Type
Enumeration defining IDs for some classes derived from Operator.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
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...
bool Good() const
Return true if the command line options were parsed successfully.
Abstract parallel finite element space.
HYPRE_BigInt GlobalTrueVSize() const
Class for parallel grid function.
void Save(std::ostream &out) const override
HypreParVector * GetTrueDofs() const
Returns the true dofs in a new HypreParVector.
void SetFromTrueDofs(const Vector &tv) override
Set the GridFunction from the given true-dof vector.
void ProjectCoefficient(Coefficient &coeff) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
void Mult(const Vector &x, Vector &y) const override
Matrix vector multiplication.
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.
Base abstract class for first order time dependent operators.
bool isExplicit() const
True if type is EXPLICIT.
Type
Enum used to describe the form of the time-dependent operator.
@ EXPLICIT
This type assumes F(u,k,t) = k.
@ IMPLICIT
This is the most general type, no assumptions on F and G.
void Neg()
(*this) = -(*this)
real_t Norml2() const
Returns the l2 norm of the vector.
Data collection with VisIt I/O routines.
void Save() override
Save the collection and a VisIt root file.
void RegisterField(const std::string &field_name, GridFunction *gf) override
Add a grid function to the collection and update the root file.
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
int close()
Close the socketstream.
real_t u(const Vector &xvec)
std::function< real_t(const Vector &)> f(real_t mass_coeff)
void Add(const DenseMatrix &A, const DenseMatrix &B, real_t alpha, DenseMatrix &C)
C = A + alpha*B.
real_t InitialTemperature(const Vector &x)
constexpr ARKODE_ERKTableID ARKODE_FEHLBERG_13_7_8