Пример #1
0
        void OutputBands()
        {
            KptList ks = KMesh;

            using (StreamWriter w = new StreamWriter("eigenvalues.k"))
            {
                w.WriteLine("# Grid");
                w.WriteLine("{0}  {1}  {2}  {3}  {4}  {5}", ks.Mesh[0], ks.Mesh[1], ks.Mesh[2],
                            ks.Shift[0], ks.Shift[1], ks.Shift[2]);

                w.WriteLine("# Eigenvalues");

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

                    w.Write("{0}    {1}    {2}             ",
                            kpt.Value.X, kpt.Value.Y, kpt.Value.Z);

                    for (int j = 0; j < kpt.Wavefunctions.Count; j++)
                    {
                        w.Write("{0}   ", kpt.Wavefunctions[j].Energy);
                    }

                    w.WriteLine();
                }
            }
        }
Пример #2
0
        BandTetrahedron GetTetrahedron(TightBinding tb, KPoint kpt, KptList kpts)
        {
            List <Pair <int, double> > lst = new List <Pair <int, double> >();

            double[] weights = new double[kpts.Kpts.Count];
            for (int j = 0; j < kpts.Kpts.Count; j++)
            {
                double distance = CalcDistance(tb, kpts.Kpts[j].Value, kpt.Value);

                weights[j] = 1 / (distance + 0.00001);
            }

            for (int j = 0; j < weights.Length; j++)
            {
                lst.Add(new Pair <int, double>(j, weights[j]));
            }

            lst.Sort((x, y) => { return(y.Second.CompareTo(x.Second)); });

            lst.RemoveRange(4, lst.Count - 4);
            List <int> ilist = lst.Select(x => x.First).ToList();

            BandTetrahedron retval = new BandTetrahedron(tb, kpt.Value, kpts, ilist);

            return(retval);
        }
Пример #3
0
        void WriteBands(TightBinding tb, KptList kpts, StreamWriter w)
        {
            int bandCount = kpts.Kpts[0].Wavefunctions.Count;


            BandTetrahedron tet = null;

            for (int i = 0; i < tb.KPath.Kpts.Count; i++)
            {
                var kpt = tb.KPath.Kpts[i];

                if (tet == null || tet.Contains(kpt) == false)
                {
                    GetTetrahedron(tb, kpt, kpts);
                }

                w.Write(i);
                w.Write("   ");

                for (int band = 0; band < bandCount; band++)
                {
                    double energy = tet.Interpolate(kpt);

                    w.Write("{0}  ", energy);
                }

                w.WriteLine();
            }
        }
Пример #4
0
        public KptList Clone()
        {
            KptList retval = new KptList();

            retval.allKpts.AddRange(allKpts.Select(x => x.Clone()));
            retval.kpts.AddRange(kpts.Select(x => x.Clone()));

            if (mesh != null)
            {
                retval.mesh = (int[])mesh.Clone();
            }
            if (shift != null)
            {
                retval.shift = (int[])shift.Clone();
            }

            retval.gammaCentered = gammaCentered;

            foreach (KeyValuePair <int, int> var in Nvalues)
            {
                retval.Nvalues.Add(var.Key, var.Value);
            }
            foreach (KeyValuePair <int, int> var in AllNvalues)
            {
                retval.AllNvalues.Add(var.Key, var.Value);
            }

            retval.sdir   = sdir;
            retval.tdir   = tdir;
            retval.origin = origin;

            return(retval);
        }
Пример #5
0
        private void RpaChi0Thread(object obj)
        {
            RpaThreadInfo info = (RpaThreadInfo)obj;

            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();
            TightBinding     tb   = info.tb;
            List <RpaParams> rpa  = info.RpaParams;
            KptList          qpts = info.qpts;

            for (int i = 0; i < rpa.Count; i++)
            {
                SetTemperature(tb, rpa[i].Temperature, rpa[i].ChemicalPotential);

                rpa[i].X0 = CalcX0(tb, rpa[i].Frequency, qpts.Kpts[rpa[i].Qindex]);

                if (i == 0 && info.PrimaryThread)
                {
                    long     time = watch.ElapsedTicks * rpa.Count;
                    TimeSpan s    = new TimeSpan(time);

                    Output.WriteLine("Estimated total time {0:+hh.mm}", s);
                }
                Complex val = rpa[i].X0.Trace();


                Output.Write("q = {0}, T = {1:0.000}, mu = {2:0.000}, omega = {3:0.0000}",
                             rpa[i].Qindex + 1, rpa[i].Temperature, rpa[i].ChemicalPotential, rpa[i].Frequency);
                Output.WriteLine(", Tr(X_0) = {0}", val.ToString("0.0000"));
            }
        }
Пример #6
0
        void OutputBands(TightBinding tb, KptList ks,
                         List <RpaParams> rpa, MatrixGetter g, string name)
        {
            using (StreamWriter w = new StreamWriter("eigenvalues." + name + ".q"))
            {
                w.WriteLine("# Grid");
                w.WriteLine("{0}  {1}  {2}  {3}  {4}  {5}", ks.Mesh[0], ks.Mesh[1], ks.Mesh[2],
                            ks.Shift[0], ks.Shift[1], ks.Shift[2]);

                w.WriteLine("# Eigenvalues");

                foreach (var rpa_i in rpa)
                {
                    var qpt = rpa_i.QptValue;

                    w.Write("{0}    {1}    {2}             ",
                            qpt.X, qpt.Y, qpt.Z);

                    Matrix chi     = g(rpa_i);
                    Matrix evalues = chi.EigenValues();

                    for (int j = 0; j < evalues.Rows; j++)
                    {
                        w.Write("{0}   ", evalues[j, 0].RealPart);
                    }

                    w.WriteLine();
                }
            }
        }
Пример #7
0
        public void WriteGraceHeader(KptList kpath)
        {
            file.WriteLine("@with g0");

            var pairs = kpath.Kpts.Select(
                (kpt, index) => new Pair <int, KPoint>(index, kpt)).ToArray();

            var pts = (
                from val in pairs
                where string.IsNullOrEmpty(val.Second.Name) == false
                select val
                ).ToArray();


            file.WriteLine("@    xaxis  tick spec type both");
            file.WriteLine("@    xaxis  tick spec {0}", pts.Length);
            for (int i = 0; i < pts.Length; i++)
            {
                string label = pts[i].Second.Name;

                if (label.StartsWith("G"))
                {
                    label = @"\xG\f{}" + label.Substring(1);
                }

                label = label.Replace("$_", @"\s");
                label = label.Replace("$^", @"\S");
                label = label.Replace("$.", @"\N");

                file.WriteLine("@    xaxis  tick major {0}, {1}", i, pts[i].First);
                file.WriteLine("@    xaxis  ticklabel {0}, \"{1}\"", i, label);
            }
        }
Пример #8
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);
                }
            }
        }
Пример #9
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);
                }
            }
        }
Пример #10
0
        public static KptPlane GeneratePlane(Lattice lattice, Vector3[] points, KptList qmesh)
        {
            Vector3 diff_1 = points[1] - points[0];
            Vector3 diff_2 = points[2] - points[0];
            Vector3 norm   = Vector3.CrossProduct(diff_1, diff_2);

            KptPlane retval = new KptPlane();

            retval.SetLattice(lattice);

            retval.mesh  = (int[])qmesh.Mesh.Clone();
            retval.shift = new int[3];

            retval.origin = points[0];
            retval.sdir   = diff_1;
            retval.tdir   = diff_2;

            NormalizeST(lattice, retval);

            int zmax = qmesh.Mesh[2] * 2;
            int ymax = qmesh.Mesh[1] * 2;
            int xmax = qmesh.Mesh[0] * 2;

            List <KPoint> planePoints = new List <KPoint>();

            for (int i = 0; i < qmesh.Kpts.Count; i++)
            {
                var qpt = qmesh.Kpts[i];

                Vector3 diff = lattice.ReciprocalExpand(qpt.Value) - points[0];
                double  dot  = Math.Abs(diff.DotProduct(norm));

                if (dot < 1e-8)
                {
                    double s, t;

                    retval.GetPlaneST(qpt, out s, out t);
                    retval.AddKpt(qpt);
                }
            }

            // now sort q-points to lay them in the s,t plane.
            retval.SortKpoints();

            Vector3 sd = retval.sdir / SmallestNonzero(retval.sdir);
            Vector3 td = retval.tdir / SmallestNonzero(retval.tdir);

            Output.WriteLine("Plane horizontal direction: {0}", sd);
            Output.WriteLine("Plane vertical direction: {0}", td);

            Output.WriteLine("Plane horizontal vector: {0}", retval.sdir);
            Output.WriteLine("Plane vertical vector: {0}", retval.tdir);

            return(retval);
        }
Пример #11
0
        public static KptPlane GeneratePlane(Lattice lattice, Vector3[] points, KptList qmesh)
        {
            Vector3 diff_1 = points[1] - points[0];
            Vector3 diff_2 = points[2] - points[0];
            Vector3 norm = Vector3.CrossProduct(diff_1, diff_2);

            KptPlane retval = new KptPlane();

            retval.SetLattice(lattice);

            retval.mesh = (int[])qmesh.Mesh.Clone();
            retval.shift = new int[3];

            retval.origin = points[0];
            retval.sdir = diff_1;
            retval.tdir = diff_2;

            NormalizeST(lattice, retval);

            int zmax = qmesh.Mesh[2] * 2;
            int ymax = qmesh.Mesh[1] * 2;
            int xmax = qmesh.Mesh[0] * 2;

            List<KPoint> planePoints = new List<KPoint>();
            for (int i = 0; i < qmesh.Kpts.Count; i++)
            {
                var qpt = qmesh.Kpts[i];

                Vector3 diff = lattice.ReciprocalExpand(qpt.Value) - points[0];
                double dot = Math.Abs(diff.DotProduct(norm));

                if (dot < 1e-8)
                {
                    double s, t;

                    retval.GetPlaneST(qpt, out s, out t);
                    retval.AddKpt(qpt);
                }
            }

            // now sort q-points to lay them in the s,t plane.
            retval.SortKpoints();

            Vector3 sd = retval.sdir / SmallestNonzero(retval.sdir);
            Vector3 td = retval.tdir / SmallestNonzero(retval.tdir);

            Output.WriteLine("Plane horizontal direction: {0}", sd);
            Output.WriteLine("Plane vertical direction: {0}", td);

            Output.WriteLine("Plane horizontal vector: {0}", retval.sdir);
            Output.WriteLine("Plane vertical vector: {0}", retval.tdir);

            return retval;
        }
Пример #12
0
            void ReadKPathSection(string section, ref KptList path)
            {
                if (path != null)
                {
                    ThrowEx(section + " found twice.");
                }

                Vector3 lastKpt = Vector3.Zero;

                char[]       array   = new char[] { ' ' };
                const double ptScale = 400;
                int          ptCount = 0;

                path = new KptList();
                while (EOF == false && LineType != LineType.NewSection)
                {
                    double dummy;

                    string[] vals = Line.Split(array, StringSplitOptions.RemoveEmptyEntries);
                    if (vals.Length != 3 && vals.Length != 4)
                    {
                        ThrowEx("Cannot understand path entry.");
                    }

                    string text = Line;
                    string name = string.Empty;

                    if (double.TryParse(vals[0], out dummy) == false)
                    {
                        text = text.Substring(text.IndexOf(' '));
                        name = vals[0];
                    }

                    Vector3 vecval = Vector3.Parse(text);
                    Vector3 kpt    = vecval;
                    double  length = (kpt - lastKpt).Magnitude;

                    if (ptCount == 0)
                    {
                        path.AddPts(kpt, kpt, 1);
                    }
                    else
                    {
                        path.AddPts(lastKpt, kpt, Math.Max((int)(ptScale * length), 1));
                    }
                    path.Kpts[path.Kpts.Count - 1].Name = name;
                    ptCount++;

                    lastKpt = kpt;

                    ReadNextLine();
                }
            }
