MFEM v4.8.0
Finite element discretization library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
ex16p.cpp
Go to the documentation of this file.
1// MFEM Example 16 - Parallel Version
2// SUNDIALS Modification
3//
4// Compile with:
5// make ex16p (GNU make)
6// make sundials_ex16p (CMake)
7//
8// Sample runs:
9// mpirun -np 4 ex16p
10// mpirun -np 4 ex16p -m ../../data/inline-tri.mesh
11// mpirun -np 4 ex16p -m ../../data/disc-nurbs.mesh -tf 2
12// mpirun -np 4 ex16p -s 12 -a 0.0 -k 1.0
13// mpirun -np 4 ex16p -s 15 -a 0.0 -k 1.0
14// mpirun -np 4 ex16p -s 8 -a 1.0 -k 0.0 -dt 4e-6 -tf 2e-2 -vs 50
15// mpirun -np 4 ex16p -s 11 -a 1.0 -k 0.0 -dt 4e-6 -tf 2e-2 -vs 50
16// mpirun -np 8 ex16p -s 9 -a 0.5 -k 0.5 -o 4 -dt 8e-6 -tf 2e-2 -vs 50
17// mpirun -np 8 ex16p -s 12 -a 0.5 -k 0.5 -o 4 -dt 8e-6 -tf 2e-2 -vs 50
18// mpirun -np 4 ex16p -s 10 -dt 2.0e-4 -tf 4.0e-2
19// mpirun -np 4 ex16p -s 13 -dt 2.0e-4 -tf 4.0e-2
20// mpirun -np 16 ex16p -m ../../data/fichera-q2.mesh
21// mpirun -np 16 ex16p -m ../../data/escher-p2.mesh
22// mpirun -np 8 ex16p -m ../../data/beam-tet.mesh -tf 10 -dt 0.1
23// mpirun -np 4 ex16p -m ../../data/amr-quad.mesh -o 4 -rs 0 -rp 0
24// mpirun -np 4 ex16p -m ../../data/amr-hex.mesh -o 2 -rs 0 -rp 0
25//
26// Description: This example solves a time dependent nonlinear heat equation
27// problem of the form du/dt = C(u), with a non-linear diffusion
28// operator C(u) = \nabla \cdot (\kappa + \alpha u) \nabla u.
29//
30// The example demonstrates the use of nonlinear operators (the
31// class ConductionOperator defining C(u)), as well as their
32// implicit time integration. Note that implementing the method
33// ConductionOperator::ImplicitSolve is the only requirement for
34// high-order implicit (SDIRK) time integration. By default, this
35// example uses the SUNDIALS ODE solvers from CVODE and ARKODE.
36//
37// We recommend viewing examples 2, 9 and 10 before viewing this
38// example.
39
40#include "mfem.hpp"
41#include <fstream>
42#include <iostream>
43
44using namespace std;
45using namespace mfem;
46
47/** After spatial discretization, the conduction model is expressed as
48 *
49 * M du/dt = - K(u) u
50 *
51 * where u is the vector representing the temperature, M is the mass matrix,
52 * and K(u) is the diffusion operator with diffusivity depending on u:
53 * (\kappa + \alpha u).
54 *
55 * Class ConductionOperatorOperator represents the above ODE operator in the
56 * general form F(u, k, t) = G(u, t) where either
57 *
58 * 1. F(u, du/dt, t) = du/dt (ODE is expressed in EXPLICIT form)
59 * G(u, t) = - inv(M) K(u) u
60 * 2. F(u, du/dt, t) = M du/dt (ODE is expressed in IMPLICIT form)
61 * G(u, t) = - K(u) u
62 */
63class ConductionOperator : public TimeDependentOperator
64{
65 ParFiniteElementSpace &fespace;
66 Array<int> ess_tdof_list; // this list remains empty for pure Neumann b.c.
67
69 HypreParMatrix Mmat;
70
71 const real_t alpha, kappa;
72 std::unique_ptr<BilinearForm> K;
73 HypreParMatrix Kmat;
74
75 std::unique_ptr<HypreParMatrix> T; // T = M + gam K(u)
76
77 CGSolver M_solver; // Krylov solver for inverting the mass matrix M
78 HypreSmoother M_prec; // Preconditioner for the mass matrix M
79
80 CGSolver T_solver; // Implicit solver for T = M + gam K(u)
81 HypreSmoother T_prec; // Preconditioner for the implicit solver
82
83 mutable Vector z; // auxiliary vector
84
85public:
86
87 ConductionOperator(ParFiniteElementSpace &f, const real_t alpha,
88 const real_t kappa, const Vector &u,
89 const Type &ode_expression_type);
90
91 // Compute K(u_n) for use as an approximation in - K(u) u
92 void SetConductionTensor(const Vector &u);
93
94 /** Compute G(u, t) as defined in the IMPLICIT expression form of the ODE
95 operator, i.e., @a v = - K(u_n) @a u. Note that K(u_n) is an
96 approximation to K(u). */
97 void ExplicitMult(const Vector &u, Vector &v) const override;
98
99 /** Solve for k in F(u, k, t) = G(u, t) for either EXPLICIT or IMPLICIT
100 expression forms of the ODE operator, i.e., @a k = - inv(M) K(u_n) @a u.
101 Note that K(u_n) is an approximation to K(u). */
102 void Mult(const Vector &u, Vector &k) const override;
103
104 /** Solve for k in F(u + gam*k, k, t) = G(u + gam*k, t) for either EXPLICIT
105 or IMPLICIT expression forms of the ODE operator, i.e.,
106 [ M + @a gam K(u_n) ] @a k = - K(u_n) @a u . Note that K(u_n) is an
107 approximation to K(u). */
108 void ImplicitSolve(const real_t gam, const Vector &u, Vector &k) override;
109
110 /** Setup to solve for dk in [dF/dk + gam*dF/du - gam*dG/du] dk = G - F for
111 either EXPLICIT or IMPLICIT expression forms of the ODE operator, i.e.,
112 [M - @a gam Jf(u)] dk = G - F, where Jf(u) is an approximation of the
113 Jacobian of -K(u) u. The approximation chosen here is Jf(u) = -K(u_n). */
114 int SUNImplicitSetup(const Vector &u, const Vector &fu, int jok, int *jcur,
115 real_t gam) override;
116
117 /** Solve for @a dk in the system in SUNImplicitSetup to the given tolerance,
118 with the residual @a r providing either
119 1. @a r = G - F = inv(M) f(u) - k (EXPLICIT expression form)
120 1. @a r = G - F = f(u) - M k (IMPLICIT expression form)
121 */
122 int SUNImplicitSolve(const Vector &r, Vector &dk, real_t tol) override;
123
124 int SUNMassSetup() override;
125
126 int SUNMassSolve(const Vector &b, Vector &x, real_t tol) override;
127
128 int SUNMassMult(const Vector &x, Vector &v) override;
129};
130
132{
133 if (x.Norml2() < 0.5)
134 {
135 return 2.0;
136 }
137 else
138 {
139 return 1.0;
140 }
141}
142
143
144int main(int argc, char *argv[])
145{
146 // 1. Initialize MPI, HYPRE, and SUNDIALS.
147 Mpi::Init(argc, argv);
148 int num_procs = Mpi::WorldSize();
149 int myid = Mpi::WorldRank();
150 Hypre::Init();
152
153 // 2. Parse command-line options.
154 const char *mesh_file = "../../data/star.mesh";
155 int ser_ref_levels = 2;
156 int par_ref_levels = 1;
157 int order = 2;
158 int ode_solver_type = 9; // CVODE implicit BDF
159 real_t t_final = 0.5;
160 real_t dt = 1.0e-2;
161 real_t alpha = 1.0e-2;
162 real_t kappa = 0.5;
163 bool visualization = true;
164 bool visit = false;
165 int vis_steps = 5;
166
167 // Relative and absolute tolerances for CVODE and ARKODE.
168 const real_t reltol = 1e-4, abstol = 1e-4;
169
170 int precision = 8;
171 cout.precision(precision);
172
173 OptionsParser args(argc, argv);
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.");
180 args.AddOption(&order, "-o", "--order",
181 "Order (degree) of the finite elements.");
182 args.AddOption(&ode_solver_type, "-s", "--ode-solver",
183 "ODE solver:\n\t"
184 "1 - Forward Euler,\n\t"
185 "2 - RK2,\n\t"
186 "3 - RK3 SSP,\n\t"
187 "4 - RK4,\n\t"
188 "5 - Backward Euler,\n\t"
189 "6 - SDIRK 2,\n\t"
190 "7 - SDIRK 3,\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",
202 "Time step.");
203 args.AddOption(&alpha, "-a", "--alpha",
204 "Alpha coefficient.");
205 args.AddOption(&kappa, "-k", "--kappa",
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.");
215 args.Parse();
216 if (!args.Good())
217 {
218 args.PrintUsage(cout);
219 return 1;
220 }
221
222 if (Mpi::Root())
223 {
224 args.PrintOptions(cout);
225 }
226
227 bool use_mass_solver = ode_solver_type >= 13;
228
229 // 3. Define a parallel mesh by a partitioning of a serial mesh. Read the
230 // serial mesh from the given mesh file on all processors. We can
231 // handle triangular, quadrilateral, tetrahedral and hexahedral meshes
232 // with the same code.
233 std::unique_ptr<ParMesh> pmesh;
234 {
235 std::unique_ptr<Mesh> mesh(new Mesh(mesh_file, 1, 1));
236
237 // 4. Refine the mesh in serial to increase the resolution. In this example
238 // we do 'ser_ref_levels' of uniform refinement, where 'ser_ref_levels' is
239 // a command-line parameter.
240 for (int lev = 0; lev < ser_ref_levels; lev++)
241 {
242 mesh->UniformRefinement();
243 }
244
245 // 5. Refine this mesh further in parallel to increase the resolution.
246 // Once the parallel mesh is defined, the serial mesh can be deleted.
247 pmesh = std::make_unique<ParMesh>(MPI_COMM_WORLD, *mesh);
248 }
249 for (int lev = 0; lev < par_ref_levels; lev++)
250 {
251 pmesh->UniformRefinement();
252 }
253
254 // 6. Define the vector finite element space representing the current and the
255 // initial temperature, u_ref.
256 int dim = pmesh->Dimension();
257 H1_FECollection fe_coll(order, dim);
258 ParFiniteElementSpace fespace(pmesh.get(), &fe_coll);
259
260 int fe_size = fespace.GlobalTrueVSize();
261 if (myid == 0)
262 {
263 cout << "Number of temperature unknowns: " << fe_size << endl;
264 }
265
266 ParGridFunction u_gf(&fespace);
267
268 // 7. Set the initial conditions for u. All boundaries are considered
269 // natural.
271 u_gf.ProjectCoefficient(u_0);
272 Vector u;
273 u_gf.GetTrueDofs(u);
274
275 // 8. Initialize the conduction ODE operator and the visualization.
276 ConductionOperator::Type ode_expression_type;
277 if (use_mass_solver)
278 {
279 ode_expression_type = ConductionOperator::Type::IMPLICIT;
280 }
281 else
282 {
283 ode_expression_type = ConductionOperator::Type::EXPLICIT;
284 }
285 ConductionOperator oper(fespace, alpha, kappa, u, ode_expression_type);
286
287 u_gf.SetFromTrueDofs(u);
288 {
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);
294 pmesh->Print(omesh);
295 ofstream osol(sol_name.str().c_str());
296 osol.precision(precision);
297 u_gf.Save(osol);
298 }
299
300 VisItDataCollection visit_dc("Example16-Parallel", pmesh.get());
301 visit_dc.RegisterField("temperature", &u_gf);
302 if (visit)
303 {
304 visit_dc.SetCycle(0);
305 visit_dc.SetTime(0.0);
306 visit_dc.Save();
307 }
308
309 socketstream sout;
310 if (visualization)
311 {
312 char vishost[] = "localhost";
313 int visport = 19916;
314 sout.open(vishost, visport);
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());
318 if (!all_good)
319 {
320 sout.close();
321 visualization = false;
322 if (myid == 0)
323 {
324 cout << "Unable to connect to GLVis server at "
325 << vishost << ':' << visport << endl;
326 cout << "GLVis visualization disabled.\n";
327 }
328 }
329 else
330 {
331 sout.precision(precision);
332 sout << "solution\n" << *pmesh << u_gf;
333 sout << "pause\n";
334 sout << flush;
335 if (myid == 0)
336 {
337 cout << "GLVis visualization paused."
338 << " Press space (in the GLVis window) to resume it.\n";
339 }
340 }
341 }
342
343 // 9. Define the ODE solver used for time integration.
344 real_t t = 0.0;
345 std::unique_ptr<ODESolver> ode_solver;
346 switch (ode_solver_type)
347 {
348 // MFEM explicit methods
349 case 1: ode_solver = std::make_unique<ForwardEulerSolver>(); break;
350 case 2: ode_solver = std::make_unique<RK2Solver>(0.5); break; // midpoint method
351 case 3: ode_solver = std::make_unique<RK3SSPSolver>(); break;
352 case 4: ode_solver = std::make_unique<RK4Solver>(); break;
353 // MFEM implicit L-stable methods
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;
357 // CVODE
358 case 8:
359 case 9:
360 {
361 int cvode_solver_type;
362 if (ode_solver_type == 8)
363 {
364 cvode_solver_type = CV_ADAMS;
365 }
366 else
367 {
368 cvode_solver_type = CV_BDF;
369 }
370 std::unique_ptr<CVODESolver> cvode(
371 new CVODESolver(MPI_COMM_WORLD, cvode_solver_type));
372 cvode->Init(oper);
373 cvode->SetSStolerances(reltol, abstol);
374 cvode->SetMaxStep(dt);
375 ode_solver = std::move(cvode);
376 break;
377 }
378 // ARKODE
379 case 10:
380 case 11:
381 case 12:
382 case 13:
383 case 14:
384 case 15:
385 {
386 ARKStepSolver::Type arkode_solver_type;
387 if (ode_solver_type == 12 || ode_solver_type == 15)
388 {
389 arkode_solver_type = ARKStepSolver::IMPLICIT;
390 }
391 else
392 {
393 arkode_solver_type = ARKStepSolver::EXPLICIT;
394 }
395 std::unique_ptr<ARKStepSolver> arkode(
396 new ARKStepSolver(MPI_COMM_WORLD, arkode_solver_type));
397 arkode->Init(oper);
398 arkode->SetSStolerances(reltol, abstol);
399 arkode->SetMaxStep(dt);
400 if (ode_solver_type == 11 || ode_solver_type == 14)
401 {
402 arkode->SetERKTableNum(ARKODE_FEHLBERG_13_7_8);
403 }
404 if (use_mass_solver)
405 {
406 arkode->UseMFEMMassLinearSolver(SUNFALSE);
407 }
408 ode_solver = std::move(arkode);
409 break;
410 }
411 default:
412 cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
413 return 3;
414 }
415
416 // Initialize MFEM integrators, SUNDIALS integrators are initialized above
417 if (ode_solver_type < 8) { ode_solver->Init(oper); }
418
419 // Since we want to update the diffusion coefficient after every time step,
420 // we need to use the "one-step" mode of the SUNDIALS solvers.
421 if (CVODESolver* cvode = dynamic_cast<CVODESolver*>(ode_solver.get()))
422 {
423 cvode->SetStepMode(CV_ONE_STEP);
424 }
425 else if (ARKStepSolver* arkode = dynamic_cast<ARKStepSolver*>(ode_solver.get()))
426 {
427 arkode->SetStepMode(ARK_ONE_STEP);
428 }
429
430 // 10. Perform time-integration (looping over the time iterations, ti, with a
431 // time-step dt).
432 if (Mpi::Root())
433 {
434 cout << "Integrating the ODE ..." << endl;
435 }
436 tic_toc.Clear();
437 tic_toc.Start();
438
439 bool last_step = false;
440 for (int ti = 1; !last_step; ti++)
441 {
442 real_t dt_real = min(dt, t_final - t);
443
444 // Note that since we are using the "one-step" mode of the SUNDIALS
445 // solvers, they will, generally, step over the final time and will not
446 // explicitly perform the interpolation to t_final as they do in the
447 // "normal" step mode.
448
449 ode_solver->Step(u, t, dt_real);
450
451 last_step = (t >= t_final - 1e-8*dt);
452
453 if (last_step || (ti % vis_steps) == 0)
454 {
455 if (myid == 0)
456 {
457 cout << "step " << ti << ", t = " << t << endl;
458 if (CVODESolver* cvode = dynamic_cast<CVODESolver*>(ode_solver.get()))
459 {
460 cvode->PrintInfo();
461 }
462 else if (ARKStepSolver* arkode = dynamic_cast<ARKStepSolver*>(ode_solver.get()))
463 {
464 arkode->PrintInfo();
465 }
466 }
467
468 u_gf.SetFromTrueDofs(u);
469 if (visualization)
470 {
471 sout << "parallel " << num_procs << " " << myid << "\n";
472 sout << "solution\n" << *pmesh << u_gf << flush;
473 }
474
475 if (visit)
476 {
477 visit_dc.SetCycle(ti);
478 visit_dc.SetTime(t);
479 visit_dc.Save();
480 }
481 }
482 oper.SetConductionTensor(u);
483 }
484 tic_toc.Stop();
485 if (Mpi::Root())
486 {
487 cout << "Done, " << tic_toc.RealTime() << "s." << endl;
488 }
489
490 // 11. Save the final solution in parallel. This output can be viewed later
491 // using GLVis: "glvis -np <np> -m ex16-mesh -g ex16-final".
492 u_gf.Save("ex16-final", precision);
493
494 return 0;
495}
496
497ConductionOperator::ConductionOperator(ParFiniteElementSpace &fes,
498 const real_t alpha, const real_t kappa,
499 const Vector &u,
500 const Type &ode_expression_type)
501 : TimeDependentOperator(fes.GetTrueVSize(), 0.0, ode_expression_type),
502 fespace(fes), M(&fespace), alpha(alpha), kappa(kappa),
503 M_solver(fes.GetComm()), T_solver(fes.GetComm()), z(height)
504{
505 // specify a relative tolerance for all solves with MFEM integrators
506 const real_t rel_tol = 1e-8;
507
508 M.AddDomainIntegrator(new MassIntegrator());
509 M.Assemble(0); // keep zeros to keep sparsity pattern of M and K the same
510 M.FormSystemMatrix(ess_tdof_list, Mmat);
511
512 M_solver.iterative_mode = false;
513 M_solver.SetRelTol(rel_tol); // will be overwritten with SUNDIALS integrators
514 M_solver.SetAbsTol(0.0);
515 M_solver.SetMaxIter(100);
516 M_solver.SetPrintLevel(0);
517 M_prec.SetType(HypreSmoother::Jacobi);
518 M_solver.SetPreconditioner(M_prec);
519 M_solver.SetOperator(Mmat);
520
521 T_solver.iterative_mode = false;
522 T_solver.SetRelTol(rel_tol); // will be overwritten with SUNDIALS integrators
523 T_solver.SetAbsTol(0.0);
524 T_solver.SetMaxIter(100);
525 T_solver.SetPrintLevel(0);
526 T_solver.SetPreconditioner(T_prec);
527
528 SetConductionTensor(u);
529}
530
531void ConductionOperator::SetConductionTensor(const Vector &u)
532{
533 // Compute K(u_n).
534 ParGridFunction u_alpha_gf(&fespace);
535 u_alpha_gf.SetFromTrueDofs(u);
536 for (int i = 0; i < u_alpha_gf.Size(); i++)
537 {
538 u_alpha_gf(i) = kappa + alpha*u_alpha_gf(i);
539 }
540 GridFunctionCoefficient u_coeff(&u_alpha_gf);
541
542 K = std::make_unique<ParBilinearForm>(&fespace);
544 K->Assemble(0); // keep zeros to keep sparsity pattern of M and K the same
545 K->FormSystemMatrix(ess_tdof_list, Kmat);
546}
547
548void ConductionOperator::ExplicitMult(const Vector &u, Vector &v) const
549{
550 // Compute - K(u_n) u.
551 Kmat.Mult(u, v);
552 v.Neg();
553}
554
555void ConductionOperator::Mult(const Vector &u, Vector &k) const
556{
557 // Compute - inv(M) K(u_n) u.
558 ExplicitMult(u, z);
559 M_solver.Mult(z, k);
560}
561
562void ConductionOperator::ImplicitSolve(const real_t gam, const Vector &u,
563 Vector &k)
564{
565 // Solve for k in M k = - K(u_n) [u + gam*k].
566 ExplicitMult(u, z);
567 T = std::unique_ptr<HypreParMatrix>(Add(1.0, Mmat, gam, Kmat));
568 T_solver.SetOperator(*T);
569 T_solver.Mult(z, k);
570}
571
572int ConductionOperator::SUNImplicitSetup(const Vector &u, const Vector &fu,
573 int jok, int *jcur, real_t gam)
574{
575 // Compute T = M + gamma K(u_n).
576 T = std::unique_ptr<HypreParMatrix>(Add(1.0, Mmat, gam, Kmat));
577 T_solver.SetOperator(*T);
578 *jcur = SUNTRUE; // this should eventually only be set true if K(u) is used
579 return SUN_SUCCESS;
580}
581
582int ConductionOperator::SUNImplicitSolve(const Vector &r, Vector &dk,
583 real_t tol)
584{
585 // Solve the system [M + gamma K(u_n)] dk = - K(u_n) u - M k.
586 // What value r is providing depends on the ODE expression form:
587 // EXPLICIT form: r = -inv(M) K(u_n) u - k
588 // IMPLICIT form: r = -K(u_n) u - M k
589 T_solver.SetRelTol(tol);
590 if (isExplicit())
591 {
592 Mmat.Mult(r, z);
593 T_solver.Mult(z, dk);
594 }
595 else
596 {
597 T_solver.Mult(r, dk);
598 }
599 if (T_solver.GetConverged())
600 {
601 return SUN_SUCCESS;
602 }
603 else
604 {
605 return SUNLS_CONV_FAIL;
606 }
607}
608
609int ConductionOperator::SUNMassSetup()
610{
611 // Do nothing b/c mass solver was setup in constructor.
612 return SUN_SUCCESS;
613}
614
615int ConductionOperator::SUNMassSolve(const Vector &b, Vector &x, real_t tol)
616{
617 // Solve the system M x = b.
618 M_solver.SetRelTol(tol);
619 M_solver.Mult(b, x);
620 if (M_solver.GetConverged())
621 {
622 return SUN_SUCCESS;
623 }
624 else
625 {
626 return SUNLS_CONV_FAIL;
627 }
628}
629
630int ConductionOperator::SUNMassMult(const Vector &x, Vector &v)
631{
632 // Compute M x.
633 Mmat.Mult(x, v);
634 return SUN_SUCCESS;
635}
Interface to ARKode's ARKStep module – additive Runge-Kutta methods.
Definition sundials.hpp:711
Type
Types of ARKODE solvers.
Definition sundials.hpp:715
@ IMPLICIT
Implicit RK method.
Definition sundials.hpp:717
@ EXPLICIT
Explicit RK method.
Definition sundials.hpp:716
void AddDomainIntegrator(BilinearFormIntegrator *bfi)
Adds new Domain Integrator. Assumes ownership of bfi.
void Assemble(int skip_zeros=1)
Assembles the form i.e. sums over all domain/bdr integrators.
virtual void FormSystemMatrix(const Array< int > &ess_tdof_list, OperatorHandle &A)
Form the linear system matrix A, see FormLinearSystem() for details.
Conjugate gradient method.
Definition solvers.hpp:538
void Mult(const Vector &b, Vector &x) const override
Iterative solution of the linear system using the Conjugate Gradient method.
Definition solvers.cpp:751
void SetOperator(const Operator &op) override
Set/update the solver for the given operator.
Definition solvers.hpp:551
Interface to the CVODE library – linear multi-step methods.
Definition sundials.hpp:420
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.
Definition fe_coll.hpp:275
Wrapper for hypre's ParCSR matrix class.
Definition hypre.hpp:408
Parallel smoothers in hypre.
Definition hypre.hpp:1046
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Definition hypre.cpp:33
void SetRelTol(real_t rtol)
Definition solvers.hpp:229
bool GetConverged() const
Returns true if the last call to Mult() converged successfully.
Definition solvers.hpp:282
Mesh data type.
Definition mesh.hpp:64
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.
Definition operator.hpp:284
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...
Definition optparser.hpp:82
bool Good() const
Return true if the command line options were parsed successfully.
Class for parallel bilinear form.
Abstract parallel finite element space.
Definition pfespace.hpp:29
HYPRE_BigInt GlobalTrueVSize() const
Definition pfespace.hpp:346
Class for parallel grid function.
Definition pgridfunc.hpp:50
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.
Definition tic_toc.cpp:432
void Start()
Start the stopwatch. The elapsed time is not cleared.
Definition tic_toc.cpp:411
void Stop()
Stop the stopwatch.
Definition tic_toc.cpp:422
void Clear()
Clear the elapsed time on the stopwatch and restart it if it's running.
Definition tic_toc.cpp:406
static void Init()
Definition sundials.cpp:174
Base abstract class for first order time dependent operators.
Definition operator.hpp:332
bool isExplicit() const
True if type is EXPLICIT.
Definition operator.hpp:397
Type
Enum used to describe the form of the time-dependent operator.
Definition operator.hpp:353
@ EXPLICIT
This type assumes F(u,k,t) = k.
Definition operator.hpp:354
@ IMPLICIT
This is the most general type, no assumptions on F and G.
Definition operator.hpp:355
Vector data type.
Definition vector.hpp:82
void Neg()
(*this) = -(*this)
Definition vector.cpp:375
real_t Norml2() const
Returns the l2 norm of the vector.
Definition vector.cpp:931
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.
const real_t alpha
Definition ex15.cpp:369
real_t kappa
Definition ex24.cpp:54
int dim
Definition ex24.cpp:53
int main()
real_t b
Definition lissajous.cpp:42
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
StopWatch tic_toc
Definition tic_toc.cpp:450
float real_t
Definition config.hpp:43
std::function< real_t(const Vector &)> f(real_t mass_coeff)
Definition lor_mms.hpp:30
void Add(const DenseMatrix &A, const DenseMatrix &B, real_t alpha, DenseMatrix &C)
C = A + alpha*B.
const char vishost[]
real_t InitialTemperature(const Vector &x)
Definition ex16p.cpp:131
constexpr ARKODE_ERKTableID ARKODE_FEHLBERG_13_7_8
Definition sundials.hpp:69
@ SUN_SUCCESS
Definition sundials.hpp:95