{"record":{"id":"07908bb8904ca3a5","repo":"TheAlgorithms/Java","slug":"time-step-must-be-positive-07908b","errorCode":null,"errorMessage":"Time step must be positive","messagePattern":"Time step must be positive","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/physics/SimplePendulumRK4.java","lineNumber":62,"sourceCode":"        double omega = state[1];\n        double dtheta = omega;\n        double domega = -(g / length) * Math.sin(theta);\n        return new double[] {dtheta, domega};\n    }\n\n    /**\n     * Performs one time step using the RK4 method.\n     *\n     * @param state the current state [theta, omega]\n     * @param dt the time step size\n     * @return the new state after time dt\n     */\n    public double[] stepRK4(double[] state, double dt) {\n        if (state == null || state.length != 2) {\n            throw new IllegalArgumentException(\"State must be array of length 2\");\n        }\n        if (dt <= 0) {\n            throw new IllegalArgumentException(\"Time step must be positive\");\n        }\n\n        double[] k1 = derivatives(state);\n        double[] s2 = new double[] {state[0] + 0.5 * dt * k1[0], state[1] + 0.5 * dt * k1[1]};\n\n        double[] k2 = derivatives(s2);\n        double[] s3 = new double[] {state[0] + 0.5 * dt * k2[0], state[1] + 0.5 * dt * k2[1]};\n\n        double[] k3 = derivatives(s3);\n        double[] s4 = new double[] {state[0] + dt * k3[0], state[1] + dt * k3[1]};\n\n        double[] k4 = derivatives(s4);\n\n        double thetaNext = state[0] + dt / 6.0 * (k1[0] + 2 * k2[0] + 2 * k3[0] + k4[0]);\n        double omegaNext = state[1] + dt / 6.0 * (k1[1] + 2 * k2[1] + 2 * k3[1] + k4[1]);\n\n        return new double[] {thetaNext, omegaNext};\n    }","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/physics/SimplePendulumRK4.java#L44-L80","documentation":"Thrown by SimplePendulumRK4.stepRK4 when dt <= 0. The RK4 integration advances state by dt; a non-positive step produces no forward progress (dt = 0 returns the same state) or reverses time (dt < 0), corrupting a forward-marching simulation. This is the second guard, checked after the state-array validation.","triggerScenarios":"Calling stepRK4(state, 0) or stepRK4(state, negativeValue). Typically arises when a time-marching loop computes a final step as tEnd - t that resolves to zero or negative in the last iteration.","commonSituations":"Adaptive or fixed-step loop overshooting the end time, a step counter running one iteration too far, or a config default of 0.","solutions":["Pass a strictly positive dt; for RK4 a moderately small step (e.g. 1e-3) is usually sufficient given RK4's accuracy.","In the marching loop, clamp the last step: double step = Math.min(dt, tEnd - t); break when step <= 0.","Validate dt where the integration schedule is configured."],"exampleFix":"// before\ndouble[] next = p.stepRK4(state, tEnd - t);\n// after\ndouble step = tEnd - t;\nif (step <= 0) break;\ndouble[] next = p.stepRK4(state, step);","handlingStrategy":"validation","validationCode":"double step = dt;\nif (step <= 0) {\n    throw new IllegalStateException(\"RK4 step resolved to non-positive dt\");\n}\ndouble[] next = p.stepRK4(state, step);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp the final loop step with Math.min(dt, tEnd - t) and break when <= 0.","Treat dt as a positive constant from validated config.","RK4 tolerates larger steps than Euler, but still validate positivity."],"tags":["java","physics","parameter-validation","numerical-integration","rk4","time-step","illegal-argument"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}