chem_pot.f90
Go to the documentation of this file.
1 !> @file chem_pot.f90
2 !!
3 !!
4 !! The error file code for this file is ***W13***.
5 !! @brief Subroutine \ref chempot to compute chemical potentials of electrons and positrons
6 !!
7 !! This file originates
8 !! from [Cococubed](https://cococubed.com/code_pages/chemical_potential.shtml).
9 !! The chemical potentials are only used if \ref parameter_class::use_timmes_mue is
10 !! enabled or heating is turned on.
11 
12 !>
13 !! Given a temperature temp [K], density den [g/cm**3], and a composition
14 !! characterized by y_e, this routine returns the electron and positron
15 !! chemical potentials. derivatives with respect to temperature and
16 !! density are computed, but not returned.
17 !!
18 !! References: <a href="http://adsabs.harvard.edu/abs/1999ApJS..125..277T">Timmes & Arnett ApJS 1999</a>
19 !!
20 !! \b Edited:
21 !! - 02.02.21 - MR - gave intent(in/out) and let it crash when it does not work
22 !! .
23 #include "../macros.h"
24 subroutine chempot(temp,den,ye,etaele,etapos)
28  implicit none
29  save
30 
31 !..declare the pass
32  real(r_kind),intent(in) :: temp !< Temperature [K]
33  real(r_kind),intent(in) :: den !< Density [g/ccm]
34  real(r_kind),intent(in) :: ye !< Electron fraction
35  real(r_kind),intent(out) :: etaele !< Electron chemical potential
36  real(r_kind),intent(out) :: etapos !< Positron chemical potential
37 
38 !..declare local variables
39 !..for the tables
40  integer i,j,imax,jmax
41  parameter(imax = 271, jmax = 101)
42 
43 !..for the density and temperature table
44  real(r_kind) d(imax),t(jmax)
45 
46 !..for chemical potential table
47  real(r_kind) ef(imax,jmax),efd(imax,jmax), &
48  eft(imax,jmax),efdt(imax,jmax)
49 
50 !..for storing the differences
51  real(r_kind) dt_sav(jmax), &
52  dti_sav(jmax), &
53  dd_sav(imax), &
54  ddi_sav(imax)
55 
56 !..for the interpolations
57  integer iat,jat
58  real(r_kind) tlo,thi,tstp,tstpi,dlo,dhi,dstp,dstpi, &
59  tsav,dsav,deni,tempi,kt,ktinv,beta,dbetadt
60  real(r_kind) dth,dti,dd,ddi,xt,xd,mxt,mxd, &
61  si0t,si1t,si0mt,si1mt, &
62  si0d,si1d,si0md,si1md, &
63  dsi0t,dsi1t,dsi0mt,dsi1mt, &
64  dsi0d,dsi1d,dsi0md,dsi1md, &
65  x,z,din,fi(16), &
66  xpsi0,xdpsi0,xpsi1,xdpsi1,h3, &
67  w0t,w1t,w0mt,w1mt,w0d,w1d,w0md,w1md, &
68  detadd,detadt,detapdd,detapdt
69 
70 !..physical constants and parameters
71  real(r_kind) mecc,positron_start
72 
73 !..for initialization
74  integer ifirst
75  data ifirst/0/
76  integer :: chem_pot_unit
77 
78 !..cubic hermite polynomial statement functions
79 !..psi0 & derivatives
80  xpsi0(z) = z * z * (2.0d0*z - 3.0d0) + 1.d0
81  xdpsi0(z) = z * (6.0d0*z - 6.0d0)
82 
83 !..psi1 & derivatives
84  xpsi1(z) = z * ( z * (z - 2.0d0) + 1.0d0)
85  xdpsi1(z) = z * (3.0d0*z - 4.0d0) + 1.0d0
86 
87 
88 !..bicubic hermite polynomial statement function
89  h3(i,j,w0t,w1t,w0mt,w1mt,w0d,w1d,w0md,w1md) = &
90  fi(1) *w0d*w0t + fi(2) *w0md*w0t &
91  + fi(3) *w0d*w0mt + fi(4) *w0md*w0mt &
92  + fi(5) *w0d*w1t + fi(6) *w0md*w1t &
93  + fi(7) *w0d*w1mt + fi(8) *w0md*w1mt &
94  + fi(9) *w1d*w0t + fi(10) *w1md*w0t &
95  + fi(11) *w1d*w0mt + fi(12) *w1md*w0mt &
96  + fi(13) *w1d*w1t + fi(14) *w1md*w1t &
97  + fi(15) *w1d*w1mt + fi(16) *w1md*w1mt
98 
99 !.. mecc = me*c^2 in g*cm^2/s^2
100 !.. 1.602176462d-6 ..conversion factor between MeV and g*cm^2/s^2
101  mecc = unit%mass_e*1.602176462d-6
102  positron_start = 0.02d0
103 
104 !..read the table and construct the deltas only once
105  if (ifirst .eq. 0) then
106  ifirst = 1
107  chem_pot_unit= open_infile(chem_pot_file)
108 
109  tlo = 3.0d0
110  thi = 13.0d0
111  tstp = (thi - tlo)/float(jmax-1)
112  tstpi = 1.0d0/tstp
113  dlo = -12.0d0
114  dhi = 15.0d0
115  dstp = (dhi - dlo)/float(imax-1)
116  dstpi = 1.0d0/dstp
117 
118  do j=1,jmax
119  tsav = tlo + (j-1)*tstp
120  t(j) = 10.0d0**(tsav)
121  do i=1,imax
122  dsav = dlo + (i-1)*dstp
123  d(i) = 10.0d0**(dsav)
124  read(chem_pot_unit,*) ef(i,j),efd(i,j),eft(i,j),efdt(i,j)
125  enddo
126  enddo
127 
128 !..construct the temperature and density deltas and their inverses
129  do j=1,jmax-1
130  dth = t(j+1) - t(j)
131  dti = 1.0d0/dth
132  dt_sav(j) = dth
133  dti_sav(j) = dti
134  end do
135  do i=1,imax-1
136  dd = d(i+1) - d(i)
137  ddi = 1.0d0/dd
138  dd_sav(i) = dd
139  ddi_sav(i) = ddi
140  enddo
141 
142 !..close the file
143  close(chem_pot_unit)
144  end if
145 
146 !..normal execution starts here
147 !..enter the table with ye*den
148 
149  din = ye*den
150 
151 
152 !..bomb proof the input
153  if (temp .gt. t(jmax)) then
154  call raise_exception("Temperature ("//num_to_str(temp)//&
155  ") was off the grid (hotter than "//num_to_str(t(jmax))//"K) "//new_line("A")//&
156  "when trying to interpolate electron and positron chemical potentials."//new_line("A")//&
157  "Check your conditions or consider to switch off theoretical weak rates (iwformat = 0).", &
158  "chempot",&
159  130003)
160  ! write(6,'(1x,5(a,1pe11.3))') 'temp=',temp,' t(jmax)=',t(jmax)
161  ! write(6,*) 'temp too hot, off grid, returning'
162  ! return
163  end if
164  if (temp .lt. t(1)) then
165  call raise_exception("Temperature ("//num_to_str(temp)//&
166  ") was off the grid (colder than "//num_to_str(t(1))//"K) "//new_line("A")//&
167  "when trying to interpolate electron and positron chemical potentials."//new_line("A")//&
168  "Check your conditions or consider to switch off theoretical weak rates (iwformat = 0).", &
169  "chempot",&
170  130004)
171  ! write(6,'(1x,5(a,1pe11.3))') 'temp=',temp,' t(1)=',t(1)
172  ! write(6,*) 'temp too cold, off grid, returning'
173  ! return
174  end if
175  if (din .gt. d(imax)) then
176  call raise_exception("Density * Ye ("//num_to_str(din)//&
177  ") was off the grid (larger than "//num_to_str(d(imax))//") "//new_line("A")//&
178  "when trying to interpolate electron and positron chemical potentials."//new_line("A")//&
179  "Density: "//num_to_str(den)//" g/ccm, Ye: "//num_to_str(ye)//new_line("A")//&
180  "Check your conditions or consider to switch off theoretical weak rates (iwformat = 0).", &
181  "chempot",&
182  130005)
183  ! write(6,'(1x,5(a,1pe11.3))') 'den*ye=',din,' d(imax)=',d(imax)
184  ! write(6,*) 'ye*den too big, off grid, returning'
185  ! return
186  end if
187  if (din .lt. d(1)) then
188  call raise_exception("Density * Ye ("//num_to_str(din)//&
189  ") was off the grid (smaller than "//num_to_str(d(1))//") "//new_line("A")//&
190  "when trying to interpolate electron and positron chemical potentials."//new_line("A")//&
191  "Density: "//num_to_str(den)//" g/ccm, Ye: "//num_to_str(ye)//new_line("A")//&
192  "Check your conditions or consider to switch off theoretical weak rates (iwformat = 0).", &
193  "chempot",&
194  130006)
195  ! write(6,'(1x,5(a,1pe11.3))') 'ye*den=',din,' d(1)=',d(1)
196  ! write(6,*) 'ye*den too small, off grid, returning'
197  ! return
198  end if
199 
200 !..initialize
201  deni = 1.0d0/den
202  tempi = 1.0d0/temp
203  kt = unit%kerg * temp
204  ktinv = 1.0d0/kt
205  beta = kt/mecc
206  dbetadt = unit%kerg/mecc
207 
208 !..hash locate this temperature and density
209  jat = int((log10(temp) - tlo)*tstpi) + 1
210  jat = max(1,min(jat,jmax-1))
211  iat = int((log10(din) - dlo)*dstpi) + 1
212  iat = max(1,min(iat,imax-1))
213 
214 !..look in the electron chemical potential table only once
215  fi(1) = ef(iat,jat)
216  fi(2) = ef(iat+1,jat)
217  fi(3) = ef(iat,jat+1)
218  fi(4) = ef(iat+1,jat+1)
219  fi(5) = eft(iat,jat)
220  fi(6) = eft(iat+1,jat)
221  fi(7) = eft(iat,jat+1)
222  fi(8) = eft(iat+1,jat+1)
223  fi(9) = efd(iat,jat)
224  fi(10) = efd(iat+1,jat)
225  fi(11) = efd(iat,jat+1)
226  fi(12) = efd(iat+1,jat+1)
227  fi(13) = efdt(iat,jat)
228  fi(14) = efdt(iat+1,jat)
229  fi(15) = efdt(iat,jat+1)
230  fi(16) = efdt(iat+1,jat+1)
231 
232 !..get the interpolation weight functions
233 
234  xt = max( (temp - t(jat))*dti_sav(jat), 0.0d0)
235  xd = max( (din - d(iat))*ddi_sav(iat), 0.0d0)
236  mxt = 1.0d0 - xt
237  mxd = 1.0d0 - xd
238 
239  si0t = xpsi0(xt)
240  si1t = xpsi1(xt)*dt_sav(jat)
241 
242  si0mt = xpsi0(mxt)
243  si1mt = -xpsi1(mxt)*dt_sav(jat)
244 
245  si0d = xpsi0(xd)
246  si1d = xpsi1(xd)*dd_sav(iat)
247 
248  si0md = xpsi0(mxd)
249  si1md = -xpsi1(mxd)*dd_sav(iat)
250 
251 !..derivatives of weight functions
252  dsi0t = xdpsi0(xt)*dti_sav(jat)
253  dsi1t = xdpsi1(xt)
254 
255  dsi0mt = -xdpsi0(mxt)*dti_sav(jat)
256  dsi1mt = xdpsi1(mxt)
257 
258  dsi0d = xdpsi0(xd)*ddi_sav(iat)
259  dsi1d = xdpsi1(xd)
260 
261  dsi0md = -xdpsi0(mxd)*ddi_sav(iat)
262  dsi1md = xdpsi1(mxd)
263 
264 !..electron chemical potential
265  etaele = h3(iat,jat, &
266  si0t, si1t, si0mt, si1mt, &
267  si0d, si1d, si0md, si1md)
268 
269 !..derivative with respect to density
270  x = h3(iat,jat, &
271  si0t, si1t, si0mt, si1mt, &
272  dsi0d, dsi1d, dsi0md, dsi1md)
273  detadd = ye * x
274 
275 !..derivative with respect to temperature
276  detadt = h3(iat,jat, &
277  dsi0t, dsi1t, dsi0mt, dsi1mt, &
278  si0d, si1d, si0md, si1md)
279 
280 !..positron chemical potential
281  etapos = 0.0d0
282  detapdd = 0.0d0
283  detapdt = 0.0d0
284 
285  if (beta .gt. positron_start) then
286  etapos = -etaele - 2.0d0/beta
287  detapdd = -detadd
288  detapdt = -detadt + 2.0d0/beta**2 * dbetadt
289  end if
290 
291  return
292 
293 end subroutine chempot
error_msg_class
Error handling routines.
Definition: error_msg_class.f90:16
error_msg_class::raise_exception
subroutine, public raise_exception(msg, sub, error_code)
Raise a exception with a given error message.
Definition: error_msg_class.f90:245
parameter_class::unit
type(unit_type), public unit
constants and unit conversion factors
Definition: parameter_class.f90:54
file_handling_class
Provide some basic file-handling routines.
Definition: file_handling_class.f90:18
error_msg_class::num_to_str
character(:) function, allocatable, public num_to_str(num)
Converts a given real to a string with format "(1pE10.2)".
Definition: error_msg_class.f90:205
chempot
subroutine chempot(temp, den, ye, etaele, etapos)
Given a temperature temp [K], density den [g/cm**3], and a composition characterized by y_e,...
Definition: chem_pot.f90:25
file_handling_class::open_infile
integer function, public open_infile(file_name)
Same for reading (input file)
Definition: file_handling_class.f90:126
parameter_class::chem_pot_file
character(max_fname_len) chem_pot_file
tabulated chemical potential of electron gas
Definition: parameter_class.f90:172
parameter_class
Contains all runtime parameters as well as phys and math constants.
Definition: parameter_class.f90:24