In [323]:
from itertools import combinations, combinations_with_replacement

In [326]:
import numpy as np

Lattice Boltzmann Method

Using Sage Math


In [7]:
A_R__1 = AffineSpace(1,RR,names='t')

In [8]:
A_R__2.<x,y> = AffineSpace(2,RR)

In [9]:
A_R__3.<x,y,z> = AffineSpace(3,RR)

In [14]:
[_ for _ in A_R__3.points_of_bounded_height(3.0)]


---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
<ipython-input-14-f92c0a8f1fc7> in <module>()
----> 1 [_ for _ in A_R__3.points_of_bounded_height(RealNumber('3.0'))]

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/schemes/affine/affine_space.pyc in points_of_bounded_height(self, bound)
    788             ftype = True
    789         else:
--> 790             raise NotImplementedError("self must be affine space over a number field.")
    791 
    792         bound = bound**(1/self.base_ring().absolute_degree()) # convert to relative height

NotImplementedError: self must be affine space over a number field.

In [16]:
A_R__1.<t> = AffineSpace(1,RealField())

In [17]:
A_R__2.<x,y> = AffineSpace(2,RealField())

In [18]:
A_R__3.<x,y,z> = AffineSpace(3,RealField())

In [21]:
A_R__1.coordinate_ring()


Out[21]:
Multivariate Polynomial Ring in t over Real Field with 53 bits of precision

In [22]:
A_R__1.coordinate_ring().gens()


Out[22]:
(t,)

In [23]:
A_R__2.coordinate_ring()


Out[23]:
Multivariate Polynomial Ring in x, y over Real Field with 53 bits of precision

In [24]:
A_R__2.coordinate_ring().gens()


Out[24]:
(x, y)

In [25]:
A_R__3.coordinate_ring()


Out[25]:
Multivariate Polynomial Ring in x, y, z over Real Field with 53 bits of precision

In [26]:
A_R__3.coordinate_ring().gens()


Out[26]:
(x, y, z)

In [29]:
A_R__1.coordinate_ring().monomial()


Out[29]:
1.00000000000000

In [30]:
A_R__2.coordinate_ring().monomial()


Out[30]:
1.00000000000000

In [31]:
A_R__3.coordinate_ring().monomial()


Out[31]:
1.00000000000000

In [35]:



---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-35-907ec7d01389> in <module>()
----> 1 A_R__1.rational_points(FiniteField(Integer(5)))

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/schemes/affine/affine_space.pyc in rational_points(self, F)
    246         elif not is_FiniteField(F):
    247             raise TypeError("second argument (= %s) must be a finite field"%F)
--> 248         return [ P for P in self.base_extend(F) ]
    249 
    250     def __cmp__(self, right):

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/schemes/generic/ambient_space.pyc in base_extend(self, R)
    260                 raise ValueError(
    261                     "no natural map from the base ring (=%s) to R (=%s)!"
--> 262                     % (self.base_ring(), R))
    263             return self.change_ring(R)
    264         else:

ValueError: no natural map from the base ring (=Real Field with 53 bits of precision) to R (=Finite Field of size 5)!

Lattices, that are "sufficiently" Galilean invariant, through non-perturbative algebraic theory

cf. http://staff.polito.it/pietro.asinari/publications/preprint_Asinari_PA_2010a.pdf, I. Karlin and P. Asinari, Factorization symmetry in the lattice Boltzmann method. Physica A 389, 1530 (2010). The prepaper that this seemd to be based upon and had some more calculation details is

Maxwell Lattices in 1-dim.

Maxwell's (M) moment relations


In [47]:
u = var("u",domain="real")
#T_0 = var("T_0",domain="real")
T_0 =var("T_0",domain="positive")

In [268]:
v = var("v",domain="real")

In [40]:
phi_v = sqrt( pi/(2*T_0))*exp( - (v-u)**2/(2*T_0))

In [48]:
integrate( phi_v * 1, v)


Out[48]:
-1/2*sqrt(2)*sqrt(1/2)*sqrt(pi)*sqrt(pi/T_0)*erf(-sqrt(1/2)*x/sqrt(T_0) + sqrt(1/2)*u/(T_0*1/sqrt(T_0)))/1/sqrt(T_0)

In [54]:
integrate( phi_v * 1, (v,-oo,oo)).expand().simplify()


Out[54]:
pi

In [57]:
print( integrate( phi_v * v**1, (v,-oo,oo)).expand().simplify() )
print( integrate( phi_v * v**2, (v,-oo,oo)).expand().simplify() )
print( integrate( phi_v * v**3, (v,-oo,oo)).expand().simplify() )
print( integrate( phi_v * v**4, (v,-oo,oo)).expand().simplify() )
print( integrate( phi_v * v**5, (v,-oo,oo)).expand().simplify() )
print( integrate( phi_v * v**6, (v,-oo,oo)).expand().simplify() )


pi*u
pi*u^2 + pi*T_0
pi*u^3 + 3*pi*T_0*u
pi*u^4 + 6*pi*T_0*u^2 + 3*pi*T_0^2
pi*u^5 + 10*pi*T_0*u^3 + 15*pi*T_0^2*u
pi*u^6 + 15*pi*T_0*u^4 + 45*pi*T_0^2*u^2 + 15*pi*T_0^3

Appendix A: How to find Closure Relation and verify reference temperature for a given velocity set, cf. arxiv.org:0911.5529.pdf


In [71]:
Q=5
q=Q//2

In [271]:
a_lst = var( ",".join(map(str,["a"+str(k+1) for k in range(q)])) )
v_i   = var("v_i",domain="integer")
#v_lst = var( ",".join(map(str,["v"+str(k+1) for k in range(q)])) )
# variables named or labeled from 1,2,...q, Python counts from 0,1..q-1

In [76]:
k=var('k')
sum( a_lst[int(k)]*v_lst[k], k,0,q-1)


---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-76-8330476415c9> in <module>()
      1 k=var('k')
----> 2 sum( a_lst[int(k)]*v_lst[k], k,Integer(0),q-Integer(1))

/home/topolo/Public/sage/src/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.__int__ (/home/topolo/Public/sage/src/build/cythonized/sage/symbolic/expression.cpp:8528)()
   1100             rif_self = sage.rings.all.RIF(self)
   1101         except TypeError:
-> 1102             raise ValueError("cannot convert %s to int" % self)
   1103         if rif_self > 0 or (rif_self.contains_zero() and self > 0):
   1104             result = floor(self)

ValueError: cannot convert k to int

In [95]:
closurerel = sum( [a_lst[k]*v_i**(2*k+1) for k in range(q)] ) == v_i**Q # closure relation RHS
closurerelRHS = sum( [a_lst[k]*v_i**(2*k+1) for k in range(q)] ) # closure relation RHS

In [100]:
v_ipos = [1,3]
[closurerel.subs(v_i== v_ipos[k]) for k in range(len(v_ipos))]
#[closurerelRHS.subs((v_i, v_ipos[k])) for k in range(len(v_ipos))]


Out[100]:
[a1 + a2 == 1, 3*a1 + 27*a2 == 243]

In [101]:
solve( [closurerel.subs(v_i== v_ipos[k]) for k in range(len(v_ipos))], a_lst )


Out[101]:
[[a1 == -9, a2 == 10]]

In [105]:
solve( [closurerel.subs(v_i== v_ipos[k]) for k in range(len(v_ipos))], a_lst )[0]


Out[105]:
[a1 == -9, a2 == 10]

In [106]:
closurerel.subs( solve( [closurerel.subs(v_i== v_ipos[k]) for k in range(len(v_ipos))], a_lst )[0] )


Out[106]:
10*v_i^3 - 9*v_i == v_i^5

In [117]:
asolved=[aeqn.rhs() for aeqn in solve( [closurerel.subs(v_i== v_ipos[k]) for k in range(len(v_ipos))], a_lst )[0]]
print(asolved)


[-4, 5]

Try v_ipos=[1,2]


In [107]:
v_ipos = [1,2]
solve( [closurerel.subs(v_i== v_ipos[k]) for k in range(len(v_ipos))], a_lst )


Out[107]:
[[a1 == -4, a2 == 5]]

In [108]:
1.multifactorial(2)


Out[108]:
1

In [109]:
3.multifactorial(2)


Out[109]:
3

In [110]:
5.multifactorial(2)


Out[110]:
15

In [111]:
7.multifactorial(2)


Out[111]:
105

In [112]:
T_0=var('T_0',domain="positive")

In [122]:
sum( [asolved[k]*ZZ(2*k+1).multifactorial(2)*T_0**(k) for k in range(q)] )


Out[122]:
15*T_0 - 4

In [123]:
ZZ(Q).multifactorial(2)*T_0**((Q-1)/2)-sum( [asolved[k]*ZZ(2*k+1).multifactorial(2)*T_0**(k) for k in range(q)] )


Out[123]:
15*T_0^2 - 15*T_0 + 4

In [124]:
solve( ZZ(Q).multifactorial(2)*T_0**((Q-1)/2)-sum( [asolved[k]*ZZ(2*k+1).multifactorial(2)*T_0**(k) for k in range(q)] ) , T_0)


Out[124]:
[]

In [125]:
solve( ZZ(Q).multifactorial(2)*T_0**((Q-1)/2)-sum( [asolved[k]*ZZ(2*k+1).multifactorial(2)*T_0**(k) for k in range(q)] )==0 , T_0)


Out[125]:
[]

For


