Examples ========= .. note:: To run the examples below, you need to install the **tqdm** package for progress bars. The *Jupyter Notebooks* in `examples/jupyter/ `_ additionally require **jupyter** and **ipywidgets** as well. Relaxation to mechanical equilibrium ------------------------------------ The following example shows how 100 cells relax to mechanical equilibrium from a squeezed initial configuration using the **PyAFV** package. .. literalinclude:: ../examples/relaxation.py :language: python See the plotted figures below: .. list-table:: :widths: 50 50 * - .. figure:: ../assets/initial_configuration.png :width: 100% :align: center Initial configuration. - .. figure:: ../assets/relaxed_configuration.png :width: 100% :align: center After relaxation. | Active finite Voronoi (AFV) dynamics ------------------------------------- We can incorporate self-propulsion (active-Brownian-like dynamics) for each cell to model active-matter systems. The resulting equation of motion is .. math:: \dot{\mathbf{r}}_i = -\mu \boldsymbol{\nabla}_{\!i} E + v_0 \mathbf{n}_i, where :math:`\mu` is the mobility, the interaction force on cell :math:`\mathbf{F}_i=-\boldsymbol{\nabla}_{\!i} E`, and :math:`\mathbf{n}_i = (\cos \theta_i, \sin \theta_i)` is a unit orientation vector. The orientation evolves according to .. math:: \dot{\theta}_i = \sqrt{2 D_r}\,\eta_i(t), where the noise satisfies :math:`\langle \eta_i(t) \rangle = 0` and :math:`\langle \eta_i(t)\eta_j(t') \rangle = \delta_{ij}\,\delta(t - t')`. .. literalinclude:: ../examples/active_FV.py :language: python See the plotted figure below: .. image:: ../assets/active_FV.png :alt: AFV dynamics :width: 500px :align: center | Connectivity between cells ------------------------------- **PyAFV** can directly output the cell-cell connectivity from the finite Voronoi diagram, where any two connected cells share a straight Voronoi edge. .. literalinclude:: ../examples/connections.py :language: python | Custom plotting ---------------- .. image:: https://colab.research.google.com/assets/colab-badge.svg :target: https://colab.research.google.com/github/pyafv/assets/blob/main/jupyter/custom_plot.ipynb :alt: Open In Colab See `examples/jupyter/custom_plot.ipynb `_ for an example of custom plotting using **PyAFV**, or you can run the notebook directly on **Google Colab** by clicking the badge above. This example shows how to use :py:meth:`pyafv.FiniteVoronoiSimulator.build` returned ``dict`` to plot the Voronoi diagram with custom styling, including coloring cells by their area and customizing edge colors and widths. Both a **serial** version (for *illustration*) and a **vectorized** version (⚡\ :emphasis:`much faster`) of the *custom plotting routine* are provided in the notebook. .. important:: Starting from v0.4.10, we also provide a standalone utility function :py:func:`pyafv.visualize_2d`, which wraps the **vectorized** plotting routine for easier reuse (see the :ref:`next section `). This function is generally preferred over the original :py:meth:`pyafv.FiniteVoronoiSimulator.plot_2d` method. .. image:: ../assets/model_illustration.png :alt: Custom plotting :width: 600px :align: center | This notebook also shows how to access additional internal information via :py:meth:`pyafv.FiniteVoronoiSimulator._build_voronoi_with_extensions` and :py:meth:`pyafv.FiniteVoronoiSimulator._per_cell_geometry` for advanced plotting. The public :py:meth:`pyafv.FiniteVoronoiSimulator.build` method serves as a higher-level wrapper around these two and other lower-level routines. .. automethod:: pyafv.FiniteVoronoiSimulator._build_voronoi_with_extensions :noindex: .. automethod:: pyafv.FiniteVoronoiSimulator._per_cell_geometry :noindex: | .. _standalone-plotting: A standalone plotting utility ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Inspired by the custom plotting examples used in daily research, we have implemented a **standalone** plotting utility :py:func:`pyafv.visualize_2d` that can be used to plot the finite Voronoi diagram with *color-filled cells* and *customizable styling*. A simple example usage is shown below: .. code-block:: python import numpy as np import matplotlib.pyplot as plt import pyafv as afv N = 100 # number of cells pts = np.random.rand(N, 2) * 10 # initial positions params = afv.PhysicalParams(r=1.0) # use default parameter values sim = afv.FiniteVoronoiSimulator(pts, params) # initialize the simulator diag = sim.build() # compute forces and geometry fig, ax = plt.subplots() afv.visualize_2d(pts, diag, r=1.0, ax=ax) # visualize the FV diagram plt.show() This :py:func:`pyafv.visualize_2d` function is designed to be **flexible** and **efficient** (vectorized), and it should satisfy most common plotting needs for 2D finite Voronoi diagrams. .. autofunction:: pyafv.visualize_2d :noindex: | Periodic boundary conditions ---------------------------- .. image:: https://colab.research.google.com/assets/colab-badge.svg :target: https://colab.research.google.com/github/pyafv/assets/blob/main/jupyter/periodic_plotting.ipynb :alt: Open In Colab **PyAFV** uses open boundary conditions in 2D by default, but it is also possible to implement *periodic boundary conditions* via a tiling of the edge regions. See `examples/jupyter/periodic_plotting.ipynb `_ for an example (or you can run the notebook directly on **Google Colab** by clicking the badge above), and the generated figure is shown below: .. note:: The tiling routine is now wrapped as a utility function :py:func:`pyafv.tile_pbc` (experimental). .. image:: ../assets/pbc.png :alt: PBC example :width: 500px :align: center | Varying cell target areas from cell to cell ------------------------------------------- Starting from **PyAFV** v0.3.5, the simulator supports cell-specific preferred areas, allowing the target area :math:`A_0` to vary from cell to cell, i.e., :math:`\{A_{0,i}\}` . A new read-only property :py:attr:`pyafv.FiniteVoronoiSimulator.preferred_areas` has been added. It returns the current preferred areas for all cells: .. autoattribute:: pyafv.FiniteVoronoiSimulator.preferred_areas :noindex: To modify the preferred areas, the method :py:meth:`pyafv.FiniteVoronoiSimulator.update_preferred_areas` is provided: .. automethod:: pyafv.FiniteVoronoiSimulator.update_preferred_areas :noindex: Here is an example usage: .. code-block:: python import numpy as np from pyafv import FiniteVoronoiSimulator, PhysicalParams # Initialize simulator N = 100 pts = np.random.rand(N, 2) * 10 phys = PhysicalParams(r=1.0, A0=np.pi) sim = FiniteVoronoiSimulator(pts, phys) # Set varying preferred areas per cell varying_A0 = np.pi + 0.2 * np.random.randn(N) sim.update_preferred_areas(varying_A0) # Access via property print(sim.preferred_areas) # shape: (N,) # Run simulation... In addition, the :py:meth:`pyafv.FiniteVoronoiSimulator.update_positions` method now accepts an optional second argument to update the preferred areas: .. automethod:: pyafv.FiniteVoronoiSimulator.update_positions :noindex: And the :py:meth:`pyafv.FiniteVoronoiSimulator.update_params` method will also re-initialize the preferred areas for all cells using the supplied value of *A0* in *phys*: .. automethod:: pyafv.FiniteVoronoiSimulator.update_params :noindex: