diff --git a/python/.coveragerc b/python/.coveragerc index 5daa25bb2..97114fb82 100644 --- a/python/.coveragerc +++ b/python/.coveragerc @@ -2,4 +2,3 @@ omit = tests/* damask/_asciitable.py damask/_test.py - damask/config/* diff --git a/python/damask/__init__.py b/python/damask/__init__.py index b0feee4ac..1404e88d1 100644 --- a/python/damask/__init__.py +++ b/python/damask/__init__.py @@ -24,5 +24,4 @@ from . import solver # noqa Environment = _ from ._asciitable import ASCIItable # noqa from ._test import Test # noqa -from .config import Material # noqa from .util import extendableOption # noqa diff --git a/python/damask/config/__init__.py b/python/damask/config/__init__.py deleted file mode 100644 index f5c57a879..000000000 --- a/python/damask/config/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -"""Aggregator for configuration file handling.""" - -from .material import Material # noqa diff --git a/python/damask/config/material.py b/python/damask/config/material.py deleted file mode 100644 index 433c70d03..000000000 --- a/python/damask/config/material.py +++ /dev/null @@ -1,282 +0,0 @@ -import re -import os - -from damask import util - -class Section(): - def __init__(self,data = {'__order__':[]},part = ''): - """New material.config section.""" - classes = { - 'homogenization':Homogenization, - 'microstructure':Microstructure, - 'crystallite':Crystallite, - 'phase':Phase, - 'texture':Texture, - } - self.parameters = {} - for key in data: - self.parameters[key] = data[key] if isinstance(data[key], list) else [data[key]] - - if '__order__' not in self.parameters: - self.parameters['__order__'] = list(self.parameters.keys()) - if part.lower() in classes: - self.__class__ = classes[part.lower()] - self.__init__(data) - - def add_multiKey(self,key,data): - multiKey = '(%s)'%key - if multiKey not in self.parameters: self.parameters[multiKey] = [] - if multiKey not in self.parameters['__order__']: self.parameters['__order__'] += [multiKey] - self.parameters[multiKey] += [[item] for item in data] if isinstance(data, list) else [[data]] - - def data(self): - return self.parameters - - -class Homogenization(Section): - def __init__(self,data = {'__order__':[]}): - """New material.config section.""" - Section.__init__(self,data) - - -class Crystallite(Section): - def __init__(self,data = {'__order__':[]}): - """New material.config section.""" - Section.__init__(self,data) - - -class Phase(Section): - def __init__(self,data = {'__order__':[]}): - """New material.config section.""" - Section.__init__(self,data) - - -class Microstructure(Section): - def __init__(self,data = {'__order__':[]}): - """New material.config section.""" - Section.__init__(self,data) - - -class Texture(Section): - def __init__(self,data = {'__order__':[]}): - """New material.config section.""" - Section.__init__(self,data) - - def add_component(self,theType,properties): - - scatter = properties['scatter'] if 'scatter' in list(map(str.lower,list(properties.keys()))) else 0.0 - fraction = properties['fraction'] if 'fraction' in list(map(str.lower,list(properties.keys()))) else 1.0 - - try: - multiKey = theType.lower() - except AttributeError: - pass - - if multiKey == 'gauss': - self.add_multiKey(multiKey,'phi1 %g\tPhi %g\tphi2 %g\tscatter %g\tfraction %g'%( - properties['eulers'][0], - properties['eulers'][1], - properties['eulers'][2], - scatter, - fraction, - ) - ) - - -class Material(): - """Read, manipulate, and write material.config files.""" - - def __init__(self,verbose=True): - """Generates ordered list of parts.""" - self.parts = [ - 'homogenization', - 'crystallite', - 'phase', - 'texture', - 'microstructure', - ] - self.data = { - 'homogenization': {'__order__': []}, - 'microstructure': {'__order__': []}, - 'crystallite': {'__order__': []}, - 'phase': {'__order__': []}, - 'texture': {'__order__': []}, - } - self.verbose = verbose - - def __repr__(self): - """Returns current data structure in material.config format.""" - me = [] - for part in self.parts: - if self.verbose: print(f'processing <{part}>') - me += ['', - '#'*100, - f'<{part}>', - '#'*100, - ] - for section in self.data[part]['__order__']: - me += [f'[{section}] {"#"+"-"*max(0,96-len(section))}'] - for key in self.data[part][section]['__order__']: - if key.startswith('(') and key.endswith(')'): # multiple (key) - me += [f'{key}\t{" ".join(values)}' for values in self.data[part][section][key]] - else: # plain key - me += [f'{key}\t{util.srepr(self.data[part][section][key]," ")}'] - return '\n'.join(me) + '\n' - - def parse(self, part=None, sections=[], content=None): - - re_part = re.compile(r'^<(.+)>$') # pattern for part - re_sec = re.compile(r'^\[(.+)\]$') # pattern for section - - name_section = '' - active = False - - for line in content: - line = line.split('#')[0].strip() # kill comments and extra whitespace - line = line.split('/echo/')[0].strip() # remove '/echo/' tags - line = line.lower() # be case insensitive - - if line: # content survives... - match_part = re_part.match(line) - if match_part: # found <...> separator - active = (match_part.group(1) == part) # only active in - continue - if active: - match_sec = re_sec.match(line) - if match_sec: # found [section] - name_section = match_sec.group(1) # remember name ... - if '__order__' not in self.data[part]: self.data[part]['__order__'] = [] - self.data[part]['__order__'].append(name_section) # ... and position - self.data[part][name_section] = {'__order__':[]} - continue - - if sections == [] or name_section in sections: # possibly restrict to subset - items = line.split() - if items[0] not in self.data[part][name_section]: # first encounter of key? - self.data[part][name_section][items[0]] = [] # create item - self.data[part][name_section]['__order__'].append(items[0]) - if items[0].startswith('(') and items[0].endswith(')'): # multiple "(key)" - self.data[part][name_section][items[0]].append(items[1:]) - else: # plain key - self.data[part][name_section][items[0]] = items[1:] - - - - def read(self,filename=None): - """Read material.config file.""" - def recursiveRead(filename): - """Takes care of include statements like '{}'.""" - result = [] - re_include = re.compile(r'^{(.+)}$') - with open(filename) as f: lines = f.readlines() - for line in lines: - match = re_include.match(line.split()[0]) if line.strip() else False - result += [line] if not match else \ - recursiveRead(match.group(1) if match.group(1).startswith('/') else - os.path.normpath(os.path.join(os.path.dirname(filename),match.group(1)))) - return result - - c = recursiveRead(filename) - for p in self.parts: - self.parse(part=p, content=c) - - def write(self,filename='material.config', overwrite=False): - """Write to material.config.""" - i = 0 - outname = filename - while os.path.exists(outname) and not overwrite: - i += 1 - outname = f'{filename}_{i}' - - if self.verbose: print(f'Writing material data to {outname}') - with open(outname,'w') as f: - f.write(str(self)) - return outname - - def add_section(self, part=None, section=None, initialData=None, merge=False): - """Add Update.""" - part = part.lower() - section = section.lower() - if part not in self.parts: raise Exception(f'invalid part {part}') - - if not isinstance(initialData, dict): - initialData = initialData.data() - - if section not in self.data[part]: self.data[part]['__order__'] += [section] - if section in self.data[part] and merge: - for existing in self.data[part][section]['__order__']: # replace existing - if existing in initialData['__order__']: - if existing.startswith('(') and existing.endswith(')'): # multiple (key) - self.data[part][section][existing] += initialData[existing] # add new multiple entries to existing ones - else: # regular key - self.data[part][section][existing] = initialData[existing] # plain replice - for new in initialData['__order__']: # merge new content - if new not in self.data[part][section]['__order__']: - self.data[part][section][new] = initialData[new] - self.data[part][section]['__order__'] += [new] - else: - self.data[part][section] = initialData - - - - - def add_microstructure(self, section='', - components={}, # dict of phase,texture, and fraction lists - ): - """Experimental! Needs expansion to multi-constituent microstructures...""" - microstructure = Microstructure() - # make keys lower case (http://stackoverflow.com/questions/764235/dictionary-to-lowercase-in-python) - components=dict((k.lower(), v) for k,v in components.items()) - - for key in ['phase','texture','fraction','crystallite']: - if isinstance(components[key], list): - for i, x in enumerate(components[key]): - try: - components[key][i] = x.lower() - except AttributeError: - pass - else: - try: - components[key] = [components[key].lower()] - except AttributeError: - components[key] = [components[key]] - - for (phase,texture,fraction,crystallite) in zip(components['phase'],components['texture'], - components['fraction'],components['crystallite']): - microstructure.add_multiKey('constituent','phase %i\ttexture %i\tfraction %g\ncrystallite %i'%( - self.data['phase']['__order__'].index(phase)+1, - self.data['texture']['__order__'].index(texture)+1, - fraction, - self.data['crystallite']['__order__'].index(crystallite)+1)) - - self.add_section('microstructure',section,microstructure) - - - def change_value(self, part=None, - section=None, - key=None, - value=None): - if not isinstance(value,list): - if not isinstance(value,str): - value = '%s'%value - value = [value] - newlen = len(value) - oldval = self.data[part.lower()][section.lower()][key.lower()] - oldlen = len(oldval) - print('changing %s:%s:%s from %s to %s '%(part.lower(),section.lower(),key.lower(),oldval,value)) - self.data[part.lower()][section.lower()][key.lower()] = value - if newlen is not oldlen: - print('Length of value was changed from %i to %i!'%(oldlen,newlen)) - - - def add_value(self, part=None, - section=None, - key=None, - value=None): - if not isinstance(value,list): - if not isinstance(value,str): - value = '%s'%value - value = [value] - print('adding %s:%s:%s with value %s '%(part.lower(),section.lower(),key.lower(),value)) - self.data[part.lower()][section.lower()][key.lower()] = value - self.data[part.lower()][section.lower()]['__order__'] += [key.lower()]