In [126]:
v_ipos = [1,3]
asolved=[aeqn.rhs() for aeqn in solve( [closurerel.subs(v_i== v_ipos[k]) for k in range(len(v_ipos))], a_lst )[0]]

In [127]:
solve( ZZ(Q).multifactorial(2)*T_0**((Q-1)/2)-sum( [asolved[k]*ZZ(2*k+1).multifactorial(2)*T_0**(k) for k in range(q)] )==0 , T_0)


Out[127]:
[T_0 == -1/5*sqrt(10) + 1, T_0 == 1/5*sqrt(10) + 1]

In [131]:
solve( ZZ(Q).multifactorial(2)*T_0**((Q-1)/2)-sum( [asolved[k]*ZZ(2*k+1).multifactorial(2)*T_0**(k) for k in range(q)] )==0 , T_0)[0].rhs().N >0


Out[131]:
True

In [132]:
solve( ZZ(Q).multifactorial(2)*T_0**((Q-1)/2)-sum( [asolved[k]*ZZ(2*k+1).multifactorial(2)*T_0**(k) for k in range(q)] )==0 , T_0)[1].rhs().N >0


Out[132]:
True

In [234]:
def make_closure_rel(Q, v_ipos=None,v_i=None):
    """ make_closure_rel - make closure relation
    returns, as Python tuple, the closure relation and reference temperature T_0, as (closure relation, T_0)

    INPUT/ARGUMENT
    ==============
    @type Q : positive integer
    @param Q : Q is the total number of discrete velocities
    """
    q=Q//2
    a_lst = var( ",".join(map(str,["a"+str(k+1) for k in range(q)])) )
    if v_i is None:
        v_i   = var("v_i",domain="integer")

    if v_ipos is None:
        v_ipos = range(1,q+1)

    closurerel_gen = sum( [a_lst[k]*v_i**(2*k+1) for k in range(q)] ) == v_i**Q # closure relation, in general form     
        
    sysofpolys = [closurerel_gen.subs(v_i== v_ipos[k]) for k in range(len(v_ipos))] # q different nonzero values for velocities pluuged in
    
    solved_as = solve( sysofpolys, a_lst ) # solved for a_{Q-2k},k=1...q, for given different velocities v_i
    
    solved_as = solved_as[0]
    
    closurerel = closurerel_gen.subs(solved_as)
    
#    try:
#        check_closurerel_unique = closurerel.rhs()-closurerel.lhs() # check the closure relation to see if it's nontrivial
#        if check_closurerel_unique.N() == 0: 
#            print "check_closurerel_unique failed, equals 0, i.e. no unique solution for v_i's; lattice invalid"
#            return closurerel
#    except TypeError as err:
#        print err
#        print "so far closure relation is unique, proceed"
        
    solved_as = [aeqn.rhs() for aeqn in solved_as] # [a_1,a_2,...a_q] as Python list
         
    T_0=var('T_0',domain="positive")
    
    matchingcond = -sum( [solved_as[k]*ZZ(2*k+1).multifactorial(2)*T_0**(k) for k in range(q)]) # \sum_{j=1}^q a_{Q-2k} b_{Q-2k} T_0^{(Q-2k-1)/2}
     
    matchingcond += ZZ(Q).multifactorial(2)*T_0**((Q-1)/2)  # b_QT_0^{(Q-1)/2}
    
#    try:
#        check_matchingcond = matchingcond.N()
#        if check_matchingcond == 0:
#            print "check_matchingcond failed, i.e. algebraic eqn. for ref. T_0 is 0"
#            return closurerel
#    except TypeError as err:
#        print err
#        print "We're actually safe, so far lattice exists; proceed"
    
    T_0roots = solve( matchingcond ==0, T_0) # solve for the roots of T_0

    T_0roots_passed = [] # T_0 roots s.t. T_0 >= 0
    for Tsoln in T_0roots:
        if (Tsoln.rhs().N >= 0):
            T_0roots_passed.append( Tsoln.rhs())
        
    return closurerel, T_0roots_passed

In [238]:
def make_closure_rel(Q, v_ipos=None,v_i=None):
    """ make_closure_rel - make closure relation
    returns, as Python tuple, the closure relation and reference temperature T_0, as (closure relation, T_0)

    INPUT/ARGUMENT
    ==============
    @type Q : positive integer
    @param Q : Q is the total number of discrete velocities
    """
    q=Q//2
    a_lst = var( ",".join(map(str,["a"+str(k+1) for k in range(q)])) )
    if v_i is None:
        v_i   = var("v_i",domain="integer")

    if v_ipos is None:
        v_ipos = range(1,q+1)

    closurerel_gen = sum( [a_lst[k]*v_i**(2*k+1) for k in range(q)] ) == v_i**Q # closure relation, in general form     
        
    sysofpolys = [closurerel_gen.subs(v_i== v_ipos[k]) for k in range(len(v_ipos))] # q different nonzero values for velocities pluuged in
    
    solved_as = solve( sysofpolys, a_lst ) # solved for a_{Q-2k},k=1...q, for given different velocities v_i
    
    solved_as = solved_as[0]
    
    closurerel = closurerel_gen.subs(solved_as)
    
        
    solved_as = [aeqn.rhs() for aeqn in solved_as] # [a_1,a_2,...a_q] as Python list
         
    T_0=var('T_0',domain="positive")
    
    matchingcond = -sum( [solved_as[k]*ZZ(2*k+1).multifactorial(2)*T_0**(k) for k in range(q)]) # \sum_{j=1}^q a_{Q-2k} b_{Q-2k} T_0^{(Q-2k-1)/2}
     
    matchingcond += ZZ(Q).multifactorial(2)*T_0**((Q-1)/2)  # b_QT_0^{(Q-1)/2}
    
    T_0roots = solve( matchingcond ==0, T_0) # solve for the roots of T_0

    T_0roots_passed = [] # T_0 roots s.t. T_0 >= 0
    for Tsoln in T_0roots:
        if (Tsoln.rhs().N >= 0):
            T_0roots_passed.append( Tsoln.rhs())
        
    return closurerel, T_0roots_passed

Reproducing Table I, 1-dim. Maxwell lattices with odd number of inter-valued velocities $Q$, of arxiv.org 0911.5529.pdf, pp. 3


In [229]:
make_closure_rel(5)


cannot evaluate symbolic expression numerically
so far closure relation is unique, proceed
cannot evaluate symbolic expression numerically
We're actually safe, so far lattice exists; proceed
Out[229]:
(5*v_i^3 - 4*v_i == v_i^5, [])

In [230]:
make_closure_rel(5,[1,3])


cannot evaluate symbolic expression numerically
so far closure relation is unique, proceed
cannot evaluate symbolic expression numerically
We're actually safe, so far lattice exists; proceed
Out[230]:
(10*v_i^3 - 9*v_i == v_i^5, [-1/5*sqrt(10) + 1, 1/5*sqrt(10) + 1])

In [231]:
make_closure_rel(7)


cannot evaluate symbolic expression numerically
so far closure relation is unique, proceed
cannot evaluate symbolic expression numerically
We're actually safe, so far lattice exists; proceed
Out[231]:
(14*v_i^5 - 49*v_i^3 + 36*v_i == v_i^7,
 [(1/1575*sqrt(15)*sqrt(2) + 1/945)^(1/3) - 1/45/(1/1575*sqrt(15)*sqrt(2) + 1/945)^(1/3) + 2/3])

In [214]:
q=9//2
a_lst = var( ",".join(map(str,["a"+str(k+1) for k in range(q)])) )
v_i   = var("v_i",domain="integer")
v_ipos = range(1,q+1)
closurerel_gen = sum( [a_lst[k]*v_i**(2*k+1) for k in range(q)] ) == v_i**Q
sysofpolys = [closurerel_gen.subs(v_i== v_ipos[k]) for k in range(len(v_ipos))]
solved_as_init = solve( sysofpolys, a_lst ) 
solved_as = solved_as_init[0]
closurerel = closurerel_gen.subs(solved_as)
solved_as = [aeqn.rhs() for aeqn in solved_as]
T_0=var('T_0',domain="positive")
matchingcond = -sum( [solved_as[k]*ZZ(2*k+1).multifactorial(2)*T_0**(k) for k in range(q)])
matchingcond += ZZ(Q).multifactorial(2)*T_0**((Q-1)/2)
matchingcond


Out[214]:
0

In [212]:
matchingcond.N() == 0


Out[212]:
True

In [227]:
( closurerel.lhs() - closurerel.rhs() ).N() == 0


Out[227]:
True

In [232]:
make_closure_rel(9)


cannot evaluate symbolic expression numerically
so far closure relation is unique, proceed
cannot evaluate symbolic expression numerically
We're actually safe, so far lattice exists; proceed
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-232-18b703e58983> in <module>()
----> 1 make_closure_rel(Integer(9))

<ipython-input-228-34b90b5653af> in make_closure_rel(Q, v_ipos, v_i)
     52         print "We're actually safe, so far lattice exists; proceed"
     53 
---> 54     T_0roots = solve( matchingcond ==Integer(0), T_0) # solve for the roots of T_0
     55 
     56     T_0roots_passed = [] # T_0 roots s.t. T_0 >= 0

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/symbolic/relation.pyc in solve(f, *args, **kwds)
    798     from sage.symbolic.expression import is_Expression
    799     if is_Expression(f): # f is a single expression
--> 800         ans = f.solve(*args,**kwds)
    801         return ans
    802 

