def check_state(self, atoms, tol=1e-4): """Check for any system changes since last calculation.""" if not os.path.exists(self.asei): return True if isinstance(self.restart_atoms, list): if len(self.restart_atoms) != len(atoms): return True for i in range(len(atoms)): if compare_atoms(self.restart_atoms[i], atoms[i], tol=tol, excluded_properties=set( self.ignored_changes)): self.logger.debug('Atoms changed, run a new calculation') return True else: if compare_atoms(self.restart_atoms, atoms, tol=tol, excluded_properties=set(self.ignored_changes)): self.logger.debug('Atoms changed, run a new calculation') return True # if self.igonre_parameters: # self.logger.debug('Parameter: %s are ignored, results are not affected.'%self.igonre_parameters) if self.changed_parameters: self.logger.debug('Parameter: %s changed, results are affected' % self.changed_parameters) return True self.logger.debug( 'Same geometry and parameters, use previous results.') converged, meg = self.read_convergence() if converged > 0: self.logger.debug('Not converged: %s' % meg) return True return False
def test_write_to_obj_name(at): # compare writing to a file with a particular extension and writing to # a file object that has same extension ase.io.write('direct_to_file.xyz', at) with open('to_file_obj.xyz', 'w') as fout: ase.io.write(fout, at) with open('direct_to_file.xyz') as f1, open('to_file_obj.xyz') as f2: for l1, l2 in zip(f1, f2): assert l1 == l2 # compare reading from a file with a particular extension and reading from # a file object that has same extension at1 = ase.io.read('direct_to_file.xyz') with open('to_file_obj.xyz') as fin: at2 = ase.io.read(fin) print('compare', compare_atoms(at1, at2, 1.0e-10)) assert len(compare_atoms(at1, at2)) == 0 # compare reading from a file with a particular extension and reading from # a file object that has same extension at1 = ase.io.iread('direct_to_file.xyz') with open('to_file_obj.xyz') as fin: at2 = ase.io.iread(fin) for a1, a2 in zip(at1, at2): assert len(compare_atoms(a1, a2)) == 0
def test_format(fmt): buf = to_bytes(atoms, format=fmt) atoms1 = parse_atoms(buf) err = compare_atoms(atoms, atoms1) assert not err, err # Should be empty list buf = to_bytes(images, format=fmt) images1 = parse_images(buf) assert len(images) == len(images1) for img, img1 in zip(images, images1): err = compare_atoms(img, img1) assert not err, err
def main(): if not shutil.which("cp2k"): raise unittest.SkipTest('cp2k command not available') inp = """&MOTION &PRINT &TRAJECTORY SILENT FORMAT DCD_ALIGNED_CELL &END TRAJECTORY &END PRINT &MD STEPS 5 &END MD &END MOTION &GLOBAL RUN_TYPE MD &END GLOBAL""" calc = CP2K(label='test_dcd', max_scf=1, inp=inp) h2 = molecule('H2', calculator=calc) h2.center(vacuum=2.0) h2.set_cell([10.0, 10.0, 10.0, 90.0, 90.0, 90.0]) h2.set_pbc(True) energy = h2.get_potential_energy() assert not energy == None subprocess.call(['cp2k', '-i', 'test_dcd.inp', '-o', 'test_dcd.out']) h2_end = io.read('test_dcd-pos-1.dcd') assert (h2_end.symbols == 'X').all() traj = io.read('test_dcd-pos-1.dcd', ref_atoms=h2, index=slice(0, None), aligned=True) ioITraj = io.iread('test_dcd-pos-1.dcd', ref_atoms=h2, index=slice(0, None), aligned=True) with open('test_dcd-pos-1.dcd', 'rb') as f: itraj = iread_cp2k_dcd(f, indices=slice(0, None), ref_atoms=h2, aligned=True) for i, iMol in enumerate(itraj): ioIMol = next(ioITraj) assert compare_atoms(iMol, traj[i]) == [] assert compare_atoms(iMol, ioIMol) == [] assert iMol.get_pbc().all() traj = io.read('test_dcd-pos-1.dcd', ref_atoms=h2, index=slice(0, None)) pbc = [mol.get_pbc() for mol in traj] assert not np.any(pbc) print('passed test "CP2K_DCD"')
def test_constraints(constraint): atoms = molecule('H2O') atoms.set_constraint(constraint) columns = ['symbols', 'positions', 'move_mask'] ase.io.write('tmp.xyz', atoms, columns=columns) atoms2 = ase.io.read('tmp.xyz') assert not compare_atoms(atoms, atoms2) constraint2 = atoms2.constraints cls = type(constraint) if cls == FixAtoms: assert len(constraint2) == 1 assert isinstance(constraint2[0], cls) assert np.all(constraint2[0].index == constraint.index) elif cls == FixCartesian: assert len(constraint2) == len(atoms) assert isinstance(constraint2[0], cls) assert np.all(constraint2[0].mask) assert np.all(constraint2[1].mask == constraint.mask) assert np.all(constraint2[2].mask) elif cls == list: assert len(constraint2) == len(atoms) assert np.all(constraint2[0].mask == constraint[0].mask) assert np.all(constraint2[1].mask) assert np.all(constraint2[2].mask == constraint[1].mask)
def test_surface_stack(): from ase.build.surface import _all_surface_functions from ase.build import stack from ase.calculators.calculator import compare_atoms # The purpose of this test is to test the stack() function and verify # that the various surface builder functions produce configurations # consistent with stacking. d = _all_surface_functions() exclude = {'mx2', 'graphene'} # mx2 and graphene are not like the others for name in sorted(d): if name in exclude: continue func = d[name] def has(var): c = func.__code__ return var in c.co_varnames[:c.co_argcount] for nlayers in range(1, 7): atoms = func('Au', size=(2, 2, nlayers), periodic=True, a=4.0) big_atoms = func('Au', size=(2, 2, 2 * nlayers), periodic=True, a=4.0) stacked_atoms = stack(atoms, atoms) changes = compare_atoms(stacked_atoms, big_atoms, tol=1e-11) if not changes: print('OK', name, nlayers) break else: assert 0, 'Unstackable surface {}'.format(name)
def assert_atoms_almost_equal(self, atoms, other, tol=1e-15): """Compare two Atoms objects, raising AssertionError if different""" system_changes = compare_atoms(atoms, other, tol=tol) if len(system_changes) > 0: raise AssertionError( "Atoms objects differ by {}".format(', '.join(system_changes)))
def test_read_vasp_multiple_times(outcar): result1 = read(outcar) result2 = read(outcar) assert isinstance(result1, Atoms) assert isinstance(result2, Atoms) print(result1) print(result2) assert len(compare_atoms(result1, result2)) == 0
def test_abinit_inputfile_roundtrip(): m1 = bulk('Ti') m1.set_initial_magnetic_moments(range(len(m1))) write('abinit_save.in', images=m1, format='abinit-in') m2 = read('abinit_save.in', format='abinit-in') # (How many decimals?) assert not compare_atoms(m1, m2, tol=1e-7)
def test_cif_roundtrip_mixed(): atoms = Atoms('Au', cell=[1., 2., 3.], pbc=[1, 1, 0]) atoms1 = roundtrip(atoms) # We cannot preserve PBC info for this case: assert all(atoms1.pbc) assert compare_atoms(atoms, atoms1, tol=1e-5) == ['pbc'] assert atoms.get_scaled_positions() == pytest.approx( atoms1.get_scaled_positions(), abs=1e-5)
def test_compare_atoms(): """ Check that Atoms.compare_atoms correctly accounts for the different types of system changes """ import numpy as np from ase import Atoms from ase.calculators.calculator import compare_atoms # A system property that's an attribute of Atoms, but isn't in # Atoms.arrays (currently this is just 'cell' and 'pbc') cell1 = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) cell2 = cell1 * 2 atoms1 = Atoms(cell=cell1) atoms2 = Atoms(cell=cell2) assert set(compare_atoms(atoms1, atoms2)) == {"cell"} # A system property other than 'initial_charges' or 'initial_magmoms' # that exists in the `arrays` attribute of one Atoms object but not the # other atoms1 = Atoms() atoms2 = Atoms(numbers=[0], positions=[[0, 0, 0]]) assert set(compare_atoms(atoms1, atoms2)) == {"positions", "numbers"} # A change in a system property that exists in the `arrays` attribute # of both Atoms objects passed into this function atoms1 = Atoms(numbers=[0], positions=[[0, 0, 0]]) atoms2 = Atoms(numbers=[0], positions=[[1, 0, 0]]) assert set(compare_atoms(atoms1, atoms2)) == {"positions"} # An excluded property (re-use atoms1 and atoms2 from previous check) assert set(compare_atoms(atoms1, atoms2, excluded_properties={"positions"})) == set() # Optional array (currently 'initial_charges' or 'initial_magmoms') # NOTE: Suppose you initialize an array of *zero charges* for atoms2 # but not atoms1. The current compare_atoms function will still # indicate that 'initial_charges' is in system_changes simply # because it isn't in both of them. This is despite the fact that # if one were to call atoms1.get_initial_charges, you would get # back an array of zeros. However, this scenario should only ever # occur rarely. atoms1 = Atoms(numbers=[0], positions=[[0, 0, 0]]) atoms2 = Atoms(numbers=[0], positions=[[0, 0, 0]], charges=[1.13]) assert set(compare_atoms(atoms1, atoms2)) == {"initial_charges"}
def set(self, atoms=None, **kwargs): if self.outputs: pass self.atoms = atoms self.kwargs = kwargs if atoms is not None: changes = compare_atoms(self.atoms, atoms1) self.atoms = atoms.copy() self._changes = changes
def test_dcd(factory, factories): # (Should the cp2k_main executable live on the cp2k factory?) exes = factories.executables cp2k_main = exes.get('cp2k_main') if cp2k_main is None: pytest.skip('Please define "cp2k_main" in testing executables. ' 'It should point to the main cp2k executable ' '(not the shell)') calc = factory.calc(label='test_dcd', max_scf=1, inp=inp) h2 = molecule('H2', calculator=calc) h2.center(vacuum=2.0) h2.set_pbc(True) energy = h2.get_potential_energy() assert energy is not None subprocess.check_call( [cp2k_main, '-i', 'test_dcd.inp', '-o', 'test_dcd.out']) h2_end = io.read('test_dcd-pos-1.dcd') assert (h2_end.symbols == 'X').all() traj = io.read('test_dcd-pos-1.dcd', ref_atoms=h2, index=slice(0, None), aligned=True) ioITraj = io.iread('test_dcd-pos-1.dcd', ref_atoms=h2, index=slice(0, None), aligned=True) with open('test_dcd-pos-1.dcd', 'rb') as fd: itraj = iread_cp2k_dcd(fd, indices=slice(0, None), ref_atoms=h2, aligned=True) for i, iMol in enumerate(itraj): ioIMol = next(ioITraj) assert compare_atoms(iMol, traj[i]) == [] assert compare_atoms(iMol, ioIMol) == [] assert iMol.get_pbc().all() traj = io.read('test_dcd-pos-1.dcd', ref_atoms=h2, index=slice(0, None)) pbc = [mol.get_pbc() for mol in traj] assert not np.any(pbc)
def test_convert(tmp_path, cli): infile = tmp_path / 'images.json' images = [bulk('Si'), bulk('Au')] write(infile, images, format='json') outfile = tmp_path / 'images.traj' cli.ase('convert', str(infile), str(outfile)) images2 = read(outfile, ':') assert len(images2) == 2 for a1, a2 in zip(images, images2): assert not compare_atoms(a1, a2)
def update(self, atoms: Atoms): if atoms is None and self.atoms is None: raise RuntimeError("Need an Atoms object to do anything!") changes = compare_atoms(self.atoms, atoms) if changes: self.results = {} self.atoms = atoms.copy() if self.need_setup(changes): self.setup()
def test_get_jmol_images(self, kwargs, expected): # Test the private staticmethod _get_jmol_images # used by the public write_jmol_images() method from ase.calculators.calculator import compare_atoms jmol_images = list(VibrationsData._get_jmol_images(**kwargs)) assert len(jmol_images) == len(expected) for image, reference in zip(jmol_images, expected): assert compare_atoms(image, reference) == [] for key, value in reference.info.items(): if key == 'frequency_cm-1': assert float(image.info[key]) == pytest.approx(value, abs=0.1) else: assert image.info[key] == value
def test_read_write_roundtrip(atoms, vasp5, filename): write(filename, atoms, vasp5=vasp5) atoms_loaded = read(filename) assert len(compare_atoms(atoms, atoms_loaded)) == 0
h=0.1, label='in1', xc='GGA', spin_typ=1, pseudo_dir='.') l.write_input(atoms=atoms, h=0.1, spin_typ=1, pseudo_dir='.', SPIN_TYP=1) print('input writing functional') # check reading and writing .ion files atoms.set_constraint( [FixAtoms([0]), FixedLine(1, [0, 1, 0]), FixedPlane(2, [1, 0, 0])]) write_ion(open('in1.ion', 'w'), atoms, pseudo_dir='.') recovered_atoms = read_ion(open('in1.ion', 'r')) assert compare_atoms(atoms, recovered_atoms) == [] calc = SPARC(atoms=atoms, pseudo_dir='.', SPIN_TYP=1) try: # check that `h` is required calc.write_input() raise Exception('test failed') except CalculatorSetupError: pass print('.ion reading test passed') calc = SPARC.read('read_input') print('reading test passed') d = calc.todict()
def check_state(self, atoms, tol=1e-15): return compare_atoms(self.atoms, atoms, excluded_properties={'initial_charges', 'initial_magmoms'})
from ase.calculators.calculator import compare_atoms # The purpose of this test is to test the stack() function and verify # that the various surface builder functions produce configurations # consistent with stacking. d = _all_surface_functions() exclude = {'mx2'} # mx2 is not like the others for name in sorted(d): if name in exclude: continue func = d[name] def has(var): c = func.__code__ return var in c.co_varnames[:c.co_argcount] for nlayers in range(1, 7): atoms = func('Au', size=(2, 2, nlayers), periodic=True, a=4.0) big_atoms = func('Au', size=(2, 2, 2 * nlayers), periodic=True, a=4.0) stacked_atoms = stack(atoms, atoms) changes = compare_atoms(stacked_atoms, big_atoms, tol=1e-11) if not changes: print('OK', name, nlayers) break else: assert 0, 'Unstackable surface {}'.format(name)
def test_cif_roundtrip_nonperiodic(): atoms = molecule('H2O') atoms1 = roundtrip(atoms) assert not compare_atoms(atoms, atoms1, tol=1e-5)
def assert_images_equal(images1, images2): assert len(images1) == len(images2), 'length mismatch' for atoms1, atoms2 in zip(images1, images2): differences = compare_atoms(atoms1, atoms2) assert not differences
""" Check that Atoms.compare_atoms correctly accounts for the different types of system changes """ import numpy as np from ase import Atoms from ase.calculators.calculator import compare_atoms # A system property that's an attribute of Atoms, but isn't in # Atoms.arrays (currently this is just 'cell' and 'pbc') cell1 = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) cell2 = cell1 * 2 atoms1 = Atoms(cell=cell1) atoms2 = Atoms(cell=cell2) assert set(compare_atoms(atoms1, atoms2)) == {"cell"} # A system property other than 'initial_charges' or 'initial_magmoms' # that exists in the `arrays` attribute of one Atoms object but not the # other atoms1 = Atoms() atoms2 = Atoms(numbers=[0], positions=[[0, 0, 0]]) assert set(compare_atoms(atoms1, atoms2)) == {"positions", "numbers"} # A change in a system property that exists in the `arrays` attribute # of both Atoms objects passed into this function atoms1 = Atoms(numbers=[0], positions=[[0, 0, 0]]) atoms2 = Atoms(numbers=[0], positions=[[1, 0, 0]]) assert set(compare_atoms(atoms1, atoms2)) == {"positions"} # An excluded property (re-use atoms1 and atoms2 from previous check) assert set(compare_atoms(atoms1, atoms2,
def atoms_equal(atoms1, atoms2): # Check that the tolerance is compatible with the writer's precision return compare_atoms(atoms1, atoms2, tol=1e-8) == []