-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Randall Spears
committed
May 1, 2018
0 parents
commit ca21023
Showing
8 changed files
with
308 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
*.pyc | ||
/dist/ | ||
/*.egg-info |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
include e80analysis/e80data.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# e80analysis |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
from matplotlib import pyplot as plt | ||
import itertools, json, os | ||
|
||
OS = os.name | ||
USER_HOME = os.environ.get('Homepath' if OS == 'nt' else 'HOME') | ||
USER_DOC_PATH = USER_HOME + '\\Documents\\' if OS == 'nt' else USER_HOME + '/Documents/' | ||
|
||
def sumlist(x): | ||
""" | ||
sumlist(x) | ||
Returns the running sum of a list of numbers, x. For example: | ||
sumlist([1,2,3]) would return [1,3,6]. | ||
""" | ||
try: | ||
return list(itertools.accumulate(x)) | ||
except TypeError: | ||
raise TypeError("unsupported argument type for 'sumlist'") | ||
|
||
class AnalysisError(Exception): | ||
pass | ||
|
||
class E80Analysis: | ||
def __init__(self): | ||
with open(os.path.join(os.path.dirname(__file__),'e80data.json'), 'r') as f: | ||
self.e80data = json.load(f) | ||
self.spans = range(10,201) | ||
|
||
def set_spans(self, span_lengths): | ||
self.spans = span_lengths | ||
|
||
def _run_train_single_span(self, span_length, axles): | ||
incr = 1 | ||
|
||
axle_loads = axles[0] | ||
axle_spaces = axles[1] | ||
axle_locs = sumlist(axle_spaces) | ||
|
||
train_tot = sum(axle_spaces) | ||
|
||
positions = [] | ||
point = -span_length | ||
while point <= train_tot: | ||
positions.append(point) | ||
point += incr | ||
m_array = [] | ||
v_array = [] | ||
for i in range(len(positions)): | ||
x_locs_total = [-x + positions[i] + span_length for x in axle_locs] | ||
x_locs = [x for x in x_locs_total if (x <= span_length and x >= 0)] | ||
axles_ = [axle for axle in axle_locs if axle <= span_length + positions[i] and axle >= positions[i]] | ||
axle_loads_ = [axle_loads[k] for k, axle in enumerate(axle_locs) if axle in axles_] | ||
num_axles_ = len(axles_) | ||
# a and b arrays store a and b values or each axle | ||
# r1 and r2 arrays store reactions at ends 1 and 2 for each axle | ||
# m and v arrays store m and v caused by each axle | ||
r1 = [] | ||
r2 = [] | ||
m = [] | ||
v = [] | ||
|
||
# This loop calculates individual values for each of the above | ||
# arrays and appends each value to the array. | ||
for j in range(num_axles_): | ||
a_val = span_length + positions[i] - axles_[j] | ||
|
||
b_val = span_length - a_val | ||
|
||
if 0 < b_val < span_length: | ||
r1_val = axle_loads_[j]*b_val/span_length | ||
else: | ||
r1_val = 0 | ||
r1.append(r1_val) | ||
|
||
if 0 < a_val < span_length: | ||
r2_val = axle_loads_[j]*a_val/span_length | ||
else: | ||
r2_val = 0 | ||
r2.append(r2_val) | ||
|
||
m_loc = [] | ||
v_loc = [] | ||
for x_loc in x_locs: | ||
if 0 < b_val < span_length and a_val > x_loc: | ||
m_val = axle_loads_[j]*(a_val - x_loc) | ||
else: | ||
m_val = 0 | ||
m_loc.append(m_val) | ||
|
||
if 0 < b_val < span_length and a_val < x_loc: | ||
v_val = axle_loads_[j] | ||
else: | ||
v_val = 0 | ||
v_loc.append(v_val) | ||
m.append(m_loc if m_loc != [] else [0]) | ||
v.append(v_loc if v_loc != [] else [0]) | ||
# Calculate the moment and shear at the respective x location | ||
# caused by the train at position i and push these values to the | ||
# global moment and shear arrays | ||
moments = list(zip(*m)) | ||
if x_locs != []: | ||
m_tot = max([sum(r2)*(span_length-x_locs[i]) - sum(moments[i]) for i in range(len(x_locs))]) | ||
else: | ||
m_tot = 0 | ||
v_tot = max(sum(r1), sum(r2)) | ||
m_array.append(m_tot) | ||
v_array.append(v_tot) | ||
return max(m_array), max(v_array) | ||
|
||
def _get_single_E80_env(self, span): | ||
if str(span) in self.e80data.keys(): | ||
return self.e80data[str(span)] | ||
else: | ||
axles_E80 = ([40,80,80,80,80,52,52,52,52]*2 + [8]*span, [0,8,5,5,5,9,5,6,5,8,8,5,5,5,9,5,6,5,5.5]+[1]*(span-1)) | ||
axles_E80_alt = ([100,100,100,100], [0,5,6,5]) | ||
e80_vals = self._run_train_single_span(span, axles_E80) | ||
e80_alt_vals = self._run_train_single_span(span, axles_E80_alt) | ||
return (max([e80_vals[0], e80_alt_vals[0]]), max([e80_vals[1], e80_alt_vals[1]])) | ||
|
||
def _calc_e80(self, design, e80): | ||
return (design[0]/e80[0] * 80, design[1]/e80[1] * 80) | ||
|
||
def span(self, axles, span): | ||
return self._calc_e80(self._run_train_single_span(span, axles), self._get_single_E80_env(span)) | ||
|
||
def plot(self, axles, save=False): | ||
|
||
span_data = [self.span(axles, span) for span in self.spans] | ||
plt.plot(self.spans, [x[0] for x in span_data], label='Moment') | ||
plt.plot(self.spans, [x[1] for x in span_data], label='Shear') | ||
plt.legend() | ||
plt.minorticks_on() | ||
plt.grid() | ||
plt.title("Equivalent E-Loadings") | ||
plt.xlabel('Span Length, ft') | ||
plt.ylabel('E-Rating') | ||
if save: | ||
plt.savefig(USER_DOC_PATH+'E-Loading.png') | ||
else: | ||
plt.show() | ||
plt.clf() | ||
plt.cla() | ||
plt.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"1": [25.0, 75.0], "2": [50.0, 87.5], "3": [75.0, 91.66666666666667], "4": [100.0, 93.75], "5": [125.0, 95.0], "6": [150.0, 108.33333333333333], "7": [175.0, 121.42857142857143], "8": [200.0, 131.25], "9": [234.72222222222229, 138.88888888888889], "10": [281.25, 145.0], "11": [328.40909090909093, 150.0], "12": [376.04166666666674, 160.41666666666669], "13": [425.4807692307693, 171.15384615384616], "14": [500.44642857142844, 180.35714285714286], "15": [575.4166666666665, 188.33333333333331], "16": [650.390625, 195.3125], "17": [725.3676470588239, 205.88235294117646], "18": [800.3472222222222, 216.66666666666669], "19": [875.328947368421, 226.31578947368422], "20": [950.3125, 235.0], "21": [1042.8571428571431, 242.85714285714286], "22": [1140.909090909091, 250.0], "23": [1239.1304347826087, 256.5217391304348], "24": [1337.4999999999998, 262.5], "25": [1436.0, 268.0], "26": [1534.6153846153843, 273.0769230769231], "27": [1633.3333333333335, 277.77777777777777], "28": [1732.1428571428573, 282.14285714285717], "29": [1831.034482758621, 286.2068965517242], "30": [1930.0000000000005, 290.0], "31": [2029.032258064516, 293.5483870967742], "32": [2128.125, 296.875], "33": [2227.2727272727275, 300.0], "34": [2326.4705882352946, 302.94117647058823], "35": [2425.714285714286, 305.7142857142857], "36": [2525.0, 308.33333333333337], "37": [2624.324324324324, 310.81081081081084], "38": [2723.684210526316, 313.15789473684214], "39": [2823.076923076924, 315.3846153846154], "40": [2922.5, 317.5], "41": [3021.951219512195, 319.5121951219512], "42": [3121.4285714285716, 321.42857142857144], "43": [3220.9302325581393, 323.25581395348837], "44": [3320.454545454545, 325.0], "45": [3420.0, 326.6666666666667], "46": [3519.565217391305, 328.30434782608694], "47": [3619.1489361702133, 332.7659574468086], "48": [3718.750000000001, 337.2083333333333], "49": [3818.367346938776, 341.6326530612244], "50": [3918.0, 346.0399999999999], "51": [4017.6470588235297, 350.4313725490196], "52": [4117.307692307692, 354.8076923076923], "53": [4216.981132075472, 359.1698113207547], "54": [4324.00925925926, 363.5185185185184], "55": [4466.009090909092, 367.8545454545456], "56": [4608.008928571428, 372.17857142857144], "57": [4750.008771929826, 376.4912280701755], "58": [4892.008620689655, 380.7931034482758], "59": [5040.682203389828, 385.084745762712], "60": [5195.354166666666, 389.3666666666667], "61": [5350.036885245903, 393.6393442622951], "62": [5504.729838709678, 397.90322580645164], "63": [5659.432539682541, 402.31746031746025], "64": [5822.0, 407.40625], "65": [5990.000000000002, 412.3384615384617], "66": [6157.999999999998, 417.1212121212121], "67": [6326.0, 422.65671641791045], "68": [6494.000000000002, 428.3235294117647], "69": [6661.999999999998, 433.82608695652175], "70": [6830.000000000004, 439.1714285714286], "71": [6998.725352112675, 444.3661971830986], "72": [7168.715277777779, 450.2500000000001], "73": [7340.219178082189, 456.24657534246575], "74": [7519.027027027025, 462.08108108108104], "75": [7702.009999999998, 467.76], "76": [7886.917763157897, 473.2894736842105], "77": [8072.847402597401, 478.67532467532465], "78": [8259.798076923076, 483.92307692307696], "79": [8448.708860759496, 489.03797468354423], "80": [8638.440625, 494.025], "81": [8830.000000000004, 499.37037037037044], "82": [9026.000000000002, 504.7439024390244], "83": [9222.969879518072, 509.9879518072289], "84": [9425.291666666664, 515.1071428571429], "85": [9631.088235294119, 520.1058823529412], "86": [9837.953488372092, 525.4418604651162], "87": [10045.81609195402, 530.8045977011495], "88": [10255.727272727272, 536.0454545454546], "89": [10466.516853932582, 541.1685393258426], "90": [10678.466666666664, 546.1777777777777], "91": [10892.131868131866, 551.0769230769231], "92": [11106.641304347828, 556.2934782608697], "93": [11322.634408602149, 561.5376344086022], "94": [11540.000000000015, 566.6702127659574], "95": [11758.21052631579, 571.6947368421052], "96": [11978.208333333332, 576.6145833333333], "97": [12199.257731958758, 581.8350515463917], "98": [12421.244897959183, 587.0816326530614], "99": [12645.888888888876, 592.2222222222221], "100": [12893.129999999997, 597.2599999999999], "101": [13141.861386138604, 602.1980198019803], "102": [13391.470588235294, 607.0588235294116], "103": [13642.951456310679, 611.9029126213592], "104": [13895.538461538465, 616.7307692307692], "105": [14149.12380952383, 621.5428571428572], "106": [14417.292452830188, 626.3396226415094], "107": [14696.523364485984, 631.1214953271028], "108": [14976.648148148146, 635.8888888888887], "109": [15258.825688073397, 640.6422018348624], "110": [15542.113636363632, 645.3818181818184], "111": [15826.509009009002, 650.108108108108], "112": [16113.000000000007, 654.8214285714287], "113": [16400.367256637168, 659.5221238938054], "114": [16689.118421052663, 664.2105263157893], "115": [16979.513043478262, 668.8869565217387], "116": [17270.78017241379, 673.551724137931], "117": [17563.833333333343, 678.205128205128], "118": [17858.101694915247, 682.8474576271187], "119": [18153.294117647085, 687.4789915966389], "120": [18450.59999999999, 692.1], "121": [18748.909090909074, 696.7107438016529], "122": [19052.155737704903, 701.3114754098361], "123": [19360.0325203252, 705.90243902439], "124": [19668.9677419355, 710.4838709677417], "125": [19980.032000000007, 715.0560000000002], "126": [20291.98809523809, 719.6190476190478], "127": [20605.185039370088, 724.1732283464567], "128": [20920.125, 728.71875], "129": [21235.93410852713, 733.2558139534883], "130": [21553.35, 737.7846153846154], "131": [21872.122137404585, 742.30534351145], "132": [22191.76136363636, 746.8181818181818], "133": [22513.357142857145, 751.3233082706768], "134": [22835.992537313432, 755.820895522388], "135": [23159.66666666667, 760.3111111111112], "136": [23485.352941176476, 764.7941176470589], "137": [23811.897810218987, 769.2700729927006], "138": [24140.89855072466, 773.7391304347825], "139": [24476.11510791367, 778.2014388489209], "140": [24812.38928571427, 782.657142857143], "141": [25149.719858155942, 787.1063829787238], "142": [25489.126760563384, 791.549295774648], "143": [25829.423076923085, 795.9860139860142], "144": [26170.940972222204, 800.4166666666665], "145": [26514.206896551732, 804.841379310345], "146": [26858.3595890411, 809.2602739726025], "147": [27204.03061224489, 813.6734693877551], "148": [27551.13513513514, 818.0810810810809], "149": [27899.124161073836, 822.48322147651], "150": [28248.91666666667, 826.8799999999999], "151": [28599.84105960258, 831.2715231788089], "152": [28951.684210526306, 835.6578947368422], "153": [29305.56862745098, 840.0392156862744], "154": [29660.435064935067, 844.4155844155844], "155": [30016.35483870969, 848.7870967741936], "156": [30374.128205128203, 853.1538461538461], "157": [30732.777070063697, 857.5159235668791], "158": [31092.74683544304, 861.873417721519], "159": [31454.289308176085, 866.2264150943395], "160": [31816.706250000003, 870.575], "161": [32180.701863354057, 874.9192546583852], "162": [32545.999999999985, 879.2592592592594], "163": [32912.17177914108, 883.5950920245398], "164": [33280.17073170731, 887.9268292682926], "165": [33649.21212121213, 892.2545454545455], "166": [34019.2048192771, 896.5783132530122], "167": [34391.18562874251, 900.8982035928143], "168": [34764.08035714286, 905.214285714286], "169": [35138.04437869825, 909.5266272189351], "170": [35513.78823529411, 913.8352941176471], "171": [35890.40058479521, 918.1403508771923], "172": [36268.316860465115, 922.4418604651162], "173": [36647.76878612719, 926.7398843930637], "174": [37028.08908045979, 931.0344827586207], "175": [37409.94000000001, 935.3257142857143], "176": [37793.09090909092, 939.6136363636364], "177": [38177.11016949153, 943.8983050847459], "178": [38562.879213483175, 948.1797752808994], "179": [38954.83798882681, 952.4581005586593], "180": [39349.58333333333, 956.7333333333335], "181": [39745.55248618784, 961.0055248618786], "182": [40143.16483516483, 965.2747252747251], "183": [40541.66120218577, 969.5409836065573], "184": [40941.58695652173, 973.8043478260868], "185": [41342.94054054053, 978.064864864865], "186": [41745.17741935483, 982.3225806451613], "187": [42149.042780748656, 986.5775401069516], "188": [42554.12765957447, 990.8297872340424], "189": [42960.09523809524, 995.0793650793651], "190": [43367.8842105263, 999.3263157894736], "191": [43776.69109947648, 1003.5706806282722], "192": [44186.4375, 1007.8125], "193": [44598.13471502594, 1012.0518134715027], "194": [45010.750000000015, 1016.2886597938146], "195": [45424.39743589741, 1020.5230769230769], "196": [45839.83673469386, 1024.7551020408168], "197": [46256.154822335026, 1028.9847715736043], "198": [46673.68939393945, 1033.2121212121199], "199": [47092.82412060301, 1037.4371859296482], "200": [47512.83750000001, 1041.66]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
from matplotlib import pyplot as plt | ||
import itertools, json, os | ||
|
||
OS = os.name | ||
USER_HOME = os.environ.get('Homepath' if OS == 'nt' else 'HOME') | ||
USER_DOC_PATH = USER_HOME + '\\Documents\\' if OS == 'nt' else USER_HOME + '/Documents/' | ||
|
||
def sumlist(x): | ||
""" | ||
sumlist(x) | ||
Returns the running sum of a list of numbers, x. For example: | ||
sumlist([1,2,3]) would return [1,3,6]. | ||
""" | ||
try: | ||
return list(itertools.accumulate(x)) | ||
except TypeError: | ||
raise TypeError("unsupported argument type for 'sumlist'") | ||
|
||
class AnalysisError(Exception): | ||
pass | ||
|
||
class E80Analysis: | ||
def __init__(self): | ||
with open(os.path.join(os.path.dirname(__file__),'e80data.json'), 'r') as f: | ||
self.e80data = json.load(f) | ||
self.spans = range(10,201) | ||
|
||
def set_spans(self, span_lengths): | ||
self.spans = span_lengths | ||
|
||
def _run_train_single_span(self, span_length, axles): | ||
incr = 1 | ||
|
||
axle_loads = axles[0] | ||
axle_spaces = axles[1] | ||
axle_locs = sumlist(axle_spaces) | ||
|
||
train_tot = sum(axle_spaces) | ||
|
||
positions = [] | ||
point = -span_length | ||
while point <= train_tot: | ||
positions.append(point) | ||
point += incr | ||
m_array = [] | ||
v_array = [] | ||
for i in range(len(positions)): | ||
x_locs_total = [-x + positions[i] + span_length for x in axle_locs] | ||
x_locs = [x for x in x_locs_total if (x <= span_length and x >= 0)] | ||
axles_ = [axle for axle in axle_locs if axle <= span_length + positions[i] and axle >= positions[i]] | ||
axle_loads_ = [axle_loads[k] for k, axle in enumerate(axle_locs) if axle in axles_] | ||
num_axles_ = len(axles_) | ||
# a and b arrays store a and b values or each axle | ||
# r1 and r2 arrays store reactions at ends 1 and 2 for each axle | ||
# m and v arrays store m and v caused by each axle | ||
r1 = [] | ||
r2 = [] | ||
m = [] | ||
v = [] | ||
|
||
# This loop calculates individual values for each of the above | ||
# arrays and appends each value to the array. | ||
for j in range(num_axles_): | ||
a_val = span_length + positions[i] - axles_[j] | ||
|
||
b_val = span_length - a_val | ||
|
||
if 0 < b_val < span_length: | ||
r1_val = axle_loads_[j]*b_val/span_length | ||
else: | ||
r1_val = 0 | ||
r1.append(r1_val) | ||
|
||
if 0 < a_val < span_length: | ||
r2_val = axle_loads_[j]*a_val/span_length | ||
else: | ||
r2_val = 0 | ||
r2.append(r2_val) | ||
|
||
m_loc = [] | ||
v_loc = [] | ||
for x_loc in x_locs: | ||
if 0 < b_val < span_length and a_val > x_loc: | ||
m_val = axle_loads_[j]*(a_val - x_loc) | ||
else: | ||
m_val = 0 | ||
m_loc.append(m_val) | ||
|
||
if 0 < b_val < span_length and a_val < x_loc: | ||
v_val = axle_loads_[j] | ||
else: | ||
v_val = 0 | ||
v_loc.append(v_val) | ||
m.append(m_loc if m_loc != [] else [0]) | ||
v.append(v_loc if v_loc != [] else [0]) | ||
# Calculate the moment and shear at the respective x location | ||
# caused by the train at position i and push these values to the | ||
# global moment and shear arrays | ||
moments = list(zip(*m)) | ||
if x_locs != []: | ||
m_tot = max([sum(r2)*(span_length-x_locs[i]) - sum(moments[i]) for i in range(len(x_locs))]) | ||
else: | ||
m_tot = 0 | ||
v_tot = max(sum(r1), sum(r2)) | ||
m_array.append(m_tot) | ||
v_array.append(v_tot) | ||
return max(m_array), max(v_array) | ||
|
||
def _get_single_E80_env(self, span): | ||
if str(span) in self.e80data.keys(): | ||
return self.e80data[str(span)] | ||
else: | ||
axles_E80 = ([40,80,80,80,80,52,52,52,52]*2 + [8]*span, [0,8,5,5,5,9,5,6,5,8,8,5,5,5,9,5,6,5,5.5]+[1]*(span-1)) | ||
axles_E80_alt = ([100,100,100,100], [0,5,6,5]) | ||
e80_vals = self._run_train_single_span(span, axles_E80) | ||
e80_alt_vals = self._run_train_single_span(span, axles_E80_alt) | ||
return (max([e80_vals[0], e80_alt_vals[0]]), max([e80_vals[1], e80_alt_vals[1]])) | ||
|
||
def _calc_e80(self, design, e80): | ||
return (design[0]/e80[0] * 80, design[1]/e80[1] * 80) | ||
|
||
def span(self, axles, span): | ||
return self._calc_e80(self._run_train_single_span(span, axles), self._get_single_E80_env(span)) | ||
|
||
def plot(self, axles, save=False): | ||
|
||
span_data = [self.span(axles, span) for span in self.spans] | ||
plt.plot(self.spans, [x[0] for x in span_data], label='Moment') | ||
plt.plot(self.spans, [x[1] for x in span_data], label='Shear') | ||
plt.legend() | ||
plt.minorticks_on() | ||
plt.grid() | ||
plt.title("Equivalent E-Loadings") | ||
plt.xlabel('Span Length, ft') | ||
plt.ylabel('E-Rating') | ||
if save: | ||
plt.savefig(USER_DOC_PATH+'E-Loading.png') | ||
else: | ||
plt.show() | ||
plt.clf() | ||
plt.cla() | ||
plt.close() |
Oops, something went wrong.