import mmf_setup
mmf_setup.nbinit()
This cell adds /home/docs/checkouts/readthedocs.org/user_builds/gpe/checkouts/latest/src to your path, and contains some definitions for equations and some CSS for styling the notebook. If things look a bit strange, please try the following:
- Choose "Trust Notebook" from the "File" menu.
- Re-execute this cell.
- Reload the notebook.
Travelling Waves#
A traveling wave with velocity \(v\) has the following form:
By appropriately adjusting \(\mu\) we may set \(\omega = 0\), hence we may drop the factor \(e^{-\I\omega t}\) from the wavefunction:
The last equation above now represents a stationary solution in a moving frame with coordinate \(y = x-vt\):
where \(p_v = mv\). Finally, we may recast this in terms of the original GPE by transforming \(\psi(y)\) as follows:
If the original function \(\psi(y+L) = \psi(y)\) was periodic, then \(\tilde{\psi}(y+L) = e^{\I p_v L/\hbar}\tilde{\psi}(y)\). In other words, twisted boundary conditions should be applied with a twist \(\theta = p_vL/\hbar\).
GPE#
Here we consider the problem of finding traveling wave solutions in a BEC. From a numerical perspective, it is highly beneficial if the problem can be stated in terms of a well-defined minimization problem. To start, we consider the available analytic solution for the conventional GPE. These solutions are presented in [El:2016]:
The physical interpretations are:
\(a\): Amplitude
\(v\): Phase velocity
\(u\):
A special limit is when \(m=1\):
First we test these. To match units we set \(\hbar = m = g = 1\).
K(0.9)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[2], line 1
----> 1 K(0.9)
NameError: name 'K' is not defined
from gpe.imports import *
from scipy.special import ellipj, ellipk
import gpe.bec
def sn(u, m):
return ellipj(u, m)[0]
def K(m):
return ellipk(m)
class State(gpe.bec.State):
def __init__(self, Nx=32, rs=[0.1, 0.2, 0.3, 0.4], xi0=0):
r1, r2, r3, r4 = rs = sorted(rs)
k = np.sqrt((r4 - r2) * (r3 - r1))
m = (r2 - r1) * (r4 - r3) / (r4 - r2) / (r3 - r1)
v = sum(rs) / 2.0
L = 2.0 * K(m) / k
gpe.bec.State.__init__(self, Nxyz=(Nx,), Lxyz=(L,), m=1.0, g=1.0, hbar=1.0)
x = self.xyz[0]
self.T = abs(L / v)
t = 0
xi = x - v * t - xi0
a = (r4 - r3) * (r2 - r1)
# a = m**2*k**2
# rho_0 = (r4-r3-r2+r1)**2/4.0
rho_0 = (r4 - r3 + r2 - r1) ** 2 / 4.0
rho = rho_0 + a * sn(k * xi, m) ** 2
self.a_ = self.a = a
self.m_ = m
self.k_ = self.k = k
self.rho_0_ = self.rho_0 = rho_0
k_ = self.m * v / self.hbar
self[...] = np.exp(1j * k_ * x) * np.sqrt(rho)
def get_Vext(self):
return 0.0
s = State(Nx=256, rs=[-2.0, -1.0, 1.0, 2.0])
[I 20:02:16 numexpr.utils] NumExpr defaulting to 2 threads.
---------------------------------------------------------------------------
KeyboardInterrupt Traceback (most recent call last)
Cell In[3], line 1
----> 1 from gpe.imports import *
2 from scipy.special import ellipj, ellipk
3 import gpe.bec
4
File ~/checkouts/readthedocs.org/user_builds/gpe/checkouts/latest/src/gpe/imports.py:28
26 from mmfutils.plot import imcontourf # noqa: E402
27 from gpe.minimize import MinimizeState # noqa: E402
---> 28 from gpe.utils import evolve_to, evolve, evolves # noqa: E402
29 from gpe.plot_utils import MPLGrid # noqa: E402
30 from pytimeode.evolvers import EvolverSplit, EvolverABM # noqa: E402
File ~/checkouts/readthedocs.org/user_builds/gpe/checkouts/latest/src/gpe/utils.py:35
32 from persist.objects import Archivable
33 from persist.archive import Archive
---> 35 from pytimeode.evolvers import EvolverABM
36 from pytimeode.mixins import ArrayStateMixin
37 from pytimeode.interfaces import implementer, IStateForABMEvolvers
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/pytimeode/__init__.py:2
1 from . import interfaces
----> 2 from . import mixins
3 from . import evolvers
5 __all__ = ["interfaces", "mixins", "evolvers"]
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/pytimeode/mixins.py:39
30 from .interfaces import (
31 IState,
32 IStateApply,
(...) 36 implementer,
37 )
38 from . import interfaces
---> 39 from .utils import expr
41 __all__ = [
42 "StateMixin",
43 "StatesMixin",
(...) 47 "ArraysStateWithBraketMixin",
48 ]
51 @implementer(IState)
52 class StateMixin:
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/pytimeode/utils/expr.py:18
15 import numpy as np
17 try:
---> 18 import sympy
19 except ImportError:
20 sympy = None
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/__init__.py:77
70 from .logic import (to_cnf, to_dnf, to_nnf, And, Or, Not, Xor, Nand, Nor,
71 Implies, Equivalent, ITE, POSform, SOPform, simplify_logic, bool_map,
72 true, false, satisfiable)
74 from .assumptions import (AppliedPredicate, Predicate, AssumptionsContext,
75 assuming, Q, ask, register_handler, remove_handler, refine)
---> 77 from .polys import (Poly, PurePoly, poly_from_expr, parallel_poly_from_expr,
78 degree, total_degree, degree_list, LC, LM, LT, pdiv, prem, pquo,
79 pexquo, div, rem, quo, exquo, half_gcdex, gcdex, invert,
80 subresultants, resultant, discriminant, cofactors, gcd_list, gcd,
81 lcm_list, lcm, terms_gcd, trunc, monic, content, primitive, compose,
82 decompose, sturm, gff_list, gff, sqf_norm, sqf_part, sqf_list, sqf,
83 factor_list, factor, intervals, refine_root, count_roots, all_roots,
84 real_roots, nroots, ground_roots, nth_power_roots_poly, cancel,
85 reduced, groebner, is_zero_dimensional, GroebnerBasis, poly,
86 symmetrize, horner, interpolate, rational_interpolate, viete, together,
87 BasePolynomialError, ExactQuotientFailed, PolynomialDivisionFailed,
88 OperationNotSupported, HeuristicGCDFailed, HomomorphismFailed,
89 IsomorphismFailed, ExtraneousFactors, EvaluationFailed,
90 RefinementFailed, CoercionFailed, NotInvertible, NotReversible,
91 NotAlgebraic, DomainError, PolynomialError, UnificationFailed,
92 GeneratorsError, GeneratorsNeeded, ComputationFailed,
93 UnivariatePolynomialError, MultivariatePolynomialError,
94 PolificationFailed, OptionError, FlagError, minpoly,
95 minimal_polynomial, primitive_element, field_isomorphism,
96 to_number_field, isolate, round_two, prime_decomp, prime_valuation,
97 galois_group, itermonomials, Monomial, lex, grlex,
98 grevlex, ilex, igrlex, igrevlex, CRootOf, rootof, RootOf,
99 ComplexRootOf, RootSum, roots, Domain, FiniteField, IntegerRing,
100 RationalField, RealField, ComplexField, PythonFiniteField,
101 GMPYFiniteField, PythonIntegerRing, GMPYIntegerRing, PythonRational,
102 GMPYRationalField, AlgebraicField, PolynomialRing, FractionField,
103 ExpressionDomain, FF_python, FF_gmpy, ZZ_python, ZZ_gmpy, QQ_python,
104 QQ_gmpy, GF, FF, ZZ, QQ, ZZ_I, QQ_I, RR, CC, EX, EXRAW,
105 construct_domain, swinnerton_dyer_poly, cyclotomic_poly,
106 symmetric_poly, random_poly, interpolating_poly, jacobi_poly,
107 chebyshevt_poly, chebyshevu_poly, hermite_poly, hermite_prob_poly,
108 legendre_poly, laguerre_poly, apart, apart_list, assemble_partfrac_list,
109 Options, ring, xring, vring, sring, field, xfield, vfield, sfield)
111 from .series import (Order, O, limit, Limit, gruntz, series, approximants,
112 residue, EmptySequence, SeqPer, SeqFormula, sequence, SeqAdd, SeqMul,
113 fourier_series, fps, difference_delta, limit_seq)
115 from .functions import (factorial, factorial2, rf, ff, binomial,
116 RisingFactorial, FallingFactorial, subfactorial, carmichael,
117 fibonacci, lucas, motzkin, tribonacci, harmonic, bernoulli, bell, euler,
(...) 138 Znm, elliptic_k, elliptic_f, elliptic_e, elliptic_pi, beta, mathieus,
139 mathieuc, mathieusprime, mathieucprime, riemann_xi, betainc, betainc_regularized)
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/polys/__init__.py:124
118 from .orthopolys import (jacobi_poly, chebyshevt_poly, chebyshevu_poly,
119 hermite_poly, hermite_prob_poly, legendre_poly, laguerre_poly)
121 from .appellseqs import (bernoulli_poly, bernoulli_c_poly, genocchi_poly,
122 euler_poly, andre_poly)
--> 124 from .partfrac import apart, apart_list, assemble_partfrac_list
126 from .polyoptions import Options
128 from .rings import ring, xring, vring, sring
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/polys/partfrac.py:13
9 from sympy.polys.polytools import parallel_poly_from_expr
10 from sympy.utilities import numbered_symbols, take, xthreaded, public
---> 13 @xthreaded
14 @public
15 def apart(f, x=None, full=False, **options):
16 """
17 Compute partial fraction decomposition of a rational function.
18
(...) 67 apart_list, assemble_partfrac_list
68 """
69 allowed_flags(options, [])
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/utilities/decorator.py:82, in xthreaded(func)
65 def xthreaded(func):
66 """Apply ``func`` to sub--elements of an object, excluding :class:`~.Add`.
67
68 This decorator is intended to make it uniformly possible to apply a
(...) 80
81 """
---> 82 return threaded_factory(func, False)
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/utilities/decorator.py:19, in threaded_factory(func, use_add)
17 """A factory for ``threaded`` decorators. """
18 from sympy.core import sympify
---> 19 from sympy.matrices import MatrixBase
20 from sympy.utilities.iterables import iterable
22 @wraps(func)
23 def threaded_func(expr, *args, **kwargs):
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/matrices/__init__.py:8
6 from .exceptions import ShapeError, NonSquareMatrixError
7 from .kind import MatrixKind
----> 8 from .dense import (
9 GramSchmidt, casoratian, diag, eye, hessian, jordan_cell,
10 list2numpy, matrix2numpy, matrix_multiply_elementwise, ones,
11 randMatrix, rot_axis1, rot_axis2, rot_axis3, rot_ccw_axis1,
12 rot_ccw_axis2, rot_ccw_axis3, rot_givens,
13 symarray, wronskian, zeros)
14 from .dense import MutableDenseMatrix
15 from .matrixbase import DeferredVector, MatrixBase
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/matrices/dense.py:15
13 from .exceptions import ShapeError
14 from .decompositions import _cholesky, _LDLdecomposition
---> 15 from .matrixbase import MatrixBase
16 from .repmatrix import MutableRepMatrix, RepMatrix
17 from .solvers import _lower_triangular_solve, _upper_triangular_solve
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/matrices/matrixbase.py:40
38 from sympy.core.decorators import call_highest_priority
39 from sympy.core.logic import fuzzy_and, FuzzyBool
---> 40 from sympy.tensor.array import NDimArray
41 from sympy.utilities.iterables import NotIterable
43 from .utilities import _get_intermediate_simp_bool
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/tensor/__init__.py:7
5 from .index_methods import get_contraction_structure, get_indices
6 from .functions import shape
----> 7 from .array import (MutableDenseNDimArray, ImmutableDenseNDimArray,
8 MutableSparseNDimArray, ImmutableSparseNDimArray, NDimArray, tensorproduct,
9 tensorcontraction, tensordiagonal, derive_by_array, permutedims, Array,
10 DenseNDimArray, SparseNDimArray,)
12 __all__ = [
13 'IndexedBase', 'Idx', 'Indexed',
14
(...) 22 'Array', 'DenseNDimArray', 'SparseNDimArray',
23 ]
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/tensor/array/__init__.py:251
1 r"""
2 N-dim array module for SymPy.
3
(...) 248
249 """
--> 251 from .dense_ndim_array import MutableDenseNDimArray, ImmutableDenseNDimArray, DenseNDimArray
252 from .sparse_ndim_array import MutableSparseNDimArray, ImmutableSparseNDimArray, SparseNDimArray
253 from .ndim_array import NDimArray, ArrayKind
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/tensor/array/dense_ndim_array.py:8
6 from sympy.core.singleton import S
7 from sympy.core.sympify import _sympify
----> 8 from sympy.tensor.array.mutable_ndim_array import MutableNDimArray
9 from sympy.tensor.array.ndim_array import NDimArray, ImmutableNDimArray, ArrayKind
10 from sympy.utilities.iterables import flatten
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/tensor/array/mutable_ndim_array.py:1
----> 1 from sympy.tensor.array.ndim_array import NDimArray
4 class MutableNDimArray(NDimArray):
6 def as_immutable(self):
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/tensor/array/ndim_array.py:591
586 raise ValueError('Dimension of index greater than rank of array')
588 return index
--> 591 class ImmutableNDimArray(NDimArray, Basic):
592 _op_priority = 11.0
594 def __hash__(self):
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/core/basic.py:218, in Basic.__init_subclass__(cls)
212 def __init_subclass__(cls):
213 # Initialize the default_assumptions FactKB and also any assumptions
214 # property methods. This method will only be called for subclasses of
215 # Basic but not for Basic itself so we call
216 # _prepare_class_assumptions(Basic) below the class definition.
217 super().__init_subclass__()
--> 218 _prepare_class_assumptions(cls)
File ~/checkouts/readthedocs.org/user_builds/gpe/conda/latest/lib/python3.14/site-packages/sympy/core/assumptions.py:624, in _prepare_class_assumptions(cls)
622 for k in _assume_defined:
623 attrname = as_property(k)
--> 624 v = cls.__dict__.get(attrname, '')
625 if isinstance(v, (bool, int, type(None))):
626 if v is not None:
KeyboardInterrupt:
n = s.get_density()
x = s.xyz[0]
x_ = x[1:-1]
psi_ = s[1:-1]
ddpsi_ = np.diff(np.diff(s[...])) / np.diff(x)[1:] ** 2
plt.plot(x_, ddpsi_ / psi_ / 2 + abs(psi_) ** 2)
Check the soliton limit (2.122)
s = State(Nx=128, rs=[-4.000001, 1.0, 1.000001, 2.0])
x = s.xyz[0]
s.plot()
rho_min = abs(s[...]).min() ** 2
rho_max = abs(s[...]).max() ** 2
plt.axhspan(rho_min, rho_min + s.a, fc="y", alpha=0.5)
# plt.plot(x, rho_max-s.a/np.cosh(np.sqrt(s.a)*x)**2, '+:')
rho_0 = s.rho_0
s[...] = np.sqrt(rho_0) * np.tanh(np.sqrt(rho_0) * x)
s.plot()
s.cooling_phase = 1
e = EvolverABM(s, dt=0.2 * s.t_scale)
s = State(Nx=256, rs=[-2.0, -1.0, 1.0, 2.0])
with NoInterrupt(ignore=True) as interrupted:
while e.t < e.y.T and not interrupted:
e.evolve(1000)
plt.clf()
e.y.plot()
display(plt.gcf())
clear_output(wait=True)
%debug
Solitons#
The GPE admits grey solitons with infinite period. These solitons arise from the previous solutions in the limit where \(m\rightarrow 1\) so that \(\sn\rightarrow\tanh\) and \(\cn\rightarrow\dn\rightarrow \sech\).
The soliton solution is:
This can be expressed as
or, in the same units \(m=\hbar = g = 1\) as El and Hoefer:
To compare with (2.117):
we have \(m=1\), \(\sn = \tanh\) and
Everything here is reasonable except the definition of the phase velocity \(V\) which differs from the soliton velocity \(v\).
The background density is
To compare with (2.122):
, the stationary solution must have \(\bar{\rho} = a_s\) or:
If \(r_1 = -r_4-2r_2\), then
Issues#
I was having some issues finding solutions so I considered stationary solutions:
Symbolically solving for solutions to the GPE (in Maple) gives the following solutions:
(assuming \(a,k\neq 0\) and real \(k\)) gives:
restart;
X_:=JacobiSN(k*x,sqrt(m2));
psi:=sqrt(rho[0] + a*X_^2);
Rho:=psi^2:
res:=collect(numer(simplify(-diff(psi, x, x)/2/psi + Rho - mu)), X_):
mu:=expand(solve(coeff(res, X_, 0), mu));
m2:=solve(coeff(res, X_^6), m2);
solve([coeffs(res, X_)], [a,k^2]);
The dark soliton solution has \(m=1\), \(a=k^2\)
s.m
s = State(rs=[-4.1, 1.0, 1.1, 2.0])
x = s.xyz[0]
m = s.m_
a = s.a_
k = s.k_
rho_0 = s.rho_0_
print (m, a, m ** 2 * k ** 2, rho_0, k)
k = np.sqrt(rho_0)
plt.plot(x, 1 + sn(k * x, m) ** 2)
# s[...] = np.sqrt(rho_0*(1-sn(x,m)))
To do this, we first consider boosting to a moving frame with velocity \(v\) so that in this frame, the traveling wave solution is stationary and periodic. We second Here we are looking for solutions that satisfy:
Minimization#
Here we consider the following hypothesis:
The traveling waves can be found as minimum energy solutions in a box of period \(L\) with twisted boundary conditions holding both the total particle number fixed and the value of the wavefunction at one point.
We start with the soliton solution:
At the core, the density is:
from gpe.imports import *
from scipy.special import ellipj, ellipk
import gpe.bec, gpe.minimize
reload(gpe.bec)
class State(gpe.bec.StateTwist):
def __init__(
self,
Nx=32,
L=10.0,
mu=1.0,
psi_0=1.0,
ind=None,
v=0.0,
twist=None,
m=1.0,
hbar=1.0,
g=1.0,
):
if ind is None:
ind = Nx // 2
self.ind = ind
self.psi_0 = psi_0
self.p_v = p_v = m * v
if twist is None:
twist = np.pi + p_v * L / hbar
gpe.bec.StateTwist.__init__(
self, Nxyz=(Nx,), Lxyz=(L,), m=m, hbar=hbar, g=g, mu=mu, twist=(twist,)
)
self[self.ind] = psi_0
def exact_psi(self):
"""Return the analytic soliton"""
v = abs(self.psi_0)
u = np.sqrt(self.mu - v ** 2)
return 1j * v + u * np.tanh(u * self.xyz[0])
def get_Vext(self):
return -(self.mu + self.p_v ** 2 / 2.0 / self.m)
def _compute_dy_dt(self, dy, subtract_mu=False):
dy = gpe.bec.StateTwist.compute_dy_dt(self, dy=dy, subtract_mu=subtract_mu)
# dy[self.ind] = 0
return dy
class MinimizeState(gpe.minimize.MinimizeState):
def __init__(self, state, **kw):
self.psi_0 = state.psi_0
self.ind = state.Nxyz[0] // 2
gpe.minimize.MinimizeState.__init__(self, state, **kw)
def pack(self, psi):
psi[self.ind] = self.psi_0
fact = 1 if self.real else 2
x = gpe.minimize.MinimizeState.pack(self, psi)
return np.concatenate([x[: self.ind * fact], x[(self.ind + 1) * fact :]])
def unpack(self, x, state=None):
fact = 1 if self.real else 2
x = np.concatenate([x[: self.ind * fact], [0, 0], x[self.ind * fact :]])
state = gpe.minimize.MinimizeState.unpack(self, x, state=state)
assert np.allclose(state[self.ind], 0)
state[self.ind] = self.psi_0
# plt.clf()
# state.plot()
# plt.twinx()
# plt.plot(state.xyz[0], np.angle(state[...]/state.twist_phase), 'r--')
# display(plt.gcf())
# clear_output(wait=True)
return state
s = State(Nx=128 * 8, L=120.0, mu=1.0, psi_0=0.5, v=v)
psi_s = s.exact_psi()
v = (
(np.angle(psi_s[-1]) - np.angle(psi_s[0]) + np.pi)
* s.hbar
/ s.m
/ (s.Lxyz[0] - s.Lxyz[0] / s.Nxyz[0])
)
s = State(Nx=128 * 8, L=120.0, mu=1.0, psi_0=0.5, v=v)
s[...] = s.exact_psi()
print (v)
plt.plot(s[...] / s.twist_phase)
v
s = s1
s.cooling_phase = 1.0
e = EvolverABM(s, dt=0.5 * s.t_scale)
with NoInterrupt(ignore=True) as interrupted:
while not interrupted:
e.evolve(100)
plt.clf()
e.y.plot()
display(plt.gcf())
clear_output(wait=True)
s = State(Nx=128 * 4, L=20.0, mu=1.0, psi_0=0.1, v=0.1)
s[...] = 1.0
m = MinimizeState(s, fix_N=False)
s1 = m.minimize(use_scipy=True)
plt.plot(s1.xyz[0], s1.get_density() - abs(s1.exact_psi()) ** 2)
# s1.plot()
abs(s1.get_density() - abs(s1.exact_psi()) ** 2).max()
plt.plot(s1.xyz[0], np.angle(s1[...]))
plt.plot(s1.xyz[0], np.angle(s1.exact_psi()))
vs = np.linspace(0, 0.4, 10)
errs = []
for v in vs:
s = State(Nx=128 * 4, L=20.0, mu=1.0, psi_0=0.2, v=v)
m = MinimizeState(s, fix_N=False)
s1 = m.minimize(use_scipy=True)
errs.append(abs(s1.get_density() - abs(s1.exact_psi()) ** 2).max())
plt.plot(vs, errs, "-+")
s = gpe.bec.State(Nxyz=(64,), Lxyz=(10.0,))
s[...] = 1.0
m = gpe.minimize.MinimizeState(
fix_N=False,
)
s1 = m.minimize(use_scipy=True)
s1.plot()
Es = []
m = MinimizeState(s)
m.check()
s1 = m.minimize(use_scipy=True, fix_N=False, callback=callback)
# plt.plot(s1.xyz[0], np.log10(abs(abs(s1[...])**2-s.mu)))
s1.plot()
plt.plot(s1.xyz[0], abs(s1.exact_psi()) ** 2)
plt.plot(Es)
s1.get_density().max(), 1 + (s1.k_B[0] ** 2) / 2
-s1.mu, s1.get_Vext()
Es = []
twists = np.linspace(0, 2 * np.pi, 10)
for twist in twists:
s = State(Nx=128, L=50.0, mu=1.0, psi_0=0.05, twist=twist)
m = MinimizeState(s)
s1 = m.minimize(use_scipy=True, fix_N=False)
Es.append(s1.get_energy())
print twist, Es[-1]
s1.plot()
plt.plot(twists, Es)
m = MinimizeState(s)
s1 = m.minimize(use_scipy=True)
plt.clf()
s1.plot()
s1.get_energy()