Hatch Latest Release License Pipeline Status Pylint

Synopsis

This is the Python package used to simulate and analyze the particle-based spatial continuous Kuramoto model presented in the paper entitled Particle-Based Framework for Continuous Fields of Coupled Phase Oscillators: Exploring Clustering and Symmetry Breaking by Hugues Berry, Leonardo Trujillo and Jan-Michael Rye.

Installation

The package provided a standard pyproject.toml file and should work with all standard Python package managers, e.g.

git clone "https://gitlab.inria.fr/aistrosight/kuramoto_sph.git"
pip install kuramoto_sph

From Source

With venv and pip:

git clone https://gitlab.inria.fr/aistrosight/kuramoto_sph
python3 -m venv venv
source venv/bin/activate
pip install -U pip
pip install -U -e ./kuramoto_sph

With uv:

git clone https://gitlab.inria.fr/aistrosight/kuramoto_sph
uv venv venv
source venv/bin/activate
uv pip install -U -e ./kuramoto_sph

Usage

The package provides both a Python API and command-line tools for running simulations and analyzing their results. Because all results are fully determined by the input parameters, they are stored in a common directory for re-use across different experiments. By default, results are stored in a results subdirectory of the current working directory but the location can be controlled by the KURAMOTO_SPH_RESULTS_DIR environment variable described in the subsection below.

The results files themselves are named with non-user-friendly hashes of the input parameters used to generate them. Rather than access them directly, it is recommended to use the classes and command-line tools provided by the package to retrieve them.

Command-line Usage

The package installs the kuramoto_sph executable which can be used to configure and run simulations. The executable supports multiple subcommands which are described in the command’s help message (see kuramoto_sph --help for details).

usage: kuramoto_sph [-h] {run,batch,process} ...

Simulate and analyze a particle-based spatial continous Kuramoto model.

positional arguments:
  {run,batch,process}
    run                Run one simulation.
    batch              Batch-run multiple simulations in parallel.
    process            Process results.

options:
  -h, --help           show this help message and exit

kuramoto_sph run

The run subcommand is used to run one simulation at a time. When invoked without any arguments it will run a short simulation with default arguments. Simulation parameters can be changed by command-line arguments directly or by loading a custom YAML configuration file with user-defined parameters.

usage: kuramoto_sph run [-h] [-v] [--overwrite] [-c PATH] [--gen-config PATH]
                        [--output PATH] [--seed SEED] [--n-osc N_OSC]
                        [--delta-t DELTA_T] [--coupling-k COUPLING_K]
                        [--n-timesteps N_TIMESTEPS] [--n-save N_SAVE]
                        [--lx LX] [--h-sph H_SPH]
                        [--boundary-cond BOUNDARY_COND]
                        [--particle-distrib PARTICLE_DISTRIB]
                        [--positions POSITIONS] [--omegas OMEGAS]
                        [--thetas THETAS]

