Esempio n. 1
0
        public ChargeDensity GetChargeY(ElectricPotential potential)
        {
            var vT = ThermalVoltage;

            if (DopingType == DopingType.P)
            {
                var cConc = ElectricCharge.Elementary *
                            (FreeHoleConcentration * Math.Exp(-potential / vT)
                             - FreeElectronConcentration * Math.Exp(potential / vT)
                             - DopantConcentration);

                // Apparently this is ok, but I don't know why - RT
                return(ChargeDensity.FromCoulombsPerSquareCentimeter(cConc.CoulombsPerCubicCentimeter));
            }
            else
            {
                var cConc = -ElectricCharge.Elementary *
                            (FreeElectronConcentration * Math.Exp(potential / vT)
                             - FreeHoleConcentration * Math.Exp(-potential / vT)
                             - DopantConcentration);

                // Apparently this is ok, but I don't know why - RT
                return(ChargeDensity.FromCoulombsPerSquareCentimeter(cConc.CoulombsPerCubicCentimeter));
            }
        }
Esempio n. 2
0
        private bool ShouldKeepTryingSurfacePotential(ChargeDensity charge,
                                                      ChargeDensity guessCharge, int iterationNumber)
        {
            var maxDelta = ChargeDensity.FromCoulombsPerSquareCentimeter(Math.Abs(charge.CoulombsPerSquareCentimeter * 1e-6));

            return(((charge - maxDelta > guessCharge) || (guessCharge > charge + maxDelta)) &&
                   iterationNumber < 1000);
        }
        public void TestCalculatesSurfacePotentialCorrectly()
        {
            var shellStructure = new Structure();

            shellStructure.Temperature = new Temperature(300);

            var semiconductor = CreateTestSemiconductor();

            shellStructure.AddLayer(semiconductor);

            var testCharge = ChargeDensity.FromCoulombsPerSquareCentimeter(-.25);

            var potential        = semiconductor.GetSurfacePotential(testCharge);
            var roundedPotential = Math.Round(potential.Volts, 3);

            Assert.AreEqual(.766, roundedPotential);
        }
Esempio n. 4
0
        public ChargeDensity GetDepletionCharge(ElectricPotential surfacePotential)
        {
            if (DopingType == DopingType.P)
            {
                if (surfacePotential <= ElectricPotential.Zero)
                {
                    return(ChargeDensity.Zero);
                }

                var realSurfacePotential = surfacePotential - ThermalVoltage;
                var value = -SemiconductorConstant *Math.Sqrt(realSurfacePotential.Volts);

                return(ChargeDensity.FromCoulombsPerSquareCentimeter(value));
            }
            else
            {
                // TODO: Implement for N type!
                throw new NotImplementedException();
            }
        }
Esempio n. 5
0
        public ChargeDensity GetChargeDensity(ElectricPotential surfacePotential)
        {
            var vT = ThermalVoltage;
            ElectricPotential innerTerm;

            if (DopingType == DopingType.P)
            {
                innerTerm = vT * Math.Exp(-surfacePotential / vT)
                            + surfacePotential - vT + Math.Exp(-2 * PhiF / vT)
                            * (vT * Math.Exp(surfacePotential / vT) - surfacePotential - vT);
            }
            else
            {
                innerTerm = vT * Math.Exp(surfacePotential / vT)
                            - surfacePotential - vT + Math.Exp(2 * PhiF / vT)
                            * (vT * Math.Exp(-surfacePotential / vT) - surfacePotential - vT);
            }

            var charge = ChargeDensity.FromCoulombsPerSquareCentimeter(SemiconductorConstant * Math.Sqrt(innerTerm.Volts));

            return(surfacePotential >= ElectricPotential.Zero ? -charge : charge);
        }
Esempio n. 6
0
        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));
             */
        }