Пример #13
0
        private static void NormalizeST(Lattice lattice, KptList retval)
        {
            retval.sdir /= retval.sdir.Magnitude;
            retval.tdir /= retval.tdir.Magnitude;

            retval.sdir /= GammaInDirection(lattice, retval.sdir).Magnitude;
            retval.tdir /= GammaInDirection(lattice, retval.tdir).Magnitude;

            // double them to make s and t 1 at the zone boundary, instead of 0.5.
            retval.sdir *= 2;
            retval.tdir *= 2;
        }
Пример #14
0
        private void CalcNelec()
        {
            KptList ks = KMesh;

            Matrix[] eigenvals = new Matrix[ks.Kpts.Count];

            for (int i = 0; i < KMesh.Kpts.Count; i++)
            {
                Matrix vals = new Matrix(Orbitals.Count, Orbitals.Count);

                for (int j = 0; j < Orbitals.Count; j++)
                {
                    vals[j, 0] = ks.Kpts[i].Wavefunctions[j].Energy;
                }

                eigenvals[i] = vals;
            }

            double beta = 1 / TemperatureMesh[0];

            double N = FindNelec(ks, eigenvals, MuMesh[0], beta);

            if (specifiedNelec)
            {
                MuMesh = new double[Nelec.Length];

                for (int i = 0; i < MuMesh.Length; i++)
                {
                    MuMesh[i] = FindMu(ks, eigenvals, Nelec[i], beta);
                }
            }
            else
            {
                Nelec = new double[MuMesh.Length];

                for (int i = 0; i < MuMesh.Length; i++)
                {
                    Nelec[i] = FindNelec(ks, eigenvals, MuMesh[i], beta);
                }
            }

            Output.WriteLine("           mu         Nelec");

            for (int i = 0; i < MuMesh.Length; i++)
            {
                MuMesh[i] = FindMu(ks, eigenvals, Nelec[i], beta);

                Output.WriteLine("     {0:0.000000}      {1:0.000000}", MuMesh[i], Nelec[i]);
            }
        }
Пример #15
0
        public static KptList DefaultPath(Lattice l)
        {
            const int pts = 40;
            KptList retval = new KptList();

            retval.Kpts.Add(new KPoint(Vector3.Zero));
            retval.AddPts(Vector3.Zero, l.G1 * Math.PI, pts);
            retval.AddPts(l.G1 * Math.PI, (l.G1 + l.G2) * Math.PI, pts);
            retval.AddPts((l.G1 + l.G2) * Math.PI, l.G2 * Math.PI, pts);
            retval.AddPts(l.G2 * Math.PI, l.G3 * Math.PI, pts);
            retval.AddPts(l.G3 * Math.PI, Vector3.Zero, pts);

            return retval;
        }
Пример #16
0
        public static KptList DefaultPath(Lattice l)
        {
            const int pts    = 40;
            KptList   retval = new KptList();

            retval.Kpts.Add(new KPoint(Vector3.Zero));
            retval.AddPts(Vector3.Zero, l.G1 * Math.PI, pts);
            retval.AddPts(l.G1 * Math.PI, (l.G1 + l.G2) * Math.PI, pts);
            retval.AddPts((l.G1 + l.G2) * Math.PI, l.G2 * Math.PI, pts);
            retval.AddPts(l.G2 * Math.PI, l.G3 * Math.PI, pts);
            retval.AddPts(l.G3 * Math.PI, Vector3.Zero, pts);

            return(retval);
        }
Пример #17
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;
        }
Пример #18
0
        private double FindNelec(KptList ks, Matrix[] eigenvals, double mu, double beta)
        {
            double N = 0;

            for (int i = 0; i < ks.Kpts.Count; i++)
            {
                double weight = ks.Kpts[i].Weight;

                for (int j = 0; j < eigenvals[i].Rows; j++)
                {
                    double energy = eigenvals[i][j, 0].RealPart;
                    double npt    = 2 * FermiFunction(energy, mu, beta);

                    N += npt * weight;
                }
            }
            return(N);
        }
Пример #19
0
            private void GenerateKmesh()
            {
                tb.kmesh = KptList.GenerateMesh(tb.lattice, tb.kgrid, tb.kshift, tb.symmetries, false);

                Output.WriteLine("Applied {0} symmetries to get {1} irreducible kpoints from {2}.",
                                 tb.symmetries.Count, tb.kmesh.Kpts.Count, tb.kmesh.AllKpts.Count);

                using (StreamWriter writer = new StreamWriter("kpts"))
                {
                    for (int i = 0; i < tb.kmesh.Kpts.Count; i++)
                    {
                        Vector3 red = tb.lattice.ReducedCoords(tb.kmesh.Kpts[i].Value);

                        writer.WriteLine("{0}     {1}", i, red);
                    }
                }

                if (tb.UseQPlane == false)
                {
                    tb.qmesh = KptList.GenerateMesh(tb.lattice, tb.qgrid, tb.qshift,
                                                    tb.symmetries, false);

                    Output.WriteLine("Found {0} qpoints in the zone.", tb.qmesh.Kpts.Count);
                }

                if (tb.setQplane)
                {
                    tb.qplane = KptList.GeneratePlane(tb.lattice, tb.qplaneDef, tb.symmetries, tb.qgrid, null);
                    Output.WriteLine("Found {0} irreducible qpoints in the plane of {1} qpoints.",
                                     tb.qplane.Kpts.Count, tb.qplane.AllKpts.Count);


                    using (StreamWriter writer = new StreamWriter("qpts"))
                    {
                        for (int i = 0; i < tb.qplane.Kpts.Count; i++)
                        {
                            Vector3 red = tb.lattice.ReducedCoords(tb.qplane.Kpts[i].Value);

                            writer.WriteLine("{0}     {1}", i, red);
                        }
                    }
                }
            }
Пример #20
0
        public BandTetrahedron(TightBinding tb, Vector3 anchor, KptList kpts, List<int> indices)
        {
            for (int i = 0; i < indices.Count; i++)
            {
                KPoint kpt = kpts.Kpts[indices[i]].Clone();

                Vector3 delta = kpt.Value - anchor;

                ShiftDelta(ref delta, tb.Lattice.G1);
                ShiftDelta(ref delta, tb.Lattice.G2);
                ShiftDelta(ref delta, tb.Lattice.G3);

                kpt.Value = delta + anchor;

                this.kpts.Add(kpt);
            }

            CalculateVelocityMatrix();
        }
Пример #21
0
        public BandTetrahedron(TightBinding tb, Vector3 anchor, KptList kpts, List <int> indices)
        {
            for (int i = 0; i < indices.Count; i++)
            {
                KPoint kpt = kpts.Kpts[indices[i]].Clone();

                Vector3 delta = kpt.Value - anchor;

                ShiftDelta(ref delta, tb.Lattice.G1);
                ShiftDelta(ref delta, tb.Lattice.G2);
                ShiftDelta(ref delta, tb.Lattice.G3);

                kpt.Value = delta + anchor;

                this.kpts.Add(kpt);
            }

            CalculateVelocityMatrix();
        }
Пример #22
0
        public void RunRpa(TightBinding tb, KptList qpts, bool plane)
        {
            List <KPoint>    QMesh = qpts.Kpts;
            List <RpaParams> rpa   = CreateRpaParameterList(tb, QMesh);

            Output.WriteLine("Calculating susceptibility for {0} q-points.", QMesh.Count);

            CalcSusceptibility(tb, qpts, rpa);

            if (plane)
            {
                SaveMatricesQPlane(tb, QMesh, rpa, x => x.X0, "chi_0");
                SaveMatricesQPlane(tb, QMesh, rpa, x => x.Xs, "chi_s");
                SaveMatricesQPlane(tb, QMesh, rpa, x => x.Xc, "chi_c");
            }
            else
            {
                OutputBands(tb, qpts, rpa, CalcX0 => CalcX0.X0, "chi_0");
            }
        }
Пример #23
0
        public void RunRpa(TightBinding tb, KptList qpts, bool plane)
        {
            List<KPoint> QMesh = qpts.Kpts;
            List<RpaParams> rpa = CreateRpaParameterList(tb, QMesh);

            Output.WriteLine("Calculating susceptibility for {0} q-points.", QMesh.Count);

            CalcSusceptibility(tb, qpts, rpa);

            if (plane)
            {
                SaveMatricesQPlane(tb, QMesh, rpa, x => x.X0, "chi_0");
                SaveMatricesQPlane(tb, QMesh, rpa, x => x.Xs, "chi_s");
                SaveMatricesQPlane(tb, QMesh, rpa, x => x.Xc, "chi_c");
            }
            else
            {
                OutputBands(tb, qpts, rpa, CalcX0 => CalcX0.X0, "chi_0");
            }
        }
Пример #24
0
        void Run(string inputfile)
        {
            using (StreamWriter w = new StreamWriter("gplot.out"))
            {
                Output.SetFile(w);

                TightBindingSuite.TightBinding tb = new TightBindingSuite.TightBinding();
                tb.LoadTB(inputfile);

                RpaParams p = new RpaParams(0, Vector3.Zero, tb.TemperatureMesh[0], tb.FrequencyMesh[0], tb.MuMesh[0]);
                KptList kmesh = KptList.GenerateMesh(
                    tb.Lattice, tb.KMesh.Mesh, null, tb.Symmetries, true);

                Matrix[] green = CalcGreenFunction(tb, p, kmesh);

                while (true)
                {
                    WriteGreenFunction(tb, green, kmesh);
                };
            }
        }
            void ReadKPathSection(string section, ref KptList path)
            {
                if (path != null)
                    ThrowEx(section + " found twice.");

                Vector3 lastKpt = Vector3.Zero;
                char[] array = new char[] { ' ' };
                const double ptScale = 400;
                int ptCount = 0;

                path = new KptList();
                while (EOF == false && LineType != LineType.NewSection)
                {
                    double dummy;

                    string[] vals = Line.Split(array, StringSplitOptions.RemoveEmptyEntries);
                    if (vals.Length != 3 && vals.Length != 4)
                        ThrowEx("Cannot understand path entry.");

                    string text = Line;
                    string name = string.Empty;

                    if (double.TryParse(vals[0], out dummy) == false)
                    {
                        text = text.Substring(text.IndexOf(' '));
                        name = vals[0];
                    }

                    Vector3 vecval = Vector3.Parse(text);
                    Vector3 kpt = vecval;
                    double length = (kpt - lastKpt).Magnitude;

                    if (ptCount == 0)
                    {
                        path.AddPts(kpt, kpt, 1);
                    }
                    else
                    {
                        path.AddPts(lastKpt, kpt, Math.Max((int)(ptScale * length), 1));
                    }
                    path.Kpts[path.Kpts.Count - 1].Name = name;
                    ptCount++;

                    lastKpt = kpt;

                    ReadNextLine();
                }
            }
