.. _textures: Working with crystallographic textures --------------------------------------- With the help of `orix `_, Elasticipy allows to compute averages based on crystallographic texture (in addition to single orientations; see :ref:`rotations`). Define and compose textures ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Discrete textures ================= A series of "usual" texture components (e.g. Goss, cube, Brass etc.) are already implemented in Elasticipy: .. doctest:: >>> from elasticipy.crystal_texture import DiscreteTexture >>> goss = DiscreteTexture.Goss() >>> goss Crystallographic texture φ1=0.00°, ϕ=45.00°, φ2=0.00° This texture actually consists in a single orientation (as opposed to fibre textures, see below). It can be used to rotate a stiffness tensor as follows: >>> from elasticipy.tensors.elasticity import StiffnessTensor >>> C = StiffnessTensor.cubic(C11=186, C12=134, C44=77) # Copper, mp-30 >>> C * goss Stiffness tensor (in Voigt mapping): [[ 1.86000000e+02 1.34000000e+02 1.34000000e+02 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 1.34000000e+02 2.37000000e+02 8.30000000e+01 1.42108547e-14 0.00000000e+00 0.00000000e+00] [ 1.34000000e+02 8.30000000e+01 2.37000000e+02 -7.10542736e-15 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 2.60000000e+01 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 7.70000000e+01 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 7.70000000e+01]] Fibre textures ============== Fibre textures are defined as uniformly distributed orientations around a given axis, leading to a single line when plotting an Orientation Distribution Function (ODF), hence the name. Therefore, there are three ways to define such textures. The first one consists in defining the *uvw* direction to align with a given axis (related to the sample coordinate system). For instance, let's consider the texture such that the <111> direction is aligned with the Z axis: >>> from elasticipy.crystal_texture import FibreTexture >>> from orix.crystal_map import Phase >>> from orix.vector.miller import Miller >>> >>> phase = Phase(point_group='m-3m') # Cubic symmetry >>> m = Miller(uvw=[1,1,1], phase=phase) >>> fibre_111 = FibreTexture.from_Miller_axis(m, [0,0,1]) >>> fibre_111 Fibre texture <1. 1. 1.> || [0, 0, 1] Actually, this texture is usually referred to as the γ fibre; therefore, a quicker way to define it is to use: >>> gamma = FibreTexture.gamma() This kind of shortcut also exists for alpha and epsilon textures (see `here `_) for details). The third way is to use two (out of the three) Bunge-Euler angles to define the fix angles (assuming that the orientations are uniformly distributed over the remaining angle). E.g.: >>> fibre_phi2 = FibreTexture.from_Euler(phi1=0., Phi=0.) >>> fibre_phi2 Fibre texture φ1= 0.0°, ϕ= 0.0° Then, the average stiffness resulting from such orientation distribution can be estimated from Voigt, Reuss or Hill method by integration over the all possible rotations. E.g.: >>> Chill = C.Hill_average(orientations=fibre_phi2) One can check that this results in a transversely isotropic behaviour by plotting the values of the Young modulus in planar sections. The full code is: .. plot:: >>> from elasticipy.tensors.elasticity import StiffnessTensor >>> from elasticipy.crystal_texture import FibreTexture >>> >>> C = StiffnessTensor.cubic(C11=186, C12=134, C44=77) >>> fibre_phi2 = FibreTexture.from_Euler(phi1=0., Phi=0.) >>> Chill = C.Hill_average(orientations=fibre_phi2) >>> E = Chill.Young_modulus >>> fig, ax = E.plot_xyz_sections() >>> fig.show() Composite textures ================== Different textures can be composed together to create a ``CompositeTexture`` object. For instance, if we consider a a cubic material which exhibits 40% of uniform texture, 30% of <111>||[0,0,1] and balanced copper texture, we can do the following: >>> from elasticipy.crystal_texture import UniformTexture >>> t = 0.4 * UniformTexture() + 0.3 * fibre_111 + 0.3 * DiscreteTexture.copper() >>> t Mixture of crystallographic textures Wgt. Type Component ------------------------------------------------------------ 0.40 uniform Uniform distribution over SO(3) 0.30 fibre <1. 1. 1.> || [0, 0, 1] 0.30 discrete φ1=90.00°, ϕ=35.26°, φ2=45.00° Again, the Hill average can be computed as follows: >>> C.Hill_average(orientations=t) Stiffness tensor (in Voigt mapping): [[ 2.29927005e+02 1.15004605e+02 1.09068390e+02 8.38850529e-16 1.68295444e-01 -1.42501837e-15] [ 1.15004605e+02 2.24466802e+02 1.14528593e+02 -2.58759922e-15 6.02903899e+00 9.94342227e-16] [ 1.09068390e+02 1.14528593e+02 2.30403016e+02 -2.87690846e-16 -6.19733443e+00 -2.35261749e-15] [ 9.65499494e-16 -2.35273493e-15 -1.02889997e-15 3.85692073e+01 -7.04774156e-17 5.34392791e+00] [ 1.68295444e-01 6.02903899e+00 -6.19733443e+00 -5.84888929e-16 3.50396705e+01 -8.30517047e-16] [ 5.75037319e-16 3.35378009e-15 -2.73847961e-16 5.34392791e+00 2.89814218e-16 3.85229349e+01]] Random sampling ~~~~~~~~~~~~~~ Sample of orientations can be drawn from all kind of textures. While a "random" sample from a single discrete texture does not make any sense, it can be of great interest for fibres or composite textures. For instance, a sample of 10 orientations can be drawn from the composite texture defined above as follows: >>> sample = t.sample(num=10, seed=123) # Seed here is used to ensure reproducibility >>> sample Orientation (10,) 1 [[ 0.1157 0.5901 0.2194 -0.7683] [ 0.3954 -0.6714 -0.421 0.4644] [ 0.9571 -0.1986 -0.2022 0.0609] [ 0.0802 -0.7012 0.3947 -0.5883] [ 0.1952 -0.8854 0.3814 0.1802] [-0.4814 0.4494 0.097 0.7463] [ 0.3647 -0.2798 -0.1159 -0.8805] [ 0.3647 -0.2798 -0.1159 -0.8805] [ 0.3647 -0.2798 -0.1159 -0.8805] [ 0.3647 -0.2798 -0.1159 -0.8805]] One may note that here, the 4 last orientations are the same. This is because it relates to the copper texture: >>> DiscreteTexture.copper().orientation Orientation (1,) 1 [[ 0.3647 -0.2798 -0.1159 -0.8805]] Plotting ~~~~~~~~ Pole figures can be drawn to evidence how each texture works. For instance, the (pure) Goss texture results in the following pole figure: .. plot:: >>> from elasticipy.crystal_texture import DiscreteTexture >>> from orix.crystal_map import Phase >>> from orix.vector.miller import Miller >>> >>> phase = Phase(point_group='m-3m') # Cubic symmetry >>> m = Miller(uvw=[1,0,0], phase=phase) >>> Goss = DiscreteTexture.Goss() >>> fig, ax = Goss.plot_as_pole_figure(m.symmetrise(unique=True)) >>> fig.show() Fibre textures can be drawn in a simular way. E.g.: .. plot:: >>> from elasticipy.crystal_texture import FibreTexture >>> from orix.crystal_map import Phase >>> from orix.vector.miller import Miller >>> >>> gamma = FibreTexture.gamma() >>> point_group = 'm3m' # BCC symmetry >>> m = Miller(uvw=[1,0,0], phase=Phase(point_group=point_group)) >>> fig, ax = gamma.plot_as_pole_figure(m.symmetrise(unique=True)) >>> fig.show()