Пример #1
0
        internal void SetWavefunctions(KPoint otherPt, SymmetryList symmetries, List <int> orbitalMap)
        {
            if (this.wfk.Count != 0)
            {
                throw new InvalidOperationException();
            }

            for (int n = 0; n < otherPt.Wavefunctions.Count; n++)
            {
                var otherWfk = otherPt.Wavefunctions[n];
                var wfk      = new Wavefunction(otherWfk.Coeffs.Length);

                wfk.Energy        = otherWfk.Energy;
                wfk.FermiFunction = otherWfk.FermiFunction;

                for (int k = 0; k < otherWfk.Coeffs.Length; k++)
                {
                    int newOrb = symmetries.TransformOrbital(orbitalMap, k);

                    System.Diagnostics.Debug.Assert(wfk.Coeffs[newOrb] == 0);
                    wfk.Coeffs[newOrb] = otherWfk.Coeffs[k];
                }

                this.wfk.Add(wfk);
            }
        }
Пример #2
0
        void CreateBands(TightBinding tb, string name)
        {
            using (StreamReader r = new StreamReader(name))
            {
                string line = r.ReadLine();

                if (line != "# Grid")
                {
                    Console.WriteLine("Not an eigenvalues file!");
                    System.Environment.Exit(3);
                }

                int[] grid  = new int[3];
                int[] shift = new int[3];


                ParseGrid(grid, shift, line);

                if (line != "# Eigenvalues")
                {
                    Console.WriteLine("Not an eigenvalues file!");
                    System.Environment.Exit(2);
                }

                KptList kpts = new KptList();
                kpts.Mesh  = grid;
                kpts.Shift = shift;

                while (r.EndOfStream == false)
                {
                    line = r.ReadLine();
                    string[] elements = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                    KPoint kpt = new KPoint(new Vector3(double.Parse(elements[0]),
                                                        double.Parse(elements[1]),
                                                        double.Parse(elements[2])));

                    for (int i = 3; i < elements.Length; i++)
                    {
                        Wavefunction wfk = new Wavefunction(0);
                        wfk.Energy = double.Parse(elements[i]);

                        kpt.Wavefunctions.Add(wfk);
                    }

                    kpts.Kpts.Add(kpt);
                }

                CreateTetrahedronMesh(kpts);
                string outputfile = name + ".bands";

                using (StreamWriter w = new StreamWriter(outputfile))
                {
                    WriteBands(tb, kpts, w);
                }
            }
        }
Пример #3
0
        internal void SetWavefunctions(Matrix eigenvals, Matrix eigenvecs)
        {
            for (int n = 0; n < eigenvals.Rows; n++)
            {
                var wfk = new Wavefunction(eigenvecs.Rows);

                wfk.Energy = eigenvals[n, 0].RealPart;

                for (int c = 0; c < eigenvecs.Rows; c++)
                {
                    wfk.Coeffs[c] = eigenvecs[c, n];
                }

                this.wfk.Add(wfk);
            }
        }
Пример #4
0
        private Matrix[] CalcGreenFunction(TightBindingSuite.TightBinding tb, RpaParams p, KptList kmesh)
        {
            int orbitalCount = tb.Orbitals.Count;
            Matrix[] retval = new Matrix[kmesh.Kpts.Count];

            Complex denomFactor = new Complex(0, p.Temperature);

            for (int k = 0; k < kmesh.Kpts.Count; k++)
            {
                retval[k] = new Matrix(orbitalCount, orbitalCount);

                Matrix hamilt = tb.CalcHamiltonian(kmesh.Kpts[k].Value);
                Matrix vals, vecs;
                hamilt.EigenValsVecs(out vals, out vecs);

                for (int i = 0; i < orbitalCount; i++)
                {
                    for (int j = 0; j < orbitalCount; j++)
                    {
                        for (int n = 0; n < orbitalCount; n++)
                        {
                            var wfk = new Wavefunction(orbitalCount);

                            wfk.Energy = vals[n, 0].RealPart;

                            for (int c = 0; c < vecs.Rows; c++)
                            {
                                wfk.Coeffs[c] = vecs[c, n];
                            }

                            Complex coeff =
                                wfk.Coeffs[i].Conjugate() *
                                wfk.Coeffs[j];

                            Complex g = 1.0 / (p.Frequency + p.ChemicalPotential - wfk.Energy + denomFactor);

                            retval[k][i, j] += g * coeff;
                        }
                    }
                }

            }

            return retval;
        }
