示例#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
示例#2
0
    def test_chemical_potential(self):
        if not available:
            self.skipTest(avail_msg)

        bc = get_ternary_BC()
        ecis = {"c1_0": 0.0, "c1_1": 0.0}
        atoms = bc.atoms.copy()
        bf = bc.basis_functions
        calc = CE(atoms, bc, eci=ecis)

        groups = [{"Al": 2}, {"Mg": 1, "Si": 1}]
        symbs = ["Al", "Mg", "Si"]
        T = 400
        chem_pots = [-0.2, -0.1, 0.0, 0.1, 0.2, 1.0]
        all_al = ["Al" for _ in range(len(atoms))]
        num_atom_per_fu = 2
        for mu in chem_pots:
            calc.set_symbols(all_al)
            mc = PseudoBinarySGC(atoms,
                                 T,
                                 chem_pot=mu,
                                 symbols=symbs,
                                 groups=groups)

            # At this point the chemical potentials should
            # be updated
            changes = [(0, "Al", "Mg"), (1, "Al", "Si")]
            energy = calc.get_energy()
            for change in changes:
                calc.update_cf(change)

            new_energy = calc.get_energy()
            self.assertAlmostEqual(new_energy - energy, mu)
            mc.reset_ecis()
 def __init__(self, BC):
     self.bc = BC
     cf_obj = CorrFunction(self.bc)
     self.init_cf = cf_obj.get_cf(self.bc.atoms)
     ecis = {key: 1.0
             for key in self.init_cf.keys()}  # ECIs do not matter here
     self.calc = CE(self.bc, ecis, initial_cf=self.init_cf)
     self.bc.atoms.set_calculator(self.calc)
     self.elements = self.bc.basis_elements[
         0]  # This should be updated to handle different site types
     self.status_every_sec = 30
     N = len(ecis.keys()) - 1
     self.cov_matrix = np.zeros((N, N))
     self.exp_value = np.zeros(N)
示例#4
0
    def test_double_swaps_ternary( self ):
        if ( not has_ase_with_ce ): # Disable this test
            self.skipTest("ASE version has not cluster expansion")
            return

        db_name = "test_db_ternary.db"
        conc_args = {
            "conc_ratio_min_1":[[4,0,0]],
            "conc_ratio_max_1":[[0,4,0]],
            "conc_ratio_min_1":[[2,2,0]],
            "conc_ratio_max_2":[[1,1,2]]
        }
        max_dia = get_max_cluster_dia_name()
        size_arg = {max_dia:4.05}
        ceBulk = CEBulk( crystalstructure="fcc", a=4.05, size=[4,4,4], basis_elements=[["Al","Mg","Si"]], \
                              conc_args=conc_args, db_name=db_name, max_cluster_size=3, **size_arg)
        ceBulk.reconfigure_settings()
        corr_func = CorrFunction( ceBulk )
        cf = corr_func.get_cf( ceBulk.atoms )
        #prefixes = [name.rpartition("_")[0] for name in cf.keys()]
        #prefixes.remove("")
        eci = {name:1.0 for name in cf.keys()}
        calc = CE( ceBulk, eci )
        n_tests = 10

        # Insert 25 Mg atoms and 25 Si atoms
        n = 18
        for i in range(n):
            calc.calculate( ceBulk.atoms, ["energy"], [(i,"Al","Mg")])
            calc.calculate( ceBulk.atoms, ["energy"], [(i+n,"Al","Si")])
            updated_cf = calc.get_cf()
            brute_force = corr_func.get_cf_by_cluster_names( ceBulk.atoms, updated_cf.keys() )
            for key in updated_cf.keys():
                self.assertAlmostEqual( brute_force[key], updated_cf[key])

        # Swap atoms
        for i in range(n_tests):
            indx1 = np.random.randint(low=0,high=len(ceBulk.atoms))
            symb1 = ceBulk.atoms[indx1].symbol
            indx2 = indx1
            symb2 = symb1
            while( symb2 == symb1 ):
                indx2 = np.random.randint( low=0, high=len(ceBulk.atoms) )
                symb2 = ceBulk.atoms[indx2].symbol
            calc.calculate( ceBulk.atoms, ["energy"], [(indx1,symb1,symb2),(indx2,symb2,symb1)])
            update_cf = calc.get_cf()
            brute_force = corr_func.get_cf_by_cluster_names( ceBulk.atoms, update_cf.keys() )
            for key,value in brute_force.items():
                self.assertAlmostEqual( value, update_cf[key])
