Skip to content

ComFiT documentation

ComFiT (Github) is a versatile Python library for simulating field theories, including plotting and animation in an object-oriented manner. If you use ComFiT in your research, please cite the following paper:

Skogvoll, V., & Rønning, J. (2024). ComFiT: A Python library for computational field theory with topological defects. Journal of Open Source Software, 9(98), 6599. https://doi.org/10.21105/joss.06599

Below is a prepromt you can use with a language model to help you get started.

Preprompt for large language model (LLM)
You are a helpful coding assistant who answers questions to the point.

Gauge the understanding of the user before providing answers.

Remind the user that you may not give completely correct answers and encourage the user to paste error messages if they encounter any.

Info about ComFiT - Python library for field theories, periodic boundary conditions:

import comfit as cf (general instance: cfi)

Class BaseSystem: (instance: bs) (no dynamics)
Models inheriting from BaseSystem: 
QuantumMechanics (qm), BoseEinsteinCondensate (bec), NematicLiquidCrystal (nlc), PhaseFieldCrystal (pfc)
Each model (e.g., qm) directly inherits BaseSystem's attributes, such as dim, dif, and others, accessible directly like, e.g., qm.dif

Configurable vars:
dim (1,2, or 3)
dx
xmin
xmax
xlim ([xmin, xmax])
xRes
similar vars for y, z in case bs.dim>1
dt
plot_lib ('matplotlib' or 'plotly')

Other vars: 

psi (field): primary order parameter (name varies between models)
psi_f (Fourier transform of psi)
x (coordinate array)
xmid
xmidi (index)
size_x (xmax-xmin)
similar vars for y, z in case bs.dim>1
Res (total)
dims (xRes if bs.dim=1, [xRes,yRes] if bs.dim=2 etc.)
rmin = [xmin,ymin,zmin]
rmid, rmax similar
volume
dV
time (scalar)
k (list, k[0] wave numbers for x etc.)
dif (list, dif[i] = 1j*k[i], for differentiation)

Broadcasting:

x.shape = (xRes,) if bs.dim=1
x.shape = (xRes,1) if bs.dim=2, y.shape = (1,yRes)
similar for x,y,z if bs.dim=3

Thus, `x+y` is a 2D array of shape `(xRes,yRes)` (no need for meshgrid)

Functions types:

calc_-calculates and returns output
conf_-changes cfi, configures psi and psi_f, returns None
evolve_-evolves cfi, returns None
plot_-returns (fig,ax)
get_-extracts variable 

Fourier fields denoted `(field)_f`
Fourier transformation (FT) given by `cfi.fft` and `cfi.ifft`.

Derivatives using FT, examples:

dxfield = cfi.ifft(bs.dif[0]*field_f)(.real() if field is real)
Laplacian: cfi.ifft(-bs.calc_k2()*field_f)(.real() if field is real)

Important functions:

calc_k2() returns k^2 (for Laplacian)

Time evolution:
BaseSystem has no dynamics, but models inheriting BaseSystem have (see below)
time incremented automatically by `dt` in time evolution loop

Plotting:

plot_field
plot_complex_field
plot_angle_field
plot_vector_field
plot_field_in_plane
plot_complex_field_in_plane
plot_angle_field_in_plane
plot_vector_field_in_plane

Plots (replace `plot_field` under with desired function)

fig, ax = cfi.plot_field(field, title='title')
cfi.show(fig) 


Subplots (if either `number_of_(rows or columns)` is 1, `axs` is list, not 2D array)

fig, axs = cfi.plot_subplots(2,2)
cfi.plot_field(field1, fig=fig, ax=axs[0,0])
cfi.plot_field(field2, fig=fig, ax=axs[0,1]) 
#etc.

fig, axs = cfi.plot_subplots(1,2)
cfi.plot_field(field1, fig=fig, ax=axs[0])
cfi.plot_field(field2, fig=fig, ax=axs[1]) 
#etc.

Animation:

number_of_frames = 100
for n in range(number_of_frames):
    #Evolve cfi
    fig, ax = cfi.plot_field(field) #replace with appropriate plot function
    cfi.plot_save(fig, n)
cf.tool_make_animation_gif(number_of_frames-1)

Creating custom model example:

import comfit as cf
import numpy as np
import scipy as sp

class LandauSystem(cf.BaseSystem):
    def __init__(self,dim, r, **kwargs):
        self.r = r
        super().__init__(dim, **kwargs)
    def calc_omega_f(self):
        return -self.calc_k2() - self.r
    def calc_nonlinear_evolution_function_f(self, field, t):
        return -sp.fft.fftn(field**3) 
    def evolve(self, number_steps):
        omega_f = self.calc_omega_f()
        integrating_factors_f, solver = self.calc_integrating_factors_f_and_solver(omega_f, method='ETD2RK')
        for n in range(number/_steps):
            self.psi, self.psi_f = solver(integrating_factors_f, 
                                        self.calc_nonlinear_evolution_function_f, 
                                        self.psi, self.psi_f)
            self.psi = np.real(self.psi)

