def test_read_all_dyn(): # matdyn modes: read_all_dyn() qpoints, freqs, vecs = pwscf.read_all_dyn('files/dyn/', nqpoints=2, natoms=2, base='ph.dyn') aae(qpoints, qpoints_ref) aae(freqs, freqs_modes_ref) aae(vecs.real, vecs_real_ref) aaae(vecs.imag, vecs_imag_ref)
def test_dist(): X = rand(100, 5) Y = rand(80, 5) d1 = num.distsq(X, Y) d2 = ((X[:, None, ...] - Y[None, ...])**2.0).sum(axis=-1) d3 = cdist(X, Y, metric='euclidean')**2.0 print("d1 - d2") aaae(d1, d2) print("d1 - d3") aaae(d1, d3)
def test_dist(): X = rand(100,5) Y = rand(80,5) d1 = num.distsq(X,Y) d2 = ((X[:,None,...] - Y[None,...])**2.0).sum(axis=-1) d3 = cdist(X,Y, metric='euclidean')**2.0 print "d1 - d2" aaae(d1,d2) print "d1 - d3" aaae(d1,d3)
def test_cell_tools(): # test known values: simple cubic cell_a = 5.0 cell = np.identity(3) * cell_a volume = cell_a**3.0 cryst_const = np.array([cell_a] * 3 + [90.0] * 3) np.testing.assert_array_almost_equal(crys.cell2cc(cell), cryst_const) np.testing.assert_array_almost_equal(crys.cc2cell(cryst_const), cell) np.testing.assert_almost_equal(volume, crys.volume_cc(cryst_const)) np.testing.assert_almost_equal(volume, crys.volume_cell(cell)) np.testing.assert_array_almost_equal(crys.cc2cell(crys.cell2cc(cell)), cell) np.testing.assert_array_almost_equal( crys.cell2cc(crys.cc2cell(cryst_const)), cryst_const) # random # # volume : volume_cc() always returns positive values, whereas det() and # volume_cell() may return the volume with negative sign but correct # magnitude. # cell : A random cell does also have a random orientation in space. It # does NOT conform the usual convention: a along x, b in x-y plane. # However, the cryst_const and volume must be invariant. cell = np.random.rand(3, 3) cryst_const = crys.cell2cc(cell) volume = abs(np.linalg.det(cell)) np.testing.assert_almost_equal(volume, crys.volume_cc(cryst_const)) np.testing.assert_almost_equal(volume, abs(crys.volume_cell(cell))) # this must always fail for random cells try: np.testing.assert_array_almost_equal(crys.cc2cell(crys.cell2cc(cell)), cell) except AssertionError: pass # Here, we convert cryst_const to a *different* cell which conforms to the # orientation convention, and back to cryst_const. np.testing.assert_array_almost_equal( crys.cell2cc(crys.cc2cell(cryst_const)), cryst_const) # 3d cell = rand(100, 3, 3) cc = crys.cell2cc3d(cell, axis=0) vol_cell = np.abs(crys.volume_cell3d(cell, axis=0)) vol_cc = crys.volume_cc3d(cc, axis=0) assert crys.cell2cc3d(cell, axis=0).shape == (100, 6) assert crys.cc2cell3d(cc, axis=0).shape == (100, 3, 3) assert vol_cc.shape == (100, ) assert vol_cell.shape == (100, ) aaae(vol_cell, vol_cc) aaae(crys.cell2cc3d(crys.cc2cell3d(cc)), cc)
def test_cell_tools(): # test known values: simple cubic cell_a = 5.0 cell = np.identity(3)*cell_a volume = cell_a**3.0 cryst_const = np.array([cell_a]*3 + [90.0]*3) np.testing.assert_array_almost_equal(crys.cell2cc(cell), cryst_const) np.testing.assert_array_almost_equal(crys.cc2cell(cryst_const), cell) np.testing.assert_almost_equal(volume, crys.volume_cc(cryst_const)) np.testing.assert_almost_equal(volume, crys.volume_cell(cell)) np.testing.assert_array_almost_equal(crys.cc2cell(crys.cell2cc(cell)), cell) np.testing.assert_array_almost_equal(crys.cell2cc(crys.cc2cell(cryst_const)), cryst_const) # random # # volume : volume_cc() always returns positive values, whereas det() and # volume_cell() may return the volume with negative sign but correct # magnitude. # cell : A random cell does also have a random orientation in space. It # does NOT conform the usual convention: a along x, b in x-y plane. # However, the cryst_const and volume must be invariant. cell = np.random.rand(3,3) cryst_const = crys.cell2cc(cell) volume = abs(np.linalg.det(cell)) np.testing.assert_almost_equal(volume, crys.volume_cc(cryst_const)) np.testing.assert_almost_equal(volume, abs(crys.volume_cell(cell))) # this must always fail for random cells try: np.testing.assert_array_almost_equal(crys.cc2cell(crys.cell2cc(cell)), cell) except AssertionError: pass # Here, we convert cryst_const to a *different* cell which conforms to the # orientation convention, and back to cryst_const. np.testing.assert_array_almost_equal(crys.cell2cc(crys.cc2cell(cryst_const)), cryst_const) # 3d cell = rand(100,3,3) cc = crys.cell2cc3d(cell, axis=0) vol_cell = np.abs(crys.volume_cell3d(cell, axis=0)) vol_cc = crys.volume_cc3d(cc, axis=0) assert crys.cell2cc3d(cell, axis=0).shape == (100,6) assert crys.cc2cell3d(cc, axis=0).shape == (100,3,3) assert vol_cc.shape == (100,) assert vol_cell.shape == (100,) aaae(vol_cell, vol_cc) aaae(crys.cell2cc3d(crys.cc2cell3d(cc)), cc)
def test_read_matdyn(): # matdyn.freq kpoints, freqs = pwscf.read_matdyn_freq('files/matdyn.freq') aae(kpoints, kpoints_ref) aae(freqs, freqs_ref) # matdyn modes: read_matdyn_modes() qpoints, freqs, vecs = pwscf.read_matdyn_modes('files/matdyn.modes', natoms=2) aae(qpoints, qpoints_ref) aae(freqs, freqs_modes_ref) aae(vecs.real, vecs_real_ref) aaae(vecs.imag, vecs_imag_ref)
def test_struct(): natoms = 10 cell = np.array([[3, 0, 0], [1.1, 5, -0.04], [-0.33, 1.5, 7]]) cryst_const = crys.cell2cc(cell) coords_frac = rand(natoms, 3) coords = crys.coord_trans(coords=coords_frac, old=cell, new=np.identity(3)) symbols = ['H'] * natoms stress = rand(3, 3) forces = rand(natoms, 3) # Use ``cell`` instead of ``cryst_const` as input such that # atoms.get_cell() test passes (see below for why -- cell orientation) st = Structure(coords_frac=coords_frac, symbols=symbols, cell=cell, stress=stress, forces=forces, etot=42) # Test if all getters work. for name in st.attr_lst: print(name) st.try_set_attr(name) assert getattr(st, name) is not None, "attr None: %s" % name assert eval('st.get_%s()' % name) is not None, "getter returns None: %s" % name aaae(coords_frac, st.coords_frac) aaae(cryst_const, st.cryst_const) aaae(coords, st.coords) assert st.natoms == natoms st = Structure(coords_frac=coords_frac, symbols=symbols, cell=cell) aaae(coords, st.get_coords()) # Cell calculated from cryst_const has defined orientation in space which may be # different from the original `cell`, but the volume and underlying cryst_const # must be the same. st = Structure(coords_frac=coords_frac, symbols=symbols, cryst_const=cryst_const) assert st.get_cell() is not None np.testing.assert_almost_equal(crys.volume_cell(cell), crys.volume_cell(st.get_cell())) aaae(cryst_const, crys.cell2cc(st.get_cell())) # units st = Structure(coords_frac=coords_frac, cell=cell, symbols=symbols, stress=stress, forces=forces, units={ 'length': 2, 'forces': 3, 'stress': 4 }) aaae(2 * coords, st.coords) aaae(3 * forces, st.forces) aaae(4 * stress, st.stress) traj = crys.struct2traj(st) assert traj.is_traj # copy(): Assert everything has another memory location = is a new copy of # the object. IntTypes are NOT copied by copy.deepcopy(), which we use in # Structure.copy(), apparently b/c they are always automatically copied # before in-place operations. Same for float type. # # >>> a=10; b=a; print id(a); print id(b) # 36669152 # 36669152 # >>> a*=100; print id(a); print id(b) # 72538264 # 36669152 # >>> a # 100 # >>> b # 10 # # >>> a=[1,2,3]; b=a; print id(a); print id(b) # 72624320 # 72624320 # >>> a[0] = 44; print id(a); print id(b) # 72624320 # 72624320 # >>> a # [44, 2, 3] # >>> b # [44, 2, 3] st2 = st.copy() for name in st.attr_lst: val = getattr(st, name) if val is not None and not (isinstance(val, int) or \ isinstance(val, float)): val2 = getattr(st2, name) assert id(val2) != id(val) assert_all_types_equal(val2, val)
def test_pw_scf_out(): # ref data for Structure, all lengths in Ang, energy in eV natoms = 2 symbols = ['Si', 'Si'] cell = np.array([[-2.71536701, 0., 2.71536701], [0., 2.71536701, 2.71536701], [-2.71536701, 2.71536701, 0.]]) forces = np.array([[2.57110316, 5.14220632, 7.71330948], [-2.57110316, -5.14220632, -7.71330948]]) # eV / Ang nspecies = {'Si': 2} mass = np.array([28.0855, 28.0855]) # amu cryst_const = np.array([3.84010885, 3.84010885, 3.84010885, 60., 60., 60.]) symbols_unique = ['Si'] etot = -258.58148870118305 # eV typat = [1, 1] volume = 40.041985843396688 # Ang**3 stress = np.array([[9.825, 0., 0.], [0., 9.825, 0.], [0., 0., 9.825]]) # GPa coords_frac = np.array([[0., 0., 0.], [0.25, 0.25, 0.25]]) pressure = 9.825 # GPa coords = np.array([[0., 0., 0.], [-1.35768351, 1.35768351, 1.35768351]]) order = {'Si': 1} alat = 10.2626 # Bohr filename = 'files/pw.scf.out' common.system('gunzip %s.gz' % filename) # use_alat=False. Provide high-precision alat from outside (e.g. # from pw.in instead of parsing and using low-precision value from pw.out). # Here we use the same alat for the tests. pp1 = PwSCFOutputFile( filename=filename, use_alat=False, # alat=1.0 units={'length': alat * Bohr / Ang}) struct1 = pp1.get_struct() # pp1.parse() called here assert_attrs_not_none(struct1) assert_attrs_not_none(pp1) assert pp1.scf_converged is True assert alat == pp1.get_alat(True) assert 1.0 == pp1.get_alat(False) aaae(cryst_const, struct1.cryst_const) aaae(cell, struct1.cell) aaae(coords, struct1.coords) aaae(coords_frac, struct1.coords_frac) aaae(forces, struct1.forces) aaae(stress, struct1.stress) assert np.allclose(volume, struct1.volume) assert np.allclose(etot, struct1.etot) assert np.allclose(pressure, struct1.pressure) # use_alat=True, alat = 10.2626 Bohr pp2 = PwSCFOutputFile(filename=filename, use_alat=True) struct2 = pp2.get_struct() # pp.parse() called here assert_attrs_not_none(struct2) assert_attrs_not_none(pp2) assert np.allclose(alat, pp2.alat) assert pp2.scf_converged is True assert alat == pp2.get_alat(True) # Bohr assert 1.0 == pp2.get_alat(False) # Skip coords adn cell b/c they are modified by self.alat and # pp1.alat = 1.0, pp2.alat = 10.2626 attr_lst = common.pop_from_list(pp1.attr_lst, ['coords', 'cell']) adae(pp1.__dict__, pp2.__dict__, keys=attr_lst) attr_lst = struct1.attr_lst adae(struct1.__dict__, struct2.__dict__, keys=attr_lst) pp3 = PwSCFOutputFile(filename=filename) assert alat == pp3.get_alat() # self.use_alat=True default common.system('gzip %s' % filename)
def test_traj(): natoms = 10 nstep = 100 cell = rand(nstep,3,3) stress = rand(nstep,3,3) forces = rand(nstep,natoms,3) etot = rand(nstep) cryst_const = crys.cell2cc3d(cell, axis=0) coords_frac = rand(nstep,natoms,3) coords = crys.coord_trans3d(coords=coords_frac, old=cell, new=num.extend_array(np.identity(3), nstep,axis=0), axis=1, timeaxis=0) assert cryst_const.shape == (nstep, 6) assert coords.shape == (nstep,natoms,3) symbols = ['H']*natoms # automatically calculated: # coords # cell # pressure # velocity (from coords) # temperature (from ekin) # ekin (from velocity) traj = Trajectory(coords_frac=coords_frac, cell=cell, symbols=symbols, forces=forces, stress=stress, etot=etot, timestep=1, ) # Test if all getters work. for name in traj.attr_lst: print "test if getters work:", name traj.try_set_attr(name) assert getattr(traj, name) is not None, "attr None: %s" %name assert eval('traj.get_%s()'%name) is not None, "getter returns None: %s" %name print "test if getters work:", name, "... ok" aaae(coords_frac, traj.coords_frac) aaae(coords, traj.coords) aaae(cryst_const, traj.cryst_const) aaae(np.trace(stress, axis1=1, axis2=2)/3.0, traj.pressure) assert traj.coords.shape == (nstep,natoms,3) assert traj.cell.shape == (nstep,3,3) assert traj.velocity.shape == (nstep, natoms, 3) assert traj.temperature.shape == (nstep,) assert traj.ekin.shape == (nstep,) assert traj.nstep == nstep assert traj.natoms == natoms traj = Trajectory(coords_frac=coords_frac, symbols=symbols, cell=cell) aaae(coords, traj.coords) # Cell calculated from cryst_const has defined orientation in space which may be # different from the original `cell`, but the volume and underlying cryst_const # must be the same. traj = Trajectory(coords_frac=coords_frac, symbols=symbols, cryst_const=cryst_const) np.testing.assert_almost_equal(crys.volume_cell3d(cell), crys.volume_cell3d(traj.cell)) aaae(cryst_const, crys.cell2cc3d(traj.cell)) # extend arrays cell2d = rand(3,3) cc2d = crys.cell2cc(cell2d) traj = Trajectory(coords_frac=coords_frac, cell=cell2d, symbols=symbols) assert traj.cell.shape == (nstep,3,3) assert traj.cryst_const.shape == (nstep,6) for ii in range(traj.nstep): assert (traj.cell[ii,...] == cell2d).all() assert (traj.cryst_const[ii,:] == cc2d).all() traj = Trajectory(coords_frac=coords_frac, cryst_const=cc2d, symbols=symbols) assert traj.cell.shape == (nstep,3,3) assert traj.cryst_const.shape == (nstep,6) for ii in range(traj.nstep): assert (traj.cryst_const[ii,:] == cc2d).all() # units traj = Trajectory(coords_frac=coords_frac, cell=cell, symbols=symbols, stress=stress, forces=forces, units={'length': 2, 'forces': 3, 'stress': 4}) aaae(2*coords, traj.coords) aaae(3*forces, traj.forces) aaae(4*stress, traj.stress) # iterate, check if Structures are complete traj = Trajectory(coords=coords, symbols=symbols, cell=cell, forces=forces, stress=stress, etot=etot, timestep=1.0) for struct in traj: assert struct.is_struct, "st is not Structure" assert not struct.is_traj, "st is Trajectory" assert_attrs_not_none(struct) struct = traj[0] for attr_name in traj.attr_lst: if attr_name in struct.attrs_only_traj: msg = "tr[0] %s is not None" %attr_name assert getattr(struct,attr_name) is None, msg else: msg = "tr[0] %s is None" %attr_name assert getattr(struct,attr_name) is not None, msg # slices, return traj keys = traj.attr_lst[:] tsl = traj[10:80:2] assert tsl.nstep == traj.nstep / 2 - 15 assert_attrs_not_none(tsl, attr_lst=keys) tsl = traj[slice(10,80,2)] assert tsl.nstep == traj.nstep / 2 - 15 assert_attrs_not_none(tsl, attr_lst=keys) tsl = traj[np.s_[10:80:2]] assert tsl.nstep == traj.nstep / 2 - 15 assert_attrs_not_none(tsl, attr_lst=keys) assert tsl.is_traj # iteration over sliced traj tsl = traj[10:80:2] for x in tsl: pass for x in tsl.copy(): pass # repeat iter for i in range(2): cnt = 0 for st in traj: cnt += 1 assert cnt == nstep, "%i, %i" %(cnt, nstep) # copy traj2 = traj.copy() for name in traj.attr_lst: val = getattr(traj,name) if val is not None and not (isinstance(val, types.IntType) or \ isinstance(val, types.FloatType)): val2 = getattr(traj2,name) print "test copy:", name, type(val), type(val2) assert id(val2) != id(val) assert_all_types_equal(val2, val) assert_dict_with_all_types_equal(traj.__dict__, traj2.__dict__, keys=traj.attr_lst)
def test_sum(): arr = rand(2, 3, 4) # this all goes thru np.sum(), must produce exact same result assert sum(arr) == sum(arr, axis=None) == arr.sum() # must use aaae() b/c summing order is apparently different in # np.sum(axis=None) -> small numerical noise aaae(sum(arr, axis=(0, 1, 2)), arr.sum()) aaae(sum(arr, axis=0), arr.sum(axis=0)) aaae(sum(arr, axis=1), arr.sum(axis=1)) aaae(sum(arr, axis=2), arr.sum(axis=2)) aaae(sum(arr, axis=-1), arr.sum(axis=-1)) aaae(sum(arr, axis=-2), arr.sum(axis=-2)) aaae(sum(arr, axis=(0, )), arr.sum(axis=0)) aaae(sum(arr, axis=(1, )), arr.sum(axis=1)) aaae(sum(arr, axis=(2, )), arr.sum(axis=2)) assert sum(arr, axis=(0, 1)).shape == (4, ) assert sum(arr, axis=(0, 2)).shape == (3, ) assert sum(arr, axis=(1, 2)).shape == (2, ) aaae(sum(arr, axis=(0, 1)), arr.sum(axis=0).sum(axis=0)) aaae(sum(arr, axis=(0, 2)), arr.sum(axis=0).sum(axis=1)) aaae(sum(arr, axis=(1, 2)), arr.sum(axis=1).sum(axis=1)) assert sum(arr, axis=(0, ), keepdims=True).shape == (2, ) assert sum(arr, axis=(1, ), keepdims=True).shape == (3, ) assert sum(arr, axis=(2, ), keepdims=True).shape == (4, ) assert sum(arr, axis=(0, 1), keepdims=True).shape == (2, 3) assert sum(arr, axis=(0, 2), keepdims=True).shape == (2, 4) assert sum(arr, axis=(1, 2), keepdims=True).shape == (3, 4) aaae(sum(arr, axis=(0, 1)), sum(arr, axis=(1, 0))) aaae(sum(arr, axis=(0, 2)), sum(arr, axis=(2, 0))) aaae(sum(arr, axis=(1, 2)), sum(arr, axis=(2, 1)))
def test_sum(): arr = rand(2,3,4) # this all goes thru np.sum(), must produce exact same result assert sum(arr) == sum(arr, axis=None) == arr.sum() # must use aaae() b/c summing order is apparently different in # np.sum(axis=None) -> small numerical noise aaae(sum(arr, axis=(0,1,2)), arr.sum()) aaae(sum(arr, axis=0), arr.sum(axis=0)) aaae(sum(arr, axis=1), arr.sum(axis=1)) aaae(sum(arr, axis=2), arr.sum(axis=2)) aaae(sum(arr, axis=-1), arr.sum(axis=-1)) aaae(sum(arr, axis=-2), arr.sum(axis=-2)) aaae(sum(arr, axis=(0,)), arr.sum(axis=0)) aaae(sum(arr, axis=(1,)), arr.sum(axis=1)) aaae(sum(arr, axis=(2,)), arr.sum(axis=2)) assert sum(arr, axis=(0,1)).shape == (4,) assert sum(arr, axis=(0,2)).shape == (3,) assert sum(arr, axis=(1,2)).shape == (2,) aaae(sum(arr, axis=(0,1)), arr.sum(axis=0).sum(axis=0)) aaae(sum(arr, axis=(0,2)), arr.sum(axis=0).sum(axis=1)) aaae(sum(arr, axis=(1,2)), arr.sum(axis=1).sum(axis=1)) assert sum(arr, axis=(0,), keepdims=True).shape == (2,) assert sum(arr, axis=(1,), keepdims=True).shape == (3,) assert sum(arr, axis=(2,), keepdims=True).shape == (4,) assert sum(arr, axis=(0,1), keepdims=True).shape == (2,3) assert sum(arr, axis=(0,2), keepdims=True).shape == (2,4) assert sum(arr, axis=(1,2), keepdims=True).shape == (3,4) aaae(sum(arr, axis=(0,1)), sum(arr, axis=(1,0))) aaae(sum(arr, axis=(0,2)), sum(arr, axis=(2,0))) aaae(sum(arr, axis=(1,2)), sum(arr, axis=(2,1)))
def test_pw_scf_out(): # ref data for Structure, all lengths in Ang, energy in eV natoms = 2 symbols = ['Si', 'Si'] cell = np.array([[-2.71536701, 0. , 2.71536701], [ 0. , 2.71536701, 2.71536701], [-2.71536701, 2.71536701, 0. ]]) forces = np.array([[ 2.57110316, 5.14220632, 7.71330948], [-2.57110316, -5.14220632, -7.71330948]]) # eV / Ang nspecies = {'Si': 2} mass = np.array([ 28.0855, 28.0855]) # amu cryst_const = np.array([ 3.84010885, 3.84010885, 3.84010885, 60. , 60. , 60. ]) symbols_unique = ['Si'] etot = -258.58148870118305 # eV typat = [1, 1] volume = 40.041985843396688 # Ang**3 stress = np.array([[ 9.825, 0. , 0. ], [ 0. , 9.825, 0. ], [ 0. , 0. , 9.825]]) # GPa coords_frac = np.array([[ 0. , 0. , 0. ], [ 0.25, 0.25, 0.25]]) pressure = 9.825 # GPa coords = np.array([[ 0. , 0. , 0. ], [-1.35768351, 1.35768351, 1.35768351]]) order = {'Si': 1} alat = 10.2626 # Bohr filename = 'files/pw.scf.out' common.system('gunzip %s.gz' %filename) # use_alat=False. Provide high-precision alat from outside (e.g. # from pw.in instead of parsing and using low-precision value from pw.out). # Here we use the same alat for the tests. pp1 = PwSCFOutputFile(filename=filename, use_alat=False, # alat=1.0 units={'length': alat*Bohr/Ang}) struct1 = pp1.get_struct() # pp1.parse() called here assert_attrs_not_none(struct1) assert_attrs_not_none(pp1) assert pp1.scf_converged is True assert alat == pp1.get_alat(True) assert 1.0 == pp1.get_alat(False) aaae(cryst_const, struct1.cryst_const) aaae(cell, struct1.cell) aaae(coords, struct1.coords) aaae(coords_frac, struct1.coords_frac) aaae(forces, struct1.forces) aaae(stress, struct1.stress) assert np.allclose(volume, struct1.volume) assert np.allclose(etot, struct1.etot) assert np.allclose(pressure, struct1.pressure) # use_alat=True, alat = 10.2626 Bohr pp2 = PwSCFOutputFile(filename=filename, use_alat=True) struct2 = pp2.get_struct() # pp.parse() called here assert_attrs_not_none(struct2) assert_attrs_not_none(pp2) assert np.allclose(alat, pp2.alat) assert pp2.scf_converged is True assert alat == pp2.get_alat(True) # Bohr assert 1.0 == pp2.get_alat(False) # Skip coords adn cell b/c they are modified by self.alat and # pp1.alat = 1.0, pp2.alat = 10.2626 attr_lst = common.pop_from_list(pp1.attr_lst, ['coords', 'cell']) adae(pp1.__dict__, pp2.__dict__, keys=attr_lst) attr_lst = struct1.attr_lst adae(struct1.__dict__, struct2.__dict__, keys=attr_lst) pp3 = PwSCFOutputFile(filename=filename) assert alat == pp3.get_alat() # self.use_alat=True default common.system('gzip %s' %filename)
def test_traj(): natoms = 10 nstep = 100 cell = rand(nstep, 3, 3) stress = rand(nstep, 3, 3) forces = rand(nstep, natoms, 3) etot = rand(nstep) cryst_const = crys.cell2cc3d(cell, axis=0) coords_frac = rand(nstep, natoms, 3) coords = crys.coord_trans3d(coords=coords_frac, old=cell, new=num.extend_array(np.identity(3), nstep, axis=0), axis=1, timeaxis=0) assert cryst_const.shape == (nstep, 6) assert coords.shape == (nstep, natoms, 3) symbols = ['H'] * natoms # automatically calculated: # coords # cell # pressure # velocity (from coords) # temperature (from ekin) # ekin (from velocity) traj = Trajectory( coords_frac=coords_frac, cell=cell, symbols=symbols, forces=forces, stress=stress, etot=etot, timestep=1, ) # Test if all getters work. for name in traj.attr_lst: print("test if getters work:", name) traj.try_set_attr(name) assert getattr(traj, name) is not None, "attr None: %s" % name assert eval('traj.get_%s()' % name) is not None, "getter returns None: %s" % name print("test if getters work:", name, "... ok") aaae(coords_frac, traj.coords_frac) aaae(coords, traj.coords) aaae(cryst_const, traj.cryst_const) aaae(np.trace(stress, axis1=1, axis2=2) / 3.0, traj.pressure) assert traj.coords.shape == (nstep, natoms, 3) assert traj.cell.shape == (nstep, 3, 3) assert traj.velocity.shape == (nstep, natoms, 3) assert traj.temperature.shape == (nstep, ) assert traj.ekin.shape == (nstep, ) assert traj.nstep == nstep assert traj.natoms == natoms traj = Trajectory(coords_frac=coords_frac, symbols=symbols, cell=cell) aaae(coords, traj.coords) # Cell calculated from cryst_const has defined orientation in space which may be # different from the original `cell`, but the volume and underlying cryst_const # must be the same. traj = Trajectory(coords_frac=coords_frac, symbols=symbols, cryst_const=cryst_const) np.testing.assert_almost_equal(crys.volume_cell3d(cell), crys.volume_cell3d(traj.cell)) aaae(cryst_const, crys.cell2cc3d(traj.cell)) # extend arrays cell2d = rand(3, 3) cc2d = crys.cell2cc(cell2d) traj = Trajectory(coords_frac=coords_frac, cell=cell2d, symbols=symbols) assert traj.cell.shape == (nstep, 3, 3) assert traj.cryst_const.shape == (nstep, 6) for ii in range(traj.nstep): assert (traj.cell[ii, ...] == cell2d).all() assert (traj.cryst_const[ii, :] == cc2d).all() traj = Trajectory(coords_frac=coords_frac, cryst_const=cc2d, symbols=symbols) assert traj.cell.shape == (nstep, 3, 3) assert traj.cryst_const.shape == (nstep, 6) for ii in range(traj.nstep): assert (traj.cryst_const[ii, :] == cc2d).all() # units traj = Trajectory(coords_frac=coords_frac, cell=cell, symbols=symbols, stress=stress, forces=forces, units={ 'length': 2, 'forces': 3, 'stress': 4 }) aaae(2 * coords, traj.coords) aaae(3 * forces, traj.forces) aaae(4 * stress, traj.stress) # iterate, check if Structures are complete traj = Trajectory(coords=coords, symbols=symbols, cell=cell, forces=forces, stress=stress, etot=etot, timestep=1.0) for struct in traj: assert struct.is_struct, "st is not Structure" assert not struct.is_traj, "st is Trajectory" assert_attrs_not_none(struct) struct = traj[0] for attr_name in traj.attr_lst: if attr_name in struct.attrs_only_traj: msg = "tr[0] %s is not None" % attr_name assert getattr(struct, attr_name) is None, msg else: msg = "tr[0] %s is None" % attr_name assert getattr(struct, attr_name) is not None, msg # slices, return traj keys = traj.attr_lst[:] tsl = traj[10:80:2] assert tsl.nstep == traj.nstep / 2 - 15 assert_attrs_not_none(tsl, attr_lst=keys) tsl = traj[slice(10, 80, 2)] assert tsl.nstep == traj.nstep / 2 - 15 assert_attrs_not_none(tsl, attr_lst=keys) tsl = traj[np.s_[10:80:2]] assert tsl.nstep == traj.nstep / 2 - 15 assert_attrs_not_none(tsl, attr_lst=keys) assert tsl.is_traj # iteration over sliced traj tsl = traj[10:80:2] for x in tsl: pass for x in tsl.copy(): pass # repeat iter for i in range(2): cnt = 0 for st in traj: cnt += 1 assert cnt == nstep, "%i, %i" % (cnt, nstep) # copy traj2 = traj.copy() for name in traj.attr_lst: val = getattr(traj, name) if val is not None and not (isinstance(val, int) or \ isinstance(val, float)): val2 = getattr(traj2, name) print("test copy:", name, type(val), type(val2)) assert id(val2) != id(val) assert_all_types_equal(val2, val) assert_dict_with_all_types_equal(traj.__dict__, traj2.__dict__, keys=traj.attr_lst)
def test_coord_trans(): #----------------------------------------------------------- # 2D #----------------------------------------------------------- c_X = rand(20,3) # basis vecs are assumed to be rows X = rand(3,3)*5 Y = rand(3,3)*3 # transform and back-transform c_Y = coord_trans(c_X, old=X, new=Y) c_X2 = coord_trans(c_Y, old=Y, new=X) aaae(c_X, c_X2) # simple dot product must produce same cartesian results: # X . v_X = I . v_I = v_I X = np.identity(3) Y = rand(3,3)*3 c_X = rand(20,3) c_Y = coord_trans(c_X, old=X, new=Y) # normal back-transform c_X2 = coord_trans(c_Y, old=Y, new=X) # 2 forms w/ dot(), assume: basis vecs = rows of X and Y c_X3 = np.dot(c_Y, Y) c_X4 = np.dot(Y.T, c_Y.T).T aaae(c_X, c_X2) aaae(c_X, c_X3) aaae(c_X, c_X4) # some textbook example # v_I = np.array([1.0,1.5]) I = np.identity(2) # basis vecs as rows X = sqrt(2)/2.0*np.array([[1,-1],[1,1]]).T Y = np.array([[1,1],[0,1]]).T # "identity" transform aaae(coord_trans(v_I,I,I), v_I) # v in basis X and Y v_X = coord_trans(v_I,I,X) v_Y = coord_trans(v_I,I,Y) aaae(v_X, np.array([1.76776695, 0.35355339])) aaae(v_Y, np.array([-0.5, 1.5])) # back-transform aaae(coord_trans(v_X,X,I), v_I) aaae(coord_trans(v_Y,Y,I), v_I) # higher "x,y,z"-dims: 4-vectors c_X = rand(20,4) X = rand(4,4)*5 Y = rand(4,4)*3 c_Y = coord_trans(c_X, old=X, new=Y) c_X2 = coord_trans(c_Y, old=Y, new=X) aaae(c_X, c_X2) #----------------------------------------------------------- # 3D #----------------------------------------------------------- # x,y,z case c_X = rand(20,3,10) X = rand(3,3)*5 Y = rand(3,3)*3 c_Y = coord_trans(c_X, old=X, new=Y, axis=1) c_X2 = coord_trans(c_Y, old=Y, new=X, axis=1) aaae(c_X, c_X2) c_X = rand(20,10,3) c_Y = coord_trans(c_X, old=X, new=Y, axis=-1) c_X2 = coord_trans(c_Y, old=Y, new=X, axis=-1) aaae(c_X, c_X2) c_X = rand(3,20,10) c_Y = coord_trans(c_X, old=X, new=Y, axis=0) c_X2 = coord_trans(c_Y, old=Y, new=X, axis=0) aaae(c_X, c_X2) # 3d, higher "x,y,z"-dims, i.e. 4-vectors: trajectory of 5 atoms, 10 steps, # "4d-coordinates" c_X = rand(20,4,10) X = rand(4,4)*5 Y = rand(4,4)*3 c_Y = coord_trans(c_X, old=X, new=Y, axis=1) c_X2 = coord_trans(c_Y, old=Y, new=X, axis=1) aaae(c_X, c_X2) #----------------------------------------------------------- # ND #----------------------------------------------------------- # arbitrary collection of 4-vectors c_X = rand(20,4,10,8) X = rand(4,4)*5 Y = rand(4,4)*3 c_Y = coord_trans(c_X, old=X, new=Y, axis=1) c_X2 = coord_trans(c_Y, old=Y, new=X, axis=1) aaae(c_X, c_X2) #----------------------------------------------------------- # special case 3d #----------------------------------------------------------- # Note that axis=1 is always the xyz-axis (length 3) if the timeaxis # (length 10) would be removed from all arrays (2d case then). c_X = rand(20,3,10) X = rand(3,3,10)*5 Y = rand(3,3,10)*3 c_Y = coord_trans3d(c_X, old=X, new=Y, axis=1, timeaxis=2) c_X2 = coord_trans3d(c_Y, old=Y, new=X, axis=1, timeaxis=2) aaae(c_X, c_X2) c_X = rand(20,10,3) X = rand(3,10,3)*5 Y = rand(3,10,3)*3 c_Y = coord_trans3d(c_X, old=X, new=Y, axis=1, timeaxis=1) c_X2 = coord_trans3d(c_Y, old=Y, new=X, axis=1, timeaxis=1) aaae(c_X, c_X2) c_X = rand(10,20,3) X = rand(10,3,3)*5 Y = rand(10,3,3)*3 c_Y = coord_trans3d(c_X, old=X, new=Y, axis=1, timeaxis=0) c_X2 = coord_trans3d(c_Y, old=Y, new=X, axis=1, timeaxis=0) aaae(c_X, c_X2)
def test_struct(): natoms = 10 cell = np.array([[3,0,0], [1.1,5,-0.04], [-0.33,1.5,7]]) cryst_const = crys.cell2cc(cell) coords_frac = rand(natoms,3) coords = crys.coord_trans(coords=coords_frac, old=cell, new=np.identity(3)) symbols = ['H']*natoms stress = rand(3,3) forces = rand(natoms,3) # Use ``cell`` instead of ``cryst_const` as input such that # atoms.get_cell() test passes (see below for why -- cell orientation) st = Structure(coords_frac=coords_frac, symbols=symbols, cell=cell, stress=stress, forces=forces, etot=42) # Test if all getters work. for name in st.attr_lst: print name st.try_set_attr(name) assert getattr(st, name) is not None, "attr None: %s" %name assert eval('st.get_%s()'%name) is not None, "getter returns None: %s" %name aaae(coords_frac, st.coords_frac) aaae(cryst_const, st.cryst_const) aaae(coords, st.coords) assert st.natoms == natoms st = Structure(coords_frac=coords_frac, symbols=symbols, cell=cell) aaae(coords, st.get_coords()) # Cell calculated from cryst_const has defined orientation in space which may be # different from the original `cell`, but the volume and underlying cryst_const # must be the same. st = Structure(coords_frac=coords_frac, symbols=symbols, cryst_const=cryst_const) assert st.get_cell() is not None np.testing.assert_almost_equal(crys.volume_cell(cell), crys.volume_cell(st.get_cell())) aaae(cryst_const, crys.cell2cc(st.get_cell())) # units st = Structure(coords_frac=coords_frac, cell=cell, symbols=symbols, stress=stress, forces=forces, units={'length': 2, 'forces': 3, 'stress': 4}) aaae(2*coords, st.coords) aaae(3*forces, st.forces) aaae(4*stress, st.stress) traj = crys.struct2traj(st) assert traj.is_traj # copy(): Assert everything has another memory location = is a new copy of # the object. IntTypes are NOT copied by copy.deepcopy(), which we use in # Structure.copy(), apparently b/c they are always automatically copied # before in-place operations. Same for float type. # # >>> a=10; b=a; print id(a); print id(b) # 36669152 # 36669152 # >>> a*=100; print id(a); print id(b) # 72538264 # 36669152 # >>> a # 100 # >>> b # 10 # # >>> a=[1,2,3]; b=a; print id(a); print id(b) # 72624320 # 72624320 # >>> a[0] = 44; print id(a); print id(b) # 72624320 # 72624320 # >>> a # [44, 2, 3] # >>> b # [44, 2, 3] st2 = st.copy() for name in st.attr_lst: val = getattr(st,name) if val is not None and not (isinstance(val, types.IntType) or \ isinstance(val, types.FloatType)): val2 = getattr(st2,name) assert id(val2) != id(val) assert_all_types_equal(val2, val)