Beispiel #1
0
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
Beispiel #2
0
    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 )
Beispiel #3
0
    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..."
            )
Beispiel #6
0
# 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