private void AddLeftBoundary(Vector3 closestGamma, KPoint kpt, KptPlane plane, Lattice lattice) { double s, t; plane.GetPlaneST(kpt, out s, out t); double gs, gt; plane.GetPlaneST(closestGamma, out gs, out gt); if (gs == 0) { return; } double ratio = gt / gs; // this is the solution to // |S| = |S-P| where S is the target point, P is the nearby Gamma point // and the y component of S is constrained to be the same as for the input. double news = 0.5 * (gs + gt * ratio - 2 * t * ratio); if (Math.Abs(news - s) < 1e-6) { return; } Kpts.Add(new BZoneKPoint(plane.ReduceST(news, t))); }
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(); } } }
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); }
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); } }
private Vector3 ClosestGamma(List <Vector3> nearbyGammas, KPoint kpt, Lattice lattice) { if (nearbyGammas.Count == 0) { throw new ArgumentException(); } double minDistance = double.MaxValue; Vector3 closest = new Vector3(); Vector3 kptCart = lattice.ReciprocalExpand(kpt.Value); foreach (var pt in nearbyGammas) { Vector3 gamma = lattice.ReciprocalExpand(pt); double distance = (kptCart - gamma).Magnitude; double s, t; GetPlaneST(pt, out s, out t); if (distance < minDistance) { minDistance = distance; closest = pt; } } return(closest); }
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); } } }
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); } } }
private static double GetWeight(KPoint kpt, Matrix vecs, int j, int state) { int count = 1; double wtk = vecs[state, j].MagnitudeSquared; foreach (int orb in kpt.GetEquivalentOrbitals(state)) { wtk += vecs[orb, j].MagnitudeSquared; count++; } return(wtk / count); }
public bool GetPlaneST(KPoint kpt, out double s, out double t) { s = (kpt.Value - origin).DotProduct(sdir); t = (kpt.Value - origin).DotProduct(tdir); double norm = (kpt.Value - origin).DotProduct(sdir.CrossProduct(tdir)); if (Math.Abs(norm) > 1e-7) { return(false); } else { return(true); } }
public KPoint Clone() { KPoint retval = new KPoint(Value); retval.Weight = Weight; retval.Name = Name; foreach (var transform in mOrbitalTransform) { List<int> newxform = new List<int>(); newxform.AddRange(transform); retval.mOrbitalTransform.Add(newxform); } retval.wfk.AddRange(wfk.Select(x => x.Clone())); return retval; }
public KPoint Clone() { KPoint retval = new KPoint(Value); retval.Weight = Weight; retval.Name = Name; foreach (var transform in mOrbitalTransform) { List <int> newxform = new List <int>(); newxform.AddRange(transform); retval.mOrbitalTransform.Add(newxform); } retval.wfk.AddRange(wfk.Select(x => x.Clone())); return(retval); }
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(); }
private void CalcWavefunctions() { for (int i = 0; i < KMesh.Kpts.Count; i++) { Matrix m = CalcHamiltonian(KMesh.Kpts[i]); Matrix vals, vecs; m.EigenValsVecs(out vals, out vecs); kmesh.Kpts[i].SetWavefunctions(vals, vecs); } for (int i = 0; i < kmesh.AllKpts.Count; i++) { KPoint kpt = kmesh.AllKpts[i]; List <int> orbitalMap; int index = kmesh.IrreducibleIndex(kpt, lattice, symmetries, out orbitalMap); kpt.SetWavefunctions(kmesh.Kpts[index], symmetries, orbitalMap); } }
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); } }
private int KptToInteger(Lattice lattice, KPoint qpt) { return KptToInteger(lattice, qpt.Value); }
public BZoneKPoint(KPoint value, int index) : base(value.Value) { TargetIndex = index; }
public double Interpolate(KPoint kpt) { return(0); }
private int KptToInteger(Lattice lattice, KPoint qpt) { return(KptToInteger(lattice, qpt.Value)); }
public bool GetPlaneST(KPoint kpt, out double s, out double t) { return(GetPlaneST(kpt.Value, out s, out t)); }
public double Interpolate(KPoint kpt) { return 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; }
private void AddLeftBoundary(Vector3 closestGamma, KPoint kpt, KptPlane plane, Lattice lattice) { double s, t; plane.GetPlaneST(kpt, out s, out t); double gs, gt; plane.GetPlaneST(closestGamma, out gs, out gt); if (gs == 0) return; double ratio = gt / gs; // this is the solution to // |S| = |S-P| where S is the target point, P is the nearby Gamma point // and the y component of S is constrained to be the same as for the input. double news = 0.5 * (gs + gt * ratio - 2 * t * ratio); if (Math.Abs(news - s) < 1e-6) return; Kpts.Add(new BZoneKPoint(plane.ReduceST(news, t))); }
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(); } } } }
public bool GetPlaneST(KPoint kpt, out double s, out double t) { s = (kpt.Value - origin).DotProduct(sdir); t = (kpt.Value - origin).DotProduct(tdir); double norm = (kpt.Value - origin).DotProduct(sdir.CrossProduct(tdir)); if (Math.Abs(norm) > 1e-7) return false; else return true; }
private static double GetWeight(KPoint kpt, Matrix vecs, int j, int state) { int count = 1; double wtk = vecs[state, j].MagnitudeSquared; foreach (int orb in kpt.GetEquivalentOrbitals(state)) { wtk += vecs[orb, j].MagnitudeSquared; count++; } return wtk / count; }
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; }
public bool Contains(KPoint kpt) { return(false); }
private Vector3 ClosestGamma(List<Vector3> nearbyGammas, KPoint kpt, Lattice lattice) { if (nearbyGammas.Count == 0) throw new ArgumentException(); double minDistance = double.MaxValue; Vector3 closest = new Vector3(); Vector3 kptCart = lattice.ReciprocalExpand(kpt.Value); foreach (var pt in nearbyGammas) { Vector3 gamma = lattice.ReciprocalExpand(pt); double distance = (kptCart - gamma).Magnitude; double s, t; GetPlaneST(pt, out s, out t); if (distance < minDistance) { minDistance = distance; closest = pt; } } return closest; }
public bool Contains(KPoint kpt) { return false; }
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); }
void ApplySymmetries() { List <Matrix> validSyms = new List <Matrix>(); Matrix reduce = new Matrix(3, 3); reduce.SetRows(tb.lattice.G1, tb.lattice.G2, tb.lattice.G3); int symIndex = 0; using (StreamWriter s = new StreamWriter("syms")) { foreach (var sym in GetPossibleSymmetries()) { symIndex++; s.WriteLine(); s.WriteLine("Applying symmetry " + symIndex.ToString() + ":"); s.WriteLine(sym); Matrix lat = new Matrix(3, 3); lat.SetColumns(sym * tb.lattice.A1, sym * tb.lattice.A2, sym * tb.lattice.A3); lat = reduce * lat; s.WriteLine("Lattice vector test..."); if (CheckLatticeSymmetry(lat) == false) { goto fail; } Dictionary <int, int> sitemap = new Dictionary <int, int>(); s.WriteLine("Generating site map..."); for (int i = 0; i < tb.sites.Count; i++) { var site = tb.sites[i]; Vector3 loc = sym * site.Location; int index = tb.Orbitals.FindIndex(tb.lattice, loc); if (index == -1) { s.WriteLine("Failed to map site " + i.ToString()); goto fail; } sitemap[i] = index; s.WriteLine(" " + i.ToString() + " => " + index.ToString()); } HoppingPairList newHops = new HoppingPairList(); // rotate hoppings for (int i = 0; i < tb.hoppings.Count; i++) { var pair = tb.hoppings[i]; int newleft = sitemap[pair.Left]; int newright = sitemap[pair.Right]; HoppingPair newPair = new HoppingPair(newleft, newright); newHops.Add(newPair); foreach (var hop in pair.Hoppings) { HoppingValue v = new HoppingValue(); v.Value = hop.Value; v.R = sym * hop.R; newPair.Hoppings.Add(v); } } s.WriteLine("Performing hopping test..."); if (newHops.Equals(tb.hoppings) == false) { goto fail; } s.WriteLine("Success."); validSyms.Add(sym); continue; fail: s.WriteLine("Failed."); } // now apply symmetries to reduce k-points in kmesh int initialKptCount = tb.kmesh.Kpts.Count; System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); foreach (var sym in validSyms) { for (int i = 0; i < tb.kmesh.Kpts.Count; i++) { KPoint kpt = tb.kmesh.Kpts[i]; Vector3 trans = kpt.Value; /* * for (int j = 0; j < 3; j++) * { * trans = sym * trans; * * int index = kmesh.IndexOf(trans, i+1); * * if (index == -1) * continue; * * kmesh.Kpts.RemoveAt(index); * kpt.Weight ++; * * } */ } } watch.Stop(); string fmt = string.Format("{0} total kpts, {1} irreducible kpts. Applying symmetries took {2} seconds.", initialKptCount, tb.kmesh.Kpts.Count, watch.ElapsedMilliseconds / 1000); Output.WriteLine(fmt); s.WriteLine(fmt); } }
public bool GetPlaneST(KPoint kpt, out double s, out double t) { return GetPlaneST(kpt.Value, out s, out t); }