16#include <boost/timer/timer.hpp>
18#include "dune/grid/config.h"
19#include "dune/istl/operators.hh"
20#include "dune/istl/solvers.hh"
22#include "dune/common/dynvector.hh"
445 void computeMatrices();
481 void computeMatrices();
491 template <
class Matrix,
class Vectors>
492 std::vector<typename Vectors::value_type> computeMdu(Matrix
const& M, Vectors
const& u)
494 int const n = u.size()-1;
496 using Vector =
typename Vectors::value_type;
499 std::vector<Vector> Mdu(n,tmp);
501 for (
int i=0; i<n; ++i)
505 tmp.axpy(-1.0,u[i+1]);
516 template <
class Matrix,
class ReactionDerivative>
517 void buildEulerStepMatrix(Matrix
const& M,
double s, Matrix
const& A,
518 ReactionDerivative
const& f_u, Matrix& J)
520 for (
size_t row=0; row<J.N(); ++row)
522 auto colJ = J[row].begin();
523 auto end = J[row].end();
524 auto colM = M[row].begin();
525 auto colA = A[row].begin();
527 if constexpr (std::is_same_v<ReactionDerivative,std::nullptr_t>)
531 *colJ = *colM - s * *colA;
532 ++colJ; ++colM; ++colA;
537 auto colF = f_u[row].begin();
538 auto endF = f_u[row].end();
542 *colJ = *colM - s * *colA;
544 if (colF != endF && colJ.index() == colF.index())
547 *colJ -=
std::min(0.5 * *colM, s * *colF);
550 ++colJ; ++colM; ++colA;
554 assert(colM==M[row].end());
555 assert(colA==A[row].end());
636 template <
class Matrix,
class Vectors,
class ReactionDerivatives,
class Solver>
637 typename Matrix::field_type
639 Matrix
const& M, Matrix
const& A,
640 Vectors
const& r, ReactionDerivatives
const& f_u, Vectors
const& u, Vectors& du)
642 using namespace SdcDetail;
643 auto Mdu = computeMdu(M,u);
669 template <
class Matrix,
class Vectors,
class Solver>
670 typename Matrix::field_type
672 Matrix
const& M, Matrix
const& A,
673 Vectors
const& r, Vectors
const& u, Vectors& du)
675 using namespace SdcDetail;
676 assert(isSinglyDiagonal(Shat));
678 auto Mdu = computeMdu(M,u);
679 auto solver = [&](
auto const& ,
auto& x,
auto const& b)
714 template <
class Matrix,
class Vectors,
class ReactionDerivatives,
class Solver>
715 typename Matrix::field_type
717 Matrix
const& M, Matrix
const& A,
718 Vectors
const& rUi, ReactionDerivatives
const& f_u, Vectors
const& Mdu, Vectors& du)
720 using namespace SdcDetail;
724 auto const& pts = grid.
points();
725 int const n = pts.size()-1;
727 constexpr bool reactionExplicit = std::is_same_v<ReactionDerivatives,std::nullptr_t>;
728 bool const matrixIsFixed = reactionExplicit && isSinglyDiagonal(Shat);
730 assert(Mdu.size()>=n);
731 assert(du.size()>=n+1);
733 size_t const dofs = Mdu[0].size();
742 typedef typename Vectors::value_type
Vector;
743 Vector rhs(dofs), tmp(dofs);
746 typename Matrix::field_type norm = 0;
749 for (
int i=1; i<=n; i++)
751 timer.start(
"building matrix");
753 if constexpr (reactionExplicit)
755 if (i==1 || !matrixIsFixed)
756 buildEulerStepMatrix(M,Shat[i-1][i],A,
nullptr,J);
759 buildEulerStepMatrix(M,Shat[i-1][i],A,f_u[i],J);
760 timer.stop(
"building matrix");
763 timer.start(
"building rhs");
769 for (
int j=0; j<=n; ++j)
770 rhs.axpy(S[i-1][j],rUi[j]);
775 for (
int j=1; j<i; ++j)
777 if constexpr ( ! reactionExplicit)
778 f_u[j].usmv(Shat[i-1][j],du[j],rhs);
780 tmp.axpy(Shat[i-1][j],du[j]);
783 timer.stop(
"building rhs");
786 timer.start(
"solve");
792 norm += (pts[i]-pts[i-1]) * (du[i]*rhs);
795 return std::sqrt(norm/(pts[n]-pts[0]));
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)
971 auto const& pts = grid.
points();
972 int const n = pts.size()-1;
975 assert(rUi.size()>=n);
976 assert(du.size()>=n+1);
978 size_t const dofs = rUi[0].size();
988 Dune::DynamicVector<double> r(n), y(n);
991 std::cerr <<
"using D = \n" << D <<
"\n";
994 auto diagonal = [](Matrix
const& M,
size_t i) ->
double
996 auto const& arow = M[i];
997 auto first = arow.begin();
998 auto last = arow.end();
999 while (first!=last && first.index()<i)
1003 std::cerr <<
"first==last\n";
1011 for (
size_t i=0; i<dofs; ++i)
1014 auto mii = diagonal(M,i);
1015 auto aii = diagonal(A,i);
1017 for (
int j=0; j<n; ++j)
1019 for (
int k=0; k<n; ++k)
1020 S[j][k] = mii*D[j+1][k+1];
1021 S[j][j] -= aii+diagonal(f_u[j+1],i);
1025 for (
int j=0; j<n; ++j)
1026 du[j+1][i] = 0.5*y[j];
1027 retval += 0.25 * y.two_norm2();
1030 return std::sqrt(retval);
1058 template <
class Vector>
1066 : ts(ts_), us(ts.points().size(),u0)
1086 for (
int k=0; k<us.size(); ++k)
1094 std::vector<Vector> us;
spectral time grid for defect correction methods with Gauss points
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
virtual RealVector const & points() const
Time points in the time step.
virtual RealMatrix const & integrationMatrix() const
Integration matrix .
virtual RealMatrix const & differentiationMatrix() const
Differentiation matrix .
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 .
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.
virtual RealVector const & points() const
Time points in the time step.
virtual RealMatrix const & differentiationMatrix() const
Differentiation matrix .
virtual RealMatrix const & integrationMatrix() const
Integration matrix .
Abstract base class of time grids for (block) spectral defect correction methods.
DynamicMatrix< double > RealMatrix
The type used for real (dense) matrices.
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.
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.
virtual RealMatrix const & integrationMatrix() const =0
Integration matrix .
A scope guard object that automatically closes a timing section on destruction.
Encapsulates the state of an SDC fixed point iteration and provides stepping.
void setApproximateQuadratureMatrix(SDCTimeGrid::RealMatrix const &Shat_)
Sets the approximate quadrature matrix.
Sdc(SDCTimeGrid const &ts_, Vector const &u0)
Constructor.
void setInitialValue(Vector const &u0, double decayRate=0.0)
Sets .
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.
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.
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.
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.
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.
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