Commit 2eded71d authored by lapm's avatar lapm
Browse files

Upload New File

parent b848a7f9
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Data analysis of a single tensile test (CSV)\n",
"\n",
"Lars P. Mikkelsen (lapm@dtu.dk), Composite Materials, DTU Wind Energy, Fall 2020\n",
"\n",
"This jupyter notebook is made in order to investigate individual data set and save the results in a mat-file."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import DataAnalysisFuncV1b as daf # Import functions for data analysis\n",
"import copy\n",
"\n",
"StrainRange = (0.05,0.25)\n",
"\n",
"# For Jupyter Notebook plotning\n",
"%matplotlib inline \n",
"#%matplotlib notebook "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"SpecName='EpoxyData-01'\n",
"DataFile =SpecName+'.steps.tracking.csv'\n",
"\n",
"time0,load0,strain10,strain20 = np.loadtxt(open(DataFile,'r'),skiprows=1,\n",
" delimiter=';',usecols=(0,8,9,10),dtype=float,unpack=True)\n",
"\n",
"plt.figure()\n",
"plt.plot(time0,load0,'r.-')\n",
"plt.xlabel('Time [s]',fontsize=18)\n",
"plt.ylabel('Load [kN]',fontsize=18)\n",
"plt.grid()\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure()\n",
"plt.plot(time0,strain10,'r.-', label=r'$\\varepsilon_1$')\n",
"plt.plot(time0,strain20,'b.-', label=r'$\\varepsilon_2$')\n",
"plt.xlabel('Time [s]',fontsize=18)\n",
"plt.ylabel(r'$\\varepsilon$ [%]',fontsize=18)\n",
"plt.legend(loc=2)\n",
"plt.grid()\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"icut=daf.FuncCut(load0,5) \n",
"time=time0[:icut]\n",
"strain1=strain10[:icut]\n",
"strain2=strain20[:icut]\n",
"load=load0[:icut]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"strain1Ini=copy.copy(strain1)\n",
"strain2Ini=copy.copy(strain2)\n",
"\n",
"#ia,ib=daf.FuncRange(strain1,(4.5,4.9))\n",
"#strain1a=daf.FuncStrainReplace(time,strain1,ia,ib)\n",
"strain1a=strain1 # if no extrapolation \n",
"\n",
"#ia,ib=daf.FuncRange(strain2,(5.5,5.9))\n",
"#strain2a=daf.FuncStrainReplace(time,strain2,ia,ib)\n",
"strain2a=strain2 # if no extrapolation \n",
"\n",
"plt.figure()\n",
"plt.plot(time,strain1Ini,'r-', label=r'$\\varepsilon_1$ before extrapolate')\n",
"plt.plot(time,strain1a,'b-', label=r'$\\varepsilon_1$ after extrapolate')\n",
"plt.xlabel('Time [s]',fontsize=18)\n",
"plt.ylabel(r'$\\varepsilon$ [%]',fontsize=18)\n",
"plt.legend(loc=0)\n",
"plt.grid()\n",
"plt.show()\n",
"\n",
"plt.figure()\n",
"plt.plot(time,strain2Ini,'r-', label=r'$\\varepsilon_2$ before extrapolate')\n",
"plt.plot(time,strain2a,'b-', label=r'$\\varepsilon_2$ after extrapolate')\n",
"plt.xlabel('Time [s]',fontsize=18)\n",
"plt.ylabel(r'$\\varepsilon$ [%]',fontsize=18)\n",
"plt.legend(loc=0)\n",
"plt.grid()\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"GeoDataFile='EpoxyDataWT.csv'\n",
"SpecLineGeo=daf.ReadLineNumber(GeoDataFile,SpecName,icol0=0,iskip=2,strdel=';')\n",
"# Read specific line in GeoDataFile\n",
"t1,t2,t3,w1,w2,w3 = np.loadtxt(open(GeoDataFile,'r'),skiprows=SpecLineGeo,delimiter=';'\n",
" ,usecols=(1,2,3,4,5,6),dtype=float,unpack=True,max_rows=1)\n",
"area=(t1+t2+t3)/3.0*(w1+w2+w3)/3.0\n",
"A0=area\n",
"print('Area=',area,'mm^2 for sample:',SpecName)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Stress = load*1e3/area # N/mm^2 = MPa\n",
"Strain=(strain1a+strain2a)/2 # Find mean value of strain\n",
"\n",
"plt.figure()\n",
"plt.plot(Strain,Stress,'b.-',label=SpecName)\n",
"plt.xlabel(r'$\\varepsilon$ [%]',fontsize=18)\n",
"plt.ylabel(r'$\\sigma$ [MPa]',fontsize=18)\n",
"plt.legend(loc=0)\n",
"plt.grid()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Balance the strain in a consistent way\n",
"When performing the test, the strain measurement will normally be balance when the test is started eventhough there may be a small loads present in the test. It will not alway be possible to put zero load on a test sample as the specimen geometry may be instable even under a small negative load. Here a consistent zero point is defined such that the line used for finding the initial Young modulus is going through $(\\sigma,\\varepsilon)=(0,0)$"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Strain0=copy.copy(Strain)\n",
"Stress0=copy.copy(Stress)\n",
"Strain=daf.FuncBalanceStrain(Strain,Stress,StrainRange)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Calculate the true stress versus logarithmic strain\n",
"After the strain value has been balanced, the true stress and the logarithmic strain can be calcualted from the norminal stress and the engineering strain using the following two relation\n",
"$$ \\varepsilon_{ln}=\\ln(1+\\varepsilon_e) $$\n",
"$$ \\sigma_{t}=\\sigma_n (1+\\varepsilon_e) $$\n",
"In this calulation, it is assumed that there are volume constant during the deformation. This will normally not be the case for the elastic deformation but correct for many type of plastic deformation. The plastic deformation, will normally be dominating, therefore this will normally be a good approximation. It can be shown that the deformation in a tensile test will localize e.g. developing a so-called necking zone or shear band at the load maximum. Therefore, it is only meaningfull to consider a tensile curve up the the load maximum. After the load-maximum, the stress versus strain curve will be specimen dependent and dependent on whether the localization are happening inside or outside the strain measurement zone. \n",
"\n",
"Please note that the function used for true stress, log-strain calculation are assuming that the strain are given in the unit [%]. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Strain1=copy.copy(Strain)\n",
"Stress1=copy.copy(Stress)\n",
"\n",
"# Only save the curve upto the max loading point\n",
"imax=np.argmax(load)\n",
"Strain=Strain[:imax+1] # +1 in order to include max point in array\n",
"Stress=Stress[:imax+1]\n",
"Time=time[:imax+1]\n",
"\n",
"(Strain,Stress)=daf.TrueStress(Strain,Stress)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Calculating the Young modulus, strain rate and maximum stress\n",
"The final point in the data analysis of the tensile test measurement is to calculate the Young modulus defined as the slope of the curve in the range defined by a strain range, a corresponding strain rate found in the same strain range and the maximum stress value calculated both as the nominal and true stress value."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"(ia,ib) = daf.FuncRange(Strain,StrainRange)\n",
"\n",
"pEmod = np.polyfit(Strain[ia:ib] , Stress[ia:ib] , 1)\n",
"Emod=pEmod[0]/10 # Emod in GPa\n",
"EmodStr = r'E=%4.3f GPa' % (Emod)\n",
"\n",
"pEpsRate = np.polyfit(Time[ia:ib] , Strain[ia:ib], 1)\n",
"EpsRate=pEpsRate[0] # EpsRate in [%/s]\n",
"EpsRateStr = r'$\\dot{\\varepsilon}$=%4.3f [%%/s]' % (EpsRate)\n",
"\n",
"# True stress at max load \n",
"iMax=np.abs(load).argmax()\n",
"MaxStress=Stress[iMax]\n",
"MaxStrain=Strain[iMax]\n",
"MaxStressStr =r'$\\sigma_t^{max}=%4.1f$ MPa' % (MaxStress)\n",
"# Nominal stress at max load \n",
"MaxStress0=Stress1[iMax]\n",
"MaxStrain0=Strain1[iMax]\n",
"MaxStress0Str =r'$\\sigma_n^{max}=%4.1f$ MPa' % (MaxStress0)\n",
"# Max averaged strain at failure \n",
"iMaxEnd=np.abs(Strain1).argmax()\n",
"MaxStress0End=Stress0[iMaxEnd]\n",
"MaxStrain0End=Strain0[iMaxEnd]\n",
"MaxStrain0EndStr =r'$\\varepsilon_e^{max}=%4.1f$ %%' % (MaxStrain0End)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plot of balancing the strain measure"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure()\n",
"StrainFit=np.arange(0,MaxStrain/2.0)\n",
"plt.plot(Strain0,Stress0,'g-',label='UnBalanced')\n",
"plt.plot(Strain1,Stress1,'b-',label='Balanced')\n",
"plt.plot(Strain[ia:ib],np.polyval(pEmod,Strain[ia:ib]),'-k',linewidth=4,label=EmodStr)\n",
"plt.plot(StrainFit,np.polyval(pEmod,StrainFit),'--r',linewidth=2,label='E fit line')\n",
"plt.xlabel(r'$\\varepsilon$ [%]',fontsize=18)\n",
"plt.ylabel(r'$\\sigma$ [MPa]',fontsize=18)\n",
"plt.legend(loc=4)\n",
"plt.grid()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plot of a zoom of the balancing the strain measure"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure()\n",
"StrainFit=np.arange(0,MaxStrain/2.0)\n",
"plt.plot(Strain0,Stress0,'g-',label='UnBalanced')\n",
"plt.plot(Strain1,Stress1,'b-',label='Balanced')\n",
"plt.plot(StrainRange,np.polyval(pEmod,StrainRange),'-k',linewidth=4,label=EmodStr)\n",
"plt.plot(StrainFit,np.polyval(pEmod,StrainFit),'--r',linewidth=2,label='E fit line')\n",
"plt.xlabel(r'$\\varepsilon$ [%]',fontsize=18)\n",
"plt.ylabel(r'$\\sigma$ [MPa]',fontsize=18)\n",
"plt.xlim([0,1.5*Strain[ib]])\n",
"plt.ylim([0,1.5*Stress[ib]])\n",
"plt.legend(loc=4)\n",
"plt.grid()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plot of the strain versus time curve"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure()\n",
"plt.plot(Time,Strain,'b-',label=SpecName)\n",
"plt.plot(Time[ia:ib],np.polyval(pEpsRate,Time[ia:ib]),'-k',linewidth=4,label=EpsRateStr)\n",
"plt.ylabel(r'$\\varepsilon_{ln}$ [%]',fontsize=18)\n",
"plt.xlabel(r'Time [s]',fontsize=18)\n",
"plt.legend(loc=4)\n",
"plt.grid()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plot of the stress versus strain curve"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"\n",
"plt.figure()\n",
"plt.title(SpecName)\n",
"plt.plot(Strain1,Stress1,'r-',label='Nominel')\n",
"plt.plot(Strain,Stress,'b-',label='True')\n",
"plt.plot(StrainRange,np.polyval(pEmod,StrainRange),'-k',linewidth=4,label=EmodStr)\n",
"plt.plot(MaxStrain0,MaxStress0,'rx',label=MaxStress0Str)\n",
"plt.plot(MaxStrain0End,MaxStress0End,'ro',label=MaxStrain0EndStr)\n",
"plt.plot(MaxStrain,MaxStress,'bx',label=MaxStressStr)\n",
"plt.xlabel(r'$\\varepsilon$ [%]',fontsize=18)\n",
"plt.ylabel(r'$\\sigma$ [MPa]',fontsize=18)\n",
"plt.legend(loc=4)\n",
"plt.grid()\n",
"plt.savefig(SpecName+'.png', bbox_inches='tight')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Save data for summery plot"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import scipy.io\n",
"scipy.io.savemat(SpecName+'.mat',{'Time': Time, 'Strain': Strain, 'Stress': Stress,\n",
" 'Strain0':Strain1, 'Stress0':Stress1,\n",
" 'pEmod': pEmod,'pEpsRate': pEpsRate,\n",
" 'area': area, 'EpsRate': EpsRate,'Emod': Emod,\n",
" 'MaxStrain': MaxStrain,'MaxStress': MaxStress,\n",
" 'MaxStrain0': MaxStrain0,'MaxStress0': MaxStress0,\n",
" 'MaxStrain0End': MaxStrain0End,'MaxStress0End':MaxStress0End})"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment