def load_love_numbers(LMAX, LOVE_NUMBERS=0, REFERENCE='CF'): """ Reads PREM load Love numbers for the range of spherical harmonic degrees and applies isomorphic parameters Arguments --------- LMAX: maximum spherical harmonic degree Keyword arguments ----------------- LOVE_NUMBERS: Load Love numbers dataset 0: Han and Wahr (1995) values from PREM 1: Gegout (2005) values from PREM 2: Wang et al. (2012) values from PREM REFERENCE: Reference frame for calculating degree 1 love numbers CF: Center of Surface Figure (default) CM: Center of Mass of Earth System CE: Center of Mass of Solid Earth Returns ------- kl: Love number of Gravitational Potential hl: Love number of Vertical Displacement ll: Love number of Horizontal Displacement """ #-- load love numbers file if (LOVE_NUMBERS == 0): #-- PREM outputs from Han and Wahr (1995) #-- https://doi.org/10.1111/j.1365-246X.1995.tb01819.x love_numbers_file = utilities.get_data_path(['data', 'love_numbers']) header = 2 columns = ['l', 'hl', 'kl', 'll'] elif (LOVE_NUMBERS == 1): #-- PREM outputs from Gegout (2005) #-- http://gemini.gsfc.nasa.gov/aplo/ love_numbers_file = utilities.get_data_path( ['data', 'Load_Love2_CE.dat']) header = 3 columns = ['l', 'hl', 'll', 'kl'] elif (LOVE_NUMBERS == 2): #-- PREM outputs from Wang et al. (2012) #-- https://doi.org/10.1016/j.cageo.2012.06.022 love_numbers_file = utilities.get_data_path( ['data', 'PREM-LLNs-truncated.dat']) header = 1 columns = ['l', 'hl', 'll', 'kl', 'nl', 'nk'] #-- LMAX of load love numbers from Han and Wahr (1995) is 696. #-- from Wahr (2007) linearly interpolating kl works #-- however, as we are linearly extrapolating out, do not make #-- LMAX too much larger than 696 #-- read arrays of kl, hl, and ll Love Numbers hl, kl, ll = read_love_numbers(love_numbers_file, LMAX=LMAX, HEADER=header, COLUMNS=columns, REFERENCE=REFERENCE, FORMAT='tuple') #-- return a tuple of load love numbers return (hl, kl, ll)
def test_point_masses(NPTS): # create spatial grid dlon, dlat = (1.0, 1.0) lat = np.arange(90.0 - dlat / 2.0, -90.0 - dlat / 2.0, -dlat) lon = np.arange(-180.0 + dlon / 2.0, 180.0 + dlon / 2.0, dlon) gridlon, gridlat = np.meshgrid(lon, lat) nlat, nlon = np.shape(gridlon) # parameterize point masses LAT = lat[0] - dlat * np.random.randint(0, nlat, size=NPTS) LON = lon[0] + dlon * np.random.randint(0, nlon, size=NPTS) MASS = 100.0 - 200.0 * np.random.randn(NPTS) # create test gridded field data = np.zeros((nlat, nlon)) for i in range(NPTS): indy, indx = np.nonzero((gridlat == LAT[i]) & (gridlon == LON[i])) data[indy, indx] += MASS[i] # path to load Love numbers file love_numbers_file = get_data_path(['data', 'love_numbers']) # read load Love numbers hl, kl, ll = read_love_numbers(love_numbers_file) # calculate harmonics and degree amplitudes for each case grid_Ylms = gen_stokes(data, lon, lat, LMAX=60, UNITS=2, LOVE=(hl, kl, ll)) grid_Ylms.amplitude() point_Ylms = gen_point_load(MASS, LON, LAT, LMAX=60, UNITS=2, LOVE=(hl, kl, ll)) point_Ylms.amplitude() # check that harmonic data is equal to machine precision difference_Ylms = grid_Ylms.copy() difference_Ylms.subtract(point_Ylms) harmonic_eps = np.finfo(np.float32).eps assert np.all(np.abs(difference_Ylms.clm) < harmonic_eps) # verify that the degree amplitudes are within tolerance assert np.all(np.abs(grid_Ylms.amp - point_Ylms.amp) < harmonic_eps)