def get_bulkspacegroup_binary(): # https://materials.springer.com/isp/crystallographic/docs/sd_0453869 a = 10.553 b = 10.553 c = 10.553 alpha = 90 beta = 90 gamma = 90 cellpar = [a, b, c, alpha, beta, gamma] symbols = ["Al", "Al", "Al", "Al"] #symbols = ["Al","Al","Al","Al"] basis = [(0, 0, 0), (0.324, 0.324, 0.324), (0.3582, 0.3582, 0.0393), (0.0954, 0.0954, 0.2725)] db_name = "test_db_binary_almg.db" basis_elements = [["Al", "Mg"], ["Al", "Mg"], ["Al", "Mg"], ["Al", "Mg"]] max_dia = get_max_cluster_dia_name() size_arg = {max_dia: 4.1} conc = Concentration(basis_elements=basis_elements, grouped_basis=[[0, 1, 2, 3]]) bs = CECrystal(concentration=conc, basis=basis, spacegroup=217, cellpar=cellpar, max_cluster_size=3, db_name=db_name, size=[1, 1, 1], **size_arg) return bs, db_name
def insert_atoms( self, bc_kwargs, size=[1,1,1], composition=None, cetype="CEBulk", \ T=None, n_steps_per_temp=10000, eci=None ): """ Insert a new atoms object into the database """ if (composition is None): raise TypeError("No composition given") allowed_ce_types = ["CEBulk", "CECrystal"] if (not cetype in allowed_ce_types): raise ValueError( "cetype has to be one of {}".format(allowed_ce_types)) self.cetype = cetype if (eci is None): raise ValueError( "No ECIs given! Cannot determine required energy range!") if (cetype == "CEBulk"): small_bc = CEBulk(**bc_kwargs) small_bc.reconfigure_settings() elif (ctype == "CECrystal"): small_bc = CECrystal(**bc_kwargs) small_bc.reconfigure_settings() self._check_eci(small_bc, eci) calc = get_ce_calc(small_bc, bc_kwargs, eci=eci, size=size) calc.set_composition(composition) bc = calc.BC bc.atoms.set_calculator(calc) formula = bc.atoms.get_chemical_formula() if (self.template_atoms_exists(formula)): raise AtomExistsError( "An atom object with the specified composition already exists in the database" ) Emin, Emax = self._find_energy_range(bc.atoms, T, n_steps_per_temp) cf = calc.get_cf() data = {"cf": cf} # Store this entry into the database db = connect(self.wl_db_name) scalc = SinglePointCalculator(bc.atoms, energy=Emin) bc.atoms.set_calculator(scalc) outfname = "BC_wanglandau_{}.pkl".format( bc.atoms.get_chemical_formula()) with open(outfname, 'wb') as outfile: pck.dump(bc, outfile) kvp = { "Emin": Emin, "Emax": Emax, "bcfile": outfname, "cetype": self.cetype } data["bc_kwargs"] = bc_kwargs data["supercell_size"] = size db.write(calc.BC.atoms, key_value_pairs=kvp, data=data)
def get_atoms_with_ce_calc(small_bc, bc_kwargs, eci=None, size=[1, 1, 1], db_name="temp_db.db"): """ Constructs a CE calculator for a supercell. First, the correlation function from a small cell is calculated and then a supercell is formed. Note that the correlation functions are the same for the supercell. :param ClusterExpansionSetting small_bc: Settings for small unitcell :param dict bc_kwargs: dictionary of the keyword arguments used to construct small_bc :param dict eci: Effective Cluster Interactions :param list size: The atoms in small_bc will be extended by this amount :param str db_name: Database to store info in for the large cell :return: Atoms object with CE calculator attached :rtype: Atoms """ unknown_type = False large_bc = small_bc init_cf = None error_happened = False msg = "" transfer_floating_point_classifier(bc_kwargs["db_name"], db_name) max_size_eci = get_max_size_eci(eci) if "max_cluster_size" in bc_kwargs.keys(): if max_size_eci > bc_kwargs["max_cluster_size"]: msg = "ECI specifies a cluster size larger than " msg += "ClusterExpansionSetting tracks!" raise ValueError(msg) atoms = small_bc.atoms.copy() calc1 = CE(atoms, small_bc, eci) init_cf = calc1.get_cf() min_length = small_bc.max_cluster_dia bc_kwargs["size"] = size size_name = get_max_dia_name() bc_kwargs[size_name] = min_length bc_kwargs["db_name"] = db_name if isinstance(small_bc, CEBulk): large_bc = CEBulk(**bc_kwargs) elif isinstance(small_bc, CECrystal): large_bc = CECrystal(**bc_kwargs) else: unknown_type = True atoms = large_bc.atoms.copy() # Note this automatically attach the calculator to the # atoms object CE(atoms, large_bc, eci, initial_cf=init_cf) return atoms
def load_from_dict(backup_data): """Rebuild the calculator from dictionary :param dict backup_data: All nessecary arguments """ from ase.clease import CEBulk, CECrystal classtype = backup_data["setting_kwargs"].pop("classtype") if classtype == "CEBulk": bc = CEBulk(**backup_data["setting_kwargs"]) elif classtype == "CECrystal": bc = CECrystal(**backup_data["setting_kwargs"]) else: raise ValueError("Unknown setting classtype: {}" "".format(backup_data["setting_kwargs"])) for symb in backup_data["symbols"]: bc.atoms.symbol = symb return CE(bc, eci=backup_data["eci"], initial_cf=backup_data["cf"])
def get_atoms(self, atomID, eci): """ Returns an instance of the atoms object requested """ db = connect(self.wl_db_name) row = db.get(id=atomID) bcfname = row.key_value_pairs["bcfile"] init_cf = row.data["cf"] try: with open(bcfname, 'rb') as infile: bc, atoms = pck.load(infile) calc = CE(atoms, bc, eci, initial_cf=init_cf) return atoms except IOError as exc: print(str(exc)) print("Will try to recover the CEBulk object") bc_kwargs = row.data["bc_kwargs"] cetype = row.key_value_pairs["cetype"] if (cetype == "CEBulk"): small_bc = CEBulk(**bc_kwargs) small_bc.reconfigure_settings() else: small_bc = CECrystal(**bc_kwargs) small_bc.reconfigure_settings() size = row.data["supercell_size"] atoms = get_atoms_with_ce_calc(small_bc, bc_kwargs, eci=eci, size=size) calc = atoms.get_calculator() # Determine the composition count = row.count_atoms() for key in count.keys(): count /= float(row.natoms) calc.set_composition(count) return atoms except: raise RuntimeError( "Did not manage to return the atoms object with the proper calculator attached..." )
def get_ce_calc(small_bc, bc_kwargs, eci=None, size=[1, 1, 1], db_name="temp_db.db"): """ Constructs a CE calculator for a supercell. First, the correlation function from a small cell is calculated and then a supercell is formed. Note that the correlation functions are the same for the supercell. :param ClusterExpansionSetting small_bc: Settings for small unitcell :param dict bc_kwargs: dictionary of the keyword arguments used to construct small_bc :param dict eci: Effective Cluster Interactions :param list size: The atoms in small_bc will be extended by this amount :param str db_name: Database to store info in for the large cell :return: CE calculator for the large cell :rtype: CE """ nproc = num_processors() unknown_type = False large_bc = small_bc init_cf = None error_happened = False msg = "" if not os.path.exists(db_name) and nproc > 1: raise IOError("The database has to be prepared prior to calling " "get_ce_calc") try: max_size_eci = get_max_size_eci(eci) if "max_cluster_dia" in bc_kwargs.keys(): if max_size_eci > bc_kwargs["max_cluster_dia"]: msg = "ECI specifies a cluster size larger than " msg += "ClusterExpansionSetting tracks!" raise ValueError(msg) print("Initializing calculator with small BC") calc1 = CE(small_bc, eci) print("Initialization finished") init_cf = calc1.get_cf() min_length = small_bc.max_cluster_dia bc_kwargs["size"] = size size_name = get_max_dia_name() bc_kwargs[size_name] = min_length bc_kwargs["db_name"] = db_name if isinstance(small_bc, CEBulk): large_bc = CEBulk(**bc_kwargs) elif isinstance(small_bc, CECrystal): large_bc = CECrystal(**bc_kwargs) else: unknown_type = True except MemoryError: # No default error message here error_happened = True msg = "Memory Error. Most likely went out " msg += " of memory when initializing an array" except Exception as exc: error_happened = True msg = str(exc) print(msg) # Broad cast the error flag and raise error on all processes error_happened = mpi_allreduce(error_happened) all_msg = mpi_allgather(msg) for item in all_msg: if item != "": msg = item break if error_happened: raise RuntimeError(msg) unknown_type = mpi_bcast(unknown_type, root=0) if unknown_type: msg = "The small_bc argument has to by of type " msg += "CEBulk or CECrystal" raise TypeError(msg) calc2 = CE(large_bc, eci, initial_cf=init_cf) return calc2