def collision_step_Long_Bott_Ecol_grid_R_all_cells_2D_np( xi, m_w, vel, mass_densities, cells, no_cells, dt_over_dV, E_col_grid, no_kernel_bins, R_kernel_low_log, bin_factor_R_log, no_cols): for i in range(no_cells[0]): mask_i = (cells[0] == i) for j in range(no_cells[1]): # mask_j = (cells[1] == j) mask_ij = np.logical_and(mask_i, (cells[1] == j)) # for given cell: xis = xi[mask_ij] masses = m_w[mask_ij] # mass_densities = np.ones_like(masses) * mass_density rho_p = mass_densities[mask_ij] radii = compute_radius_from_mass_vec(masses, rho_p) vels = vel[:, mask_ij] ### IN WORK: SAFETY: IS THERE A PARTICLE IN THE CELL AT ALL? collision_step_Long_Bott_Ecol_grid_R_2D(xis, masses, radii, vels, rho_p, dt_over_dV, E_col_grid, no_kernel_bins, R_kernel_low_log, bin_factor_R_log, no_cols) xi[mask_ij] = xis m_w[mask_ij] = masses
#reload = True # #if reload: grid, pos, cells, vel, m_w, m_s, xi, active_ids = \ load_grid_and_particles_full(t_grid, grid_path) if solute_type == "AS": compute_R_p_w_s_rho_p = compute_R_p_w_s_rho_p_AS mass_density_dry = c.mass_density_AS_dry elif solute_type == "NaCl": compute_R_p_w_s_rho_p = compute_R_p_w_s_rho_p_NaCl mass_density_dry = c.mass_density_NaCl_dry R_p, w_s, rho_p = compute_R_p_w_s_rho_p(m_w, m_s, grid.temperature[tuple(cells)]) R_s = compute_radius_from_mass_vec(m_s, mass_density_dry) #%% GENERATE GRID FRAMES AVG show_target_cells = True if act_gen_grid_frames_avg: from analysis import generate_field_frame_data_avg # from analysis import plot_scalar_field_frames_extend_avg load_path_list = [] for seed_n in range(no_seeds): seed_SIP_gen_ = seed_SIP_gen_list[seed_n] seed_sim_ = seed_sim_list[seed_n]
sigma_m_log = 3.0 * sigma_R_log ensemble_parameters = [ dV, DNC0, mu_m_log2, sigma_m_log, mass_density, r_critmin, kappa, eta, no_sims, start_seed ] masses, weights, m_low, bins = \ gen_mass_ensemble_weights_SinSIP_lognormal( mu_m_log, sigma_m_log, mass_density, dV, kappa, eta, weak_threshold, r_critmin, m_high_over_m_low, seed, setseed=True) xis = no_rpc * weights no_SIPs_avg_ += xis.shape[0] bins_rad = compute_radius_from_mass_vec(bins, mass_density) radii = compute_radius_from_mass_vec(masses, mass_density) np.save(ensemble_dir + f'masses_seed_{seed}', 1.0E-18 * masses) np.save(ensemble_dir + f'radii_seed_{seed}', radii) np.save(ensemble_dir + f'xis_seed_{seed}', xis) if i == 0: np.save(ensemble_dir + f'bins_mass', 1.0E-18 * bins) np.save(ensemble_dir + f'bins_rad', bins_rad) np.save(ensemble_dir + 'ensemble_parameters', ensemble_parameters) no_SIPs_avg_ /= no_sims no_SIPs_avg.append(no_SIPs_avg_) print("generated ensemble for kappa =", kappa) print("number of independent ensembles =", no_sims)
def analyze_sim_data(kappa, mass_density, dV, no_sims, start_seed, no_bins, load_dir): # f"/mnt/D/sim_data/col_box_mod/results/{kernel_name}/{gen_method}/kappa_{kappa}/dt_{int(dt)}/" # f"/mnt/D/sim_data/col_box_mod/results/{kernel_name}/{gen_method}/kappa_{kappa}/dt_{int(dt)}/perm/" save_times = np.load(load_dir + f"save_times_{start_seed}.npy") seed_list = np.arange(start_seed, start_seed + no_sims * 2, 2) masses_vs_time = [] xis_vs_time = [] for seed in seed_list: # convert to kg masses_vs_time.append(1E-18 * np.load(load_dir + f"masses_vs_time_{seed}.npy")) # masses_vs_time.append(np.load(load_dir + f"masses_vs_time_{seed}.npy")) xis_vs_time.append(np.load(load_dir + f"xis_vs_time_{seed}.npy")) masses_vs_time_T = [] xis_vs_time_T = [] no_times = len(save_times) for time_n in range(no_times): masses_ = [] xis_ = [] for i, m in enumerate(masses_vs_time): masses_.append(m[time_n]) xis_.append(xis_vs_time[i][time_n]) masses_vs_time_T.append(masses_) xis_vs_time_T.append(xis_) f_m_num_avg_vs_time = np.zeros((no_times, no_bins), dtype=np.float64) f_m_num_std_vs_time = np.zeros((no_times, no_bins), dtype=np.float64) g_m_num_avg_vs_time = np.zeros((no_times, no_bins), dtype=np.float64) g_m_num_std_vs_time = np.zeros((no_times, no_bins), dtype=np.float64) g_ln_r_num_avg_vs_time = np.zeros((no_times, no_bins), dtype=np.float64) g_ln_r_num_std_vs_time = np.zeros((no_times, no_bins), dtype=np.float64) bins_mass_vs_time = np.zeros((no_times, no_bins + 1), dtype=np.float64) bins_mass_width_vs_time = np.zeros((no_times, no_bins), dtype=np.float64) bins_rad_width_log_vs_time = np.zeros((no_times, no_bins), dtype=np.float64) bins_mass_centers = [] bins_rad_centers = [] m_max_vs_time = np.zeros(no_times, dtype=np.float64) m_min_vs_time = np.zeros(no_times, dtype=np.float64) bin_factors_vs_time = np.zeros(no_times, dtype=np.float64) moments_vs_time = np.zeros((no_times, 4, no_sims), dtype=np.float64) last_bin_factor = 1.0 # last_bin_factor = 1.5 first_bin_factor = 1.0 # first_bin_factor = 0.8 for time_n, masses in enumerate(masses_vs_time_T): xis = xis_vs_time_T[time_n] masses_sampled = np.concatenate(masses) xis_sampled = np.concatenate(xis) # print(time_n, xis_sampled.min(), xis_sampled.max()) m_min = masses_sampled.min() m_max = masses_sampled.max() # convert to microns R_min = compute_radius_from_mass_jit(1E18 * m_min, mass_density) R_max = compute_radius_from_mass_jit(1E18 * m_max, mass_density) xi_min = xis_sampled.min() xi_max = xis_sampled.max() print(kappa, time_n, f"{xi_max/xi_min:.3e}", xis_sampled.shape[0] / no_sims, R_min, R_max) m_min_vs_time[time_n] = m_min m_max_vs_time[time_n] = m_max bin_factor = (m_max / m_min)**(1.0 / no_bins) bin_factors_vs_time[time_n] = bin_factor # bin_log_dist = np.log(bin_factor) # bin_log_dist_half = 0.5 * bin_log_dist # add dummy bins for overflow # bins_mass = np.zeros(no_bins+3,dtype=np.float64) bins_mass = np.zeros(no_bins + 1, dtype=np.float64) bins_mass[0] = m_min # bins_mass[0] = m_min / bin_factor for bin_n in range(1, no_bins + 1): bins_mass[bin_n] = bins_mass[bin_n - 1] * bin_factor # the factor 1.01 is for numerical stability: to be sure # that m_max does not contribute to a bin larger than the # last bin # bins_mass[-1] *= 1.0001 bins_mass[-1] *= last_bin_factor # the factor 0.99 is for numerical stability: to be sure # that m_min does not contribute to a bin smaller than the # 0-th bin # bins_mass[0] *= 0.9999 bins_mass[0] *= first_bin_factor # m_0 = m_min / np.sqrt(bin_factor) # bins_mass_log = np.log(bins_mass) bins_mass_vs_time[time_n] = bins_mass # convert to microns bins_rad = compute_radius_from_mass_vec(1E18 * bins_mass, mass_density) bins_mass_log = np.log(bins_mass) bins_rad_log = np.log(bins_rad) bins_mass_width = (bins_mass[1:] - bins_mass[:-1]) bins_rad_width = (bins_rad[1:] - bins_rad[:-1]) bins_rad_width_log = (bins_rad_log[1:] - bins_rad_log[:-1]) bins_mass_width_vs_time[time_n] = bins_mass_width bins_rad_width_log_vs_time[time_n] = bins_rad_width_log f_m_counts = np.histogram(masses_sampled, bins_mass)[0] # define centers on lin scale bins_mass_center_lin = 0.5 * (bins_mass[:-1] + bins_mass[1:]) bins_rad_center_lin = 0.5 * (bins_rad[:-1] + bins_rad[1:]) # define centers on the logarithmic scale bins_mass_center_log = np.exp(0.5 * (bins_mass_log[:-1] + bins_mass_log[1:])) bins_rad_center_log = np.exp(0.5 * (bins_rad_log[:-1] + bins_rad_log[1:])) # bins_mass are not equally spaced on log scale because of scaling # of the first and last bin # bins_mass_center_log = bins_mass[:-1] * np.sqrt(bin_factor) # bins_rad_center_log = bins_rad[:-1] * np.sqrt(bin_factor) # bins_mass_center_log = bins_mass[:-1] * 10**(1.0/(2.0*kappa)) # bins_rad_center_log = bins_rad[:-1] * 10**(1.0/(2.0*kappa)) # define the center of mass for each bin and set it as the "bin center" # bins_mass_center_COM = g_m_num_sampled/f_m_num_sampled # bins_rad_center_COM =\ # compute_radius_from_mass(bins_mass_center_COM*1.0E18, # c.mass_density_water_liquid_NTP) # set the bin "mass centers" at the right spot such that # f_avg_i in bin in = f(mm_i), where mm_i is the "mass center" m_avg = masses_sampled.sum() / xis_sampled.sum() bins_mass_center_exact = bins_mass[:-1] \ + m_avg * np.log(bins_mass_width\ / (m_avg * (1-np.exp(-bins_mass_width/m_avg)))) # convert to microns bins_rad_center_exact =\ compute_radius_from_mass_vec(1E18*bins_mass_center_exact, mass_density) bins_mass_centers.append( np.array((bins_mass_center_lin, bins_mass_center_log, bins_mass_center_exact))) bins_rad_centers.append( np.array((bins_rad_center_lin, bins_rad_center_log, bins_rad_center_exact))) ### STATISTICAL ANALYSIS OVER no_sim runs # get f(m_i) curve for each "run" with same bins for all ensembles f_m_num = [] g_m_num = [] g_ln_r_num = [] for sim_n, mass in enumerate(masses): # convert to microns rad = compute_radius_from_mass_vec(1E18 * mass, mass_density) f_m_num.append(np.histogram(mass, bins_mass, weights=xis[sim_n])[0] \ / (bins_mass_width * dV)) g_m_num.append(np.histogram(mass, bins_mass, weights=xis[sim_n]*mass)[0] \ / (bins_mass_width * dV)) # build g_ln_r = 3*m*g_m DIRECTLY from data g_ln_r_num.append( np.histogram(rad, bins_rad, weights=xis[sim_n]*mass)[0] \ / (bins_rad_width_log * dV) ) moments_vs_time[time_n, 0, sim_n] = xis[sim_n].sum() / dV for n in range(1, 4): moments_vs_time[time_n, n, sim_n] = np.sum(xis[sim_n] * mass**n) / dV # f_m_num = np.array(f_m_num) # g_m_num = np.array(g_m_num) # g_ln_r_num = np.array(g_ln_r_num) f_m_num_avg_vs_time[time_n] = np.average(f_m_num, axis=0) f_m_num_std_vs_time[time_n] = \ np.std(f_m_num, axis=0, ddof=1) / np.sqrt(no_sims) g_m_num_avg_vs_time[time_n] = np.average(g_m_num, axis=0) g_m_num_std_vs_time[time_n] = \ np.std(g_m_num, axis=0, ddof=1) / np.sqrt(no_sims) g_ln_r_num_avg_vs_time[time_n] = np.average(g_ln_r_num, axis=0) g_ln_r_num_std_vs_time[time_n] = \ np.std(g_ln_r_num, axis=0, ddof=1) / np.sqrt(no_sims) # convert to microns R_min_vs_time = compute_radius_from_mass_vec(1E18 * m_min_vs_time, mass_density) R_max_vs_time = compute_radius_from_mass_vec(1E18 * m_max_vs_time, mass_density) moments_vs_time_avg = np.average(moments_vs_time, axis=2) moments_vs_time_std = np.std(moments_vs_time, axis=2, ddof=1) \ / np.sqrt(no_sims) moments_vs_time_Unt = np.zeros_like(moments_vs_time_avg) # mom_fac = math.log(10)/(3*kappa) for time_n in range(no_times): for n in range(4): moments_vs_time_Unt[time_n,n] =\ math.log(bin_factors_vs_time[time_n]) / 3.0 \ * np.sum( g_ln_r_num_avg_vs_time[time_n] * (bins_mass_centers[time_n][1])**(n-1) ) # np.sum( g_ln_r_num_avg_vs_time[time_n] # * (bins_mass_centers[time_n][1])**(n-1) # * bins_rad_width_log_vs_time[time_n] ) # mom_fac * np.sum( g_m_num_avg_vs_time[time_n] # * (bins_mass_centers[time_n][1])**(n-1) ) np.save( load_dir + f"moments_vs_time_avg_no_sims_{no_sims}_no_bins_{no_bins}.npy", moments_vs_time_avg) np.save( load_dir + f"moments_vs_time_std_no_sims_{no_sims}_no_bins_{no_bins}.npy", moments_vs_time_std) np.save( load_dir + f"f_m_num_avg_vs_time_no_sims_{no_sims}_no_bins_{no_bins}.npy", f_m_num_avg_vs_time) np.save( load_dir + f"f_m_num_std_vs_time_no_sims_{no_sims}_no_bins_{no_bins}.npy", f_m_num_std_vs_time) np.save( load_dir + f"g_m_num_avg_vs_time_no_sims_{no_sims}_no_bins_{no_bins}.npy", g_m_num_avg_vs_time) np.save( load_dir + f"g_m_num_std_vs_time_no_sims_{no_sims}_no_bins_{no_bins}.npy", g_m_num_std_vs_time) np.save( load_dir + f"g_ln_r_num_avg_vs_time_no_sims_{no_sims}_no_bins_{no_bins}.npy", g_ln_r_num_avg_vs_time) np.save( load_dir + f"g_ln_r_num_std_vs_time_no_sims_{no_sims}_no_bins_{no_bins}.npy", g_ln_r_num_std_vs_time) np.save(load_dir + f"bins_mass_centers_{no_sims}_no_bins_{no_bins}.npy", bins_mass_centers) np.save(load_dir + f"bins_rad_centers_{no_sims}_no_bins_{no_bins}.npy", bins_rad_centers)