def cloud_shock(self, conduction_flag=False, verbose=False): v_shock_approx = self.r_c / self.tau_cc fac_ram = bowshock.ram_pressure_fac(self.mach) * params.ram p_ps = fac_ram * self.rho_a * self.vrel**2 v_shock = sqrt(p_ps / self.p_c) * self.cs_c self.rho_c = self.rho_a * (self.vrel / self.cs_c)**2 # self.rho_c = self.rho_c * (v_shock / self.cs_c) ** 2 self.r_c = (self.M_c / self.rho_c / pi)**(1. / 3. ) # cylindrical geometry if (conduction_flag == True): T_ps = bowshock.rh_temperature_ratio(self.mach) * params.T_ps if (T_ps < 1): T_ps = 1 T_ps = T_ps * self.T_a n_ps = self.n_a * bowshock.rh_density_ratio( self.mach) * params.n_ps # self.rho_c *= conduction.evap_pressure_fac(self.r_c, self.n_a, self.T_a) else: n_ps, T_ps = self.n_a, self.T_a self.rho_c *= conduction.evap_pressure_fac(self.r_c, n_ps, T_ps) print "fac =", conduction.evap_pressure_fac(self.r_c, n_ps, T_ps) self.n_c = self.rho_c / (pc.mh * 1.30) p_therm_c = self.n_c * self.T_c * pc.k p_therm_a = n_ps * T_ps * pc.k print "c_evap = ", conduction.evap_pressure_fac(self.r_c, n_ps, T_ps) * p_therm_a * \ 4. * pi * self.r_c ** 2 / conduction.mass_loss_rate(self.r_c, n_ps, T_ps) / (1.e5) self.r_c = (self.M_c / self.rho_c / pi)**(1. / 3. ) # cylindrical geometry v_ps = v_shock - self.cs_c**2 / v_shock # post-shock velocity in rest-frame p_cond = conduction.evap_pressure_fac(self.r_c, n_ps, T_ps) * p_therm_a self.tau_evap = conduction.tau_evap(self.M_c, self.r_c, n_ps, T_ps) self.tau_khi = bowshock.fac_khi(self.mach) * self.tau_cc self.N_c = self.M_c / (1.30 * pc.mh * pi * self.r_c * self.r_c) self.L = self.r_c # self.vrel = self.vrel - v_shock fac_ram = bowshock.ram_pressure_fac(self.mach) * params.ram p_ps = fac_ram * self.rho_a * self.vrel**2 # self.a_ram = (p_ps - p_therm_a) * pi * self.r_c ** 2 / self.M_c self.a_ram = (p_ps - self.T_a * self.n_a * pc.k) * pi * ( 0.1 * ac.kpc)**2 / self.M_c self.vrel = self.vrel - self.a_ram * self.tau_cc if (verbose == True): print "" print "Post Cloud Shock" print "--------------------------------" print "n_c = ", self.n_c, "[cm^-3]" print "R_c = ", self.r_c / ac.kpc * 1.e3, "[pc]" print "v_shock = ", v_shock / 1.e5, "[km/s]" print "v_shock_approx = ", v_shock_approx / 1.e5, "[km/s]" print "Pc/k = ", p_therm_c / pc.k, "[K]" print "Pa/k = ", p_therm_a / pc.k, "[K]" print "Pps/k = ", p_ps / pc.k, "[K]" print "Pcond/k = ", p_cond / pc.k, "[K]" print "sigma0 = ", conduction.sigma_cond(self.r_c, n_ps, T_ps) print "t_cc = ", self.tau_cc / 1.e6 / ac.yr, "[Myr]" print "t_khi = ", self.tau_khi / 1.e6 / ac.yr, "[Myr]" print "t_evap = ", self.tau_evap / 1.e6 / ac.yr, "[Myr]" print "N_c = ", self.N_c, "[cm^-2]"
def cloud_shock(self): v_shock_approx = self.r_c / self.tau_cc T_ps = bowshock.rh_temperature_ratio(self.mach) * self.tau_s if (T_ps < 1): T_ps = 1 T_ps = T_ps * self.T_a n_ps = self.n_a * bowshock.rh_density_ratio(self.mach) * self.eta_s p_ps = n_ps * T_ps * pc.k p_therm_c = self.n_c * self.T_c * pc.k p_therm_a = self.n_a * self.T_a * pc.k self.v_shock = sqrt(p_ps / self.p_c) * self.cs_c # WARNING: Ignore the pressure difference between stagnation point and the shock front # if(self.mach < 1.2): # p_ps *= bowshock.postshock_pressure_fac(self.mach) self.rho_c = self.rho_c * p_ps / p_therm_a # Isothermal shock condition self.r_c = (self.M_c / self.rho_c / pi)**(1. / 3. ) # cylindrical geometry self.n_c = self.rho_c / (pc.mh * self.mu) # Assuming neutral self.r_c = (self.M_c / self.rho_c / pi)**(1. / 3. ) # cylindrical geometry p_cond = conduction.evap_pressure_fac(self.r_c, n_ps, T_ps) * p_therm_a self.tau_evap = conduction.tau_evap(self.M_c, self.r_c, n_ps, T_ps) * self.f_cond self.tau_khi = bowshock.fac_khi(self.mach) * self.tau_cc self.N_c = self.M_c / (self.mu * pc.mh * pi * self.r_c * self.r_c) self.L = self.r_c # self.vrel = self.vrel - v_shock # fac_ram = bowshock.ram_pressure_fac(self.mach) * params.ram # p_ps = fac_ram * self.rho_a * self.vrel ** 2 self.a_ram = (p_ps - p_therm_a) * pi * (self.r_c)**2 / self.M_c
def cloud_shock(self): self.v_shock_approx = self.r_c / self.tau_cc # Good when conduction is not dynamically important T_ps = max(self.tau_s, 1.0) T_ps = T_ps * self.T_a n_ps = self.n_a * self.eta_s p_ps = n_ps * T_ps * pc.k p_therm_c = self.n_c * self.T_c * pc.k p_therm_a = self.n_a * self.T_a * pc.k self.v_shock = sqrt(p_ps / self.p_c) * self.cs_c self.rho_c = self.rho_c * p_ps / p_therm_a # ---------------------------------------------------------------- # note 1: How do we define R_c after cloud shock? self.r_c = (0.75 * self.M_c / self.rho_c / pi)**(1. / 3. ) # # SPHERICAL cloud if (ADJUST_RCLOUD_FOR_VAPORPRESSURE): p_evap = 3.59 * conduction.sigma_cond(self.r_c, n_ps, T_ps)**0.28 self.rho_c *= p_evap rc_prev = self.r_c self.r_c *= (p_evap)**(-1. / 3.) print "p_evap = %5.3f, r_c(before) = %5.3f pc, r_c(now) = %5.3f pc" % ( p_evap, rc_prev / ac.pc, self.r_c / ac.pc) # L_c changes according the internal structure we assume # ---------------------------------------------------------------- self.n_c = self.rho_c / (pc.mh * self.mu) # Assuming neutral p_evap = conduction.evap_pressure_fac(self.r_c, n_ps, T_ps) * p_therm_a self.tau_evap = conduction.tau_evap(self.M_c, self.r_c, n_ps, T_ps) * self.f_cond self.tau_khi = bowshock.fac_khi(self.mach) * self.tau_cc self.a_ram = p_ps * pi * ( self.r_c)**2 / self.M_c / self.pressure_factor self.debug_flag = 1
def cloud_shock(self): self.v_shock_approx = self.r_c / self.tau_cc # Good when conduction is not dynamically important T_ps = max(self.tau_s, 1.0) T_ps = T_ps * self.T_a n_ps = self.n_a * self.eta_s p_ps = n_ps * T_ps * pc.k p_therm_c = self.n_c * self.T_c * pc.k p_therm_a = self.n_a * self.T_a * pc.k self.v_shock = sqrt(p_ps / self.p_c) * self.cs_c # WARNING: Ignore the pressure difference between stagnation point and the shock front # if(self.mach < 1.2): # p_ps *= bowshock.postshock_pressure_fac(self.mach) self.rho_c = self.rho_c * p_ps / p_therm_a # Isothermal shock condition if (USE_MINIMUM_EXPANSION_SPEED): self.v_max = self.v_shock_approx / self.cs_c - 3.0 # upper limit # self.v_max = self.v_shock_approx # upper limit self.v_max = min(self.v_max, log(self.rho_c / self.rho_c0)) else: self.v_max = log(self.rho_c / self.rho_c0) print "v_shock_approx = %5.3f; v_shock = %5.3f; c*log(rho_c/rho_c0) = %5.3f" % ( self.v_shock_approx / 1.e5, self.v_shock / 1.e5, log(self.rho_c / self.rho_c0) * self.cs_c / 1.e5) # self.v_max = log(self.rho_c/self.rho_c0) self.v_max0 = self.v_max # ---------------------------------------------------------------- # note 1: How do we define R_c after cloud shock? self.r_c = (self.M_c / self.rho_c / pi / 2.)**( 1. / 3.) # cylindrical geometry p_evap_ratio = conduction.evap_pressure_fac(self.r_c, n_ps, T_ps) print " ---> P_evap initial: ", p_evap_ratio if (ADJUST_RHOC_WITH_PEVAP): if (p_evap_ratio > 1): self.rho_c *= p_evap_ratio self.r_c *= (p_evap_ratio)**(-1. / 3.) # L_c changes according the internal structure we assume # 180712: We no longer accept the case with constant density! self.L = 2. * self.r_c self.tau_sc = 2.0 * self.r_c / self.cs_c if (self.n_poly == 1.0): # self.L = self.r_c * self.v_max # isothermal, 5.0 by default, constrained from x300v1700 self.L = self.r_c * 4.0 self.v_max = self.v_max else: self.L = self.r_c * (self.n_poly + 1.0) / (self.n_poly - 1.0) # ---------------------------------------------------------------- self.n_c = self.rho_c / (pc.mh * self.mu) # Assuming neutral self.tau_evap = conduction.tau_evap(self.M_c, self.r_c, n_ps, T_ps) / self.f_cond self.tau_khi = bowshock.fac_khi(self.mach) * self.tau_cc self.N_c = self.M_c / (self.mu * pc.mh * pi * self.r_c * self.r_c) # self.vrel = self.vrel - v_shock # fac_ram = bowshock.ram_pressure_fac(self.mach) * params.ram # p_ps = fac_ram * self.rho_a * self.vrel ** 2 self.a_ram = p_ps * pi * ( self.r_c)**2 / self.M_c / self.pressure_factor self.debug_flag = 1
def dynamical_update(self, dt, verbose=False, conduction_flag=True, compression_flag=False, geometry="spherical"): if (conduction_flag == True): # TRICK # self.a_ram *= conduction.evap_pressure_fac(self.r_c, self.n_a, self.T_a) T_ps = bowshock.rh_temperature_ratio(self.mach) * params.T_ps if (T_ps < 1): T_ps = 1 T_ps = T_ps * self.T_a n_ps = self.n_a * bowshock.rh_density_ratio( self.mach) * params.n_ps else: T_ps, n_ps = self.T_a, self.n_a self.tau_evap = conduction.tau_evap(self.M_c, self.r_c, n_ps, T_ps) # print self.tau_evap / ac.yr / 1.e6, n_ps, T_ps, self.r_c, self.L if (geometry == "cylindrical"): self.tau_evap = self.tau_evap / (self.L / (2.0 * self.r_c)) # self.tau_evap = self.tau_evap mlr = conduction.mass_loss_rate(self.r_c, n_ps, T_ps) * 0.5 mlr += conduction.mass_loss_rate(self.r_c, self.n_a, self.T_a) * self.L / (2.0 * self.r_c) self.tau_evap = self.M_c / mlr print mlr / (conduction.mass_loss_rate(self.r_c, n_ps, T_ps) * 0.5) # Calculate Acceleration fac_ram = bowshock.ram_pressure_fac(self.mach) * params.ram p_ps = fac_ram * self.rho_a * self.vrel**2 p_therm_c = self.n_c * self.T_c * pc.k # p_therm_a = n_ps * T_ps * pc.k p_therm_a = self.n_a * self.T_a * pc.k self.a_ram = (p_ps - p_therm_a) * pi * self.r_c**2 / self.M_c self.tau_khi = bowshock.fac_khi(self.mach) * self.tau_cc # Update Cloud Properties self.time = self.time + dt self.r = self.r + self.vrel * dt self.vrel = self.vrel - self.a_ram * dt self.mach = self.vrel / self.cs_a self.M_c = self.M_c * exp(-dt / self.tau_evap) # self.M_c = self.M_c * exp(-dt / self.tau_khi) # TRICK # rho_eq = conduction.evap_pressure_fac(self.r_c, n_ps, T_ps) * (n_ps / self.n_a) * self.rho_a * T_ps / self.T_c # print rho_eq, self.rho_c, n_ps, T_ps, conduction.evap_pressure_fac(self.r_c, self.n_a, T_ps) # rho_eq = self.rho_a * self.T_a / self.T_c # print rho_eq, self.n_a, self.T_a, conduction.evap_pressure_fac(self.r_c, self.n_a, self.T_a) rho_eq = conduction.evap_pressure_fac( self.r_c, self.n_a, self.T_a) * self.rho_a * self.T_a / self.T_c if (compression_flag == False): L_eq = self.M_c / (rho_eq * self.r_c * self.r_c * pi) self.L = self.L + self.cs_c * dt * 3.0 # Here using free expansion approximation: v = 2.0 * c / (gamma - 1) self.r_c = sqrt(self.M_c / (self.N_c * pc.mh * 1.30) / pi) if (self.L > L_eq): self.L = L_eq else: L_eq = self.M_c / ( (self.T_a * self.rho_a / self.T_c) * self.r_c * self.r_c * pi) # Lower pressure (no vapor pressure), therefore longer L_eq self.L = self.L + self.cs_c * dt * 3.0 if (self.L > L_eq): self.L = L_eq self.rho_c = self.M_c / (self.L * self.r_c * self.r_c * pi) # Allow cloud size to shrink # However, problem is it induces a positive feedback: # Smaller Rc leads to higher vapor pressure and higher rho_eq, the cloud will collapse! if (self.rho_c < rho_eq): self.r_c = sqrt(self.M_c / (rho_eq * self.L * pi)) self.rho_c = self.M_c / (self.L * self.r_c * self.r_c * pi) self.n_c = self.rho_c / (pc.mh * 1.30) if (verbose == True): print "%5.3f(%5.3f) %6.2f %6.1f %5.3f %6.2f(%5.3f) %6.2f %5.3f %7.2f" % \ (self.time/ac.yr/1.e6, self.time/self.tau_cc, self.r / ac.kpc, self.vrel / 1.e5, self.M_c / M_0, \ self.L * 1.e3 / ac.kpc, self.L / L_eq, self.r_c * 1.e3 / ac.kpc, \ self.n_c, self.tau_evap / ac.yr / 1.e6)