Domains API Reference

The mechanics_dsl.domains package provides domain-specific physics implementations following a common interface defined by the abstract PhysicsDomain base class.

Base Classes

PhysicsDomain

class mechanics_dsl.domains.PhysicsDomain

Abstract base class that all physics domains must inherit from. Defines the common interface for Lagrangian/Hamiltonian derivation and equation solving.

Attributes:

  • name: Human-readable domain name

  • coordinates: List of generalized coordinates

  • parameters: Dictionary of physical parameters

  • equations: Derived equations of motion

  • is_compiled: Whether equations have been derived

Abstract Methods:

abstract define_lagrangian() sp.Expr

Define the Lagrangian L = T - V.

abstract define_hamiltonian() sp.Expr

Define the Hamiltonian H = T + V.

abstract derive_equations_of_motion() Dict[str, sp.Expr]

Derive equations of motion.

abstract get_state_variables() List[str]

Get list of state variables for ODE system.

Common Methods:

set_parameter(name: str, value: float) None

Set a single physical parameter.

set_parameters(params: Dict[str, float]) None

Set multiple parameters at once.

add_coordinate(name: str) None

Add a generalized coordinate.

validate_parameters() Tuple[bool, List[str]]

Validate that all required parameters are set.

get_conserved_quantities() Dict[str, sp.Expr]

Get expressions for conserved quantities.

Classical Mechanics

The mechanics_dsl.domains.classical package provides implementations for traditional point-mass and rigid body mechanics.

LagrangianMechanics

class mechanics_dsl.domains.classical.LagrangianMechanics

Lagrangian mechanics using the Euler-Lagrange equations.

Example:

from mechanics_dsl.domains.classical import LagrangianMechanics
import sympy as sp

# Create domain
domain = LagrangianMechanics("simple_pendulum")
domain.add_coordinate("theta")
domain.set_parameters({"m": 1.0, "l": 1.0, "g": 9.81})

# Define energy
theta = domain.get_symbol("theta")
theta_dot = domain.get_symbol("theta_dot")
m, l, g = sp.symbols("m l g", positive=True)

T = sp.Rational(1, 2) * m * l**2 * theta_dot**2
V = m * g * l * (1 - sp.cos(theta))

domain.set_kinetic_energy(T)
domain.set_potential_energy(V)

# Derive equations
equations = domain.derive_equations_of_motion()
print(equations)

Methods:

get_symbol(name: str, **assumptions) sp.Symbol

Get or create a SymPy symbol with caching.

set_kinetic_energy(expr: sp.Expr) None

Set the kinetic energy T.

set_potential_energy(expr: sp.Expr) None

Set the potential energy V.

set_lagrangian(expr: sp.Expr) None

Set the Lagrangian directly (alternative to T and V).

derive_equations_of_motion() Dict[str, sp.Expr]

Derive equations using d/dt(∂L/∂q̇) - ∂L/∂q = 0.

HamiltonianMechanics

class mechanics_dsl.domains.classical.HamiltonianMechanics

Hamiltonian mechanics using Hamilton’s equations.

Example:

from mechanics_dsl.domains.classical import HamiltonianMechanics

domain = HamiltonianMechanics("harmonic_oscillator")
domain.add_coordinate("q")

# Define Hamiltonian H = p²/2m + kq²/2
q = domain.get_symbol("q")
p = domain.get_symbol("p_q")
m, k = sp.symbols("m k", positive=True)

H = p**2 / (2*m) + k * q**2 / 2
domain.set_hamiltonian(H)

# Get Hamilton's equations: dq/dt = ∂H/∂p, dp/dt = -∂H/∂q
equations = domain.derive_equations_of_motion()

Methods:

set_hamiltonian(expr: sp.Expr) None

Set the Hamiltonian expression.

derive_equations_of_motion() Dict[str, sp.Expr]

Derive Hamilton’s equations.

ConstraintHandler

class mechanics_dsl.domains.classical.ConstraintHandler

Handles mechanical constraints using Lagrange multipliers.

Example:

from mechanics_dsl.domains.classical import ConstraintHandler
import sympy as sp

handler = ConstraintHandler()

# Pendulum constraint: x² + y² = l²
x, y, l = sp.symbols("x y l")
constraint = x**2 + y**2 - l**2

lambda_sym = handler.add_holonomic_constraint(constraint)

# Augment Lagrangian
L_original = ...
L_augmented = handler.augment_lagrangian(L_original)

Methods:

add_holonomic_constraint(constraint: sp.Expr) sp.Symbol

Add constraint g(q) = 0. Returns Lagrange multiplier symbol.

add_nonholonomic_constraint(constraint: sp.Expr) None

Add velocity-dependent constraint.

augment_lagrangian(lagrangian: sp.Expr) sp.Expr

Create L’ = L + Σ(λᵢgᵢ).

