gpe.interfaces#

Interface Definitions.

To help keep the code modular and predictable, we provide several interfaces. The idea is that generalized code should only these methods and attributes defined in the interface so that it is easy for one to extend the code by implementing a different version of the same interface.

Classes#

IMinimizeState

Interface provided by state minimizers.

IExperimentMinimal

Minimal Interface for Experiments.

IExperiment

Full interface for Experiment classes.

IStateDFT

Extension to the IState interface for orbital-free DFT equations.

IStateMinimizeDFT

Extension of IStateDFT that permits minimization.

Module Contents#

class IMinimizeState(real=False, fix_N=True)[source]#

Bases: zope.interface.Interface

Interface provided by state minimizers.

minimize(E_tol=1e-12, callback=None, **kw)[source]#

Return the state minimizing the energy.

Parameters:
  • psi_tol (float) – Desired relative tolerance for the wavefunction.

  • E_tol (float) – Desired relative tolerance for the energy.

  • callback (function) – Optional callback function called as callback(state) during iterations for debugging.

  • kw (dict) – Additional arguments to pass to the solver.

class IExperimentMinimal(name, bases=(), attrs=None, __doc__=None, __module__=None)[source]#

Bases: zope.interface.Interface

Minimal Interface for Experiments.

The full IExperiment interface can be defined from these minimal attributes by the ExperimentBase class.

State[source]#
t_unit[source]#
t_name[source]#
image_ts_[source]#
init()[source]#

Performs any complex initialization other that assigning parameters (which is done by the constructor). Subclasses should not overload the constructor.

get_Vext(fiducial=False, expt=False)[source]#

Return the external potential(s) as relevant for the experiment.

The potential should return three different types of potential depending on the arguments:

  • If expt==False, then return the potential appropriate for the simulation. This may differ from the actual physical potential if cells_x is not None since then only a portion at the center of the trap will be simulation. In this case, the potential should be a periodic extension of the experimental potential matching the experiment in the middle, but becoming periodic at the boundaries so as not to introduce cusps.

    The simulation may also have different parameters such as the trapping frequency along x since one might like to consider a homogeneous state.

  • If expt==True, then return the full experimental potential with the experimental parameters. This potential should not be a periodic modification nor should it use modified parameters such as the trapping frequencies. The idea here is to return the potential that should be used to defined the initial state by determining the chemical potential at the center of the system.

    This potential may depend on one more flag:

    • If fiducial==True, then return a potential such that V_ext(x_TF) = V_TF at the edge of the cloud x_TF in the Thomas Fermi approximation. This is generally how the initial state is specified, however, this potential might not be the one actually used to initialize the simulation as described below.

    • If fiducial==False, then return the actual potential used to initialize the simulation. This may differ from the previous case if the initial experimental state is obtained after adiabatic evolution from V_ext(fiducial=True, expt=True) to V_ext(fiducial=False, expt=True). Strictly speaking, our simulation should also perform this adiabatic evolution, but this can be very costly. Instead, it is often better to minimize into the initial state directly, but to do this, one needs to specify and fix the appropriate particle number or chemical potential from the fiducial state.

Parameters:
  • state (IState) – Current state. Use this to get the time state.t and abscissa state.basis.xyz.

  • fiducial (bool) – If True, then return the potential that should be used to define the initial state in terms of the Thomas Fermi radius of the cloud x_TF.

  • expt (bool) – If True, then return the proper experimental potential rather than the potential used in the simulation.

get_state()[source]#

Quickly return a valid State object.

Should not set state.initializing = False unless initialize == True.

Parameters:

initialize (bool) –

If False, then the initial data need not be provided. (Used by simulations when data is loaded from a file.)

If returning a fully initialized state, then may set state.initializing=True, but users should not generally rely on this flag, and should still call pre_evolve_hook() before evolving.

get_initial_state()[source]#

Return the valid t=0 state to initialize the simulations.

The returned state should have state.initializing == False.

get_initialized_state()[source]#

Return a valid state initialized from state.

This is used in chained simulations where a specified state of one simulation is used to initialize a state for further use. For example, for expansion.

class IExperiment(**kw)[source]#

Bases: IExperimentMinimal

Full interface for Experiment classes.

States should delegate to the experiment allowing the experiment to control external potentials etc.

Note: All times are expressed in terms of t_unit such that t_ = t/t_unit. We try to consistently use the name t_ for such dimensionless quantities except in class variables which are assumed to be in the specified t_unit.

Simulations and Imaging#

The idea of an “Experiment” is some sort of simulation run defined by a set of parameters (attributes of this class) that is evolved through a set of image_ts_ under a set of “normal” experimental conditions. These states would be what is observed in “in situ imaging”. Typically, however, from these states, one evolves for an additional time t__image without any interactions or traps to allow the clouds to “expand”, after which an “expansion image” is taken, usually resolving better details like vortices and domain walls.

