예제 #1
0
        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 });
        }
예제 #2
0
        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;
                    }
                }
            }
        }
예제 #3
0
        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();
            }
        }