Skip to content
Bg-crPublic

About

A dimensional safe C++ header-only mechanics and electromagnetics simulation library.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Phyth

A dimensionally safe C++ header-only mechanics and electromagnetics simulation library.

CI License C++ Header-only Code Size

Table of Contents

Description

Phyth is a C++ simulation library designed for numerical method researchers. While maintaining lightweight and safety, it breaks down the simulation process into replaceable independent components, allowing you to change integrators or constraint solvers like building blocks, without being troubled by the complex architecture of large engines.

Features

  • Type-safe physical quantities: Literals like 1_kg, 1_m make code concise and readable, while the type system catches dimension mismatches at compile time—assigning meters to seconds, or using force as mass, fails before runtime, eliminating unit-confusion bugs.

  • Semantic unit conversion: Units of the same dimension (e.g., joules and newton-meters) retain distinct semantic labels. Conversions preserve meaning, and output formatting automatically distinguishes J from N*m—no redundant re-declaration, no ambiguity.

  • Straightforward simulation workflow: Create particles → apply constraints → define forces → loop over integration and correction. The simulation loop follows the same sequence as a physics textbook, making the learning curve remarkably shallow.

  • Interchangeable components: Constraint solvers (e.g., DistanceConstraint) and force models (e.g., GravityFormula) are designed as pluggable, independent components—swap integrators or implement custom algorithms without restructuring the entire framework.

  • Zero dependencies, lightweight core: The core library has no third-party dependencies and compiles to a small binary, suitable for embedded environments, teaching demonstrations, and research scenarios that demand deep customization.

  • Built-in validation hooks: Energy monitoring interfaces (e.g., GetTotalEnergy()) are available out of the box, making it easy to verify physical conservation laws during simulation and simplifying debugging and experiment validation.

Positioning

Existing physics engines sit at two extremes:

Industrial Engines Scientific Engines
Speed ✅ Fast ⚠️ Slow
Robustness ✅ Battle-tested ⚠️ Academic
Transparency ❌ Black box (stages fused) ✅ Exposed internals
Modifiability ❌ Fixed solver, hard to swap ⚠️ Heavy codebase, hard to modify
Dependencies ✅ Minimal ❌ Heavy dependency graph

Phyth sits right in the middle:

Transparent like a scientific engine, lightweight like an industrial one.

It gives researchers the freedom to develop new numerical methods, without the friction of production-level complexity or academic-level baggage.

  • More transparent than industrial engines — simulation stages are exposed as replaceable components, so you can swap integrators or constraint solvers without fighting the framework.
  • More lightweight than scientific engines — zero dependencies, minimal codebase, easy to build, modify, and experiment with.

In short, Phyth gives researchers the freedom to develop new numerical methods, without the friction of production-level complexity or academic-level baggage.

Accuracy Verification

The first image is the analysis (based on the Quick Start code with detailed output):

SinglePendulumAnalysis.png

The latest image below shows the data analysis of the double pendulum simulation (dt=2e-4 s and sample 1000 points), and the calculated relative fluctuation is about 1.37e-3%(1.37e-5):

DoublePendulumAnalysisDt2e-4.png

Requirements

  • C++17 or higher
  • Compiler: GCC 9+, Clang 10+, MSVC 19.20+ (Visual Studio 2019+)

Platform Support

Phyth is a header-only library with no third-party dependencies and no platform-specific system calls. It relies exclusively on the C++ standard library, making it portable across platforms.

Platform Compiler Status
Linux GCC 9+, Clang 10+ ✅ CI-tested
Windows MSVC 19.20+, MinGW ✅ Verified
macOS Apple Clang 13+ ⚠️ Expected to work

Note: If you use Phyth on an untested platform and encounter issues, please file an issue — we'll help investigate.

Installation

Clone the Repository

git clone https://github.com/Bg-cr/Phyth.git

Include in Your Project

Add the include/ directory to your compiler's header search path:

#include <Phyth/Phyth.hpp>

Done. No compilation required.

Quick Start

The following code demonstrates single pendulum motion under gravity. The output results consist of the particle and total mechanical energy for each time step, which are used to verify numerical stability.

#include "Phyth/Phyth.hpp"
#include <iostream>

using namespace Phyth;
using namespace Phyth::Mechanics;

constexpr Quantity<Second> SIMULATION_TIME = 2.73_s;

int main() {
    Config::dt = 1_s / 1000;
    const auto anchor = std::make_shared<Particle>(1_kg, Vector3<Quantity<Meter>>{0_m, 0_m, 0_m});
    anchor->SetFixed(true);
    
    const auto pendulum = std::make_shared<Particle>(1_kg, Vector3<Quantity<Meter>>{1_m, 0_m, 0_m});
    
    const DistanceConstrainer constraint{anchor, pendulum};

    pendulum->SetComputeForcesFunction([](Particle *p) {
        p->ApplyForce({0_N, -1_kg * Consts::g, 0_N});
    });

    for (Quantity<Second> t = 0_s; t < SIMULATION_TIME; t += Config::dt) {
        pendulum->Integrate();
        constraint.Correct();

        std::cout << t << " " << *pendulum << " " << pendulum->GetTotalEnergy(-1_m) << std::endl;
    }

    return 0;
}

Expected output example

