Пример #1
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)
        if system_changes: # if anything at all changed (could be made more fine-grained)
            self.logger.pr('calculation triggered with properties={0}, system_changes={1}'.format(properties,
                                                                                                  system_changes))
            self.server.put(atoms, 0, self.label)
            if self.label != 1:
                # send atoms over socket, unless first time
                self.logger.pr('socket calculator sending Atoms label={0}'.format(self.label))
                self.server.handle_request()
            # wait for results to be ready
            self.logger.pr('socket calculator waiting for results label={0}'.format(self.label))
            self.server.handle_request()

            self.label += 1
            [results] = self.server.get_results()

            # we always compute energy, forces and stresses, regardless of what was requested
            stress = -(results.info['virial']/results.get_volume())
            self.results = {'energy': results.info['energy'],
                            'forces': results.arrays['force'],
                            'stress': full_3x3_to_Voigt_6_stress(stress)}
        else:
            self.logger.pr('calculation avoided with properties={0}, system_changes={1}'.format(properties,
                                                                                                system_changes))
Пример #2
0
    def calculate(self, atoms=None, properties=['energy'],
                  system_changes=all_changes):
        """EAM Calculator

        atoms: Atoms object
            Contains positions, unit-cell, ...
        properties: list of str
            List of what needs to be calculated.  Can be any combination
            of 'energy', 'forces'
        system_changes: list of str
            List of what has changed since last calculation.  Can be
            any combination of these five: 'positions', 'numbers', 'cell',
            'pbc', 'initial_charges' and 'initial_magmoms'.
            """

        Calculator.calculate(self, atoms, properties, system_changes)

        # we shouldn't really recalc if charges or magmos change
        if len(system_changes) > 0:  # something wrong with this way
            self.update(self.atoms)
            self.calculate_energy(self.atoms)

            if 'forces' in properties:
                self.calculate_forces(self.atoms)

        # check we have all the properties requested
        for property in properties:
            if property not in self.results:
                if property is 'energy':
                    self.calculate_energy(self.atoms)

                if property is 'forces':
                    self.calculate_forces(self.atoms)
Пример #3
0
    def relax(self, atoms=None, properties=['energy'],
              system_changes=some_changes,
              flag_damping=2,
              converge_eps=1.0e-3,nsteps=100,min_iteration=5,
              converge_num=3,time_interval=2.0,
              initial_temperature=10.0):
        """
        Relax atom positions by running damped MD in pmd instead of using
        optimize module in ASE.
        """
        self.set(flag_damping=flag_damping,
                 converge_eps=converge_eps,
                 num_iteration=nsteps,
                 min_iteration=min_iteration,
                 num_out_energy=nsteps,
                 converge_num=converge_num,
                 time_interval=time_interval,
                 initial_temperature=initial_temperature,
                 flag_sort=1)
        Calculator.calculate(self, atoms, properties, system_changes)
        # print 'type(atoms),type(self.atoms)= ',type(atoms),type(self.atoms)
        # print 'self.atoms = ',self.atoms
        self.write_input(self.atoms, properties, system_changes)

        olddir = os.getcwd()
        try:
            os.chdir(self.directory)
            errorcode = subprocess.call(self.command, shell=True)
        finally:
            os.chdir(olddir)

        if errorcode:
            raise RuntimeError('%s returned an error: %d' %
                               (self.name, errorcode))
        self.read_results(relax=True)
Пример #4
0
    def calculate(self, atoms=None, properties=['energy'],
                  system_changes=all_changes):
        """GEBF Calculator
        """

        Calculator.calculate(self, atoms, properties, system_changes)

        if len(system_changes) > 0:  # something wrong with this way
            self.update(self.atoms)
            if 'energy' in properties:
                self.calculate_energy(self.atoms)

            if 'forces' in properties:
                self.calculate_forces(self.atoms)

            if 'charges' in properties:
                self.calculate_charges(self.atoms)

        # check we have all the properties requested
        for property in properties:
            if property not in self.results:
                if property is 'energy':
                    self.calculate_energy(self.atoms)

                if property is 'forces':
                    self.calculate_forces(self.atoms)

                if property is 'charges':
                    self.calculate_charges(self.atoms)

#FUMPORTANT|
        atoms.set_initial_charges(self.results['charges'])
Пример #5
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)
        
        if self.qmatoms is None:
            self.initialize_qm(atoms)
            
        self.qmatoms.positions = atoms.positions[self.selection]
        if self.vacuum:
            self.qmatoms.positions += (self.center -
                                       self.qmatoms.positions.mean(axis=0))
            
        energy = self.mmcalc2.get_potential_energy(atoms)
        forces = self.mmcalc2.get_forces(atoms)
        
        energy += self.qmcalc.get_potential_energy(self.qmatoms)
        qmforces = self.qmcalc.get_forces(self.qmatoms)
        if self.vacuum:
            qmforces -= qmforces.mean(axis=0)
        forces[self.selection] += qmforces
        
        energy -= self.mmcalc1.get_potential_energy(self.qmatoms)
        forces[self.selection] -= self.mmcalc1.get_forces(self.qmatoms)

        self.results['energy'] = energy
        self.results['forces'] = forces
Пример #6
0
    def calculate(self, atoms=None, properties=['energy'],
                  system_changes=None):
        """Runs a calculation, only if necessary."""
        if self.calculation_required(atoms, properties):

            # The subclass implementation should first call this
            # implementation to set the atoms attribute.
            Calculator.calculate(self, atoms, properties, system_changes)

            self.write_input(atoms, properties, system_changes)

            if self.command is None:
                raise RuntimeError('Please set $%s environment variable ' %
                                   ('ASE_' + self.name.upper() + '_COMMAND') +
                                   'or supply the command keyword')

            olddir = os.getcwd()
            try:
                os.chdir(self.directory)
                errorcode = subprocess.call(self.command,
                                            stdout=subprocess.PIPE,
                                            shell=True)

            finally:
                os.chdir(olddir)

            if errorcode:
                s = '{} returned an error: {}'
                raise RuntimeError(s.format(self.name, errorcode))

        # This sets self.results, and updates the atoms
        self.read_results()
Пример #7
0
    def calculate(self, atoms=None, properties=['energy'],
                  system_changes=all_changes):
        # We don't call FileIOCalculator.calculate here, because that method
        # calls subprocess.call(..., shell=True), which we don't want to do.
        # So, we reproduce some content from that method here.
        Calculator.calculate(self, atoms, properties, system_changes)

        # If a parameter file exists in the working directory, delete it
        # first. If we need that file, we'll recreate it later.
        localparfile = os.path.join(self.directory, '.dftd3par.local')
        if os.path.isfile(localparfile):
            os.remove(localparfile)

        # Write XYZ or POSCAR file and .dftd3par.local file if we are using
        # custom damping parameters.
        self.write_input(self.atoms, properties, system_changes)
        command = self._generate_command()

        # Finally, call dftd3 and parse results.
        with open(self.label + '.out', 'w') as f:
            errorcode = subprocess.call(command, cwd=self.directory, stdout=f)

        if errorcode:
            raise RuntimeError('%s returned an error: %d' %
                               (self.name, errorcode))
        self.read_results()
    def calculate(self, atoms, properties, system_changes):
        """
        Calculation of the energy of system and forces of all atoms.
        """
        # The inherited method below just sets the atoms object,
        # if specified, to self.atoms.
        Calculator.calculate(self, atoms, properties, system_changes)

        log = self.log
        log('Calculation requested.')

        images = hash_images([self.atoms])
        key = images.keys()[0]

        if properties == ['energy']:
            log('Calculating potential energy...', tic='pot-energy')
            self.descriptor.calculate_fingerprints(images=images,
                                                   log=log,
                                                   calculate_derivatives=False)
            energy = self.model.get_energy(self.descriptor.fingerprints[key])
            self.results['energy'] = energy
            log('...potential energy calculated.', toc='pot-energy')

        if properties == ['forces']:
            log('Calculating forces...', tic='forces')
            self.descriptor.calculate_fingerprints(images=images,
                                                   log=log,
                                                   calculate_derivatives=True)
            forces = \
                self.model.get_forces(self.descriptor.fingerprints[key],
                                      self.descriptor.fingerprintprimes[key])
            self.results['forces'] = forces
            log('...forces calculated.', toc='forces')