Пример #26
0
        public static KptList oldGenerateMesh(Lattice lattice, int[] kgrid, int[] shift, SymmetryList syms, bool includeEnds)
        {
            bool centerGamma = false;
            KptList retval = new KptList();
            int zmax = kgrid[2] * 2;
            int ymax = kgrid[1] * 2;
            int xmax = kgrid[0] * 2;

            if (shift == null)
                shift = new int[3];

            retval.mesh = (int[])kgrid.Clone();
            retval.shift = (int[])shift.Clone();
            retval.gammaCentered = centerGamma;

            int index = 0;
            Vector3 gridVector = new Vector3(kgrid[0], kgrid[1], kgrid[2]);

            SymmetryList compatSyms = new SymmetryList();
            foreach (var symmetry in syms)
            {
                Vector3 grid2 = symmetry.Value * gridVector;
                for (int gi = 0; gi < 3; gi++)
                    grid2[gi] = Math.Abs(grid2[gi]);

                if (grid2 == gridVector)
                {
                    compatSyms.Add(symmetry);
                }
            }

            for (int k = 0; k <= zmax; k += 2)
            {
                for (int j = 0; j <= ymax; j += 2)
                {
                    for (int i = 0; i <= xmax; i += 2)
                    {
                        if (includeEnds == false)
                        {
                            if (k == zmax) break;
                            if (i == xmax) break;
                            if (j == ymax) break;
                        }

                        int N = retval.KptToInteger(i, j, k);
                        bool foundSym = false;

                        double dx = (i + shift[0]) / (double)xmax;
                        double dy = (j + shift[1]) / (double)ymax;
                        double dz = (k + shift[2]) / (double)zmax;
                        int symN = N;
                        List<int> orbitals = null;

                        if (centerGamma)
                        {
                            if (kgrid[0] > 1) dx -= 0.5;
                            if (kgrid[1] > 1) dy -= 0.5;
                            if (kgrid[2] > 1) dz -= 0.5;
                        }

                        Vector3 pt = CalcK(lattice, dx, dy, dz);

            #if DEBUG
                        int testi, testj, testk;
                        retval.ReduceKpt(lattice, new Vector3(pt), out testi, out testj, out testk);

                        //System.Diagnostics.Debug.Assert(i == testi);
                        //System.Diagnostics.Debug.Assert(j == testj);
                        //System.Diagnostics.Debug.Assert(k == testk);

            #endif
                        foreach (var symmetry in compatSyms)
                        {
                            Vector3 Tpt = symmetry.Value * pt;

                            if (Tpt == pt)
                                continue;

                            Vector3 red = lattice.ReducedCoords(Tpt, true);

                            int newi = (int)Math.Round(xmax * red.X - shift[0]);
                            int newj = (int)Math.Round(ymax * red.Y - shift[1]);
                            int newk = (int)Math.Round(zmax * red.Z - shift[2]);

                            if (newi % 2 != 0 || newj % 2 != 0 || newk % 2 != 0)
                                continue;

                            symN = retval.KptToInteger(newi, newj, newk);

                            if (symN < N)
                            {
                                foundSym = true;

                                if (symmetry.OrbitalTransform.Count > 0)
                                {
                                    orbitals = symmetry.OrbitalTransform;
                                }
                            }

                            if (foundSym)
                                break;
                        }

                        Vector3 kptValue = CalcK(lattice, dx, dy, dz);

                        retval.allKpts.Add(new KPoint(kptValue));

                        if (retval.Nvalues.ContainsKey(N))
                        {

                        }
                        else if (foundSym == false)
                        {
                            retval.kpts.Add(new KPoint(kptValue));
                            retval.Nvalues.Add(N, index);
                            index++;
                        }
                        else
                        {
                            int newIndex = retval.Nvalues[symN];
                            retval.kpts[newIndex].Weight++;
                            retval.kpts[newIndex].AddOrbitalSymmetry(orbitals);

                            retval.Nvalues.Add(N, newIndex);
                        }
                    }
                }
            }

            int count = kgrid[0] * kgrid[1] * kgrid[2];
            for (int i = 0; i < retval.kpts.Count; i++)
            {
                retval.kpts[i].Weight /= count;
                retval.allKpts[i].Weight /= count;
            }

            if (includeEnds)
            {
                retval.allKpts.Sort((x, y) => x.Value.Z.CompareTo(y.Value.Z));

                List<int> removeThese = new List<int>();
                List<int> equivKpt = new List<int>();

                // read this value first, because the size of the array will change.
                int kptCount = retval.AllKpts.Count;
                for (int kindex = 0; kindex < kptCount; kindex++)
                {
                    if (removeThese.Contains(kindex))
                        continue;

                    Vector3 kpt = retval.allKpts[kindex].Value;
                    double dist = kpt.Magnitude;

                    equivKpt.Clear();

                    for (int k = -1; k <= 1; k++)
                    {
                        for (int j = -1; j <= 1; j++)
                        {
                            for (int i = -1; i <= 1; i++)
                            {
                                if (i == 0 && j == 0 && k == 0)
                                    continue;

                                Vector3 pt = kpt +
                                    i * lattice.G1 +
                                    j * lattice.G2 +
                                    k * lattice.G3;

                                double newDist = pt.Magnitude;

                                if (newDist < dist - 1e-6)
                                {
                                    foreach (var value in equivKpt)
                                    {
                                        if (removeThese.Contains(value) == false)
                                            removeThese.Add(value);
                                    }

                                    equivKpt.Clear();

                                    int search = retval.AllKpts.FindIndex(x => (x.Value - pt).Magnitude < 1e-6);

                                    if (search != -1)
                                    {
                                        if (removeThese.Contains(kindex) == false)
                                            removeThese.Add(kindex);

                                        // break out of the loop
                                        k = 1; j = 1; i = 2;
                                    }
                                    else
                                    {
                                        retval.allKpts[kindex].Value = pt;
                                        kpt = pt;
                                        dist = newDist;

                                        // reset variables since we updated this kpoint value.
                                        k = -1;
                                        j = -1;
                                        i = -2;
                                    }
                                }
                                else if (Math.Abs(dist - newDist) < 1e-6)
                                {
                                    int search = retval.AllKpts.FindIndex(x => (x.Value - pt).Magnitude < 1e-6);

                                    if (search != -1)
                                    {
                                        if (removeThese.Contains(search))
                                        {
                                            k = 1; j = 1; i = 2;
                                            removeThese.Add(kindex);
                                            break;
                                        }

                                        equivKpt.Add(search);
                                        continue;
                                    }

                                    equivKpt.Add(retval.allKpts.Count);
                                    retval.allKpts.Add(new KPoint(pt));
                                }
                            }
                        }
                    }
                }

                // sort in reverse order
                removeThese.Sort((x, y) => -x.CompareTo(y));

                for (int i = 0; i < removeThese.Count; i++)
                {
                    retval.allKpts.RemoveAt(removeThese[i]);
                }

                retval.allKpts.Sort((x, y) => x.Value.Z.CompareTo(y.Value.Z));
            }
            #if DEBUG
            if (!includeEnds)
            {
                double check = 0;
                for (int i = 0; i < retval.kpts.Count; i++)
                    check += retval.kpts[i].Weight;

                System.Diagnostics.Debug.Assert(Math.Abs(check - 1) < 1e-8);
            }
            #endif

            return retval;
        }
Пример #27
0
 void CreateTetrahedronMesh(KptList kpts)
 {
 }
Пример #28
0
        private double FindMu(KptList ks, Matrix[] eigenvals, double Ntarget, double beta)
        {
            double N;
            double mu_lower, mu_upper;
            double N_lower, N_upper;
            double mu;

            mu_lower = mu_upper = mu = 0;

            // first bracket
            N = FindNelec(ks, eigenvals, mu, beta);

            if (N > Ntarget)
            {
                mu_upper = mu;

                while (mu_lower >= mu_upper)
                {
                    mu -= 1;
                    N = FindNelec(ks, eigenvals, mu, beta);

                    if (N > Ntarget)
                        mu_upper = mu;
                    else
                        mu_lower = mu;
                }
            }
            else
            {
                mu_lower = mu;

                while (mu_lower >= mu_upper)
                {
                    mu += 1;
                    N = FindNelec(ks, eigenvals, mu, beta);

                    if (N > Ntarget)
                        mu_upper = mu;
                    else
                        mu_lower = mu;
                }
            }

            mu = 0.5 * (mu_upper + mu_lower);

            N_lower = FindNelec(ks, eigenvals, mu_lower, beta);
            N_upper = FindNelec(ks, eigenvals, mu_upper, beta);

            // do linear extrapolation
            int iter = 0;
            while (Math.Abs(N - Ntarget) > 1e-11 && iter < 300)
            {
                double slope = (N_upper - N_lower) / (mu_upper - mu_lower);

                if ((iter / 3) % 5 < 2)
                {
                    // bisection in case system is gapped at target number
                    mu = 0.5 * (mu_upper + mu_lower);
                }
                else
                {
                    // linear extrapoliation
                    mu = (Ntarget - N_lower) / slope + mu_lower;
                }

                N = FindNelec(ks, eigenvals, mu, beta);

                if (N < Ntarget)
                {
                    mu_lower = mu;
                    N_lower = N;
                }
                else if (N > Ntarget)
                {
                    mu_upper = mu;
                    N_upper = N;
                }

                iter++;
            }

            if (iter >= 300)
            {
                Output.WriteLine("Failed to find chemical potential.  Check the number of electrons.");
                throw new Exception("Failed to find chemical potential.");
            }

            return mu;
        }
Пример #29
0
        BandTetrahedron GetTetrahedron(TightBinding tb, KPoint kpt, KptList kpts)
        {
            List<Pair<int, double>> lst = new List<Pair<int, double>>();

            double[] weights = new double[kpts.Kpts.Count];
            for (int j = 0; j < kpts.Kpts.Count; j++)
            {
                double distance = CalcDistance(tb, kpts.Kpts[j].Value, kpt.Value);

                weights[j] = 1 / (distance + 0.00001);
            }

            for (int j = 0; j < weights.Length; j++)
            {
                lst.Add(new Pair<int, double>(j, weights[j]));
            }

            lst.Sort((x,y) => { return y.Second.CompareTo(x.Second); });

            lst.RemoveRange(4, lst.Count - 4);
            List<int> ilist = lst.Select(x => x.First).ToList();

            BandTetrahedron retval = new BandTetrahedron(tb, kpt.Value, kpts, ilist);

            return retval;
        }
