|
| 1 | +import pytest |
| 2 | +import numpy as np |
| 3 | +import pycba as cba |
| 4 | + |
| 5 | + |
| 6 | +def test_sum_compatible_envelopes(): |
| 7 | + """Test summing two compatible envelopes from load patterning and vehicle analysis""" |
| 8 | + L = [30, 30, 30] |
| 9 | + EI = 30 * 10e9 * 1e-6 |
| 10 | + R = [-1, 0, -1, 0, -1, 0, -1, 0] |
| 11 | + |
| 12 | + bridge = cba.BeamAnalysis(L, EI, R) |
| 13 | + |
| 14 | + # Dead + permanent loads (factored) |
| 15 | + LMd = [ |
| 16 | + [1, 1, 12.5 * 1.35 + 50 * 1.5, 0, 0], |
| 17 | + [2, 1, 12.5 * 1.35 + 50 * 1.5, 0, 0], |
| 18 | + [3, 1, 12.5 * 1.35 + 50 * 1.5, 0, 0], |
| 19 | + ] |
| 20 | + |
| 21 | + # Variable UDL loads |
| 22 | + LMq = [ |
| 23 | + [1, 1, 13.5, 0, 0], |
| 24 | + [2, 1, 13.5, 0, 0], |
| 25 | + [3, 1, 13.5, 0, 0], |
| 26 | + ] |
| 27 | + |
| 28 | + # Create load pattern envelope |
| 29 | + loadpattern = cba.LoadPattern(bridge) |
| 30 | + loadpattern.set_dead_loads(LMd, 1.0, 1.0) |
| 31 | + loadpattern.set_live_loads(LMq, 1.50, 0) |
| 32 | + env_udl = loadpattern.analyze() |
| 33 | + |
| 34 | + # Create vehicle envelope |
| 35 | + vehicle = cba.Vehicle([1.20], [600, 600]) |
| 36 | + bridge_analysis = cba.BridgeAnalysis(bridge, vehicle) |
| 37 | + env_veh = bridge_analysis.run_vehicle(0.5) |
| 38 | + |
| 39 | + # Sum the envelopes |
| 40 | + env_sum = cba.Envelopes.zero_like(env_udl) |
| 41 | + env_sum.sum(env_udl) |
| 42 | + env_sum.sum(env_veh) |
| 43 | + |
| 44 | + # Verify: the summed envelope equals the element-wise sum of the individual ones |
| 45 | + assert env_sum.Mmax == pytest.approx(env_udl.Mmax + env_veh.Mmax) |
| 46 | + assert env_sum.Mmin == pytest.approx(env_udl.Mmin + env_veh.Mmin) |
| 47 | + assert env_sum.Vmax == pytest.approx(env_udl.Vmax + env_veh.Vmax) |
| 48 | + assert env_sum.Vmin == pytest.approx(env_udl.Vmin + env_veh.Vmin) |
| 49 | + assert env_sum.Rmaxval == pytest.approx(env_udl.Rmaxval + env_veh.Rmaxval) |
| 50 | + assert env_sum.Rminval == pytest.approx(env_udl.Rminval + env_veh.Rminval) |
| 51 | + |
| 52 | + |
| 53 | +def test_sum_incompatible_envelopes(): |
| 54 | + """Test that summing envelopes from different beam geometries raises ValueError""" |
| 55 | + L1 = [30, 30, 30] |
| 56 | + EI1 = 30 * 10e9 * 1e-6 |
| 57 | + R1 = [-1, 0, -1, 0, -1, 0, -1, 0] |
| 58 | + bridge1 = cba.BeamAnalysis(L1, EI1, R1) |
| 59 | + |
| 60 | + L2 = [20, 20] |
| 61 | + EI2 = 30 * 10e9 * 1e-6 |
| 62 | + R2 = [-1, 0, -1, 0, -1, 0] |
| 63 | + bridge2 = cba.BeamAnalysis(L2, EI2, R2) |
| 64 | + |
| 65 | + LMd1 = [[1, 1, 12.5, 0, 0], [2, 1, 12.5, 0, 0], [3, 1, 12.5, 0, 0]] |
| 66 | + LMq1 = [[1, 1, 13.5, 0, 0], [2, 1, 13.5, 0, 0], [3, 1, 13.5, 0, 0]] |
| 67 | + |
| 68 | + LMd2 = [[1, 1, 12.5, 0, 0], [2, 1, 12.5, 0, 0]] |
| 69 | + LMq2 = [[1, 1, 13.5, 0, 0], [2, 1, 13.5, 0, 0]] |
| 70 | + |
| 71 | + lp1 = cba.LoadPattern(bridge1) |
| 72 | + lp1.set_dead_loads(LMd1, 1.35, 1.0) |
| 73 | + lp1.set_live_loads(LMq1, 1.50, 0) |
| 74 | + env1 = lp1.analyze() |
| 75 | + |
| 76 | + lp2 = cba.LoadPattern(bridge2) |
| 77 | + lp2.set_dead_loads(LMd2, 1.35, 1.0) |
| 78 | + lp2.set_live_loads(LMq2, 1.50, 0) |
| 79 | + env2 = lp2.analyze() |
| 80 | + |
| 81 | + env_sum = cba.Envelopes.zero_like(env1) |
| 82 | + with pytest.raises(ValueError, match="Cannot sum with an inconsistent envelope"): |
| 83 | + env_sum.sum(env2) |
0 commit comments