Last active
March 21, 2024 14:07
-
-
Save flare9x/b0b8995cac0680d4791075110e717155 to your computer and use it in GitHub Desktop.
ASME Section VIII – Division 1 - Appendix 13
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
# ASME VIII 2017 | |
# 13-4 DESIGN OF VESSELS OF NONCIRCULAR CROSS SECTION | |
# Figure 13-2(a) Vessels of Rectangular Cross Section | |
# Selection = Sketch (1) | |
#--- Begin single script - validate calculations against example problem | |
# ASME PTB-4-2013 - Example Problem - Header Box Data | |
# Material = SA516, Grade 70 (S) | |
S = 20000 | |
# Design Conditions = 900 psig@350 F(P) | |
P = 400 | |
# Inside Length (Short Side) = 10.625 in (H) | |
H = 7.125 | |
# Inside Length (Long Side) = 126.0 in (h) | |
h = 9.25 | |
# Overall Vessel Length = 346.38 + 8 in (Lv) | |
Lv = 40.0 | |
# Thickness (Short Side) = 1.625 in (t1) | |
t1 = 1.0 | |
# Thickness (Long Side) = 1.625 in (t2) | |
t2 = 1.0 | |
# Thickness (End Plate) = 1.625 in (t5) | |
t5 = .75 | |
# Corrosion Allowance = 0.125 in (CA) | |
CA = .125 | |
# Weld Joint Efficiency (Corner Joint) = (E = 1.0) # 100% UT + Spot RT | |
E = 1.0 | |
# Tube Outside Diameter = 1.0000 in | |
do = 1.0 | |
# Tube Pitch = 2.3910 in | |
p = 2.3910 | |
# Paragraph 13-5 – Calculate the equation constants. | |
h = h + 2*CA | |
H = H +2*(CA) | |
t1 = t1 - CA | |
t2 = t2 - CA | |
t5 = t5 - CA | |
t = t1 # Plates same t | |
# The design equations in this paragraph | |
# are based on vessels in which the ratio of the length of the vessel to the long side or short side | |
# lengths (aspect ratio) is greater than four. These equations are conservatively applicable to vessels | |
# of aspect ratio less than four. Vessels with aspect ratios less than four may be designed in | |
# accordance with the provisions of U-2(g). | |
if (Lv/h > 4) { | |
print("Satisfied") | |
} else if (Lv/h < 4) { | |
print("Not Satisifed") | |
} | |
# Paragraph 13-5 – Calculate the equation constants. | |
b = 1.0 | |
c = t / 2 # The sign of ci is positive. The sign of co is negative | |
I1 = b*(t1^3) / 12 | |
I2 = b*(t2^3) / 12 | |
a = H/h | |
K = (I2/I1)*a | |
# Paragraph 13-7(a) – Calculate the membrane and membrane plus bending stresses. | |
# The membrane stress on the short side plate, Equation (1): | |
Sm_eq1 = (P * h) / (2*t1) | |
# The membrane stress on the long side plate, Equation (2): | |
# 13-6 LIGAMENT EFFICIENCY OF MULTIDIAMETER HOLES IN PLATES | |
# In calculations made according to this Appendix for the | |
# case of a plate with uniform diameter holes, the ligament | |
# efficiency factors em and eb for membrane and bending | |
# stresses, respectively, are considered to be the same. | |
em = (p - do) / p | |
eb = em | |
Sm_eq2 = (P * H) / (2 * t2 * em) | |
# The bending stress at Location N, short side plate, Equation (3): | |
SbN_eq3 = ((P*+c) / (12*I1)) * (-1.5 * (H)^2 + (h)^2*((1 + (a)^2 * K) / (1+K))) | |
SbN_eq3i = -SbN_eq3 # Inside is negative | |
SbN_eq3o = SbN_eq3 # Outside is positive | |
# The bending stress at Location Q, short side plate, Equation (4): | |
SbQ_eq4 = ((P * h^2 * c) / (12 * I1)) * ((1 + a^2 * K) / (1 + K)) | |
SbQ_eq4i = SbQ_eq4 # Inside is positive | |
SbQ_eq4o = -SbQ_eq4 # Outside is negative | |
# The bending stress at Location M, long side plate, Equation (5): | |
SbM_eq5 = ((P * h^2 * c) / (12 * I2 * eb)) * (-1.5+(1+a^2*K) / (1 + K)) | |
SbM_eq5i = SbM_eq5 # Inside is negative | |
SbM_eq5o = abs(SbM_eq5) # Outside is positive | |
# The bending stress at Location Q, long side plate, Equation (6): | |
SbQ_eq6 = (((P * h^2 * c) / (12 * I2)) * ((1 + a^2 * K) / (1 + K))) | |
SbQ_eq6i = SbQ_eq6 # Inside is positive | |
SbQ_eq6o = -SbQ_eq6 # Outside is negative | |
# Paragraphs 13-4(b), 13-4(c), and 13-7, Equations (7) through (10) – Acceptance Criteria: | |
if (Sm_eq1 <= (S * E)) { | |
cat("Short Side Membrane Stress",Sm_eq1,"psig is below Allowable Stress (S * E)", S*E,"psig") | |
} | |
# Short side plate at Location N, Membrane + Bending Stress: | |
N_totali = Sm_eq1 + SbN_eq3i | |
N_totalo = Sm_eq1 + SbN_eq3o | |
if (N_totali <= 1.5 * (S * E)) { | |
cat("Short Side Membrane + Bending Stress at location N (inside)",N_totali,"psig is below Allowable Stress 1.5*(S * E)", 1.5*(S*E),"psig") | |
} | |
if (N_totalo <= 1.5 * (S * E)) { | |
cat("Short Side Membrane + Bending Stress at location N (outside)",N_totalo,"psig is below Allowable Stress 1.5*(S * E)", 1.5*(S*E),"psig") | |
} | |
# Short side plate at Location Q, Membrane + Bending Stress: | |
Q_totali = Sm_eq1 + SbQ_eq4i | |
Q_totalo = Sm_eq1 + SbQ_eq4o | |
if (Q_totali <= 1.5 * (S * E)) { | |
cat("Short Side Membrane + Bending Stress at location Q (inside)",Q_totali,"psig is below Allowable Stress 1.5*(S * E)", 1.5*(S*E),"psig") | |
} | |
if (Q_totalo <= 1.5 * (S * E)) { | |
cat("Short Side Membrane + Bending Stress at location Q (outside)",Q_totalo,"psig is below Allowable Stress 1.5*(S * E)", 1.5*(S*E),"psig") | |
} | |
# Long side plate, Membrane Stress: | |
if (Sm_eq2 <= (S * E)) { | |
cat("Short Side Membrane Stress",Sm_eq2,"psig is below Allowable Stress (S * E)", S*E,"psig") | |
} | |
# Long side plate at Location M, Membrane + Bending Stress: | |
M_totali = Sm_eq2 + SbM_eq5i | |
M_totalo = Sm_eq2 + SbM_eq5o | |
if (M_totali <= 1.5 * (S * E)) { | |
cat("True - Long Side Membrane + Bending Stress at location M (inside)",M_totali,"psig is below Allowable Stress 1.5*(S * E)", 1.5*(S*E),"psig") | |
} else if (M_totali > 1.5 * (S * E)) { | |
cat("Flase - Long Side Membrane + Bending Stress at location M (inside)",M_totali,"psig is above Allowable Stress 1.5*(S * E)", 1.5*(S*E),"psig") | |
} | |
if (M_totalo <= 1.5 * (S * E)) { | |
cat("True - Long Side Membrane + Bending Stress at location M (outside)",M_totalo,"psig is below Allowable Stress 1.5*(S * E)", 1.5*(S*E),"psig") | |
} else if (M_totalo > 1.5 * (S * E)) { | |
cat("False - Long Side Membrane + Bending Stress at location M (outside)",M_totalo,"psig is above Allowable Stress 1.5*(S * E)", 1.5*(S*E),"psig") | |
} | |
# Long side plate at Location Q, Membrane + Bending Stress: | |
Q_totali = Sm_eq2 + SbQ_eq6i | |
Q_totalo = Sm_eq2 + SbQ_eq6o | |
if (Q_totali <= 1.5 * (S * E)) { | |
cat("True - Long Side Membrane + Bending Stress at location Q (inside)",Q_totali,"psig is below Allowable Stress 1.5*(S * E)", 1.5*(S*E),"psig") | |
} else if (Q_totali > 1.5 * (S * E)) { | |
cat("Flase - Long Side Membrane + Bending Stress at location Q (inside)",Q_totali,"psig is above Allowable Stress 1.5*(S * E)", 1.5*(S*E),"psig") | |
} | |
if (Q_totalo <= 1.5 * (S * E)) { | |
cat("True - Long Side Membrane + Bending Stress at location Q (outside)",Q_totalo,"psig is below Allowable Stress 1.5*(S * E)", 1.5*(S*E),"psig") | |
} else if (Q_totalo > 1.5 * (S * E)) { | |
cat("False - Long Side Membrane + Bending Stress at location Q (outside)",Q_totalo,"psig is above Allowable Stress 1.5*(S * E)", 1.5*(S*E),"psig") | |
} | |
#--- End single script | |
#--- Begin iterative script | |
# Iterate to find the failure thickness's | |
S = 20000 | |
P = 400 | |
H = 7.125 | |
h = 9.25 | |
Lv = 40.0 | |
t1 = 1.0 | |
t2 = 1.0 | |
t5 = .75 | |
CA = .125 | |
E = 1.0 | |
do = 1.0 | |
p = 2.3910 | |
# Substitute t1 and t2 for a range of thickness | |
t1 = seq(from=0.01,to=3.05,by=0.05) | |
t2 = seq(from=0.01,to=3.05,by=0.05) | |
# Establish this appendix can be used | |
if (Lv/h > 4) { | |
print("Satisfied") | |
} else if (Lv/h < 4) { | |
print("Not Satisifed") | |
} | |
# Iterate through varying t1 and t2 thickness to find failure points | |
# Initialize output | |
output = data.frame(short_side_membrane_stress = numeric(0), short_side_membrane_plus_bending_stress_at_location_N_inside = numeric(0), short_side_membrane_plus_bending_stress_at_location_N_outside = numeric(0), | |
short_side_membrane_plus_bending_stress_at_location_Q_inside = numeric(0), short_side_membrane_plus_bending_stress_at_location_Q_outside = numeric(0), | |
long_side_membrane_stress = numeric(0),long_side_membrane_plus_bending_stress_at_location_M_inside = numeric(0),long_side_membrane_plus_bending_stress_at_location_M_outside = numeric(0), | |
long_side_membrane_plus_bending_stress_at_location_Q_inside = numeric(0), long_side_membrane_plus_bending_stress_at_location_Q_outside = numeric(0),t1_thickness = numeric(0),t2_thickness = numeric(0), all_pass = numeric(0)) | |
for (i in 1:length(t1)) { | |
# Paragraph 13-5 – Calculate the equation constants. | |
b = 1.0 | |
c = t1[i] / 2 # The sign of ci is positive. The sign of co is negative | |
I1 = b*(t1[i]^3) / 12 | |
I2 = b*(t2[i]^3) / 12 | |
a = H/h | |
K = (I2/I1)*a | |
# Paragraph 13-7(a) – Calculate the membrane and membrane plus bending stresses. | |
# The membrane stress on the short side plate, Equation (1): | |
Sm_eq1 = (P * h) / (2*t1[i]) | |
# The membrane stress on the long side plate, Equation (2): | |
em = (p - do) / p | |
eb = em | |
Sm_eq2 = (P * H) / (2 * t2[i] * em) | |
# The bending stress at Location N, short side plate, Equation (3): | |
SbN_eq3 = ((P*+c) / (12*I1)) * (-1.5 * (H)^2 + (h)^2*((1 + (a)^2 * K) / (1+K))) | |
SbN_eq3i = -SbN_eq3 # Inside is negative - compression | |
SbN_eq3o = SbN_eq3 # Outside is positive + positive | |
# The bending stress at Location Q, short side plate, Equation (4): | |
SbQ_eq4 = ((P * h^2 * c) / (12 * I1)) * ((1 + a^2 * K) / (1 + K)) | |
SbQ_eq4i = SbQ_eq4 # Inside is positive + positive | |
SbQ_eq4o = -SbQ_eq4 # Outside is negative - compression | |
# The bending stress at Location M, long side plate, Equation (5): | |
SbM_eq5 = ((P * h^2 * c) / (12 * I2 * eb)) * (-1.5+(1+a^2*K) / (1 + K)) | |
SbM_eq5i = SbM_eq5 # Inside is negative - compression | |
SbM_eq5o = abs(SbM_eq5) # Outside is positive + positive | |
# The bending stress at Location Q, long side plate, Equation (6): | |
SbQ_eq6 = (((P * h^2 * c) / (12 * I2)) * ((1 + a^2 * K) / (1 + K))) | |
SbQ_eq6i = SbQ_eq6 # Inside is positive + positive | |
SbQ_eq6o = -SbQ_eq6 # Outside is negative - compression | |
# Paragraphs 13-4(b), 13-4(c), and 13-7, Equations (7) through (10) – Acceptance Criteria: | |
# 1 = true, 0 = false | |
if (Sm_eq1 <= (S * E)) { | |
short_side_membrane_stress = 1 | |
} else if (Sm_eq1 > (S * E)) { | |
short_side_membrane_stress = 0 | |
} | |
# Short side plate at Location N, Membrane + Bending Stress: | |
N_totali = Sm_eq1 + SbN_eq3i | |
N_totalo = Sm_eq1 + SbN_eq3o | |
if (N_totali <= 1.5 * (S * E)) { | |
short_side_membrane_plus_bending_stress_at_location_N_inside = 1 | |
} else if (N_totali > 1.5 * (S * E)) { | |
short_side_membrane_plus_bending_stress_at_location_N_inside = 0 | |
} | |
if (N_totalo <= 1.5 * (S * E)) { | |
short_side_membrane_plus_bending_stress_at_location_N_outside = 1 | |
} else if (N_totalo > 1.5 * (S * E)) { | |
short_side_membrane_plus_bending_stress_at_location_N_outside = 0 | |
} | |
# Short side plate at Location Q, Membrane + Bending Stress: | |
Q_totali = Sm_eq1 + SbQ_eq4i | |
Q_totalo = Sm_eq1 + SbQ_eq4o | |
if (Q_totali <= 1.5 * (S * E)) { | |
short_side_membrane_plus_bending_stress_at_location_Q_inside = 1 | |
} else if (Q_totali > 1.5 * (S * E)) { | |
short_side_membrane_plus_bending_stress_at_location_Q_inside = 0 | |
} | |
if (Q_totalo <= 1.5 * (S * E)) { | |
short_side_membrane_plus_bending_stress_at_location_Q_outside = 1 | |
} else if (Q_totalo > 1.5 * (S * E)) { | |
short_side_membrane_plus_bending_stress_at_location_Q_outside = 0 | |
} | |
# Long side plate, Membrane Stress: | |
if (Sm_eq2 <= (S * E)) { | |
long_side_membrane_stress = 1 | |
} else if (Sm_eq2 > (S * E)) { | |
long_side_membrane_stress = 0 | |
} | |
# Long side plate at Location M, Membrane + Bending Stress: | |
M_totali = Sm_eq2 + SbM_eq5i | |
M_totalo = Sm_eq2 + SbM_eq5o | |
if (M_totali <= 1.5 * (S * E)) { | |
long_side_membrane_plus_bending_stress_at_location_M_inside = 1 | |
} else if (M_totali > 1.5 * (S * E)) { | |
long_side_membrane_plus_bending_stress_at_location_M_inside = 0 | |
} | |
if (M_totalo <= 1.5 * (S * E)) { | |
long_side_membrane_plus_bending_stress_at_location_M_outside = 1 | |
} else if (M_totalo > 1.5 * (S * E)) { | |
long_side_membrane_plus_bending_stress_at_location_M_outside = 0 | |
} | |
# Long side plate at Location Q, Membrane + Bending Stress: | |
Q_totali = Sm_eq2 + SbQ_eq6i | |
Q_totalo = Sm_eq2 + SbQ_eq6o | |
if (Q_totali <= 1.5 * (S * E)) { | |
long_side_membrane_plus_bending_stress_at_location_Q_inside = 1 | |
} else if (Q_totali > 1.5 * (S * E)) { | |
long_side_membrane_plus_bending_stress_at_location_Q_inside = 0 | |
} | |
if (Q_totalo <= 1.5 * (S * E)) { | |
long_side_membrane_plus_bending_stress_at_location_Q_outside = 1 | |
} else if (Q_totalo > 1.5 * (S * E)) { | |
long_side_membrane_plus_bending_stress_at_location_Q_outside = 0 | |
} | |
t1_thickness = t1[i] | |
t2_thickness = t2[i] | |
# For varying t1,t2 check if Stresses at N,M and Q (inside and outside) Pass | |
test_all_pass = sum(short_side_membrane_stress,short_side_membrane_plus_bending_stress_at_location_N_inside,short_side_membrane_plus_bending_stress_at_location_N_outside, | |
short_side_membrane_plus_bending_stress_at_location_Q_inside,short_side_membrane_plus_bending_stress_at_location_Q_outside,long_side_membrane_stress, | |
long_side_membrane_plus_bending_stress_at_location_M_inside,long_side_membrane_plus_bending_stress_at_location_M_outside,long_side_membrane_plus_bending_stress_at_location_Q_inside, | |
long_side_membrane_plus_bending_stress_at_location_Q_outside) | |
if(test_all_pass == 10) { | |
all_pass = 1 | |
} else if (test_all_pass != 10) { | |
all_pass = 0 | |
} | |
temp_row = data.frame(short_side_membrane_stress,short_side_membrane_plus_bending_stress_at_location_N_inside,short_side_membrane_plus_bending_stress_at_location_N_outside, | |
short_side_membrane_plus_bending_stress_at_location_Q_inside,short_side_membrane_plus_bending_stress_at_location_Q_outside,long_side_membrane_stress, | |
long_side_membrane_plus_bending_stress_at_location_M_inside,long_side_membrane_plus_bending_stress_at_location_M_outside,long_side_membrane_plus_bending_stress_at_location_Q_inside, | |
long_side_membrane_plus_bending_stress_at_location_Q_outside,t1_thickness,t2_thickness,all_pass) | |
output = rbind(output,temp_row) | |
} # end | |
# Find first passing thickness (tmin) | |
for (i in 2:nrow(output)) { | |
if(output$all_pass[i-1] == 0 & output$all_pass[i] == 1) { | |
tmin = max(output$t1_thickness[i],output$t2_thickness[i]) | |
} | |
} | |
cat("Resulting Pressure Tmin = ",tmin) | |
# plot data | |
t = output$t1_thickness | |
index = 1:nrow(output) | |
plot(x = index,y = t, xlab = "No.", ylab = "t", main = "Thickness Needed For Stresses At Location N, M and Q To All Pass", cex.main=1.0,axes = FALSE,col = ifelse(t < tmin,'red','green'), pch = 19 ) | |
axis(side = 1, at = 1:length(t),labels = 1:length(t), las =1,cex.axis=.7,tck = 0, lty = 2, col = "grey") | |
axis(side = 2, at = seq(from=0.01,to=3.05,by=0.05),labels = seq(from=0.01,to=3.05,by=0.05), las =0,cex.axis=.7,tck = 0, lty = 2) | |
box() | |
abline(h=tmin) | |
text(13, 1.0, expression("Tmin = 0.86"), col = "black") | |
text(25, .7, expression("Thickness = Fail"), col = "red") | |
text(55, 2.0, expression("Thickness = Pass"), col = "green") | |
#--- End iterative script |
Hello flare9x. Do you have a user manual of it?. Looks very interesting !
ASME Section VIII Div 1 Mandatory Appendix 13
how do i run this?
its written for R. There's a single script for a given plate thickness - what the stresses are, end line 157. There is another script that at a specified plate dimension, will iterate over a 'range' of plate thickness's and check that the stresses induced are within code allowable stress - that output is saved in a dataframe and the plot at the bottom will show this result as well. Run script in R, RStudio.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello flare9x. Do you have a user manual of it?. Looks very interesting !