Near-Far Barrier

template <typename T = double>
class NearFarBarrier : public ipc::BarrierBase<double>;

Inheritance diagram for ipc::NearFarBarrier:

digraph { graph [bgcolor="#00000000"] node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2] edge [color="#1414CE"] "2" [label="ipc::BarrierBase< T >" tooltip="ipc::BarrierBase< T >"] "1" [label="ipc::NearFarBarrier< T >" tooltip="ipc::NearFarBarrier< T >" fillcolor="#BFBFBF"] "1" -> "2" [dir=forward tooltip="public-inheritance"] }

Collaboration diagram for ipc::NearFarBarrier:

digraph { graph [bgcolor="#00000000"] node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2] edge [color="#1414CE"] "2" [label="ipc::BarrierBase< T >" tooltip="ipc::BarrierBase< T >"] "1" [label="ipc::NearFarBarrier< T >" tooltip="ipc::NearFarBarrier< T >" fillcolor="#BFBFBF"] "1" -> "2" [dir=forward tooltip="public-inheritance"] }

Near-Far barrier function.

This barrier function takes another “base” barrier object as argument. All operations defined in BarrierBase defer the computation to its base barrier. In addition, it splits the base barrier \(b\) into a near and a far part,

\[ b_\text{near}(d) = b(d)\,(1 - H(d)), \quad b_\text{far}(d) = b(d)\,H(d), \quad b_\text{near} + b_\text{far} = b, \]

where \(H\) is a C² piecewise-cubic step rising from 0 at \(d = \alpha\hat{d}/2\) to 1 at \(d = \alpha\hat{d}\). Below \(\alpha\hat{d}/2\) the near part is exactly \(b\) and the far part exactly 0, so the identity also holds at contact, where the log barriers give \(b_\text{near} = +\infty\). For \(\alpha \ge 2\) the far part vanishes identically, since \(b = 0\) for \(d \ge \hat{d}\). ESPPotential uses \(\alpha =\) dbar_factor.

Public Functions

inline NearFarBarrier(
    
const BarrierBase<T>* const base_barrier, const double alpha);

Construct a NearFarBarrier that borrows its base barrier.

Parameters:
const BarrierBase<T> *const base_barrier

The base barrier function to use. This does not take ownership, so the base barrier must outlive this object.

const double alpha

Split parameter: the far weight H rises from 0 at d = alpha * dhat / 2 to 1 at d = alpha * dhat.

Throws:

std::invalid_argument – if alpha is not positive and finite. At alpha = 0 the step H collapses to a jump and its derivatives are NaN.

inline NearFarBarrier(
    
std::shared_ptr<const BarrierBase<T>> base_barrier,
    
const double alpha);

Construct a NearFarBarrier holding shared ownership of the base barrier.

Prefer this over the raw-pointer overload whenever the caller already has a shared_ptr — it pins the base barrier for the lifetime of this object, eliminating dangling-pointer risk.

inline virtual T operator()(const T d, const T dhat) const override;

Evaluate the barrier function.

Parameters:
const T d

Distance.

const T dhat

Activation distance of the barrier.

Returns:

The value of the barrier function at d.

inline virtual T first_derivative(
    
const T d, const T dhat) const override;

Evaluate the first derivative of the barrier function wrt d.

Parameters:
const T d

Distance.

const T dhat

Activation distance of the barrier.

Returns:

The value of the first derivative of the barrier function at d.

inline virtual T second_derivative(
    
const T d, const T dhat) const override;

Evaluate the second derivative of the barrier function wrt d.

Parameters:
const T d

Distance.

const T dhat

Activation distance of the barrier.

Returns:

The value of the second derivative of the barrier function at d.

inline virtual T units(const T dhat) const override;

Get the units of the barrier function.

Parameters:
const T dhat

The activation distance of the barrier.

Returns:

The units of the barrier function.

T near_value(const T d, const T dhat) const;

Evaluate the near part b(d) (1 - H(d)).

Parameters:
const T d

Distance.

const T dhat

Activation distance of the barrier.

Returns:

The value of the near part at d.

T far_value(const T d, const T dhat) const;

Evaluate the far part b(d) H(d).

Parameters:
const T d

Distance.

const T dhat

Activation distance of the barrier.

Returns:

The value of the far part at d.

T first_derivative_near(const T d, const T dhat) const;

Evaluate the first derivative of the near part wrt d.

Parameters:
const T d

Distance.

const T dhat

Activation distance of the barrier.

Returns:

The first derivative of the near part at d.

T first_derivative_far(const T d, const T dhat) const;

Evaluate the first derivative of the far part wrt d.

Parameters:
const T d

Distance.

const T dhat

Activation distance of the barrier.

Returns:

The first derivative of the far part at d.

T second_derivative_near(const T d, const T dhat) const;

Evaluate the second derivative of the near part wrt d.

Parameters:
const T d

Distance.

const T dhat

Activation distance of the barrier.

Returns:

The second derivative of the near part at d.

T second_derivative_far(const T d, const T dhat) const;

Evaluate the second derivative of the far part wrt d.

Parameters:
const T d

Distance.

const T dhat

Activation distance of the barrier.

Returns:

The second derivative of the far part at d.

Private Types

using Mask = decltype(std::declval<T>() <= std::declval<T>());

The result of comparing two T: a bool for a scalar, and a per-lane mask for a batch.

Private Functions

inline void validate_alpha() const;
Mask is_purely_near(const T d, const T dhat) const;

Whether d lies where the far weight H vanishes identically (d <= alpha * dhat / 2), so near = b and far = 0.

T far_weight(const T d, const T dhat) const;

The far weight H(d).

T far_weight_first_derivative(const T d, const T dhat) const;

The first derivative of the far weight H wrt d.

T far_weight_second_derivative(const T d, const T dhat) const;

The second derivative of the far weight H wrt d.

Private Members

const std::shared_ptr<const BarrierBase<T>> m_base_barrier;

The base barrier.

It owns the barrier when built from a shared_ptr and only aliases it when built from a raw pointer.

const double m_alpha;