2021-04-01 17:17:27 +05:30
|
|
|
import bz2
|
|
|
|
import pickle
|
2020-05-26 02:35:31 +05:30
|
|
|
import time
|
2019-11-23 23:28:44 +05:30
|
|
|
import shutil
|
|
|
|
import os
|
2020-07-31 20:34:14 +05:30
|
|
|
import sys
|
2021-04-03 11:01:31 +05:30
|
|
|
import hashlib
|
2020-05-26 02:35:31 +05:30
|
|
|
from datetime import datetime
|
2019-11-23 23:28:44 +05:30
|
|
|
|
|
|
|
import pytest
|
2021-06-19 00:41:01 +05:30
|
|
|
import vtk
|
2019-11-23 23:28:44 +05:30
|
|
|
import numpy as np
|
|
|
|
|
2020-03-03 03:35:35 +05:30
|
|
|
from damask import Result
|
2020-08-24 10:58:10 +05:30
|
|
|
from damask import Rotation
|
|
|
|
from damask import Orientation
|
2020-11-16 03:44:46 +05:30
|
|
|
from damask import tensor
|
2019-11-23 23:28:44 +05:30
|
|
|
from damask import mechanics
|
2020-07-31 20:20:01 +05:30
|
|
|
from damask import grid_filters
|
2019-11-23 23:28:44 +05:30
|
|
|
|
|
|
|
@pytest.fixture
|
2020-11-30 01:20:41 +05:30
|
|
|
def default(tmp_path,ref_path):
|
2020-03-03 03:35:35 +05:30
|
|
|
"""Small Result file in temp location for modification."""
|
2019-11-23 23:28:44 +05:30
|
|
|
fname = '12grains6x7x8_tensionY.hdf5'
|
2020-11-30 01:20:41 +05:30
|
|
|
shutil.copy(ref_path/fname,tmp_path)
|
2020-07-31 20:20:01 +05:30
|
|
|
f = Result(tmp_path/fname)
|
2021-04-05 11:23:19 +05:30
|
|
|
return f.view('times',20.0)
|
2019-11-23 23:28:44 +05:30
|
|
|
|
2020-05-26 11:36:39 +05:30
|
|
|
@pytest.fixture
|
2020-11-30 01:20:41 +05:30
|
|
|
def single_phase(tmp_path,ref_path):
|
2020-05-26 11:36:39 +05:30
|
|
|
"""Single phase Result file in temp location for modification."""
|
|
|
|
fname = '6grains6x7x8_single_phase_tensionY.hdf5'
|
2020-11-30 01:20:41 +05:30
|
|
|
shutil.copy(ref_path/fname,tmp_path)
|
2020-07-31 20:20:01 +05:30
|
|
|
return Result(tmp_path/fname)
|
2020-05-26 11:36:39 +05:30
|
|
|
|
2019-11-23 23:28:44 +05:30
|
|
|
@pytest.fixture
|
2020-11-30 01:20:41 +05:30
|
|
|
def ref_path(ref_path_base):
|
2019-11-27 17:49:58 +05:30
|
|
|
"""Directory containing reference results."""
|
2020-11-30 01:20:41 +05:30
|
|
|
return ref_path_base/'Result'
|
2019-11-23 23:28:44 +05:30
|
|
|
|
2021-04-01 17:17:27 +05:30
|
|
|
def dict_equal(d1, d2):
|
|
|
|
for k in d1:
|
|
|
|
if (k not in d2):
|
|
|
|
return False
|
|
|
|
else:
|
|
|
|
if type(d1[k]) is dict:
|
|
|
|
return dict_equal(d1[k],d2[k])
|
|
|
|
else:
|
|
|
|
if not np.allclose(d1[k],d2[k]):
|
|
|
|
return False
|
|
|
|
return True
|
2019-11-23 23:28:44 +05:30
|
|
|
|
2020-03-03 03:35:35 +05:30
|
|
|
class TestResult:
|
2019-12-04 10:29:52 +05:30
|
|
|
|
2020-04-21 14:47:15 +05:30
|
|
|
def test_self_report(self,default):
|
|
|
|
print(default)
|
|
|
|
|
|
|
|
|
2021-01-13 19:27:58 +05:30
|
|
|
def test_view_all(self,default):
|
2021-04-06 21:09:44 +05:30
|
|
|
a = default.view('increments',True).get('F')
|
2021-04-03 16:41:20 +05:30
|
|
|
|
2021-04-06 21:09:44 +05:30
|
|
|
assert dict_equal(a,default.view('increments','*').get('F'))
|
|
|
|
assert dict_equal(a,default.view('increments',default.increments_in_range(0,np.iinfo(int).max)).get('F'))
|
2020-05-23 14:08:25 +05:30
|
|
|
|
2021-04-06 21:09:44 +05:30
|
|
|
assert dict_equal(a,default.view('times',True).get('F'))
|
|
|
|
assert dict_equal(a,default.view('times','*').get('F'))
|
|
|
|
assert dict_equal(a,default.view('times',default.times_in_range(0.0,np.inf)).get('F'))
|
2020-05-23 14:08:25 +05:30
|
|
|
|
2021-04-10 13:05:10 +05:30
|
|
|
@pytest.mark.parametrize('what',['increments','times','phases','fields']) # ToDo: discuss homogenizations
|
2021-01-13 19:27:58 +05:30
|
|
|
def test_view_none(self,default,what):
|
2021-04-10 13:05:10 +05:30
|
|
|
n0 = default.view(what,False)
|
|
|
|
n1 = default.view(what,[])
|
2020-05-23 14:08:25 +05:30
|
|
|
|
2021-04-10 13:05:10 +05:30
|
|
|
label = 'increments' if what == 'times' else what
|
2020-05-23 14:08:25 +05:30
|
|
|
|
2021-04-10 13:05:10 +05:30
|
|
|
assert n0.get('F') is n1.get('F') is None and \
|
|
|
|
len(n0.visible[label]) == len(n1.visible[label]) == 0
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('what',['increments','times','phases','fields']) # ToDo: discuss homogenizations
|
2021-01-13 19:27:58 +05:30
|
|
|
def test_view_more(self,default,what):
|
2021-04-05 11:23:19 +05:30
|
|
|
empty = default.view(what,False)
|
2020-05-23 14:08:25 +05:30
|
|
|
|
2021-04-06 21:09:44 +05:30
|
|
|
a = empty.view_more(what,'*').get('F')
|
|
|
|
b = empty.view_more(what,True).get('F')
|
2020-05-23 14:08:25 +05:30
|
|
|
|
2021-04-03 16:41:20 +05:30
|
|
|
assert dict_equal(a,b)
|
2020-05-23 14:08:25 +05:30
|
|
|
|
2021-04-10 13:05:10 +05:30
|
|
|
@pytest.mark.parametrize('what',['increments','times','phases','fields']) # ToDo: discuss homogenizations
|
2021-01-13 19:27:58 +05:30
|
|
|
def test_view_less(self,default,what):
|
2021-04-05 11:23:19 +05:30
|
|
|
full = default.view(what,True)
|
2020-05-23 14:08:25 +05:30
|
|
|
|
2021-04-10 13:05:10 +05:30
|
|
|
n0 = full.view_less(what,'*')
|
|
|
|
n1 = full.view_less(what,True)
|
|
|
|
|
|
|
|
label = 'increments' if what == 'times' else what
|
2020-05-23 14:08:25 +05:30
|
|
|
|
2021-04-10 13:05:10 +05:30
|
|
|
assert n0.get('F') is n1.get('F') is None and \
|
|
|
|
len(n0.visible[label]) == len(n1.visible[label]) == 0
|
2020-05-23 14:08:25 +05:30
|
|
|
|
2021-01-13 19:27:58 +05:30
|
|
|
def test_view_invalid(self,default):
|
2020-05-23 14:08:25 +05:30
|
|
|
with pytest.raises(AttributeError):
|
2021-01-13 19:27:58 +05:30
|
|
|
default.view('invalid',True)
|
2019-12-04 10:29:52 +05:30
|
|
|
|
2019-12-04 10:45:32 +05:30
|
|
|
def test_add_absolute(self,default):
|
2020-11-06 02:44:49 +05:30
|
|
|
default.add_absolute('F_e')
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = np.abs(default.place('F_e'))
|
|
|
|
in_file = default.place('|F_e|')
|
2019-11-23 23:28:44 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
2020-02-01 14:12:04 +05:30
|
|
|
|
2020-07-31 20:20:01 +05:30
|
|
|
@pytest.mark.parametrize('mode',['direct','function'])
|
2020-07-31 20:34:14 +05:30
|
|
|
def test_add_calculation(self,default,tmp_path,mode):
|
2020-07-31 20:20:01 +05:30
|
|
|
|
|
|
|
if mode == 'direct':
|
2021-04-25 11:17:00 +05:30
|
|
|
default.add_calculation('2.0*np.abs(#F#)-1.0','x','-','my notes')
|
2020-07-31 20:20:01 +05:30
|
|
|
else:
|
2020-07-31 20:34:14 +05:30
|
|
|
with open(tmp_path/'f.py','w') as f:
|
|
|
|
f.write("import numpy as np\ndef my_func(field):\n return 2.0*np.abs(field)-1.0\n")
|
|
|
|
sys.path.insert(0,str(tmp_path))
|
|
|
|
import f
|
|
|
|
default.enable_user_function(f.my_func)
|
2021-04-25 11:17:00 +05:30
|
|
|
default.add_calculation('my_func(#F#)','x','-','my notes')
|
2020-07-31 20:20:01 +05:30
|
|
|
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = 2.0*np.abs(default.place('F'))-1.0
|
|
|
|
in_file = default.place('x')
|
2020-02-01 14:12:04 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
2019-11-23 23:28:44 +05:30
|
|
|
|
2020-11-18 03:26:22 +05:30
|
|
|
def test_add_stress_Cauchy(self,default):
|
|
|
|
default.add_stress_Cauchy('P','F')
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = mechanics.stress_Cauchy(default.place('P'), default.place('F'))
|
|
|
|
in_file = default.place('sigma')
|
2019-11-23 23:28:44 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
2019-12-04 10:19:43 +05:30
|
|
|
def test_add_determinant(self,default):
|
|
|
|
default.add_determinant('P')
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = np.linalg.det(default.place('P'))
|
|
|
|
in_file = default.place('det(P)')
|
2019-12-04 10:19:43 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
2019-12-04 10:45:32 +05:30
|
|
|
def test_add_deviator(self,default):
|
|
|
|
default.add_deviator('P')
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = tensor.deviatoric(default.place('P'))
|
|
|
|
in_file = default.place('s_P')
|
2019-12-04 10:45:32 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
2020-05-27 21:06:30 +05:30
|
|
|
@pytest.mark.parametrize('eigenvalue,function',[('max',np.amax),('min',np.amin)])
|
|
|
|
def test_add_eigenvalue(self,default,eigenvalue,function):
|
2020-11-18 03:26:22 +05:30
|
|
|
default.add_stress_Cauchy('P','F')
|
2020-05-27 21:06:30 +05:30
|
|
|
default.add_eigenvalue('sigma',eigenvalue)
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = function(tensor.eigenvalues(default.place('sigma')),axis=1)
|
|
|
|
in_file = default.place(f'lambda_{eigenvalue}(sigma)')
|
2020-02-15 21:25:12 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
2020-05-27 21:06:30 +05:30
|
|
|
@pytest.mark.parametrize('eigenvalue,idx',[('max',2),('mid',1),('min',0)])
|
|
|
|
def test_add_eigenvector(self,default,eigenvalue,idx):
|
2020-11-18 03:26:22 +05:30
|
|
|
default.add_stress_Cauchy('P','F')
|
2020-05-27 21:06:30 +05:30
|
|
|
default.add_eigenvector('sigma',eigenvalue)
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = tensor.eigenvectors(default.place('sigma'))[:,idx]
|
|
|
|
in_file = default.place(f'v_{eigenvalue}(sigma)')
|
2020-02-15 21:25:12 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
2020-05-23 12:43:45 +05:30
|
|
|
@pytest.mark.parametrize('d',[[1,0,0],[0,1,0],[0,0,1]])
|
2020-07-01 01:13:57 +05:30
|
|
|
def test_add_IPF_color(self,default,d):
|
2020-12-02 19:15:47 +05:30
|
|
|
default.add_IPF_color(d,'O')
|
2021-04-04 22:35:58 +05:30
|
|
|
qu = default.place('O')
|
|
|
|
crystal_structure = qu.dtype.metadata['lattice']
|
2020-11-29 13:36:47 +05:30
|
|
|
c = Orientation(rotation=qu,lattice=crystal_structure)
|
2020-11-18 21:15:53 +05:30
|
|
|
in_memory = np.uint8(c.IPF_color(np.array(d))*255)
|
2021-04-04 22:35:58 +05:30
|
|
|
in_file = default.place('IPFcolor_({} {} {})'.format(*d))
|
2020-05-23 12:43:45 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
2020-02-15 21:25:12 +05:30
|
|
|
def test_add_maximum_shear(self,default):
|
2020-11-18 03:26:22 +05:30
|
|
|
default.add_stress_Cauchy('P','F')
|
2020-02-15 21:25:12 +05:30
|
|
|
default.add_maximum_shear('sigma')
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = mechanics.maximum_shear(default.place('sigma'))
|
|
|
|
in_file = default.place('max_shear(sigma)')
|
2020-02-15 21:25:12 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
2020-02-16 14:34:33 +05:30
|
|
|
def test_add_Mises_strain(self,default):
|
|
|
|
t = ['V','U'][np.random.randint(0,2)]
|
|
|
|
m = np.random.random()*2.0 - 1.0
|
2020-11-16 05:42:23 +05:30
|
|
|
default.add_strain('F',t,m)
|
2020-06-25 01:04:51 +05:30
|
|
|
label = f'epsilon_{t}^{m}(F)'
|
2020-11-18 03:26:22 +05:30
|
|
|
default.add_equivalent_Mises(label)
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = mechanics.equivalent_strain_Mises(default.place(label))
|
|
|
|
in_file = default.place(label+'_vM')
|
2020-02-16 14:34:33 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
|
|
|
def test_add_Mises_stress(self,default):
|
2020-11-18 03:26:22 +05:30
|
|
|
default.add_stress_Cauchy('P','F')
|
|
|
|
default.add_equivalent_Mises('sigma')
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = mechanics.equivalent_stress_Mises(default.place('sigma'))
|
|
|
|
in_file = default.place('sigma_vM')
|
2020-02-16 14:34:33 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
2020-11-06 04:17:37 +05:30
|
|
|
def test_add_Mises_invalid(self,default):
|
2020-11-18 03:26:22 +05:30
|
|
|
default.add_stress_Cauchy('P','F')
|
2021-04-25 11:17:00 +05:30
|
|
|
default.add_calculation('#sigma#','sigma_y',unit='y')
|
2020-11-18 03:26:22 +05:30
|
|
|
default.add_equivalent_Mises('sigma_y')
|
2021-04-10 13:05:10 +05:30
|
|
|
assert default.get('sigma_y_vM') is None
|
2020-11-06 04:17:37 +05:30
|
|
|
|
|
|
|
def test_add_Mises_stress_strain(self,default):
|
2020-11-18 03:26:22 +05:30
|
|
|
default.add_stress_Cauchy('P','F')
|
2021-04-25 11:17:00 +05:30
|
|
|
default.add_calculation('#sigma#','sigma_y',unit='y')
|
|
|
|
default.add_calculation('#sigma#','sigma_x',unit='x')
|
2020-11-18 03:26:22 +05:30
|
|
|
default.add_equivalent_Mises('sigma_y',kind='strain')
|
|
|
|
default.add_equivalent_Mises('sigma_x',kind='stress')
|
2021-04-03 16:41:20 +05:30
|
|
|
assert not np.allclose(default.place('sigma_y_vM'),default.place('sigma_x_vM'))
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('ord',[1,2])
|
|
|
|
@pytest.mark.parametrize('dataset,axis',[('F',(1,2)),('xi_sl',(1,))])
|
|
|
|
def test_add_norm(self,default,ord,dataset,axis):
|
|
|
|
default.add_norm(dataset,ord)
|
|
|
|
in_memory = np.linalg.norm(default.place(dataset),ord=ord,axis=axis,keepdims=True)
|
|
|
|
in_file = default.place(f'|{dataset}|_{ord}')
|
2019-12-04 10:19:43 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
2020-11-18 03:26:22 +05:30
|
|
|
def test_add_stress_second_Piola_Kirchhoff(self,default):
|
|
|
|
default.add_stress_second_Piola_Kirchhoff('P','F')
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = mechanics.stress_second_Piola_Kirchhoff(default.place('P'),default.place('F'))
|
|
|
|
in_file = default.place('S')
|
2020-02-15 22:26:20 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
2020-11-10 01:50:56 +05:30
|
|
|
@pytest.mark.skip(reason='requires rework of lattice.f90')
|
2020-05-23 11:49:08 +05:30
|
|
|
@pytest.mark.parametrize('polar',[True,False])
|
|
|
|
def test_add_pole(self,default,polar):
|
|
|
|
pole = np.array([1.,0.,0.])
|
2020-11-06 02:44:49 +05:30
|
|
|
default.add_pole('O',pole,polar)
|
2021-04-03 16:41:20 +05:30
|
|
|
rot = Rotation(default.place('O'))
|
2020-05-23 11:49:08 +05:30
|
|
|
rotated_pole = rot * np.broadcast_to(pole,rot.shape+(3,))
|
|
|
|
xy = rotated_pole[:,0:2]/(1.+abs(pole[2]))
|
|
|
|
in_memory = xy if not polar else \
|
|
|
|
np.block([np.sqrt(xy[:,0:1]*xy[:,0:1]+xy[:,1:2]*xy[:,1:2]),np.arctan2(xy[:,1:2],xy[:,0:1])])
|
2021-04-03 16:41:20 +05:30
|
|
|
in_file = default.place('p^{}_[1 0 0)'.format(u'rφ' if polar else 'xy'))
|
2020-05-23 11:49:08 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
2020-11-20 03:16:52 +05:30
|
|
|
def test_add_rotation(self,default):
|
|
|
|
default.add_rotation('F')
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = mechanics.rotation(default.place('F')).as_matrix()
|
|
|
|
in_file = default.place('R(F)')
|
2020-02-15 22:26:20 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
2019-11-23 23:28:44 +05:30
|
|
|
def test_add_spherical(self,default):
|
|
|
|
default.add_spherical('P')
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = tensor.spherical(default.place('P'),False)
|
|
|
|
in_file = default.place('p_P')
|
2019-11-23 23:28:44 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
2020-02-15 22:26:20 +05:30
|
|
|
|
2020-02-16 14:34:33 +05:30
|
|
|
def test_add_strain(self,default):
|
|
|
|
t = ['V','U'][np.random.randint(0,2)]
|
|
|
|
m = np.random.random()*2.0 - 1.0
|
2020-11-16 05:42:23 +05:30
|
|
|
default.add_strain('F',t,m)
|
2020-06-25 01:04:51 +05:30
|
|
|
label = f'epsilon_{t}^{m}(F)'
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = mechanics.strain(default.place('F'),t,m)
|
|
|
|
in_file = default.place(label)
|
2020-02-16 14:34:33 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
2020-02-15 22:26:20 +05:30
|
|
|
def test_add_stretch_right(self,default):
|
|
|
|
default.add_stretch_tensor('F','U')
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = mechanics.stretch_right(default.place('F'))
|
|
|
|
in_file = default.place('U(F)')
|
2020-02-15 22:26:20 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
|
|
|
|
|
|
|
def test_add_stretch_left(self,default):
|
|
|
|
default.add_stretch_tensor('F','V')
|
2021-04-03 16:41:20 +05:30
|
|
|
in_memory = mechanics.stretch_left(default.place('F'))
|
|
|
|
in_file = default.place('V(F)')
|
2020-02-15 22:26:20 +05:30
|
|
|
assert np.allclose(in_memory,in_file)
|
2020-05-22 22:34:02 +05:30
|
|
|
|
2020-05-26 10:19:29 +05:30
|
|
|
def test_add_invalid(self,default):
|
|
|
|
with pytest.raises(TypeError):
|
|
|
|
default.add_calculation('#invalid#*2')
|
|
|
|
|
2021-05-28 16:55:28 +05:30
|
|
|
|
|
|
|
@pytest.mark.parametrize('shape',['vector','tensor'])
|
|
|
|
def test_add_curl(self,default,shape):
|
|
|
|
if shape == 'vector': default.add_calculation('#F#[:,:,0]','x','1','just a vector')
|
|
|
|
if shape == 'tensor': default.add_calculation('#F#[:,:,:]','x','1','just a tensor')
|
|
|
|
x = default.place('x')
|
|
|
|
default.add_curl('x')
|
|
|
|
in_file = default.place('curl(x)')
|
|
|
|
in_memory = grid_filters.curl(default.size,x.reshape(tuple(default.cells)+x.shape[1:])).reshape(in_file.shape)
|
|
|
|
assert (in_file==in_memory).all()
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('shape',['vector','tensor'])
|
|
|
|
def test_add_divergence(self,default,shape):
|
|
|
|
if shape == 'vector': default.add_calculation('#F#[:,:,0]','x','1','just a vector')
|
|
|
|
if shape == 'tensor': default.add_calculation('#F#[:,:,:]','x','1','just a tensor')
|
|
|
|
x = default.place('x')
|
|
|
|
default.add_divergence('x')
|
|
|
|
in_file = default.place('divergence(x)')
|
|
|
|
in_memory = grid_filters.divergence(default.size,x.reshape(tuple(default.cells)+x.shape[1:])).reshape(in_file.shape)
|
|
|
|
assert (in_file==in_memory).all()
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('shape',['scalar','pseudo_scalar','vector'])
|
|
|
|
def test_add_gradient(self,default,shape):
|
|
|
|
if shape == 'pseudo_scalar': default.add_calculation('#F#[:,0,0:1]','x','1','a pseudo scalar')
|
|
|
|
if shape == 'scalar': default.add_calculation('#F#[:,0,0]','x','1','just a scalar')
|
|
|
|
if shape == 'vector': default.add_calculation('#F#[:,:,1]','x','1','just a vector')
|
|
|
|
x = default.place('x').reshape((np.product(default.cells),-1))
|
|
|
|
default.add_gradient('x')
|
|
|
|
in_file = default.place('gradient(x)')
|
|
|
|
in_memory = grid_filters.gradient(default.size,x.reshape(tuple(default.cells)+x.shape[1:])).reshape(in_file.shape)
|
|
|
|
assert (in_file==in_memory).all()
|
|
|
|
|
2020-05-26 10:19:29 +05:30
|
|
|
@pytest.mark.parametrize('overwrite',['off','on'])
|
|
|
|
def test_add_overwrite(self,default,overwrite):
|
2021-04-24 10:43:36 +05:30
|
|
|
last = default.view('increments',-1)
|
2020-05-26 10:19:29 +05:30
|
|
|
|
2021-04-05 11:23:19 +05:30
|
|
|
last.add_stress_Cauchy()
|
2021-04-05 13:43:08 +05:30
|
|
|
|
|
|
|
created_first = last.place('sigma').dtype.metadata['created']
|
2020-05-26 10:19:29 +05:30
|
|
|
created_first = datetime.strptime(created_first,'%Y-%m-%d %H:%M:%S%z')
|
|
|
|
|
|
|
|
if overwrite == 'on':
|
2021-04-24 10:43:36 +05:30
|
|
|
last = last.modification_enable()
|
2020-05-26 10:19:29 +05:30
|
|
|
else:
|
2021-04-24 10:43:36 +05:30
|
|
|
last = last.modification_disable()
|
2020-05-26 10:19:29 +05:30
|
|
|
|
|
|
|
time.sleep(2.)
|
2020-11-06 03:30:56 +05:30
|
|
|
try:
|
2021-04-25 11:17:00 +05:30
|
|
|
last.add_calculation('#sigma#*0.0+311.','sigma','not the Cauchy stress')
|
2020-11-06 03:30:56 +05:30
|
|
|
except ValueError:
|
|
|
|
pass
|
2021-04-05 13:43:08 +05:30
|
|
|
|
|
|
|
created_second = last.place('sigma').dtype.metadata['created']
|
2020-05-26 10:19:29 +05:30
|
|
|
created_second = datetime.strptime(created_second,'%Y-%m-%d %H:%M:%S%z')
|
2021-04-04 22:02:17 +05:30
|
|
|
|
2020-05-26 10:19:29 +05:30
|
|
|
if overwrite == 'on':
|
2021-04-05 11:23:19 +05:30
|
|
|
assert created_first < created_second and np.allclose(last.place('sigma'),311.)
|
2020-05-26 10:19:29 +05:30
|
|
|
else:
|
2021-04-05 11:23:19 +05:30
|
|
|
assert created_first == created_second and not np.allclose(last.place('sigma'),311.)
|
2020-05-26 10:19:29 +05:30
|
|
|
|
2020-06-01 15:03:22 +05:30
|
|
|
@pytest.mark.parametrize('allowed',['off','on'])
|
|
|
|
def test_rename(self,default,allowed):
|
|
|
|
if allowed == 'on':
|
2021-04-03 16:41:20 +05:30
|
|
|
F = default.place('F')
|
2021-04-24 10:43:36 +05:30
|
|
|
default = default.modification_enable()
|
2020-06-01 15:03:22 +05:30
|
|
|
default.rename('F','new_name')
|
2021-04-03 16:41:20 +05:30
|
|
|
assert np.all(F == default.place('new_name'))
|
2021-04-24 10:43:36 +05:30
|
|
|
default = default.modification_disable()
|
2020-06-01 15:03:22 +05:30
|
|
|
|
|
|
|
with pytest.raises(PermissionError):
|
|
|
|
default.rename('P','another_new_name')
|
|
|
|
|
2021-04-24 10:43:36 +05:30
|
|
|
@pytest.mark.parametrize('allowed',['off','on'])
|
|
|
|
def test_remove(self,default,allowed):
|
|
|
|
if allowed == 'on':
|
|
|
|
unsafe = default.modification_enable()
|
|
|
|
unsafe.remove('F')
|
|
|
|
assert unsafe.get('F') is None
|
|
|
|
else:
|
|
|
|
with pytest.raises(PermissionError):
|
|
|
|
default.remove('F')
|
|
|
|
|
2020-07-31 20:20:01 +05:30
|
|
|
@pytest.mark.parametrize('mode',['cell','node'])
|
|
|
|
def test_coordinates(self,default,mode):
|
|
|
|
if mode == 'cell':
|
2020-12-04 03:30:49 +05:30
|
|
|
a = grid_filters.coordinates0_point(default.cells,default.size,default.origin)
|
|
|
|
b = default.coordinates0_point.reshape(tuple(default.cells)+(3,),order='F')
|
2020-07-31 20:20:01 +05:30
|
|
|
elif mode == 'node':
|
2020-12-04 03:30:49 +05:30
|
|
|
a = grid_filters.coordinates0_node(default.cells,default.size,default.origin)
|
|
|
|
b = default.coordinates0_node.reshape(tuple(default.cells+1)+(3,),order='F')
|
2020-07-31 20:20:01 +05:30
|
|
|
assert np.allclose(a,b)
|
|
|
|
|
2021-04-03 11:01:31 +05:30
|
|
|
# need to wait for writing in parallel, output order might change if select more then one
|
|
|
|
@pytest.mark.parametrize('output',['F','*',['P']],ids=range(3))
|
|
|
|
@pytest.mark.parametrize('fname',['12grains6x7x8_tensionY.hdf5'],ids=range(1))
|
|
|
|
@pytest.mark.parametrize('inc',[4,0],ids=range(2))
|
2021-04-26 02:22:13 +05:30
|
|
|
def test_vtk(self,request,tmp_path,ref_path,update,patch_execution_stamp,patch_datetime_now,output,fname,inc):
|
2021-04-05 11:23:19 +05:30
|
|
|
result = Result(ref_path/fname).view('increments',inc)
|
2020-05-26 03:09:19 +05:30
|
|
|
os.chdir(tmp_path)
|
2021-04-03 11:01:31 +05:30
|
|
|
result.save_VTK(output)
|
2021-06-15 20:32:02 +05:30
|
|
|
fname = fname.split('.')[0]+f'_inc{(inc if type(inc) == int else inc[0]):0>2}.vti'
|
2021-04-03 11:01:31 +05:30
|
|
|
last = ''
|
|
|
|
for i in range(10):
|
|
|
|
if os.path.isfile(tmp_path/fname):
|
|
|
|
with open(fname) as f:
|
2021-04-06 21:40:35 +05:30
|
|
|
cur = hashlib.md5(f.read().encode()).hexdigest()
|
2021-04-03 11:01:31 +05:30
|
|
|
if cur == last:
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
last = cur
|
|
|
|
time.sleep(.5)
|
|
|
|
if update:
|
|
|
|
with open((ref_path/'save_VTK'/request.node.name).with_suffix('.md5'),'w') as f:
|
|
|
|
f.write(cur)
|
|
|
|
with open((ref_path/'save_VTK'/request.node.name).with_suffix('.md5')) as f:
|
2021-04-06 21:40:35 +05:30
|
|
|
assert cur == f.read()
|
2020-05-26 11:36:39 +05:30
|
|
|
|
2021-04-26 03:52:37 +05:30
|
|
|
@pytest.mark.parametrize('mode',['point','cell'])
|
|
|
|
@pytest.mark.parametrize('output',[False,True])
|
|
|
|
def test_vtk_marc(self,tmp_path,ref_path,mode,output):
|
|
|
|
os.chdir(tmp_path)
|
|
|
|
result = Result(ref_path/'check_compile_job1.hdf5')
|
|
|
|
result.save_VTK(output,mode)
|
|
|
|
|
|
|
|
def test_marc_coordinates(self,ref_path):
|
|
|
|
result = Result(ref_path/'check_compile_job1.hdf5').view('increments',-1)
|
|
|
|
c_n = result.coordinates0_node + result.get('u_n')
|
|
|
|
c_p = result.coordinates0_point + result.get('u_p')
|
|
|
|
assert len(c_n) > len(c_p)
|
|
|
|
|
2020-10-27 21:16:08 +05:30
|
|
|
@pytest.mark.parametrize('mode',['point','cell'])
|
|
|
|
def test_vtk_mode(self,tmp_path,single_phase,mode):
|
|
|
|
os.chdir(tmp_path)
|
2020-11-30 13:58:46 +05:30
|
|
|
single_phase.save_VTK(mode=mode)
|
2020-10-27 21:16:08 +05:30
|
|
|
|
2021-06-19 11:42:49 +05:30
|
|
|
def test_XDMF_datatypes(self,tmp_path,single_phase,update,ref_path):
|
2020-11-30 15:10:46 +05:30
|
|
|
for shape in [('scalar',()),('vector',(3,)),('tensor',(3,3)),('matrix',(12,))]:
|
|
|
|
for dtype in ['f4','f8','i1','i2','i4','i8','u1','u2','u4','u8']:
|
2021-04-25 11:17:00 +05:30
|
|
|
single_phase.add_calculation(f"np.ones(np.shape(#F#)[0:1]+{shape[1]},'{dtype}')",f'{shape[0]}_{dtype}')
|
2020-11-30 15:10:46 +05:30
|
|
|
fname = os.path.splitext(os.path.basename(single_phase.fname))[0]+'.xdmf'
|
2020-05-26 11:36:39 +05:30
|
|
|
os.chdir(tmp_path)
|
2021-06-19 00:41:01 +05:30
|
|
|
|
2020-09-21 01:34:28 +05:30
|
|
|
single_phase.save_XDMF()
|
2021-06-19 00:41:01 +05:30
|
|
|
|
2021-06-19 11:42:49 +05:30
|
|
|
if update:
|
|
|
|
shutil.copy(tmp_path/fname,ref_path/fname)
|
|
|
|
|
|
|
|
assert sorted(open(tmp_path/fname).read()) == sorted(open(ref_path/fname).read()) # XML is not ordered
|
|
|
|
|
|
|
|
@pytest.mark.skipif(not hasattr(vtk,'vtkXdmfReader'),reason='https://discourse.vtk.org/t/2450')
|
|
|
|
def test_XDMF_shape(self,tmp_path,single_phase):
|
|
|
|
os.chdir(tmp_path)
|
|
|
|
|
|
|
|
single_phase.save_XDMF()
|
|
|
|
fname = os.path.splitext(os.path.basename(single_phase.fname))[0]+'.xdmf'
|
2021-06-19 00:41:01 +05:30
|
|
|
reader_xdmf = vtk.vtkXdmfReader()
|
|
|
|
reader_xdmf.SetFileName(fname)
|
|
|
|
reader_xdmf.Update()
|
|
|
|
dim_xdmf = reader_xdmf.GetOutput().GetDimensions()
|
|
|
|
bounds_xdmf = reader_xdmf.GetOutput().GetBounds()
|
|
|
|
|
2021-06-19 11:42:49 +05:30
|
|
|
single_phase.view('increments',0).save_VTK()
|
|
|
|
fname = os.path.splitext(os.path.basename(single_phase.fname))[0]+'_inc00.vti'
|
|
|
|
for i in range(10): # waiting for parallel IO
|
|
|
|
reader_vti = vtk.vtkXMLImageDataReader()
|
|
|
|
reader_vti.SetFileName(fname)
|
|
|
|
reader_vti.Update()
|
|
|
|
dim_vti = reader_vti.GetOutput().GetDimensions()
|
|
|
|
bounds_vti = reader_vti.GetOutput().GetBounds()
|
|
|
|
if dim_vti == dim_xdmf and bounds_vti == bounds_xdmf:
|
|
|
|
return
|
|
|
|
time.sleep(.5)
|
2021-06-19 00:41:01 +05:30
|
|
|
|
2021-06-19 11:42:49 +05:30
|
|
|
assert False
|
2020-11-30 15:10:46 +05:30
|
|
|
|
|
|
|
def test_XDMF_invalid(self,default):
|
|
|
|
with pytest.raises(TypeError):
|
|
|
|
default.save_XDMF()
|
2021-04-01 17:17:27 +05:30
|
|
|
|
2021-04-08 17:09:48 +05:30
|
|
|
@pytest.mark.parametrize('view,output,flatten,prune',
|
2021-04-01 17:17:27 +05:30
|
|
|
[({},['F','P','F','L_p','F_e','F_p'],True,True),
|
|
|
|
({'increments':3},'F',True,True),
|
|
|
|
({'increments':[1,8,3,4,5,6,7]},['F','P'],True,True),
|
|
|
|
({'phases':['A','B']},['F','P'],True,True),
|
|
|
|
({'phases':['A','C'],'homogenizations':False},['F','P','O'],True,True),
|
|
|
|
({'phases':False,'homogenizations':False},['F','P','O'],True,True),
|
|
|
|
({'phases':False},['Delta_V'],True,True),
|
|
|
|
({},['u_p','u_n'],False,False)],
|
|
|
|
ids=list(range(8)))
|
2021-04-08 17:09:48 +05:30
|
|
|
def test_get(self,update,request,ref_path,view,output,flatten,prune):
|
2021-04-01 17:17:27 +05:30
|
|
|
result = Result(ref_path/'4grains2x4x3_compressionY.hdf5')
|
|
|
|
for key,value in view.items():
|
2021-04-05 11:23:19 +05:30
|
|
|
result = result.view(key,value)
|
2021-04-01 17:17:27 +05:30
|
|
|
|
2021-04-03 11:01:31 +05:30
|
|
|
fname = request.node.name
|
2021-04-08 17:09:48 +05:30
|
|
|
cur = result.get(output,flatten,prune)
|
2021-04-01 17:17:27 +05:30
|
|
|
if update:
|
2021-04-08 17:09:48 +05:30
|
|
|
with bz2.BZ2File((ref_path/'get'/fname).with_suffix('.pbz2'),'w') as f:
|
2021-04-01 17:17:27 +05:30
|
|
|
pickle.dump(cur,f)
|
2021-04-01 19:22:43 +05:30
|
|
|
|
2021-04-08 17:09:48 +05:30
|
|
|
with bz2.BZ2File((ref_path/'get'/fname).with_suffix('.pbz2')) as f:
|
2021-04-10 13:05:10 +05:30
|
|
|
ref = pickle.load(f)
|
|
|
|
assert cur is None if ref is None else dict_equal(cur,ref)
|
2021-04-01 19:22:43 +05:30
|
|
|
|
2021-04-08 17:09:48 +05:30
|
|
|
@pytest.mark.parametrize('view,output,flatten,constituents,prune',
|
2021-04-01 19:22:43 +05:30
|
|
|
[({},['F','P','F','L_p','F_e','F_p'],True,True,None),
|
|
|
|
({'increments':3},'F',True,True,[0,1,2,3,4,5,6,7]),
|
|
|
|
({'increments':[1,8,3,4,5,6,7]},['F','P'],True,True,1),
|
|
|
|
({'phases':['A','B']},['F','P'],True,True,[1,2]),
|
|
|
|
({'phases':['A','C'],'homogenizations':False},['F','P','O'],True,True,[0,7]),
|
|
|
|
({'phases':False,'homogenizations':False},['F','P','O'],True,True,[1,2,3,4]),
|
|
|
|
({'phases':False},['Delta_V'],True,True,[1,2,4]),
|
|
|
|
({},['u_p','u_n'],False,False,None)],
|
|
|
|
ids=list(range(8)))
|
2021-04-08 17:09:48 +05:30
|
|
|
def test_place(self,update,request,ref_path,view,output,flatten,prune,constituents):
|
2021-04-01 19:22:43 +05:30
|
|
|
result = Result(ref_path/'4grains2x4x3_compressionY.hdf5')
|
|
|
|
for key,value in view.items():
|
2021-04-05 11:23:19 +05:30
|
|
|
result = result.view(key,value)
|
2021-04-01 19:22:43 +05:30
|
|
|
|
2021-04-03 11:01:31 +05:30
|
|
|
fname = request.node.name
|
2021-04-08 17:09:48 +05:30
|
|
|
cur = result.place(output,flatten,prune,constituents)
|
2021-04-01 19:22:43 +05:30
|
|
|
if update:
|
2021-04-03 11:01:31 +05:30
|
|
|
with bz2.BZ2File((ref_path/'place'/fname).with_suffix('.pbz2'),'w') as f:
|
2021-04-01 19:22:43 +05:30
|
|
|
pickle.dump(cur,f)
|
|
|
|
|
2021-04-03 11:01:31 +05:30
|
|
|
with bz2.BZ2File((ref_path/'place'/fname).with_suffix('.pbz2')) as f:
|
2021-04-10 13:05:10 +05:30
|
|
|
ref = pickle.load(f)
|
|
|
|
assert cur is None if ref is None else dict_equal(cur,ref)
|