np.transpose(my_data[exp]['theta_v'][it, :, :, :]) - my_data[exp]['theta_v'][it, :, :, :].mean(axis=(1, 2))) for it in range(my_data[exp]['mcl_times'].size) ]) my_data[exp]['q_total'] = my_data[exp][q_key] + my_data[exp][ mcl_key] + my_data[exp][mr_key] my_data[exp]['q_total_prime'] = np.array([ np.transpose( np.transpose(my_data[exp]['q_total'][it, :, :, :]) - my_data[exp]['q_total'][it, :, :, :].mean(axis=(1, 2))) for it in range(my_data[exp]['mcl_times'].size) ]) # define RH my_data[exp]['RH'] = 100. * my_data[exp][q_key] / getQ( my_data[exp][temp_key][:] * 1., [100.], my_data[exp][pthe_key][:] * 1., t_units='K', p_units='Pa') # define the updraught mask my_data[exp]['up_mask'] = np.where( (my_data[exp][mcl_key][:] > 0) * (my_data[exp][w_key] > 0), 1.0, np.nan) # define the core mask my_data[exp]['core_mask'] = np.where( (my_data[exp][mcl_key][:] > 0) * (my_data[exp][w_key] > 0) * (my_data[exp]['theta_v_prime'] > 0), 1.0, np.nan) # calculate the profiles first for exp in experiments: t_idx = [ it for it in range(my_data[exp]['mcl_times'].size)
path_key = path.split('/')[-2] my_RH_data[path_key] = {} with Dataset(path + 'bouy_00.nc', 'r') as bouy_nc: my_RH_data[path_key][q_key] = bouy_nc.variables[q_key][ 1, :-1, :, :].mean(axis=(1, 2)) my_RH_data[path_key][temp_key] = bouy_nc.variables[temp_key][ 1, :-1, :, :].mean(axis=(1, 2)) z = bouy_nc.variables['thlev_zsea_theta'][:-1] * 1. with Dataset(path + 'fluxes_00.nc', 'r') as fluxes_nc: my_RH_data[path_key][pthe_key] = fluxes_nc.variables[pthe_key][ 1, :-1, :, :].mean(axis=(1, 2)) my_RH_data[path_key]['q_sat'] = getQ(my_RH_data[path_key][temp_key], [100.], my_RH_data[path_key][pthe_key], t_units='K', p_units='Pa') my_RH_data[path_key]['RH'] = 100. * my_RH_data[path_key][ q_key] / my_RH_data[path_key]['q_sat'] my_colors = {'RH_BLm25': 'red', 'RH_FAm25': 'blue', 'Control_short': 'k'} my_lw = {'RH_BLm25': '2', 'RH_FAm25': '2', 'Control_short': '1'} my_labels = { 'RH_BLm25': 'BLm25', 'RH_FAm25': 'FAm25', 'Control_short': 'Control (short)' } fig = plt.figure() axa = fig.add_subplot(1, 2, 1)
def get_IC_from_txt(experiment): """ Opens and reads the initial conditions text files. """ ### Open the initial conditions text files ### with open('../InitialFields_Moisture/InitialFields_Moisture_' + experiment + '.txt') as moisture: moisture = moisture.read() with open('../InitialFields_Temperature/InitialFields_Temperature_' + experiment + '.txt') as temperature: temperature = temperature.read() with open('../InitialFields_Wind/InitialFields_Wind_' + experiment + '.txt') as wind: wind = wind.read() ### Read in the data ### # The heights for the moisture data, km mv_z = np.array( [float(x) for x in moisture.split('\n')[2].split(' ')[1].split(',')]) / 1000. # The moisture data mv_data = np.array( [float(x) for x in moisture.split('\n')[4].split(' ')[1].split(',')]) * 100. # The heights for the theta data, km theta_z = np.array([ float(x) for x in temperature.split('\n')[2].split(' ')[1].split(',') ]) # The theta data, K theta_data = np.array([ float(x) for x in temperature.split('\n')[4].split(' ')[1].split(',') ]) # The heights for the wind data, km u_z = np.array( [float(x) for x in wind.split('\n')[2].split(' ')[1].split(',')]) / 1000. # The wind data, m/s u_data = np.array( [float(x) for x in wind.split('\n')[3].split(' ')[1].split(',')]) v_data = np.array( [float(x) for x in wind.split('\n')[4].split(' ')[1].split(',')]) ### Estimate the pressure so that we can compute the specific humidity ### p_sfc = 101700. # the surface pressure used to initialise the simulations temperature_data = theta_data - g * theta_z / cpd pressure_data = np.zeros_like(temperature_data) pressure_data[0] = p_sfc * 1. # set the surface pressure dz = 1. z = 0 temperature_interp = interpolate.interp1d(x=theta_z, y=temperature_data) for k in range(1, len(theta_z)): rho_0 = pressure_data[k - 1] / ( Rd * temperature_interp(z) ) # get the air density at the level below p_temp = pressure_data[k - 1] - g * rho_0 * dz z += dz # use that air density to compute the pressure slightly above and iterate until just below the next level while (z + dz) < theta_z[k]: rho_0 = p_temp / (Rd * temperature_interp(z)) p_temp = p_temp - g * rho_0 * dz z += dz # do the remaining distance to get to the next level rho_0 = p_temp / (Rd * temperature_interp(z)) pressure_data[k] = p_temp - g * rho_0 * (theta_z[k] - z) z += (theta_z[k] - z) # iterate to get a better temperature estimate temperature_data = PTtoTemp(theta_data, pressure_data, t_units='K', p_units='Pa') # iterate to get a better pressure estimate pressure_data[0] = p_sfc * 1. # set the surface pressure dz = 1. z = 0 temperature_interp = interpolate.interp1d(x=theta_z, y=temperature_data) for k in range(1, len(theta_z)): rho_0 = pressure_data[k - 1] / ( Rd * temperature_interp(z) ) # get the air density at the level below p_temp = pressure_data[k - 1] - g * rho_0 * dz z += dz # use that air density to compute the pressure slightly above and iterate until just below the next level while (z + dz) < theta_z[k]: rho_0 = p_temp / (Rd * temperature_interp(z)) p_temp = p_temp - g * rho_0 * dz z += dz # do the remaining distance to get to the next level rho_0 = p_temp / (Rd * temperature_interp(z)) pressure_data[k] = p_temp - g * rho_0 * (theta_z[k] - z) z += (theta_z[k] - z) ### Store the data to a dictionary and return ### data_dict = { 'mv_z': mv_z, 'theta_z': theta_z / 1000., 'u_z': u_z, 'RH_data': mv_data, 'theta_data': theta_data, 'u_data': u_data, 'v_data': v_data, 'mv_data': getQ(interpolate.interp1d(x=theta_z / 1000., y=temperature_data, fill_value='extrapolate')(mv_z), mv_data, interpolate.interp1d(x=theta_z / 1000., y=pressure_data, fill_value='extrapolate')(mv_z), t_units='K', p_units='Pa') * 1000.0 } return data_dict
# Get the first point # Calculate the distance between levels dz = 1. # Calculate the temperature at the lower level T = (theta[-1] / ((p0 * 100. / p[-1])**(Rd / cpd))) # Calculate the virtual temperature at the lower level Tv = T * (1. + 0.608 * mv[-1]) # Calculate the air density at the lower level rho = p[-1] / (Rd * Tv) # Use hydrostatic balance and air density at the lower level to calculate the pressure at the upper level p_ext = [p[-1] - g * rho * dz] # Calculate the temperature at the upper level T_new = T - getGM(T, 0.5 * (p[-1] + p_ext[0]), t_units='K', p_units='Pa') * dz # Calculate the specific humidity at the upper level RH_const = 100. * mv[-1] / getQ(T, 100., p[-1], t_units='K', p_units='Pa') q = getQ(T_new, RH_const, p_ext[0], t_units='K', p_units='Pa')[0] # Convert specific humidity to mixing ratio mv_ext = [q / (1. - q)] # Calculate the new potential temperature at the upper level theta_ext = [T_new * (p0 * 100. / p_ext[0])**(Rd / cpd)] z_ext_integration = [z.max() + dz] ### repeat for the remaining levels for k in xrange(1, int((z_ext.max() - (z.max() + dz)) / dz)): T = (theta_ext[k - 1] / ((p0 * 100. / p_ext[k - 1])**(Rd / cpd))) Tv = T * (1. + 0.608 * mv_ext[k - 1]) rho = p_ext[k - 1] / (Rd * Tv) p_ext.append(p_ext[k - 1] - g * rho * dz) T_new = T - getGM(
mr_nc.close() u_nc.close() v_nc.close() # Convert from potential temperature to temperature temp = PTtoTemp(theta_data, pressure_regrid, t_units = 'K', p_units = 'Pa') # Horizontally average the temperatures temperature[theta_data.shape[0]*days.index(day):theta_data.shape[0]*(days.index(day)+1),:] = np.nanmean(temp, axis = (2, 3)) pressure_rg[theta_data.shape[0]*days.index(day):theta_data.shape[0]*(days.index(day)+1),:] = np.nanmean(pressure_regrid, axis = (2, 3)) dewpoint_rg[theta_data.shape[0]*days.index(day):theta_data.shape[0]*(days.index(day)+1),:] = np.nanmean(getDew(q_regrid, pressure_regrid, q_units = 'kg/kg', p_units = 'Pa'), axis = (2, 3)) u_rg[theta_data.shape[0]*days.index(day):theta_data.shape[0]*(days.index(day)+1),:] = np.nanmean(u_regrid, axis = (2, 3)) v_rg[theta_data.shape[0]*days.index(day):theta_data.shape[0]*(days.index(day)+1),:] = np.nanmean(v_regrid, axis = (2, 3)) q_rg[theta_data.shape[0]*days.index(day):theta_data.shape[0]*(days.index(day)+1),:] = np.nanmean(q_regrid, axis = (2, 3)) mv_rg[theta_data.shape[0]*days.index(day):theta_data.shape[0]*(days.index(day)+1),:] = np.nanmean(mv_regrid, axis = (2, 3)) rh_rg[theta_data.shape[0]*days.index(day):theta_data.shape[0]*(days.index(day)+1),:] = np.nanmean(q_regrid/getQ(temp, [100.], pressure_regrid, t_units = 'K', p_units = 'Pa'), axis = (2, 3)) theta_rg[theta_data.shape[0]*days.index(day):theta_data.shape[0]*(days.index(day)+1),:] = np.nanmean(theta_data, axis = (2, 3)) # Time output every ten minutes (blindly manufactured) times = np.arange(1., 14400.*len(days), 10.)/60. dt_i = theta_data.shape[0] # Number of time steps per day if l_diagnostics: print 'Starting Temperature.' with open('../InitialFields_Temperature_' + ID + '.txt', 'w') as my_file: my_file.write('Specify initial temperature profiles\n') # Find minimum number of required levels to reproduce theta profile over the last four days theta_levels, theta_init = RDP(z, np.mean(theta_rg[-4*dt_i:,:], axis = 0), 0.1) n_thlev = len(theta_levels) # First namelist entry
p_sfc = 101700.0 # Pa pressure_init = [p_sfc] # Use the ideal gas law for dry air and the hydrostatic equation to compute p temperature_init = theta_init - (g/cpd)*theta_init_z temperature_fun = interpolate.interp1d(x = theta_init_z, y = temperature_init, fill_value = 'extrapolate') dz = 1 for z in range(1, 40001, dz): rho = pressure_init[-1]/(Rd*temperature_fun(z-0.5*dz)) # ideal gas law pressure_init.append(pressure_init[-1] - rho*g*dz) # hydrostatic balance pressure_init_theta = np.array([pressure_init[i] for i in range(len(pressure_init)) if i in theta_init_z]) pressure_init_RH = np.array([pressure_init[i] for i in range(len(pressure_init)) if i in RH_init_z]) # Use getQ to convert from RH to q q_init = getQ(temperature_fun(RH_init_z), RH_init*100.0, pressure_init_RH, t_units = 'K', p_units = 'Pa') # Define the idealised forcing profiles Q_rad = np.array([-2.0, -2.0, 0.0, 0.0])/86400.0 # K/day -> K/s Q_rad_z = np.array([0.0, 3217.0, 4326.0, 40000.0]) w_subs = np.array([0.0, -0.156, -0.379, -0.588, -0.603, -0.498, -0.384, -0.337, -0.315, -0.311, -0.291, -0.300, -0.418, -0.208, 0.0, 0.0])/100.0 # cm/s -> m/s w_subs_z = np.array([0.0, 148.0, 392.0, 628.0, 857.0, 1119.0, 1381.0, 1644.0, 1906.0, 2168.0, 2430.0, 2693.0, 3217.0, 3867.0, 4326.0, 40000.0]) # Interpolate everything onto the same grid z = np.arange(0, 40000.1, dz) z_half = np.arange(dz/2., 40000.1, dz) # initial variables theta_fun = interpolate.interp1d(theta_init_z, theta_init, fill_value = 'extrapolate') q_fun = interpolate.interp1d(RH_init_z, q_init, fill_value = 'extrapolate')