ngamma_eq.py
Go to the documentation of this file.
1 import numpy as np
2 import pandas as pd
3 from winvn_class import winvn
4 from numba import jit
5 
6 
7 class ngamma_eq(object):
8 
9  def __init__(self, path_winvn="winvne_v2.0.dat"):
10  """
11  Constructor for the class
12  """
13  # Set the paths
14  self.__path_winvn = path_winvn
15 
16  # Read the files
17  self.__read_winvn()
18  self.__calc_Sn_winvn()
19 
20  # Define constants
21  self.__kb = 8.617343e-11 # MeV/K
22  self.__mu = 1.660539e-24 # g
23  self.__hix = 1.036427e-18
24  self.__NA = 6.02214076e23 # 1/mol
25  self.__hbar = 6.582119e-22 # MeV s
26 
27 
28 
29  def __read_winvn(self):
30  """
31  Read the file containing the partition functions
32  """
33  w = winvn(self.__path_winvn)
34  w.read_winvn()
35  df = w.get_dataframe()
36  pf = df["function"].values
37  Z = df["Z"].values
38  N = df["N"].values
39  spin = df["spin"].values
40 
41  # Create 2D array with Z and N, fill non existing with nans
42  # pf is of type function
43  self.__pf_Z_N = np.zeros((Z.max()+1,N.max()+1),dtype=object)
44  self.__spin_Z_N = np.zeros((Z.max()+1,N.max()+1))
45  self.__pf_Z_N[:] = lambda x: np.nan
46  self.__pf_Z_N[Z,N] = pf
47 
48  self.__spin_Z_N[Z,N] = spin
49 
50 
51  def __calc_Sn_winvn(self):
52  """
53  Calculate the neutron separation energy from the mass excess in the winvn
54  """
55  w = winvn(self.__path_winvn)
56  w.read_winvn()
57  df = w.get_dataframe()
58 
59  mexc_n = df.loc["n","mass excess"]
60 
61  # Put mass excesses in 2D array
62  Zwinvn = df["Z"].values
63  Nwinvn = df["N"].values
64  mexc = df["mass excess"].values
65 
66  # Create 2D array with Z and N, fill non existing with nans
67  self.__Sn_Z_N_winvn = np.zeros((Zwinvn.max()+1,Nwinvn.max()+1))
68  self.__Sn_Z_N_winvn[:] = np.nan
69  self.__Sn_Z_N_winvn[Zwinvn,Nwinvn] = mexc
70 
71  # Now calculate the neutron separation energy
72  self.__Sn_Z_N_winvn[:,1:] = (self.__Sn_Z_N_winvn[:,0:-1] + mexc_n) - self.__Sn_Z_N_winvn[:,1:]
73 
74  # Put this into the Sn array
76  # ALso A Z and N
77  self.__A = df["A"].values
78  self.__Z = df["Z"].values
79  self.__N = df["N"].values
80 
81 
82 
83  @staticmethod
84  @jit(nopython=True)
85  def helper_calc(Sn_array,density,temperature,yn,pf,spin):
86  """
87  Helper function to calculate the path of the r-process. Necessary to use numba.
88  """
89 
90  def helper_calc_ratio(Z, N, T, ndens, Sn_Z_N, pf_Z_N, spin_Z_N):
91  # Define constants
92  kb = 8.617343e-11 # MeV/K
93  hix = 1.036427e-18
94  NA = 6.02214076e23 # 1/mol
95  hbar = 6.582119e-22 # MeV s
96 
97  # kbT in MeV
98  kbT = kb * T * 1e9
99  A = Z + N
100  Snp1 = Sn_Z_N[Z, N + 1]
101  Sn = Sn_Z_N[Z, N]
102  pf = pf_Z_N[Z, N]
103  pf1 = pf_Z_N[Z, N + 1]
104 
105  sp = 2 * spin_Z_N[Z, N] + 1
106  sp1 = 2 * spin_Z_N[Z, N + 1] + 1
107 
108  a = np.log((A + 1) / A) * 3 / 2
109  b = (Snp1) / (kbT)
110  c = np.log(pf * sp / (2 * pf1 * sp1))
111 
112  d = np.log(2 * np.pi * hbar**2 / (hix * kbT)) * 1.5
113  e = np.log(ndens * NA)
114 
115  ratio = a + b + c + d + e
116  return ratio
117 
118  ndens = density*yn
119 
120  # Make zerolike self.__S2n_Z_N_winvn
121  Zmax = Sn_array.shape[0]-1
122  Nmax = Sn_array.shape[1]-1
123  logratios = np.zeros((Zmax+1, Nmax+1))*np.nan
124 
125  path_Z = []
126  path_N = []
127  for Z in range(0,Zmax):
128  for N in range(0,Nmax):
129  if np.isnan(Sn_array[Z,N]):
130  continue
131 
132  logratios[Z,N] = helper_calc_ratio(Z,N,temperature,ndens,Sn_array,pf,spin)
133 
134  # Find the first occurence of ratio <= 1
135  if np.all(np.isnan(logratios[Z,:])):
136  continue
137  if Z<=2:
138  continue
139 
140  log_ratios = logratios[Z, :]
141  log_cumprod = np.nancumsum(log_ratios) # Cumulative sum of logarithmic values
142 
143  maxval = np.where(~np.isnan(Sn_array[Z,:]) & (Sn_array[Z,:]>0))[0][-1]
144  minval = np.where(~np.isnan(Sn_array[Z,:]))[0][0]
145 
146  idx = np.minimum(np.maximum(np.argmax(log_cumprod)+1,minval),maxval)
147 
148  if len(path_Z) >= 1:
149  if path_Z[-1] != Z:
150  path_Z.append(Z)
151  path_N.append(path_N[-1]-1)
152 
153  path_Z.append(Z)
154  path_N.append(idx)
155 
156  return path_Z, path_N
157 
158 
159 
160  def calc_r_process_path(self,density,temperature,yn):
161  """
162  Get the path of the r-process
163  """
164 
165  # Precompute the shape once
166  rows, cols = self.__pf_Z_N.shape
167 
168  # Use np.empty to pre-allocate the pf array
169  pf = np.empty((rows, cols))
170  def apply_callable(Z, N):
171  func = self.__pf_Z_N[Z, N]
172  if callable(func):
173  return func(temperature)
174  return np.nan # or some default value if not callable
175 
176  # Apply the function across the array using np.vectorize
177  vectorized_calc = np.vectorize(apply_callable)
178  pf = vectorized_calc(np.arange(rows)[:, None], np.arange(cols))
179 
180  self.path_Z, self.path_N = self.helper_calc(self.__Sn_Z_N,density,temperature,yn,pf,self.__spin_Z_N)
181 
182 
183  # @jit(nopython=True)
184  def __calc_ratio(self,Z,N,T,ndens):
185  # kbT in MeV
186  kbT = self.__kb*T*1e9
187  A = Z+N
188  Snp1 = self.__Sn_Z_N[Z,N+1]
189  Sn = self.__Sn_Z_N[Z,N]
190  pf = self.__pf_Z_N[Z,N](T)
191  pf1 = self.__pf_Z_N[Z,N+1](T)
192 
193  sp = 2*self.__spin_Z_N[Z,N]+1
194  sp1 = 2*self.__spin_Z_N[Z,N+1]+1
195 
196  a = np.log((A+1)/A)*3/2
197  b = (Snp1)/(kbT)
198  # with warnings.catch_warnings():
199  # warnings.simplefilter("ignore", RuntimeWarning)
200  c = np.log(pf*sp/(2*pf1*sp1))
201 
202  d = np.log(2*np.pi*self.__hbar**2 / (self.__hix*kbT)) * 1.5
203  e = np.log(ndens*self.__NA)
204 
205  # with warnings.catch_warnings():
206  # warnings.simplefilter("ignore", RuntimeWarning)
207  ratio = np.exp(a+b+c+d+e,dtype=np.float128)
208 
209  return ratio
210 
211 if __name__ == "__main__":
212 
213  # Create the object
214  ng = ngamma_eq("/home/mreichert/data/Networks/comparison_winNet/WinNet-dev/data/winvne_v2.0.dat")
215  ng.calc_r_process_path(1e6,4,5e-1)
create_rates_grid.func
func
Definition: create_rates_grid.py:54
src_files.ngamma_eq.ngamma_eq.calc_r_process_path
def calc_r_process_path(self, density, temperature, yn)
Definition: ngamma_eq.py:160
src_files.ngamma_eq.ngamma_eq.__A
__A
Definition: ngamma_eq.py:77
src_files.ngamma_eq.ngamma_eq.__calc_ratio
def __calc_ratio(self, Z, N, T, ndens)
Definition: ngamma_eq.py:184
src_files.ngamma_eq.ngamma_eq.__NA
__NA
Definition: ngamma_eq.py:24
src_files.ngamma_eq.ngamma_eq.__kb
__kb
Definition: ngamma_eq.py:21
src_files.ngamma_eq.ngamma_eq.helper_calc
def helper_calc(Sn_array, density, temperature, yn, pf, spin)
Definition: ngamma_eq.py:85
src_files.ngamma_eq.ngamma_eq.path_N
path_N
Definition: ngamma_eq.py:180
src_files.ngamma_eq.ngamma_eq.__pf_Z_N
__pf_Z_N
Definition: ngamma_eq.py:43
src_files.ngamma_eq.ngamma_eq.__calc_Sn_winvn
def __calc_Sn_winvn(self)
Definition: ngamma_eq.py:51
src_files.ngamma_eq.ngamma_eq.__hix
__hix
Definition: ngamma_eq.py:23
src_files.ngamma_eq.ngamma_eq.__Sn_Z_N
__Sn_Z_N
Definition: ngamma_eq.py:75
src_files.ngamma_eq.ngamma_eq.__init__
def __init__(self, path_winvn="winvne_v2.0.dat")
Definition: ngamma_eq.py:9
src_files.ngamma_eq.ngamma_eq.__spin_Z_N
__spin_Z_N
Definition: ngamma_eq.py:44
src_files.ngamma_eq.ngamma_eq.__Z
__Z
Definition: ngamma_eq.py:78
src_files.ngamma_eq.ngamma_eq.__N
__N
Definition: ngamma_eq.py:79
src_files.ngamma_eq.ngamma_eq.__mu
__mu
Definition: ngamma_eq.py:22
src_files.ngamma_eq.ngamma_eq.__hbar
__hbar
Definition: ngamma_eq.py:25
src_files.ngamma_eq.ngamma_eq.__read_winvn
def __read_winvn(self)
Definition: ngamma_eq.py:29
src_files.ngamma_eq.ngamma_eq.__Sn_Z_N_winvn
__Sn_Z_N_winvn
Definition: ngamma_eq.py:67
src_files.ngamma_eq.ngamma_eq
Definition: ngamma_eq.py:7
src_files.winvn_class.winvn
Definition: winvn_class.py:7
src_files.ngamma_eq.ngamma_eq.__path_winvn
__path_winvn
Definition: ngamma_eq.py:14