Пример #5
0
        private Matrix[] CalcGreenFunction(TightBindingSuite.TightBinding tb, RpaParams p, KptList kmesh)
        {
            int orbitalCount = tb.Orbitals.Count;
            Matrix[] retval = new Matrix[kmesh.Kpts.Count];

            Complex denomFactor = new Complex(0, p.Temperature);

            for (int k = 0; k < kmesh.Kpts.Count; k++)
            {
                retval[k] = new Matrix(orbitalCount, orbitalCount);

                Matrix hamilt = tb.CalcHamiltonian(kmesh.Kpts[k].Value);
                Matrix vals, vecs;
                hamilt.EigenValsVecs(out vals, out vecs);

                for (int i = 0; i < orbitalCount; i++)
                {
                    for (int j = 0; j < orbitalCount; j++)
                    {
                        for (int n = 0; n < orbitalCount; n++)
                        {
                            var wfk = new Wavefunction(orbitalCount);

                            wfk.Energy = vals[n, 0].RealPart;

                            for (int c = 0; c < vecs.Rows; c++)
                            {
                                wfk.Coeffs[c] = vecs[c, n];
                            }

                            Complex coeff =
                                wfk.Coeffs[i].Conjugate() *
                                wfk.Coeffs[j];

                            Complex g = 1.0 / (p.Frequency + p.ChemicalPotential - wfk.Energy + denomFactor);

                            retval[k][i, j] += g * coeff;
                        }
                    }
                }

            }

            return retval;
        }
Пример #6
0
        public Wavefunction Clone(List<int> orbitalMap)
        {
            Wavefunction retval = new Wavefunction(coeffs.Length);

            retval.Energy = Energy;
            retval.FermiFunction = FermiFunction;

            if (orbitalMap != null && orbitalMap.Count > 0)
            {
                for (int i = 0; i < coeffs.Length; i++)
                {
                    retval.coeffs[orbitalMap[i]] = coeffs[i];
                }
            }
            else
                retval.coeffs = (Complex[])coeffs.Clone();

            return retval;
        }
Пример #7
0
        public Wavefunction Clone(List <int> orbitalMap)
        {
            Wavefunction retval = new Wavefunction(coeffs.Length);

            retval.Energy        = Energy;
            retval.FermiFunction = FermiFunction;

            if (orbitalMap != null && orbitalMap.Count > 0)
            {
                for (int i = 0; i < coeffs.Length; i++)
                {
                    retval.coeffs[orbitalMap[i]] = coeffs[i];
                }
            }
            else
            {
                retval.coeffs = (Complex[])coeffs.Clone();
            }

            return(retval);
        }
Пример #8
0
        void DoDensityOfStates()
        {
            KptList ks = KMesh;

            using (StreamWriter outf = new StreamWriter(outputfile + ".dos"))
            {
                double smearing = TemperatureMesh[0];
                double effBeta  = 1 / smearing;

                double emin = double.MaxValue, emax = double.MinValue;

                for (int i = 0; i < ks.Kpts.Count; i++)
                {
                    KPoint kpt = ks.Kpts[i];

                    emin = Math.Min(emin, kpt.Wavefunctions.Min(x => x.Energy));
                    emax = Math.Max(emax, kpt.Wavefunctions.Max(x => x.Energy));
                }

                emin -= smearing * 10;
                emax += smearing * 10;

                emin -= MuMesh[0];
                emax -= MuMesh[0];

                int epts = 3000;

                double[] energyGrid = new double[epts];
                double[,] dos = new double[epts, Orbitals.Count + 1];
                int zeroIndex = 0;

                Output.WriteLine(
                    "Calculating DOS from {0} to {1} with finite temperature smearing {2}.",
                    emin, emax, smearing);

                Output.WriteLine("Using {0} kpts.", ks.Kpts.Count);

                for (int i = 0; i < epts; i++)
                {
                    energyGrid[i] = emin + (emax - emin) * i / (double)(epts - 1);

                    if (energyGrid[i] < 0)
                    {
                        zeroIndex = i;
                    }
                }

                for (int i = 0; i < ks.Kpts.Count; i++)
                {
                    KPoint kpt = ks.Kpts[i];

                    for (int j = 0; j < kpt.Wavefunctions.Count; j++)
                    {
                        Wavefunction wfk = kpt.Wavefunctions[j];

                        double energy = wfk.Energy - MuMesh[0];

                        int startIndex = FindIndex(energyGrid, energy - smearing * 10);
                        int endIndex   = FindIndex(energyGrid, energy + smearing * 10);

                        for (int k = startIndex; k <= endIndex; k++)
                        {
                            double ferm        = FermiFunction(energyGrid[k], energy, effBeta);
                            double smearWeight = ferm * (1 - ferm) * effBeta;
                            smearWeight *= ks.Kpts[i].Weight;

                            double weight = 0;
                            for (int l = 0; l < wfk.Coeffs.Length; l++)
                            {
                                if (PoleStates.Contains(l))
                                {
                                    continue;
                                }

                                double stateval = wfk.Coeffs[l].MagnitudeSquared;
                                weight += stateval;
                            }

                            if (PoleStates.Count == 0 && Math.Abs(weight - 1) > 1e-8)
                            {
                                throw new Exception("Eigenvector not normalized!");
                            }

                            dos[k, 0] += smearWeight * weight;

                            for (int state = 0; state < wfk.Coeffs.Length; state++)
                            {
                                if (PoleStates.Contains(state))
                                {
                                    continue;
                                }

                                double wtk = wfk.Coeffs[state].MagnitudeSquared;

                                dos[k, state + 1] += smearWeight * wtk;
                            }
                        }
                    }
                }

                // symmetrize DOS for equivalent orbitals.
                for (int k = 0; k < epts; k++)
                {
                    for (int i = 0; i < Orbitals.Count; i++)
                    {
                        double wtk   = dos[k, i + 1];
                        int    count = 1;

                        foreach (int equiv in Orbitals[i].Equivalent)
                        {
                            wtk += dos[k, equiv + 1];
                            count++;
                        }

                        dos[k, i + 1] = wtk / count;

                        foreach (int equiv in Orbitals[i].Equivalent)
                        {
                            dos[k, equiv + 1] = wtk / count;
                        }
                    }
                }

                if (emin < 0 && emax > 0)
                {
                    if (zeroIndex + 1 >= energyGrid.Length)
                    {
                        zeroIndex = energyGrid.Length - 2;
                    }

                    double slope = (dos[zeroIndex, 0] - dos[zeroIndex + 1, 0]) / (energyGrid[zeroIndex] - energyGrid[zeroIndex + 1]);
                    double dosEF = slope * (-energyGrid[zeroIndex]) + dos[zeroIndex, 0];

                    Output.WriteLine("Density of states at chemical potential: {0}", dosEF);

                    for (int i = 0; i < epts; i++)
                    {
                        outf.Write("{0}     ", energyGrid[i]);

                        for (int j = 0; j < Orbitals.Count + 1; j++)
                        {
                            outf.Write("{0}  ", dos[i, j]);
                        }

                        outf.WriteLine();
                    }
                }
            }
        }