示例#5
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):
        if not available:
            self.skipTest(skipMsg)

        no_throw = True
        msg = ""
        try:
            bc = get_ternary_BC()
            eci = get_example_ecis(bc)

            atoms = bc.atoms.copy()
            CE(atoms, bc, eci=eci)

            mc = Montecarlo(atoms, 1000)
            mc.insert_symbol_random_places("Mg", num=10, swap_symbs=["Al"])

            # Note: convergence_factor should never be
            # set to a negative value! Here it is done
            # to make the test converged after one step
            bias = AdaptiveBiasReactionPathSampler(
                mc_obj=mc,
                react_crd_init=DummyReacCrdInit(),
                react_crd=[-1.0, 1.0],
                convergence_factor=-1.0)
            bias.run()
        except Exception as exc:
            msg = str(exc)
            no_throw = False
        self.assertTrue(no_throw, msg=msg)
示例#7
0
    def test_with_bias_potential(self):
        if not available:
            self.skipTest(avail_msg)

        msg = ""
        try:
            os.remove("test_db_ternary.db")
        except Exception:
            pass
        no_throw = True
        try:
            bc = get_ternary_BC()
            ecis = get_example_ecis(bc=bc)
            atoms = bc.atoms.copy()
            calc = CE(atoms, bc, eci=ecis)

            groups = [{"Al": 2}, {"Mg": 1, "Si": 1}]
            symbs = ["Al", "Mg", "Si"]
            T = 400
            mc = PseudoBinarySGC(atoms,
                                 T,
                                 chem_pot=-0.2,
                                 symbols=symbs,
                                 groups=groups)
            conc_init = PseudoBinaryConcInitializer(mc)
            reac_crd = np.linspace(0.0, 1.0, 10)
            bias_pot = reac_crd**2
            bias = PseudoBinaryFreeEnergyBias(conc_init, reac_crd, bias_pot)
            mc.add_bias(bias)
            mc.runMC(mode="fixed", steps=100, equil=False)
            os.remove("test_db_ternary.db")
        except Exception as exc:
            msg = "{}: {}".format(type(exc).__name__, str(exc))
            no_throw = False
        self.assertTrue(no_throw, msg)
示例#8
0
    def test_no_throw(self):
        if not available:
            self.skipTest(avail_msg)

        msg = ""
        try:
            os.remove("test_db_ternary.db")
        except Exception:
            pass
        no_throw = True
        try:
            bc = get_ternary_BC()
            ecis = get_example_ecis(bc=bc)
            atoms = bc.atoms.copy()
            calc = CE(atoms, bc, eci=ecis)

            groups = [{"Al": 2}, {"Mg": 1, "Si": 1}]
            symbs = ["Al", "Mg", "Si"]
            T = 400
            mc = PseudoBinarySGC(atoms,
                                 T,
                                 chem_pot=-0.2,
                                 symbols=symbs,
                                 groups=groups)
            mc.runMC(mode="fixed", steps=100, equil=False)
            os.remove("test_db_ternary.db")
        except Exception as exc:
            msg = "{}: {}".format(type(exc).__name__, str(exc))
            no_throw = False
        self.assertTrue(no_throw, msg)
示例#9
0
    def test_pair_observer(self):
        if not available:
            self.skipTest(skip_msg)

        no_throw = True
        msg = ""

        bc = get_ternary_BC()
        ecis = get_example_ecis(bc=bc)
        atoms = bc.atoms.copy()
        calc = CE(atoms, bc, eci=ecis)
        atoms.set_calculator(calc)

        T = 1000
        nn_names = [name for name in bc.cluster_family_names
                    if int(name[1]) == 2]

        mc = FixedNucleusMC(
            atoms, T, network_name=nn_names,
            network_element=["Mg", "Si"])
        mc.insert_symbol_random_places("Mg", swap_symbs=["Al"])
        elements = {"Mg": 3, "Si": 3}
        mc.grow_cluster(elements)
        obs = PairObserver(mc.atoms, cutoff=4.1, elements=["Mg", "Si"])
        mc.attach(obs)
        mc.runMC(steps=200)
        self.assertEqual(obs.num_pairs, obs.num_pairs_brute_force())
        self.assertTrue(obs.symbols_is_synced())
