Skip to content

Anisotropic friction#210

Open
antoinebou12 wants to merge 49 commits intoipc-sim:mainfrom
antoinebou12:anisotropic_friction
Open

Anisotropic friction#210
antoinebou12 wants to merge 49 commits intoipc-sim:mainfrom
antoinebou12:anisotropic_friction

Conversation

@antoinebou12
Copy link
Copy Markdown
Contributor

@antoinebou12 antoinebou12 commented Feb 4, 2026

Description

This PR adds anisotropic friction to IPC Toolkit’s tangential contact model: per-contact tangent-space velocity scaling and optional Erleben et al. (2019) “matchstick” / elliptical-L2 direction-dependent static and kinetic coefficients, with backward-compatible defaults.

The implementation follows the lagged-coefficient approach discussed with maintainers: direction-dependent effective μ_s / μ_k are refreshed explicitly from the current slip geometry (scaled tangential velocity τ_aniso = μ_aniso ⊙ τ) and stored on each TangentialCollision as mu_s_effective_lagged / mu_k_effective_lagged. Within a dissipative-potential evaluation, those scalars are held fixed, so the dissipative potential’s gradient and Hessian stay consistent with the friction force and force Jacobian for that lagging choice—without claiming a globally exact potential for a fully direction-varying μ (which would generally introduce non-conservative / “curl” effects in 2D tangent space; see Derivation of an Incremental Potential for Anisotropic Friction Models, Z. Ferguson).

Callers using directional anisotropy (mu_s_aniso nonzero in 3D with a 2D tangent space) must invoke
TangentialCollisions::update_lagged_anisotropic_friction_coefficients(...) after build and whenever lagged positions or velocities used for slip change (e.g. each Newton iteration), so lagged μ matches the geometry you intend. This is documented in the friction tutorial and Python API.

Fixes #4.


Summary of changes

  • Per-collision parameters on TangentialCollision:
    • mu_aniso: positive tangent-axis scaling of slip before friction evaluation (default (1,1) → previous behavior).
    • mu_s_aniso / mu_k_aniso: optional ellipse axes for matchstick effective μ (default zero → scalar mu_s / mu_k).
    • mu_s_effective_lagged / mu_k_effective_lagged: cached effective scalars for the current lagged state.
  • Friction energy / gradient / Hessian, friction force, and force Jacobians use ‖τ_aniso‖ (or ‖u_aniso‖ in the dissipative potential path) and the lagged scalar μ pair when directional anisotropy is active—no chain rule through ∂μ_eff/∂τ inside those derivatives.
  • Helpers in ipc/friction for matchstick effective μ (and related utilities), plus Python bindings for collision fields and update_lagged_anisotropic_friction_coefficients.
  • Tests for helpers, edge cases, and Jacobian checks with anisotropy; docs (advanced_friction tutorial, API notes), bibliography (Erleben et al.), and optional notebook for derivations/plots.

Motivation

Many real interfaces are anisotropic (grain, brushing, weave). This adds a local, per-contact model compatible with implicit stepping, while keeping isotropic simulations unchanged by default.


Design note (why lagging)

Fully treating μ_s(τ), μ_k(τ) as state-dependent inside the same scalar dissipative potential as the isotropic IPC friction energy is not generally compatible with a pure potential in velocity space when μ varies with slip direction. Lagging effective μ (and refreshing it when the user updates lagged kinematics) matches how IPC already treats other lagged contact data and avoids inconsistent “force vs. gradient” pairings for the matchstick part.


Limitations / follow-ups (optional but honest)

  • Directional matchstick path is enabled when mu_s_aniso is nonzero and the tangent space is 2D (typical 3D sims). 2D sims (1D tangent space) keep isotropic μ for the directional model, as before.
  • If only mu_k_aniso were nonzero with mu_s_aniso = 0, the current gate still treats the contact as non-directional for lagged μ; document or extend if you need that asymmetry.

Dependencies

  • No new runtime library dependencies.
  • Optional: Jupyter to run notebooks/anisotropic_friction_math.ipynb.

How tested

  • Local CMake build (Windows).
  • CTest including friction / anisotropy targets.
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release
ctest --test-dir build -C Release
ctest --test-dir build -C Release -R friction

Environment (example): Windows 11, MSVC 2022.


Risk

High: touches core friction force / Jacobian / dissipative-potential paths. Defaults are safe; misuse of the lagged-μ API (skipping update_lagged_anisotropic_friction_coefficients) can desynchronize force and dissipative gradient. Tests and docs mitigate but do not remove integration responsibility.


Type of change

  • Enhancement
  • New feature (non-breaking)
  • Documentation

Checklist

  • I have followed the project style guide
  • My code follows the clang-format style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules (N/A — no downstream dependency changes required)

Note

High Risk
Touches core friction force/Jacobian/Hessian code paths used by solvers, so mistakes can affect stability and convergence across simulations. While defaults are backward-compatible and tests were added, the new derivative logic increases numerical/edge-case risk.

