/*
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 Inductor {
public static final int FLAG_BACK_EULER = 2;
int nodes[];
int flags;
CirSim sim;
double inductance;
double compResistance, current;
double curSourceValue;
Inductor(CirSim s) {
sim = s;
nodes = new int[2];
}
void setup(double ic, double cr, int f) {
inductance = ic;
current = cr;
flags = f;
}
boolean isTrapezoidal() { return (flags & FLAG_BACK_EULER) == 0; }
void reset() {
// need to set curSourceValue here in case one of inductor nodes is node 0. In that case
// calculateCurrent() may get called (from setNodeVoltage()) when analyzing circuit, before
// startIteration() gets called
current = curSourceValue = 0;
}
void stamp(int n0, int n1) {
// inductor companion model using trapezoidal or backward euler
// approximations (Norton equivalent) consists of a current
// source in parallel with a resistor. Trapezoidal is more
// accurate than backward euler but can cause oscillatory behavior.
// The oscillation is a real problem in circuits with switches.
nodes[0] = n0;
nodes[1] = n1;
if (isTrapezoidal())
compResistance = 2*inductance/sim.timeStep;
else // backward euler
compResistance = inductance/sim.timeStep;
sim.stampResistor(nodes[0], nodes[1], compResistance);
sim.stampRightSide(nodes[0]);
sim.stampRightSide(nodes[1]);
}
boolean nonLinear() { return false; }
void startIteration(double voltdiff) {
if (isTrapezoidal())
curSourceValue = voltdiff/compResistance+current;
else // backward euler
curSourceValue = current;
}
double calculateCurrent(double voltdiff) {
// we check compResistance because this might get called
// before stamp(), which sets compResistance, causing
// infinite current
if (compResistance > 0)
current = voltdiff/compResistance + curSourceValue;
return current;
}
void doStep(double voltdiff) {
sim.stampCurrentSource(nodes[0], nodes[1], curSourceValue);
}
}