示例#10
0
    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)
示例#11
0
 def get_cebulk(self):
     conc = Concentration(basis_elements=[["Al","Mg"]])
     ceBulk = CEBulk(crystalstructure="fcc", a=4.05, size=[3,3,3], concentration=conc, db_name=db_name,  
                     max_cluster_size=3, max_cluster_dia=4.5)
     ceBulk.reconfigure_settings()
     cf = CorrFunction(ceBulk)
     cf = cf.get_cf(ceBulk.atoms)
     ecis = {key:1.0 for key in cf.keys()}
     atoms = ceBulk.atoms.copy()
     calc = CE( atoms, ceBulk, ecis )
     return atoms
示例#12
0
 def __init__(self, ground_states):
     self.calcs = []
     self.orig_symbols = []
     for ground_state in ground_states:
         self.calcs.append(
             CE(ground_state["atoms"],
                ground_state["bc"],
                ground_state["eci"],
                initial_cf=ground_state["cf"]))
         symbs = [atom.symbol for atom in ground_state["atoms"]]
         self.orig_symbols.append(symbs)
示例#13
0
 def __init__(self, ground_states):
     self.calcs = []
     self.orig_symbols = []
     for ground_state in ground_states:
         self.calcs.append(
             CE(ground_state["bc"],
                ground_state["eci"],
                initial_cf=ground_state["cf"]))
         ground_state["bc"].atoms.set_calculator(self.calcs[-1])
         symbs = [atom.symbol for atom in ground_state["bc"].atoms]
         self.orig_symbols.append(symbs)
    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 test_run(self):
        if not available:
            self.skipTest(reason)

        bc = get_ternary_BC()
        eci = get_example_ecis(bc)
        atoms = bc.atoms.copy()
        calc = CE(atoms, bc, eci=eci)

        mc = Montecarlo(atoms, 1000000)
        mc.insert_symbol_random_places("Mg", swap_symbs=["Al"], num=3)
        performance_monitor = MultithreadPerformance(4)
        performance_monitor.run(mc, 100)
示例#16
0
 def get_cebulk(self):
     conc_args = {
         "conc_ratio_min_1":[[1,0]],
         "conc_ratio_max_1":[[0,1]],
     }
     ceBulk = CEBulk( crystalstructure="fcc", a=4.05, size=[3,3,3], basis_elements=[["Al","Mg"]], conc_args=conc_args, db_name=db_name)
     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.atoms.set_calculator(calc)
     return ceBulk
示例#17
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 )
示例#18
0
 def test_binary_spacegroup( self ):
     if ( not has_ase_with_ce ):
         self.skipTest("ASE version does not have CE")
         return
     bs, db_name = get_bulkspacegroup_binary()
     cf = CorrFunction( bs )
     cf_vals = cf.get_cf( bs.atoms )
     ecis = {name:1.0 for name in cf_vals.keys()}
     calc = CE( bs, ecis )
     bs.atoms.set_calculator( calc )
     for i in range(25):
         if ( bs.atoms[i].symbol == "Al" ):
             new_symb = "Mg"
             old_symb = "Al"
         else:
             new_symb = "Al"
             old_symb = "Mg"
         calc.calculate( bs.atoms, ["energy"], [(i,old_symb,new_symb)] )
         updated_cf = calc.get_cf()
         brute_force = cf.get_cf_by_cluster_names( bs.atoms, updated_cf.keys() )
         for key,value in brute_force.items():
             self.assertAlmostEqual( value, updated_cf[key] )
 def init_bulk_crystal(self):
     conc = Concentration(basis_elements=[["Al", "Mg", "Si"]])
     ceBulk = CEBulk(crystalstructure="fcc",
                     a=4.05,
                     size=[4, 4, 4],
                     concentration=conc,
                     db_name=db_name,
                     max_cluster_size=2,
                     max_cluster_dia=4.0)
     ceBulk.reconfigure_settings()
     ecis = get_example_ecis(bc=ceBulk)
     atoms = ceBulk.atoms.copy()
     calc = CE(atoms, ceBulk, ecis)
     return ceBulk, atoms
