kawin.ElasticFactors
class kawin.StrainEnergy(self)
Defines class for calculating strain energy of a precipitate
Ellipsoidal precipitates will use the Eshelby's tensor
Spherical and Cuboidal precipitates will use the Khachaturyan's approximation
kawin.StrainEnergy.setAspectRatioResolution(self, resolution = 0.01, cachedRange = 5)
Sets resolution to which equilibrium aspect ratios are calculated
Equilibrium aspect ratios are found by calculated strain energy for a range of aspect ratios
and finding the aspect ratio giving the minimum energy (strain + interfacial energy)
If aspect ratio does not vary much in a given system, then the default parameters may lead to poor
prediction of the aspect ratios
Parameters
----------
resolution : float (optional)
Minimum distance between aspect ratios when calculating cache (default at 0.01)
cachedRange : float (optional)
Range of aspect ratio to calculate strain energy when updated cache (default at 5)
kawin.StrainEnergy.setInterfacialEnergyMethod(self, method)
Sets method for calculating interfacial energy as a function of aspect ratio
Parameters
----------
method : str
'eqradius' - interfacial energy is determined using the equivalent spherical radius
'thermo' - interfacial energy is determined using dG/dSA (default)
kawin.StrainEnergy.setSpherical(self)
Assumes spherical geometry for strain energy calculation
Uses Khachaturyan's approximation
kawin.StrainEnergy.setCuboidal(self)
Assumes cuboidal geometry for strain energy calculation
Uses Khachaturyan's approximation
kawin.StrainEnergy.setEllipsoidal(self)
Assumes ellipsoidal geometry for strain energy calculation
Uses Eshelby's tensor
kawin.StrainEnergy.setConstantElasticEnergy(self, energy)
If elastic strain energy is known to be a constant, this can be use to greatly
simplify calculations
Parameters
----------
energy - strain energy in J/m3
kawin.StrainEnergy.setElasticTensor(self, tensor)
kawin.StrainEnergy.setElasticConstants(self, c11, c12, c44)
kawin.StrainEnergy.setModuli(self, E = None, nu = None, G = None, lam = None, K = None, M = None)
kawin.StrainEnergy.setElasticTensorPrecipitate(self, tensor)
kawin.StrainEnergy.setElasticConsantsPrecipitate(self, c11, c12, c44)
kawin.StrainEnergy.setModuliPrecipitate(self, E = None, nu = None, G = None, lam = None, K = None, M = None)
kawin.StrainEnergy._setElasticTensor(self, tensor)
Inputs 6x6 elastic matrix
Parameters
----------
tensor : matrix of floats
Must be 6x6
kawin.StrainEnergy._setElasticConstants(self, c11, c12, c44)
Creates elastic tensor from c11, c12 and c44 constants assuming isotropic system
Parameters
----------
c11 : float
c12 : float
c44 : float
kawin.StrainEnergy._setModuli(self, E = None, nu = None, G = None, lam = None, K = None, M = None)
Set elastic tensor by defining at least two of the moduli
Everything will be converted to E, nu and G
If more than two parameters are defined, then the following priority will be used:
E - Youngs modulus
nu - Poisson's ratio
G - shear modulus
lam - Lame's first parameter
K - bulk modulus
M - P-wave modulus
NOTE: There's gotta be a better way to implement the conversions
kawin.StrainEnergy.setRotationMatrix(self, rot)
Sets rotation matrix to be applied to the matrix
This is for cases where the axes of the precipitate does not align with the axes of the matrix
(e.g., the long/short axes of the precipitate is not parallel to the <100> directions of the matrix)
Parameters
----------
rot : matrix
3x3 rotation matrix
kawin.StrainEnergy.setRotationPrecipitate(self, rot)
kawin.StrainEnergy.setEigenstrain(self, strain)
Sets eigenstrain of precipitate
Parameters
----------
strain : float, array or matrix
float - assume strain is the same along all 3 axis
array - each index corresponds to strain in a given axis
matrix - full 2nd rank strain tensor
NOTE: when using in conjunction with ShapeFactors, the axis are order specific
For needle-like precipitates, x1, x2 and x3 correspond to (short axis, short axis, long axis)
For plate-like precipitates, x1, x2 and x3 correspond to (long axis, long axis, short axis)
kawin.StrainEnergy.setAppliedStress(self, stress)
Sets applied stress tensor
Axes of stress tensor should be the same as the matrix
Parameters
----------
stress : float, array or matrix
float - assume stress is the same along all 3 axis
array - each index corresponds to stress in a given axis
matrix - full 2nd rank stress tensor
NOTE: The applied stress is in reference to the coordinate axes of the precipitates
Thus, this is only valid if the following conditions are met:
The matrix phase has a single orientation (either as a single crystal or highly textured)
Precipitates will form only in a single orientation with respect to the matrix
TODO: It will be nice to expand on this.
For polycrystalline matrix and randomly oriented precipitates, it should be possible
to average the strain energy contributions over all matrix/precipitate orientations
kawin.StrainEnergy.getAppliedStrain(self)
Calculates applied strain tensor from applied stress tensor and elastic tensor
kawin.StrainEnergy.setup(self)
Sets up elastic constants
kawin.StrainEnergy._convert2To4rankTensor(self, c)
Converts 2nd rank elastic tensor to 4th rank
Parameters
----------
c : ndarray
2nd rank elastic tensor
Returns
-------
c4 : ndarray
4th rank elastic tensor
kawin.StrainEnergy._convert4To2rankTensor(self, c4)
Converts 4th rank elastic tensor to 4nd rank
Parameters
----------
c4 : ndarray
4th rank elastic tensor
Returns
-------
c : ndarray
2nd rank elastic tensor
kawin.StrainEnergy._invert4rankTensor(self, c4)
Inverts 4th rank tensor to give stiffness tensor
This is done by converting to 2nd rank, inverting, then converting back to 4th rank
kawin.StrainEnergy._convertVecTo2rankTensor(self, v)
Converts strain/stress vector to 2nd rank tensor
Parameters
----------
v : 1d array
Strain/stress vector
Returns
-------
e : ndarray
2nd rank elastic tensor
kawin.StrainEnergy._convert2rankToVec(self, c)
kawin.StrainEnergy._rotateRank2Tensor(self, rot, tensor)
Rotates a 2nd rank tensor
T_ij = r_il * r_jk * T_lk
Parameters
----------
tensor : ndarray
2nd rank tensor to rotate (3x3 array)
kawin.StrainEnergy._rotateRank4Tensor(self, rot, tensor)
Rotates a 4th rank tensor
T_ijkl = r_im * r_jn * r_ok * r_lp * T_mnop
Parameters
----------
tensor : ndarray
4th rank tensor to rotate (3x3x3x3 array)
kawin.StrainEnergy.setIntegrationIntervals(self, phiInt, thetaInt, assumeSymmetric=True)
Number of intervals to split domain along phi and theta for integration
Parameters
----------
phiInt : int
Number of intervals to divide along phi
thetaInt : int
Number of intervals to divide along theta
assumeSymmetric : bool (optional)
If True (default), will only integrate Eshelby's tensor on a single quadrant and
multiply the results by 8
kawin.StrainEnergy.lebedevIntegration(self, order = ‘high’)
Creates Lebedev quadrature points and nodes for integrating Eshebly's tensor
This is preferred over discretizing phi and theta
Parameters
----------
order : str
'low' - uses quadrature order or 53 (974 points)
'mid' - uses quadrature order or 83 (2354 points)
'high' (default) - uses quadrature order or 131 (5810 points)
kawin.StrainEnergy._n(self, phi, theta)
Unit normal vector of sphere
Parameters
----------
phi - azimuthal angle
theta - polar angle
kawin.StrainEnergy._beta(self, a, b, c, phi, theta)
Distance from center to surface of ellipsoid
Parameters
----------
a, b, c - radii of ellipsoid along x,y,z axes
phi, theta - azimuthal, polar angle
kawin.StrainEnergy._OhmGeneral(self, n)
Ohm term for general system
Ohm_ij = inverse(C_iklj * n_k * n_l)
kawin.StrainEnergy.sphInt(self)
Faster version of calculating the Dijkl, which avoids
using a for loop to iterate across phi and theta
kawin.StrainEnergy.Dijkl(self)
kawin.StrainEnergy.Sijmn(self, D)
S_ijmn = -0.5 * C_lkmn * (D_iklj + D_jkli)
kawin.StrainEnergy._multiply(self, a, b)
Multiplies 2 tensors
4th x 2nd -> c_ij = a_ijkl * b_kl
4th x 4th -> c_ijkl = a_ijmn * b_mnkl
kawin.StrainEnergy._strainEnergy(self, stress, strain, V)
u = -0.5 * V * sigma_ij * strain_ij
kawin.StrainEnergy._strainEnergyEllipsoidWithStress(self)
kawin.StrainEnergy._strainEnergyEllipsoid(self)
kawin.StrainEnergy._strainEnergyEllipsoid2(self)
kawin.StrainEnergy._strainEnergyBohm(self)
kawin.StrainEnergy._strainEnergyBohm2(self)
kawin.StrainEnergy._Khachaturyan(self, I1, I2)
Khachaturyan's approximation for strain energy of spherical and cuboidal precipitates
kawin.StrainEnergy._strainEnergyCube(self)
Strain energy of perfect cube (cubic factor = sqrt(2))
kawin.StrainEnergy._strainEnergySphere(self)
Strain energy of perfect sphere (cubic factor = 1)
kawin.StrainEnergy._strainEnergyCuboidal(self, eta = 1)
For cuboidal preciptitates, strain energy can be approximated
as a linear interpolation between a perfect cube and sphere
kawin.StrainEnergy._strainEnergyConstant(self)
kawin.StrainEnergy._strainEnergySingle(self, rsingle)
Generic strain energy function
kawin.StrainEnergy.strainEnergy(self, r)
kawin.StrainEnergy._OhmCubic(self, n)
Ohm term for cubic crystal symmetry
kawin.StrainEnergy._D(self, n)
Needed for the Ohm term with cubic crystal symmetry
kawin.StrainEnergy._xi(self)
kawin.StrainEnergy.eqAR_byGR(self, Rsph, gamma, shpFactor, a=1.001, b=100)
Golden ratio search
Parameters
----------
Rsph : float or array
Equivalent spherical radius
gamma : float
Interfacial energy
shpFactor : ShapeFactor object
a, b : float
Min and max bounds
Default is 1.001 and 100
kawin.StrainEnergy._GRsearch(self, Rsph, gamma, interfacial, normR, a, b)
Golden ratio search for a single radius
kawin.StrainEnergy.updateCache(self, normR)
Update cached calculations
kawin.StrainEnergy.clearCache(self)
Clear cached calculations
kawin.StrainEnergy.eqAR_bySearch(self, Rsph, gamma, shpFactor)
Cached search
Parameters
----------
Rsph : float or array
Equivalent spherical radius
gamma : float
Interfacial energy
shpFactor : ShapeFactor object
kawin.StrainEnergy._cachedSearch(self, Rsph, gamma, interfacial, normR)
Cached search for a single radius