예제 #1
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;
        }
예제 #2
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;
        }
예제 #3
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);
        }
예제 #4
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);
        }
예제 #5
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();
                    }
                }
            }
        }