示例#20
0
 def init_bulk_crystal(self):
     max_dia_name = get_max_cluster_dia_name()
     size_arg = {max_dia_name: 4.05}
     conc = Concentration(basis_elements=[["Al", "Mg", "Si"]])
     ceBulk = CEBulk(crystalstructure="fcc",
                     a=4.05,
                     size=[3, 3, 3],
                     concentration=conc,
                     db_name=db_name,
                     max_cluster_size=3,
                     **size_arg)
     ceBulk.reconfigure_settings()
     atoms = ceBulk.atoms.copy()
     calc = CE(atoms, ceBulk, ecis)
     return ceBulk, atoms
示例#21
0
 def init_bulk_crystal(self):
     conc_args = {
         "conc_ratio_min_1": [[2, 1, 1]],
         "conc_ratio_max_1": [[0, 2, 2]],
     }
     max_dia_name = get_max_cluster_dia_name()
     size_arg = {max_dia_name: 4.05}
     ceBulk = CEBulk(crystalstructure="fcc", a=4.05, size=[3, 3, 3],
                          basis_elements=[["Al", "Mg", "Si"]],
                          conc_args=conc_args, db_name=db_name,
                          max_cluster_size=3, **size_arg)
     ceBulk.reconfigure_settings()
     calc = CE(ceBulk, ecis)
     ceBulk.atoms.set_calculator(calc)
     return ceBulk
示例#22
0
    def test_no_throw(self):
        if (not has_ase_with_ce):
            self.skipTest("The ASE version does not include the CE module!")
            return

        no_throw = True
        msg = ""
        try:
            db_name = "test_db.db"
            conc = Concentration(basis_elements=[["Al", "Mg"]])
            ceBulk = CEBulk(crystalstructure="fcc",
                            a=4.05,
                            size=[3, 3, 3],
                            concentration=conc,
                            db_name=db_name,
                            max_cluster_size=3,
                            max_cluster_dia=4.5)
            ceBulk.reconfigure_settings()
            cf = CorrFunction(ceBulk)
            cf = cf.get_cf(ceBulk.atoms)
            ecis = {key: 0.001 for key in cf.keys()}
            atoms = ceBulk.atoms.copy()
            calc = Clease(ceBulk, cluster_name_eci=ecis)  # Bug in the update
            atoms.set_calculator(calc)
            #ceBulk.atoms.set_calculator( calc )
            mf = MeanFieldApprox(atoms, ceBulk)
            chem_pot = {"c1_0": -1.05}
            betas = np.linspace(1.0 / (kB * 100), 1.0 / (kB * 800), 50)
            G = mf.free_energy(betas, chem_pot=chem_pot)
            G = mf.free_energy(betas)  # Try when chem_pot is not given
            U = mf.internal_energy(betas, chem_pot=chem_pot)
            U = mf.internal_energy(betas)
            Cv = mf.heat_capacity(betas, chem_pot=chem_pot)
            Cv = mf.heat_capacity(betas)

            atoms = ceBulk.atoms.copy()
            atoms[0].symbol = "Mg"
            atoms[1].symbol = "Mg"
            calc = CE(atoms, ceBulk, eci=ecis)
            #ceBulk.atoms.set_calculator(calc)
            # Test the Canonical MFA
            T = [500, 400, 300, 200, 100]
            canonical_mfa = CanonicalMeanField(atoms=atoms, T=T)
            res = canonical_mfa.calculate()
        except Exception as exc:
            no_throw = False
            msg = str(exc)
        self.assertTrue(no_throw, msg=msg)
示例#23
0
    def get_calc(self, lat):
        db_name = "test_db_{}.db".format(lat)

        conc = Concentration(basis_elements=[["Al", "Mg"]])
        a = 4.05
        ceBulk = CEBulk(crystalstructure=lat, a=a, size=[3, 3, 3],
                        concentration=conc, db_name=db_name,
                        max_cluster_size=3, max_cluster_dia=6.0)
        ceBulk.reconfigure_settings()
        cf = CorrFunction(ceBulk)
        corrfuncs = cf.get_cf(ceBulk.atoms)
        eci = {name: 1.0 for name in corrfuncs.keys()}
        atoms = ceBulk.atoms.copy()
        calc = CE(atoms, ceBulk, eci)
        atoms.set_calculator(calc)
        return atoms, ceBulk, eci
