44 * Comprehensive test suite for SimplePendulumRK4.
55 * Tests numerical accuracy, physical correctness, and edge cases.
66 */
7- public class SimplePendulumRK4Test {
7+ public final class SimplePendulumRK4Test {
88
99 private static final double EPSILON = 1e-6 ;
1010
11+ // Private constructor to prevent instantiation
12+ private SimplePendulumRK4Test () {
13+ throw new UnsupportedOperationException ("Utility class" );
14+ }
15+
1116 // ANSI color codes for terminal output
1217 private static final String GREEN = "\u001B [32m" ;
1318 private static final String RED = "\u001B [31m" ;
@@ -33,7 +38,7 @@ public static void main(String[] args) {
3338 runTest ("Energy Conservation (Small Angle)" , SimplePendulumRK4Test ::testEnergySmallAngle );
3439 runTest ("Energy Conservation (Large Angle)" , SimplePendulumRK4Test ::testEnergyLargeAngle );
3540
36- // Method tests
41+ // Method tests`
3742 runTest ("Simulate Method" , SimplePendulumRK4Test ::testSimulate );
3843 runTest ("Energy Calculation" , SimplePendulumRK4Test ::testEnergyCalculation );
3944
@@ -177,48 +182,6 @@ private static void testEnergyConservation(SimplePendulumRK4 p, double[] initial
177182 assertTrue (drift < maxDrift , String .format ("Energy drift %.6f exceeds limit %.6f" , drift , maxDrift ));
178183 }
179184
180- private static void testPeriodAccuracy (double angleDegrees ) {
181- SimplePendulumRK4 p = new SimplePendulumRK4 (1.0 , 9.81 );
182- double [] state = {Math .toRadians (angleDegrees ), 0.0 };
183- double dt = 0.001 ;
184-
185- // Measure period by detecting zero crossings with positive velocity
186- double prevTheta = state [0 ];
187- int zeroCrossings = 0 ;
188- int periodSteps = 0 ;
189-
190- for (int i = 0 ; i < 10000 ; i ++) {
191- state = p .stepRK4 (state , dt );
192-
193- // Detect zero crossing with positive velocity (moving right)
194- if (prevTheta < 0 && state [0 ] >= 0 && state [1 ] > 0 ) {
195- zeroCrossings ++;
196- if (zeroCrossings == 2 ) {
197- // Two zero crossings = one complete period
198- periodSteps = i + 1 ;
199- break ;
200- }
201- }
202-
203- prevTheta = state [0 ];
204- }
205-
206- assertTrue (periodSteps > 0 , "Could not measure period" );
207-
208- double measuredPeriod = periodSteps * dt ;
209- double theoreticalPeriod = 2 * Math .PI * Math .sqrt (1.0 / 9.81 );
210-
211- // For small angles, should match theoretical period closely
212- if (angleDegrees < 10 ) {
213- double error = Math .abs (measuredPeriod - theoreticalPeriod ) / theoreticalPeriod ;
214- assertTrue (error < 0.02 , "Period error: " + error );
215- } else {
216- // For larger angles, just verify we got a reasonable period
217- assertTrue (measuredPeriod > theoreticalPeriod * 0.8 , "Period too short" );
218- assertTrue (measuredPeriod < theoreticalPeriod * 1.5 , "Period too long" );
219- }
220- }
221-
222185 private static void testSimulate () {
223186 SimplePendulumRK4 p = new SimplePendulumRK4 (1.0 , 9.81 );
224187 double [] initialState = {Math .toRadians (20.0 ), 0.0 };
@@ -246,18 +209,18 @@ private static void testEnergyCalculation() {
246209
247210 // At equilibrium with no velocity: E = 0
248211 double [] state1 = {0.0 , 0.0 };
249- double E1 = p .calculateEnergy (state1 );
250- assertEquals (0.0 , E1 , EPSILON , "Energy at equilibrium" );
212+ double energy1 = p .calculateEnergy (state1 );
213+ assertEquals (0.0 , energy1 , EPSILON , "Energy at equilibrium" );
251214
252215 // At rest at max angle: E = potential only
253216 double [] state2 = {Math .PI / 2 , 0.0 };
254- double E2 = p .calculateEnergy (state2 );
255- assertTrue (E2 > 0 , "Energy should be positive at max angle" );
217+ double energy2 = p .calculateEnergy (state2 );
218+ assertTrue (energy2 > 0 , "Energy should be positive at max angle" );
256219
257220 // Energy with angular velocity
258221 double [] state3 = {0.0 , 1.0 };
259- double E3 = p .calculateEnergy (state3 );
260- assertTrue (E3 > 0 , "Energy should be positive with velocity" );
222+ double energy3 = p .calculateEnergy (state3 );
223+ assertTrue (energy3 > 0 , "Energy should be positive with velocity" );
261224 }
262225
263226 private static void testInvalidConstructor () {
0 commit comments