SPhysics 0.6.0-dev

This is a prerelease version of SPhysics.
dotnet add package SPhysics --version 0.6.0-dev
                    
NuGet\Install-Package SPhysics -Version 0.6.0-dev
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SPhysics" Version="0.6.0-dev" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SPhysics" Version="0.6.0-dev" />
                    
Directory.Packages.props
<PackageReference Include="SPhysics" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SPhysics --version 0.6.0-dev
                    
#r "nuget: SPhysics, 0.6.0-dev"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SPhysics@0.6.0-dev
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SPhysics&version=0.6.0-dev&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=SPhysics&version=0.6.0-dev&prerelease
                    
Install as a Cake Tool

<p align="center"> <img src="src/code/SPhysics/icon.png" alt="SPhysics" width="50"/> </p>

SPhysics

GitHub repo size GitHub code size Nuget
Build Code Analysis Code Lint Documentation

Physics for .NET, written against generic math. Every formula is generic over the numeric type, so the same call site works for double, float, decimal or Half without overloads or casting. Builds on top of SMath.

Documentation

Full API reference, guides, and performance benchmarks are available on the Documentation Website.

Design

Generic over the number type. Constraints express the physics rather than a concrete type: a formula needing a square root asks for IRootFunctions<N>, one needing only addition asks for INumberBase<N>. Passing a type that cannot support the operation is a compile error.

Static and allocation free. There are no wrapper structs for quantities or vectors. Values are plain scalars and tuples, so they stay on the stack and interoperate with any other library. All entry points are static.

Names that read as the formula. Types are named after the quantity being computed, giving call sites like GravitationalForce.Outside(m1, m2, r) or KineticEnergy.Linear(m, v).

Contents

Area Types
Base quantities Length, Mass, Time, ElectricCurrent, Temperature, AmountOfSubstance, LuminousIntensity
Mechanics Velocity, Acceleration, Jerk, Momentum, AngularMomentum, AngularVelocity, Impulse, Force, FrictionForce, DragForce, DragCoefficient, MomentOfInertia, CenterOfMass, CenterOfGravity, ReducedMass, VelocityVerlet, ElasticCollision
Energy & Power Energy, KineticEnergy, PotentialEnergy, GravitationalEnergy, Power, ThermalRadiation
Gravitation Gravity, GravitationalForce, GravitationalIntensity, GravitationalPotential, NBodyGravity
Celestial mechanics Barycenter, EscapeVelocity, MeanAnomaly, MeanMotion, OrbitalEccentricity, OrbitalPeriod, SemiMajorAxis, TrueAnomaly, OrbitalVelocity, HillSphere, RocheLimit, EccentricAnomaly, OrbitalStateVectors, MeanLongitude
Other Density, Distance, PlaneAngle, SolidAngle, Frequency, Pressure, AbsorbedDose

Setup

<PackageReference Include="SPhysics" Version="X.X.X" />

Replace X.X.X with the current version from NuGet. The package targets net8.0 and runs on any newer runtime.

Usage

Gravitation, with the numeric type inferred from the arguments:

using SPhysics;
using SPhysics.CelestialMechanics;

const double G = 6.67430e-11;

// Newton's law of universal gravitation between two point bodies
var force = GravitationalForce.Outside(mass1: 5.972e24, mass2: 7.342e22, distance: 3.844e8);

// Escape velocity from a spherically symmetric body of given mass and radius
var vEsc = EscapeVelocity.Eval(mass: 5.972e24, distance: 6.371e6, gravitationalConstant: G);

Energy and motion:

using SPhysics;

// Linear kinetic energy
var keLinear = KineticEnergy.Linear(mass: 1.5, velocity: 12.0);

// Spinning kinetic energy
var keSpin = KineticEnergy.Spinning(momentOfInertia: 0.4, angularVelocity: 3.0);

// Gravitational potential energy between two bodies
var epg = GravitationalEnergy.Eval(mass1: 5.972e24, mass2: 1.5, distance: 6.371e6);

N-body force accumulation into a stack allocated span:

using SPhysics;

const double G = 6.67430e-11;

Span<(double X, double Y, double Mass)> bodies = stackalloc (double, double, double)[]
{
    (0, 0, 5.972e24),
    (3.844e8, 0, 7.342e22),
    (1.496e11, 0, 1.989e30),
};

var (fx, fy) = GravitationalForce.Eval<double>(bodies, index: 0, gravitationConst: G);

Performance

NBodyGravity evaluates all pairs, O(n^2), in one of two kernels:

  • Vectorized across the pairs: one Vector<T> evaluates 8 float or 4 double pairs at once with AVX2. The overloads over tuples copy the components into pooled spans first; NBodyGravity.Soa takes them in separate spans (structure of arrays) and skips the copies.
  • Scalar, NBodyGravity.Scalar: pair by pair on the tuples, no copies.

Time of one evaluation, float bodies, a gravitational constant per body (NBodyGravityBenchmark, x64 with AVX2):

Overloads 4 bodies 16 64 512 3000
NBodyGravity.Scalar, 2D 55 ns 0.72 µs 11.9 µs 0.76 ms 26.0 ms
NBodyGravity, 2D 123 ns 0.78 µs 4.6 µs 0.12 ms 3.6 ms
NBodyGravity.Soa, 2D 87 ns 0.74 µs 4.2 µs 0.12 ms 3.5 ms
NBodyGravity.Scalar, 3D 71 ns 0.98 µs 16.2 µs 1.04 ms 35.4 ms
NBodyGravity, 3D 169 ns 0.94 µs 5.9 µs 0.17 ms 5.0 ms
NBodyGravity.Soa, 3D 103 ns 0.84 µs 5.6 µs 0.17 ms 5.0 ms
  • The scalar kernel is faster below about 16 bodies; from there the vectorized one wins, 7x for thousands of bodies. The caller picks the kernel for its body count.
  • The kernels differ in rounding. The vectorized one sums the pulls on a body in several lanes, so its rounding depends on the vector width: reproducible on one machine, not across machines with different vector widths. The scalar one is reproducible everywhere.
  • VelocityVerlet.Soa advances the structure of arrays, bitwise identical to the tuple steps.

Contributing

Ideas, bug reports and pull requests are welcome. Open an issue to propose a change, or send a pull request directly.

License

Project is under MIT license.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.6.0-dev 115 10/21/2026
0.5.0-dev 57 10/21/2026
0.4.0-dev 84 10/21/2026
0.3.0-dev 107 10/7/2026
0.2.0 306 8/5/2026
0.1.0 302 3/8/2025