diff --git a/python/damask/__init__.py b/python/damask/__init__.py index 684ab48b5..c5677aaf5 100644 --- a/python/damask/__init__.py +++ b/python/damask/__init__.py @@ -18,7 +18,7 @@ from .dadf5 import DADF5 # noqa #from .block import Block # only one class from .result import Result # noqa -from .geometry import Geometry # noqa +from .geom import Geom # noqa from .solver import Solver # noqa from .test import Test # noqa from .util import extendableOption # noqa diff --git a/python/damask/geom.py b/python/damask/geom.py new file mode 100644 index 000000000..c1a119ca0 --- /dev/null +++ b/python/damask/geom.py @@ -0,0 +1,133 @@ +import numpy as np +import math +from io import StringIO +import io + +class Geom(): + + def __init__(self,size,microstructure,homogenization=1,comments=[]): + """Geometry definition for grid solvers""" + + if len(size) != 3 or any(np.array(size)<=0): + raise ValueError('invalid size') + else: + self.size = np.array(size) + + if len(microstructure.shape) != 3: + raise ValueError('invalid microstructure') + else: + self.microstructure = microstructure + + if not isinstance(homogenization,int) or homogenization < 1: + raise ValueError('invalid homogenization') + else: + self.homogenization = homogenization + + if not isinstance(comments,list): + self.comments = [str(comments)] + else: + self.comments = [str(comment) for comment in comments] + + def __repr__(self): + f=StringIO() + self.to_file(f) + f.seek(0) + return ''.join(f.readlines()) + + def add_comment(self,comment): + if not isinstance(comment,list): + self.comments += [str(comment)] + else: + self.comments += [str(c) for c in comment] + + def set_size(self,size): + self.size = np.array(size) + + def get_size(self): + return self.size + + def get_grid(self): + return np.array(self.microstructure.shape) + + def get_homogenization(self): + return self.homogenization + + @classmethod + def from_file(cls,fname): + if isinstance(fname,str): + with open(fname) as f: + header_length = int(f.readline().split()[0]) + comments_old = [f.readline() for i in range(header_length)] + else: + fname.seek(0) + header_length = int(fname.readline().split()[0]) + comments_old = [fname.readline() for i in range(header_length)] + + comments = [] + for i,line in enumerate(comments_old): + if line.lower().strip().startswith('grid'): + grid = np.array([int(line.split()[j]) for j in [2,4,6]]) # assume correct order (a,b,c) + elif line.lower().strip().startswith('size'): + size = np.array([float(line.split()[j]) for j in [2,4,6]]) # assume correct order (x,y,z) + elif line.lower().strip().startswith('homogenization'): + homogenization = int(line.split()[1]) + else: + comments.append(line[:-1]) + + try: + if isinstance(fname,io.TextIOWrapper) or isinstance(fname,io.StringIO): + fname.seek(0) + microstructure = np.loadtxt(fname,skiprows=header_length+1) + if np.any(np.mod(microstructure.flatten(),1)!=0.0): + pass + else: + microstructure = microstructure.astype('int') + except: # has 'to' and 'of' compression + if isinstance(fname,str): + with open(fname) as f: + raw = f.readlines()[header_length+1:] + else: + fname.seek(0) + raw = fname.readlines()[header_length+1:] + + microstructure = np.empty(grid.prod()) # initialize as flat array + i = 0 + + for line in raw: + items = line.split() + if len(items) == 3: + if items[1].lower() == 'of': + items = np.ones(int(items[0]))*int(items[2]) + elif items[1].lower() == 'to': + items = np.linspace(int(items[0]),int(items[2]), + abs(int(items[2])-int(items[0]))+1,dtype=int) + else: items = list(map(int,items)) + else: items = list(map(int,items)) + + microstructure[i:i+len(items)] = items + i += len(items) + microstructure = microstructure.reshape(grid,order='F') + + return cls(size,microstructure.reshape(grid),homogenization,comments) + + def to_file(self,fname): + grid = self.get_grid() + header = ['{} header'.format(len(self.comments)+3)] + header += self.comments + header.append('grid a {} b {} c {}'.format(*grid)) + header.append('size a {} b {} c {}'.format(*self.get_size())) + header.append('homogenization {}'.format(self.get_homogenization())) + if self.microstructure.dtype == 'int': + format_string='%{}i'.format(int(math.floor(math.log10(self.microstructure.max())+1))) + else: + format_string='%.18e' + np.savetxt(fname, self.microstructure.reshape([np.prod(grid[1:]),grid[0]],order='F'), + header='\n'.join(header), fmt=format_string, comments='') + + def info(self): + return ['grid a b c: {}'.format(' x '.join(map(str,self.get_grid()))), + 'size x y z: {}'.format(' x '.join(map(str,self.get_size()))), + 'homogenization: {}'.format(self.get_homogenization()), + '# microstructures: {}'.format(len(np.unique(self.microstructure))), + 'max microstructures: {}'.format(np.max(self.microstructure)), + ] diff --git a/python/damask/geometry/__init__.py b/python/damask/geometry/__init__.py deleted file mode 100644 index 51199965b..000000000 --- a/python/damask/geometry/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# -*- coding: UTF-8 no BOM -*- - -"""Aggregator for geometry handling""" - -from .geometry import Geometry # noqa -from .spectral import Spectral # noqa -from .marc import Marc # noqa diff --git a/python/damask/geometry/geometry.py b/python/damask/geometry/geometry.py deleted file mode 100644 index 0976299e3..000000000 --- a/python/damask/geometry/geometry.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: UTF-8 no BOM -*- - - -import damask.geometry - -class Geometry(): - """ - General class for geometry parsing. - - Sub-classed by the individual solvers. - """ - - def __init__(self,solver=''): - solverClass = { - 'spectral': damask.geometry.Spectral, - 'marc': damask.geometry.Marc, - } - if solver.lower() in list(solverClass.keys()): - self.__class__=solverClass[solver.lower()] - self.__init__() - diff --git a/python/damask/geometry/marc.py b/python/damask/geometry/marc.py deleted file mode 100644 index 405227664..000000000 --- a/python/damask/geometry/marc.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: UTF-8 no BOM -*- - - -from .geometry import Geometry - -class Marc(Geometry): - - def __init__(self): - self.solver='Marc' diff --git a/python/damask/geometry/spectral.py b/python/damask/geometry/spectral.py deleted file mode 100644 index 0e4f19399..000000000 --- a/python/damask/geometry/spectral.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: UTF-8 no BOM -*- - - -from .geometry import Geometry - -class Spectral(Geometry): - - def __init__(self): - self.solver='Spectral'