Пример #30
0
        void DoBandStructure()
        {
            KptList kpath = KPath;

            Output.WriteLine("Computing band structure with {0} k-points.",
                             kpath.Kpts.Count);

            List <Matrix> eigenvals = new List <Matrix>();
            List <Matrix> eigenvecs = new List <Matrix>();

            for (int i = 0; i < kpath.Kpts.Count; i++)
            {
                Matrix m = CalcHamiltonian(kpath.Kpts[i]);
                Matrix vals, vecs;
                m.EigenValsVecs(out vals, out vecs);
                eigenvals.Add(vals);
                eigenvecs.Add(vecs);

                for (int j = 0; j < vals.Rows; j++)
                {
                    if (double.IsNaN(vals[j, 0].RealPart))
                    {
                        throw new Exception("NaN found while diagonalizing tight binding at kpt " + i.ToString() + ".");
                    }
                }
            }
            int datasets = eigenvals[0].Rows;

            using (AgrWriter writer = new AgrWriter(outputfile + ".band.agr"))
            {
                int[] colors = new int[datasets];
                for (int i = 0; i < colors.Length; i++)
                {
                    colors[i] = 1;
                }

                writer.WriteGraceHeader(kpath);
                writer.WriteGraceSetLineStyle(0, 2);
                writer.WriteGraceSetLineColor(0);
                writer.WriteGraceSetLineColor(1, colors);
                writer.WriteGraceBaseline(kpath.Kpts.Count);

                for (int i = 0; i < datasets; i++)
                {
                    writer.WriteGraceDataset(kpath.Kpts.Count,
                                             x => new Pair <double, double>(x, eigenvals[x][i, 0].RealPart - MuMesh[0]));
                }
            }
            // Do fat bands plot
            using (AgrWriter writer = new AgrWriter(outputfile + ".bweights.agr"))
            {
                // set all band lines to black
                int[] colors = new int[datasets];
                for (int i = 0; i < colors.Length; i++)
                {
                    colors[i] = 1;
                }

                writer.WriteGraceHeader(kpath);
                writer.WriteGraceSetLineStyle(0, 2);

                writer.WriteGraceSetLineColor(0);
                writer.WriteGraceSetLineColor(1, colors);

                int set = datasets + 1;

                for (int j = 0; j < Orbitals.Count; j++)
                {
                    int color = j + 1;
                    if (color > 15)
                    {
                        color -= 15;
                    }

                    writer.WriteGraceSetLineColor(set, color);
                    writer.WriteGraceSetSymbol(set, 1);
                    writer.WriteGraceSetSymbolColor(set, color);
                    writer.WriteGraceSetSymbolFill(set, 1);

                    set++;
                }

                set = datasets + 1;
                for (int j = 0; j < Orbitals.Count; j++)
                {
                    writer.WriteGraceLegend(set, Orbitals[j].Name);
                    set += 1;
                }

                writer.WriteGraceBaseline(kpath.Kpts.Count);

                for (int i = 0; i < datasets * Orbitals.Count; i++)
                {
                    writer.WriteGraceSetLineStyle(i + datasets + 1, 0);
                }

                for (int i = 0; i < datasets; i++)
                {
                    writer.WriteGraceDataset(kpath.Kpts.Count,
                                             x => new Pair <double, double>(x, eigenvals[x][i, 0].RealPart - MuMesh[0]));
                }

                for (int j = 0; j < Orbitals.Count; j++)
                {
                    writer.WriteGraceDataset("xysize", kpath.Kpts.Count * datasets,
                                             x =>
                    {
                        int k      = x % kpath.Kpts.Count;
                        int i      = x / kpath.Kpts.Count;
                        double mag = eigenvecs[k][j, i].MagnitudeSquared;
                        if (mag < 0.0001)
                        {
                            return(null);
                        }

                        return(new Triplet <double, double, double>(
                                   k,
                                   eigenvals[k][i, 0].RealPart - MuMesh[0],
                                   mag));
                    });
                }
            }
        }
Пример #31
0
        public static KptList oldGenerateMesh(Lattice lattice, int[] kgrid, int[] shift, SymmetryList syms, bool includeEnds)
        {
            bool    centerGamma = false;
            KptList retval      = new KptList();
            int     zmax        = kgrid[2] * 2;
            int     ymax        = kgrid[1] * 2;
            int     xmax        = kgrid[0] * 2;

            if (shift == null)
            {
                shift = new int[3];
            }

            retval.mesh          = (int[])kgrid.Clone();
            retval.shift         = (int[])shift.Clone();
            retval.gammaCentered = centerGamma;

            int     index      = 0;
            Vector3 gridVector = new Vector3(kgrid[0], kgrid[1], kgrid[2]);

            SymmetryList compatSyms = new SymmetryList();

            foreach (var symmetry in syms)
            {
                Vector3 grid2 = symmetry.Value * gridVector;
                for (int gi = 0; gi < 3; gi++)
                {
                    grid2[gi] = Math.Abs(grid2[gi]);
                }

                if (grid2 == gridVector)
                {
                    compatSyms.Add(symmetry);
                }
            }

            for (int k = 0; k <= zmax; k += 2)
            {
                for (int j = 0; j <= ymax; j += 2)
                {
                    for (int i = 0; i <= xmax; i += 2)
                    {
                        if (includeEnds == false)
                        {
                            if (k == zmax)
                            {
                                break;
                            }
                            if (i == xmax)
                            {
                                break;
                            }
                            if (j == ymax)
                            {
                                break;
                            }
                        }

                        int  N        = retval.KptToInteger(i, j, k);
                        bool foundSym = false;

                        double     dx       = (i + shift[0]) / (double)xmax;
                        double     dy       = (j + shift[1]) / (double)ymax;
                        double     dz       = (k + shift[2]) / (double)zmax;
                        int        symN     = N;
                        List <int> orbitals = null;

                        if (centerGamma)
                        {
                            if (kgrid[0] > 1)
                            {
                                dx -= 0.5;
                            }
                            if (kgrid[1] > 1)
                            {
                                dy -= 0.5;
                            }
                            if (kgrid[2] > 1)
                            {
                                dz -= 0.5;
                            }
                        }

                        Vector3 pt = CalcK(lattice, dx, dy, dz);

#if DEBUG
                        int testi, testj, testk;
                        retval.ReduceKpt(lattice, new Vector3(pt), out testi, out testj, out testk);

                        //System.Diagnostics.Debug.Assert(i == testi);
                        //System.Diagnostics.Debug.Assert(j == testj);
                        //System.Diagnostics.Debug.Assert(k == testk);
#endif
                        foreach (var symmetry in compatSyms)
                        {
                            Vector3 Tpt = symmetry.Value * pt;

                            if (Tpt == pt)
                            {
                                continue;
                            }

                            Vector3 red = lattice.ReducedCoords(Tpt, true);

                            int newi = (int)Math.Round(xmax * red.X - shift[0]);
                            int newj = (int)Math.Round(ymax * red.Y - shift[1]);
                            int newk = (int)Math.Round(zmax * red.Z - shift[2]);

                            if (newi % 2 != 0 || newj % 2 != 0 || newk % 2 != 0)
                            {
                                continue;
                            }

                            symN = retval.KptToInteger(newi, newj, newk);

                            if (symN < N)
                            {
                                foundSym = true;

                                if (symmetry.OrbitalTransform.Count > 0)
                                {
                                    orbitals = symmetry.OrbitalTransform;
                                }
                            }

                            if (foundSym)
                            {
                                break;
                            }
                        }

                        Vector3 kptValue = CalcK(lattice, dx, dy, dz);

                        retval.allKpts.Add(new KPoint(kptValue));

                        if (retval.Nvalues.ContainsKey(N))
                        {
                        }
                        else if (foundSym == false)
                        {
                            retval.kpts.Add(new KPoint(kptValue));
                            retval.Nvalues.Add(N, index);
                            index++;
                        }
                        else
                        {
                            int newIndex = retval.Nvalues[symN];
                            retval.kpts[newIndex].Weight++;
                            retval.kpts[newIndex].AddOrbitalSymmetry(orbitals);

                            retval.Nvalues.Add(N, newIndex);
                        }
                    }
                }
            }

            int count = kgrid[0] * kgrid[1] * kgrid[2];
            for (int i = 0; i < retval.kpts.Count; i++)
            {
                retval.kpts[i].Weight    /= count;
                retval.allKpts[i].Weight /= count;
            }

            if (includeEnds)
            {
                retval.allKpts.Sort((x, y) => x.Value.Z.CompareTo(y.Value.Z));

                List <int> removeThese = new List <int>();
                List <int> equivKpt    = new List <int>();

                // read this value first, because the size of the array will change.
                int kptCount = retval.AllKpts.Count;
                for (int kindex = 0; kindex < kptCount; kindex++)
                {
                    if (removeThese.Contains(kindex))
                    {
                        continue;
                    }

                    Vector3 kpt  = retval.allKpts[kindex].Value;
                    double  dist = kpt.Magnitude;

                    equivKpt.Clear();

                    for (int k = -1; k <= 1; k++)
                    {
                        for (int j = -1; j <= 1; j++)
                        {
                            for (int i = -1; i <= 1; i++)
                            {
                                if (i == 0 && j == 0 && k == 0)
                                {
                                    continue;
                                }

                                Vector3 pt = kpt +
                                             i * lattice.G1 +
                                             j * lattice.G2 +
                                             k * lattice.G3;

                                double newDist = pt.Magnitude;

                                if (newDist < dist - 1e-6)
                                {
                                    foreach (var value in equivKpt)
                                    {
                                        if (removeThese.Contains(value) == false)
                                        {
                                            removeThese.Add(value);
                                        }
                                    }

                                    equivKpt.Clear();

                                    int search = retval.AllKpts.FindIndex(x => (x.Value - pt).Magnitude < 1e-6);

                                    if (search != -1)
                                    {
                                        if (removeThese.Contains(kindex) == false)
                                        {
                                            removeThese.Add(kindex);
                                        }

                                        // break out of the loop
                                        k = 1; j = 1; i = 2;
                                    }
                                    else
                                    {
                                        retval.allKpts[kindex].Value = pt;
                                        kpt  = pt;
                                        dist = newDist;

                                        // reset variables since we updated this kpoint value.
                                        k = -1;
                                        j = -1;
                                        i = -2;
                                    }
                                }
                                else if (Math.Abs(dist - newDist) < 1e-6)
                                {
                                    int search = retval.AllKpts.FindIndex(x => (x.Value - pt).Magnitude < 1e-6);

                                    if (search != -1)
                                    {
                                        if (removeThese.Contains(search))
                                        {
                                            k = 1; j = 1; i = 2;
                                            removeThese.Add(kindex);
                                            break;
                                        }

                                        equivKpt.Add(search);
                                        continue;
                                    }

                                    equivKpt.Add(retval.allKpts.Count);
                                    retval.allKpts.Add(new KPoint(pt));
                                }
                            }
                        }
                    }
                }

                // sort in reverse order
                removeThese.Sort((x, y) => - x.CompareTo(y));

                for (int i = 0; i < removeThese.Count; i++)
                {
                    retval.allKpts.RemoveAt(removeThese[i]);
                }

                retval.allKpts.Sort((x, y) => x.Value.Z.CompareTo(y.Value.Z));
            }
#if DEBUG
            if (!includeEnds)
            {
                double check = 0;
                for (int i = 0; i < retval.kpts.Count; i++)
                {
                    check += retval.kpts[i].Weight;
                }

                System.Diagnostics.Debug.Assert(Math.Abs(check - 1) < 1e-8);
            }
#endif

            return(retval);
        }
