Beispiel #1
0
 def __init__(self, *args, **results):
     """Save energy, forces, stress, ... for the current configuration."""
     if args and isinstance(args[0], float):
         # Old interface:
         assert not results
         for key, value in zip(['energy', 'forces', 'stress', 'magmoms'],
                               args):
             if value is not None:
                 results[key] = value
         atoms = args[-1]
     else:
         if args:
             atoms = args[0]
         else:
             atoms = results.pop('atoms')
         
     Calculator.__init__(self)
     self.results = {}
     for property, value in results.items():
         assert property in all_properties
         if value is None:
             continue
         if property in ['energy', 'magmom']:
             self.results[property] = value
         else:
             self.results[property] = np.array(value, float)
     self.atoms = atoms.copy()
Beispiel #2
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()
Beispiel #3
0
 def __init__(self, calculator, db='checkpoints.db', logfile=None):
     Calculator.__init__(self)
     self.calculator = calculator
     if logfile is None:
         logfile = DevNull()
     self.checkpoint = Checkpoint(db, logfile)
     self.logfile = logfile
    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')
Beispiel #5
0
    def __init__(self, restart=None, ignore_bad_restart_file=False, label=None,
                 atoms=None, calc=None, block=False, **kwargs):
        '''Basic calculator implementation.
        restart: str
            Prefix for restart file.  May contain a directory.  Default
            is None: don't restart.
        ignore_bad_restart_file: bool
            Ignore broken or missing restart file.  By default, it is an
            error if the restart file is missing or broken.
        label: str
            Name used for all files.  May contain a directory.
        atoms: Atoms object
            Optional Atoms object to which the calculator will be
            attached.  When restarting, atoms will get its positions and
            unit-cell updated from file.

        Create a remote execution calculator based on actual ASE calculator 
        calc.
        '''
        logging.debug("Calc: %s Label: %s" % (calc, label))
        Calculator.__init__(self, restart, ignore_bad_restart_file, label, atoms, **kwargs)
        logging.debug("Dir: %s Ext: %s" % (self.directory, self.ext))
        self.calc=calc
        self.jobid=None
        self.block=block
Beispiel #6
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))
Beispiel #7
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)
Beispiel #8
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()
Beispiel #9
0
 def __init__(self, morses=None, bonds=None, angles=None, dihedrals=None,
              vdws=None, coulombs=None, **kwargs):
     Calculator.__init__(self, **kwargs)
     if (morses is None and
         bonds is None and
         angles is None and
         dihedrals is None and
         vdws is None and
             coulombs is None):
         raise ImportError("At least one of morses, bonds, angles, dihedrals,"
                           "vdws or coulombs lists must be defined!")
     if morses is None:
         self.morses = []
     else:
         self.morses = morses
     if bonds is None:
         self.bonds = []
     else:
         self.bonds = bonds
     if angles is None:
         self.angles = []
     else:
         self.angles = angles
     if dihedrals is None:
         self.dihedrals = []
     else:
         self.dihedrals = dihedrals
     if vdws is None:
         self.vdws = []
     else:
         self.vdws = vdws
     if coulombs is None:
         self.coulombs = []
     else:
         self.coulombs = coulombs
Beispiel #10
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()
Beispiel #11
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)
Beispiel #12
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
Beispiel #13
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))
Beispiel #14
0
    def __init__(self,                  
                 hirshfeld=None, vdwradii=None, calculator=None,
                 Rmax = 10, # maximal radius for periodic calculations
                 vdWDB_alphaC6 = vdWDB_alphaC6,
                 txt=None,
                 ):
        """Constructor

        Parameters
        ==========
        hirshfeld: the Hirshfeld partitioning object
        calculator: the calculator to get the PBE energy
        """
        self.hirshfeld = hirshfeld
        if calculator is None:
            self.calculator = self.hirshfeld.get_calculator()
        else:
            self.calculator = calculator
        if txt is None:
            self.txt = self.calculator.txt
        else:
            self.txt = get_txt(txt, rank)
        self.vdwradii = vdwradii
        self.vdWDB_alphaC6 = vdWDB_alphaC6
        self.Rmax = Rmax
        self.atoms = None

        self.sR = 0.94
        self.d = 20

        Calculator.__init__(self)
