def store_enumeration(self, filename=None): for SG in range(self.SG_start, self.SG_end + 1): with PrototypeSQL(filename=filename) as DB: enumerated = [DB.is_enumerated(self.stoichiometry, SG, num, self.num_type) for num in range(self.num_start, self.num_end + 1)] if np.all(enumerated): print('spacegroup={} already enumerated for n_{}={}:{}' .format(SG, self.num_type, self.num_start, self.num_end)) continue E = be.enumerator.ENUMERATOR() try: enumerations = E.get_bulk_enumerations( self.stoichiometry, self.num_start, self.num_end, SG, SG, self.num_type) print('Found {} prototypes for spacegroup={}'.format( len(enumerations), SG)) except: print('Found 0 prototypes for spacegroup={}'.format(SG)) with PrototypeSQL(filename=filename) as DB: for entry in enumerations: entry.update({'source': 'prototype'}) DB.write_prototype(entry=entry) for num in range(self.num_start, self.num_end + 1): DB.write_enumerated(self.stoichiometry, SG, num, self.num_type)
def store_atom_enumeration(self, filename=None, multithread=False, max_candidates=1): self.filename = filename DB = PrototypeSQL(filename=filename) DB._connect() N0 = DB.ase_db.count() prototypes = DB.select(max_atoms=self.max_atoms, spacegroups=self.spacegroups, source='prototype') Nprot = len(prototypes) pool = Pool() t0 = time.time() if multithread: res = pool.amap(self.store_atoms_for_prototype, prototypes) while not res.ready(): N = DB.ase_db.count() - N0 t = time.time() - t0 N_per_t = N / t if N > 0: print('---------------------------------') print( "{}/{} structures generated in {:.2f} sec".format(N, Nprot, t)) print("{} sec / structure".format(t / N)) print('Estimated time left: {:.2f} min'.format( Nprot / N_per_t / 60)) print('---------------------------------') time.sleep(10) res = res.get() else: for prototype in prototypes: self.store_atoms_for_prototype(prototype)
def store_enumeration(self, filename, chemical_formula, max_atoms=None): """ Saves the enumerated prototypes and atomic species in a database""" distinct_protonames = \ self.get_distinct_prototypes( chemical_formula=chemical_formula, max_atoms=max_atoms) for count, proto_name in enumerate(distinct_protonames): data_list = \ self.get_atoms_for_prototype(chemical_formula, proto_name) DB = PrototypeSQL(filename=filename) for d in data_list: atoms = d.pop('atoms') formula = d.pop('chemical_formula') original_formula = d.pop('original_formula') # Same format as Enumerator output entry = d.copy() entry['spaceGroupNumber'] = entry.pop('spacegroup') entry['name'] = entry.pop('p_name') entry['parameters'] = {} entry['source'] = 'icsd' structure_name = d['structure_name'] if DB.ase_db.count(structure_name=structure_name) > 0: continue # Save prototype DB.write_prototype(entry=entry) key_value_pairs = \ {'p_name': d['p_name'], 'spacegroup': d['spacegroup'], 'permutations': json.dumps(d['specie_permutations']), 'wyckoffs': json.dumps(d['wyckoffs']), 'species': json.dumps(d['species']), 'structure_name': structure_name, 'source': 'icsd', 'relaxed': 0, 'completed': 0, 'submitted': 0} # Save structure DB.ase_db.write(atoms, key_value_pairs) if (count + 1) % 10 == 0: print(' {}/{} completed'.format(count + 1, len(distinct_protonames)))
def store_atoms_for_prototype(self, prototype, max_candidates=1): p_name = prototype['name'] counts = [] for a in p_name.split('_')[0]: if a.isdigit(): counts[-1] += int(a) - 1 else: counts += [1] species_lists = self.get_species_lists( prototype['species'], prototype['permutations'], counts) cell_parameters = prototype.get('cell_parameters', None) if cell_parameters: cell_parameters = json.load(cell_parameters) for species in species_lists: structure_name = str(prototype['spacegroup']) for spec, wy_spec in zip(species, prototype['wyckoffs']): structure_name += '_{}_{}'.format(spec, wy_spec) with PrototypeSQL(filename=self.filename) as DB: if DB.ase_db.count(structure_name=structure_name) > 0: continue for row in DB.ase_db.select(p_name=prototype['name'], limit=1): cell_parameters = json.loads(row.cell_parameters) BB = BuildBulk(prototype['spacegroup'], prototype['wyckoffs'], species, ) atoms_list, parameters = \ BB.get_wyckoff_candidate_atoms(proximity=1, primitive_cell=True, return_parameters=True, max_candidates=max_candidates) key_value_pairs = {'p_name': prototype['name'], 'spacegroup': prototype['spacegroup'], 'wyckoffs': json.dumps(prototype['wyckoffs']), 'species': json.dumps(species), 'structure_name': structure_name, 'source': 'prototype', 'relaxed': 0, 'completed': 0, 'submitted': 0} for i, atoms in enumerate(atoms_list): atoms.info.pop('spacegroup') if 'spacegroup_kinds' in atoms.info: atoms.info.pop('spacegroup_kinds') key_value_pairs.update(atoms.info) key_value_pairs.update( {'cell_parameters': json.dumps(parameters[i])}) fitness = get_fitness(atoms) apf = get_covalent_density(atoms) key_value_pairs.update({'fitness': fitness, 'apf': apf}) with PrototypeSQL(filename=self.filename) as DB: DB.ase_db.write(atoms, key_value_pairs)