Particles
Particle realizations shared by the physics packages: point masses, active and Brownian particles, and forces.
ActiveParticleElement(label, visual=POINTS, *, x=0.0, theta=0.0, D_t=0.1, D_r=1.0, omega=0.0)
Bases: Element
Active particle in the plane, whose position diffuses, dx = sqrt(2 D_t) dW, and whose orientation turns.
The orientation turns at the angular velocity omega and diffuses, dtheta = omega dt + sqrt(2 D_r) dW. A
SelfPropulsionInteraction adds the drift v (cos theta, sin theta) of the position. With omega = 0 it is an
active Brownian particle, and otherwise a chiral active particle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the particle or the group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
POINTS
|
x
|
Annotated[ArrayLike, StateSpec(vector=True, role=position)]
|
The initial position. |
0.0
|
theta
|
Annotated[float, StateSpec(period=2 * pi, role=direction)]
|
The initial orientation. |
0.0
|
D_t
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The translational diffusion coefficient. |
0.1
|
D_r
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The rotational diffusion coefficient. |
1.0
|
omega
|
Annotated[float, ParameterSpec()]
|
The angular velocity of a chiral particle. |
0.0
|
Examples:
>>> from skcomplex.systems.physics.common.particles import ActiveParticleElement
>>> ActiveParticleElement('swimmer', D_r=2.0).D_r
2.0
Source code in src/skcomplex/systems/physics/common/particles/_active_particle.py
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | |
BrownianParticleElement(label, visual=POINTS, *, x=0.0, gamma=1.0, temperature=1.0)
Bases: Element
Overdamped Brownian particle at the position x, with the friction gamma and the thermal energy temperature.
The particle moves by dx = F / gamma dt + sqrt(2 temperature / gamma) dW, with the thermal noise of
ThermalNoiseInteraction and the forces of other interactions, which divide by gamma.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the particle or the group. |
required |
visual
|
VisualSpec | None
|
How the element is drawn, or |
POINTS
|
x
|
Annotated[ArrayLike, StateSpec(vector=True, role=position)]
|
The initial position. |
0.0
|
gamma
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The friction coefficient. |
1.0
|
temperature
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The thermal energy. |
1.0
|
Examples:
>>> from skcomplex.systems.physics.common.particles import BrownianParticleElement
>>> BrownianParticleElement('bead', temperature=2.0).temperature
2.0
Source code in src/skcomplex/systems/physics/common/particles/_brownian_particle.py
46 47 48 49 50 51 52 53 54 55 56 57 58 | |
ConstantForceInteraction(label, *, target, F=0.0, state='x', divisor='m')
Bases: RateInteraction
Constant force F on a target, the second derivative F / m of its position of order 2.
It is the rate F with the mass as divisor, and the LAMMPS backend runs it as fix addforce.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the element or group the force acts on. |
required |
F
|
Annotated[ArrayLike, ParameterSpec(vector=True)]
|
The force vector. A number applies to every component. |
0.0
|
state
|
str
|
The name of the vector state of order 2 that holds the position of the target. |
'x'
|
divisor
|
str
|
The name of the state or parameter that holds the mass of the target. |
'm'
|
Examples:
>>> from skcomplex.systems.physics.common.particles import ConstantForceInteraction
>>> ConstantForceInteraction('gravity', target='ball', F=[0, -9.81]).F
[0, -9.81]
Source code in src/skcomplex/systems/physics/common/particles/_constant_force.py
42 43 44 45 46 47 48 49 50 51 52 | |
DampingInteraction(label, *, target, gamma=0.1, state='x', divisor='m')
Bases: RateInteraction
Linear damping, a force -gamma * v proportional and opposite to the velocity v of a target.
The velocity is the first derivative of the position, a state of order 2, whose second derivative changes by
-gamma * v / m with the mass as divisor. The LAMMPS backend runs it as fix viscous.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the element or group whose velocity is damped. |
required |
gamma
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The damping coefficient. |
0.1
|
state
|
str
|
The name of the state of order 2 that holds the position of the target. |
'x'
|
divisor
|
str
|
The name of the state or parameter that holds the mass of the target. |
'm'
|
Examples:
>>> from types import SimpleNamespace
>>> from sage.all__sagemath_symbolics import var
>>> from skcomplex.systems.physics.common.particles import DampingInteraction
>>> target = SimpleNamespace(x=var('x'), m=2)
>>> damping = DampingInteraction('air', target='ball', gamma=0.1).prepare()
>>> [law.value for law in damping.run(SimpleNamespace(target=target, gamma=var('gamma'))).laws_]
[-1/2*gamma*derivative(x, 1)]
Source code in src/skcomplex/systems/physics/common/particles/_damping.py
49 50 51 52 53 54 55 56 57 58 59 | |
DoubleWellElement(label, visual=None, *, x=-1.0, amplitude=0.1, frequency=0.01, D=0.12)
Bases: Element
Particle at the position x in the double well x^4 / 4 - x^2 / 2, forced periodically and by noise.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the particle. |
required |
visual
|
VisualSpec | None
|
How the particle is drawn, or |
None
|
x
|
Annotated[float, StateSpec(role=position)]
|
The initial position. |
-1.0
|
amplitude
|
Annotated[float, ParameterSpec()]
|
The amplitude of the periodic forcing. |
0.1
|
frequency
|
Annotated[float, ParameterSpec()]
|
The frequency of the forcing. |
0.01
|
D
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The noise intensity. |
0.12
|
Examples:
>>> from skcomplex.systems.physics.common.particles import DoubleWellElement
>>> DoubleWellElement('particle', D=0.2).D
0.2
Source code in src/skcomplex/systems/physics/common/particles/_double_well.py
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | |
HarmonicForceInteraction(label, *, target, F=0.0, omega=1.0, state='x', divisor='m')
Bases: RateInteraction
Periodic force F cos(omega t) on a target, the second derivative F cos(omega t) / m of its position.
It is the rate F cos(omega t) with the mass as divisor, applied to every component of the position.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the element or group the force acts on. |
required |
F
|
Annotated[float, ParameterSpec()]
|
The amplitude of the force. |
0.0
|
omega
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The angular frequency of the force. |
1.0
|
state
|
str
|
The name of the state of order 2 that holds the position of the target. |
'x'
|
divisor
|
str
|
The name of the state or parameter that holds the mass of the target. |
'm'
|
Examples:
>>> from skcomplex.systems.physics.common.particles import HarmonicForceInteraction
>>> HarmonicForceInteraction('drive', target='mass', F=0.5, omega=2.0).omega
2.0
Source code in src/skcomplex/systems/physics/common/particles/_harmonic_force.py
46 47 48 49 50 51 52 53 54 55 56 57 58 | |
HarmonicPotentialInteraction(label, *, target, k=1.0, center=0.0, states='x', divisor='m')
Bases: PotentialEnergyInteraction
Harmonic potential that pulls a particle towards a center.
The energy is k * |x - center|**2 / 2.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the particle. |
required |
k
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The stiffness. |
1.0
|
center
|
Annotated[ArrayLike, ParameterSpec(vector=True)]
|
The center. A number applies to every component. |
0.0
|
states
|
str
|
The name of the vector state that holds the position of the particle. |
'x'
|
divisor
|
str
|
The name of the state or parameter that holds the mass of the particle. |
'm'
|
Examples:
>>> from skcomplex.systems.physics.common.particles import HarmonicPotentialInteraction
>>> HarmonicPotentialInteraction('trap', target='ball', k=2.0).k
2.0
Source code in src/skcomplex/systems/physics/common/particles/_harmonic_potential.py
47 48 49 50 51 52 53 54 55 56 57 58 59 | |
LangevinThermostatInteraction(label, *, target, temperature=1.0, gamma=1.0, state='x', divisor='m')
Bases: RelaxationInteraction
Langevin thermostat, which adds a drag -gamma * v and a random force that hold particles at a temperature.
Every velocity component follows dv = -gamma * v / m * dt + sqrt(2 * gamma * temperature) / m * dW, with the
temperature in energy units, a relaxation of the velocity towards rest over the time m / gamma with additive
noise. The velocity is the first derivative of the position, a state of order 2, and the mass is the divisor. A
system with a thermostat is stochastic, and its velocities relax to the Maxwell-Boltzmann distribution at that
temperature.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the particle or particle group. |
required |
temperature
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The temperature in energy units. |
1.0
|
gamma
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The friction coefficient. |
1.0
|
state
|
str
|
The name of the vector state of order 2 that holds the positions of the particles. |
'x'
|
divisor
|
str
|
The name of the state or parameter that holds the masses of the particles. |
'm'
|
Examples:
>>> from skcomplex.systems.physics.common.particles import LangevinThermostatInteraction
>>> LangevinThermostatInteraction('bath', target='gas', temperature=2.0).temperature
2.0
Source code in src/skcomplex/systems/physics/common/particles/_langevin_thermostat.py
51 52 53 54 55 56 57 58 59 60 61 62 63 64 | |
LennardJonesInteraction(label, first, second, cutoff=1.0, position='x', *, write='x', divisor=None, period=None, epsilon=1.0, sigma=1.0)
Bases: PairCouplingInteraction
Lennard-Jones pair potential, 4 * epsilon * ((sigma / r) ** 12 - (sigma / r) ** 6), without a shift.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
first
|
str
|
The path of the group or particle of the first members. |
required |
second
|
str
|
The path of the group or particle of the second members. |
required |
cutoff
|
float
|
The distance beyond which pairs do not interact. |
1.0
|
position
|
str
|
The name of the vector state that holds the positions of the members. |
'x'
|
write
|
str
|
The name of the state whose rate the force changes, the position of order 2 by default. |
'x'
|
divisor
|
str | None
|
The name of the parameter that holds the masses of the members, or |
None
|
period
|
float | None
|
The side of a periodic box, for minimum image distances, or |
None
|
epsilon
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The depth of the potential well. |
1.0
|
sigma
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The distance at which the potential is zero. |
1.0
|
Examples:
>>> from skcomplex.systems.physics.common.particles import LennardJonesInteraction
>>> LennardJonesInteraction('lj', first='gas', second='gas', cutoff=2.5).sigma
1.0
Source code in src/skcomplex/systems/physics/common/particles/_lennard_jones.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | |
MassPointElement(label, x=0.0, x_d1=0.0, visual=None, *, m=1.0)
Bases: PointElement
Point mass, a point whose position x has order 2, with its velocity x_d1 and a mass m.
The forces on the point divide by the mass through their divisor 'm'.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the point. |
required |
x
|
ArrayLike
|
The initial position. A number applies to every component. |
0.0
|
x_d1
|
ArrayLike
|
The initial velocity. A number applies to every component. |
0.0
|
visual
|
VisualSpec | None
|
How the point is drawn, or |
None
|
m
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The mass. |
1.0
|
Attributes:
| Name | Type | Description |
|---|---|---|
default_visual_ |
Points at the positions. |
Examples:
>>> from skcomplex.systems.physics.common.particles import MassPointElement
>>> MassPointElement('ball', x=[0.0, 1.0], m=2.0).m
2.0
Source code in src/skcomplex/systems/physics/common/particles/_mass_point.py
47 48 49 50 51 52 53 54 55 56 57 | |
PotentialEnergyInteraction(label, *, target, potential=None, states='x', divisor='m')
Bases: GradientInteraction
Potential energy of the positions of particles, whose force on every particle changes its velocity.
It is the gradient of the energy with the mass as divisor: the force -dU/dx on every particle gives the second
derivative of its position of order 2, the force divided by its mass. A subclass binds one role per particle and
returns the energy from _get_potential, or a user passes the energy as potential.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the particle or particle group. |
required |
potential
|
Callable[[SimpleNamespace], object] | None
|
A function of the namespace that returns the energy, or |
None
|
states
|
str | Sequence[str]
|
The name of the vector state that holds the position of every particle. |
'x'
|
divisor
|
str
|
The name of the state or parameter that holds the mass of every particle. |
'm'
|
Examples:
>>> from types import SimpleNamespace
>>> from sage.all__sagemath_symbolics import var, vector
>>> from skcomplex.systems.physics.common.particles import PotentialEnergyInteraction
>>> ball = SimpleNamespace(x=vector([var('x')]), m=2)
>>> trap = PotentialEnergyInteraction('trap', target='ball', potential=lambda s: s.target.x[0] ** 2)
>>> [law.value for law in trap.prepare().run(SimpleNamespace(target=ball)).laws_]
[(-x)]
Source code in src/skcomplex/systems/physics/common/particles/_potential_energy.py
47 48 49 50 51 52 53 54 55 56 | |
PropulsionStepInteraction(label, *, target, speed=1.0, state='x', heading='theta')
Bases: MapInteraction
Step x(t + 1) = x + speed (cos theta, sin theta) of a position in the plane along a heading, in discrete time.
The step reads the heading at the start of the step, as every map of the step does.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction, unique among the parts of its system. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the particle or the group whose positions move. |
required |
speed
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The distance moved in one step. |
1.0
|
state
|
str
|
The name of the vector state that holds the position. |
'x'
|
heading
|
str
|
The name of the state that holds the heading. |
'theta'
|
Examples:
>>> from types import SimpleNamespace
>>> from sage.all__sagemath_symbolics import var, vector
>>> from skcomplex.systems.physics.common.particles import PropulsionStepInteraction
>>> step = PropulsionStepInteraction('propulsion', target='flock').prepare()
>>> target = SimpleNamespace(x=vector([var('x1'), var('x2')]), theta=var('theta'))
>>> [law.value for law in step.run(SimpleNamespace(target=target, speed=var('v'))).laws_]
[(v*cos(theta) + x1, v*sin(theta) + x2)]
Source code in src/skcomplex/systems/physics/common/particles/_propulsion_step.py
48 49 50 51 52 53 54 55 56 57 58 59 | |
SelfPropulsionInteraction(label, *, target, speed=1.0, state='x', heading='theta')
Bases: RateInteraction
Self-propulsion x' += speed (cos theta, sin theta) of a position in the plane along a heading theta.
The heading is a state of the same target, which other laws turn and diffuse.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction, unique among the parts of its system. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the particle or the group whose positions move. |
required |
speed
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The self-propulsion speed. |
1.0
|
state
|
str
|
The name of the vector state that holds the position. |
'x'
|
heading
|
str
|
The name of the state that holds the heading. |
'theta'
|
Examples:
>>> from types import SimpleNamespace
>>> from sage.all__sagemath_symbolics import var, vector
>>> from skcomplex.systems.physics.common.particles import SelfPropulsionInteraction
>>> propulsion = SelfPropulsionInteraction('propulsion', target='swimmers').prepare()
>>> target = SimpleNamespace(x=vector([var('x1'), var('x2')]), theta=var('theta'))
>>> [law.value for law in propulsion.run(SimpleNamespace(target=target, speed=var('v'))).laws_]
[(v*cos(theta), v*sin(theta))]
Source code in src/skcomplex/systems/physics/common/particles/_self_propulsion.py
48 49 50 51 52 53 54 55 56 57 58 59 | |
SpringInteraction(label, *, first, second, k=1.0, length=0.0, states='x', divisor='m')
Bases: PotentialEnergyInteraction
Spring between two particles.
The energy is k * (|x_first - x_second| - length)**2 / 2, and its gradient moves both particles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
first
|
Annotated[str, RoleSpec()]
|
The path of the first particle. |
required |
second
|
Annotated[str, RoleSpec()]
|
The path of the second particle. |
required |
k
|
Annotated[float, ParameterSpec(domain=open(0, oo))]
|
The stiffness. |
1.0
|
length
|
Annotated[float, ParameterSpec(domain=closed_open(0, oo))]
|
The rest length. |
0.0
|
states
|
str
|
The name of the vector state that holds the positions of the particles. |
'x'
|
divisor
|
str
|
The name of the state or parameter that holds the masses of the particles. |
'm'
|
Examples:
>>> from skcomplex.systems.physics.common.particles import SpringInteraction
>>> SpringInteraction('spring', first='a', second='b', k=3.0, length=1.0).length
1.0
Source code in src/skcomplex/systems/physics/common/particles/_spring.py
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | |
ThermalNoiseInteraction(label, *, target, state='x')
Bases: RateInteraction
Thermal noise of overdamped particles, the random force sqrt(2 gamma temperature) dW divided by gamma.
The friction gamma and the thermal energy temperature are parameters of the target, so every component of the
position diffuses with the coefficient temperature / gamma.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
The label of the interaction. |
required |
target
|
Annotated[str, RoleSpec()]
|
The path of the particle or the group. |
required |
state
|
str
|
The name of the state that holds the positions. |
'x'
|
Examples:
>>> from skcomplex.systems.physics.common.particles import ThermalNoiseInteraction
>>> ThermalNoiseInteraction('bath', target='beads').divisor
'gamma'
Source code in src/skcomplex/systems/physics/common/particles/_thermal_noise.py
37 38 | |