/home/topolo/Public/sage/src/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.solve (/home/topolo/Public/sage/src/build/cythonized/sage/symbolic/expression.cpp:55109)()
  10662             for ix, soln in reversed(list(enumerate(X))):
  10663                 if soln.lhs().is_symbol():
> 10664                     if any([a.contradicts(soln) for a in to_check]):
  10665                         del X[ix]
  10666                         if multiplicities:

/home/topolo/Public/sage/src/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.contradicts (/home/topolo/Public/sage/src/build/cythonized/sage/symbolic/expression.cpp:19942)()
   2793             True
   2794         """
-> 2795         return bool(self.negation().subs(soln))
   2796 
   2797     def is_unit(self):

/home/topolo/Public/sage/src/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.__nonzero__ (/home/topolo/Public/sage/src/build/cythonized/sage/symbolic/expression.cpp:16820)()
   2552                 if pynac_result == relational_notimplemented and self.operator()==operator.ne:
   2553                     return not (self.lhs()-self.rhs()).is_trivial_zero()
-> 2554                 res = self.test_relation()
   2555                 if res is True:
   2556                     return True

/home/topolo/Public/sage/src/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.test_relation (/home/topolo/Public/sage/src/build/cythonized/sage/symbolic/expression.cpp:17446)()
   2661         if domain is None:
   2662             is_interval = True
-> 2663             if self.lhs().is_algebraic() and self.rhs().is_algebraic():
   2664                 if op == equal or op == not_equal:
   2665                     domain = QQbar

/home/topolo/Public/sage/src/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.is_algebraic (/home/topolo/Public/sage/src/build/cythonized/sage/symbolic/expression.cpp:13856)()
   1899         """
   1900         try:
-> 1901             ex = sage.rings.all.QQbar(self)
   1902         except (TypeError, ValueError, NotImplementedError):
   1903             return False

/home/topolo/Public/sage/src/sage/structure/parent.pyx in sage.structure.parent.Parent.__call__ (/home/topolo/Public/sage/src/build/cythonized/sage/structure/parent.c:9869)()
   1107         if mor is not None:
   1108             if no_extra_args:
-> 1109                 return mor._call_(x)
   1110             else:
   1111                 return mor._call_with_args(x, args, kwds)

/home/topolo/Public/sage/src/sage/structure/coerce_maps.pyx in sage.structure.coerce_maps.DefaultConvertMap_unique._call_ (/home/topolo/Public/sage/src/build/cythonized/sage/structure/coerce_maps.c:4525)()
    102         cdef Parent C = self._codomain
    103         try:
--> 104             return C._element_constructor(x)
    105         except Exception:
    106             if print_warnings:

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in _element_constructor_(self, x)
   1121             return AlgebraicNumber(x._descr)
   1122         elif hasattr(x, '_algebraic_'):
-> 1123             return x._algebraic_(QQbar)
   1124         return AlgebraicNumber(x)
   1125 

/home/topolo/Public/sage/src/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression._algebraic_ (/home/topolo/Public/sage/src/build/cythonized/sage/symbolic/expression.cpp:10805)()
   1447         """
   1448         from sage.symbolic.expression_conversions import algebraic
-> 1449         return algebraic(self, field)
   1450 
   1451     def __hash__(self):

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in algebraic(ex, field)
    950         0
    951     """
--> 952     return AlgebraicConverter(field)(ex)
    953 
    954 ##############

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in __call__(self, ex)
    217                 div = self.get_fake_div(ex)
    218                 return self.arithmetic(div, div.operator())
--> 219             return self.arithmetic(ex, operator)
    220         elif operator in relation_operators:
    221             return self.relation(ex, operator)

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in arithmetic(self, ex, operator)
    833                 elif operator is mul_vararg:
    834                     operator = _operator.mul
--> 835                 return reduce(operator, map(self, ex.operands()))
    836         except TypeError:
    837             pass

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in __call__(self, ex)
    217                 div = self.get_fake_div(ex)
    218                 return self.arithmetic(div, div.operator())
--> 219             return self.arithmetic(ex, operator)
    220         elif operator in relation_operators:
    221             return self.relation(ex, operator)

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in arithmetic(self, ex, operator)
    833                 elif operator is mul_vararg:
    834                     operator = _operator.mul
--> 835                 return reduce(operator, map(self, ex.operands()))
    836         except TypeError:
    837             pass

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in __call__(self, ex)
    217                 div = self.get_fake_div(ex)
    218                 return self.arithmetic(div, div.operator())
--> 219             return self.arithmetic(ex, operator)
    220         elif operator in relation_operators:
    221             return self.relation(ex, operator)

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.pyc in arithmetic(self, ex, operator)
    827                 base = self.field(base)
    828                 expt = Rational(expt)
--> 829                 return self.field(base**expt)
    830             else:
    831                 if operator is add_vararg:

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in __pow__(self, e)
   3911                 # crosses the negative real line and self._value
   3912                 # is known to be non-zero.
-> 3913                 isgn = self.imag().sign()
   3914                 val = self._value
   3915                 argument = val.argument()

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in sign(self)
   4728             # print self._value
   4729             self._more_precision()
-> 4730             return self.sign()
   4731         else:
   4732             # Sigh...

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in sign(self)
   4731         else:
   4732             # Sigh...
-> 4733             self.exactify()
   4734             return self.sign()
   4735 

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in exactify(self)
   3275         od = self._descr
   3276         if isinstance(od, (ANRational, ANExtensionElement)): return
-> 3277         self._set_descr(self._descr.exactify())
   3278 
   3279     def _set_descr(self, new_descr):

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in exactify(self)
   6845 
   6846         if op == 'imag':
-> 6847             arg.exactify()
   6848             iv = QQbar_I * (arg.conjugate() - arg) / 2
   6849             iv.exactify()

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in exactify(self)
   3275         od = self._descr
   3276         if isinstance(od, (ANRational, ANExtensionElement)): return
-> 3277         self._set_descr(self._descr.exactify())
   3278 
   3279     def _set_descr(self, new_descr):

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in exactify(self)
   7078             left = self._left
   7079             right = self._right
-> 7080             left.exactify()
   7081             right.exactify()
   7082             gen = left._exact_field().union(right._exact_field())

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in exactify(self)
   3275         od = self._descr
   3276         if isinstance(od, (ANRational, ANExtensionElement)): return
-> 3277         self._set_descr(self._descr.exactify())
   3278 
   3279     def _set_descr(self, new_descr):

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in exactify(self)
   7078             left = self._left
   7079             right = self._right
-> 7080             left.exactify()
   7081             right.exactify()
   7082             gen = left._exact_field().union(right._exact_field())

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in exactify(self)
   3275         od = self._descr
   3276         if isinstance(od, (ANRational, ANExtensionElement)): return
-> 3277         self._set_descr(self._descr.exactify())
   3278 
   3279     def _set_descr(self, new_descr):

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in exactify(self)
   7079             right = self._right
   7080             left.exactify()
-> 7081             right.exactify()
   7082             gen = left._exact_field().union(right._exact_field())
   7083             left_value = gen(left._exact_value())

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in exactify(self)
   3275         od = self._descr
   3276         if isinstance(od, (ANRational, ANExtensionElement)): return
-> 3277         self._set_descr(self._descr.exactify())
   3278 
   3279     def _set_descr(self, new_descr):

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in exactify(self)
   7078             left = self._left
   7079             right = self._right
-> 7080             left.exactify()
   7081             right.exactify()
   7082             gen = left._exact_field().union(right._exact_field())

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in exactify(self)
   3275         od = self._descr
   3276         if isinstance(od, (ANRational, ANExtensionElement)): return
-> 3277         self._set_descr(self._descr.exactify())
   3278 
   3279     def _set_descr(self, new_descr):

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in exactify(self)
   7079             right = self._right
   7080             left.exactify()
-> 7081             right.exactify()
   7082             gen = left._exact_field().union(right._exact_field())
   7083             left_value = gen(left._exact_value())

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in exactify(self)
   3275         od = self._descr
   3276         if isinstance(od, (ANRational, ANExtensionElement)): return
-> 3277         self._set_descr(self._descr.exactify())
   3278 
   3279     def _set_descr(self, new_descr):

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in exactify(self)
   6143             newpol_sage_y = QQy(newpol_sage)
   6144 
-> 6145             red_elt, red_back, red_pol = do_polred(newpol_sage_y)
   6146 
   6147             new_nf = NumberField(red_pol, name='a', check=False)

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/rings/qqbar.pyc in do_polred(poly)
   1707         (1/4*x, 4*x, x^4 - 268435456*x^2 + 211973662764908353025)
   1708     """
-> 1709     new_poly, elt_back = poly._pari_().polredbest(flag=1)
   1710 
   1711     parent = poly.parent()

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/libs/pari/auto_gen.pxi in sage.libs.pari.gen.gen_auto.polredbest (/home/topolo/Public/sage/src/build/cythonized/sage/libs/pari/gen.c:80318)()
  15049         """
  15050         cdef GEN _T = T.g
> 15051         sig_on()
  15052         cdef GEN _ret = polredbest(_T, flag)
  15053         return pari_instance.new_gen(_ret)

src/cysignals/signals.pyx in cysignals.signals.sig_raise_exception (build/src/cysignals/signals.c:1116)()

KeyboardInterrupt: 

In [239]:
make_closure_rel(9,[1,2,3,5])


Out[239]:
(39*v_i^7 - 399*v_i^5 + 1261*v_i^3 - 900*v_i == v_i^9,
 [1/36*sqrt(1/35)*sqrt((11340*(2/893025*sqrt(54997406) + 9052/893025)^(2/3) + 5355*(2/893025*sqrt(54997406) + 9052/893025)^(1/3) - 632)/(2/893025*sqrt(54997406) + 9052/893025)^(1/3)) - 1/2*sqrt(-(2/893025*sqrt(54997406) + 9052/893025)^(1/3) + 3419/6*sqrt(1/35)/sqrt((11340*(2/893025*sqrt(54997406) + 9052/893025)^(2/3) + 5355*(2/893025*sqrt(54997406) + 9052/893025)^(1/3) - 632)/(2/893025*sqrt(54997406) + 9052/893025)^(1/3)) + 158/2835/(2/893025*sqrt(54997406) + 9052/893025)^(1/3) + 17/18) + 13/12,
  1/36*sqrt(1/35)*sqrt((11340*(2/893025*sqrt(54997406) + 9052/893025)^(2/3) + 5355*(2/893025*sqrt(54997406) + 9052/893025)^(1/3) - 632)/(2/893025*sqrt(54997406) + 9052/893025)^(1/3)) + 1/2*sqrt(-(2/893025*sqrt(54997406) + 9052/893025)^(1/3) + 3419/6*sqrt(1/35)/sqrt((11340*(2/893025*sqrt(54997406) + 9052/893025)^(2/3) + 5355*(2/893025*sqrt(54997406) + 9052/893025)^(1/3) - 632)/(2/893025*sqrt(54997406) + 9052/893025)^(1/3)) + 158/2835/(2/893025*sqrt(54997406) + 9052/893025)^(1/3) + 17/18) + 13/12])

In [246]:
print( len(make_closure_rel(9,[1,2,3,5])[1]) )
print(make_closure_rel(9,[1,2,3,5])[1][0].N() )
make_closure_rel(9,[1,2,3,5])[1][1].N()


2
0.756080852594268
Out[246]:
2.17538238657304

In [253]:
print( make_closure_rel(11)[0] )
print( make_closure_rel(11)[1] )
find_root( make_closure_rel(11)[1][0], 0,2)


55*v_i^9 - 1023*v_i^7 + 7645*v_i^5 - 21076*v_i^3 + 14400*v_i == v_i^11
[3465*T_0^5 - 17325*T_0^4 + 35805*T_0^3 - 38225*T_0^2 + 21076*T_0 - 4800]
Out[253]:
1.062793577485728

In [254]:
make_closure_rel(13)


Out[254]:
(91*v_i^11 - 3003*v_i^9 + 44473*v_i^7 - 296296*v_i^5 + 773136*v_i^3 - 518400*v_i == v_i^13,
 [45045*T_0^6 - 315315*T_0^5 + 945945*T_0^4 - 1556555*T_0^3 + 1481480*T_0^2 - 773136*T_0 + 172800])

In [259]:
find_root( make_closure_rel(13)[1][0], 0,10)


---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-259-e96f4f57aae6> in <module>()
----> 1 find_root( make_closure_rel(Integer(13))[Integer(1)][Integer(0)], Integer(0),Integer(10))

/home/topolo/Public/sage/src/sage/misc/lazy_import.pyx in sage.misc.lazy_import.LazyImport.__call__ (/home/topolo/Public/sage/src/build/cythonized/sage/misc/lazy_import.c:3627)()
    384             True
    385         """
--> 386         return self._get_object()(*args, **kwds)
    387 
    388     def __repr__(self):

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/numerical/optimize.pyc in find_root(f, a, b, xtol, rtol, maxiter, full_output)
     74     """
     75     try:
---> 76         return f.find_root(a=a,b=b,xtol=xtol,rtol=rtol,maxiter=maxiter,full_output=full_output)
     77     except AttributeError:
     78         pass

/home/topolo/Public/sage/src/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.find_root (/home/topolo/Public/sage/src/build/cythonized/sage/symbolic/expression.cpp:57525)()
  10914         elif self.number_of_arguments() == 1:
  10915             f = self._fast_float_(self.default_variable())
> 10916             return find_root(f, a=a, b=b, xtol=xtol,
  10917                              rtol=rtol,maxiter=maxiter,
  10918                              full_output=full_output)

/home/topolo/Public/sage/local/lib/python2.7/site-packages/sage/numerical/optimize.pyc in find_root(f, a, b, xtol, rtol, maxiter, full_output)
     92                 else:
     93                     return s
---> 94             raise RuntimeError("f appears to have no zero on the interval")
     95         # If we found such an s, then we just instead find
     96         # a root between left and s or s and right.

RuntimeError: f appears to have no zero on the interval

In [260]:
make_closure_rel(13,[1,2,3,4,5,7])


Out[260]:
(104*v_i^11 - 3718*v_i^9 + 57772*v_i^7 - 395681*v_i^5 + 1047124*v_i^3 - 705600*v_i == v_i^13,
 [45045*T_0^6 - 360360*T_0^5 + 1171170*T_0^4 - 2022020*T_0^3 + 1978405*T_0^2 - 1047124*T_0 + 235200])

In [261]:
find_root( make_closure_rel(13,[1,2,3,4,5,7])[1][0],0,2 )  # find a root between 0 and 2 for T_0


Out[261]:
1.1359579057687192

In [262]:
make_closure_rel(15)


Out[262]:
(140*v_i^13 - 7462*v_i^11 + 191620*v_i^9 - 2475473*v_i^7 + 15291640*v_i^5 - 38402064*v_i^3 + 25401600*v_i == v_i^15,
 [675675*T_0^7 - 6306300*T_0^6 + 25855830*T_0^5 - 60360300*T_0^4 + 86641555*T_0^3 - 76458200*T_0^2 + 38402064*T_0 - 8467200])

In [264]:
find_root( make_closure_rel(15)[1][0],0,2 )  # find a root between 0 and 2 for T_0


Out[264]:
1.4276826654691732
$Q$ $V$ Closure $T_0$
3 $\lbrace 0, \pm 1 \rbrace$ $v_{(i)}^3=v_{(i)}$ $1/3$
5 $\lbrace 0, \pm 1, \pm 3 \rbrace$ $v_{(i)}^5=10v_{(i)}^3 - 9v_{(i)}$ $1 \pm \sqrt{2/5}$

Table 1: 1-dim. Maxwell lattices with odd number of integer-valued velocities, $Q=3,5,7,9,11,13,15$


In [274]:
phi_v = sqrt( 1/(2*T_0*pi))*exp( - (v-u)**2/(2*T_0))

For $Q=3$


In [275]:
phi_v.subs(T_0==1/3).subs(v==v_i)


Out[275]:
sqrt(3)*sqrt(1/2)*e^(-3/2*(u - v_i)^2)/sqrt(pi)

In [276]:
phi_v.subs(T_0==1/3).subs(v==0)


Out[276]:
sqrt(3)*sqrt(1/2)*e^(-3/2*u^2)/sqrt(pi)

In [277]:
phi_v.subs(T_0==1/3).subs(v==1)


Out[277]:
sqrt(3)*sqrt(1/2)*e^(-3/2*(u - 1)^2)/sqrt(pi)

In [278]:
phi_v.subs(T_0==1/3).subs(v==-1)


Out[278]:
sqrt(3)*sqrt(1/2)*e^(-3/2*(u + 1)^2)/sqrt(pi)

In [282]:
( 0 + phi_v.subs(T_0==1/3).subs(v==1) + phi_v.subs(T_0==1/3).subs(v==-1)*(-1) ).expand().simplify()


Out[282]:
1/2*sqrt(3)*sqrt(2)*e^(-3/2*u^2 + 3*u - 3/2)/sqrt(pi) - 1/2*sqrt(3)*sqrt(2)*e^(-3/2*u^2 - 3*u - 3/2)/sqrt(pi)

In [283]:
v_i   = var("v_i",domain="integer")
make_closure_rel(5,[1,3])


Out[283]:
(10*v_i^3 - 9*v_i == v_i^5, [-1/5*sqrt(10) + 1, 1/5*sqrt(10) + 1])

In [ ]:


In [ ]:

from Lattices for the lattice Boltzmann method, Chikatamarla and Karlin (2009), PHYSICAL REVIEW E 79, 046701 (2009)


In [284]:
u = var("u",domain="real")
T_0 =var("T_0",domain="positive")
v = var("v",domain="real")

In [285]:
phi_v = sqrt( 1/(2*pi*T_0))*exp( - (v-u)**2/(2*T_0))

In [286]:
print( integrate( phi_v * v**0, (v,-oo,oo)).expand().simplify() )
print( integrate( phi_v * v**1, (v,-oo,oo)).expand().simplify() )
print( integrate( phi_v * v**2, (v,-oo,oo)).expand().simplify() )
print( integrate( phi_v * v**3, (v,-oo,oo)).expand().simplify() )
print( integrate( phi_v * v**4, (v,-oo,oo)).expand().simplify() )
print( integrate( phi_v * v**5, (v,-oo,oo)).expand().simplify() )
print( integrate( phi_v * v**6, (v,-oo,oo)).expand().simplify() )


1
u
u^2 + T_0
u^3 + 3*T_0*u
u^4 + 6*T_0*u^2 + 3*T_0^2
u^5 + 10*T_0*u^3 + 15*T_0^2*u
u^6 + 15*T_0*u^4 + 45*T_0^2*u^2 + 15*T_0^3

$d\equiv D=2$, 2-dim. case


In [288]:
u1,u2=var("u1,u2",domain="real")
v1,v2=var("v1,v2",domain="positive")
phi_v = 1/(2*pi*T_0)*exp( - ((v1-u1)**2+(v2-u2)**2)/(2*T_0))