Пример #9
0
    def calculate(self, atoms, properties, system_changes):
        # call parent method:
        Calculator.calculate(self, atoms, properties, system_changes)

        if not(system_changes is None):
            self.update_atoms()

        if 'energy' in properties:
            energy = self.ff.Energy()
            # energy units are kcal/mole according to http://forums.openbabel.org/Energy-units-td1574278.html
            # and in Avogadro they are reported as kJ/mole ...
            self.results['energy'] = energy * units.kJ / units.mol

        if 'forces' in properties:
            d = 0.001
            F_ai = np.zeros( (self.natoms, 3) )
            for iatom in xrange( self.natoms ):
                for iaxis in xrange( 3 ):
                    obatom = self.mol.GetAtom( 1 + iatom )
                    vec = obatom.GetVector()

                    obatom.SetVector( self._shift_OBvec(vec, iaxis, d) )
                    self.ff.Setup( self.mol )
                    eplus = self.ff.Energy() * units.kJ/units.mol

                    obatom.SetVector( self._shift_OBvec(vec, iaxis, -2*d) )
                    self.ff.Setup( self.mol )
                    eminus = self.ff.Energy() * units.kJ/units.mol

                    obatom.SetVector( self._shift_OBvec(vec, iaxis, d) ) # put it back
                    F_ai[iatom, iaxis] = (eminus - eplus) / (2 * d)
            self.results['forces'] = F_ai
Пример #10
0
    def calculate(self, atoms=None, properties=['energy'],
                  system_changes=['positions', 'numbers', 'cell',
                                  'pbc', 'charges', 'magmoms']):

        Calculator.calculate(self, atoms, properties, system_changes)
        epsilon = self.parameters.epsilon
        rho0 = self.parameters.rho0
        r0 = self.parameters.r0

        positions = self.atoms.get_positions()
        energy = 0.0
        energies = np.zeros(len(self.atoms))
        forces = np.zeros((len(self.atoms), 3))

        preF = 2 * epsilon * rho0 / r0
        for i1, p1 in enumerate(positions):
            for i2, p2 in enumerate(positions[:i1]):
                diff = p2 - p1
                r = sqrt(np.dot(diff, diff))
                expf = exp(rho0 * (1.0 - r / r0))
                energy += epsilon * expf * (expf - 2)
                energies[i1] += epsilon * expf * (expf - 2)
                energies[i2] += epsilon * expf * (expf - 2)
                F = preF * expf * (expf - 1) * diff / r
                forces[i1] -= F
                forces[i2] += F
        self.results['energy'] = energy
        self.results['forces'] = forces
        self.results['potential_energies'] = energies
Пример #11
0
 def calculate(self, atoms, properties, system_changes):
     Calculator.calculate(self, atoms, properties, system_changes)
     try:
         results = self.checkpoint.load(atoms)
         prev_atoms, results = results[0], results[1:]
         try:
             assert atoms_almost_equal(atoms, prev_atoms)
         except AssertionError:
             raise AssertionError('mismatch between current atoms and those read from checkpoint file')
         self.logger.pr('retrieved results for {0} from checkpoint'.format(properties))
         # save results in calculator for next time
         if isinstance(self.calculator, Calculator):
             if not hasattr(self.calculator, 'results'):
                 self.calculator.results = {}
             self.calculator.results.update(dict(zip(properties, results)))
     except NoCheckpoint:
         if isinstance(self.calculator, Calculator):
             self.logger.pr('doing calculation of {0} with new-style calculator interface'.format(properties))
             self.calculator.calculate(atoms, properties, system_changes)
             results = [self.calculator.results[prop] for prop in properties]
         else:
             self.logger.pr('doing calculation of {0} with old-style calculator interface'.format(properties))
             results = []
             for prop in properties:
                 method_name = CheckpointCalculator.property_to_method_name[prop]
                 method = getattr(self.calculator, method_name)
                 results.append(method(atoms))
         _calculator = atoms.get_calculator
         try:
             atoms.set_calculator(self.calculator)
             self.checkpoint.save(atoms, *results)
         finally:
             atoms.set_calculator(_calculator)
         
     self.results = dict(zip(properties, results))
Пример #12
0
 def run_calculation(self, atoms=None, properties=None,
                         system_changes=all_changes):
     '''
     Internal calculation executor. We cannot use FileIOCalculator
     directly since we need to support remote execution.
     
     This calculator is different from others. 
     It prepares the directory, launches the remote process and
     raises the exception to signal that we need to come back for results
     when the job is finished.
     '''
     if properties is None:
         properties = ['energy']
     Calculator.calculate(self, atoms, properties, system_changes)
     self.write_input(self.atoms, properties, system_changes)
     if self.command is None:
         raise RuntimeError('Please configure RemoteQE calculator!')
     olddir = os.getcwd()
     errorcode=0
     try:
         os.chdir(self.directory)
         output = subprocess.check_output(self.command, shell=True)
         self.jobid=output.split()[0]
         self.submited=True
         #print "Job %s submitted. Waiting for it." % (self.jobid)
         # Waiting loop. To be removed.
     except subprocess.CalledProcessError as e:
         errorcode=e.returncode
     finally:
         os.chdir(olddir)
     
     if errorcode:
         raise RuntimeError('%s returned an error: %d' %
                            (self.name, errorcode))
     self.read_results()
Пример #13
0
    def calculate(self, atoms=None, properties=None,
                  system_changes=all_changes):
        '''Do the calculation.'''

        if(not properties):
            properties = ['energy']
        Calculator.calculate(self, atoms, properties, system_changes)

        if('numbers' in system_changes or
           'initial_magmoms' in system_changes):
            self._release_force_env()

        if(self._force_env_id is None):
            self._create_force_env()

        n_atoms = len(self.atoms)
        if('cell' in system_changes):
            cell = self.atoms.get_cell()
            self._send('SET_CELL %d' % self._force_env_id)
            self._send(' '.join(['%.10f' % x for x in cell.flat]))
            assert(self._recv() == '* READY')

        if('positions' in system_changes):
            self._send('SET_POS %d' % self._force_env_id)
            self._send('%d' % (3 * n_atoms))
            for pos in self.atoms.get_positions():
                self._send('%.10f   %.10f   %.10f' % (pos[0], pos[1], pos[2]))
            self._send('*END')
            assert(float(self._recv()) >= 0)  # max change -> ignore
            assert(self._recv() == '* READY')

        self._send('EVAL_EF %d' % self._force_env_id)
        assert(self._recv() == '* READY')

        self._send('GET_E %d' % self._force_env_id)
        self.results['energy'] = float(self._recv()) * Hartree
        assert(self._recv() == '* READY')

        forces = np.zeros(shape=(n_atoms, 3))
        self._send('GET_F %d' % self._force_env_id)
        assert(int(self._recv()) == 3 * n_atoms)
        for i in range(n_atoms):
            line = self._recv()
            forces[i, :] = [float(x) for x in line.split()]
        assert(self._recv() == '* END')
        assert(self._recv() == '* READY')
        self.results['forces'] = forces * Hartree / Bohr

        self._send('GET_STRESS %d' % self._force_env_id)
        line = self._recv()
        assert(self._recv() == '* READY')

        stress = np.array([float(x) for x in line.split()]).reshape(3, 3)
        assert(np.all(stress == np.transpose(stress)))   # should be symmetric
        # Convert 3x3 stress tensor to Voigt form as required by ASE
        stress = np.array([stress[0, 0], stress[1, 1], stress[2, 2],
                           stress[1, 2], stress[0, 2], stress[0, 1]])
        self.results['stress'] = stress * Hartree / Bohr**3
Пример #14
0
 def calculate(self, atoms, properties, system_changes):
     Calculator.calculate(self, atoms, properties, system_changes)
     energy, forces = 0, np.zeros((self.N, 3))
     e, f = self._calculate_harm(atoms)
     energy += e
     forces += f
     e, f = self._calculate_soft(atoms)
     energy += e
     forces += f
     self.results = {'energy': energy, 'forces': forces}
Пример #15
0
    def calculate(self, atoms=None, properties=['energy', 'forces'], system_changes=['positions']):
        Calculator.calculate(self, atoms, properties, system_changes)

        if 'energy' in properties:
            self.results['energy'] = self.energy(atoms)
        if 'forces' in properties:
            F = self.forces(atoms)
            if self.noZ:
                F[:,-1] = 0
            self.results['forces'] = F
Пример #16
0
 def calculate(self, atoms, properties, system_changes):
     Calculator.calculate(self, atoms)
     self.kpts = kpts2ndarray(self.parameters.kpts, atoms)
     icell = atoms.get_reciprocal_cell() * 2 * np.pi * Bohr
     n = 7
     offsets = np.indices((n, n, n)).T.reshape((n**3, 1, 3)) - n // 2
     eps = 0.5 * (np.dot(self.kpts + offsets, icell)**2).sum(2).T
     eps.sort()
     self.eigenvalues = eps[:, :20] * Ha
     self.results = {'energy': 0.0}
Пример #17
0
 def calculate(self, atoms, properties, system_changes):
     Calculator.calculate(self, atoms)
     self.kpts = kpts2ndarray(self.parameters.kpts, atoms)
     icell = atoms.get_reciprocal_cell() * 2 * np.pi * Bohr
     n = 7
     offsets = np.indices((n, n, n)).T.reshape((n**3, 1, 3)) - n // 2
     eps = 0.5 * (np.dot(self.kpts + offsets, icell)**2).sum(2).T
     eps.sort()
     self.eigenvalues = eps[:, :20] * Ha
     self.results = {'energy': 0.0}
Пример #18
0
 def calculate(self, atoms, properties, system_changes):
     Calculator.calculate(self, atoms, properties, system_changes)
     julia_atoms = ASEAtoms(atoms)
     self.results = {}
     if 'energy' in properties:
         self.results['energy'] = julia.energy(self.julip_calculator, julia_atoms)
     if 'forces' in properties:
         self.results['forces'] = np.array(julia.forces(self.julip_calculator, julia_atoms))
     if 'stress' in properties:
         self.results['stress'] = np.array(julia.stress(self.julip_calculator, julia_atoms))
Пример #19
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms)

        cf_by_name = self.corrFunc.get_cf_by_cluster_names(
            atoms, self.eci.keys())
        energy = 0.0
        for key, value in self.eci.items():
            energy += value * cf_by_name[key]
        self.results["energy"] = energy * len(
            atoms)  # Should not return energy per atom!
Пример #20
0
    def calculate(self,
                  atoms=None,
                  properties=['energy'],
                  system_changes=all_changes):

        Calculator.calculate(self, atoms, properties, system_changes)

        #chem_symbols = list(set(atoms.get_chemical_symbols()))
        #self.ff = PyXtal_FF(model={'system': chem_symbols}, logo=self.parameters.logo)
        #self.ff.run(mode='predict', mliap=self.parameters.mliap)

        # base potential
        if self.parameters.ff._descriptors['base_potential']:
            self.base_potential = ZBL(
                self.parameters.ff._descriptors['base_potential']['inner'],
                self.parameters.ff._descriptors['base_potential']['outer'],
                atomic_energy=True)
            base_results = self.base_potential.calculate(atoms)
            base_energy = base_results['energy']
            base_forces = base_results['force']
            base_stress = base_results['stress']  # eV/A^3
            base_energies = base_results['energies']
        else:
            base_energy = 0
            base_forces = np.zeros([len(atoms), 3])
            base_stress = np.zeros([6])
            base_energies = 0.

        desp = compute_descriptor(self.parameters.ff._descriptors, atoms)
        energies, forces, stress = self.parameters.ff.model.calculate_properties(
            desp, bforce=True, bstress=True)

        self.desp = desp
        self.results['energies'] = energies + base_energies
        self.results['energy'] = energies.sum() + base_energy
        self.results['free_energy'] = energies.sum() + base_energy
        self.results['forces'] = forces + base_forces

        # pyxtal_ff and lammps uses: xx, yy, zz, xy, xz, yz
        # ase uses: xx, yy, zz, yz, xz, xy
        # from eV/A^3 to GPa
        self.results['stress_zbl'] = base_stress / units.GPa
        self.results['energy_zbl'] = base_energy
        self.results['forces_zbl'] = base_forces
        self.results['stress_ml'] = stress
        self.results['energy_ml'] = energies.sum()
        self.results['forces_ml'] = forces

        # ase counts the stress differently
        if self.style == 'ase':
            self.results['stress'] = -(stress * units.GPa +
                                       base_stress)[[0, 1, 2, 5, 4, 3]]
        else:
            self.results['stress'] = self.results['stress_zbl'] + self.results[
                'stress_ml']
