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); } }
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); } } }
internal void SetWavefunctions(Matrix eigenvals, Matrix eigenvecs) { for (int n = 0; n < eigenvals.Rows; n++) { var wfk = new Wavefunction(eigenvecs.Rows); wfk.Energy = eigenvals[n, 0].RealPart; for (int c = 0; c < eigenvecs.Rows; c++) { wfk.Coeffs[c] = eigenvecs[c, n]; } this.wfk.Add(wfk); } }
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; }
public Wavefunction Clone(List<int> orbitalMap) { Wavefunction retval = new Wavefunction(coeffs.Length); retval.Energy = Energy; retval.FermiFunction = FermiFunction; if (orbitalMap != null && orbitalMap.Count > 0) { for (int i = 0; i < coeffs.Length; i++) { retval.coeffs[orbitalMap[i]] = coeffs[i]; } } else retval.coeffs = (Complex[])coeffs.Clone(); return retval; }
public Wavefunction Clone(List <int> orbitalMap) { Wavefunction retval = new Wavefunction(coeffs.Length); retval.Energy = Energy; retval.FermiFunction = FermiFunction; if (orbitalMap != null && orbitalMap.Count > 0) { for (int i = 0; i < coeffs.Length; i++) { retval.coeffs[orbitalMap[i]] = coeffs[i]; } } else { retval.coeffs = (Complex[])coeffs.Clone(); } return(retval); }
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(); } } } }
Matrix CalcX0(TightBinding tb, double freq, Vector3 q) { int orbitalCount = tb.Orbitals.Count; int size = orbitalCount * orbitalCount; Matrix x = new Matrix(size, size); Complex denom_factor = new Complex(0, 1e-4); //StreamWriter w = new StreamWriter(string.Format("qcont.{0}", q.ToString("0.000"))); //bool writeThis = false; for (int l1 = 0; l1 < orbitalCount; l1++) { for (int l4 = 0; l4 < orbitalCount; l4++) { for (int l3 = l1; l3 < orbitalCount; l3++) { for (int l2 = l4; l2 < orbitalCount; l2++) { int i = GetIndex(tb, l1, l2); int j = GetIndex(tb, l3, l4); bool foundSymmetry = false; //if (l1 == 0 && l2 == 0 && l3 == 0 && l4 == 0) // writeThis = true; //else //writeThis = false; //if (writeThis) // w.WriteLine("{0}{1}{2}{3}", l1, l2, l3, l4); for (int s = 0; s < tb.Symmetries.Count; s++) { Symmetry sym = tb.Symmetries[s]; if (sym.OrbitalTransform == null || sym.OrbitalTransform.Count == 0) { continue; } int newL1 = sym.OrbitalTransform[l1]; int newL2 = sym.OrbitalTransform[l2]; int newL3 = sym.OrbitalTransform[l3]; int newL4 = sym.OrbitalTransform[l4]; int newI = GetIndex(tb, newL1, newL2); int newJ = GetIndex(tb, newL3, newL4); if (newI == i && newJ == j) { continue; } foundSymmetry = true; if (newL1 > l1) { foundSymmetry = false; } if (newL2 > l2) { foundSymmetry = false; } if (newL3 > l3) { foundSymmetry = false; } if (newL4 > l4) { foundSymmetry = false; } if (foundSymmetry) { x[i, j] = x[newI, newJ]; x[j, i] = x[i, j].Conjugate(); break; } } if (foundSymmetry) { continue; } Complex total = 0; for (int allkindex = 0; allkindex < tb.KMesh.AllKpts.Count; allkindex++) { Complex val = 0; Vector3 k = tb.KMesh.AllKpts[allkindex]; Vector3 kq = k + q; //List<int> kOrbitalMap; //List<int> kqOrbitalMap; //int kindex = tb.KMesh.IrreducibleIndex(k, tb.Lattice, tb.Symmetries, out kOrbitalMap); //int kqindex = tb.KMesh.IrreducibleIndex(kq, tb.Lattice, tb.Symmetries, out kqOrbitalMap); int kindex = tb.KMesh.AllKindex(k, tb.Lattice); int kqindex = tb.KMesh.AllKindex(kq, tb.Lattice); System.Diagnostics.Debug.Assert(kindex == allkindex); //int newL1 = TransformOrbital(kqOrbitalMap, l1); //int newL2 = TransformOrbital(kOrbitalMap, l2); //int newL3 = TransformOrbital(kqOrbitalMap, l3); //int newL4 = TransformOrbital(kOrbitalMap, l4); for (int n1 = 0; n1 < orbitalCount; n1++) { Wavefunction wfk = Bands(tb, kindex, n1); double e1 = wfk.Energy; double f1 = wfk.FermiFunction; for (int n2 = 0; n2 < orbitalCount; n2++) { Wavefunction wfq = Bands(tb, kqindex, n2); double e2 = wfq.Energy; double f2 = wfq.FermiFunction; Complex coeff = wfq.Coeffs[l1] * wfq.Coeffs[l4].Conjugate() * wfk.Coeffs[l3] * wfk.Coeffs[l2].Conjugate(); if (coeff == 0) { continue; } if (f1 < 1e-15 && f2 < 1e-15) { continue; } Complex denom_p = (e2 - e1 + freq + denom_factor); //Complex denom_n = (e2 - e1 - freq - denom_factor); //Complex lindhard = (f1 - f2) * (1.0 / denom_p + 1.0 / denom_n); Complex lindhard = (f1 - f2) * (1.0 / denom_p); Complex contrib = coeff * lindhard; if (Math.Abs(f1 - f2) < 1e-11 && freq == 0.0) { contrib = coeff * f1 * (1 - f1) * Beta; } //w.Write("{0} {1} {2} {3} ", kindex, kqindex, n1, n2); //w.WriteLine("{0} {1} {2} {3} {4}", coeff, e1, e2, f1, f2); if (double.IsNaN(contrib.RealPart) || double.IsNaN(contrib.ImagPart)) { throw new Exception("Found NaN when evaluating X0"); } val += contrib; } } //w.WriteLine("{0} {1} total {2} + {3}i", kindex, kqindex, // Math.Round(val.RealPart, 4), Math.Round(val.ImagPart, 4)); //Output.WriteLine(tb.KMesh.AllKpts[kindex].Weight.ToString()); val *= tb.KMesh.AllKpts[kindex].Weight; total += val; //if (writeThis) // w.WriteLine("{0} {1} {2}", allkindex, total, val); } x[i, j] = total; x[j, i] = total.Conjugate(); //if (writeThis) //{ // w.WriteLine("total for {0}{1}{2}{3}: {4}", l1, l2, l3, l4, total); // w.WriteLine("---------------------"); //} } } } } //w.Close(); return(x); }
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); } }
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); } } }