CHAPTER 4: DISLOCATION DENSITY DISTRIBUTION INVERSE PROBLEM
4.5 Comparison of Dislocation Modeling Techniques
Until now the only method for optimizing a dislocation arrangement to match a strain field is that of continuum dislocations presented in Sections 4.1-4.2. Throughout the course of the project, however, a method utilizing discrete dislocations was also extensively studied. In this method the analytical solution for a plane-strain edge dislocation in an infinite plate was employed. The linearity of the analytical dislocation strain field allows the strain field from an arrangement of dis-locations to be calculated through superposing the strain fields from each individual dislocation.
A sample of code that performs this calculation is given in Appendix B. A set number of in-plane discrete edge dislocations were placed in a computational domain. The x-location, y-location, Burgers vector magnitude, and orientation of each dislocation was treated as an optimization pa-rameter leading to 4Nd parameters for Nd dislocations. The parameters were varied until a local minimum in the difference between the calculated and measured strain values was reached. The downfall of the method comes when strains near the boundary are desired. The analytical solutions used in the calculation are derived from an infinite plate assumption. In order to mimic a material boundary image dislocations were used to enforce zero stress boundary conditions. Image disloca-tions are a mirror image of a dislocation located on the opposite side of a free surface. The strain calculation simply superposes the image dislocation strain field with the original dislocation strain field. Image dislocation behavior is not entirely physical though as each component of stress is set to zero at the boundaries, rather than just the normal stress. This method is much easier to code and orders of magnitude faster to compute.
Despite the simplicity of the method, the optimized strains agreed quite well with measured strains. Contours of the measured strain components are compared with the optimized strain con-tours for the AA7075 sample in Figure 4.15. The optimized discrete dislocations are overlaid on the calculated strain contours. The measured and calculated strains are compared along the x = 0 line in Figure 4.17. Free surface boundaries were placed at the minimum and maximum y-coordinate of the measured data points, which explain why each strain component approaches zero
at the minimum and maximum y-coordinate. The calculation domain only included the measure-ment region since vertical free surfaces could easily be excluded on the left and right side of the measurement region. The physical representation of the ˜α13distribution discussed in Section 4.3 is easier to see here. Comparing the ˜α13distribution given in Figure 4.5 with the discrete dislocations displayed in Figure 4.15 gives insight to a physical representation. Regions of negative ˜α13located near the top and bottom of the domain in Figure 4.5 correspond to the negative edge dislocations in Figure 4.15, while the region of positive ˜α13 located in the middle of the domain in Figure 4.5 corresponds to the positive edge dislocations in Figure 4.15. The method lost some accuracy when only the εexxmeasurements were supplied to the objective function. Strain contours are displayed in Figure 4.16, and a line plots comparing the XRD measurements to the optimized strains is in Fig-ure 4.18. At first glance there is an obvious discrepancy between the measFig-ured and calculated εexy. This could be due to the lack of a periodic boundary condition, which would be more appropriate since the effect of material on both sides of the domain is not included in the model. The trend in the εeyycalculation matches that of the measurements, despite this component being withheld from the objective function.
Discrete dislocation optimization results for the Ti-64 sample are displayed in Figure 4.19.
Only contour plots from this calculation are presented as the inherent 2D nature of the strain fields caused by the notches prevents a line plot from conveying the ability of the method. It is clear from these contours that the magnitudes are not in close agreement, but the overall trends are captured.
More interestingly, the trends in all three strain components are still captured when only the εexx component is supplied to the objective function, as seen in the results presented in Figure 4.20. The discrete dislocation method proved to be useful to quickly determine an approximate layout of the dislocation distribution, and was reliable if strain values are desired “far” from a boundary. In real applications this will likely not be the case as boundary behavior is especially important to fatigue behavior. To calculate realistic full field behavior both BVPs must be solved so that equilibrium is ensured and boundary conditions are enforced. That is not to say that the discrete dislocation optimization does not have its place as a quick first calculation.
4.6 Figures
Figure 4.1 Mesh Used for AA7075 Continuum Dislocation Calculations
−40−30−20−10 0 10 20 30 40
Figure 4.2 AA7075 XRD Measurements
−40−30−20−10 0 10 20 30 40
(c) Residual ABAQUS εexx
−40−30−20−10 0 10 20 30 40
(d) Residual ABAQUS εeyy Figure 4.3 ABAQUS Calculations
-6.0 -4.0 -2.0 0.0 2.0 4.0 6.0
y-coordinate (mm)
-1.0 -0.5 0.0 0.5 1.0
Strain(%)
XRD xx
XRD yy
XRD xy
ABAQUS xx
ABAQUS yy
ABAQUS xy
(a) Loaded State
-6.0 -4.0 -2.0 0.0 2.0 4.0 6.0
y-coordinate (mm)
-0.4 -0.2 0.0 0.2 0.4
Strain(%)
XRD xx
XRD yy
XRD xy
ABAQUS xx
ABAQUS yy
ABAQUS xy
(b) Residual State
Figure 4.4 Comparison of AA7075 XRD Measurements to ABAQUS Calculations
−40−30−20−10 0 10 20 30 40
(d) Optimized ˜α13Distribution
-6.0 -4.0 -2.0 0.0 2.0 4.0 6.0
Optimized xx
Optimized yy
Optimized xy
(e) Comparison of ABAQUS εeand Optimized εeAlong x= 0
−40−30−20−10 0 10 20 30 40
(d) Optimized ˜α13Distribution
-6.0 -4.0 -2.0 0.0 2.0 4.0 6.0
Optimized xx
Optimized yy
Optimized xy
(e) Comparison of ABAQUS εeand Optimized εeAlong x= 0
−40−30−20−10 0 10 20 30 40
(d) Optimized ˜α13Distribution
-6.0 -4.0 -2.0 0.0 2.0 4.0 6.0
Optimized xx
Optimized yy
Optimized xy
(e) Comparison of XRD εeand Optimized εeAlong x= 0
−40 −30 −20 −10 0 10 20 30 40
(a) Zeros Added to εexxMeasurements
−40 −30 −20 −10 0 10 20 30 40
(b) Zeros Added to εeyyMeasurements
−40 −30 −20 −10 0 10 20 30 40
(c) Zeros Added to εexyMeasurements
Figure 4.8 Zeros Added to AA7075 XRD Measurements
−40−30−20−10 0 10 20 30 40
(d) Optimized ˜α13Distribution
-6.0 -4.0 -2.0 0.0 2.0 4.0 6.0
Optimized xx
Optimized yy
Optimized xy
(e) Comparison of XRD εeand Optimized εeAlong x= 0
−40−30−20−10 0 10 20 30 40
(d) Optimized ˜α13Distribution
-6.0 -4.0 -2.0 0.0 2.0 4.0 6.0
Optimized xx
Optimized yy
Optimized xy
(e) Comparison of XRD εeand Optimized εeAlong x= 0
Figure 4.11 Mesh Used for Ti-64 Continuum Dislocation Calculations
−40 −30 −20 −10 0 10 20 30 40
(a) εexxMeasurements
−40 −30 −20 −10 0 10 20 30 40
(b) εeyyMeasurements
−40 −30 −20 −10 0 10 20 30 40
(c) εexyMeasurements
Figure 4.12 Ti-64 XRD Measurements
−40−30−20−10 0 10 20 30 40
(d) Optimized ˜α13Distribution
-3.0 -2.0 -1.0 0.0 1.0 2.0 3.0
Optimized xx
Optimized yy
Optimized xy
(e) Comparison of XRD εeand Optimized εeAlong x= 0
−40−30−20−10 0 10 20 30 40
(d) Optimized ˜α13Distribution
-3.0 -2.0 -1.0 0.0 1.0 2.0 3.0
Optimized xx
Optimized yy
Optimized xy
(e) Comparison of XRD εeand Optimized εeAlong x= 0
−6 −4 −2 0 2 4 6 Figure 4.15 AA7075 Discrete Dislocation Optimization Results
−6 −4 −2 0 2 4 6 Figure 4.16 AA7075 Discrete Dislocation Comparing εexxOnly Optimization Results
-6.0 -4.0 -2.0 0.0 2.0 4.0 6.0
y-coordinate (mm)
-0.4 -0.2 0.0 0.2 0.4
Strain(%)
XRD xx
XRD yy
XRD xy
Optimized xx
Optimized yy
Optimized xy
Figure 4.17 Comparison of Measured and Optimized Strains from Discrete Dislocation Optimization
-6.0 -4.0 -2.0 0.0 2.0 4.0 6.0
y-coordinate (mm)
-0.4 -0.2 0.0 0.2 0.4
Strain(%)
XRD xx
XRD yy
XRD xy
Optimized xx
Optimized yy
Optimized xy
Figure 4.18 Comparison of Measured and Optimized Strains from Discrete Dislocation Optimization, Only εexxCompared
−6 −4 −2 0 2 4 6 Figure 4.19 Ti-64 Discrete Dislocation Optimization Results
−6 −4 −2 0 2 4 6 Figure 4.20 Ti-64 Discrete Dislocation Comparing εexxOnly Optimization Results
CHAPTER 5: CONCLUSION
Understanding the residual stress state of processed metals is crucial to accurately predict their fatigue life. Residual stresses, or those present in the absence of applied loads, are caused by ar-rangements of crystalline defects referred to as dislocations. Dislocations introduce elastic strains into a crystal lattice by shifting material. XRD measurements are ideally suited for measuring residual stresses, since they are non-destructive and only sensitive to elastic strain. A continuum dislocation formulation has been presented that allows elastic strains to be calculated from known dislocation density distributions. This work aims to develop a technique for reducing the number of necessary XRD measurements needed to fully characterize the residual stress state. Instead of measuring the entire strain field, only essential regions that characterize the strain behavior are measured. An inverse problem is then solved to determine an optimal dislocation density dis-tribution whose calculated strain field matches the XRD measurements. The optimal dislocation distribution is then used to solve two BVPs; first for the incompatible elastic distortion field and then for the displacement field. Finally, the stress field in the entire sample can be calculated from the displacement field.
The proposed technique was explored in a four-point bending experiments using both AA7075 and Ti-64 samples. Continuum and discrete techniques for modeling dislocations were explored and compared. The continuum approach is much more complicated to understand and develop in code, however, realistic boundary conditions are respected. The discrete approach is much simpler, but does not enforce proper boundary conditions and can only be used under the plane strain assumption. Thus, a trade off exists that should be explored for each specific application.
If a quick answer is desired and strains are low or unimportant near the boundaries, the discrete technique may be a reasonable choice. If an accurate answer is desired and strains are high or important near the boundaries, the continuum technique should be employed.
The ability of a dislocation strain field to match all components of a measured residual strain field provides further evidence that dislocations are the underlying mechanism in residual stress.
This concept was verified by determining a dislocation distribution whose strain field matched residual strains predicted from an ABAQUS simulation. The optimal dislocation distribution had a physical parallel to regions of positive and negative edge dislocations. Further optimizations explored the behavior of the technique as measurement locations and strain components were withheld from the objective function. It was determined that so long as enough measurements were taken such that the essence of the strain behavior was captured, the optimization algorithm was able to determine a dislocation arrangement whose calculated strain field reasonably matched the measurements. In the case of bending, multiple strain components that capture the overall behavior of the strain field are necessary to produce a reasonable match between measured and calculated strain across the entire sample.
REFERENCES
[1] Amit Acharya. Personal communication.
[2] Amit Acharya. A model of crystal plasticity based on the theory of continuously distributed dislocations. Journal of the Mechanics and Physics of Solids, 49(4):761–784, 2001.
[3] Aerospace Specification Metals Inc. Aluminum 7075-T6; 7075-T651.
[4] Aerospace Specification Metals Inc. Titanium Ti-6Al-4V (Grade 5), Annealed.
[5] ALCOA. Alloy 7075 Plate and Sheet.
[6] J. V. Bernier, N. R. Barton, U. Lienert, and M.P. Miller. Far-field high energy diffraction microscopy: A tool for intergranular orientation and strain analysis. Journal of Strain Analysis for Engineering Design, 46(7):527–547, 2011.
[7] William D. Jr. Callister and David G. Rethwisch. Materials Science and Engineering An Introduction. John Wiley & Sons, Inc., 111 River Street, Hoboken, NJ 07030-5774, eighth edition, 2010.
[8] P. Chadwick. Continuum Mechanics: Concise Theory and Problems. Dover Publications, Inc., Mineola, New York, 1999.
[9] M. Croft, V. Shukla, E.K. Akdoˇgan, N. Jisrawi, Z. Zhong, R. Sadangi, A. Ignatov,
L. Balarinni, K. Horvath, and T. Tsakalakos. In situ strain profiling of elastoplastic bending in ti-6al-4v alloy by synchrotron energy dispersive x-ray diffraction. Journal of Applied Physics, 105:093505, 2009.
[10] Bob. He. Two-Dimensional X-Ray Diffraction. John Wiley & Sons, Inc., 111 River Street, Hoboken, NJ 07030-5774, 2009.
[11] A.K. Head, S.D. Howison, J.R. Ockendon, and S.P. Tighe. An equilibrium theory of dislocation continua. SIAM Review, 35(4):580–609, 1993.
[12] R. Keivani, M. Jahazi, T. Pham, A. R. Khodabandeh, and M. R. Afshar. Predicting residual stresses and distortion during multisequence welding of large size structures using fem. The International Journal of Advanced Manufacturing Technology, 73(1):409–419, 2014.
[13] Ekkehart Kr¨oner. General continuum theory of dislocations and proper stresses. Archive for Rational Mechanics and Analysis, 4:273–334, 1960.
[14] Ekkehart Kr¨oner. On the physical reality of torque stresses in continuum mechanics.
[15] Gerd L¨utjering and James C. Williams. Titanium. Springer Science+Business Media, New York, NY, second edition, 2007.
[16] Kurt M. Marshek and Robert C. Juvinall. Fundamentals of Machine Component Design.
John Wiley & Sons, Inc., 111 River Street, Hoboken, NJ 07030-5774, 4th edition, 2006.
[17] I.C. Noyan and J.B. Cohen. Residual Stress. Springer Science+Business Media, New York, NY, 1987.
[18] Bing Pan, Kemao Qian, Huimin Xie, and Anand Asundi. Two-dimensional digital image correlation for in-plane displacement and strain measurement: A review. Measurement Science and Technology, 20(6):062001, 2009.
[19] E.C. Reed and J.A. Viens. The influence of surface residual stress on fatigue limit of titanium. Journal of Engineering for Industry - Transactions of the ASME, 82(1):76–78, 1960.
[20] Anish Roy and Amit Acharya. Finite element approximation of field dislocation mechanics.
Journal of the Mechanics and Physics of Solids, 53(1):143–170, 2005.
[21] Hiroyuki Sasahara. The effect on fatigue life of residual stress and surface hardness resulting from different cutting conditions of 0.45%c steel. International Journal of Machine Tools and Manufacture, 45(2):131–136, 2005.
[22] Michael A. Sutton, Jean-Jos´e Orteu, and Hubert W. Schreier. Image Correlation for Shape, Motion and Deformation Measurements. Springer Science+Business Media, New York, NY, 2009.
[23] G.A. Webster and A.N. Ezeilo. Residual stress distributions and their influence on fatigue lifetimes. International Journal of Fatigue, 23(1):375–383, 2001.
[24] Johannes Weertman. Dislocation Based Fracture Mechanics. World Scientific Publishing Co. Pte. Ltd., 5 Toh Tuck Link, Singapore 596224, 1996.
[25] P.J. Withers and H.K.D.H. Bhadeshia. Residual stress part 1 - measurement techniques.
Materials Science and Technology, 17(4):355–365, 2001.
APPENDIX A: XRD STRAIN CALCULATION PYTHON CODE
import numpy as np import numpy.linalg as la
from scipy.optimize importleastsq
########################################################################################################
# User Inputs
########################################################################################################
dark_path = ’/media/kswartz92/Swartz/chess/ti64_notched/1081/ff/ff_02650.ge2’
data_path = ’/media/kswartz92/Swartz/chess/ti64_notched/1091/ff/ff_02660.ge2’
detector_dist = 4261.26 # pixels
true_center = [1021.42, 1027.24] # [row, column] of detector image center in pixels (shifted by 1 for python index)
E = 113800 # elastic modulus (MPa)
v = 0.342 # poisson’s ratio
radius = 500 # ring radius in pixels
dr = 25 # half of ring width in pixels
err_max = 0.5 # 2 norm of error / 2 norm of data
min_amp = 200 # minimum acceptable peak amplitude
two_theta_0 = 0.11661487 # unstressed two_theta value
num_vecs = 360 # number of diffraction vectors to fit peaks dgamma = np.radians(0.1) # size of azimuthal patch analyzed in each peak fit
########################################################################################################
# Functions
########################################################################################################
def ge2_reader(path, header_size=4096, image_size=2048):
FID = open(path, ’r’)
image_1d = np.fromfile(FID, dtype=np.uint16) FID.close()
num_images = (image_1d.shape[0] - header_size) / image_size**2
images = np.array(image_1d[header_size:].reshape(num_images,image_size,image_size), dtype=float)
returnimages
def gaussian(x, param):
peakCtr, fwhmL, fwhmR, amp = param
xL = x[x<=peakCtr]
NLG = (xL-peakCtr)**2 DLG = 2*(fwhmL)**2 LG = amp*np.exp(-NLG/DLG) xR = x[x>peakCtr]
NRG = (xR-peakCtr)**2 DRG = 2*(fwhmR)**2 RG = amp*np.exp(-NRG/DRG)
returnnp.hstack([LG,RG])
def residualsG(param, x, y):
returny - gaussian(x, param)
def get_peak_fit_indices(peak, ctr=0.5, lo=0.2, hi=0.8):
peakCtr = int(round(len(peak)*ctr)) loCut = int(round(len(peak)*lo )) hiCut = int(round(len(peak)*hi ))
return peakCtr, loCut, hiCut
def fitPeak(x, y, peakCtr0, fwhm0=10, amp0=3000):
param0 = [peakCtr0, fwhm0, fwhm0, amp0]
param_opt = leastsq(residualsG, param0, args=(x, y), full_output=1)[0]
fit = gaussian(x, param_opt)
err = la.norm( residualsG(param_opt, x, y), 2.0) / la.norm(y, 2.0)
return fit, param_opt, err
def RemoveBackground(x, y, loCut, hiCut):
x_bg = np.concatenate([ x[x<loCut], x[x>hiCut] ]) y_bg = np.concatenate([ y[x<loCut], y[x>hiCut] ]) coeff = np.polyfit(x_bg, y_bg, 1.0)
background = np.polyval(coeff, x) yClean = y - background
return yClean, background
########################################################################################################
# Strain Calculation
########################################################################################################
# read in dark image
dark_image = DataReader.ge2_reader(dark_path)
# average dark images if len(dark_image.shape) > 1:
dark_image = np.mean(dark_image, axis=0)
# read in detector image
image = DataReader.ge2_reader(data_path)[0] # only using first image
image -= dark_image # subtract dark image
# generate coordinates of each pixel and calculate radius and vector angle
x, y = np.meshgrid(np.arange(image.shape[1], dtype=float), np.arange(image.shape[0], dtype=float))
x -= true_center[1]
y -= true_center[0]
rad = np.sqrt( x**2 + y**2 ) # covert x,y coordinates into r,omega coordinates gamma = np.arctan2(y, x) # covert x,y coordinates into r,omega coordinates
# initialize storage arrays
vec_gamma = np.linspace(-np.pi+(dgamma/2), np.pi-(dgamma/2), num=num_vecs)
two_theta = np.zeros(num_vecs)
peak_amps = np.zeros(num_vecs)
peak_errs = np.zeros(num_vecs)
# loop through each diffraction vector for i_vec in range(num_vecs):
# grab slice of detector pixels that are within domega of desired omega img_slice = image[np.abs(gamma-vec_gamma[i_vec]) < dgamma]
r_slice = rad[np.abs(gamma-vec_gamma[i_vec]) < dgamma]
# grab section of slice that is within dr of ring radius
img_slice = img_slice[np.abs(r_slice-radius) < dr]
r_slice = r_slice[np.abs(r_slice-radius) < dr]
sorted_indices = np.argsort(r_slice)
sorted_r = r_slice[sorted_indices]
sorted_peak = img_slice[sorted_indices]
# fit peak to sorted selected pixel values
ctr_ind, lo_ind, hi_ind = PeakFitting.get_peak_fit_indices(sorted_peak)
peak_bg_rm, _ = PeakFitting.RemoveBackground(sorted_r, sorted_peak, sorted_r[lo_ind], sorted_r[hi_ind])
peak_fit, p_opt, err = PeakFitting.fitPeak(sorted_r, peak_bg_rm, sorted_r[ctr_ind])
# calculate 2 theta
opp = p_opt[0]
adj = detector_dist
two_theta[i_vec] = np.arctan(opp/adj)
# store peak amplitude and relative error peak_amps[i_vec] = p_opt[3]
peak_errs[i_vec] = err
# determine which points to use in analysis
use = np.ones((num_vecs), dtype=bool)
use[peak_errs > err_max] = False use[peak_amps < min_amp] = False
theta_0 = two_theta_0 / 2
theta = two_theta / 2
# only use peak fits that met filtering criteria
vec_gamma = vec_gamma[use]
theta = theta[use]
# true strain definition
normal_strains = np.log( np.sin(theta_0) / np.sin(theta) )
# strain rosette equation
A = np.zeros((vec_gamma.shape[0], 3))
A[:, 0] = (1+np.cos(2*vec_gamma)) / 2 A[:, 1] = (1-np.cos(2*vec_gamma)) / 2
A[:, 2] = np.sin(2*vec_gamma)
rhs = normal_strains / np.cos(theta)**2 # project snormal strains onto sample x1-x2 plane exx, eyy, exy = la.lstsq(A, rhs)[0] # solve linear least squares problem
APPENDIX B: DISCRETE DISLOCATION STRAIN CALCULATION PYTHON CODE
import numpy as np
def get_image_dis(free_surface, xc, yc, b, t):
# orientation and location of free surface coord, surf_loc = free_surface
# vertical free surface ifcoord == ’x’:
xi = 2*surf_loc - xc
yi = yc
bi = b
ti = np.pi - t
# horizontal free surface ifcoord == ’y’:
xi = xc
yi = 2*surf_loc - yc
bi = b
ti = -t
returnxi, yi, bi, ti
def superpose_strain_field(exx, eyy, exy, xc, yc, b, t, x, y, mat_props):
# unpack material properties E, G, v = mat_props
# calculate components in dislocation coordinate system (rotate coordinates by theta) x1 = np.cos(t)*(x-xc) + np.sin(t)*(y-yc)
x2 = -np.sin(t)*(x-xc) + np.cos(t)*(y-yc)
# calculate strain components
e11 = ( (G*b) / (2*np.pi*E*(1-v)) ) * ( ( (x1**2*x2)*(2*v**2-1*v-3) ) + ( (x2**3)*(2*v**2+v-1) ) ) / ( (x1**2+x2**2)**2 )
e22 = ( (G*b) / (2*np.pi*E*(1-v)) ) * ( ( (x1**2*x2)*(2*v**2+3*v+1) ) + ( (x2**3)*(2*v**2+v-1) ) ) / ( (x1**2+x2**2)**2 )
e12 = ( b / (4*np.pi*(1-v)) ) * ( x1*(x1**2-x2**2) ) / ( (x1**2+x2**2)**2 )
# rotate coordinates by -theta
exx += (e11*np.cos(t)**2) + (e22*np.sin(t)**2) - (2*e12*np.sin(t)*np.cos(t)) eyy += (e11*np.sin(t)**2) + (e22*np.cos(t)**2) + (2*e12*np.sin(t)*np.cos(t)) exy += ((e11-e22)*np.sin(t)*np.cos(t)) + (e12*(np.cos(t)**2-np.sin(t)**2))
return exx, eyy, exy
def calculate_strain(params, x, y, free_surfaces, mat_props):
""" function calculates the superposed elastic stress/strain fields from input discrete dislocations in an infinite plate with plane strain assumption
inputs:
params : 1d array with lists of (x-positions, y-positions, Burgers vector maginitudes, and orientations) dislocation parameters
x : nd array of x coordinates where stress/strain field is to be calculated y : nd array of y coordinates where stress/strain field is to be calculated free_surfaces : list of free surfaces (example entry: [’x’,4.0])
mat_props : list of material properties containing [elastic modulus, shear modulus, poisson’s ratio]
outputs:
exx : array of xx normal strain values at data points given by x and y arrays eyy : array of yy normal strain values at data points given by x and y arrays exy : array of xy shear strain values at data points given by x and y arrays """
# unpack parameters
n_dis = params.shape[0]//4 # number of dislocations xd = params[0*n_dis : 1*n_dis]
yd = params[1*n_dis : 2*n_dis]
bd = params[2*n_dis : 3*n_dis]
td = params[3*n_dis : 4*n_dis]
# initialize stress/strain arrays
exx, eyy, exy = np.zeros(x.shape), np.zeros(x.shape), np.zeros(x.shape)
# sum up contribution from each dislocation for i_dis in range(n_dis):
# superpose strain field from dislocation
exx, eyy, exy = superpose_strain_field(exx, eyy, exy, xd[i_dis], yd[i_dis], bd[i_dis], td[i_dis], x, y, mat_props)
# superpose strain fields from image dislocations for surface in free_surfaces:
xi, yi, bi, ti = get_image_dis(surface, xd[i_dis], yd[i_dis], bd[i_dis], td[i_dis]) exx, eyy, exy = superpose_strain_field(exx, eyy, exy, xi, yi, bi, ti, x, y, mat_props)
returnexx, eyy, exy