KASKADE 7 development version
limex.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) 2002-2011 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 LIMEX_HH
14#define LIMEX_HH
15
16#include <boost/timer/timer.hpp>
17
19#include "fem/iterate_grid.hh"
21
22namespace Kaskade
23{
31 template <class Eq>
32 class Limex
33 {
34 public:
36 typedef typename EvolutionEquation::AnsatzVars::VariableSet State;
37
38 private:
41
42 public:
48 EvolutionEquation& eq_, typename EvolutionEquation::AnsatzVars const& ansatzVars_,
49 std::vector<std::pair<double,double> > const& tolX):
50 ansatzVars(ansatzVars_), eq(&eq_,0), gop(ansatzVars.spaces), extrap(0),
52
66 State const& step(State const& x, double dt, int order)
67 {
68 boost::timer::cpu_timer timer;
69
70 std::vector<double> stepFractions(order+1);
71 for (int i=0; i<=order; ++i) stepFractions[i] = 1.0/(i+1);
72 extrap.clear();
73
74 int const nvars = EvolutionEquation::AnsatzVars::noOfVariables;
75 int const neq = EvolutionEquation::TestVars::noOfVariables;
76 size_t nnz = gop.nnz(0,neq,0,nvars,false);
77 size_t size = ansatzVars.degreesOfFreedom(0,nvars);
78
79 std::vector<int> ridx(nnz), cidx(nnz);
80 std::vector<double> data(nnz), rhs(size), sol(size);
81
82 State dx(x), dxsum(x), tmp(x);
83 double const t = eq.time();
84
85 eq.temporalEvaluationRange(t,t+dt);
86
87 for (int i=0; i<=order; ++i) {
88 double const tau = stepFractions[i]*dt;
89 eq.setTau(tau);
90 eq.time(t);
91
92 // Evaluate and factorize matrix B(t)-tau*J
93 dx *= 0;
94 timer.start();
95 gop.assemble(Linearization(eq,x,x,dx));
96 matrixAssemblyTime += (double)(timer.elapsed().user)/1e9;
97
98 timer.start();
99 gop.toTriplet(0,neq,0,nvars,ridx.begin(),cidx.begin(),data.begin(),false);
100 UMFFactorization<double> matrix(size,ridx,cidx,data);
101 factorizationTime += timer.elapsed();
102
103 // First right hand side (j=0) has been assembled together with matrix.
104 timer.start();
105 gop.toSequence(0,neq,rhs.begin());
106 for (int k=0; k<rhs.size(); ++k) assert(finite(rhs[k]));
107 matrix.solve(rhs,sol);
108 for (int k=0; k<sol.size(); ++k) assert(finite(sol[k]));
109 dx.read(sol.begin());
110 dxsum = dx;
111 solutionTime += (double)(timer.elapsed().user)/1e9;
112
113 // propagate by linearly implicit Euler
114 for (int j=1; j<=i; ++j) {
115 // Assemble new right hand side tau*f(x_j)+(B(t)-B(t+j*tau))*dx_(j-1)
116 eq.time(eq.time()+tau);
117 tmp = x; tmp += dxsum;
118 timer.start();
119 gop.assemble(Linearization(eq,tmp,x,dx),GOp::RHS);
120 rhsAssemblyTime += timer.elapsed();
121 timer.start();
122 gop.toSequence(0,neq,rhs.begin());
123 for (int k=0; k<rhs.size(); ++k) assert(finite(rhs[k]));
124 matrix.solve(rhs,sol);
125 for (int k=0; k<sol.size(); ++k) assert(finite(sol[k]));
126 dx.read(sol.begin());
127 dxsum += dx;
128 solutionTime += (double)(timer.elapsed().user)/1e9;
129 }
130
131 // insert into extrapolation tableau
132 extrap.push_back(dxsum,stepFractions[i]);
133
134 // restore initial time
135 eq.time(t);
136 }
137
138 return extrap.back();
139 }
140
141 double estimateError(State const& x,int i, int j) const
142 {
143 assert(extrap.size()>1);
144
145 std::vector<std::pair<double,double> > e(ansatzVars.noOfVariables);
146
147 relativeError(typename EvolutionEquation::AnsatzVars::Variables(),extrap[i].data,
148 extrap[j].data,x.data,ansatzVars.spaces,eq.scaling(),
149 e.begin());
150
151 return e[0].first/(0.1+e[0].second);
152 }
153
154 template <class OutStream>
155 void reportTime(OutStream& out) const {
156 out << "Limex time: " << matrixAssemblyTime << "s matrix assembly\n"
157 << " " << rhsAssemblyTime << "s rhs assembly\n"
158 << " " << factorizationTime << "s factorization\n"
159 << " " << solutionTime << "s solution\n";
160 }
161
162 void advanceTime(double dt) { eq.time(eq.time()+dt); }
163
164
165 private:
166 typename EvolutionEquation::AnsatzVars const& ansatzVars;
168 GOp gop;
169
170 public:
173 };
174} // namespace Kaskade
175#endif
void push_back(T t, double hnew)
Extrapolated linearly implicit Euler method.
Definition: limex.hh:33
EvolutionEquation::AnsatzVars::VariableSet State
Definition: limex.hh:36
double rhsAssemblyTime
Definition: limex.hh:172
State const & step(State const &x, double dt, int order)
Definition: limex.hh:66
double estimateError(State const &x, int i, int j) const
Definition: limex.hh:141
double matrixAssemblyTime
Definition: limex.hh:172
void advanceTime(double dt)
Definition: limex.hh:162
double solutionTime
Definition: limex.hh:172
Limex(GridManager< typename EvolutionEquation::AnsatzVars::Grid > &gridManager, EvolutionEquation &eq_, typename EvolutionEquation::AnsatzVars const &ansatzVars_, std::vector< std::pair< double, double > > const &tolX)
Definition: limex.hh:47
ExtrapolationTableau< State > extrap
Definition: limex.hh:171
void reportTime(OutStream &out) const
Definition: limex.hh:155
Eq EvolutionEquation
Definition: limex.hh:35
double factorizationTime
Definition: limex.hh:172
Self & setTau(Scalar dt)
Sets the time step size.
Definition: semieuler.hh:428
Proxy class for the linearization of semi-linear time stepping schemes.
Factorization of sparse linear systems with UMFPack.
void solve(std::vector< Scalar > const &b, std::vector< Scalar > &x, bool transposed=false) const
void toSequence(int rbegin, int rend, DataOutIter xi) const
Writes the subvector defined by the half-open block range [rbegin,rend) to the output iterator xi.
size_t nnz(size_t rbegin=0, size_t rend=TestVariableSetDescription::noOfVariables, size_t cbegin=0, size_t cend=AnsatzVariableSetDescription::noOfVariables, bool extractOnlyLowerTriangle=false) const
Returns the number of structurally nonzero entries in the submatrix defined by the half-open block ra...
void assemble(F const &f, unsigned int flags=Assembler::EVERYTHING, int nThreads=0, bool verbose=false)
Assembly without block filter or cell filter.
void relativeError(Variables const &varDesc, Functions const &f1, Functions const &f2, Functions const &f3, Spaces const &spaces, Scaling const &scaling, OutIter out)