options:
  -h, --help            show this help message and exit
  -v, --verbose         Increase logging level to DEBUG.
  --overwrite           Overwrite existing files.
  -c, --config PATH     Load parameters from a YAML configuration file at the
                        given path. Parameters given on the command-line will
                        override values in the configuration file.
  --gen-config PATH     Generate a configuration file at the given path. If
                        the path is "-", the file will be printed to STDOUT.
  --output PATH         Save the results to a CSV file.
  --seed SEED           Seed for the random number generation. [default value:
                        0]
  --n-osc N_OSC         Total number of oscillators. [default value: 10]
  --delta-t DELTA_T     Integration time step (dt). [default value: 1.00e-01]
  --coupling-k COUPLING_K
                        Coupling constant. .. math:: WARNING: In the article,
                        K is aggregated with the kernel: dphi_i/dt = w + 1/N
                        \sum_j W(r,h) sin(phij - phi_i) with W(r,h)=10
                        K/(7*pi*h**2)*f(q) we used K=20 throughout the paper
                        here in the code, it is put outside of the kernel:
                        dphi_i/dt = w + K/N \sum_j W(r,h) sin(phij - phi_i)
                        with W(r,h)=10/(7*pi*h**2)*f(q) it is only a matter of
                        writting [default value: 20]
  --n-timesteps N_TIMESTEPS
                        The number of time steps. The total time will be the
                        number of time steps (n_timesteps) times the
                        integration time step (delta_t). [default value: 2000]
  --n-save N_SAVE       The number of time points to save in the dumped result
                        file, in addition to the initial phases. If less than
                        1, all time points will be saved. [default value: 50]
  --lx LX               The length of the spatial domain. [default value: 10]
  --h-sph H_SPH         The parameter of the smooth kernel h. [default value:
                        1.00e-02]
  --boundary-cond BOUNDARY_COND
                        Boundary condition: [FREE, PERIODIC]. See
                        :py:class:`BoundaryCondition` for available options.
                        [default value: FREE]
  --particle-distrib PARTICLE_DISTRIB
                        Distribution of particle positions: [UNIFORM,
                        CLUSTERED]. See :py:class:`ParticleDistribution` for
                        available options. [default value: UNIFORM]
  --positions POSITIONS
                        An optional 2D array of fixed initial positions to
                        use, where element ij gives the position of the ith
                        oscillator on axis j (j=0 for x, j=1 for y, etc.). If
                        omitted, then random positions will be generated
                        according to the other parameters. [default value:
                        None]
  --omegas OMEGAS       An optional 1D array of natural frequencies or a
                        single natural frequency to use. If an array is given,
                        the ith element specifies the frequency of the ith
                        oscillator. If omitted, the default natural frequency
                        will be used. [default value: None]
  --thetas THETAS       An optional 1D array of phases or single phase to use
                        for the initial phases. If an array is given, the ith
                        element specifies the initial phase of the ith
                        oscillator. If omitted, random initial phases will be
                        generated. [default value: None]

# Parameters

# Seed for the random number generation.
# Type: int [OPTIONAL]
seed: 0

# Total number of oscillators.
# Type: int [OPTIONAL]
n_osc: 10

# Integration time step (dt).
# Type: float [OPTIONAL]
delta_t: 0.1

# Coupling constant.  .. math::      WARNING: In the article, K is aggregated with the kernel:     dphi_i/dt = w + 1/N
# \sum_j W(r,h) sin(phij - phi_i) with     W(r,h)=10 K/(7*pi*h**2)*f(q) we used K=20 throughout the paper     here in
# the code, it is put outside of the kernel: dphi_i/dt = w     + K/N \sum_j W(r,h) sin(phij - phi_i) with
# W(r,h)=10/(7*pi*h**2)*f(q) it is only a matter of writting
# Type: float [OPTIONAL]
coupling_k: 20

# The number of time steps. The total time will be the number of time steps (n_timesteps) times the integration time
# step (delta_t).
# Type: int [OPTIONAL]
n_timesteps: 2000

# The number of time points to save in the dumped result file, in addition to the initial phases. If less than 1, all
# time points will be saved.
# Type: int [OPTIONAL]
n_save: 50

# The length of the spatial domain.
# Type: float [OPTIONAL]
lx: 10

# The parameter of the smooth kernel h.
# Type: float [OPTIONAL]
h_sph: 0.01

# Boundary condition: [FREE, PERIODIC]. See :py:class:`BoundaryCondition` for available options.
# Type: BoundaryCondition [OPTIONAL]
boundary_cond: FREE

# Distribution of particle positions: [UNIFORM, CLUSTERED]. See :py:class:`ParticleDistribution` for available options.
# Type: ParticleDistribution [OPTIONAL]
particle_distrib: UNIFORM

# An optional 2D array of fixed initial positions to use, where element ij gives the position of the ith oscillator on
# axis j (j=0 for x, j=1 for y, etc.). If omitted, then random positions will be generated according to the other
# parameters.
# Type: ndarray[tuple[Any, ...], dtype[float64]] [OPTIONAL]
positions: null

# An optional 1D array of natural frequencies or a single natural frequency to use. If an array is given, the ith
# element specifies the frequency of the ith oscillator. If omitted, the default natural frequency will be used.
# Type: Union[ndarray[tuple[Any, ...], dtype[float64]], float64] [OPTIONAL]
omegas: null

