/*
Copyright (C) Paul Falstad and Iain Sharp
This file is part of CircuitJS1.
CircuitJS1 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
CircuitJS1 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CircuitJS1. If not, see <http://www.gnu.org/licenses/>.
*/
package com.lushprojects.circuitjs1.client;
//import java.awt.*;
//import java.util.StringTokenizer;
class TunnelDiodeElm extends CircuitElm {
public TunnelDiodeElm(int xx, int yy) {
super(xx, yy);
setup();
}
public TunnelDiodeElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
setup();
}
boolean nonLinear() { return true; }
void setup() {
}
int getDumpType() { return 175; }
final int hs = 8;
Polygon poly;
Point cathode[];
void setPoints() {
super.setPoints();
calcLeads(16);
cathode = newPointArray(4);
Point pa[] = newPointArray(2);
interpPoint2(lead1, lead2, pa[0], pa[1], 0, hs);
interpPoint2(lead1, lead2, cathode[0], cathode[1], 1, hs);
interpPoint2(lead1, lead2, cathode[2], cathode[3], .8, hs);
poly = createPolygon(pa[0], pa[1], lead2);
}
void draw(Graphics g) {
setBbox(point1, point2, hs);
double v1 = volts[0];
double v2 = volts[1];
draw2Leads(g);
// draw arrow thingy
setPowerColor(g, true);
setVoltageColor(g, v1);
g.fillPolygon(poly);
// draw thing arrow is pointing to
setVoltageColor(g, v2);
drawThickLine(g, cathode[0], cathode[1]);
drawThickLine(g, cathode[2], cathode[0]);
drawThickLine(g, cathode[3], cathode[1]);
doDots(g);
drawPosts(g);
}
void reset() {
lastvoltdiff = volts[0] = volts[1] = curcount = 0;
}
double lastvoltdiff;
double limitStep(double vnew, double vold) {
// Prevent voltage changes of more than 1V when iterating. Wow, I thought it would be
// much harder than this to prevent convergence problems.
if (vnew > vold+1)
return vold+1;
if (vnew < vold-1)
return vold-1;
return vnew;
}
void stamp() {
sim.stampNonLinear(nodes[0]);
sim.stampNonLinear(nodes[1]);
}
static final double pvp = .1;
static final double pip = 4.7e-3;
static final double pvv = .37;
static final double pvt = .026;
static final double pvpp = .525;
static final double piv = 370e-6;
void doStep() {
double voltdiff = volts[0] - volts[1];
if (Math.abs(voltdiff-lastvoltdiff) > .01)
sim.converged = false;
//System.out.println(voltdiff + " " + lastvoltdiff + " " + Math.abs(voltdiff-lastvoltdiff));
voltdiff = limitStep(voltdiff, lastvoltdiff);
lastvoltdiff = voltdiff;
double i = pip*Math.exp(-pvpp/pvt)*(Math.exp(voltdiff/pvt)-1) +
pip*(voltdiff/pvp)*Math.exp(1-voltdiff/pvp) +
piv*Math.exp(voltdiff-pvv);
double geq = pip*Math.exp(-pvpp/pvt)*Math.exp(voltdiff/pvt)/pvt +
pip*Math.exp(1-voltdiff/pvp)/pvp
- Math.exp(1-voltdiff/pvp)*pip*voltdiff/(pvp*pvp) +
Math.exp(voltdiff-pvv)*piv;
double nc = i - geq*voltdiff;
sim.stampConductance(nodes[0], nodes[1], geq);
sim.stampCurrentSource(nodes[0], nodes[1], nc);
}
void calculateCurrent() {
double voltdiff = volts[0] - volts[1];
current = pip*Math.exp(-pvpp/pvt)*(Math.exp(voltdiff/pvt)-1) +
pip*(voltdiff/pvp)*Math.exp(1-voltdiff/pvp) +
piv*Math.exp(voltdiff-pvv);
}
void getInfo(String arr[]) {
arr[0] = "tunnel diode";
arr[1] = "I = " + getCurrentText(getCurrent());
arr[2] = "Vd = " + getVoltageText(getVoltageDiff());
arr[3] = "P = " + getUnitText(getPower(), "W");
}
}