Commit 44b50ef0 authored by oliver.sander_at_tu-dresden.de's avatar oliver.sander_at_tu-dresden.de
Browse files

Linearization: Allow to hand over 'ignore' after object has been created

Previously the 'ignore' field could only be set in the constructor.
But the 'ignore' field is part of the iteration step, and as a
consequence there was no way to have a Linearization with non-standard
state.  For the brittle-fracture code I want to set
gradientAwareTruncation in BCQFConstrainedLinearization, for which
the Linearization object needs to be constructed before the TNNMGStep
object.
parent 3c1c3691
Pipeline #49478 passed with stage
in 7 minutes and 22 seconds
......@@ -112,14 +112,32 @@ public:
using ConstrainedBitVector = BitVector;
/** \brief Construct linearization for a given functional
*/
BoxConstrainedQuadraticFunctionalConstrainedLinearization(const F& f) :
f_(f),
truncationTolerance_(1e-10),
regularizeDiagonal_(false),
gradientAwareTruncation_(false)
{}
/** \brief Construct linearization for a given functional and set of degrees of freedom to ignore
*/
BoxConstrainedQuadraticFunctionalConstrainedLinearization(const F& f, const BitVector& ignore) :
f_(f),
ignore_(ignore),
ignore_(&ignore),
truncationTolerance_(1e-10),
regularizeDiagonal_(false),
gradientAwareTruncation_(false)
{}
/** \brief Specify what degrees of freedom to ignore
*/
void setIgnore(const BitVector& ignore)
{
ignore_ = &ignore;
}
void setTruncationTolerance(double tolerance)
{
truncationTolerance_ = tolerance;
......@@ -168,7 +186,7 @@ public:
negativeGradient_ = derivative(f_)(x);
negativeGradient_ *= -1;
hessian_ = derivative(derivative(f_))(x);
truncationFlags_ = ignore_;
truncationFlags_ = *ignore_;
// determine which components to truncate
if (gradientAwareTruncation_)
......@@ -204,7 +222,7 @@ public:
private:
const F& f_;
const BitVector& ignore_;
const BitVector* ignore_;
double truncationTolerance_;
bool regularizeDiagonal_;
......
......@@ -32,16 +32,23 @@ public:
QuadraticFunctionalConstrainedLinearization(const F& f, const BitVector& ignore) :
f_(f),
ignore_(ignore),
ignore_(&ignore),
truncationTolerance_(1e-10)
{}
/** \brief Specify what degrees of freedom to ignore
*/
void setIgnore(const BitVector& ignore)
{
ignore_ = &ignore;
}
void bind(const Vector& x)
{
negativeGradient_ = derivative(f_)(x);
negativeGradient_ *= -1;
hessian_ = derivative(derivative(f_))(x);
truncationFlags_ = ignore_;
truncationFlags_ = *ignore_;
// truncate
for(std::size_t i=0; i<x.size(); ++i)
......@@ -88,7 +95,7 @@ public:
private:
const F& f_;
const BitVector& ignore_;
const BitVector* ignore_;
double truncationTolerance_;
......
......@@ -34,9 +34,27 @@ public:
: addends_(std::apply([&](auto&&... fi) {
return std::make_tuple(Addends(fi, ignore)...);
}, f.functions())),
ignore_(ignore)
ignore_(&ignore)
{}
/** \brief Constructor from a set of addends
*
* These addends must all be connected to the same functional.
*/
SumFunctionalConstrainedLinearization(Addends... addends)
: addends_(addends...)
{}
/** \brief Specify what degrees of freedom to ignore
*/
void setIgnore(const BitVector& ignore)
{
ignore_ = &ignore;
Hybrid::forEach(addends_, [&](auto&& addend) {
addend.setIgnore(ignore);
});
}
/** \brief Pre-compute derivative information at the configuration x
*/
void bind(const Vector& x)
......@@ -64,7 +82,7 @@ public:
////////////////////////////////////////////////////
// Truncate all degrees of freedom explicitly requested in the constructor
truncationFlags_ = ignore_;
truncationFlags_ = *ignore_;
// Also truncate a degree of freedom if one of the addends wants it truncated
for (std::size_t i=0; i<truncationFlags_.size(); i++)
......@@ -142,7 +160,7 @@ private:
std::tuple<Addends...> addends_;
// Mark degrees of freedom that should be truncated
const BitVector& ignore_;
const BitVector* ignore_;
Vector negativeGradient_;
Matrix hessian_;
......
......@@ -118,6 +118,11 @@ public:
preSmoothingSteps_ = i;
}
void setLinearization(std::shared_ptr<Linearization> linearization)
{
linearization_ = linearization;
}
/**
* \brief Do one TNNMG step
*/
......@@ -134,7 +139,9 @@ public:
// Compute constraint/truncated linearization
if (not linearization_)
// TODO: Don't hand over the 'ignore' field. Requires new constructors for all linearizations!
linearization_ = std::make_shared<Linearization>(f, ignore);
linearization_->setIgnore(ignore);
linearization_->bind(x);
......
......@@ -118,10 +118,17 @@ public:
TrescaFrictionFunctionalConstrainedLinearization(const F& f, const BitVector& ignore) :
f_(f),
ignore_(ignore),
ignore_(&ignore),
truncationTolerance_(1e-10)
{}
/** \brief Specify what degrees of freedom to ignore
*/
void setIgnore(const BitVector& ignore)
{
ignore_ = &ignore;
}
void bind(const Vector& x)
{
constexpr double tolerance = 1e-15;
......@@ -180,7 +187,7 @@ public:
const auto& obstacleFunctional = std::get<0>(f_.functions());
// The ignore_ field contains the Dirichlet dofs
truncationFlags_ = ignore_;
truncationFlags_ = *ignore_;
// determine which components to truncate
for (std::size_t i=0; i<x.size(); ++i)
......@@ -251,7 +258,7 @@ public:
private:
const F& f_;
const BitVector& ignore_;
const BitVector* ignore_;
double truncationTolerance_;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment