API Reference
System
Classes which specify the physical system.
Notes
This file is part of OpenFerro.
- class openferro.system.System(lattice)[source]
Bases:
objectA class to define a physical system.
A system is a lattice with fields and a Hamiltonian. Fields are added to the system by the user. Interactions are added to the system by the user. Pointers to fields and interactions are stored in dictionaries.
- lattice
The lattice of the system
- Type:
- get_field_by_ID(ID)[source]
Get a field by ID.
- Parameters:
ID (str) – ID of the field
- Returns:
The field with the given ID
- Return type:
- Raises:
ValueError – If field with given ID does not exist
- get_all_fields()[source]
Get all fields in the system.
- Returns:
All fields in the system
- Return type:
- move_fields_to_multi_devs(mesh: DeviceMesh)[source]
Move all fields to given devices for parallelization.
- Parameters:
mesh (DeviceMesh) – The device mesh to move the fields to
- add_field(ID, ftype='scalar', dim=None, value=None, mass=1.0)[source]
Add a predefined field to the system.
- Parameters:
ID (str) – ID of the field
ftype (str, optional) – Type of the field. Can be ‘scalar’, ‘SO3’, ‘LocalStrain3D’, etc
dim (int, optional) – Dimension of the field. Only used for Rn fields
value (array-like, optional) – Initial value of the field. Will be broadcasted to the shape of the field
mass (float or array-like, optional) – Mass of the field. When mass is a float, it will be broadcasted to the shape of the field
- Returns:
The field with the given ID
- Return type:
- Raises:
ValueError – If field with this ID already exists or if ID is reserved
ValueError – If field type is unknown
- add_global_strain(value=None, mass=1)[source]
Add a global strain to the system. Allow variable cell simulation.
- Parameters:
value (array-like, optional) – Initial value of the global strain
mass (float, optional) – Effective mass of the global strain for the barostat
- Returns:
The global strain field
- Return type:
- Raises:
AssertionError – If value is provided but not a 6D vector
- property interaction_dict
Get all interactions in the system.
- Returns:
All interactions in the system
- Return type:
- get_interaction_by_ID(interaction_ID)[source]
Get an interaction by ID.
- Parameters:
interaction_ID (str) – ID of the interaction
- Returns:
The interaction with the given ID
- Return type:
Interaction
- Raises:
ValueError – If interaction with given ID does not exist
- _add_interaction_sanity_check(ID)[source]
Sanity check for adding an interaction.
- Parameters:
ID (str) – ID of the interaction to check
- Raises:
ValueError – If ID is reserved or already exists
- add_dipole_dipole_interaction(ID, field_ID, prefactor=1.0, enable_jit=True)[source]
Add the long-range dipole-dipole interaction term to the Hamiltonian.
- add_pressure(pressure)[source]
Add a pressure term (pV) to the Hamiltonian.
The ID of the interaction is reserved as ‘pV’. V is the volume of the system, which is calculated from the reference lattice vectors and the global strain.
- Parameters:
pressure (float) – Pressure in bars
- Returns:
The pV interaction
- Return type:
Interaction
- Raises:
ValueError – If pV term already exists or if gstrain field is invalid
- add_homo_strain_dipole_interaction(ID, field_1_ID, field_2_ID, B1xx, B1yy, B4yz, enable_jit=True)[source]
- add_inhomo_strain_dipole_interaction(ID, field_1_ID, field_2_ID, B1xx, B1yy, B4yz, enable_jit=True)[source]
- add_cubic_anisotropy_interaction(ID, field_ID, K1, K2, enable_jit=True)[source]
Add the cubic anisotropy interaction term.
- _add_isotropic_exchange_interaction_by_rollers(ID, field_ID, coupling, rollers, enable_jit=True)[source]
Add the isotropic exchange interaction term H=sum_{i~j} Jij*Si*Sj to the Hamiltonian.
- Parameters:
- Returns:
The created interaction
- Return type:
Interaction
- add_isotropic_exchange_interaction_1st_shell(ID, field_ID, coupling, enable_jit=True)[source]
Add the first shell isotropic exchange interaction term.
The first shell is defined in lattice class.
- add_isotropic_exchange_interaction_2nd_shell(ID, field_ID, coupling, enable_jit=True)[source]
Add the second shell isotropic exchange interaction term.
The second shell is defined in lattice class.
- add_isotropic_exchange_interaction_3rd_shell(ID, field_ID, coupling, enable_jit=True)[source]
Add the third shell isotropic exchange interaction term.
The third shell is defined in lattice class.
- add_isotropic_exchange_interaction_4th_shell(ID, field_ID, coupling, enable_jit=True)[source]
Add the fourth shell isotropic exchange interaction term.
The fourth shell is defined in lattice class.
- add_self_interaction(ID, field_ID, energy_engine, parameters=None, enable_jit=True)[source]
Add a custom self-interaction term to the Hamiltonian.
- Parameters:
- Returns:
The created interaction
- Return type:
Interaction
- add_mutual_interaction(ID, field_1_ID, field_2_ID, energy_engine, parameters=None, enable_jit=True)[source]
Add a custom mutual interaction term to the Hamiltonian.
- Parameters:
ID (str) – ID of the interaction
field_1_ID (str) – ID of the first field
field_2_ID (str) – ID of the second field
energy_engine (callable) – A function that takes the fields as input and returns the interaction energy
parameters (array-like, optional) – Parameters for the interaction
enable_jit (bool, optional) – Whether to use JIT compilation
- Returns:
The created interaction
- Return type:
Interaction
- add_triple_interaction(ID, field_1_ID, field_2_ID, field_3_ID, energy_engine, parameters=None, enable_jit=True)[source]
Add a custom triple interaction term to the Hamiltonian.
- Parameters:
ID (str) – ID of the interaction
field_1_ID (str) – ID of the first field
field_2_ID (str) – ID of the second field
field_3_ID (str) – ID of the third field
energy_engine (callable) – A function that takes the fields as input and returns the interaction energy
parameters (array-like, optional) – Parameters for the interaction
enable_jit (bool, optional) – Whether to use JIT compilation
- Returns:
The created interaction
- Return type:
Interaction
- calc_energy_by_ID(interaction_ID)[source]
Calculate the energy of an interaction by ID.
- Parameters:
interaction_ID (str) – ID of the interaction
- Returns:
The energy of the interaction
- Return type:
- Raises:
ValueError – If interaction with given ID does not exist
- calc_force_by_ID(interaction_ID)[source]
Calculate the gradient force from an interaction by ID.
- Parameters:
interaction_ID (str) – ID of the interaction
- Returns:
The gradient force of the interaction
- Return type:
array
- Raises:
ValueError – If interaction with given ID does not exist
- calc_total_self_energy()[source]
Calculate the total self-interaction energy.
- Returns:
Total self-interaction energy
- Return type:
- calc_total_mutual_interaction()[source]
Calculate the total mutual interaction energy.
- Returns:
Total mutual interaction energy
- Return type:
- calc_total_triple_interaction()[source]
Calculate the total triple interaction energy.
- Returns:
Total triple interaction energy
- Return type:
- calc_total_potential_energy()[source]
Calculate the total potential energy of the system.
Calculate the total potential energy of the system. Total potential energy is the sum of self-interaction energy, mutual interaction energy, and triple interaction energy.
- calc_excess_stress()[source]
Get instantaneous stress - applied stress (e.g. from hydrostatic pressure)
- update_force_from_self_interaction(profile=False)[source]
update the gradient force felt by each field from self interactions.
- update_force_from_mutual_interaction(profile=False)[source]
update the gradient force felt by each field from mutual interactions.
Fields
Classes which define the fields on the lattice.
- class openferro.field.Field(lattice, ID: str)[source]
Bases:
objectTemplate class to define a field on a lattice.
- __init__(lattice, ID: str)[source]
Initialize a field.
- Parameters:
lattice (BravaisLattice3D) – Lattice object
ID (str) – ID of the field
- get_values()[source]
Get the values of the field.
- Returns:
Values of the field
- Return type:
array_like
- Raises:
ValueError – If field has no values set
- property size
- to_multi_devs(mesh: DeviceMesh)[source]
- class openferro.field.FieldRn(lattice, ID, dim, unit=None)[source]
Bases:
FieldR^n field on a lattice. Values are stored as n-dimensional vectors.
- __init__(lattice, ID, dim, unit=None)[source]
Initialize a field.
- Parameters:
lattice (BravaisLattice3D) – Lattice object
ID (str) – ID of the field
- property mean
Calculate the average of the field over the lattice.
- Returns:
Mean value of field
- Return type:
array_like
- property var
Calculate the variance of the field over the lattice.
- Returns:
Variance of field
- Return type:
array_like
- set_local_value(loc, value)[source]
Set the value of the field at a given location.
- Parameters:
loc (tuple) – Location tuple with length equal to lattice dimension
value (array_like) – Value to set at location
- set_integrator(integrator_class, dt, temp=None, tau=None)[source]
Set the integrator according to the given integrator class. Set the time step.
- Parameters:
- Raises:
ValueError – If integrator class not supported or required parameters missing
- class openferro.field.FieldScalar(lattice, ID, unit=None)[source]
Bases:
FieldRnScalar field. Values are stored as scalars. Example: mass, density, any onsite constant, etc.
- __init__(lattice, ID, unit=None)[source]
Initialize a field.
- Parameters:
lattice (BravaisLattice3D) – Lattice object
ID (str) – ID of the field
- class openferro.field.FieldR3(lattice, ID, unit=None)[source]
Bases:
FieldRn3D vector field. Values are stored as 3-dimensional vectors. Example: flexible dipole moment.
- __init__(lattice, ID, unit=None)[source]
Initialize a field.
- Parameters:
lattice (BravaisLattice3D) – Lattice object
ID (str) – ID of the field
- class openferro.field.FieldSO3(lattice, ID, unit=None)[source]
Bases:
FieldRn3D vector field with fixed magnitude and flexible orientation. Values are stored as 3-dimensional vectors. Example: rigid atomistic spin, molecular orientation, etc.
- __init__(lattice, ID, unit=None)[source]
Initialize a field.
- Parameters:
lattice (BravaisLattice3D) – Lattice object
ID (str) – ID of the field
- to_multi_devs(mesh: DeviceMesh)[source]
- set_integrator(integrator_class, dt, temp=None, alpha=None)[source]
Set the integrator according to the given integrator class. Set the time step.
- Parameters:
- Raises:
ValueError – If integrator class not supported or required parameters missing
- class openferro.field.LocalStrain3D(lattice, ID)[source]
Bases:
FieldRnStrain field on 3D lattice are separated into local contribution (local strain field) and global contribution (homogeneous strain associated to the supercell). The local strain field is encoded by the local displacement vector v_i(R)/a_i (a_i: the lattice vector) associated with each lattice site at R.
- __init__(lattice, ID)[source]
Initialize a field.
- Parameters:
lattice (BravaisLattice3D) – Lattice object
ID (str) – ID of the field
- static get_local_strain_symmetric(values)[source]
Calculate the local strain field from the local displacement field.
- Parameters:
values (array_like) – Local displacement field values
- Returns:
Local strain field with shape (l1, l2, l3, 6)
- Return type:
array_like
- static get_local_strain(values)[source]
Calculate the local strain field from the local displacement field. Implemented according to Physical Review B 52.9 (1995): 6301.
- Parameters:
values (array_like) – Local displacement field values
- Returns:
Local strain field with shape (l1, l2, l3, 6)
- Return type:
array_like
- class openferro.field.GlobalStrain(lattice, ID)[source]
Bases:
FieldThe homogeneous strain is represented by the strain tensor with Voigt convention, which is a 6-dimensional vector.
- __init__(lattice, ID)[source]
Initialize a field.
- Parameters:
lattice (BravaisLattice3D) – Lattice object
ID (str) – ID of the field
- to_multi_devs(mesh: DeviceMesh)[source]
- set_integrator(integrator_class, dt, temp=None, tau=None, freeze_x=False, freeze_y=False, freeze_z=False)[source]
Set the integrator according to the given integrator class. Set the time step.
- Parameters:
integrator_class (str) – Integrator class
dt (float) – Time step
temp (float, optional) – Temperature for isothermal integrator
tau (float, optional) – Relaxation time for Langevin integrator
freeze_x (bool, optional) – Whether to freeze x-component of strain, by default False
freeze_y (bool, optional) – Whether to freeze y-component of strain, by default False
freeze_z (bool, optional) – Whether to freeze z-component of strain, by default False
- Raises:
ValueError – If integrator class not supported or required parameters missing
Lattice
Classes to define the Bravais lattices
Notes
This file is part of OpenFerro.
- class openferro.lattice.BravaisLattice3D(l1, l2, l3, a1=None, a2=None, a3=None, pbc=True)[source]
Bases:
objectBase class to represent a 3D Bravais lattice
- Parameters:
l1 (int) – Size in first dimension
l2 (int) – Size in second dimension
l3 (int) – Size in third dimension
a1 (array_like, optional) – First primitive vector, defaults to [1,0,0]
a2 (array_like, optional) – Second primitive vector, defaults to [0,1,0]
a3 (array_like, optional) – Third primitive vector, defaults to [0,0,1]
pbc (bool, optional) – Whether to use periodic boundary conditions, defaults to True
- property nsites
- property unit_volume
Returns the volume of the unit cell
- Returns:
Volume of unit cell
- Return type:
- property ref_volume
- property latt_vec
Returns lattice vectors.
- Returns:
3x3 array of lattice vectors
- Return type:
ndarray
- property reciprocal_latt_vec
Calculates reciprocal lattice vectors.
- Returns:
3x3 array of reciprocal lattice vectors
- Return type:
ndarray
- class openferro.lattice.SimpleCubic3D(l1, l2, l3, a1=None, a2=None, a3=None, pbc=True)[source]
Bases:
BravaisLattice3DA class to represent a simple cubic lattice
- Parameters:
l1 (int) – Size in first dimension
l2 (int) – Size in second dimension
l3 (int) – Size in third dimension
a1 (array_like, optional) – First primitive vector
a2 (array_like, optional) – Second primitive vector
a3 (array_like, optional) – Third primitive vector
pbc (bool, optional) – Whether to use periodic boundary conditions, defaults to True
Notes
Coordination number is 6. First shell has 6 neighbours. Second shell has 12 neighbours. Third shell has 8 neighbours.
- _1st_shell_roller()[source]
Return a list of rolling functions for moving a site to all sites in the first shell of the lattice.
- Returns:
List of rolling functions. The number of rolling functions is half the shell coordination number. Used to calculate interactions between a site and its neighbours.
- Return type:
- _2nd_shell_roller()[source]
Return a list of rolling functions for moving a site to all sites in the second shell of the lattice.
- Returns:
List of rolling functions. The number of rolling functions is half the shell coordination number. Used to calculate interactions between a site and its neighbours.
- Return type:
- _3rd_shell_roller()[source]
Return a list of rolling functions for moving a site to all sites in the third shell of the lattice.
- Returns:
List of rolling functions. The number of rolling functions is half the shell coordination number. Used to calculate interactions between a site and its neighbours.
- Return type:
- class openferro.lattice.BodyCenteredCubic3D(l1, l2, l3, a1=None, a2=None, a3=None, pbc=True)[source]
Bases:
SimpleCubic3DA class to represent a body-centered cubic lattice
- Parameters:
l1 (int) – Size in first dimension
l2 (int) – Size in second dimension
l3 (int) – Size in third dimension
a1 (array_like, optional) – First primitive vector
a2 (array_like, optional) – Second primitive vector
a3 (array_like, optional) – Third primitive vector
pbc (bool, optional) – Whether to use periodic boundary conditions, defaults to True
Notes
Coordination number is 8. First shell has 8 neighbours. Second shell has 6 neighbours. Third shell has 12 neighbours. Fourth shell has 24 neighbours.
- _1st_shell_roller()[source]
Return a list of rolling functions for moving a site to all sites in the first shell of the lattice.
- Returns:
List of rolling functions. The number of rolling functions is half the shell coordination number. Used to calculate interactions between a site and its neighbours.
- Return type:
- _2nd_shell_roller()[source]
Return a list of rolling functions for moving a site to all sites in the second shell of the lattice.
- Returns:
List of rolling functions. The number of rolling functions is half the shell coordination number. Used to calculate interactions between a site and its neighbours.
- Return type:
- _3rd_shell_roller()[source]
Return a list of rolling functions for moving a site to all sites in the third shell of the lattice.
- Returns:
List of rolling functions. The number of rolling functions is half the shell coordination number. Used to calculate interactions between a site and its neighbours.
- Return type:
- _4th_shell_roller()[source]
Return a list of rolling functions for moving a site to all sites in the fourth shell of the lattice.
- Returns:
List of rolling functions. The number of rolling functions is half the shell coordination number. Used to calculate interactions between a site and its neighbours.
- Return type:
- class openferro.lattice.FaceCenteredCubic3D(l1, l2, l3, a1=None, a2=None, a3=None, pbc=True)[source]
Bases:
BodyCenteredCubic3DA class to represent a face-centered cubic lattice
- Parameters:
l1 (int) – Size in first dimension
l2 (int) – Size in second dimension
l3 (int) – Size in third dimension
a1 (array_like, optional) – First primitive vector
a2 (array_like, optional) – Second primitive vector
a3 (array_like, optional) – Third primitive vector
pbc (bool, optional) – Whether to use periodic boundary conditions, defaults to True
Notes
Coordination number is 12. First shell has 12 neighbours. Second shell has 6 neighbours. Third shell has 24 neighbours.
- class openferro.lattice.Hexagonal3D(l1, l2, l3, a1=None, a2=None, a3=None, pbc=True)[source]
Bases:
BravaisLattice3DA class to represent a hexagonal lattice
- Parameters:
l1 (int) – Size in first dimension
l2 (int) – Size in second dimension
l3 (int) – Size in third dimension
a1 (array_like, optional) – First primitive vector
a2 (array_like, optional) – Second primitive vector
a3 (array_like, optional) – Third primitive vector
pbc (bool, optional) – Whether to use periodic boundary conditions, defaults to True
- class openferro.lattice.BravaisLattice2D(l1, l2, a1=None, a2=None, pbc=True)[source]
Bases:
objectBase class to represent a 2D Bravais lattice
- Parameters:
- property ref_area
- property latt_vec
Returns lattice vectors.
- Returns:
2x2 array of lattice vectors
- Return type:
ndarray
- property reciprocal_latt_vec
Calculates reciprocal lattice vectors.
- Returns:
2x2 array of reciprocal lattice vectors
- Return type:
ndarray
- class openferro.lattice.SimpleSquare2D(l1, l2, a1=None, a2=None, pbc=True)[source]
Bases:
BravaisLattice2DA class to represent a simple square lattice
- Parameters:
Notes
Coordination number is 4. First shell has 4 neighbours. Second shell has 4 neighbours. Third shell has 4 neighbours.
- _1st_shell_roller()[source]
Return a list of rolling functions for moving a site to all sites in the first shell of the lattice.
- Returns:
List of rolling functions. The number of rolling functions is half the shell coordination number. Used to calculate interactions between a site and its neighbours.
- Return type:
- _2nd_shell_roller()[source]
Return a list of rolling functions for moving a site to all sites in the second shell of the lattice.
- Returns:
List of rolling functions. The number of rolling functions is half the shell coordination number. Used to calculate interactions between a site and its neighbours.
- Return type:
- _3rd_shell_roller()[source]
Return a list of rolling functions for moving a site to all sites in the third shell of the lattice.
- Returns:
List of rolling functions. The number of rolling functions is half the shell coordination number. Used to calculate interactions between a site and its neighbours.
- Return type:
- class openferro.lattice.Hexagonal2D(l1, l2, a1=None, a2=None)[source]
Bases:
SimpleSquare2DA class to represent a hexagonal lattice
- Parameters:
Notes
Coordination number is 6.
Hamiltonian
Elastic
Functions that define a term in the elastic energy.
These functions will be added into <class interaction> for automatic differentiation.
Notes
This file is part of OpenFerro.
- openferro.engine.elastic.homo_elastic_energy(global_strain, parameters)[source]
Returns the homogeneous elastic energy of a strain field.
- Parameters:
global_strain (jnp.ndarray) – The global strain of a supercell, shape=(6)
parameters (jnp.ndarray) – The parameters of the energy function
- Returns:
The homogeneous elastic energy
- Return type:
jnp.ndarray
- openferro.engine.elastic.pV_energy(global_strain, parameters)[source]
Returns pressure * (volume - reference volume)
- Parameters:
global_strain (jnp.ndarray) – The global strain of a supercell, shape=(6)
parameters (jnp.ndarray) – The parameters of the energy function
- Returns:
The pV energy
- Return type:
jnp.ndarray
- openferro.engine.elastic.inhomo_elastic_energy(local_displacement, parameters)[source]
Returns the inhomogeneous elastic energy of a strain field.
- Parameters:
local_displacement (jnp.ndarray) – The local displacement field, shape=(nx, ny, nz, 3)
parameters (tuple) – The parameters of the energy function containing: - B11 (float): elastic constant B11 - B12 (float): elastic constant B12 - B44 (float): elastic constant B44
- Returns:
The total elastic energy (homogeneous + inhomogeneous)
- Return type:
jnp.ndarray
Ferroelectric
Functions that define a ferroelectric term in the Hamiltonian. They will be added into <class interaction> for automatic differentiation.
- openferro.engine.ferroelectric.self_energy_onsite_isotropic(field, parameters)[source]
Returns the isotropic self-energy of a 3D field. See Eq.(2-3) in [Zhong, W., David Vanderbilt, and K. M. Rabe. Physical Review B 52.9 (1995): 6301.] for meaning of the parameters.
- Parameters:
field (jnp.array) – The field to calculate the energy
parameters (jax.numpy array) – The parameters of the energy function
- Returns:
The energy of the field
- Return type:
jnp.array
- openferro.engine.ferroelectric.self_energy_onsite_scalar(field, parameters)[source]
Returns the self-energy of a scalar field. E= sum_i E_i. (sum over the lattice sites i) E_i = k_2 * u_i^2 + alpha * u_i^4
- Parameters:
field (jnp.array) – The field to calculate the energy
parameters (jax.numpy array) – The parameters of the energy function
- Returns:
The energy of the field
- Return type:
jnp.array
- openferro.engine.ferroelectric.short_range_1stnn_isotropic_scalar(field, parameters)[source]
Returns the short-range interaction of nearest neighbors for a R^3 field defined on a lattice with periodic boundary conditions.
- Parameters:
field (jnp.array) – The field to calculate the energy
parameters (jax.numpy array) – The parameters of the energy function
- Returns:
The energy of the field
- Return type:
jnp.array
- openferro.engine.ferroelectric.short_range_1stnn_isotropic(field, parameters)[source]
Returns the short-range interaction of nearest neighbors for a R^3 field defined on a isotropic lattice with periodic boundary conditions.
- Parameters:
field (jnp.array) – The field to calculate the energy
parameters (jax.numpy array) – The parameters of the energy function
- Returns:
The energy of the field
- Return type:
jnp.array
- openferro.engine.ferroelectric.short_range_1stnn_anisotropic(field, parameters)[source]
Returns the short-range interaction of nearest neighbors for a R^3 field defined on a anisotropic lattice with periodic boundary conditions.
- Parameters:
field (jnp.array) – The field to calculate the energy
parameters (jax.numpy array) – The parameters of the energy function
- Returns:
The energy of the field
- Return type:
jnp.array
- openferro.engine.ferroelectric.short_range_2ednn_isotropic(field, parameters)[source]
Returns the short-range interaction of nearest neighbors for a R^3 field defined on a lattice with periodic boundary conditions.
- Parameters:
field (jnp.array) – The field to calculate the energy
parameters (jax.numpy array) – The parameters of the energy function
- Returns:
The energy of the field
- Return type:
jnp.array
- openferro.engine.ferroelectric.get_short_range_3rdnn_isotropic()[source]
Returns the engine of short-range interaction of third nearest neighbors for a R^3 field defined on a lattice with periodic boundary conditions.
- Returns:
The interaction function
- Return type:
function
- openferro.engine.ferroelectric.homo_strain_dipole_interaction(global_strain, dipole_field, parameters)[source]
Returns the homogeneous strain dipole interaction energy.
- Parameters:
global_strain (jnp.array) – Shape=(6), the global strain of a supercell
dipole_field (jnp.array) – Shape=(nx, ny, nz, 3), the dipole field
parameters (jax.numpy array) – The parameters of the energy function containing B1xx : Elastic constant B1xx B1yy : Elastic constant B1yy B4yz : Elastic constant B4yz
- Returns:
The homogeneous strain dipole interaction energy
- Return type:
jnp.array
- openferro.engine.ferroelectric.get_inhomo_strain_dipole_interaction(enable_jit=True)[source]
Returns the inhomogeneous strain dipole interaction function.
- Parameters:
enable_jit (bool, optional) – Whether to enable JIT compilation, by default True
- Returns:
The interaction function
- Return type:
function
- openferro.engine.ferroelectric.dipole_efield_interaction(field, parameters)[source]
Returns the dipole-electric field interaction energy.
- Parameters:
field (jnp.array) – The field to calculate the energy
parameters (jax.numpy array) – The parameters of the energy function
- Returns:
The interaction energy
- Return type:
jnp.array
Magnetic
Functions that define a term in the magnetic Hamiltonian. They will be added into <class interaction> for automatic differentiation.
- openferro.engine.magnetic.get_isotropic_exchange_energy_engine(rollers)[source]
Returns the exchange energy engine for a R^3 field defined on a lattice with periodic boundary conditions.
- Parameters:
rollers (list) – List of jnp.roll functions specifying the neighbors
- Returns:
Energy engine function
- Return type:
callable
- openferro.engine.magnetic.cubic_anisotropy_energy(field, parameters)[source]
Returns the anisotropy energy of the field.
- Parameters:
field (ndarray) – The magnetic field
parameters (ndarray) – Array containing K1 and K2 anisotropy constants
- Returns:
The anisotropy energy: -K1*(mx^2*my^2 + my^2*mz^2 + mx^2*mz^2) - K2*mx^2*my^2*mz^2
- Return type:
- openferro.engine.magnetic.Dzyaloshinskii_Moriya_energy(field, parameters)[source]
Returns the Dzyaloshinskii-Moriya energy of the field.
- Parameters:
field (ndarray) – The magnetic field
parameters (ndarray) – Array of parameters
- Returns:
The Dzyaloshinskii-Moriya energy
- Return type:
Ewald
Functions for Ewald summation
- openferro.engine.ewald.get_dipole_dipole_ewald(latt, sharding=None)[source]
Returns the function to calculate the energy of dipole-dipole interaction.
Implemented according to Sec.5.3 of “Wang, D., et al. ‘Ewald summation for ferroelectric perovksites with charges and dipoles.’ Computational Materials Science 162 (2019): 314-321.”
- Parameters:
latt (Lattice) – The lattice object containing size and lattice vectors
sharding (jax.sharding.Sharding, optional) – Sharding specification for distributed arrays
- Returns:
Function that calculates dipole-dipole interaction energy
- Return type:
callable
- openferro.engine.ewald.dipole_dipole_ewald_plain(field, parameters)[source]
Brute-force Ewald summation for dipole-dipole interaction.
For benchmarking purpose only.
- Parameters:
field (ndarray) – The field values, shape=(l1, l2, l3, 3)
parameters (dict) –
- Dictionary containing:
- a1float
First lattice vector
- a2float
Second lattice vector
- a3float
Third lattice vector
- Z_starfloat
Born effective charge
- epsilon_inffloat
High-frequency dielectric constant
- Returns:
The dipole-dipole interaction energy
- Return type:
Integrators
Base
Base class for integrators.
This file is part of OpenFerro.
- class openferro.integrator.base.Integrator(dt)[source]
Bases:
objectBase class for integrators.
- Parameters:
dt (float) – Time step size
- step(field, force_updater=None)[source]
Update the field by one time step.
In most cases, the force will be updated for all fields in one setting, before any integrator is called. So the force_updater is not necessary in most cases. However, for some implicit integrators, the force_updater is needed.
Molecular Dynamics
Integrators for unconstrained molecular dynamics.
This file is part of OpenFerro.
- class openferro.integrator.md.GradientDescentIntegrator(dt)[source]
Bases:
IntegratorGradient descent integrator.
- Parameters:
dt (float) – Time step size
- class openferro.integrator.md.GradientDescentIntegrator_Strain(dt, freeze_x=False, freeze_y=False, freeze_z=False)[source]
Bases:
GradientDescentIntegratorGradient descent integrator for global strain.
- Parameters:
- class openferro.integrator.md.LeapFrogIntegrator(dt)[source]
Bases:
IntegratorLeapfrog integrator.
- Parameters:
dt (float) – Time step size
- class openferro.integrator.md.LeapFrogIntegrator_Strain(dt, freeze_x=False, freeze_y=False, freeze_z=False)[source]
Bases:
LeapFrogIntegratorLeapfrog integrator for global strain.
- Parameters:
- class openferro.integrator.md.LangevinIntegrator(dt, temp, tau)[source]
Bases:
IntegratorLangevin integrator as in J. Phys. Chem. A 2019, 123, 28, 6056-6079. ABOBA scheme: exp(i L dt) = exp(i Lx dt/2)exp(i Lt dt)exp(i Lx dt/2)exp(i Lp dt)
Lx/2: half-step position update (_step_x) Lt: velocity update from damping and noise (_step_t) Lp: full-step velocity update (_step_p)
- class openferro.integrator.md.LangevinIntegrator_Strain(dt, temp, tau, freeze_x=False, freeze_y=False, freeze_z=False)[source]
Bases:
LangevinIntegratorLangevin integrator for global strain.
- Parameters:
Landau-Lifshitz-Gilbert
Integrators for Landau-Lifshitz equations of motion. Fields are constrained to have fixed magnitude.
This file is part of OpenFerro.
- class openferro.integrator.llg.ConservativeLLIntegrator(dt, gamma=None)[source]
Bases:
Integrator[For testing purposes: naive geometric integrator that may cause increasement in energy.] Adiabatic spin precession, i.e. Landau-Lifshitz equation of motion without dissipative damping term.
The equation of motion is: dM/dt = -gamma M x B
- Parameters:
- class openferro.integrator.llg.LLIntegrator(dt, alpha, gamma=None)[source]
Bases:
ConservativeLLIntegrator[For testing purposes: naive geometric integrator.] Landau-Lifshitz equation of motion.
See Eriksson, Olle, et al. Atomistic spin dynamics: foundations and applications. Oxford university press, 2017, Sec.7.4.5 for details.
The equation of motion is
dM/dt = -gamma M x B - (gamma * alpha / |M|) * M x (M x B)
Here gamma=(gyromagnetic ratio)/ (1+alpha^2) is the renormalized gyromagnetic ratio for simulating LLG equation in Landau-Lifshitz form.
- Parameters:
- class openferro.integrator.llg.LLLangevinIntegrator(dt, temp, alpha, gamma=None)[source]
Bases:
LLIntegrator[For testing purposes: naive geometric integrator.] Stochastic Landau-Lifshitz equation of motion.
See Eriksson, Olle, et al. Atomistic spin dynamics: foundations and applications. Oxford university press, 2017, Sec.7.4.5 for details.
The equation of motion is: dM/dt = -gamma M x (B + b) - (gamma * alpha / |M|) * M x (M x (B + b))
b is the stochastic force <b_i_alpha(t) b_j_beta(s)> = 2 * D * delta_ij * delta_alpha_beta * delta(t-s) A steady Boltzmann state requires D= alpha/(1+alpha^2) * kbT / gamma / |m|
- Parameters:
- class openferro.integrator.llg.ConservativeLLSIBIntegrator(dt, gamma=None, max_iter=10, tol=1e-06)[source]
Bases:
Integrator[Semi-implicit B (SIB) scheme. (J. Phys.: Condens. Matter 22 (2010) 176001) ] Adiabatic spin precession, i.e. Landau-Lifshitz equation of motion without dissipative damping term.
The equation of motion is
dM/dt = -gamma M x B
Let M[i] be the spin configuration at time step i, Y[i] be the auxiliary spin configuration at time step i+1, B(M) be the magnetic field of configuration M. The SIB scheme is
(step 1) Y[i] = M[i] - dt * gamma * (M[i]+Y[i])/2 x B(M[i])
(step 2) M[i+1] = M[i] - dt * gamma * (M[i]+M[i+1])/2 x B((M[i] + Y[i])/2)
Both equations are implicit, and can be solved iteratively through fixed-point iterations.
- Parameters:
dt (float) – Time step size
gamma (float, optional) – Gyromagnetic ratio. If None, uses electron gyromagnetic ratio
max_iter (int, optional) – Maximum number of iterations for fixed-point iterations
tol (float, optional) – Tolerance for convergence. Convergence is declared if Average[|M_new - M_old|/Ms] < tol
- class openferro.integrator.llg.LLSIBIntegrator(dt, alpha, gamma=None, max_iter=10, tol=1e-06)[source]
Bases:
IntegratorLandau-Lifshitz equation of motion.
See Eriksson, Olle, et al. Atomistic spin dynamics: foundations and applications. Oxford university press, 2017, Sec.7.4.5 for details.
The equation of motion is
dM/dt = -gamma M x B - (gamma * alpha / |M|) * M x (M x B)
Here gamma=(gyromagnetic ratio)/ (1+alpha^2) is the renormalized gyromagnetic ratio for simulating LLG equation in Landau-Lifshitz form. Let M[i] be the spin configuration at time step i, Y[i] be the auxiliary spin configuration at time step i+1. Let B(M) be the effective magnetic field that includes also the dissipative damping term. The SIB scheme is
(step 1) Y[i] = M[i] - dt * gamma * (M[i]+Y[i])/2 x B(M[i])
(step 2) M[i+1] = M[i] - dt * gamma * (M[i]+M[i+1])/2 x B((M[i] + Y[i])/2)
Both equations are implicit, and can be solved iteratively through fixed-point iterations.
- Parameters:
dt (float) – Time step size
alpha (float) – Gilbert damping constant
gamma (float, optional) – Gyromagnetic ratio. If None, uses electron gyromagnetic ratio
max_iter (int, optional) – Maximum number of iterations for fixed-point iterations
tol (float, optional) – Tolerance for convergence. Convergence is declared if Average[|M_new - M_old|/Ms averaged over lattice] < tol
- _update_x(M, Ms, Y, B, step_size)[source]
One iteration of (step 1) or (step 2) in the SIB scheme. Will be called iteratively through fixed-point iterations.
- class openferro.integrator.llg.LLSIBLangevinIntegrator(dt, temp, alpha, gamma=None, max_iter=10, tol=1e-06)[source]
Bases:
LLSIBIntegratorStochastic Landau-Lifshitz equation of motion.
See Eriksson, Olle, et al. Atomistic spin dynamics: foundations and applications. Oxford university press, 2017, Sec.7.4.5 for details.
The equation of motion is
dM/dt = -gamma M x (B + b) - (gamma * alpha / |M|) * M x (M x (B + b))
Here gamma=(gyromagnetic ratio)/ (1+alpha^2) is the renormalized gyromagnetic ratio for simulating LLG equation in Landau-Lifshitz form. b is the stochastic force <b_i_alpha(t) b_j_beta(s)> = 2 * D * delta_ij * delta_alpha_beta * delta(t-s) A steady Boltzmann state requires D= alpha/(1+alpha^2) * kbT / gamma / |m|
Let M[i] be the spin configuration at time step i, Y[i] be the auxiliary spin configuration at time step i+1. Let B(M[i]) be the effective magnetic field including also the dissipative damping term and the stochastic force. The SIB scheme is
(step 1) Y[i] = M[i] - dt * gamma * (M[i]+Y[i])/2 x B(M[i])
(step 2) M[i+1] = M[i] - dt * gamma * (M[i]+M[i+1])/2 x B((M[i] + Y[i])/2)
Both equations are implicit, and can be solved iteratively through fixed-point iterations.
Simulation
Classes which define the time evolution of physical systems.
Notes
This file is part of OpenFerro.
- class openferro.simulation.Simulation(system)[source]
Bases:
objectThe base class to define a simulation.
A simulation controls the time evolution of a system. This class does not implement any time integration algorithm. Each field object has its own integrator. The class only calls the step method of each integrator and controls output.
- Parameters:
system (System) – The physical system to simulate
- add_thermo_reporter(file='thermo.log', log_interval=100, global_strain=False, excess_stress=False, volume=False, potential_energy=False, kinetic_energy=False, temperature=False)[source]
Add a reporter to output global thermodynamic information.
- Parameters:
file (str, optional) – Output file name, by default ‘thermo.log’
log_interval (int, optional) – Number of steps between outputs, by default 100
global_strain (bool, optional) – Whether to output global strain, by default False
excess_stress (bool, optional) – Whether to output excess stress, by default False
volume (bool, optional) – Whether to output volume, by default False
potential_energy (bool, optional) – Whether to output potential energy, by default False
kinetic_energy (bool, optional) – Whether to output kinetic energy, by default False
temperature (bool, optional) – Whether to output temperature, by default False
- add_field_reporter(file_prefix, field_ID, log_interval=100, field_average=True, dump_field=False)[source]
Add a reporter to dump the values of a given field.
- Parameters:
file_prefix (str) – Prefix for output files
field_ID (str) – ID of field to report
log_interval (int, optional) – Number of steps between outputs, by default 100
field_average (bool, optional) – Whether to output field averages, by default True
dump_field (bool, optional) – Whether to dump full field values, by default False
- class openferro.simulation.MDMinimize(system, max_iter=100, tol=1e-05)[source]
Bases:
SimulationClass for energy minimization using molecular dynamics.
- Parameters:
- _step(variable_cell)[source]
Update the field by one time step.
- Parameters:
variable_cell (bool) – Whether to allow cell parameters to vary
- run(variable_cell=True, pressure=None)[source]
Run the minimization.
- Parameters:
- Raises:
ValueError – If pressure not specified for variable cell minimization If pressure specified for fixed cell minimization If integrator not set for any field
- class openferro.simulation.SimulationNVE(system)[source]
Bases:
SimulationClass for NVE (microcanonical) molecular dynamics simulation.
- Parameters:
system (System) – The physical system to simulate
- _step(profile=False)[source]
Update the field by one step.
- Parameters:
profile (bool, optional) – Whether to profile timing, by default False
- run(nsteps=1, profile=False)[source]
Run the simulation.
- Parameters:
- Raises:
ValueError – If integrator not set for any field
- class openferro.simulation.SimulationNVTLangevin(system)[source]
Bases:
SimulationNVEClass for NVT molecular dynamics simulation using Langevin dynamics.
- Parameters:
system (System) – The physical system to simulate
- _step(keys, profile=False)[source]
Update the field by one step.
- Parameters:
keys (array_like) – Random keys for Langevin dynamics
profile (bool, optional) – Whether to profile timing, by default False
- run(nsteps=1, profile=False)[source]
Run the simulation.
- Parameters:
- Raises:
ValueError – If integrator not set for any field
- class openferro.simulation.SimulationNPTLangevin(system, pressure=0.0)[source]
Bases:
SimulationNVTLangevinClass for NPT molecular dynamics simulation using Langevin dynamics.
- Parameters:
Interaction (Abstract)
Classes which define the “interaction” between fields.
Each interaction is associated with a term in the Hamiltonian. Each interaction stores a function “self.energy_engine” that calculates the energy of the interaction and a function “force engine” that calculates the force of the interaction.
Only the energy engine is required. The force engine is optional. If the force engine is not set, the force will be calculated by automatic differentiation of the energy engine.
Notes
This file is part of OpenFerro.
- class openferro.interaction.interaction_base(parameters=None)[source]
Bases:
objectThe base class to specify the interaction between fields.
- set_parameters(parameters)[source]
Set the parameters of the interaction.
- Parameters:
parameters (array_like) – The parameters of the interaction
- Raises:
ValueError – If parameters is not a numpy array, list, or jax array
- get_parameters()[source]
Get the parameters of the interaction.
- Returns:
The parameters of the interaction
- Return type:
jax.numpy.ndarray
- set_energy_engine(energy_engine, enable_jit=True)[source]
Set the energy engine of the interaction.
- Parameters:
energy_engine (callable) – The energy engine of the interaction. It should take the values of the fields as input and return the energy as output.
enable_jit (bool, optional) – Whether to enable jit for the energy engine, by default True
- class openferro.interaction.self_interaction(field_ID, parameters=None)[source]
Bases:
interaction_baseA class to specify the self-interaction of a field.
- Parameters:
field_ID (str) – Identifier for the field
parameters (array_like, optional) – Parameters for the interaction, by default None
- create_force_engine(enable_jit=True)[source]
Derive the force engine of the interaction from the energy engine through automatic differentiation.
- Parameters:
enable_jit (bool, optional) – Whether to enable jit for the force engine, by default True
- Raises:
ValueError – If energy engine is not set
- class openferro.interaction.mutual_interaction(field_1_ID, field_2_ID, parameters=None)[source]
Bases:
interaction_baseA class to specify the mutual interaction between two fields.
- Parameters:
- create_force_engine(enable_jit=True)[source]
Derive the force engine of the interaction from the energy engine through automatic differentiation.
- Parameters:
enable_jit (bool, optional) – Whether to enable jit for the force engine, by default True
- Raises:
ValueError – If energy engine is not set
- calc_energy(field1, field2)[source]
Calculate the energy of the interaction for a given pair of fields.
- class openferro.interaction.triple_interaction(field_1_ID, field_2_ID, field_3_ID, parameters=None)[source]
Bases:
objectA class to specify the mutual interaction between three fields.
- Parameters:
- create_force_engine(enable_jit=True)[source]
Derive the force engine of the interaction from the energy engine through automatic differentiation.
- Parameters:
enable_jit (bool, optional) – Whether to enable jit for the force engine, by default True
- Raises:
ValueError – If energy engine is not set
- calc_energy(field1, field2, field3)[source]
Calculate the energy of the interaction for a given triple of fields.
Utilities
Reporters
Classes for reporting simulation data.
This module contains classes for reporting thermodynamic quantities and field values during simulations.
- class openferro.reporter.Thermo_Reporter(file='thermo.log', log_interval=100, global_strain=False, excess_stress=False, volume=True, potential_energy=False, kinetic_energy=False, temperature=False)[source]
Bases:
objectReporter for thermodynamic quantities.
- Parameters:
file (str, optional) – Output file name, by default ‘thermo.log’
log_interval (int, optional) – Number of steps between outputs, by default 100
global_strain (bool, optional) – Whether to output global strain, by default False
excess_stress (bool, optional) – Whether to output excess stress, by default False
volume (bool, optional) – Whether to output volume, by default True
potential_energy (bool, optional) – Whether to output potential energy, by default False
kinetic_energy (bool, optional) – Whether to output kinetic energy, by default False
temperature (bool, optional) – Whether to output temperature, by default False
- __init__(file='thermo.log', log_interval=100, global_strain=False, excess_stress=False, volume=True, potential_energy=False, kinetic_energy=False, temperature=False)[source]
- class openferro.reporter.Field_Reporter(file_prefix, field_ID, log_interval=100, field_average=True, dump_field=False)[source]
Bases:
objectReporter for field values.
- Parameters:
file_prefix (str) – Prefix for output files
field_ID (str) – ID of field to report
log_interval (int, optional) – Number of steps between outputs, by default 100
field_average (bool, optional) – Whether to output field averages, by default True
dump_field (bool, optional) – Whether to dump full field values, by default False
Units
Module containing classes that define the internal units.
Notes
This file is part of OpenFerro.
- class openferro.units.Constants[source]
Bases:
objectClass containing fundamental physical constants and unit conversions. This class specifies the internal units of OpenFerro.
- Angstrom = 1.0
- length = 1.0
- eV = 1.0
- energy = 1.0
- ps = 1.0
- time = 1.0
- elementary_charge = 1.0
- charge = 1.0
- Kelvin = 1.0
- temperature = 1.0
derived units
- kb = 8.6173303e-05
- amu = 0.0001035
- me = 5.677803e-08
- epsilon0 = 0.005526349406
- meter = 10000000000.0
- cm = 100000000.0
- mm = 10000000.0
- um = 10000.0
- nm = 10.0
- pm = 0.001
- bohr_radius = 0.52917721
- second = 1000000000000.0
- ms = 1000000000.0
- us = 1000000.0
- ns = 1000.0
- fs = 0.001
- bar = 6.24150912510413e-07
- Coulomb = 6.241509074460763e+18
- Ampere = 6241509.0744607635
- Voltage = 1.0
- V_Angstrom = 1.0
- Joule = 6.241509e+18
- Ry = 13.605693123
- mRy = 0.013605693123000001
- hbar = 0.0006582119569
- hartree = 27.211386245988
we will use Bohr magneton based unit system for magnetic interactions. This is not entirely consistent with the other base units. For example, here mu0 will be in unit of eV * A^3 / muB^2, instead of eV * ps^2 / A * e^-2 Derivation: _speed_of_light = 2997924.58 # Speed of light in A/ps _mu0 = 1 / _speed_of_light**2 / epsilon0 # Vacuum permeability in eV*ps^2/A*e^-2 _muB = elementary_charge * hbar / 2 / me # Bohr magneton in e * A^2 / ps mu0 = _mu0 * _muB**2 / Angstrom**3 # Vacuum permeability in eV * A^3 / muB^2
- muB = 1.0
- mu0 = 0.0006764429231627333
- Tesla = 5.788381806e-05
- electron_g_factor = 2.00231930436
- electron_gyro_ratio = 3042.058539608398
- class openferro.units.AtomicUnits_to_InternalUnits[source]
Bases:
objectClass defining atomic units, given in terms of the internal units of OpenFerro.
- time = 2.418884326505e-05
- length = 0.52917721
- energy = 27.211386245988
- mass = 5.677803e-08
- velocity = 21876.91259980993
- force = 51.42206756407367
- electric_dipole_moment = 0.52917721
Helper Functions
Utility functions.
- openferro.utilities.SO3_rotation(B: Array, dt: float)[source]
Calculate batched rotation matrix for proper rotation around magnetic field axis.
- Parameters:
B (jnp.ndarray) – The magnetic field with shape (*, 3)
dt (float) – The time step
- Returns:
The rotation matrix with shape (*, 3, 3)
- Return type:
jnp.ndarray
Notes
Returns the batched rotation matrix (shape=(*, 3, 3)) of a proper rotation of a vector by an angle theta (shape=(*,)) around the axes u (shape=(*, 3)). See https://en.wikipedia.org/wiki/Rotation_matrix for details.
The angle and axes are specified by the magnetic field B and time step dt as: u = B / jnp.linalg.norm(B, axis=-1)[…, None] theta = jnp.linalg.norm(B, axis=-1) * dt
Parallelism
Classes for multi-GPU parallelism.
Notes
This file is part of OpenFerro.
- class openferro.parallelism.DeviceMesh(devices=None, num_rows=None, num_cols=None)[source]
Bases:
object- __init__(devices=None, num_rows=None, num_cols=None)[source]
Initialize the single-host multi-device parallelism. Get the mesh of the devices.
- Parameters:
- Raises:
ValueError – If only one device is available If num_rows * num_cols does not match number of devices