The assumption is that one experiment object is shared between all states belonging to a simulation. For example, this means that experiment.t__image will be the same for each state (along with every other parameter).

image_ts_[source]#
t__image[source]#
max_key_length[source]#
directory_per_key[source]#
dir_name[source]#
items()[source]#

Provides support for Archivable.

copy()[source]#

Return a copy of the experiment.

class IStateDFT(name, bases=(), attrs=None, __doc__=None, __module__=None)[source]#

Bases: pytimeode.interfaces.IStateFlat, pytimeode.interfaces.IStateWithBraket

Extension to the IState interface for orbital-free DFT equations.

The specialization here is to provide a basis capable of applying a Schrodinger-like Hamiltonian to a wavefunction, including a Laplacian. Various extensions can be supported, including using changing basis to account for expansion, rotation, and motion, as well as to multiple components.

This basic interface should be provided by all such classes, and will be relied upon by various utilities.

experiment[source]#

All states should delegate to an Experiment object for control. Experiment objects can be shared, and help provide mechanisms for archiving to disk etc. This is an additional requirement of this project above the requirements of pytimeode.

Type:

IExperiment

t_final[source]#

This is a special parameter used to signify how a state should be run. From t=0 to t==t_final the experiment should be run under “normal” conditions, while for t_final < t the experiment should be run under “imaging” conditions, which might include letting a trapped gas expand, or ramping the coupling constants etc.

In general, the state could have many different stages of evolution, but the need for expansion images is so common that we make a special case here – storing a single “normal” evolution up to different t_final times followed by chains of imaging evolution. In these cases, the values of these parameters (which should be considered volatile) will be manipulated by the Simulation class.

States often also use t_ < 0 to prepare the initial state, which might be prepared (minimized) under different conditions than the run.

Type:

float, None

xyz[source]#
t__scale[source]#
t_final[source]#
experiment[source]#
initializing[source]#
set_psi()[source]#

Set the state from a physical wavefunction.

This should perform any corrections required such as un-applying Bloch twists so that the underlying computational function is periodic, or performing any adjustments to account for changing coordinates.

This is used by the Simulation class to restore data from disk, so this should accept a contiguous numpy array as input.

get_psi()[source]#

Return the physical wavefunction.

This should perform any corrections required such as applying Bloch twists so that the underlying computational function is periodic, or performing any adjustments to account for changing coordinates.

This is used by the Simulation class to archive data to disk, so this should return a contiguous numpy array as input.

apply_V(exp=False)[source]#

Apply V as a potential to the state and return self.

Parameters:
  • V (array-like) – Diagonal potential to be applied by multiplication to the state.

  • exp (bool) – If True then exp(V) will be applied instead.

apply_laplacian(exp=False)[source]#

Apply the laplacian multiplied by factor to the state.

Parameters:
  • factor (array-like) – The result will be multiplied by this factor.

  • exp (bool) – If True then exp(factor*laplacian)(y) will be computed instead.

class IStateMinimizeDFT(name, bases=(), attrs=None, __doc__=None, __module__=None)[source]#

Bases: IStateDFT, pytimeode.interfaces.IStateWithNormalize

Extension of IStateDFT that permits minimization.

These extensions are not needed for direct evolution, but helpful for ground-state preparation.

asnumpy[source]#
xp[source]#
metric[source]#
pre_minimize_hook()[source]#

Called like pre_evolve_hook() but should not set initializing=False.

fill()[source]#

Fill state will constant value.

normalize()[source]#

Normalize the state and return `(s, N)`self.

This is a generalization of the method required by the IStateWithNormalize interface which returns the scale-factor s effecting the normalization through multiplication:

state *= s
Parameters:

s (float or array-like, None) – The scale factor to scale the state by such that y*s is normalized. If None, then the scale factor should be computed and returned along with the final normalization.

Returns:

  • s (float or array-like) – The scale factor such that y*s is normalized.

  • N (float or array-like) – Final normalization. This is used in two cases: 1) if some of the normalization values are zero np.any(N == 0), then if any values are zero, then the minimizers expect the non-zero entries of state*N to be zero and will not optimize over these values. 2) When fixing the constraints, N is used to remove the singular directions from the Hamiltonian.

get_energy()[source]#

Return the energy of the state.

Used by minimizers.

get_Hy()[source]#

Return H*psi = dE/dpsi.T.conj().

This determines the descent direction to minimize the energy. Usually it is implemented simply as 1j*hbar*dy_dt and the default implementation in mixins does this.

Parameters:

subtract_mu (bool) – If True, then the appropriate chemical potentials should be subtracted from the Hamiltonian so that real-time evolution would fix the particle number.