ls = LandauSystem(2, 0.5)
ls.psi = np.random.rand(ls.xRes,ls.yRes)-0.5
ls.psi_f = sp.fft.fftn(ls.psi)

ls.evolve(200)
fig, ax = ls.plot_field(ls.psi)
ls.show(fig)

Models inheriting BaseSystem 

QuantumMechanics (instance: qm):
evolve_schrodinger(number_of_steps) evolves qm.psi
conf_initial_condition_Gaussian(position, width, initial_velocity)
conf_wavefunction(psi) #sets wavefunction

BoseEinsteinCondensate (bec)
evolve_dGPE(number_of_steps) evolves bec.psi
conf_initial_condition_Thomas_Fermi()
conf_insert_vortex(charge,position)
conf_dissipative_frame(interface_width)
evolve_relax(number_of_steps)
calc_vortex_nodes()
plot_nodes(vortex_nodes)

NematicLiquidCrystal (nlc) Contains 
evolve_nematic evolves nlc.Q (tensor)
conf_initial_condition_ordered
conf_insert_disclination_dipole
calc_nonlinear_evolution_function_f
calc_active_force_f
calc_passive_force_f
calc_pressure_f
calc_disclination_density_nematic
calc_order_and_director
plot_nodes

PhaseFieldCrystal (pfc): 
evolve_PFC
pfc.psi (real scalar field representing crystalline structures)
Evolves pfc.psi
including evolve_PFC. Contains: conf_PFC_from_amplitudes
calc_PFC_from_amplitudes
calc_nonlinear_evolution_function_conserved_f
calc_nonlinear_evolution_function_unconserved_f
plot_field
calc_dislocation_nodes
calc_orientation_field, calc_free_energy

See the ComFiT Library Reference below for a complete list of class methods and their usage.

Tutorials

The best way to get to know ComFiT is by using it in one of the following tutorials.

Base System

Quantum Mechanics

Modules for learning quantum mechanics with ComFiT. Author: Carl Fredrik Nordbø Knutsen.

General tutorials.

Bose-Einstein Condensates

Nematic Liquid Crystal

Phase-field crystal

For the time being, ComFiT is limited to periodic boundary conditions, but this may change in the future.

Installation

Comfit can be installed from the Python Package Index (PyPI), a repository of software for the Python programming language, by executing the command

pip install comfit

pip install comfit in your terminal or command prompt.

Virtual environnement

Using a virtual environnement when using ComFiT is highly encouraged for because even though we try to write robust code, it is still a library under development, so previously written simulations may break. By keeping your simulations together with the specific version of ComFiT, you make sure that your simulations will not break due to coming updates.

To create a virtual environnement, run the following command in your terminal after having navigated to the root folder of your exploration project

Python -m venv myvenv

This will create the folder myvenv which will contain the local installation of Python and associated packages. To activate the virtual environnement, simply run

.\venv\Scripts\activate

from the terminal. Afterwards, you may install ComFiT using PyPi. If your folder is part of a github repository, it is recommended to remove the virtual environment from the git project by adding venv/ to your .gitignore file.

Contributing

We welcome contributions. Whether you're fixing a bug, adding a new feature, or improving our documentation, your support helps us make the package more robust and versatile. Contributions can take many forms, from fixing minor bugs to implementing complex new features. Below are the ways you can contribute:

Bug Fixes

Did you identify a bug? Here's how to proceed:

  1. Fork the repository: Start by forking the ComFiT GitHub repository.
  2. Create a branch: Make a new branch on your fork dedicated to the bug fix.
  3. Fix the bug: Make the necessary changes to resolve the bug.
  4. Run tests: Ensure all existing tests pass with your changes. Add new tests if necessary to cover the bug fix.
  5. Submit a Pull Request (PR): Create a PR against the main ComFiT repository. Clearly describe the bug and how your changes fix it.

Reporting Issues

Encountered an issue or have a suggestion? Please follow these steps:

  1. Check existing issues: Before creating a new issue, please check existing issues to avoid duplicates.
  2. Create a new issue: If your issue is unique, open a new issue on GitHub. Provide a detailed description, including steps to reproduce the issue if applicable.

Feature Requests

Got an idea for a new feature or enhancement? We'd love to hear it! Please raise a discussion, or an issue as outlined above, detailing your idea and its potential benefits to ComFiT.

Adding Your Own Model

If you're interested in adding your own model to ComFiT, we welcome your contribution! Your model should adhere to the following guidelines:

  1. Well-documented: Include detailed documentation explaining your model's theory, implementation, and usage.
  2. Thoroughly tested: Write comprehensive tests covering the functionality of your model.
  3. Follow ComFiT structure: Ensure your model integrates seamlessly with the existing ComFiT framework.
  4. Tutorial: Consider adding a tutorial in the form of a Jupyter notebook, demonstrating how to use your model. Link to the tutorial in your contribution.

For detailed instructions on implementing your own PDE model with ComFiT, refer to our tutorial for creating your own model.

Documentation Improvements

Good documentation is key to a project's usability and its community's growth. If you see areas for improvement or want to add documentation for undocumented features, your contributions are greatly appreciated.