def calculate(self, atoms=None, properties=['energy'], system_changes=all_changes): bad = [ change for change in system_changes if change not in self.supported_changes ] # First time calculate() is called, system_changes will be # all_changes. After that, only positions and cell may change. if self.atoms is not None and any(bad): raise PropertyNotImplementedError( 'Cannot change {} through IPI protocol. ' 'Please create new socket calculator.'.format( bad if len(bad) > 1 else bad[0])) self.atoms = atoms.copy() if self.server is None: self.server = self.launch_server() proc = self.launch_client(atoms, properties, port=self._port, unixsocket=self._unixsocket) self.server.proc = proc # XXX nasty hack results = self.server.calculate(atoms) results['free_energy'] = results['energy'] virial = results.pop('virial') if self.atoms.cell.rank == 3 and any(self.atoms.pbc): vol = atoms.get_volume() results['stress'] = -full_3x3_to_voigt_6_stress(virial) / vol self.results.update(results)
def calculate(self, atoms=None, properties=['energy'], system_changes=all_changes): bad = [ change for change in system_changes if change not in self.supported_changes ] if self.calculator_initialized and any(bad): raise PropertyNotImplementedError( 'Cannot change {} through IPI protocol. ' 'Please create new socket calculator.'.format( bad if len(bad) > 1 else bad[0])) self.calculator_initialized = True if self.server is None: assert self.calc is not None cmd = self.calc.command.replace('PREFIX', self.calc.prefix) self.calc.write_input(atoms, properties=properties, system_changes=system_changes) self.launch_server(cmd) self.atoms = atoms.copy() results = self.server.calculate(atoms) virial = results.pop('virial') if self.atoms.number_of_lattice_vectors == 3 and any(self.atoms.pbc): from ase.constraints import full_3x3_to_voigt_6_stress vol = atoms.get_volume() results['stress'] = -full_3x3_to_voigt_6_stress(virial) / vol self.results.update(results)
def calculate(self, atoms = None, properties = ['energy', 'forces', 'stress'], system_changes = all_changes ): """ Calculates all the specific property for each calculator and returns with the summed value. """ super().calculate(atoms, properties, system_changes) if not set(properties).issubset(self.implemented_properties): raise PropertyNotImplementedError('Some of the requested property is not \ in the ''list of supported properties \ ({})'.format(self.implemented_properties)) for w, calc in zip(self.weights, self.calcs): if calc.calculation_required(atoms, properties): calc.calculate(atoms, properties, system_changes) for k in properties: if k not in self.results: self.results[k] = w * calc.results[k] else: self.results[k] += w * calc.results[k]
def __init__(self, calcs, weights, atoms=None): """Implementation of sum of calculators. calcs: list List of an arbitrary number of :mod:`ase.calculators` objects. weights: list of float Weights for each calculator in the list. atoms: Atoms object Optional :class:`~ase.Atoms` object to which the calculator will be attached. """ super().__init__(atoms=atoms) if len(calcs) == 0: raise ValueError('The value of the calcs must be a list of Calculators') for calc in calcs: if not isinstance(calc, Calculator): raise ValueError('All the calculators should be inherited form the ase\'s Calculator class') common_properties = set.intersection(*(set(calc.implemented_properties) for calc in calcs)) self.implemented_properties = list(common_properties) if not self.implemented_properties: raise PropertyNotImplementedError('There are no common property implemented for the potentials!') if len(weights) != len(calcs): raise ValueError('The length of the weights must be the same as the number of calculators!') self.calcs = calcs self.weights = weights
def get_property(self, name, atoms=None, allow_calculation=True): if name not in self.results or self.check_state(atoms): if allow_calculation: raise PropertyNotImplementedError( 'The property "{0}" is not available.'.format(name)) return None result = self.results[name] if isinstance(result, np.ndarray): result = result.copy() return result
def get_hirsh_volrat(self): """ Return rescaling ratios for atomic polarizabilities (CPA ratios) """ if hasattr(self, 'CPA_ratios'): return self.CPA_ratios else: msg = "Could not obtain CPA ratios. You need to specify the " msg += "MBD or TS dispersion model and set " msg += "Options_WriteCPA = 'Yes'" raise PropertyNotImplementedError(msg)
def get_property(self, name, atoms=None, allow_calculation=True): if name not in self.implemented_properties: raise PropertyNotImplementedError(f"{name} property not implemented") self.update(atoms) if name not in self.results: if not allow_calculation: return None self.calculate(atoms=atoms) if name not in self.results: # For some reason the calculator was not able to do what we want, # and that is OK. raise PropertyNotImplementedError( f"{name} property not present in results!" ) result = self.results[name] if isinstance(result, np.ndarray): result = result.copy() return result
def __init__(self, calcs, weights = None, atoms = None): """Implementation of sum of calculators. calcs: list List of an arbitrary number of :mod:`ase.calculators` objects. weights: list of float Weights for each calculator in the list. atoms: Atoms object Optional :class:`~ase.Atoms` object to which the calculator will be attached. """ super().__init__(atoms = atoms) if len(calcs) == 0: raise ValueError('The value of the calcs must be a list of Calculators') for calc in calcs: if not isinstance(calc, Calculator): raise ValueError('All the calculators should be inherited form the \ ase\'s Calculator class') common_properties = set.intersection(*(set(calc.implemented_properties) for calc in calcs)) self.implemented_properties = list(common_properties) if not self.implemented_properties: raise PropertyNotImplementedError('There are no common property \ implemented for the potentials!') self.calcs = calcs ''' if weights is not None: self.weights = weights.copy() ''' weights = np.ones(len(calcs)).tolist() pi_fmax = 1.0 for i in range(len(calcs)): forces_i = calcs[i].get_property('forces', atoms) pi_fmax = pi_fmax*np.amax(np.absolute(forces_i)) for j in range(len(weights)): forces_j = calcs[j].get_property('forces', atoms) weights[j] = pi_fmax / np.amax(np.absolute(forces_j)) if len(weights) != len(calcs): raise ValueError('The length of the weights must be the same as \ the number of calculators!') # self.calcs = calcs self.weights = weights
def get_property(self, name, atoms=None, allow_calculation=True): if name not in self.implemented_properties: raise PropertyNotImplementedError( "{} property not implemented".format(name)) if atoms is None: atoms = self.atoms system_changes = [] else: self.calcs[0].system_changes = self.calcs[0].check_state(atoms) if self.calcs[0].system_changes: self.calcs[0].reset() self.calcs[1].system_changes = self.calcs[1].check_state(atoms) if self.calcs[1].system_changes: self.calcs[1].reset() result = super().get_property(name, atoms=atoms, allow_calculation=allow_calculation) for calc in self.calcs: if hasattr(calc, "system_changes"): calc.system_changes = None return result
def calculate(self, atoms=None, properties=['energy'], system_changes=all_changes): bad = [change for change in system_changes if change not in self.supported_changes] if self.calculator_initialized and any(bad): raise PropertyNotImplementedError( 'Cannot change {} through IPI protocol. ' 'Please create new socket calculator.' .format(bad if len(bad) > 1 else bad[0])) self.calculator_initialized = True if self.server is None: #if 'vc' in self.calculation: # self.cell_factor = 10 #self.calculation = 'scf' self.cell_dynamics = 'ipi' self.ion_dynamics = 'ipi' self.dontcalcforces = False self.write_input(atoms, properties=properties, system_changes=system_changes) if self._socket_type=='UNIX' or ((not self._unixsocket and not self._port) and self._socket_type!='INET'): self._socket_type = 'UNIX' if not self._unixsocket: self._unixsocket = self.scratch.split('/')[-1] socket_string = ' --ipi {0}:UNIX >> {1}'.format(self._unixsocket,self.log) elif self._socket_type=='INET' or (not self._unixsocket and self._port): self._socket_type = 'INET' port = SocketServer.default_port SocketServer.default_port += 1 while socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect_ex(('localhost', port)) == 0: port += 1 self._port = port if re.match('^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$', self.ionode_address): self._ip = self.ionode_address elif self.ionode_address in self.site.nic_inet_ips.keys(): self._ip = self.site.nic_inet_ips[self.ionode_address] else: raise Exception('Not a valida IPV4 address or NIC interface: {}'.format(self.ionode_address)) socket_string = ' --ipi {0}:{1} >> {2}'.format(self._ip,self._port,self.log) else: raise Exception('Socket type: {} not implemented.'.format(self._socket_type)) if self.socket_log: print(self._socket_type,file=self.socket_log) cmd = ' '.join(self.command) + socket_string self.launch_server(cmd) results = self.server.calculate(atoms,properties) if 'virial' in results.keys(): if self.atoms.number_of_lattice_vectors == 3 and any(self.atoms.pbc): from ase.constraints import full_3x3_to_voigt_6_stress vol = atoms.get_volume() results['stress'] = -full_3x3_to_voigt_6_stress(results['virial']) / vol else: raise Exception('Stress calculation: cell and periodic boundary conditions must be defined.') self.results.update(results)
def check_version(): if LooseVersion(self.version) < '3.8': raise PropertyNotImplementedError( 'Version lower than 3.8 does not support stress ' 'calculation. Your version is %s' % self.version)
def get_property(self, name, atoms=None, allow_calculation=True): """Returns the value of a property""" if name not in Vasp.implemented_properties: raise PropertyNotImplementedError('Error :: ' + name + ' property not implemented') if atoms is None: atoms = self.atoms saved_property = { 'energy': 'energy_zero', 'forces': 'forces', 'dipole': 'dipole', 'fermi': 'fermi', 'stress': 'stress', 'magmom': 'magnetic_moment', 'magmoms': 'magnetic_moments' } property_getter = { 'energy': { 'function': 'get_potential_energy', 'args': [atoms] }, 'forces': { 'function': 'get_forces', 'args': [atoms] }, 'dipole': { 'function': 'get_dipole_moment', 'args': [atoms] }, 'fermi': { 'function': 'get_fermi_level', 'args': [] }, 'stress': { 'function': 'get_stress', 'args': [atoms] }, 'magmom': { 'function': 'get_magnetic_moment', 'args': [atoms] }, 'magmoms': { 'function': 'get_magnetic_moments', 'args': [atoms] } } if allow_calculation: function = property_getter[name]['function'] args = property_getter[name]['args'] result = getattr(self, function)(*args) else: if hasattr(self, saved_property[name]): result = getattr(self, saved_property[name]) else: result = None if isinstance(result, np.ndarray): result = result.copy() return result