Пример #9
0
        Matrix CalcX0(TightBinding tb, double freq, Vector3 q)
        {
            int    orbitalCount = tb.Orbitals.Count;
            int    size         = orbitalCount * orbitalCount;
            Matrix x            = new Matrix(size, size);

            Complex denom_factor = new Complex(0, 1e-4);

            //StreamWriter w = new StreamWriter(string.Format("qcont.{0}", q.ToString("0.000")));
            //bool writeThis = false;

            for (int l1 = 0; l1 < orbitalCount; l1++)
            {
                for (int l4 = 0; l4 < orbitalCount; l4++)
                {
                    for (int l3 = l1; l3 < orbitalCount; l3++)
                    {
                        for (int l2 = l4; l2 < orbitalCount; l2++)
                        {
                            int  i             = GetIndex(tb, l1, l2);
                            int  j             = GetIndex(tb, l3, l4);
                            bool foundSymmetry = false;

                            //if (l1 == 0 && l2 == 0 && l3 == 0 && l4 == 0)
                            //    writeThis = true;
                            //else
                            //writeThis = false;

                            //if (writeThis)
                            //    w.WriteLine("{0}{1}{2}{3}", l1, l2, l3, l4);

                            for (int s = 0; s < tb.Symmetries.Count; s++)
                            {
                                Symmetry sym = tb.Symmetries[s];

                                if (sym.OrbitalTransform == null || sym.OrbitalTransform.Count == 0)
                                {
                                    continue;
                                }

                                int newL1 = sym.OrbitalTransform[l1];
                                int newL2 = sym.OrbitalTransform[l2];
                                int newL3 = sym.OrbitalTransform[l3];
                                int newL4 = sym.OrbitalTransform[l4];

                                int newI = GetIndex(tb, newL1, newL2);
                                int newJ = GetIndex(tb, newL3, newL4);

                                if (newI == i && newJ == j)
                                {
                                    continue;
                                }

                                foundSymmetry = true;

                                if (newL1 > l1)
                                {
                                    foundSymmetry = false;
                                }
                                if (newL2 > l2)
                                {
                                    foundSymmetry = false;
                                }
                                if (newL3 > l3)
                                {
                                    foundSymmetry = false;
                                }
                                if (newL4 > l4)
                                {
                                    foundSymmetry = false;
                                }

                                if (foundSymmetry)
                                {
                                    x[i, j] = x[newI, newJ];
                                    x[j, i] = x[i, j].Conjugate();

                                    break;
                                }
                            }

                            if (foundSymmetry)
                            {
                                continue;
                            }

                            Complex total = 0;

                            for (int allkindex = 0; allkindex < tb.KMesh.AllKpts.Count; allkindex++)
                            {
                                Complex val = 0;
                                Vector3 k   = tb.KMesh.AllKpts[allkindex];
                                Vector3 kq  = k + q;

                                //List<int> kOrbitalMap;
                                //List<int> kqOrbitalMap;

                                //int kindex = tb.KMesh.IrreducibleIndex(k, tb.Lattice, tb.Symmetries, out kOrbitalMap);
                                //int kqindex = tb.KMesh.IrreducibleIndex(kq, tb.Lattice, tb.Symmetries, out kqOrbitalMap);
                                int kindex  = tb.KMesh.AllKindex(k, tb.Lattice);
                                int kqindex = tb.KMesh.AllKindex(kq, tb.Lattice);

                                System.Diagnostics.Debug.Assert(kindex == allkindex);

                                //int newL1 = TransformOrbital(kqOrbitalMap, l1);
                                //int newL2 = TransformOrbital(kOrbitalMap, l2);
                                //int newL3 = TransformOrbital(kqOrbitalMap, l3);
                                //int newL4 = TransformOrbital(kOrbitalMap, l4);

                                for (int n1 = 0; n1 < orbitalCount; n1++)
                                {
                                    Wavefunction wfk = Bands(tb, kindex, n1);
                                    double       e1  = wfk.Energy;
                                    double       f1  = wfk.FermiFunction;

                                    for (int n2 = 0; n2 < orbitalCount; n2++)
                                    {
                                        Wavefunction wfq = Bands(tb, kqindex, n2);
                                        double       e2  = wfq.Energy;
                                        double       f2  = wfq.FermiFunction;

                                        Complex coeff =
                                            wfq.Coeffs[l1] * wfq.Coeffs[l4].Conjugate() *
                                            wfk.Coeffs[l3] * wfk.Coeffs[l2].Conjugate();

                                        if (coeff == 0)
                                        {
                                            continue;
                                        }
                                        if (f1 < 1e-15 && f2 < 1e-15)
                                        {
                                            continue;
                                        }

                                        Complex denom_p = (e2 - e1 + freq + denom_factor);
                                        //Complex denom_n = (e2 - e1 - freq - denom_factor);
                                        //Complex lindhard = (f1 - f2) * (1.0 / denom_p + 1.0 / denom_n);
                                        Complex lindhard = (f1 - f2) * (1.0 / denom_p);
                                        Complex contrib  = coeff * lindhard;

                                        if (Math.Abs(f1 - f2) < 1e-11 && freq == 0.0)
                                        {
                                            contrib = coeff * f1 * (1 - f1) * Beta;
                                        }

                                        //w.Write("{0}  {1}   {2}   {3}           ", kindex, kqindex, n1, n2);
                                        //w.WriteLine("{0}   {1}   {2}   {3}   {4}", coeff, e1, e2, f1, f2);

                                        if (double.IsNaN(contrib.RealPart) || double.IsNaN(contrib.ImagPart))
                                        {
                                            throw new Exception("Found NaN when evaluating X0");
                                        }

                                        val += contrib;
                                    }
                                }

                                //w.WriteLine("{0}  {1}   total           {2} + {3}i", kindex, kqindex,
                                //    Math.Round(val.RealPart, 4), Math.Round(val.ImagPart, 4));

                                //Output.WriteLine(tb.KMesh.AllKpts[kindex].Weight.ToString());
                                val   *= tb.KMesh.AllKpts[kindex].Weight;
                                total += val;

                                //if (writeThis)
                                //    w.WriteLine("{0}        {1}              {2}", allkindex, total, val);
                            }

                            x[i, j] = total;
                            x[j, i] = total.Conjugate();

                            //if (writeThis)
                            //{
                            //    w.WriteLine("total for {0}{1}{2}{3}: {4}", l1, l2, l3, l4, total);
                            //    w.WriteLine("---------------------");
                            //}
                        }
                    }
                }
            }

            //w.Close();

            return(x);
        }