Beispiel #15
0
    def __init__(self, restart=None, ignore_bad_restart_file=False, label=None,
                 atoms=None, k=10, rt=1.5, sp_type='rep', **kwargs):

        Calculator.__init__(self, restart, ignore_bad_restart_file,
                            label, atoms, **kwargs)
        # Common parameters to all springs
        self.sp_type = sp_type
        self.k = k
        self.rt = rt

        # Depending on the spring type use different kernels
        self.nrg_func = spring_nrg
        self.f_func = spring_force
        self.v_nrg = voxel_spring_nrg
        self.atomwise_nrg = atomwise_spring_nrg
        if sp_type == 'com':
            self.nrg_func = com_spring_nrg
            self.f_func = com_spring_force
            self.v_nrg = voxel_com_spring_nrg
            self.atomwise_nrg = atomwise_com_spring_nrg
        if sp_type == 'att':
            self.nrg_func = att_spring_nrg
            self.f_func = att_spring_force
            self.v_nrg = voxel_att_spring_nrg
            self.atomwise_nrg = atomwise_att_spring_nrg
Beispiel #16
0
    def __init__(self, f, cutoff=None):
        Calculator.__init__(self)
        self.f = f

        self.dict = {x: obj.get_cutoff() for x, obj in f.items()}
        self.df = {x: obj.derivative(1) for x, obj in f.items()}
        self.df2 = {x: obj.derivative(2) for x, obj in f.items()}
Beispiel #17
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
Beispiel #18
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'])
Beispiel #19
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
Beispiel #20
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
Beispiel #21
0
Datei: cp2k.py Projekt: jboes/ase
    def __init__(self, restart=None, ignore_bad_restart_file=False,
                 label='cp2k', atoms=None, command=None,
                 debug=False, **kwargs):
        """Construct CP2K-calculator object."""

        self._debug = debug
        self._force_env_id = None
        self._child = None
        self._shell_version = None
        self.label = None
        self.parameters = None
        self.results = None
        self.atoms = None

        # Several places are check to determine self.command
        if command is not None:
            self.command = command
        elif CP2K.command is not None:
            self.command = CP2K.command
        elif 'ASE_CP2K_COMMAND' in os.environ:
            self.command = os.environ['ASE_CP2K_COMMAND']
        else:
            self.command = 'cp2k_shell'  # default

        assert 'cp2k_shell' in self.command

        Calculator.__init__(self, restart, ignore_bad_restart_file,
                            label, atoms, **kwargs)

        # launch cp2k_shell child process
        if self._debug:
            print(self.command)
        self._child = Popen(self.command, shell=True, universal_newlines=True,
                            stdin=PIPE, stdout=PIPE, bufsize=1)
        assert self._recv() == '* READY'

        # check version of shell
        self._send('VERSION')
        shell_version = self._recv().rsplit(":", 1)
        assert self._recv() == '* READY'
        assert shell_version[0] == "CP2K Shell Version"
        self._shell_version = float(shell_version[1])
        assert self._shell_version >= 1.0

        # enable harsh mode, stops on any error
        self._send('HARSH')
        assert self._recv() == '* READY'

        if restart is not None:
            try:
                self.read(restart)
            except:
                if ignore_bad_restart_file:
                    self.reset()
                else:
                    raise
Beispiel #22
0
    def __init__(self, restart=None, ignore_bad_restart_file=False, label=None,
                 atoms=None, **kwargs):
        """Accepted Keypairs
        calculation:
            str - only scf[default] supported at the moment
        ecutwfc: 
            plane wave cuttoff [eV] notice not in Ry!
        nbands:
            number of bands for calculation (see pw.x -> nbnd)
        usesymm:
            whether or not to use symmetry in calculation (True/False)
        maxiter:
            maximum number of iterations in an scf step
        convergence:
            {'energy', <value>} - only one implemented
        kpts:
            (1, 1, 1) - gamma point
            (n1, n2, n3) - Morstead Packing
            [[k1, k2, k3] ... ] - List of kpoints
        prefix: (self.label is meaningless at moment)
            str - string to append to output files
        pseudo:
            {'atom symbol': 'name of pseudo potential', ...} - dictionary of pseudo per atom
        outdir:
            str - relative or absolute path to output directory.
                  Will create it if it does not exist.
        pseudo_dir:
            str - relative or absolute path to pseudo directory.
        occupations:
            str - 'smearing', 'tetrahedra', 'fixed', 'from_input'
        input_dft:
            str - functional to use
        fft_mesh:
            [nr1, nr2, nr3] - fft mesh to use for calculation
        keypairs:
            way to initialize via the base class PWBase. 
            (DO NOT SET CELL OR ATOM POSITIONS via PWBase this is done 
            automagically via ASE Atoms)
        debug:
            if True will print input and output QE files

        AUTOMATICALLY SET KEYPAIRS:
        Set so we can always extract stress and forces:
            control.tstress=True
            control.tprnfor=True
        From atoms object:
            CARD 'CELL PARAMETERS (angstroms)' from atoms.cell
            CARD 'ATOMIC POSITIONS (angstroms)' from atoms[i]
            system.nat from number of unique atoms in atoms[i]
            system.ntyp from len(atoms)
        Thus DO NOT SET:
            A, B, C, cosAB, cosBC, cosAC, celldm(1-6)
            or any of these previously mentioned. Be smart
        """
        Calculator.__init__(self, restart, ignore_bad_restart_file, label, atoms, **kwargs)
        self._pw = None
Beispiel #23
0
 def __init__(self, atoms=None, label=None, top=None, crd=None,
              mm_options=None, qm_options=None, permutation=None, **kwargs):
     if not have_sander:
         raise RuntimeError("sander Python module could not be imported!")
     Calculator.__init__(self, label, atoms)
     self.permutation = permutation
     if qm_options is not None:
         sander.setup(top, crd.coordinates, crd.box, mm_options, qm_options)
     else:
         sander.setup(top, crd.coordinates, crd.box, mm_options)
Beispiel #24
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}
Beispiel #25
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
            #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]]
Beispiel #26
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])}
Beispiel #27
0
 def __init__(self, calculator, jsonfile=None, dumpjson=False):
     Calculator.__init__(self)
     self.calculator = calculator
     self.fmax = {}
     self.walltime = {}
     self.energy_evals = {}
     self.energy_count = {}
     self.set_label('(none)')
     if jsonfile is not None:
         self.read_json(jsonfile)
     self.dumpjson = dumpjson
Beispiel #28
0
    def __init__(self, rc=5.0, width=1.0):
        """TIP3P potential.

        rc: float
            Cutoff radius for Coulomb part.
        width: float
            Width for cutoff function for Coulomb part.
        """
        self.rc = rc
        self.width = width
        Calculator.__init__(self)
Beispiel #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}
    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)
Beispiel #31
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, :]]
Beispiel #32
0
    def __init__(self,
                 hirshfeld=None, vdwradii=None, calculator=None,
                 Rmax=10.,  # maximal radius for periodic calculations
                 Ldecay=1., # decay length for the smoothing in periodic calculations
                 vdWDB_alphaC6=vdWDB_alphaC6,
                 txt=None, sR=None
                ):
        """Constructor

        Parameters
        ==========
        hirshfeld: the Hirshfeld partitioning object
        calculator: the calculator to get the PBE energy
        """
        self.hirshfeld = hirshfeld
        if calculator is None:
            self.calculator = self.hirshfeld.get_calculator()
        else:
            self.calculator = calculator
            
        if txt is None:
            txt = get_logging_file_descriptor(self.calculator)
        self.txt = convert_string_to_fd(txt)

        self.vdwradii = vdwradii
        self.vdWDB_alphaC6 = vdWDB_alphaC6
        self.Rmax = Rmax
        self.Ldecay = Ldecay
        self.atoms = None

        if sR is None:
            try:
                xc_name = self.calculator.get_xc_functional()
                self.sR = sR_opt[xc_name]
            except KeyError:
                raise ValueError('Tkatchenko-Scheffler dispersion correction not implemented for %s functional' % xc_name)
        else:
            self.sR = sR
        self.d = 20

        Calculator.__init__(self)
Beispiel #33
0
    def calculate(
        self,
        atoms=None,
        properties=['energy', 'forces'],
        system_changes=all_changes,
    ):
        """Calculates the desired properties for the given AtomsBatch.

        Args:
            atoms (AtomsBatch): custom Atoms subclass that contains implementation
                of neighbor lists, batching and so on. Avoids the use of the Dataset
                to calculate using the models created.
            properties (list of str): 'energy', 'forces' or both
            system_changes (default from ase)
        """

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

        # run model
        #atomsbatch = AtomsBatch(atoms)
        # batch_to(atomsbatch.get_batch(), self.device)
        batch = batch_to(atoms.get_batch(), self.device)

        # add keys so that the readout function can calculate these properties
        batch['energy'] = []
        batch['energy_grad'] = []

        prediction = self.model(batch)

        # change energy and force to numpy array
        energy = prediction['energy'].detach().cpu(
        ).numpy() * (1 / const.EV_TO_KCAL_MOL)
        energy_grad = prediction['energy_grad'].detach(
        ).cpu().numpy() * (1 / const.EV_TO_KCAL_MOL)

        self.results = {
            'energy': energy.reshape(-1)
        }

        if 'forces' in properties:
            self.results['forces'] = -energy_grad.reshape(-1, 3)
