Validation_codes/Twin_reorientation_check.ipynb

821 lines
82 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"id": "e2ae546c-570b-4245-99fa-60519f448e1e",
"metadata": {},
"source": [
"# Code to verify and visualize reorientation caused twinning in the deformation gradient.\n",
"## Using the correspondence matrix method.\n",
"By Satyapriya Gupta, Achal H P\n",
"\n",
"Reference Niewczas, Acta Materialia, 2010"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "8faa8558-2109-45ed-b795-94150b3c998d",
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"import numpy as np\n",
"import scipy.linalg\n",
"from numpy.linalg import inv\n",
"import damask"
]
},
{
"cell_type": "markdown",
"id": "bc185fbf-e55d-445e-b8aa-f17abdd93b9a",
"metadata": {},
"source": [
"### Test Case: Extension Twinning $( \\bar{1} 0 1 2) [1 0 \\bar{1} 1] $\n",
"\n",
"Conversion to Miller indices: $ (\\bar{1} 0 2) [2 1 1] $"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "fee7fbb5-3a4b-421c-bbe7-636c3fd412e9",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2.3743159014756228\n",
"1.6881920256873888\n",
"[0.63176092 0.36474734 0.68398649]\n",
"[-0.59234968 -0.34199325 0.72949468]\n"
]
}
],
"source": [
"# Twin direction:\n",
"m = np.array([2, 1, 1])\n",
"# Habit plane normal\n",
"n = np.array([-1, 0, 2])\n",
"# Mapping from Miller indes to cartesian coordinate system\n",
"matA=np.array([[1, -0.5, 0],[0, 0.5*np.sqrt(3), 0],[0, 0, 1.624]])\n",
"#norm of twin direction\n",
"norm_mcart=np.linalg.norm(np.matmul(matA,m))\n",
"# norm of twin plane\n",
"norm_ncart=np.linalg.norm(np.matmul(n,inv(matA)))\n",
"# normalized unit vectors:\n",
"unit_mcart = np.matmul(matA,m)/norm_mcart\n",
"unit_ncart = np.matmul(n, inv(matA))/norm_ncart\n",
"# Characteristic shear for Extension twin of Mg\n",
"s = 0.128917\n",
"print(norm_mcart)\n",
"print(norm_ncart)\n",
"print(unit_mcart)\n",
"print(unit_ncart)"
]
},
{
"cell_type": "markdown",
"id": "716495ad-76ca-4790-b1f4-a2f249e452db",
"metadata": {},
"source": [
"### Please provide Euler Angles Here:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "eaa69469-71ca-42fc-a4ed-afa0fb84a230",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[-0.9400045 -0.29372535 0.1735424 ]\n",
" [-0.17610919 -0.01790229 -0.98420783]\n",
" [ 0.2921936 -0.9557222 -0.0348995 ]]\n"
]
}
],
"source": [
"phi_1 = 17\n",
"phi_ = 92\n",
"phi_2 = 170\n",
"\n",
"init = (damask.Orientation.from_Euler_angles(\n",
" phi=[phi_1,phi_,phi_2],\n",
" degrees=True,\n",
" family='hexagonal',\n",
" lattice='hP',\n",
" a=1.0,b=1.0,c=1.6235).as_matrix())\n",
"print(init)\n"
]
},
{
"cell_type": "markdown",
"id": "1262386a-1d9c-4bb0-a147-c409f45ec751",
"metadata": {},
"source": [
"### Initial Undeformed Condition, $ F = Identity matrix $"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "689c6399-fd48-4456-be57-a8f7f7e16276",
"metadata": {},
"outputs": [],
"source": [
"F = np.identity(3)"
]
},
{
"cell_type": "markdown",
"id": "64b46853-7012-432f-93c1-4acb1fe4dc9a",
"metadata": {},
"source": [
"### If $F = I$, then inverse of $F$ gives $F_e$."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "3c3bfb00-2af0-4754-8d4e-89ee10d62519",
"metadata": {},
"outputs": [],
"source": [
"Fp=init\n",
"Fe=inv(Fp)\n",
"Rinv = inv(init)"
]
},
{
"cell_type": "markdown",
"id": "6786e80d-c9b2-41de-9fc1-40e8d3fc5acd",
"metadata": {},
"source": [
"### Shape change by twinning in the reference configuration:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "83c683bf-e3b8-4ec3-9e59-d0a25a55ca0e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"deformation gradient of shape change= \n",
" [[ 0.95095672 0.03054648 -0.01230733]\n",
" [-0.09052208 1.05638144 -0.02271637]\n",
" [-0.02924172 0.01821313 0.99266184]]\n"
]
}
],
"source": [
"S_ref= (s * np.einsum('i,j',np.matmul(Rinv,unit_mcart),np.matmul(Rinv,unit_ncart)) \n",
" + np.identity(3))\n",
"print(\"deformation gradient of shape change= \\n\", S_ref)"
]
},
{
"cell_type": "markdown",
"id": "eb708c6b-38ea-4f4a-ac59-91e31b55df95",
"metadata": {},
"source": [
"### After twinning, $ F_1 = Fe_1 * {F_p}_1 $ , where $ {F_p}_1 = C * {F_p}$"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "b1ad7d3a-fcf2-4116-9339-0451961ece5d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"with determinant of 1.000000166095149\n"
]
}
],
"source": [
"F1=S_ref\n",
"C=np.array([[-0.25,0.433013,-0.923645],[0.433013,-0.75,-0.533267],[-0.812, -0.468808, 0]])\n",
"Fe1=np.matmul(F1,inv(np.matmul(C,Fp)))\n",
"print (\"with determinant of \",np.linalg.det(Fe1))"
]
},
{
"cell_type": "markdown",
"id": "d21c31d5-72b1-43ed-91e4-2b194cd4eaaf",
"metadata": {},
"source": [
"### Right polar decomposition of $F_e$, $ F_e = R U $ gives the rotation of deformed voxel."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "9e5edf14-8645-4816-86ee-89d0fb02335e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[206.53799212 70.1926324 77.64540521]\n"
]
}
],
"source": [
"(R_,U_) = scipy.linalg.polar(Fe1,'right')\n",
"check = (damask.Orientation.from_matrix(R=R_,\n",
" family='hexagonal',lattice='hP',\n",
" a=1.0,b=1.0,c=1.6235)\n",
" .as_Euler_angles(degrees=True))\n",
"print(check)"
]
},
{
"cell_type": "markdown",
"id": "749c4997-c181-41c7-8359-f0fd37ee1a38",
"metadata": {},
"source": [
"### Get the orientation details"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "e6e8b162-7e0b-45dc-a37f-bee3071ce353",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[102.35459479 70.1926324 333.46200788]\n"
]
}
],
"source": [
"new_ori = (damask.Orientation.from_matrix(R=np.linalg.inv(R_),\n",
" family='hexagonal',\n",
" lattice='hP',a=1.0,b=1.0,c=1.6235))\n",
"(print(damask.Orientation.from_matrix(R=np.linalg.inv(R_),\n",
" family='hexagonal',lattice='hP',\n",
" a=1.0,b=1.0,c=1.6235).as_Euler_angles(degrees=True)))"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "80ac2638-3ebd-47c6-8e80-243a1c69fce1",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Crystal family: hexagonal\n",
"Bravais lattice: hP\n",
"a=1 m, b=1 m, c=1.6235 m\n",
"α=90°, β=90°, γ=120°\n",
"Quaternion [ 0.04240788 -0.16792654 0.69946438 -0.69336269]\n"
]
}
],
"source": [
"old_ori = (damask.Orientation.from_Euler_angles(phi=[phi_1,phi_,phi_2],\n",
" degrees=True,family='hexagonal',\n",
" lattice='hP',a=1.0,b=1.0,c=1.6235))\n",
"print(old_ori)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "cc1b231c-16e6-4d7d-bda2-8d0a4799839f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Crystal family: hexagonal\n",
"Bravais lattice: hP\n",
"a=1 m, b=1 m, c=1.6235 m\n",
"α=90°, β=90°, γ=120°\n",
"Quaternion [7.29494643e-01 6.83986524e-01 3.14974755e-08 1.07984812e-07]\n",
"[ 0. 86.31191012 0. ]\n"
]
}
],
"source": [
"dis = old_ori.disorientation(new_ori)\n",
"print(dis)\n",
"print(dis.as_Euler_angles(degrees=True))"
]
},
{
"cell_type": "markdown",
"id": "3efee0a1-5ebe-42bd-bb05-61721097458d",
"metadata": {},
"source": [
"## Result: Print the disorientation between undeformed and deformed voxel."
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "10b562ea-c067-4ec0-8b26-59dd8722305a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"disorientation = 86.31191011698508 degrees\n"
]
}
],
"source": [
"print('disorientation =',dis.as_axis_angle(degrees=True,pair=True)[1],'degrees')"
]
},
{
"cell_type": "markdown",
"id": "10bdf007-9926-4e38-9195-dd3fd349f634",
"metadata": {},
"source": [
"# Code to visualization of lattice reorientation caused by twinning.\n",
"\n",
"First cell below gives HCP unit cell with euler angles 0,0,0.\n",
"\n",
"Second cell below rotates unit cell by provided euler angles.\n",
"\n",
"Third cell below shows reorientation done after twinning."
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "37f8aa5b-a6df-45be-861f-46bdd218154a",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from mpl_toolkits.mplot3d import Axes3D\n",
"from math import cos, sin, radians\n",
"\n",
"# Define the line\n",
"x = np.linspace(0, 1.2, 100)\n",
"y = np.zeros_like(x)\n",
"z = np.zeros_like(x)\n",
"\n",
"x1 = np.zeros_like(x)\n",
"y1 = np.zeros_like(x)\n",
"z1 = np.linspace(0, 1.2, 100)\n",
"\n",
"x2 = np.zeros_like(x)\n",
"y2 = np.linspace(0, 1.2, 100)\n",
"z2 = np.zeros_like(x)\n",
"\n",
"h11 = np.linspace(1,0.5,100)\n",
"h12 = h11*np.sqrt(3) - np.sqrt(3)\n",
"h13 = np.zeros_like(h11)\n",
"\n",
"h21 = np.linspace(-0.5, 0.5, 100)\n",
"h22 = np.ones_like(h21) * np.sqrt(3) / 2\n",
"h23 = np.zeros_like(h21)\n",
"\n",
"h31 = np.linspace(-0.5, 0.5, 100)\n",
"h32 = - np.ones_like(h31) * np.sqrt(3) / 2\n",
"h33 = np.zeros_like(h31)\n",
"\n",
"h41 = np.linspace(1,0.5,100)\n",
"h42 = - h41*np.sqrt(3) + np.sqrt(3)\n",
"h43 = np.zeros_like(h41)\n",
"\n",
"h51 = np.linspace(-1,-0.5,100)\n",
"h52 = - h51*np.sqrt(3) - np.sqrt(3)\n",
"h53 = np.zeros_like(h51)\n",
"\n",
"h61 = np.linspace(-1,-0.5,100)\n",
"h62 = h61*np.sqrt(3) + np.sqrt(3)\n",
"h63 = np.zeros_like(h61)\n",
"\n",
"k11 = np.linspace(1,0.5,100)\n",
"k12 = k11*np.sqrt(3) - np.sqrt(3)\n",
"k13 = np.ones_like(k11)\n",
"\n",
"k21 = np.linspace(-0.5, 0.5, 100)\n",
"k22 = np.ones_like(k21) * np.sqrt(3) / 2\n",
"k23 = np.ones_like(k21)\n",
"\n",
"k31 = np.linspace(-0.5, 0.5, 100)\n",
"k32 = - np.ones_like(k31) * np.sqrt(3) / 2\n",
"k33 = np.ones_like(k31)\n",
"\n",
"k41 = np.linspace(1,0.5,100)\n",
"k42 = - k41*np.sqrt(3) + np.sqrt(3)\n",
"k43 = np.ones_like(k41)\n",
"\n",
"k51 = np.linspace(-1,-0.5,100)\n",
"k52 = - k51*np.sqrt(3) - np.sqrt(3)\n",
"k53 = np.ones_like(k51)\n",
"\n",
"k61 = np.linspace(-1,-0.5,100)\n",
"k62 = k61*np.sqrt(3) + np.sqrt(3)\n",
"k63 = np.ones_like(k61)\n",
"\n",
"\n",
"\n",
"v11 = np.ones_like(x) * 0.5\n",
"v12 = np.ones_like(x) * np.sqrt(3) / 2\n",
"v13 = np.linspace(0, 1, 100)\n",
"\n",
"v21 = - np.ones_like(x) * 0.5\n",
"v22 = np.ones_like(x) * np.sqrt(3) / 2\n",
"v23 = np.linspace(0, 1, 100)\n",
"\n",
"v31 = - np.ones_like(x) * 0.5\n",
"v32 = - np.ones_like(x) * np.sqrt(3) / 2\n",
"v33 = np.linspace(0, 1, 100)\n",
"\n",
"v41 = np.ones_like(x) * 0.5\n",
"v42 = - np.ones_like(x) * np.sqrt(3) / 2\n",
"v43 = np.linspace(0, 1, 100)\n",
"\n",
"v51 = - np.ones_like(x)\n",
"v52 = np.zeros_like(x)\n",
"v53 = np.linspace(0, 1, 100)\n",
"\n",
"v61 = np.ones_like(x)\n",
"v62 = np.zeros_like(x)\n",
"v63 = np.linspace(0, 1, 100)\n",
"\n",
"# Plot the line\n",
"fig = plt.figure()\n",
"ax = fig.add_subplot(111, projection='3d')\n",
"ax.plot(x, y, z)\n",
"ax.plot(x1, y1, z1)\n",
"#ax.plot(x2, y2, z2)\n",
"ax.plot(h11, h12, h13, 'k-')\n",
"ax.plot(h21, h22, h23, 'k-')\n",
"ax.plot(h31, h32, h33, 'k-')\n",
"ax.plot(h41, h42, h43, 'k-')\n",
"ax.plot(h51, h52, h53, 'k-')\n",
"ax.plot(h61, h62, h63, 'k-')\n",
"ax.plot(k11, k12, k13, 'k-')\n",
"ax.plot(k21, k22, k23, 'k-')\n",
"ax.plot(k31, k32, k33, 'k-')\n",
"ax.plot(k41, k42, k43, 'k-')\n",
"ax.plot(k51, k52, k53, 'k-')\n",
"ax.plot(k61, k62, k63, 'k-')\n",
"ax.plot(v11, v12, v13, 'k-')\n",
"ax.plot(v21, v22, v23, 'k-')\n",
"ax.plot(v31, v32, v33, 'k-')\n",
"ax.plot(v41, v42, v43, 'k-')\n",
"ax.plot(v51, v52, v53, 'k-')\n",
"ax.plot(v61, v62, v63, 'k-')\n",
"\n",
"ax.set_xticks([])\n",
"ax.set_yticks([])\n",
"ax.set_zticks([])\n",
"\n",
"ax.set_xlabel('')\n",
"ax.set_ylabel('')\n",
"ax.set_zlabel('')\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "a523f432-ce0a-4506-9d83-bd469e1c9ba3",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAOcAAADnCAYAAADl9EEgAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAA460lEQVR4nO2deXyM9/bH3zPZYwliKbHXUuVqEWRBBLFGElprbVftQkpoSmlttSu9dhprWzQJgiAShCyWJLS32lrurZYSbSxpySKZmef3h9/MnURCJnlm5pl43q/XvETyLCeT5zPnfM/3e85XIQgCMjIy0kNpbgNkZGQKRxanjIxEkcUpIyNRZHHKyEgUWZwyMhLF+iU/l1O5MjLGR1HYN2XPKSMjUWRxyshIFFmcMjISRRanjIxEkcUpIyNRZHHKyEgUWZwyMhJFFqeMjESRxSkjI1FkccrISBRZnDIyEkUWp4yMRJHFKSMjUWRxyshIFFmcMjISRRanGRAEAbVajdz5UOZFvKzYWkZkBEEgNzeXnJwcBEHAysoKGxsbrK2tsbKyQqEotO5W5hVE8ZJPb/mjXUQ0Gg25ubkIgoBKpUIQBN1LiyzWV5JC/8iyOE2AVowqlUontry8vEKPEwQBjUajO04W6yuBLE5zoNFoyMvL0wlOoVDoQtuXCa0wsVpbW+tesljLDIX+EeUxp5HQJn20HlIrTEPQnqNUKp+7pr5YtZ5VqVTKYi1DyOI0AgXDWLEEU5RYVSqV7uf6YbAsVstGFqfIFBbGFoUgCKUST8HrFyZW/TBYFqtlIY85RaJgyPkyEWiztsYUS8FssCxWySInhIyFIAjk5eWhVquLHcaaQpwF0SaXtGjFamNjg5WVlSxW8yGL0xjoz10aMr40hzgLUphY9adtZLGaDFmcYlLapI8UxFkQrVj1P2i0YrW2thY1uSWTD1mcYqGdpyxO0qcopCjOghQlVm0YLItVNGRxioFKpSrV3KUWSxCnPtrnRD8MViqVz41ZZUqELM7SIPbcpaWJsyCyWEVFFmdJMWTusrhYujgLIou1VMjiNJSCS/DEfLjKmjgLUljFjVKpfC4bLAPI4jSMksxdGkJZF2dBXlQeZ2VlpcsGv6LI4iwuJZ27NIRXTZwFkWtZ8yGL82UYa8F6YeiPYWVeebHK4nwRYsxdGoIszhfziolVFmdRaJM+xgxjCyKL0zDKeJcIWZwFMWUYWxBZnKWjjIlVFqc+xpi7NARZnOJSVEsXbTZY4mKV25SAOO1DZKTHy7pEgOW1dHmlxGnsuUsZ6VAWukS8MuI0xdyljHQpTKwFixikJtYyP+Y0tH2IqZDHnNLCzC1dXr2EkKnnLg1BFqe0MXGXiFdLnFIPY2VxWhYvEqsIXSJeDXGac+7SEFQqlS4xJWN56HeJgP9V3JSwS0ShB5apmh1tGCt1YcpYPtoG3vqeMzc3l8zMTP7++28+++wzfvvtt1Ldo0yIU+stc3JyJDm+LIo1a9ZQr1491q9fz4ULF/jrr7/MbZJMCdGKVTsevXDhAmq1ulTXtPipFEsJY/XRaDSsX7+e+fPno9FomDVrlu5ntWrVomnTprzxxhs0a9ZM93XlypXNaLGMISgUCjIzMylfvnyprmPR4jT3ErySkJaWxpgxYzh58iQ9e/Zk0qRJzJs3j0uXLuHi4kLz5s1JT09n586dZGVl6c6rUaMGb7zxBk2bNqVZs2a88cYbvPHGGzg7O5vxt5EpiszMTCpUqFCqa1hkQkiqc5cvIzIykkmTJpGVlcWSJUsYOXIkVlZWCILAvn37mDNnDunp6YwePZo5c+bw5MkTfv75Z65du8bVq1e5evUq165d48mTJ7prVq1aNZ9otf9Wq1bNYt6XskjHjh1JTU3FysqqOIeXjWytJS7Be/LkCTNnzmT79u20atWKHTt28Prrr6NSqfL10fnrr79YvHgxW7ZswcnJifnz5zN8+PB8xwiCwJ07dwoVrf6YtXLlyjrvqu9tX3vtNYt4zyydjh07cvny5eK+15YvTqnPXRZGSkoKo0aN4r///S/BwcF88skn2Nra6sbJhTW5+vHHHwkODiYpKYk2bdqwatUqWrdu/cL7CIJAWlpaPrFqv3706JHuOCcnJ904Vv/l4uJiEe+nJSAIAp06dXo1xGmJSR+1Ws2KFStYtGgRr732GqGhoXh5eel+/iJxAoWGunPnzqVKlSoG2SEIAn/++adOqFrh/vzzzzx48EB3XIUKFfKJVvt1nTp15C55BiIIAl5eXly+fLm4p1imOKW8BK8ofv31V0aPHk1SUhIDBgxg7dq1VKpUKd8xLxOnFm2ou3nzZipVqlRoqFtS7t+/n0+02teff/6pO8bR0ZGmTZs+l0GuV69eccdTrxxqtZouXbpw6dKl4p5ieeIUa+sDUyEIAnv37iUoKAh4No85dOjQQo8trji1XLlyheDgYM6dO4erqyurVq2iVatWotmuz8OHD/OFxdpXWlqa7hh7e3ucnZ158OAB3377LZ07dzaKLZbI48ePGThwIAkJCcU9xXLEaYlhbEZGBlOmTCEsLAx3d3e2bdtGgwYNijxem202xANqxT937txShbolJSMjg2vXrumEu3//fu7evYuNjQ1TpkwhODi41NMHZYF79+4RGBhIdHR0cU+xjOV72qSPJQkzPj4eV1dX9u/fz6effkpsbOwLhVlSFAoFQ4YMITU1lQkTJrBjxw7atGnDrl278i3KNhaVKlWiffv2jBgxgsWLFzNv3jwAunfvzueff06bNm345ptvTGKLlBFjAQJISJxab/n06VM0Go0kil1fRm5uLnPnzqV79+7Y2dkRFxfHrFmzjD4Wc3JyYtmyZcTHx9OkSRMCAwPp1q2bIQkIUXBwcABg9uzZxMbG4uLiwoQJE+jWrRvJyckmtUVKPHnyhHLlypX6OpIQp3buUruowBKyg9evX6dz586sWLGCkSNHcuHCBdq2bWtSG1q0aMHx48fZvHkzt27donPnzkybNo2HDx+a5P729vYA5OTk0K5dO06ePMnGjRu5ffs2Xbt2Zfz48dy7d88ktkiJzMzMsiFOjUbD06dPLWZRgSAIfPnll7i5ufHrr7+yd+9eNm3aJEoYUxL0Q93x48ezfft2k4W6jo6OAGRnZwPPyqbee+89Ll26xLRp04iIiKB169Z8/vnnPH361Ki2SAmLD2u13lL7R7OEMDY9PZ0BAwYQGBiIm5sbKSkpBAQEmNss4Fmou3z5chISEkwW6mo9p1acWipUqMD8+fO5ePEiXl5ezJs3j7Zt2xIVFcVLEpBlAosWpyXWXZ44cQJXV1dOnDjB8uXLOXLkCLVq1TK3Wc+hDXU3bdpk9FBXO+bMyckp9OcNGzZkz549HDx4EHt7e4YMGUJAQAA///yz6LZICYsNa9VqtS7pYwnCzM7OJjg4GD8/P5ydnUlMTGTq1KmSHhcrFAqGDh2qy+pu376d1q1bix7qFuU5C9KlSxcSExNZvnw5ly9fxsPDg5kzZ5psbGxqnjx5YlmeUxvG5ubmPruxBYSxP/zwA56enqxfv57JkyeTmJjIP/7xD3ObVWy0Wd2EhASaNm0qeqj7Ms+pj42NDRMmTODy5cuMGjWKrVu30rp1a7Zu3Zqv8XNZICsrS5T5XpOI09LmLjUaDV988QWenp48fPiQQ4cOsWrVKt3DaGkYK9QtrufUx9nZmdWrV5OQkEDz5s0JDg6mY8eOxMfHl8oWKWERYW3BuUtLEOadO3fw9fUlJCSE7t27k5ycTPfu3UW/j6nfB/1QVz+ru3v37hKHuoZ4zoK0aNGCI0eOsHv3bh4/fkyfPn0YPnx4qfvuSAHJJ4QKm7uUujAPHjxI27ZtOX/+POvWrSMsLIxq1aqZ2yxR0c/qNm7cmMmTJ+Pj48N3331n8LW0nlO/Y4MhKBQK/P39SU5OZs6cOcTExODq6sqCBQvIzMws0TWlgKTFaWlzl48fP2b8+PEMHjyYBg0acP78ecaMGSN5u0tDixYtiI6OZtOmTfz66694eXkZHOoqlUrs7OxK5Dn1cXBw4MMPPyQ1NRU/Pz9WrlxJmzZt2Ldvn0VOvUgyrNUPY8Eykj4XL16kffv27Nq1i5kzZxIXF0eTJk3MbZZJECPUdXBwMGjM+SJcXFwIDQ0lJiaGGjVqMHbsWLp3725I6ZUkEKN/EIgoTu3cpaX09VGpVCxevBhvb2/y8vKIjo5m4cKF2NjYmNs0k1OpUiWWL19OfHy8waGug4NDqT1nQdq3b8/p06dZv349v/zyC97e3kyePJk//vhD1PsYC8mFtVoxWoIwb968iY+PDwsWLODdd98lOTmZTp06mdsss/OPf/yD6OhoNm7cqAt1p0+fnq/NSUHs7e1F85z6KJVKhg8fzuXLl5kyZQp79+6ldevWfPHFF7rpOKmSlZUlLXGC9MNYQRD46quvaNeuHT/++CM7duxg586dz3UpeJVRKBS89957pKamMm7cOLZt20bLli114aV+5z8wjufUp2LFiixatIjz58/j4eHB3LlzadeuHceOHZPseDQ3Nxc7O7tSX0fUYmttD1kp8ujRI6ZOnUpYWBgeHh5s376devXqmc0e7dyvlFcaAezatYugoKB83ctdXFxo3LgxjRo1Ijo6mqpVq/LVV1/h4uJi9N8nJiaGWbNmcf36dbp27crSpUtp2rSpUe9pKAZ23gNTdEKQqjjPnDnD+++/z71795g7dy4zZswwe/8bqYszLy+PJUuWsGrVKurXr8+oUaNo2LAh169f58aNG7rX33//rTvHwcGBRo0a0bhxYxo3bkyTJk10IhazaicvL4/NmzezbNkyMjMzGTduHB999JEkIiBtc69Lly5JS5zanbOkQm5uLgsWLGDVqlW8/vrr7NixA1dXV3ObBfyvW70UhwE3b97k/fffJyUlheHDh7Ns2bJCxSUIAr6+vvzxxx9MmjQpn3Bv3bqV74Na39tqRdukSZNSedv79++zcOFCduzYQZUqVfjkk08YMWKEWT94S9B5D141cV67do1Ro0Zx+fJlRo8ezfLly81Wc1kYUhXnvn37mD59Okqlki+++IL+/fu/8PihQ4fyyy+/cP78+Xzfz8nJ4ZdffuHGjRs60V6/fp3//Oc/onvb77//npCQEJKSkmjZsiXLli3D09PT8F9eBFQqFd26dSM1NdWQ0wp9CCx6r5TC0BZDf/jhhzg6OvLtt9/i5+dnbrMkz99//82MGTPYu3cvbm5ufPnll9StW/el5xU1z2lvb8+bb77Jm2++me/72j66+l72+vXrXLp0iYMHDxbqbfVfhXnbt956i2PHjrF//37mzp1Lr1696N+/PwsWLCjW7yAmYi1AgDImzj///JOJEycSFRVFt27d2LJliyRrLqVGcnIy77//Prdu3WLWrFnMnDkTa+viPRqGZmsVCgU1atSgRo0adOzYMd/PivK2+/btK5a37dGjB7169eKLL75gzZo1HD16lKCgIKZNm6br2mBsJCtOc4Zo0dHRjBs3joyMDFauXMmkSZMkm2zRot1Wwlyo1WrWrFnDokWLcHFx4fjx47i5uRl0DTHnOYvrbbX/FuVtmzRpQkBAAD/99BPLli1j586dfPbZZ7z77rtGf78lK05zkJ6ezuLFi9m4cSMtWrQgKiqKFi1amNusYmFOYd65c4dx48YRHx9P//79WbNmTYmyncae54TieduCYXJqaqrO2967d4/333+fcePGkZaWpluwbwzEKrQGCxfnH3/8oZurHD9+PMuWLTPqGy8m5hTmkSNHmDx5Mrm5uWzYsIH33nuvxPbY29vrdhQ3R6RSHG977do1li9fzv37943+fIjVFhNEXiFk6geuUqVKurWwUVFR0i7YzTV/CVRWVhbTpk1j6NCh1K9fn/j4eIYNG1aqv1tpajqNidbbduzYkTFjxtCnTx+TzIOKtXQPJNAaszTY2dnRrFkzPDw8KFeuHH379mXSpEn5kgeSIC8bm+3dsD4+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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Define the rotation angles (in radians)\n",
"alpha = radians(phi_1) # Rotation around the x-axis\n",
"beta = radians(phi_) # Rotation around the y-axis\n",
"gamma = radians(phi_2) # Rotation around the z-axis\n",
"\n",
"# Create the rotation matrices\n",
"Rx = np.array([[1, 0, 0],\n",
" [0, cos(alpha), -sin(alpha)],\n",
" [0, sin(alpha), cos(alpha)]])\n",
"\n",
"Ry = np.array([[cos(beta), 0, sin(beta)],\n",
" [0, 1, 0],\n",
" [-sin(beta), 0, cos(beta)]])\n",
"\n",
"Rz = np.array([[cos(gamma), -sin(gamma), 0],\n",
" [sin(gamma), cos(gamma), 0],\n",
" [0, 0, 1]])\n",
"\n",
"# Combine the rotation matrices\n",
"R = Rz @ Ry @ Rx\n",
"\n",
"# Apply the rotation to the line\n",
"point1 = np.column_stack((x, y, z))\n",
"point2 = np.column_stack((x1, y1, z1))\n",
"point3 = np.column_stack((h11,h12,h13))\n",
"point4 = np.column_stack((h21, h22, h23))\n",
"point5 = np.column_stack((h31, h32, h33))\n",
"point6 = np.column_stack((h41, h42, h43))\n",
"point7 = np.column_stack((h51, h52, h53))\n",
"point8 = np.column_stack((h61, h62, h63))\n",
"point9 = np.column_stack((k11, k12, k13))\n",
"point10 = np.column_stack((k21, k22, k23))\n",
"point11 = np.column_stack((k31, k32, k33))\n",
"point12 = np.column_stack((k41, k42, k43))\n",
"point13 = np.column_stack((k51, k52, k53))\n",
"point14 = np.column_stack((k61, k62, k63))\n",
"point15 = np.column_stack((v11, v12, v13))\n",
"point16 = np.column_stack((v21, v22, v23))\n",
"point17 = np.column_stack((v31, v32, v33))\n",
"point18 = np.column_stack((v41, v42, v43))\n",
"point19 = np.column_stack((v51, v52, v53))\n",
"point20 = np.column_stack((v61, v62, v63))\n",
"point21 = np.column_stack((x2, y2, z2))\n",
"\n",
"rotated_point1 = np.dot(R, point1.T).T\n",
"rotated_point2 = np.dot(R, point2.T).T\n",
"rotated_point3 = np.dot(R, point3.T).T\n",
"rotated_point4 = np.dot(R, point4.T).T\n",
"rotated_point5 = np.dot(R, point5.T).T\n",
"rotated_point6 = np.dot(R, point6.T).T\n",
"rotated_point7 = np.dot(R, point7.T).T\n",
"rotated_point8 = np.dot(R, point8.T).T\n",
"rotated_point9 = np.dot(R, point9.T).T\n",
"rotated_point10 = np.dot(R, point10.T).T\n",
"rotated_point11 = np.dot(R, point11.T).T\n",
"rotated_point12 = np.dot(R, point12.T).T\n",
"rotated_point13 = np.dot(R, point13.T).T\n",
"rotated_point14 = np.dot(R, point14.T).T\n",
"rotated_point15 = np.dot(R, point15.T).T\n",
"rotated_point16 = np.dot(R, point16.T).T\n",
"rotated_point17 = np.dot(R, point17.T).T\n",
"rotated_point18 = np.dot(R, point18.T).T\n",
"rotated_point19 = np.dot(R, point19.T).T\n",
"rotated_point20 = np.dot(R, point20.T).T\n",
"rotated_point21 = np.dot(R, point21.T).T\n",
"\n",
"# Extract the rotated coordinates\n",
"x_rotated1, y_rotated1, z_rotated1 = rotated_point1.T\n",
"x_rotated2, y_rotated2, z_rotated2 = rotated_point2.T\n",
"x_rotated3, y_rotated3, z_rotated3 = rotated_point3.T\n",
"x_rotated4, y_rotated4, z_rotated4 = rotated_point4.T\n",
"x_rotated5, y_rotated5, z_rotated5 = rotated_point5.T\n",
"x_rotated6, y_rotated6, z_rotated6 = rotated_point6.T\n",
"x_rotated7, y_rotated7, z_rotated7 = rotated_point7.T\n",
"x_rotated8, y_rotated8, z_rotated8 = rotated_point8.T\n",
"x_rotated9, y_rotated9, z_rotated9 = rotated_point9.T\n",
"x_rotated10, y_rotated10, z_rotated10 = rotated_point10.T\n",
"x_rotated11, y_rotated11, z_rotated11 = rotated_point11.T\n",
"x_rotated12, y_rotated12, z_rotated12 = rotated_point12.T\n",
"x_rotated13, y_rotated13, z_rotated13 = rotated_point13.T\n",
"x_rotated14, y_rotated14, z_rotated14 = rotated_point14.T\n",
"x_rotated15, y_rotated15, z_rotated15 = rotated_point15.T\n",
"x_rotated16, y_rotated16, z_rotated16 = rotated_point16.T\n",
"x_rotated17, y_rotated17, z_rotated17 = rotated_point17.T\n",
"x_rotated18, y_rotated18, z_rotated18 = rotated_point18.T\n",
"x_rotated19, y_rotated19, z_rotated19 = rotated_point19.T\n",
"x_rotated20, y_rotated20, z_rotated20 = rotated_point20.T\n",
"x_rotated21, y_rotated21, z_rotated21 = rotated_point21.T\n",
"\n",
"\n",
"# Plot the line\n",
"fig = plt.figure()\n",
"ax = fig.add_subplot(projection='3d')\n",
"ax.plot(x_rotated1, y_rotated1, z_rotated1)\n",
"ax.plot(x_rotated2, y_rotated2, z_rotated2)\n",
"#ax.plot(x_rotated21, y_rotated21, z_rotated21)\n",
"ax.plot(x_rotated3, y_rotated3, z_rotated3, 'k-')\n",
"ax.plot(x_rotated4, y_rotated4, z_rotated4, 'k-')\n",
"ax.plot(x_rotated5, y_rotated5, z_rotated5, 'k-')\n",
"ax.plot(x_rotated6, y_rotated6, z_rotated6, 'k-')\n",
"ax.plot(x_rotated7, y_rotated7, z_rotated7, 'k-')\n",
"ax.plot(x_rotated8, y_rotated8, z_rotated8, 'k-')\n",
"ax.plot(x_rotated9, y_rotated9, z_rotated9, 'k-')\n",
"ax.plot(x_rotated10, y_rotated10, z_rotated10, 'k-')\n",
"ax.plot(x_rotated11, y_rotated11, z_rotated11, 'k-')\n",
"ax.plot(x_rotated12, y_rotated12, z_rotated12, 'k-')\n",
"ax.plot(x_rotated13, y_rotated13, z_rotated13, 'k-')\n",
"ax.plot(x_rotated14, y_rotated14, z_rotated14, 'k-')\n",
"ax.plot(x_rotated15, y_rotated15, z_rotated15, 'k-')\n",
"ax.plot(x_rotated16, y_rotated16, z_rotated16, 'k-')\n",
"ax.plot(x_rotated17, y_rotated17, z_rotated17, 'k-')\n",
"ax.plot(x_rotated18, y_rotated18, z_rotated18, 'k-')\n",
"ax.plot(x_rotated19, y_rotated19, z_rotated19, 'k-')\n",
"ax.plot(x_rotated20, y_rotated20, z_rotated20, 'k-')\n",
"\n",
"ax.set_xticks([])\n",
"ax.set_yticks([])\n",
"ax.set_zticks([])\n",
"\n",
"ax.set_xlabel('')\n",
"ax.set_ylabel('')\n",
"ax.set_zlabel('')\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "0f461c1e-f9db-4880-8ed3-2a4c841b2251",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Define the rotation angles (in radians)\n",
"alpha = damask.Orientation.from_matrix(R=np.linalg.inv(R_),family='hexagonal',lattice='hP',a=1.0,b=1.0,c=1.6235).as_Euler_angles(degrees=False)[0] \n",
"beta = damask.Orientation.from_matrix(R=np.linalg.inv(R_),family='hexagonal',lattice='hP',a=1.0,b=1.0,c=1.6235).as_Euler_angles(degrees=False)[1] \n",
"gamma = damask.Orientation.from_matrix(R=np.linalg.inv(R_),family='hexagonal',lattice='hP',a=1.0,b=1.0,c=1.6235).as_Euler_angles(degrees=False)[2] \n",
"\n",
"# Create the rotation matrices\n",
"Rx = np.array([[1, 0, 0],\n",
" [0, cos(alpha), -sin(alpha)],\n",
" [0, sin(alpha), cos(alpha)]])\n",
"\n",
"Ry = np.array([[cos(beta), 0, sin(beta)],\n",
" [0, 1, 0],\n",
" [-sin(beta), 0, cos(beta)]])\n",
"\n",
"Rz = np.array([[cos(gamma), -sin(gamma), 0],\n",
" [sin(gamma), cos(gamma), 0],\n",
" [0, 0, 1]])\n",
"\n",
"# Combine the rotation matrices\n",
"R = Rz @ Ry @ Rx\n",
"\n",
"# Apply the rotation to the line\n",
"point21 = np.column_stack((x_rotated1, y_rotated1, z_rotated1))\n",
"point22 = np.column_stack((x_rotated2, y_rotated2, z_rotated2))\n",
"point23 = np.column_stack((x_rotated3, y_rotated3, z_rotated3))\n",
"point24 = np.column_stack((x_rotated4, y_rotated4, z_rotated4))\n",
"point25 = np.column_stack((x_rotated5, y_rotated5, z_rotated5))\n",
"point26 = np.column_stack((x_rotated6, y_rotated6, z_rotated6))\n",
"point27 = np.column_stack((x_rotated7, y_rotated7, z_rotated7))\n",
"point28 = np.column_stack((x_rotated8, y_rotated8, z_rotated8))\n",
"point29 = np.column_stack((x_rotated9, y_rotated9, z_rotated9))\n",
"point30 = np.column_stack((x_rotated10, y_rotated10, z_rotated10))\n",
"point31 = np.column_stack((x_rotated11, y_rotated11, z_rotated11))\n",
"point32 = np.column_stack((x_rotated12, y_rotated12, z_rotated12))\n",
"point33 = np.column_stack((x_rotated13, y_rotated13, z_rotated13))\n",
"point34 = np.column_stack((x_rotated14, y_rotated14, z_rotated14))\n",
"point35 = np.column_stack((x_rotated15, y_rotated15, z_rotated15))\n",
"point36 = np.column_stack((x_rotated16, y_rotated16, z_rotated16))\n",
"point37 = np.column_stack((x_rotated17, y_rotated17, z_rotated17))\n",
"point38 = np.column_stack((x_rotated18, y_rotated18, z_rotated18))\n",
"point39 = np.column_stack((x_rotated19, y_rotated19, z_rotated19))\n",
"point40 = np.column_stack((x_rotated20, y_rotated20, z_rotated20))\n",
"point41 = np.column_stack((x_rotated21, y_rotated21, z_rotated21))\n",
"\n",
"rotated_point21 = np.dot(R, point21.T).T\n",
"rotated_point22 = np.dot(R, point22.T).T\n",
"rotated_point23 = np.dot(R, point23.T).T\n",
"rotated_point24 = np.dot(R, point24.T).T\n",
"rotated_point25 = np.dot(R, point25.T).T\n",
"rotated_point26 = np.dot(R, point26.T).T\n",
"rotated_point27 = np.dot(R, point27.T).T\n",
"rotated_point28 = np.dot(R, point28.T).T\n",
"rotated_point29 = np.dot(R, point29.T).T\n",
"rotated_point30 = np.dot(R, point30.T).T\n",
"rotated_point31 = np.dot(R, point31.T).T\n",
"rotated_point32 = np.dot(R, point32.T).T\n",
"rotated_point33 = np.dot(R, point33.T).T\n",
"rotated_point34 = np.dot(R, point34.T).T\n",
"rotated_point35 = np.dot(R, point35.T).T\n",
"rotated_point36 = np.dot(R, point36.T).T\n",
"rotated_point37 = np.dot(R, point37.T).T\n",
"rotated_point38 = np.dot(R, point38.T).T\n",
"rotated_point39 = np.dot(R, point39.T).T\n",
"rotated_point40 = np.dot(R, point40.T).T\n",
"rotated_point41 = np.dot(R, point41.T).T\n",
"\n",
"# Extract the rotated coordinates\n",
"x_rotated21, y_rotated21, z_rotated21 = rotated_point21.T\n",
"x_rotated22, y_rotated22, z_rotated22 = rotated_point22.T\n",
"x_rotated23, y_rotated23, z_rotated23 = rotated_point23.T\n",
"x_rotated24, y_rotated24, z_rotated24 = rotated_point24.T\n",
"x_rotated25, y_rotated25, z_rotated25 = rotated_point25.T\n",
"x_rotated26, y_rotated26, z_rotated26 = rotated_point26.T\n",
"x_rotated27, y_rotated27, z_rotated27 = rotated_point27.T\n",
"x_rotated28, y_rotated28, z_rotated28 = rotated_point28.T\n",
"x_rotated29, y_rotated29, z_rotated29 = rotated_point29.T\n",
"x_rotated30, y_rotated30, z_rotated30 = rotated_point30.T\n",
"x_rotated31, y_rotated31, z_rotated31 = rotated_point31.T\n",
"x_rotated32, y_rotated32, z_rotated32 = rotated_point32.T\n",
"x_rotated33, y_rotated33, z_rotated33 = rotated_point33.T\n",
"x_rotated34, y_rotated34, z_rotated34 = rotated_point34.T\n",
"x_rotated35, y_rotated35, z_rotated35 = rotated_point35.T\n",
"x_rotated36, y_rotated36, z_rotated36 = rotated_point36.T\n",
"x_rotated37, y_rotated37, z_rotated37 = rotated_point37.T\n",
"x_rotated38, y_rotated38, z_rotated38 = rotated_point38.T\n",
"x_rotated39, y_rotated39, z_rotated39 = rotated_point39.T\n",
"x_rotated40, y_rotated40, z_rotated40 = rotated_point40.T\n",
"x_rotated41, y_rotated41, z_rotated41 = rotated_point41.T\n",
"\n",
"\n",
"# Plot the line\n",
"fig = plt.figure()\n",
"ax = fig.add_subplot(111, projection='3d')\n",
"ax.plot(x_rotated21, y_rotated21, z_rotated21)\n",
"ax.plot(x_rotated22, y_rotated22, z_rotated22)\n",
"ax.plot(x_rotated23, y_rotated23, z_rotated23, 'k-')\n",
"ax.plot(x_rotated24, y_rotated24, z_rotated24, 'k-')\n",
"ax.plot(x_rotated25, y_rotated25, z_rotated25, 'k-')\n",
"ax.plot(x_rotated26, y_rotated26, z_rotated26, 'k-')\n",
"ax.plot(x_rotated27, y_rotated27, z_rotated27, 'k-')\n",
"ax.plot(x_rotated28, y_rotated28, z_rotated28, 'k-')\n",
"ax.plot(x_rotated29, y_rotated29, z_rotated29, 'k-')\n",
"ax.plot(x_rotated30, y_rotated30, z_rotated30, 'k-')\n",
"ax.plot(x_rotated31, y_rotated31, z_rotated31, 'k-')\n",
"ax.plot(x_rotated32, y_rotated32, z_rotated32, 'k-')\n",
"ax.plot(x_rotated33, y_rotated33, z_rotated33, 'k-')\n",
"ax.plot(x_rotated34, y_rotated34, z_rotated34, 'k-')\n",
"ax.plot(x_rotated35, y_rotated35, z_rotated35, 'k-')\n",
"ax.plot(x_rotated36, y_rotated36, z_rotated36, 'k-')\n",
"ax.plot(x_rotated37, y_rotated37, z_rotated37, 'k-')\n",
"ax.plot(x_rotated38, y_rotated38, z_rotated38, 'k-')\n",
"ax.plot(x_rotated39, y_rotated39, z_rotated39, 'k-')\n",
"ax.plot(x_rotated40, y_rotated40, z_rotated40, 'k-')\n",
"ax.plot(x_rotated40, y_rotated40, z_rotated40, 'k-')\n",
"#ax.plot(x_rotated41, y_rotated41, z_rotated41)\n",
"\n",
"ax.set_xticks([])\n",
"ax.set_yticks([])\n",
"ax.set_zticks([])\n",
"\n",
"ax.set_xlabel('')\n",
"ax.set_ylabel('')\n",
"ax.set_zlabel('')\n",
"plt.show()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}