Overview
Adds anisotropic friction support to tangential contact by introducing per-collision parameters mu_aniso (tangent-space velocity scaling) and optional direction-dependent ellipse axes mu_s_aniso/mu_k_aniso, with zero/default values preserving existing isotropic behavior.

Updates tangential friction energy/force/gradient/Hessian and force Jacobians to evaluate friction using scaled tangential velocity (tau_aniso) and, when ellipse axes are provided, an effective friction coefficient via an elliptical L2 ("matchstick") model; includes new helper functions (and Python bindings) for effective-μ evaluation and derivatives.

Extends documentation (C++/Python API pages and advanced_friction tutorial), adds the Erleben2019Matchstick reference plus a derivation notebook, and adds/updates unit tests covering the new helpers and anisotropic force/Jacobian correctness.

antoinebou12 and others added 17 commits January 26, 2026 17:31
This commit introduces a new example script demonstrating the use of anisotropic friction in the IPC Toolkit. The script showcases the setup of a simple collision scenario, building normal and tangential collisions, assigning anisotropic friction coefficients, and computing effective friction for various velocity directions. Additionally, it compares the results with isotropic friction to highlight the differences in behavior.
… of effective friction coefficients and ensure finite results. Update documentation to reflect changes in function name and return values.
…nd improve clarity. Update documentation and tests to reflect changes from `anisotropic_mu_eff_sqrt_mu0_t0_sq_plus_mu1_t1_sq` to `anisotropic_mu_eff_f` and related functions.
…ility by consolidating function calls into single lines. This change enhances clarity without altering the test logic.
… and consistency. Convert markdown cells to code cells in the notebook, enhance symbolic variable definitions, and streamline friction force visualization. Update test cases to ensure consistent function calls and improve readability.
…move backward compatibility section from the tutorial, update execution counts in the notebook, and streamline function definitions in the C++ code. Enhance test cases for consistency and readability.
This commit introduces the Matchstick model for anisotropic friction, enhancing the IPC Toolkit's capabilities. Key changes include:

- Addition of the Matchstick model reference in `references.bib`.
- Updates to the C++ and Python API documentation to include anisotropic friction helpers and their usage.
- Enhancements in the `advanced_friction` tutorial to cover anisotropic friction features and their implementation.
- New tests for anisotropic friction transitions and effective coefficient calculations.

Documentation now references Erleben et al. (2019) for the model's derivation and implementation details.
…prove code comments for clarity in tangential collision and potential implementations.
@codecov
Copy link
Copy Markdown

codecov bot commented Feb 4, 2026

Codecov Report

❌ Patch coverage is 96.25668% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.84%. Comparing base (9a704ea) to head (1dedbf5).

Files with missing lines Patch % Lines
src/ipc/potentials/tangential_potential.hpp 0.00% 6 Missing ⚠️
...pc/collisions/tangential/tangential_collisions.cpp 98.38% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #210      +/-   ##
==========================================
+ Coverage   95.77%   95.84%   +0.07%     
==========================================
  Files         159      160       +1     
  Lines       16521    16655     +134     
  Branches      927      944      +17     
==========================================
+ Hits        15823    15963     +140     
+ Misses        698      692       -6     
Flag Coverage Δ
unittests 95.84% <96.25%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@zfergus
Copy link
Copy Markdown
Member

zfergus commented Feb 4, 2026

Woooow! This is really awesome. Thanks for the contribution. The matchstick method for anisotropic friction was something I was interested in implementing, so I am super excited you did it already. 😄

I'll review the changes in depth when I have some free time. 🚀

@zfergus zfergus added the enhancement New feature or request label Feb 4, 2026
@zfergus zfergus added this to the v1.6.0 milestone Feb 4, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds anisotropic friction support to IPC Toolkit’s tangential contact model by introducing per-collision anisotropy parameters, helper math for effective direction-dependent friction coefficients, Python bindings, and expanded docs/tests.

Changes:

  • Added anisotropic friction parameters on TangentialCollision (mu_aniso, mu_s_aniso, mu_k_aniso) and exposed them to Python.
  • Updated tangential friction potential/force/Jacobian computations to use anisotropically scaled tangential velocity and effective-μ helpers.
  • Added anisotropic effective-μ helper functions plus new/updated unit tests and documentation.