In [298]:
print( integrate( integrate( phi_v * v1**0*v2**0, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**1*v2**0, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**0*v2**1, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**2*v2**0, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**0*v2**2, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**1*v2**1, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**3*v2**0, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**2*v2**1, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**1*v2**2, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**0*v2**3, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**4*v2**0, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**3*v2**1, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**2*v2**2, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**1*v2**3, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**0*v2**4, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**5*v2**0, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**4*v2**1, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**3*v2**2, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**2*v2**3, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**1*v2**4, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**0*v2**5, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )


1
u1
u2
u1^2 + T_0
u2^2 + T_0
u1*u2
u1^3 + 3*T_0*u1
u1^2*u2 + T_0*u2
u1*u2^2 + T_0*u1
u2^3 + 3*T_0*u2
u1^4 + 6*T_0*u1^2 + 3*T_0^2
u1^3*u2 + 3*T_0*u1*u2
u1^2*u2^2 + T_0*u1^2 + T_0*u2^2 + T_0^2
u1*u2^3 + 3*T_0*u1*u2
u2^4 + 6*T_0*u2^2 + 3*T_0^2
u1^5 + 10*T_0*u1^3 + 15*T_0^2*u1
u1^4*u2 + 6*T_0*u1^2*u2 + 3*T_0^2*u2
u1^3*u2^2 + T_0*u1^3 + 3*T_0*u1*u2^2 + 3*T_0^2*u1
u1^2*u2^3 + 3*T_0*u1^2*u2 + T_0*u2^3 + 3*T_0^2*u2
u1*u2^4 + 6*T_0*u1*u2^2 + 3*T_0^2*u1
u2^5 + 10*T_0*u2^3 + 15*T_0^2*u2

In [299]:
Q=9
W_lst = var(",".join(map(str,["W"+str(k) for k in range(Q)])) ) # Python list of weights W_i, i=0,1,...Q-1

In [300]:
c_0 = (0,0)
c_1,c_3 = (1,0),(-1,0); c_2,c_4=(0,1),(0,-1)
c_5,c_6,c_7,c_8 =(1,1),(-1,1),(1,-1),(-1,-1)
cs = [c_0,c_1,c_2,c_3,c_4,c_5,c_6,c_7,c_8]

In [302]:
sum(W_lst)


Out[302]:
W0 + W1 + W2 + W3 + W4 + W5 + W6 + W7 + W8

In [303]:
sum( [W_lst[k]*cs[k][0] for k in range(Q)] )


Out[303]:
W1 - W3 + W5 - W6 + W7 - W8

In [304]:
sum( [W_lst[k]*cs[k][1] for k in range(Q)] )


Out[304]:
W2 - W4 + W5 + W6 - W7 - W8

In [306]:
print( sum( [W_lst[k]*cs[k][0]*cs[k][0] for k in range(Q)] ) )
print( sum( [W_lst[k]*cs[k][0]*cs[k][1] for k in range(Q)] ) )
print( sum( [W_lst[k]*cs[k][1]*cs[k][1] for k in range(Q)] ) )


W1 + W3 + W5 + W6 + W7 + W8
W5 - W6 - W7 + W8
W2 + W4 + W5 + W6 + W7 + W8

In [307]:
print( sum( [W_lst[k]*cs[k][0]*cs[k][0]*cs[k][0] for k in range(Q)] ) )
print( sum( [W_lst[k]*cs[k][1]*cs[k][0]*cs[k][0] for k in range(Q)] ) )
print( sum( [W_lst[k]*cs[k][1]*cs[k][1]*cs[k][0] for k in range(Q)] ) )
# print( sum( [W_lst[k]*cs[k][1]*cs[k][1]*cs[k][1] for k in range(Q)] ) ) # the same


W1 - W3 + W5 - W6 + W7 - W8
W5 + W6 - W7 - W8
W5 - W6 + W7 - W8
W2 - W4 + W5 + W6 - W7 - W8

In [312]:
# print( sum( [W_lst[k]*cs[k][0]*cs[k][0]*cs[k][0]*cs[k][0] for k in range(Q)] ) ) # the same
# print( sum( [W_lst[k]*cs[k][1]*cs[k][0]*cs[k][0]*cs[k][0] for k in range(Q)] ) ) # the same
print( sum( [W_lst[k]*cs[k][0]*cs[k][0]*cs[k][1]*cs[k][1] for k in range(Q)] ) )
#print( sum( [W_lst[k]*cs[k][0]*cs[k][1]*cs[k][1]*cs[k][1] for k in range(Q)] ) )  # the same
#print( sum( [W_lst[k]*cs[k][1]*cs[k][1]*cs[k][1]*cs[k][1] for k in range(Q)] ) )


W5 + W6 + W7 + W8
W2 + W4 + W5 + W6 + W7 + W8

Is there a way to generate all the discrete velocities, $\mathbf{c}_i \equiv \mathbf{v}_i$?

I will use the mirror symmetry so we only need to consider the "positive values"


In [315]:
d=2 # D=2
v_ipos = [1,] # v_i positive values
dimidx = range(d) # indices for the components

In [317]:
[zeroidx for zeroidx in combinations(dimidx,1)]


Out[317]:
[(0,), (1,)]

In [318]:
[_ for _ in combinations(v_ipos,1)]


Out[318]:
[(1,)]

If $Q= $ total number of discrete vectors is given and known beforehand:


In [320]:
v_is =[[0 for _ in range(d)] for _ in range(Q)]

In [322]:
[_ for _ in combinations(dimidx,d)]


Out[322]:
[(0, 1)]

In [328]:
[_ for _ in combinations(range(3),2)]


Out[328]:
[(0, 1), (0, 2), (1, 2)]

In [324]:
[_ for _ in combinations_with_replacement(v_ipos,1) ]


Out[324]:
[(1,)]

In [325]:
[_ for _ in combinations_with_replacement(v_ipos,2) ]


Out[325]:
[(1, 1)]

In [335]:
d=3 # D=3
v_ipos = [1,2] # v_i positive values
dimidx = range(d) # indices for the components

In [336]:
c_d_nonzeros = [np.zeros(d) for _ in range( len([_ for _ in combinations(dimidx,2)]) )]
for nonzeros in combinations(dimidx,2): # d_nonzero = 0,1,..d-1
    print( [_ for _ in combinations_with_replacement(v_ipos,2)]  )


[(1, 1), (1, 2), (2, 2)]
[(1, 1), (1, 2), (2, 2)]
[(1, 1), (1, 2), (2, 2)]

In [339]:
[_ for _ in combinations_with_replacement([0,1],1)]


Out[339]:
[(0,), (1,)]

In [340]:
[_ for _ in combinations_with_replacement([0,1],2)]


Out[340]:
[(0, 0), (0, 1), (1, 1)]

In [341]:
[_ for _ in combinations_with_replacement([0,1],3)]


Out[341]:
[(0, 0, 0), (0, 0, 1), (0, 1, 1), (1, 1, 1)]

In [342]:
[_ for _ in combinations_with_replacement([0,1],4)]


Out[342]:
[(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 1, 1), (0, 1, 1, 1), (1, 1, 1, 1)]

In [347]:
d=2 # D=2
v_ipos = [1,] # v_i positive values
dimidx = range(d) # indices for the components

In [343]:
unique_W_lst = []

In [345]:
if sum(W_lst) not in unique_W_lst:
    unique_W_lst.append( sum(W_lst))

In [348]:
for alpha in combinations_with_replacement(dimidx,1):
    W_to_lst = sum( [W_lst[k]*cs[k][alpha[0]] for k in range(Q)] )
    if W_to_lst not in unique_W_lst:
        unique_W_lst.append( W_to_lst )

print(unique_W_lst)


[W0 + W1 + W2 + W3 + W4 + W5 + W6 + W7 + W8, W1 - W3 + W5 - W6 + W7 - W8, W2 - W4 + W5 + W6 - W7 - W8]

In [349]:
for alpha in combinations_with_replacement(dimidx,2):
    W_to_lst = sum( [W_lst[k]*cs[k][alpha[0]]*cs[k][alpha[1]] for k in range(Q)] )
    if W_to_lst not in unique_W_lst:
        unique_W_lst.append( W_to_lst )

print(unique_W_lst)


[W0 + W1 + W2 + W3 + W4 + W5 + W6 + W7 + W8, W1 - W3 + W5 - W6 + W7 - W8, W2 - W4 + W5 + W6 - W7 - W8, W1 + W3 + W5 + W6 + W7 + W8, W5 - W6 - W7 + W8, W2 + W4 + W5 + W6 + W7 + W8]

In [350]:
for alpha in combinations_with_replacement(dimidx,3):
    W_to_lst = sum( [W_lst[k]*cs[k][alpha[0]]*cs[k][alpha[1]]*cs[k][alpha[2]] for k in range(Q)] )
    if W_to_lst not in unique_W_lst:
        unique_W_lst.append( W_to_lst )

print(unique_W_lst)


[W0 + W1 + W2 + W3 + W4 + W5 + W6 + W7 + W8, W1 - W3 + W5 - W6 + W7 - W8, W2 - W4 + W5 + W6 - W7 - W8, W1 + W3 + W5 + W6 + W7 + W8, W5 - W6 - W7 + W8, W2 + W4 + W5 + W6 + W7 + W8, W5 + W6 - W7 - W8, W5 - W6 + W7 - W8]

In [351]:
for alpha in combinations_with_replacement(dimidx,4):
    W_to_lst = sum( [W_lst[k]*cs[k][alpha[0]]*cs[k][alpha[1]]*cs[k][alpha[2]]*cs[k][alpha[3]] for k in range(Q)] )
    if W_to_lst not in unique_W_lst:
        unique_W_lst.append( W_to_lst )

print(unique_W_lst)


[W0 + W1 + W2 + W3 + W4 + W5 + W6 + W7 + W8, W1 - W3 + W5 - W6 + W7 - W8, W2 - W4 + W5 + W6 - W7 - W8, W1 + W3 + W5 + W6 + W7 + W8, W5 - W6 - W7 + W8, W2 + W4 + W5 + W6 + W7 + W8, W5 + W6 - W7 - W8, W5 - W6 + W7 - W8, W5 + W6 + W7 + W8]

In [352]:
len(unique_W_lst)


Out[352]:
9

In [354]:
for alpha in combinations_with_replacement(dimidx,3):
    todolst = [ W_lst[k]*prod( [cs[k][alpha[order]] for order in range(3)]) for k in range(Q)]
    print sum(todolst)


W1 - W3 + W5 - W6 + W7 - W8
W5 + W6 - W7 - W8
W5 - W6 + W7 - W8
W2 - W4 + W5 + W6 - W7 - W8

In [376]:
def make_W_lin_sys(d,Q,cs, ORDER=4):
    """ make_W_lin_sys - make the linear system of W_i's
    
    NOTES
    =====
    Remember that W_lst corresponds directly with cs, i.e. W_i's with c_i \equiv v_i's (discrete velocity i)
    """
    W_lst = var(",".join(map(str,["W"+str(k) for k in range(Q)])) ) # Python list of weights W_i, i=0,1,...Q-1
    dimidx = range(d)
    unique_W_lst = []
    if sum(W_lst) not in unique_W_lst:
        unique_W_lst.append( sum(W_lst))
    
    for order in range(1,ORDER+1): # order = 1,2,..ORDER=4
        for alpha in combinations_with_replacement(dimidx,order):
            W_to_lst = [W_lst[k]*prod( [cs[k][alpha[orderidx]] for orderidx in range(order)]) for k in range(Q)]
            W_to_lst = sum( W_to_lst )
            if W_to_lst not in unique_W_lst:
                unique_W_lst.append(W_to_lst)
    return unique_W_lst

In [378]:
test_d2Q9_W_is = make_W_lin_sys(2,9,cs)
print(len(test_d2Q9_W_is))


9

In [380]:
print(len(test_d2Q9_W_is))
test_d2Q9_W_is


9
Out[380]:
[W0 + W1 + W2 + W3 + W4 + W5 + W6 + W7 + W8,
 W1 - W3 + W5 - W6 + W7 - W8,
 W2 - W4 + W5 + W6 - W7 - W8,
 W1 + W3 + W5 + W6 + W7 + W8,
 W5 - W6 - W7 + W8,
 W2 + W4 + W5 + W6 + W7 + W8,
 W5 + W6 - W7 - W8,
 W5 - W6 + W7 - W8,
 W5 + W6 + W7 + W8]

In [359]:
range(1)


Out[359]:
[0]

Now consider the "right-hand side (RHS)", the "moments" or the velocity moments-over Maxwell distribution (what Wolf calls it)


In [364]:
u1,u2=var("u1,u2",domain="real")
v1,v2=var("v1,v2",domain="positive")
phi_v = 1/(2*pi*T_0)*exp( - ((v1-u1)**2+(v2-u2)**2)/(2*T_0))

In [365]:
print( integrate( integrate( phi_v * v1**0*v2**0, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**1*v2**0, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**0*v2**1, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**2*v2**0, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**0*v2**2, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**1*v2**1, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**3*v2**0, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**2*v2**1, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**1*v2**2, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**0*v2**3, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**4*v2**0, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**3*v2**1, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**2*v2**2, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**1*v2**3, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )
print( integrate( integrate( phi_v * v1**0*v2**4, (v1,-oo,oo)),(v2,-oo,oo)).expand().simplify() )


1
u1
u2
u1^2 + T_0
u2^2 + T_0
u1*u2
u1^3 + 3*T_0*u1
u1^2*u2 + T_0*u2
u1*u2^2 + T_0*u1
u2^3 + 3*T_0*u2
u1^4 + 6*T_0*u1^2 + 3*T_0^2
u1^3*u2 + 3*T_0*u1*u2
u1^2*u2^2 + T_0*u1^2 + T_0*u2^2 + T_0^2
u1*u2^3 + 3*T_0*u1*u2
u2^4 + 6*T_0*u2^2 + 3*T_0^2

In [366]:
for alpha in combinations_with_replacement(dimidx,1):
    print alpha


(0,)
(1,)

In [367]:
for alpha in combinations_with_replacement(dimidx,2):
    print alpha


(0, 0)
(0, 1)
(1, 1)

In [368]:
for alpha in combinations_with_replacement(dimidx,3):
    print alpha


(0, 0, 0)
(0, 0, 1)
(0, 1, 1)
(1, 1, 1)

In [496]:
def make_moment(d,alphas, u_vec=None,T_0=None):
    """ make_moment - compute moment of Maxwell distribution
    
    INPUTS/ARGUMENTS
    ================
    @type alphas : Python iterable, most likely a Python tuple or Python list of length order, order of moment we want to calculate
    @param alphas : alpha exponents
    """
    v_i_vec = var(",".join(map(str,["v"+str(k+1) for k in range(d)])) )
    if u_vec is None:
        u_vec = var(",".join(map(str,["u"+str(k+1) for k in range(d)])) )
    if T_0 is None:
        T_0 =var("T_0",domain="positive")
    
    if (d>=2):
        norm_uminusv = sum( [ (v_i_vec[k]-u_vec[k])**2 for k in range(d)])
    elif (d==1):
        norm_uminusv = (v_i_vec - u_vec)**2
    
    phi_v = 1/(2*pi*T_0)**(d/2)*exp( - norm_uminusv/(2*T_0))

    if (d>=2):
        tointegrate = phi_v*prod([v_i_vec[i] for i in alphas])
    elif (d==1):
        tointegrate = phi_v*prod([v_i_vec for i in alphas])
        
    if (d>=2):
        for v_i in v_i_vec:
            tointegrate = integrate( tointegrate, (v_i,-oo,oo))
    elif (d==1):
        tointegrate = integrate( tointegrate, (v_i_vec,-oo,oo))
        
    return tointegrate.expand().simplify()

In [484]:
test_M3 = make_moment(2,(0,1,1))

In [485]:
test_M3


Out[485]:
u1*u2^2 + T_0*u1

In [497]:
def make_W_lin_sys(d,Q,cs, ORDER=4,u_vec=None,T_0=None):
    """ make_W_lin_sys - make the linear system of W_i's
    
    NOTES
    =====
    Remember that W_lst corresponds directly with cs, i.e. W_i's with c_i \equiv v_i's (discrete velocity i)
    """
    v_i_vec = var(",".join(map(str,["v"+str(k+1) for k in range(d)])) )
    if u_vec is None:
        u_vec = var(",".join(map(str,["u"+str(k+1) for k in range(d)])) )
    if T_0 is None:
        T_0 =var("T_0",domain="positive")
    
    W_lst = var(",".join(map(str,["W"+str(k) for k in range(Q)])) ) # Python list of weights W_i, i=0,1,...Q-1
    dimidx = range(d)
    unique_W_lst = [] # Use this Python list to keep out redundancies, check for redundancies
    unique_W_dict_lst = []
    if sum(W_lst) not in unique_W_lst:
        unique_W_lst.append( sum(W_lst))
        rhs_out = make_moment(d,[],u_vec,T_0)
        Weqn_out = {"lhs": sum(W_lst),"rhs":rhs_out}
        unique_W_dict_lst.append(Weqn_out)
    for order in range(1,ORDER+1): # order = 1,2,..ORDER=4
        for alpha in combinations_with_replacement(dimidx,order):
            W_to_lst = [W_lst[k]*prod( [cs[k][alpha[orderidx]] for orderidx in range(order)]) for k in range(Q)]
            W_to_lst = sum( W_to_lst )
            if W_to_lst not in unique_W_lst:
                unique_W_lst.append(W_to_lst)
                rhs_out = make_moment(d,alpha,u_vec,T_0)
                Weqn_out = { "lhs":W_to_lst,"rhs":rhs_out}
                unique_W_dict_lst.append( Weqn_out)
                
    return unique_W_dict_lst, W_lst

In [498]:
test_W_sys, test_W_is = make_W_lin_sys(2,9,cs,4)
print(len(test_W_sys))


9

In [499]:
test_W_sys


Out[499]:
[{'lhs': W0 + W1 + W2 + W3 + W4 + W5 + W6 + W7 + W8, 'rhs': 1},
 {'lhs': W1 - W3 + W5 - W6 + W7 - W8, 'rhs': u1},
 {'lhs': W2 - W4 + W5 + W6 - W7 - W8, 'rhs': u2},
 {'lhs': W1 + W3 + W5 + W6 + W7 + W8, 'rhs': u1^2 + T_0},
 {'lhs': W5 - W6 - W7 + W8, 'rhs': u1*u2},
 {'lhs': W2 + W4 + W5 + W6 + W7 + W8, 'rhs': u2^2 + T_0},
 {'lhs': W5 + W6 - W7 - W8, 'rhs': u1^2*u2 + T_0*u2},
 {'lhs': W5 - W6 + W7 - W8, 'rhs': u1*u2^2 + T_0*u1},
 {'lhs': W5 + W6 + W7 + W8, 'rhs': u1^2*u2^2 + T_0*u1^2 + T_0*u2^2 + T_0^2}]

In [462]:
prod( [range(3)[i] for i in []] )


Out[462]:
1

The $W_i$ for directions with identical speeds are equal for reasons of symmetry.


In [500]:
#test_W_sys[0]["lhs"].subs(W2==W1).subs(W3==W1).subs(W4==W1).subs(W5==W2).subs(W6==W2).subs(W7==W2).subs(W8==W2)
for i in range(Q):
    print( test_W_sys[i]["lhs"].subs(W2==W1).subs(W3==W1).subs(W4==W1).subs(W5==W2).subs(W6==W2).subs(W7==W2).subs(W8==W2) )
for i in range(Q):
    print( test_W_sys[i]["rhs"].subs(u1==0).subs(u2==0))


W0 + 4*W1 + 4*W2
0
0
2*W1 + 4*W2
0
2*W1 + 4*W2
0
0
4*W2
1
0
0
T_0
0
T_0
0
0
T_0^2

In [501]:
test_W_sys_temp = []
for eqn in test_W_sys:
    lhs =eqn["lhs"].subs(W2==W1).subs(W3==W1).subs(W4==W1).subs(W5==W2).subs(W6==W2).subs(W7==W2).subs(W8==W2)
    rhs =eqn["rhs"].subs(u1==0).subs(u2==0)
    test_W_sys_temp.append( lhs==rhs)

In [502]:
test_W_sys_temp


Out[502]:
[W0 + 4*W1 + 4*W2 == 1,
 0 == 0,
 0 == 0,
 2*W1 + 4*W2 == T_0,
 0 == 0,
 2*W1 + 4*W2 == T_0,
 0 == 0,
 0 == 0,
 4*W2 == T_0^2]

In [503]:
solve( test_W_sys_temp, [W0,W1,W2])


Out[503]:
[[W0 == T_0^2 - 2*T_0 + 1, W1 == -1/2*T_0^2 + 1/2*T_0, W2 == 1/4*T_0^2]]

In [504]:
print( solve( test_W_sys_temp, [W0,W1,W2])[0][0].subs(T_0==1/3) )
print( solve( test_W_sys_temp, [W0,W1,W2])[0][1].subs(T_0==1/3) )
print( solve( test_W_sys_temp, [W0,W1,W2])[0][2].subs(T_0==1/3) )


W0 == (4/9)
W1 == (1/9)
W2 == (1/36)

So pp. 169 solution in Section 5.2.1of Wolf, and (same thing) on pp. 166, for the D2Q9 lattice (5.2.1), the $W_i$ are obtained.

going back to $d\equiv D=1$, 1-dim. case


In [505]:
make_closure_rel(5,[1,3])


Out[505]:
(10*v_i^3 - 9*v_i == v_i^5, [-1/5*sqrt(10) + 1, 1/5*sqrt(10) + 1])

In [506]:
make_closure_rel(7)


Out[506]:
(14*v_i^5 - 49*v_i^3 + 36*v_i == v_i^7,
 [(1/1575*sqrt(15)*sqrt(2) + 1/945)^(1/3) - 1/45/(1/1575*sqrt(15)*sqrt(2) + 1/945)^(1/3) + 2/3])

In [537]:
make_closure_rel(7)[1][0].N()


Out[537]:
0.697953322019683

In [415]:
make_closure_rel(9,[1,2,3,5])


Out[415]:
(39*v_i^7 - 399*v_i^5 + 1261*v_i^3 - 900*v_i == v_i^9,
 [1/36*sqrt(1/35)*sqrt((11340*(2/893025*sqrt(54997406) + 9052/893025)^(2/3) + 5355*(2/893025*sqrt(54997406) + 9052/893025)^(1/3) - 632)/(2/893025*sqrt(54997406) + 9052/893025)^(1/3)) - 1/2*sqrt(-(2/893025*sqrt(54997406) + 9052/893025)^(1/3) + 3419/6*sqrt(1/35)/sqrt((11340*(2/893025*sqrt(54997406) + 9052/893025)^(2/3) + 5355*(2/893025*sqrt(54997406) + 9052/893025)^(1/3) - 632)/(2/893025*sqrt(54997406) + 9052/893025)^(1/3)) + 158/2835/(2/893025*sqrt(54997406) + 9052/893025)^(1/3) + 17/18) + 13/12,
  1/36*sqrt(1/35)*sqrt((11340*(2/893025*sqrt(54997406) + 9052/893025)^(2/3) + 5355*(2/893025*sqrt(54997406) + 9052/893025)^(1/3) - 632)/(2/893025*sqrt(54997406) + 9052/893025)^(1/3)) + 1/2*sqrt(-(2/893025*sqrt(54997406) + 9052/893025)^(1/3) + 3419/6*sqrt(1/35)/sqrt((11340*(2/893025*sqrt(54997406) + 9052/893025)^(2/3) + 5355*(2/893025*sqrt(54997406) + 9052/893025)^(1/3) - 632)/(2/893025*sqrt(54997406) + 9052/893025)^(1/3)) + 158/2835/(2/893025*sqrt(54997406) + 9052/893025)^(1/3) + 17/18) + 13/12])

In [422]:
print( make_closure_rel(9,[1,2,3,5])[1][0].N() )
print( make_closure_rel(9,[1,2,3,5])[1][1].N() )


0.756080852594268
2.17538238657304

In [416]:
make_closure_rel(11)


Out[416]:
(55*v_i^9 - 1023*v_i^7 + 7645*v_i^5 - 21076*v_i^3 + 14400*v_i == v_i^11,
 [3465*T_0^5 - 17325*T_0^4 + 35805*T_0^3 - 38225*T_0^2 + 21076*T_0 - 4800])

In [425]:
print( find_root( make_closure_rel(11)[1][0], 0,3) )
#print( find_root( make_closure_rel(11)[1][0], 3,6) )


1.06279357749

In [442]:
make_closure_rel(13,[1,2,3,4,5,7])


Out[442]:
(104*v_i^11 - 3718*v_i^9 + 57772*v_i^7 - 395681*v_i^5 + 1047124*v_i^3 - 705600*v_i == v_i^13,
 [45045*T_0^6 - 360360*T_0^5 + 1171170*T_0^4 - 2022020*T_0^3 + 1978405*T_0^2 - 1047124*T_0 + 235200])

In [446]:
print( find_root( make_closure_rel(13,[1,2,3,4,5,7])[1][0], 0,3) )
#print( find_root( make_closure_rel(13,[1,2,3,4,5,7])[1][0], 3,6) )


2.67428803233

In [418]:
make_closure_rel(15)


Out[418]:
(140*v_i^13 - 7462*v_i^11 + 191620*v_i^9 - 2475473*v_i^7 + 15291640*v_i^5 - 38402064*v_i^3 + 25401600*v_i == v_i^15,
 [675675*T_0^7 - 6306300*T_0^6 + 25855830*T_0^5 - 60360300*T_0^4 + 86641555*T_0^3 - 76458200*T_0^2 + 38402064*T_0 - 8467200])

In [436]:
print( find_root( make_closure_rel(15)[1][0], 0,2) )


1.42768266547

$Q=3, V= \lbrace 0, \pm 1\rbrace$


In [447]:
v_0 = (0,)
v_1 = (1,)
v_m1=(-1,)
V = [v_0,v_1,v_m1]

In [508]:
#make_W_lin_sys(1,3,V, ORDER=2,u_vec=None,T_0=None)
D1Q3_W_sys, D1Q3_W_is = make_W_lin_sys(1,3,V,ORDER=2)

In [510]:
def W_sys_solver( sys_from_make_W_lin_sys, W_is):
    eqns_to_solve = []
    for eqn in sys_from_make_W_lin_sys:
        eqns_to_solve.append( eqn['lhs'] == eqn['rhs'] )
    return solve( eqns_to_solve,W_is)

In [511]:
W_sys_solver( D1Q3_W_sys, D1Q3_W_is)


Out[511]:
[[W0 == -u1^2 - T_0 + 1, W1 == 1/2*u1^2 + 1/2*T_0 + 1/2*u1, W2 == 1/2*u1^2 + 1/2*T_0 - 1/2*u1]]

In [520]:
print( W_sys_solver( D1Q3_W_sys, D1Q3_W_is)[0][0].subs(u1==0).subs(T_0==1/3) )
print( W_sys_solver( D1Q3_W_sys, D1Q3_W_is)[0][1].subs(u1==0).subs(T_0==1/3) )
print( W_sys_solver( D1Q3_W_sys, D1Q3_W_is)[0][2].subs(u1==0).subs(T_0==1/3) )


W0 == (2/3)
W1 == (1/6)
W2 == (1/6)

In [457]:
len(v_i_vec)


Out[457]:
2

$Q=5,...$,


In [512]:
V = [(0,),(1,),(-1,),(3,),(-3,)]
D1Q5_W_sys, D1Q5_W_is = make_W_lin_sys(1,5,V,ORDER=4)

In [521]:
W_sys_solver( D1Q5_W_sys, D1Q5_W_is)


Out[521]:
[[W0 == 1/9*u1^4 + 2/9*(3*T_0 - 5)*u1^2 + 1/3*T_0^2 - 10/9*T_0 + 1, W1 == -1/16*u1^4 - 3/16*(2*T_0 - 3)*u1^2 - 1/16*u1^3 - 3/16*T_0^2 - 3/16*(T_0 - 3)*u1 + 9/16*T_0, W2 == -1/16*u1^4 - 3/16*(2*T_0 - 3)*u1^2 + 1/16*u1^3 - 3/16*T_0^2 + 3/16*(T_0 - 3)*u1 + 9/16*T_0, W3 == 1/144*u1^4 + 1/144*(6*T_0 - 1)*u1^2 + 1/48*u1^3 + 1/48*T_0^2 + 1/48*(3*T_0 - 1)*u1 - 1/144*T_0, W4 == 1/144*u1^4 + 1/144*(6*T_0 - 1)*u1^2 - 1/48*u1^3 + 1/48*T_0^2 - 1/48*(3*T_0 - 1)*u1 - 1/144*T_0]]

In [531]:
print( W_sys_solver( D1Q5_W_sys, D1Q5_W_is)[0][0].subs(u1==0).subs(T_0==-1/5*sqrt(10) + 1).rhs().expand().simplify() )
print( W_sys_solver( D1Q5_W_sys, D1Q5_W_is)[0][1].subs(u1==0).subs(T_0==-1/5*sqrt(10) + 1).rhs().expand().simplify() )
print( W_sys_solver( D1Q5_W_sys, D1Q5_W_is)[0][2].subs(u1==0).subs(T_0==-1/5*sqrt(10) + 1).rhs().expand().simplify() )
print( W_sys_solver( D1Q5_W_sys, D1Q5_W_is)[0][3].subs(u1==0).subs(T_0==-1/5*sqrt(10) + 1).rhs().expand().simplify() )
print( W_sys_solver( D1Q5_W_sys, D1Q5_W_is)[0][4].subs(u1==0).subs(T_0==-1/5*sqrt(10) + 1).rhs().expand().simplify() )


4/45*sqrt(10) + 16/45
-3/80*sqrt(10) + 3/10
-3/80*sqrt(10) + 3/10
-1/144*sqrt(10) + 1/45
-1/144*sqrt(10) + 1/45

In [532]:
print( W_sys_solver( D1Q5_W_sys, D1Q5_W_is)[0][0].subs(u1==0).subs(T_0==1/5*sqrt(10) + 1).rhs().expand().simplify() )
print( W_sys_solver( D1Q5_W_sys, D1Q5_W_is)[0][1].subs(u1==0).subs(T_0==1/5*sqrt(10) + 1).rhs().expand().simplify() )
print( W_sys_solver( D1Q5_W_sys, D1Q5_W_is)[0][2].subs(u1==0).subs(T_0==1/5*sqrt(10) + 1).rhs().expand().simplify() )
print( W_sys_solver( D1Q5_W_sys, D1Q5_W_is)[0][3].subs(u1==0).subs(T_0==1/5*sqrt(10) + 1).rhs().expand().simplify() )
print( W_sys_solver( D1Q5_W_sys, D1Q5_W_is)[0][4].subs(u1==0).subs(T_0==1/5*sqrt(10) + 1).rhs().expand().simplify() )


-4/45*sqrt(10) + 16/45
3/80*sqrt(10) + 3/10
3/80*sqrt(10) + 3/10
1/144*sqrt(10) + 1/45
1/144*sqrt(10) + 1/45

In [533]:
V = [(0,),(1,),(-1,),(2,),(-2,),(3,),(-3,)]
D1Q7_W_sys, D1Q7_W_is = make_W_lin_sys(1,7,V,ORDER=6)

In [535]:
D1Q7_W_solved= W_sys_solver( D1Q7_W_sys, D1Q7_W_is)

In [542]:
print( D1Q7_W_solved[0][0].subs(u1==0).subs(T_0==make_closure_rel(7)[1][0]).rhs().N() )
print( D1Q7_W_solved[0][1].subs(u1==0).subs(T_0==make_closure_rel(7)[1][0]).rhs().N() )
print( D1Q7_W_solved[0][2].subs(u1==0).subs(T_0==make_closure_rel(7)[1][0]).rhs().N() )
print( D1Q7_W_solved[0][3].subs(u1==0).subs(T_0==make_closure_rel(7)[1][0]).rhs().N() )
print( D1Q7_W_solved[0][4].subs(u1==0).subs(T_0==make_closure_rel(7)[1][0]).rhs().N() )
print( D1Q7_W_solved[0][5].subs(u1==0).subs(T_0==make_closure_rel(7)[1][0]).rhs().N() )
print( D1Q7_W_solved[0][6].subs(u1==0).subs(T_0==make_closure_rel(7)[1][0]).rhs().N() )


0.476669886589207
0.233914737826825
0.233914737826825
0.0269381893448255
0.0269381893448255
0.000812129533746113
0.000812129533746113

In [555]:
for i in range(7):
    print( D1Q7_W_solved[0][i].subs(u1==0) )


W0 == -5/12*T_0^3 + 7/6*T_0^2 - 49/36*T_0 + 1
W1 == 5/16*T_0^3 - 13/16*T_0^2 + 3/4*T_0
W2 == 5/16*T_0^3 - 13/16*T_0^2 + 3/4*T_0
W3 == -1/8*T_0^3 + 1/4*T_0^2 - 3/40*T_0
W4 == -1/8*T_0^3 + 1/4*T_0^2 - 3/40*T_0
W5 == 1/48*T_0^3 - 1/48*T_0^2 + 1/180*T_0
W6 == 1/48*T_0^3 - 1/48*T_0^2 + 1/180*T_0

Note that Eqns.(7-10) of Physical Review E 93, 063302 (2016), "Entropic Lattice Boltzmann Model for Gas..." is computed!


In [543]:
V = [(0,),(1,),(-1,),(2,),(-2,),(3,),(-3,),(5,),(-5,)]
D1Q9_W_sys, D1Q9_W_is = make_W_lin_sys(1,9,V,ORDER=8)

In [544]:
D1Q9_W_solved= W_sys_solver( D1Q9_W_sys, D1Q9_W_is)

In [547]:
print( D1Q9_W_solved[0][0].subs(u1==0).subs(T_0==0.756080852594268 ) )
print( D1Q9_W_solved[0][1].subs(u1==0).subs(T_0==0.756080852594268 ) )
print( D1Q9_W_solved[0][2].subs(u1==0).subs(T_0==0.756080852594268 ) )
print( D1Q9_W_solved[0][3].subs(u1==0).subs(T_0==0.756080852594268 ) )
print( D1Q9_W_solved[0][4].subs(u1==0).subs(T_0==0.756080852594268 ) )
print( D1Q9_W_solved[0][5].subs(u1==0).subs(T_0==0.756080852594268 ) )
print( D1Q9_W_solved[0][6].subs(u1==0).subs(T_0==0.756080852594268 ) )
print( D1Q9_W_solved[0][7].subs(u1==0).subs(T_0==0.756080852594268 ) )
print( D1Q9_W_solved[0][8].subs(u1==0).subs(T_0==0.756080852594268 ) )


W0 == 0.458135155507677
W1 == 0.237342808577940
W2 == 0.237342808577940
W3 == 0.0323246537886549
W4 == 0.0323246537886549
W5 == 0.00126406215153651
W6 == 0.00126406215153651
W7 == (8.97728029819293e-7)
W8 == (8.97728029819293e-7)

In [548]:
V = [(0,),(1,),(-1,),(2,),(-2,),(3,),(-3,),(4,),(-4,),(5,),(-5,)]
D1Q11_W_sys, D1Q11_W_is = make_W_lin_sys(1,11,V,ORDER=10)

In [549]:
D1Q11_W_solved= W_sys_solver( D1Q11_W_sys, D1Q11_W_is)

In [550]:
for i in range(11):
    print( D1Q11_W_solved[0][i].subs(u1==0).subs(T_0==1.06279357749 ) )


W0 == 0.386938173756423
W1 == 0.241783399935941
W2 == 0.241783399935941
W3 == 0.0589224589534500
W4 == 0.0589224589534500
W5 == 0.00561525499547714
W6 == 0.00561525499547714
W7 == 0.000206524765228670
W8 == 0.000206524765228670
W9 == (3.27447169225388e-6)
W10 == (3.27447169225388e-6)

In [551]:
V = [(0,),(1,),(-1,),(2,),(-2,),(3,),(-3,),(4,),(-4,),(5,),(-5,),(7,),(-7,)]
D1Q13_W_sys, D1Q13_W_is = make_W_lin_sys(1,13,V,ORDER=12)

In [552]:
D1Q13_W_solved= W_sys_solver( D1Q13_W_sys, D1Q13_W_is)

In [554]:
for i in range(13):
    print( D1Q13_W_solved[0][i].subs(u1==0).subs(T_0==2.67428803233 ) )


W0 == 0.209277700019864
W1 == 0.233124580765899
W2 == 0.233124580765899
W3 == 0.0940510743102689
W4 == 0.0940510743102689
W5 == 0.0569233844131427
W6 == 0.0569233844131427
W7 == 0.00750076758077400
W8 == 0.00750076758077400
W9 == 0.00370055858049668
W10 == 0.00370055858049668
W11 == 0.0000607843394884751
W12 == 0.0000607843394884751

Analytical solution to quadratic system of equations, in terms of Lagrange multipliers, for minimizing the entropy $H$, while constraining for conservation laws (mass, momentum, energy), found in Ansumali, Karlin, Ottinger, Europhys. Lett., 63 (6), 2003, Minimal entropic kinetic models for hydrodynamics


In [ ]: