def __init__(self, E_0, rho_0, metallicity, gamma=5 / 3): super(SedovSolution, self).__init__() self.E_0 = E_0 # blast energy self.rho_0 = rho_0 # background density (constant spatially) self.mu = calculate_mean_molecular_weight(metallicity) self.gamma = gamma # adiabatic index self.j = 3 # spherical geometry self.w = 0 # uniform background if self.w > (self.j * (3 - self.gamma) + 2 * (self.gamma - 1)) / (self.gamma + 1): raise ValueError("Vacuum case -- invalid choice of gamma") elif self.w == (self.j * (3 - self.gamma) + 2 * (self.gamma - 1)) / (self.gamma + 1): raise ValueError("Singular case -- invalid choice of gamma") # significant self-similatiry parameters, V self.V_0 = 2 / ((self.j + 2 - self.w) * gamma) # origin self.V_2 = 4 / ((self.j + 2 - self.w) * (gamma + 1)) # shock front self.a = (self.j + 2 - self.w) * (gamma + 1) / 4 self.b = (gamma + 1) / (gamma - 1) self.c = (self.j + 2 - self.w) * gamma / 2 self.d = (self.j+2-self.w) * (gamma+1) \ / ( ((self.j+2-self.w)*(gamma+1)) - 2*(2+self.j*(gamma-1))) self.e = (2 + self.j * (gamma - 1)) / 2 self.alpha_0 = 2 / (self.j + 2 - self.w) self.alpha_2 = -(gamma - 1) / (2 * (gamma - 1) + self.j - gamma * self.w) self.alpha_1 = ( (self.j+2-self.w)*gamma / (2 + self.j*(gamma-1)) ) \ * ( ( 2*(self.j*(2-gamma) - self.w)\ / (gamma*(self.j+2-self.w))**2 ) - self.alpha_2 ) self.alpha_3 = (self.j - self.w) / (2 * (gamma - 1) + self.j - gamma * self.w) self.alpha_4 = self.alpha_1 * (self.j+2-self.w)*(self.j-self.w) \ / ( self.j*(2-gamma) - self.w ) self.alpha_5 = ( self.w*(1+gamma) - 2*self.j ) \ / ( self.j*(2-gamma) - self.w ) self.xi_0 = self.get_xi_0() # amortized results: self.E_kin = self.get_E_kin() self.E_int = self.get_E_int() self.E_tot = self.E_kin + self.E_int self.momentum_dimensionless = self.get_momentum_dimensionless()
def __init__(self, E_0, rho_0, metallicity, gamma=5/3): super(SedovSolution, self).__init__() self.E_0 = E_0 # blast energy self.rho_0 = rho_0 # background density (constant spatially) self.mu = calculate_mean_molecular_weight(metallicity) self.gamma = gamma # adiabatic index self.j = 3 # spherical geometry self.w = 0 # uniform background if self.w > ( self.j*(3-self.gamma) + 2*(self.gamma-1) ) / (self.gamma+1): raise ValueError("Vacuum case -- invalid choice of gamma") elif self.w == ( self.j*(3-self.gamma) + 2*(self.gamma-1) ) / (self.gamma+1): raise ValueError("Singular case -- invalid choice of gamma") # significant self-similatiry parameters, V self.V_0 = 2 / ( (self.j+2-self.w) * gamma ) # origin self.V_2 = 4 / ( (self.j+2-self.w)*(gamma+1) ) # shock front self.a = (self.j+2-self.w)*(gamma+1) / 4 self.b = (gamma+1) / (gamma-1) self.c = (self.j+2-self.w) * gamma / 2 self.d = (self.j+2-self.w) * (gamma+1) \ / ( ((self.j+2-self.w)*(gamma+1)) - 2*(2+self.j*(gamma-1))) self.e = (2 + self.j*(gamma-1)) / 2 self.alpha_0 = 2 / (self.j+2-self.w) self.alpha_2 = - (gamma-1) / ( 2*(gamma-1) + self.j - gamma*self.w ) self.alpha_1 = ( (self.j+2-self.w)*gamma / (2 + self.j*(gamma-1)) ) \ * ( ( 2*(self.j*(2-gamma) - self.w)\ / (gamma*(self.j+2-self.w))**2 ) - self.alpha_2 ) self.alpha_3 = (self.j-self.w) / ( 2*(gamma-1) + self.j - gamma*self.w ) self.alpha_4 = self.alpha_1 * (self.j+2-self.w)*(self.j-self.w) \ / ( self.j*(2-gamma) - self.w ) self.alpha_5 = ( self.w*(1+gamma) - 2*self.j ) \ / ( self.j*(2-gamma) - self.w ) self.xi_0 = self.get_xi_0() # amortized results: self.E_kin = self.get_E_kin() self.E_int = self.get_E_int() self.E_tot = self.E_kin + self.E_int self.momentum_dimensionless = self.get_momentum_dimensionless()
def __init__(self, data_dir = None, id = None): super(RunSummary, self).__init__() if data_dir is None: return # create an empty place holder checkpoint_filenames = glob.glob(os.path.join(data_dir, id + "*checkpoint_*.dat")) checkpoint_filenames = sorted(checkpoint_filenames) num_checkpoints = len(checkpoint_filenames) if num_checkpoints == 0: raise FileNotFoundError("No checkpoints found") # ensure that the id is actually the FULL id id = get_full_id_from_partial_id(data_dir, id) times = np.empty(num_checkpoints) for k, checkpoint_filename in enumerate(checkpoint_filenames): f = open(checkpoint_filename, 'r') line = f.readline() times[k] = float(line.split()[3]) f.close() overview = Overview(os.path.join(data_dir, id + "_overview.dat")) mu = calculate_mean_molecular_weight(overview.metallicity) E_int = np.empty(num_checkpoints) E_kin = np.empty(num_checkpoints) momentum = np.empty(num_checkpoints) E_tot = np.empty(num_checkpoints) E_R_int = np.empty(num_checkpoints) # Energy of the remnant E_R_kin = np.empty(num_checkpoints) # Energy of the remnant E_R_tot = np.empty(num_checkpoints) # Energy of the remnant R_shock = np.empty(num_checkpoints) # size of the shock/remnant M_R = np.empty(num_checkpoints) # mass of the shock/remnant M_tot = np.empty(num_checkpoints) Z_tot = np.empty(num_checkpoints) zones = np.empty(num_checkpoints) Luminosity = np.empty(num_checkpoints) zones_for_each_checkpoint = [get_num_zones_in_checkpoint(checkpoint_filename) for checkpoint_filename in checkpoint_filenames] dataframe_columns = ["Radius", "dR", "dV", "Density", "Pressure", "Velocity", "Z", "Mass", "M_int", "Temperature", "Energy", "Entropy", "C_ad", "Crossing_time", ] tuples = [(k,i) for k,zones_tmp in enumerate(zones_for_each_checkpoint) for i in range(zones_tmp)] index = pd.MultiIndex.from_tuples(tuples, names=["k", "i"]) df = pd.DataFrame(index=index, columns=dataframe_columns, dtype=float) #### PARSE DATAFILES INTO DATAFRAME for k, checkpoint_filename in enumerate(checkpoint_filenames): df_tmp = df.loc[k] df_tmp.loc[:,cols_in] = pd.read_csv(checkpoint_filename, delim_whitespace=True, engine="c", dtype=np.float64, skiprows=2, names=cols_in, header=None ).iloc[1:-1].values df_tmp.Mass = calculate_mass(df_tmp.Density.values, df_tmp.dV.values) df_tmp.M_int = df_tmp.Mass.cumsum() df_tmp.Temperature = calculate_temperature(df_tmp.Pressure.values, df_tmp.Density.values, mu) df_tmp.Energy = calculate_internal_energy(df_tmp.Mass.values, df_tmp.Pressure.values, df_tmp.Density.values) \ / df_tmp.Mass.values df_tmp.Entropy = calculate_entropy(df_tmp.Temperature.values, df_tmp.Density.values, mu) df_tmp.C_ad = calculate_c_ad(df_tmp.Pressure.values, df_tmp.Density.values) w_cell = calculate_w_cell(df_tmp.Velocity.values) df_tmp.Crossing_time = calculate_crossing_time(df_tmp.C_ad.values, df_tmp.Velocity.values, w_cell, df_tmp.dR.values ) E_kin[k] = calculate_kinetic_energy(df_tmp.Mass.values, df_tmp.Velocity.values).sum() E_int[k] = calculate_internal_energy(df_tmp.Mass.values, df_tmp.Pressure.values, df_tmp.Density.values).sum() momentum[k] = calculate_momentum(df_tmp.Mass.values, df_tmp.Velocity.values).sum() E_tot[k] = E_kin[k] + E_int[k] M_tot[k] = df_tmp.M_int.iloc[-1] Z_tot[k] = np.sum(df_tmp.Mass * df_tmp.Z) zones[k] = df_tmp.shape[0] over_dense = np.where(df_tmp.Density > overview.background_density * 1.0001)[0] if over_dense.size > 0: shock_index = over_dense.max() else: shock_index = 0 R_shock[k] = df_tmp.iloc[shock_index].Radius M_R[k] = df_tmp.iloc[shock_index].M_int E_R_kin[k] = calculate_kinetic_energy(df_tmp.iloc[0:shock_index+1].Mass.values, df_tmp.iloc[0:shock_index+1].Velocity.values).sum() E_R_int[k] = calculate_internal_energy(df_tmp.iloc[0:shock_index+1].Mass.values, df_tmp.iloc[0:shock_index+1].Pressure.values, df_tmp.iloc[0:shock_index+1].Density.values).sum() E_R_tot[k] = E_R_int[k] + E_R_kin[k] if k == 0: Luminosity[k] = 0 else: Luminosity[k] = -(E_R_tot[k] - E_R_tot[k-1]) / (times[k] - times[k-1]) df["zones"] = df.index.get_level_values(1) df.dR /= pc df.Radius /= pc df.Mass /= M_solar df.M_int /= M_solar self.id = id self.data_dir = data_dir self.df = df self.times = times self.zones = zones self.E_tot = E_tot self.Z_tot = Z_tot self.E_int = E_int self.E_kin = E_kin self.E_R_int = E_R_int self.E_R_kin = E_R_kin self.E_R_tot = E_R_tot self.R_shock = R_shock self.M_R = M_R self.momentum = momentum self.Luminosity = Luminosity self.overview = overview self.filenames = checkpoint_filenames # filter for when initial transients have settled # assume that the settling time scales with the total time # (e.g. since t_0 of Thornton should scale with our final end time) t_settled = np.max(times) / 3e3 valid_lums = Luminosity[times > t_settled] smoothing_width = 2 # how many checkpoints wide smoothing_kernel = Gaussian1DKernel(smoothing_width) smoothed_lums = convolve(valid_lums, smoothing_kernel) max_lum = valid_lums[np.argmax(smoothed_lums)] self.t_0 = times[np.isclose(Luminosity, max_lum, atol=0)][0] self.t_f = 13 * self.t_0 # to match with t_f given by Thornton
def __init__(self, data_dir=None, id=None): super(RunSummary, self).__init__() if data_dir is None: return # create an empty place holder checkpoint_filenames = glob.glob( os.path.join(data_dir, id + "*checkpoint_*.dat")) checkpoint_filenames = sorted(checkpoint_filenames) num_checkpoints = len(checkpoint_filenames) if num_checkpoints == 0: raise FileNotFoundError("No checkpoints found") # ensure that the id is actually the FULL id id = get_full_id_from_partial_id(data_dir, id) times = np.empty(num_checkpoints) for k, checkpoint_filename in enumerate(checkpoint_filenames): f = open(checkpoint_filename, 'r') line = f.readline() times[k] = float(line.split()[3]) f.close() overview = Overview(os.path.join(data_dir, id + "_overview.dat")) mu = calculate_mean_molecular_weight(overview.metallicity) E_int = np.empty(num_checkpoints) E_kin = np.empty(num_checkpoints) momentum = np.empty(num_checkpoints) E_tot = np.empty(num_checkpoints) E_R_int = np.empty(num_checkpoints) # Energy of the remnant E_R_kin = np.empty(num_checkpoints) # Energy of the remnant E_R_tot = np.empty(num_checkpoints) # Energy of the remnant R_shock = np.empty(num_checkpoints) # size of the shock/remnant M_R = np.empty(num_checkpoints) # mass of the shock/remnant M_tot = np.empty(num_checkpoints) Z_tot = np.empty(num_checkpoints) zones = np.empty(num_checkpoints) Luminosity = np.empty(num_checkpoints) zones_for_each_checkpoint = [ get_num_zones_in_checkpoint(checkpoint_filename) for checkpoint_filename in checkpoint_filenames ] dataframe_columns = [ "Radius", "dR", "dV", "Density", "Pressure", "Velocity", "Z", "Mass", "M_int", "Temperature", "Energy", "Entropy", "C_ad", "Crossing_time", ] tuples = [(k, i) for k, zones_tmp in enumerate(zones_for_each_checkpoint) for i in range(zones_tmp)] index = pd.MultiIndex.from_tuples(tuples, names=["k", "i"]) df = pd.DataFrame(index=index, columns=dataframe_columns, dtype=float) #### PARSE DATAFILES INTO DATAFRAME for k, checkpoint_filename in enumerate(checkpoint_filenames): df_tmp = df.loc[k] df_tmp.loc[:, cols_in] = pd.read_csv(checkpoint_filename, delim_whitespace=True, engine="c", dtype=np.float64, skiprows=2, names=cols_in, header=None).iloc[1:-1].values df_tmp.Mass = calculate_mass(df_tmp.Density.values, df_tmp.dV.values) df_tmp.M_int = df_tmp.Mass.cumsum() df_tmp.Temperature = calculate_temperature(df_tmp.Pressure.values, df_tmp.Density.values, mu) df_tmp.Energy = calculate_internal_energy(df_tmp.Mass.values, df_tmp.Pressure.values, df_tmp.Density.values) \ / df_tmp.Mass.values df_tmp.Entropy = calculate_entropy(df_tmp.Temperature.values, df_tmp.Density.values, mu) df_tmp.C_ad = calculate_c_ad(df_tmp.Pressure.values, df_tmp.Density.values) w_cell = calculate_w_cell(df_tmp.Velocity.values) df_tmp.Crossing_time = calculate_crossing_time( df_tmp.C_ad.values, df_tmp.Velocity.values, w_cell, df_tmp.dR.values) E_kin[k] = calculate_kinetic_energy(df_tmp.Mass.values, df_tmp.Velocity.values).sum() E_int[k] = calculate_internal_energy(df_tmp.Mass.values, df_tmp.Pressure.values, df_tmp.Density.values).sum() momentum[k] = calculate_momentum(df_tmp.Mass.values, df_tmp.Velocity.values).sum() E_tot[k] = E_kin[k] + E_int[k] M_tot[k] = df_tmp.M_int.iloc[-1] Z_tot[k] = np.sum(df_tmp.Mass * df_tmp.Z) zones[k] = df_tmp.shape[0] over_dense = np.where( df_tmp.Density > overview.background_density * 1.0001)[0] if over_dense.size > 0: shock_index = over_dense.max() else: shock_index = 0 R_shock[k] = df_tmp.iloc[shock_index].Radius M_R[k] = df_tmp.iloc[shock_index].M_int E_R_kin[k] = calculate_kinetic_energy( df_tmp.iloc[0:shock_index + 1].Mass.values, df_tmp.iloc[0:shock_index + 1].Velocity.values).sum() E_R_int[k] = calculate_internal_energy( df_tmp.iloc[0:shock_index + 1].Mass.values, df_tmp.iloc[0:shock_index + 1].Pressure.values, df_tmp.iloc[0:shock_index + 1].Density.values).sum() E_R_tot[k] = E_R_int[k] + E_R_kin[k] if k == 0: Luminosity[k] = 0 else: Luminosity[k] = -(E_R_tot[k] - E_R_tot[k - 1]) / (times[k] - times[k - 1]) df["zones"] = df.index.get_level_values(1) df.dR /= pc df.Radius /= pc df.Mass /= M_solar df.M_int /= M_solar self.id = id self.data_dir = data_dir self.df = df self.times = times self.zones = zones self.E_tot = E_tot self.Z_tot = Z_tot self.E_int = E_int self.E_kin = E_kin self.E_R_int = E_R_int self.E_R_kin = E_R_kin self.E_R_tot = E_R_tot self.R_shock = R_shock self.M_R = M_R self.momentum = momentum self.Luminosity = Luminosity self.overview = overview self.filenames = checkpoint_filenames # filter for when initial transients have settled # assume that the settling time scales with the total time # (e.g. since t_0 of Thornton should scale with our final end time) t_settled = np.max(times) / 3e3 valid_lums = Luminosity[times > t_settled] smoothing_width = 2 # how many checkpoints wide smoothing_kernel = Gaussian1DKernel(smoothing_width) smoothed_lums = convolve(valid_lums, smoothing_kernel) max_lum = valid_lums[np.argmax(smoothed_lums)] self.t_0 = times[np.isclose(Luminosity, max_lum, atol=0)][0] self.t_f = 13 * self.t_0 # to match with t_f given by Thornton