Newton Alignment
NovaPhy is being progressively reshaped to align with the Newton physics engine by Disney Research / Google DeepMind / NVIDIA — a GPU-accelerated, batched, differentiable physics engine built on NVIDIA Warp.
Motivation
- Shared Model / State / Control / Contacts abstraction — One scene description, one state object, many pluggable solvers.
- Unified
SolverBase.step() contract — Out-of-place stepping makes checkpoint/restore, parallel rollout, and differentiable rollout straightforward.
- Clear solver taxonomy — Users pick
SolverFeatherstone, SolverSemiImplicit, SolverXPBD, SolverVBD without understanding legacy class hierarchies.
- Batched multi-world data layout — Embodied-intelligence training needs thousands of worlds per GPU.
Current Status
Completed
| Change |
Details |
SolverSemiImplicit |
Renamed from SolverSequentialImpulse, absorbs legacy FreeBodySolver |
SolverFeatherstone |
Renamed from MultiBodySolver |
SolverBase contract |
Out-of-place step(model, state_in, state_out, control, contacts, dt) |
Contacts aggregate |
Unified rigid / manifolds / particle / soft channels |
JointSupportMatrix |
Declarative per-solver joint type support |
SolverNotifyFlags |
Bit-mask for model change notifications |
New Public Types
| Type |
Header |
Purpose |
Contacts |
core/contacts.h |
Unified contact aggregate |
ParticleContact |
core/contacts.h |
Particle-rigid contact (for PBF/MPM) |
SoftContact |
core/contacts.h |
Soft-element contact (for VBD/IPC) |
SolverNotifyFlags |
dynamics/solver_base.h |
Model change bit-mask |
JointSupportMatrix |
dynamics/solver_base.h |
Per-solver joint support table |
SolverBase Interface
class SolverBase {
public:
// Legacy in-place step (unchanged)
virtual void step(const Model&, SimState&, const Control&, float dt,
const Vec3f& gravity) = 0;
// Newton-aligned out-of-place step
virtual void step(const Model&, const SimState& in, SimState& out,
const Control*, Contacts*, float dt, const Vec3f& gravity);
virtual void notify_model_changed(SolverNotifyFlags flags);
virtual void update_contacts(Contacts& out, const SimState* state) const;
virtual JointSupportMatrix joint_support() const;
};
Roadmap
| Step |
Scope |
Risk |
Status |
| Rename solvers |
SolverSequentialImpulse -> SolverSemiImplicit, MultiBodySolver -> SolverFeatherstone |
Breaking |
Done |
Delete ArticulatedSolver |
Migrate to featherstone::* primitives |
Breaking |
Done |
| VBD/IPC as solvers |
VBDWorld -> SolverVBD, IPCWorld -> SolverIPC headers |
Medium |
Done |
| Unify joint taxonomy |
DISTANCE / D6 / CABLE; merge XPBDJoint into Joint |
Medium |
Planned |
| Extend SolverXPBD |
Articulations, torsional + rolling friction |
Medium |
Partial |
| Slim World |
std::vector<SolverBase*> pipeline; promote PBFSolver to SolverPBF |
Medium |
Planned |
| Batched multi-world |
*_world index arrays, per-world gravity, world-partitioned SAP |
Large |
Planned |
| DeviceArray abstraction |
DeviceArray<T> / DeviceContext; SoA kernel rewrite |
Large |
Planned |
| SolverMPM, SolverLBM |
MPM/LBM solvers + Akinci coupling pass |
Large |
Scaffolds exist |
| SolverMuJoCo |
Soft-constraint CG/PGS + MJCF importer |
Large |
Planned |
| Differentiable rollout |
Adjoint / Warp-Tape-style |
Large |
Planned |
Using the New API
import novaphy
# Unified contact aggregate
contacts = novaphy.Contacts()
assert contacts.empty()
# Newton-style solver metadata
solver = novaphy.SolverSemiImplicit()
assert isinstance(solver, novaphy.SolverBase)
matrix = solver.joint_support()
solver.notify_model_changed(novaphy.SolverNotifyFlags.ModelProperties)
solver.update_contacts(contacts)