Other classes¶
Heterostructure functions and methods¶
HT.get_dc_current()¶
Compute the time-averaged (DC) current through a two-terminal junction at a
bias voltage \(V\), with the Floquet-Keldysh formalism. The leads can be
normal or superconducting, built with heterostructures.build(h1,h2), with
or without a central region. With superconducting leads this includes
multiple Andreev reflection. See Quantum transport.
Arguments:
- voltage: bias voltage \(eV\)
Optional arguments:
- nmax=6, nmax_max=40: initial and maximal number of Floquet sidebands. The
number grows until the current converges to
tol; a warning is printed ifnmax_maxis reached first - tol=1e-3: relative tolerance on the current
- temperature=0.: temperature of the leads
- delta=None: broadening, by default
HT.delta. It must be much smaller than the smallest superconducting gap
Returns the DC current
HT.get_iv_curve()¶
HT.get_dc_current() for an array of voltages.
Arguments:
- voltages: array of bias voltages
Returns an array of DC currents
HT.didv_curve() / lp.didv_curve()¶
The differential conductance \(dI/dV\) for an array of energies, the same as
[ht.didv(energy=e) for e in es]. It is also available as
didv(energies=...).
Arguments:
- energies: array of bias energies
- any keyword argument of
didv(method,delta,temp, ...)
Returns an array of \(dI/dV\) values
Note that T means different things on the two classes. On a
Heterostructure, T is the temperature. On a LocalProbe, T is the
transparency of the probe, the coupling between probe and sample, and the
temperature is temp. A T= or a delta= given to one call applies only to
that call. HT.with_delta(delta), lp.with_delta(delta) and
lp.with_coupling(T) return a copy with a new broadening or coupling, to
use in several calls.
HT.get_kappa()¶
Compute the exponent ratio \(\kappa\), which tells single-particle tunneling
from Andreev reflection (also LocalProbe.get_kappa(), see
Quantum transport).
Optional arguments:
- energy=0.0: energy at which \(\kappa\) is computed (returns a number)
- energies: array of energies instead (returns an array); do not give both
- temp=0.: temperature. A finite value averages the conductances over the Fermi window
- T=1e-2: coupling around which the exponent is computed
Returns \(\kappa\), a number or an array like energies
\(\kappa\) is the exponent \(d\log G/d\log T\) of the conductance with the
coupling \(T\), divided by the same exponent with the pairing removed. It is
1 for single-particle tunneling, since \(G\propto T\), and 2 for Andreev
reflection, since \(G\propto T^2\). Inside a superconducting gap the
broadening delta of a LocalProbe acts as a finite quasiparticle
lifetime, and it gives a normal conductance \(G_N\delta/\Delta\). The Andreev
conductance is \(G_N^2/4\) in the tunneling limit, so the plateau at 2 needs
delta well below \(\Delta G_N/4\) at the smallest coupling, for example
delta=1e-10 for a gap of 0.1 down to T=1e-3. See
examples/transport/localprobe_kappa_1D and
jupyter-notebooks/functionalities/quantum_transport/07_differential_decay_rate.ipynb.
SpinModel functions and methods¶
A SpinModel is a classical spin model with energy
where \(\vec S_i\) is a unit vector with angles \((\theta_i,\phi_i)\), \(\vec b_i\) a magnetic field, and \(J_{ij}\) a \(3\times3\) exchange tensor. See Classical spin models.
sm.add_heisenberg()¶
Add exchange couplings between neighbor shells. Several calls add up.
Optional arguments:
- Jij=None: list of couplings of each shell, for example
[J1,J2,J3]for first, second and third neighbors. It accepts everything thattijofg.get_hamiltonian()accepts;Noneis first neighbors with \(J=1\) - Jm=[1.,1.,1.]: diagonal weights \((J_x,J_y,J_z)\) multiplying
Jij; use different values for XXZ or Ising anisotropy
Modifies sm in place, no return value
sm.add_field()¶
Add a uniform magnetic field \(\vec b\) to every site. Several calls add up.
Arguments:
- v: the field, a 3-vector, for example
[0.,0.,1.]
sm.add_tensor() / sm.add_tensor_2d()¶
Add a general coupling tensor \(J_{ij}\) given by a function
fun(r1,r2) -> 3x3 matrix (see generating_functions below).
add_tensor only couples sites inside the unit cell. add_tensor_2d also
sums the periodic images \(i_a\mathbf a_1 + j_a\mathbf a_2\) with
\(i_a,j_a\) in [-ncells,ncells], and can rotate the tensor of each image
around \(z\) by the angle \(\pi(v_0 i_a + v_1 j_a)\), with \((v_0,v_1)\) given by
vspiral. This puts a spin-spiral wavevector into the exchange.
Arguments:
- fun: coupling function, for example one from
generating_functions
Optional arguments (add_tensor_2d only):
- ncells=1: number of periodic images on each side, along each lattice vector
- vspiral=[0.,0.]: rotation angles per image, in units of \(\pi\)
Modifies sm in place, no return value
classicalspin.generating_functions()¶
Return a coupling function fun(r1,r2) -> 3x3 matrix of a common type, to
use with add_tensor and add_tensor_2d.
Optional arguments:
- name="Heisenberg": the type of coupling.
"Heisenberg"is isotropic exchange, cut byfc(distance)."Linear"is the tensor \(J\,\hat r\hat r/r^3\), with \(\hat r\) the bond direction."RKKYTI"is the RKKY coupling on the surface of a topological insulator, \(J(\tfrac32\hat r\hat r - 1)/r^3\)."ZZ"is Ising, only \(S^z_i S^z_j\)."XYZ"is diagonal with weightsv."DM"is a first-neighbor Dzyaloshinskii-Moriya coupling \(\vec D_{ij}\cdot(\vec S_i\times\vec S_j)\), with \(\vec D_{ij}\) along \(\mathbf r_{ij}\times\vec v\), sovplays the role of the direction of the intermediate ion (or a function of the bond vector) - J=1.0: strength of the coupling
- v=[0.,0.,1.]: vector used by the type, or a function of the bond vector
- fc=None: function of the distance that cuts or modulates the coupling;
by default first neighbors (
0.9 < d < 1.1) - fdiff=lambda x,y: x-y: how the bond vector is computed from
(r1,r2) - fr=None: extra rotation matrix
fr(r1,r2)applied to the coupling (by default the identity)
Returns the coupling function
sm.minimize_energy()¶
Find the classical ground state, by minimizing \(E\) over the angles \((\theta_i,\phi_i)\) of all spins from several random starting points. Only states with the periodicity of the unit cell are found, so a spiral needs a supercell that fits it.
Optional arguments:
- theta0=None, phi0=None: starting angles. With
Noneeach try starts from random angles, which is what makestriesuseful. With explicit arrays every try starts at the same point and gives the same result - tries=10: number of minimizations; the one with the lowest energy is kept
- calle=None: a function
calle(sm) -> floatadded to the energy, for example a penalty that favors a texture - silent=False: if
True, the minimum energy is not printed
Sets sm.theta, sm.phi and sm.magnetization to the best result, and
returns (theta,phi)
sm.get_energy() / sm.energy()¶
The energy \(E\) above for the current angles. Returns a number.
sm.get_local_energy()¶
The energy of each site: its field term plus half of each exchange term
it belongs to. The values add up to sm.get_energy().
Returns an array over sites
sm.get_magnetization()¶
The Cartesian components of the spins, \(\vec S_i = (\sin\theta_i\cos\phi_i,\sin\theta_i\sin\phi_i,\cos\theta_i)\).
Returns (mx,my,mz), arrays over sites
align.most_perpendicular_vector() / align.most_perp_basis()¶
(classicalspintk.align) Find the direction most perpendicular to a set of
vectors, for example a magnetization, and rotate the vectors so that this
direction is the new \(z\) axis. The vectors are then mostly in the new \(xy\)
plane, which helps to plot a skyrmion or a spiral as arrows in the plane.
See examples/classicalspin/perpendicular/main.py.
Returns the perpendicular unit vector, or (for most_perp_basis) the
vectors in the rotated basis
LatticeGas functions and methods¶
A LatticeGas is a classical lattice gas with occupations \(n_i=0,1\) and
energy
where the sum runs over ordered pairs, so each bond counts twice. See Lattice gas models.
lg.add_interaction()¶
Add a density-density coupling \(J_{ij}\) between neighbor shells. Several calls add up.
Optional arguments:
- Jij: list of couplings of each shell, for example
[J1,J2,J3]. A positive value is repulsive and a negative one attractive. It accepts everything thattijofg.get_hamiltonian()accepts
Modifies lg in place, no return value
lg.set_filling()¶
Replace the occupations lg.den by a random configuration with a given
filling, for example to start a new anneal.
Arguments:
- filling: fraction of occupied sites (rounded to an integer number of sites)
lg.get_energy()¶
The energy \(E\) above for the current occupations lg.den. Returns a
number.
lg.optimize_energy()¶
Lower the energy with Metropolis moves at fixed filling. In each step one to three random pairs of an occupied and an empty site are swapped. The move is accepted if the energy does not increase, and with probability \(e^{-\Delta E/T}\) otherwise.
Optional arguments:
- temp=0.1: Metropolis temperature \(T\).
temp=0only accepts moves that do not increase the energy - ntries=1e5: number of attempted swaps
- resync_every=1000: every how many attempts the energy is recomputed from scratch, to avoid accumulated rounding errors
- patience=None: if given, stop after this many attempts without a new lowest energy
- checkpoint_at=None: an integer or a list of integers; a copy of
lg.denafter that many attempts is stored inlg.checkpoints, a dictionarystep -> den
Sets lg.den to the final configuration, and returns the energy after each
attempt
lg.anneal()¶
Simulated annealing: lg.optimize_energy() at each temperature of a
decreasing list. The lowest-energy configuration of the whole schedule is
kept.
Optional arguments:
- temps=None: temperatures, from high to low; by default 10 temperatures on a geometric scale from 2.0 to 0.05
- ntries=1e4: attempts per temperature
- checkpoint_at=None: as in
lg.optimize_energy(), but counted over the whole schedule - any other keyword of
lg.optimize_energy(), used at every temperature
Sets lg.den to the best configuration, and returns the energies of the
whole schedule
lg.optimize_energy_multistart()¶
Run nstart independent optimizations from random configurations at the
current filling, and keep the lowest energy. This lowers the chance of
ending in a metastable state. The runs are parallel after
parallel.set_cores() (see Parallelism).
Optional arguments:
- nstart=10: number of runs
- any other keyword of
lg.optimize_energy()(temp,ntries,patience...), the same for every run
Sets lg.den to the best configuration, and returns its energy
lg.optimize_grand_canonical()¶
Metropolis sampling in the grand-canonical ensemble. Single sites are
switched between occupied and empty, so the filling is not fixed and is set
by the chemical potential lg.mu. Use it to scan a phase diagram as a
function of the chemical potential, or to sample at a fixed temperature for
latticegas.get_specific_heat() and get_susceptibility().
Optional arguments: the same as lg.optimize_energy() (temp, ntries,
resync_every, without patience), but the default is temp=1.0
Sets lg.den to the final configuration, and returns (es, ns): the energy
and the number of occupied sites after each attempt
latticegas.get_specific_heat() / latticegas.get_susceptibility()¶
Thermodynamic quantities from a trajectory sampled at a fixed temperature
\(T\), by lg.optimize_energy() or lg.optimize_grand_canonical().
get_specific_heat(es, temp, burn=0.2) gives the specific heat
\(C=\mathrm{Var}(E)/T^2\) from the energies. get_susceptibility(ns, temp,
burn=0.2) gives the compressibility \(dN/d\mu=\mathrm{Var}(N)/T\) from the
number of particles; it only makes sense in the grand-canonical case, where
\(N\) fluctuates. burn is the fraction at the start of the trajectory that
is thrown away as thermalization.
lg.add_tensor()¶
Add a coupling \(J_{ij}=\mathrm{fun}(\mathbf r_i,\mathbf r_j)\) between all pairs of sites, for interactions beyond neighbor shells, for example a screened or dipolar \(1/r^n\) interaction. Pairs with zero coupling are not stored.
Modifies lg in place, no return value
lg.regroup()¶
Merge repeated pairs from several add_interaction() or add_tensor()
calls, summing their couplings. The energy does not change, only the
calculation gets faster.
Modifies lg in place, no return value
lg.write() / lg.read()¶
Write the occupations lg.den to a text file, and read them back. read()
raises ValueError if the number of sites in the file is not lg.nsites.
Optional arguments:
- name="DENSITY.OUT": file name
lg.get_local_energy() / lg.get_local_mu()¶
get_local_energy() gives the energy of each site,
\(\mu_i n_i + \sum_j J_{ij} n_i n_j\); the values add up to lg.get_energy().
get_local_mu() gives the same expression with site \(i\) occupied, meaning
the energy cost of putting a particle on site \(i\) with its neighbors as they
are.
Optional arguments:
- normalize=False: divide the value of each site by the sum of its couplings
Returns an array over sites
lg.get_correlator()¶
The density-density correlator of the current occupations, as a function of
the neighbor shell. It shows whether the ground state is ordered. n is
the number of shells, normalized divides out the mean occupation.
Returns (distances, correlators)
lg.get_structure_factor()¶
The structure factor of the current occupations,
computed on the real positions of the sites. The correlator gives the length scale of the order, and \(S(\mathbf q)\) gives its wavevector. Since the mean occupation \(\bar n\) is subtracted, \(S(\mathbf q=0)=0\), so a peak at another \(\mathbf q\) signals order. This is the quantity measured in a diffraction experiment.
Optional arguments:
- qpath=None: array of \(\mathbf q\) vectors. By default a square grid of
nq\(\times\)nqpoints between \(-q_{max}\) and \(q_{max}\) - nq=60: points per direction of the default grid
- qmax=None: size of the default grid; by default \(2\pi/d\), with \(d\) the first-neighbor distance
Returns (qpath, sq), the \(\mathbf q\) vectors and \(S(\mathbf q)\)
LatticeIsing functions and methods¶
A LatticeIsing is a classical Ising model with spins \(s_i=\pm1\) and
energy
where the sum runs over ordered pairs, so each bond counts twice, which is two times the usual convention. See Ising models.
li.add_interaction()¶
Add an exchange \(J_{ij}\) between neighbor shells. Several calls add up.
Optional arguments:
- Jij: list of couplings of each shell, for example
[J1,J2,J3]. A positive value is ferromagnetic (note the opposite sign toLatticeGas.add_interaction()). It accepts everything thattijofg.get_hamiltonian()accepts
Modifies li in place, no return value
li.add_field()¶
Add a magnetic field \(b_i\).
Arguments:
- h: a number (the same on every site) or an array with one value per site
Modifies li in place, no return value
li.set_magnetization()¶
Replace the spins li.s by a random configuration with a given
magnetization.
Arguments:
- m=0.0: average magnetization, between -1 and 1 (rounded to an integer number of up spins)
li.get_energy()¶
The energy \(E\) above for the current spins li.s. Returns a number.
li.get_magnetization()¶
The magnetization per site, \(m=\frac{1}{N}\sum_i s_i\), between -1 and 1.
li.optimize_energy()¶
Metropolis dynamics with single spin flips. In each step one random spin is flipped. The flip is accepted if the energy does not increase, and with probability \(e^{-\Delta E/T}\) otherwise. The magnetization is not fixed.
Optional arguments:
- temp=1.0: Metropolis temperature \(T\);
temp=0only accepts flips that do not increase the energy - ntries=1e5: number of attempted flips
- resync_every=1000: every how many attempts the energy is recomputed from scratch
- checkpoint_at=None: an integer or a list of integers; a copy of
li.safter that many attempts is stored inli.checkpoints
There is no patience option, because the trajectory is meant for
latticegas.get_specific_heat() and get_susceptibility(), and stopping
early would bias them.
Sets li.s to the final configuration, and returns (es, ms): the energy
and the total magnetization \(\sum_i s_i\) after each attempt
li.optimize_conserved()¶
Kawasaki dynamics: in each step a random up spin and a random down spin are
exchanged, so the magnetization is fixed. Raises ValueError if li.s does
not contain both up and down spins.
Optional arguments: the same as li.optimize_energy(), but with default
temp=0.1, and also:
- patience=None: if given, stop after this many attempts without a new lowest energy
Sets li.s to the final configuration, and returns the energy after each
attempt
li.anneal()¶
Simulated annealing: li.optimize_energy() at each temperature of a
decreasing list, keeping the lowest-energy configuration of the whole
schedule.
Optional arguments:
- temps=None: temperatures from high to low; by default 10 temperatures on a geometric scale from 2.0 to 0.05
- ntries=1e4: attempts per temperature
- checkpoint_at=None: as in
li.optimize_energy(), counted over the whole schedule - any other keyword of
li.optimize_energy(), used at every temperature
Sets li.s to the best configuration, and returns (es, ms) for the whole
schedule
li.optimize_energy_multistart()¶
Run nstart independent optimizations from random spins with the current
magnetization, and keep the lowest energy. Parallel as in
lg.optimize_energy_multistart().
Optional arguments:
- nstart=10: number of runs
- any other keyword of
li.optimize_energy()(temp,ntries), the same for every run
Sets li.s to the best configuration, and returns its energy
li.get_local_energy() / li.get_local_field()¶
get_local_energy() gives the energy of each site; the values add up to
li.get_energy(). get_local_field() gives the effective field on each
site, \(h^{\mathrm{eff}}_i=b_i+2\sum_k J_{ik}s_k\), so that flipping \(s_i\)
costs exactly \(2s_ih^{\mathrm{eff}}_i\).
Returns an array over sites
li.get_correlator() / li.get_structure_factor()¶
The spin-spin correlator and the structure factor of the current spins
li.s. The arguments are the same as in lg.get_correlator() and
lg.get_structure_factor().
li.add_tensor() / li.regroup()¶
The same as lg.add_tensor() and lg.regroup().
Modifies li in place, no return value
li.write() / li.read()¶
Write the spins li.s to a text file, and read them back. read() takes
the sign of each value, so the spins are exactly \(\pm1\), and raises
ValueError if the number of sites in the file is not li.nsites.
Optional arguments:
- name="SPIN.OUT": file name