MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
ode.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2026, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
13#include "../general/forall.hpp"
14#include "operator.hpp"
15#include "ode.hpp"
16
17namespace mfem
18{
19
20std::string ODESolver::ExplicitTypes =
21 "\n\tExplicit solver: \n\t"
22 " RK : 1 - Forward Euler, 2 - RK2(0.5), 3 - RK3 SSP, 4 - RK4, 6 - RK6,\n\t"
23 " AB : 11 - AB1, 12 - AB2, 13 - AB3, 14 - AB4, 15 - AB5\n";
24
25std::string ODESolver::ImplicitTypes =
26 "\n\tImplicit solver: \n\t"
27 " (L-Stab): 21 - Backward Euler, 22 - SDIRK23(2), 23 - SDIRK33,\n\t"
28 " (A-Stab): 32 - Implicit Midpoint, 33 - SDIRK23, 34 - SDIRK34,\n\t"
29 " GA : 40 -- 50 - Generalized-alpha,\n\t"
30 " AM : 51 - AM1, 52 - AM2, 53 - AM3, 54 - AM4\n";
31
32std::string ODESolver::IMEXTypes =
33 "\n\tIMEX solver: \n\t"
34 " (L-Stab): 61 - Forward Backward Euler, 62 - IMEXRK2(2,2,2),\n\t"
35 " 63 - IMEXRK2(2,3,2), 64 - IMEX_DIRK_RK3\n";
36
40
41std::unique_ptr<ODESolver> ODESolver::Select(int ode_solver_type)
42{
43 if (ode_solver_type < 20)
44 {
45 return SelectExplicit(ode_solver_type);
46 }
47 else
48 {
49 return SelectImplicit(ode_solver_type);
50 }
51}
52
53std::unique_ptr<ODESolver> ODESolver::SelectExplicit(int ode_solver_type)
54{
55 using ode_ptr = std::unique_ptr<ODESolver>;
56 switch (ode_solver_type)
57 {
58 // Explicit RK methods
59 case 1: return ode_ptr(new ForwardEulerSolver);
60 case 2: return ode_ptr(new RK2Solver(0.5)); // midpoint method
61 case 3: return ode_ptr(new RK3SSPSolver);
62 case 4: return ode_ptr(new RK4Solver);
63 case 6: return ode_ptr(new RK6Solver);
64
65 // Explicit AB methods
66 case 11: return ode_ptr(new AB1Solver);
67 case 12: return ode_ptr(new AB2Solver);
68 case 13: return ode_ptr(new AB3Solver);
69 case 14: return ode_ptr(new AB4Solver);
70 case 15: return ode_ptr(new AB5Solver);
71
72 default:
73 MFEM_ABORT("Unknown ODE solver type: " << ode_solver_type);
74 }
75}
76
77std::unique_ptr<ODESolver> ODESolver::SelectImplicit(int ode_solver_type)
78{
79 using ode_ptr = std::unique_ptr<ODESolver>;
80 switch (ode_solver_type)
81 {
82 // Implicit L-stable methods
83 case 21: return ode_ptr(new BackwardEulerSolver);
84 case 22: return ode_ptr(new SDIRK23Solver(2));
85 case 23: return ode_ptr(new SDIRK33Solver);
86
87 // Implicit A-stable methods (not L-stable)
88 case 32: return ode_ptr(new ImplicitMidpointSolver);
89 case 33: return ode_ptr(new SDIRK23Solver);
90 case 34: return ode_ptr(new SDIRK34Solver);
91
92 // Implicit generalized alpha
93 case 40: return ode_ptr(new GeneralizedAlphaSolver(0.0));
94 case 41: return ode_ptr(new GeneralizedAlphaSolver(0.1));
95 case 42: return ode_ptr(new GeneralizedAlphaSolver(0.2));
96 case 43: return ode_ptr(new GeneralizedAlphaSolver(0.3));
97 case 44: return ode_ptr(new GeneralizedAlphaSolver(0.4));
98 case 45: return ode_ptr(new GeneralizedAlphaSolver(0.5));
99 case 46: return ode_ptr(new GeneralizedAlphaSolver(0.6));
100 case 47: return ode_ptr(new GeneralizedAlphaSolver(0.7));
101 case 48: return ode_ptr(new GeneralizedAlphaSolver(0.8));
102 case 49: return ode_ptr(new GeneralizedAlphaSolver(0.9));
103 case 50: return ode_ptr(new GeneralizedAlphaSolver(1.0));
104
105 // Implicit AM methods
106 case 51: return ode_ptr(new AM1Solver);
107 case 52: return ode_ptr(new AM2Solver);
108 case 53: return ode_ptr(new AM3Solver);
109 case 54: return ode_ptr(new AM4Solver);
110
111 default:
112 MFEM_ABORT("Unknown ODE solver type: " << ode_solver_type );
113 }
114}
115
116std::unique_ptr<ODESolver> ODESolver::SelectIMEX(const int ode_solver_type)
117{
118 using ode_ptr = std::unique_ptr<ODESolver>;
119 switch (ode_solver_type)
120 {
121 // L-stable IMEX methods
122 case 61: return ode_ptr(new IMEXExpImplEuler);
123 case 62: return ode_ptr(new IMEXRK2);
124 case 63: return ode_ptr(new IMEXRK2_3StageExplicit);
125 case 64: return ode_ptr(new IMEX_DIRK_RK3);
126
127 default: MFEM_ABORT("Unknown ODE solver type: " << ode_solver_type );
128 }
129}
130
132{
133 mem_type = m_t;
134 for (int i = 0; i < smax; i++)
135 {
136 idx[i] = smax - i - 1;
137 data[i].SetSize(vsize, mem_type);
138 }
139
140 ss = 0;
141}
142
144{
145 MFEM_ASSERT_INDEX_IN_RANGE(i,0,ss);
146 return data[idx[i]];
147}
148
150{
151 MFEM_ASSERT_INDEX_IN_RANGE(i,0,ss);
152 return data[idx[i]];
153}
154
155void ODEStateDataVector::Get(int i, Vector &vec) const
156{
157 MFEM_ASSERT_INDEX_IN_RANGE(i,0,ss);
158 vec = data[idx[i]];
159}
160
162{
163 MFEM_ASSERT_INDEX_IN_RANGE(i,0,smax);
164 data[idx[i]] = state;
165}
166
168{
169 ShiftStages();
170 data[idx[0]] = state;
171 Increment();
172}
173
174void ODEStateDataVector::Print(std::ostream &os) const
175{
176 os << ss <<"/" <<smax<<std::endl;
177 idx.Print(os);
178 for (int i = 0; i < ss; i++) { data[idx[i]].Print(os); }
179}
180
181
183{
184 auto implicit_type = f_.GetImplicitVariableType();
185 if (!SupportsImplicitVariableType(implicit_type))
186 {
187 MFEM_ABORT("The ODE solver does not support the implicit variable type.");
188 }
189
190 this->f = &f_;
192}
193
195 Vector &k)
196{
197 // k currently holds state u(t+dt),
198 // convert to slope k = du/dt ~= (u(t+dt)-u(t))/dt
199 const int usz = u.Size();
200 real_t fac = 1.0/dt;
201 auto d_u = u.Read();
202 auto d_k = k.ReadWrite();
203
204 mfem::forall(usz, [=] MFEM_HOST_DEVICE (int i)
205 {
206 d_k[i] -= d_u[i];
207 d_k[i] *= fac;
208 });
209}
210
216
218{
219 f->SetTime(t);
220 f->Mult(x, dxdt);
221 x.Add(dt, dxdt);
222 t += dt;
223}
224
225
227{
228 ODESolver::Init(f_);
229 int n = f->Width();
230 dxdt.SetSize(n, mem_type);
231 x1.SetSize(n, mem_type);
232}
233
235{
236 // 0 |
237 // a | a
238 // ---+--------
239 // | 1-b b b = 1/(2a)
240
241 const real_t b = 0.5/a;
242
243 f->SetTime(t);
244 f->Mult(x, dxdt);
245 add(x, (1. - b)*dt, dxdt, x1);
246 x.Add(a*dt, dxdt);
247
248 f->SetTime(t + a*dt);
249 f->Mult(x, dxdt);
250 add(x1, b*dt, dxdt, x);
251 t += dt;
252}
253
254
256{
257 ODESolver::Init(f_);
258 int n = f->Width();
259 y.SetSize(n, mem_type);
260 k.SetSize(n, mem_type);
261}
262
264{
265 // x0 = x, t0 = t, k0 = dt*f(t0, x0)
266 f->SetTime(t);
267 f->Mult(x, k);
268
269 // x1 = x + k0, t1 = t + dt, k1 = dt*f(t1, x1)
270 add(x, dt, k, y);
271 f->SetTime(t + dt);
272 f->Mult(y, k);
273
274 // x2 = 3/4*x + 1/4*(x1 + k1), t2 = t + 1/2*dt, k2 = dt*f(t2, x2)
275 y.Add(dt, k);
276 add(3./4, x, 1./4, y, y);
277 f->SetTime(t + dt/2);
278 f->Mult(y, k);
279
280 // x3 = 1/3*x + 2/3*(x2 + k2), t3 = t + dt
281 y.Add(dt, k);
282 add(1./3, x, 2./3, y, x);
283 t += dt;
284}
285
286
288{
289 ODESolver::Init(f_);
290 int n = f->Width();
291 y.SetSize(n, mem_type);
292 k.SetSize(n, mem_type);
293 z.SetSize(n, mem_type);
294}
295
297{
298 // 0 |
299 // 1/2 | 1/2
300 // 1/2 | 0 1/2
301 // 1 | 0 0 1
302 // -----+-------------------
303 // | 1/6 1/3 1/3 1/6
304
305 f->SetTime(t);
306 f->Mult(x, k); // k1
307 add(x, dt/2, k, y);
308 add(x, dt/6, k, z);
309
310 f->SetTime(t + dt/2);
311 f->Mult(y, k); // k2
312 add(x, dt/2, k, y);
313 z.Add(dt/3, k);
314
315 f->Mult(y, k); // k3
316 add(x, dt, k, y);
317 z.Add(dt/3, k);
318
319 f->SetTime(t + dt);
320 f->Mult(y, k); // k4
321 add(z, dt/6, k, x);
322 t += dt;
323}
324
326 const real_t *c_)
327{
328 s = s_;
329 a = a_;
330 b = b_;
331 c = c_;
332 k = new Vector[s];
333}
334
336{
337 ODESolver::Init(f_);
338 int n = f->Width();
339 y.SetSize(n, mem_type);
340 for (int i = 0; i < s; i++)
341 {
342 k[i].SetSize(n, mem_type);
343 }
344}
345
347{
348 // 0 |
349 // c[0] | a[0]
350 // c[1] | a[1] a[2]
351 // ... | ...
352 // c[s-2] | ... a[s(s-1)/2-1]
353 // --------+---------------------
354 // | b[0] b[1] ... b[s-1]
355
356 f->SetTime(t);
357 f->Mult(x, k[0]);
358 for (int l = 0, i = 1; i < s; i++)
359 {
360 add(x, a[l++]*dt, k[0], y);
361 for (int j = 1; j < i; j++)
362 {
363 y.Add(a[l++]*dt, k[j]);
364 }
365
366 f->SetTime(t + c[i-1]*dt);
367 f->Mult(y, k[i]);
368 }
369 for (int i = 0; i < s; i++)
370 {
371 x.Add(b[i]*dt, k[i]);
372 }
373 t += dt;
374}
375
377{
378 delete [] k;
379}
380
381const real_t RK6Solver::a[] =
382{
383 .6e-1,
384 .1923996296296296296296296296296296296296e-1,
385 .7669337037037037037037037037037037037037e-1,
386 .35975e-1,
387 0.,
388 .107925,
389 1.318683415233148260919747276431735612861,
390 0.,
391 -5.042058063628562225427761634715637693344,
392 4.220674648395413964508014358283902080483,
393 -41.87259166432751461803757780644346812905,
394 0.,
395 159.4325621631374917700365669070346830453,
396 -122.1192135650100309202516203389242140663,
397 5.531743066200053768252631238332999150076,
398 -54.43015693531650433250642051294142461271,
399 0.,
400 207.0672513650184644273657173866509835987,
401 -158.6108137845899991828742424365058599469,
402 6.991816585950242321992597280791793907096,
403 -.1859723106220323397765171799549294623692e-1,
404 -54.66374178728197680241215648050386959351,
405 0.,
406 207.9528062553893734515824816699834244238,
407 -159.2889574744995071508959805871426654216,
408 7.018743740796944434698170760964252490817,
409 -.1833878590504572306472782005141738268361e-1,
410 -.5119484997882099077875432497245168395840e-3
411};
412const real_t RK6Solver::b[] =
413{
414 .3438957868357036009278820124728322386520e-1,
415 0.,
416 0.,
417 .2582624555633503404659558098586120858767,
418 .4209371189673537150642551514069801967032,
419 4.405396469669310170148836816197095664891,
420 -176.4831190242986576151740942499002125029,
421 172.3641334014150730294022582711902413315
422};
423const real_t RK6Solver::c[] =
424{
425 .6e-1,
426 .9593333333333333333333333333333333333333e-1,
427 .1439,
428 .4973,
429 .9725,
430 .9995,
431 1.,
432};
433
434const real_t RK8Solver::a[] =
435{
436 .5e-1,
437 -.69931640625e-2,
438 .1135556640625,
439 .399609375e-1,
440 0.,
441 .1198828125,
442 .3613975628004575124052940721184028345129,
443 0.,
444 -1.341524066700492771819987788202715834917,
445 1.370126503900035259414693716084313000404,
446 .490472027972027972027972027972027972028e-1,
447 0.,
448 0.,
449 .2350972042214404739862988335493427143122,
450 .180855592981356728810903963653454488485,
451 .6169289044289044289044289044289044289044e-1,
452 0.,
453 0.,
454 .1123656831464027662262557035130015442303,
455 -.3885046071451366767049048108111244567456e-1,
456 .1979188712522045855379188712522045855379e-1,
457 -1.767630240222326875735597119572145586714,
458 0.,
459 0.,
460 -62.5,
461 -6.061889377376669100821361459659331999758,
462 5.650823198222763138561298030600840174201,
463 65.62169641937623283799566054863063741227,
464 -1.180945066554970799825116282628297957882,
465 0.,
466 0.,
467 -41.50473441114320841606641502701994225874,
468 -4.434438319103725011225169229846100211776,
469 4.260408188586133024812193710744693240761,
470 43.75364022446171584987676829438379303004,
471 .787142548991231068744647504422630755086e-2,
472 -1.281405999441488405459510291182054246266,
473 0.,
474 0.,
475 -45.04713996013986630220754257136007322267,
476 -4.731362069449576477311464265491282810943,
477 4.514967016593807841185851584597240996214,
478 47.44909557172985134869022392235929015114,
479 .1059228297111661135687393955516542875228e-1,
480 -.5746842263844616254432318478286296232021e-2,
481 -1.724470134262485191756709817484481861731,
482 0.,
483 0.,
484 -60.92349008483054016518434619253765246063,
485 -5.95151837622239245520283276706185486829,
486 5.556523730698456235979791650843592496839,
487 63.98301198033305336837536378635995939281,
488 .1464202825041496159275921391759452676003e-1,
489 .6460408772358203603621865144977650714892e-1,
490 -.7930323169008878984024452548693373291447e-1,
491 -3.301622667747079016353994789790983625569,
492 0.,
493 0.,
494 -118.011272359752508566692330395789886851,
495 -10.14142238845611248642783916034510897595,
496 9.139311332232057923544012273556827000619,
497 123.3759428284042683684847180986501894364,
498 4.623244378874580474839807625067630924792,
499 -3.383277738068201923652550971536811240814,
500 4.527592100324618189451265339351129035325,
501 -5.828495485811622963193088019162985703755
502};
503const real_t RK8Solver::b[] =
504{
505 .4427989419007951074716746668098518862111e-1,
506 0.,
507 0.,
508 0.,
509 0.,
510 .3541049391724448744815552028733568354121,
511 .2479692154956437828667629415370663023884,
512 -15.69420203883808405099207034271191213468,
513 25.08406496555856261343930031237186278518,
514 -31.73836778626027646833156112007297739997,
515 22.93828327398878395231483560344797018313,
516 -.2361324633071542145259900641263517600737
517};
518const real_t RK8Solver::c[] =
519{
520 .5e-1,
521 .1065625,
522 .15984375,
523 .39,
524 .465,
525 .155,
526 .943,
527 .901802041735856958259707940678372149956,
528 .909,
529 .94,
530 1.,
531};
532
533
535 stages(s_), state(s_)
536{
537 a = a_;
538}
539
541{
542 ODESolver::Init(f_);
543 if (RKsolver) { RKsolver->Init(f_); }
544 state.SetSize(f->Width(), mem_type);
545 dt_ = -1.0;
546}
547
549{
550 CheckTimestep(dt);
551
552 if (state.Size() >= stages -1)
553 {
554 f->SetTime(t);
555 f->Mult(x, state[0]);
556 state.Increment();
557 for (int i = 0; i < stages; i++)
558 {
559 x.Add(a[i]*dt, state[i]);
560 }
561 t += dt;
562 }
563 else
564 {
565 f->Mult(x,state[0]);
566 RKsolver->Step(x,t,dt);
567 state.Increment();
568 }
569
570 state.ShiftStages();
571}
572
574{
575 if (dt_ < 0.0)
576 {
577 dt_ = dt;
578 return;
579 }
580 else if (fabs(dt-dt_) >10*std::numeric_limits<real_t>::epsilon())
581 {
582 state.Reset();
583 dt_ = dt;
584
585 if (print())
586 {
587 mfem::out << "WARNING:" << std::endl;
588 mfem::out << " - Time step changed" << std::endl;
589 mfem::out << " - Purging time stepping history" << std::endl;
590 mfem::out << " - Will run Runge-Kutta to rebuild history" << std::endl;
591 }
592 }
593}
594
595const real_t AB1Solver::a[] =
596{1.0};
597const real_t AB2Solver::a[] =
598{1.5,-0.5};
599const real_t AB3Solver::a[] =
600{23.0/12.0,-4.0/3.0, 5.0/12.0};
601const real_t AB4Solver::a[] =
602{55.0/24.0,-59.0/24.0, 37.0/24.0,-9.0/24.0};
603const real_t AB5Solver::a[] =
604{1901.0/720.0,-2774.0/720.0, 2616.0/720.0,-1274.0/720.0, 251.0/720.0};
605
606
608 stages(s_), state(s_)
609{
610 a = a_;
611}
612
614{
615 ODESolver::Init(f_);
616 if (RKsolver) { RKsolver->Init(f_); }
617 state.SetSize(f->Width(), mem_type);
618 dt_ = -1.0;
619}
620
622{
623 if (dt_ < 0.0)
624 {
625 dt_ = dt;
626 }
627 else if (fabs(dt-dt_) > 10*std::numeric_limits<real_t>::epsilon())
628 {
629 state.Reset();
630 dt_ = dt;
631
632 if (print())
633 {
634 mfem::out << "WARNING:" << std::endl;
635 mfem::out << " - Time step changed" << std::endl;
636 mfem::out << " - Purging time stepping history" << std::endl;
637 mfem::out << " - Will run Runge-Kutta to rebuild history" << std::endl;
638 }
639 }
640
641 if ((state.Size() == 0)&&(stages>1))
642 {
643 f->Mult(x,state[0]);
644 state.Increment();
645 }
646
647 if (state.Size() >= stages )
648 {
649 f->SetTime(t);
650 for (int i = 0; i < stages; i++)
651 {
652 x.Add(a[i+1]*dt, state[i]);
653 }
654 state.ShiftStages();
655 f->ImplicitSolve(a[0]*dt, x, state[0]);
657 {
658 ComputeSlopeFromState(a[0]*dt, x, state[0]);
659 }
660 x.Add(a[0]*dt, state[0]);
661 t += dt;
662 }
663 else
664 {
665 state.ShiftStages();
666 RKsolver->Step(x,t,dt);
667 f->Mult(x,state[0]);
668 state.Increment();
669 }
670}
671
672const real_t AM1Solver::a[] =
673{0.5, 0.5};
674const real_t AM2Solver::a[] =
675{5.0/12.0, 2.0/3.0, -1.0/12.0};
676const real_t AM3Solver::a[] =
677{3.0/8.0, 19.0/24.0,-5.0/24.0, 1.0/24.0};
678const real_t AM4Solver::a[] =
679{251.0/720.0,646.0/720.0,-264.0/720.0, 106.0/720.0, -19.0/720.0};
680
681
687
689{
690 f->SetTime(t + dt);
691 f->ImplicitSolve(dt, x, k); // solve for k: k = f(x + dt*k, t + dt)
693 {
694 x = k; // x = u_{i+1}
695 }
696 else
697 {
698 x.Add(dt, k);
699 }
700
701 t += dt;
702}
703
704
710
712{
713 f->SetTime(t + dt/2);
714 f->ImplicitSolve(dt/2, x, k);
716 {
717 x.Neg();
718 x.Add(2.0, k);
719 }
720 else
721 {
722 x.Add(dt, k);
723 }
724
725 t += dt;
726}
727
728
730{
731 if (gamma_opt == 0)
732 {
733 gamma = (3. - sqrt(3.))/6.; // not A-stable, order 3
734 }
735 else if (gamma_opt == 2)
736 {
737 gamma = (2. - sqrt(2.))/2.; // L-stable, order 2
738 }
739 else if (gamma_opt == 3)
740 {
741 gamma = (2. + sqrt(2.))/2.; // L-stable, order 2
742 }
743 else
744 {
745 gamma = (3. + sqrt(3.))/6.; // A-stable, order 3
746 }
747}
748
755
757{
758 // with a = gamma:
759 // a | a
760 // 1-a | 1-2a a
761 // ------+-----------
762 // | 1/2 1/2
763 // note: with gamma_opt=3, both solve are outside [t,t+dt] since a>1
764 f->SetTime(t + gamma*dt);
765 f->ImplicitSolve(gamma*dt, x, k);
767 {
769 }
770 add(x, (1.-2.*gamma)*dt, k, y); // y = x + (1-2*gamma)*dt*k
771 x.Add(dt/2, k);
772
773 f->SetTime(t + (1.-gamma)*dt);
774 f->ImplicitSolve(gamma*dt, y, k);
776 {
778 }
779 x.Add(dt/2, k);
780 t += dt;
781}
782
783
791
793{
794 // a | a
795 // 1/2 | 1/2-a a
796 // 1-a | 2a 1-4a a
797 // ------+--------------------
798 // | b 1-2b b
799 // note: two solves are outside [t,t+dt] since c1=a>1, c3=1-a<0
800 const real_t a = 1./sqrt(3.)*cos(M_PI/18.) + 0.5;
801 const real_t b = 1./(6.*(2.*a-1.)*(2.*a-1.));
802
803 f->SetTime(t + a*dt);
804 f->ImplicitSolve(a*dt, x, k);
806 {
807 ComputeSlopeFromState(a*dt, x, k);
808 }
809 add(x, (0.5-a)*dt, k, y);
810 add(x, (2.*a)*dt, k, z);
811 x.Add(b*dt, k);
812
813 f->SetTime(t + dt/2);
814 f->ImplicitSolve(a*dt, y, k);
816 {
818 }
819 z.Add((1.-4.*a)*dt, k);
820 x.Add((1.-2.*b)*dt, k);
821
822 f->SetTime(t + (1.-a)*dt);
823 f->ImplicitSolve(a*dt, z, k);
825 {
827 }
828 x.Add(b*dt, k);
829 t += dt;
830}
831
832
839
841{
842 // a | a
843 // c | c-a a
844 // 1 | b 1-a-b a
845 // -----+----------------
846 // | b 1-a-b a
847 const real_t a = 0.435866521508458999416019;
848 const real_t b = 1.20849664917601007033648;
849 const real_t c = 0.717933260754229499708010;
850
851 f->SetTime(t + a*dt);
852 f->ImplicitSolve(a*dt, x, k);
854 {
855 ComputeSlopeFromState(a*dt, x, k);
856 }
857 add(x, (c-a)*dt, k, y);
858 x.Add(b*dt, k);
859
860 f->SetTime(t + c*dt);
861 f->ImplicitSolve(a*dt, y, k);
863 {
865 }
866 x.Add((1.0-a-b)*dt, k);
867
868 f->SetTime(t + dt);
869 f->ImplicitSolve(a*dt, x, k);
871 {
872 ComputeSlopeFromState(a*dt, x, k);
873 }
874 x.Add(a*dt, k);
875 t += dt;
876}
877
884
886{
887 // 0 | 0 0
888 // 1 | 1/2 1/2
889 // ------+-----------
890 // | 1/2 1/2
891 f->SetTime(t);
892 f->Mult(x,k);
893 add(x, dt/2.0, k, y);
894 x.Add(dt/2.0, k);
895
896 f->SetTime(t + dt);
897 f->ImplicitSolve(dt/2.0, y, k);
899 {
900 ComputeSlopeFromState(0.5*dt, y, k);
901 }
902 x.Add(dt/2.0, k);
903 t += dt;
904}
905
913
915{
916 // 0 | 0 0 0
917 // 2a | a a 0
918 // 1 | 1-b-a b a
919 // ------+--------------------
920 // | 1-b-a b a
921 const real_t a = (2.0 - sqrt(2.0)) / 2.0;
922 const real_t b = (1.0 - 2.0*a) / (4.0*a);
923
924 f->SetTime(t);
925 f->Mult(x,k);
926 add(x, a*dt, k, y);
927 add(x, (1.0-b-a)*dt, k, z);
928 x.Add((1.0-b-a)*dt, k);
929
930 f->SetTime(t + (2.0*a)*dt);
931 f->ImplicitSolve(a*dt, y, k);
933 {
935 }
936 z.Add(b*dt, k);
937 x.Add(b*dt, k);
938
939 f->SetTime(t + dt);
940 f->ImplicitSolve(a*dt, z, k);
942 {
944 }
945 x.Add(a*dt, k);
946 t += dt;
947}
948
956
958{
959 // 0 | 0 0 0
960 // 2a | a a 0
961 // 1 | 1-b-a b a
962 // ------+----------------------------
963 // | 1-b_2-b_3 b_2 b_3
964 const real_t a = (3.0 + sqrt(3.0)) / 6.0;
965 const real_t b = (1.0 - 2.0*a) / (4.0*a);
966 const real_t b_2 = 1.0 / ( 12.0*a*(1.0 - 2.0*a) );
967 const real_t b_3 = (1.0 - 3.0*a) / ( 3.0*(1.0 - 2.0*a) );
968
969 f->SetTime(t);
970 f->Mult(x,k);
971 add(x, a*dt, k, y);
972 add(x, (1.0-b-a)*dt, k, z);
973 x.Add((1.0-b_2-b_3)*dt, k);
974
975 f->SetTime(t + (2.0*a)*dt);
976 f->ImplicitSolve(a*dt, y, k);
978 {
980 }
981 z.Add(b*dt, k);
982 x.Add(b_2*dt, k);
983
984 f->SetTime(t + dt);
985 f->ImplicitSolve(a*dt, z, k);
987 {
989 }
990 x.Add(b_3*dt, k);
991 t += dt;
992}
993
1001
1003{
1004 rho_inf = (rho_inf > 1.0) ? 1.0 : rho_inf;
1005 rho_inf = (rho_inf < 0.0) ? 0.0 : rho_inf;
1006
1007 // According to Jansen
1008 alpha_m = 0.5*(3.0 - rho_inf)/(1.0 + rho_inf);
1009 alpha_f = 1.0/(1.0 + rho_inf);
1010 gamma = 0.5 + alpha_m - alpha_f;
1011}
1012
1014{
1015 os << "Generalized alpha time integrator:" << std::endl;
1016 os << "alpha_m = " << alpha_m << std::endl;
1017 os << "alpha_f = " << alpha_f << std::endl;
1018 os << "gamma = " << gamma << std::endl;
1019
1020 if (gamma == 0.5 + alpha_m - alpha_f)
1021 {
1022 os<<"Second order"<<" and ";
1023 }
1024 else
1025 {
1026 os<<"First order"<<" and ";
1027 }
1028
1029 if ((alpha_m >= alpha_f)&&(alpha_f >= 0.5))
1030 {
1031 os<<"Stable"<<std::endl;
1032 }
1033 else
1034 {
1035 os<<"Unstable"<<std::endl;
1036 }
1037}
1038
1039// This routine state[0] represents xdot
1041{
1042 if (state.Size() == 0)
1043 {
1044 f->Mult(x,state[0]);
1045 state.Increment();
1046 }
1047
1048 // Set y = x + alpha_f*(1.0 - (gamma/alpha_m))*dt*xdot
1049 add(x, alpha_f*(1.0 - (gamma/alpha_m))*dt, state[0], y);
1050
1051 // Solve k = f(y + dt_eff*k)
1052 real_t dt_eff = (gamma*alpha_f/alpha_m)*dt;
1053 f->SetTime(t + alpha_f*dt);
1054 f->ImplicitSolve(dt_eff, y, k);
1056 {
1057 ComputeSlopeFromState(dt_eff, y, k);
1058 }
1059
1060 // Update x and xdot
1061 x.Add((1.0 - (gamma/alpha_m))*dt, state[0]);
1062 x.Add( (gamma/alpha_m) *dt, k);
1063
1064 state[0] *= (1.0-(1.0/alpha_m));
1065 state[0].Add((1.0/alpha_m),k);
1066
1067 t += dt;
1068}
1069
1070
1071void
1073{
1074 P_ = &P; F_ = &F;
1075
1076 dp_.SetSize(F_->Height());
1077 dq_.SetSize(P_->Height());
1078}
1079
1080void
1082{
1083 F_->SetTime(t);
1084 F_->Mult(q,dp_);
1085 p.Add(dt,dp_);
1086
1087 P_->Mult(p,dq_);
1088 q.Add(dt,dq_);
1089
1090 t += dt;
1091}
1092
1093void
1095{
1096 P_->Mult(p,dq_);
1097 q.Add(0.5*dt,dq_);
1098
1099 F_->SetTime(t+0.5*dt);
1100 F_->Mult(q,dp_);
1101 p.Add(dt,dp_);
1102
1103 P_->Mult(p,dq_);
1104 q.Add(0.5*dt,dq_);
1105
1106 t += dt;
1107}
1108
1110 : order_(order)
1111{
1112 a_.SetSize(order);
1113 b_.SetSize(order);
1114
1115 switch (order_)
1116 {
1117 case 1:
1118 a_[0] = 1.0;
1119 b_[0] = 1.0;
1120 break;
1121 case 2:
1122 a_[0] = 0.5;
1123 a_[1] = 0.5;
1124 b_[0] = 0.0;
1125 b_[1] = 1.0;
1126 break;
1127 case 3:
1128 a_[0] = 2.0/3.0;
1129 a_[1] = -2.0/3.0;
1130 a_[2] = 1.0;
1131 b_[0] = 7.0/24.0;
1132 b_[1] = 0.75;
1133 b_[2] = -1.0/24.0;
1134 break;
1135 case 4:
1136 a_[0] = (2.0+pow(2.0,1.0/3.0)+pow(2.0,-1.0/3.0))/6.0;
1137 a_[1] = (1.0-pow(2.0,1.0/3.0)-pow(2.0,-1.0/3.0))/6.0;
1138 a_[2] = a_[1];
1139 a_[3] = a_[0];
1140 b_[0] = 0.0;
1141 b_[1] = 1.0/(2.0-pow(2.0,1.0/3.0));
1142 b_[2] = 1.0/(1.0-pow(2.0,2.0/3.0));
1143 b_[3] = b_[1];
1144 break;
1145 default:
1146 MFEM_ASSERT(false, "Unsupported order in SIAVSolver");
1147 };
1148}
1149
1150void
1152{
1153 for (int i=0; i<order_; i++)
1154 {
1155 if ( b_[i] != 0.0 )
1156 {
1157 F_->SetTime(t);
1158 if ( F_->isExplicit() )
1159 {
1160 F_->Mult(q, dp_);
1161 }
1162 else
1163 {
1164 F_->ImplicitSolve(b_[i] * dt, q, dp_);
1165 }
1166 p.Add(b_[i] * dt, dp_);
1167 }
1168
1169 P_->Mult(p, dq_);
1170 q.Add(a_[i] * dt, dq_);
1171
1172 t += a_[i] * dt;
1173 }
1174}
1175
1176std::string SecondOrderODESolver::Types =
1177 "ODE solver: \n\t"
1178 " [0--10] - GeneralizedAlpha(0.1 * s),\n\t"
1179 " 11 - Average Acceleration, 12 - Linear Acceleration\n\t"
1180 " 13 - CentralDifference, 14 - FoxGoodwin";
1181
1183{
1184 SecondOrderODESolver* ode_solver = NULL;
1185 switch (ode_solver_type)
1186 {
1187 // Implicit methods
1188 case 0: ode_solver = new GeneralizedAlpha2Solver(0.0); break;
1189 case 1: ode_solver = new GeneralizedAlpha2Solver(0.1); break;
1190 case 2: ode_solver = new GeneralizedAlpha2Solver(0.2); break;
1191 case 3: ode_solver = new GeneralizedAlpha2Solver(0.3); break;
1192 case 4: ode_solver = new GeneralizedAlpha2Solver(0.4); break;
1193 case 5: ode_solver = new GeneralizedAlpha2Solver(0.5); break;
1194 case 6: ode_solver = new GeneralizedAlpha2Solver(0.6); break;
1195 case 7: ode_solver = new GeneralizedAlpha2Solver(0.7); break;
1196 case 8: ode_solver = new GeneralizedAlpha2Solver(0.8); break;
1197 case 9: ode_solver = new GeneralizedAlpha2Solver(0.9); break;
1198 case 10: ode_solver = new GeneralizedAlpha2Solver(1.0); break;
1199
1200 case 11: ode_solver = new AverageAccelerationSolver(); break;
1201 case 12: ode_solver = new LinearAccelerationSolver(); break;
1202 case 13: ode_solver = new CentralDifferenceSolver(); break;
1203 case 14: ode_solver = new FoxGoodwinSolver(); break;
1204
1205 default:
1206 MFEM_ABORT("Unknown ODE solver type: " << ode_solver_type);
1207 }
1208 return ode_solver;
1209}
1210
1211// In this routine state[0] represents d2xdt2
1213 real_t &dt)
1214{
1215 x.Add(dt, dxdt);
1216
1217 f->SetTime(t + dt);
1218 f->ImplicitSolve(0.5*dt*dt, dt, x, dxdt, state[0]);
1219
1220 x.Add(0.5*dt*dt, state[0]);
1221 dxdt.Add(dt, state[0]);
1222 t += dt;
1223}
1224
1225// In this routine state[0] represents d2xdt2
1227 real_t &dt)
1228{
1229 x.Add(0.5*dt, dxdt);
1230
1231 f->SetTime(t + dt);
1232 f->ImplicitSolve(0.25*dt*dt, 0.5*dt, x, dxdt, state[0]);
1233
1234 x.Add(0.5*dt, dxdt);
1235 x.Add(0.5*dt*dt, state[0]);
1236 dxdt.Add(dt, state[0]);
1237 t += dt;
1238}
1239
1246
1248{
1249 os << "Newmark time integrator:" << std::endl;
1250 os << "beta = " << beta << std::endl;
1251 os << "gamma = " << gamma << std::endl;
1252
1253 if (gamma == 0.5)
1254 {
1255 os<<"Second order"<<" and ";
1256 }
1257 else
1258 {
1259 os<<"First order"<<" and ";
1260 }
1261
1262 if ((gamma >= 0.5) && (beta >= (gamma + 0.5)*(gamma + 0.5)/4))
1263 {
1264 os<<"A-Stable"<<std::endl;
1265 }
1266 else if ((gamma >= 0.5) && (beta >= 0.5*gamma))
1267 {
1268 os<<"Conditionally stable"<<std::endl;
1269 }
1270 else
1271 {
1272 os<<"Unstable"<<std::endl;
1273 }
1274}
1275
1276// In this routine state[0] represents d2xdt2
1278{
1279 real_t fac0 = 0.5 - beta;
1280 real_t fac2 = 1.0 - gamma;
1281 real_t fac3 = beta;
1282 real_t fac4 = gamma;
1283
1284 // In the first pass compute d2xdt2 directly from operator.
1285 if (state.Size() == 0)
1286 {
1287 if (no_mult)
1288 {
1289 MidPointStep(x, dxdt, t, dt);
1290 return;
1291 }
1292 else
1293 {
1294 f->Mult(x, dxdt, state[0]);
1295 }
1296 state.Increment();
1297 }
1298 f->SetTime(t + dt);
1299
1300 x.Add(dt, dxdt);
1301 x.Add(fac0*dt*dt, state[0]);
1302 dxdt.Add(fac2*dt, state[0]);
1303
1304 f->SetTime(t + dt);
1305 f->ImplicitSolve(fac3*dt*dt, fac4*dt, x, dxdt, state[0]);
1306
1307 x.Add(fac3*dt*dt, state[0]);
1308 dxdt.Add(fac4*dt, state[0]);
1309 t += dt;
1310}
1311
1319
1321{
1322 os << "Generalized alpha time integrator:" << std::endl;
1323 os << "alpha_m = " << alpha_m << std::endl;
1324 os << "alpha_f = " << alpha_f << std::endl;
1325 os << "beta = " << beta << std::endl;
1326 os << "gamma = " << gamma << std::endl;
1327
1328 if (gamma == 0.5 + alpha_m - alpha_f)
1329 {
1330 os<<"Second order"<<" and ";
1331 }
1332 else
1333 {
1334 os<<"First order"<<" and ";
1335 }
1336
1337 if ((alpha_m >= alpha_f)&&
1338 (alpha_f >= 0.5) &&
1339 (beta >= 0.25 + 0.5*(alpha_m - alpha_f)))
1340 {
1341 os<<"Stable"<<std::endl;
1342 }
1343 else
1344 {
1345 os<<"Unstable"<<std::endl;
1346 }
1347}
1348
1349// In this routine state[0] represents d2xdt2
1351 real_t &t, real_t &dt)
1352{
1353 real_t fac0 = (0.5 - (beta/alpha_m));
1354 real_t fac1 = alpha_f;
1355 real_t fac2 = alpha_f*(1.0 - (gamma/alpha_m));
1356 real_t fac3 = beta*alpha_f/alpha_m;
1357 real_t fac4 = gamma*alpha_f/alpha_m;
1358 real_t fac5 = alpha_m;
1359
1360 // In the first pass compute d2xdt2 directly from operator.
1361 if (state.Size() == 0)
1362 {
1363 if (no_mult)
1364 {
1365 MidPointStep(x, dxdt, t, dt);
1366 return;
1367 }
1368 else
1369 {
1370 f->Mult(x, dxdt, state[0]);
1371 }
1372 state.Increment();
1373 }
1374
1375 // Predict alpha levels
1376 add(dxdt, fac0*dt, state[0], va);
1377 add(x, fac1*dt, va, xa);
1378 add(dxdt, fac2*dt, state[0], va);
1379
1380 // Solve alpha levels
1381 f->SetTime(t + dt);
1382 f->ImplicitSolve(fac3*dt*dt, fac4*dt, xa, va, aa);
1383
1384 // Correct alpha levels
1385 xa.Add(fac3*dt*dt, aa);
1386 va.Add(fac4*dt, aa);
1387
1388 // Extrapolate
1389 x *= 1.0 - 1.0/fac1;
1390 x.Add (1.0/fac1, xa);
1391
1392 dxdt *= 1.0 - 1.0/fac1;
1393 dxdt.Add (1.0/fac1, va);
1394
1395 state[0] *= 1.0 - 1.0/fac5;
1396 state[0].Add (1.0/fac5, aa);
1397
1398 t += dt;
1399}
1400
1402{
1403 ODESolver::Init(f_);
1404 int n = f->Width();
1405 k1.SetSize(n, mem_type);
1406 k2.SetSize(n, mem_type);
1407}
1408
1410{
1411 f->SetTime(t);
1413 f->Mult(x, k1);
1414
1415 f->SetTime(t+dt);
1417 f->ImplicitSolve(dt, x, k2);
1418
1419 f->SetTime(t);
1420 x.Add(dt, k1);
1421 x.Add(dt, k2);
1422 t += dt;
1423}
1424
1426{
1427 ODESolver::Init(f_);
1428 int n = f->Width();
1429 k1_exp.SetSize(n, mem_type);
1430 k2_exp.SetSize(n, mem_type);
1431 k_imp.SetSize(n, mem_type);
1432 y.SetSize(n, mem_type);
1433}
1434
1436{
1437 double gamma = 1 - sqrt(2)/2;
1438 double delta = 1 - 1/(2*gamma);
1439
1440 f->SetTime(t);
1441
1442 //K1 exp is just f_1(t, x)
1444 f->Mult(x, k1_exp);
1445
1446 //K2 exp is f_1(t + gamma dt, x + dt gamma K1)
1447 f->SetTime(t + gamma*dt);
1448 add(x, dt*gamma, k1_exp, y);
1450 f->Mult(y, k2_exp);
1451
1452 //K2_imp = f_2(t + gamma dt, x + dt gamma K2_imp)
1454 f->ImplicitSolve(dt*gamma, x, k_imp);
1455 //reuse k_imp to avoid extra vector
1456
1457 //K3_imp = f_2(t+dt,x + dt(1-gamma)K2_imp + dt gamma K3_imp)
1458 f -> SetTime(t + dt);
1459 //add(x, dt*(1-gamma), k2_imp, z);
1460 //optimization to avoid extra vector
1461 x.Add(dt*(1-gamma), k_imp);
1463 //f->ImplicitSolve(dt*gamma, z, k3_imp);
1464 //reuse k_imp to avoid extra vector
1465 f->ImplicitSolve(dt*gamma, x, k_imp);
1466
1467 //add it all up
1468 x.Add(dt*delta, k1_exp);
1469 x.Add(dt*(1-delta), k2_exp);
1470 //x.Add(dt*(1-gamma), k2_imp); it is already added to x above
1471 x.Add(dt*gamma, k_imp);
1472 t += dt;
1473}
1474
1476{
1477 ODESolver::Init(f_);
1478 int n = f->Width();
1479 k1_exp.SetSize(n, mem_type);
1480 k2_exp.SetSize(n, mem_type);
1481 k3_exp.SetSize(n, mem_type);
1482 k_imp.SetSize(n, mem_type);
1483 y.SetSize(n, mem_type);
1484}
1485
1487{
1488 double gamma = 1 - sqrt(2)/2;
1489 double delta = -2*sqrt(2)/3;
1490
1491 f->SetTime(t);
1492
1493 //K1 exp is just f_1(t, x)
1495 f->Mult(x, k1_exp);
1496
1497 //K2 exp is f_1(t + gamma dt, x + dt gamma K1)
1498 f->SetTime(t + gamma*dt);
1499 add(x, dt*gamma, k1_exp, y);
1501 f->Mult(y, k2_exp);
1502
1503 //K3 Exp is f_1(t + dt, x + dt delta K1_exp + dt (1-delta) K2_exp)
1504 f->SetTime(t + dt);
1505 add(x, dt*delta, k1_exp, y);
1506 //add(y, dt*(1-delta), k2_exp, w);
1507 //optimization to avoid extra vector
1508 y.Add(dt*(1-delta), k2_exp);
1510 f->Mult(y, k3_exp);
1511
1512 //K2_imp = f_2(t + gamma dt, x + dt gamma K2_imp)
1513 f->SetTime(t + gamma*dt);
1515 f->ImplicitSolve(dt*gamma, x, k_imp);
1516
1517 //K3_imp = f_2(t+dt,x + dt(1-gamma)K2_imp + dt gamma K3_imp)
1518 f -> SetTime(t + dt);
1519 //add(x, dt*(1-gamma), k2_imp, z);
1520 x.Add(dt*(1-gamma), k_imp);
1522 f->ImplicitSolve(dt*gamma, x, k_imp);
1523
1524 //add it all up
1525 x.Add(dt*delta, k2_exp);
1526 x.Add(dt*(1-delta), k3_exp);
1527 //x.Add(dt*(1-gamma), k2_imp); // it is already added to x above
1528 x.Add(dt*gamma, k_imp);
1529 t += dt;
1530}
1531
1533{
1534 ODESolver::Init(f_);
1535 int n = f->Width();
1536 k1_exp.SetSize(n, mem_type);
1537 k2_exp.SetSize(n, mem_type);
1538 k3_exp.SetSize(n, mem_type);
1539 k4_exp.SetSize(n, mem_type);
1540 k2_imp.SetSize(n, mem_type);
1541 k3_imp.SetSize(n, mem_type);
1542 y.SetSize(n, mem_type);
1543}
1544
1546{
1547 double gamma = 0.4358665215;
1548 double b1 = 1.208496649;
1549 double b2 = -0.644363171;
1550 double a_31 = 0.3212788860;
1551 double a_32 = 0.3966543747;
1552 double a_41 = -0.105858296;
1553 double a_42 = 0.5529291479;
1554 double a_43 = 0.5529291479;
1555
1556 //K1_exp
1557 f->SetTime(t);
1559 f->Mult(x, k1_exp);
1560
1561 //K2_imp, K2_exp
1562 f->SetTime(t + gamma*dt);
1563 add(x, dt*gamma, k1_exp, y);
1565 f->Mult(y, k2_exp);
1567 f->ImplicitSolve(dt*gamma, x, k2_imp);
1568
1569 //K3_imp, K3_exp
1570 f->SetTime(t + (1+gamma)/2*dt);
1571 add(x, dt*a_31, k1_exp, y);
1572 //add(y, dt*a_32, k2_exp, w);
1573 //optimization to avoid extra vector
1574 y.Add(dt*a_32, k2_exp);
1576 f->Mult(y, k3_exp);
1577 add(x, dt*(1-gamma)/2, k2_imp, y);
1579 f->ImplicitSolve(dt*gamma, y, k3_imp);
1580
1581 //K4_imp, K4_exp
1582 f->SetTime(t+dt);
1583 add(x, dt*a_41, k1_exp, y);
1584 //add(y, dt*a_42, k2_exp, v);
1585 y.Add(dt*a_42, k2_exp);
1586 //add(w, dt*a_43, k3_exp, v);
1587 y.Add(dt*a_43, k3_exp);
1589 f->Mult(y, k4_exp);
1590 //add(x, dt*b1, k2_imp, z);
1591 //add(z, dt*b2, k3_imp, u);
1592 //optimization to avoid extra vector
1593 x.Add(dt*b1, k2_imp);
1594 x.Add(dt*b2, k3_imp);
1596 f->ImplicitSolve(dt*gamma, x, k3_imp);
1597
1598 //add it all together
1599 x.Add(dt*b1, k2_exp);
1600 x.Add(dt*b2, k3_exp);
1601 x.Add(dt*gamma, k4_exp);
1602 //x.Add(dt*b1, k2_imp); //already added above
1603 //x.Add(dt*b2, k3_imp); //already added above
1604 x.Add(dt*gamma, k3_imp);
1605 t += dt;
1606
1607}
1608
1609}
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:540
void CheckTimestep(real_t dt)
Definition ode.cpp:573
AdamsBashforthSolver(int s_, const real_t *a_)
Definition ode.cpp:534
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:548
std::unique_ptr< ODESolver > RKsolver
Definition ode.hpp:596
std::unique_ptr< ODESolver > RKsolver
Definition ode.hpp:679
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:621
AdamsMoultonSolver(int s_, const real_t *a_)
Definition ode.cpp:607
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:613
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:869
void Print(std::ostream &out=mfem::out, int width=4) const
Prints array to stream with width elements per row.
Definition array.cpp:24
The classical midpoint method.
Definition ode.hpp:994
Backward Euler ODE solver. L-stable.
Definition ode.hpp:392
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:682
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:688
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:906
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:914
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:949
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:957
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:346
virtual ~ExplicitRKSolver()
Definition ode.cpp:376
ExplicitRKSolver(int s_, const real_t *a_, const real_t *b_, const real_t *c_)
Definition ode.cpp:325
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:335
The classical forward Euler method.
Definition ode.hpp:281
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:217
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:211
void PrintProperties(std::ostream &os=mfem::out)
Definition ode.cpp:1320
void Init(SecondOrderTimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:1312
void Step(Vector &x, Vector &dxdt, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:1350
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:994
void SetRhoInf(real_t rho_inf)
Definition ode.cpp:1002
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:1040
void PrintProperties(std::ostream &os=mfem::out)
Definition ode.cpp:1013
Forward-backward Euler method.
Definition ode.hpp:1050
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:1401
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:1409
Second order, 2/3-stage implicit-explicit (IMEX) Runge-Kutta (RK) method.
Definition ode.hpp:1088
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:1475
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:1486
Second order, two-stage implicit-explicit (IMEX) Runge-Kutta (RK) method.
Definition ode.hpp:1069
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:1425
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:1435
Third order, 3/4-stage implicit-explicit (IMEX) Runge-Kutta (RK) method.
Definition ode.hpp:1108
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:1532
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:1545
Implicit midpoint method. A-stable, not L-stable.
Definition ode.hpp:411
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:711
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:705
void Step(Vector &x, Vector &dxdt, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:1277
void PrintProperties(std::ostream &os=mfem::out)
Definition ode.cpp:1247
TimeDependentOperator * f
Pointer to the associated TimeDependentOperator.
Definition ode.hpp:125
virtual void Init(TimeDependentOperator &f_)
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:182
static MFEM_EXPORT std::unique_ptr< ODESolver > SelectImplicit(const int ode_solver_type)
Definition ode.cpp:77
static MFEM_EXPORT std::string Types
Definition ode.hpp:235
static MFEM_EXPORT std::unique_ptr< ODESolver > Select(const int ode_solver_type)
Definition ode.cpp:41
virtual void ComputeSlopeFromState(const real_t dt, const Vector &u, Vector &k)
Compute the finite-difference slope, , and store it in k.
Definition ode.cpp:194
MemoryType mem_type
Definition ode.hpp:126
virtual bool SupportsImplicitVariableType(ImplicitVariableType var) const
Returns true if the ODESolver supports the given ImplicitVariableType, var, and returns false otherwi...
Definition ode.hpp:201
static MFEM_EXPORT std::string ImplicitTypes
Definition ode.hpp:233
static MFEM_EXPORT std::unique_ptr< ODESolver > SelectIMEX(const int ode_solver_type)
Definition ode.cpp:116
static MFEM_EXPORT std::string ExplicitTypes
Definition ode.hpp:232
static MFEM_EXPORT std::unique_ptr< ODESolver > SelectExplicit(const int ode_solver_type)
Definition ode.cpp:53
static MFEM_EXPORT std::string IMEXTypes
Definition ode.hpp:234
void Increment()
Increment the stage counter.
Definition ode.hpp:80
const Vector & Get(int i) const override
Get the ith state vector.
Definition ode.cpp:143
void Set(int i, Vector &state) override
Set the ith state vector.
Definition ode.cpp:161
void SetSize(int vsize, MemoryType mem_type)
Set the number of stages and the size of the vectors.
Definition ode.cpp:131
void Append(Vector &state) override
Add state vector and increment state size.
Definition ode.cpp:167
void ShiftStages()
Shift the stage counter for the next timestep.
Definition ode.hpp:74
void Print(std::ostream &os=mfem::out) const
Print state data.
Definition ode.cpp:174
int Size() const override
Get the current number of stored stages.
Definition ode.hpp:96
void Reset()
Reset the stage counter.
Definition ode.hpp:83
Abstract operator.
Definition operator.hpp:27
virtual MemoryClass GetMemoryClass() const
Return the MemoryClass preferred by the Operator.
Definition operator.hpp:88
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition operator.hpp:68
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition operator.hpp:74
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:226
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:234
Third-order, strong stability preserving (SSP) Runge-Kutta method.
Definition ode.hpp:314
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:255
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:263
The classical explicit fourth-order Runge-Kutta method, RK4.
Definition ode.hpp:327
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:287
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:296
SDIRK23Solver(int gamma_opt=1)
Definition ode.cpp:729
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:756
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:749
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:840
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:833
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:792
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:784
void Step(Vector &q, Vector &p, real_t &t, real_t &dt) override
Definition ode.cpp:1081
void Step(Vector &q, Vector &p, real_t &t, real_t &dt) override
Definition ode.cpp:1094
TimeDependentOperator * F_
Definition ode.hpp:778
Vector dq_
Definition ode.hpp:782
Vector dp_
Definition ode.hpp:781
virtual void Init(Operator &P, TimeDependentOperator &F)
Definition ode.cpp:1072
Operator * P_
Definition ode.hpp:779
void Step(Vector &q, Vector &p, real_t &t, real_t &dt) override
Definition ode.cpp:1151
SIAVSolver(int order)
Definition ode.cpp:1109
Abstract class for solving systems of ODEs: d2x/dt2 = f(x,dx/dt,t)
Definition ode.hpp:819
SecondOrderTimeDependentOperator * f
Pointer to the associated TimeDependentOperator.
Definition ode.hpp:822
void MidPointStep(Vector &x, Vector &dxdt, real_t &t, real_t &dt)
Definition ode.cpp:1226
ODEStateDataVector state
Definition ode.hpp:824
static MFEM_EXPORT std::string Types
Help info for SecondOrderODESolver options.
Definition ode.hpp:910
void EulerStep(Vector &x, Vector &dxdt, real_t &t, real_t &dt)
Definition ode.cpp:1212
static MFEM_EXPORT SecondOrderODESolver * Select(const int ode_solver_type)
Function selecting the desired SecondOrderODESolver.
Definition ode.cpp:1182
virtual void Init(SecondOrderTimeDependentOperator &f)
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:1240
Base abstract class for second order time dependent operators.
Definition operator.hpp:807
virtual void Mult(const Vector &x, const Vector &dxdt, Vector &y) const
Perform the action of the operator: y = k = f(x,@ dxdt, t), where k solves the algebraic equation F(x...
Definition operator.cpp:367
virtual void ImplicitSolve(const real_t fac0, const real_t fac1, const Vector &x, const Vector &dxdt, Vector &k)
Solve the equation: k = f(x + fac0 k, dxdt + fac1 k, t), for the unknown k at the current time t.
Definition operator.cpp:374
Base abstract class for first order time dependent operators.
Definition operator.hpp:367
bool isExplicit() const
True if type is EXPLICIT.
Definition operator.hpp:445
virtual ImplicitVariableType GetImplicitVariableType() const
Returns the ImplicitVariableType for ImplicitSolve().
Definition operator.hpp:479
virtual void ImplicitSolve(const real_t gamma, const Vector &u, Vector &k)
Solve for the unknown k, at the current time t, the following equation:
Definition operator.cpp:313
virtual bool ImplicitVarTypeIsState() const
Returns true if implicit variable is STATE and false otherwise. Used by ODESolver to identify the sta...
Definition operator.hpp:484
void Mult(const Vector &u, Vector &k) const override
Perform the action of the operator (u,t) -> k(u,t) where t is the current time set by SetTime() and k...
Definition operator.cpp:308
virtual void SetEvalMode(const EvalMode new_eval_mode)
Set the evaluation mode of the time-dependent operator.
Definition operator.hpp:465
virtual void SetTime(const real_t t_)
Set the current time.
Definition operator.hpp:442
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:885
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:878
Vector data type.
Definition vector.hpp:82
void Neg()
(*this) = -(*this)
Definition vector.cpp:376
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:536
void SetSize(int s)
Resize the vector to size s.
Definition vector.hpp:633
Vector & Add(const real_t a, const Vector &Va)
(*this) += a * Va
Definition vector.cpp:326
real_t b
Definition lissajous.cpp:42
real_t delta
Definition lissajous.cpp:43
real_t a
Definition lissajous.cpp:41
mfem::real_t real_t
real_t u(const Vector &xvec)
Definition lor_mms.hpp:22
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition globals.hpp:66
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition vector.cpp:414
MemoryType GetMemoryType(MemoryClass mc)
Return a suitable MemoryType for a given MemoryClass.
float real_t
Definition config.hpp:46
MemoryType
Memory types supported by MFEM.
void forall(int N, lambda &&body)
Definition forall.hpp:1134
real_t p(const Vector &x, real_t t)