Пример #32
0
        void WriteBands(TightBinding tb, KptList kpts, StreamWriter w)
        {
            int bandCount = kpts.Kpts[0].Wavefunctions.Count;

            BandTetrahedron tet = null;

            for (int i = 0; i < tb.KPath.Kpts.Count; i++)
            {
                var kpt = tb.KPath.Kpts[i];

                if (tet == null || tet.Contains(kpt) == false)
                {
                    GetTetrahedron(tb, kpt, kpts);
                }

                w.Write(i);
                w.Write("   ");

                for (int band = 0; band < bandCount; band++)
                {
                    double energy = tet.Interpolate(kpt);

                    w.Write("{0}  ", energy);
                }

                w.WriteLine();
            }
        }
Пример #33
0
        private static void NormalizeST(Lattice lattice, KptList retval)
        {
            retval.sdir /= retval.sdir.Magnitude;
            retval.tdir /= retval.tdir.Magnitude;

            retval.sdir /= GammaInDirection(lattice, retval.sdir).Magnitude;
            retval.tdir /= GammaInDirection(lattice, retval.tdir).Magnitude;

            // double them to make s and t 1 at the zone boundary, instead of 0.5.
            retval.sdir *= 2;
            retval.tdir *= 2;
        }
Пример #34
0
        public static KptList GenerateMesh(Lattice lattice, int[] kgrid, int[] shift, SymmetryList syms, bool includeEnds)
        {
            KptList retval = new KptList();

            if (shift == null)
                shift = new int[3];

            for (int i = 0; i < 3; i++)
                if (kgrid[i] == 1)
                    shift[i] = 1;

            retval.mesh = (int[])kgrid.Clone();
            retval.shift = (int[])shift.Clone();
            retval.gammaCentered = true;

            SymmetryList compatSyms = FindCompatibleSymmetries(kgrid, syms);

            int index = 0;
            for (int k = -kgrid[2] + shift[2]; k <= kgrid[2]; k += 2)
            {
                for (int j = -kgrid[1] + shift[1]; j <= kgrid[1]; j += 2)
                {
                    for (int i = -kgrid[0] + shift[0]; i <= kgrid[0]; i += 2)
                    {
                        if (includeEnds == false)
                        {
                            if (k == kgrid[2]) break;
                            if (j == kgrid[1]) break;
                            if (i == kgrid[0]) break;
                        }

                        double dx = i * 0.5 / kgrid[0];
                        double dy = j * 0.5 / kgrid[1];
                        double dz = k * 0.5 / kgrid[2];

                        Vector3 kptValue = CalcK(lattice, dx, dy, dz);

                        int N = retval.KptToInteger(i, j, k);
                        int symN = N;

                        System.Diagnostics.Debug.Assert(!(retval.Nvalues.ContainsKey(N) && includeEnds == false));

                        List<int> orbitals = null;
                        bool foundSym = false;

                        foreach (var symmetry in compatSyms)
                        {
                            Vector3 Tpt = symmetry.Value * kptValue;

                            if (Tpt == kptValue)
                                continue;

                            int newi, newj, newk;

                            retval.ReduceKpt(lattice, Tpt, out newi, out newj, out newk);

                            if (Math.Abs(newi) % 2 != shift[0] ||
                                Math.Abs(newj) % 2 != shift[1] ||
                                Math.Abs(newk) % 2 != shift[2])
                                continue;

                            symN = retval.KptToInteger(newi, newj, newk);

                            if (symN < N)
                            {
                                foundSym = true;

                                if (symmetry.OrbitalTransform.Count > 0)
                                {
                                    orbitals = symmetry.OrbitalTransform;
                                }

                                break;
                            }
                        }

                        if (includeEnds)
                        {
                            if (retval.AllNvalues.ContainsKey(N))
                            {
                                retval.allKpts.Add(new KPoint(kptValue));
                                continue;
                            }
                        }

                        retval.AllNvalues.Add(N, retval.allKpts.Count);
                        retval.allKpts.Add(new KPoint(kptValue));

                        if (foundSym == false)
                        {
                            retval.kpts.Add(new KPoint(kptValue));
                            retval.Nvalues.Add(N, index);
                            index++;
                        }
                        else
                        {
                            int newIndex = retval.Nvalues[symN];
                            retval.kpts[newIndex].Weight++;
                            retval.kpts[newIndex].AddOrbitalSymmetry(orbitals);

                            retval.Nvalues.Add(N, newIndex);
                        }
                    }
                }
            }

            int count = kgrid[0] * kgrid[1] * kgrid[2];
            for (int i = 0; i < retval.kpts.Count; i++)
            {
                retval.kpts[i].Weight /= count;
            }
            for (int i = 0; i < retval.allKpts.Count; i++)
            {
                retval.allKpts[i].Weight /= count;
            }

            return retval;
        }
Пример #35
0
        private static bool CenterOnGamma(Lattice lattice, ref KPoint qpt, KptList list)
        {
            double dist = qpt.Value.Magnitude;
            double olddist = dist;
            Vector3 newPt = qpt.Value;
            bool retval = true;
            double bs, bt;

            list.GetPlaneST(qpt, out bs, out bt);

            for (int k = -1; k <= 1; k++)
            {
                for (int j = -1; j <= 1; j++)
                {
                    for (int i = -1; i <= 1; i++)
                    {
                        if (i == 0 && j == 0 && k == 0)
                            continue;

                        Vector3 pt = qpt.Value +
                            i * lattice.G1 +
                            j * lattice.G2 +
                            k * lattice.G3;

                        double s, t;
                        bool valid = list.GetPlaneST(new KPoint(pt), out s, out t);

                        if (!valid)
                            continue;

                        if (pt.Magnitude < dist - 1e-6)
                        {
                            if (list.allKpts.Any(x => Math.Abs((x.Value - pt).Magnitude) > 1e-6))
                            {
                                retval = false;
                                continue;
                            }

                            dist = pt.Magnitude;
                            newPt = pt;
                        }
                    }
                }
            }

            if (olddist != dist)
                retval = true;

            if (retval == false)
                return false;

            qpt.Value = newPt;

            return true;
        }
Пример #36
0
 private void WriteGreenFunction(TightBindingSuite.TightBinding tb, Matrix[] green, KptList kmesh)
 {
     WriteGreenFunctionPlane(tb, green, kmesh);
 }
Пример #37
0
        private void WriteGreenFunctionPlane(TightBindingSuite.TightBinding tb, Matrix[] green, KptList kmesh)
        {
            Console.WriteLine("Output as a plane.");
            Console.WriteLine();

            Console.WriteLine("Enter vectors as a series of three numbers, like: 1 1 0");
            Console.WriteLine("Only integer values need be used.");
            Console.WriteLine();

            Console.Write("Enter first vector: ");
            string first = Console.ReadLine();
            if (string.IsNullOrEmpty(first))
                return;

            Console.Write("Enter second vector: ");
            string second = Console.ReadLine();

            Vector3 sdir = Vector3.Parse(first);
            Vector3 tdir = Vector3.Parse(second);
            Vector3 udir = Vector3.CrossProduct(sdir, tdir);

            Console.Write("Enter origin point: ");
            string origin = Console.ReadLine();
            Vector3 orig = Vector3.Parse(origin);

            Vector3 closestKpt = Vector3.Zero;
            double closestDistance = 999999999;

            foreach (var kpt in kmesh.AllKpts)
            {
                double distance = (kpt.Value - orig).MagnitudeSquared;

                if (distance < closestDistance)
                {
                    closestKpt = kpt.Value;
                    closestDistance = distance;
                }
            }

            if (closestDistance > 1e-6)
            {
                Console.WriteLine("Using closest k-point to specified origin: {0}.", closestKpt);
                orig = closestKpt;
                sdir += closestKpt;
                tdir += closestKpt;
            }

            KptList plane = KptList.GeneratePlane(
                tb.Lattice, new Vector3[] { orig, sdir, tdir }, tb.Symmetries, kmesh);

            string tr_filename = string.Format("green.tr.pln");
            StreamWriter tr = new StreamWriter(tr_filename);

            double lastt = double.MinValue;

            for (int k = 0; k < plane.AllKpts.Count; k++)
            {
                Complex trValue = new Complex();

                for (int i = 0; i < green[k].Rows; i++)
                {
                    trValue += green[k][i, i];
                }
                Vector3 kpt = plane.AllKpts[k].Value;
                List<int> orbitalMap;
                double s, t;

                plane.GetPlaneST(plane.AllKpts[k], out s, out t);

                int kindex = kmesh.IrreducibleIndex(kpt, tb.Lattice, tb.Symmetries, out orbitalMap);

                if (Math.Abs(t - lastt) > 1e-6)
                {
                    tr.WriteLine();
                    lastt = t;
                }

                tr.WriteLine("{0}\t{1}\t{2}", s, t, -trValue.ImagPart);
            }
            tr.Close();

            for (int i = 0; i < green[0].Rows; i++)
            {
                for (int j = 0; j < green[0].Columns; j++)
                {
                    string re_filename = string.Format("green.re.{0}.{1}.pln", i,j);
                    string im_filename = string.Format("green.im.{0}.{1}.pln", i, j);
                    string mag_filename = string.Format("green.mag.{0}.{1}.pln", i, j);

                    StreamWriter rew = new StreamWriter(re_filename);
                    StreamWriter imw = new StreamWriter(im_filename);
                    StreamWriter mag = new StreamWriter(mag_filename);

                    try
                    {
                        lastt = double.MaxValue;

                        for (int k = 0; k < plane.AllKpts.Count; k++)
                        {
                            Vector3 kpt = plane.AllKpts[k].Value;
                            List<int> orbitalMap;
                            double s, t;

                            plane.GetPlaneST(plane.AllKpts[k], out s, out t);

                            int kindex = kmesh.IrreducibleIndex(kpt, tb.Lattice, tb.Symmetries, out orbitalMap);

                            if (Math.Abs(t - lastt) > 1e-6)
                            {
                                rew.WriteLine();
                                imw.WriteLine();
                                mag.WriteLine();

                                lastt = t;
                            }

                            rew.WriteLine("{0}\t{1}\t{2}", s, t, green[kindex][i, j].RealPart);
                            imw.WriteLine("{0}\t{1}\t{2}", s, t, -green[kindex][i, j].ImagPart);
                            mag.WriteLine("{0}\t{1}\t{2}", s, t, green[kindex][i, j].Magnitude);

                        }
                    }
                    finally
                    {
                        rew.Dispose();
                        imw.Dispose();
                        mag.Dispose();
                    }
                }
            }
        }
Пример #38
0
        void OutputBands(TightBinding tb, KptList ks, 
            List<RpaParams> rpa, MatrixGetter g, string name)
        {
            using (StreamWriter w = new StreamWriter("eigenvalues." + name + ".q"))
            {
                w.WriteLine("# Grid");
                w.WriteLine("{0}  {1}  {2}  {3}  {4}  {5}", ks.Mesh[0], ks.Mesh[1], ks.Mesh[2],
                            ks.Shift[0], ks.Shift[1], ks.Shift[2]);

                w.WriteLine("# Eigenvalues");

                foreach(var rpa_i in rpa)
                {
                    var qpt = rpa_i.QptValue;

                    w.Write("{0}    {1}    {2}             ",
                            qpt.X, qpt.Y, qpt.Z);

                    Matrix chi = g(rpa_i);
                    Matrix evalues = chi.EigenValues();

                    for (int j = 0; j < evalues.Rows; j++)
                    {
                        w.Write("{0}   ", evalues[j, 0].RealPart);
                    }

                    w.WriteLine();
                }
            }
        }
