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, bool one_sided=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

void residual (const VecD &p, double &r, VecD &dr) const
 r and its gradient under either residual (see the constructor).
 

Private Attributes

std::shared_ptr< const OffsetPotential< DIM > > m_potential
 
double m_weight
 
bool m_gauss_newton
 
bool m_distance_residual
 
bool m_one_sided
 

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,
bool  one_sided = 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. Both dimensions' front placement passes true.

one_sided charges only points on the input's side of the level set (is_inside_offset()): beyond it the term and its derivatives are zero, so the term pushes a vertex out to the level set and never pulls one in. C^1 at the level set, where the residual is zero from both sides. The repulsion passes before the march use it (TopoOffsetTetMesh::repulsion_smoothing()).


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