private void GenerateSymmetries() { Symmetries = new SymmetryList(); Symmetries.Add(new Symmetry(Matrix.Identity(3))); foreach (var sym in PrimitiveSymmetries) { Symmetries.Add(sym.Clone()); GenerateSymmetries(sym); } }
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); }
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); }
static void Initialize() { if (init) { return; } init = true; InitializeRegex(); string groups = Properties.Resources.spgroup; using (StringReader r = new StringReader(groups)) { for (; ;) { string groupName = r.ReadLine().Trim(); int number; if (groupName.EndsWith("&")) { break; } if (int.TryParse(groupName.Substring(1, groupName.Length - 2), out number) == false) { throw new Exception(); } SpaceGroup sp = new SpaceGroup(); sp.Number = number; for (; ;) { if (r.Peek() == '/') { break; } string text = r.ReadLine(); int lastColon = text.IndexOf(":", 8); var sym = ParseSymmetry(text); sym.Name = text.Substring(lastColon + 1).Trim(); if (sym.Value.IsIdentity) { continue; } if (mPrimitiveSymmetries.Contains(sym) == false) { mPrimitiveSymmetries.Add(sym); } sp.PrimitiveSymmetries.Add(sym); } mGroups.Add(number, sp); } } using (StringReader r = new StringReader(Properties.Resources.spnames)) { for (; ;) { string text = r.ReadLine(); if (text == "&") { break; } string[] vals = text.Split('-'); int number = int.Parse(vals[0]); string name = vals[1].Trim(); mGroups[number].Name = name; } } }