Пример #39
0
        private void CalcSusceptibility(TightBinding tb, KptList qpts, List <RpaParams> rpa)
        {
            Matrix ident = Matrix.Identity(tb.Orbitals.Count * tb.Orbitals.Count);

            Matrix[] S, C;
            CalcSpinChargeMatrices(tb, rpa, out S, out C);

            Output.WriteLine("Calculating X0...");


            RpaThreadInfo[] threadInfos = CreateThreadInfos(tb, rpa, qpts);

            Output.WriteLine("Using {0} threads.", threads);

            for (int i = 0; i < threadInfos.Length; i++)
            {
                RunRpaThread(threadInfos[i]);

                if (i == 0)
                {
                    Thread.Sleep(20);
                }
            }

            bool threadsRunning;

            do
            {
                threadsRunning = false;

                for (int i = 0; i < threadInfos.Length; i++)
                {
                    if (threadInfos[i].Thread.ThreadState == ThreadState.Running)
                    {
                        threadsRunning = true;
                    }
                }

                Thread.Sleep(10);
            } while (threadsRunning);

            Output.WriteLine();
            Output.WriteLine("Bare susceptibility calculation completed.");
            Output.WriteLine();

            double factor = InteractionAdjustment(rpa, S, C, tb);

            if (tb.Interactions.AdjustInteractions)
            {
                Output.WriteLine("Multiplying interactions by {0}.", factor);

                for (int i = 0; i < rpa.Count; i++)
                {
                    S[i] *= factor;
                    C[i] *= factor;
                }
            }
            else if (factor < 1)
            {
                Output.WriteLine("WARNING:  There will be divergent geometric series.");
                Output.WriteLine("          Interpret results with care!");
            }

            Output.WriteLine();
            Output.WriteLine("Calculating dressed susceptibilities.");
            Output.WriteLine();

            RpaParams largestParams = null;
            double    largest       = 0;
            string    indices       = "";
            bool      charge        = false;

            for (int i = 0; i < rpa.Count; i++)
            {
                Matrix s_denom = (ident - S[i] * rpa[i].X0);
                Matrix c_denom = (ident + C[i] * rpa[i].X0);

                Matrix s_inv = s_denom.Invert();
                Matrix c_inv = c_denom.Invert();

                System.Diagnostics.Debug.Assert((s_denom * s_inv).IsIdentity);

                rpa[i].Xs = rpa[i].X0 * s_inv;
                rpa[i].Xc = rpa[i].X0 * c_inv;

                for (int l1 = 0; l1 < tb.Orbitals.Count; l1++)
                {
                    for (int l2 = 0; l2 < tb.Orbitals.Count; l2++)
                    {
                        for (int l3 = 0; l3 < tb.Orbitals.Count; l3++)
                        {
                            for (int l4 = 0; l4 < tb.Orbitals.Count; l4++)
                            {
                                int a = GetIndex(tb, l1, l2);
                                int b = GetIndex(tb, l3, l4);

                                bool found = false;

                                if (rpa[i].Xs[a, b].MagnitudeSquared > largest)
                                {
                                    largest = rpa[i].Xs[a, b].MagnitudeSquared;
                                    charge  = false;
                                    found   = true;
                                }
                                if (rpa[i].Xc[a, b].MagnitudeSquared > largest)
                                {
                                    largest = rpa[i].Xc[a, b].MagnitudeSquared;
                                    charge  = true;
                                    found   = true;
                                }
                                if (found == false)
                                {
                                    continue;
                                }

                                indices       = string.Format("{0}{1}{2}{3}", l1, l2, l3, l4);
                                largestParams = rpa[i];
                            }
                        }
                    }
                }
            }

            Output.WriteLine("Largest susceptibility found at:");
            Output.WriteLine("    {0} susceptibility: {1}", charge ? "Charge" : "Spin", Math.Sqrt(largest));
            Output.WriteLine("    Indices: {0}", indices);
            Output.WriteLine("    Temperature: {0}", largestParams.Temperature);
            Output.WriteLine("    Frequency: {0}", largestParams.Frequency);
            Output.WriteLine("    Chemical Potential: {0}", largestParams.ChemicalPotential);
            Output.WriteLine("    Q: {0}", largestParams.QptValue);
        }
Пример #40
0
        private static bool CenterOnGamma(Lattice lattice, ref KPoint qpt, KptList list)
        {
            double  dist = qpt.Value.Magnitude;
            double  olddist = dist;
            Vector3 newPt = qpt.Value;
            bool    retval = true;
            double  bs, bt;

            list.GetPlaneST(qpt, out bs, out bt);


            for (int k = -1; k <= 1; k++)
            {
                for (int j = -1; j <= 1; j++)
                {
                    for (int i = -1; i <= 1; i++)
                    {
                        if (i == 0 && j == 0 && k == 0)
                        {
                            continue;
                        }

                        Vector3 pt = qpt.Value +
                                     i * lattice.G1 +
                                     j * lattice.G2 +
                                     k * lattice.G3;

                        double s, t;
                        bool   valid = list.GetPlaneST(new KPoint(pt), out s, out t);

                        if (!valid)
                        {
                            continue;
                        }

                        if (pt.Magnitude < dist - 1e-6)
                        {
                            if (list.allKpts.Any(x => Math.Abs((x.Value - pt).Magnitude) > 1e-6))
                            {
                                retval = false;
                                continue;
                            }

                            dist  = pt.Magnitude;
                            newPt = pt;
                        }
                    }
                }
            }

            if (olddist != dist)
            {
                retval = true;
            }

            if (retval == false)
            {
                return(false);
            }

            qpt.Value = newPt;

            return(true);
        }
Пример #41
0
        public static KptList GenerateMesh(Lattice lattice, int[] kgrid, int[] shift, SymmetryList syms, bool includeEnds)
        {
            KptList retval = new KptList();

            if (shift == null)
            {
                shift = new int[3];
            }

            for (int i = 0; i < 3; i++)
            {
                if (kgrid[i] == 1)
                {
                    shift[i] = 1;
                }
            }

            retval.mesh          = (int[])kgrid.Clone();
            retval.shift         = (int[])shift.Clone();
            retval.gammaCentered = true;

            SymmetryList compatSyms = FindCompatibleSymmetries(kgrid, syms);

            int index = 0;

            for (int k = -kgrid[2] + shift[2]; k <= kgrid[2]; k += 2)
            {
                for (int j = -kgrid[1] + shift[1]; j <= kgrid[1]; j += 2)
                {
                    for (int i = -kgrid[0] + shift[0]; i <= kgrid[0]; i += 2)
                    {
                        if (includeEnds == false)
                        {
                            if (k == kgrid[2])
                            {
                                break;
                            }
                            if (j == kgrid[1])
                            {
                                break;
                            }
                            if (i == kgrid[0])
                            {
                                break;
                            }
                        }

                        double dx = i * 0.5 / kgrid[0];
                        double dy = j * 0.5 / kgrid[1];
                        double dz = k * 0.5 / kgrid[2];

                        Vector3 kptValue = CalcK(lattice, dx, dy, dz);

                        int N    = retval.KptToInteger(i, j, k);
                        int symN = N;

                        System.Diagnostics.Debug.Assert(!(retval.Nvalues.ContainsKey(N) && includeEnds == false));

                        List <int> orbitals = null;
                        bool       foundSym = false;

                        foreach (var symmetry in compatSyms)
                        {
                            Vector3 Tpt = symmetry.Value * kptValue;

                            if (Tpt == kptValue)
                            {
                                continue;
                            }

                            int newi, newj, newk;

                            retval.ReduceKpt(lattice, Tpt, out newi, out newj, out newk);

                            if (Math.Abs(newi) % 2 != shift[0] ||
                                Math.Abs(newj) % 2 != shift[1] ||
                                Math.Abs(newk) % 2 != shift[2])
                            {
                                continue;
                            }

                            symN = retval.KptToInteger(newi, newj, newk);

                            if (symN < N)
                            {
                                foundSym = true;

                                if (symmetry.OrbitalTransform.Count > 0)
                                {
                                    orbitals = symmetry.OrbitalTransform;
                                }

                                break;
                            }
                        }

                        if (includeEnds)
                        {
                            if (retval.AllNvalues.ContainsKey(N))
                            {
                                retval.allKpts.Add(new KPoint(kptValue));
                                continue;
                            }
                        }

                        retval.AllNvalues.Add(N, retval.allKpts.Count);
                        retval.allKpts.Add(new KPoint(kptValue));

                        if (foundSym == false)
                        {
                            retval.kpts.Add(new KPoint(kptValue));
                            retval.Nvalues.Add(N, index);
                            index++;
                        }
                        else
                        {
                            int newIndex = retval.Nvalues[symN];
                            retval.kpts[newIndex].Weight++;
                            retval.kpts[newIndex].AddOrbitalSymmetry(orbitals);

                            retval.Nvalues.Add(N, newIndex);
                        }
                    }
                }
            }

            int count = kgrid[0] * kgrid[1] * kgrid[2];

            for (int i = 0; i < retval.kpts.Count; i++)
            {
                retval.kpts[i].Weight /= count;
            }
            for (int i = 0; i < retval.allKpts.Count; i++)
            {
                retval.allKpts[i].Weight /= count;
            }

            return(retval);
        }
Пример #42
0
        private double FindMu(KptList ks, Matrix[] eigenvals, double Ntarget, double beta)
        {
            double N;
            double mu_lower, mu_upper;
            double N_lower, N_upper;
            double mu;

            mu_lower = mu_upper = mu = 0;

            // first bracket
            N = FindNelec(ks, eigenvals, mu, beta);

            if (N > Ntarget)
            {
                mu_upper = mu;

                while (mu_lower >= mu_upper)
                {
                    mu -= 1;
                    N   = FindNelec(ks, eigenvals, mu, beta);

                    if (N > Ntarget)
                    {
                        mu_upper = mu;
                    }
                    else
                    {
                        mu_lower = mu;
                    }
                }
            }
            else
            {
                mu_lower = mu;

                while (mu_lower >= mu_upper)
                {
                    mu += 1;
                    N   = FindNelec(ks, eigenvals, mu, beta);

                    if (N > Ntarget)
                    {
                        mu_upper = mu;
                    }
                    else
                    {
                        mu_lower = mu;
                    }
                }
            }

            mu = 0.5 * (mu_upper + mu_lower);

            N_lower = FindNelec(ks, eigenvals, mu_lower, beta);
            N_upper = FindNelec(ks, eigenvals, mu_upper, beta);

            // do linear extrapolation
            int iter = 0;

            while (Math.Abs(N - Ntarget) > 1e-11 && iter < 300)
            {
                double slope = (N_upper - N_lower) / (mu_upper - mu_lower);

                if ((iter / 3) % 5 < 2)
                {
                    // bisection in case system is gapped at target number
                    mu = 0.5 * (mu_upper + mu_lower);
                }
                else
                {
                    // linear extrapoliation
                    mu = (Ntarget - N_lower) / slope + mu_lower;
                }

                N = FindNelec(ks, eigenvals, mu, beta);

                if (N < Ntarget)
                {
                    mu_lower = mu;
                    N_lower  = N;
                }
                else if (N > Ntarget)
                {
                    mu_upper = mu;
                    N_upper  = N;
                }

                iter++;
            }

            if (iter >= 300)
            {
                Output.WriteLine("Failed to find chemical potential.  Check the number of electrons.");
                throw new Exception("Failed to find chemical potential.");
            }

            return(mu);
        }
