Source code for gpe.Examples.hydro_1d
"""Simple hydrodynamic experiments."""
import numpy as np
# import matplotlib.pyplot as plt
from gpe.utils import ExperimentBase
from gpe.hydro_1d import StateFV_BEC, u
[docs]
class Experiment(ExperimentBase):
"""Harmonic Sloshing experiment.
Here we start with a harmonically trapped gas, we then display the trap center so
that the gas sloshes back and forth. This should result in purely sinusoidal
center-of-mass (CoM) motion. Next, we add a small bump. In the presence of
viscosity, this should dissipate energy, causing CoM amplitude to decrease.
We use this decrease as a way of measuring the effective viscosity in a superfluid
which has strictly no energy loss.
Experiment for Finite-Volume SWE.
M = amu, L = microns, T = 1/Hz.
"""
######################################################################
# Attributes required by IExperiment
[docs]
t_unit = u.ms # All times specified in this unit
[docs]
t__image = 2 # Expansion time for imaging
# End of attributes required by IExperiment
######################################################################
[docs]
species = (1, -1) # Spin states of the species
[docs]
g = 1 # Coupling constants: determined from states
[docs]
omega = (
2
* np.pi
* np.asarray(
[
1000,
]
)
* u.Hz
)
# Bump parameters
[docs]
x0 = 0 * u.micron # Initial location of bump in microns
[docs]
u_piston = 0 * u.mm * u.Hz
[docs]
V0p = 0.5 # MMF: Units?
[docs]
x0_t = 3 * u.micron # Trap shift
[docs]
_Vext = 0 # Pre-caching
# Viscosity (in units of "micron**2 * Hz")
[docs]
def init(self):
key = (self.species, self.species)
self.scattering_length = u.scattering_lengths[key]
if self.m is None:
self.m = u.masses[self.species]
if self.g is None:
self.g = 4 * np.pi * u.hbar**2 / self.m * self.scattering_length
# self.nu = self.nu_ * u.micron * u.Hz
self.nu = self.nu_ * u.hbar / u.micron / self.m
[docs]
def get_state(self, initialize=False):
args = dict(
experiment=self,
Nx=self.Nx,
Lx=self.Lx,
m=self.m,
x_TF=self.x_TF,
)
state = self.State(**args)
return state
[docs]
def get_initial_state(self, **kw):
state = self.get_state(**kw, initialize=True)
return state
[docs]
def get_nu(self, state):
return self.nu
[docs]
def get_Vtrap(self, state, d=0):
x = state.x
t = state.t
w = self.omega[0]
x_trap = 0
if t <= 0:
# Trap is initially displaced for finding the ground state.
x_trap = self.x0_t
if d == 0:
_Vext = 0.5 * state.m * (w * (x - x_trap)) ** 2
elif d == 1:
_Vext = state.m * (x - x_trap) * w**2
else:
raise NotImplementedError
return _Vext
[docs]
def get_Vext(self, state, d=0):
x = state.x
t = state.t
_Vext = self.get_Vtrap(state=state, d=d)
x_adj = self.x0 - (self.u_piston * t)
x_ = (x - x_adj) / self.p_sigma
if d == 0:
_Vext += self.V0p * np.exp(-(x_**2) / 2)
elif d == 1:
_Vext += -self.V0p * np.exp(-(x_**2) / 2) * x_ / self.p_sigma
else:
raise NotImplementedError
return _Vext
######################################################################
# State-dependent properties.
# These should probably not be here because they are algorithm dependent. They do
# not play a role in defining the experiment.
[docs]
def get_f(self, state, n=None, d=0):
"""Return fluxes."""
if n is None:
n = state.get_density()
a = (self.g * state.m) / (4 * np.pi * self.hbar**2)
if d == 0:
return 0.5 * self.g * n**2
elif d == 1:
return self.g * n