Exemple #1
0
        public void Evaluate()
        {
            var phiS           = SurfacePotential;
            var storePotential = EvalPoints[0].Potential;

            // First remove all the points
            EvalPoints.Clear();

            // Find the thickness through integration
            // Integrate from 0 to the surface potential
            // Integrate 2000 times so change stepSize depending on the surface potential
            var stepSize = phiS / 20;

            stepSize = phiS > ElectricPotential.Zero ?
                       ElectricPotential.Abs(stepSize) : -ElectricPotential.Abs(stepSize);

            var previousValue     = 1 / GetElectricField(phiS).VoltsPerMeter;
            var runningThickness  = Length.Zero;
            var previousThickness = Length.Zero;

            var point = new EvalPoint
            {
                Location      = runningThickness,
                ChargeDensity = GetChargeY(phiS),
                ElectricField = new ElectricField(1 / previousValue),
                Potential     = phiS
            };

            EvalPoints.Add(point);

            for (var i = 1; ElectricPotential.Abs(phiS - stepSize * i)
                 > ElectricPotential.FromMillivolts(1) && i < 10000; i++)
            {
                var potentialValue = phiS - stepSize * i;
                var value          = 1 / GetElectricField(potentialValue).VoltsPerMeter;
                previousThickness = runningThickness;
                runningThickness += new Length(((previousValue + value) / 2) * stepSize.Volts);

                if (double.IsNaN(runningThickness.Meters))
                {
                    Debug.WriteLine("Por que Nan??");
                }

                point = new EvalPoint
                {
                    Location      = runningThickness,
                    ChargeDensity = GetChargeY(potentialValue) * 1E-8,
                    ElectricField = new ElectricField(1 / value),
                    Potential     = potentialValue
                };

                EvalPoints.Add(point);
                previousValue = value;
            }

            // Now add the offset in potential
            var checkCharge = ChargeDensity.Zero; // check and see if the charges add up

            foreach (var checkPoint in EvalPoints)
            {
                checkPoint.Potential = checkPoint.Potential + storePotential;
                checkPoint.Potential = checkPoint.Potential - phiS;
                checkCharge         += checkPoint.ChargeDensity;
            }
        }
        private void Evaluate(CancellationToken cancellationToken = default(CancellationToken))
        {
            // Don't do anything if the structure isn't valid
            if (!IsValid)
            {
                return;
            }

            int iterationNumber;

            // Since we integrate left to right, we want to specify the voltage on the left
            var voltageBias = -Bias + WorkFunctionDifference;

            // Iterate until we find the desired voltage
            var chargeHigh  = ChargeDensity.FromCoulombsPerSquareCentimeter(1.0);
            var chargeLow   = ChargeDensity.FromCoulombsPerSquareCentimeter(-1.0);
            var chargeGuess = (chargeHigh + chargeLow) / 2;

            // !!!!!!!!!!!!!!!!!!
            EvaluateGivenCharge(chargeGuess, cancellationToken);
            // !!!!!!!!!!!!!!!!!!

            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }

            var potentialCalc    = BottomLayer.EvalPoints[1].Potential;
            var tinyPositiveBias = new ElectricPotential(1e-6);
            var tinyNegativeBias = new ElectricPotential(-1e-6);

            // Iterate
            for (iterationNumber = 0;
                 (potentialCalc > voltageBias + ElectricPotential.Abs(voltageBias * 1e-6)
                  + tinyPositiveBias ||
                  potentialCalc < voltageBias - ElectricPotential.Abs(voltageBias * 1e-6)
                  + tinyNegativeBias) &&
                 iterationNumber < maximumIterations;
                 iterationNumber++)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                if (potentialCalc > voltageBias)
                {
                    chargeLow = chargeGuess;
                }
                else
                {
                    chargeHigh = chargeGuess;
                }

                // Update the guessCharge
                chargeGuess = (chargeHigh + chargeLow) / 2;

                // !!!!!!!!!!!!!!!!!!
                EvaluateGivenCharge(chargeGuess, cancellationToken);
                // !!!!!!!!!!!!!!!!!!

                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                potentialCalc = BottomLayer.EvalPoints[1].Potential;

                if (iterationNumber == maximumIterations - 1)
                {
                    if (!(potentialCalc > voltageBias + ElectricPotential.FromMillivolts(1) ||
                          potentialCalc < voltageBias - ElectricPotential.FromMillivolts(1)))
                    {
                        // TODO: Inform that solution only found to accuracy of 1e-3
                    }
                    else
                    {
                        NoSolution = true;
                        return;
                    }
                }
            }

            // If the last material is a semiconductor, fill in the missing points
            if (IsBottomLayerSemiconductor)
            {
                ((Semiconductor)BottomLayer).Evaluate();

                // Now subtract the potential from all the points so the right is ref to 0
                var lastPoint = BottomLayer.EvalPoints.Last();
                var potential = lastPoint.Potential;

                foreach (var layer in Layers)
                {
                    foreach (var ep in layer.EvalPoints)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            return;
                        }

                        ep.Potential = ep.Potential - potential;
                    }
                }

                var trueLast = lastPoint.DeepClone();
                if (trueLast.Location < Length.FromNanometers(50))
                {
                    trueLast.Location = Length.FromNanometers(50);
                }
                BottomLayer.EvalPoints.Add(trueLast);
            }

            NoSolution = false;

            /*
             * Debug.WriteLine(String.Format("Evaluation finished after {0} iterations in {1} ms",
             *  iterationNumber, stopwatch.ElapsedMilliseconds));
             */
        }