Merge branch 'XDMF-improvements' into 'development'
Xdmf improvements See merge request damask/DAMASK!293
This commit is contained in:
commit
5726f0bce9
2
PRIVATE
2
PRIVATE
|
@ -1 +1 @@
|
||||||
Subproject commit 751f96155294e449b31c5d4913fea7bc02ce81b1
|
Subproject commit 68cde52291ebb683ca6f610879f2ae28372597a7
|
|
@ -61,7 +61,7 @@ class Result:
|
||||||
self.increments = [increments_unsorted[i] for i in sorted(increments_unsorted)]
|
self.increments = [increments_unsorted[i] for i in sorted(increments_unsorted)]
|
||||||
self.times = [round(f[i].attrs['time/s'],12) for i in self.increments]
|
self.times = [round(f[i].attrs['time/s'],12) for i in self.increments]
|
||||||
|
|
||||||
self.N_materialpoints, self.N_constituents = np.shape(f['mapping/phase'])
|
self.N_materialpoints, self.N_constituents = np.shape(f['mapping/phase'])
|
||||||
|
|
||||||
self.homogenizations = [m.decode() for m in np.unique(f['mapping/homogenization']['Name'])]
|
self.homogenizations = [m.decode() for m in np.unique(f['mapping/homogenization']['Name'])]
|
||||||
self.phases = [c.decode() for c in np.unique(f['mapping/phase']['Name'])]
|
self.phases = [c.decode() for c in np.unique(f['mapping/phase']['Name'])]
|
||||||
|
@ -1176,8 +1176,17 @@ class Result:
|
||||||
This works only for scalar, 3-vector and 3x3-tensor data.
|
This works only for scalar, 3-vector and 3x3-tensor data.
|
||||||
Selection is not taken into account.
|
Selection is not taken into account.
|
||||||
"""
|
"""
|
||||||
if self.N_constituents != 1 or not self.structured:
|
if self.N_constituents != 1 or len(self.phases) != 1 or not self.structured:
|
||||||
raise NotImplementedError('XDMF only available for grid results with 1 constituent.')
|
raise TypeError('XDMF output requires homogeneous grid')
|
||||||
|
|
||||||
|
|
||||||
|
attribute_type_map = defaultdict(lambda:'Matrix', ( ((),'Scalar'), ((3,),'Vector'), ((3,3),'Tensor')) )
|
||||||
|
|
||||||
|
def number_type_map(dtype):
|
||||||
|
if dtype in np.sctypes['int']: return 'Int'
|
||||||
|
if dtype in np.sctypes['uint']: return 'UInt'
|
||||||
|
if dtype in np.sctypes['float']: return 'Float'
|
||||||
|
|
||||||
|
|
||||||
xdmf=ET.Element('Xdmf')
|
xdmf=ET.Element('Xdmf')
|
||||||
xdmf.attrib={'Version': '2.0',
|
xdmf.attrib={'Version': '2.0',
|
||||||
|
@ -1227,8 +1236,6 @@ class Result:
|
||||||
delta.text="{} {} {}".format(*(self.size/self.grid))
|
delta.text="{} {} {}".format(*(self.size/self.grid))
|
||||||
|
|
||||||
|
|
||||||
type_map = defaultdict(lambda:'Matrix', ( ((),'Scalar'), ((3,),'Vector'), ((3,3),'Tensor')) )
|
|
||||||
|
|
||||||
with h5py.File(self.fname,'r') as f:
|
with h5py.File(self.fname,'r') as f:
|
||||||
attributes.append(ET.SubElement(grid, 'Attribute'))
|
attributes.append(ET.SubElement(grid, 'Attribute'))
|
||||||
attributes[-1].attrib={'Name': 'u / m',
|
attributes[-1].attrib={'Name': 'u / m',
|
||||||
|
@ -1249,18 +1256,17 @@ class Result:
|
||||||
shape = f[name].shape[1:]
|
shape = f[name].shape[1:]
|
||||||
dtype = f[name].dtype
|
dtype = f[name].dtype
|
||||||
|
|
||||||
if dtype != np.float64: continue
|
if dtype not in np.sctypes['int']+np.sctypes['uint']+np.sctypes['float']: continue
|
||||||
prec = f[name].dtype.itemsize
|
|
||||||
unit = f[name].attrs['Unit'] if h5py3 else f[name].attrs['Unit'].decode()
|
unit = f[name].attrs['Unit'] if h5py3 else f[name].attrs['Unit'].decode()
|
||||||
|
|
||||||
attributes.append(ET.SubElement(grid, 'Attribute'))
|
attributes.append(ET.SubElement(grid, 'Attribute'))
|
||||||
attributes[-1].attrib={'Name': name.split('/',2)[2]+f' / {unit}',
|
attributes[-1].attrib={'Name': name.split('/',2)[2]+f' / {unit}',
|
||||||
'Center': 'Cell',
|
'Center': 'Cell',
|
||||||
'AttributeType': type_map[shape]}
|
'AttributeType': attribute_type_map[shape]}
|
||||||
data_items.append(ET.SubElement(attributes[-1], 'DataItem'))
|
data_items.append(ET.SubElement(attributes[-1], 'DataItem'))
|
||||||
data_items[-1].attrib={'Format': 'HDF',
|
data_items[-1].attrib={'Format': 'HDF',
|
||||||
'NumberType': 'Float',
|
'NumberType': number_type_map(dtype),
|
||||||
'Precision': f'{prec}',
|
'Precision': f'{dtype.itemsize}',
|
||||||
'Dimensions': '{} {} {} {}'.format(*self.grid,1 if shape == () else
|
'Dimensions': '{} {} {} {}'.format(*self.grid,1 if shape == () else
|
||||||
np.prod(shape))}
|
np.prod(shape))}
|
||||||
data_items[-1].text=f'{os.path.split(self.fname)[1]}:{name}'
|
data_items[-1].text=f'{os.path.split(self.fname)[1]}:{name}'
|
||||||
|
@ -1269,7 +1275,7 @@ class Result:
|
||||||
f.write(xml.dom.minidom.parseString(ET.tostring(xdmf).decode()).toprettyxml())
|
f.write(xml.dom.minidom.parseString(ET.tostring(xdmf).decode()).toprettyxml())
|
||||||
|
|
||||||
|
|
||||||
def save_vtk(self,labels=[],mode='cell'):
|
def save_VTK(self,labels=[],mode='cell'):
|
||||||
"""
|
"""
|
||||||
Export to vtk cell/point data.
|
Export to vtk cell/point data.
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -366,13 +366,24 @@ class TestResult:
|
||||||
@pytest.mark.parametrize('output',['F',[],['F','P']])
|
@pytest.mark.parametrize('output',['F',[],['F','P']])
|
||||||
def test_vtk(self,tmp_path,default,output):
|
def test_vtk(self,tmp_path,default,output):
|
||||||
os.chdir(tmp_path)
|
os.chdir(tmp_path)
|
||||||
default.save_vtk(output)
|
default.save_VTK(output)
|
||||||
|
|
||||||
@pytest.mark.parametrize('mode',['point','cell'])
|
@pytest.mark.parametrize('mode',['point','cell'])
|
||||||
def test_vtk_mode(self,tmp_path,single_phase,mode):
|
def test_vtk_mode(self,tmp_path,single_phase,mode):
|
||||||
os.chdir(tmp_path)
|
os.chdir(tmp_path)
|
||||||
single_phase.save_vtk(mode=mode)
|
single_phase.save_VTK(mode=mode)
|
||||||
|
|
||||||
def test_XDMF(self,tmp_path,single_phase):
|
def test_XDMF(self,tmp_path,single_phase,update,reference_dir):
|
||||||
|
for shape in [('scalar',()),('vector',(3,)),('tensor',(3,3)),('matrix',(12,))]:
|
||||||
|
for dtype in ['f4','f8','i1','i2','i4','i8','u1','u2','u4','u8']:
|
||||||
|
single_phase.add_calculation(f'{shape[0]}_{dtype}',f"np.ones(np.shape(#F#)[0:1]+{shape[1]},'{dtype}')")
|
||||||
|
fname = os.path.splitext(os.path.basename(single_phase.fname))[0]+'.xdmf'
|
||||||
os.chdir(tmp_path)
|
os.chdir(tmp_path)
|
||||||
single_phase.save_XDMF()
|
single_phase.save_XDMF()
|
||||||
|
if update:
|
||||||
|
shutil.copy(tmp_path/fname,reference_dir/fname)
|
||||||
|
assert sorted(open(tmp_path/fname).read()) == sorted(open(reference_dir/fname).read()) # XML is not ordered
|
||||||
|
|
||||||
|
def test_XDMF_invalid(self,default):
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
default.save_XDMF()
|
||||||
|
|
Loading…
Reference in New Issue