Beispiel #34
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')
Beispiel #35
0
    def __init__(self,
                 fn=None,
                 atomic_numbers=None,
                 F=None,
                 f=None,
                 rep=None,
                 cutoff=None,
                 kind='eam/alloy'):
        Calculator.__init__(self)
        if fn is not None:
            source, parameters, F, f, rep = read_eam(fn, kind=kind)
            self._db_atomic_numbers = parameters.atomic_numbers
            self._db_cutoff = parameters.cutoff
            dr = parameters.distance_grid_spacing
            dF = parameters.density_grid_spacing

            # Create spline interpolation
            self.F = _make_splines(dF, F)
            self.f = _make_splines(dr, f)
            self.rep = _make_splines(dr, rep)
        else:
            self._db_atomic_numbers = atomic_numbers
            self.F = F
            self.f = f
            self.rep = rep
            self._db_cutoff = cutoff

        self.atnum_to_index = -np.ones(np.max(self._db_atomic_numbers) + 1,
                                       dtype=int)
        self.atnum_to_index[self._db_atomic_numbers] = \
            np.arange(len(self._db_atomic_numbers))

        # Derivative of spline interpolation
        self.dF = _make_derivative(self.F)
        self.df = _make_derivative(self.f)
        self.drep = _make_derivative(self.rep)

        # Second derivative of spline interpolation
        self.ddF = _make_derivative(self.F, n=2)
        self.ddf = _make_derivative(self.f, n=2)
        self.ddrep = _make_derivative(self.rep, n=2)
Beispiel #36
0
    def __init__(self,
                 restart=None,
                 ignore_bad_restart_file=False,
                 label='cp2k',
                 atoms=None,
                 command=None,
                 debug=False,
                 **kwargs):
        """Construct CP2K-calculator object."""

        self._debug = debug
        self._force_env_id = None
        self._shell = None
        self.label = None
        self.parameters = None
        self.results = None
        self.atoms = None

        # Several places are check to determine self.command
        if command is not None:
            self.command = command
        elif CP2K.command is not None:
            self.command = CP2K.command
        elif 'ASE_CP2K_COMMAND' in os.environ:
            self.command = os.environ['ASE_CP2K_COMMAND']
        else:
            self.command = 'cp2k_shell'  # default

        Calculator.__init__(self, restart, ignore_bad_restart_file, label,
                            atoms, **kwargs)

        self._shell = Cp2kShell(self.command, self._debug)

        if restart is not None:
            try:
                self.read(restart)
            except:
                if ignore_bad_restart_file:
                    self.reset()
                else:
                    raise
Beispiel #37
0
    def calculate(self,
                  atoms=None,
                  properties=["energy"],
                  system_changes=all_changes):
        """
        Args:
            atoms (ase.Atoms): ASE atoms object.
            properties (list of str): do not use this, no functionality
            system_changes (list of str): List of changes for ASE.
        """
        # First call original calculator to set atoms attribute
        # (see https://wiki.fysik.dtu.dk/ase/_modules/ase/calculators/calculator.html#Calculator)
        Calculator.calculate(self, atoms)

        # Convert to schnetpack input format
        model_inputs = self.atoms_converter(atoms)
        # Call model
        model_results = self.model(model_inputs)

        results = {}
        # Convert outputs to calculator format
        if self.model_energy is not None:
            if self.model_energy not in model_results.keys():
                raise SpkCalculatorError(
                    "'{}' is not a property of your model. Please "
                    "check the model "
                    "properties!".format(self.model_energy))
            energy = model_results[self.model_energy].cpu().data.numpy()
            results[self.energy] = energy.reshape(-1) * self.energy_units

        if self.model_forces is not None:
            if self.model_forces not in model_results.keys():
                raise SpkCalculatorError(
                    "'{}' is not a property of your model. Please "
                    "check the model"
                    "properties!".format(self.model_forces))
            forces = model_results[self.model_forces].cpu().data.numpy()
            results[self.forces] = forces.reshape(
                (len(atoms), 3)) * self.forces_units

        self.results = results
Beispiel #38
0
    def set(self, **kwargs):
        """Set parameters like set(key1=value1, key2=value2, ...)."""
        msg = '"%s" is not a known keyword for the CP2K calculator. ' \
              'To access all features of CP2K by means of an input ' \
              'template, consider using the "inp" keyword instead.'
        for key in kwargs:
            if key not in self.default_parameters:
                raise CalculatorSetupError(msg % key)

        changed_parameters = Calculator.set(self, **kwargs)
        if changed_parameters:
            self.reset()
 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'] = self.calc.get_potential_energy(atoms)
     if 'forces' in properties and 'forces' not in self.results:
         raw_forces = self.calc.get_forces(atoms)
         self.results['forces'] = symmetrize.forces(
             atoms.get_cell(),
             atoms.get_reciprocal_cell().T, raw_forces, self.rotations,
             self.translations, self.symm_map)
     if 'stress' in properties and 'stress' not in self.results:
         raw_stress = self.calc.get_stress(atoms)
         if len(raw_stress) == 6:  # Voigt
             raw_stress = voigt_6_to_full_3x3_stress(raw_stress)
         symmetrized_stress = symmetrize.stress(
             atoms.get_cell(),
             atoms.get_reciprocal_cell().T, raw_stress, self.rotations)
         self.results['stress'] = full_3x3_to_voigt_6_stress(
             symmetrized_stress)
Beispiel #40
0
    def __init__(self, learner_params, parent_dataset, parent_calc, base_calc,
                 trainer, n_ensembles, n_cores):
        Calculator.__init__(self)

        self.n_ensembles = n_ensembles
        self.parent_calc = parent_calc
        self.base_calc = base_calc
        self.calcs = [parent_calc, base_calc]
        self.trainer = trainer
        self.learner_params = learner_params
        self.n_cores = n_cores
        self.ensemble_sets, self.parent_dataset = bootstrap_ensemble(
            parent_dataset, n_ensembles=n_ensembles)
        self.init_training_data()
        self.ensemble_calc = make_ensemble(self.ensemble_sets, self.trainer,
                                           self.base_calc, self.refs,
                                           self.n_cores)

        self.uncertain_tol = learner_params["uncertain_tol"]
        self.parent_calls = 0
        self.init_training_data()
Beispiel #41
0
    def __init__(self,
                 model=None,
                 atoms=None,
                 to_eV=1.0,
                 properties=['energy', 'forces', 'stress']):
        """PiNN interface with ASE as a calculator

        Args:
            model: tf.Estimator object
            atoms: optional, ase Atoms object
            properties: properties to calculate.
                the properties to calculate is fixed for each calculator,
                to avoid resetting the predictor during get_* calls.
        """
        Calculator.__init__(self)
        self.implemented_properties = properties
        self.model = model
        self.pbc = False
        self.atoms = atoms
        self.predictor = None
        self.to_eV = to_eV
Beispiel #42
0
 def calculate(self,
               atoms=None,
               properties=['energy'],
               system_changes=all_changes):
     Calculator.calculate(self, atoms, properties, system_changes)
     # calculate energy-subtract
     subtract = 0
     if self.subtract:
         for a in self.atoms:
             subtract += self.single_atom_energy(a.symbol)
     # single-point calculation
     output = self._run(self.atoms)
     if output is None:
         raise RuntimeError('gaussian calculation failed!')
     self.calc = output.calc
     self.results = output.calc.results
     # set dummy stress
     if 'stress' not in self.results:
         self.results['stress'] = np.zeros(6)
     # subtract single atom energies
     self.results['energy'] -= subtract
Beispiel #43
0
    def calculate(self,
                  atoms=None,
                  properties=['energy'],
                  system_changes=all_changes):

        # Calculator essentially does: self.atoms = atoms
        Calculator.calculate(self, atoms, properties, system_changes)

        has_results = [p in self.results for p in properties]
        if (len(system_changes) > 0) or (not np.all(has_results)):
            self.update(self.atoms)
            if ('energy' in properties) and ('forces' in properties):
                # Forces evaluation requires energy. No need to compute
                # energy twice.
                del properties[properties.index('energy')]
            for p in properties:
                if p in self.implemented_properties:
                    self.implemented_properties[p](self.atoms)
                else:
                    raise NotImplementedError(
                        "Property not implemented: {}".format(p))
