diff --git a/dune/tectonic/frictionpotential.hh b/dune/tectonic/frictionpotential.hh index 3bf6a11debb3173bbd97c5ff53e0795a2dff76ec..60b474ed767bb14fbbdbbd18565fddd816195db7 100644 --- a/dune/tectonic/frictionpotential.hh +++ b/dune/tectonic/frictionpotential.hh @@ -44,7 +44,7 @@ class TruncatedRateState : public FrictionPotential { return weight * fd.C - weightedNormalStress * coefficientOfFriction(V); } - double second_deriv(double V) const override { + double second_deriv(double V) const override { if (V <= Vmin) return 0; diff --git a/dune/tectonic/localfriction.hh b/dune/tectonic/localfriction.hh index 227b8ff5c3af92f90a9c1c83d6bad6a163c9a079..12b98e5606f3424e477929fead99d77f66ab31ee 100644 --- a/dune/tectonic/localfriction.hh +++ b/dune/tectonic/localfriction.hh @@ -53,7 +53,7 @@ class WrappedScalarFriction : public LocalFriction<dimension> { double regularity(VectorType const &x) const override { double const xnorm = x.two_norm(); - if (xnorm <= 0.0) + if (xnorm < 0.0) return std::numeric_limits<double>::infinity(); return func_.regularity(xnorm); diff --git a/src/multi-body-problem.cfg b/src/multi-body-problem.cfg index 77de9404eafc006ed026f47ebfd43b58a4db1fe1..83476cb76ec11d3bd5d1e9f0375e731d578692ba 100644 --- a/src/multi-body-problem.cfg +++ b/src/multi-body-problem.cfg @@ -32,7 +32,7 @@ V0 = 5e-5 # [m/s] L = 2.25e-5 # [m] initialAlpha = 0 # [ ] stateModel = AgeingLaw -frictionModel = Regularised +frictionModel = Truncated #Regularised [boundary.friction.weakening] a = 0.002 # [ ] b = 0.017 # [ ] @@ -47,10 +47,10 @@ relativeTau = 1e-4 # 1e-6 [timeSteps] scheme = newmark -timeSteps = 1 +timeSteps = 100 [u0.solver] -maximumIterations = 20 +maximumIterations = 100 verbosity = full [a0.solver] diff --git a/src/solverfactorytest.cc b/src/solverfactorytest.cc index 3a4ceebe7d28710f6197627839ffefe651442271..a2c95ae0e3596cbe4fe6f128f870bdc4c872ab6a 100644 --- a/src/solverfactorytest.cc +++ b/src/solverfactorytest.cc @@ -90,6 +90,9 @@ Dune::Solvers::Criterion reductionFactorCriterion( double normOfCorrection = norm.diff(*lastIterate, *iterationStep.getIterate()); double convRate = (normOfOldCorrection > 0) ? normOfCorrection / normOfOldCorrection : 0.0; + if (convRate>1.0) + DUNE_THROW(Dune::Exception, "Solver convergence rate of " + std::to_string(convRate)); + normOfOldCorrection = normOfCorrection; *lastIterate = *iterationStep.getIterate(); @@ -202,18 +205,30 @@ void solveProblem(const ContactNetwork& contactNetwork, refSolver.preprocess(); refSolver.solve(); - /*if (initial) { + //print(refX, "refX: "); + + if (initial) { x = refX; return; - }*/ + } // set up solver factory solver // set up functional - /*auto& globalFriction = contactNetwork.globalFriction(); + auto& globalFriction = contactNetwork.globalFriction(); + + /* std::vector<const Dune::BitSetVector<1>*> nodes; + contactNetwork.frictionNodes(nodes); + print(*nodes[0], "frictionNodes: "); + print(*nodes[1], "frictionNodes: "); + + print(ignore, "ignore: ");*/ + using MyFunctional = Functional<Matrix&, Vector&, std::decay_t<decltype(globalFriction)>&, Vector&, Vector&, typename Matrix::field_type>; - MyFunctional J(mat, rhs, globalFriction, lower, upper);*/ - using MyFunctional = Functional<Matrix&, Vector&, ZeroNonlinearity&, Vector&, Vector&, typename Matrix::field_type>; - MyFunctional J(mat, rhs, ZeroNonlinearity(), lower, upper); + MyFunctional J(mat, rhs, globalFriction, lower, upper); + //using MyFunctional = Functional<Matrix&, Vector&, ZeroNonlinearity, Vector&, Vector&, typename Matrix::field_type>; + //MyFunctional J(mat, rhs, ZeroNonlinearity(), lower, upper); + + //std::cout << "ref energy: " << J(refX) << std::endl; // set up TNMMG solver // dummy solver, uses direct solver for linear correction no matter what is set here @@ -239,7 +254,7 @@ void solveProblem(const ContactNetwork& contactNetwork, LoopSolver<Vector> solver( tnnmgStep.get(), parset.get<size_t>("u0.solver.maximumIterations"), parset.get<double>("u0.solver.tolerance"), &norm, - Solver::FULL, true, &refX); // absolute error + Solver::FULL); //, true, &refX); // absolute error solver.addCriterion( [&](){ @@ -260,7 +275,7 @@ void solveProblem(const ContactNetwork& contactNetwork, solver.addCriterion( [&](){ - return Dune::formatString(" % 12.5e", step.lastDampingFactor()); + return Dune::formatString(" % 12.5e", tnnmgStep->lastDampingFactor()); }, " damping "); @@ -270,6 +285,10 @@ void solveProblem(const ContactNetwork& contactNetwork, }, " truncated "); + + std::vector<double> factors; + solver.addCriterion(reductionFactorCriterion(*tnnmgStep, norm, factors)); + solver.preprocess(); solver.solve(); @@ -527,10 +546,26 @@ void run(Updaters& updaters, ContactNetwork& contactNetwork, Vector totalVelocityIterate; nBodyAssembler.nodalToTransformed(velocityIterates, totalVelocityIterate); + // project in onto admissible set + const size_t blocksize = Vector::block_type::dimension; + for (size_t i=0; i<totalVelocityIterate.size(); i++) { + for (size_t j=0; j<blocksize; j++) { + if (totalVelocityIterate[i][j] < lower[i][j]) { + totalVelocityIterate[i][j] = lower[i][j]; + } + + if (totalVelocityIterate[i][j] > upper[i][j]) { + totalVelocityIterate[i][j] = upper[i][j]; + } + } + } + for (fixedPointIteration = 0; fixedPointIteration < fixedPointMaxIterations; ++fixedPointIteration) { // contribution from nonlinearity + //print(alpha, "alpha: "); + globalFriction.updateAlpha(alpha); solveProblem(contactNetwork, bilinearForm, totalRhs, totalVelocityIterate, totalDirichletNodes, lower, upper, false); @@ -549,6 +584,8 @@ void run(Updaters& updaters, ContactNetwork& contactNetwork, std::vector<Vector> v_rel; relativeVelocities(contactNetwork, totalVelocityIterate, v_rel); + //print(v_rel, "v_rel"); + std::cout << "- State problem set" << std::endl; // solve a state problem diff --git a/src/spatial-solving/solverfactory.cc b/src/spatial-solving/solverfactory.cc index d682cd0594f4065759e0ed3960a4ce2f9f84e289..bca8290aab62771a1ff759ca6b09256e8b6aba4d 100644 --- a/src/spatial-solving/solverfactory.cc +++ b/src/spatial-solving/solverfactory.cc @@ -26,9 +26,9 @@ SolverFactory<Functional, BitVector>::SolverFactory( auto linearSolver_ptr = Dune::Solvers::wrap_own_share<std::decay_t<LinearSolver>>(std::forward<LinearSolver>(linearSolver)); - tnnmgStep_ = std::make_shared<Step>(*J_, dummyIterate_, nonlinearSmoother_, linearSolver_ptr, DefectProjection(), Dune::TNNMG::ScalarObstacleSolver()); + //tnnmgStep_ = std::make_shared<Step>(*J_, dummyIterate_, nonlinearSmoother_, linearSolver_ptr, DefectProjection(), Dune::TNNMG::ScalarObstacleSolver()); - //tnnmgStep_ = std::make_shared<Step>(*J_, dummyIterate_, nonlinearSmoother_, linearSolver_ptr, DefectProjection(), LineSearchSolver()); + tnnmgStep_ = std::make_shared<Step>(*J_, dummyIterate_, nonlinearSmoother_, linearSolver_ptr, DefectProjection(), LineSearchSolver()); tnnmgStep_->setPreSmoothingSteps(parset.get<int>("main.pre")); tnnmgStep_->setIgnore(ignoreNodes); } diff --git a/src/spatial-solving/solverfactory.hh b/src/spatial-solving/solverfactory.hh index 2e1855e05ad051cec6e0315db54d2815adc543e8..1613dd45ba77e1984d69b405d9445eb935982145 100644 --- a/src/spatial-solving/solverfactory.hh +++ b/src/spatial-solving/solverfactory.hh @@ -33,8 +33,8 @@ class SolverFactory { using Linearization = Linearization<Functional, BitVector>; using DefectProjection = typename Dune::TNNMG::ObstacleDefectProjection; - //using Step = Dune::TNNMG::TNNMGStep<Functional, BitVector, Linearization, DefectProjection, LineSearchSolver>; - using Step = Dune::TNNMG::TNNMGStep<Functional, BitVector, Linearization, DefectProjection, Dune::TNNMG::ScalarObstacleSolver>; + using Step = Dune::TNNMG::TNNMGStep<Functional, BitVector, Linearization, DefectProjection, LineSearchSolver>; + //using Step = Dune::TNNMG::TNNMGStep<Functional, BitVector, Linearization, DefectProjection, Dune::TNNMG::ScalarObstacleSolver>; template <class LinearSolver> SolverFactory(const Dune::ParameterTree&, diff --git a/src/spatial-solving/tnnmg/functional.hh b/src/spatial-solving/tnnmg/functional.hh old mode 100644 new mode 100755 index 97dab68876812aefab43d4fe30549bdecf20429e..eff8e22d34a8572122b67b503ed573463117d2d5 --- a/src/spatial-solving/tnnmg/functional.hh +++ b/src/spatial-solving/tnnmg/functional.hh @@ -21,7 +21,7 @@ template<class M, class V, class N, class L, class U, class R> class DirectionalRestriction; -template<class M, class E, class V, class N, class R> +template<class M, class E, class V, class N, class L, class U, class O, class R> class ShiftedFunctional; template <class M, class V, class N, class L, class U, class R> @@ -35,32 +35,82 @@ class Functional; * \tparam V nonlinearity type * \tparam R Range type */ -template<class M, class E, class V, class N, class R> -class ShiftedFunctional : public Dune::TNNMG::ShiftedBoxConstrainedQuadraticFunctional<M,V,R> { - using Base = Dune::TNNMG::ShiftedBoxConstrainedQuadraticFunctional<M,V,R>; +template<class M, class E, class V, class N, class L, class U, class O, class R> +class ShiftedFunctional { public: - using Matrix = M; + using Matrix = std::decay_t<M>; using Eigenvalues = E; - using Vector = V; - using Nonlinearity = N; - using LowerObstacle = Vector; - using UpperObstacle = Vector; + using Vector = std::decay_t<V>; + using Nonlinearity = std::decay_t<N>; + using LowerObstacle = std::decay_t<L>; + using UpperObstacle = std::decay_t<U>; + using Origin = std::decay_t<O>; using Range = R; - ShiftedFunctional(const Matrix& quadraticPart, const Eigenvalues& maxEigenvalues, const Vector& linearPart, const Nonlinearity& phi, const LowerObstacle& lowerObstacle, const UpperObstacle& upperObstacle, const Vector& origin) : - Base(quadraticPart, linearPart, lowerObstacle, upperObstacle, origin), - phi_(phi), - maxEigenvalues_(maxEigenvalues) + template <class MM, class VV, class LL, class UU, class OO> + ShiftedFunctional(MM&& matrix, const Eigenvalues& maxEigenvalues, VV&& linearPart, const Nonlinearity& phi, + LL&& lower, UU&& upper, OO&& origin) : + quadraticPart_(std::forward<MM>(matrix)), + maxEigenvalues_(maxEigenvalues), + originalLinearPart_(std::forward<VV>(linearPart)), + phi_(phi), + originalLowerObstacle_(std::forward<LL>(lower)), + originalUpperObstacle_(std::forward<UU>(upper)), + origin_(std::forward<OO>(origin)) {} Range operator()(const Vector& v) const { - auto temp = Base::Base::origin(); - temp += v; - if (checkInsideBox(temp, this->originalLowerObstacle(), this->originalUpperObstacle())) - return Base::Base::operator()(v) + phi_.operator()(temp); + auto w = origin(); + w += v; + if (Dune::TNNMG::checkInsideBox(w, originalLowerObstacle(), originalUpperObstacle())) { + Vector temp; + Dune::Solvers::resizeInitializeZero(temp,v); + quadraticPart().umv(w, temp); + temp *= 0.5; + temp -= originalLinearPart(); + return temp*w + phi()(w); + } return std::numeric_limits<Range>::max(); + + /*Vector temp; + Dune::Solvers::resizeInitializeZero(temp,v); + quadraticPart().umv(w, temp); + temp *= 0.5; + temp -= originalLinearPart(); + return temp*w + phi()(w);*/ + } + + const Matrix& quadraticPart() const + { + return quadraticPart_.get(); + } + + const Vector& originalLinearPart() const + { + return originalLinearPart_.get(); + } + + const Origin& origin() const + { + return origin_.get(); + } + + void updateOrigin() + {} + + void updateOrigin(std::size_t i) + {} + + const LowerObstacle& originalLowerObstacle() const + { + return originalLowerObstacle_.get(); + } + + const UpperObstacle& originalUpperObstacle() const + { + return originalUpperObstacle_.get(); } const auto& phi() const { @@ -72,13 +122,17 @@ class ShiftedFunctional : public Dune::TNNMG::ShiftedBoxConstrainedQuadraticFunc } protected: - const Nonlinearity& phi_; + Dune::Solvers::ConstCopyOrReference<M> quadraticPart_; const Eigenvalues& maxEigenvalues_; -}; - + Dune::Solvers::ConstCopyOrReference<V> originalLinearPart_; + const Nonlinearity& phi_; + Dune::Solvers::ConstCopyOrReference<L> originalLowerObstacle_; + Dune::Solvers::ConstCopyOrReference<U> originalUpperObstacle_; + Dune::Solvers::ConstCopyOrReference<O> origin_; +}; /** \brief Coordinate restriction of box constrained quadratic functional with nonlinearity; * mainly used for line search step in TNNMG algorithm @@ -183,11 +237,11 @@ class FirstOrderFunctional { using field_type = typename V::field_type; public: - template <class NN, class LL, class UU, class OO, class DD> + template <class LL, class UU, class OO, class DD> FirstOrderFunctional( const Range& maxEigenvalue, const Range& linearPart, - NN&& phi, + const Nonlinearity& phi, LL&& lower, UU&& upper, OO&& origin, @@ -198,7 +252,7 @@ class FirstOrderFunctional { upper_(std::forward<UU>(upper)), origin_(std::forward<OO>(origin)), direction_(std::forward<DD>(direction)), - phi_(std::forward<NN>(phi)) { + phi_(phi) { // set defect obstacles defectLower_ = -std::numeric_limits<field_type>::max(); @@ -206,15 +260,15 @@ class FirstOrderFunctional { Dune::TNNMG::directionalObstacles(origin_.get(), direction_.get(), lower_.get(), upper_.get(), defectLower_, defectUpper_); // set domain - phi_.get().directionalDomain(origin_.get(), direction_.get(), domain_); + phi_.directionalDomain(origin_.get(), direction_.get(), domain_); - /*if (domain_[0] < defectLower_) { + if (domain_[0] < defectLower_) { domain_[0] = defectLower_; } if (domain_[1] > defectUpper_) { domain_[1] = defectUpper_; - }*/ + } } Range operator()(const Vector& v) const @@ -227,7 +281,7 @@ class FirstOrderFunctional { Vector uxv = origin_.get(); Dune::MatrixVector::addProduct(uxv, x, direction_.get()); - phi_.get().directionalSubDiff(uxv, direction_.get(), Di); + phi_.directionalSubDiff(uxv, direction_.get(), Di); const auto Axmb = quadraticPart_ * x - linearPart_; Di[0] += Axmb; @@ -273,7 +327,7 @@ class FirstOrderFunctional { Dune::Solvers::ConstCopyOrReference<Vector> origin_; Dune::Solvers::ConstCopyOrReference<Vector> direction_; - Dune::Solvers::ConstCopyOrReference<N> phi_; + const Nonlinearity& phi_; Interval domain_; @@ -285,10 +339,10 @@ class FirstOrderFunctional { // but gcc-4.9.2 shipped with debian jessie does not accept // inline friends with auto return type due to bug-59766. // Notice, that this is fixed in gcc-4.9.3. -template<class Index, class M, class E, class V, class Nonlinearity, class R> -auto coordinateRestriction(const ShiftedFunctional<M, E, V, Nonlinearity, R>& f, const Index& i) +template<class GlobalShiftedFunctional, class Index> +auto coordinateRestriction(const GlobalShiftedFunctional& f, const Index& i) { - using Range = R; + using Range = typename GlobalShiftedFunctional::Range; using LocalMatrix = std::decay_t<decltype(f.quadraticPart()[i][i])>; using LocalVector = std::decay_t<decltype(f.originalLinearPart()[i])>; using LocalLowerObstacle = std::decay_t<decltype(f.originalLowerObstacle()[i])>; @@ -299,7 +353,8 @@ auto coordinateRestriction(const ShiftedFunctional<M, E, V, Nonlinearity, R>& f, const LocalMatrix* Aii_p = nullptr; - //print(f.origin(), "f.origin: "); + //print(f.originalLinearPart(), "f.linearPart: "); + //print(f.quadraticPart(), "f.quadraticPart: "); LocalVector ri = f.originalLinearPart()[i]; const auto& Ai = f.quadraticPart()[i]; @@ -311,9 +366,15 @@ auto coordinateRestriction(const ShiftedFunctional<M, E, V, Nonlinearity, R>& f, Dune::TNNMG::Imp::mmv(Aij, f.origin()[j], ri, Dune::PriorityTag<1>()); }); - auto&& phii = f.phi().restriction(i); + //print(*Aii_p, "Aii_p:"); + //print(ri, "ri:"); + + //print(f.originalLowerObstacle()[i], "lower:"); + //print(f.originalUpperObstacle()[i], "upper:"); + + auto& phii = f.phi().restriction(i); - return ShiftedFunctional<LocalMatrix, Range, LocalVector, decltype(phii), Range>(*Aii_p, f.maxEigenvalues()[i], std::move(ri), std::move(phii), f.originalLowerObstacle()[i], f.originalUpperObstacle()[i], f.origin()[i]); + return ShiftedFunctional<LocalMatrix&, Range, LocalVector, std::decay_t<decltype(phii)>, LocalLowerObstacle&, LocalUpperObstacle&, LocalVector&, Range>(*Aii_p, f.maxEigenvalues()[i], std::move(ri), phii, f.originalLowerObstacle()[i], f.originalUpperObstacle()[i], f.origin()[i]); } @@ -378,8 +439,12 @@ class Functional : public Dune::TNNMG::BoxConstrainedQuadraticFunctional<M, V, L Range operator()(const Vector& v) const { - if (Dune::TNNMG::checkInsideBox(v, this->lower_.get(), this->upper_.get())) - return Dune::TNNMG::QuadraticFunctional<M,V,R>::operator()(v) + phi_.get().operator()(v); + //print(v, "v:"); + //print(this->lowerObstacle(), "lower: "); + //print(this->upperObstacle(), "upper: "); + //std::cout << Dune::TNNMG::checkInsideBox(v, this->lowerObstacle(), this->upperObstacle()) << " " << Dune::TNNMG::QuadraticFunctional<M,V,R>::operator()(v) << " " << phi_.get().operator()(v) << std::endl; + if (Dune::TNNMG::checkInsideBox(v, this->lowerObstacle(), this->upperObstacle())) + return Dune::TNNMG::QuadraticFunctional<M,V,R>::operator()(v) + phi_.get()(v); return std::numeric_limits<Range>::max(); } @@ -390,9 +455,9 @@ class Functional : public Dune::TNNMG::BoxConstrainedQuadraticFunctional<M, V, L } friend auto shift(const Functional& f, const Vector& origin) - -> ShiftedFunctional<Matrix, Eigenvalues, Vector, Nonlinearity, Range> + -> ShiftedFunctional<Matrix&, Eigenvalues, Vector&, Nonlinearity&, LowerObstacle&, UpperObstacle&, Vector&, Range> { - return ShiftedFunctional<Matrix, Eigenvalues, Vector, Nonlinearity, Range>(f.quadraticPart(), f.maxEigenvalues(), f.linearPart(), f.phi(), f.lowerObstacle(), f.upperObstacle(), origin); + return ShiftedFunctional<Matrix&, Eigenvalues, Vector&, Nonlinearity&, LowerObstacle&, UpperObstacle&, Vector&, Range>(f.quadraticPart(), f.maxEigenvalues(), f.linearPart(), f.phi(), f.lowerObstacle(), f.upperObstacle(), origin); } }; diff --git a/src/spatial-solving/tnnmg/linearization.hh b/src/spatial-solving/tnnmg/linearization.hh index bc6095a8cb03395cfa236332a269f419962ea203..362dcec47a4daa8a6b43432339368980ed3b3586 100644 --- a/src/spatial-solving/tnnmg/linearization.hh +++ b/src/spatial-solving/tnnmg/linearization.hh @@ -33,7 +33,14 @@ class Linearization { template <class T> void determineRegularityTruncation(const Vector& x, BitVector& truncationFlags, const T& truncationTolerance) { + //std::cout << "x: " << x << std::endl; + for (size_t i = 0; i < x.size(); ++i) { + //if (truncationFlags[i].all()) + // continue; + + //std::cout << f_.phi().regularity(i, x[i]) << " xnorm: " << x[i].two_norm() << std::endl; + if (f_.phi().regularity(i, x[i]) > truncationTolerance) { truncationFlags[i] = true; } @@ -90,7 +97,8 @@ class Linearization { Linearization(const F& f, const BitVector& ignore) : f_(f), ignore_(ignore), - truncationTolerance_(1e-10) + obstacleTruncationTolerance_(1e-10), + regularityTruncationTolerance_(1e8) {} void bind(const Vector& x) { @@ -101,11 +109,28 @@ class Linearization { // determine which components to truncate // ---------------- - truncationFlags_ = ignore_; + BitVector obstacleTruncationFlags = ignore_; + BitVector regularityTruncationFlags = ignore_; + + //std::cout << "ignore truncation: " << truncationFlags_.count(); + + determineTruncation(x, f_.lowerObstacle(), f_.upperObstacle(), obstacleTruncationFlags, obstacleTruncationTolerance_); // obstacle truncation + + //std::cout << " obstacle truncation: " << truncationFlags_.count(); + //std::cout << " " << obstacleTruncationTolerance_; - determineTruncation(x, f_.lowerObstacle(), f_.upperObstacle(), truncationFlags_, truncationTolerance_); // obstacle truncation - determineRegularityTruncation(x, truncationFlags_, truncationTolerance_); // truncation due to regularity deficit of nonlinearity + determineRegularityTruncation(x, regularityTruncationFlags, regularityTruncationTolerance_); // truncation due to regularity deficit of nonlinearity + //std::cout << " regularity truncation: " << truncationFlags_.count() << std::endl; + //std::cout << " " << regularityTruncationTolerance_; + + truncationFlags_ = obstacleTruncationFlags; + size_t blocksize = truncationFlags_[0].size(); + for (size_t i=0; i<truncationFlags_.size(); i++) { + for (size_t j=0; j<blocksize; j++) { + //truncationFlags_[i][j] = truncationFlags_[i][j] and regularityTruncationFlags[i][j]; + } + } // compute hessian // --------------- @@ -126,11 +151,15 @@ class Linearization { hessian_[i][it.index()] += *it; } + truncateMatrix(hessian_, obstacleTruncationFlags, obstacleTruncationFlags); + //print(hessian_, "Hessian:"); //std::cout << "--------" << (double) hessian_[21][21] << "------------" << std::endl; // nonlinearity part phi.addHessian(x, hessian_); + truncateMatrix(hessian_, regularityTruncationFlags, regularityTruncationFlags); + // compute gradient // ---------------- @@ -144,9 +173,11 @@ class Linearization { // -grad is needed for Newton step negativeGradient_ *= -1; - // truncate gradient and hessian + // truncate gradient truncateVector(negativeGradient_, truncationFlags_); - truncateMatrix(hessian_, truncationFlags_, truncationFlags_); + + //print(hessian_, "hessian: "); + //print(negativeGradient_, "negativeGradient: "); } @@ -171,7 +202,8 @@ class Linearization { const F& f_; const BitVector& ignore_; - double truncationTolerance_; + double obstacleTruncationTolerance_; + double regularityTruncationTolerance_; Vector negativeGradient_; Matrix hessian_; diff --git a/src/spatial-solving/tnnmg/linesearchsolver.hh b/src/spatial-solving/tnnmg/linesearchsolver.hh index 93471396dc10a5e89299f59e5d3a6928ddd719fb..587c81567d57ba7f49e90243018ba692b18c02e2 100644 --- a/src/spatial-solving/tnnmg/linesearchsolver.hh +++ b/src/spatial-solving/tnnmg/linesearchsolver.hh @@ -18,28 +18,24 @@ class LineSearchSolver void operator()(Vector& x, const Functional& f, const BitVector& ignore) const { x = 0; - Dune::Solvers::Interval<double> D; + if (ignore) + return; + + /*Dune::Solvers::Interval<double> D; D = f.subDifferential(0); if (D[1] > 0) // NOTE: Numerical instability can actually get us here return; - +*/ if (almost_equal(f.domain()[0], f.domain()[1], 2)) { x = f.domain()[0]; return; } - if (not ignore) { - int bisectionsteps = 0; - const Bisection globalBisection; - // std::cout << "LineSearchSolver: starting bisection" << std::endl; - x = globalBisection.minimize(f, 1.0, 0.0, bisectionsteps); + int bisectionsteps = 0; + const Bisection globalBisection(0.0, 1.0, 0.0, 0.0);; - x = f.domain().projectIn(x); - - - //std::cout << "LineSearchSolver: bisection terminated" << std::endl; - // x = globalBisection.minimize(f, vNorm, 0.0, bisectionsteps) / vNorm; // used rescaled v in f? - } + x = globalBisection.minimize(f, 0.0, 0.0, bisectionsteps); + //x = f.domain().projectIn(x); } }; diff --git a/src/spatial-solving/tnnmg/localbisectionsolver.hh b/src/spatial-solving/tnnmg/localbisectionsolver.hh index b24eb8ee6f84da9652d11924ea1a44056a1836c8..8df8265c5adf5fc8ee2ed7c5134f6b3524c1323a 100644 --- a/src/spatial-solving/tnnmg/localbisectionsolver.hh +++ b/src/spatial-solving/tnnmg/localbisectionsolver.hh @@ -30,6 +30,7 @@ class LocalBisectionSolver auto origin = f.origin(); auto linearPart = f.originalLinearPart(); + Dune::MatrixVector::addProduct(linearPart, maxEigenvalue, origin); for (size_t j = 0; j < ignore.size(); ++j) @@ -43,16 +44,31 @@ class LocalBisectionSolver return; linearPart /= linearPartNorm; + //std::cout << "maxEigenvalue " << maxEigenvalue << std::endl; + //std::cout << "linearPartNorm " << linearPartNorm << std::endl; + //print(origin, "origin:"); + //print(linearPart, "linearPart:"); + using Nonlinearity = std::decay_t<decltype(f.phi())>; using Range = std::decay_t<decltype(f.maxEigenvalues())>; using FirstOrderFunctional = FirstOrderFunctional<Nonlinearity, Vector, Range>; - FirstOrderFunctional firstOrderFunctional(maxEigenvalue, linearPartNorm, f.phi(), f.originalLowerObstacle(), f.originalUpperObstacle(), origin, linearPart); + auto lower = f.originalLowerObstacle(); + auto upper = f.originalUpperObstacle(); + + //print(lower, "lower:"); + //print(upper, "upper:"); + + FirstOrderFunctional firstOrderFunctional(maxEigenvalue, linearPartNorm, f.phi(), + lower, upper, + origin, linearPart); + + //std::cout << "lower: " << firstOrderFunctional.lowerObstacle() << " upper: " << firstOrderFunctional.upperObstacle() << std::endl; // scalar obstacle solver without nonlinearity typename Functional::Range alpha; - /*Dune::TNNMG::ScalarObstacleSolver obstacleSolver; - obstacleSolver(alpha, firstOrderFunctional, false);*/ + //Dune::TNNMG::ScalarObstacleSolver obstacleSolver; + //obstacleSolver(alpha, firstOrderFunctional, false); //direction *= alpha; @@ -71,31 +87,36 @@ class LocalBisectionSolver auto D = directionalF.subDifferential(0); std::cout << "subDiff at x: " << D[0] << " " << D[1] << std::endl;*/ + //std::cout << "domain: " << firstOrderFunctional.domain()[0] << " " << firstOrderFunctional.domain()[1] << std::endl; + + const auto& domain = firstOrderFunctional.domain(); if (std::abs(domain[0]-domain[1])>safety) { int bisectionsteps = 0; const Bisection globalBisection(0.0, 1.0, 0.0, 0.0); alpha = globalBisection.minimize(firstOrderFunctional, 0.0, 0.0, bisectionsteps); - - if (alpha < firstOrderFunctional.lowerObstacle() ) { - alpha = firstOrderFunctional.lowerObstacle(); - } - - if (alpha > firstOrderFunctional.upperObstacle() ) { - alpha = firstOrderFunctional.upperObstacle(); - } + } else { + alpha = domain[0]; } linearPart *= alpha; + //std::cout << linearPart << std::endl; + #ifdef NEW_TNNMG_COMPUTE_ITERATES_DIRECTLY - x = origin; - x += linearPart; + if (std::abs(alpha)> safety) { + x = origin; + x += linearPart; + } else { + x = f.origin(); + } #else - //x = origin; - //x -= f.origin(); - x = linearPart; + if (std::abs(alpha)> safety) { + x = origin; + x += linearPart; + x -= f.origin(); + } #endif } }; diff --git a/src/time-stepping/rate/newmark.cc b/src/time-stepping/rate/newmark.cc index 0ec590126ea5fd19755e6699324a259b5b5daeb8..dec66b98d732c2589b7bc79c4c371a47de336714 100644 --- a/src/time-stepping/rate/newmark.cc +++ b/src/time-stepping/rate/newmark.cc @@ -108,7 +108,7 @@ void Newmark<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::setup( } } } - //sprint(iterate, "iterate:"); + //print(iterate, "iterate:"); } template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes>