Wildmeshing Toolkit
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
wmtk::components::topological_offset::OffsetEnergy< DIM > Class Template Reference

The offset term of the smoothing objective: w * (Phi(x) - c)^2. More...

#include <OffsetPotential.hpp>

Inheritance diagram for wmtk::components::topological_offset::OffsetEnergy< DIM >:

Public Types

using VecD = Eigen::Matrix< double, DIM, 1 >
 
using MatD = Eigen::Matrix< double, DIM, DIM >
 

Public Member Functions

 OffsetEnergy (const std::shared_ptr< const OffsetPotential< DIM > > &potential, double weight=1., bool gauss_newton=true, bool distance_residual=false)
 
double value (const TVector &x) override
 
void gradient (const TVector &x, TVector &gradv) override
 
void hessian (const TVector &x, THessian &hessian) override
 
void hessian (const TVector &x, MatrixXd &hessian) override
 
void solution_changed (const TVector &new_x) override
 

Private Member Functions

bool root_distance (const VecD &p, double &s, VecD &n) const
 
void residual (const VecD &p, double &r, VecD &dr) const
 

Private Attributes

std::shared_ptr< const OffsetPotential< DIM > > m_potential
 
double m_weight
 
bool m_gauss_newton
 
bool m_distance_residual
 
double m_last_root = 0.
 warm start for root_distance(), see there
 
bool m_cache_valid = false
 
VecD m_cache_p
 
double m_cache_r = 0.
 
VecD m_cache_dr
 

Detailed Description

template<int DIM>
class wmtk::components::topological_offset::OffsetEnergy< DIM >

The offset term of the smoothing objective: w * (Phi(x) - c)^2.

A polysolve::nonlinear::Problem in the shape of ExactDistanceEnergy2D/3D, so the shared smoother composes it into its EnergySum beside AMIPS with no special case, which is what lets a front vertex take the same path as every other vertex.

The residual form rather than Phi itself: Phi is a barrier, so minimising it would drive the vertex to infinity and maximising it into the complex, while the squared residual has its minimum exactly on the level set, where the front belongs.

Value, gradient and Hessian all follow from Phi, grad Phi and hess Phi by the chain rule:

E     = w (Phi - c)^2
grad  = 2 w (Phi - c) grad Phi
hess  = 2 w [ grad Phi grad Phi^T + (Phi - c) hess Phi ]

The second Hessian term changes sign with the residual and can make H indefinite far from the level set; gauss_newton drops it, leaving the always-PSD outer product. On by default: the dropped term vanishes at the solution, so it costs nothing at convergence and buys a descent direction everywhere.

Constructor & Destructor Documentation

◆ OffsetEnergy()

template<int DIM>
wmtk::components::topological_offset::OffsetEnergy< DIM >::OffsetEnergy ( const std::shared_ptr< const OffsetPotential< DIM > > &  potential,
double  weight = 1.,
bool  gauss_newton = true,
bool  distance_residual = false 
)

distance_residual charges the signed distance from x to the level set along the field's normal, over delta – what (d - delta)/delta already is for the Euclidean field – instead of the value ratio (Phi - c)/c, which for the smooth field is a barrier value and not a length, and pulls far harder where two fronts are pressed together. Same level set and same root either way; only the charge changes. 3D keeps the value ratio (false).

Member Function Documentation

◆ residual()

template<int DIM>
void wmtk::components::topological_offset::OffsetEnergy< DIM >::residual ( const VecD &  p,
double &  r,
VecD &  dr 
) const
private

r and its gradient under either residual (see the constructor). The last point's answer is cached: value, gradient and Hessian are asked at the same x in one iteration.

◆ root_distance()

template<int DIM>
bool wmtk::components::topological_offset::OffsetEnergy< DIM >::root_distance ( const VecD &  p,
double &  s,
VecD &  n 
) const
private

The signed distance s from p to the level set along the field's normal n at p (n points toward the input; s > 0: the level set lies outward of p). Safeguarded Newton. false when no root brackets within 2 dhat, e.g. outside the support.


The documentation for this class was generated from the following files: