def move_random(self, entry_id, factor=0.2, in_place=False, kind='move'): """ Change the magnetic orientation randomly for all the atoms considered magnetic 'mag_atoms' The 'factor' argument scales the intensite of the movement. :param entry_id: :param factor: :param in_place: :param kind: :return: """ entry = self.get_entry(entry_id, {'properties.magmom': 1}) # Magnetic Momenta are stored in spherical coordinates magmom_i = spherical_to_cartesian(entry['properties']['magmom']) # Converted into cartesians magmom_xyz = spherical_to_cartesian(magmom_i) # Randomly disturbed using the factor magmom_xyz += factor * np.random.random((self.structure.natom, 3)) - factor / 2 # Reconverting to spherical coordinates magmom_new = cartesian_to_spherical(magmom_xyz) # Resetting magnitudes for i in range(len(magmom_i)): if magmom_i[i][0] > 0.0: magmom_new[i, 0] = self.magmom_magnitude else: magmom_new[i, 0] = 0.0 properties = {'magmom': list(magmom_new.flatten()), 'energy': self.debug_evaluation(magmom_new)} if in_place: return self.update_properties(entry_id, new_properties=properties) else: return self.new_entry(magmom_new, active=False)
def move(self, entry_id, entry_jd, factor=0.2, in_place=False): #FAKE FACTOR # factor=1.0 magmom_new_xyz = np.zeros((self.structure.natom, 3)) entry = self.get_entry(entry_id, {'properties.magmom': 1}) magmom_i = np.array(entry['properties']['magmom']).reshape((-1, 3)) magmom_ixyz = spherical_to_cartesian(magmom_i) entry = self.get_entry(entry_jd, {'properties.magmom': 1}) magmom_j = np.array(entry['properties']['magmom']).reshape((-1, 3)) magmom_jxyz = spherical_to_cartesian(magmom_j) # print('Rotating %s towards %s with factor %f' % (entry_id, entry_jd, factor)) # print('Origin:\n %s ' % magmom_i[self.mag_atoms]) # print('Destin:\n %s ' % magmom_j[self.mag_atoms]) for i in self.mag_atoms: #print('Atom %d' % i) if magmom_i[i][0] > 0 and magmom_j[i][0] > 0: magmom_new_xyz[i] = rotate_towards_axis(magmom_ixyz[i], magmom_jxyz[i], fraction=factor) #print('Final magmom Cartesian : %d %s' % (i,magmom_new_xyz[i])) magmom_new = cartesian_to_spherical(magmom_new_xyz) # print('Final spherical:\n %s' % magmom_new[self.mag_atoms]) magmom_new[:, 0] = self.magmom_magnitude properties = {'magmom': list(magmom_new.flatten()), 'energy': self.fake_evaluation(magmom_new)} if in_place: self.update_properties(entry_id, new_properties=properties) return entry_id else: return self.new_entry(magmom_new, active=False)
def distance(self, entry_id, entry_jd): entry = self.get_entry(entry_id, {'properties.magmom': 1}) magmom_i = spherical_to_cartesian(entry['properties']['magmom']) entry = self.get_entry(entry_id, {'properties.magmom': 1}) magmom_j = spherical_to_cartesian(entry['properties']['magmom']) magmom_ixyz = spherical_to_cartesian(magmom_i) magmom_jxyz = spherical_to_cartesian(magmom_j) distance = np.sum(angle_between_vectors(magmom_ixyz, magmom_jxyz)) distance /= len(self.mag_atoms) return distance
def distance(self, entry_id, entry_jd): entry = self.get_entry(entry_id, {'properties.magmom': 1}) magmom_i = np.array(entry['properties']['magmom']).reshape((-1,3)) entry = self.get_entry(entry_jd, {'properties.magmom': 1}) magmom_j = np.array(entry['properties']['magmom']).reshape((-1,3)) #print(entry_id) #print(magmom_i[self.mag_atoms]) #print(entry_jd) #print(magmom_j[self.mag_atoms]) magmom_ixyz = spherical_to_cartesian(magmom_i) magmom_jxyz = spherical_to_cartesian(magmom_j) distance = np.sum(angle_between_vectors(magmom_ixyz, magmom_jxyz)) distance /= len(self.mag_atoms) return distance
def move_random(self, entry_id, factor=0.2, in_place=False, kind='move'): """ Change the magnetic orientation randomly for all the atoms considered magnetic 'mag_atoms' The 'factor' argument scales the intensite of the movement. :param entry_id: :param factor: :param in_place: :param kind: :return: """ entry = self.get_entry(entry_id, {'properties.magmom': 1}) # Magnetic Momenta are stored in spherical coordinates magmom_xyz = spherical_to_cartesian(entry['properties']['magmom']) # Randomly disturbed using the factor magmom_xyz += factor * np.random.random( (self.structure.natom, 3)) - factor / 2 # Reconverting to spherical coordinates magmom_new = cartesian_to_spherical(magmom_xyz) # Resetting magnitudes for i in range(len(magmom_xyz)): if magmom_xyz[i][0] > 0.0: magmom_new[i, 0] = self.magmom_magnitude else: magmom_new[i, 0] = 0.0 properties = { 'magmom': list(magmom_new.flatten()), 'energy': self.debug_evaluation(magmom_new) } if in_place: return self.update_properties(entry_id, new_properties=properties) else: return self.new_entry(magmom_new, active=False)
def distance(self, entry_id, entry_jd): entry = self.get_entry(entry_id, {'properties.magmom': 1}) magmom_i = np.array(entry['properties']['magmom']).reshape((-1, 3)) entry = self.get_entry(entry_jd, {'properties.magmom': 1}) magmom_j = np.array(entry['properties']['magmom']).reshape((-1, 3)) #print(entry_id) #print(magmom_i[self.mag_atoms]) #print(entry_jd) #print(magmom_j[self.mag_atoms]) magmom_ixyz = spherical_to_cartesian(magmom_i) magmom_jxyz = spherical_to_cartesian(magmom_j) distance = np.sum(angle_between_vectors(magmom_ixyz, magmom_jxyz)) distance /= len(self.mag_atoms) return distance
def fake_evaluation(self, magmom_sph): magmom_car=spherical_to_cartesian(magmom_sph) good_magmom = np.zeros((self.structure.natom, 3)) good_magmom[0]=[ 1.15470054, 1.15470054, 1.15470054] good_magmom[1]=[ -1.15470054, -1.15470054, -1.15470054] distance = np.sum(angle_between_vectors(magmom_car, good_magmom)) distance /= len(self.mag_atoms) return distance-np.pi
def fake_evaluation(self, magmom_sph): magmom_car = spherical_to_cartesian(magmom_sph) good_magmom = np.zeros((self.structure.natom, 3)) good_magmom[0] = [1.15470054, 1.15470054, 1.15470054] good_magmom[1] = [-1.15470054, -1.15470054, -1.15470054] distance = np.sum(angle_between_vectors(magmom_car, good_magmom)) distance /= len(self.mag_atoms) return distance - np.pi
def move_random(self, entry_id, factor=0.2, in_place=False, kind='move'): entry = self.get_entry(entry_id, {'properties.magmom': 1}) # Magnetic Momenta are stored in spherical coordinates magmom_i = spherical_to_cartesian(entry['properties']['magmom']) # Converted into cartesians magmom_xyz = spherical_to_cartesian(magmom_i) # Randomly disturbed using the factor magmom_xyz += factor * np.random.rand((self.structure.natom, 3)) - factor / 2 # Reconverting to spherical coordinates magmom_new = cartesian_to_spherical(magmom_xyz) # Resetting magnitudes magmom_new[:, 0] = self.magmom_magnitude properties = {'magmom': magmom_new} if in_place: return self.update_properties(entry_id, new_properties=properties) else: return self.new_entry(magmom_new, active=False)
def distance(self, entry_id, entry_jd): """ Compute the distance between 2 candidates as the average angular movement between the magnetic moments for all the atoms considered magnetic ('mag_atoms') :param entry_id: :param entry_jd: :return: """ entry = self.get_entry(entry_id, {'properties.magmom': 1}) magmom_i = np.array(entry['properties']['magmom']).reshape((-1, 3)) entry = self.get_entry(entry_jd, {'properties.magmom': 1}) magmom_j = np.array(entry['properties']['magmom']).reshape((-1, 3)) magmom_ixyz = spherical_to_cartesian(magmom_i) magmom_jxyz = spherical_to_cartesian(magmom_j) distance = np.sum(angle_between_vectors(magmom_ixyz, magmom_jxyz)) distance /= len(self.mag_atoms) return distance
def distance(self, entry_id, entry_jd): """ Compute the distance between 2 candidates as the average angular movement between the magnetic moments for all the atoms considered magnetic ('mag_atoms') :param entry_id: :param entry_jd: :return: """ entry = self.get_entry(entry_id, {'properties.magmom': 1}) magmom_i = np.array(entry['properties']['magmom']).reshape((-1, 3)) entry = self.get_entry(entry_jd, {'properties.magmom': 1}) magmom_j = np.array(entry['properties']['magmom']).reshape((-1, 3)) magmom_ixyz = spherical_to_cartesian(magmom_i) magmom_jxyz = spherical_to_cartesian(magmom_j) distance = np.sum(angle_between_vectors(magmom_ixyz, magmom_jxyz)) distance /= len(self.mag_atoms) return distance
def move(self, entry_id, entry_jd, factor=0.2, in_place=False): """ Move the magnetic moments from one candidate in the direction of another. :param entry_id: Source candidate, this one will be moved :param entry_jd: Destination candidate, this one is not moved. :param factor: (float) a value in range [0,1] 0 being the source, 1 the destination :param in_place: (bool) if true the new magnetic moments replace those in entry_id :return: """ magmom_new_xyz = np.zeros((self.structure.natom, 3)) entry = self.get_entry(entry_id, {'properties.magmom': 1}) magmom_i = np.array(entry['properties']['magmom']).reshape((-1, 3)) magmom_ixyz = spherical_to_cartesian(magmom_i) entry = self.get_entry(entry_jd, {'properties.magmom': 1}) magmom_j = np.array(entry['properties']['magmom']).reshape((-1, 3)) magmom_jxyz = spherical_to_cartesian(magmom_j) for i in self.mag_atoms: # print('Atom %d' % i) if magmom_i[i][0] > 0 and magmom_j[i][0] > 0: magmom_new_xyz[i] = rotate_towards_axis(magmom_ixyz[i], magmom_jxyz[i], fraction=factor) # print('Final magmom Cartesian : %d %s' % (i,magmom_new_xyz[i])) magmom_new = cartesian_to_spherical(magmom_new_xyz) magmom_new[:, 0] = self.magmom_magnitude for i in range(self.structure.natom): if i not in self.mag_atoms: magmom_new[i, :] = 0.0 properties = { 'magmom': list(magmom_new.flatten()), 'energy': self.debug_evaluation(magmom_new) } if in_place: self.update_properties(entry_id, new_properties=properties) return entry_id else: return self.new_entry(magmom_new, active=False)
def move(self, entry_id, entry_jd, factor=0.2, in_place=False): """ Move the magnetic moments from one candidate in the direction of another. :param entry_id: :param entry_jd: :param factor: :param in_place: :return: """ magmom_new_xyz = np.zeros((self.structure.natom, 3)) entry = self.get_entry(entry_id, {'properties.magmom': 1}) magmom_i = np.array(entry['properties']['magmom']).reshape((-1, 3)) magmom_ixyz = spherical_to_cartesian(magmom_i) entry = self.get_entry(entry_jd, {'properties.magmom': 1}) magmom_j = np.array(entry['properties']['magmom']).reshape((-1, 3)) magmom_jxyz = spherical_to_cartesian(magmom_j) # print('Rotating %s towards %s with factor %f' % (entry_id, entry_jd, factor)) # print('Origin:\n %s ' % magmom_i[self.mag_atoms]) # print('Destin:\n %s ' % magmom_j[self.mag_atoms]) for i in self.mag_atoms: #print('Atom %d' % i) if magmom_i[i][0] > 0 and magmom_j[i][0] > 0: magmom_new_xyz[i] = rotate_towards_axis(magmom_ixyz[i], magmom_jxyz[i], fraction=factor) #print('Final magmom Cartesian : %d %s' % (i,magmom_new_xyz[i])) magmom_new = cartesian_to_spherical(magmom_new_xyz) # print('Final spherical:\n %s' % magmom_new[self.mag_atoms]) magmom_new[:, 0] = self.magmom_magnitude for i in range(self.structure.natom): if i not in self.mag_atoms: magmom_new[i, :] = 0.0 properties = {'magmom': list(magmom_new.flatten()), 'energy': self.debug_evaluation(magmom_new)} if in_place: self.update_properties(entry_id, new_properties=properties) return entry_id else: return self.new_entry(magmom_new, active=False)
def debug_evaluation(self, magmom_sph): if self.debug: magmom_car=spherical_to_cartesian(magmom_sph) good_magmom = np.zeros((self.structure.natom, 3)) for i in self.mag_atoms: good_magmom[i] = (-1**i) * 1.15470054 * np.ones(3) distance = np.sum(angle_between_vectors(magmom_car, good_magmom)) distance /= len(self.mag_atoms) return distance-np.pi else: return None
def move(self, entry_id, entry_jd, factor=0.2, in_place=False): magmom_new_xyz = np.zeros((self.structure.natom, 3)) entry = self.get_entry(entry_id, {'properties.magmom': 1}) magmom_i = np.array(entry['properties']['magmom']).reshape((-1, 3)) magmom_ixyz = spherical_to_cartesian(magmom_i) entry = self.get_entry(entry_id, {'properties.magmom': 1}) magmom_j = np.array(entry['properties']['magmom']).reshape((-1, 3)) magmom_jxyz = spherical_to_cartesian(magmom_j) for i in range(self.structure.natom): if magmom_ixyz[i][0] > 0 and magmom_jxyz[i][0] > 0: magmom_new_xyz[i] = rotate_towards_axis(magmom_ixyz[i], magmom_jxyz[i], fraction=factor) magmom_new = cartesian_to_spherical(magmom_new_xyz) magmom_new[:, 0] = self.magmom_magnitude properties = {'magmom': magmom_new} if in_place: return self.update_properties(entry_id, new_properties=properties) else: return self.new_entry(magmom_new, active=False)
def move(self, entry_id, entry_jd, factor=0.2, in_place=False): """ Move the magnetic moments from one candidate in the direction of another. :param entry_id: Source candidate, this one will be moved :param entry_jd: Destination candidate, this one is not moved. :param factor: (float) a value in range [0,1] 0 being the source, 1 the destination :param in_place: (bool) if true the new magnetic moments replace those in entry_id :return: """ magmom_new_xyz = np.zeros((self.structure.natom, 3)) entry = self.get_entry(entry_id, {'properties.magmom': 1}) magmom_i = np.array(entry['properties']['magmom']).reshape((-1, 3)) magmom_ixyz = spherical_to_cartesian(magmom_i) entry = self.get_entry(entry_jd, {'properties.magmom': 1}) magmom_j = np.array(entry['properties']['magmom']).reshape((-1, 3)) magmom_jxyz = spherical_to_cartesian(magmom_j) for i in self.mag_atoms: # print('Atom %d' % i) if magmom_i[i][0] > 0 and magmom_j[i][0] > 0: magmom_new_xyz[i] = rotate_towards_axis(magmom_ixyz[i], magmom_jxyz[i], fraction=factor) # print('Final magmom Cartesian : %d %s' % (i,magmom_new_xyz[i])) magmom_new = cartesian_to_spherical(magmom_new_xyz) magmom_new[:, 0] = self.magmom_magnitude for i in range(self.structure.natom): if i not in self.mag_atoms: magmom_new[i, :] = 0.0 properties = {'magmom': list(magmom_new.flatten()), 'energy': self.debug_evaluation(magmom_new)} if in_place: self.update_properties(entry_id, new_properties=properties) return entry_id else: return self.new_entry(magmom_new, active=False)
def move(self, entry_id, entry_jd, factor=0.2, in_place=False): #FAKE FACTOR # factor=1.0 magmom_new_xyz = np.zeros((self.structure.natom, 3)) entry = self.get_entry(entry_id, {'properties.magmom': 1}) magmom_i = np.array(entry['properties']['magmom']).reshape((-1, 3)) magmom_ixyz = spherical_to_cartesian(magmom_i) entry = self.get_entry(entry_jd, {'properties.magmom': 1}) magmom_j = np.array(entry['properties']['magmom']).reshape((-1, 3)) magmom_jxyz = spherical_to_cartesian(magmom_j) # print('Rotating %s towards %s with factor %f' % (entry_id, entry_jd, factor)) # print('Origin:\n %s ' % magmom_i[self.mag_atoms]) # print('Destin:\n %s ' % magmom_j[self.mag_atoms]) for i in self.mag_atoms: #print('Atom %d' % i) if magmom_i[i][0] > 0 and magmom_j[i][0] > 0: magmom_new_xyz[i] = rotate_towards_axis(magmom_ixyz[i], magmom_jxyz[i], fraction=factor) #print('Final magmom Cartesian : %d %s' % (i,magmom_new_xyz[i])) magmom_new = cartesian_to_spherical(magmom_new_xyz) # print('Final spherical:\n %s' % magmom_new[self.mag_atoms]) magmom_new[:, 0] = self.magmom_magnitude properties = { 'magmom': list(magmom_new.flatten()), 'energy': self.fake_evaluation(magmom_new) } if in_place: self.update_properties(entry_id, new_properties=properties) return entry_id else: return self.new_entry(magmom_new, active=False)
def prepare_folder(self, entry_id, workdir, binary='vasp', source_dir='.'): if not os.path.isdir(workdir): os.mkdir(workdir) for i in ['KPOINTS', 'POSCAR', 'POTCAR']: if os.path.exists(workdir+os.sep+i): os.remove(workdir+os.sep+i) os.symlink(os.path.abspath(self.source_dir+os.sep+i), workdir+os.sep+i) incar = read_incar(self.source_dir + os.sep + 'INCAR') magmom_sph = self.get_entry(entry_id, {'properties.magmom': 1})['properties']['magmom'] magmom_car = spherical_to_cartesian(magmom_sph) incar['MAGMOM'] = [float(x) for x in magmom_car.flatten()] incar['M_CONSTR'] = [float(x) for x in magmom_car.flatten()] for i in self.incar_extra: incar[i] = self.incar_extra[i] incar.write(workdir + os.sep + 'INCAR')
def prepare_folder(self, entry_id, workdir, binary='vasp', source_dir='.'): vj = VaspJob() structure = self.get_structure(entry_id) kp = KPoints.optimized_grid(structure.lattice, kp_density=2E4) vj.initialize(structure, workdir=workdir, kpoints=kp, binary=binary) vj.clean() vj.input_variables = read_incar(source_dir + '/INCAR') magmom_sph = self.get_entry(entry_id, {'properties.magmom': 1})['properties']['magmom'] magmom_car = spherical_to_cartesian(magmom_sph) vj.input_variables.variables['MAGMOM'] = [float(x) for x in magmom_car.flatten()] vj.input_variables.variables['M_CONSTR'] = [float(x) for x in magmom_car.flatten()] vj.input_variables.variables['IBRION'] = -1 vj.input_variables.variables['LWAVE'] = True vj.input_variables.variables['EDIFF'] = 1E-5 vj.input_variables.variables['LAMBDA'] = 10 vj.input_variables.variables['NSW'] = 0 vj.input_variables.variables['I_CONSTRAINED_M'] = 1 vj.set_inputs()
def debug_evaluation(self, magmom_sph): """ For debugging ONLY: Fake evaluation of total energy using a magnetic configuration as the minimal energy, the numerical distance with other candidates defines their energy. :param magmom_sph: :return: """ if self.debug: magmom_car = spherical_to_cartesian(magmom_sph) good_magmom = np.zeros((self.structure.natom, 3)) for i in self.mag_atoms: good_magmom[i] = (-1**i) * 1.15470054 * np.ones(3) distance = np.sum(angle_between_vectors(magmom_car, good_magmom)) distance /= len(self.mag_atoms) return distance-np.pi else: return None
def debug_evaluation(self, magmom_sph): """ For debugging ONLY: Fake evaluation of total energy using a magnetic configuration as the minimal energy, the numerical distance with other candidates defines their energy. :param magmom_sph: :return: """ if self.debug: magmom_car = spherical_to_cartesian(magmom_sph) good_magmom = np.zeros((self.structure.natom, 3)) for i in self.mag_atoms: good_magmom[i] = (-1**i) * 1.15470054 * np.ones(3) distance = np.sum(angle_between_vectors(magmom_car, good_magmom)) distance /= len(self.mag_atoms) return distance - np.pi else: return None
def prepare_folder(self, entry_id, workdir, binary='vasp', source_dir='.'): if not os.path.isdir(workdir): os.mkdir(workdir) for i in ['KPOINTS', 'POSCAR', 'POTCAR']: if os.path.exists(workdir + os.sep + i): os.remove(workdir + os.sep + i) os.symlink(os.path.abspath(self.source_dir + os.sep + i), workdir + os.sep + i) input = read_incar(self.source_dir + os.sep + 'INCAR') magmom_sph = self.get_entry( entry_id, {'properties.magmom': 1})['properties']['magmom'] magmom_car = spherical_to_cartesian(magmom_sph) input['MAGMOM'] = [float(x) for x in magmom_car.flatten()] input['M_CONSTR'] = [float(x) for x in magmom_car.flatten()] for i in self.incar_extra: input[i] = self.incar_extra[i] input.write(workdir + os.sep + 'INCAR')
def prepare_folder(self, entry_id, workdir, binary='vasp', source_dir='.'): if not os.path.isdir(workdir): os.mkdir(workdir) for i in ['KPOINTS', 'POSCAR', 'POTCAR']: if os.path.exists(workdir+os.sep+i): os.remove(workdir+os.sep+i) os.symlink(os.path.abspath(self.source_dir+os.sep+i), workdir+os.sep+i) input = read_incar(self.source_dir + os.sep + 'INCAR') magmom_sph = self.get_entry(entry_id, {'properties.magmom': 1})['properties']['magmom'] magmom_car = spherical_to_cartesian(magmom_sph) input['MAGMOM'] = [float(x) for x in magmom_car.flatten()] input['M_CONSTR'] = [float(x) for x in magmom_car.flatten()] input['IBRION'] = -1 input['LWAVE'] = True input['EDIFF'] = 1E-5 input['LAMBDA'] = self.var_lambda input['NSW'] = 0 input['I_CONSTRAINED_M'] = 1 input.write(workdir + os.sep + 'INCAR')