Source code for plastic_slip

import numpy as np
import math

[docs] class dislocation_dipole: """ Class to calculate plastic slip due to a dislocation dipole. Attributes: dislocation_points (np.ndarray): Array of coordinates for dislocations (2D points). period (float): Periodicity of the system (typically along GB direction). burgers_vector (float): Magnitude of the Burgers vector. dislocation_vector (np.ndarray): Vector from first to second dislocation. dislocation_distance (float): Distance between the two dislocations. """
[docs] def __init__(self,dislocation_points, period, burgers_vector): """ Initialize a dislocation dipole object. Args: dislocation_points (np.ndarray): Coordinates of the dislocation pair (shape: 2x2). period (float): Periodicity of the system (along grain boundary direction). burgers_vector (float): Magnitude of the Burgers vector. """ self.dislocation_points = dislocation_points self.period = period self.burgers_vector = burgers_vector self.dislocation_vector = dislocation_points[0]-dislocation_points[1] self.dislocation_distance = np.linalg.norm(self.dislocation_vector)
def _local_position(self,disloc1,disloc2,x): """ Transform a point `x` into a local coordinate system based on a dislocation segment. Args: disloc1 (np.ndarray): Starting point of the dislocation segment. disloc2 (np.ndarray): Ending point of the dislocation segment. x (np.ndarray): Point to transform into local coordinates. Returns: tuple: - np.ndarray: Local coordinates [parallel, perpendicular] relative to the segment. - float: Half length of the dislocation segment. """ A2B = self.dislocation_vector normA2B = self.dislocation_distance t = A2B / normA2B n = np.array([-t[1], t[0]]) c = 0.5 * (disloc1 + disloc2) return np.array([np.dot(x - c, t), np.dot(x - c, n)]), 0.5 * normA2B
[docs] def plastic_displacement(self,x,nImages=2): """ Compute the plastic displacement at a point `x` due to a dislocation dipole. Args: x (np.ndarray): 2D point at which displacement is calculated. nImages (int, optional): Number of periodic image dipoles to consider. Defaults to 2. Returns: tuple: - float: Total angle of plastic distortion (radians). - float: Plastic displacement at the point `x`. """ angle = 0 disloc_points = self.dislocation_points b = self.burgers_vector period = self.period normA2B = self.dislocation_distance if abs(normA2B) < 1e-6: displacement = 0 else: for i in range(-nImages, nImages + 1, 1): for k in range(len(disloc_points) - 1): disloc1 = disloc_points[k] disloc2 = disloc_points[k + 1] xL, halfLength = self._local_position(disloc1,disloc2,x + i * period*100) if abs(xL[1]) < 1e-16: if abs(xL[0]) < halfLength: if xL[1] > 0: angle += 2.0 * np.pi elif xL[1] < 0: angle -= 2.0 * np.pi else: angle += 0.0 else: Yterm = abs(1.0 / xL[1]) angle += 2 * np.sign(xL[1]) * (-math.atan((xL[0] - halfLength) * Yterm) + math.atan((xL[0] + halfLength) * Yterm)) displacement = -(angle / (4.0 * np.pi)) * b return angle, displacement