public Matrix CalcHamiltonian(Vector3 kpt) { Matrix m = new Matrix(Orbitals.Count, Orbitals.Count); kpt *= 2 * Math.PI; for (int i = 0; i < Orbitals.Count; i++) { for (int j = 0; j < Orbitals.Count; j++) { HoppingPair p = Hoppings.FindOrThrow(i, j); Complex val = new Complex(); for (int k = 0; k < p.Hoppings.Count; k++) { HoppingValue hop = p.Hoppings[k]; Vector3 R = hop.R; Complex newval = hop.Value * Complex.Exp(new Complex(0, kpt.DotProduct(R))); val += newval; } m[i, j] = val; } } if (m.IsHermitian == false) { throw new Exception("Hamiltonian at k = " + kpt.ToString() + " is not Hermitian."); } return(m); }
/// <summary> /// This function does not work with symmetries, so it is unused. /// </summary> /// <param name="inp"></param> /// <param name="outputfile"></param> void tet_DoDensityOfStates(TightBinding.TbInputFileReader inp) { KptList ks = KMesh; StreamWriter outf = new StreamWriter(outputfile + ".dos"); double smearing = TemperatureMesh[0]; double smearNorm = 1 / smearing * Math.Pow(Math.PI, -0.5); double oneOverSmearSquared = Math.Pow(smearing, -2); double emin, emax; Hoppings.EnergyScale(out emin, out emax); emin -= smearing * 5; emax += smearing * 5; int epts = 2000; double[] energyGrid = new double[epts]; double[,] dos = new double[epts, Orbitals.Count + 1]; smearNorm /= ks.Kpts.Count; for (int i = 0; i < epts; i++) { energyGrid[i] = emin + (emax - emin) * i / (double)(epts - 1); } Output.WriteLine("Calculating DOS from {0} to {1} with tetrahedron method.", emin, emax, smearing); Output.WriteLine("Using {0} tetrahedrons.", ks.Tetrahedrons.Count); for (int tetindex = 0; tetindex < ks.Tetrahedrons.Count; tetindex++) { Tetrahedron tet = ks.Tetrahedrons[tetindex]; if (tetindex % (ks.Tetrahedrons.Count / 10) == 0 && tetindex > 0) { Output.WriteLine("At {0}...", tetindex); } Matrix[] eigenvals = new Matrix[4]; for (int i = 0; i < 4; i++) { Matrix m = CalcHamiltonian(tet.Corners[i]); Matrix vals, vecs; m.EigenValsVecs(out vals, out vecs); eigenvals[i] = vals; } for (int nband = 0; nband < eigenvals[0].Rows; nband++) { for (int i = 0; i < 4; i++) { tet.Values[i] = eigenvals[i][nband, 0].RealPart; } tet.SortCorners(); int estart = FindIndex(energyGrid, tet.Values[0]); int eend = FindIndex(energyGrid, tet.Values[3]); for (int ei = estart; ei < eend; ei++) { dos[ei, 0] += tet.IntegrateArea(energyGrid[ei]); } } } for (int i = 0; i < epts; i++) { dos[i, 0] /= ks.Tetrahedrons.Count; } 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(); } outf.Close(); Output.WriteLine("Creating +coeff file."); outf = new StreamWriter(Path.Combine(Path.GetDirectoryName(outputfile), "+coeff")); outf.WriteLine("#\t1\t0\t" + ks.Kpts.Count.ToString()); outf.Write("# band index\te(k,n)\t"); for (int i = 0; i < Orbitals.Count; i++) { if (string.IsNullOrEmpty(Orbitals[i].Name)) { outf.Write("TB{0}\t", i); } else { outf.Write("{0}\t", Orbitals[i].Name); } } outf.WriteLine(); for (int kindex = 0; kindex < ks.Kpts.Count; kindex++) { Matrix m = CalcHamiltonian(ks.Kpts[kindex]); Matrix vals, vecs; m.EigenValsVecs(out vals, out vecs); outf.WriteLine("# spin= 1 k={0}", ks.Kpts[kindex].Value); for (int i = 0; i < vals.Rows; i++) { outf.Write("{0} {1} ", i + 1, vals[i, 0].RealPart); for (int j = 0; j < vecs.Columns; j++) { outf.Write("{0} {1} ", vecs[i, j].RealPart, vecs[i, j].ImagPart); } outf.WriteLine(); } } }