sEE_minimum.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from charged_shells import expansion, interactions, mapping
  4. from charged_shells.parameters import ModelParams
  5. from functools import partial
  6. from pathlib import Path
  7. import json
  8. from matplotlib import cm
  9. from mpl_toolkits.axes_grid1 import make_axes_locatable
  10. from labellines import labelLine, labelLines
  11. from matplotlib.colors import TwoSlopeNorm
  12. from matplotlib.ticker import FuncFormatter
  13. Expansion = expansion.Expansion
  14. def sEE_minimum(ex: Expansion, params: ModelParams, accuracy=1e-2, dist=2., match_expansion_axis_to_params=None,
  15. angle_start: float = 0, angle_stop: float = np.pi / 2):
  16. ex2 = ex.clone()
  17. angle_range = np.linspace(angle_start, angle_stop, int((angle_stop - angle_start) / accuracy), endpoint=True)
  18. # angle_range = np.linspace(0.1, 0.7, int(1 / accuracy), endpoint=True)
  19. ex.rotate_euler(alpha=0, beta=angle_range, gamma=0)
  20. ex2.rotate_euler(alpha=0, beta=angle_range, gamma=0)
  21. if match_expansion_axis_to_params is not None:
  22. match_expansion_axis_to_params += 1
  23. energy_fn = mapping.parameter_map_two_expansions(partial(interactions.charged_shell_energy, dist=dist),
  24. match_expansion_axis_to_params)
  25. energy = energy_fn(ex, ex2, params)
  26. min_idx = np.argmin(energy, axis=0)
  27. min_energy = np.min(energy, axis=0)
  28. return min_energy, angle_range[min_idx]
  29. def contours():
  30. kappaR = np.linspace(1, 10, 20)
  31. a_bar = np.linspace(0.2, 0.6, 20)
  32. params = ModelParams(R=150, kappaR=kappaR)
  33. ex = expansion.MappedExpansionQuad(a_bar[:, None], kappaR[None, :], 0.001)
  34. min_energy, min_angle = sEE_minimum(ex, params, match_expansion_axis_to_params=1, accuracy=0.01)
  35. kR_mesh, a_mesh = np.meshgrid(kappaR, a_bar)
  36. print(np.min(min_angle), np.max(min_angle))
  37. print(np.min(min_energy), np.max(min_energy))
  38. plt.contourf(kR_mesh, a_mesh, min_angle)
  39. # plt.imshow(min_angle)
  40. plt.show()
  41. plt.contourf(kR_mesh, a_mesh, min_energy, np.array([-9, -5, -2.5, -1, -0.5, -0.2, 0]))
  42. # plt.imshow(min_energy)
  43. plt.show()
  44. def kappaR_dependence(kappaR, save_as=None, cmap=cm.jet):
  45. a_bar = np.linspace(0.12, 0.8, 15)
  46. params = ModelParams(R=150, kappaR=kappaR)
  47. ex = expansion.MappedExpansionQuad(a_bar[None, :], kappaR[:, None], 0.001)
  48. min_energy, min_angle = sEE_minimum(ex, params, match_expansion_axis_to_params=0, accuracy=0.001,
  49. angle_start=0.5, angle_stop=1.)
  50. kappaR_alt = np.array([0.01, 2, 5, 10, 50])
  51. params_alt = ModelParams(R=150, kappaR=kappaR_alt)
  52. a_bar_alt = np.linspace(np.min(a_bar) - 0.05, np.max(a_bar) + 0.05, 20)
  53. ex2 = expansion.MappedExpansionQuad(a_bar_alt[:, None], kappaR_alt[None, :], 0.001)
  54. min_energy_alt, min_angle_alt = sEE_minimum(ex2, params_alt, match_expansion_axis_to_params=1, accuracy=0.001,
  55. angle_start=0.5, angle_stop=1.)
  56. colors = cmap(np.linspace(0, 1, len(a_bar)))
  57. sm = cm.ScalarMappable(cmap=cmap, norm=plt.Normalize(vmin=np.min(a_bar), vmax=np.max(a_bar)))
  58. sm.set_array([])
  59. # Transformation to the position along our quadrupolar rotational path
  60. min_angle = np.pi - min_angle
  61. min_angle_alt = np.pi - min_angle_alt
  62. kappaR_labels = [rf'$\kappa R={kR:.1f}$' for kR in kappaR_alt]
  63. fig, ax = plt.subplots(figsize=plt.figaspect(0.5))
  64. for me, ma, lbl in zip(min_energy_alt.T, min_angle_alt.T, kappaR_labels):
  65. ax.plot(ma, me, ls=':', c='k', label=lbl)
  66. labelLines(ax.get_lines(), align=False, fontsize=14, xvals=(2.35, 2.65))
  67. for me, ma, lbl, c in zip(min_energy.T, min_angle.T, [rf'$\bar a={a:.2f}$' for a in a_bar], colors):
  68. ax.plot(ma, me, label=lbl, c=c)
  69. # ax.plot(min_angle, min_energy)
  70. # ax.legend(fontsize=17)
  71. ax.tick_params(which='both', direction='in', top=True, right=True, labelsize=12)
  72. ax.set_xlabel('angle', fontsize=15)
  73. ax.set_ylabel('U', fontsize=20)
  74. ax.set_xlim(2.2, 2.65)
  75. ax.set_ylim(-20, 1)
  76. divider = make_axes_locatable(ax)
  77. cax = divider.append_axes('right', size='5%', pad=0.05)
  78. cbar = fig.colorbar(sm, cax=cax, orientation='vertical')
  79. cbar.set_label(r'$\bar a$', rotation=90, labelpad=15, fontsize=15)
  80. plt.tight_layout()
  81. if save_as is not None:
  82. plt.savefig(save_as, dpi=600)
  83. plt.show()
  84. def IC_kappaR_dependence(config_data: dict, which_kappa_lines: list,
  85. save_as=None, cmap=cm.jet, file_suffix=""):
  86. em_data_path = (Path(config_data["emanuele_data"]).joinpath("FIG_9"))
  87. em_data = np.load(em_data_path.joinpath(f"fig9{file_suffix}.npz"))['arr_0']
  88. # print(em_data.shape)
  89. a_bar, indices, counts = np.unique(em_data[:, 0], return_counts=True, return_inverse=True)
  90. print(a_bar)
  91. if not np.all(counts == counts[0]):
  92. raise ValueError("Data not reshapable.")
  93. colors = cmap(np.linspace(0, 1, len(a_bar)))
  94. sm = cm.ScalarMappable(cmap=cmap, norm=plt.Normalize(vmin=np.min(a_bar), vmax=np.max(a_bar)))
  95. sm.set_array([])
  96. min_energy = em_data[:, 3].reshape(-1, counts[0])
  97. min_angle = em_data[:, 2].reshape(-1, counts[0])
  98. kappa_line_energy = []
  99. kappa_line_angle = []
  100. kappaR_labels = []
  101. for kappa in which_kappa_lines:
  102. ind = em_data[:, 1] == kappa
  103. if np.sum(ind) == 0:
  104. print(f'No lines with kR={kappa} in data. Available values: {np.unique(em_data[:, 1])}')
  105. continue
  106. kappa_line_energy.append(em_data[:, 3][ind])
  107. kappa_line_angle.append(em_data[:, 2][ind])
  108. kappaR_labels.append(rf'$\kappa R={kappa:.1f}$')
  109. fig, ax = plt.subplots(figsize=plt.figaspect(0.5))
  110. for me, ma, lbl in zip(kappa_line_energy, kappa_line_angle, kappaR_labels):
  111. sort = np.argsort(ma)
  112. ax.plot(ma[sort], me[sort], ls=':', c='k', label=lbl)
  113. labelLines(ax.get_lines(), align=False, fontsize=14, xvals=(2.4, 2.65))
  114. for me, ma, lbl, c in zip(min_energy, min_angle, [rf'$\bar a={a:.2f}$' for a in a_bar], colors):
  115. ax.plot(ma, me, label=lbl, c=c)
  116. # ax.plot(min_angle, min_energy)
  117. # ax.legend(fontsize=17)
  118. ax.tick_params(which='both', direction='in', top=True, right=True, labelsize=12)
  119. ax.set_xlabel('angle', fontsize=15)
  120. ax.set_ylabel('U', fontsize=20)
  121. ax.set_xlim(2.2, 2.65)
  122. ax.set_ylim(-40, 1)
  123. divider = make_axes_locatable(ax)
  124. cax = divider.append_axes('right', size='5%', pad=0.05)
  125. cbar = fig.colorbar(sm, cax=cax, orientation='vertical')
  126. cbar.set_label(r'$\bar a$', rotation=90, labelpad=15, fontsize=12)
  127. plt.tight_layout()
  128. if save_as is not None:
  129. plt.savefig(save_as, dpi=600)
  130. plt.show()
  131. # def charge_dependence(charge, save_as=None):
  132. #
  133. # a_bar = np.array([0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8])
  134. # params = ModelParams(R=150, kappaR=kappaR)
  135. #
  136. # ex = expansion.MappedExpansionQuad(a_bar[None, :], kappaR[:, None], 0.001)
  137. # min_energy, min_angle = sEE_minimum(ex, params, match_expansion_axis_to_params=0, accuracy=0.001,
  138. # angle_start=0.5, angle_stop=1.)
  139. #
  140. # kappaR_alt = np.array([0.01, 2, 5, 10, 50])
  141. # params_alt = ModelParams(R=150, kappaR=kappaR_alt)
  142. # a_bar_alt = np.linspace(np.min(a_bar) - 0.05, np.max(a_bar) + 0.05, 20)
  143. # ex2 = expansion.MappedExpansionQuad(a_bar_alt[:, None], kappaR_alt[None, :], 0.001)
  144. # min_energy_alt, min_angle_alt = sEE_minimum(ex2, params_alt, match_expansion_axis_to_params=1, accuracy=0.001,
  145. # angle_start=0.5, angle_stop=1.)
  146. #
  147. # fig, ax = plt.subplots(figsize=plt.figaspect(0.5))
  148. # for me, ma, lbl in zip(min_energy_alt.T, min_angle_alt.T, [rf'$\bar a={a:.2f}$' for a in a_bar]):
  149. # ax.plot(ma, me, ls=':', c='k')
  150. # for me, ma, lbl in zip(min_energy.T, min_angle.T, [rf'$\bar a={a:.2f}$' for a in a_bar]):
  151. # ax.plot(ma, me, label=lbl)
  152. # # ax.plot(min_angle, min_energy)
  153. # ax.legend(fontsize=17)
  154. # ax.tick_params(which='both', direction='in', top=True, right=True, labelsize=12)
  155. # ax.set_xlabel('angle', fontsize=15)
  156. # ax.set_ylabel('U', fontsize=20)
  157. # ax.set_xlim(0.56, 0.93)
  158. # ax.set_ylim(-20, 1)
  159. # plt.tight_layout()
  160. # if save_as is not None:
  161. # plt.savefig(save_as, dpi=600)
  162. # plt.show()
  163. def main():
  164. with open(Path("/home/andraz/ChargedShells/charged-shells/config.json")) as config_file:
  165. config_data = json.load(config_file)
  166. # contours()
  167. kappaR_dependence(kappaR=np.linspace(0.1, 30, 20),
  168. save_as=Path(config_data["figures"]).joinpath('sEE_min_kappaR_abar.png')
  169. )
  170. # IC_kappaR_dependence(config_data, which_kappa_lines=[0.01, 3., 5., 10., 50.], file_suffix="_1",
  171. # save_as=Path(config_data["figures"]).joinpath("Emanuele_data").joinpath('sEE_min_kappaR_abar.png')
  172. # )
  173. if __name__ == '__main__':
  174. main()