Beispiel #1
0
 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
Beispiel #2
0
 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]"
Beispiel #3
0
 def dynamical_update(self, dt):
     self.eta_s = conduction.fac_conduction_density(self.q_s, self.mach)
     self.tau_s = conduction.fac_conduction_temperature(self.q_s, self.mach)
     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
     self.tau_evap = conduction.tau_evap(self.M_c, self.r_c, n_ps,
                                         T_ps) * self.f_cond
     self.tau_evap = self.tau_evap / (self.L / (2.0 * self.r_c))
     mlr = conduction.mass_loss_rate(self.r_c, n_ps, T_ps) * 0.5  # Head
     mlr += conduction.mass_loss_rate(self.r_c, FACDENS * self.n_a,
                                      FACTEMP * self.T_a) * self.L / (
                                          2.0 * self.r_c)  # Tail
     self.tau_evap = self.M_c / mlr * self.f_cond
     # Calculate Acceleration
     p_therm_c = self.n_c * self.T_c * pc.k
     p_therm_a = self.n_a * self.T_a * pc.k
     p_ps = n_ps * T_ps * 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
     if (self.gravity == True):
         a_grav = self.V_c**2 / self.r
         self.vrel = self.vrel - a_grav * dt
     self.mach = self.vrel / self.cs_a
     P_evap = 3.59 * conduction.sigma_cond(self.r_c, n_ps, T_ps)**0.28
     if (self.tau_evap > 0):
         if (P_evap > 1.0): tau_disrupt = self.tau_evap
         else: tau_disrupt = 1. / (1. / self.tau_evap + 1. / self.tau_khi)
     else: tau_disrupt = self.tau_khi
     self.M_c = self.M_c * exp(-dt / tau_disrupt)
     print "Mc=%4.2f t(KHI,evap,cc)=%5.2f, %5.2f, %5.2f mach=%4.2f Pevap/Pth=%4.2f" % (
         self.M_c / params.M_c, self.tau_khi / ac.myr,
         self.tau_evap / ac.myr, self.tau_cc / ac.myr, self.mach, P_evap)
     # ---------------- The Expansion ----------------
     rho_eq = self.rho_a * self.T_a / self.T_c
     L_eq = self.M_c / (rho_eq * self.r_c * self.r_c * pi)
     v_exp = self.v_shock - (self.v_h - self.vrel)
     if (v_exp < 0): v_exp = 0
     self.L = self.L + v_exp * dt
     # Here using free expansion approximation: v = 2.0 * c / (gamma - 1)
     self.r_c = sqrt(self.M_c / (self.N_c * pc.mh * self.mu) / pi)
     if (self.L > L_eq): self.L = L_eq
     self.rho_c = self.M_c / (self.L * self.r_c * self.r_c * pi)
     self.n_c = self.rho_c / (pc.mh * self.mu)
Beispiel #4
0
 def dynamical_update(self, dt):
     self.eta_s = 1. / conduction.fac_conduction_x(self.q_s, self.mach)
     self.tau_s = conduction.ratio_temperature(self.q_s, self.mach)
     T_ps = max(self.tau_s, 1.0)
     T_ps = T_ps * self.T_a
     n_ps = self.n_a * self.eta_s
     # The Cowie & McKee 1977 conduction rate
     self.tau_evap = conduction.tau_evap(self.M_c, self.r_c, n_ps,
                                         T_ps) * self.f_cond
     # self.tau_evap = self.M_c / mlr * self.f_cond
     # Calculate Acceleration
     p_therm_c = self.n_c * self.T_c * pc.k
     p_therm_a = self.n_a * self.T_a * pc.k
     p_ps = n_ps * T_ps * pc.k
     # self.rho_c = self.rho_c0 * p_ps / p_therm_a
     self.a_ram = p_ps * pi * self.r_c**2 / self.M_c  #/ self.pressure_factor
     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
     if (self.gravity == True):
         a_grav = self.V_c**2 / self.r
         self.vrel = self.vrel - a_grav * dt
     self.mach = self.vrel / self.cs_a
     P_evap = 3.59 * conduction.sigma_cond(self.r_c, n_ps, T_ps)**0.28
     if (self.tau_evap > 0):
         if (P_evap > 1.0): tau_disrupt = self.tau_evap
         else: tau_disrupt = 1. / (1. / self.tau_evap + 1. / self.tau_khi)
     else: tau_disrupt = self.tau_khi
     self.M_c = self.M_c * exp(-dt / tau_disrupt)
     if (VERBOSE == True):
         print "Mc=%4.2f t(KHI,evap,cc)=%5.2f, %5.2f, %5.2f mach=%4.2f Pevap/Pth=%4.2f" % (
             self.M_c / params.M_c, self.tau_khi / ac.myr, self.tau_evap /
             ac.myr, self.tau_cc / ac.myr, self.mach, P_evap)
     # ---------------- The Expansion ----------------
     self.tclock -= dt
     self.rho_c = self.rho_c0 * (p_ps / p_therm_a / self.pressure_factor)
     if (ADJUST_RCLOUD_FOR_VAPORPRESSURE):
         self.rho_c *= P_evap
     self.r_c = (0.75 * self.M_c / self.rho_c / pi)**(1. / 3.
                                                      )  # # SPHERICAL cloud
     # self.r_c = sqrt(self.M_c / (self.N_c * pc.mh * self.mu) / pi)
     self.n_c = self.rho_c / (pc.mh * self.mu)
Beispiel #5
0
    def dynamical_update(self, dt):
        self.eta_s = 1. / conduction.fac_conduction_x(self.q_s, self.mach)
        self.tau_s = conduction.ratio_temperature(self.q_s, self.mach)
        T_ps = max(self.tau_s, 1.0)
        T_ps = T_ps * self.T_a
        n_ps = self.n_a * self.eta_s
        # self.tau_evap = conduction.tau_evap(self.M_c, self.r_c, n_ps, T_ps) / self.f_cond
        # self.tau_evap = self.tau_evap / (self.L / (2.0 * self.r_c))

        # mlr = conduction.mass_loss_rate(self.r_c, n_ps, T_ps) * 0.5 # Head
        # mlr_tail = conduction.mass_loss_rate(self.r_c, self.n_a, self.T_a)
        # mlr += mlr_tail * self.L / (2.0 * self.r_c) # Tail
        # mlr = conduction.mass_loss_rate(self.r_c, n_ps, T_ps) / self.v_max * self.L / (2.0 * self.r_c)
        # mlr = conduction.mass_loss_rate(self.r_c, n_ps, T_ps) / 3.5 * self.L / (2.0 * self.r_c)
        # mlr = 2.3e-34 * T_ps ** 2.5 * self.L / 3.5 * 2. * pi * ac.pc / 3.5

        mlr_tail = 4.46e-15 * self.T_a**2.5 / (self.r_c)
        self.v_max = -log(mlr_tail * self.time / self.rho_c / self.r_c)
        # SH191104: Huge bug identified here... Used to be > 0
        # SH191106: A more robust way of doing evaporation
        if (conduction.evaluate_saturation_point(self.T_c, n_ps, T_ps,
                                                 self.r_c) < 0):
            # The classical conduction all the way down. No turning point.
            T_star = 1.e4
            # mlr = 4.46e-15 * (T_ps ** 2.5 - T_star ** 2.5) * self.L / 3.5 # Equation (1)
        else:
            T_star = conduction.solve_for_saturation_point(n_ps,
                                                           T_ps,
                                                           self.r_c,
                                                           T_c=self.T_c,
                                                           verbose=False)
            # mlr = 1.42e-25 * n_ps * T_ps * self.r_c * T_star ** 1.03 * self.L / 3.5 Equation (2)
            # Should be equivalent to Equation (1)
        mlr = 4.46e-15 * (T_ps**2.5 -
                          T_star**2.5) * self.L / 3.5  # Equation (1)

        # print n_ps, T_ps/1.e6, T_star/1.e6
        # mlr = 1.56e-15 * T_ps ** 2.5 * self.L
        self.tau_evap = self.M_c / mlr / self.f_cond
        # pdb.set_trace()
        # Calculate Acceleration
        p_therm_c = self.n_c * self.T_c * pc.k
        p_therm_a = self.n_a * self.T_a * pc.k
        p_ps = n_ps * T_ps * pc.k
        # Here we assume rho_c do not change with time???
        # if(ADJUST_RHOC_WITH_PEVAP):
        #     p_evap_ratio = conduction.evap_pressure_fac(self.r_c, n_ps, T_ps)
        #     if(p_evap_ratio > 1):
        #         self.rho_c *= p_evap_ratio
        #         self.r_c *= (p_evap_ratio) ** (-1./3.)
        # self.rho_c = self.rho_c0 * p_ps / p_therm_a

        self.a_ram = p_ps * pi * self.r_c**2 / self.M_c  #/ self.pressure_factor
        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
        if (self.gravity == True):
            a_grav = self.V_c**2 / self.r
            self.vrel = self.vrel - a_grav * dt
        self.mach = self.vrel / self.cs_a
        P_evap = 3.59 * conduction.sigma_cond(self.r_c, n_ps, T_ps)**0.28
        if (KHI_MODIFIED_TIMESCALE):
            lkh = conduction.lambda_kh(1.0,
                                       self.n_c / n_ps,
                                       T_ps,
                                       n_ps,
                                       fcond=self.f_cond)
            # print "LKH, Rc = ", lkh/ac.pc, self.r_c/ac.pc
            tau_disrupt = 1. / (1. / self.tau_evap +
                                exp(-lkh / self.r_c) / self.tau_khi)
            self.lkh = lkh
            self.n_ps, self.T_ps = n_ps, T_ps
        else:
            tau_disrupt = self.tau_evap
        self.M_c = self.M_c * exp(-dt / tau_disrupt)
        if (VERBOSE == True):
            print "Mc=%4.2f t(KHI,evap,cc)=%5.2f, %5.2f, %5.2f mach=%4.2f Pevap/Pth=%4.2f" % (
                self.M_c / params.M_c, self.tau_khi / ac.myr, self.tau_evap /
                ac.myr, self.tau_cc / ac.myr, self.mach, P_evap)
        # ---------------- The Expansion ----------------
        self.tclock -= dt
        self.v_max = min(self.v_max, log(self.rho_c / self.rho_c0))
        # print self.v_max, log(self.rho_c/self.rho_c0)
        # self.v_max = log(self.rho_c/self.rho_c0)
        if (self.n_poly == 1.0):
            v_exp = self.cs_c * self.v_max
        elif (self.n_poly > 1.0):
            v_exp = 2.0 * self.cs_c / (self.n_poly - 1.0)
        # flux_cond = mlr_tail
        # flux_mass = self.rho_c * exp(-self.v_max) * self.v_max * self.cs_c
        # if(flux_cond <= flux_mass and self.rho_c * exp(-self.v_max) > self.rho_c0 and self.L < 250.*ac.pc): # Only expand when evaporation is inefficient
        if (self.v_max > 0.0):  # Only expand when evaporation is inefficient
            self.L_prev = self.L
            self.L = self.L + v_exp * dt
            # if(self.time / self.tau_cc >= 15. and self.debug_flag == 1):
            #     print flux_cond / flux_mass
            #     self.debug_flag = 0
        else:
            if (self.L_prev < self.L):
                print "Lmax reached: t= %5.1f, L= %5.2f, v_max = %3.1f\n" % \
                    (self.time/self.tau_cc, self.L/ac.pc, self.v_max)
                self.L_prev = self.L
            # Set a timer when the new tail end reaches L
        # self.L = self.L - (self.v_h - self.vrel) * dt
        # ----------------------------------------------------------------
        # note 3: How does the internal structure evolve with time?
        # ----------------------------------------------------------------
        # OPTION 1: Allow rho_c (head density) to change
        # if(self.rho_c > self.rho_c0 * (p_ps / p_therm_a / self.pressure_factor)): # Density is still large
        #     self.rho_c = self.rho_c * self.L_prev / self.L
        #     self.r_c = sqrt(self.M_c / (self.rho_c * pi * self.L / 4.0))
        # else: # Density reaches the 1/3 value
        # OPTION 2: Make rho_c strictly as constrained by the post-shock gas. Let R_c change
        self.rho_c = self.rho_c0 * (p_ps / p_therm_a / self.pressure_factor)
        # self.r_c = sqrt(self.M_c / (self.rho_c * pi * self.L / self.v_max)) # If we let the Pc = Pa
        self.r_c = sqrt(self.M_c / (self.N_c * pc.mh * self.mu) / pi)
        self.n_c = self.rho_c / (pc.mh * self.mu)