/* 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; class CapacitorElm extends CircuitElm { double capacitance; double compResistance, voltdiff; Point plate1[], plate2[]; public static final int FLAG_BACK_EULER = 2; public CapacitorElm(int xx, int yy) { super(xx, yy); capacitance = 1e-5; } public CapacitorElm(int xa, int ya, int xb, int yb, int f, StringTokenizer st) { super(xa, ya, xb, yb, f); capacitance = new Double(st.nextToken()).doubleValue(); voltdiff = new Double(st.nextToken()).doubleValue(); } boolean isTrapezoidal() { return (flags & FLAG_BACK_EULER) == 0; } void setNodeVoltage(int n, double c) { super.setNodeVoltage(n, c); voltdiff = volts[0]-volts[1]; } void reset() { super.reset(); current = curcount = curSourceValue = 0; // put small charge on caps when reset to start oscillators voltdiff = 1e-3; } int getDumpType() { return 'c'; } String dump() { return super.dump() + " " + capacitance + " " + voltdiff; } Point platePoints[]; void setPoints() { super.setPoints(); double f = (dn/2-4)/dn; // calc leads lead1 = interpPoint(point1, point2, f); lead2 = interpPoint(point1, point2, 1-f); // calc plates plate1 = newPointArray(2); plate2 = newPointArray(2); interpPoint2(point1, point2, plate1[0], plate1[1], f, 12); interpPoint2(point1, point2, plate2[0], plate2[1], 1-f, 12); } void draw(Graphics g) { int hs = 12; setBbox(point1, point2, hs); // draw first lead and plate setVoltageColor(g, volts[0]); drawThickLine(g, point1, lead1); setPowerColor(g, false); drawThickLine(g, plate1[0], plate1[1]); if (sim.powerCheckItem.getState()) g.setColor(Color.gray); // draw second lead and plate setVoltageColor(g, volts[1]); drawThickLine(g, point2, lead2); setPowerColor(g, false); if (platePoints == null) drawThickLine(g, plate2[0], plate2[1]); else { int i; for (i = 0; i != 7; i++) drawThickLine(g, platePoints[i], platePoints[i+1]); } updateDotCount(); if (sim.dragElm != this) { drawDots(g, point1, lead1, curcount); drawDots(g, point2, lead2, -curcount); } drawPosts(g); if (sim.showValuesCheckItem.getState()) { String s = getShortUnitText(capacitance, "F"); drawValues(g, s, hs); } } void stamp() { // capacitor companion model using trapezoidal approximation // (Norton equivalent) consists of a current source in // parallel with a resistor. Trapezoidal is more accurate // than backward euler but can cause oscillatory behavior // if RC is small relative to the timestep. if (isTrapezoidal()) compResistance = sim.timeStep/(2*capacitance); else compResistance = sim.timeStep/capacitance; sim.stampResistor(nodes[0], nodes[1], compResistance); sim.stampRightSide(nodes[0]); sim.stampRightSide(nodes[1]); } void startIteration() { if (isTrapezoidal()) curSourceValue = -voltdiff/compResistance-current; else curSourceValue = -voltdiff/compResistance; } void calculateCurrent() { double voltdiff = volts[0] - volts[1]; // we check compResistance because this might get called // before stamp(), which sets compResistance, causing // infinite current if (compResistance > 0) current = voltdiff/compResistance + curSourceValue; } double curSourceValue; void doStep() { sim.stampCurrentSource(nodes[0], nodes[1], curSourceValue); } void getInfo(String arr[]) { arr[0] = "capacitor"; getBasicInfo(arr); arr[3] = "C = " + getUnitText(capacitance, "F"); arr[4] = "P = " + getUnitText(getPower(), "W"); //double v = getVoltageDiff(); //arr[4] = "U = " + getUnitText(.5*capacitance*v*v, "J"); } @Override String getScopeText(int v) { return sim.LS("capacitor") + ", " + getUnitText(capacitance, "F"); } public EditInfo getEditInfo(int n) { if (n == 0) return new EditInfo("Capacitance (F)", capacitance, 0, 0); if (n == 1) { EditInfo ei = new EditInfo("", 0, -1, -1); ei.checkbox = new Checkbox("Trapezoidal Approximation", isTrapezoidal()); return ei; } return null; } public void setEditValue(int n, EditInfo ei) { if (n == 0 && ei.value > 0) capacitance = ei.value; if (n == 1) { if (ei.checkbox.getState()) flags &= ~FLAG_BACK_EULER; else flags |= FLAG_BACK_EULER; } } int getShortcut() { return 'c'; } }