Beispiel #44
0
    def __init__(self, model):
        Calculator.__init__(self)

        if not os.path.exists("results/trained_models"):
            os.mkdir("results/trained_models")
        self.save_logs = model.save_logs
        label = model.label
        self.log = Logger("results/logs/" + label + ".txt")
        self.log("Filename: %s" % label)
        self.model = model
        self.label = "".join(["results/trained_models/", label, ".pt"])
        self.fp_scaling = self.model.training_data.fprange
        self.target_sd = self.model.scalings[0]
        self.target_mean = self.model.scalings[1]
        self.lj = self.model.training_data.lj
        self.Gs = self.model.training_data.Gs
        self.log("Symmetry function parameters: %s" % self.Gs)
        if self.lj:
            self.fitted_params = self.model.lj_data[3]
            self.params_dict = self.model.lj_data[4]
            self.lj_model = self.model.lj_data[5]
Beispiel #45
0
    def _toatoms(self, include_results=False):
        if not include_results:
            return ase.atoms.Atoms(
                self.numbers,
                self.positions,
                cell=self.cell,
                pbc=(self.pbc & np.array([1, 2, 4])).astype(bool),
            )
        if self.constraints:
            print(self.constraints)
            constraints = json.loads(self.constraints)
            print(constraints)
            if len(constraints[0]['kwargs']['indices']) > 0:
                constraints = [dict2constraint(d) for d in constraints]
        else:
            constraints = None
        atoms = ase.atoms.Atoms(self.numbers,
                                self.positions,
                                cell=self.cell,
                                pbc=(self.pbc
                                     & np.array([1, 2, 4])).astype(bool),
                                magmoms=self.initial_magmoms,
                                charges=self.initial_charges,
                                tags=self.tags,
                                masses=self.masses,
                                momenta=self.momenta,
                                constraint=constraints)
        atoms.info = {}
        atoms.info['unique_id'] = self.unique_id
        atoms.info['key_value_pairs'] = self.key_value_pairs

        data = self.data
        if data:
            atoms.info['data'] = data

        if not self.calculator == "unknown":
            params = self.calculator_parameters
            atoms.calc = Calculator(self.calculator, **params)
            atoms.calc.name = self.calculator
        else:
            all_properties = [
                'energy', 'forces', 'stress', 'dipole', 'charges', 'magmom',
                'magmoms', 'free_energy'
            ]
            results = {}
            for prop in all_properties:
                result = getattr(self, prop, None)
                if result is not None:
                    results[prop] = result
            if results:
                atoms.calc = SinglePointCalculator(atoms, **results)
                atoms.calc.name = getattr(self, 'calculator', 'unknown')
        return atoms
Beispiel #46
0
 def __init__(self,
              lmp,
              lmpcmds=None,
              path='tmp',
              lmp_file=None,
              ntyp=None,
              *args,
              **kwargs):
     Calculator.__init__(self, *args, **kwargs)
     self.lmp = lmp
     self.lmp_file = lmp_file
     self.folder = path
     self.ntyp = ntyp
     if not os.path.exists(self.folder):
         os.makedirs(self.folder)
     self.lammps_data = self.folder + '/data.lammps'
     self.lammps_in = self.folder + '/in.lammps'
     self.lmpcmds = lmpcmds
     self.paras = []
     for para in lmpcmds:
         self.paras.append(para)
