18#ifndef KASKADE_TIMESTEPPING_EULERSDC_WORKMODEL_HH_
19#define KASKADE_TIMESTEPPING_EULERSDC_WORKMODEL_HH_
31#include <boost/math/special_functions/round.hpp>
32#include <boost/math/tools/minima.hpp>
35#include "dune/common/dynmatrix.hh"
36#include "dune/common/dynvector.hh"
71 template<
class Vector,
class Norm,
class Utils>
94 std::vector<Vector>
const& yCurrent,
95 std::vector<Vector>
const& yNext) = 0;
107 std::vector<Vector>
const& yCurrent,
119 template<
class Vector,
class Norm,
class Utils>
129 std::vector<Vector>
const& y0_, std::vector<Vector>
const& y1_,
130 Norm& norm_, Utils& util_,
147 std::vector<Vector>
const& yCurrent,
148 std::vector<Vector>
const& yNext,
162 std::vector<Vector>
const& yCurrent,
163 std::vector<Vector>
const& yNext,
168 std::vector<Vector>
const& yCurrent,
169 std::vector<Vector>
const& yNext)
172 auto rho = util.sdcContractionFactor(yPrev, yCurrent, yNext, norm);
174 auto maxSDCIterations =
getIterJ(yPrev, yCurrent, yNext, rho);
176 auto mu = computeMu(yPrev, yCurrent, rho, maxSDCIterations, nIntervals, tol, norm);
178 auto alphaVec = util.computeAlphaVec(timePts, integrationMatrix, yPrev, yCurrent, yNext);
180 int itJ = (int) maxSDCIterations;
182 for (
auto i = 0; i < nIntervals; ++i)
184 for (
auto j = 0; j < itJ; ++j)
186 xijMat[i][j] = -1/(mu * std::pow(rho, itJ-1-j) * alphaVec[i]);
195 std::vector<Vector>
const& yCurrent,
199 auto lboundJ = std::log((1-rho) * tol / val) / std::log(rho);
200 return boost::math::round(lboundJ);
206 std::vector<Vector>
const& yCurrent,
207 std::vector<Vector>
const& yNext,
210 auto yTotal = yPrev[0] + yCurrent[0] + yNext[0];
211 return (yTotal[0] + yTotal[1]) * rho;
219 std::vector<Vector> y0;
220 std::vector<Vector> y1;
234 field_type static costFunction(std::vector<Vector>
const& yPrev,
235 std::vector<Vector>
const& yCurrent,
236 std::vector<Vector>
const& yNext,
246 field_type static computeMu(std::vector<Vector>
const& yPrev,
247 std::vector<Vector>
const& yCurrent,
254 field_type computeDerivativeMu(std::vector<Vector>
const& yPrev,
255 std::vector<Vector>
const& yCurrent,
259 field_type derivativeCostFunction(std::vector<Vector>
const& yPrev,
260 std::vector<Vector>
const& yCurrent,
271 field_type computeIterJ(std::vector<Vector>
const& yPrev,
272 std::vector<Vector>
const& yCurrent,
273 std::vector<Vector>
const& yNext,
284 template<
class Vector,
class Norm,
class Utils>
295 std::vector<Vector>
const& y0_, std::vector<Vector>
const& y1_,
296 Norm& norm_, Utils& util_,
306 std::vector<Vector>
const& yCurrent,
310 std::vector<Vector>
const& yCurrent,
311 std::vector<Vector>
const& yNext)
315 auto rho = util.sdcContractionFactor(yPrev, yCurrent, yNext, norm);
318 maxSDCIterations =
getIterJ(yPrev, yCurrent, rho);
319 auto alphaVec = util.computeAlphaVec(timePts, integrationMatrix, yPrev, yCurrent, yNext);
320 auto lambda = computeLambda(yPrev, yCurrent, yNext, maxSDCIterations);
323 int itJ = (int) maxSDCIterations;
325 for (
auto i = 0; i < nIntervals; ++i)
327 auto val = std::pow(alphaVec[i],
d2);
328 for (
auto j = 0; j < itJ; ++j)
330 d1 = (maxSDCIterations-1-j)/(
d2);
331 xijMat[i][j] = lambda * std::pow(rho,
d1) * val;
340 std::vector<Vector>
const& yCurrent,
344 auto lboundJ = std::log((1-rho)*tol/val)/std::log(rho);
345 return boost::math::round(lboundJ);
354 std::vector<Vector> y0;
355 std::vector<Vector> y1;
368 field_type computeA(std::vector<Vector>
const& yPrev,
369 std::vector<Vector>
const& yCurrent,
370 std::vector<Vector>
const& yNext);
372 field_type computeLambda(std::vector<Vector>
const& yPrev,
373 std::vector<Vector>
const& yCurrent,
374 std::vector<Vector>
const& yNext,
390 template<
class Vector,
class Norm,
class Utils>
392 std::vector<Vector>
const& y0_, std::vector<Vector>
const& y1_,
393 Norm& norm_, Utils& util_,
395 field_type tolNewton_,
int maxPrecisionBrent_,
397 : tol(tol_), y0(y0_), y1(y1_),
399 timePts(timePts_), integrationMatrix(integrationMatrix_), nIntervals(timePts.size()-1),
400 maxPrecisionBrent(maxPrecisionBrent_),
401 rhoit(rhoit_), mmin(mmin_){}
407 template<
class Vector,
class Norm,
class Utils>
409 std::vector<Vector>
const& yCurrent,
410 std::vector<Vector>
const& yNext,
416 auto rho = util.sdcContractionFactor(yPrev, yCurrent, yNext, norm);
418 auto c = std::log(normy01);
420 auto k = -mmin * std::log(rhoit);
422 auto rows = tolMat.rows();
423 auto cols = tolMat.cols();
424 for (
auto i = 0u; i < rows; ++i)
426 for (
auto j = 0u; j < cols; ++j)
428 totalCost +=
std::max(k, c - std::log(tolMat[i][j]/std::pow(rho,j)));
437 template<
class Vector,
class Norm,
class Utils>
439 std::vector<Vector>
const& yCurrent,
440 std::vector<Vector>
const& yNext,
443 auto maxSDCIterations = computeIterJ(yPrev, yCurrent, yNext, rho);
444 return boost::math::round(maxSDCIterations);
454 template<
class Vector,
class Norm,
class Utils>
456 std::vector<Vector>
const& yCurrent,
457 std::vector<Vector>
const& yNext,
458 field_type maxSDCIterations,
468 auto rho = util.sdcContractionFactor(yPrev, yCurrent, yNext, norm);
470 auto c = std::log(normy01);
472 auto mu = computeMu(yPrev, yCurrent, rho, maxSDCIterations, nIntervals, tol, norm);
473 auto alphaVec = util.computeAlphaVec(timePts, integrationMatrix, yPrev, yCurrent, yNext);
474 auto alphaProd = computeProduct(alphaVec);
475 auto cost = nIntervals * c + nIntervals * maxSDCIterations * std::log(rho) + nIntervals * std::log(-mu) + std::log(alphaProd);
483 template<
class Vector,
class Norm,
class Utils>
484 typename Vector::value_type Iteration<Vector, Norm, Utils>::computeMu(std::vector<Vector>
const& yPrev,
485 std::vector<Vector>
const& yCurrent,
487 field_type maxSDCIterations,
492 auto mu = -((1-rho) * (maxSDCIterations - 1) * nIntervals)/((1-rho) * tol - std::pow(rho, maxSDCIterations) *
Kaskade::normVecDiff(yPrev,yCurrent,norm));
499 template<
class Vector,
class Norm,
class Utils>
500 typename Vector::value_type Iteration<Vector, Norm, Utils>::computeDerivativeMu(std::vector<Vector>
const& yPrev,
501 std::vector<Vector>
const& yCurrent,
503 field_type maxSDCIterations)
506 auto rhoJ = std::pow(rho, maxSDCIterations);
507 auto dervMu = nIntervals * (1-rho) *
508 (-(1-rho) * tol + val * rhoJ * (1 - (maxSDCIterations - 1) * std::log(rho)))/
509 (std::pow((rhoJ * val - (1-rho) * tol), 2));
516 template<
class Vector,
class Norm,
class Utils>
517 typename Vector::value_type Iteration<Vector, Norm, Utils>::derivativeCostFunction(std::vector<Vector>
const& yPrev,
518 std::vector<Vector>
const& yCurrent,
520 field_type alphaProd,
522 field_type maxSDCIterations)
525 auto mu = computeMu(yPrev, yCurrent, rho, maxSDCIterations, nIntervals, tol, norm);
526 auto dervMu = computeDerivativeMu(yPrev, yCurrent, rho, maxSDCIterations);
527 auto dervCost = nIntervals * c + nIntervals * (2*maxSDCIterations - 1) * std::log(rho) + std::log(alphaProd)
528 + nIntervals * std::log(-mu) + nIntervals * (maxSDCIterations - 1) * dervMu/mu;
535 template<
class Vector,
class Norm,
class Utils>
536 typename Vector::value_type Iteration<Vector, Norm, Utils>::computeProduct(
RealVector const& alpha)
538 field_type alphaProd = 1;
539 for(
auto i = 0u; i < alpha.size(); ++i)
540 alphaProd *= alpha[i];
571 template<
class Vector,
class Norm,
class Utils>
572 typename Vector::value_type Iteration<Vector, Norm, Utils>::computeIterJ(std::vector<Vector>
const& yPrev,
573 std::vector<Vector>
const& yCurrent,
574 std::vector<Vector>
const& yNext,
578 field_type lbmaxSDCIterations = lowerBoundIterJ(yPrev, yCurrent, rho);
579 field_type maxSDCIterations = lbmaxSDCIterations + 1;
581 field_type minCost = costFunction(yPrev, yCurrent, yNext, lbmaxSDCIterations, norm, util, normy01,
582 timePts, integrationMatrix, nIntervals, tol);
583 field_type val = costFunction(yPrev, yCurrent, yNext, maxSDCIterations, norm, util, normy01,
584 timePts, integrationMatrix, nIntervals, tol);
589 val = costFunction(yPrev, yCurrent, yNext, maxSDCIterations, norm, util, normy01,
590 timePts, integrationMatrix, nIntervals, tol);
592 return maxSDCIterations;
604 template<
class Vector,
class Norm,
class Utils>
606 std::vector<Vector>
const& y0_, std::vector<Vector>
const& y1_,
607 Norm& norm_, Utils& util_,
613 timePts(timePts_), integrationMatrix(integrationMatrix_), nIntervals(timePts.size()-1),
619 template<
class Vector,
class Norm,
class Utils>
625 auto rows = tolMat.rows();
626 auto cols = tolMat.cols();
627 for (
auto i = 0u; i < rows; ++i)
629 for (
auto j = 0u; j < cols; ++j)
630 totalCost += 1/std::pow(tolMat[i][j], dim);
639 template<
class Vector,
class Norm,
class Utils>
641 std::vector<Vector>
const& yCurrent,
645 maxSDCIterations = (dim + 1)/(std::log(rho)) * std::log((1-rho)*tol / val);
647 return boost::math::round(maxSDCIterations);
653 template<
class Vector,
class Norm,
class Utils>
655 std::vector<Vector>
const& yCurrent,
656 std::vector<Vector>
const& yNext)
659 auto alphaVec = util.computeAlphaVec(timePts, integrationMatrix, yPrev, yCurrent, yNext);
661 auto alphaTildeVec =
RealVector(alphaVec.size(), 0.0);
663 double d = ((double) dim)/((double) dim + 1);
664 field_type sumAlphaTilde = 0.0;
666 for (
auto i = 0u; i < alphaVec.size(); ++i)
668 alphaTildeVec[i] = std::pow(alphaVec[i], d);
669 sumAlphaTilde += alphaTildeVec[i];
671 return sumAlphaTilde;
677 template<
class Vector,
class Norm,
class Utils>
678 typename Vector::value_type FiniteElementDiscretization<Vector, Norm, Utils>::computeLambda
679 (std::vector<Vector>
const& yPrev,
680 std::vector<Vector>
const& yCurrent,
681 std::vector<Vector>
const& yNext,
682 field_type maxSDCIterations)
685 auto rho = util.sdcContractionFactor(yPrev, yCurrent, yNext, norm);
687 double d = ((double) dim)/((double) dim + 1);
688 field_type tildeRho = std::pow(rho, d);
689 auto sumAlphaTilde = computeA(yPrev, yCurrent, yNext);
691 auto lambda = ((1-rho) * tol - val * std::pow(rho, maxSDCIterations)) * (1 - tildeRho) / ((1 - rho) * (1 - std::pow(tildeRho, maxSDCIterations)) * sumAlphaTilde);
field_type computeCost(RealMatrix const &tolMat)
FiniteElementDiscretization(field_type tol_, std::vector< Vector > const &y0_, std::vector< Vector > const &y1_, Norm &norm_, Utils &util_, RealVector const &timePts_, RealMatrix const &integrationMatrix_, int dim_)
Dune::DynamicMatrix< double > RealMatrix
typename Vector::value_type field_type
virtual field_type lowerBoundIterJ(std::vector< Vector > const &yPrev, std::vector< Vector > const &yCurrent, field_type rho)
virtual RealMatrix const & computeLocalTolerances(std::vector< Vector > const &yPrev, std::vector< Vector > const &yCurrent, std::vector< Vector > const &yNext)
Pure virtual function implemented in derived classes for different work models. Computes the local to...
field_type getIterJ(std::vector< Vector > const &yPrev, std::vector< Vector > const &yCurrent, field_type rho)
virtual ~FiniteElementDiscretization()
field_type computeCost(std::vector< Vector > const &yPrev, std::vector< Vector > const &yCurrent, std::vector< Vector > const &yNext, RealMatrix const &tolMat)
typename Vector::value_type field_type
field_type getIterJ(std::vector< Vector > const &yPrev, std::vector< Vector > const &yCurrent, std::vector< Vector > const &yNext, field_type rho)
virtual RealMatrix const & computeLocalTolerances(std::vector< Vector > const &yPrev, std::vector< Vector > const &yCurrent, std::vector< Vector > const &yNext)
Pure virtual function implemented in derived classes for different work models. Computes the local to...
Dune::DynamicMatrix< double > RealMatrix
Iteration(field_type tol_, std::vector< Vector > const &y0_, std::vector< Vector > const &y1_, Norm &norm_, Utils &util_, RealVector const &timePts_, RealMatrix const &integrationMatrix_, field_type tolNewton_, int maxIterNewton_, field_type rhoit_, int mmin_)
virtual field_type lowerBoundIterJ(std::vector< Vector > const &yPrev, std::vector< Vector > const &yCurrent, field_type rho)
static field_type f(std::vector< Vector > const &yPrev, std::vector< Vector > const &yCurrent, std::vector< Vector > const &yNext, double rho)
Abstract base class of various norms.
Abstract base class for different work models.
Dune::DynamicMatrix< double > RealMatrix
Dune::DynamicVector< double > RealVector
virtual RealMatrix const & computeLocalTolerances(std::vector< Vector > const &yPrev, std::vector< Vector > const &yCurrent, std::vector< Vector > const &yNext)=0
Pure virtual function implemented in derived classes for different work models. Computes the local to...
virtual field_type lowerBoundIterJ(std::vector< Vector > const &yPrev, std::vector< Vector > const &yCurrent, field_type rho)=0
typename Vector::value_type field_type
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Functional::Scalar d1(Assembler &assembler, Functional const &f, typename Functional::AnsatzVars::VariableSet &x, typename Functional::Scalar tolerance=1e-6, typename Functional::Scalar increment=1e-12, bool toFile=false, std::string const &filename=std::string("d1error"))
Functional::Scalar d2(Assembler &assembler, Functional const &f, typename Functional::AnsatzVars::VariableSet const &x, typename Functional::Scalar increment=1e-12, typename Functional::Scalar tolerance=1e-6, bool toFile=false, std::string const &savefilename=std::string("d2error"))
Dune::DynamicVector< double > RealVector
WorkModelType
Enum class to define the norm type is class Norm.
Vector::value_type normVecDiff(std::vector< Vector > const &y0, std::vector< Vector > const &y1, Norm norm)
Some utility functions.
Dune::DynamicMatrix< double > RealMatrix