Skip to content
Snippets Groups Projects
Commit 14233a9d authored by podlesny's avatar podlesny
Browse files

.

parent 19dcc1be
No related branches found
No related tags found
No related merge requests found
# -*- mode:conf -*- # -*- mode:conf -*-
[boundary.friction] [boundary.friction]
smallestDiameter = 0.01 # 2e-3 [m] smallestDiameter = 0.5 # 2e-3 [m]
[timeSteps] [timeSteps]
refinementTolerance = 1e-5 # 1e-5 refinementTolerance = 1e-5 # 1e-5
......
...@@ -11,7 +11,7 @@ vtk.write = true ...@@ -11,7 +11,7 @@ vtk.write = true
[problem] [problem]
finalTime = 100 # [s] #1000 finalTime = 100 # [s] #1000
bodyCount = 4 bodyCount = 2
[body] [body]
bulkModulus = 0.5e5 # [Pa] bulkModulus = 0.5e5 # [Pa]
......
...@@ -16,10 +16,12 @@ ...@@ -16,10 +16,12 @@
#include <dune/tnnmg/functionals/boxconstrainedquadraticfunctional.hh> #include <dune/tnnmg/functionals/boxconstrainedquadraticfunctional.hh>
#include "../../utils/debugutils.hh"
template<class M, class V, class N, class L, class U, class R> template<class M, class V, class N, class L, class U, class R>
class DirectionalRestriction; class DirectionalRestriction;
template<class M, class V, class N, class R> template<class M, class E, class V, class N, class R>
class ShiftedFunctional; class ShiftedFunctional;
template <class M, class V, class N, class L, class U, class R> template <class M, class V, class N, class L, class U, class R>
...@@ -33,21 +35,23 @@ class Functional; ...@@ -33,21 +35,23 @@ class Functional;
* \tparam V nonlinearity type * \tparam V nonlinearity type
* \tparam R Range type * \tparam R Range type
*/ */
template<class M, class V, class N, class R> template<class M, class E, class V, class N, class R>
class ShiftedFunctional : public Dune::TNNMG::ShiftedBoxConstrainedQuadraticFunctional<M,V,R> { class ShiftedFunctional : public Dune::TNNMG::ShiftedBoxConstrainedQuadraticFunctional<M,V,R> {
using Base = Dune::TNNMG::ShiftedBoxConstrainedQuadraticFunctional<M,V,R>; using Base = Dune::TNNMG::ShiftedBoxConstrainedQuadraticFunctional<M,V,R>;
public: public:
using Matrix = M; using Matrix = M;
using Eigenvalues = E;
using Vector = V; using Vector = V;
using Nonlinearity = N; using Nonlinearity = N;
using LowerObstacle = Vector; using LowerObstacle = Vector;
using UpperObstacle = Vector; using UpperObstacle = Vector;
using Range = R; using Range = R;
ShiftedFunctional(const Matrix& quadraticPart, const Vector& linearPart, const Nonlinearity& phi, const LowerObstacle& lowerObstacle, const UpperObstacle& upperObstacle, const Vector& origin) : 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), Base(quadraticPart, linearPart, lowerObstacle, upperObstacle, origin),
phi_(phi) phi_(phi),
maxEigenvalues_(maxEigenvalues)
{} {}
Range operator()(const Vector& v) const Range operator()(const Vector& v) const
...@@ -63,14 +67,13 @@ class ShiftedFunctional : public Dune::TNNMG::ShiftedBoxConstrainedQuadraticFunc ...@@ -63,14 +67,13 @@ class ShiftedFunctional : public Dune::TNNMG::ShiftedBoxConstrainedQuadraticFunc
return phi_; return phi_;
} }
friend auto directionalRestriction(const ShiftedFunctional& f, const Vector& origin, const Vector& direction) const auto& maxEigenvalues() const {
-> DirectionalRestriction<Matrix, Vector, Nonlinearity, LowerObstacle, UpperObstacle, Range> return maxEigenvalues_;
{
return DirectionalRestriction<Matrix, Vector, Nonlinearity, LowerObstacle, UpperObstacle, Range>(f.quadraticPart(), f.originalLinearPart(), f.phi(), f.originalLowerObstacle(), f.originalUpperObstacle(), origin, direction);
} }
protected: protected:
const Nonlinearity& phi_; const Nonlinearity& phi_;
const Eigenvalues& maxEigenvalues_;
}; };
...@@ -167,80 +170,56 @@ class DirectionalRestriction : ...@@ -167,80 +170,56 @@ class DirectionalRestriction :
* \tparam U Upper obstacle type * \tparam U Upper obstacle type
* \tparam R Range type * \tparam R Range type
*/ */
/*template<class V, class N, class L, class U, class O, class D, class R> template<class N, class V, class R>
class FirstOrderModelFunctional { class FirstOrderFunctional {
using Interval = typename Dune::Solvers::Interval<R>; using Interval = typename Dune::Solvers::Interval<R>;
public: public:
using Vector = std::decay_t<V>;
using Nonlinearity = std::decay_t<N>; using Nonlinearity = std::decay_t<N>;
using LowerObstacle = std::decay_t<L>; using Vector = V;
using UpperObstacle = std::decay_t<U>; using LowerObstacle = V;
using UpperObstacle = V;
using Range = R; using Range = R;
using field_type = typename Vector::field_type; using field_type = typename V::field_type;
public: public:
template <class VV1, class NN, class LL, class UU, class VV2> template <class NN, class LL, class UU, class OO, class DD>
FirstOrderModelFunctional( FirstOrderFunctional(
const Range& maxEigenvalue, const Range& maxEigenvalue,
VV1&& linearTerm, const Range& linearPart,
NN&& phi, NN&& phi,
LL&& lower, LL&& lower,
UU&& upper, UU&& upper,
VV2&& origin) : OO&& origin,
maxEigenvalue_(maxEigenvalue), DD&& direction) :
linearTerm_(std::forward<VV1>(linearTerm)), quadraticPart_(maxEigenvalue),
linearPart_(linearPart),
lower_(std::forward<LL>(lower)), lower_(std::forward<LL>(lower)),
upper_(std::forward<UU>(upper)), upper_(std::forward<UU>(upper)),
origin_(std::forward<VV2>(origin)), origin_(std::forward<OO>(origin)),
//direction_(linearTerm_), direction_(std::forward<DD>(direction)),
phi_(std::forward<NN>(phi)) { phi_(std::forward<NN>(phi)) {
auto& origin = origin_.get();
auto& direction = direction_.get();
auto v = ri;
double const vnorm = v.two_norm();
if (vnorm > 1.0)
v /= vnorm;
// set defect obstacles // set defect obstacles
defectLower_ = -std::numeric_limits<field_type>::max(); defectLower_ = -std::numeric_limits<field_type>::max();
defectUpper_ = std::numeric_limits<field_type>::max(); defectUpper_ = std::numeric_limits<field_type>::max();
Dune::TNNMG::directionalObstacles(origin, direction, lower_.get(), upper_.get(), defectLower_, defectUpper_); Dune::TNNMG::directionalObstacles(origin_.get(), direction_.get(), lower_.get(), upper_.get(), defectLower_, defectUpper_);
// set domain // set domain
phi_.get().directionalDomain(origin, direction, domain_); phi_.get().directionalDomain(origin_.get(), direction_.get(), domain_);
if (domain_[0] < defectLower_) { /*if (domain_[0] < defectLower_) {
domain_[0] = defectLower_; domain_[0] = defectLower_;
} }
if (domain_[1] > defectUpper_) { if (domain_[1] > defectUpper_) {
domain_[1] = defectUpper_; domain_[1] = defectUpper_;
} }*/
} }
template <class BitVector>
auto setIgnore(const BitVector& ignore) const {
Vector direction = direction_.get();
Vector origin = origin_.get();
// Dune::Solvers::resizeInitializeZero(direction, linearPart());
for (size_t j = 0; j < ignore.size(); ++j)
if (ignore[j])
direction[j] = 0; // makes sure result remains in subspace after correction
else
origin[j] = 0; // shift affine offset
// set quadratic and linear parts of functional
quadraticPart_ = maxEigenvalue_ * direction.two_norm2();
linearPart_ = linearTerm_.get() * direction;
}
Range operator()(const Vector& v) const Range operator()(const Vector& v) const
{ {
DUNE_THROW(Dune::NotImplemented, "Evaluation of FirstOrderModelFunctional not implemented"); DUNE_THROW(Dune::NotImplemented, "Evaluation of FirstOrderFunctional not implemented");
} }
auto subDifferential(double x) const { auto subDifferential(double x) const {
...@@ -261,49 +240,53 @@ class FirstOrderModelFunctional { ...@@ -261,49 +240,53 @@ class FirstOrderModelFunctional {
return domain_; return domain_;
} }
const Vector& origin() const { const auto& origin() const {
return origin_.get(); return origin_.get();
} }
const Vector& direction() const { const auto& direction() const {
return direction_.get(); return direction_.get();
} }
const field_type& defectLower() const { const auto& lowerObstacle() const {
return defectLower_; return defectLower_;
} }
const field_type& defectUpper() const { const auto& upperObstacle() const {
return defectUpper_; return defectUpper_;
} }
const auto& quadraticPart() const {
return quadraticPart_;
}
const auto& linearPart() const {
return linearPart_;
}
private: private:
Dune::Solvers::ConstCopyOrReference<V> linearTerm_; const Range quadraticPart_;
Dune::Solvers::ConstCopyOrReference<L> lower_; const Range linearPart_;
Dune::Solvers::ConstCopyOrReference<U> upper_;
Dune::Solvers::ConstCopyOrReference<LowerObstacle> lower_;
Dune::Solvers::ConstCopyOrReference<UpperObstacle> upper_;
Dune::Solvers::ConstCopyOrReference<O> origin_; Dune::Solvers::ConstCopyOrReference<Vector> origin_;
Dune::Solvers::ConstCopyOrReference<D> direction_; Dune::Solvers::ConstCopyOrReference<Vector> direction_;
Dune::Solvers::ConstCopyOrReference<N> phi_; Dune::Solvers::ConstCopyOrReference<N> phi_;
Interval domain_; Interval domain_;
Range maxEigenvalue_;
field_type quadraticPart_;
field_type linearPart_;
field_type defectLower_; field_type defectLower_;
field_type defectUpper_; field_type defectUpper_;
};*/ };
// \ToDo This should be an inline friend of ShiftedBoxConstrainedQuadraticFunctional // \ToDo This should be an inline friend of ShiftedBoxConstrainedQuadraticFunctional
// but gcc-4.9.2 shipped with debian jessie does not accept // but gcc-4.9.2 shipped with debian jessie does not accept
// inline friends with auto return type due to bug-59766. // inline friends with auto return type due to bug-59766.
// Notice, that this is fixed in gcc-4.9.3. // Notice, that this is fixed in gcc-4.9.3.
template<class Index, class M, class V, class Nonlinearity, class R> template<class Index, class M, class E, class V, class Nonlinearity, class R>
auto coordinateRestriction(const ShiftedFunctional<M, V, Nonlinearity, R>& f, const Index& i) auto coordinateRestriction(const ShiftedFunctional<M, E, V, Nonlinearity, R>& f, const Index& i)
{ {
using Range = R; using Range = R;
using LocalMatrix = std::decay_t<decltype(f.quadraticPart()[i][i])>; using LocalMatrix = std::decay_t<decltype(f.quadraticPart()[i][i])>;
...@@ -316,6 +299,8 @@ auto coordinateRestriction(const ShiftedFunctional<M, V, Nonlinearity, R>& f, co ...@@ -316,6 +299,8 @@ auto coordinateRestriction(const ShiftedFunctional<M, V, Nonlinearity, R>& f, co
const LocalMatrix* Aii_p = nullptr; const LocalMatrix* Aii_p = nullptr;
//print(f.origin(), "f.origin: ");
LocalVector ri = f.originalLinearPart()[i]; LocalVector ri = f.originalLinearPart()[i];
const auto& Ai = f.quadraticPart()[i]; const auto& Ai = f.quadraticPart()[i];
sparseRangeFor(Ai, [&](auto&& Aij, auto&& j) { sparseRangeFor(Ai, [&](auto&& Aij, auto&& j) {
...@@ -326,35 +311,9 @@ auto coordinateRestriction(const ShiftedFunctional<M, V, Nonlinearity, R>& f, co ...@@ -326,35 +311,9 @@ auto coordinateRestriction(const ShiftedFunctional<M, V, Nonlinearity, R>& f, co
Dune::TNNMG::Imp::mmv(Aij, f.origin()[j], ri, Dune::PriorityTag<1>()); Dune::TNNMG::Imp::mmv(Aij, f.origin()[j], ri, Dune::PriorityTag<1>());
}); });
// set maxEigenvalue from matrix
LocalVector eigenvalues;
Dune::FMatrixHelp::eigenValues(*Aii_p, eigenvalues);
auto maxEigenvalue = *std::max_element(std::begin(eigenvalues), std::end(eigenvalues));
Dune::MatrixVector::addProduct(ri, maxEigenvalue, f.origin()[i]);
LocalMatrix Aii = 0;
for (size_t d=0; d<Aii.N(); d++) {
Aii[d][d] = maxEigenvalue;
}
LocalLowerObstacle dli = f.originalLowerObstacle()[i];
LocalUpperObstacle dui = f.originalUpperObstacle()[i];
dli -= f.origin()[i];
dui -= f.origin()[i];
auto&& phii = f.phi().restriction(i); auto&& phii = f.phi().restriction(i);
/*std::cout << "maxEigenvalue matrix: " << std::endl; 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]);
for (size_t i=0; i<Aii.N(); i++) {
for (size_t j=0; j<Aii.M(); j++) {
std::cout << Aii[i][j] << " ";
}
std::cout << std::endl;
}*/
//return FirstOrderModelFunctional<LocalVector, decltype(phii), LocalLowerObstacle, LocalUpperObstacle, LocalVector, LocalVector, Range>(maxEigenvalue, std::move(ri), std::move(phii), std::move(dli), std::move(dui), std::move(f.origin()[i]));
return ShiftedFunctional<LocalMatrix, LocalVector, decltype(phii), Range>(std::move(Aii), std::move(ri), std::move(phii), std::move(dli), std::move(dui), f.origin()[i]);
} }
...@@ -382,8 +341,11 @@ class Functional : public Dune::TNNMG::BoxConstrainedQuadraticFunctional<M, V, L ...@@ -382,8 +341,11 @@ class Functional : public Dune::TNNMG::BoxConstrainedQuadraticFunctional<M, V, L
using LowerObstacle = typename Base::LowerObstacle; using LowerObstacle = typename Base::LowerObstacle;
using UpperObstacle = typename Base::UpperObstacle; using UpperObstacle = typename Base::UpperObstacle;
using Eigenvalues = std::vector<Range>;
private: private:
Dune::Solvers::ConstCopyOrReference<N> phi_; Dune::Solvers::ConstCopyOrReference<N> phi_;
Eigenvalues maxEigenvalues_;
public: public:
...@@ -395,13 +357,25 @@ class Functional : public Dune::TNNMG::BoxConstrainedQuadraticFunctional<M, V, L ...@@ -395,13 +357,25 @@ class Functional : public Dune::TNNMG::BoxConstrainedQuadraticFunctional<M, V, L
LL&& lower, LL&& lower,
UU&& upper) : UU&& upper) :
Base(std::forward<MM>(matrix), std::forward<VV>(linearPart), std::forward<LL>(lower), std::forward<UU>(upper)), Base(std::forward<MM>(matrix), std::forward<VV>(linearPart), std::forward<LL>(lower), std::forward<UU>(upper)),
phi_(std::forward<NN>(phi)) phi_(std::forward<NN>(phi)),
{} maxEigenvalues_(this->linearPart().size())
{
for (size_t i=0; i<this->quadraticPart().N(); ++i) {
typename Vector::block_type eigenvalues;
Dune::FMatrixHelp::eigenValues(this->quadraticPart()[i][i], eigenvalues);
maxEigenvalues_[i] =
*std::max_element(std::begin(eigenvalues), std::end(eigenvalues));
}
}
const Nonlinearity& phi() const { const Nonlinearity& phi() const {
return phi_.get(); return phi_.get();
} }
const auto& maxEigenvalues() const {
return maxEigenvalues_;
}
Range operator()(const Vector& v) const Range operator()(const Vector& v) const
{ {
if (Dune::TNNMG::checkInsideBox(v, this->lower_.get(), this->upper_.get())) if (Dune::TNNMG::checkInsideBox(v, this->lower_.get(), this->upper_.get()))
...@@ -416,9 +390,9 @@ class Functional : public Dune::TNNMG::BoxConstrainedQuadraticFunctional<M, V, L ...@@ -416,9 +390,9 @@ class Functional : public Dune::TNNMG::BoxConstrainedQuadraticFunctional<M, V, L
} }
friend auto shift(const Functional& f, const Vector& origin) friend auto shift(const Functional& f, const Vector& origin)
-> ShiftedFunctional<Matrix, Vector, Nonlinearity, Range> -> ShiftedFunctional<Matrix, Eigenvalues, Vector, Nonlinearity, Range>
{ {
return ShiftedFunctional<Matrix, Vector, Nonlinearity, Range>(f.quadraticPart(), f.linearPart(), f.phi(), f.lowerObstacle(), f.upperObstacle(), origin); return ShiftedFunctional<Matrix, Eigenvalues, Vector, Nonlinearity, Range>(f.quadraticPart(), f.maxEigenvalues(), f.linearPart(), f.phi(), f.lowerObstacle(), f.upperObstacle(), origin);
} }
}; };
......
...@@ -3,8 +3,13 @@ ...@@ -3,8 +3,13 @@
#ifndef DUNE_TECTONIC_LOCALBISECTIONSOLVER_HH #ifndef DUNE_TECTONIC_LOCALBISECTIONSOLVER_HH
#define DUNE_TECTONIC_LOCALBISECTIONSOLVER_HH #define DUNE_TECTONIC_LOCALBISECTIONSOLVER_HH
#include <dune/matrix-vector/axpy.hh>
#include <dune/tnnmg/localsolvers/scalarobstaclesolver.hh> #include <dune/tnnmg/localsolvers/scalarobstaclesolver.hh>
#include <dune/tnnmg/problem-classes/bisection.hh> #include <dune/tnnmg/problem-classes/bisection.hh>
#include "functional.hh"
#include "../../utils/debugutils.hh" #include "../../utils/debugutils.hh"
/** /**
...@@ -21,26 +26,33 @@ class LocalBisectionSolver ...@@ -21,26 +26,33 @@ class LocalBisectionSolver
return; return;
} }
Vector origin = f.origin(); auto maxEigenvalue = f.maxEigenvalues();
Vector direction = f.originalLinearPart();
auto origin = f.origin();
auto linearPart = f.originalLinearPart();
Dune::MatrixVector::addProduct(linearPart, maxEigenvalue, origin);
for (size_t j = 0; j < ignore.size(); ++j) for (size_t j = 0; j < ignore.size(); ++j)
if (ignore[j]) if (ignore[j])
direction[j] = 0; // makes sure result remains in subspace after correction linearPart[j] = 0; // makes sure result remains in subspace after correction
else else
origin[j] = 0; // shift affine offset origin[j] = 0; // shift affine offset
double const directionNorm = direction.two_norm(); double const linearPartNorm = linearPart.two_norm();
if (directionNorm <= 0.0) if (linearPartNorm <= 0.0)
return; return;
direction /= directionNorm; linearPart /= linearPartNorm;
auto&& directionalF = directionalRestriction(f, origin, direction); 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);
// scalar obstacle solver without nonlinearity // scalar obstacle solver without nonlinearity
typename Functional::Range alpha; typename Functional::Range alpha;
Dune::TNNMG::ScalarObstacleSolver obstacleSolver; /*Dune::TNNMG::ScalarObstacleSolver obstacleSolver;
obstacleSolver(alpha, directionalF, false); obstacleSolver(alpha, firstOrderFunctional, false);*/
//direction *= alpha; //direction *= alpha;
...@@ -59,23 +71,31 @@ class LocalBisectionSolver ...@@ -59,23 +71,31 @@ class LocalBisectionSolver
auto D = directionalF.subDifferential(0); auto D = directionalF.subDifferential(0);
std::cout << "subDiff at x: " << D[0] << " " << D[1] << std::endl;*/ std::cout << "subDiff at x: " << D[0] << " " << D[1] << std::endl;*/
const auto& domain = directionalF.domain(); const auto& domain = firstOrderFunctional.domain();
if (std::abs(domain[0]-domain[1])>safety) { if (std::abs(domain[0]-domain[1])>safety) {
int bisectionsteps = 0; int bisectionsteps = 0;
const Bisection globalBisection; 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();
}
alpha = globalBisection.minimize(directionalF, alpha, 0.0, bisectionsteps); if (alpha > firstOrderFunctional.upperObstacle() ) {
alpha = firstOrderFunctional.upperObstacle();
}
} }
direction *= alpha; linearPart *= alpha;
#ifdef NEW_TNNMG_COMPUTE_ITERATES_DIRECTLY #ifdef NEW_TNNMG_COMPUTE_ITERATES_DIRECTLY
x = origin; x = origin;
x += direction; x += linearPart;
#else #else
//x = origin; //x = origin;
x -= f.origin(); //x -= f.origin();
x += direction; x = linearPart;
#endif #endif
} }
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment