from charged_shells import expansion, functions as fn, potentials, patch_size import numpy as np from charged_shells.parameters import ModelParams import matplotlib.pyplot as plt import scipy.special as sps from pathlib import Path from functools import partial from matplotlib.lines import Line2D def point_to_gauss_map(sigma_m, a_bar, lbd, params: ModelParams): return (sigma_m * fn.coefficient_Cim(2, params.kappaR) / fn.coefficient_Cpm(2, params.kappaR) * np.sinh(lbd) / (lbd * fn.sph_bessel_i(2, lbd)) * a_bar ** 2) def point_to_cap_map(sigma_m, a_bar, theta0, params: ModelParams): return (sigma_m * 10 * fn.coefficient_Cim(2, params.kappaR) / fn.coefficient_Cpm(2, params.kappaR) * a_bar ** 2 / (sps.eval_legendre(1, np.cos(theta0)) - sps.eval_legendre(3, np.cos(theta0)))) def ic_cs_comparison(): kappaR = 15 params = ModelParams(R=150, kappaR=kappaR) sigma_m = 0.001 sigma0 = 0.0001 a_bar = 0.3 theta = np.linspace(0, np.pi, 1001) phi = 0. dist = 1 ex_cp = expansion.MappedExpansionQuad(a_bar=a_bar, kappaR=params.kappaR, sigma_tilde=sigma_m, l_max=30, sigma0=sigma0) potential_cp = potentials.charged_shell_potential(theta, phi, dist, ex_cp, params) potential_ic = potentials.inverse_patchy_particle_potential(theta, dist, a_bar, -2 * sigma_m + sigma0, (sigma_m, sigma_m), params, 30) fig, ax = plt.subplots() ax.scatter(theta[::50], 1000 * potential_ic.T[::50], marker='o', label='ICi', facecolors='none', edgecolors='tab:red') ax.plot(theta, 1000 * potential_cp.T, label='CSp - mapped', linewidth=2) # ax.plot(1000 * potential_ic.T - 1000 * potential_cp.T) ax.tick_params(which='both', direction='in', top=True, right=True, labelsize=12) ax.set_xlabel(r'$\theta$', fontsize=15) ax.set_ylabel(r'$\phi$ [mV]', fontsize=15) custom_ticks = [0, np.pi / 4, np.pi / 2, 3 * np.pi / 4, np.pi] custom_labels = ['0', r'$\pi/4$', r'$\pi/2$', r'$3\pi/4$', r'$\pi$'] plt.axhline(y=0, color='black', linestyle=':') plt.xticks(custom_ticks, custom_labels, fontsize=13) plt.legend(fontsize=12) plt.tight_layout() # plt.savefig(Path("/home/andraz/ChargedShells/Figures/potential_shape_comparison_overcharged05.pdf"), dpi=300) plt.show() def models_comparison(): target_patch_size = 0.92 kappaR = 3 params = ModelParams(R=150, kappaR=kappaR) sigma_m = 0.001 sigma0 = 0 # taking this total charge parameter nonzero causes cap model to fail in finding the appropriate theta0 sigma0_mapped = expansion.net_charge_map(sigma0, kappaR) def fn1(x): return expansion.MappedExpansionQuad(a_bar=x, kappaR=params.kappaR, sigma_tilde=sigma_m, l_max=30, sigma0=sigma0) def fn2(x): return expansion.GaussianCharges(lambda_k=x, omega_k=np.array([[0, 0], [np.pi, 0]]), sigma1=0.001, l_max=30, sigma0=sigma0_mapped) def fn3(x): return expansion.SphericalCap(theta0_k=x, sigma1=0.001, l_max=50, omega_k=np.array([[0, 0], [np.pi, 0]]), sigma0=sigma0_mapped) a_bar = patch_size.inverse_potential_patch_size(target_patch_size, fn1, 0.5, params) lbd = patch_size.inverse_potential_patch_size(target_patch_size, fn2, 5, params) theta0 = patch_size.inverse_potential_patch_size(target_patch_size, fn3, 0.5, params) ex_point = expansion.MappedExpansionQuad(a_bar=a_bar, kappaR=params.kappaR, sigma_tilde=sigma_m, l_max=30, sigma0=sigma0) gauss_sigma = point_to_gauss_map(sigma_m, a_bar, lbd, params) ex_gauss = expansion.GaussianCharges(lambda_k=lbd, omega_k=np.array([[0, 0], [np.pi, 0]]), sigma1=gauss_sigma, l_max=30, sigma0=sigma0_mapped) cap_sigma = point_to_cap_map(sigma_m, a_bar, theta0, params) ex_cap = expansion.SphericalCap(theta0_k=theta0, sigma1=cap_sigma, omega_k=np.array([[0, 0], [np.pi, 0]]), l_max=30, sigma0=sigma0_mapped) theta = np.linspace(0, np.pi, 1001) phi = 0. dist = 1 potential_ic = potentials.inverse_patchy_particle_potential(theta, dist, a_bar, -2 * sigma_m + sigma0, (sigma_m, sigma_m), params, 30) potential1 = potentials.charged_shell_potential(theta, phi, dist, ex_point, params) potential2 = potentials.charged_shell_potential(theta, phi, dist, ex_gauss, params) potential3 = potentials.charged_shell_potential(theta, phi, dist, ex_cap, params) # print(potential.shape) # print(potential) # expansion.plot_theta_profile_multiple([ex_point, ex_gauss, ex_cap], ['IC', 'Gauss', 'cap'], num=1000) fig, ax = plt.subplots() ax.scatter(theta[::50], 1000 * potential_ic.T[::50], marker='o', label='ICi', facecolors='none', edgecolors='tab:red') ax.plot(theta, 1000 * potential1.T, label='CSp - mapped', linewidth=2) # ax.plot(theta, potential_ic.T, label='IC', ls=':', linewidth=2, marker='o', markevery=50, mfc='none') ax.plot(theta, 1000 * potential2.T, label='CSp - Gauss', linewidth=2, ls='--') ax.plot(theta, 1000 * potential3.T, label='CSp - caps', linewidth=2, ls='--') ax.tick_params(which='both', direction='in', top=True, right=True, labelsize=12) ax.set_xlabel(r'$\theta$', fontsize=15) ax.set_ylabel(r'$\phi$ [mV]', fontsize=15) custom_ticks = [0, np.pi / 4, np.pi / 2, 3 * np.pi / 4, np.pi] custom_labels = ['0', r'$\pi/4$', r'$\pi/2$', r'$3\pi/4$', r'$\pi$'] plt.axhline(y=0, color='black', linestyle=':') plt.axvline(x=target_patch_size, color='black', linestyle=':') plt.xticks(custom_ticks, custom_labels, fontsize=13) plt.legend(fontsize=12) plt.tight_layout() plt.savefig(Path("/home/andraz/ChargedShells/Figures/potential_shape_comparison.pdf"), dpi=300) plt.show() def abar_comparison(): target_patch_sizes = [0.8, 0.85, 0.92] params = ModelParams(R=150, kappaR=3) sigma_m = 0.001 theta = np.linspace(0, np.pi, 1001) phi = 0. dist = 1 def fn1(x): return expansion.MappedExpansionQuad(a_bar=x, kappaR=params.kappaR, sigma_tilde=sigma_m, l_max=30) pots = [] for ps in target_patch_sizes: a_bar = patch_size.inverse_potential_patch_size(ps, fn1, 0.5, params) ex_point = expansion.MappedExpansionQuad(a_bar=a_bar, kappaR=params.kappaR, sigma_tilde=sigma_m, l_max=30) pots.append(potentials.charged_shell_potential(theta, phi, dist, ex_point, params)) fig, ax = plt.subplots() for pot, ps in zip(pots, target_patch_sizes): ax.plot(theta, 1000 * pot, label=fr'$\theta_0={180 / np.pi * ps:.1f}^o$', linewidth=2) ax.tick_params(which='both', direction='in', top=True, right=True, labelsize=12) ax.set_xlabel(r'$\theta$', fontsize=15) ax.set_ylabel(r'$\phi$ [mV]', fontsize=15) custom_ticks = [0, np.pi / 4, np.pi / 2, 3 * np.pi / 4, np.pi] custom_labels = ['0', r'$\pi/4$', r'$\pi/2$', r'$3\pi/4$', r'$\pi$'] plt.axhline(y=0, color='black', linestyle=':') plt.xticks(custom_ticks, custom_labels, fontsize=13) plt.legend(fontsize=12) plt.tight_layout() plt.savefig(Path("/home/andraz/ChargedShells/Figures/potential_amplitude_comparison.pdf"), dpi=300) plt.show() def charge_comparsion(): charges = np.array([-0.001, 0, 0.001, 0.002]) a_bar = 0.6 params = ModelParams(R=150, kappaR=10) sigma_m = 0.001 theta = np.linspace(0, np.pi, 1001) phi = 0. dist = 1 ex_point = expansion.MappedExpansionQuad(a_bar=a_bar, kappaR=params.kappaR, sigma_tilde=sigma_m, l_max=30, sigma0=charges) pot = potentials.charged_shell_potential(theta, phi, dist, ex_point, params) fig, ax = plt.subplots() for p, lbl in zip(pot, [fr'$\sigma_0={c}$' for c in charges]): ax.plot(theta, 1000 * p, linewidth=2, label=lbl) ax.tick_params(which='both', direction='in', top=True, right=True, labelsize=12) ax.set_xlabel(r'$\theta$', fontsize=15) ax.set_ylabel(r'$\phi$ [mV]', fontsize=15) custom_ticks = [0, np.pi / 4, np.pi / 2, 3 * np.pi / 4, np.pi] custom_labels = ['0', r'$\pi/4$', r'$\pi/2$', r'$3\pi/4$', r'$\pi$'] plt.axhline(y=0, color='black', linestyle=':') plt.xticks(custom_ticks, custom_labels, fontsize=13) plt.legend(fontsize=12) plt.tight_layout() # plt.savefig(Path("/home/andraz/ChargedShells/Figures/potential_charge_comparison.pdf"), dpi=300) plt.show() # TODO: comparison of patch shape at different kappaR and a neutral particle, with fixed patch size def IC_CS_comparison(): target_patch_size = 0.92 kappaR = 3 params = ModelParams(R=150, kappaR=kappaR) sigma_m = 0.001 sigma0_array = np.array([-0.0002, 0, 0.0002]) theta = np.linspace(0, np.pi, 1001) phi = 0. dist = 1 def fn1(x): return expansion.MappedExpansionQuad(a_bar=x, kappaR=params.kappaR, sigma_tilde=sigma_m, l_max=30, sigma0=0) # a_bar is determined only for a neutral particle (patch size only well-defined in this case) a_bar = patch_size.inverse_potential_patch_size(target_patch_size, fn1, 0.5, params) potential_ic = [] potential_cs = [] for sigma0 in sigma0_array: ex_point = expansion.MappedExpansionQuad(a_bar=a_bar, kappaR=params.kappaR, sigma_tilde=sigma_m, l_max=30, sigma0=sigma0) potential_ic.append(potentials.inverse_patchy_particle_potential(theta, dist, a_bar, -2 * sigma_m + sigma0, (sigma_m, sigma_m), params, 30)) potential_cs.append(potentials.charged_shell_potential(theta, phi, dist, ex_point, params)) fig, ax = plt.subplots() lines = [] for p_ic, p_cs, charge in zip(potential_ic, potential_cs, sigma0_array): ax.scatter(theta[::50], 1000 * p_ic.T[::50], marker='o', facecolors='none', edgecolors='tab:red') l, = ax.plot(theta, 1000 * p_cs.T, label=rf'$\tilde \sigma_0 = {charge}$', linewidth=2) lines.append(l) # ax.plot(theta, potential_ic.T, label='IC', ls=':', linewidth=2, marker='o', markevery=50, mfc='none') ax.tick_params(which='both', direction='in', top=True, right=True, labelsize=12) ax.set_xlabel(r'$\theta$', fontsize=15) ax.set_ylabel(r'$\phi$ [mV]', fontsize=15) custom_ticks = [0, np.pi / 4, np.pi / 2, 3 * np.pi / 4, np.pi] custom_labels = ['0', r'$\pi/4$', r'$\pi/2$', r'$3\pi/4$', r'$\pi$'] plt.axhline(y=0, color='black', linestyle=':') plt.axvline(x=target_patch_size, color='black', linestyle=':') plt.xticks(custom_ticks, custom_labels, fontsize=13) lines.append(Line2D([0], [0], color='k', label='CSp')) lines.append(plt.scatter([], [], marker='o', facecolor='none', edgecolor='red', label='ICi')) plt.legend(handles=lines, fontsize=12) plt.tight_layout() plt.savefig(Path("/home/andraz/ChargedShells/Figures/potential_ic_cs_comparison_new.pdf"), dpi=300) plt.show() def main(): # models_comparison() # ic_cs_comparison() IC_CS_comparison() # abar_comparison() # charge_comparsion() if __name__ == '__main__': main()