Beispiel #47
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.logfile.write('retrieved results for {0} from checkpoint\n'
                               .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.logfile.write('doing calculation of {0} with new-style '
                                   'calculator interface\n'.format(properties))
                self.calculator.calculate(atoms, properties, system_changes)
                results = [self.calculator.results[prop]
                           for prop in properties]
            else:
                self.logfile.write('doing calculation of {0} with old-style '
                                   'calculator interface\n'.format(properties))
                results = []
                for prop in properties:
                    method_name = self.property_to_method_name[prop]
                    method = getattr(self.calculator, method_name)
                    results.append(method(atoms))
            _calculator = atoms.calc
            try:
                atoms.calc = self.calculator
                self.checkpoint.save(atoms, *results)
            finally:
                atoms.calc = _calculator

        self.results = dict(zip(properties, results))
Beispiel #48
0
def test_calculator_label():
    from ase.calculators.calculator import Calculator

    calc = Calculator()
    assert calc.directory == '.'
    assert calc.prefix is None
    assert calc.label is None

    calc.label = 'dir/pref'
    assert calc.directory == 'dir'
    assert calc.prefix == 'pref'
    assert calc.label == 'dir/pref'

    calc.label = 'dir2/'
    assert calc.directory == 'dir2'
    assert calc.prefix is None
    assert calc.label == 'dir2/'

    calc.label = 'hello'
    assert calc.directory == '.'
    assert calc.prefix == 'hello'
    assert calc.label == 'hello'

    calc.label = None
    assert calc.label is None
    assert calc.prefix is None
    assert calc.directory == '.'
Beispiel #49
0
    def __init__(self, restart=None, ignore_bad_restart_file=False,
                 label='pmd', atoms=None, 
                 command='pmd > out.pmd',
                 dimension=(True,True,True),
                 specorder=None, **kwargs):
        """Construct PMD-calculator object.

        Parameters
        ==========
        label: str
            Prefix to use for filenames (in.label, erg.label, ...).
            Default is 'pmd'.

        Examples
        ========
        Use default values:

        >>> h = Atoms('H', calculator=PMD(label='pmd',force_type='NN'))
        >>> e = h.get_potential_energy()

        """

        Calculator.__init__(self, restart, ignore_bad_restart_file,
                            label, atoms, **kwargs)

        if label not in ['pmd']:
            raise RuntimeError('label must be pmd.')

        if self.parameters['force_type'] is None:
            raise RuntimeError('force_type must be specified.')

        if command is None:
            self.command = self.label+' > out.'+self.label
        elif '>' in command:
            self.command = command.split('>')[0] +' > out.'+self.label
        else:
            self.command = command +' > out.'+self.label

        self.specorder= specorder
        self.dimension = dimension
Beispiel #50
0
    def __init__(self, restart=None, ignore_bad_restart_file=False,
                 label=os.curdir, atoms=None, **kwargs):

        # set any additional keyword arguments
        # for arg, val in self.parameters.iteritems():
        for arg, val in kwargs.items():
            if arg in self.valid_args:
                # satisfy our static 8-char requirement in fortran
                if (arg == ('sedc_scheme' or 'sedc_xc')):
                    setattr(self, arg, str(val).ljust(8))
                elif (arg == 'logfile_name'):
                    setattr(self, arg, str(val).ljust(50))
                else:
                    setattr(self, arg, val)
            else:
                raise RuntimeError('unknown keyword arg "%s" : not in %s'
                                   % (arg, self.valid_args))

        self.hirshvolrat_is_set = False

        Calculator.__init__(self, restart, ignore_bad_restart_file,
                            label, atoms, **kwargs)
Beispiel #51
0
    def calculate(self,
                  atoms=None,
                  properties=['energy', 'forces'],
                  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(verbose=0)
        self.results['forces'] = -1 * grad.RHF(self.mf).kernel(
        )  # convert forces to gradient (*-1) !!!!! for the NEB run
        self.results['mf'] = self.mf
Beispiel #52
0
    def __setattr__(self, key, value):
        """Catch attribute sets to emulate legacy behavior.

        Old LAMMPSRUN allows to just override the parameters
        dictionary. "Modern" ase calculators can assume that default
        parameters are always set, overrides of the
        'parameters'-dictionary have to be caught and the default
        parameters need to be added first.  A check refuses to set
        calculator attributes if they are unknown and set outside the
        '__init__' functions.
        """
        # !TODO: remove and break somebody's code (e.g. the test examples)
        if (key == "parameters" and value is not None
                and self.parameters is not None):
            temp_dict = self.get_default_parameters()
            if self.parameters:
                for l_key in self.legacy_parameters:
                    try:
                        temp_dict[l_key] = self.parameters[l_key]
                    except KeyError:
                        pass
            temp_dict.update(value)
            value = temp_dict
        if key in self.legacy_parameters and key != "parameters":
            warnings.warn(self.legacy_warn_string.format(key))
            self.set(**{key: value})
        elif key in self.legacy_parameters_map:
            warnings.warn(
                self.legacy_warn_string.format("{} for {}".format(
                    self.legacy_parameters_map[key], key)))
            self.set(**{self.legacy_parameters_map[key]: value})
        # Catch setting none-default attributes
        # one test was assigning an useless Attribute, but it still worked
        # because the assigned object was before manipulation already handed
        # over to the calculator (10/2018)
        elif hasattr(self, key) or inspect.stack()[1][3] == "__init__":
            Calculator.__setattr__(self, key, value)
        else:
            raise AttributeError("Setting unknown Attribute '{}'".format(key))
Beispiel #53
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
     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)
             F = preF * expf * (expf - 1) * diff / r
             forces[i1] -= F
             forces[i2] += F
     self.results['energy'] = energy
     self.results['forces'] = forces
    def calculate(self,
                  atoms=None,
                  properties=["energy"],
                  system_changes=all_changes):
        r"""
        This method will be called by ASE functions.
        """
        if self.calculation_required(atoms, properties):
            from mlcalcdriver.base.posinp import Posinp

            Calculator.calculate(self, atoms)
            posinp = Posinp.from_ase(atoms)

            from mlcalcdriver.base.job import Job

            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
Beispiel #55
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
Beispiel #56
0
    def calculate(self,
                  atoms=None,
                  properties=['energy'],
                  system_changes=changes):
        Calculator.calculate(self, atoms, properties, system_changes)
        self.write_input(self.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:
            syscall = self.command + ' ' + \
                    self.parameters['INPUT_FILE'] + '> OUT '
            errorcode = subprocess.call(syscall, shell=True)
        finally:
            os.chdir(olddir)

        if errorcode:
            raise RuntimeError('%s returned an error: %d' %
                               (self.name, errorcode))
        self.read_results()
Beispiel #57
0
    def calculate(self,
                  atoms=None,
                  properties=['energy'],
                  system_changes=[
                      'positions', 'numbers', 'cell', 'pbc', 'charges',
                      'magmoms'
                  ]):
        Calculator.calculate(self, atoms, properties, system_changes)

        D = self.parameters.D
        alpha = self.parameters.alpha
        r0 = self.parameters.r0

        # energy evaluation
        dist = self.atoms.get_all_distances(mic=True).reshape(
            -1
        )  # calculates all interatomic distances of the system using the minimum image convention
        dist = dist[
            dist !=
            0]  # excludes self-interaction (list of interatomic distances includes distance of atom to itself)
        expf = np.exp(
            alpha * r0 *
            (1.0 - dist / r0))  # calculation of exponential factor of morse
        energy = 0.5 * np.sum(
            D * expf * (expf - 2)
        )  # evaluates Morse term for all distances and sums over the resulting energies, 0.5 is needed to account fo

        # force evaluation
        preF = 2 * D * alpha
        dist_vec = self.atoms.get_all_distances(mic=True, vector=True)
        dist = self.atoms.get_all_distances(mic=True)
        dist[dist == 0] = 1e-9
        expf = np.exp(alpha * r0 * (1.0 - dist / r0))
        F2 = preF * expf * (expf - 1) / dist
        F2 = -dist_vec * F2[:, :, np.newaxis]
        forces = np.sum(F2, axis=1)

        self.results['energy'] = energy
        self.results['forces'] = forces
Beispiel #58
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()
        }
Beispiel #59
0
 def calculate(self,
               atoms=None,
               properties=['energy'],
               system_changes=all_changes):
     Calculator.calculate(self, atoms, properties, system_changes)
     if self.atoms.is_distributed:
         raise NotImplementedError(
             'variance is not implemented for distributed atoms')
     self.atoms.update()
     energy, energy_var = self.potential([self.atoms],
                                         'energy',
                                         variance=True)
     forces, forces_var = self.potential([self.atoms],
                                         'forces',
                                         variance=True)
     self.results['energy'] = energy.detach().numpy()[0]
     self.results['forces'] = forces.detach().numpy()
     # variances
     self.results['energy_var'] = energy_var.detach().numpy()[0]
     self.results['forces_var'] = forces_var.detach().numpy()
     # NOTE: check if this is correct!
     self.results['free_energy'] = self.results['energy']
Beispiel #60
0
    def __init__(self, restart=None, ignore_bad_restart_file=False,
                 label='PySCF', atoms=None, scratch=None, **kwargs):
        """Construct PySCF-calculator object.

        Parameters
        ==========
        label: str
            Prefix to use for filenames (label.in, label.txt, ...).
            Default is 'PySCF'.

        mfclass: PySCF mean-field class
        molcell: PySCF :Mole: or :Cell:
        """
        Calculator.__init__(self, restart=None, ignore_bad_restart_file=False,
                            label='PySCF', atoms=None, scratch=None, **kwargs)

        # TODO
        # This explicitly refers to "cell". How to refer
        # to both cell and mol together?

        self.mf=None
        self.initialize(**kwargs)