Пример #43
0
        private RpaThreadInfo[] CreateThreadInfos(TightBinding tb, List <RpaParams> rpa, KptList qpts)
        {
            RpaThreadInfo[] infos = new RpaThreadInfo[threads];

            for (int i = 0; i < infos.Length; i++)
            {
                infos[i]      = new RpaThreadInfo();
                infos[i].tb   = tb.Clone();
                infos[i].qpts = qpts;
            }

            infos[0].PrimaryThread = true;

            for (int i = 0; i < rpa.Count; i++)
            {
                infos[i % threads].RpaParams.Add(rpa[i]);
            }

            return(infos);
        }
Пример #44
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();
                    }
                }
            }
        }
Пример #45
0
        public static KptList GeneratePlane(Lattice lattice, Vector3[] points, SymmetryList syms, KptList qmesh)
        {
            Vector3 diff_1 = points[1] - points[0];
            Vector3 diff_2 = points[2] - points[0];
            Vector3 norm   = Vector3.CrossProduct(diff_1, diff_2);

            KptList retval = new KptList();

            retval.mesh          = (int[])qmesh.mesh.Clone();
            retval.shift         = new int[3];
            retval.gammaCentered = true;

            retval.origin = points[0];
            retval.sdir   = diff_1;
            retval.tdir   = Vector3.CrossProduct(norm, diff_1);

            NormalizeST(lattice, retval);

            int zmax = qmesh.mesh[2] * 2;
            int ymax = qmesh.mesh[1] * 2;
            int xmax = qmesh.mesh[0] * 2;

            int index = 0;

            List <KPoint> planePoints = new List <KPoint>();

            for (int i = 0; i < qmesh.AllKpts.Count; i++)
            {
                var qpt = qmesh.AllKpts[i];

                Vector3 diff = qpt.Value - points[0];
                double  dot  = Math.Abs(diff.DotProduct(norm));

                if (dot < 1e-8)
                {
                    double s, t;

                    retval.GetPlaneST(qpt, out s, out t);
                    planePoints.Add(qpt);
                }
            }
            SortByDistanceFromGamma(planePoints);

            for (int i = 0; i < planePoints.Count; i++)
            {
                var    qpt = planePoints[i];
                double s, t;
                retval.GetPlaneST(qpt, out s, out t);

                //if (CenterOnGamma(lattice, ref qpt, retval) == false)
                //    continue;

                //retval.GetPlaneST(qpt, out news, out newt);

                retval.allKpts.Add(qpt);
            }

            // now sort q-points to lay them in the s,t plane.
            Comparison <KPoint> sorter = (x, y) =>
            {
                double s_x, s_y, t_x, t_y;

                retval.GetPlaneST(x, out s_x, out t_x);
                retval.GetPlaneST(y, out s_y, out t_y);

                if (Math.Abs(t_x - t_y) > 1e-6)
                {
                    return(t_x.CompareTo(t_y));
                }
                else
                {
                    return(s_x.CompareTo(s_y));
                }
            };

            retval.allKpts.Sort(sorter);

            // now reduce points by symmetry.
            for (int i = 0; i < retval.allKpts.Count; i++)
            {
                var qpt = retval.AllKpts[i];

                int        N        = retval.KptToInteger(lattice, qpt);
                int        symN     = N;
                bool       foundSym = false;
                List <int> orbitals = null;

                Vector3 pt = qpt.Value;

                foreach (var symmetry in syms)
                {
                    Vector3 Tpt = symmetry.Value * pt;

                    int newi, newj, newk;
                    retval.ReduceKpt(lattice, Tpt, out newi, out newj, out newk);

                    if (newi % 2 != 0 || newj % 2 != 0 || newk % 2 != 0)
                    {
                        continue;
                    }

                    symN = retval.KptToInteger(newi, newj, newk);

                    if (retval.Nvalues.ContainsKey(symN))
                    {
                        foundSym = true;

                        if (symmetry.OrbitalTransform.Count > 0)
                        {
                            orbitals = symmetry.OrbitalTransform;
                        }
                    }

                    if (foundSym)
                    {
                        break;
                    }
                }

                if (foundSym == false && retval.Nvalues.ContainsKey(N) == false)
                {
                    retval.kpts.Add(qpt);
                    retval.Nvalues.Add(N, index);
                    index++;
                }
                else if (retval.Nvalues.ContainsKey(N) == false)
                {
                    int newIndex = retval.Nvalues[symN];
                    retval.kpts[newIndex].AddOrbitalSymmetry(orbitals);

                    retval.Nvalues.Add(N, newIndex);
                }
                else
                {
                }                    // skip points which are already in there.  This should only happen for zone edge points
            }

            retval.kpts.Sort(sorter);

            Vector3 sd = retval.sdir / SmallestNonzero(retval.sdir);
            Vector3 td = retval.tdir / SmallestNonzero(retval.tdir);

            Output.WriteLine("Plane horizontal direction: {0}", sd);
            Output.WriteLine("Plane vertical direction: {0}", td);

            Output.WriteLine("Plane horizontal vector: {0}", retval.sdir);
            Output.WriteLine("Plane vertical vector: {0}", retval.tdir);

            return(retval);
        }
Пример #46
0
        /// <summary>
        /// This function does not work with symmetries, so it is unused.
        /// </summary>
        /// <param name="inp"></param>
        /// <param name="outputfile"></param>
        void tet_DoDensityOfStates(TightBinding.TbInputFileReader inp)
        {
            KptList      ks   = KMesh;
            StreamWriter outf = new StreamWriter(outputfile + ".dos");

            double smearing            = TemperatureMesh[0];
            double smearNorm           = 1 / smearing * Math.Pow(Math.PI, -0.5);
            double oneOverSmearSquared = Math.Pow(smearing, -2);

            double emin, emax;

            Hoppings.EnergyScale(out emin, out emax);

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


            int epts = 2000;

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

            smearNorm /= ks.Kpts.Count;

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

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

            Output.WriteLine("Using {0} tetrahedrons.", ks.Tetrahedrons.Count);

            for (int tetindex = 0; tetindex < ks.Tetrahedrons.Count; tetindex++)
            {
                Tetrahedron tet = ks.Tetrahedrons[tetindex];
                if (tetindex % (ks.Tetrahedrons.Count / 10) == 0 && tetindex > 0)
                {
                    Output.WriteLine("At {0}...", tetindex);
                }

                Matrix[] eigenvals = new Matrix[4];

                for (int i = 0; i < 4; i++)
                {
                    Matrix m = CalcHamiltonian(tet.Corners[i]);
                    Matrix vals, vecs;
                    m.EigenValsVecs(out vals, out vecs);

                    eigenvals[i] = vals;
                }

                for (int nband = 0; nband < eigenvals[0].Rows; nband++)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        tet.Values[i] = eigenvals[i][nband, 0].RealPart;
                    }

                    tet.SortCorners();

                    int estart = FindIndex(energyGrid, tet.Values[0]);
                    int eend   = FindIndex(energyGrid, tet.Values[3]);

                    for (int ei = estart; ei < eend; ei++)
                    {
                        dos[ei, 0] += tet.IntegrateArea(energyGrid[ei]);
                    }
                }
            }

            for (int i = 0; i < epts; i++)
            {
                dos[i, 0] /= ks.Tetrahedrons.Count;
            }

            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();
            }

            outf.Close();

            Output.WriteLine("Creating +coeff file.");
            outf = new StreamWriter(Path.Combine(Path.GetDirectoryName(outputfile), "+coeff"));

            outf.WriteLine("#\t1\t0\t" + ks.Kpts.Count.ToString());
            outf.Write("# band index\te(k,n)\t");

            for (int i = 0; i < Orbitals.Count; i++)
            {
                if (string.IsNullOrEmpty(Orbitals[i].Name))
                {
                    outf.Write("TB{0}\t", i);
                }
                else
                {
                    outf.Write("{0}\t", Orbitals[i].Name);
                }
            }
            outf.WriteLine();

            for (int kindex = 0; kindex < ks.Kpts.Count; kindex++)
            {
                Matrix m = CalcHamiltonian(ks.Kpts[kindex]);
                Matrix vals, vecs;
                m.EigenValsVecs(out vals, out vecs);

                outf.WriteLine("# spin=    1 k={0}", ks.Kpts[kindex].Value);

                for (int i = 0; i < vals.Rows; i++)
                {
                    outf.Write("{0}     {1}    ", i + 1, vals[i, 0].RealPart);

                    for (int j = 0; j < vecs.Columns; j++)
                    {
                        outf.Write("{0}    {1}    ", vecs[i, j].RealPart, vecs[i, j].ImagPart);
                    }
                    outf.WriteLine();
                }
            }
        }
Пример #47
0
        private void CalcSusceptibility(TightBinding tb, KptList qpts, List<RpaParams> rpa)
        {
            Matrix ident = Matrix.Identity(tb.Orbitals.Count * tb.Orbitals.Count);

            Matrix[] S, C;
            CalcSpinChargeMatrices(tb, rpa, out S, out C);

            Output.WriteLine("Calculating X0...");

            RpaThreadInfo[] threadInfos = CreateThreadInfos(tb, rpa, qpts);

            Output.WriteLine("Using {0} threads.", threads);

            for (int i = 0; i < threadInfos.Length; i++)
            {
                RunRpaThread(threadInfos[i]);

                if (i == 0)
                    Thread.Sleep(20);
            }

            bool threadsRunning;

            do
            {
                threadsRunning = false;

                for (int i = 0; i < threadInfos.Length; i++)
                {
                    if (threadInfos[i].Thread.ThreadState == ThreadState.Running)
                        threadsRunning = true;
                }

                Thread.Sleep(10);

            } while (threadsRunning);

            Output.WriteLine();
            Output.WriteLine("Bare susceptibility calculation completed.");
            Output.WriteLine();

            double factor = InteractionAdjustment(rpa, S, C, tb);

            if (tb.Interactions.AdjustInteractions)
            {
                Output.WriteLine("Multiplying interactions by {0}.", factor);

                for (int i = 0; i < rpa.Count; i++)
                {
                    S[i] *= factor;
                    C[i] *= factor;
                }
            }
            else if (factor < 1)
            {
                Output.WriteLine("WARNING:  There will be divergent geometric series.");
                Output.WriteLine("          Interpret results with care!");
            }

            Output.WriteLine();
            Output.WriteLine("Calculating dressed susceptibilities.");
            Output.WriteLine();

            RpaParams largestParams = null;
            double largest = 0;
            string indices = "";
            bool charge = false;

            for (int i = 0; i < rpa.Count; i++)
            {
                Matrix s_denom = (ident - S[i] * rpa[i].X0);
                Matrix c_denom = (ident + C[i] * rpa[i].X0);

                Matrix s_inv = s_denom.Invert();
                Matrix c_inv = c_denom.Invert();

                System.Diagnostics.Debug.Assert((s_denom * s_inv).IsIdentity);

                rpa[i].Xs = rpa[i].X0 * s_inv;
                rpa[i].Xc = rpa[i].X0 * c_inv;

                for (int l1 = 0; l1 < tb.Orbitals.Count; l1++)
                {
                    for (int l2 = 0; l2 < tb.Orbitals.Count; l2++)
                    {
                        for (int l3 = 0; l3 < tb.Orbitals.Count; l3++)
                        {
                            for (int l4 = 0; l4 < tb.Orbitals.Count; l4++)
                            {
                                int a = GetIndex(tb, l1, l2);
                                int b = GetIndex(tb, l3, l4);

                                bool found = false;

                                if (rpa[i].Xs[a,b].MagnitudeSquared > largest)
                                {
                                    largest = rpa[i].Xs[a,b].MagnitudeSquared;
                                    charge = false;
                                    found = true;
                                }
                                if (rpa[i].Xc[a, b].MagnitudeSquared > largest)
                                {
                                    largest = rpa[i].Xc[a, b].MagnitudeSquared;
                                    charge = true;
                                    found = true;
                                }
                                if (found == false)
                                    continue;

                                indices = string.Format("{0}{1}{2}{3}", l1, l2, l3, l4);
                                largestParams = rpa[i];
                            }
                        }
                    }
                }
            }

            Output.WriteLine("Largest susceptibility found at:");
            Output.WriteLine("    {0} susceptibility: {1}", charge ? "Charge" : "Spin", Math.Sqrt(largest));
            Output.WriteLine("    Indices: {0}", indices);
            Output.WriteLine("    Temperature: {0}", largestParams.Temperature);
            Output.WriteLine("    Frequency: {0}", largestParams.Frequency);
            Output.WriteLine("    Chemical Potential: {0}", largestParams.ChemicalPotential);
            Output.WriteLine("    Q: {0}", largestParams.QptValue);
        }
