fedoo.constraint.IPCContact

class IPCContact(mesh, surface_mesh=None, extract_surface=False, dhat=0.001, dhat_is_relative=True, barrier_stiffness=None, friction_coefficient=0.0, eps_v=0.001, broad_phase='hash_grid', adaptive_barrier_stiffness=True, use_ccd=None, line_search_energy=None, use_ogc=False, space=None, name='IPC Contact')

Contact Assembly based on the IPC (Incremental Potential Contact) method.

Uses the ipctk library to guarantee intersection-free configurations through barrier potentials and optional CCD (Continuous Collision Detection) line search.

The IPC method adds a barrier energy term \(\kappa\,B(\mathbf{x})\) to the total potential energy. The barrier \(B\) grows to infinity as the distance between surfaces approaches zero and vanishes when the distance exceeds dhat. This guarantees that the deformed configuration remains intersection-free at every Newton–Raphson iteration.

Barrier stiffness auto-tuning — When barrier_stiffness is left to None (recommended), the stiffness \(\kappa\) is automatically initialised by ipctk.initial_barrier_stiffness so that it balances the elastic and barrier energy gradients. If no contact exists at the initial configuration (common for self-contact problems), \(\kappa\) is re-initialised the first time collisions appear, using the actual elastic forces at that stage. Afterwards, \(\kappa\) is updated adaptively at each converged time increment via ipctk.update_barrier_stiffness.

Convergence safeguards (SDI) — When the set of active collisions changes during a Newton–Raphson iteration (new contacts appear or existing ones separate), or when the minimum gap drops below 0.1 × d_hat, the solver is forced to perform at least one additional NR iteration even if the displacement criterion is already satisfied. When surfaces are dangerously close (gap < 0.01 × d_hat), at least three extra iterations are forced. This prevents premature convergence when the contact state is still evolving.

CCD line search — When use_ccd=True, the Newton–Raphson step size is clamped to the largest value that keeps all surfaces intersection-free. For the elastic prediction of an increment where no contacts existed at the start, a conservative minimum distance of 0.1 × d_hat is enforced to prevent surfaces from jumping deep into the barrier zone. If this conservative bound yields a zero step (e.g. due to shared mesh edges at zero distance in self-contact), the CCD falls back to the standard min_distance=0 computation.

OGC trust-region — When use_ogc=True, the Offset Geometric Contact (OGC) trust-region method from ipctk.ogc replaces CCD. Instead of uniformly scaling the displacement step by a single scalar, OGC filters the displacement per vertex, clamping each vertex’s move to lie within a trust region that guarantees no intersection. This can provide better convergence by not penalising distant vertices for a tight contact elsewhere. use_ogc and use_ccd are mutually exclusive.

Warning

OGC is only supported for shell / surface meshes where every node lies on the contact surface. Solid meshes with interior nodes must use use_ccd=True instead. An error is raised at initialization if use_ogc=True is used with a solid mesh.

Parameters:
  • mesh (fedoo.Mesh) – Full volumetric mesh (needed for DOF compatibility).

  • surface_mesh (fedoo.Mesh, optional) – Pre-extracted surface mesh (lin2 in 2D, tri3 in 3D).

  • extract_surface (bool, default=False) – If True, automatically extract the surface from the volumetric mesh.

  • dhat (float, default=1e-3) – Barrier activation distance. Pairs of primitives closer than dhat receive a repulsive barrier force. A smaller value gives a tighter contact (less visible gap) but requires finer time steps.

  • dhat_is_relative (bool, default=True) – If True, dhat is interpreted as a fraction of the bounding box diagonal of the surface mesh.

  • barrier_stiffness (float, optional) – Barrier stiffness \(\kappa\). If None (default), it is automatically computed and adaptively updated — this is the recommended setting. When specified explicitly, the value is kept fixed unless adaptive_barrier_stiffness is True, in which case it is used as the initial value and may be updated.

  • friction_coefficient (float, default=0.0) – Coulomb friction coefficient \(\mu\). Set to 0 for frictionless contact.

  • eps_v (float, default=1e-3) – Friction smoothing velocity (only relevant when friction_coefficient > 0).

  • broad_phase (str, default="hash_grid") – Broad-phase collision detection method. One of "hash_grid", "brute_force", "spatial_hash" or "bvh".

  • adaptive_barrier_stiffness (bool, default=True) – If True, \(\kappa\) is updated adaptively at each converged time increment using ipctk.update_barrier_stiffness.

  • use_ccd (bool, optional) – Enable Continuous Collision Detection (CCD) line search. When active, the Newton–Raphson step size is limited to prevent interpenetration between iterations. Default is True unless use_ogc is enabled. Note: use_ccd and use_ogc are mutually exclusive.

  • line_search_energy (bool or None, default=None) – Controls energy-based backtracking after CCD line search. The step is halved until total energy (exact barrier + quadratic elastic approximation) decreases. When None (default), automatically enabled when use_ccd=True — this matches the reference IPC algorithm. Set to False to disable (faster but may degrade convergence). Has no effect when use_ogc is enabled.

  • use_ogc (bool, default=False) – Enable OGC (Offset Geometric Contact) trust-region step filtering. Per-vertex displacement clamping replaces the uniform scalar step of CCD. Mutually exclusive with use_ccd. Only supported for shell / surface meshes where all nodes are on the surface; raises ValueError for solid meshes with interior nodes.

  • space (ModelingSpace, optional) – Modeling space. If None, the active ModelingSpace is used.

  • name (str, default="IPC Contact") – Name of the contact assembly.

Notes

The IPC assembly is used by adding it to the structural assembly with fedoo.Assembly.sum():

solid = fd.Assembly.create(wf, mesh)
ipc   = fd.constraint.IPCContact(mesh, surface_mesh=surf)
assembly = fd.Assembly.sum(solid, ipc)

When using add_output, pass the solid assembly (not the sum) to avoid errors.

See also

IPCSelfContact

Convenience wrapper for self-contact problems.

fedoo.constraint.Contact

Penalty-based contact method.

__init__(mesh, surface_mesh=None, extract_surface=False, dhat=0.001, dhat_is_relative=True, barrier_stiffness=None, friction_coefficient=0.0, eps_v=0.001, broad_phase='hash_grid', adaptive_barrier_stiffness=True, use_ccd=None, line_search_energy=None, use_ogc=False, space=None, name='IPC Contact')

Methods

IPCContact.assemble_global_mat([compute])

Recompute barrier contributions from cached vertex positions.

IPCContact.delete_global_mat()

Delete Global Matrix and Global Vector related to the assembly.

IPCContact.get_all()

Return a dict with all the known Assembly (with a name).

IPCContact.get_global_matrix()

Get the last computed global matrix.

IPCContact.get_global_vector()

Get the last computed global vector.

IPCContact.initialize(pb)

Initialize the IPC contact assembly.

IPCContact.reset()

Reset the assembly.

IPCContact.set_start(pb)

Begin a new time increment.

IPCContact.to_start(pb)

Restart the current time increment after NR failure.

IPCContact.update(pb[, compute])

Update the IPC assembly for the current Newton–Raphson iteration.

IPCContact.name

Name of the assembly if defined.

IPCContact.space

Modeling space associated to the assembly.

IPCContact.current

Assembly associated to the mesh of the deformed geometry.

IPCContact.associated_assembly_sum

AssemblySum object that contains the assembly.