Пример #10
0
        internal void SetWavefunctions(KPoint otherPt, SymmetryList symmetries, List<int> orbitalMap)
        {
            if (this.wfk.Count != 0) throw new InvalidOperationException();

            for (int n = 0; n < otherPt.Wavefunctions.Count; n++)
            {
                var otherWfk = otherPt.Wavefunctions[n];
                var wfk = new Wavefunction(otherWfk.Coeffs.Length);

                wfk.Energy = otherWfk.Energy;
                wfk.FermiFunction = otherWfk.FermiFunction;

                for (int k = 0; k < otherWfk.Coeffs.Length; k++)
                {
                    int newOrb = symmetries.TransformOrbital(orbitalMap, k);

                    System.Diagnostics.Debug.Assert(wfk.Coeffs[newOrb] == 0);
                    wfk.Coeffs[newOrb] = otherWfk.Coeffs[k];

                }

                this.wfk.Add(wfk);
            }
        }
Пример #11
0
        internal void SetWavefunctions(Matrix eigenvals, Matrix eigenvecs)
        {
            for (int n = 0; n < eigenvals.Rows; n++)
            {
                var wfk = new Wavefunction(eigenvecs.Rows);

                wfk.Energy = eigenvals[n, 0].RealPart;

                for (int c = 0; c < eigenvecs.Rows; c++)
                {
                    wfk.Coeffs[c] = eigenvecs[c, n];
                }

                this.wfk.Add(wfk);
            }
        }
Пример #12
0
        void CreateBands(TightBinding tb, string name)
        {
            using (StreamReader r = new StreamReader(name))
            {
                string line = r.ReadLine();

                if (line != "# Grid")
                {
                    Console.WriteLine("Not an eigenvalues file!");
                    System.Environment.Exit(3);
                }

                int[] grid = new int[3];
                int[] shift = new int[3];

                ParseGrid(grid, shift, line);

                if (line != "# Eigenvalues")
                {
                    Console.WriteLine("Not an eigenvalues file!");
                    System.Environment.Exit(2);
                }

                KptList kpts = new KptList();
                kpts.Mesh = grid;
                kpts.Shift = shift;

                while (r.EndOfStream == false)
                {
                    line = r.ReadLine();
                    string[] elements = line.Split(new char[] { ' '}, StringSplitOptions.RemoveEmptyEntries );

                    KPoint kpt = new KPoint(new Vector3(double.Parse(elements[0]),
                                                        double.Parse(elements[1]),
                                                        double.Parse(elements[2])));

                    for (int i = 3; i < elements.Length; i++)
                    {
                        Wavefunction wfk = new Wavefunction(0);
                        wfk.Energy = double.Parse(elements[i]);

                        kpt.Wavefunctions.Add(wfk);
                    }

                    kpts.Kpts.Add(kpt);
                }

                CreateTetrahedronMesh(kpts);
                string outputfile = name + ".bands";

                using (StreamWriter w = new StreamWriter(outputfile))
                {
                    WriteBands(tb, kpts, w);
                }
            }
        }