Пример #48
0
        private double FindNelec(KptList ks, Matrix[] eigenvals, double mu, double beta)
        {
            double N = 0;

            for (int i = 0; i < ks.Kpts.Count; i++)
            {
                double weight = ks.Kpts[i].Weight;

                for (int j = 0; j < eigenvals[i].Rows; j++)
                {
                    double energy = eigenvals[i][j, 0].RealPart;
                    double npt = 2 * FermiFunction(energy, mu, beta);

                    N += npt * weight;
                }
            }
            return N;
        }
Пример #49
0
        private RpaThreadInfo[] CreateThreadInfos(TightBinding tb, List<RpaParams> rpa, KptList qpts)
        {
            RpaThreadInfo[] infos = new RpaThreadInfo[threads];

            for (int i = 0; i < infos.Length; i++)
            {
                infos[i] = new RpaThreadInfo();
                infos[i].tb = tb.Clone();
                infos[i].qpts = qpts;
            }

            infos[0].PrimaryThread = true;

            for (int i = 0; i < rpa.Count; i++)
            {
                infos[i % threads].RpaParams.Add(rpa[i]);
            }

            return infos;
        }
Пример #50
0
            protected override void Validate()
            {
                if (tb.lattice == null)
                {
                    ThrowEx(@"""Lattice"" section missing.");
                }
                if (tb.sites == null)
                {
                    ThrowEx(@"""Sites"" section missing.");
                }
                if (tb.hoppings == null)
                {
                    ThrowEx(@"""Hoppings"" section missing.");
                }
                if (tb.kpath == null)
                {
                    tb.kpath = KptList.DefaultPath(tb.lattice);
                }
                if (tb.kgrid == null || tb.kgrid[0] == 0 || tb.kgrid[1] == 0 || tb.kgrid[2] == 0)
                {
                    ThrowEx(@"KMesh was not defined properly.");
                }

                if (tb.sites.Count == 0)
                {
                    ThrowEx(@"There are no sites.");
                }
                if (tb.hoppings.Count == 0)
                {
                    ThrowEx(@"There are no hoppings.");
                }
                if (tb.symmetries.Count == 0)
                {
                    tb.symmetries.Add(new Symmetry(Matrix.Identity(3)));
                }

                if (tb.Nelec != null)
                {
                    if (tb.MuMesh != null)
                    {
                        ThrowEx(@"Specify only one of Nelec or Mu.");
                    }

                    tb.MuMesh = new double[tb.Nelec.Length];

                    for (int i = 0; i < tb.Nelec.Length; i++)
                    {
                        if (tb.Nelec[i] > tb.Orbitals.Count * 2)
                        {
                            ThrowEx(@"Nelec is too large.");
                        }
                        else if (tb.Nelec[i] < 0)
                        {
                            ThrowEx(@"Nelec cannot be less than zero.");
                        }
                    }
                }

                if (tb.MuMesh == null)
                {
                    tb.MuMesh = new double[] { 0 }
                }
                ;
                if (tb.TemperatureMesh == null)
                {
                    tb.TemperatureMesh = new double[] { 1 }
                }
                ;
                if (tb.FrequencyMesh == null)
                {
                    tb.FrequencyMesh = new double[] { 0 }
                }
                ;

                foreach (HoppingPair h in tb.hoppings)
                {
                    if (h.Left >= tb.sites.Count || h.Right >= tb.sites.Count)
                    {
                        ThrowEx(string.Format(@"The hopping {0} to {1} was specified, but there are only {2} sites.",
                                              h.Left + 1, h.Right + 1, tb.sites.Count));
                    }
                }

                foreach (Orbital orb in tb.Orbitals)
                {
                    var interactionOrbs = tb.Orbitals.Where((x, y) => x.InteractionGroup == orb.InteractionGroup);

                    foreach (Orbital otherOrb in interactionOrbs)
                    {
                        Vector3 delta = otherOrb.Location - orb.Location;

                        if (delta.Magnitude > 1e-8)
                        {
                            ThrowEx(string.Format("In the interaction group {0}, orbitals {1} and {2} are present, but they are in different positions.",
                                                  orb.InteractionGroup, orb.Name, otherOrb.Name));
                        }
                    }
                }
            }
Пример #51
0
        public static KptList GeneratePlane(Lattice lattice, Vector3[] points, SymmetryList syms, int[] qgrid, int[] qshift)
        {
            KptList qmesh = GenerateMesh(lattice, qgrid, qshift, syms, true);

            return(GeneratePlane(lattice, points, syms, qmesh));
        }
Пример #52
0
        public KptList Clone()
        {
            KptList retval = new KptList();

            retval.allKpts.AddRange(allKpts.Select(x => x.Clone()));
            retval.kpts.AddRange(kpts.Select(x => x.Clone()));

            if (mesh != null)
                retval.mesh = (int[])mesh.Clone();
            if (shift != null)
                retval.shift = (int[])shift.Clone();

            retval.gammaCentered = gammaCentered;

            foreach (KeyValuePair<int, int> var in Nvalues)
                retval.Nvalues.Add(var.Key, var.Value);
            foreach (KeyValuePair<int, int> var in AllNvalues)
                retval.AllNvalues.Add(var.Key, var.Value);

            retval.sdir = sdir;
            retval.tdir = tdir;
            retval.origin = origin;

            return retval;
        }
Пример #53
0
        public static KptList GeneratePlane(Lattice lattice, Vector3[] points, SymmetryList syms, KptList qmesh)
        {
            Vector3 diff_1 = points[1] - points[0];
            Vector3 diff_2 = points[2] - points[0];
            Vector3 norm = Vector3.CrossProduct(diff_1, diff_2);

            KptList retval = new KptList();

            retval.mesh = (int[])qmesh.mesh.Clone();
            retval.shift = new int[3];
            retval.gammaCentered = true;

            retval.origin = points[0];
            retval.sdir = diff_1;
            retval.tdir = Vector3.CrossProduct(norm, diff_1);

            NormalizeST(lattice, retval);

            int zmax = qmesh.mesh[2] * 2;
            int ymax = qmesh.mesh[1] * 2;
            int xmax = qmesh.mesh[0] * 2;

            int index = 0;

            List<KPoint> planePoints  = new List<KPoint>();
            for (int i = 0; i < qmesh.AllKpts.Count; i++)
            {
                var qpt = qmesh.AllKpts[i];

                Vector3 diff = qpt.Value - points[0];
                double dot = Math.Abs(diff.DotProduct(norm));

                if (dot < 1e-8)
                {
                    double s, t;

                    retval.GetPlaneST(qpt, out s, out t);
                    planePoints.Add(qpt);
                }
            }
            SortByDistanceFromGamma(planePoints);

            for (int i = 0; i <planePoints.Count; i++)
            {
                var qpt = planePoints[i];
                double s, t;
                retval.GetPlaneST(qpt, out s, out t);

                //if (CenterOnGamma(lattice, ref qpt, retval) == false)
                //    continue;

                //retval.GetPlaneST(qpt, out news, out newt);

                retval.allKpts.Add(qpt);
            }

            // now sort q-points to lay them in the s,t plane.
            Comparison<KPoint> sorter = (x, y) =>
            {
                double s_x, s_y, t_x, t_y;

                retval.GetPlaneST(x, out s_x, out t_x);
                retval.GetPlaneST(y, out s_y, out t_y);

                if (Math.Abs(t_x - t_y) > 1e-6)
                    return t_x.CompareTo(t_y);
                else
                    return s_x.CompareTo(s_y);
            };

            retval.allKpts.Sort(sorter);

            // now reduce points by symmetry.
            for (int i = 0; i < retval.allKpts.Count; i++)
            {
                var qpt = retval.AllKpts[i];

                int N = retval.KptToInteger(lattice, qpt);
                int symN = N;
                bool foundSym = false;
                List<int> orbitals = null;

                Vector3 pt = qpt.Value;

                foreach (var symmetry in syms)
                {
                    Vector3 Tpt = symmetry.Value * pt;

                    int newi, newj, newk;
                    retval.ReduceKpt(lattice, Tpt, out newi, out newj, out newk);

                    if (newi % 2 != 0 || newj % 2 != 0 || newk % 2 != 0)
                        continue;

                    symN = retval.KptToInteger(newi, newj, newk);

                    if (retval.Nvalues.ContainsKey(symN))
                    {
                        foundSym = true;

                        if (symmetry.OrbitalTransform.Count > 0)
                        {
                            orbitals = symmetry.OrbitalTransform;
                        }
                    }

                    if (foundSym)
                        break;
                }

                if (foundSym == false && retval.Nvalues.ContainsKey(N) == false)
                {
                    retval.kpts.Add(qpt);
                    retval.Nvalues.Add(N, index);
                    index++;
                }
                else if (retval.Nvalues.ContainsKey(N) == false)
                {
                    int newIndex = retval.Nvalues[symN];
                    retval.kpts[newIndex].AddOrbitalSymmetry(orbitals);

                    retval.Nvalues.Add(N, newIndex);
                }
                else
                { }  // skip points which are already in there.  This should only happen for zone edge points
            }

            retval.kpts.Sort(sorter);

            Vector3 sd = retval.sdir / SmallestNonzero(retval.sdir);
            Vector3 td = retval.tdir / SmallestNonzero(retval.tdir);

            Output.WriteLine("Plane horizontal direction: {0}", sd);
            Output.WriteLine("Plane vertical direction: {0}", td);

            Output.WriteLine("Plane horizontal vector: {0}", retval.sdir);
            Output.WriteLine("Plane vertical vector: {0}", retval.tdir);

            return retval;
        }