/* Copyright (C) Paul Falstad 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 CCVSElm extends VCCSElm { public CCVSElm(int xa, int ya, int xb, int yb, int f, StringTokenizer st) { super(xa, ya, xb, yb, f, st); // exprString = CustomLogicModel.unescape(st.nextToken()); inputCount = 2; // parseExpr(); setupPins(); } public CCVSElm(int xx, int yy) { super(xx, yy); exprString = "2*i"; parseExpr(); // setupPins(); } void setupPins() { sizeX = 2; sizeY = 2; pins = new Pin[3]; pins[0] = new Pin(0, SIDE_W, "C+"); pins[1] = new Pin(1, SIDE_W, "C-"); pins[1].output = true; pins[2] = new Pin(0, SIDE_E, "V+"); pins[2].output = true; pins[3] = new Pin(1, SIDE_E, "V-"); exprState = new ExprState(1); } String getChipName() { return "CCVS"; } void stamp() { // voltage source (0V) between C+ and C- so we can measure current int vn1 = pins[1].voltSource; sim.stampVoltageSource(nodes[0], nodes[1], vn1, 0); // voltage source for outputs int vn2 = pins[2].voltSource; sim.stampNonLinear(vn2 + sim.nodeList.size()); sim.stampVoltageSource(nodes[3], nodes[2], vn2); } double lastCurrent; void doStep() { // converged yet? // double limitStep = getLimitStep()*.1; double convergeLimit = getConvergeLimit()*.1; double cur = pins[1].current; if (Math.abs(cur-lastCurrent) > convergeLimit) { sim.converged = false; // if (Math.abs(cur-lastCurrent) > limitStep) // volts[i] = lastVolts[i] + sign(volts[i]-lastVolts[i], limitStep); } int vn1 = pins[1].voltSource + sim.nodeList.size(); int vn2 = pins[2].voltSource + sim.nodeList.size(); if (expr != null) { // calculate output exprState.values[8] = cur; // I = current exprState.t = sim.t; double v0 = expr.eval(exprState); double rs = v0; double dv = 1e-6; exprState.values[8] = cur+dv; double v = expr.eval(exprState); exprState.values[8] = cur-dv; double v2 = expr.eval(exprState); double dx = (v-v2)/(dv*2); if (Math.abs(dx) < 1e-6) dx = sign(dx, 1e-6); sim.stampMatrix(vn2, vn1, -dx); // adjust right side rs -= dx*cur; // sim.console("ccedx " + cur + " " + dx + " " + rs); sim.stampRightSide(vn2, rs); } lastCurrent = cur; } int getPostCount() { return 4; } int getVoltageSourceCount() { return 2; } int getDumpType() { return 214; } boolean getConnection(int n1, int n2) { if (comparePair(0, 1, n1, n2)) return true; if (comparePair(2, 3, n1, n2)) return true; return false; } boolean hasCurrentOutput() { return false; } void setCurrent(int vn, double c) { if (pins[1].voltSource == vn) { pins[0].current = -c; pins[1].current = c; } if (pins[2].voltSource == vn) { pins[2].current = c; pins[3].current = -c; } } }