def distance(self, entry_id, entry_jd, rcut=50): ids_pair = [entry_id, entry_jd] ids_pair.sort() distance_entry = self.pcdb.db.distances.find_one({'pair': ids_pair}, {'distance': 1}) self.pcdb.db.distances.create_index([("pair", ASCENDING)]) if distance_entry is None: print('Distance not in DB') fingerprints = {} for entry_ijd in [entry_id, entry_jd]: if self.pcdb.db.fingerprints.find_one({'_id': entry_ijd }) is None: structure = self.get_structure(entry_ijd) analysis = StructureAnalysis(structure, radius=rcut) x, ys = analysis.fp_oganov() fingerprint = {'_id': entry_ijd} for k in ys: atomic_number1 = atomic_number(structure.species[k[0]]) atomic_number2 = atomic_number(structure.species[k[1]]) pair = '%06d' % min( atomic_number1 * 1000 + atomic_number2, atomic_number2 * 1000 + atomic_number1) fingerprint[pair] = list(ys[k]) if self.pcdb.db.fingerprints.find_one({'_id': entry_ijd }) is None: self.pcdb.db.fingerprints.insert(fingerprint) else: self.pcdb.db.fingerprints.update({'_id': entry_ijd}, fingerprint) fingerprints[entry_ijd] = fingerprint else: fingerprints[ entry_ijd] = self.pcdb.db.fingerprints.find_one( {'_id': entry_ijd}) dij = [] for pair in fingerprints[entry_id]: if pair in fingerprints[entry_jd] and pair != '_id': uvect1 = unit_vector(fingerprints[entry_id][pair]) uvect2 = unit_vector(fingerprints[entry_jd][pair]) dij.append(0.5 * (1.0 - np.dot(uvect1, uvect2))) distance = float(np.mean(dij)) self.pcdb.db.distances.insert({ 'pair': ids_pair, 'distance': distance }) else: distance = distance_entry['distance'] return distance
def distance(self, entry_id, entry_jd, rcut=50): ids_pair = [entry_id, entry_jd] ids_pair.sort() distance_entry = self.pcdb.db.distances.find_one({'pair': ids_pair}, {'distance': 1}) self.pcdb.db.distances.create_index([("pair", pymongo.ASCENDING)]) if distance_entry is None: print('Distance not in DB') fingerprints = {} for entry_ijd in [entry_id, entry_jd]: if self.pcdb.db.fingerprints.find_one({'_id': entry_ijd}) is None: structure = self.get_structure(entry_ijd) analysis = StructureAnalysis(structure, radius=rcut) x, ys = analysis.fp_oganov() fingerprint = {'_id': entry_ijd} for k in ys: atomic_number1 = atomic_number(structure.species[k[0]]) atomic_number2 = atomic_number(structure.species[k[1]]) pair = '%06d' % min(atomic_number1 * 1000 + atomic_number2, atomic_number2 * 1000 + atomic_number1) fingerprint[pair] = list(ys[k]) if self.pcdb.db.fingerprints.find_one({'_id': entry_ijd}) is None: self.pcdb.db.fingerprints.insert(fingerprint) else: self.pcdb.db.fingerprints.update({'_id': entry_ijd}, fingerprint) fingerprints[entry_ijd] = fingerprint else: fingerprints[entry_ijd] = self.pcdb.db.fingerprints.find_one({'_id': entry_ijd}) dij = [] for pair in fingerprints[entry_id]: if pair in fingerprints[entry_jd] and pair != '_id': uvect1 = unit_vector(fingerprints[entry_id][pair]) uvect2 = unit_vector(fingerprints[entry_jd][pair]) dij.append(0.5 * (1.0 - np.dot(uvect1, uvect2))) distance = float(np.mean(dij)) self.pcdb.db.distances.insert({'pair': ids_pair, 'distance': distance}) else: distance = distance_entry['distance'] return distance
def worker(db_settings, entry_id, workdir, target_forces, relaxator_params): pcdb = get_database(db_settings) pcm_log.info('[%s]: Starting relaxation. Target forces: %7.3e' % (str(entry_id), target_forces)) if pcdb.is_locked(entry_id): return else: pcdb.lock(entry_id) structure = pcdb.get_structure(entry_id) structure = structure.scale() print('relaxator_params', relaxator_params) relaxer = IonRelaxation(structure, workdir=workdir, target_forces=target_forces, waiting=False, binary=relaxator_params['binary'], encut=1.3, kp_grid=None, kp_density=1E4, relax_cell=True, max_calls=10) print('relaxing on:', relaxer.workdir) relaxer.run(relaxator_params['nmpiparal']) pcm_log.info('[%s]: Finished relaxation. Target forces: %7.3e' % (str(entry_id), target_forces)) filename = workdir + os.sep + 'OUTCAR' if os.path.isfile(filename): forces, stress, total_energy = relaxer.get_forces_stress_energy() if forces is not None: magnitude_forces = np.apply_along_axis(np.linalg.norm, 1, forces) print('Forces: Max: %9.3e Avg: %9.3e' % (np.max(magnitude_forces), np.average(magnitude_forces))) print('Stress: ', np.max(np.abs(stress.flatten()))) if forces is None: pcm_log.error('No forces found on %s' % filename) if stress is None: pcm_log.error('No stress found on %s' % filename) if total_energy is None: pcm_log.error('No total_energy found on %s' % filename) new_structure = relaxer.get_final_geometry() if forces is not None and stress is not None and total_energy is not None and new_structure is not None: pcm_log.info('[%s]: Updating properties' % str(entry_id)) pcdb.update(entry_id, structure=new_structure) te = total_energy pcdb.entries.update({'_id': entry_id}, { '$set': { 'status.relaxation': 'succeed', 'status.target_forces': target_forces, 'properties.forces': generic_serializer(forces), 'properties.stress': generic_serializer(stress), 'properties.energy': te, 'properties.energy_pa': te / new_structure.natom, 'properties.energy_pf': te / new_structure.get_composition().gcd } }) # Fingerprint # Update the fingerprints only if the two structures are really different diffnatom = structure.natom != new_structure.natom diffcell = np.max( np.abs((structure.cell - new_structure.cell).flatten())) diffreduced = np.max( np.abs((structure.reduced - new_structure.reduced).flatten())) if diffnatom != 0 or diffcell > 1E-7 or diffreduced > 1E-7: analysis = StructureAnalysis(new_structure, radius=50) x, ys = analysis.fp_oganov(delta=0.01, sigma=0.01) fingerprint = {'_id': entry_id} for k in ys: atomic_number1 = atomic_number(new_structure.species[k[0]]) atomic_number2 = atomic_number(new_structure.species[k[1]]) pair = '%06d' % min(atomic_number1 * 1000 + atomic_number2, atomic_number2 * 1000 + atomic_number1) fingerprint[pair] = list(ys[k]) if pcdb.db.fingerprints.find_one({'_id': entry_id}) is None: pcdb.db.fingerprints.insert(fingerprint) else: pcdb.db.fingerprints.update({'_id': entry_id}, fingerprint) else: pcm_log.debug('Original and new structures are very similar.') pcm_log.debug('Max diff cell: %10.3e' % np.max( np.absolute( (structure.cell - new_structure.cell).flatten()))) if structure.natom == new_structure.natom: pcm_log.debug( 'Max diff reduced coordinates: %10.3e' % np.max( np.absolute((structure.reduced - new_structure.reduced).flatten()))) else: pcdb.entries.update({'_id': entry_id}, {'$set': { 'status.relaxation': 'failed' }}) pcm_log.error( 'Bad data after relaxation. Tagging relaxation as failed') else: pcm_log.error('ERROR: File not found %s' % filename) pcm_log.info('[%s]: Unlocking the entry' % str(entry_id)) pcdb.unlock(entry_id)
def worker(db_settings, entry_id, workdir, target_forces, relaxator_params): pcdb = get_database(db_settings) pcm_log.info('[%s]: Starting relaxation. Target forces: %7.3e' % (str(entry_id), target_forces)) if pcdb.is_locked(entry_id): return else: pcdb.lock(entry_id) structure = pcdb.get_structure(entry_id) structure = structure.scale() print('relaxator_params', relaxator_params) relaxer = IonRelaxation2(structure, workdir=workdir, target_forces=target_forces, waiting=False, binary=relaxator_params['binary'], encut=1.3, kp_grid=None, kp_density=1E4, relax_cell=True) print('relaxing on:', relaxer.workdir) relaxer.run(relaxator_params['nmpiparal']) pcm_log.info('[%s]: Finished relaxation. Target forces: %7.3e' % (str(entry_id), target_forces)) filename = workdir + os.sep + 'OUTCAR' if os.path.isfile(filename): forces, stress, total_energy = relaxer.get_forces_stress_energy() if forces is not None: magnitude_forces = np.apply_along_axis(np.linalg.norm, 1, forces) print('Forces: Max: %9.3e Avg: %9.3e' % (np.max(magnitude_forces), np.average(magnitude_forces))) print('Stress: ', np.max(np.abs(stress.flatten()))) if forces is None: pcm_log.error('No forces found on %s' % filename) if stress is None: pcm_log.error('No stress found on %s' % filename) if total_energy is None: pcm_log.error('No total_energy found on %s' % filename) new_structure = relaxer.get_final_geometry() if forces is not None and stress is not None and total_energy is not None and new_structure is not None: pcm_log.info('[%s]: Updating properties' % str(entry_id)) pcdb.update(entry_id, structure=new_structure) te = total_energy pcdb.entries.update({'_id': entry_id}, {'$set': {'status.relaxation': 'succeed', 'status.target_forces': target_forces, 'properties.forces': generic_serializer(forces), 'properties.stress': generic_serializer(stress), 'properties.energy': te, 'properties.energy_pa': te / new_structure.natom, 'properties.energy_pf': te / new_structure.get_composition().gcd}}) # Fingerprint # Update the fingerprints only if the two structures are really different diffnatom = structure.natom != new_structure.natom diffcell = np.max(np.abs((structure.cell - new_structure.cell).flatten())) diffreduced = np.max(np.abs((structure.reduced - new_structure.reduced).flatten())) if diffnatom != 0 or diffcell > 1E-7 or diffreduced > 1E-7: analysis = StructureAnalysis(new_structure, radius=50) x, ys = analysis.fp_oganov(delta=0.01, sigma=0.01) fingerprint = {'_id': entry_id} for k in ys: atomic_number1 = atomic_number(new_structure.species[k[0]]) atomic_number2 = atomic_number(new_structure.species[k[1]]) pair = '%06d' % min(atomic_number1 * 1000 + atomic_number2, atomic_number2 * 1000 + atomic_number1) fingerprint[pair] = list(ys[k]) if pcdb.db.fingerprints.find_one({'_id': entry_id}) is None: pcdb.db.fingerprints.insert(fingerprint) else: pcdb.db.fingerprints.update({'_id': entry_id}, fingerprint) else: pcm_log.debug('Original and new structures are very similar.') pcm_log.debug('Max diff cell: %10.3e' % np.max(np.absolute((structure.cell - new_structure.cell).flatten()))) if structure.natom == new_structure.natom: pcm_log.debug('Max diff reduced coordinates: %10.3e' % np.max(np.absolute((structure.reduced - new_structure.reduced).flatten()))) else: pcdb.entries.update({'_id': entry_id}, {'$set': {'status.relaxation': 'failed'}}) pcm_log.error('Bad data after relaxation. Tagging relaxation as failed') else: pcm_log.error('ERROR: File not found %s' % filename) pcm_log.info('[%s]: Unlocking the entry' % str(entry_id)) pcdb.unlock(entry_id)