0 s Particle{pos=(1 m, -4.90332e-06 m, 0 m), mass=1 kg} 9.80665 J
0.001 s Particle{pos=(1 m, -1.96133e-05 m, 0 m), mass=1 kg} 9.80665 J
0.002 s Particle{pos=(1 m, -4.41299e-05 m, 0 m), mass=1 kg} 9.80665 J
0.003 s Particle{pos=(1 m, -7.84532e-05 m, 0 m), mass=1 kg} 9.80665 J
0.004 s Particle{pos=(1 m, -0.000122583 m, 0 m), mass=1 kg} 9.80665 J
0.005 s Particle{pos=(1 m, -0.00017652 m, 0 m), mass=1 kg} 9.80665 J
0.006 s Particle{pos=(1 m, -0.000240263 m, 0 m), mass=1 kg} 9.80665 J
0.007 s Particle{pos=(1 m, -0.000313813 m, 0 m), mass=1 kg} 9.80665 J
0.008 s Particle{pos=(1 m, -0.000397169 m, 0 m), mass=1 kg} 9.80665 J
0.009 s Particle{pos=(1 m, -0.000490332 m, 0 m), mass=1 kg} 9.80665 J
0.01 s Particle{pos=(1 m, -0.000593302 m, 0 m), mass=1 kg} 9.80665 J
0.011 s Particle{pos=(1 m, -0.000706079 m, 0 m), mass=1 kg} 9.80665 J
0.012 s Particle{pos=(1 m, -0.000828662 m, 0 m), mass=1 kg} 9.80665 J
0.013 s Particle{pos=(1 m, -0.000961052 m, 0 m), mass=1 kg} 9.80665 J
0.014 s Particle{pos=(0.999999 m, -0.00110325 m, 0 m), mass=1 kg} 9.80665 J
0.015 s Particle{pos=(0.999999 m, -0.00125525 m, 0 m), mass=1 kg} 9.80665 J
...

Note: The above output is formatted for readability. Actual raw output may show slight variations in the last 3–4 significant digits due to floating-point rounding.

Verification method If the above code is run, the total energy at each moment should be approximately 9.80665 J.

In fact, after running and analysis the data, it can be concluded that the relative fluctuation within 2.73s is approximately 1.32e-5, which confirms that the integrator and constraint solver are working properly.

For specific analysis of the above program, see Accuracy Verification.

Simulation workflow

  1. Set Config::dt (time step)
  2. Add elements (e.g., Particle)
  3. Loop:
  • Integrate() updates every element
  • Correct() applies Velocity Correct to particles.
  • process data

Project Struct

Below is the project tree diagram and introduction:

F:.
├─examples
├─include
│  └─Phyth
│      ├─Core
│      ├─Elements
│      │  ├─Electromagnetics
│      │  │  └─ChargeSources
│      │  └─Mechanics
│      ├─Physical
│      ├─System
│      └─Tools
└─Phyth
  • example/ — Examples, like SinglePendulum.cpp
  • Phyth/include/
    • Core/ — Compile-time dimensional analysis system
    • Elements/ — Physics building blocks (mechanics + electromagnetics)
    • Physical/ — Constants like g, G, epsilon_0
    • Tools/ — Tools such as Vector3 and helper functions

FAQ

Q: Is dimensionality checking performed during compilation or at runtime? Is it zero-cost?

A: Compile-time. In Release mode, Quantity<T, Dim> has a memory layout identical to that of a native double, with zero runtime overhead.

Q: Can units in a parallel relationship be transformed into each other?

A: Yes. For example, for N*m and J, the dimensional system will automatically deduce the units, while the unit labels will retain the original semantics. The display format is managed by UnitsRegistry to ensure that the physical meaning is not lost during output.

Q: Is electromagnetic field an analytical solution or a numerical solution?

Numerical integration. The electric field and potential are approximately calculated by dividing a rectangular prism into volume elements and superimposing Coulomb fields on each volume element. The accuracy is comparable to the analytical formula, but the speed is not very fast. This is the implementation decision of the current version - prioritizing code clarity over computational efficiency.

Q: What physics can be considered at present?

  • Mechanics: Particle, Spring, Distance Constraint (Single/Double Pendulum Verified)
  • Electromagnetics: Calculation of point/line/surface/bulk charges, electric dipoles, and electrostatic fields, etc.

Known Limitations

  • Performance: Electromagnetic field calculations use direct summation over volume elements . For large-scale 3D simulations, this may be slow.
  • No GPU acceleration: All computations are CPU-bound in the current version.
  • No collision detection: Phyth focuses on dynamics and field calculations, not contact mechanics.
  • No automatic differentiation: Gradients must be computed manually if needed for optimization.

Contributing

We welcome contributions from researchers, students, and developers!

How to Contribute

  1. Report bugs or request features → Use our Issue Templates
  2. Submit code changes → Fork the repo, create a branch, and open a Pull Request
  3. Suggest new physics modules → Start a Discussion

Guidelines

  • All new formulas must include validation tests (compare against analytical solutions)
  • Follow Google C++ Style Guide
  • Write descriptive commit messages

See CONTRIBUTING.md for full details.

Acknowledgments

Phyth's dimensional analysis system draws inspiration from:

  • Boost.Units — compile-time dimensional analysis in C++
  • The foundational work on dimensional analysis by Buckingham and Bridgman

The validation framework was inspired by best practices in computational physics education.

About

A dimensional safe C++ header-only mechanics and electromagnetics simulation library.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages