KASKADE 7 development version
sdc.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2012-2024 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef SDC_HH
14#define SDC_HH
15
16#include <boost/timer/timer.hpp>
17
18#include "dune/grid/config.h"
19#include "dune/istl/operators.hh"
20#include "dune/istl/solvers.hh"
21
22#include "dune/common/dynvector.hh"
23
25#include "utilities/timing.hh"
26
27#include <cassert>
28
29
30namespace Kaskade {
31
68 {
69 public:
73 typedef Dune::DynamicVector<double> RealVector;
74
79
87 virtual RealVector const& points() const = 0;
88
94 double point(int k) const
95 {
96 return points()[k];
97 }
98
118 virtual RealMatrix const& integrationMatrix() const = 0;
119
132 virtual RealMatrix const& differentiationMatrix() const = 0;
133
147 virtual void refine(RealMatrix& p) = 0;
148
156 virtual RealMatrix interpolate(RealVector const& x) const = 0;
157 };
158
159 // ---------------------------------------------------------------------------------------------------
160
170 {
171 public:
172
173 virtual RealVector const& points() const
174 {
175 return pts;
176 }
177
178 virtual RealMatrix const& integrationMatrix() const
179 {
180 return integ;
181 }
182
183 virtual RealMatrix const& differentiationMatrix() const
184 {
185 return diff;
186 }
187
188
189 protected:
193 };
194
195 // ---------------------------------------------------------------------------------------------------
196
221
234
255
268
286
309
311
312
313// /**
314// * \ingroup sdc
315// * \brief Types of weight functions for optimized integration matrices.
316// */
317// enum IntegrationMatrixOptimizationWeight
318// {
319// /// optimization for a contraction factor uniform on the real spectrum
320// OW_FLAT,
321// /// optimization for a contraction factor uniform on the real negative spectrum, but for SDIRK
322// OW_FLAT_SDIRK
323// };
324//
325// /**
326// * \ingroup sdc
327// * \brief Triangular approximate differentiation and integration matrix \f$ \hat D, \hat S \f$ corresponding to specialized multi-step integrators
328// *
329// * \param grid the collocation time grid
330// * \param k the sweep number
331// * \param w the type of weight function for the optimization
332// *
333// * This returns one of a set of precomputed, optimized integration matrices, if available for the given grid.
334// * If no precomputed matrix is available, a lookup exception is thrown.
335// */
336// std::pair<SDCTimeGrid::RealMatrix,SDCTimeGrid::RealMatrix>
337// optimizedMatrices(SDCTimeGrid const& grid, int k, IntegrationMatrixOptimizationWeight w=OW_FLAT);
338//
339// /**
340// * \ingroup sdc
341// * \brief Triangular approximate differentiation and integration matrix \f$ \hat D, \hat S \f$ corresponding
342// * to specialized multi-step integrators
343// *
344// * \param grid the time grid
345// * \param k the sweep number
346// * \param Df the differentiation matrix returned in case no precomputed optimized matrix is available
347// * \param Sf the integration matrix returned in case no precomputed optimized matrix is available
348// * \param w the type of weight function for the optimization
349// *
350// * This returns one of a set of precomputed, optimized integration matrices, if available for the given grid.
351// * If no precomputed matrix is available, the provided fallback matrix is returned.
352// * This is a convenience overload.
353// */
354// std::pair<SDCTimeGrid::RealMatrix,SDCTimeGrid::RealMatrix>
355// optimizedIntegrationMatrix(SDCTimeGrid const& grid, int k, SDCTimeGrid::RealMatrix const& Df, SDCTimeGrid::RealMatrix const& Sf,
356// IntegrationMatrixOptimizationWeight w=OW_FLAT);
357
358
359 // ---------------------------------------------------------------------------------------------------
360
374 {
375 public:
381 LobattoTimeGrid(int n, double a, double b);
382
383 virtual RealVector const& points() const
384 {
385 return pts;
386 }
387
388 virtual RealMatrix const& integrationMatrix() const
389 {
390 return integ;
391 }
392
393 virtual RealMatrix const& differentiationMatrix() const
394 {
395 return diff;
396 }
397
403 virtual void refine(RealMatrix& p);
404
405 virtual RealMatrix interpolate(RealVector const& x) const;
406
407 private:
408 RealVector pts;
409 RealMatrix integ;
410 RealMatrix diff;
411 };
412
426 {
427 public:
433 RadauTimeGrid(int n, double a, double b);
434
440 virtual void refine(RealMatrix& p);
441
442 virtual RealMatrix interpolate(RealVector const& x) const;
443
444 private:
445 void computeMatrices();
446 };
447
448
462 {
463 public:
469 GaussTimeGrid(int n, double a, double b);
470
476 virtual void refine(RealMatrix& p);
477
478 virtual RealMatrix interpolate(RealVector const& x) const;
479
480 private:
481 void computeMatrices();
482 double b; // store the end point of the interval
483 };
484
485
486 // -----------------------------------------------------------------------------------------------
487
489 namespace SdcDetail
490 {
491 template <class Matrix, class Vectors>
492 std::vector<typename Vectors::value_type> computeMdu(Matrix const& M, Vectors const& u)
493 {
494 int const n = u.size()-1; // number of subintervals
495
496 using Vector = typename Vectors::value_type;
497
498 Vector tmp = u[0];
499 std::vector<Vector> Mdu(n,tmp);
500
501 for (int i=0; i<n; ++i)
502 {
503 // compute M (u_{i}-u_{i+1}) TODO: loop fusion
504 tmp = u[i];
505 tmp.axpy(-1.0,u[i+1]);
506 M.mv(tmp,Mdu[i]);
507 }
508
509 return Mdu;
510 }
511
512
513 // Construct J = M - s*(A+f_u), where f_u may have a sparsity pattern that is a subset
514 // of the sparsity pattern of J, M, and A (which need to be equal.
515 // f_u may be nullptr, in which case f_u is completely ignored.
516 template <class Matrix, class ReactionDerivative>
517 void buildEulerStepMatrix(Matrix const& M, double s, Matrix const& A,
518 ReactionDerivative const& f_u, Matrix& J)
519 {
520 for (size_t row=0; row<J.N(); ++row)
521 {
522 auto colJ = J[row].begin();
523 auto end = J[row].end();
524 auto colM = M[row].begin();
525 auto colA = A[row].begin();
526
527 if constexpr (std::is_same_v<ReactionDerivative,std::nullptr_t>) // no reaction derivative
528 { // to be considered
529 while (colJ != end)
530 {
531 *colJ = *colM - s * *colA;
532 ++colJ; ++colM; ++colA;
533 }
534 }
535 else
536 {
537 auto colF = f_u[row].begin();
538 auto endF = f_u[row].end();
539
540 while (colJ != end)
541 {
542 *colJ = *colM - s * *colA;
543
544 if (colF != endF && colJ.index() == colF.index()) // f_u can have subset of sparsity pattern
545 {
546 // guarantee M - Shat*fu is nonnegative -- reduce by at most 50%
547 *colJ -= std::min(0.5 * *colM, s * *colF);
548 ++colF;
549 }
550 ++colJ; ++colM; ++colA;
551 }
552 }
553
554 assert(colM==M[row].end());
555 assert(colA==A[row].end());
556 }
557 }
558
559 // Checks if all diagonal values (that lead to implicit behavior)
560 // are the same, such that the same system has to be solved for all stages.
561 bool isSinglyDiagonal(SDCTimeGrid::RealMatrix const& Shat, double relError=1e-6);
562
563
564 }
566
567 // -----------------------------------------------------------------------------------------------
568
636 template <class Matrix, class Vectors, class ReactionDerivatives, class Solver>
637 typename Matrix::field_type
638 sdcIterationStep(SDCTimeGrid const& grid, SDCTimeGrid::RealMatrix const& Shat, Solver const& solve,
639 Matrix const& M, Matrix const& A,
640 Vectors const& r, ReactionDerivatives const& f_u, Vectors const& u, Vectors& du)
641 {
642 using namespace SdcDetail;
643 auto Mdu = computeMdu(M,u);
644 return sdcIterationStep2(grid,Shat,solve,M,A,r,f_u,Mdu,du);
645 }
646
669 template <class Matrix, class Vectors, class Solver>
670 typename Matrix::field_type
671 sdcIMEXStep(SDCTimeGrid const& grid, SDCTimeGrid::RealMatrix const& Shat, Solver const& solve,
672 Matrix const& M, Matrix const& A,
673 Vectors const& r, Vectors const& u, Vectors& du)
674 {
675 using namespace SdcDetail;
676 assert(isSinglyDiagonal(Shat));
677
678 auto Mdu = computeMdu(M,u);
679 auto solver = [&](auto const& /* J */, auto& x, auto const& b)
680 {
681 solve(x,b);
682 };
683 return sdcIterationStep2(grid,Shat,solver,M,A,r,nullptr,Mdu,du);
684 }
685
714 template <class Matrix, class Vectors, class ReactionDerivatives, class Solver>
715 typename Matrix::field_type
716 sdcIterationStep2(SDCTimeGrid const& grid, SDCTimeGrid::RealMatrix const& Shat, Solver const& solve,
717 Matrix const& M, Matrix const& A,
718 Vectors const& rUi, ReactionDerivatives const& f_u, Vectors const& Mdu, Vectors& du)
719 {
720 using namespace SdcDetail;
721 auto& timer = Timings::instance();
722 ScopedTimingSection("SDC sweep",timer);
723
724 auto const& pts = grid.points();
725 int const n = pts.size()-1; // number of subintervals
726
727 constexpr bool reactionExplicit = std::is_same_v<ReactionDerivatives,std::nullptr_t>;
728 bool const matrixIsFixed = reactionExplicit && isSinglyDiagonal(Shat);
729
730 assert(Mdu.size()>=n);
731 assert(du.size()>=n+1); // including start point
732
733 size_t const dofs = Mdu[0].size();
734
735 // compute exact integration matrix
736 auto const& S = grid.integrationMatrix();
737
738
739 // initialize correction at starting point to zero
740 du[0] = 0.0;
741
742 typedef typename Vectors::value_type Vector;
743 Vector rhs(dofs), tmp(dofs); // declare here to prevent frequent reallocation
744
745 // perform n "Euler" steps
746 typename Matrix::field_type norm = 0;
747 Matrix J = M;
748
749 for (int i=1; i<=n; i++)
750 {
751 timer.start("building matrix");
752 // matrix J = M - Shat_i-1,i*(A+f_u)
753 if constexpr (reactionExplicit)
754 {
755 if (i==1 || !matrixIsFixed) // only rebuild if it might change
756 buildEulerStepMatrix(M,Shat[i-1][i],A,nullptr,J);
757 }
758 else
759 buildEulerStepMatrix(M,Shat[i-1][i],A,f_u[i],J);
760 timer.stop("building matrix");
761
762 // build right-hand side for linear system
763 timer.start("building rhs");
764 // M * ( u_i^{k} - u_{i+1}^k + du_i)
765 rhs = Mdu[i-1];
766 M.umv(du[i-1],rhs);
767
768 // add sum_j S_ij r_j to right hand side
769 for (int j=0; j<=n; ++j)
770 rhs.axpy(S[i-1][j],rUi[j]);
771
772 // add sum_j Shat_ij r'(u_j) du_j with r' = A + f_u, but ignore
773 // f_u if that is not provided
774 tmp = 0;
775 for (int j=1; j<i; ++j) // we can start at 1 since du[0] is zero
776 {
777 if constexpr ( ! reactionExplicit)
778 f_u[j].usmv(Shat[i-1][j],du[j],rhs);
779
780 tmp.axpy(Shat[i-1][j],du[j]);
781 }
782 A.umv(tmp,rhs);
783 timer.stop("building rhs");
784
785 // solve linear system
786 timer.start("solve");
787 du[i] = du[i-1]; // previous increment is probably a good starting value
788 solve(J,du[i],rhs);
789 timer.stop("solve");
790
791 // evaluate norm of correction
792 norm += (pts[i]-pts[i-1]) * (du[i]*rhs);
793 } // end i - loop
794
795 return std::sqrt(norm/(pts[n]-pts[0]));
796 }
797
798// THIS HAS BEEN A TESTBED FOR PLAYING WITH SDC VARIANTS. WHILE INTERESTING, IN ITS CURRENT FORM
799// IT DOES NOT BELONG INTO THE KASKADE CORE LIBRARY. [MW 2024]
800//
801// template <class Matrix, class Vectors, class Reaction, class Solver>
802// typename Matrix::field_type
803// sdcIterationStep3(SDCTimeGrid const& grid, SDCTimeGrid::RealMatrix const& Shat, Solver const& solve,
804// Matrix const& M, Matrix const& Stiff,
805// Vectors const& rUi, Reaction const& fAt, Vectors const& Mdu, Vectors& du,
806// int nReactionSweeps)
807// {
808// auto const& pts = grid.points();
809// int const n = pts.size()-1; // number of subintervals
810//
811// assert(Mdu.size()>=n);
812// assert(du.size()>=n+1); // including start point
813//
814// size_t const dofs = Mdu[0].size();
815//
816// // compute exact integration matrix
817// auto const& S = grid.integrationMatrix();
818// // auto const& S = Shat;
819//
820// // initialize correction at starting point to zero
821// du[0] = 0.0;
822//
823// typedef typename Vectors::value_type Vector;
824// Vector rhs(dofs), tmp(dofs); // declare here to prevent frequent reallocation
825//
826//
827// // perform n basic steps
828// typename Matrix::field_type norm = 0;
829// Matrix J = M;
830// for (int i=1; i<=n; i++)
831// {
832// // Each basic step consists of a splitting method, separating a linearly implicit Euler step
833// // from the pointwise nonlinearity of the right hand side. First we perform the linearly implicit
834// // Euler step.
835//
836// // right-hand side for linear system
837//
838// // M * ( u_{i-1}^{k} - u_{i}^k + du_{i-1})
839// rhs = Mdu[i-1];
840// M.umv(du[i-1],rhs);
841//
842// // add sum_j S_ij r_j to right hand side
843// for (int j=0; j<=n; ++j)
844// rhs.axpy(S[i-1][j],rUi[j]);
845//
846// // add sum_j Shat_ij r'(u_j) du_j with r' = A + f_u, i.e. A (sum_j Shat_ij du_j) + sum_j Shat_ij f_uj du_j
847// // addition of f_u is postponed to matrix loop
848// tmp = 0;
849// for (int j=0; j<i; ++j) // TODO: start at 1 instead of 0? du[0] is zero anyway...
850// tmp.axpy(Shat[i-1][j],du[j]);
851// Stiff.umv(tmp,rhs);
852//
853// // matrix J = M - Shat_i-1,i*(A+f_u)
854// auto const f = fAt( pts[i] );
855// for (size_t row=0; row<J.N(); ++row)
856// {
857// auto colJ = J[row].begin();
858// auto end = J[row].end();
859// auto colM = M[row].begin();
860// auto colA = Stiff[row].begin();
861//
862// while (colJ != end)
863// {
864// auto fu = *colM * (f(row,0.0,1) + f(colJ.index(),0.0,1)) / 2;
865// // *colJ = *colM - Shat[i-1][i] * (*colA + fu); // exact Newton, but for large step sizes the Jacobi matrix becomes singular...
866// // *colJ = *colM - Shat[i-1][i] * (*colA + std::min(0.0,fu)); // this modification guarantees an invertible Jacobian
867// *colJ = *colM - Shat[i-1][i] * (*colA); // explicit reaction
868// if (colJ.index()==row)
869// *colJ -= Shat[i-1][i] * fu; // only diagonal of reaction mass matrix
870//
871// // // add f_u contribution to right hand side (no-op for Euler SDC as Shat[i-1][j]=0 for j<i)
872// // for (int j=0; j<i; ++j) // TODO: start at 1 instead of 0? du[0] is zero anyway...
873// // {
874// // auto f = fAt(pts[j]);
875// // rhs[row] += *colM*Shat[i-1][j]*(f(row,0.0,1)+f(colJ.index(),0.0,1))/2 * du[j][colJ.index()];
876// // }
877//
878// ++colJ; ++colM; ++colA;
879// }
880// }
881//
882// // solve linear system
883// du[i] = du[i-1]; // previous increment is probably a good starting value
884// solve(J,du[i],rhs);
885//
886// std::cerr << "du=" << du[i] << "\n";
887// // std::cerr << "|du| = " << du[i].two_norm2() << " du[i]=" << du[i][0] << " du[i-1]=" << du[i-1][0] << "\n";
888// // Second part is the remaining nonlinearity, which we address by a subsequent run of a couple of Euler steps
889// double const tau = pts[i]-pts[i-1];
890// double snorm = 0;
891// for (size_t row=0; row<J.N(); ++row)
892// {
893// auto fend = fAt(pts[i]);
894// double dfdu = std::min(0.0,fend(row,0.0,1)) * du[i][row];
895//
896// double s = 0;
897// int l = nReactionSweeps;
898// for (int j=0; j<l; ++j)
899// {
900// double theta = 0.0; // where in the subinterval to evaluate (theta=0 explicit Euler, theta=0.5 lin. impl. midpoint, theta=1 lin. impl Euler)
901// auto f = fAt(pts[i-1]+(j+theta)*tau/l);
902// double dut = ((l-j-theta)*du[i-1][row]+(j+theta)*du[i][row])/l;
903//
904// // if (row==0)
905// // std::cerr << "j=" << j << " du+s=" << dut+s << " f(u+du+s)=" << f(row,dut+s,0) << " f(u)=" << f(row,0.0,0) << " dfdu=" << dfdu << " sum rhs=" << (f(row,dut+s,0) - f(row,0.0,0) - dfdu);
906// // s += tau/l * (f(row,dut+s,0) - f(row,0.0,0) - dfdu) / (1-1.0*tau/l*std::min(0.0,f(row,dut+s,1)));
907// if (row==0)
908// std::cerr << "j=" << j << " du+s=" << dut+s << " f(u+du+s)=" << f(row,dut+s,0) << " f(u)=" << f(row,0.0,0) << " dfdu=" << f(row,dut+s,1) << " sum rhs=" << (f(row,dut+s,0) - f(row,0.0,0));
909// s += tau/l * (f(row,dut+s,0) - f(row,0.0,0) - f(row,0.0,1)*(dut+s)) / (1-theta*tau/l*std::min(0.0,f(row,dut+s,1)));
910// if (row==0) std::cerr << " -> s=" << s << "\n";
911// }
912// du[i][row] += s;
913// snorm += s*s;
914// }
915// // std::cerr << "|s| = " << snorm << "\n";
916//
917// // evaluate norm of correction
918// norm += (pts[i]-pts[i-1]) * (du[i]*rhs);
919// } // end i - loop
920//
921// return std::sqrt(norm/(pts[n]-pts[0]));
922// }
923
966 template <class Matrix, class Vectors, class ReactionDerivatives>
968 Matrix const& M, Matrix const& A,
969 Vectors const& rUi, ReactionDerivatives const& f_u, Vectors& du)
970 {
971 auto const& pts = grid.points();
972 int const n = pts.size()-1; // number of subintervals -- left interval boundary always included in points
973
974
975 assert(rUi.size()>=n);
976 assert(du.size()>=n+1); // including start point - usually 0
977
978 size_t const dofs = rUi[0].size();
979
980 // We need to solve the scalar ODE
981 // Mii y_t = Aii y + Rii y + ri, y(0) = 0
982 // We approximate y_t by the spectral differentiation matrix D as Dy and obtain, as system in the
983 // collocation points (excluding the initial value 0)
984 // (MiiD - diag(Aii+Rii)) y = r.
985 // The system matrix is called S here.
986
987 DynamicMatrix<double> S(n,n); // n x n system matrix TODO: use Kaskade::DynamicMatrix?
988 Dune::DynamicVector<double> r(n), y(n);
989 auto const& D = grid.differentiationMatrix();
990
991 std::cerr << "using D = \n" << D << "\n";
992
993 // a function to extract diagonal entries
994 auto diagonal = [](Matrix const& M, size_t i) -> double
995 {
996 auto const& arow = M[i];
997 auto first = arow.begin();
998 auto last = arow.end();
999 while (first!=last && first.index()<i)
1000 ++first;
1001 if (first==last)
1002 {
1003 std::cerr << "first==last\n";
1004 std::cerr.flush();
1005 }
1006 return *first;
1007 };
1008
1009 double retval = 0;
1010
1011 for (size_t i=0; i<dofs; ++i)
1012 {
1013 std::cerr.flush();
1014 auto mii = diagonal(M,i);
1015 auto aii = diagonal(A,i);
1016
1017 for (int j=0; j<n; ++j)
1018 {
1019 for (int k=0; k<n; ++k)
1020 S[j][k] = mii*D[j+1][k+1]; // remember D starts with left interval point
1021 S[j][j] -= aii+diagonal(f_u[j+1],i);
1022 r[j] = rUi[j+1][i];
1023 }
1024 S.solve(y,r);
1025 for (int j=0; j<n; ++j)
1026 du[j+1][i] = 0.5*y[j]; // Jacobi damping (otherwise we get spatially high-frequent errors)
1027 retval += 0.25 * y.two_norm2();
1028 }
1029
1030 return std::sqrt(retval);
1031 }
1032
1058 template <class Vector>
1059 class Sdc
1060 {
1061 public:
1065 Sdc(SDCTimeGrid const& ts_, Vector const& u0)
1066 : ts(ts_), us(ts.points().size(),u0)
1067 {
1068 }
1069
1075 {
1076 Shat = Shat_;
1077 }
1078
1082 void setInitialValue(Vector const& u0, double decayRate=0.0)
1083 {
1084 Vector du = u0;
1085 du -= us[0];
1086 for (int k=0; k<us.size(); ++k)
1087 us[k].axpy(std::exp(-(ts.points()[k]-ts.points()[0])*decayRate),du);
1088 }
1089
1090 protected:
1091
1092 private:
1093 SDCTimeGrid ts;
1094 std::vector<Vector> us;
1096 };
1097
1098}
1099
1100
1101#endif
spectral time grid for defect correction methods with Gauss points
Definition: sdc.hh:462
virtual RealMatrix interpolate(RealVector const &x) const
Compute interpolation coefficients.
virtual void refine(RealMatrix &p)
perform refinement of the grid, filling the prolongation matrix
GaussTimeGrid(int n, double a, double b)
constructs a Gauss grid with points on
spectral time grid for defect correction methods with Lobatto points on
Definition: sdc.hh:374
virtual RealVector const & points() const
Time points in the time step.
Definition: sdc.hh:383
virtual RealMatrix const & integrationMatrix() const
Integration matrix .
Definition: sdc.hh:388
virtual RealMatrix const & differentiationMatrix() const
Differentiation matrix .
Definition: sdc.hh:393
virtual RealMatrix interpolate(RealVector const &x) const
Compute interpolation coefficients.
virtual void refine(RealMatrix &p)
perform refinement of the grid, filling the prolongation matrix
LobattoTimeGrid(int n, double a, double b)
constructs a Lobatto grid with points on .
spectral time grid for defect correction methods with Radau points on .
Definition: sdc.hh:426
virtual void refine(RealMatrix &p)
perform refinement of the grid, filling the prolongation matrix
virtual RealMatrix interpolate(RealVector const &x) const
Compute interpolation coefficients.
RadauTimeGrid(int n, double a, double b)
constructs a Radau grid with points on
A convenience class simplifying the implementation of different SDCTimeGrid derived classes.
Definition: sdc.hh:170
virtual RealVector const & points() const
Time points in the time step.
Definition: sdc.hh:173
virtual RealMatrix const & differentiationMatrix() const
Differentiation matrix .
Definition: sdc.hh:183
virtual RealMatrix const & integrationMatrix() const
Integration matrix .
Definition: sdc.hh:178
Abstract base class of time grids for (block) spectral defect correction methods.
Definition: sdc.hh:68
DynamicMatrix< double > RealMatrix
The type used for real (dense) matrices.
Definition: sdc.hh:78
virtual void refine(RealMatrix &p)=0
Perform refinement of the grid, filling the prolongation matrix.
double point(int k) const
Time points in the time step.
Definition: sdc.hh:94
virtual RealMatrix interpolate(RealVector const &x) const =0
Compute interpolation coefficients.
virtual RealVector const & points() const =0
Time points in the time step.
virtual RealMatrix const & differentiationMatrix() const =0
Differentiation matrix .
Dune::DynamicVector< double > RealVector
The type used for real vectors.
Definition: sdc.hh:73
virtual RealMatrix const & integrationMatrix() const =0
Integration matrix .
A scope guard object that automatically closes a timing section on destruction.
Definition: timing.hh:181
Encapsulates the state of an SDC fixed point iteration and provides stepping.
Definition: sdc.hh:1060
void setApproximateQuadratureMatrix(SDCTimeGrid::RealMatrix const &Shat_)
Sets the approximate quadrature matrix.
Definition: sdc.hh:1074
Sdc(SDCTimeGrid const &ts_, Vector const &u0)
Constructor.
Definition: sdc.hh:1065
void setInitialValue(Vector const &u0, double decayRate=0.0)
Sets .
Definition: sdc.hh:1082
static Timings & instance()
Returns a reference to a single default instance.
Dune::FieldVector< T, n > min(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise minimum.
Definition: fixdune.hh:122
SDCTimeGrid::RealMatrix SDIRKIntegrationMatrix(SDCTimeGrid const &grid)
Triangular approximate integration matrix corresponding to an SDIRK sweep (i.e. with constant "step ...
double waveformRelaxationStep2(SDCTimeGrid const &grid, Matrix const &M, Matrix const &A, Vectors const &rUi, ReactionDerivatives const &f_u, Vectors &du)
A single waveform relaxation iteration.
Definition: sdc.hh:967
SDCTimeGrid::RealMatrix singleEulerIntegrationMatrix(SDCTimeGrid const &grid)
Triangular approximate integration matrix corresponding to an Euler sweep with constant "step size".
Matrix::field_type sdcIterationStep2(SDCTimeGrid const &grid, SDCTimeGrid::RealMatrix const &Shat, Solver const &solve, Matrix const &M, Matrix const &A, Vectors const &rUi, ReactionDerivatives const &f_u, Vectors const &Mdu, Vectors &du)
A single spectral defect correction iteration sweep.
Definition: sdc.hh:716
void luIntegrationMatrix(SDCTimeGrid const &grid, SDCTimeGrid::RealMatrix &Shat)
Triangular approximate integration matrix corresponding to a specialized DIRK sweep.
Matrix::field_type sdcIMEXStep(SDCTimeGrid const &grid, SDCTimeGrid::RealMatrix const &Shat, Solver const &solve, Matrix const &M, Matrix const &A, Vectors const &r, Vectors const &u, Vectors &du)
A single IMEX SDIRK spectral deferred correction sweep.
Definition: sdc.hh:671
void eulerIntegrationMatrix(SDCTimeGrid const &grid, SDCTimeGrid::RealMatrix &Shat)
Triangular approximate integration matrix corresponding to the implicit Euler integrator.
Matrix::field_type sdcIterationStep(SDCTimeGrid const &grid, SDCTimeGrid::RealMatrix const &Shat, Solver const &solve, Matrix const &M, Matrix const &A, Vectors const &r, ReactionDerivatives const &f_u, Vectors const &u, Vectors &du)
A single spectral defect correction iteration sweep.
Definition: sdc.hh:638
void axpy(Dune::BCRSMatrix< Dune::FieldMatrix< Scalar, 1, 1 > > const &P, Dune::BlockVector< Dune::FieldVector< Scalar, n > > const &x, Dune::BlockVector< Dune::FieldVector< Scalar, n > > &y, Scalar alpha=1.0)
Compute . If resetSolution=true computes .
Dune::FieldVector< Scalar, dim > Vector