KASKADE 7 development version
util.hh
Go to the documentation of this file.
1/*
2 * util.hh
3 *
4 * Created on: May 3, 2015
5 * Author: sunayana_ghosh
6 */
7/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
8/* */
9/* This file is part of the library KASKADE 7 */
10/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
11/* */
12/* Copyright (C) 2015-2015 Zuse Institute Berlin */
13/* */
14/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
15/* see $KASKADE/academic.txt */
16/* */
17/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
18
19//In this file we implement some of the utility functions necessary for
20//the classes WorkModel, ErrorEstimate and the main integrate function of the class EulerSDC.
21
22#ifndef KASKADE_TIMESTEPPING_EULERSDC_UTIL_HH_
23#define KASKADE_TIMESTEPPING_EULERSDC_UTIL_HH_
24
25#include "norm.hh"
26
27#include <cmath> //std::abs
28#include <functional> //std::function
29#include <vector>
30
31#include <boost/timer/timer.hpp>
32
33#include "dune/common/dynmatrix.hh"
34#include "dune/common/dynvector.hh"
35
36#include "fem/fixdune.hh"
37#include "timestepping/sdc.hh"
38
39namespace Kaskade {
44//=================================================================================================
45// Utility function to find norm of a difference of vector of two Vectors
46//=================================================================================================
47
57template<class Vector, class Norm>
58typename Vector::value_type normVecDiff(std::vector<Vector> const& y0, std::vector<Vector> const& y1, Norm norm);
59
60
61//=================================================================================================
62// Implementation for single sdc iteration step based on explicit Euler method.
63//=================================================================================================
109 template<class Vector>
111 std::function<Vector(typename Vector::value_type, Vector const&)> rhsFunc,
112 std::vector<Vector> & yi, std::vector<Vector> & dyi,
113 bool verbose = false)
114 {
115 //extract time points from the grid
116 auto const& pts = grid.points();
117 //extracting values of the integration matrix corresponding to the time grid.
118 auto const& integ = grid.integrationMatrix();
119 //number of intervals
120 int const n = pts.size() - 1;
121
122 //including starting point for yi and dyi
123 assert(yi.size() == n+1);
124 assert(dyi.size() == n+1);
125
126 //initialize all elements of dyi to zero.
127 for (int i = 0; i <= n; ++i)
128 {
129 dyi[i] = Vector(0.0);
130 }
131
132 //declare Vector total to be used inside the for loop
133 Vector total(0.0);
134
135 //the SDC step for explicit Euler
136 //perform n Euler steps
137 boost::timer::cpu_timer timer;
138 for (auto i = 1; i <= n; ++i)
139 {
140 //Initialize all the entries of total to zero
141 total = Vector(0.0);
142 //computation of the Lagrange interpolation
143 for (int k = 0; k <= n; ++k)
144 {
145 total += integ[i-1][k] * rhsFunc(pts[k], yi[k]);
146 }
147 //approximate correction computation
148 dyi[i] = dyi[i-1] + (pts[i] - pts[i-1]) *(rhsFunc(pts[i-1],yi[i-1]+dyi[i-1]) - rhsFunc(pts[i-1],yi[i-1])) + total - yi[i] + yi[i-1];
149 }
150
151 //Compute the next iteration of yi.
152 for (auto i = 0; i <= n; ++i)
153 {
154 yi[i] += dyi[i];
155 if (verbose)
156 std::cout << "yi[" << i << "] = " << yi[i] << "\n";
157 }
158
159 }
160
161 //=================================================================================================
162 // Implementation for single inexact sdc iteration step based on explicit Euler method.
163 //=================================================================================================
164
165
166 template<class Vector, class RealVector>
168 std::function<Vector(typename Vector::value_type, Vector const&)> rhsFunc,
169 RealVector const& toleranceVector, typename Vector::value_type rho,
170 Kaskade::NormType norm_t,
171 std::vector<Vector> & yi, std::vector<Vector> & dyi,
172 bool verbose = false)
173 {
174 //extract time points from the grid
175 auto const& tpts = grid.points();
176 //extracting values of the integration matrix corresponding to the time grid.
177 auto const& integ = grid.integrationMatrix();
178 //number of intervals
179 unsigned int const n = tpts.size() - 1;
180
181 //including starting point for yi and dyi
182 assert(yi.size() == n+1);
183 assert(dyi.size() == n+1);
184
185 //initialize all elements of dyi to zero.
186 for (auto i = 0u; i <= n; ++i)
187 {
188 dyi[i] = Vector(0.0);
189 }
190
191 //declare Vector total to be used inside the for loop
192 Vector total(0.0);
193
194 //convert the toleranceVector which is a vector of doubles to a vector of Vectors.
195 std::vector<Vector> errVector(n+1, Vector(0.0));
196 //depending on the normType fill in err vector. This step is taken since the tolerance vector is a vector of scalars
197 switch(norm_t)
198 {
200 {
201 auto sz = dyi[0].size();
202 for (auto i = 1u; i <= n; ++i)
203 errVector[i] = Vector(toleranceVector[i]/sz);
204 break;
205 }
207 {
208 for (auto i = 1u; i <= n; ++i)
209 errVector[i] = Vector(toleranceVector[i]);
210 break;
211 }
212 }
213
214 //the perturbed SDC step for explicit Euler
215 //perform n Euler steps
216 boost::timer::cpu_timer timer;
217 for (auto i = 1u; i <= n; ++i)
218 {
219 //Initialize all the entries of total to zero
220 total = Vector(0.0);
221
222 //computation of the Lagrange interpolation
223 for (auto k = 0u; k <= n; ++k)
224 {
225 total += integ[i-1][k] * (rhsFunc(tpts[k], yi[k]) + errVector[k]);
226 }
227 //approximate correction computation
228 dyi[i] = dyi[i-1] + (tpts[i] - tpts[i-1]) *((rhsFunc(tpts[i-1],yi[i-1]+dyi[i-1]) - rhsFunc(tpts[i-1],yi[i-1]))- (1 - rho)*errVector[i-1]) + total - yi[i] + yi[i-1];
229 }
230
231 //Compute the next iteration of yi.
232 for (auto i = 0u; i <= n; ++i)
233 {
234 yi[i] += dyi[i];
235 if (verbose)
236 std::cout << "yi[" << i << "] = " << yi[i] << "\n";
237 }
238 }
239
240
241 //===================================================================================================
242 // Implementation of the abstract base class SDCUtil for all utility methods depending on the norms.
243 //===================================================================================================
244
245 template <class Vector, class Norm>
247 {
248 public:
249 using field_type = typename Vector::value_type;
250 using RealVector = Dune::DynamicVector<double>;
251 using RealMatrix = Dune::DynamicMatrix<double>;
252
253 //virtual function
270 field_type sdcContractionFactor(std::vector<Vector> const& yPrev,
271 std::vector<Vector> const& yCurrent,
272 std::vector<Vector> const& yNext,
273 Norm& norm);
274
275 //pure virtual functions
300 virtual RealVector const& computeAlphaVec(RealVector const& timePoints,
301 RealMatrix const& integrationMatrix,
302 std::vector<Vector> const& yPrev,
303 std::vector<Vector> const& yCurrent,
304 std::vector<Vector> const& yNext) = 0;
305
306
307 //virtual destructor
308 virtual ~SDCUtil(){}
309 };
310
311 //===================================================================================================
312 // Implementation of the derived class SDCUtilOneNorm w.r.t. 1-norm.
313 //===================================================================================================
314 template<class Vector, class Norm>
315 class SDCUtilOneNorm : public SDCUtil<Vector, Norm>
316 {
317 public:
318 using field_type = typename Vector::value_type;
319 using RealVector = Dune::DynamicVector<double>;
320 using RealMatrix = Dune::DynamicMatrix<double>;
321
332 virtual RealVector const& computeAlphaVec(RealVector const& timePts,
333 RealMatrix const& integrationMatrix,
334 std::vector<Vector> const& yPrev,
335 std::vector<Vector> const& yCurrent,
336 std::vector<Vector> const& yNext)
337 {
338 //number of collocation points
339 auto nCollocationPts = timePts.size();
340 alphaVec = RealVector(nCollocationPts-1, 0.0);
341
342 //create one norm object
344 //compute sdc contraction rate
345 auto rho = Kaskade::SDCUtil<Vector, Norm>::sdcContractionFactor(yPrev, yCurrent, yNext, on);
346 for (auto i = 0u; i < nCollocationPts-1; ++i)
347 {
348 field_type total = 0.0;
349 for (auto k = 0u; k < nCollocationPts-1; ++k)
350 total += std::abs(integrationMatrix[k][i]);
351 if (i != nCollocationPts-2)
352 alphaVec[i] = (total + (timePts[i+1] - timePts[i]) * (1 + rho));
353 else
354 alphaVec[i] = total;
355 }
356 return alphaVec;
357 }
358
359
360 virtual ~SDCUtilOneNorm(){}
361
362 private:
363 RealVector alphaVec;
364 RealMatrix alphaMat;
365 };
366
367 //===================================================================================================
368 // Implementation of the derived class SDCUtilMaxNorm w.r.t. max-norm.
369 //===================================================================================================
370 template<class Vector, class Norm>
371 class SDCUtilMaxNorm : public SDCUtil<Vector, Norm>
372 {
373 public:
374 using field_type = typename Vector::value_type;
375 using RealVector = Dune::DynamicVector<double>;
376 using RealMatrix = Dune::DynamicMatrix<double>;
377
378
379 //TODO: Doc me
389 virtual RealVector const& computeAlphaVec(RealVector const& timePts,
390 RealMatrix const& integrationMatrix,
391 std::vector<Vector> const& yPrev,
392 std::vector<Vector> const& yCurrent,
393 std::vector<Vector> const& yNext)
394 {
395 //number of collocation points.
396 auto nCollocationPts = timePts.size();
397 gamma = RealVector(nCollocationPts, 0.0);
398
399 //initialize the matrix alpha with size (nCollocationPts - 1) x nCollocationPts
400 auto alphaMat = computeAlphaMat(timePts, integrationMatrix, yPrev, yCurrent, yNext, nCollocationPts);
401 //Compute the vector Gamma.
402 for (int i = 0; i < nCollocationPts -1; ++i)
403 {
404 for (int j = 0; j < nCollocationPts; ++j)
405 {
406 if (alphaMat[i][j] > gamma[j])
407 gamma[j] = alphaMat[i][j];
408 }
409 }
410 return gamma;
411 }
412
413
414
415 virtual ~SDCUtilMaxNorm() {};
416 private:
417 RealVector gamma;
418 RealMatrix alphaMat;
419
430 RealMatrix const& computeAlphaMat(RealVector const& timePts,
431 RealMatrix const& integrationMatrix,
432 std::vector<Vector> const& yPrev,
433 std::vector<Vector> const& yCurrent,
434 std::vector<Vector> const& yNext,
435 int nCollocationPts);
436
437
438 };
439
440
441 //=================================================================================================
442 // FUNCTION DEFINITION BEGINS FROM HERE
443 //=================================================================================================
444
445 //=================================================================================================
446 // Utility function to find norm of a difference of vector of two Vectors
447 //=================================================================================================
448
449 template<class Vector, class Norm>
450 typename Vector::value_type normVecDiff(std::vector<Vector> const& y0, std::vector<Vector> const& y1, Norm norm)
451 {
452 //Initialize the all the entries of dy to 0.0
453 std::vector<Vector> dy(y0.size(), Vector(0.0));
454 for (auto i = 0u; i < y0.size(); ++i)
455 {
456 dy[i] = y1[i] - y0[i];
457 }
458 return norm.value(dy);
459 }
460
461 //===================================================================================================
462 // Implementation of the abstract base class SDCUtil for all utility methods depending on the norms.
463 //===================================================================================================
464
465 template <class Vector, class Norm>
466 typename Vector::value_type SDCUtil<Vector, Norm>::sdcContractionFactor(std::vector<Vector> const& yPrev,
467 std::vector<Vector> const& yCurrent,
468 std::vector<Vector> const& yNext,
469 Norm& norm)
470 {
471 size_t n = yPrev.size();
472 //Compute the differences: yPrev - yCurrent and yCurrent - yNext
473 std::vector<Vector> y01(n, Vector(0.0));
474 std::vector<Vector> y12(n, Vector(0.0));
475 for (auto i = 0u; i < n; ++i)
476 {
477 y01[i] = yCurrent[i] - yPrev[i] ;
478 y12[i] = yNext[i] - yCurrent[i];
479 }
480 auto val01 = norm.value(y01);
481 auto val12 = norm.value(y12);
482 auto beta = val12/(val01 + val12);
483 auto val = val12/val01;
484 if (val > 1 || val != val) //check if val > 1 or val is NaN.
485 {
486 if (beta != beta) //check if beta = NaN
487 val = 0.70;
488 else
489 val = beta;
490 }
491 return val;
492 }
493
494
495 //===================================================================================================
496 // Implementation of the private method computeAlphaMat for the derived class SDCUtilMaxNorm
497 //===================================================================================================
498 using RealVector = Dune::DynamicVector<double>;
499 using RealMatrix = Dune::DynamicMatrix<double>;
500
501 template<class Vector, class Norm>
503 RealMatrix const& integrationMatrix,
504 std::vector<Vector> const& yPrev,
505 std::vector<Vector> const& yCurrent,
506 std::vector<Vector> const& yNext,
507 int nCollocationPts)
508 {
509 //create max norm object
511 //compute sdc contraction rate
512 auto rho = Kaskade::SDCUtil<Vector, Norm>::sdcContractionFactor(yPrev, yCurrent, yNext, mn);
513 alphaMat = RealMatrix(nCollocationPts-1, nCollocationPts, 0.0);
514 for (auto i = 0; i < nCollocationPts-1; ++i)
515 {
516 for (auto k = 0; k < nCollocationPts; ++k)
517 {
518 if (i == k)
519 alphaMat[i][k] = std::abs(integrationMatrix[i][k]) + (timePts[i+1] - timePts[i]) * (1 + rho);
520 else
521 alphaMat[i][k] = std::abs(integrationMatrix[i][k]);
522 }
523 }
524 return alphaMat;
525 }
526
527
528}//end namespace Kaskade
529
530
531
532
533#endif /* KASKADE_TIMESTEPPING_EULERSDC_UTIL_HH_ */
MaxNorm class derived from the abstract base class Norm. Here the max norm represents the max norm of...
Definition: norm.hh:131
Abstract base class of various norms.
Definition: norm.hh:59
virtual field_type value(std::vector< Vector > const &vecs)=0
OneNorm class derived from the abstract base class Norm.
Definition: norm.hh:97
Abstract base class of time grids for (block) spectral defect correction methods.
Definition: sdc.hh:43
virtual RealVector const & points() const =0
Time points in the time step.
virtual RealMatrix const & integrationMatrix() const =0
Integration matrix .
Dune::DynamicMatrix< double > RealMatrix
Definition: util.hh:251
typename Vector::value_type field_type
Definition: util.hh:249
Dune::DynamicVector< double > RealVector
Definition: util.hh:250
virtual RealVector const & computeAlphaVec(RealVector const &timePoints, RealMatrix const &integrationMatrix, std::vector< Vector > const &yPrev, std::vector< Vector > const &yCurrent, std::vector< Vector > const &yNext)=0
virtual ~SDCUtil()
Definition: util.hh:308
field_type sdcContractionFactor(std::vector< Vector > const &yPrev, std::vector< Vector > const &yCurrent, std::vector< Vector > const &yNext, Norm &norm)
Definition: util.hh:466
virtual ~SDCUtilMaxNorm()
Definition: util.hh:415
virtual RealVector const & computeAlphaVec(RealVector const &timePts, RealMatrix const &integrationMatrix, std::vector< Vector > const &yPrev, std::vector< Vector > const &yCurrent, std::vector< Vector > const &yNext)
Definition: util.hh:389
Dune::DynamicVector< double > RealVector
Definition: util.hh:375
virtual ~SDCUtilOneNorm()
Definition: util.hh:360
Dune::DynamicVector< double > RealVector
Definition: util.hh:319
virtual RealVector const & computeAlphaVec(RealVector const &timePts, RealMatrix const &integrationMatrix, std::vector< Vector > const &yPrev, std::vector< Vector > const &yCurrent, std::vector< Vector > const &yNext)
Definition: util.hh:332
This file contains various utility functions that augment the basic functionality of Dune.
Dune::FieldVector< Scalar, dim > Vector
Dune::DynamicVector< double > RealVector
Definition: util.hh:498
NormType
Enum class to define the norm type in class Norm.
Definition: norm.hh:39
@ ONE_NORM
ONE_NORM.
@ MAX_NORM
MAX_NORM.
Vector::value_type normVecDiff(std::vector< Vector > const &y0, std::vector< Vector > const &y1, Norm norm)
Some utility functions.
Definition: util.hh:450
Dune::DynamicMatrix< double > RealMatrix
Definition: util.hh:499
void sdcExplicitEulerIterationStep(Kaskade::SDCTimeGrid const &grid, std::function< Vector(typename Vector::value_type, Vector const &)> rhsFunc, std::vector< Vector > &yi, std::vector< Vector > &dyi, bool verbose=false)
Definition: util.hh:110
void inexactSDCExplicitEulerIterationStep(Kaskade::SDCTimeGrid const &grid, std::function< Vector(typename Vector::value_type, Vector const &)> rhsFunc, RealVector const &toleranceVector, typename Vector::value_type rho, Kaskade::NormType norm_t, std::vector< Vector > &yi, std::vector< Vector > &dyi, bool verbose=false)
Definition: util.hh:167