def minimize(self, cluster: Cluster, *args, **kwargs) -> Cluster: """ Method to locally minimise a cluster of Lennard-Jones particles. Uses the L-BFGS-B method implemented within scipy.minimize. Attributes: coordinates: np.array(shape=(number_of_particles, 3), dtype=float) array of coordinates kwargs: Dict containing any other keyword arguments to be passed to the scipy optimizer molecules: list(int), optional, Returns ------- result_dict{'coordinates': optimised structure coordinates, 'energy': final energy of the cluster, 'success': True if successfully minimised} """ positions = list(cluster.get_particle_positions()) coordinates = positions[0].flatten() # args = {"sigma": self.sigma, "epsilon": self.epsilon4, "base_exp": 6} result = scipy.optimize.minimize( fun=self.get_energy, x0=coordinates, # , args=args, method='L-BFGS-B', jac=self.get_jacobian) positions = (result.x.reshape( (self.n_atoms, 3)), positions[1], positions[2]) cluster.set_particle_positions(positions) cluster.cost = result.fun return cluster
def minimize(self, cluster: Cluster, *args, **kwargs) -> Cluster: """ Method to locally minimise a cluster of Lennard-Jones particles. Uses the L-BFGS-B method implemented within scipy.minimize. Args: cluster: Cluster instance, required, cluster instance to be minimized kwargs: Dict containing any other keyword arguments to be passed to the scipy optimizer Returns: result_dict{'coordinates': optimised structure coordinates, 'energy': final energy of the cluster, 'success': True if successfully minimised} """ coords, ids, labels = cluster.get_particle_positions() coordinates = coords result = minimize(fun=self.get_energy, x0=coordinates.flatten(), method='L-BFGS-B', jac=self.get_jacobian, *args, **kwargs) if not result.success: print("Optimization failed") cluster.set_particle_positions( (result.x.reshape(coordinates.shape), ids, labels)) cluster.cost = result.fun return cluster
def get_energy(self, cluster: Cluster, *args, **kwargs) -> Cluster: """Provides the interface between the client and the minimise method of the Args: cluster: Cluster object, required, the Cluster to be minimised Returns: """ self.log.debug("Getting energy for cluster: {}".format(cluster)) # noinspection PyUnresolvedReferences result = self.potential.get_energy(cluster) cluster.cost = result return cluster
pot = LJcPotential(6) MC = MonteCarlo(potential=pot, temperature=0.1, update_steps=101, move_classes=[RandomSingleTranslation()]) c1 = Cluster(molecules=[ Molecule(coordinates=np.array([[0.0, 0.0, 0.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[1.0, 1.0, 1.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[1.0, -1.0, 1.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[-1.0, 1.0, 1.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[-1.0, -1.0, 1.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[-2.0, -2.0, 2.0]]), particle_names=["LJ"]) ], cost=0.0) c1 = pot.minimize(cluster=c1) c1.cost = pot.get_energy(c1) print(c1.cost) print(MC.move_classes[0].random) c1 = MC.run(cluster=c1, n_steps=10001) print(c1.cost)
def run_DeMonNano( self, cluster: Cluster, dir_name: str, optimize: bool = False): # TODO move minimize and energy to here """Common interface to DeMonNano""" if dir_name is not None: dir_name = os.path.abspath(dir_name) else: dir_name = os.path.abspath(self.get_directory()) inp_fname = dir_name + "/deMon.inp" out_fname = dir_name + "/deMon.out" shutil.copyfile("SCC-SLAKO", dir_name + "/SCC-SLAKO") shutil.copyfile("SLAKO", dir_name + "/SLAKO") coords, molecule_ids, atom_labels = cluster.get_particle_positions() Natoms = len(molecule_ids) xyz_formatted_coordinates = self.format_XYZ(coords, atom_labels) with work_dir(): os.chdir(dir_name) # Change into the scratch dir. tag_dict = {"<XYZ>": xyz_formatted_coordinates} if optimize: template = self.minimize_template else: template = self.energy_template self.insert_to_template(template=self.work_dir + template, out_file=inp_fname, target_dict=tag_dict) with open("error_file", "w") as ef: # self.run_string should just be the location of the deMonNano executable dftb_process = subprocess.Popen([self.run_string], cwd=dir_name, shell=True, stderr=ef, stdout=ef) exit_code = dftb_process.wait() # check exit code if exit_code != 0: try: raise DFTBError( f"DFTB+ exited unexpectedly with exitcode: {exit_code}\n" ) except DFTBError as error: self.log.exception(error) raise else: self.log.debug( f"DFTB+ exited successfully. Exit code: {exit_code}") if optimize: # noinspection PyTypeChecker parser = DeMonNanoParser(out_fname, natoms=Natoms, logger=self.log) result_dict = parser.parse_DeMonNano_output() new_coords = result_dict["coordinates"] cluster.set_particle_positions( (new_coords, molecule_ids, atom_labels)) else: # noinspection PyTypeChecker parser = DeMonNanoParser(out_fname, natoms=Natoms, geometry_opt=False, logger=self.log) result_dict = parser.parse_DeMonNano_output() energy = result_dict["energy"] cluster.cost = energy # os.chdir("..") # Come back out of the scratch dir. return cluster