def dynamic_height_1d(Tb, Sb, dT, dS): # # INPUT: background Tb and Sb # departure from background: dT, dS # OUTPUT: Dynamic height departure from background # ogrid = ModelGrid(fname='../wrkdir/grid_spec.nc') p = np.ones(np.shape(Sb)) h = np.ones(np.shape(Sb)) for index in range(0, np.shape(p)[0]): p[index] = ogrid.zt[index] if (index == 0): h[index] = ogrid.zb[index] #-eta else: h[index] = abs(ogrid.zb[index] - ogrid.zb[index - 1]) print 'compute rho' rho_b = eos.density(Sb, Tb, p) rho_a = eos.density(Sb + dS, Tb + dT, p) rho_a_halo = eos.density(Sb + dS, Tb, p) rho_a_thermo = eos.density(Sb, Tb + dT, p) dh = -np.nansum(h * (rho_a - rho_b) / rho_b, axis=0) dh_halo = -np.nansum(h * (rho_a_halo - rho_b) / rho_b, axis=0) dh_thermo = -np.nansum(h * (rho_a_thermo - rho_b) / rho_b, axis=0) return dh, dh_thermo, dh_halo
def central_values(Pc, delta_m, mue): """ Constructs the boundary conditions at the edge of a small, constant density core of mass delta_m with central pressure P_c Arguments Pc central pressure (units = Pa) delta_m core mass (units = kg) mue nucleon/electron ratio Returns z = array([ r, p ]) central values of radius and pressure (units = m, Pa) """ z = np.zeros(2) r_delta_m = ((3 * delta_m) / (4 * sc.pi * density(Pc, mue)))**( 1 / 3) #Radius depends on delta_m and density p_delta_m = Pc #Pressure is equal to Pc # compute initial values of z = [ r, p ] z = [r_delta_m, p_delta_m] return z
def stellar_derivatives(m, z, mue): """ RHS of Lagrangian differential equations for radius and pressure Arguments m current value of the mass (units = kg) z (array) current values of (radius, pressure) (units = m, Pa) Returns dzdm (array) Lagrangian derivatives dr/dm, dP/dm (units =m/kg,Pa/kg) """ rho = density(z[1], mue) drdm = 1 / (4 * np.pi * z[0]**2 * rho ) #Lagrangian Derivative of r w.r.t. m dpdm = (-sc.G * m) / (4 * z[0]**4 * np.pi ) #Lagrangian Derivative of p w.r.t. m dzdm = np.zeros_like(z) dzdm[0] = drdm dzdm[1] = dpdm return dzdm
def create_table(): """ Creates tables of values and saves them as a .txt file returns: nothing explicitly, function creates table """ outfile = 'table.txt' with open(outfile, 'w') as fout: fout.write( ' | {0:7} | {1:7} | {2:7} | {3:7} | {4:7} | {5:7} | \n'.format( 'M/M_sun ', 'R/R_sun', 'P_c (MKS)', 'P_c / GM^2R^-4', 'rho_c (MKS)', 'rho / [3M /4 *pi R^3] ')) # '--:' means right-align fout.write( ' | {0:7} | {1:7} | {2:7} | {3:7} | {4:7} | {5:7} | \n'.format( '--:', '--:', '--:', '--:', '--:', '--:')) for i in range(len(actual_masses)): mass = actual_masses[i] Pc, ms, rs, ps = get_zeros(mass) #getting actual central density and radius central_r = rs[-1] central_dens = density(ps[0], mue) fout.write( ' | {0:7.1f} | {1:7e} | {2:7e} | {3:7e} | {4:7e} | {5:7f} | \n' .format(mass / sc.Msun, central_r / sc.Rsun, Pc, Pc * central_r**4 / (sc.G * mass**2), central_dens, central_dens / (3 * mass / (4 * np.pi * central_r**3))))
def rotprofile(eos, energy_center, number=100, initr=0.001, energy_0=1e7): '''Calculate the enthalpy profile of a slowly rotating neutron star with equation of state eos and central energy density energy_center in g/cm^3. optional arguments: number: number of points initr: size of central seed energy_0: energy density at which to stop resolving crust. This doesn't need to be tiny (and may cause problems if it is). Integration still goes to surface. ''' #TODO: consolodate the profile functions; this mostly just repeats #profile but with different initial conditions # central enthalpy and density enth_c = eos.enthalpy(energy_center) dens_c = eos.density(enth_c) # set up a core with small initial radius and mass initm = 4.0 / 3.0 * np.pi * (initr)**3 * energy_center * Gcc initma = 4.0 / 3.0 * np.pi * (initr)**3 * dens_c * Gcc init_rm = np.array([initr, initm, initma, 0.0, 1.0]) # resolve core with linear spacing linenths = np.linspace(enth_c, enth_c / 10, number)[:-1] # resolve crust with log enth spacing enth_0 = eos.enthalpy(energy_0) # end the crust spacing here and jump to 0 logenths = np.logspace(np.log10(linenths[-1]), np.log10(enth_0), number / 2 + 1) # set of enthalpies to calculate energy density, radius, and mass at enths = np.hstack( (np.array(linenths), np.array(logenths[1:]), np.array(0))) # enths = np.linspace(enth_c, 0, number) # boring way for debugging # integrate the TOV equations specified in deriv above rms = integrate.odeint(rotderiv, init_rm, enths, args=(eos, )) return np.vstack((enths, np.transpose(rms)))
def rotprofile(eos, energy_center , number=100, initr=0.001, energy_0=1e7): '''Calculate the enthalpy profile of a slowly rotating neutron star with equation of state eos and central energy density energy_center in g/cm^3. optional arguments: number: number of points initr: size of central seed energy_0: energy density at which to stop resolving crust. This doesn't need to be tiny (and may cause problems if it is). Integration still goes to surface. ''' #TODO: consolodate the profile functions; this mostly just repeats #profile but with different initial conditions # central enthalpy and density enth_c = eos.enthalpy(energy_center) dens_c = eos.density(enth_c) # set up a core with small initial radius and mass initm = 4.0/3.0*np.pi*(initr)**3 * energy_center * Gcc initma = 4.0/3.0*np.pi*(initr)**3 * dens_c * Gcc init_rm = np.array([initr,initm, initma, 0.0, 1.0]) # resolve core with linear spacing linenths = np.linspace(enth_c, enth_c/10, number)[:-1] # resolve crust with log enth spacing enth_0 = eos.enthalpy(energy_0) # end the crust spacing here and jump to 0 logenths = np.logspace(np.log10(linenths[-1]),np.log10(enth_0), number/2+1) # set of enthalpies to calculate energy density, radius, and mass at enths = np.hstack((np.array(linenths),np.array(logenths[1:]),np.array(0))) # enths = np.linspace(enth_c, 0, number) # boring way for debugging # integrate the TOV equations specified in deriv above rms = integrate.odeint(rotderiv, init_rm, enths, args=(eos,)) return np.vstack((enths,np.transpose(rms)))
def rotderiv(rm_vector, enthalpy, eos): ''' The TOV equations augmented for a linearly perturbed, slowly rotating neutron star. Also includes rest mass of star.''' (rad, mass, restmass, alpha, omega) = rm_vector pr = eos.pressure(enthalpy) * Gcc en = eos.energy(enthalpy) * Gcc rho = eos.density(enthalpy)**Gcc factor = rad - 2 * mass coef = 4.0 * np.pi drdenth = -rad * factor / (mass + coef * rad**3 * pr) dmdenth = coef * en * rad**2 * drdenth dmadenth = coef * rho * rad**2 * drdenth / (factor / rad)**0.5 domega = alpha * drdenth dalpha = drdenth * (- 4.0 * alpha / rad \ + coef * rad * (pr + en) * (4.0 * omega + rad * alpha ) / factor ) return np.array([drdenth, dmdenth, dmadenth, dalpha, domega])
def rotderiv(rm_vector, enthalpy, eos): ''' The TOV equations augmented for a linearly perturbed, slowly rotating neutron star. Also includes rest mass of star.''' (rad, mass, restmass, alpha, omega) = rm_vector pr = eos.pressure(enthalpy) * Gcc en = eos.energy(enthalpy) * Gcc rho = eos.density(enthalpy) ** Gcc factor = rad - 2 * mass coef = 4.0 * np.pi drdenth = - rad * factor / (mass + coef * rad**3 * pr) dmdenth = coef * en * rad**2 * drdenth dmadenth = coef * rho * rad**2 * drdenth / ( factor / rad )**0.5 domega = alpha * drdenth dalpha = drdenth * (- 4.0 * alpha / rad \ + coef * rad * (pr + en) * (4.0 * omega + rad * alpha ) / factor ) return np.array([drdenth,dmdenth, dmadenth, dalpha, domega])
def steric(Tb, Sb, dT, dS, deta, eta): ogrid = ModelGrid(fname='../wrkdir/grid_spec.nc') p = np.ones(np.shape(Sb)) h = np.ones(np.shape(Sb)) for index in range(0, np.shape(p)[0]): p[index, :, :] = ogrid.zt[index] if (index == 0): h[index, :, :] = ogrid.zb[index] #-eta else: h[index, :, :] = abs(ogrid.zb[index] - ogrid.zb[index - 1]) rho_b = eos.density(Sb, Tb, p) rho_a = eos.density(Sb + dS, Tb + dT, p) rho_a_halo = eos.density(Sb + dS, Tb, p) rho_a_thermo = eos.density(Sb, Tb + dT, p) dsteric = -np.nansum(h * (rho_a - rho_b) / rho_b, axis=0) dhalosteric = -np.nansum(h * (rho_a_halo - rho_b) / rho_b, axis=0) dthermosteric = -np.nansum(h * (rho_a_thermo - rho_b) / rho_b, axis=0) return dsteric, dhalosteric, dthermosteric ''' print np.shape(dsteric), np.shape(Sb) dsteric[dsteric==0.0]=np.nan deta[deta==0.0]=np.nan print 'deta-dsteric=',np.nansum(np.abs(deta-dsteric)) fig = plt.figure(num=1, figsize=(19,12), facecolor='w') #grid = AxesGrid(fig, 111, nrows_ncols = (2, 3), axes_pad = 0.5, # cbar_location="bottom", # cbar_mode="each", # cbar_size="7%", # cbar_pad="2%") vmax=0.1 vmin=-vmax #plt.sca(grid[0]) plt.subplot(231) ch=plt2d(ogrid.x, ogrid.y, dsteric, minval=vmin, maxval=vmax, colmap=cm.jet) #grid.cbar_axes[0].colorbar(ch) plt.title('Steric height infered increment [m]') #plt.sca(grid[1]) plt.subplot(232) incr_s=np.flipud(dhalosteric) incr_s[incr_s==0.0]=np.nan ch=plt2d(ogrid.x, ogrid.y, dhalosteric, minval=vmin, maxval=vmax, colmap=cm.jet) #grid.cbar_axes[1].colorbar(ch) plt.title('Halo Steric height infered increment [m]') #plt.sca(grid[2]) plt.subplot(233) incr_t=np.flipud(dthermosteric) incr_t[incr_t==0.0]=np.nan ch=plt2d(ogrid.x, ogrid.y, dthermosteric, minval=vmin, maxval=vmax, colmap=cm.jet) #grid.cbar_axes[2].colorbar(ch) plt.title('Thermo Steric height infered increment [m]') #plt.sca(grid[3]) plt.subplot(234) ch=plt2d(ogrid.x, ogrid.y, deta, minval=vmin, maxval=vmax, colmap=cm.jet) #grid.cbar_axes[3].colorbar(ch) plt.title('SSH increment [m]') vmin=-0.1 vmax=0.1 #plt.sca(grid[4]) plt.subplot(235) err=deta-dsteric #err[np.abs(err)<0.05]=np.nan #err=np.abs(deta/dsteric) ch=plt2d(ogrid.x, ogrid.y, err, minval=vmin, maxval=vmax, colmap=cm.bwr) #grid.cbar_axes[4].colorbar(ch) plt.title('SSH - Steric [m]') #plt.sca(grid[5]) plt.subplot(236) err=deta-dthermosteric #err=np.abs(deta/dthermosteric) #err[np.abs(err)<0.05]=np.nan ch=plt2d(ogrid.x, ogrid.y, err, minval=vmin, maxval=vmax, colmap=cm.bwr) #grid.cbar_axes[5].colorbar(ch) plt.title('SSH - Thermosteric [m]') ''' plt.subplot(235) incr_t = np.flipud(dthermosteric) incr_t[incr_t == 0.0] = np.nan plt.imshow(incr_t, vmin=vmin, vmax=vmax) #plt.imshow(np.flipud(dthermosteric),vmin=vmin,vmax=vmax) plt.colorbar() plt.subplot(231) plt.imshow(np.flipud(deta), vmin=vmin, vmax=vmax) plt.title('SSH increment [m]') plt.colorbar() plt.subplot(233) err = np.flipud(deta - dsteric) err[np.abs(err) < 0.02] = np.nan plt.imshow(err, vmin=vmin, vmax=vmax) #plt.imshow(np.flipud(deta-dsteric),vmin=vmin,vmax=vmax) plt.title('SSH - Steric height [m]') plt.colorbar() '''