Commit 91e544e6 authored by MischaD's avatar MischaD
Browse files

Analyse Tensor Rank and getgroup

parent 43601b92
import click
import re
from lbmweights.lattice import Lattice
from lbmweights.utils.mylog import logger
@click.group()
......@@ -16,9 +17,7 @@ def main():
def lbmweights(dimension, order, shells, seed):
shell_list = [int(x) for x in re.findall(u"\d+", shells)]
l = Lattice(dimension=dimension, order=order, shell_list=shell_list, seed=seed)
print(l)
l = Lattice.init_by_order(dimension=2, order=6)
print(l)
l.calculate_weights()
if __name__ == "__main__":
main()
......
class OrderNotImplementedException(Exception):
"""Order in classmethod of Lattice not implemented
"""
pass
class ImpossibleVelocityShellException(Exception):
"""No velocity sets could be constructed. Only positive integer possible
"""
pass
\ No newline at end of file
import numpy as np
from lbmweights.utils.mylog import logger
from .exceptions import OrderNotImplementedException
from .exceptions import OrderNotImplementedException, ImpossibleVelocityShellException
from .utils.utils import analyse_tensor_dimension, get_group
class Lattice:
......@@ -10,13 +12,14 @@ class Lattice:
:param shell_list:
:param seed:
"""
logger.info("Okay")
self._dimensions = dimension
self._order = order
self._shell_list = shell_list
self._seed = seed
self._tensor_space_dimension = 0
self._possible_tensors = []
def __str__(self):
string = "D{} - Order: {} - Shells: {}".format(
self._dimensions, self._order, str(self._shell_list)
......@@ -53,3 +56,60 @@ class Lattice:
)
return cls(dimension=dimension, order=order, shell_list=shell_list, seed=seed)
@property
def tensor_space_dimension(self):
return np.array([len(x) for x in self._possible_tensors]).sum()
@staticmethod
def velocities_for_shell(dimension, shell):
"""
:param dimension: Lattice dimension
:param shell: Squared velocity of the shell
:return: list of velocities with squared length equal to shell
"""
velocities = []
linear_lattice_size = 2 * shell + 1
full_lattice_size = linear_lattice_size ** dimension
for site in range(full_lattice_size):
tmp = site
cur_vel_squared = 0
cur_vec = []
for dim in range(dimension):
coordinate = tmp % linear_lattice_size
tmp = (tmp - coordinate) // linear_lattice_size
shifted_coordinate = coordinate - shell
cur_vec.append(shifted_coordinate)
cur_vel_squared += shifted_coordinate ** 2
if cur_vel_squared == shell:
velocities.append(np.array(cur_vec, dtype=int))
return velocities
def calculate_weights(self):
logger.debug("Entering Calculate Weights")
logger.info(str(self))
if self._order % 2 == 1:
self._order -= 1
logger.warning("Odd order for isotropy entered. This package only handles symmetric lattices, therefore"
"the equations for odd orders are automatically fulfilled. "
"Reduction of order to {}".format(self._order))
# Do tensor dimension analysis for every order up to the desired
for k in np.arange(2, self._order + 2, 2):
possible_tensors = analyse_tensor_dimension(k)
self._possible_tensors.append(possible_tensors)
################################################
velocities_amount = 1
grand_total_list = []
subshells = []
group = get_group(self._dimensions) # TODO test output
for shell in range(len(self._shell_list)):
velocities = self.velocities_for_shell(dimension=self._dimensions, shell=self._shell_list[shell])
if len(velocities) == 0:
raise ImpossibleVelocityShellException("No velocity sets found for velocity shell {}".format(shell))
#getlist of subshells
......@@ -17,4 +17,7 @@ ch.setFormatter(formatter)
# fh.setFormatter(formatter)
logger = logging.getLogger("LBMweights")
logger.setLevel(logging.DEBUG)
log_levels = dict(debug=logging.DEBUG, info=logging.INFO, warning=logging.WARNING)
import itertools
import numpy as np
import math
def analyse_tensor_dimension(tensor_rank):
"""
:param tensor_rank:
:return:
"""
first_entry = tensor_rank
first_entries = [tensor_rank]
possible_tensors = [first_entries]
while first_entry > 2:
first_entry = first_entry - 2
first_entries = [first_entry]
rest = tensor_rank - first_entry
reduced_possible_tensors = analyse_tensor_dimension(rest)
reduced_tensor_dimension = len(reduced_possible_tensors)
for i in range(reduced_tensor_dimension):
if reduced_possible_tensors[i][0] <= first_entry:
possible_tensors.append(first_entries + reduced_possible_tensors[i])
return possible_tensors
def get_group(dimension):
def to_matrix(arr):
"""Convert an array of unit vectors to proper matrix."""
dim = len(arr)
M = np.zeros((dim, dim), dtype=np.int8)
for col in range(dim):
Row = arr[col] - 1
M[Row][col] = 1
return M
unit_vectors = np.arange(1, dimension + 1)
permutations = itertools.permutations(unit_vectors, dimension)
sign_combinations = np.zeros((2**dimension, dimension))
format_ = "0{}b".format(dimension)
for i in range(2**dimension):
binary = format(i, format_)
sign_combinations[i] = np.array([2*int(binary[j]) - 1 for j in range(dimension)])
group = []
for permutation in permutations:
M = to_matrix(permutation)
for sign_combination in sign_combinations:
group.append(np.multiply(sign_combination, M))
transformation_amount = np.math.factorial(dimension) * 2 ** dimension
assert len(group) == transformation_amount # Todo Exception
return group
import unittest
from lbmweights.lattice import Lattice
class TestAnalyzeTensorDimensions(unittest.TestCase):
def setUp(self):
self.lattice2 = Lattice(dimension=2, order=2, shell_list=[1,2,4])
self.lattice4 = Lattice(dimension=2, order=4, shell_list=[1,2,4])
self.lattice6 = Lattice(dimension=2, order=6, shell_list=[1,2,4])
self.lattice8 = Lattice(dimension=2, order=8, shell_list=[1,2,4])
def test_analyze_tensor_dimensions(self):
self.lattice2.calculate_weights()
self.assertTrue(self.lattice2._possible_tensors == [[[2]]])
self.lattice4.calculate_weights()
self.assertTrue(self.lattice4._possible_tensors == [[[2]], [[4], [2,2]]])
self.lattice6.calculate_weights()
self.assertTrue(self.lattice6._possible_tensors == [[[2]], [[4], [2, 2]], [[6], [4,2],[2,2,2]]])
self.lattice8.calculate_weights()
self.assertTrue(self.lattice8._possible_tensors == [[[2]], [[4], [2, 2]], [[6], [4,2],[2,2,2]], [[8],[6,2],[4,4],[4,2,2],[2,2,2,2]]])
if __name__ == "__main__":
unittest.main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment