def find_gs_structure(ceBulk, mg_conc): fname = "data/{}.json".format(db_name.split(".")[0]) with open(fname, 'r') as infile: ecis = json.load(infile) calc = CE(ceBulk, ecis) ceBulk.atoms.set_calculator(calc) conc = {"Mg": mg_conc, "Al": 1.0 - mg_conc} calc.set_composition(conc) print(ceBulk.basis_functions) formula = ceBulk.atoms.get_chemical_formula() temps = [ 800, 700, 500, 300, 200, 100, 50, 20, 19, 18, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ] n_steps_per = 1000 lowest_struct = mcobs.LowestEnergyStructure(calc, None) for T in temps: print("Temperature {}".format(T)) mc_obj = mc.Montecarlo(ceBulk.atoms, T) lowest_struct.mc_obj = mc_obj mc_obj.attach(lowest_struct) mc_obj.runMC(steps=n_steps_per, verbose=False) thermo = mc_obj.get_thermodynamic() print("Mean energy: {}".format(thermo["energy"])) fname = "data/gs_structure%s.xyz" % (formula) write(fname, lowest_struct.lowest_energy_atoms) print("Lowest energy found: {}".format(lowest_struct.lowest_energy)) print("GS structure saved to %s" % (fname)) fname = "data/cf_functions_gs%s.csv" % (formula) cf = calc.get_cf() with open(fname, 'w') as outfile: for key, value in cf.iteritems(): outfile.write("{},{}\n".format(key, value)) print("CFs saved to %s" % (fname)) return lowest_struct.lowest_energy
def test_set_singlets( self ): if ( not has_ase_with_ce ): self.skipTest( "ASE version does not have CE" ) return system_types = [["Al","Mg"],["Al","Mg","Si"],["Al","Mg","Si","Cu"]] db_name = "test_singlets.db" n_concs = 4 no_throw = True msg = "" try: for basis_elems in system_types: conc_args = { "conc_ratio_min_1":[[1,0]], "conc_ratio_max_1":[[0,1]], } a = 4.05 mx_dia_name = get_max_cluster_dia_name() size_arg = {mx_dia_name:a} ceBulk = CEBulk( crystalstructure="fcc", a=a, size=[5, 5, 5], basis_elements=[basis_elems], conc_args=conc_args, \ db_name=db_name, max_cluster_size=2,**size_arg) ceBulk.reconfigure_settings() cf = CorrFunction(ceBulk) corrfuncs = cf.get_cf(ceBulk.atoms) eci = {name:1.0 for name in corrfuncs.keys()} calc = CE( ceBulk,eci ) for _ in range(n_concs): conc = np.random.rand(len(basis_elems))*0.97 conc /= np.sum(conc) conc_dict = {} for i in range(len(basis_elems)): conc_dict[basis_elems[i]] = conc[i] calc.set_composition(conc_dict) ref_cf = calc.get_cf() singlets = {} for key,value in ref_cf.items(): if ( key.startswith("c1") ): singlets[key] = value comp = calc.singlet2comp(singlets) dict_comp = "Ref {}. Computed {}".format(conc_dict,comp) for key in comp.keys(): self.assertAlmostEqual( comp[key], conc_dict[key], msg=dict_comp, places=1 ) calc.set_singlets(singlets) except Exception as exc: msg = str(exc) no_throw = False self.assertTrue( no_throw, msg=msg )
def get_gs(self, BC, ecis=None, composition=None, temps=None, n_steps_per_temp=1000, atoms=None): """ Computes the ground states :param BC: Instance of *CEBulk* or *CECrystal* from ASE :param ecis: Dictionary with the Effecitve Cluster Interactions :param composition: Dictionary with compositions (i.e. {"Mg":0.2,"Al":0.8}) :param temps: List of cooling temperatures :param n_steps_per_temp: Number of MC steps per temperature """ if atoms is None: atoms = BC.atoms.copy() if atoms.get_calculator() is None: if ecis is None: raise ValueError("When a calculator is not attached " "the ECIs has to be given!") calc = CE(atoms, BC, ecis) else: calc = atoms.get_calculator() #print (calc.get_cf()) if (temps is None): temps = np.linspace(1, 1500, 30)[::-1] if (composition is not None): calc.set_composition(composition) minimum_energy = LowestEnergyStructure(calc, None) for T in temps: print("Temperature {}".format(T)) mc_obj = Montecarlo(atoms, T) mc_obj.constraints = self.constraints minimum_energy.mc_obj = mc_obj mc_obj.attach(minimum_energy) mc_obj.runMC(steps=n_steps_per_temp, verbose=False, equil=False) thermo = mc_obj.get_thermodynamic() result = { "atoms": minimum_energy.atoms, "energy": minimum_energy.lowest_energy, "cf": minimum_energy.lowest_energy_cf } return result
def test_no_throw(self): no_throw = True if not available: self.skipTest(reason) return msg = "" # try: conc_args = { "conc_ratio_min_1": [[1, 0]], "conc_ratio_max_1": [[0, 1]], } kwargs = { "crystalstructure": "fcc", "a": 4.05, "size": [4, 4, 4], "basis_elements": [["Al", "Mg"]], "conc_args": conc_args, "db_name": "data/temporary_bcnucleationdb.db", "max_cluster_size": 3 } ceBulk = CEBulk(**kwargs) ceBulk.reconfigure_settings() cf = CorrFunction(ceBulk) cf = cf.get_cf(ceBulk.atoms) ecis = {key: 1.0 for key in cf.keys()} calc = CE(ceBulk, ecis) ceBulk = calc.BC ceBulk.atoms.set_calculator(calc) T = 500 c_mg = 0.4 comp = {"Mg": c_mg, "Al": 1.0 - c_mg} calc.set_composition(comp) act_sampler = ActivitySampler(ceBulk.atoms, T, moves=[("Al", "Mg")], mpicomm=comm) act_sampler.runMC(mode="fixed", steps=1000) act_sampler.get_thermodynamic() # except Exception as exc: # msg = str(exc) # no_throw = False self.assertTrue(no_throw, msg=msg)
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..." )
# Initialize a Cluster Expansion calculator (C++ version is required) from cemc import CE atoms = bc.atoms.copy() calc = CE(atoms, bc, eci) # NOTE: At this point all changes to the atoms object has to be done via # the calculator. The reason is that the calculator keeps track of the # changes in the atoms object. mg_conc = 0.25 # Magnesium concentration composition = {"Mg": mg_conc, "Al": 1.0 - mg_conc} # Set the composition calc.set_composition(composition) # Define temperatures (in a real applciation consider more temperatures) temps = [800, 700, 600, 500, 400, 300, 200, 100] # Define the number of steps per temperature n_steps_per_temp = 100 # In a real application condier more that this # We have to keep track of the lowest structure. This can be done # adding an observer to the Monte Carlo that always store the # lowest energy structure from cemc.mcmc.mc_observers import LowestEnergyStructure obs = LowestEnergyStructure(calc, None) # Now we import the Monte Carlo class from cemc.mcmc.montecarlo import Montecarlo