Skip to content
Snippets Groups Projects
Commit 3550423d authored by Elias Pipping's avatar Elias Pipping
Browse files

[Algorit] Use state energy norm to terminate

parent 5c0f35f2
No related branches found
No related tags found
No related merge requests found
...@@ -5,7 +5,8 @@ std::pair<T1, T2> clonePair(std::pair<T1, T2> in) { ...@@ -5,7 +5,8 @@ std::pair<T1, T2> clonePair(std::pair<T1, T2> in) {
return { in.first->clone(), in.second->clone() }; return { in.first->clone(), in.second->clone() };
} }
template <class Factory, class UpdaterPair> class AdaptiveTimeStepper { template <class Factory, class UpdaterPair, class ErrorNorm>
class AdaptiveTimeStepper {
using StateUpdater = typename UpdaterPair::first_type::element_type; using StateUpdater = typename UpdaterPair::first_type::element_type;
using VelocityUpdater = typename UpdaterPair::second_type::element_type; using VelocityUpdater = typename UpdaterPair::second_type::element_type;
using Vector = typename Factory::Vector; using Vector = typename Factory::Vector;
...@@ -13,13 +14,14 @@ template <class Factory, class UpdaterPair> class AdaptiveTimeStepper { ...@@ -13,13 +14,14 @@ template <class Factory, class UpdaterPair> class AdaptiveTimeStepper {
using Nonlinearity = typename ConvexProblem::NonlinearityType; using Nonlinearity = typename ConvexProblem::NonlinearityType;
using MyCoupledTimeStepper = using MyCoupledTimeStepper =
CoupledTimeStepper<Factory, StateUpdater, VelocityUpdater>; CoupledTimeStepper<Factory, StateUpdater, VelocityUpdater, ErrorNorm>;
public: public:
AdaptiveTimeStepper( AdaptiveTimeStepper(
Factory &factory, Dune::ParameterTree const &parset, Factory &factory, Dune::ParameterTree const &parset,
std::shared_ptr<Nonlinearity> globalFriction, UpdaterPair &current, std::shared_ptr<Nonlinearity> globalFriction, UpdaterPair &current,
std::function<void(double, Vector &)> externalForces, std::function<void(double, Vector &)> externalForces,
ErrorNorm const &errorNorm,
std::function<bool(UpdaterPair &, UpdaterPair &)> mustRefine) std::function<bool(UpdaterPair &, UpdaterPair &)> mustRefine)
: finalTime_(parset.get<double>("problem.finalTime")), : finalTime_(parset.get<double>("problem.finalTime")),
relativeTime_(0.0), relativeTime_(0.0),
...@@ -31,10 +33,11 @@ template <class Factory, class UpdaterPair> class AdaptiveTimeStepper { ...@@ -31,10 +33,11 @@ template <class Factory, class UpdaterPair> class AdaptiveTimeStepper {
R1_(clonePair(current_)), R1_(clonePair(current_)),
externalForces_(externalForces), externalForces_(externalForces),
mustRefine_(mustRefine), mustRefine_(mustRefine),
iterationWriter_("iterations", std::fstream::out) { iterationWriter_("iterations", std::fstream::out),
MyCoupledTimeStepper coupledTimeStepper(finalTime_, factory_, parset_, errorNorm_(errorNorm) {
globalFriction_, R1_.first, MyCoupledTimeStepper coupledTimeStepper(
R1_.second, externalForces_); finalTime_, factory_, parset_, globalFriction_, R1_.first, R1_.second,
errorNorm, externalForces_);
stepAndReport("R1", coupledTimeStepper, relativeTime_, relativeTau_); stepAndReport("R1", coupledTimeStepper, relativeTime_, relativeTau_);
iterationWriter_ << std::endl; iterationWriter_ << std::endl;
} }
...@@ -47,18 +50,18 @@ template <class Factory, class UpdaterPair> class AdaptiveTimeStepper { ...@@ -47,18 +50,18 @@ template <class Factory, class UpdaterPair> class AdaptiveTimeStepper {
while (relativeTime_ + relativeTau_ < 1.0) { while (relativeTime_ + relativeTau_ < 1.0) {
R2_ = clonePair(R1_); R2_ = clonePair(R1_);
{ {
MyCoupledTimeStepper coupledTimeStepper(finalTime_, factory_, parset_, MyCoupledTimeStepper coupledTimeStepper(
globalFriction_, R2_.first, finalTime_, factory_, parset_, globalFriction_, R2_.first,
R2_.second, externalForces_); R2_.second, errorNorm_, externalForces_);
stepAndReport("R2", coupledTimeStepper, relativeTime_ + relativeTau_, stepAndReport("R2", coupledTimeStepper, relativeTime_ + relativeTau_,
relativeTau_); relativeTau_);
} }
UpdaterPair C = clonePair(current_); UpdaterPair C = clonePair(current_);
{ {
MyCoupledTimeStepper coupledTimeStepper(finalTime_, factory_, parset_, MyCoupledTimeStepper coupledTimeStepper(
globalFriction_, C.first, finalTime_, factory_, parset_, globalFriction_, C.first, C.second,
C.second, externalForces_); errorNorm_, externalForces_);
stepAndReport("C", coupledTimeStepper, relativeTime_, stepAndReport("C", coupledTimeStepper, relativeTime_,
2.0 * relativeTau_); 2.0 * relativeTau_);
...@@ -81,9 +84,9 @@ template <class Factory, class UpdaterPair> class AdaptiveTimeStepper { ...@@ -81,9 +84,9 @@ template <class Factory, class UpdaterPair> class AdaptiveTimeStepper {
UpdaterPair F2 = clonePair(current_); UpdaterPair F2 = clonePair(current_);
UpdaterPair F1; UpdaterPair F1;
{ {
MyCoupledTimeStepper coupledTimeStepper(finalTime_, factory_, parset_, MyCoupledTimeStepper coupledTimeStepper(
globalFriction_, F2.first, finalTime_, factory_, parset_, globalFriction_, F2.first, F2.second,
F2.second, externalForces_); errorNorm_, externalForces_);
stepAndReport("F1", coupledTimeStepper, relativeTime_, stepAndReport("F1", coupledTimeStepper, relativeTime_,
relativeTau_ / 2.0); relativeTau_ / 2.0);
...@@ -135,4 +138,5 @@ template <class Factory, class UpdaterPair> class AdaptiveTimeStepper { ...@@ -135,4 +138,5 @@ template <class Factory, class UpdaterPair> class AdaptiveTimeStepper {
std::function<void(double, Vector &)> externalForces_; std::function<void(double, Vector &)> externalForces_;
std::function<bool(UpdaterPair &, UpdaterPair &)> mustRefine_; std::function<bool(UpdaterPair &, UpdaterPair &)> mustRefine_;
std::fstream iterationWriter_; std::fstream iterationWriter_;
ErrorNorm const &errorNorm_;
}; };
...@@ -5,23 +5,28 @@ ...@@ -5,23 +5,28 @@
#include "coupledtimestepper.hh" #include "coupledtimestepper.hh"
#include "fixedpointiterator.hh" #include "fixedpointiterator.hh"
template <class Factory, class StateUpdater, class VelocityUpdater> template <class Factory, class StateUpdater, class VelocityUpdater,
CoupledTimeStepper<Factory, StateUpdater, VelocityUpdater>::CoupledTimeStepper( class ErrorNorm>
double finalTime, Factory &factory, Dune::ParameterTree const &parset, CoupledTimeStepper<Factory, StateUpdater, VelocityUpdater, ErrorNorm>::
std::shared_ptr<Nonlinearity> globalFriction, CoupledTimeStepper(double finalTime, Factory &factory,
std::shared_ptr<StateUpdater> stateUpdater, Dune::ParameterTree const &parset,
std::shared_ptr<VelocityUpdater> velocityUpdater, std::shared_ptr<Nonlinearity> globalFriction,
std::function<void(double, Vector &)> externalForces) std::shared_ptr<StateUpdater> stateUpdater,
std::shared_ptr<VelocityUpdater> velocityUpdater,
ErrorNorm const &errorNorm,
std::function<void(double, Vector &)> externalForces)
: finalTime_(finalTime), : finalTime_(finalTime),
factory_(factory), factory_(factory),
parset_(parset), parset_(parset),
globalFriction_(globalFriction), globalFriction_(globalFriction),
stateUpdater_(stateUpdater), stateUpdater_(stateUpdater),
velocityUpdater_(velocityUpdater), velocityUpdater_(velocityUpdater),
externalForces_(externalForces) {} externalForces_(externalForces),
errorNorm_(errorNorm) {}
template <class Factory, class StateUpdater, class VelocityUpdater> template <class Factory, class StateUpdater, class VelocityUpdater,
int CoupledTimeStepper<Factory, StateUpdater, VelocityUpdater>::step( class ErrorNorm>
int CoupledTimeStepper<Factory, StateUpdater, VelocityUpdater, ErrorNorm>::step(
double relativeTime, double relativeTau) { double relativeTime, double relativeTau) {
stateUpdater_->nextTimeStep(); stateUpdater_->nextTimeStep();
velocityUpdater_->nextTimeStep(); velocityUpdater_->nextTimeStep();
...@@ -38,8 +43,8 @@ int CoupledTimeStepper<Factory, StateUpdater, VelocityUpdater>::step( ...@@ -38,8 +43,8 @@ int CoupledTimeStepper<Factory, StateUpdater, VelocityUpdater>::step(
stateUpdater_->setup(tau); stateUpdater_->setup(tau);
velocityUpdater_->setup(ell, tau, newRelativeTime, velocityRHS, velocityUpdater_->setup(ell, tau, newRelativeTime, velocityRHS,
velocityIterate, velocityMatrix); velocityIterate, velocityMatrix);
FixedPointIterator<Factory, StateUpdater, VelocityUpdater> fixedPointIterator( FixedPointIterator<Factory, StateUpdater, VelocityUpdater, ErrorNorm>
factory_, parset_, globalFriction_); fixedPointIterator(factory_, parset_, globalFriction_, errorNorm_);
auto const iterations = auto const iterations =
fixedPointIterator.run(stateUpdater_, velocityUpdater_, velocityMatrix, fixedPointIterator.run(stateUpdater_, velocityUpdater_, velocityMatrix,
velocityRHS, velocityIterate); velocityRHS, velocityIterate);
......
...@@ -6,7 +6,8 @@ ...@@ -6,7 +6,8 @@
#include <dune/common/parametertree.hh> #include <dune/common/parametertree.hh>
template <class Factory, class StateUpdater, class VelocityUpdater> template <class Factory, class StateUpdater, class VelocityUpdater,
class ErrorNorm>
class CoupledTimeStepper { class CoupledTimeStepper {
using Vector = typename Factory::Vector; using Vector = typename Factory::Vector;
using Matrix = typename Factory::Matrix; using Matrix = typename Factory::Matrix;
...@@ -19,6 +20,7 @@ class CoupledTimeStepper { ...@@ -19,6 +20,7 @@ class CoupledTimeStepper {
std::shared_ptr<Nonlinearity> globalFriction, std::shared_ptr<Nonlinearity> globalFriction,
std::shared_ptr<StateUpdater> stateUpdater, std::shared_ptr<StateUpdater> stateUpdater,
std::shared_ptr<VelocityUpdater> velocityUpdater, std::shared_ptr<VelocityUpdater> velocityUpdater,
ErrorNorm const &errorNorm,
std::function<void(double, Vector &)> externalForces); std::function<void(double, Vector &)> externalForces);
int step(double relativeTime, double relativeTau); int step(double relativeTime, double relativeTau);
...@@ -31,5 +33,6 @@ class CoupledTimeStepper { ...@@ -31,5 +33,6 @@ class CoupledTimeStepper {
std::shared_ptr<StateUpdater> stateUpdater_; std::shared_ptr<StateUpdater> stateUpdater_;
std::shared_ptr<VelocityUpdater> velocityUpdater_; std::shared_ptr<VelocityUpdater> velocityUpdater_;
std::function<void(double, Vector &)> externalForces_; std::function<void(double, Vector &)> externalForces_;
ErrorNorm const &errorNorm_;
}; };
#endif #endif
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <dune/common/function.hh> #include <dune/common/function.hh>
#include <dune/solvers/norms/energynorm.hh>
#include <dune/tnnmg/problem-classes/convexproblem.hh> #include <dune/tnnmg/problem-classes/convexproblem.hh>
#include <dune/tectonic/globalfriction.hh> #include <dune/tectonic/globalfriction.hh>
...@@ -18,9 +19,13 @@ ...@@ -18,9 +19,13 @@
using Function = Dune::VirtualFunction<double, double>; using Function = Dune::VirtualFunction<double, double>;
using Factory = SolverFactory< using Factory = SolverFactory<
MY_DIM, MyBlockProblem<ConvexProblem<GlobalFriction<Matrix, Vector>, Matrix>>, MY_DIM,
MyBlockProblem<ConvexProblem<GlobalFriction<Matrix, Vector>, Matrix>>,
Grid>; Grid>;
using MyStateUpdater = StateUpdater<ScalarVector, Vector>; using MyStateUpdater = StateUpdater<ScalarVector, Vector>;
using MyVelocityUpdater = TimeSteppingScheme<Vector, Matrix, Function, MY_DIM>; using MyVelocityUpdater = TimeSteppingScheme<Vector, Matrix, Function, MY_DIM>;
template class CoupledTimeStepper<Factory, MyStateUpdater, MyVelocityUpdater>; using ErrorNorm = EnergyNorm<ScalarMatrix, ScalarVector>;
template class CoupledTimeStepper<Factory, MyStateUpdater, MyVelocityUpdater,
ErrorNorm>;
...@@ -11,4 +11,5 @@ using LocalMatrix = Dune::FieldMatrix<double, MY_DIM, MY_DIM>; ...@@ -11,4 +11,5 @@ using LocalMatrix = Dune::FieldMatrix<double, MY_DIM, MY_DIM>;
using Vector = Dune::BlockVector<LocalVector>; using Vector = Dune::BlockVector<LocalVector>;
using Matrix = Dune::BCRSMatrix<LocalMatrix>; using Matrix = Dune::BCRSMatrix<LocalMatrix>;
using ScalarVector = Dune::BlockVector<Dune::FieldVector<double, 1>>; using ScalarVector = Dune::BlockVector<Dune::FieldVector<double, 1>>;
using ScalarMatrix = Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1>>;
#endif #endif
...@@ -13,10 +13,12 @@ ...@@ -13,10 +13,12 @@
#include "fixedpointiterator.hh" #include "fixedpointiterator.hh"
template <class Factory, class StateUpdater, class VelocityUpdater> template <class Factory, class StateUpdater, class VelocityUpdater,
FixedPointIterator<Factory, StateUpdater, VelocityUpdater>::FixedPointIterator( class ErrorNorm>
Factory &factory, Dune::ParameterTree const &parset, FixedPointIterator<Factory, StateUpdater, VelocityUpdater, ErrorNorm>::
std::shared_ptr<Nonlinearity> globalFriction) FixedPointIterator(Factory &factory, Dune::ParameterTree const &parset,
std::shared_ptr<Nonlinearity> globalFriction,
ErrorNorm const &errorNorm)
: factory_(factory), : factory_(factory),
parset_(parset), parset_(parset),
globalFriction_(globalFriction), globalFriction_(globalFriction),
...@@ -25,10 +27,12 @@ FixedPointIterator<Factory, StateUpdater, VelocityUpdater>::FixedPointIterator( ...@@ -25,10 +27,12 @@ FixedPointIterator<Factory, StateUpdater, VelocityUpdater>::FixedPointIterator(
lambda_(parset.get<double>("v.fpi.lambda")), lambda_(parset.get<double>("v.fpi.lambda")),
velocityMaxIterations_(parset.get<size_t>("v.solver.maximumIterations")), velocityMaxIterations_(parset.get<size_t>("v.solver.maximumIterations")),
velocityTolerance_(parset.get<double>("v.solver.tolerance")), velocityTolerance_(parset.get<double>("v.solver.tolerance")),
verbosity_(parset.get<Solver::VerbosityMode>("v.solver.verbosity")) {} verbosity_(parset.get<Solver::VerbosityMode>("v.solver.verbosity")),
errorNorm_(errorNorm) {}
template <class Factory, class StateUpdater, class VelocityUpdater> template <class Factory, class StateUpdater, class VelocityUpdater,
int FixedPointIterator<Factory, StateUpdater, VelocityUpdater>::run( class ErrorNorm>
int FixedPointIterator<Factory, StateUpdater, VelocityUpdater, ErrorNorm>::run(
std::shared_ptr<StateUpdater> stateUpdater, std::shared_ptr<StateUpdater> stateUpdater,
std::shared_ptr<VelocityUpdater> velocityUpdater, std::shared_ptr<VelocityUpdater> velocityUpdater,
Matrix const &velocityMatrix, Vector const &velocityRHS, Matrix const &velocityMatrix, Vector const &velocityRHS,
...@@ -39,21 +43,12 @@ int FixedPointIterator<Factory, StateUpdater, VelocityUpdater>::run( ...@@ -39,21 +43,12 @@ int FixedPointIterator<Factory, StateUpdater, VelocityUpdater>::run(
LoopSolver<Vector> velocityProblemSolver( LoopSolver<Vector> velocityProblemSolver(
multigridStep, velocityMaxIterations_, velocityTolerance_, &energyNorm, multigridStep, velocityMaxIterations_, velocityTolerance_, &energyNorm,
verbosity_, false); // absolute error verbosity_, false); // absolute error
Vector previousVelocityIterate = velocityIterate;
size_t fixedPointIteration; size_t fixedPointIteration;
ScalarVector alpha;
stateUpdater->extractAlpha(alpha);
for (fixedPointIteration = 0; fixedPointIteration < fixedPointMaxIterations_; for (fixedPointIteration = 0; fixedPointIteration < fixedPointMaxIterations_;
++fixedPointIteration) { ++fixedPointIteration) {
Vector v_m;
velocityUpdater->extractOldVelocity(v_m);
v_m *= 1.0 - lambda_;
Arithmetic::addProduct(v_m, lambda_, velocityIterate);
// solve a state problem
stateUpdater->solve(v_m);
ScalarVector alpha;
stateUpdater->extractAlpha(alpha);
// solve a velocity problem // solve a velocity problem
globalFriction_->updateAlpha(alpha); globalFriction_->updateAlpha(alpha);
ConvexProblem convexProblem(1.0, velocityMatrix, *globalFriction_, ConvexProblem convexProblem(1.0, velocityMatrix, *globalFriction_,
...@@ -63,13 +58,21 @@ int FixedPointIterator<Factory, StateUpdater, VelocityUpdater>::run( ...@@ -63,13 +58,21 @@ int FixedPointIterator<Factory, StateUpdater, VelocityUpdater>::run(
velocityProblemSolver.preprocess(); velocityProblemSolver.preprocess();
velocityProblemSolver.solve(); velocityProblemSolver.solve();
if (energyNorm.diff(previousVelocityIterate, velocityIterate) < Vector v_m;
fixedPointTolerance_) { velocityUpdater->extractOldVelocity(v_m);
v_m *= 1.0 - lambda_;
Arithmetic::addProduct(v_m, lambda_, velocityIterate);
// solve a state problem
stateUpdater->solve(v_m);
ScalarVector newAlpha;
stateUpdater->extractAlpha(newAlpha);
if (errorNorm_.diff(alpha, newAlpha) < fixedPointTolerance_) {
fixedPointIteration++; fixedPointIteration++;
break; break;
} }
alpha = newAlpha;
previousVelocityIterate = velocityIterate;
} }
if (fixedPointIteration == fixedPointMaxIterations_) if (fixedPointIteration == fixedPointMaxIterations_)
DUNE_THROW(Dune::Exception, "FPI failed to converge"); DUNE_THROW(Dune::Exception, "FPI failed to converge");
......
...@@ -8,7 +8,8 @@ ...@@ -8,7 +8,8 @@
#include <dune/solvers/norms/norm.hh> #include <dune/solvers/norms/norm.hh>
#include <dune/solvers/solvers/solver.hh> #include <dune/solvers/solvers/solver.hh>
template <class Factory, class StateUpdater, class VelocityUpdater> template <class Factory, class StateUpdater, class VelocityUpdater,
class ErrorNorm>
class FixedPointIterator { class FixedPointIterator {
using ScalarVector = typename StateUpdater::ScalarVector; using ScalarVector = typename StateUpdater::ScalarVector;
using Vector = typename Factory::Vector; using Vector = typename Factory::Vector;
...@@ -19,7 +20,8 @@ class FixedPointIterator { ...@@ -19,7 +20,8 @@ class FixedPointIterator {
public: public:
FixedPointIterator(Factory &factory, Dune::ParameterTree const &parset, FixedPointIterator(Factory &factory, Dune::ParameterTree const &parset,
std::shared_ptr<Nonlinearity> globalFriction); std::shared_ptr<Nonlinearity> globalFriction,
ErrorNorm const &errorNorm_);
int run(std::shared_ptr<StateUpdater> stateUpdater, int run(std::shared_ptr<StateUpdater> stateUpdater,
std::shared_ptr<VelocityUpdater> velocityUpdater, std::shared_ptr<VelocityUpdater> velocityUpdater,
...@@ -37,5 +39,6 @@ class FixedPointIterator { ...@@ -37,5 +39,6 @@ class FixedPointIterator {
size_t velocityMaxIterations_; size_t velocityMaxIterations_;
double velocityTolerance_; double velocityTolerance_;
Solver::VerbosityMode verbosity_; Solver::VerbosityMode verbosity_;
ErrorNorm const &errorNorm_;
}; };
#endif #endif
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <dune/common/function.hh> #include <dune/common/function.hh>
#include <dune/solvers/norms/energynorm.hh>
#include <dune/tnnmg/problem-classes/convexproblem.hh> #include <dune/tnnmg/problem-classes/convexproblem.hh>
#include <dune/tectonic/globalfriction.hh> #include <dune/tectonic/globalfriction.hh>
...@@ -18,9 +19,13 @@ ...@@ -18,9 +19,13 @@
using Function = Dune::VirtualFunction<double, double>; using Function = Dune::VirtualFunction<double, double>;
using Factory = SolverFactory< using Factory = SolverFactory<
MY_DIM, MyBlockProblem<ConvexProblem<GlobalFriction<Matrix, Vector>, Matrix>>, MY_DIM,
MyBlockProblem<ConvexProblem<GlobalFriction<Matrix, Vector>, Matrix>>,
Grid>; Grid>;
using MyStateUpdater = StateUpdater<ScalarVector, Vector>; using MyStateUpdater = StateUpdater<ScalarVector, Vector>;
using MyVelocityUpdater = TimeSteppingScheme<Vector, Matrix, Function, MY_DIM>; using MyVelocityUpdater = TimeSteppingScheme<Vector, Matrix, Function, MY_DIM>;
template class FixedPointIterator<Factory, MyStateUpdater, MyVelocityUpdater>; using ErrorNorm = EnergyNorm<ScalarMatrix, ScalarVector>;
template class FixedPointIterator<Factory, MyStateUpdater, MyVelocityUpdater,
ErrorNorm>;
...@@ -57,7 +57,7 @@ maximumIterations = 100000 ...@@ -57,7 +57,7 @@ maximumIterations = 100000
verbosity = quiet verbosity = quiet
[v.fpi] [v.fpi]
tolerance = 1e-8 tolerance = 1e-5
maximumIterations = 10000 maximumIterations = 10000
lambda = 0.5 lambda = 0.5
......
...@@ -436,9 +436,10 @@ int main(int argc, char *argv[]) { ...@@ -436,9 +436,10 @@ int main(int argc, char *argv[]) {
size_t timeStep = 1; size_t timeStep = 1;
AdaptiveTimeStepper<NonlinearFactory, UpdaterPair> adaptiveTimeStepper( AdaptiveTimeStepper<NonlinearFactory, UpdaterPair,
factory, parset, myGlobalFriction, current, computeExternalForces, EnergyNorm<ScalarMatrix, ScalarVector>>
mustRefine); adaptiveTimeStepper(factory, parset, myGlobalFriction, current,
computeExternalForces, stateEnergyNorm, mustRefine);
while (!adaptiveTimeStepper.reachedEnd()) { while (!adaptiveTimeStepper.reachedEnd()) {
adaptiveTimeStepper.advance(); adaptiveTimeStepper.advance();
reportTimeStep(adaptiveTimeStepper.getRelativeTime(), reportTimeStep(adaptiveTimeStepper.getRelativeTime(),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment