def test_disorientation_blending(self, lattice, a, b): o = Orientation.from_random(lattice=lattice, shape=a) p = Orientation.from_random(lattice=lattice, shape=b) blend = util.shapeblender(o.shape, p.shape) for loc in np.random.randint(0, blend, (10, len(blend))): assert o[tuple(loc[:len(o.shape)])].disorientation(p[tuple(loc[-len(p.shape):])]) \ .isclose(o.disorientation(p)[tuple(loc)])
def test_disorientation_blending(self, family, left, right): o = Orientation.from_random(family=family, shape=left) p = Orientation.from_random(family=family, shape=right) blend = util.shapeblender(o.shape, p.shape) for loc in np.random.randint(0, blend, (10, len(blend))): # print(f'{a}/{b} @ {loc}') # print(o[tuple(loc[:len(o.shape)])].disorientation(p[tuple(loc[-len(p.shape):])])) # print(o.disorientation(p)[tuple(loc)]) assert o[tuple(loc[:len(o.shape)])].disorientation(p[tuple(loc[-len(p.shape):])]) \ .isclose(o.disorientation(p)[tuple(loc)])
def test_disorientation(self, lattice, N): o = Orientation.from_random(lattice=lattice, shape=N) p = Orientation.from_random(lattice=lattice, shape=N) d, ops = o.disorientation(p, return_operators=True) for n in range(N): assert np.allclose(d[n].as_quaternion(), o[n].equivalent[ops[n][0]] .misorientation(p[n].equivalent[ops[n][1]]) .as_quaternion()) \ or np.allclose((~d)[n].as_quaternion(), o[n].equivalent[ops[n][0]] .misorientation(p[n].equivalent[ops[n][1]]) .as_quaternion())
def test_IPF_color_vectorization(self, lattice, shape, vector, proper, in_SST): o = Orientation.from_random(lattice=lattice, shape=shape) for r, theO in zip( o.IPF_color(vector, in_SST=in_SST, proper=proper).reshape( (-1, 3)), o.flatten()): assert np.allclose( r, theO.IPF_color(vector, in_SST=in_SST, proper=proper))
def test_to_SST_blending(self, family, left, right): o = Orientation.from_random(family=family, shape=left) v = np.random.random(right + (3, )) blend = util.shapeblender(o.shape, v.shape[:-1]) for loc in np.random.randint(0, blend, (10, len(blend))): assert np.allclose( o[tuple(loc[:len(o.shape)])].to_SST(v[tuple( loc[-len(v.shape[:-1]):])]), o.to_SST(v)[tuple(loc)])
def test_Schmid_vectorization(self, lattice): O = Orientation.from_random(shape=4, lattice=lattice) # noqa for mode in ['slip', 'twin']: Ps = O.Schmid(N_slip='*') if mode == 'slip' else O.Schmid( N_twin='*') for i in range(4): P = O[i].Schmid(N_slip='*') if mode == 'slip' else O[i].Schmid( N_twin='*') assert np.allclose(P, Ps[:, i])
def test_reduced_equivalent(self, lattice): i = Orientation(lattice=lattice) o = Orientation.from_random(lattice=lattice) eq = o.equivalent FZ = np.argmin( abs( eq.misorientation(i.broadcast_to( len(eq))).as_axis_angle(pair=True)[1])) assert o.reduced == eq[FZ]
def test_to_SST_blending(self, lattice, a, b): o = Orientation.from_random(lattice=lattice, shape=a) v = np.random.random(b + (3, )) blend = util.shapeblender(o.shape, b) for loc in np.random.randint(0, blend, (10, len(blend))): print(f'{a}/{b} @ {loc}') print(o[tuple(loc[:len(o.shape)])].to_SST(v[tuple(loc[-len(b):])])) print(o.to_SST(v)[tuple(loc)]) assert np.allclose( o[tuple(loc[:len(o.shape)])].to_SST(v[tuple(loc[-len(b):])]), o.to_SST(v)[tuple(loc)])
def test_to_pole(self, shape, lattice, a, b, c, alpha, beta, gamma, vector, kw, with_symmetry): o = Orientation.from_random(shape=shape, lattice=lattice, a=a, b=b, c=c, alpha=alpha, beta=beta, gamma=gamma) assert o.to_pole(**{kw:vector,'with_symmetry':with_symmetry}).shape \ == o.shape + (o.symmetry_operations.shape if with_symmetry else ()) + vector.shape
def test_to_pole_blending(self, lattice, a, b, c, alpha, beta, gamma, left, right): o = Orientation.from_random(shape=left, lattice=lattice, a=a, b=b, c=c, alpha=alpha, beta=beta, gamma=gamma) v = np.random.random(right + (3, )) blend = util.shapeblender(o.shape, v.shape[:-1]) for loc in np.random.randint(0, blend, (10, len(blend))): assert np.allclose( o[tuple(loc[:len(o.shape)])].to_pole( uvw=v[tuple(loc[-len(v.shape[:-1]):])]), o.to_pole(uvw=v)[tuple(loc)])
def test_basis_real(self): for gamma in np.random.random(2**8) * np.pi: basis = np.tril(np.random.random((3, 3)) + 1e-6) basis[1, :2] = basis[1, 1] * np.array( [np.cos(gamma), np.sin(gamma)]) basis[2, :2] = basis[2, :2] * 2 - 1 lengths = np.linalg.norm(basis, axis=-1) cosines = np.roll( np.einsum('ij,ij->i', basis, np.roll(basis, 1, axis=0)) / lengths / np.roll(lengths, 1), 1) o = Orientation.from_random( lattice='aP', **dict(zip(['a', 'b', 'c'], lengths)), **dict(zip(['alpha', 'beta', 'gamma'], np.arccos(cosines))), ) assert np.allclose( o.to_frame(uvw=np.eye(3)), basis), 'Lattice basis disagrees with initialization'
class TestConfig: @pytest.mark.parametrize('flow_style', [None, True, False]) def test_load_save_str(self, tmp_path, flow_style): config = Config() config['A'] = 1 config['B'] = [2, 3] config.save(tmp_path / 'config.yaml', default_flow_style=flow_style) assert Config.load(tmp_path / 'config.yaml') == config def test_load_save_file(self, tmp_path): config = Config() config['A'] = 1 config['B'] = [2, 3] with open(tmp_path / 'config.yaml', 'w') as f: config.save(f) with open(tmp_path / 'config.yaml') as f: assert Config.load(f) == config def test_add_remove(self): dummy = {'hello': 'world', 'foo': 'bar'} config = Config() config |= dummy assert config == Config() | dummy config = config.delete(dummy) assert config == Config() assert (config | dummy).delete('hello') == config | {'foo': 'bar'} assert (config | dummy).delete(['hello', 'foo']) == config assert (config | Config(dummy)).delete({ 'hello': 1, 'foo': 2 }) == config assert (config | Config(dummy)).delete(Config({'hello': 1})) == config | { 'foo': 'bar' } def test_repr(self, tmp_path): config = Config() config['A'] = 1 config['B'] = [2, 3] with open(tmp_path / 'config.yaml', 'w') as f: f.write(config.__repr__()) assert Config.load(tmp_path / 'config.yaml') == config def test_numpy(self, tmp_path): assert Config({ 'A': np.ones(3, 'i') }).__repr__() == Config({ 'A': [1, 1, 1] }).__repr__() def test_abstract_is_valid(self): with pytest.raises(NotImplementedError): Config().is_valid def test_abstract_is_complete(self): with pytest.raises(NotImplementedError): Config().is_complete @pytest.mark.parametrize( 'data', [Rotation.from_random(), Orientation.from_random(lattice='cI')]) def test_rotation_orientation(self, data): assert str(Config(a=data)) == str(Config(a=data.as_quaternion())) def test_initialize(self): yml = """ a: - 1 - 2 """ assert Config(yml) == Config('{"a":[1,2]}') == Config( a=[1, 2]) == Config(dict(a=[1, 2]))
def test_relationship_forward_backward(self, model, lattice): o = Orientation.from_random(lattice=lattice) for i, r in enumerate(o.related(model)): assert o.disorientation(r.related(model)[i]).as_axis_angle( degrees=True, pair=True)[1] < 1.0e-5
def test_invalid_rot(self): with pytest.raises(TypeError): Orientation.from_random(lattice='cubic') * np.ones(3)
def test_close(self, lattice, shape): R = Orientation.from_random(lattice=lattice, shape=shape) assert R.isclose(R.reduced).all() and R.allclose(R.reduced)
def test_close(self, family, shape): R = Orientation.from_random(family=family, shape=shape) assert R.isclose(R.reduced).all() and R.allclose(R.reduced)
def test_to_SST_vectorization(self, lattice, shape, vector, proper): o = Orientation.from_random(lattice=lattice, shape=shape) for r, theO in zip( o.to_SST(vector=vector, proper=proper).reshape((-1, 3)), o.flatten()): assert np.allclose(r, theO.to_SST(vector=vector, proper=proper))
def test_reduced_vectorization(self, lattice, shape): o = Orientation.from_random(lattice=lattice, shape=shape) for r, theO in zip(o.reduced.flatten(), o.flatten()): assert r == theO.reduced
def test_repr(self, kwargs): o = Orientation.from_random(**kwargs) assert isinstance(o.__repr__(), str)
def test_mul_invalid(self): with pytest.raises(TypeError): Orientation.from_random(lattice='cF') * np.ones(3)
def test_copy(self, kwargs): o = Orientation.from_random(**kwargs) p = o.copy(rotation=Rotation.from_random()) assert o != p