RigidBodyDynamics

class mechanics_dsl.domains.classical.RigidBodyDynamics

Rigid body dynamics with rotational degrees of freedom.

Methods:

set_inertia_tensor(I: sp.Matrix) None

Set the 3×3 inertia tensor.

Kinematics

The mechanics_dsl.domains.kinematics package provides analytical kinematics tools for motion analysis without forces.

KinematicsSolver

class mechanics_dsl.domains.kinematics.KinematicsSolver

Analytical solver for constant acceleration problems.

Example:

from mechanics_dsl.domains.kinematics import KinematicsSolver

solver = KinematicsSolver()
solution = solver.solve(v0=10, a=-9.81, t=2)

print(f"Final velocity: {solution.state.final_velocity} m/s")
print(solution.show_work())

Methods:

solve(**kwargs) KinematicSolution

Solve for unknown kinematic variables given knowns.

derive_formula(unknown: str, knowns: List[str]) sp.Expr

Derive a symbolic formula for the unknown.

ProjectileMotion

class mechanics_dsl.domains.kinematics.ProjectileMotion

Complete projectile motion analysis.

Example:

from mechanics_dsl.domains.kinematics import ProjectileMotion

proj = ProjectileMotion(v0=20, angle=45, height=0)

print(f"Range: {proj.range():.2f} m")
print(f"Max height: {proj.max_height():.2f} m")
print(f"Flight time: {proj.time_of_flight():.2f} s")

Methods:

max_height() float

Calculate maximum height above launch point.

range() float

Calculate horizontal range.

time_of_flight() float

Calculate total time in air.

position_at(t: float) Tuple[float, float]

Get (x, y) position at time t.

velocity_at(t: float) Tuple[float, float]

Get (vx, vy) velocity at time t.

UniformMotion

class mechanics_dsl.domains.kinematics.UniformMotion

Constant velocity motion (zero acceleration).

Methods:

position_at(t: float) float

Get position at time t.

time_to_reach(x: float) float

Get time to reach position x.

FreeFall

class mechanics_dsl.domains.kinematics.FreeFall

Free-fall motion near Earth’s surface.

Methods:

time_to_ground() float

Calculate time to reach ground.

velocity_at_ground() float

Calculate velocity when reaching ground.

Fluid Dynamics

The mechanics_dsl.domains.fluids package provides SPH fluid simulation.

SPHFluid

class mechanics_dsl.domains.fluids.SPHFluid

Smoothed Particle Hydrodynamics fluid simulation.

Example:

from mechanics_dsl.domains.fluids import SPHFluid

# Create fluid with parameters
fluid = SPHFluid(
    smoothing_length=0.05,
    rest_density=1000.0,
    gas_constant=2000.0,
    viscosity=1.0
)

# Add particles in a grid
for i in range(20):
    for j in range(20):
        fluid.add_particle(
            x=0.1 + i * 0.02,
            y=0.1 + j * 0.02,
            mass=0.01
        )

# Simulate
for _ in range(1000):
    fluid.step(dt=0.001)

# Get positions
x, y = fluid.get_positions()

Attributes:

  • smoothing_length: SPH kernel width (h)

  • rest_density: Reference density (ρ₀)

  • gas_constant: Stiffness for equation of state

  • viscosity: Dynamic viscosity coefficient

  • gravity: Gravity vector [gx, gy]

Methods:

add_particle(x, y, mass=1.0, vx=0, vy=0, particle_type='fluid')

Add a particle to the simulation.

compute_density_pressure() None

Compute density and pressure for all particles.

compute_forces() List[np.ndarray]

Compute pressure, viscosity, and gravity forces.

step(dt: float) None

Advance simulation by one timestep.

get_positions() Tuple[np.ndarray, np.ndarray]

Get (x, y) arrays of particle positions.

BoundaryConditions

class mechanics_dsl.domains.fluids.BoundaryConditions

Boundary condition handler for fluid simulations.

Example:

from mechanics_dsl.domains.fluids import BoundaryConditions

bc = BoundaryConditions(
    domain_min=(0.0, 0.0),
    domain_max=(1.0, 1.0)
)

# Add walls
bc.add_wall(0, 0, 1, 0, wall_type='no_slip')  # Bottom
bc.add_wall(0, 0, 0, 1, wall_type='no_slip')  # Left

# Generate boundary particles
boundary_particles = bc.generate_boundary_particles(spacing=0.02)

Methods:

add_wall(x1, y1, x2, y2, wall_type='no_slip')

Add a wall segment. Types: ‘no_slip’, ‘free_slip’, ‘open’.

enforce_box_boundary(position, velocity, restitution=0.5)

Enforce box boundaries with reflection.

enforce_periodic(position) np.ndarray

Apply periodic boundary conditions.

generate_boundary_particles(spacing: float) List[Dict]

Generate boundary particles along walls.