def __getitem__(self, i=-1): b = self.backend[i] atoms = Atoms(positions=b.positions, numbers=self.numbers, cell=b.cell, masses=self.masses, pbc=self.pbc, celldisp=self.celldisp, info=b.get('info'), constraint=[dict2constraint(d) for d in decode(self.constraints)], momenta=b.get('momenta'), magmoms=b.get('magmoms'), charges=b.get('charges'), tags=b.get('tags')) atoms._readTags(self.new_tags) if 'calculator' in b: results = {} c = b.calculator for prop in all_properties: if prop in c: results[prop] = c.get(prop) calc = SinglePointCalculator(atoms, **results) calc.name = b.calculator.name atoms.set_calculator(calc) return atoms
def encode_to_atoms(encode, out_file='input.traj'): """ Dump the encoding to a local traj file. """ # First, decode the trajectory data = json.loads(encode, encoding='utf-8') # Construct the initial atoms object atoms = Atoms( data['numbers'], data['trajectory']['0']['positions'], cell=data['trajectory']['0']['cell'], pbc=data['pbc']) atoms.info = data['calculator_parameters'] atoms.set_constraint([dict2constraint(_) for _ in data['constraints']]) # Attach the calculator calc = SPC( atoms=atoms, energy=data['trajectory']['0'].get('energy'), forces=data['trajectory']['0'].get('forces'), stress=data['trajectory']['0'].get('stress')) atoms.set_calculator(calc) # Collect the rest of the trajectory information images = [atoms] for i in range(len(data['trajectory']))[1:]: atoms = atoms.copy() if data['trajectory'][str(i)]['cell']: atoms.set_cell(data['trajectory'][str(i)]['cell']) if data['trajectory'][str(i)]['positions']: atoms.set_positions(data['trajectory'][str(i)]['positions']) calc = SPC( atoms=atoms, energy=data['trajectory'][str(i)].get('energy'), forces=data['trajectory'][str(i)].get('forces'), stress=data['trajectory'][str(i)].get('stress')) atoms.set_calculator(calc) images += [atoms] # Write the traj file if out_file: write(out_file, images) return images
def constraints(self): """List of constraints.""" if not isinstance(self._constraints, list): # Lazy decoding: cs = decode(self._constraints) self._constraints = [] for c in cs: # Convert to new format: name = c.pop('__name__', None) if name: c = {'name': name, 'kwargs': c} if c['name'].startswith('ase'): c['name'] = c['name'].rsplit('.', 1)[1] self._constraints.append(c) return [dict2constraint(d) for d in self._constraints]
def mongo_doc_atoms(doc): atoms = Atoms([Atom(atom['symbol'], atom['position'], tag=atom['tag'], momentum=atom['momentum'], magmom=atom['magmom'], charge=atom['charge']) for atom in doc['atoms']['atoms']], cell=doc['atoms']['cell'], pbc=doc['atoms']['pbc'], info=doc['atoms']['info'], constraint=[dict2constraint(c) for c in doc['atoms']['constraints']]) from ase.calculators.singlepoint import SinglePointCalculator results = doc['results'] calc = SinglePointCalculator(energy=results.get('energy', None), forces=results.get('forces', None), stress=results.get('stress', None), atoms=atoms) atoms.set_calculator(calc) return atoms
def read_atoms(backend, header=None): b = backend if header: pbc, numbers, masses, constraints = header else: pbc = b.pbc numbers = b.numbers masses = b.get('masses') constraints = b.get('constraints', '[]') atoms = Atoms(positions=b.positions, numbers=numbers, cell=b.cell, masses=masses, pbc=pbc, info=b.get('info'), constraint=[dict2constraint(d) for d in decode(constraints)], momenta=b.get('momenta'), magmoms=b.get('magmoms'), charges=b.get('charges'), tags=b.get('tags')) return atoms
def test_parameteric_constr(): import numpy as np from ase.build import bulk from ase.constraints import ( dict2constraint, FixScaledParametricRelations, FixCartesianParametricRelations, ) from ase.calculators.emt import EMT # Build the atoms object and attach a calculator a = bulk("Ni", cubic=True) a.set_calculator(EMT()) # Get adjusted cell cell = a.cell + 0.01 # Generate lattice constraint param_lat = ["a"] expr_lat = [ "a", "0", "0", "0", "a", "0", "0", "0", "a", ] constr_lat = FixCartesianParametricRelations.from_expressions( indices=[0, 1, 2], params=param_lat, expressions=expr_lat, use_cell=True, ) # Check expression generator for const_expr, passed_expr in zip(constr_lat.expressions.flatten(), expr_lat): assert const_expr == passed_expr # Check adjust_cell constr_lat.adjust_cell(a, cell) # Check serialization and construction from dict constr_lat_dict = constr_lat.todict() dict2constraint(constr_lat_dict) cell_diff = (cell - a.cell).flatten() expected_cell_diff = np.array( [0.01, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.01]) assert np.max(np.abs(cell_diff - expected_cell_diff)) < 1e-12 # Check adjust_stress a.cell += 0.01 stress = a.get_stress().copy() constr_lat.adjust_stress(a, stress) stress_rat = stress / a.get_stress() assert np.max( np.abs(stress_rat - np.array([1., 1., 1., 0., 0., 0.]))) < 1e-12 # Reset cell a.cell -= 0.01 # Get adjusted cell/positions for the system pos = a.get_positions().copy() + 0.01 # Generate proper atomic constraints constr_atom = FixScaledParametricRelations( [0, 1, 2, 3], np.ndarray((12, 0)), a.get_scaled_positions().flatten(), ) # Check serialization and construction from dict constr_atom_dict = constr_atom.todict() dict2constraint(constr_atom_dict) # Check adjust_positions constr_atom.adjust_positions(a, pos) assert np.max(np.abs(a.get_positions() - pos)) < 1e-12 # Check adjust_forces assert np.max(np.abs(a.get_forces())) < 1e-12 # Check non-empty constraint param_atom = ["dis"] expr_atom = [ "dis", "dis", "dis", "dis", "-0.5", "0.5", "0.5", "dis", "0.5", "0.5", "0.5", "dis", ] constr_atom = FixScaledParametricRelations.from_expressions( indices=[0, 1, 2, 3], params=param_atom, expressions=expr_atom, ) # Restart position adjustment pos += 0.01 * a.cell[0, 0] # Check adjust_positions constr_atom.adjust_positions(a, pos) scaled_pos = a.cell.scaled_positions(pos) pos_diff = (scaled_pos - a.get_scaled_positions()).flatten() expected_pos_diff = np.array( [0.01, 0.01, 0.01, 0.01, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.01]) assert np.max(np.abs(pos_diff - expected_pos_diff)) < 1e-12 # Check adjust_forces a.set_positions(pos + 0.3) forces = a.get_forces() constr_atom.adjust_forces(a, forces) forces_rat = forces / a.get_forces() assert np.max( np.abs(forces_rat.flatten() / 100.0 - expected_pos_diff)) < 1e-12 # Check auto-remapping/expression generation, the -0.5 should now be 0.5 expr_atom[4] = "0.5" current_expression = constr_atom.expressions.flatten() for const_expr, passed_expr in zip(current_expression, expr_atom): assert const_expr == passed_expr # Check with Cartesian parametric constraints now expr_atom = [ "dis", "dis", "dis", "dis", "1.76", "1.76", "1.76", "dis", "1.76", "1.76", "1.76", "dis", ] constr_atom = FixCartesianParametricRelations.from_expressions( indices=[0, 1, 2, 3], params=param_atom, expressions=expr_atom, ) # Restart position adjustment a.set_positions(pos) pos += 0.01 # Check adjust_positions constr_atom.adjust_positions(a, pos) pos_diff = (pos - a.get_positions()).flatten() expected_pos_diff = np.array( [0.01, 0.01, 0.01, 0.01, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.01]) assert np.max(np.abs(pos_diff - expected_pos_diff)) < 1e-12 # Check adjust_forces a.set_positions(pos + 0.3) forces = a.get_forces() constr_atom.adjust_forces(a, forces) forces_rat = forces / a.get_forces() assert np.max( np.abs(forces_rat.flatten() / 100.0 - expected_pos_diff)) < 1e-12