def elaz2radec_lst(el, az, lst, lat=38.43312): """DO NOT USE THIS ROUTINE FOR ANTHING THAT NEEDS TO BE RIGHT. IT DOES NOT CORRECT FOR PRECESSION. Calculates the Ra and Dec from elavation, aximuth, LST and Latitude. This function is vectorized with numpy so should be fast. Standart numpy broadcasting should also work. All angles in degrees, lst in seconds. Latitude defaults to GBT. """ # Convert everything to radians. el = sp.radians(el) az = sp.radians(az) lst = sp.array(lst, dtype=float) * 2 * sp.pi / 86400 lat = sp.radians(lat) # Calculate dec. dec = sp.arcsin( sp.sin(el) * sp.sin(lat) + sp.cos(el) * sp.cos(lat) * sp.cos(az)) # Calculate the hour angle ha = sp.arccos( (sp.sin(el) - sp.sin(lat) * sp.sin(dec)) / (sp.cos(lat) * sp.cos(dec))) ra = sp.degrees(lst - ha) % 360 return ra, sp.degrees(dec)
def calc_max_width_in_slab(out_of_dip, slab_width, max_width): """Calculate the max width of a rupture within a slab in kms; given the slab width, and the out of dip angle. the returned max width values are compared to the calculated width and the fault width, and then the mimium value of the 3 is used as the rupture width. out_of_dip out of dip angle in Degrees slab_width width of slab in kms max_width width of the fault Returns the max width of ruptures within a slab in kms. """ max_width_in_slab = zeros(len(out_of_dip)) i = where(out_of_dip >= 180) out_of_dip[i] = out_of_dip[i] - 180 i = where(out_of_dip <= 1) max_width_in_slab[i] = max_width j = where(((out_of_dip < 90) & (out_of_dip > 1))) max_width_in_slab[j] = slab_width / (sin(radians(out_of_dip[j]))) k = where(out_of_dip == 90) max_width_in_slab[k] = slab_width k = where((out_of_dip > 90) & (out_of_dip < 179)) max_width_in_slab[k] = slab_width / (sin(radians(180 - out_of_dip[k]))) i = where(out_of_dip >= 179) max_width_in_slab[i] = max_width return max_width_in_slab
def extract_targets_from_hal_logs_xyzabvt(shiftToZero=True): targetsMatrix = sp.array( io.parse_halscope_log_xyzabvt("halscope_xyzabvt_dataset.txt")) (rowCount, colCount) = targetsMatrix.shape xTargets, yTargets, zTargets, aTargets, bTargets, velocites, targetTimestamps = targetsMatrix[:, 0], targetsMatrix[:, 1], targetsMatrix[:, 2], targetsMatrix[:, 3], targetsMatrix[:, 4], targetsMatrix[:, 5], targetsMatrix[:, 6] if (shiftToZero): targetTimestamps -= sp.ones_like(targetTimestamps) * min( targetTimestamps) xSplineTCK = interpolate.splrep(targetTimestamps, sp.radians(xTargets)) ySplineTCK = interpolate.splrep(targetTimestamps, sp.radians(yTargets)) zSplineTCK = interpolate.splrep(targetTimestamps, sp.radians(zTargets)) aSplineTCK = interpolate.splrep(targetTimestamps, sp.radians(aTargets)) bSplineTCK = interpolate.splrep(targetTimestamps, sp.radians(bTargets)) print "B = %f, E = %f, len = %d" % ( min(targetTimestamps), max(targetTimestamps), len(targetTimestamps)) # plt.plot(targetTimestamps, interpolate.splev(targetTimestamps, aSplineTCK, der = 1)) # plt.show() return (xSplineTCK, ySplineTCK, zSplineTCK, aSplineTCK, bSplineTCK)
def extract_targets_from_hal_logs_abvt(shiftToZero=True): targetsMatrix = sp.array( io.parse_halscope_log_abvt("halscope_single_dataset.txt")) (rowCount, colCount) = targetsMatrix.shape aTargets, bTargets, velocites, targetTimestamps = targetsMatrix[:, 0], targetsMatrix[:, 1], targetsMatrix[:, 2], targetsMatrix[:, 3] if (shiftToZero): targetTimestamps -= sp.ones_like(targetTimestamps) * min( targetTimestamps) aSplineTCK = interpolate.splrep(targetTimestamps, sp.radians(smooth(aTargets))) bSplineTCK = interpolate.splrep(targetTimestamps, sp.radians(smooth(bTargets))) print "B = %f, E = %f, len = %d" % ( min(targetTimestamps), max(targetTimestamps), len(targetTimestamps)) # plt.plot(targetTimestamps, interpolate.splev(targetTimestamps, aSplineTCK, der = 1)) # plt.show() return (aSplineTCK, bSplineTCK)
def elaz2radec_lst(el, az, lst, lat = 38.43312) : """DO NOT USE THIS ROUTINE FOR ANTHING THAT NEEDS TO BE RIGHT. IT DOES NOT CORRECT FOR PRECESSION. Calculates the Ra and Dec from elavation, aximuth, LST and Latitude. This function is vectorized with numpy so should be fast. Standart numpy broadcasting should also work. All angles in degrees, lst in seconds. Latitude defaults to GBT. """ # Convert everything to radians. el = sp.radians(el) az = sp.radians(az) lst = sp.array(lst, dtype = float)*2*sp.pi/86400 lat = sp.radians(lat) # Calculate dec. dec = sp.arcsin(sp.sin(el)*sp.sin(lat) + sp.cos(el)*sp.cos(lat)*sp.cos(az)) # Calculate the hour angle ha = sp.arccos((sp.sin(el) - sp.sin(lat)*sp.sin(dec)) / (sp.cos(lat)*sp.cos(dec))) ra = sp.degrees(lst - ha) % 360 return ra, sp.degrees(dec)
def radar_cross_section(frequency, width, incident_angle, observation_angle): """ Calculate the bistatic radar cross section for a 2D strip. :param frequency: The frequency of the incident energy (Hz). :param width: The width of the strip (m). :param incident_angle: The incident angle (deg). :param observation_angle: The observation angle (deg). :return: The bistatic radar cross section (m^2). """ # Wavelength wavelength = c / frequency # Wavenumber k = 2.0 * pi / wavelength phi_i = radians(incident_angle) phi_o = radians(observation_angle) rcs_tm = k * width**2 * sin(phi_i) * sinc(width / wavelength * (cos(phi_o) + cos(phi_i)))**2 rcs_te = k * width**2 * sin(phi_o) * sinc(width / wavelength * (cos(phi_o) + cos(phi_i)))**2 return rcs_tm, rcs_te
def lla2ecef(lla: Sequence[float], cst: ConstantsFile, lla_as_degrees: bool=False) -> Tuple[float, float, float]: """ converts LLA (Latitude, Longitude, Altitude) coordinates to ECEF (Earth-Centre, Earth-First) XYZ coordinates. """ lat, lon, alt = lla if lla_as_degrees: lat = radians(lat) lon = radians(lon) a = cst.semi_major_axis b = cst.semi_minor_axis # calc. ellipsoid flatness f = (a - b) / a # calc. eccentricity e = sqrt(f * (2 - f)) # Calculate length of the normal to the ellipsoid N = a / sqrt(1 - (e * sin(lat)) ** 2) # Calculate ecef coordinates x = (N + alt) * cos(lat) * cos(lon) y = (N + alt) * cos(lat) * sin(lon) z = (N * (1 - e ** 2) + alt) * sin(lat) # Return the ecef coordinates return x, y, z
def radar_cross_section(frequency, width, length, incident_theta, observation_theta, observation_phi): """ Calculate the bistatic radar cross section for a rectangular plate. :param frequency: The frequency of the incident energy (Hz). :param width: The width of the plate (m). :param length: The length of the plate (m). :param incident_theta: The incident angle theta (deg). :param observation_theta: The observation angle theta (deg). :param observation_phi: The observation angle phi (deg). :return: The bistatic radar cross section (m^2). """ # Wavelength wavelength = c / frequency theta_i = radians(incident_theta) theta_o = radians(observation_theta) phi_o = radians(observation_phi) x = width / wavelength * sin(theta_o) * cos(phi_o) y = length / wavelength * (sin(theta_o) * sin(phi_o) - sin(theta_i)) rcs_tm = 4.0 * pi * (length * width / wavelength)**2 * ( cos(theta_i)**2 * (cos(theta_o)**2 * cos(phi_o)**2 + sin(phi_o)**2)) * sinc(x)**2 * sinc(y)**2 rcs_te = 4.0 * pi * (length * width / wavelength)**2 * ( cos(theta_o)**2 * sin(phi_o)**2 + cos(phi_o)**2) * sinc(x)**2 * sinc(y)**2 return rcs_tm, rcs_te
def T2d_s(Degree, Ener, wavelenghts=False): """from Theta angle and Energyg return the d_spacing if wavelengh is true Energy is espressed in wavelenght """ if wavelenghts: return E2W(Ener) / (2 * (scipy.sin(scipy.radians(Degree)))) else: return Ener / (2 * (scipy.sin(scipy.radians(Degree))))
def __init__(self, solar, area=1, efficiency=0.20, el_tilt=0, az_tilt=0): self.area = area self.efficiency = efficiency self.el_tilt = sp.radians(el_tilt) self.az_tilt = sp.radians(az_tilt) #self.el_tilt = el_tilt #self.az_tilt = az_tilt self.solar = solar
def get_orientations(self, start_region): if(self.dname == "d8"): return radians(self.get_d8_orientations(start_region)) elif(self.dname == "d1"): return radians(self.get_d1_orientations(start_region)) return [[radians(orient) for orient in self.dg_model.get_viewpoint_orientations(self.dg_model.num_viewpoints)]]
def calc_new_rupture_trace_lower_slab( top_dip, depth_bottom, top_trace_lat_s, top_trace_lon_s, top_trace_lat_e, top_trace_lon_e, lower_dip, ): """Calculates the trace for a lower slab so that it matches the bottom of the upper slab. top_dip dip of top slab depth_bottom depth of the bottom of top slab top_trace_lat_s latitude of start point - top slab top_trace_lon_s longitude of start point - top slab top_trace_lat_e latitude of end point - top slab top_trace_lon_e longitude of end point - top slab lower_dip Returns low_trace_lat_s, low_trace_lon_s, low_trace_lat_e,low_trace_lon_e. """ azimuth = azimuth_of_trace(top_trace_lat_s, top_trace_lon_s, top_trace_lat_e, top_trace_lon_e) y1 = depth_bottom * ((cos(radians(top_dip))) / (sin(radians(top_dip)))) (temp_trace_lat_s, temp_trace_lon_s) = \ azimuthal_orthographic_xy_to_ll(0, y1, top_trace_lat_s, top_trace_lon_s, azimuth) (temp2_trace_lat_s, temp2_trace_lon_s) = \ get_new_ll(top_trace_lat_s, top_trace_lon_s, azimuth + 90, y1) (temp_trace_lat_e, temp_trace_lon_e) = \ azimuthal_orthographic_xy_to_ll(0, y1, top_trace_lat_e, top_trace_lon_e, azimuth) (temp2_trace_lat_e, temp2_trace_lon_e) = \ get_new_ll(top_trace_lat_e, top_trace_lon_e, azimuth + 90, y1) y2 = depth_bottom * ((cos(radians(lower_dip))) / (sin(radians(lower_dip)))) y = y1 - y2 (low_trace_lat_s, low_trace_lon_s) = \ azimuthal_orthographic_xy_to_ll(0, y, top_trace_lat_s, top_trace_lon_s, azimuth) (low_trace_lat_e, low_trace_lon_e) = \ azimuthal_orthographic_xy_to_ll(0, y, top_trace_lat_e, top_trace_lon_e, azimuth) return low_trace_lat_s, low_trace_lon_s, low_trace_lat_e, low_trace_lon_e
def calc_new_rupture_trace_lower_slab(top_dip, depth_bottom, top_trace_lat_s, top_trace_lon_s, top_trace_lat_e, top_trace_lon_e, lower_dip,): """Calculates the trace for a lower slab so that it matches the bottom of the upper slab. top_dip dip of top slab depth_bottom depth of the bottom of top slab top_trace_lat_s latitude of start point - top slab top_trace_lon_s longitude of start point - top slab top_trace_lat_e latitude of end point - top slab top_trace_lon_e longitude of end point - top slab lower_dip Returns low_trace_lat_s, low_trace_lon_s, low_trace_lat_e,low_trace_lon_e. """ azimuth = azimuth_of_trace( top_trace_lat_s, top_trace_lon_s, top_trace_lat_e, top_trace_lon_e) y1 = depth_bottom * ((cos(radians(top_dip))) / (sin(radians(top_dip)))) (temp_trace_lat_s, temp_trace_lon_s) = \ azimuthal_orthographic_xy_to_ll(0, y1, top_trace_lat_s, top_trace_lon_s, azimuth) (temp2_trace_lat_s, temp2_trace_lon_s) = \ get_new_ll(top_trace_lat_s, top_trace_lon_s, azimuth + 90, y1) (temp_trace_lat_e, temp_trace_lon_e) = \ azimuthal_orthographic_xy_to_ll(0, y1, top_trace_lat_e, top_trace_lon_e, azimuth) (temp2_trace_lat_e, temp2_trace_lon_e) = \ get_new_ll(top_trace_lat_e, top_trace_lon_e, azimuth + 90, y1) y2 = depth_bottom * ((cos(radians(lower_dip))) / (sin(radians(lower_dip)))) y = y1 - y2 (low_trace_lat_s, low_trace_lon_s) = \ azimuthal_orthographic_xy_to_ll(0, y, top_trace_lat_s, top_trace_lon_s, azimuth) (low_trace_lat_e, low_trace_lon_e) = \ azimuthal_orthographic_xy_to_ll(0, y, top_trace_lat_e, top_trace_lon_e, azimuth) return low_trace_lat_s, low_trace_lon_s, low_trace_lat_e, low_trace_lon_e
def calSquareDegree_conver(sqdeg,dec0): """ input sqdeg: unit in deg. dec0: dec center in decimal deg. assume decw = sqrt(sqdeg) return: raw ref:http://en.wikipedia.org/wiki/Solid_angle """ sa = sqdeg/((180./S.pi)**2) decw = S.sqrt(sqdeg) raw = S.degrees(sa /(S.sin(S.radians(dec0+decw/2.) ) - S.sin(S.radians(dec0-decw/2.)))) return raw
def test_solar_elevation(): ''' sun should be directly overhead on the equator at noon on the equinox ''' # TODO: why is the decimal agreement so low? solar = pypvsim.Solar(lat=0) date = np.datetime64('2013-03-20T12:00Z') assert_almost_equal(solar.elevation(date.astype(object)), sp.radians(90), 1) date = np.datetime64('2013-09-22T12:00Z') assert_almost_equal(solar.elevation(date.astype(object)), sp.radians(90), 1)
def get_orientations_annotated(model, start_region, dataset_name): print "dataset_name", dataset_name if(dataset_name == "df8full"): return [radians(get_d8_full_orientations(start_region))] elif(dataset_name == "df8"): return [radians(get_d8_orientations(start_region))] elif(dataset_name == "df13d"): return [radians(get_d1_3d_orientations(start_region))] elif(dataset_name == "df1"): return [radians(get_d1_orientations(start_region))] print "Unexpected dataset"+str(dataset_name) raise ValueError("Unexpected dataset"+str(dataset_name))
def lac_test_02(): mat01 = predefined.carbon_fiber_generic() mat02 = predefined.glass_fiber_generic() a = layup.Laminate() t = 150e-6 a.append(layup.Ply(scipy.radians(40),t,mat01)) a.append(layup.Ply(scipy.radians(-50),t,mat02)) a.append(layup.Ply(scipy.radians(-5),t,mat02)) a.append(layup.Ply(scipy.radians(85),t,mat01)) return a
def purcell(physics, network, geometry, fluid, propname, r_toroid, pore_surface_tension='surface_tension', pore_contact_angle='contact_angle', throat_diameter='diameter', **params): r""" Computes the throat capillary entry pressure assuming the throat is a toroid. Parameters ---------- network : OpenPNM Network Object The network on which to apply the calculation sigma : float, array_like Surface tension of the invading/defending fluid pair. Units must be consistent with the throat size values, but SI is encouraged. theta : float, array_like Contact angle formed by a droplet of the invading fluid and solid surface, measured through the defending fluid phase. Angle must be given in degrees. r_toroid : float or array_like The radius of the solid Notes ----- This approach accounts for the converging-diverging nature of many throat types. Advancing the meniscus beyond the apex of the toroid requires an increase in capillary pressure beyond that for a cylindical tube of the same radius. The details of this equation are described by Mason and Morrow [1]_, and explored by Gostick [2]_ in the context of a pore network model. References ---------- .. [1] G. Mason, N. R. Morrow, Effect of contact angle on capillary displacement curvatures in pore throats formed by spheres. J. Colloid Interface Sci. 168, 130 (1994). .. [2] J. Gostick, Random pore network modeling of fibrous PEMFC gas diffusion media using Voronoi and Delaunay tessellations. J. Electrochem. Soc. 160, F731 (2013). """ #This seesm to work, but I wrote it quickly and lost track of the degree-radians conversions """TODO: Triple check the accuracy of this equation """ sigma = network.get_pore_data(phase=fluid,prop=pore_surface_tension) sigma = network.interpolate_throat_data(sigma) theta = network.get_pore_data(phase=fluid,prop=pore_contact_angle) theta = network.interpolate_throat_data(theta) r = network.get_throat_data(prop=throat_diameter)/2 R = r_toroid alpha = theta - 180 + sp.arcsin(sp.sin(sp.radians(theta)/(1+r/R))) value = (-2*sigma/r)*(sp.cos(sp.radians(theta - alpha))/(1 + R/r*(1-sp.cos(sp.radians(alpha))))) mask = network.get_throat_indices(geometry) network.set_throat_data(phase=fluid,prop=propname,data=value[mask],locations=geometry)
def radar_cross_section(frequency, radius, incident_angle, observation_angle, number_of_modes): """ Calculate the bistatic radar cross section for the infinite cylinder with oblique incidence. :param frequency: The frequency of the incident energy (Hz). :param radius: The radius of the cylinder (m). :param incident_angle: The angle of incidence from z-axis (deg). :param observation_angle: The observation angle (deg). :param number_of_modes: The number of terms to take in the summation. :return: The bistatic radar cross section for the infinite cylinder (m^2). """ # Wavelength wavelength = c / frequency # Wavenumber k = 2.0 * pi / wavelength modes = range(number_of_modes + 1) # Initialize the sum s_tm = 0 s_te = 0 phi = radians(observation_angle) theta_i = radians(incident_angle) # Argument for Bessel and Hankel functions z = k * radius * sin(theta_i) for n in modes: en = 2.0 if n == 0: en = 1.0 an = jv(n, z) / hankel2(n, z) jp = n * jv(n, z) / z - jv(n + 1, z) hp = n * hankel2(n, z) / z - hankel2(n + 1, z) bn = -jp / hp s_tm += en * an * cos(n * phi) s_te += en * bn * cos(n * phi) rcs_tm = 2.0 * wavelength / (pi * sin(theta_i)) * abs(s_tm)**2 rcs_te = 2.0 * wavelength / (pi * sin(theta_i)) * abs(s_te)**2 return rcs_te, rcs_tm
def n_circles(phases, mag_min=-40.0, mag_max=12.0): """Constant-phase contours of the function Gcl = Gol/(1+Gol), where Gol is an open-loop transfer function, and Gcl is a corresponding closed-loop transfer function. Usage ===== contours = n_circles(phases, mag_min, mag_max) Parameters ---------- phases : array-like Array of phases in degrees of the N-circles mag_min : dB Minimum magnitude in dB of the N-circles mag_max : dB Maximum magnitude in dB of the N-circles Return values ------------- contours : complex array Array of complex numbers corresponding to the contours. """ # Convert phases and magnitude range into a grid suitable for # building contours mags = sp.linspace(10**(mag_min/20.0), 10**(mag_max/20.0), 2000) Gcl_phases, Gcl_mags = sp.meshgrid(sp.radians(phases), mags) return closed_loop_contours(Gcl_mags, Gcl_phases)
def process_wind_data(wind_data_file, release_delay, wind_dt=None): #Takes in a csv file and outputs wind_angle,wind_speed,wind_dt wind_df = pd.read_csv( '/home/annie/work/programming/odor_tracking_sim/data_files/' + wind_data_file) cols = list(wind_df.columns.values) #if a release delay is required, insert rows for the extra time into the dataframe with value of beginning wind value rows_to_add = int((release_delay * 60) / wind_dt) df_to_insert = pd.DataFrame({ cols[0]: [wind_df[cols[0]][0] for i in range(rows_to_add)], cols[1]: [wind_df[cols[1]][0] for i in range(rows_to_add)], cols[2]: [wind_df[cols[2]][0] for i in range(rows_to_add)] }) wind_df = pd.concat([df_to_insert, wind_df.ix[:]]).reset_index(drop=True) secs, degs, mph = tuple(wind_df[col].as_matrix() for col in cols) #Convert min to seconds times = 60. * secs if wind_dt is None: wind_dt = times[1] - times[0] else: #Directly provided wind_dt in seconds wind_dt = wind_dt #Convert degrees to radians and switch to going vs coming wind_angle = (scipy.radians(degs) + scipy.pi) % (2 * scipy.pi) #Convert mph to meters/sec wind_speed = mph * (1 / 3600.) * 1609.34 return { 'wind_angle': wind_angle, 'wind_speed': wind_speed, 'wind_dt': wind_dt }
def setFromEuler(self,angles,order='Aerospace',degrees=True): ''' Set this quaternion from the Euler angle sequence angle Keyword args: order - the order used to apply the Euler angle sequence. Choices are: 'Aerospace' or 'ZYX' for standard aerospace sequence (default) 'BVH' of 'ZXY' for order used in BVH files 'ZXZ' for ZXZ order degrees - set True to indicate that angles are in degrees (default) or false for radians ''' angles = asarray(angles)/2 if degrees: angles = radians(angles) if order == 'Aerospace' or order == 'ZYX': self.set(Quat(cos(angles[0]),0,0,sin(angles[0])) * Quat(cos(angles[1]),0,sin(angles[1]),0) * Quat(cos(angles[2]),sin(angles[2]),0,0)) elif order == 'BVH' or order == 'ZXY': self.set(Quat(cos(angles[0]),0,0,sin(angles[0])) * Quat(cos(angles[1]),sin(angles[1]),0,0) * Quat(cos(angles[2]),0,sin(angles[2]),0)) elif order == 'ZXZ': self.set(Quat(cos(angles[0]),0,0,sin(angles[0])) * Quat(cos(angles[1]),sin(angles[1]),0,0) * Quat(cos(angles[2]),0,0,sin(angles[2]))) else: raise RuntimeError("Unknown rotation order: %s"%order) return self
def T2E(Degree, dspacing): """from angle and dspacing return the energy in eV in diffraction condition E=hc/(sin(theta)*2d))) """ Ener = 1.23984E4 / (scipy.sin(scipy.radians(Degree)) * 2 * dspacing) return Ener
def m_circles(mags, phase_min=-359.75, phase_max=-0.25): """Constant-magnitude contours of the function Gcl = Gol/(1+Gol), where Gol is an open-loop transfer function, and Gcl is a corresponding closed-loop transfer function. Usage ===== contours = m_circles(mags, phase_min, phase_max) Parameters ---------- mags : array-like Array of magnitudes in dB of the M-circles phase_min : degrees Minimum phase in degrees of the N-circles phase_max : degrees Maximum phase in degrees of the N-circles Return values ------------- contours : complex array Array of complex numbers corresponding to the contours. """ # Convert magnitudes and phase range into a grid suitable for # building contours phases = sp.radians(sp.linspace(phase_min, phase_max, 2000)) Gcl_mags, Gcl_phases = sp.meshgrid(10.0**(mags/20.0), phases) return closed_loop_contours(Gcl_mags, Gcl_phases)
def integrand(z): """ Determine the integrand for calculating the apparent elevation angle. :param z: The altitude (km). :return: The integrand. """ # Effective radius of the Earth (km) re = 6378.137 # Standard values a = 0.000315 b = 0.1361 # Refractive index and derivative as a function of altitude n_z = 1. + a * exp(-b * z) np_z = -(a * b * exp(-b * z)) # Refractive index at the given height n_h = 1. + a * exp(-b * height) tan_phi = tan( arccos(((re + height) * n_h) / ((re + z) * n_z) * cos(radians(theta_true)))) return np_z / (n_z * tan_phi)
def radar_cross_section_3d(frequency, radius, incident_angle, observation_angle, number_of_modes, length): """ Calculate the bistatic radar cross section for a finite length cylinder with oblique incidence. :param frequency: The frequency of the incident energy (Hz). :param radius: The radius of the cylinder (m). :param incident_angle: The angle of incidence from z-axis (deg). :param observation_angle: The observation angle (deg). :param number_of_modes: The number of terms to take in the summation. :param length: The length of the cylinder (m). :return: The bistatic radar cross section for the infinite cylinder (m^2). """ # Wavelength wavelength = c / frequency theta_i = radians(incident_angle) theta_o = theta_i # Calculate the 2D RCS rcs_te, rcs_tm = radar_cross_section(frequency, radius, incident_angle, observation_angle, number_of_modes) value = 2.0 * length ** 2 / wavelength * sin(theta_o) ** 2 * \ sinc(length / wavelength * (cos(theta_i) + cos(theta_o))) ** 2 return rcs_te * value, rcs_tm * value
def purcell(physics, phase, network, r_toroid, pore_surface_tension='pore.surfac_tension', pore_contact_angle='pore.contact_angle', throat_diameter='throat.diameter', **kwargs): r""" Computes the throat capillary entry pressure assuming the throat is a toroid. Parameters ---------- network : OpenPNM Network Object The network on which to apply the calculation sigma : float, array_like Surface tension of the invading/defending phase pair. Units must be consistent with the throat size values, but SI is encouraged. theta : float, array_like Contact angle formed by a droplet of the invading phase and solid surface, measured through the defending phase phase. Angle must be given in degrees. r_toroid : float or array_like The radius of the solid Notes ----- This approach accounts for the converging-diverging nature of many throat types. Advancing the meniscus beyond the apex of the toroid requires an increase in capillary pressure beyond that for a cylindical tube of the same radius. The details of this equation are described by Mason and Morrow [1]_, and explored by Gostick [2]_ in the context of a pore network model. References ---------- .. [1] G. Mason, N. R. Morrow, Effect of contact angle on capillary displacement curvatures in pore throats formed by spheres. J. Colloid Interface Sci. 168, 130 (1994). .. [2] J. Gostick, Random pore network modeling of fibrous PEMFC gas diffusion media using Voronoi and Delaunay tessellations. J. Electrochem. Soc. 160, F731 (2013). TODO: Triple check the accuracy of this equation """ throats = phase.throats(physics.name) sigma = phase[pore_surface_tension] sigma = phase.interpolate_data(data=sigma) theta = phase[pore_contact_angle] theta = phase.interpolate_data(data=theta) r = network[throat_diameter] / 2 R = r_toroid alpha = theta - 180 + _sp.arcsin(_sp.sin(_sp.radians(theta) / (1 + r / R))) value = (-2 * sigma / r) * (_sp.cos(_sp.radians(theta - alpha)) / (1 + R / r * (1 - _sp.cos(_sp.radians(alpha))))) value = value[throats] return value
def getDebyeWallerFactor(self, energy_keV, roughness_A, incident_angle_deg): roughness_cm = roughness_A * A_cm incident_angle_rad = scipy.radians(incident_angle_deg) numerator = 4.0 * pi * roughness_cm * scipy.sin(incident_angle_rad) lambda_cm = convertEnergykeV2LambdaCM(energy_keV) denominator = lambda_cm factor = scipy.exp(-(numerator/denominator)**2) return factor
def main(): theta = linspace(0, 360, 360) r = 1 + sin(radians(theta)) f = Scatter(r=r, t=theta) # Reemplazar por las credenciales de su cuenta en plot.ly sign_in('', '') plot(Data([f]), filename='1 + sin(theta)')
def test_solar_declination(): ''' declination should be 23.45 degrees on summer solstice ''' solar = pypvsim.Solar() date = np.datetime64('2013-06-21T12:00Z') declination = solar.declination(date.astype(object)) assert_almost_equal(declination, sp.radians(23.45), 5)
def calc_ll_dist(lat1, lon1, lat2, lon2): """Calculate a length in kms given start and end positions. lat1 latitude of start point lon1 longitude of start point lat2 latitude of end point lon2 longitude of end point Returns length from start point in kms. """ R = 6371 dLat = radians(abs(lat2 - lat1)) dLon = radians(abs(lon2 - lon1)) a = (sin(dLat / 2) * sin(dLat / 2) + cos(radians(lat1)) * cos(radians(lat2)) * sin(dLon / 2) * sin(dLon / 2)) c = 2 * arctan2(sqrt(a), sqrt(1 - a)) return R * c
def raDeg (raHr, raMin, raSec, dec=0.0): # Make this one better """#changes ra from time units to degrees, dec in degrees""" raTime = raHr + (raMin/60.0) + (raSec/3600.0) newra = raTime*(15.0)*(sc.cos(sc.radians(dec)) ) #should be dec != 0.0? Works if dec =0.0... #15.0 = (360 degrees)/(24 hours) #print 'converted ra, in degrees:' return newra
def earthRelease(degs): ang = sp.radians(degs%360) # -pi<ang<pi height = Earth.rad + (100+2*600)*1e3 pos = Earth.orbitPos(0) + sp.array([sp.cos(ang), sp.sin(ang)])*height vel = Earth.orbitVel(pos, 0, 1) # stable circular around earth vel = vel + 3.5e3*unitV(sp.array([0,0]), vel) # add v from tether rotation vel = vel + Sun.orbitVel(pos, 0, 1) # add sun orbital v return pos, vel
def Distance(origin, destination): """Distance - Get the distance in kilometers between two coordinates. :param origin: tuple of origin lat and long :param destination: tuple of destination lat and long """ lat1, lon1 = origin lat2, lon2 = destination radius = 6371 # km dlat = sp.radians(lat2 - lat1) dlon = sp.radians(lon2 - lon1) a = sp.sin(dlat / 2) * sp.sin(dlat / 2) + sp.cos(sp.radians(lat1)) \ * sp.cos(sp.radians(lat2)) * sp.sin(dlon / 2) * sp.sin(dlon / 2) c = 2 * sp.arctan2(sp.sqrt(a), sp.sqrt(1 - a)) d = radius * c return d
def angsep(x1,y1,x2,y2): # """ # spherical angle separation, aka haversine formula # input and output are in degrees # """ dlat = sp.radians(y2 - y1) dlon = sp.radians(x2 - x1) y1 = sp.radians(y1) y2 = sp.radians(y2) a = sp.sin(dlat/2.)*sp.sin(dlat/2.) + sp.cos(y1)*sp.cos(y2)*sp.sin(dlon/2.)*sp.sin(dlon/2.) #if a<0 or a>1.: print 'a:',a,x1,y1,x2,y2,dlat,dlon,'!!!!!' try: c = 2*sp.arctan2(sp.sqrt(a), sp.sqrt(1.-a)) except: print '!!!:',a,x1,y1,x2,y2,dlat,dlon,'!!!!!' c=0 pass return sp.degrees(c)
def _update_canvas(self): """ Update the figure when the user changes an input value :return: """ # Get the parameters from the form frequency = float(self.frequency.text()) number_of_elements = int(self.number_of_elements.text()) scan_angle = float(self.scan_angle.text()) element_spacing = float(self.element_spacing.text()) side_lobe_level = float(self.side_lobe_level.text()) # Get the selected antenna from the form antenna_type = self.antenna_type.currentText() # Set the angular span theta = linspace(0.0, pi, 1000) # Set up the args kwargs = { 'number_of_elements': number_of_elements, 'scan_angle': radians(scan_angle), 'element_spacing': element_spacing, 'frequency': frequency, 'theta': theta, 'window_type': antenna_type, 'side_lobe_level': side_lobe_level } # Get the array factor af = linear_array.array_factor(**kwargs) # Clear the axes for the updated plot self.axes1.clear() # Create the line plot self.axes1.plot(degrees(theta), 20.0 * log10(abs(af) + finfo(float).eps), '') # Set the y axis limit self.axes1.set_ylim(-80, 5) # Set the x and y axis labels self.axes1.set_xlabel("Theta (degrees)", size=12) self.axes1.set_ylabel("Array Factor (dB)", size=12) # Turn on the grid self.axes1.grid(linestyle=':', linewidth=0.5) # Set the plot title and labels self.axes1.set_title('Linear Array Antenna Pattern', size=14) # Set the tick label size self.axes1.tick_params(labelsize=12) # Update the canvas self.my_canvas.draw()
def washburn(target, surface_tension='pore.surface_tension', contact_angle='pore.contact_angle', diameter='throat.diameter'): r""" Computes the capillary entry pressure assuming the throat in a cylindrical tube. Parameters ---------- target : OpenPNM Object The object for which these values are being calculated. This controls the length of the calculated array, and also provides access to other necessary thermofluid properties. surface_tension : string The dictionary key containing the surface tension values to be used. If a pore property is given, it is interpolated to a throat list. contact_angle : string The dictionary key containing the contact angle values to be used. If a pore property is given, it is interpolated to a throat list. diameter : string The dictionary key containing the throat diameter values to be used. Returns ------- value : NumPy ndarray Array containing pore/throat capillary entry pressure values. Notes ----- The Washburn equation is: .. math:: P_c = -\frac{2\sigma(cos(\theta))}{r} This is the most basic approach to calculating entry pressure and is suitable for highly non-wetting invading phases in most materials. """ network = target.project.network phase = target.project.find_phase(target) element, sigma, theta = _get_key_props(phase=phase, diameter=diameter, surface_tension=surface_tension, contact_angle=contact_angle) r = network[diameter] / 2 value = -2 * sigma * _sp.cos(_sp.radians(theta)) / r if diameter.split('.')[0] == 'throat': value = value[phase.throats(target.name)] else: value = value[phase.pores(target.name)] value[_sp.absolute(value) == _sp.inf] = 0 return value
def washburn(physics, phase, network, surface_tension='pore.surface_tension', contact_angle='pore.contact_angle', throat_diameter='throat.diameter', **kwargs): r""" Computes the capillary entry pressure assuming the throat in a cylindrical tube. Parameters ---------- network : OpenPNM Network Object The Network object is phase : OpenPNM Phase Object Phase object for the invading phases containing the surface tension and contact angle values. sigma : dict key (string) The dictionary key containing the surface tension values to be used. If a pore property is given, it is interpolated to a throat list. theta : dict key (string) The dictionary key containing the contact angle values to be used. If a pore property is given, it is interpolated to a throat list. throat_diameter : dict key (string) The dictionary key containing the throat diameter values to be used. Notes ----- The Washburn equation is: .. math:: P_c = -\frac{2\sigma(cos(\theta))}{r} This is the most basic approach to calculating entry pressure and is suitable for highly non-wetting invading phases in most materials. """ if surface_tension.split('.')[0] == 'pore': sigma = phase[surface_tension] sigma = phase.interpolate_data(data=sigma) else: sigma = phase[surface_tension] if contact_angle.split('.')[0] == 'pore': theta = phase[contact_angle] theta = phase.interpolate_data(data=theta) else: theta = phase[contact_angle] r = network[throat_diameter] / 2 value = -2 * sigma * _sp.cos(_sp.radians(theta)) / r if throat_diameter.split('.')[0] == 'throat': value = value[phase.throats(physics.name)] else: value = value[phase.pores(physics.name)] value[_sp.absolute(value) == _sp.inf] = 0 return value
def obsolete_calc_azimuth(lat1, lon1, lat2, lon2): """NOT USED Calculate a trace azimuth given start and end positions. lat1 latitude of start point lon1 longitude of start point lat2 latitude of end point lon2 longitude of end point Returns azimuth at start point in degrees, in range [0, 360). """ lat1 = radians(lat1) lon1 = radians(lon1) lat2 = radians(lat2) lon2 = radians(lon2) numerator = sin(lon1 - lon2) * cos(lat2) denominator = sin(arccos((sin(lat2) * sin(lat1)) + (cos(lat1) * cos(lat2) * cos(lon2 - lon1)))) azimuth = degrees(arcsin(numerator / denominator)) return azimuth
def washburn(physics, phase, network, surface_tension='pore.surface_tension', contact_angle='pore.contact_angle', diameter='throat.diameter', **kwargs): r""" Computes the capillary entry pressure assuming the throat in a cylindrical tube. Parameters ---------- network : OpenPNM Network Object The Network object is phase : OpenPNM Phase Object Phase object for the invading phases containing the surface tension and contact angle values. sigma : dict key (string) The dictionary key containing the surface tension values to be used. If a pore property is given, it is interpolated to a throat list. theta : dict key (string) The dictionary key containing the contact angle values to be used. If a pore property is given, it is interpolated to a throat list. diameter : dict key (string) The dictionary key containing the throat diameter values to be used. Notes ----- The Washburn equation is: .. math:: P_c = -\frac{2\sigma(cos(\theta))}{r} This is the most basic approach to calculating entry pressure and is suitable for highly non-wetting invading phases in most materials. """ if (surface_tension.split('.')[0] == 'pore' and diameter.split('.')[0] == 'throat'): sigma = phase[surface_tension] sigma = phase.interpolate_data(data=sigma) else: sigma = phase[surface_tension] if (contact_angle.split('.')[0] == 'pore' and diameter.split('.')[0] == 'throat'): theta = phase[contact_angle] theta = phase.interpolate_data(data=theta) else: theta = phase[contact_angle] r = network[diameter]/2 value = -2*sigma*_sp.cos(_sp.radians(theta))/r if diameter.split('.')[0] == 'throat': value = value[phase.throats(physics.name)] else: value = value[phase.pores(physics.name)] value[_sp.absolute(value) == _sp.inf] = 0 return value
def resourceCalc(date, sigma, phi_c, I_B, lats, rho): ''' inputs ------ date - datetime object sigma - collector angle rho - factor for ground reflectance ''' #time = datenum(dates); #sigma = (sigma)*pi/180 #collector angle sigma from ground sigma = sp.radians(sigma) L = lats L = sp.radians(L) phi_c = sp.radians(phi_c) #n = ceil((1:length(time))/24)'; # give day of year n = int(date.strftime('%j')) delta = 23.45 * pi / 180. * sin(2 * pi / 365. * (n - 81)) time_solar = int(date.strftime('%H'))+1 H = 2 * pi / 24 * (12 - time_solar) beta = arcsin(cos(L) * cos(delta) * cos(H) + sin(L) * sin(delta)) phi_s = arcsin(cos(delta) * sin(H) / cos(beta)) # C ambient light correction C = 0.095 + 0.04 * sin(360 / 365. * (n - 100)) # Stationary Collector I_C = I_B * (cos(beta) * cos(phi_s - phi_c) * sin(sigma) + sin(beta) * cos(sigma) + C * (1+cos(sigma)) / 2. + rho * (sin(beta)+C) * (1-cos(sigma))/2.) if I_C < 0: I_C = 0 return I_C
def calc_fault_width(depth_top, depth_bottom, dip): """Calculate the width of a fault in kms given the dip and depth top and bottom. depth_top depth to the top of the seismogenic zone depth_bottom depth to the bottom of the seismogenic zone dip angle of dip of the fault in decimal degrees Returns width of fault in kms. """ fault_width = (depth_bottom - depth_top) / sin(radians(dip)) return fault_width
def latlon(distance, bearing, printout="DDM"): x = distance * sp.cos(sp.radians(bearing)) y = distance * sp.sin(sp.radians(bearing)) xdeg = x / KM_TO_DEGREES * sp.cos(sp.radians(GGI_LAT)) + GGI_LON ydeg = x / KM_TO_DEGREES + GGI_LAT x_decimal_min = (xdeg % 1) * 60 y_decimal_min = (xdeg % 1) * 60 x_sec = (x_decimal_min % 1) * 60 y_sec = (y_decimal_min % 1) * 60 if printout == "DDM": print "%i %f', %i %f'" % (int(ydeg), y_decimal_min, int(xdeg), x_decimal_min) elif printout == "DMS": print "%i %i' %i\", %i %i' %i\"" % ( int(ydeg), int(y_decimal_min), round(y_sec), int(ydeg), int(y_decimal_min), round(y_sec), ) else: print ydeg, xdeg
def pw_cf_angleply(): mat = predefined.carbon_fiber_generic() a = layup.Laminate() t = 150e-6 a.append(layup.Ply(scipy.radians(30),t,mat)) a.append(layup.Ply(scipy.radians(-30),t,mat)) a.append(layup.Ply(scipy.radians(0),t,mat)) a.append(layup.Ply(scipy.radians(90),t,mat)) a.append(layup.Ply(scipy.radians(90),t,mat)) a.append(layup.Ply(scipy.radians(0),t,mat)) a.append(layup.Ply(scipy.radians(-30),t,mat)) a.append(layup.Ply(scipy.radians(30),t,mat)) return a
def calc_fault_area(lat1, lon1, lat2, lon2, depth_top, depth_bottom, dip): """Calculate the area of a fault in kms given the trace, dip and depth top and bottom. lat1 latitude of start point lon1 longitude of start point lat2 latitude of end point lon2 longitude of end point depth_top depth to the top of the seismogenic zone depth_bottom depth to the bottom of the seismogenic zone dip angle of dip of the fault in decimal degrees Returns area of fault in kms. """ fault_length = calc_ll_dist(lat1, lon1, lat2, lon2) fault_width = (depth_bottom - depth_top) / sin(radians(dip)) fault_area = fault_length * fault_width return fault_area
def washburn(physics, fluid, geometry, network, propname, pore_surface_tension='surface_tension', pore_contact_angle='contact_angle', throat_diameter='diameter', **params): r""" Computes the capillary entry pressure assuming the throat is a cylindrical tube. Parameters ---------- network : OpenPNM Network Object The network on which to apply the calculation fluid : OpenPNM Fluid Object Fluid object for the invading fluids Notes ----- The Washburn equation is: .. math:: P_c = -\frac{2\sigma(cos(\theta))}{r} This is the most basic approach to calculating entry pressure and is suitable for highly non-wetting invading fluids in most materials. """ sigma = network.get_pore_data(phase=fluid,prop=pore_surface_tension) sigma = network.interpolate_throat_data(sigma) theta = network.get_pore_data(phase=fluid,prop=pore_contact_angle) theta = network.interpolate_throat_data(theta) r = network.get_throat_data(prop=throat_diameter)/2 value = -2*sigma*sp.cos(sp.radians(theta))/r mask = network.get_throat_indices(geometry) network.set_throat_data(phase=fluid,prop=propname,data=value[mask],locations=geometry)
def write_netcdf(self, outfile): """ Output a netCDF file containing the results of the calculation specified by the GridCalc object. Each stress field encapsulated in the GridCalc object will be output within the netCDF file as three data fields, one for each of the stress tensor components L{Ttt}_NAME, L{Tpt}_NAME, L{Tpp}_NAME, where NAME is the name of the L{StressDef} object (e.g. L{Diurnal} or L{NSR}). Writing out the calculation results causes the calculation to take place. No mechanism for performing the calculation and retaining it in memory for manipulation is currently provided. """ # Create a netCDF file object to stick the calculation results in: nc_out = netCDF3.Dataset(outfile, 'w') # Set metadata fields of nc_out appropriate to the calculation at hand. nc_out.description = "satstress calculation on a regular grid. All parameter units are SI (meters-kilograms-seconds)" nc_out.history = """Created: %s using the satstress python package: http://code.google.com/p/satstress""" % ( time.ctime(time.time()) ) nc_out.Conventions = __NETCDF_CONVENTIONS__ ######################################################################## # Independent (input) parameters for the run: ######################################################################## nc_out.grid_id = self.grid.grid_id nc_out.system_id = self.grid.satellite.system_id nc_out.planet_mass = self.grid.satellite.planet_mass nc_out.orbit_eccentricity = self.grid.satellite.orbit_eccentricity nc_out.orbit_semimajor_axis = self.grid.satellite.orbit_semimajor_axis nc_out.layer_id_0 = self.grid.satellite.layers[0].layer_id nc_out.density_0 = self.grid.satellite.layers[0].density nc_out.lame_mu_0 = self.grid.satellite.layers[0].lame_mu nc_out.lame_lambda_0 = self.grid.satellite.layers[0].lame_lambda nc_out.thickness_0 = self.grid.satellite.layers[0].thickness nc_out.viscosity_0 = self.grid.satellite.layers[0].viscosity nc_out.tensile_str_0 = self.grid.satellite.layers[0].tensile_str nc_out.layer_id_1 = self.grid.satellite.layers[1].layer_id nc_out.density_1 = self.grid.satellite.layers[1].density nc_out.lame_mu_1 = self.grid.satellite.layers[1].lame_mu nc_out.lame_lambda_1 = self.grid.satellite.layers[1].lame_lambda nc_out.thickness_1 = self.grid.satellite.layers[1].thickness nc_out.viscosity_1 = self.grid.satellite.layers[1].viscosity nc_out.tensile_str_1 = self.grid.satellite.layers[1].tensile_str nc_out.layer_id_2 = self.grid.satellite.layers[2].layer_id nc_out.density_2 = self.grid.satellite.layers[2].density nc_out.lame_mu_2 = self.grid.satellite.layers[2].lame_mu nc_out.lame_lambda_2 = self.grid.satellite.layers[2].lame_lambda nc_out.thickness_2 = self.grid.satellite.layers[2].thickness nc_out.viscosity_2 = self.grid.satellite.layers[2].viscosity nc_out.tensile_str_2 = self.grid.satellite.layers[2].tensile_str nc_out.layer_id_3 = self.grid.satellite.layers[3].layer_id nc_out.density_3 = self.grid.satellite.layers[3].density nc_out.lame_mu_3 = self.grid.satellite.layers[3].lame_mu nc_out.lame_lambda_3 = self.grid.satellite.layers[3].lame_lambda nc_out.thickness_3 = self.grid.satellite.layers[3].thickness nc_out.viscosity_3 = self.grid.satellite.layers[3].viscosity nc_out.tensile_str_3 = self.grid.satellite.layers[3].tensile_str ######################################################################## # A selection of dependent (output) parameters for the run. ######################################################################## nc_out.satellite_radius = self.grid.satellite.radius() nc_out.satellite_mass = self.grid.satellite.mass() nc_out.satellite_density = self.grid.satellite.density() nc_out.satellite_surface_gravity = self.grid.satellite.surface_gravity() nc_out.satellite_orbit_period = self.grid.satellite.orbit_period() ######################################################################## # What about Frequency dependent Parameters? ######################################################################## # There are a variety of interesting frequency-dependent parameters # that we ought to really output as well (delta, and the complex Love # numbers, Lame parameters...) for reference, but they'll all depend on # exactly which slice (for instance) in NSR we're looking at, so the # right place to put this meta-data isn't really in the global section # it should be associated with the stress variables themselves. # # It seems that the right way to do this is to define several 1-d # variables that are not coordinate variables (that is, they don't # correspond to one of the dimensions, unlike latitude, or longitude) # e.g.: # nc_out.createVariable('nsr_delta_upper', self.grid.nsr_period_num, ('nsr_period')) # nc_out.createVariable('nsr_lame_mu_twiddle', self.grid.nsr_period_num, ('nsr_period')) ######################################################################## # A few parameters pertaining to the web-interface only: ######################################################################## # TODO nc_out.ssweb_run_id = "" nc_out.ssweb_username = "" nc_out.ssweb_ip_address = "" ######################################################################## # Specify the size and shape of the output datacube. ######################################################################## # LATITUDE: nc_out.createDimension('latitude', self.grid.lat_num) lats = nc_out.createVariable('latitude', 'f4', ('latitude',)) lats.units = "degrees_north" lats.long_name = "latitude" lats[:] = numpy.linspace(self.grid.lat_min, self.grid.lat_max, self.grid.lat_num) # LONGITUDE: nc_out.createDimension('longitude', self.grid.lon_num) lons = nc_out.createVariable('longitude', 'f4', ('longitude',)) lons.units = "degrees_east" lons.long_name = "longitude" lons[:] = numpy.linspace(self.grid.lon_min, self.grid.lon_max, self.grid.lon_num) # NSR_PERIOD nc_out.createDimension('nsr_period', self.grid.nsr_period_num) nsr_periods = nc_out.createVariable('nsr_period', 'f4', ('nsr_period',)) nsr_periods.units = "seconds" nsr_periods.long_name = "NSR period" nsr_periods[:] = numpy.logspace(numpy.log10(self.grid.nsr_period_min), numpy.log10(self.grid.nsr_period_max), self.grid.nsr_period_num) # TIME: # Check to see what kind of units we're using for time, and name the # variables and their units appropriately if self.grid.orbit_min is None: nc_out.createDimension('time', self.grid.time_num) times = nc_out.createVariable('time', 'f4', ('time',)) times.units = "seconds" times.long_name = "time after periapse" times[:] = numpy.linspace(self.grid.time_min, self.grid.time_max, self.grid.time_num) else: nc_out.createDimension('time', self.grid.orbit_num) times = nc_out.createVariable('time', 'f4', ('time',)) times.units = "degrees" times.long_name = "degrees after periapse" times[:] = numpy.linspace(self.grid.orbit_min, self.grid.orbit_max, self.grid.orbit_num) # At this point, we should have all the netCDF dimensions and their # corresponding coordinate variables created (latitutde, longitude, # time/orbit, nsr_period), but we still haven't created the data # variables, which will ultimately hold the results of our stress # calculation, and which depend on the aforedefined dimensions # DIURNAL: Ttt_Diurnal = nc_out.createVariable('Ttt_Diurnal', 'f4', ('time', 'latitude', 'longitude',)) Ttt_Diurnal.units = "Pa" Ttt_Diurnal.long_name = "north-south component of Diurnal eccentricity stresses" Tpt_Diurnal = nc_out.createVariable('Tpt_Diurnal', 'f4', ('time', 'latitude', 'longitude',)) Tpt_Diurnal.units = "Pa" Tpt_Diurnal.long_name = "shear component of Diurnal eccentricity stresses" Tpp_Diurnal = nc_out.createVariable('Tpp_Diurnal', 'f4', ('time', 'latitude', 'longitude',)) Tpp_Diurnal.units = "Pa" Tpp_Diurnal.long_name = "east-west component of Diurnal eccentricity stresses" # NSR: Ttt_NSR = nc_out.createVariable('Ttt_NSR', 'f4', ('nsr_period', 'latitude', 'longitude',)) Ttt_NSR.units = "Pa" Ttt_NSR.long_name = "north-south component of NSR stresses" Tpt_NSR = nc_out.createVariable('Tpt_NSR', 'f4', ('nsr_period', 'latitude', 'longitude',)) Tpt_NSR.units = "Pa" Tpt_NSR.long_name = "shear component of NSR stresses" Tpp_NSR = nc_out.createVariable('Tpp_NSR', 'f4', ('nsr_period', 'latitude', 'longitude',)) Tpp_NSR.units = "Pa" Tpp_NSR.long_name = "east-west component of NSR stresses" # Get the StressDef objects corresponding to Diurnal and NSR stresses: for stress in self.stresscalc.stresses: if stress.__name__ is 'Diurnal': diurnal_stress = ss.StressCalc([stress,]) if stress.__name__ is 'NSR': nsr_stress = ss.StressCalc([stress,]) # Loop over the time variable, doing diurnal calculations over an orbit for t in range(len(times[:])): # We need some kind of progress update, and we need to make sure that # we have a representation of the time coordinate in seconds, because # that's what the satstress library expects - even if we're ultimately # communicating time to the user in terms of "degrees after periapse" if self.grid.orbit_min is None: time_sec = times[t] else: time_sec = diurnal_stress.stresses[0].satellite.orbit_period()*(times[t]/360.0) print "Calculating Diurnal stresses at", times[t], times.long_name for lon in range(len(lons[:])): for lat in range(len(lats[:])): Tau_D = diurnal_stress.tensor(theta = scipy.radians(90.0-lats[lat]),\ phi = scipy.radians(lons[lon]),\ t = time_sec ) nc_out.variables['Ttt_Diurnal'][t,lat,lon] = Tau_D[0,0] nc_out.variables['Tpt_Diurnal'][t,lat,lon] = Tau_D[1,0] nc_out.variables['Tpp_Diurnal'][t,lat,lon] = Tau_D[1,1] # Make sure everything gets written out to the file. nc_out.sync() # Change the satellite's eccentricity to zero to exclude the Diurnal # stresses for the purposes of calculating the NSR stresses: nsr_stress.stresses[0].satellite.orbit_eccentricity = 0.0 # Loop over all the prescribed values of NSR_PERIOD, and do the NSR stress calculation # at each point on the surface. for p_nsr in range(len(nsr_periods[:])): # Adjust the properties of the Satellite and StressDef objects # for the nsr_period being considered: new_sat = nsr_stress.stresses[0].satellite new_sat.nsr_period = nsr_periods[p_nsr] nsr_stress = ss.StressCalc([ss.NSR(new_sat),]) print "Calculating NSR stresses for Pnsr = %g %s" % (nsr_periods[p_nsr], nsr_periods.units,) for lon in range(len(lons[:])): for lat in range(len(lats[:])): Tau_N = nsr_stress.tensor(theta = scipy.radians(90-lats[lat]),\ phi = scipy.radians(lons[lon]),\ t = 0 ) nc_out.variables['Ttt_NSR'][p_nsr,lat,lon] = Tau_N[0,0] nc_out.variables['Tpt_NSR'][p_nsr,lat,lon] = Tau_N[1,0] nc_out.variables['Tpp_NSR'][p_nsr,lat,lon] = Tau_N[1,1] # Make sure everything gets written out to the file. nc_out.sync()
def main(argv): """ Main method """ # read the input file inputfile = ''; outputfile = ''; try: opts, args = getopt.getopt(argv,"hi:o:",["ifile=","ofile="]); except getopt.GetoptError: print 'test.py -i <inputfile> -o <outputfile>' sys.exit(2); for opt, arg in opts: if opt == '-h': print 'test.py -i <inputfile> -o <outputfile>' sys.exit(); elif opt in ("-i", "--ifile"): inputfile = arg; elif opt in ("-o", "--ofile"): outputfile = arg; global exported_trajectory_file exported_trajectory_file = open(outputfile,"w"); global ref_xyz ref_xyz = np.genfromtxt(inputfile, delimiter = ','); x_init_x[0] = ref_xyz[0,0]; x_init_y[0] = ref_xyz[0,1]; x_init_z[0] = ref_xyz[0,2]; Vehicle = VehicleParameters(mass,max_xy_vel,max_z_vel,radians(maxRollPitch),maxDeltaT); Environment = EnvironmentParameters(9.8065); Tuning = TuningParameters(sample_time,Q_x,R_x,Q_y,R_y,Q_z,R_z,max_error_xyz); filt = Filter2ndOrder(1,2,1,Tuning.Ts); t_vec = np.arange(0,10,Tuning.Ts); # used only for open-loop simulations u_vec = np.ones((len(t_vec),1)); u_vec[0] = 0; # used only for open-loop simulations SimulationPars = SimulationParameters(Tuning.Ts,t_vec,u_vec,ref_xyz[:,0],ref_xyz[:,1],ref_xyz[:,2]); OverallSys = SystemDynamics(VehicleParameters = Vehicle, EnvironmentParameters = Environment, TuningParameters = Tuning, SimulationParameters = SimulationPars); Xctrl = LQctrl(OverallSys.SysX_d,Tuning.Qx,Tuning.Rx); Yctrl = LQctrl(OverallSys.SysY_d,Tuning.Qy,Tuning.Ry); Zctrl = LQctrl(OverallSys.SysZ_d,Tuning.Qz,Tuning.Rz); [Nr,Ny] = ref_xyz.shape; X_vec = np.zeros((1,2)); X_vec[0,0] = x_init_x[0]; X_vec[0,1] = x_init_x[1]; Y_vec = np.zeros((1,2)); Y_vec[0,0] = x_init_y[0]; Y_vec[0,1] = x_init_y[1]; Z_vec = np.zeros((1,2)); Z_vec[0,0] = x_init_z[0]; Z_vec[0,1] = x_init_z[1]; Yaw_vec = np.zeros((1,1)); Yaw_vec[0,0] = x_init_yaw[0]; SimResults = np.zeros((1,7)); SimResults[0,0] = x_init_x[0]; SimResults[0,1] = x_init_x[1]; SimResults[0,2] = x_init_y[0]; SimResults[0,3] = x_init_y[1]; SimResults[0,4] = x_init_z[0]; SimResults[0,5] = x_init_z[1]; SimResults[0,6] = x_init_yaw[0]; two_indices = np.zeros((1,2)); two_yaw_refs = np.zeros((1,2)); # simulate the whole path and extract the trajectory for i in range(1,Nr): SysX_Cl = ClosedLoopSim(OverallSys.SysX_d,Xctrl,x_init_x,ref_xyz[i,0],Tuning.Ts,accuracy_range,Vehicle.maxPitch,max_error_xyz); SysY_Cl = ClosedLoopSim(OverallSys.SysY_d,Yctrl,x_init_y,ref_xyz[i,1],Tuning.Ts,accuracy_range,Vehicle.maxRoll,max_error_xyz); SysZ_Cl = ClosedLoopSim(OverallSys.SysZ_d,Zctrl,x_init_z,ref_xyz[i,2],Tuning.Ts,accuracy_range,Vehicle.maxDeltaT,max_error_xyz); x_vec, t_x = SysX_Cl.Simulate(); x_init_x[0] = x_vec[len(t_x)-1,0]; x_init_x[1] = x_vec[len(t_x)-1,1]; y_vec, t_y = SysY_Cl.Simulate(); x_init_y[0] = y_vec[len(t_y)-1,0]; x_init_y[1] = y_vec[len(t_y)-1,1]; z_vec, t_z = SysZ_Cl.Simulate(); x_init_z[0] = z_vec[len(t_z)-1,0]; x_init_z[1] = z_vec[len(t_z)-1,1]; max_len = max(len(x_vec),len(y_vec)); max_len = max(max_len,len(z_vec)); val_vec_x = np.linspace(0,len(x_vec),len(x_vec)); val_vec_y = np.linspace(0,len(y_vec),len(y_vec)); val_vec_z = np.linspace(0,len(z_vec),len(z_vec)); x_pos_interp = np.interp(np.linspace(0,len(x_vec),max_len),val_vec_x,x_vec[:,0]); x_vel_interp = np.interp(np.linspace(0,len(x_vec),max_len),val_vec_x,x_vec[:,1]); y_pos_interp = np.interp(np.linspace(0,len(y_vec),max_len),val_vec_y,y_vec[:,0]); y_vel_interp = np.interp(np.linspace(0,len(y_vec),max_len),val_vec_y,y_vec[:,1]); z_pos_interp = np.interp(np.linspace(0,len(z_vec),max_len),val_vec_z,z_vec[:,0]); z_vel_interp = np.interp(np.linspace(0,len(z_vec),max_len),val_vec_z,z_vec[:,1]); two_indices[0,0] = 0; two_indices[0,1] = max_len; two_yaw_refs[0,0] = ref_xyz[i-1,3]; two_yaw_refs[0,1] = ref_xyz[i,3]; yaw_vec_interp = np.interp(np.linspace(0,max_len,max_len),two_indices[:,0],two_yaw_refs[:,0]); sim_results = np.zeros((len(x_pos_interp),7)); sim_results[:,0] = x_pos_interp; sim_results[:,1] = x_vel_interp; sim_results[:,2] = y_pos_interp; sim_results[:,3] = y_vel_interp; sim_results[:,4] = z_pos_interp; sim_results[:,5] = z_vel_interp; sim_results[:,6] = yaw_vec_interp; SimResults = np.vstack((SimResults,sim_results)); t_out = np.linspace(0,len(SimResults)*Tuning.Ts,len(SimResults)); # pass all states from a second order filter SimResults_Filter = np.zeros((len(SimResults)+1,8)); SimResults_Filter[:,0] = filt.RunFilter(SimResults[:,0],t_out).transpose(); SimResults_Filter[:,1] = filt.RunFilter(SimResults[:,1],t_out).transpose(); SimResults_Filter[:,2] = filt.RunFilter(SimResults[:,2],t_out).transpose(); SimResults_Filter[:,3] = filt.RunFilter(SimResults[:,3],t_out).transpose(); SimResults_Filter[:,4] = filt.RunFilter(SimResults[:,4],t_out).transpose(); SimResults_Filter[:,5] = filt.RunFilter(SimResults[:,5],t_out).transpose(); SimResults_Filter[:,6] = filt.RunFilter(SimResults[:,6],t_out).transpose(); SimResults_Filter[:,7] = np.linspace(0,len(SimResults)*Tuning.Ts,len(SimResults)+1); np.savetxt(exported_trajectory_file,SimResults_Filter, delimiter = ',') # plot the results plot_result(SimResults_Filter[1:len(SimResults_Filter),:],ref_xyz,'o','g','*','b'); raw_input("Press Enter to close");
def purcell(physics, phase, network, r_toroid, surface_tension='pore.surface_tension', contact_angle='pore.contact_angle', throat_diameter='throat.diameter', **kwargs): r""" Computes the throat capillary entry pressure assuming the throat is a toroid. Parameters ---------- network : OpenPNM Network Object The Network on which to apply the calculation sigma : dict key (string) The dictionary key containing the surface tension values to be used. If a pore property is given, it is interpolated to a throat list. theta : dict key (string) The dictionary key containing the contact angle values to be used. If a pore property is given, it is interpolated to a throat list. throat_diameter : dict key (string) The dictionary key containing the throat diameter values to be used. r_toroid : float or array_like The radius of the toroid surrounding the pore Notes ----- This approach accounts for the converging-diverging nature of many throat types. Advancing the meniscus beyond the apex of the toroid requires an increase in capillary pressure beyond that for a cylindical tube of the same radius. The details of this equation are described by Mason and Morrow [1]_, and explored by Gostick [2]_ in the context of a pore network model. References ---------- .. [1] G. Mason, N. R. Morrow, Effect of contact angle on capillary displacement curvatures in pore throats formed by spheres. J. Colloid Interface Sci. 168, 130 (1994). .. [2] J. Gostick, Random pore network modeling of fibrous PEMFC gas diffusion media using Voronoi and Delaunay tessellations. J. Electrochem. Soc. 160, F731 (2013). TODO: Triple check the accuracy of this equation """ if surface_tension.split('.')[0] == 'pore': sigma = phase[surface_tension] sigma = phase.interpolate_data(data=sigma) else: sigma = phase[surface_tension] if contact_angle.split('.')[0] == 'pore': theta = phase[contact_angle] theta = phase.interpolate_data(data=theta) else: theta = phase[contact_angle] r = network[throat_diameter]/2 R = r_toroid alpha = theta - 180 + _sp.arcsin(_sp.sin(_sp.radians(theta)/(1+r/R))) value = (-2*sigma/r) * \ (_sp.cos(_sp.radians(theta - alpha)) / (1 + R/r*(1 - _sp.cos(_sp.radians(alpha))))) if throat_diameter.split('.')[0] == 'throat': value = value[phase.throats(physics.name)] else: value = value[phase.pores(physics.name)] return value
def __init__(self, lat=40, tmy=None): self.lat = sp.radians(lat) self.tmy = tmy
def hour_angle(self, date): # TODO: add seconds? decimal_hour = date.hour + date.minute / 60. return sp.radians(15 * (decimal_hour - 12))
def declination(self, date): day_of_year = self.day_of_year(date) return sp.radians(23.45 * sp.sin(2 * sp.pi * (day_of_year - 81) / 365.0))