Reviewed changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
src/ipc/potentials/tangential_potential.cpp Integrates anisotropic scaling/effective-μ into friction potential and force/Jacobian computations.
src/ipc/friction/smooth_mu.hpp Declares new anisotropic effective-μ helpers and derivatives.
src/ipc/friction/smooth_mu.cpp Implements effective-μ evaluation and derivative helpers.
src/ipc/collisions/tangential/tangential_collision.hpp Adds per-collision anisotropy parameters to the tangential collision model.
python/src/friction/smooth_mu.cpp Exposes anisotropic effective-μ helpers to Python.
python/src/collisions/tangential/tangential_collision.cpp Exposes new tangential collision anisotropy fields to Python.
tests/src/tests/potential/test_friction_potential.cpp Updates friction potential FD tests to handle filtered meshes/displacement mapping.
tests/src/tests/friction/test_smooth_mu.cpp Adds unit tests for anisotropic effective-μ helpers and derivatives.
tests/src/tests/friction/test_force_jacobian.cpp Adjusts force/Jacobian tests for mesh sizing and adds coverage for no-μ paths.
tests/src/tests/friction/test_anisotropic_friction.cpp Adds new anisotropic friction tests (helpers + force/Jacobian scenarios).
tests/src/tests/friction/CMakeLists.txt Registers the new anisotropic friction test file.
docs/source/tutorials/advanced_friction.rst Adds an anisotropic friction tutorial section and usage examples.
docs/source/cpp-api/friction.rst Documents anisotropic helper APIs for C++.
docs/source/python-api/friction.rst Documents anisotropic helper APIs for Python.
docs/source/references.bib Adds the matchstick model citation.
docs/source/developers/tools.rst / docs/source/developers/style_guide.rst Clarifies formatting/tooling expectations (clang-format version/style).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// NOTE: Direction-dependent anisotropic friction only makes sense in 3D
// (2D tangent space). For 2D simulations (1D tangent space), disable.
const bool is_anisotropic =
tangent_dim > 1 && collision.mu_s_aniso.squaredNorm() > 0;
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The anisotropy enable check uses only collision.mu_s_aniso.squaredNorm() > 0, so a non-zero mu_k_aniso alone won’t activate the anisotropic path (and will also skip the dμ/dτ contribution). Consider enabling anisotropy when either mu_s_aniso or mu_k_aniso is non-zero and handling them independently if only one is provided.

Suggested change
tangent_dim > 1 && collision.mu_s_aniso.squaredNorm() > 0;
tangent_dim > 1
&& (collision.mu_s_aniso.squaredNorm() > 0
|| collision.mu_k_aniso.squaredNorm() > 0);

Copilot uses AI. Check for mistakes.
@ipc-sim ipc-sim deleted a comment from Copilot AI Feb 6, 2026
@ipc-sim ipc-sim deleted a comment from Copilot AI Feb 6, 2026
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
zfergus and others added 16 commits February 6, 2026 14:05
…lations and updating documentation. Added tests for anisotropic friction scenarios and improved clarity in comments and code structure.
Update TangentialPotential::gradient to include contributions from the
gradients of effective mu_s and mu_k (direction-dependent friction),
obtaining grad_mu_* via anisotropic_mu_eff_f_grad and adding the
corresponding drift terms.

Add virtual mu_f0_grad_mu_s/mu_k declarations and provide
finite-difference
fallback implementations in friction_potential.hpp and
tangential_adhesion_potential.hpp.

Update tests: replace M_PI with igl::PI and add a test that verifies the
TangentialPotential gradient and Hessian against finite differences.

WARNING: tests fail because Hessian has not been updated to account for
anisotropic coefficients
@zfergus
Copy link
Copy Markdown
Member

zfergus commented Feb 24, 2026

Hi Antoine,

I’ve put together a document detailing the challenges of integrating anisotropic friction into a fully implicit framework: Anisotropic_IPC_Friction.pdf.

The core issue is that anisotropic coefficients create a nonzero curl on the tangent vector space. Because of this, we can't derive an incremental potential that perfectly matches the required forces. While the document proposes an approximate potential, I recommend lagging the anisotropic coefficients—similar to our current approach with normal forces and tangent bases—as a more practical path forward.

-Z

@antoinebou12
Copy link
Copy Markdown
Contributor Author

Hi Zachary,

Thanks for sharing the PDF, it clarified a lot for me, especially the curl issue (I hadn’t considered that case at all) and the lagged anisotropy approach.

I’ve been a bit busy with school lately, but I’m excited to get back to this. My current implementation is fairly naive, so I’ll likely rework it to better follow your formulation probably starting with the lagged version since it fits well with the existing codebase.

I’ll keep you posted once I have something close to working

Best,
Antoine

Antoine Boucher added 9 commits April 13, 2026 13:27
…ian BarrierPotential API

Made-with: Cursor
- Add mu_s_effective_lagged/mu_k_effective_lagged and TangentialCollisions
  reset/update methods; refresh after build and when slip changes.
- Use lagged scalars in dissipative potential, force, and Jacobians; remove
  ad-hoc d(mu)/d(tau) Jacobian terms and align smooth_contact jacobian with force.
- Python: expose lagged fields and update/reset on TangentialCollisions.
- Tests: BarrierPotential(dhat, kappa) and build API; call update for anisotropic
  cases; tighten combined FD check; add gradient vs -force test; extend smooth
  3D jacobian check with lagged anisotropic FD.
- Docs: advanced_friction lagging section and BarrierPotential build snippets.

Made-with: Cursor
- Removed the `anisotropic_mu_eff_f_grad` function from the C++ API and related documentation, as it is no longer needed for the lagged matchstick model.
- Updated documentation to clarify the use of lagged anisotropic friction coefficients in the Python API and tutorials.
- Adjusted tests to reflect changes in the friction model and ensure compatibility with the new API structure.
- Simplified function calls in `test_anisotropic_friction.cpp` and `test_force_jacobian.cpp` by removing unnecessary line breaks.
- Enhanced code clarity without altering functionality.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants