private int GetGreenIndex(RpaParams[] plist) { if (plist.Length == 1) return 0; Console.WriteLine(); Console.WriteLine("Found {0} Green's functions.", plist.Length); for(;;) { Console.Write("Enter index to use (1-{0}): ", plist.Length); int index; if (int.TryParse(Console.ReadLine(), out index) == false) continue; Console.WriteLine(); Console.WriteLine("Chose Green's function index {0}.", index); Console.WriteLine(" Temperature: {0}", plist[index].Temperature); Console.WriteLine(" Frequency: {0}", plist[index].Frequency); Console.WriteLine(" Mu: {0}", plist[index].ChemicalPotential); Console.WriteLine(); Console.Write("Is this ok (y/n)? "); var key = Console.ReadKey(); if (key.Key == ConsoleKey.Y) { return index; } } }
/// <summary> /// Sorts by temperature, chemical potential, frequency, qindex. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public static int QIndexComparison(RpaParams x, RpaParams y) { if (x.Temperature != y.Temperature) return x.Temperature.CompareTo(y.Temperature); if (x.ChemicalPotential != y.ChemicalPotential) return x.ChemicalPotential.CompareTo(y.ChemicalPotential); if (x.Frequency != y.Frequency) return x.Frequency.CompareTo(y.Frequency); return x.Qindex.CompareTo(y.Qindex); }
double InteractionAdjustment(List <RpaParams> rpa, Matrix[] S, Matrix[] C, TightBinding tb) { double largest = double.MinValue; RpaParams largestParams = null; bool Cdiv = false; for (int i = 0; i < rpa.Count; i++) { RpaParams p = rpa[i]; Matrix x0 = p.X0; double lv = LargestPositiveEigenvalue(x0 * S[i]); if (lv > largest) { largest = lv; largestParams = p; Cdiv = false; } lv = LargestPositiveEigenvalue(-x0 * C[i]); if (lv > largest) { largest = lv; largestParams = p; Cdiv = true; } } if (largest >= 1) { Output.WriteLine("Interaction should be reduced to avoid divergence.", largest); } Output.WriteLine("Largest eigenvalue of denominator found at:"); Output.WriteLine(" Eigenvalue: {0}", largest); Output.WriteLine(" {0} susceptibility", Cdiv ? "Charge" : "Spin"); Output.WriteLine(" q = {0}", largestParams.QptValue); Output.WriteLine(" Temperature = {0}", largestParams.Temperature); Output.WriteLine(" Chemical Potential = {0}", largestParams.ChemicalPotential); Output.WriteLine(" Frequency = {0}", largestParams.Frequency); largest /= tb.Interactions.MaxEigenvalue; Output.WriteLine(); return(1 / largest); }
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; }
/// <summary> /// Sorts by temperature, chemical potential, frequency, qindex. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public static int QIndexComparison(RpaParams x, RpaParams y) { if (x.Temperature != y.Temperature) { return(x.Temperature.CompareTo(y.Temperature)); } if (x.ChemicalPotential != y.ChemicalPotential) { return(x.ChemicalPotential.CompareTo(y.ChemicalPotential)); } if (x.Frequency != y.Frequency) { return(x.Frequency.CompareTo(y.Frequency)); } return(x.Qindex.CompareTo(y.Qindex)); }
void Run(string inputfile) { using (StreamWriter w = new StreamWriter("gplot.out")) { Output.SetFile(w); TightBindingSuite.TightBinding tb = new TightBindingSuite.TightBinding(); tb.LoadTB(inputfile); RpaParams p = new RpaParams(0, Vector3.Zero, tb.TemperatureMesh[0], tb.FrequencyMesh[0], tb.MuMesh[0]); KptList kmesh = KptList.GenerateMesh( tb.Lattice, tb.KMesh.Mesh, null, tb.Symmetries, true); Matrix[] green = CalcGreenFunction(tb, p, kmesh); while (true) { WriteGreenFunction(tb, green, kmesh); }; } }
private void CalcSusceptibility(TightBinding tb, KptList qpts, List <RpaParams> rpa) { Matrix ident = Matrix.Identity(tb.Orbitals.Count * tb.Orbitals.Count); Matrix[] S, C; CalcSpinChargeMatrices(tb, rpa, out S, out C); Output.WriteLine("Calculating X0..."); RpaThreadInfo[] threadInfos = CreateThreadInfos(tb, rpa, qpts); Output.WriteLine("Using {0} threads.", threads); for (int i = 0; i < threadInfos.Length; i++) { RunRpaThread(threadInfos[i]); if (i == 0) { Thread.Sleep(20); } } bool threadsRunning; do { threadsRunning = false; for (int i = 0; i < threadInfos.Length; i++) { if (threadInfos[i].Thread.ThreadState == ThreadState.Running) { threadsRunning = true; } } Thread.Sleep(10); } while (threadsRunning); Output.WriteLine(); Output.WriteLine("Bare susceptibility calculation completed."); Output.WriteLine(); double factor = InteractionAdjustment(rpa, S, C, tb); if (tb.Interactions.AdjustInteractions) { Output.WriteLine("Multiplying interactions by {0}.", factor); for (int i = 0; i < rpa.Count; i++) { S[i] *= factor; C[i] *= factor; } } else if (factor < 1) { Output.WriteLine("WARNING: There will be divergent geometric series."); Output.WriteLine(" Interpret results with care!"); } Output.WriteLine(); Output.WriteLine("Calculating dressed susceptibilities."); Output.WriteLine(); RpaParams largestParams = null; double largest = 0; string indices = ""; bool charge = false; for (int i = 0; i < rpa.Count; i++) { Matrix s_denom = (ident - S[i] * rpa[i].X0); Matrix c_denom = (ident + C[i] * rpa[i].X0); Matrix s_inv = s_denom.Invert(); Matrix c_inv = c_denom.Invert(); System.Diagnostics.Debug.Assert((s_denom * s_inv).IsIdentity); rpa[i].Xs = rpa[i].X0 * s_inv; rpa[i].Xc = rpa[i].X0 * c_inv; for (int l1 = 0; l1 < tb.Orbitals.Count; l1++) { for (int l2 = 0; l2 < tb.Orbitals.Count; l2++) { for (int l3 = 0; l3 < tb.Orbitals.Count; l3++) { for (int l4 = 0; l4 < tb.Orbitals.Count; l4++) { int a = GetIndex(tb, l1, l2); int b = GetIndex(tb, l3, l4); bool found = false; if (rpa[i].Xs[a, b].MagnitudeSquared > largest) { largest = rpa[i].Xs[a, b].MagnitudeSquared; charge = false; found = true; } if (rpa[i].Xc[a, b].MagnitudeSquared > largest) { largest = rpa[i].Xc[a, b].MagnitudeSquared; charge = true; found = true; } if (found == false) { continue; } indices = string.Format("{0}{1}{2}{3}", l1, l2, l3, l4); largestParams = rpa[i]; } } } } } Output.WriteLine("Largest susceptibility found at:"); Output.WriteLine(" {0} susceptibility: {1}", charge ? "Charge" : "Spin", Math.Sqrt(largest)); Output.WriteLine(" Indices: {0}", indices); Output.WriteLine(" Temperature: {0}", largestParams.Temperature); Output.WriteLine(" Frequency: {0}", largestParams.Frequency); Output.WriteLine(" Chemical Potential: {0}", largestParams.ChemicalPotential); Output.WriteLine(" Q: {0}", largestParams.QptValue); }