public double[] GetAveragePotentials() { int n = posParticles.Length; double pSum = 0.0; double pSum2 = 0.0; double charge = 1.0 / n; // Total one Coulomb on each surface. foreach (Vector x in posParticles) { double phi = EField.GetPotential(x, posParticles, negParticles, charge); pSum += phi; pSum2 += phi * phi; } double nSum = 0.0; double nSum2 = 0.0; foreach (Vector x in negParticles) { double phi = EField.GetPotential(x, posParticles, negParticles, charge); nSum += phi; nSum2 += phi * phi; } double pAvg = pSum / n; double pVar = (pSum2 - n * pAvg * pAvg) / (n - 1); double pSdev = Math.Sqrt(pVar); double nAvg = nSum / n; double nVar = (nSum2 - n * nAvg * nAvg) / (n - 1); double nSdev = Math.Sqrt(nVar); return(new double[] { pAvg, pSdev, nAvg, nSdev }); }
public void DoSteps(int nSteps) { int n = posParticles.Length; double charge = 1.0 / n; // Total one Coulomb on each surface. for (int iStep = 0; iStep < nSteps; iStep++) { // All the positive particles. for (int i = 0; i < n; i++) { Vector x0 = posParticles[i]; double phi0 = EField.GetPotential(x0, posParticles, negParticles, charge); Vector x1 = anode.RandomPoint(); posParticles[i] = x1; double phi1 = EField.GetPotential(x1, posParticles, negParticles, charge); // Put back the old position if the energy is not lowered. if (phi1 > phi0) { posParticles[i] = x0; } } // All the negative particles. for (int i = 0; i < n; i++) { Vector x0 = negParticles[i]; double phi0 = EField.GetPotential(x0, posParticles, negParticles, charge); Vector x1 = cathode.RandomPoint(); negParticles[i] = x1; double phi1 = EField.GetPotential(x1, posParticles, negParticles, charge); // Put back the old position if the energy is not lowered. (I.e. moved toward zero.) if (phi1 < phi0) { negParticles[i] = x0; } } } }
static void Main(string[] args) { if (!ReadArgs(args)) { return; } try { if (outFile != null) { tw = new StreamWriter(outFile); } //WriteLine("Command line: efield {0}", String.Join(" ", args)); WriteLine("Command line: {0}", Environment.CommandLine); WriteLine("Run by: {0}\\{1} on {2}", Environment.UserDomainName, Environment.UserName, Environment.MachineName); DateTime startTime = DateTime.Now; WriteLine(startTime.ToString()); if (!haveSeed) { seed = (uint)startTime.Ticks; } PseudoDES rand = new PseudoDES(0, seed); WriteLine("Seed = {0}", seed); if (!File.Exists(posFileName)) { throw new Exception(string.Format("Anode description file {0} not found", posFileName)); } if (!File.Exists(negFileName)) { throw new Exception(string.Format("Cathode description file {0} not found", negFileName)); } Surface anode = new Surface(new StlFile(posFileName), rand); Surface cathode = new Surface(new StlFile(negFileName), rand); WriteLine("Anode: {0} Triangles: {1} Area: {2:0.0000} m^2", posFileName, anode.TriangleCount, anode.TotalArea); WriteLine("Cathode: {0} Triangles: {1} Area: {2:0.0000} m^2", negFileName, cathode.TriangleCount, cathode.TotalArea); // Trap ^C Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress); // Create the Balancer. Balancer baal = new Balancer(nParticles, anode, cathode); // Let's see the starting potentials. double[] pots = baal.GetAveragePotentials(); WriteLine("Steps: {0,5} Potentials: {1:0.00e00} {2:0.00e00} {3:0.00e00} {4:0.00e00}", 0, pots[0], pots[1], pots[2], pots[3]); int batch = 10; for (int nDone = 0; nDone < nReps; nDone += batch) { // Run some steps. baal.DoSteps(Math.Min(batch, nReps - nDone)); // And report. pots = baal.GetAveragePotentials(); WriteLine("Steps: {0,5} Potentials: {1:0.00e00} {2:0.00e00} {3:0.00e00} {4:0.00e00}", Math.Min(nDone + batch, nReps), pots[0], pots[1], pots[2], pots[3]); if (cancelWasReceived) { break; } } DateTime endTime = DateTime.Now; TimeSpan runTime = endTime - startTime; if (cancelWasReceived) { WriteLine("Received ^C, terminating early!"); } WriteLine("Run time = {0:0.000} minutes", runTime.TotalMinutes); double potentialDifference = pots[0] - pots[2]; double posSdev = 100.0 * pots[1] / Math.Abs(pots[0]); double negSdev = 100.0 * pots[3] / Math.Abs(pots[2]); double capacitance = 1e12 / potentialDifference; // in picoFarads WriteLine("Final potentials: {0:0.00e00} ({1:0.0}%) {2:0.00e00} ({3:0.0}%)", pots[0], posSdev, pots[2], negSdev); WriteLine("Final potential difference: {0:0.00e00}", potentialDifference); WriteLine("Capacitance: {0:0.0} pF", capacitance); // If writing to a file, dump the final particle positions if (tw != null) { if (xN > 0) { double step = (x1 - x0) / xN; double charge = 1.0 / baal.posParticles.Length; tw.WriteLine("Scan along X-axis"); for (int i = 0; i <= xN; i++) { double x = x0 + i * step; // x in mm double phi = EField.GetPotential(new Vector(x * 0.001, 0.0, 0.0), baal.posParticles, baal.posParticles, charge); tw.WriteLine("{0,10:0.00} {1:0.000e00}", x, phi); } } int n = baal.posParticles.Length; tw.WriteLine("particles {0} {0}", n); foreach (Vector x in baal.posParticles) { tw.WriteLine("{0,10:0.0000}{1,10:0.0000}{2,10:0.0000}", x.x, x.y, x.z); } foreach (Vector x in baal.negParticles) { tw.WriteLine("{0,10:0.0000}{1,10:0.0000}{2,10:0.0000}", x.x, x.y, x.z); } } } catch (Exception e) { Console.WriteLine("Exception: {0}", e.Message); } if (tw != null) { tw.Close(); } }