public void doStep() {
        double vd = volts[1] - volts[0];
        if (Math.abs(lastvd - vd) > .1) {
            sim.setConverged(false);
        } else if (volts[2] > maxOut + .1 || volts[2] < minOut - .1) {
            sim.setConverged(false);
        }
        double x = 0;
        int vn = sim.nodeListSize() + voltSource;
        double dx = 0;
        if (vd >= maxOut / gain && (lastvd >= 0 || sim.getrand(4) == 1)) {
            dx = 1e-4;
            x = maxOut - dx * maxOut / gain;
        } else if (vd <= minOut / gain && (lastvd <= 0 || sim.getrand(4) == 1)) {
            dx = 1e-4;
            x = minOut - dx * minOut / gain;
        } else {
            dx = gain;
        }
        //System.out.println("opamp " + vd + " " + volts[2] + " " + dx + " "  + x + " " + lastvd + " " + sim.converged);

        // newton-raphson
        sim.stampMatrix(vn, nodes[0], dx);
        sim.stampMatrix(vn, nodes[1], -dx);
        sim.stampMatrix(vn, nodes[2], 1);
        sim.stampRightSide(vn, x);

        lastvd = vd;
        /*if (sim.converged)
         System.out.println((volts[1]-volts[0]) + " " + volts[2] + " " + initvd);*/
    }