# An optional 1D array of phases or single phase to use for the initial phases.  If an array is given, the ith element
# specifies the initial phase of the ith oscillator. If omitted, random initial phases will be generated.
# Type: Union[ndarray[tuple[Any, ...], dtype[float64]], float64] [OPTIONAL]
thetas: null

kuramoto_sph batch

The batch subcommand is used to batch-run multiple simulations from a configuration file. The simulations will be launched in parallel on multi-cpu systems. Currently this command only runs the simulations but post-processing options will be added to this command later.

usage: kuramoto_sph batch [-h] [-v] [--overwrite] [--gen-config] PATH

positional arguments:
  PATH           The path to a YAML batch configuration file.

options:
  -h, --help     show this help message and exit
  -v, --verbose  Increase logging level to DEBUG.
  --overwrite    Overwrite existing files.
  --gen-config   Generate a batch configuration file at the given path instead
                 of reading it. If the path is "-", the file will be printed
                 to STDOUT.

# BatchConfig

# The epsilon parameter for DBSCAN clustering. The default of 0.045 was empirically determined to yield the best
# results.
# Type: float [OPTIONAL]
dbscan_eps: 0.045

# The number of steps of the spatial grid used to compute the order parameter. The value of delta x will be lx /
# n_delta_x. The default value of 40 will yield a delta x of 0.5 with lx's default value of 20.
# Type: int [OPTIONAL]
n_delta_x: 40

# Output directory for saving results. Local paths are interpretted relative to the current working directory. This does
# not change the output dirctory for results because results are deterministic as a function of their input parameters
# and should therefore be shared across workflows to avoid redundant simulations.
# Type: Path [OPTIONAL]
output_directory: batch_output

# If True, overwrite existing plots.
# Type: bool [OPTIONAL]
overwrite_plots: false

# If True, rerun simulations and overwrite existings results. Normally simulations are only run when no results already
# exist.
# Type: bool [OPTIONAL]
overwrite_simulations: false

# Prefactor for the cutoff distance of the neighborhood, which will be prefactor * lx / n_osc.  For n_osc=2000, this
# yields a cutoff distance of 1.5 for lx=20 and a cutoff distance of 3.75 for lx=50.
# Type: float [OPTIONAL]
pref_cutoff_dist: 150

# If True, force recomputation of the speckle contrasts.
# Type: bool [OPTIONAL]
recompute_speckles: false

# If True, show plots after they are saved.
# Type: bool [OPTIONAL]
show_plots: true

# A list if parameters for the simulations to run and analyze. These should be dicts containing the same arguments
# accepted by the Parameter class. The list items may also be paths to YAML parameter files or even paths to CSV files
# containing tabulated parameters.  When invoked within Python, instances of Parameters may also be passed.
# Type: list[Parameters] [OPTIONAL]
parameters_list: []
  # Parameters

  # Seed for the random number generation.
  # Type: int [OPTIONAL]
  # - seed: 0

  # Total number of oscillators.
  # Type: int [OPTIONAL]
  #   n_osc: 10

  # Integration time step (dt).
  # Type: float [OPTIONAL]
  #   delta_t: 0.1

  # Coupling constant.  .. math::      WARNING: In the article, K is aggregated with the kernel:     dphi_i/dt = w + 1/N
  # \sum_j W(r,h) sin(phij - phi_i) with     W(r,h)=10 K/(7*pi*h**2)*f(q) we used K=20 throughout the paper     here in
  # the code, it is put outside of the kernel: dphi_i/dt = w     + K/N \sum_j W(r,h) sin(phij - phi_i) with
  # W(r,h)=10/(7*pi*h**2)*f(q) it is only a matter of writting
  # Type: float [OPTIONAL]
  #   coupling_k: 20

  # The number of time steps. The total time will be the number of time steps (n_timesteps) times the integration time
  # step (delta_t).
  # Type: int [OPTIONAL]
  #   n_timesteps: 2000

  # The number of time points to save in the dumped result file, in addition to the initial phases. If less than 1, all
  # time points will be saved.
  # Type: int [OPTIONAL]
  #   n_save: 50

  # The length of the spatial domain.
  # Type: float [OPTIONAL]
  #   lx: 10

  # The parameter of the smooth kernel h.
  # Type: float [OPTIONAL]
  #   h_sph: 0.01

  # Boundary condition: [FREE, PERIODIC]. See :py:class:`BoundaryCondition` for available options.
  # Type: BoundaryCondition [OPTIONAL]
  #   boundary_cond: FREE

  # Distribution of particle positions: [UNIFORM, CLUSTERED]. See :py:class:`ParticleDistribution` for available
  # options.
  # Type: ParticleDistribution [OPTIONAL]
  #   particle_distrib: UNIFORM

  # An optional 2D array of fixed initial positions to use, where element ij gives the position of the ith oscillator on
  # axis j (j=0 for x, j=1 for y, etc.). If omitted, then random positions will be generated according to the other
  # parameters.
  # Type: ndarray[tuple[Any, ...], dtype[float64]] [OPTIONAL]
  #   positions: null

  # An optional 1D array of natural frequencies or a single natural frequency to use. If an array is given, the ith
  # element specifies the frequency of the ith oscillator. If omitted, the default natural frequency will be used.
  # Type: Union[ndarray[tuple[Any, ...], dtype[float64]], float64] [OPTIONAL]
  #   omegas: null

  # An optional 1D array of phases or single phase to use for the initial phases.  If an array is given, the ith element
  # specifies the initial phase of the ith oscillator. If omitted, random initial phases will be generated.
  # Type: Union[ndarray[tuple[Any, ...], dtype[float64]], float64] [OPTIONAL]
  #   thetas: null

