This page converts the Engineering stress-strain curve provided by the user to true stress-strain curve using the well known conversion equations. The user is required to input the strain value corresponding to the elasticity limit which the application uses to calculate Young's modulus as the slope of the initial elastic portion. The elasticity limit in this application is assumed to always be less than 0.005 and the user is required to input 8 data points beyond the initial zero point. The page also ouputs the stress-plastic strain data required by some finite element analysis software and provides the best-fit Ramberg-Osgood approximation to the given data.
import matplotlib.pyplot as plt import numpy as np import base64 import io #This function is used to create an image from the plot created using matplotlib.plt def plt_show(plt, width=500, dpi=100): # Converts matplotlib plt to data string # dpi (dots per inch) is the resolution of the image # width is width of image in pixels bytes = io.BytesIO() plt.savefig(bytes, format='png', dpi=dpi) # Save as png image plt.close() bytes.seek(0) base64_string = "data:image/png;base64," + \ base64.b64encode(bytes.getvalue()).decode("utf-8") return "" def main(inputs): elasticitylimit=inputs['elasticitylimit'] stress=[inputs['stress_0'],inputs['stress_1'],inputs['stress_2'],inputs['stress_3'],inputs['stress_4'],inputs['stress_5'],inputs['stress_6'],inputs['stress_7'],inputs['stress_8']] strain=[inputs['strain_0'],inputs['strain_1'],inputs['strain_2'],inputs['strain_3'],inputs['strain_4'],inputs['strain_5'],inputs['strain_6'],inputs['strain_7'],inputs['strain_8']] # print(stress) # print(strain) n = len(stress) straine = [i for i in strain if i < elasticitylimit] stresse = [stress[i] for i in range(len(straine))] truestrain = [np.log(1.0 + i) for i in strain] truestress = [stress[i] * (1 + strain[i]) for i in range(len(strain))] # find Young's modulus p = np.polyfit(straine, stresse, 1) x = np.linspace(0, elasticitylimit) y = np.poly1d(p) E = y[1] #Young = "Young's modulus = " + str(round(E, 2)) + " (MPa)" Young=str(round(E,2)) # find yield stress from scipy.interpolate import interp1d from scipy.optimize import root_scalar y1 = interp1d(truestrain, truestress, kind="linear") def g(x): return E * (x - 0.2 / 100) - y1(x) x2 = root_scalar(g, x0=0.5 / 100, x1=0.4 / 100) yield1 = ( "Yield strength using 0.005 total strain criterion: " + str(np.round(y1(0.005), 2)) + " (MPa)" ) yield2 = ( "Yield strength using 0.2% offset criterion: " + str(np.round(y1(x2.root), 2)) + " (MPa)" ) yield3 = "Yield strain using 0.2% offset criterion: " + str(np.round(x2.root, 4)) yieldl = [yield1, yield2, yield3] x1 = np.linspace(0.002, 0.007) y1 = E * (x1 - 0.002) plasticstrain = [ max(0, truestrain[i] - truestress[i] / E) for i in range(len(strain)) ] plasticstrainzero = [] for i in reversed(plasticstrain): plasticstrainzero.append(i) if i == 0: break plasticstrainzero.reverse() stresszero = truestress[len(truestress) - len(plasticstrainzero) : len(truestress)] # Ramberg Osgood in the form Keps^n from scipy.optimize import curve_fit plasticstrainzerocurve=plasticstrainzero stresszerocurve=stresszero if plasticstrainzero[0] == 0: plasticstrainzero = plasticstrainzero[1 : len(plasticstrainzero)] stresszero = stresszero[1 : len(stresszero)] def f(eps, k, n): return k * eps ** n coeff, covariance = curve_fit(f, plasticstrainzero, stresszero) x_val = np.arange(0, plasticstrainzero[-1], 0.001) y_val = f(x_val, coeff[0], coeff[1]) rodatax = np.arange(0, plasticstrainzero[-1], 0.001) rodatay = f(rodatax, coeff[0], coeff[1]) k = coeff[0] n = coeff[1] # R squared x = np.array(plasticstrainzero) y = np.array(stresszero) y_fit = f(x, coeff[0], coeff[1]) ss_res = np.sum((y - y_fit) ** 2) ss_tot = np.sum((y - np.mean(y)) ** 2) r2 = 1 - (ss_res / ss_tot) #ROmessage = ( # "\(R^2\): " # + str(round(r2, 3)) # + ", \(k\)= " # + str(round(k, 2)) # + ", \(n\)= " # + str(round(n, 5)) #) ROmessage=[str(round(r2, 3)),str(round(k, 2)),str(round(n, 5))] # final curve import pandas as pd def eps(sigma): return sigma / E + (sigma / k) ** (1 / n) y_val = truestress x_val = [i / E + (i / k) ** (1 / n) for i in truestress] data = [ ( round(truestress[i], 2), round(truestrain[i], 4), round(plasticstrain[i], 4), ) for i in range(len(strain)) ] a = pd.DataFrame( data=data, columns=["True Stress", "True Strain", "Plastic Strain"] ) xstrain = x2.root xelastic = [0.002, 0.007] xelasticyoung = [0, 0.005] yelastic = [0.0, E * (0.005)] smax = max(stress) rox = rodatax.tolist() roy = rodatay.tolist() ro = [rox, roy] curve = [strain, stress] truecurve = [truestrain, truestress] # Plotting the first Graph plt.plot(strain, stress,label="Engineering S-S Curve") plt.plot(truestrain,truestress,label="True S-S Curve") plt.legend(shadow=True, fancybox=True) plt.title("True and Engineering Stress-Strain Curves") plt.xlabel("Strain") plt.ylabel("Stress (MPa)") plt.xlim(xmin=0.0) plt.ylim(ymin=0.0) curve=plt_show(plt,500) plt.clf() #Plot the elastic curve. plt.plot(truestrain,truestress,label="True S-S Curve") plt.plot(xelasticyoung,yelastic,label="Initial Linear Curve") plt.xlabel("Strain") plt.ylabel("Stress (MPa)") plt.xlim(xmin=0.0) plt.ylim(ymin=0.0) plt.legend(shadow=True, fancybox=True) ecurve=plt_show(plt,500) plt.clf() #Plot the yield curve. plt.plot(truestrain,truestress,label="True S-S Curve") plt.plot(xelastic,yelastic,label="0.2% Offset Criterion") plt.plot([0.005,0.005],[0,smax],label="0.005 Strain Criterion") plt.xlabel("Strain") plt.ylabel("Stress (MPa)") plt.xlim(xmin=0.0) plt.ylim(ymin=0.0) plt.legend(shadow=True, fancybox=True) yieldcurve=plt_show(plt,500) plt.clf() #Plot the plastic curve. plt.plot(plasticstrainzerocurve,stresszerocurve,label="Stress Plastic Strain Data") maxstrain=max(plasticstrainzerocurve) x1=np.linspace(0,maxstrain) plt.plot(x1,k*x1**n,label="Ramberg Osgood Idealization") plt.xlabel("Plastic Strain") plt.ylabel("Stress (MPa)") plt.xlim(xmin=0.0) plt.ylim(ymin=0.0) plt.legend(shadow=True, fancybox=True) plasticcurve=plt_show(plt,500) plt.clf() #Plot the final curve. plt.plot(truestrain,truestress,label="True S-S Curve (Data)") maxstress=max(truestress) y1=np.linspace(0,maxstress) x1=y1/E+(y1/k)**(1/n) plt.plot(x1,y1,label="True S-S curve using the Ramberg Osgood idealization") plt.xlabel("Strain") plt.ylabel("Stress (MPa)") plt.xlim(xmin=0.0) plt.ylim(ymin=0.0) plt.legend(shadow=True, fancybox=True) finalcurve=plt_show(plt,500) plt.clf() # finalcurve = [x_val, y_val] tables = [a.to_html(justify="center", col_space="100px", header="True")] # finalcurve = [x_val, y_val] tables = [a.to_html(justify="center", col_space="100px", header="True")] return{ "curve":curve, "xstrain":xstrain, "ecurve":ecurve, "yieldcurve":yieldcurve, "yieldl":yieldl, "Young":Young, "plasticcurve":plasticcurve, "ROmessage":ROmessage, "ro":ro, "finalcurve":finalcurve, "tables":tables}
The Output Page:
Analysis Results: The True Stress Strain Curve: The true stress strain data calculated using the well known conversion equations is plotted with the Engineering stress strain curve in the following figure. \varepsilon_{true}=\ln{\left(1+\varepsilon_{eng}\right)} \sigma_{true}=\sigma_{eng}\left(1+\varepsilon_{eng}\right) where: \sigma_{true} and \sigma_{eng} are the true and engineering stresses while \varepsilon_{true} and \varepsilon_{eng} are the true and engineering strains. {{outputs.curve|safe}} Young's Modulus: By fitting a straight line to the first few points in the data, Young's modulus can be estimated as the slope of the linear portion. Young's modulus = {{outputs.Young}} MPa {{outputs.ecurve|safe}} Yield Strength: Two different criteria can be used to estimate the yield strength of the material: {{outputs.yieldl[0]}} {{outputs.yieldl[1]}} {{outputs.yieldl[2]}} {{outputs.yieldcurve|safe}} Ramberg Osgood Approximation: The Ramberg Osgood Approximation used has the following form: \varepsilon=\frac{\sigma}{E}+\left(\frac{\sigma}{k}\right)^n where the stress is related to the plastic strain \varepsilon_p using the following equation: \sigma=k \varepsilon_p^n Using nonlinear curve fitting, the Ramberg Osgood Coefficients and the R^2 are equal to: R^2= {{outputs.ROmessage[0]}} k= {{outputs.ROmessage[1]}} n= {{outputs.ROmessage[2]}} The stress vs. plastic strain curve has the form: {{outputs.plasticcurve|safe}} The stress vs. strain curve using the Ramberg Osgood approximation has the form: {{outputs.finalcurve|safe}} Here is the final data: {{outputs.tables|safe}}
Copyright © MecSimCalc 2025
Terms | Privacy