Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Mischa Dombrowski
lbmweights
Commits
0698e79c
Commit
0698e79c
authored
Sep 08, 2019
by
MischaD
Browse files
Solution Expected Function
parent
674eea74
Changes
2
Hide whitespace changes
Inline
Side-by-side
lbmweights/lattice.py
View file @
0698e79c
...
...
@@ -9,13 +9,13 @@ from .shell import Shell
class
Lattice
:
BY_NAME
=
{
"D2Q9"
:
{
"dimension"
:
2
,
"order"
:
4
,
"shell_list"
:
[
1
,
2
,
4
]},
"D2V17"
:
{
"dimension"
:
2
,
"order"
:
6
,
"shell_list"
:
[
1
,
2
,
4
,
8
,
9
]},
"D2V37"
:
{
"dimension"
:
2
,
"order"
:
8
,
"shell_list"
:
[
1
,
2
,
4
,
5
,
8
,
9
,
10
,
16
]},
"D3Q19"
:
{
"dimension"
:
3
,
"order"
:
4
,
"shell_list"
:
[
1
,
2
,
4
]},
"D3Q15"
:
{
"dimension"
:
3
,
"order"
:
4
,
"shell_list"
:
[
1
,
3
,
4
]},
BY_NAME
=
{
"D2Q9"
:
{
"dimension"
:
2
,
"order"
:
4
,
"shell_list"
:
[
1
,
2
,
4
]
,
"seed"
:
44
},
"D2V17"
:
{
"dimension"
:
2
,
"order"
:
6
,
"shell_list"
:
[
1
,
2
,
4
,
8
,
9
]
,
"seed"
:
44
},
"D2V37"
:
{
"dimension"
:
2
,
"order"
:
8
,
"shell_list"
:
[
1
,
2
,
4
,
5
,
8
,
9
,
10
,
16
]
,
"seed"
:
44
},
"D3Q19"
:
{
"dimension"
:
3
,
"order"
:
4
,
"shell_list"
:
[
1
,
2
,
4
]
,
"seed"
:
44
},
"D3Q15"
:
{
"dimension"
:
3
,
"order"
:
4
,
"shell_list"
:
[
1
,
3
,
4
]
,
"seed"
:
44
},
"D3Q41-ZOT"
:
{
"dimension"
:
3
,
"order"
:
6
,
"shell_list"
:
[
1
,
2
,
3
,
9
,
16
,
27
],
"boundary"
:
"sup"
,
"unwanted_subshells"
:
[
"221"
,
"511"
]},
"unwanted_subshells"
:
[
"221"
,
"511"
]
,
"seed"
:
44
},
}
def
__init__
(
self
,
dimension
=
2
,
order
=
4
,
shell_list
=
[
1
,
2
,
4
],
seed
=
None
,
boundary
=
None
,
unwanted_subshells
=
[],
svd_tolerance
=
1e-8
):
...
...
@@ -83,16 +83,16 @@ class Lattice:
return
string
@
classmethod
def
from_name
(
cls
,
name
,
seed
=
None
):
def
from_name
(
cls
,
name
):
"""Initiate the Lattice with the correct values corresponding to a know Lattice in literature.
A complete list can be seen in Lattice.BY_NAME.keys()"""
kwargs
=
cls
.
BY_NAME
.
get
(
name
)
if
not
kwargs
:
raise
ValueError
(
"No Lattice with this name is known or implemented"
)
return
cls
(
**
kwargs
,
seed
=
seed
)
return
cls
(
**
kwargs
)
@
classmethod
def
from_order
(
cls
,
dimension
,
order
,
seed
=
None
):
def
from_order
(
cls
,
dimension
,
order
):
"""
:param dimension:
:param order:
...
...
@@ -227,13 +227,16 @@ class Lattice:
reduced_rhs
[
i
,
:]
=
rhs
[
i
,
:]
/
singular_value
if
cols
-
rows
>
0
:
# TODO Better
raise
InfiniteSolutionsException
(
"Reduce order, remove shells, or use continue.py in "
"https://github.com/BDuenweg/Lattice-Boltzmann-weights"
)
self
.
_solution
=
np
.
dot
(
np
.
transpose
(
V
),
reduced_rhs
)
return
self
.
_solution
def
_calculate_coefficients
(
self
):
"""Use _all_velocity_vectors and _solution to calculate the coefficients of the
weigth polynomials. Writes them into _coefficients
"""
solution_columns
=
self
.
_order
//
2
coefficients
=
np
.
zeros
((
1
+
solution_columns
))
coefficients
[
0
]
=
1
...
...
@@ -275,8 +278,13 @@ class Lattice:
self
.
_interval
=
sp
.
Complement
(
interval
,
sp
.
FiniteSet
(
0
))
return
self
.
_interval
def
calculate_polynomials
(
self
):
c_s_sq
=
sp
.
Symbol
(
"c_s_sq"
)
def
solution_expected
(
self
):
"""Evaluate if the order, dimension and amount of shells entered are expected to retrieve a solution.
This is in no way a guarantee on the existence of a solution or whether or not the program
will finish successful, but it can be used as a quick hint on the existence of a solution.
Changes the state of self._solution and self._velocity vectors for future calculations."""
if
self
.
_order
%
2
==
1
:
self
.
_order
-=
1
logger
.
warning
(
"Only odd order valid. Decrease by one"
)
...
...
@@ -292,30 +300,32 @@ class Lattice:
self
.
_svd
()
self
.
_calculate_coefficients
()
return
self
.
_solution
is
not
None
apporx_coeffs
=
[[
approximate_ratio
(
x
)
for
x
in
pol_coffs
]
for
pol_coffs
in
self
.
_coefficients
]
def
calculate_polynomials
(
self
,
approximate
=
True
):
"""Main algorithm as proposed by D. Spiller and B Duenweg.
self
.
_weight_polynomials
=
[
sp
.
Poly
([
approximate_ratio
(
x
)
for
x
in
pol_coffs
],
c_s_sq
)
for
pol_coffs
in
self
.
_coefficients
]
if
not
self
.
_weight_polynomials
:
raise
NoSolutionException
(
"Something went wrong"
)
Divided into the part where the existence of a solution and calculated together with all the velocity
vectors. If one is expected the coefficients are calculated, the interval evaluated and the weight
polynomials returned.
self
.
_interval
=
self
.
_calculate_valid_interval
()
if
self
.
_interval
==
sp
.
EmptySet
():
return
[]
return
self
.
_weight_polynomials
:param approximate: Use python Fraction to approximate the calculated polynomial coefficients as rational
number. This should give better results, since they should have a rational representation.
def
calculate_reduced_weights
(
self
,
boundary
=
"inf"
):
"""
Calculate the weights of this lattice for a reduced model.
If the smallest or biggest value of the valid interval is taken, they reduce
the amount of shells necessary by one.
Overwrites the weight values in self.shell
:return: List of Sympy Polynomials."""
:param boundary: "inf" --> smallest possible value is taken, otherwise the largest
:return: list of weights in the order of their shells.
"""
return
self
.
calculate_weights
(
boundary
=
boundary
)
self
.
solution_expected
()
self
.
_calculate_coefficients
()
c_s_sq
=
sp
.
Symbol
(
"c_s_sq"
)
if
approximate
:
self
.
_weight_polynomials
=
[
sp
.
Poly
([
approximate_ratio
(
x
)
for
x
in
pol_coffs
],
c_s_sq
)
for
pol_coffs
in
self
.
_coefficients
]
else
:
self
.
_weight_polynomials
=
[
sp
.
Poly
(
pol_coffs
,
c_s_sq
)
for
pol_coffs
in
self
.
_coefficients
]
self
.
_interval
=
self
.
_calculate_valid_interval
()
return
[]
if
self
.
_interval
==
sp
.
EmptySet
else
self
.
_weight_polynomials
def
calculate_weights
(
self
,
c_s_sq
=
None
,
boundary
=
None
):
"""
...
...
@@ -330,7 +340,7 @@ class Lattice:
:param c_s_sq: Float value for the speed of sound, has to be inside of the valid interval
:param boundary: Get reduced model by using the infimum or supremum of the interval. Fallback value if
no c_s_sq is given
:return:
:return:
weights With zero weight(s) included
"""
if
not
self
.
_weight_polynomials
:
...
...
@@ -358,9 +368,11 @@ class Lattice:
def
velocity_set
(
self
):
"""
Returns the values that are important for the Lattice Boltzmann Model, i.e.
Removes unwanted shells, i.e. weight == = and
returns the values that are important for the Lattice Boltzmann Model, i.e.
a list of the velocity values their corresponding weights and the value for the speed of sound.
:return: (c_s_sq, weights, velocities): c_s_sq
:return: (c_s_sq, weights, velocities)
"""
if
not
self
.
weights
:
self
.
calculate_weights
()
...
...
test/test_lattice.py
View file @
0698e79c
...
...
@@ -4,6 +4,16 @@ from lbmweights import Lattice
from
lbmweights.utils.mylog
import
logger
class
SolutionExpected
(
unittest
.
TestCase
):
def
setUp
(
self
):
pass
def
test_solution_expected
(
self
):
for
name
,
lattice_args
in
Lattice
.
BY_NAME
.
items
():
lattice
=
Lattice
(
**
lattice_args
)
self
.
assertTrue
(
lattice
.
solution_expected
())
class
TestQ9
(
unittest
.
TestCase
):
def
setUp
(
self
):
self
.
seed
=
20
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment