def test_get_ase_atoms(): natoms = 10 st = crys.Structure(coords_frac=rand(natoms,3), symbols=['H']*10, cell=rand(3,3)) try: import ase st2 = crys.atoms2struct(crys.struct2atoms(st)) keys = ['natoms', 'coords', 'coords_frac', 'symbols', 'cryst_const', 'cell', 'volume', 'mass'] tools.assert_dict_with_all_types_almost_equal(\ st.__dict__, st2.__dict__, keys=keys, strict=True) # in case the test fails, use this to find out which key failed ## for kk in keys: ## print("testing: %s ..." %kk) ## tools.assert_all_types_almost_equal(st.__dict__[kk], st2.__dict__[kk]) for pbc in [True,False]: at = st.get_ase_atoms(pbc=pbc) assert (at.pbc == np.array([pbc]*3)).all() at = crys.struct2atoms(st, pbc=pbc) assert (at.pbc == np.array([pbc]*3)).all() except ImportError: tools.skip("cannot import ase, skipping test get_ase_atoms()")
def test_get_ase_atoms(): natoms = 10 st = crys.Structure(coords_frac=rand(natoms, 3), symbols=['H'] * 10, cell=rand(3, 3)) try: import ase st2 = crys.atoms2struct(crys.struct2atoms(st)) keys = [ 'natoms', 'coords', 'coords_frac', 'symbols', 'cryst_const', 'cell', 'volume', 'mass' ] tools.assert_dict_with_all_types_almost_equal(\ st.__dict__, st2.__dict__, keys=keys, strict=True) # in case the test fails, use this to find out which key failed ## for kk in keys: ## print("testing: %s ..." %kk) ## tools.assert_all_types_almost_equal(st.__dict__[kk], st2.__dict__[kk]) for pbc in [True, False]: at = st.get_ase_atoms(pbc=pbc) assert (at.pbc == np.array([pbc] * 3)).all() at = crys.struct2atoms(st, pbc=pbc) assert (at.pbc == np.array([pbc] * 3)).all() except ImportError: tools.skip("cannot import ase, skipping test get_ase_atoms()")
def test_plot_dis(): spp = kpath.SpecialPointsPath(ks=np.array([[0,0,0], [.5,0,0], [.7,0,0]]), ks_frac=np.array([[0,0,0], [.55,0,0], [.77,0,0]]), symbols=['A','B', 'C']) path_norm = np.linspace(0,1,100) nfreq = 5 freqs = np.random.rand(100, nfreq) try: print os.environ['DISPLAY'] fig1,ax1,axdos1 = kpath.plot_dis(path_norm, freqs, spp, show_coords='cart') assert axdos1 is None fig2,ax2 = mpl.fig_ax() kpath.plot_dis(path_norm, freqs, spp, ax=ax2, show_coords='frac') lines1 = ax1.get_lines() lines2 = ax2.get_lines() for idx in range(nfreq): x1 = lines1[idx].get_xdata() x2 = lines2[idx].get_xdata() y1 = lines1[idx].get_ydata() y2 = lines2[idx].get_ydata() assert (x1 == x2).all() assert (y1 == y2).all() faxis = np.linspace(freqs.min(), freqs.max(), 30) dos = np.array([faxis, np.random.rand(len(faxis))]).T fig3,ax3,ax3dos = kpath.plot_dis(path_norm, freqs, spp, dos=dos, show_coords=None) # plot 90 rotated -> x and y swapped assert (ax3dos.get_lines()[0].get_xdata() == dos[:,1]).all() assert (ax3dos.get_lines()[0].get_ydata() == dos[:,0]).all() except KeyError: tools.skip("no DISPLAY environment variable, skipping test")
def test_interpol2d_CloughTocher(): dd, tgt = get_test_data() try: from scipy.interpolate import CloughTocher2DInterpolator inter = num.Interpol2D(dd=dd, what='ct') assert np.allclose(inter([[-3,-4],[0,0]]), tgt, atol=1e-1) assert np.allclose(return_min(inter), 5.0, atol=1e-1) dump(inter) except ImportError: tools.skip("couldn't import scipy.interpolate.CloughTocher2DInterpolator")
def test_ct(self): try: from scipy.interpolate import CloughTocher2DInterpolator inter = num.Interpol2D(dd=self.dd, what='ct') assert np.allclose(inter([[-3, -4], [0, 0]]), self.tgt, atol=1e-1) assert np.allclose(return_min(inter), 5.0, atol=1e-1) assert np.allclose(inter(self.dd.XY), self.dd.zz) dump(inter) except ImportError: tools.skip( "couldn't import scipy.interpolate.CloughTocher2DInterpolator")
def test_h5(): try: import h5py dct1 = \ {'/a': 'abcgs', '/b/c/x1': 3, '/b/c/x2': rand(2,3), } # writing a dct w/o leading slash will always be read back in *with* # leading slash dct2 = \ {'a': 'abciqo4iki', 'b/c/x1': 3, 'b/c/x2': rand(2,3), } for idx, dct in enumerate([dct1, dct2]): h5fn = os.path.join(testdir, 'test_%i.h5' % idx) io.write_h5(h5fn, dct) read_dct = io.read_h5(h5fn) for kk in list(read_dct.keys()): assert kk.startswith('/') for kk in list(dct.keys()): key = '/' + kk if not kk.startswith('/') else kk tools.assert_all_types_equal(dct[kk], read_dct[key]) # write mode='a', test appending h5fn = os.path.join(testdir, 'test_append.h5') io.write_h5(h5fn, {'/a': 1.0}) read_dct = io.read_h5(h5fn) assert list(read_dct.keys()) == ['/a'] assert read_dct['/a'] == 1.0 # append '/b', using {'/a': 1.0, '/b': 2.0} would be an error since /a # already exists, use mode='w' then, but this overwrites all! io.write_h5(h5fn, {'/b': 2.0}, mode='a') read_dct2 = io.read_h5(h5fn) # sort(...): sort possible [/b, /a] -> [/a, /b] assert np.sort(np.array(list( read_dct2.keys()))).tolist() == ['/a', '/b'] assert read_dct2['/a'] == 1.0 assert read_dct2['/b'] == 2.0 # overwrite io.write_h5(h5fn, {'/b': 22.0, '/c': 33.0}, mode='w') read_dct3 = io.read_h5(h5fn) assert np.sort(np.array(list( read_dct3.keys()))).tolist() == ['/b', '/c'] except ImportError: tools.skip("skipping test_h5, no h5py importable")
def test_h5(): try: import h5py dct1 = \ {'/a': 'abcgs', '/b/c/x1': 3, '/b/c/x2': rand(2,3), } # writing a dct w/o leading slash will always be read back in *with* # leading slash dct2 = \ {'a': 'abciqo4iki', 'b/c/x1': 3, 'b/c/x2': rand(2,3), } for idx,dct in enumerate([dct1, dct2]): h5fn = os.path.join(testdir, 'test_%i.h5' %idx) io.write_h5(h5fn, dct) read_dct = io.read_h5(h5fn) for kk in read_dct.keys(): assert kk.startswith('/') for kk in dct.keys(): key = '/'+kk if not kk.startswith('/') else kk tools.assert_all_types_equal(dct[kk], read_dct[key]) # write mode='a', test appending h5fn = os.path.join(testdir, 'test_append.h5') io.write_h5(h5fn, {'/a': 1.0}) read_dct = io.read_h5(h5fn) assert read_dct.keys() == ['/a'] assert read_dct['/a'] == 1.0 # append '/b', using {'/a': 1.0, '/b': 2.0} would be an error since /a # already exists, use mode='w' then, but this overwrites all! io.write_h5(h5fn, {'/b': 2.0}, mode='a') read_dct2 = io.read_h5(h5fn) # sort(...): sort possible [/b, /a] -> [/a, /b] assert np.sort(np.array(read_dct2.keys())).tolist() == ['/a', '/b'] assert read_dct2['/a'] == 1.0 assert read_dct2['/b'] == 2.0 # overwrite io.write_h5(h5fn, {'/b': 22.0, '/c': 33.0}, mode='w') read_dct3 = io.read_h5(h5fn) assert np.sort(np.array(read_dct3.keys())).tolist() == ['/b', '/c'] except ImportError: tools.skip("skipping test_h5, no h5py importable")
def test_pwscf_calculator(): if not have_ase(): skip("no ASE found, skipping test") elif not have_pwx(): skip("no pw.x found, skipping test") else: pseudo_dir = pj(testdir, prefix, 'pseudo') print(common.backtick("mkdir -pv {p}; cp files/qe_pseudos/*.gz {p}/; \ gunzip {p}/*".format(p=pseudo_dir))) at = get_atoms_with_calc_pwscf(pseudo_dir) print("scf") # trigger calculation here forces = at.get_forces() etot = at.get_potential_energy() stress = at.get_stress(voigt=False) # 3x3 st = io.read_pw_scf(at.calc.label + '.out') assert np.allclose(forces, st.forces) assert np.allclose(etot, st.etot) assert np.allclose(st.stress, -stress * constants.eV_by_Ang3_to_GPa) # files/ase/pw.scf.out.start is a norm-conserving LDA struct, # calculated with pz-vbc.UPF, so the PBE vc-relax will make the cell # a bit bigger print("vc-relax") from ase.optimize import BFGS from ase.constraints import UnitCellFilter opt = BFGS(UnitCellFilter(at)) cell = parse.arr2d_from_txt(""" -1.97281509 0. 1.97281509 0. 1.97281509 1.97281509 -1.97281509 1.97281509 0.""") assert np.allclose(cell, at.get_cell()) opt.run(fmax=0.05) # run only 2 steps cell = parse.arr2d_from_txt(""" -2.01837531 0. 2.01837531 0. 2.01837531 2.01837531 -2.01837531 2.01837531 0""") assert np.allclose(cell, at.get_cell()) # at least 1 backup files must exist: pw.*.0 is the SCF run, backed up # in the first iter of the vc-relax assert os.path.exists(at.calc.infile + '.0')
def test_pwscf_calculator(): if not have_ase(): skip("no ASE found, skipping test") elif not have_pwx(): skip("no pw.x found, skipping test") else: pseudo_dir = pj(testdir, prefix, 'pseudo') print common.backtick("mkdir -pv {p}; cp files/qe_pseudos/*.gz {p}/; \ gunzip {p}/*".format(p=pseudo_dir)) at = get_atoms_with_calc_pwscf(pseudo_dir) print "scf" # trigger calculation here forces = at.get_forces() etot = at.get_potential_energy() stress = at.get_stress(voigt=False) # 3x3 st = io.read_pw_scf(at.calc.label + '.out') assert np.allclose(forces, st.forces) assert np.allclose(etot, st.etot) assert np.allclose(st.stress, -stress * constants.eV_by_Ang3_to_GPa) # files/ase/pw.scf.out.start is a norm-conserving LDA struct, # calculated with pz-vbc.UPF, so the PBE vc-relax will make the cell # a bit bigger print "vc-relax" from ase.optimize import BFGS from ase.constraints import UnitCellFilter opt = BFGS(UnitCellFilter(at)) cell = parse.arr2d_from_txt(""" -1.97281509 0. 1.97281509 0. 1.97281509 1.97281509 -1.97281509 1.97281509 0.""") assert np.allclose(cell, at.get_cell()) opt.run(fmax=0.05) # run only 2 steps cell = parse.arr2d_from_txt(""" -2.01837531 0. 2.01837531 0. 2.01837531 2.01837531 -2.01837531 2.01837531 0""") assert np.allclose(cell, at.get_cell()) # at least 1 backup files must exist: pw.*.0 is the SCF run, backed up # in the first iter of the vc-relax assert os.path.exists(at.calc.infile + '.0')
def test_mpl(): try: from pwtools import mpl try: import os print(os.environ['DISPLAY']) fig,ax = mpl.fig_ax(dpi=15,num=20) assert fig.dpi == 15 assert fig.number == 20 pl = mpl.Plot(dpi=15,num=20) assert pl.fig.dpi == 15 assert pl.fig.number == 20 dct = mpl.prepare_plots(['test'], dpi=15,num=20) assert dct['test'].fig.dpi == 15 assert dct['test'].fig.number == 20 except KeyError: tools.skip("no DISPLAY environment variable, skipping test") except ImportError: tools.skipping("couldn't import matplotlib, skipping test")
def test_mpl(): try: from pwtools import mpl try: import os print os.environ['DISPLAY'] fig,ax = mpl.fig_ax(dpi=15,num=20) assert fig.dpi == 15 assert fig.number == 20 pl = mpl.Plot(dpi=15,num=20) assert pl.fig.dpi == 15 assert pl.fig.number == 20 dct = mpl.prepare_plots(['test'], dpi=15,num=20) assert dct['test'].fig.dpi == 15 assert dct['test'].fig.number == 20 except KeyError: tools.skip("no DISPLAY environment variable, skipping test") except ImportError: tools.skipping("couldn't import matplotlib, skipping test")
def test_lammps_calculator(): if not have_ase(): skip("no ASE found, skipping test") elif not have_lmp(): skip("no lammps found, skipping test") else: at = get_atoms_with_calc_lammps() at.rattle(stdev=0.001, seed=int(time.time())) common.makedirs(at.calc.directory) print(common.backtick("cp -v utils/lammps/AlN.tersoff {p}/".format( p=at.calc.directory))) print("scf") forces = at.get_forces() etot = at.get_potential_energy() stress = at.get_stress(voigt=False) # 3x3 st = io.read_lammps_md_txt(at.calc.label + '.out')[0] assert np.allclose(forces, st.forces) assert np.allclose(etot, st.etot) assert np.allclose(st.stress, -stress * constants.eV_by_Ang3_to_GPa, atol=1e-10) print("relax") from ase.optimize import BFGS opt = BFGS(at, maxstep=0.04) opt.run(fmax=0.001, steps=10) coords_frac = parse.arr2d_from_txt(""" 3.3333341909920072e-01 6.6666683819841532e-01 4.4325467247779138e-03 6.6666681184103216e-01 3.3333362368205072e-01 5.0443254824788963e-01 3.3333341909918301e-01 6.6666683819838046e-01 3.8356759709402671e-01 6.6666681184101539e-01 3.3333362368201563e-01 8.8356759861713752e-01 """) assert np.allclose(coords_frac, at.get_scaled_positions(), atol=1e-2) # at least 1 backup files must exist assert os.path.exists(at.calc.infile + '.0') assert os.path.exists(at.calc.outfile + '.0') assert os.path.exists(at.calc.dumpfile + '.0') assert os.path.exists(at.calc.structfile + '.0')
def test_lammps_calculator(): if not have_ase(): skip("no ASE found, skipping test") elif not have_lmp(): skip("no lammps found, skipping test") else: at = get_atoms_with_calc_lammps() at.rattle(stdev=0.001, seed=int(time.time())) common.makedirs(at.calc.directory) print common.backtick("cp -v utils/lammps/AlN.tersoff {p}/".format( p=at.calc.directory)) print "scf" forces = at.get_forces() etot = at.get_potential_energy() stress = at.get_stress(voigt=False) # 3x3 st = io.read_lammps_md_txt(at.calc.label + '.out')[0] assert np.allclose(forces, st.forces) assert np.allclose(etot, st.etot) assert np.allclose(st.stress, -stress * constants.eV_by_Ang3_to_GPa, atol=1e-10) print "relax" from ase.optimize import BFGS opt = BFGS(at, maxstep=0.04) opt.run(fmax=0.001, steps=10) coords_frac = parse.arr2d_from_txt(""" 3.3333341909920072e-01 6.6666683819841532e-01 4.4325467247779138e-03 6.6666681184103216e-01 3.3333362368205072e-01 5.0443254824788963e-01 3.3333341909918301e-01 6.6666683819838046e-01 3.8356759709402671e-01 6.6666681184101539e-01 3.3333362368201563e-01 8.8356759861713752e-01 """) assert np.allclose(coords_frac, at.get_scaled_positions(), atol=1e-2) # at least 1 backup files must exist assert os.path.exists(at.calc.infile + '.0') assert os.path.exists(at.calc.outfile + '.0') assert os.path.exists(at.calc.dumpfile + '.0') assert os.path.exists(at.calc.structfile + '.0')
def test_plot_dis(): spp = kpath.SpecialPointsPath(ks=np.array([[0, 0, 0], [.5, 0, 0], [.7, 0, 0]]), ks_frac=np.array([[0, 0, 0], [.55, 0, 0], [.77, 0, 0]]), symbols=['A', 'B', 'C']) path_norm = np.linspace(0, 1, 100) nfreq = 5 freqs = np.random.rand(100, nfreq) try: print(os.environ['DISPLAY']) fig1, ax1, axdos1 = kpath.plot_dis(path_norm, freqs, spp, show_coords='cart') assert axdos1 is None fig2, ax2 = mpl.fig_ax() kpath.plot_dis(path_norm, freqs, spp, ax=ax2, show_coords='frac') lines1 = ax1.get_lines() lines2 = ax2.get_lines() for idx in range(nfreq): x1 = lines1[idx].get_xdata() x2 = lines2[idx].get_xdata() y1 = lines1[idx].get_ydata() y2 = lines2[idx].get_ydata() assert (x1 == x2).all() assert (y1 == y2).all() faxis = np.linspace(freqs.min(), freqs.max(), 30) dos = np.array([faxis, np.random.rand(len(faxis))]).T fig3, ax3, ax3dos = kpath.plot_dis(path_norm, freqs, spp, dos=dos, show_coords=None) # plot 90 rotated -> x and y swapped assert (ax3dos.get_lines()[0].get_xdata() == dos[:, 1]).all() assert (ax3dos.get_lines()[0].get_ydata() == dos[:, 0]).all() except KeyError: tools.skip("no DISPLAY environment variable, skipping test")
def test_eos(): # load reference fitted with ElkEOSFit, data points [Bohr^3, Ha] -> [Ang^3, eV] # EV input data [Bohr^3, Ry] -> [Ang^3, eV] data = np.loadtxt("files/ev/evdata.txt") volume = data[:,0] * Bohr3_to_Ang3 energy = data[:,1] * (Ry / eV) ref_ev = np.loadtxt("files/ev/EVPAI.OUT.gz") ref_ev[:,0] *= Bohr3_to_Ang3 ref_ev[:,1] *= (Ha / eV) ref_pv = np.loadtxt("files/ev/PVPAI.OUT.gz") ref_pv[:,0] *= Bohr3_to_Ang3 ref_min = np.loadtxt("files/ev/min.txt") ref_min[0] *= Bohr3_to_Ang3 # v0 ref_min[1] *= (Ry / eV) # e0 assert ref_ev.shape[0] == ref_pv.shape[0], ("reference data lengths " "inconsistent") ref = {} ref['ev'] = ref_ev ref['pv'] = ref_pv ref['v0'], ref['e0'], ref['p0'], ref['b0'] = ref_min # test new EosFit class, default func=Vinet() eos = EosFit(volume=volume, energy=energy) assert np.allclose(eos.params['v0'], eos.spl.get_min()) assert np.allclose(eos.params['v0'], eos.get_min()) assert np.allclose(eos.params['e0'], eos(eos.params['v0'])) assert np.allclose(eos.params['b0']*eV_by_Ang3_to_GPa, eos.bulkmod(eos.params['v0'])) now = {} now['v0'] = eos.params['v0'] now['e0'] = eos.params['e0'] now['b0'] = eos.params['b0'] * eV_by_Ang3_to_GPa now['p0'] = eos.pressure(eos.params['v0']) for key,val in now.items(): msg = "EosFit: key=%s, ref=%e, val=%e" %(key, ref[key], val) assert np.allclose(val, ref[key], atol=1e-7), msg # Test legacy ElkEOSFit / ExternEOS. # 'exe' must be on your $PATH. exe = 'eos.x' app = common.backtick("which %s" %exe).strip() if app == '': tools.skip("cannot find '%s' on PATH, skipping test" %exe) else: eos_store = {} type_arr = type(np.array([1.0,2.0])) for bv_method in ['ev', 'pv']: print("bv_method: %s" %bv_method) # natoms = 1, no normalization eos = ElkEOSFit(energy=energy, volume=volume, natoms=1, etype=1, npoints=300, dir=testdir, bv_method=bv_method) eos.fit() now = {} now['ev'] = eos.ev now['pv'] = eos.pv now.update(eos.get_min()) # compare to reference for key, val in ref.items(): print("ElkEOSFit: testing:", key) if type(val) == type_arr: np.testing.assert_array_almost_equal(now[key], ref[key]) else: np.testing.assert_almost_equal(now[key], ref[key], decimal=3) eos_store[bv_method] = eos # internal check: are the splines correct? for name in ['ev', 'pv', 'bv']: # API getter = getattr(eos, 'get_spl_' + name) assert getattr(eos, 'spl_' + name) == getter() # (N,2) arrays self.{ev,pv,bv} data = getattr(eos, name) vv = data[:,0] yy = data[:,1] # self.spl_{ev,pv,bv} spl = getattr(eos, 'spl_' + name) np.testing.assert_array_almost_equal(yy, spl(vv)) # Other attrs for which we do not have external ref data. Test only # among the two bv_methods 'ev' and 'pv'. print("bv") np.testing.assert_array_almost_equal(eos_store['ev'].bv, eos_store['pv'].bv, decimal=2)
def test_eos(): # load reference fitted with ElkEOSFit, data points [Bohr^3, Ha] -> [Ang^3, eV] # EV input data [Bohr^3, Ry] -> [Ang^3, eV] data = np.loadtxt("files/ev/evdata.txt") volume = data[:,0] * Bohr3_to_Ang3 energy = data[:,1] * (Ry / eV) ref_ev = np.loadtxt("files/ev/EVPAI.OUT.gz") ref_ev[:,0] *= Bohr3_to_Ang3 ref_ev[:,1] *= (Ha / eV) ref_pv = np.loadtxt("files/ev/PVPAI.OUT.gz") ref_pv[:,0] *= Bohr3_to_Ang3 ref_min = np.loadtxt("files/ev/min.txt") ref_min[0] *= Bohr3_to_Ang3 # v0 ref_min[1] *= (Ry / eV) # e0 assert ref_ev.shape[0] == ref_pv.shape[0], ("reference data lengths " "inconsistent") ref = {} ref['ev'] = ref_ev ref['pv'] = ref_pv ref['v0'], ref['e0'], ref['p0'], ref['b0'] = ref_min # test new EosFit class, default func=Vinet() eos = EosFit(volume=volume, energy=energy) assert np.allclose(eos.params['v0'], eos.spl.get_min()) assert np.allclose(eos.params['v0'], eos.get_min()) assert np.allclose(eos.params['e0'], eos(eos.params['v0'])) assert np.allclose(eos.params['b0']*eV_by_Ang3_to_GPa, eos.bulkmod(eos.params['v0'])) now = {} now['v0'] = eos.params['v0'] now['e0'] = eos.params['e0'] now['b0'] = eos.params['b0'] * eV_by_Ang3_to_GPa now['p0'] = eos.pressure(eos.params['v0']) for key,val in now.iteritems(): msg = "EosFit: key=%s, ref=%e, val=%e" %(key, ref[key], val) assert np.allclose(val, ref[key], atol=1e-7), msg # Test legacy ElkEOSFit / ExternEOS. # 'exe' must be on your $PATH. exe = 'eos.x' app = common.backtick("which %s" %exe).strip() if app == '': tools.skip("cannot find '%s' on PATH, skipping test" %exe) else: eos_store = {} type_arr = type(np.array([1.0,2.0])) for bv_method in ['ev', 'pv']: print "bv_method: %s" %bv_method # natoms = 1, no normalization eos = ElkEOSFit(energy=energy, volume=volume, natoms=1, etype=1, npoints=300, dir=testdir, bv_method=bv_method) eos.fit() now = {} now['ev'] = eos.ev now['pv'] = eos.pv now.update(eos.get_min()) # compare to reference for key, val in ref.iteritems(): print "ElkEOSFit: testing:", key if type(val) == type_arr: np.testing.assert_array_almost_equal(now[key], ref[key]) else: np.testing.assert_almost_equal(now[key], ref[key], decimal=3) eos_store[bv_method] = eos # internal check: are the splines correct? for name in ['ev', 'pv', 'bv']: # API getter = getattr(eos, 'get_spl_' + name) assert getattr(eos, 'spl_' + name) == getter() # (N,2) arrays self.{ev,pv,bv} data = getattr(eos, name) vv = data[:,0] yy = data[:,1] # self.spl_{ev,pv,bv} spl = getattr(eos, 'spl_' + name) np.testing.assert_array_almost_equal(yy, spl(vv)) # Other attrs for which we do not have external ref data. Test only # among the two bv_methods 'ev' and 'pv'. print "bv" np.testing.assert_array_almost_equal(eos_store['ev'].bv, eos_store['pv'].bv, decimal=2)