def strain_energy(): C_al3Mg = np.array([[0.64, 0.24, 0.24, 0, 0, 0], [0.24, 0.64, 0.24, 0, 0, 0], [0.24, 0.24, 0.64, 0, 0, 0], [0, 0, 0, 0.65, 0, 0], [0, 0, 0, 0, 0.65, 0], [0, 0, 0, 0, 0, 0.65]]) C_al = np.array([[0.63, 0.41, 0.41, 0, 0, 0], [0.41, 0.63, 0.41, 0, 0, 0], [0.41, 0.41, 0.63, 0, 0, 0], [0, 0, 0, 0.43, 0, 0], [0, 0, 0, 0, 0.43, 0], [0, 0, 0, 0, 0, 0.43]]) C_al = np.array([[0.62639459, 0.41086487, 0.41086487, 0, 0, 0], [0.41086487, 0.62639459, 0.41086487, 0, 0, 0], [0.41086487, 0.41086487, 0.62639459, 0, 0, 0], [0, 0, 0, 0.42750351, 0, 0], [0, 0, 0, 0, 0.42750351, 0], [0, 0, 0, 0, 0, 0.42750351]]) eigenstrain = [0.023, 0.023, 0.023, 0.0, 0.0, 0.0] mu_al = 0.34876 mu_al3mg = 0.20835377082353254 poisson = 0.5*(mu_al + mu_al3mg) poisson = mu_al strain_energy = StrainEnergy(eigenstrain=eigenstrain, poisson=poisson) print(strain_energy.is_isotropic(C_al)) energy = strain_energy.strain_energy(C_matrix=C_al, C_prec=C_al3Mg) v_per_atom = 16.60753125 print(energy*1000.0*v_per_atom) print(energy*1000.0)
def plot(self, princ_misfit=[0.1, 0.1, 0.1], theta=0.0, phi=0.0, show=True): from matplotlib import pyplot as plt from cemc.tools import rot_matrix_spherical_coordinates from cemc.tools import rotate_tensor scale_factors = np.logspace(-3, 3, 100) # Sphere aspects = { "Sphere": [1.0, 1.0, 1.0], "Needle": [10000.0, 1.0, 1.0], "Plate": [10000.0, 10000.0, 1.0] } fig = plt.figure() ax1 = fig.add_subplot(1, 1, 1) colors = ["#5D5C61", "#7395AE", "#B1A296"] color_count = 0 for k, v in aspects.items(): strain_tensor = np.diag(princ_misfit) rot_matrix = rot_matrix_spherical_coordinates(phi, theta) strain_tensor = rotate_tensor(strain_tensor, rot_matrix) strain = StrainEnergy(aspect=v, misfit=strain_tensor, poisson=self.poisson) energy = [ strain.strain_energy(C_matrix=self.tensor, scale_factor=f) for f in scale_factors ] ax1.plot(scale_factors, energy, label=k, color=colors[color_count % 3]) color_count += 1 ax1.set_xscale("log") ax1.set_yscale("log") ax1.spines["right"].set_visible(False) ax1.spines["top"].set_visible(False) ax1.set_xlabel("Scale factor") ax1.set_ylabel("Strain energy") ax1.legend(frameon=False) if show: plt.show()
def __call__(self, system_changes): self.cov_obs(system_changes) inertia_tensor = np.trace( self.cov_obs.cov_matrix) * np.eye(3) - self.cov_obs.cov_matrix principal, rot_matrix = np.linalg.eigh(inertia_tensor) # The rotation to be applied to the material properties # and the misfit, is the transpose of the eigenvector # matrix C_mat = rotate_rank4_mandel(self.C_matrix, rot_matrix.T) C_prec = rotate_rank4_mandel(self.C_prec, rot_matrix.T) misfit = rotate_tensor(self.misfit, rot_matrix.T) axes = self.ellipsoid_axes(principal) str_eng = StrainEnergy(aspect=axes, misfit=misfit, poisson=self.poisson) str_energy = str_eng.strain_energy(C_matrix=C_mat, C_prec=C_prec) # Bias potential should not alter the observer # The MC object will handle this self.cov_obs.undo_last() return str_energy * ellipsoid_volume(axes)
def optimal_orientation(self, princ_misfit=[0.1, 0.1, 0.1], aspect=[1.0, 1.0, 1.0], scale=1.0, show_map=True): """Find the optimial orientation of the ellipsoid.""" from itertools import product from cemc.tools import rot_matrix_spherical_coordinates from cemc.tools import rotate_tensor from scipy.interpolate import griddata from matplotlib import pyplot as plt # Quick exploration of the space theta = np.linspace(0.0, np.pi / 2.0, 100) phi = np.linspace(0.0, np.pi / 2.0, 100) energy = [] all_theta = [] all_phi = [] for ang in product(phi, theta): strain_tensor = np.diag(princ_misfit) rot_matrix = rot_matrix_spherical_coordinates(ang[0], ang[1]) strain_tensor = rotate_tensor(strain_tensor, rot_matrix) strain = StrainEnergy(aspect=aspect, misfit=strain_tensor, poisson=self.poisson) new_energy = strain.strain_energy(C_matrix=self.tensor, scale_factor=scale) energy.append(new_energy) all_theta.append(ang[1]) all_phi.append(ang[0]) # Locate the minimal energy min_indx = np.argmin(energy) theta_min = all_theta[min_indx] phi_min = all_phi[min_indx] if theta_min > np.pi / 2.0: theta_min = np.pi - theta_min print("Min. energy: {}. Theta: {} Phi. {}" "".format(energy[min_indx], int(theta_min * 180 / np.pi), int(phi_min * 180 / np.pi))) print("Poisson ratio: {}".format(self.poisson)) T, P = np.meshgrid(theta, phi) data = griddata(np.vstack((all_theta, all_phi)).T, energy, (T, P)) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) im = ax.imshow(data.T, origin="lower", aspect="auto", cmap="inferno", extent=[0, 90, 0, 90]) cbar = fig.colorbar(im) cbar.set_label("Strain energy") ax.set_xlabel("Polar angle (deg)") ax.set_ylabel("Azimuthal angle (deg)") if show_map: plt.show()