{"record":{"id":"a666d43b9ef8b987","repo":"TheAlgorithms/Java","slug":"time-step-must-be-positive","errorCode":null,"errorMessage":"Time step must be positive.","messagePattern":"Time step must be positive\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/physics/DampedOscillator.java","lineNumber":87,"sourceCode":"        double omegaD = Math.sqrt(Math.max(0.0, omega0 * omega0 - gamma * gamma));\n        return amplitude * Math.exp(-gamma * time) * Math.cos(omegaD * time + phase);\n    }\n\n    /**\n     * Performs a single integration step using the explicit Euler method.\n     * State vector format: [x, v], where v = dx/dt.\n     *\n     * @param state the current state [x, v]\n     * @param dt    the time step (seconds)\n     * @return the next state [x_next, v_next]\n     * @throws IllegalArgumentException if the state array is invalid or dt is non-positive\n     */\n    public double[] stepEuler(double[] state, double dt) {\n        if (state == null || state.length != 2) {\n            throw new IllegalArgumentException(\"State must be a non-null array of length 2.\");\n        }\n        if (dt <= 0) {\n            throw new IllegalArgumentException(\"Time step must be positive.\");\n        }\n\n        double x = state[0];\n        double v = state[1];\n        double acceleration = -2.0 * gamma * v - omega0 * omega0 * x;\n\n        double xNext = x + dt * v;\n        double vNext = v + dt * acceleration;\n\n        return new double[] {xNext, vNext};\n    }\n\n    /** @return the natural (undamped) angular frequency (rad/s). */\n    public double getOmega0() {\n        return omega0;\n    }\n\n    /** @return the damping coefficient (s⁻¹). */","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/physics/DampedOscillator.java#L69-L105","documentation":"Thrown by DampedOscillator.stepEuler when dt <= 0. The Euler integration step advances the state by dt; a non-positive time step produces no forward progress (dt = 0 yields the identical state) or reverses integration (dt < 0), both of which corrupt a time-marching simulation. This is the second guard, checked after the state-array validation.","triggerScenarios":"Calling stepEuler(state, 0) or stepEuler(state, negativeValue). Commonly happens when dt is computed as an end-minus-start difference that resolves to zero, or when a step counter runs past the loop bound producing a negative remainder.","commonSituations":"Adaptive step code that undershoots to dt = 0 at the final step, a loop where (tEnd - t) becomes negative in the last iteration, or a config default of 0.","solutions":["Pass a strictly positive dt (e.g. 1e-3 or 1e-4 for stiff systems).","In a time-marching loop, clamp the final step: double step = Math.min(dt, tEnd - t); only call stepEuler when step > 0.","Validate dt at the boundary where the integration schedule is configured."],"exampleFix":"// before\ndouble[] next = osc.stepEuler(state, tEnd - t);\n// after\ndouble step = tEnd - t;\nif (step <= 0) break;\ndouble[] next = osc.stepEuler(state, step);","handlingStrategy":"validation","validationCode":"double step = dt;\nif (step <= 0) {\n    throw new IllegalStateException(\"integration step resolved to non-positive dt\");\n}\ndouble[] next = osc.stepEuler(state, step);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp the final loop step: Math.min(dt, tEnd - t) and skip when <= 0.","Treat dt as a positive constant from validated config.","Add an assertion at the loop entry that the remaining interval is positive."],"tags":["java","physics","parameter-validation","numerical-integration","time-step","illegal-argument"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}