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)); */ }