示例#24
0
    def test_network(self):
        if (not available):
            self.skipTest("ASE version does not have CE!")
            return

        msg = ""
        no_throw = True
        try:
            db_name = "test_db_network.db"

            conc = Concentration(basis_elements=[["Al", "Mg"]])
            a = 4.05
            ceBulk = CEBulk(crystalstructure="fcc",
                            a=a,
                            size=[3, 3, 3],
                            concentration=conc,
                            db_name=db_name,
                            max_cluster_size=3,
                            max_cluster_dia=4.5)
            ceBulk.reconfigure_settings()

            cf = CorrFunction(ceBulk)
            atoms = ceBulk.atoms.copy()
            cf = cf.get_cf(atoms)
            eci = {key: 0.001 for key in cf.keys()}
            calc = CE(atoms, ceBulk, eci=eci)
            trans_mat = ceBulk.trans_matrix

            for name, info in ceBulk.cluster_info[0].items():
                if info["size"] == 2:
                    net_name = name
                    break
            obs = NetworkObserver(calc=calc,
                                  cluster_name=[net_name],
                                  element=["Mg"])

            # Several hard coded tests
            calc.update_cf((0, "Al", "Mg"))
            size = 2
            clusters = ceBulk.cluster_info[0][net_name]["indices"]
            for sub_clust in clusters:
                calc.update_cf((sub_clust[0], "Al", "Mg"))
                # Call the observer
                obs(None)

                res = obs.fast_cluster_tracker.get_cluster_statistics_python()
                self.assertEqual(res["cluster_sizes"][0], size)
                size += 1
            obs.get_indices_of_largest_cluster_with_neighbours()
            os.remove("test_db_network.db")

        except Exception as exc:
            msg = "{}: {}".format(type(exc).__name__, str(exc))
            no_throw = False
        self.assertTrue(no_throw, msg=msg)
示例#25
0
 def init_bulk_crystal(self):
     conc_args = {
         "conc_ratio_min_1": [[2, 1, 1]],
         "conc_ratio_max_1": [[0, 2, 2]],
     }
     ceBulk = CEBulk(crystalstructure="fcc",
                     a=4.05,
                     size=[4, 4, 4],
                     basis_elements=[["Al", "Mg", "Si"]],
                     conc_args=conc_args,
                     db_name=db_name,
                     max_cluster_size=2,
                     max_cluster_dia=4.0)
     ceBulk.reconfigure_settings()
     ecis = get_example_ecis(bc=ceBulk)
     calc = CE(ceBulk, ecis)
     ceBulk.atoms.set_calculator(calc)
     return ceBulk
示例#26
0
    def get_calc(self, lat):
        db_name = "test_db_{}.db".format(lat)

        conc_args = {
            "conc_ratio_min_1": [[1, 0]],
            "conc_ratio_max_1": [[0, 1]],
        }
        a = 4.05
        ceBulk = CEBulk(crystalstructure=lat, a=a, size=[3, 3, 3],
                             basis_elements=[["Al", "Mg"]],
                             conc_args=conc_args,
                             db_name=db_name, max_cluster_size=3)
        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)
        return calc, ceBulk, eci
示例#27
0
    def test_raise_error_on_invalid_chem_pot(self):
        if not available:
            self.skipTest(avail_msg)

        bc = get_ternary_BC()
        ecis = get_example_ecis(bc=bc)
        ecis.pop('c1_1')
        atoms = bc.atoms.copy()
        calc = CE(atoms, bc, eci=ecis)
        atoms.set_calculator(calc)

        groups = [{"Al": 2}, {"Mg": 1, "Si": 1}]
        symbs = ["Al", "Mg", "Si"]
        T = 400
        with self.assertRaises(InvalidChemicalPotentialError):
            PseudoBinarySGC(atoms,
                            T,
                            chem_pot=-0.2,
                            symbols=symbs,
                            groups=groups)
