Skip to content

Commit 1b0ea53

Browse files
esaruohoclaude
andcommitted
Fix SCR convergence failure with series resistor (sharpie7#851)
Move the SCR on/off state evaluation from doStep() to startIteration() so it is evaluated once per timestep rather than on every Newton-Raphson sub-iteration. The previous code switched the anode resistance between 0.0105 ohms (on) and 100K ohms (off) inside doStep(), causing the resistance to flip-flop on every iteration when the SCR was near its trigger threshold with an external series resistor, preventing convergence. This matches the pattern used by TriacElm and DiacElm, which both evaluate their state in startIteration(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6b826de commit 1b0ea53

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

src/com/lushprojects/circuitjs1/client/SCRElm.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ void undumpXml(XMLDeserializer xml) {
9797
double ia, ic, ig, curcount_a, curcount_c, curcount_g;
9898
double lastvac, lastvag;
9999
double gresistance, triggerI, holdingI;
100+
boolean state;
100101

101102
final int hs = 8;
102103
Polygon poly;
@@ -217,6 +218,19 @@ void stamp() {
217218
diode.stamp(nodes[inode], nodes[cnode]);
218219
}
219220

221+
// Evaluate the on/off state once per timestep, not during Newton-Raphson
222+
// iterations. Previously the state switching was inside doStep(), causing
223+
// the anode resistance to flip-flop between on (0.0105) and off (10e5) on
224+
// every sub-iteration when an external series resistance was present,
225+
// preventing convergence (issue #851). This matches the pattern used by
226+
// TriacElm and DiacElm.
227+
void startIteration() {
228+
double icmult = 1/triggerI;
229+
double iamult = 1/holdingI - icmult;
230+
state = (-icmult*ic + ia*iamult > 1);
231+
aresistance = state ? .0105 : 10e5;
232+
}
233+
220234
void doStep() {
221235
double vac = volts[anode]-volts[cnode]; // typically negative
222236
double vag = volts[anode]-volts[gnode]; // typically positive
@@ -226,11 +240,6 @@ void doStep() {
226240
lastvac = vac;
227241
lastvag = vag;
228242
diode.doStep(volts[inode]-volts[cnode]);
229-
double icmult = 1/triggerI;
230-
double iamult = 1/holdingI - icmult;
231-
//System.out.println(icmult + " " + iamult);
232-
aresistance = (-icmult*ic + ia*iamult > 1) ? .0105 : 10e5;
233-
//System.out.println(vac + " " + vag + " " + sim.converged + " " + ic + " " + ia + " " + aresistance + " " + volts[inode] + " " + volts[gnode] + " " + volts[anode]);
234243
sim.stampResistor(nodes[anode], nodes[inode], aresistance);
235244
}
236245
void getInfo(String arr[]) {

0 commit comments

Comments
 (0)