Пример #1
0
        public static SpaceGroup IdentifyGroup(SymmetryList syms)
        {
            for (int i = 230; i >= 1; i--)
            {
                SpaceGroup test = mGroups[i];
                bool found = true;

                foreach (var sym in test.PrimitiveSymmetries)
                {
                    if (syms.Contains(sym) == false)
                        found = false;
                }

                if (found)
                {
                    test.GenerateSymmetries();
                    return test;
                }
            }

            // return lowest symmetry group.
            mGroups[1].GenerateSymmetries();
            return mGroups[1];
        }
Пример #2
0
        internal void SetWavefunctions(KPoint otherPt, SymmetryList symmetries, List<int> orbitalMap)
        {
            if (this.wfk.Count != 0) throw new InvalidOperationException();

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

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

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

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

                }

                this.wfk.Add(wfk);
            }
        }
Пример #3
0
 public SpaceGroup()
 {
     PrimitiveSymmetries = new SymmetryList();
 }
Пример #4
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;
        }
Пример #5
0
        private void GenerateSymmetries()
        {
            Symmetries = new SymmetryList();
            Symmetries.Add(new Symmetry(Matrix.Identity(3)));

            foreach (var sym in PrimitiveSymmetries)
            {
                Symmetries.Add(sym.Clone());

                GenerateSymmetries(sym);
            }
        }
Пример #6
0
        public int IrreducibleIndex(Vector3 kpt, Lattice lattice, SymmetryList symmetries, out List<int> orbitalMap)
        {
            for (int s = 0; s < symmetries.Count; s++)
            {
                int newi, newj, newk;
                Vector3 newKpt = symmetries[s].Inverse * kpt;

                ReduceKpt(lattice, newKpt, out newi, out newj, out newk);

                int N = KptToInteger(newi, newj, newk);

                if (Nvalues.ContainsKey(N))
                {
                    int index = Nvalues[N];

                    orbitalMap = symmetries[s].OrbitalTransform;
                    return index;
                }
            }

            throw new Exception(string.Format("Could not find k-point {0}", kpt));
        }
Пример #7
0
        private static SymmetryList FindCompatibleSymmetries(int[] kgrid, SymmetryList syms)
        {
            SymmetryList compatSyms;
            compatSyms = new SymmetryList();
            Vector3 gridVector = new Vector3(kgrid[0], kgrid[1], kgrid[2]);

            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);
                }
            }
            return compatSyms;
        }
Пример #8
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;
        }
Пример #9
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;
        }
Пример #10
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);
 }
Пример #11
0
        public KptPlane CreateIrreduciblePlane(SymmetryList symmetries)
        {
            KptPlane p = new KptPlane();

            p.origin = origin;
            p.tdir = tdir;
            p.sdir = sdir;

            FillIrreducibleMesh(symmetries, p);

            return p;
        }
Пример #12
0
 public override KptList CreateIrreducibleMesh(SymmetryList symmetryList)
 {
     return CreateIrreduciblePlane(symmetryList);
 }