示例#28
0
    def test_save_load_calculator(self):
        if not has_ase_with_ce:
            self.skipTest("ASE does not have CE")

        calc, ceBulk, eci = self.get_calc("fcc")
        calc_fname = "calculator.json"
        calc.save(calc_fname)
        calc2 = CE.load(calc_fname)
        os.remove(calc_fname)

        self.assertEqual(calc.BC.cluster_info, calc2.BC.cluster_info)
        self.assertEqual(calc.eci, calc2.eci)
        self.assertEqual(calc.get_cf(), calc2.get_cf())

        # Test to pickle a calculator
        import pickle
        pickled_string = pickle.dumps(calc)
        calc2 = pickle.loads(pickled_string)
        self.assertEqual(calc.BC.cluster_info, calc2.BC.cluster_info)
        self.assertEqual(calc.eci, calc2.eci)
        self.assertEqual(calc.get_cf(), calc2.get_cf())
示例#29
0
    def test_with_covariance_reac_crd(self):
        if not available:
            self.skipTest("ASE version does not have CE!")

        msg = ""
        no_throw = True
        try:
            bc = get_ternary_BC()
            atoms = bc.atoms.copy()
            ecis = get_example_ecis(bc=bc)
            calc = CE(atoms, bc, eci=ecis)
            #bc.atoms.set_calculator(calc)

            T = 200
            nn_names = [name for name in bc.cluster_family_names
                        if int(name[1]) == 2]

            mc = FixedNucleusMC(
                atoms, T, network_name=nn_names,
                network_element=["Mg", "Si"])

            elements = {"Mg": 4, "Si": 4}
            mc.insert_symbol_random_places("Mg", num=1, swap_symbs=["Al"])
            mc.grow_cluster(elements)
            conc_init = CovarianceCrdInitializer(
                fixed_nucl_mc=mc, matrix_element="Al",
                cluster_elements=["Mg", "Si"])
            
            mc.runMC(steps=100, init_cluster=False)

            match, match_msg = self._spherical_nano_particle_matches(conc_init)
            self.assertTrue(match, msg=match_msg)
        except Exception as exc:
            no_throw = False
            msg = str(exc)

        self.assertTrue(no_throw, msg=msg)