# The window size for frequency and phase offset estimation.
# Type: int [OPTIONAL]
window: 5

kuramoto_sph process

The process subcommand provides a command-line interface to processing results. Currently it only supports tabulating simulation parameters and filepaths into a CSV file.

usage: kuramoto_sph process [-h] [-v] [--overwrite]
                            [--tabulate PATH [PATH ...]]

options:
  -h, --help            show this help message and exit
  -v, --verbose         Increase logging level to DEBUG.
  --overwrite           Overwrite existing files.
  --tabulate PATH [PATH ...]
                        Tabulate the results in the given directories.

API Usage

Documentation for the kuramoto_sph Python package API can be found in the link above. For real-world usages examples, please consult the scripts provided in article which were used to generate, analyze and visualize the results from the article.

Examples

Run One Simulation

from kuramoto_sph.parameters import Parameters
from kuramoto_sph.simulation import Simulator

params = Parameters(seed=25, n_osc=2000, coupling_k=20, lx=20, h_sph=5e-1)
sim = Simulator(params)
sim.run()

Environment Variables

Some aspects of the package can be configured via environment variables. These may be set in multiple ways. For example, the command export KURAMOTO_SPH_N_WORKERS=10 may be used in a terminal or in a script to limit the number of workers to 10 before running a command. Environment variables may also be set for single invocations by prepending them to the command, e.g. KURAMOTO_SPH_N_WORKERS=10 kuramoto_sph run --n_osc 200.

For persistent configuration, add the export commands to your shell’s configuration file (e.g. .bashrc).

KURAMOTO_SPH_N_WORKERS

This variable sets the maximum number of works to use for multiprocessing. If not set then the current number of detected CPUs will be used. Any value below 2 will restrict processing to a single worker.

KURAMOTO_SPH_RESULTS_DIR

The path to a directory for storing simulation results. Relative paths are interpretted relative to the current working directory. Set this to an absolute path to centralize results for re-use.

TQDM_DISABLE

Set this variable to a non-zero value to disable the tqdm progress bars. Use this for e.g. batching jobs on a cluster to reduce the size of log files.

Remarks

  • All simulations can be resumed after interruption.

Article

TODO: Insert the final article reference here once it has been accepted.

Figures

The figures from the article can be generated with the script gen_figures.py. Note that due to the number of simulations, this may take a long time. The script provides an option to export files for parallel batch processing on the Grid5000 platform using g5k-besteffort-runner. The export functions can be used as a starting point for preparing batch processing on other platforms.

usage: gen_figures.py [-h] [--g5k]

Run simulations and generate figures for the article.

options:
  -h, --help  show this help message and exit
  --g5k       Create a directory named g5k that can be copied to Grid5000 to
              run the simulations in parallel batches.