Пример #21
0
    def calculate(self,
                  atoms=None,
                  properties=['energy'],
                  system_changes=all_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        natoms = len(self.atoms)

        sigma = self.parameters.sigma
        epsilon = self.parameters.epsilon
        rc = self.parameters.rc
        if rc is None:
            rc = 3 * sigma

        if 'numbers' in system_changes:
            self.nl = NeighborList([rc / 2] * natoms, self_interaction=False)

        self.nl.update(self.atoms)

        positions = self.atoms.positions
        cell = self.atoms.cell

        e0 = 4 * epsilon * ((sigma / rc)**12 - (sigma / rc)**6)

        energy = 0.0
        forces = np.zeros((natoms, 3))
        stress = np.zeros((3, 3))

        for a1 in range(natoms):
            neighbors, offsets = self.nl.get_neighbors(a1)
            cells = np.dot(offsets, cell)
            d = positions[neighbors] + cells - positions[a1]
            r2 = (d**2).sum(1)
            c6 = (sigma**2 / r2)**3
            c6[r2 > rc**2] = 0.0
            energy -= e0 * (c6 != 0.0).sum()
            c12 = c6**2
            energy += 4 * epsilon * (c12 - c6).sum()
            f = (24 * epsilon * (2 * c12 - c6) / r2)[:, np.newaxis] * d
            forces[a1] -= f.sum(axis=0)
            for a2, f2 in zip(neighbors, f):
                forces[a2] += f2
            stress += np.dot(f.T, d)

        if 'stress' in properties:
            if self.atoms.number_of_lattice_vectors == 3:
                stress += stress.T.copy()
                stress *= -0.5 / self.atoms.get_volume()
                self.results['stress'] = stress.flat[[0, 4, 8, 5, 2, 1]]
            else:
                raise PropertyNotImplementedError

        self.results['energy'] = energy
        self.results['free_energy'] = energy
        self.results['forces'] = forces
Пример #22
0
Файл: lj.py Проект: PHOTOX/fuase
    def calculate(self, atoms=None,
                  properties=['energy'],
                  system_changes=all_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        natoms = len(self.atoms)

        sigma = self.parameters.sigma
        epsilon = self.parameters.epsilon
        rc = self.parameters.rc
        if rc is None:
            rc = 3 * sigma
        
        if 'numbers' in system_changes:
            self.nl = NeighborList([rc / 2] * natoms, self_interaction=False)

        self.nl.update(self.atoms)
        
        positions = self.atoms.positions
        cell = self.atoms.cell
        
        e0 = 4 * epsilon * ((sigma / rc)**12 - (sigma / rc)**6)
        
        energy = 0.0
        forces = np.zeros((natoms, 3))
        stress = np.zeros((3, 3))

        for a1 in range(natoms):
            neighbors, offsets = self.nl.get_neighbors(a1)
            cells = np.dot(offsets, cell)
            d = positions[neighbors] + cells - positions[a1]
            r2 = (d**2).sum(1)
            c6 = (sigma**2 / r2)**3
            c6[r2 > rc**2] = 0.0
            energy -= e0 * (c6 != 0.0).sum()
            c12 = c6**2
            energy += 4 * epsilon * (c12 - c6).sum()
            f = (24 * epsilon * (2 * c12 - c6) / r2)[:, np.newaxis] * d
            #print d
            #print r2**.5
            #print offsets
            #print f
            #print neighbors
            forces[a1] -= f.sum(axis=0)
            for a2, f2 in zip(neighbors, f):
                forces[a2] += f2
            stress += np.dot(f.T, d)
        
        #stress = np.dot(stress, cell)
        stress += stress.T.copy()
        stress *= -0.5 / self.atoms.get_volume()
        
        self.results['energy'] = energy
        self.results['forces'] = forces
        self.results['stress'] = stress.flat[[0, 4, 8, 5, 2, 1]]
Пример #23
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        nat = len(self.atoms)
        atnums = self.atoms.numbers
        atnums_in_system = set(atnums)

        i_n, j_n, dr_nc, abs_dr_n = neighbour_list(
            'ijDd', self.atoms, self.dict)

        e_n = np.zeros_like(abs_dr_n)
        de_n = np.zeros_like(abs_dr_n)
        for params, pair in enumerate(self.dict):
            if pair[0] == pair[1]:
                mask1 = atnums[i_n] == pair[0]
                mask2 = atnums[j_n] == pair[0]
                mask = np.logical_and(mask1, mask2)

                e_n[mask] = self.f[pair](abs_dr_n[mask])
                de_n[mask] = self.df[pair](abs_dr_n[mask])

            if pair[0] != pair[1]:
                mask1 = np.logical_and(
                    atnums[i_n] == pair[0], atnums[j_n] == pair[1])
                mask2 = np.logical_and(
                    atnums[i_n] == pair[1], atnums[j_n] == pair[0])
                mask = np.logical_or(mask1, mask2)

                e_n[mask] = self.f[pair](abs_dr_n[mask])
                de_n[mask] = self.df[pair](abs_dr_n[mask])

        epot = 0.5*np.sum(e_n)

        # Forces
        df_nc = -0.5*de_n.reshape(-1, 1)*dr_nc/abs_dr_n.reshape(-1, 1)

        # Sum for each atom
        fx_i = np.bincount(j_n, weights=df_nc[:, 0], minlength=nat) - \
            np.bincount(i_n, weights=df_nc[:, 0], minlength=nat)
        fy_i = np.bincount(j_n, weights=df_nc[:, 1], minlength=nat) - \
            np.bincount(i_n, weights=df_nc[:, 1], minlength=nat)
        fz_i = np.bincount(j_n, weights=df_nc[:, 2], minlength=nat) - \
            np.bincount(i_n, weights=df_nc[:, 2], minlength=nat)

        # Virial
        virial_v = -np.array([dr_nc[:, 0]*df_nc[:, 0],               # xx
                              dr_nc[:, 1]*df_nc[:, 1],               # yy
                              dr_nc[:, 2]*df_nc[:, 2],               # zz
                              dr_nc[:, 1]*df_nc[:, 2],               # yz
                              dr_nc[:, 0]*df_nc[:, 2],               # xz
                              dr_nc[:, 0]*df_nc[:, 1]]).sum(axis=1)  # xy

        self.results = {'energy': epot,
                        'stress': virial_v/self.atoms.get_volume(),
                        'forces': np.transpose([fx_i, fy_i, fz_i])}
Пример #24
0
 def calculate(self,
               atoms=None,
               properties=["energy"],
               system_changes=all_changes):
     Calculator.calculate(self, atoms, properties, system_changes)
     image = atoms
     natoms = len(image)
     energy = 0.0
     forces = np.zeros((natoms, 3))
     self.results["energy"] = energy
     self.results["forces"] = forces
Пример #25
0
    def calculate(self,
                  atoms=None,
                  properties=['energy'],
                  system_changes=all_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        natoms = len(self.atoms)

        k = self.parameters.k
        tolerAngs = self.parameters.tolerAngs
        tolerMult = self.parameters.tolerMult
        cutoff = self.parameters.cutoff

        if 'numbers' in system_changes:
            # Want agregation?  cutoff > 2.00
            # Want uniform?     cutoff < 1.50
            # Directional?      cutoff < 1.25
            self.nl = NeighborList([cutoff / 2] * natoms,\
                      self_interaction=False)

        self.nl.update(self.atoms)

        positions = self.atoms.positions
        cell = self.atoms.cell

        energy = 0.0
        forces = np.zeros((natoms, 3))
        stress = np.zeros((3, 3))

        for a1 in range(natoms):
            neighbors, offsets = self.nl.get_neighbors(a1)
            #            print(neighbors)
            cells = np.dot(offsets, cell)
            vecBond = positions[neighbors] + cells - positions[a1]
            lenBond = np.sqrt((vecBond**2).sum(1))
            covalBl = covalRadii[self.atoms.get_atomic_numbers()[a1]]+\
                covalRadii[self.atoms.get_atomic_numbers()[neighbors]]
            compress = covalBl - lenBond
            energy += k / 2 * ((compress)**2).sum()
            # only repulsion
            compress[covalBl - lenBond < tolerAngs] = 0.0
            compress[lenBond / covalBl > 1 - tolerMult] = 0.0
            # # also attraction
            # compress[np.abs(covalBl - lenBond) < tolerAngs] = 0.0
            # compress[np.abs(1 - lenBond / covalBl) < tolerMult] = 0.0
            f = k * (compress)[:, np.newaxis] * vecBond
            forces[a1] -= f.sum(axis=0)
            for a2, f2 in zip(neighbors, f):
                forces[a2] += f2

        self.results['energy'] = energy
        self.results['free_energy'] = energy
        self.results['forces'] = forces
Пример #26
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        results = [
            self.calculator.get_property(prop, atoms) for prop in properties
        ]

        # Only count evaluation if system (typically the position)
        # has changed
        if system_changes:
            self.n_evals += 1
        self.results = dict(zip(properties, results))
Пример #27
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        R = atoms.get_positions()
        charges = self.get_virtual_charges(atoms)
        pbc = atoms.pbc

        energy = 0.0
        forces = np.zeros_like(atoms.get_positions())

        for m in range(len(atoms)):
            D = R[m + 1:] - R[m]
            shift = np.zeros_like(D)
            for i, periodic in enumerate(pbc):
                if periodic:
                    L = atoms.cell.diagonal()[i]
                    shift[:, i] = (D[:, i] + L / 2) % L - L / 2 - D[:, i]
            D += shift
            d2 = (D**2).sum(1)
            d = d2**0.5

            x1 = d > self.rc - self.width
            x2 = d < self.rc
            x12 = np.logical_and(x1, x2)
            y = (d[x12] - self.rc + self.width) / self.width
            t = np.zeros(len(d))  # cutoff function
            t[x2] = 1.0
            t[x12] -= y**2 * (3.0 - 2.0 * y)
            dtdd = np.zeros(len(d))
            dtdd[x12] -= 6.0 / self.width * y * (1.0 - y)

            c6 = (self.sigma**2 / d2)**3
            c12 = c6**2
            e_lj = 4 * self.epsilon * (c12 - c6)
            e_c = k_c * charges[m + 1:] * charges[m] / d

            energy += np.dot(t, e_lj)
            energy += np.dot(t, e_c)

            F = (24 * self.epsilon *
                 (2 * c12 - c6) / d2 * t - e_lj * dtdd / d)[:, None] * D

            forces[m] -= F.sum(0)
            forces[m + 1:] += F

            F = (e_c / d2 * t)[:, None] * D \
                - (e_c * dtdd / d)[:, None] * D

            forces[m] -= F.sum(0)
            forces[m + 1:] += F

        self.results['energy'] = energy
        self.results['forces'] = forces
Пример #28
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        # construct neighbor list
        i_p, j_p, r_p, r_pc = neighbour_list('ijdD',
                                             atoms=atoms,
                                             cutoff=self.cutoff)

        nb_atoms = len(self.atoms)
        nb_pairs = len(i_p)

        # normal vectors
        n_pc = (r_pc.T / r_p).T
        nx_p, ny_p, nz_p = n_pc.T

        # construct triplet list
        first_i = first_neighbours(nb_atoms, i_p)
        ij_t, ik_t = triplet_list(first_i)

        # calculate energy
        G_t = self.G(r_pc[ij_t], r_pc[ik_t])
        xi_p = np.bincount(ij_t, weights=G_t, minlength=nb_pairs)
        F_p = self.F(r_p, xi_p)
        epot = 0.5 * np.sum(F_p)

        d1G_t = self.d1G(r_pc[ij_t], r_pc[ik_t])
        d2F_d2G_t = (self.d2F(r_p[ij_t], xi_p[ij_t]) *
                     self.d2G(r_pc[ij_t], r_pc[ik_t]).T).T
        # calculate forces (per pair)
        fx_p = \
            self.d1F(r_p, xi_p) * n_pc[:, 0] + \
            self.d2F(r_p, xi_p) * np.bincount(ij_t, d1G_t[:, 0], minlength=nb_pairs) + \
            np.bincount(ik_t, d2F_d2G_t[:, 0], minlength=nb_pairs)
        fy_p = \
            self.d1F(r_p, xi_p) * n_pc[:, 1] + \
            self.d2F(r_p, xi_p) * np.bincount(ij_t, d1G_t[:, 1], minlength=nb_pairs) + \
            np.bincount(ik_t, d2F_d2G_t[:, 1], minlength=nb_pairs)
        fz_p = \
            self.d1F(r_p, xi_p) * n_pc[:, 2] + \
            self.d2F(r_p, xi_p) * np.bincount(ij_t, d1G_t[:, 2], minlength=nb_pairs) + \
            np.bincount(ik_t, d2F_d2G_t[:, 2], minlength=nb_pairs)

        # collect atomic forces
        fx_n = 0.5 * (np.bincount(i_p, weights=fx_p) -
                      np.bincount(j_p, weights=fx_p))
        fy_n = 0.5 * (np.bincount(i_p, weights=fy_p) -
                      np.bincount(j_p, weights=fy_p))
        fz_n = 0.5 * (np.bincount(i_p, weights=fz_p) -
                      np.bincount(j_p, weights=fz_p))

        f_n = np.transpose([fx_n, fy_n, fz_n])

        self.results = {'energy': epot, 'forces': f_n}
Пример #29
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        P = atoms.positions
        D = np.array([P - p for p in P])  # all distance vectors
        d = (D**2).sum(2)**0.5
        dd = d - self.target
        d.ravel()[::len(d) + 1] = 1  # avoid dividing by zero
        d4 = d**4
        e = 0.5 * (dd**2 / d4).sum()
        f = -2 * ((dd * (1 - 2 * dd / d) / d**5)[..., np.newaxis] * D).sum(0)
        self.results = {'energy': e, 'forces': f}
Пример #30
0
    def calculate(
        self,
        atoms=None,
        properties=["energy", "forces", "stress"],
        system_changes=["positions", "numbers", "cell", "pbc"],
    ):
        """
        Inherited method from the ase Calculator class that is called by
        get_property()

        Parameters
        ----------
        atoms : Atoms
            Atoms object whose properties are desired

        properties : list of str
            List of what needs to be calculated.  Can be any combination
            of 'energy', 'forces' and 'stress'.

        system_changes : list of str
            List of what has changed since last calculation.  Can be any
            combination of these six: 'positions', 'numbers', 'cell',
            and 'pbc'.
        """

        Calculator.calculate(self, atoms, properties, system_changes)

        # Update KIM API input data and neighbor list, if necessary
        if system_changes:
            if self.need_neigh_update(atoms, system_changes):
                self.update_neigh(atoms, self.species_map)
                self.energy = np.array([0.0], dtype=np.double)
                self.forces = np.zeros([self.num_particles[0], 3], dtype=np.double)
                self.update_compute_args_pointers(self.energy, self.forces)
            else:
                self.update_kim_coords(atoms)

            self.kim_model.compute(self.compute_args, self.release_GIL)

        energy = self.energy[0]
        forces = self.assemble_padding_forces()

        try:
            volume = atoms.get_volume()
            stress = self.compute_virial_stress(self.forces, self.coords, volume)
        except ValueError:  # Volume cannot be computed
            stress = None

        # Quantities passed back to ASE
        self.results["energy"] = energy
        self.results["free_energy"] = energy
        self.results["forces"] = forces
        self.results["stress"] = stress
Пример #31
0
 def calculate(self, atoms, properties, system_changes):
     Calculator.calculate(self, atoms, properties, system_changes)
     if system_changes:
         self.results = {}
     if 'energy' in properties and 'energy' not in self.results:
         e1 = self.calc1.get_potential_energy(atoms)
         e2 = self.calc2.get_potential_energy(atoms)
         self.results['energy'] = e1 + e2
     if 'forces' in properties and 'forces' not in self.results:
         f1 = self.calc1.get_forces(atoms)
         f2 = self.calc2.get_forces(atoms)
         self.results['forces'] = f1 + f2
Пример #32
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)
        dataset = TestDataset(images=atoms,
                              descriptor=self.model.descriptor,
                              Gs=self.Gs,
                              fprange=self.fp_scaling,
                              label=self.model.label)
        fp_length = dataset.fp_length()
        unique_atoms = dataset.unique()
        architecture = copy.copy(self.model.structure)
        architecture.insert(0, fp_length)
        batch_size = len(dataset)
        dataloader = DataLoader(dataset,
                                batch_size,
                                collate_fn=dataset.collate_test,
                                shuffle=False)
        if properties == ['energy']:
            model = FullNN(unique_atoms,
                           architecture,
                           "cpu",
                           forcetraining=False)
        elif properties == ['forces']:
            model = FullNN(unique_atoms,
                           architecture,
                           "cpu",
                           forcetraining=True)
        model.load_state_dict(torch.load(self.label))
        model.eval()

        for batch in dataloader:
            input_data = [batch[0], len(batch[1]), unique_atoms]
            for element in unique_atoms:
                input_data[0][element][0] = input_data[0][element][
                    0].requires_grad_(True)
            fp_primes = batch[2]
            energy, forces = model(input_data, fp_primes)
        energy = (energy * self.target_sd) + self.target_mean
        energy = np.concatenate(energy.detach().numpy())
        if properties == ['forces']:
            forces = (forces * self.target_sd).detach().numpy()

        if self.lj:
            lj_energy, lj_forces, _ = self.lj_model.lj_pred([atoms],
                                                            self.fitted_params,
                                                            self.params_dict)
            lj_energy = np.squeeze(lj_energy)
            energy += lj_energy
            if properties == ['forces']:
                forces += lj_forces

        self.results["energy"] = float(energy)
        self.results["forces"] = forces
Пример #33
0
    def calculate(self, atoms=None, properties=['energy'],
                  system_changes=[]):

        Calculator.calculate(self, atoms, properties, system_changes)

        # only one property allowed
        assert(len(properties) == 1)
        
        # make sure we have a water molecule, and identify O, H1, H2
        chemical_formula = self.atoms.get_chemical_formula(mode='all')
        
        if chemical_formula == 'OHH':
            o = 0
            h1= 1
            h2 =2
        elif chemical_formula == 'HOH':
            o = 1
            h1= 0
            h2 =2
        elif chemical_formula == 'HHO':
            o = 2
            h1= 0
            h2 =1
        else:
            raise RuntimeError("chemical formula '{}' is not a water molecule!".format(chemical_formula))
        
        # compute internal coordinates, both stretch coordinates q1, q2 in [bohr] and theta in radians  
        pos=atoms.get_positions() / Bohr 
        #q1_tmp = (pos[h1] -  pos[o]) / Bohr
        #q2_tmp = (pos[h2] -  pos[o]) / Bohr
        #
        #q1 = np.linalg.norm(q1_tmp)
        #q2 = np.linalg.norm(q2_tmp)
        #
        #q1_norm = q1_tmp / q1 
        #q2_norm = q2_tmp / q2
        #q_norm_sum = q1_norm + q2_norm  
        #q_norm_sum_norm = q_norm_sum / np.linalg.norm(q_norm_sum)
        #
        #theta = 2.0 * abs(np.arcsin(np.linalg.norm(np.cross(q1_norm,q_norm_sum_norm))))

        q1,q2,theta = get_internal_coords_h2o(pos[o], pos[h1], pos[h2])
        
        if properties[0] == 'energy':

            V =0.0
            V= h2o_pjt2.pots(q1,q2,theta)
            
            self.results['energy'] = V * Ha

        if properties[0] == 'forces':
            self.results['forces'] = self.calculate_numerical_forces(atoms, d=0.00000001)
Пример #34
0
    def calculate(self,
                  atoms=None,
                  properties=['energy'],
                  system_changes=all_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        #        natoms = len(self.atoms)

        #        positions = self.atoms.positions
        #        cell = self.atoms.cell

        self.results['energy'] = self.energy
        self.results['forces'] = self.forces
Пример #35
0
 def calculate(self, atoms, properties, system_changes):
     Calculator.calculate(self, atoms, properties, system_changes)
     if system_changes:
         self.results = {}
     if 'energy' in properties and 'energy' not in self.results:
         self.results['energy'] = 0.0
         for constraint in self.constraint:
             self.results['energy'] += constraint.adjust_potential_energy(
                 atoms)
     if 'forces' in properties and 'forces' not in self.results:
         self.results['forces'] = np.zeros((len(atoms), 3))
         for constraint in self.constraint:
             constraint.adjust_forces(atoms, self.results['forces'])
Пример #36
0
    def calculate(self, atoms=None, properties=['energy'],
                  system_changes=all_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        X = [self.atoms]
        managers = self.representation.transform(X)

        energy = self.model.predict(managers)
        forces = -self.model.predict(managers, compute_gradients=True)

        self.results['energy'] = energy
        self.results['free_energy'] = energy
        self.results['forces'] = forces
Пример #37
0
    def calculate(self, atoms, properties, system_changes):
        """Calculation of the energy of system and forces of all atoms."""
        # The inherited method below just sets the atoms object,
        # if specified, to self.atoms.
        Calculator.calculate(self, atoms, properties, system_changes)

        if properties == ['energy']:
            energy = self.model.calculate_energy(atoms)
            self.results['energy'] = energy[0]

        if properties == ['forces']:
            forces = self.model.calculate_forces(atoms)
            self.results['forces'] = forces[0]
Пример #38
0
 def calculate(self, atoms, properties, system_changes):
     Calculator.calculate(self, atoms, properties, system_changes)
     julia_atoms = ASEAtoms(atoms)
     julia_atoms = convert(julia_atoms)
     self.results = {}
     if 'energy' in properties:
         self.results['energy'] = energy(self.julip_calculator, julia_atoms)
     if 'forces' in properties:
         self.results['forces'] = np.array(
             forces(self.julip_calculator, julia_atoms))
     if 'stress' in properties:
         voigt_stress = full_3x3_to_voigt_6_stress(
             np.array(stress(self.julip_calculator, julia_atoms)))
         self.results['stress'] = voigt_stress
Пример #39
0
Файл: test.py Проект: jboes/ase
 def calculate(self, atoms, properties, system_changes):
     Calculator.calculate(self, atoms, properties, system_changes)
     E = 0.0
     R = atoms.positions
     F = np.zeros_like(R)
     for a, r in enumerate(R):
         D = R - r
         d = (D**2).sum(1)**0.5
         x = d - 1.0
         E += np.vdot(x, x)
         d[a] = 1
         F -= (x / d)[:, None] * D
     energy = 0.25 * E
     self.results = {'energy': energy, 'forces': F}
Пример #40
0
    def calculate(self, atoms=None, properties=None, system_changes=all_changes):
        """calculate and store energy"""
        if not properties:
           properties = 'energy'

        """
        If system_changes, atoms etc will be updated.
        """
        Calculator.calculate(self, atoms, properties, system_changes)

        e_old = self.ann_model.predict(self.atoms)[0][0]

        self.results['energy'] = float(e_old)
        self.results['forces'] = np.array(self.cal_force(e_old))
Пример #41
0
 def calculate(self,
               atoms=None,
               properties=None,
               system_changes=all_changes):
     Calculator.calculate(self, atoms, properties, system_changes)
     image = atoms
     natoms = len(image)
     energy = 0.0
     forces = np.zeros((natoms, 3))
     self.results["energy"] = energy
     self.results["forces"] = forces
     self.results["stress"] = -np.array([0, 0, 0, 0, 0, 0])
     self.results["force_stds"] = zeros_like(forces)
     atoms.info["max_force_stds"] = np.nanmax(self.results["force_stds"])
Пример #42
0
 def calculate(self, atoms, properties, system_changes):
     Calculator.calculate(self, atoms, properties, system_changes)
     E = 0.0
     R = atoms.positions
     F = np.zeros_like(R)
     for a, r in enumerate(R):
         D = R - r
         d = (D**2).sum(1)**0.5
         x = d - 1.0
         E += np.vdot(x, x)
         d[a] = 1
         F -= (x / d)[:, None] * D
     energy = 0.25 * E
     self.results = {'energy': energy, 'forces': F}
Пример #43
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)
        data_object = self.a2g.convert(atoms)
        batch = data_list_collater([data_object])

        predictions = self.trainer.predict(batch,
                                           per_image=False,
                                           disable_tqdm=True)
        if self.trainer.name == "s2ef":
            self.results["energy"] = predictions["energy"].item()
            self.results["forces"] = predictions["forces"].cpu().numpy()

        elif self.trainer.name == "is2re":
            self.results["energy"] = predictions["energy"].item()
Пример #44
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)
        data_object = self.a2g.convert(atoms)
        batch = data_list_collater([data_object])
        if self.pbc_graph:
            edge_index, cell_offsets, neighbors = radius_graph_pbc(
                batch, 6, 50, batch.pos.device)
            batch.edge_index = edge_index
            batch.cell_offsets = cell_offsets
            batch.neighbors = neighbors
        predictions = self.trainer.predict(batch)

        self.results["energy"] = predictions["energy"][0]
        self.results["forces"] = predictions["forces"][0]
Пример #45
0
    def calculate(self,
                  atoms=None,
                  properties=['energy'],
                  system_changes=all_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        # start_time2 = time.time()
        ## make up for stress
        ## TODO
        # stress_ani = np.zeros((1, 3))
        stress_ani = np.zeros(6)

        if self.Setup or self.nc.ncl[0].request_setup():
            # Setup molecule for MD
            natoms = len(self.atoms)
            atom_symbols = self.atoms.get_chemical_symbols()
            xyz = self.atoms.get_positions()
            self.nc.set_molecule(xyz.astype(np.float32), atom_symbols)
            self.nc.set_pbc(self.atoms.get_pbc()[0],
                            self.atoms.get_pbc()[1],
                            self.atoms.get_pbc()[2])

            self.Setup = False
        else:
            xyz = self.atoms.get_positions()
            # Set the conformers in NeuroChem
            self.nc.set_coordinates(xyz.astype(np.float32))

            # TODO works only for 3D periodic. For 1,2D - update np.zeros((3,3)) part
            pbc_inv = (np.linalg.inv(self.atoms.get_cell())).astype(
                np.float32) if atoms.pbc.all() else np.zeros(
                    (3, 3), dtype=np.float32)
            self.nc.set_cell((self.atoms.get_cell()).astype(np.float32),
                             pbc_inv)

        energy, force, stddev = self.nc.compute_mean_props()

        self.stddev = conv_au_ev * stddev

        self.results['energy'] = conv_au_ev * energy
        if 'forces' in properties:
            forces = conv_au_ev * force

            # restrain atoms
            for i in self.reslist:
                forces[i] = 0.0

            self.results['forces'] = -forces
        self.results['stress'] = conv_au_ev * stress_ani
Пример #46
0
    def calculate(self,
                  atoms=None,
                  properties=["energy"],
                  system_changes=all_changes):
        if self.calculation_required(atoms, properties):
            Calculator.calculate(self, atoms)
            posinp = Posinp.from_ase(atoms)

            job = Job(posinp=posinp, calculator=self.schnetpackcalculator)
            for prop in properties:
                job.run(prop)
            results = {}
            for prop, result in zip(job.results.keys(), job.results.values()):
                results[prop] = np.squeeze(result)
            self.results = results
Пример #47
0
    def calculate(self,
                  atoms=None,
                  properties=['energy'],
                  system_changes=all_changes):

        Calculator.calculate(self, atoms, properties, system_changes)

        self.write_pw_input(atoms)

        self.run_pw()
        Ep = self.parse_E()
        F = self.parse_F(atoms)
        #        s = self.parse_Stress()
        self.results['energy'] = Ep
        self.results['forces'] = F
Пример #48
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        i_n, j_n, dr_nc, abs_dr_n = neighbour_list('ijDd', self.atoms,
                                                   self._db_cutoff)

        epot, virial_v, forces_ic = self.energy_virial_and_forces(
            self.atoms.numbers, i_n, j_n, dr_nc, abs_dr_n)

        self.results = {
            'energy': epot,
            'free_energy': epot,
            'stress': virial_v / self.atoms.get_volume(),
            'forces': forces_ic
        }
Пример #49
0
    def calculate(self, atoms=None, properties=['energy'],
                  system_changes=['positions', 'numbers', 'cell',
                                  'pbc', 'charges','magmoms']):

        Calculator.calculate(self, atoms)

        calc_molcell = self.molcell.copy()
        calc_molcell.atom = ase_atoms_to_pyscf(atoms)
        calc_molcell.a = atoms.cell
        calc_molcell.build(None,None)
        self.mf = self.mf_class(calc_molcell)
        for key in self.mf_dict:
            self.mf.__dict__[key] = self.mf_dict[key]

        self.results['energy']=self.mf.scf()
        self.results['mf']=self.mf
Пример #50
0
    def calculate(self, atoms=None, properties=['energy'],
                  system_changes=some_changes):
        Calculator.calculate(self, atoms, properties, system_changes)
        self.write_input(self.atoms, properties, system_changes)

        olddir = os.getcwd()
        try:
            os.chdir(self.directory)
            errorcode = subprocess.call(self.command, shell=True)
        finally:
            os.chdir(olddir)

        if errorcode:
            raise RuntimeError('%s returned an error: %d' %
                               (self.name, errorcode))
        self.read_results()
Пример #51
0
    def calculate(self, atoms=None, properties=['energy'],
                  system_changes=['positions', 'numbers', 'cell']):
        Calculator.calculate(self, atoms, properties, system_changes)

        if not system_changes:
            return

        if 'numbers' in system_changes:
            self.close()

        self._run_vasp(atoms)

        new = read(os.path.join(self.path, 'vasprun.xml'), index=-1)

        self.results = {'free_energy': new.get_potential_energy(force_consistent=True),
                        'energy': new.get_potential_energy(),
                        'forces': new.get_forces()[self.resort],
                        'stress': new.get_stress()}
Пример #52
0
    def calculate(
        self,
        atoms=None,
        properties=["energy"],
        system_changes=["positions", "numbers", "cell", "pbc", "charges", "magmoms"],
    ):

        Calculator.calculate(self, atoms)

        calc_molcell = self.molcell.copy()
        calc_molcell.atom = ase_atoms_to_pyscf(atoms)
        calc_molcell.h = atoms.cell
        calc_molcell.build(None, None)
        self.mf = self.mf_class(calc_molcell)
        for key in self.mf_dict:
            self.mf.__dict__[key] = self.mf_dict[key]

        self.results["energy"] = self.mf.scf()
        self.results["mf"] = self.mf
Пример #53
0
 def calculate(self, atoms, properties, system_changes):
     Calculator.calculate(self, atoms, properties, system_changes)
     if system_changes:
         if 'energy' in self.results:
             del self.results['energy']
         if 'forces' in self.results:
             del self.results['forces']
     if 'energy' not in self.results:
         if self.permutation is None:
             crd = np.reshape(atoms.get_positions(), (1, len(atoms), 3))
         else:
             crd = np.reshape(atoms.get_positions()
                              [self.permutation[0, :]], (1, len(atoms), 3))
         sander.set_positions(crd)
         e, f = sander.energy_forces()
         self.results['energy'] = e.tot * units.kcal / units.mol
         if self.permutation is None:
             self.results['forces'] = (np.reshape(np.array(f),
                                                  (len(atoms), 3)) *
                                       units.kcal / units.mol)
         else:
             ff = np.reshape(np.array(f), (len(atoms), 3)) * \
                 units.kcal / units.mol
             self.results['forces'] = ff[self.permutation[1, :]]
     if 'forces' not in self.results:
         if self.permutation is None:
             crd = np.reshape(atoms.get_positions(), (1, len(atoms), 3))
         else:
             crd = np.reshape(atoms.get_positions()[self.permutation[0, :]],
                              (1, len(atoms), 3))
         sander.set_positions(crd)
         e, f = sander.energy_forces()
         self.results['energy'] = e.tot * units.kcal / units.mol
         if self.permutation is None:
             self.results['forces'] = (np.reshape(np.array(f),
                                                  (len(atoms), 3)) *
                                       units.kcal / units.mol)
         else:
             ff = np.reshape(np.array(f), (len(atoms), 3)) * \
                 units.kcal / units.mol
             self.results['forces'] = ff[self.permutation[1, :]]
Пример #54
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        if self.np_atoms is None:
            self.initialize_np(atoms)

        if self.sp_atoms is None:
            self.initialize_sp(atoms)

        energy = 0
        forces = np.zeros(shape=(len(atoms), 3))
        ## 1. Nanoparticle
        self.np_atoms.positions = atoms.positions[self.np_selection]
        if self.vacuum:
            self.np_atoms.positions += (self.center -
                                       self.np_atoms.positions.mean(axis=0))
        energy += self.np_calc.get_potential_energy(self.np_atoms)
        np_forces = self.np_calc.get_forces(self.np_atoms)
        if self.vacuum:
            np_forces -= np_forces.mean(axis=0)
        forces[self.np_selection] += np_forces
        ## 2. Support. Copy-Paste. TODO: make loop over subsystems
        self.sp_atoms.positions = atoms.positions[self.sp_selection]
        if self.vacuum:
            self.sp_atoms.positions += (self.center -
                                       self.sp_atoms.positions.mean(axis=0))
        energy += self.sp_calc.get_potential_energy(self.sp_atoms)
        sp_forces = self.sp_calc.get_forces(self.sp_atoms)
        if self.vacuum:
            sp_forces -= sp_forces.mean(axis=0)
        forces[self.sp_selection] += sp_forces
        ## 3. INTERACTION
        if self.ia_calc is not None:
            ienergy, inpforces, ispforces = self.ia_calc.calculate(
                self.np_atoms, self.sp_atoms, (0, 0, 0))
            forces[self.np_selection] += inpforces
            forces[self.sp_selection] += ispforces
            energy += ienergy
        ## 4. return result
        self.results['energy'] = energy
        self.results['forces'] = forces
Пример #55
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        if not(system_changes is None):
            self.update_atoms()
        species = set(atoms.numbers)
        charges = [atom.charge for atom in atoms]

        energy = 0.0
        forces = np.zeros((len(atoms), 3))
        chems = atoms.get_chemical_symbols()
        for i, R1, symb1, Q1 in zip(count(), atoms.positions, chems, charges):
            for j, R2, symb2, Q2 in zip(count(), atoms.positions, chems, charges):

                if j<=i:
                    continue

                pair = _tup2str((symb1,symb2))

                if pair not in self.parameters:
                    continue

                A, rho, C = self.parameters[pair]
                D = R1 - R2
                d2 = (D**2).sum()
                if (d2 > 0.001):
                    d = np.sqrt(d2)
                    coul = COUL_COEF*Q1*Q2/d
                    Aexp = A*np.exp(-d/rho)
                    Cr6 = C/d2**3
                    energy += Aexp - Cr6 + coul
                    force = (1/rho*Aexp - 6/d*Cr6 + coul/d)*D/d
                    forces[i, :] +=  force
                    forces[j, :] += -force

        if 'energy' in properties:
            self.results['energy'] = energy

        if 'forces' in properties:
            self.results['forces'] = forces
Пример #56
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        if isinstance(self.calculator, Calculator):
            results = [self.calculator.get_property(prop, atoms)
                       for prop in properties]
        else:
            results = []
            for prop in properties:
                method_name = self.property_to_method_name[prop]
                method = getattr(self.calculator, method_name)
                results.append(method(atoms))

        if 'energy' in properties or 'energies' in properties:
            self.energy_evals.setdefault(self.label, 0)
            self.energy_evals[self.label] += 1
            try:
                energy = results[properties.index('energy')]
            except IndexError:
                energy = sum(results[properties.index('energies')])
            logger.info('energy call count=%d energy=%.3f',
                        self.energy_evals[self.label], energy)
        self.results = dict(zip(properties, results))

        if 'forces' in self.results:
            fmax = self.fmax.setdefault(self.label, [])
            walltime = self.walltime.setdefault(self.label, [])
            forces = self.results['forces'].copy()
            energy_count = self.energy_count.setdefault(self.label, [])
            energy_evals = self.energy_evals.setdefault(self.label, 0)
            energy_count.append(energy_evals)
            for constraint in atoms.constraints:
                constraint.adjust_forces(atoms, forces)
            fmax.append(abs(forces).max())
            walltime.append(time.time())
            logger.info('force call fmax=%.3f', fmax[-1])

        if self.dumpjson:
            self.write_json('dump.json')
Пример #57
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)

        a = self.parameters['a']
        rc = self.parameters['rc']
        k = self.parameters['k']
        beta = self.parameters['beta']

        energies = np.zeros(len(atoms))
        forces = np.zeros((len(atoms), 3))
        velocities = (atoms.get_momenta().T/atoms.get_masses()).T
                
        i, j, dr, r = neighbour_list('ijDd', atoms, rc)
        if len(i) > 0:
            dr_hat = (dr.T/r).T
            dv = velocities[j] - velocities[i]

            de = 0.5*k*(r - a)**2 # spring energies
            e = 0.5*de # half goes to each end of spring
            f = (k*(r - a)*dr_hat.T).T + beta*dv

            energies[:] = np.bincount(i, e)            
            for kk in range(3):
                forces[:, kk] = np.bincount(i, weights=f[:, kk])

        energy = energies.sum()
            
        # add energy 0.5*k*(rc - a)**2 for each broken bond
        if len(i) < self.crystal_bonds:
            de = 0.5*k*(rc - a)**2
            energy += 0.5*de*(self.crystal_bonds - len(i))

        # Stokes dissipation
        if 'stokes' in atoms.arrays:
            b = atoms.get_array('stokes')
            forces -= (velocities.T*b).T
        
        self.results = {'energy':   energy,
                        'forces':   forces}
Пример #58
0
    def calculate(self, atoms, properties, system_changes):
        Calculator.calculate(self, atoms, properties, system_changes)
        
        if self.qmatoms is None:
            self.initialize(atoms)
            
        self.mmatoms.set_positions(atoms.positions[~self.mask])
        self.qmatoms.set_positions(atoms.positions[self.mask])
        
        if self.vacuum:
            shift = self.center - self.qmatoms.positions.mean(axis=0)
            self.qmatoms.positions += shift
        else:
            shift = (0, 0, 0)
            
        self.embedding.update(shift)

        ienergy, iqmforces, immforces = self.interaction.calculate(
            self.qmatoms, self.mmatoms, shift)
        
        qmenergy = self.qmatoms.get_potential_energy()
        mmenergy = self.mmatoms.get_potential_energy()
        energy = ienergy + qmenergy + mmenergy
        
        print('Energies: {0:12.3f} {1:+12.3f} {2:+12.3f} = {3:12.3f}'
              .format(ienergy, qmenergy, mmenergy, energy), file=self.output)
        
        qmforces = self.qmatoms.get_forces()
        mmforces = self.mmatoms.get_forces()
        
        mmforces += self.embedding.get_mm_forces()
        
        forces = np.empty((len(atoms), 3))
        forces[self.mask] = qmforces + iqmforces
        forces[~self.mask] = mmforces + immforces

        self.results['energy'] = energy
        self.results['forces'] = forces
Пример #59
0
    def calculate(self, atoms=None, properties=['energy'],
                  system_changes=all_changes):

        sim = self.sim

        # check that only things we actually pass to PINY are changed
        if not self.changes.issuperset(system_changes):
            msg = 'Not all changes are supported: {:s}'.format(str(system_changes))
            raise NotImplementedError(msg)

        # update PINY positions, recalculate ghosts and set them back in atoms
        sim.set_x((atoms.get_positions() / units.Bohr)[:,:,np.newaxis])
        atoms.set_positions(sim.get_x()[:,:,0] * units.Bohr)

        # now call parent method to remember the atoms, with ghosts updated
        Calculator.calculate(self, atoms=atoms)

        # run and extract results
        sim.update()
        self.results = {
            'energy': sim.get_V().item() * units.Ha,
            'forces': - sim.get_dV_dx()[:,:,0] * units.Ha / units.Bohr
        }