class PopulationVariance(object):
    """
    Object that estimates the covariance and the mean of all the
    correlation functions in the population
    """
    def __init__(self, BC):
        self.bc = BC
        cf_obj = CorrFunction(self.bc)
        self.init_cf = cf_obj.get_cf(self.bc.atoms)
        ecis = {key: 1.0
                for key in self.init_cf.keys()}  # ECIs do not matter here
        self.calc = CE(self.bc, ecis, initial_cf=self.init_cf)
        self.bc.atoms.set_calculator(self.calc)
        self.elements = self.bc.basis_elements[
            0]  # This should be updated to handle different site types
        self.status_every_sec = 30
        N = len(ecis.keys()) - 1
        self.cov_matrix = np.zeros((N, N))
        self.exp_value = np.zeros(N)

    def swap_random_atoms(self):
        """
        Changes the symbol of a random atom
        """
        indx = np.random.randint(low=0, high=len(self.bc.atoms))
        symb = self.bc.atoms[indx].symbol
        new_symb = self.elements[np.random.randint(low=0,
                                                   high=len(self.elements))]
        system_change = [(indx, symb, new_symb)]
        self.bc.atoms._calc.calculate(self.bc.atoms, ["energy"], system_change)

    def estimate(self, n_probe_structures=10000, fname=""):
        """
        Estimate the covariance matrix
        """

        if (fname != ""):
            if (not fname.endswith(".json")):
                raise ValueError(
                    "The program is going to write a json file so the file extension should be .json"
                )

        step = 0
        cfs = []
        cur_time = time.time()
        while (step < n_probe_structures):
            step += 1
            if (time.time() - cur_time > self.status_every_sec):
                print("Step {} of {}".format(step, n_probe_structures))
                cur_time = time.time()
            for i in range(len(self.bc.atoms)):
                self.swap_random_atoms()
            new_cfs = self.calc.get_cf()
            cf_array = [
                new_cfs[key] for key in self.init_cf.keys() if key != "c0"
            ]  # Make sure that the order is the same as in init_cf
            self.update_cov_matrix(cf_array)

        cfs = np.array(cfs)
        cov = self.cov_matrix / n_probe_structures
        mu = self.exp_value / n_probe_structures
        cov -= np.outer(mu, mu)
        return cov, mu

    def array2dict(self, cov, mu):
        """
        Converts an array to a dictionary
        """
        # Create dictionaries
        keys = self.init_cf.keys()
        del keys[keys.index("c0")]
        mu_dict = {keys[i]: mu[i] for i in range(len(keys))}

        cov_dict = {key: {} for key in keys}
        for i in range(len(keys)):
            for j in range(len(keys)):
                cov_dict[keys[i]][keys[j]] = cov[i, j]
        return cov_dict, mu_dict

    def update_cov_matrix(self, new_cfs):
        """
        Updates the covariance matrix
        """
        outer = np.outer(new_cfs, new_cfs)
        self.cov_matrix += outer
        self.exp_value += np.array(new_cfs)

    def save(self, eigval, eigvec, fname="eigenvectors.h5", fraction=0.95):
        """
        Store the lowest fraction of the eigenvectors
        """
        srt_indx = np.argsort(eigval)[::-1]
        eigval_srt = [eigval[indx] for indx in srt_indx]
        eigvec_srt = np.array([eigvec[:, indx] for indx in srt_indx]).T
        cumsum_eig = np.cumsum(eigval_srt)
        tot_sum = np.sum(eigval_srt)

        relative_sum = cumsum_eig / tot_sum

        max_indx = np.argmin(np.abs(relative_sum - fraction))
        matrix = eigvec_srt[:, :max_indx]
        eigen = eigval_srt[:max_indx]
        with h5.File(fname, 'w') as hf:
            dset_vec = hf.create_dataset("eigenvectors", data=matrix)
            dset_eigen = hf.create_dataset("eigenvalues", data=eigen)
            dset_eigen.attrs["fraction"] = fraction

        print("Result written to {}".format(fname))

    def diagonalize(self, cov, plot=False):
        """
        Diagonalize the covariance matrix
        """
        eigval, eigvec = np.linalg.eigh(cov)

        # Sort accorting to eigenvalues
        srt_indx = np.argsort(eigval)[::-1]
        eigval_srt = [eigval[indx] for indx in srt_indx]
        eigvec_srt = np.array([eigvec[:, indx] for indx in srt_indx]).T

        cumsum_eig = np.cumsum(eigval_srt)
        tot_sum = np.sum(eigval_srt)

        if (plot):
            x_val = np.arange(len(eigval))
            fig = plt.figure()
            ax = fig.add_subplot(1, 1, 1)
            ax.plot(x_val, cumsum_eig / tot_sum, ls="steps")
            ax.set_xlabel("Number of eigenvectors")
            ax.set_ylabel("Normalized variance")
        return eigval, eigvec

    def plot_eigen(self, eigenvalues, eigenvectors):
        """
        Creates a visualization of the eigenvectors and the eigenvalues
        NOTE: Eigenvalues and eigenvectors must NOT be sorted. They have
              to be given in the same order as returned by diagonalize
        """
        keys = self.init_cf.keys()
        del keys[keys.index("c0")]
        srt_indx = np.argsort(eigenvalues)[::-1]
        key_srt = [keys[indx] for indx in srt_indx]
        eigval_srt = [eigenvalues[indx] for indx in srt_indx]
        eigvec_srt = np.array([eigenvectors[:, indx] for indx in srt_indx]).T

        grid_kw = {"hspace": 0.0, "height_ratios": [1, 4]}
        fig, ax = plt.subplots(nrows=2, sharex=True, gridspec_kw=grid_kw)
        x = np.arange(len(eigvec_srt))
        cumsum = np.cumsum(eigval_srt)
        tot_sum = np.sum(eigval_srt)
        ax[0].plot(x, cumsum / tot_sum, ls="steps")
        keys_srt, eigvec_srt = self.sort_eigenvectors_by_size(keys, eigvec_srt)
        #ax[1].imshow( eigvec_srt, cmap="coolwarm", aspect="auto" )
        print(eigvec_srt[:, 0])

        # Separation lines to separate different sizes
        hlines = []
        size = 2
        for i, name in enumerate(keys_srt):
            prefix = "c{}".format(size)
            if (name.startswith(prefix)):
                hlines.append(i)
                size += 1

        for line in hlines:
            ax[1].axhline(line)
        return fig

    def sort_eigenvectors_by_size(self, keys, eigvec):
        """
        Sort the eigenvector values
        """
        srt_indx = np.argsort(keys)
        keys_srt = [keys[indx] for indx in srt_indx]
        eigvec_srt = np.array([eigvec[indx, :] for indx in srt_indx])
        return keys_srt, eigvec_srt