def main(): d_lith = 150.e3 rho_crust = 2900. d_sigma = 45.e3 lmax_hydro = 2 gravfile = 'Data/gmm3_120_sha.tab' topofile = 'Data/MarsTopo719.shape' potential = pyshtools.SHGravCoeffs.from_file(gravfile, header_units='km') omega = pyshtools.constant.omega_mars.value potential.omega = omega print('Gravity file = {:s}'.format(gravfile)) print('Lmax of potential coefficients = {:d}'.format(potential.lmax)) print('Reference radius (km) = {:f}'.format(potential.r0 / 1.e3)) print('GM = {:e}'.format(potential.gm)) print('Mass = {:e}'.format(potential.mass)) print('Omega = {:e}'.format(potential.omega)) lmax_calc = 90 lmax = 359 topo = pyshtools.SHCoeffs.from_file(topofile, lmax=lmax) topo.r0 = topo.coeffs[0, 0, 0] print('Topography file = {:s}'.format(topofile)) print('Lmax of topography coefficients = {:d}'.format(topo.lmax)) print('Reference radius (km) = {:f}\n'.format(topo.r0 / 1.e3)) # --- read 1D reference interior model --- model_name = [ 'DWThot', 'DWThotCrust1', 'DWThotCrust1r', 'EH45Tcold', 'EH45TcoldCrust1', 'EH45TcoldCrust1r', 'EH45ThotCrust2', 'EH45ThotCrust2r', 'LFAK', 'SANAK', 'TAYAK', 'DWAK', 'ZG_DW' ] spec = 'Data/Mars-reference-interior-models/Smrekar/' interior_file = [spec + name + '.deck' for name in model_name] for file in interior_file: print('=== Reading model {:s} ==='.format(file)) with open(file, 'r') as f: lines = f.readlines() print(lines[0].strip()) data = lines[1].split() if float(data[2]) != 1: raise RuntimeError( 'Program not capable of reading polynomial ' + 'files') num_file = int(lines[2].split()[0]) crust_index_file = int(lines[2].split()[3]) core_index_file = int(lines[2].split()[2]) i_crust_file = crust_index_file - 1 i_core_file = core_index_file - 1 radius = np.zeros(num_file) rho = np.zeros(num_file) num = 0 for i in range(0, num_file - 1): data = lines[i + 3].split() rb = float(data[0]) rhob = float(data[1]) data = lines[i + 4].split() rt = float(data[0]) rhot = float(data[1]) if rb == rt: if i == i_core_file: i_core = num if i == i_crust_file: i_crust = num else: radius[num] = rb rho[num] = (rhot + rhob) / 2. num += 1 radius[num] = rt rho[num] = 0. # the density above the surface is zero num += 1 n = num - 1 radius = radius[:n + 1] rho = rho[:n + 1] r0_model = radius[n] print('Surface radius of model (km) = {:f}'.format(r0_model / 1.e3)) for i in range(0, n + 1): if radius[i] <= (r0_model - d_lith) and \ radius[i+1] > (r0_model - d_lith): if radius[i] == (r0_model - d_lith): i_lith = i elif (r0_model - d_lith) - radius[i] <= radius[i+1] -\ (r0_model - d_lith): i_lith = i else: i_lith = i + 1 break rho_mantle = rho[i_crust - 1] rho_core = rho[i_core - 1] print('Mantle density (kg/m3) = {:f}'.format(rho_mantle)) print('Mantle radius (km) = {:f}'.format(radius[i_crust] / 1.e3)) print('Core density (kg/m3) = {:f}'.format(rho_core)) print('Core radius (km) = {:f}'.format(radius[i_core] / 1.e3)) print('Assumed depth of lithosphere (km) = {:f}'.format(d_lith / 1.e3)) print( 'Actual depth of lithosphere in discretized model (km) = {:f}'. format((r0_model - radius[i_lith]) / 1.e3)) r_sigma = topo.r0 - d_sigma hlm, clm_hydro, mass_model = \ HydrostaticShapeLith(radius, rho, i_lith, potential, topo, rho_crust, r_sigma, omega, lmax_hydro) print('Percentage of h20 derived from hydrostatic mantle = ' '{:f}'.format(clm_hydro.coeffs[0, 2, 0] / potential.coeffs[0, 2, 0] * 100)) # --- read 1D reference interior model --- # --- From Rivoldini model_dir = 'Data/Mars-reference-interior-models/modelsMQS-2' models = os.listdir(model_dir) models.sort() pmin = 100 pmax = 0 for file in models: if os.path.splitext(file)[1] != '.dat': continue print('=== Reading model {:s} ==='.format(file)) with open(os.path.join(model_dir, file), 'r') as f: lines = f.readlines() num = len(lines) - 4 num_dis = num radius = np.zeros(num) rho = np.zeros(num) for i in range(0, num): data = lines[i + 4].split() radius[i] = float(data[0]) rho[i] = float(data[1]) r0_model = radius[num - 1] print('Surface radius of model (km) = {:f}'.format(r0_model / 1.e3)) for i in range(0, num): if radius[i] <= (r0_model - d_lith) and \ radius[i+1] > (r0_model - d_lith): if radius[i] == (r0_model - d_lith): i_lith = i elif (r0_model - d_lith) - radius[i] <= radius[i+1] -\ (r0_model - d_lith): i_lith = i else: i_lith = i + 1 break n = num - 1 rho[n] = 0. # the density above the surface is zero print('Assumed depth of lithosphere (km) = {:f}'.format(d_lith / 1.e3)) print('Actual depth of lithosphere in discretized model (km) = ' '{:f}'.format((r0_model - radius[i_lith]) / 1.e3)) r_sigma = topo.r0 - d_sigma hlm, clm_hydro, mass_model = \ HydrostaticShapeLith(radius, rho, i_lith, potential, topo, rho_crust, r_sigma, omega, lmax_hydro) percent = clm_hydro.coeffs[0, 2, 0] / potential.coeffs[0, 2, 0] * 100 print('Percentage of h20 derived from hydrostatic mantle = ' '{:f}'.format(percent)) if percent > pmax: pmax = percent if percent < pmin: pmin = percent print(pmin, pmax)
def main(): gravfile = 'Data/gmm3_120_sha.tab' topofile = 'Data/MarsTopo719.shape' densityfile = 'Data/dichotomy_359.sh' model_name = [ 'dwcold', 'dwhot_modif', 'dwhot_stairs', 'DWTh2Ref1', 'DWTh2Ref2', 'eh70cold', '"eh70hot', 'Gudkova' ] spec = 'Data/Mars-reference-interior-models/model_' interior_file = [spec + name for name in model_name] lmax_calc = 90 lmax = lmax_calc * 4 potcoefs, lmaxp, header = pyshtools.shio.shread(gravfile, header=True, lmax=lmax) potential = pyshtools.SHCoeffs.from_array(potcoefs) potential.r_ref = float(header[0]) * 1.e3 potential.gm = float(header[1]) * 1.e9 potential.mass = potential.gm / float(pyshtools.constant.grav_constant) print('Gravity file = {:s}'.format(gravfile)) print('Lmax of potential coefficients = {:d}'.format(lmaxp)) print('Reference radius (km) = {:f}'.format(potential.r_ref / 1.e3)) print('GM = {:e}\n'.format(potential.gm)) topo = pyshtools.SHCoeffs.from_file(topofile, lmax=lmax) topo.r0 = topo.coeffs[0, 0, 0] print('Topography file = {:s}'.format(topofile)) print('Lmax of topography coefficients = {:d}'.format(topo.lmax)) print('Reference radius (km) = {:f}\n'.format(topo.r0 / 1.e3)) density = pyshtools.SHCoeffs.from_file(densityfile, lmax=lmax) print('Lmax of density coefficients = {:d}\n'.format(density.lmax)) lat_insight = 4.43 lon_insight = 135.84 filter = 1 half = 50 nmax = 7 lmax_hydro = 15 t0_sigma = 5. # maximum difference between minimum crustal thickness omega = float(pyshtools.constant.omega_mars) d_lith = 150.e3 t0 = 1.e3 # minimum crustal thickness model = 3 # identifier for the interior reference model # --- read 1D reference interior model --- print('=== Reading model {:s} ==='.format(model_name[model])) with open(interior_file[model], 'r') as f: lines = f.readlines() print(lines[0].strip()) data = lines[1].split() if float(data[2]) != 1: raise RuntimeError('Program not capable of reading polynomial ' + 'files') num = int(lines[2].split()[0]) crust_index = int(lines[2].split()[3]) mantle_index = int(lines[2].split()[3]) radius = np.zeros(num) rho = np.zeros(num) for i in range(0, num): data = lines[i + 3].split() radius[i] = float(data[0]) rho[i] = float(data[1]) r0_model = radius[num - 1] print('Surface radius of model (km) = {:f}'.format(r0_model / 1.e3)) for i in range(0, num): if radius[i] <= (r0_model - d_lith) and \ radius[i+1] > (r0_model - d_lith): if radius[i] == (r0_model - d_lith): i_lith = i elif (r0_model - d_lith) - radius[i] <= radius[i+1] -\ (r0_model - d_lith): i_lith = i else: i_lith = i + 1 break n = num - 1 rho[n] = 0. # the density above the surface is zero rho_mantle = rho[crust_index - 1] print('Mantle density (kg/m3) = {:f}'.format(rho_mantle)) print('Assumed depth of lithosphere (km) = {:f}'.format(d_lith / 1.e3)) print('Actual depth of lithosphere in discretized model (km) = {:f}'. format((r0_model - radius[i_lith]) / 1.e3)) # --- Compute gravity contribution from hydrostatic density interfaces --- if False: # compute values for a planet that is completely fluid hlm_fluid, clm_fluid, mass_model = \ HydrostaticShape(radius, rho, omega, potential.gm, potential.r_ref, finiteamplitude=True) print('--- Hydrostatic potential coefficients for a fluid planet ---') print('c20 = {:e}\nc40 = {:e}'.format(clm_fluid.coeffs[0, 2, 0], clm_fluid.coeffs[0, 4, 0])) print('--- Hydrostatic relief of surface for a fluid planet ---') print('h20 = {:e}\nh40 = {:e}'.format(hlm_fluid[n].coeffs[0, 2, 0], hlm_fluid[n].coeffs[0, 4, 0])) hlm, clm_hydro, mass_model = \ HydrostaticShapeLith(radius, rho, i_lith, potential, omega, lmax_hydro, finiteamplitude=False) print('Total mass of model (kg) = {:e}'.format(mass_model)) print('% of J2 arising from beneath lithosphere = {:f}'.format( clm_hydro.coeffs[0, 2, 0] / potential.coeffs[0, 2, 0] * 100.)) potential.coeffs[:, :lmax_hydro+1, :lmax_hydro+1] -= \ clm_hydro.coeffs[:, :lmax_hydro+1, :lmax_hydro+1] # --- Constant density model --- rho_c = 2900. print('-- Constant density model --\nrho_c = {:f}'.format(rho_c)) tmin = 1.e9 thickave = 44.e3 # initial guess of average crustal thickness while abs(tmin - t0) > t0_sigma: # iterate to fit assumed minimum crustal thickness moho = pyMoho.pyMoho(potential, topo, lmax, rho_c, rho_mantle, thickave, filter_type=filter, half=half, lmax_calc=lmax_calc, nmax=nmax, quiet=True) thick_grid = (topo.pad(lmax) - moho.pad(lmax)).expand(grid='DH2') print('Average crustal thickness (km) = {:f}'.format(thickave / 1.e3)) print('Crustal thickness at InSight landing sites (km) = {:f}'.format( (topo.pad(lmax) - moho.pad(lmax)).expand(lat=lat_insight, lon=lon_insight) / 1.e3)) tmin = thick_grid.data.min() tmax = thick_grid.data.max() print('Minimum thickness (km) = {:e}'.format(tmin / 1.e3)) print('Maximum thickness (km) = {:e}'.format(tmax / 1.e3)) thickave += t0 - tmin thick_grid.plot(show=False, fname='Thick-Mars-1.png') moho.plot_spectrum(show=False, fname='Moho-spectrum-Mars-1.png') # --- Model with variable density --- rho_south = 2900. rho_north = 2900. porosity = 0.0 print('-- Variable density model ---\n' + 'rho_south = {:f}\n'.format(rho_south) + 'rho_north = {:f}'.format(rho_north)) density = density * (rho_north - rho_south) density.coeffs[0, 0, 0] += rho_south tmin = 1.e9 thickave = 44.e3 # initial guess of average crustal thickness while abs(tmin - t0) > t0_sigma: # iterate to fit assumed minimum crustal thickness moho = pyMoho.pyMohoRho(potential, topo, density, porosity, lmax, rho_mantle, thickave, filter_type=filter, half=half, lmax_calc=lmax_calc, quiet=True, nmax=nmax) thick_grid = (topo.pad(lmax) - moho.pad(lmax)).expand(grid='DH2') print('Average crustal thickness (km) = {:e}'.format(thickave / 1.e3)) print('Crustal thickness at InSight landing sites (km) = {:e}'.format( (topo.pad(lmax) - moho.pad(lmax)).expand(lat=lat_insight, lon=lon_insight) / 1.e3)) tmin = thick_grid.data.min() tmax = thick_grid.data.max() print('Minimum thickness (km) = {:e}'.format(tmin / 1.e3)) print('Maximum thickness (km) = {:e}'.format(tmax / 1.e3)) thickave += t0 - tmin thick_grid.plot(show=False, fname='Thick-Mars-2.png') moho.plot_spectrum(show=False, fname='Moho-spectrum-Mars-2.png')
def main(): lmax_grid = 359 lmax = 6 omega = pyshtools.constant.omega_moon.value rem = pyshtools.constant.a_moon.value mass_earth = pyshtools.constant.mass_earth.value r0 = pyshtools.constant.r_moon.value cthick = 34.e3 # 43.e3 or 34.0e3 rho_crust = 2550. out_rc_fc = "rc_fc_34_2550.dat" out_rc_rhoc = "rc_rhoc_34_2550.dat" out_rc_beta = "rc_beta_34_2550.dat" sh_core = "core_34.sh" core_shape = "core_shape_330_34.dat" rcore_int = 1.e3 rcore_start = 250.e3 rcore_end = 450.e3 rhocore_start = 5000. rhocore_end = 8000. rhocore_int = 1. ismr2 = 0.3927280 # Williams et al. (2014) ismr2 = ismr2 * (1738.e3 / r0)**2 pot_file = "/Users/lunokhod/Moon/GRAIL/GravityModels/" + \ "JGGRAIL_900C11A_SHA.TAB" potential = pyshtools.SHGravCoeffs.from_file(pot_file, header_units='km') print("Mean planetary radius (km) = {:e}".format(r0 / 1.e3)) print("Is/MR2 (solid Moon using mean radius) = {:e}".format(ismr2)) print("Lmax of Gravitational potential = {:d}".format(potential.lmax)) print("Reference radius of potential model (km) = {:e}".format( potential.r0 / 1.e3)) print("GM = {:e}".format(potential.gm)) mass = potential.gm / pyshtools.constant.G.value print("Mass (kg) = {:e}".format(mass)) print("Omega = {:e}".format(omega)) print("Period (days) = {:e}".format(2. * np.pi / omega / 60. / 60. / 24.)) print("Average crustal thickness (km) = {:e}".format(cthick / 1.e3)) print("Crustal density (kg/m3) = {:e}".format(rho_crust)) radius = np.zeros(4) radius[0] = 0. radius[2] = r0 - cthick radius[3] = r0 rho = np.zeros(4) rho[2] = rho_crust mass_crust = 4. * np.pi / 3. * rho_crust * (radius[3]**3 - radius[2]**3) n = 3 i_lith = 2 i_core = 1 # For each core radius, find rho_mantle and rho_core that fit total mass # and moment of inertia f_rc_fc = open(out_rc_fc, 'w') f_rc_rhoc = open(out_rc_rhoc, 'w') f_rc_beta = open(out_rc_beta, 'w') for r_core in np.arange(rcore_start, rcore_end + rcore_int, rcore_int, dtype=float): radius[1] = r_core first = True for rho_core in np.arange(rhocore_start, rhocore_end + rhocore_int, rhocore_int, dtype=float): mass_core = 4. * np.pi / 3. * rho_core * r_core**3 mass_mantle = mass - mass_crust - mass_core rho_mantle = mass_mantle * 3. / np.pi / 4. / (radius[2]**3 - r_core**3) rho[0] = rho_core rho[1] = rho_mantle if rho_mantle >= rho_core: continue ismr2_model = moi_solid(radius, rho, n) if first is True: diff_old = ismr2 - ismr2_model first = False else: diff_new = ismr2 - ismr2_model if diff_new * diff_old <= 0.: # interpolate to get the best fitting core density rho_core_final = (rho_core - rhocore_int) - diff_old * \ (rhocore_int) / (diff_new - diff_old) rho[0] = rho_core_final mass_core = 4. * np.pi / 3. * rho[0] * r_core**3 mass_mantle = mass - mass_crust - mass_core rho_mantle = mass_mantle * 3. / np.pi / 4. / \ (radius[2]**3 - r_core**3) rho[1] = rho_mantle hlm, clm_hydro, mass_model = \ HydrostaticShapeLith(radius, rho, i_lith, potential, omega, lmax, finiteamplitude=False, rp=rem, mp=mass_earth) a = hlm[1].expand(lat=0., lon=0., lmax_calc=lmax) b = hlm[1].expand(lat=0., lon=90., lmax_calc=lmax) c = hlm[1].expand(lat=90., lon=0., lmax_calc=lmax) f_core = ((a + b) / 2. - c) / ((a + b) / 2.) beta_core = (a**2 - b**2) / (a**2 + b**2) print(r_core / 1.e3, rho[0], rho[1], f_core, beta_core) f_rc_fc.write('{:e}, {:e}\n'.format(r_core / 1.e3, f_core)) f_rc_rhoc.write('{:e}, {:e}\n'.format( r_core / 1.e3, rho[0])) f_rc_beta.write('{:e}, {:e}\n'.format( r_core / 1.e3, beta_core)) if r_core == 330.e3: hlm[i_core].to_file(sh_core) print("Rcore (km) = {:e}".format(r_core / 1.e3)) print("A (km) = {:e}".format(a / 1.e3)) print("B (km) = {:e}".format(b / 1.e3)) print("C (km) = {:e}".format(c / 1.e3)) print("rho_core (kg/m3) = {:e}".format(rho[0])) grid = hlm[i_core].expand(lmax=lmax_grid, grid='DH2') grid.to_file(core_shape) print("Size of output grid = {:d}, {:d}".format( grid.nlat, grid.nlon)) print("Maximum = {:e}\nMinimum = {:e}".format( grid.data.max(), grid.data.min())) diff_old = diff_new
def main(): d_lith = 150.e3 rho_crust = 2900. d_sigma = 45.e3 lmax_hydro = 90 gravfile = 'Data/gmm3_120_sha.tab' topofile = 'Data/MarsTopo719.shape' densityfile = 'Data/dichotomy_359.sh' model_name = [ 'DWThot', 'DWThotCrust1', 'DWThotCrust1r', 'EH45Tcold', 'EH45TcoldCrust1', 'EH45TcoldCrust1r', 'EH45ThotCrust2', 'EH45ThotCrust2r', 'LFAK', 'SANAK', 'TAYAK', 'DWAK', 'ZG_DW' ] spec = 'Data/Mars-reference-interior-models/Smrekar/' interior_file = [spec + name + '.deck' for name in model_name] potential = pyshtools.SHGravCoeffs.from_file(gravfile, header_units='km') omega = pyshtools.constant.omega_mars.value potential.omega = omega mass_mars = np.float_(potential.mass) print('Gravity file = {:s}'.format(gravfile)) print('Lmax of potential coefficients = {:d}'.format(potential.lmax)) print('Reference radius (km) = {:f}'.format(potential.r0 / 1.e3)) print('GM = {:e}'.format(potential.gm)) print('Mass = {:e}'.format(potential.mass)) print('Omega = {:e}'.format(potential.omega)) lmax_calc = 90 lmax = 359 model = 10 topo = pyshtools.SHCoeffs.from_file(topofile, lmax=lmax) topo.r0 = topo.coeffs[0, 0, 0] r_mars = topo.coeffs[0, 0, 0] print('Topography file = {:s}'.format(topofile)) print('Lmax of topography coefficients = {:d}'.format(topo.lmax)) print('Reference radius (km) = {:f}\n'.format(topo.r0 / 1.e3)) # --- Make geoid map, expand in spherical harmonics # --- and then remove degree-0 term, for plotting purposes only. u0 = potential.gm / potential.r0 geoid = potential.geoid(u0, r=topo.r0, order=2, lmax_calc=lmax_calc, lmax=lmax) geoidsh = geoid.geoid.expand() geoidsh.coeffs[0, 0, 0] = 0. geoid = geoidsh.expand(grid='DH2') # --- read 1D reference interior model --- radius, rho, i_crust, i_core, i_lith = ReadRefModel(interior_file[model], depth=d_lith) rho_mantle = rho[i_crust - 1] rho_core = rho[i_core - 1] n = len(radius) - 1 r0_model = radius[n] # --- Compute purely hydrostatic relief of all interfaces --- print('\n=== Fluid planet ===') if False: for i in range(1, n + 1): hlm_fluid, clm_fluid, mass_model = HydrostaticShape(radius, rho, omega, potential.gm, potential.r0, i_clm_hydro=i) print('i = {:d}, r = {:f}, rho = {:f}, %C20 = {:f}'.format( i, radius[i], rho[i], clm_fluid.coeffs[0, 2, 0] / potential.coeffs[0, 2, 0] * 100)) hlm_fluid, clm_fluid, mass_model = \ HydrostaticShape(radius, rho, omega, potential.gm, potential.r0) print('--- Hydrostatic relief of surface for a fluid planet ---') print('h20 = {:e}\n'.format(hlm_fluid[n].coeffs[0, 2, 0]) + 'h40 = {:e}'.format(hlm_fluid[n].coeffs[0, 4, 0])) hydro_surface = hlm_fluid[n].expand() print('Elevation difference between pole and equator (km)' ' {:e}'.format(hydro_surface.max() / 1.e3 - hydro_surface.min() / 1.e3)) print('--- Hydrostatic relief of core-mantle boundary for a fluid planet ' '---') print('h20 = {:e}\n'.format(hlm_fluid[i_core].coeffs[0, 2, 0]) + 'h40 = {:e}'.format(hlm_fluid[i_core].coeffs[0, 4, 0])) print('Moments of hydrostatic core') II, AA, BB, CC, mass, RR, vec = InertiaTensor_from_shape(hlm_fluid, rho, i_core, quiet=False) print('I = ', II) print('A, B, C = ', AA, BB, CC) print('A, B, C / (mass_mars r0^2) = ', (AA, BB, CC) / mass_mars / r_mars**2) print('mass of core (kg) = ', mass) print('R core (m) = ', RR) print('Moments of hydrostatic planet') II, AA, BB, CC, mass, RR, vec = InertiaTensor_from_shape(hlm_fluid, rho, n, quiet=False) print('I = ', II) print('A, B, C = ', AA, BB, CC) print('A, B, C / (mass_mars r0^2) = ', (AA, BB, CC) / mass_mars / r_mars**2) print('mass of planet (kg) = ', mass) print('R surface (m) = ', RR) # --- Compute relief along hydrostatic interfaces with a lithosphere --- print('\n=== Planet with a lithosphere ===') r_sigma = topo.r0 - d_sigma hlm, clm_hydro, mass_model = \ HydrostaticShapeLith(radius, rho, i_lith, potential, topo, rho_crust, r_sigma, omega, lmax_hydro) print('--- Core shape, with lithosphere ---') for l in range(0, 5): for m in range(0, l + 1): print( l, m, hlm[i_core].coeffs[0, l, m], hlm[i_core].coeffs[1, l, m], ) print('Max and min of degree-1 core shape =', hlm[i_core].expand(lmax=1).max(), hlm[i_core].expand(lmax=1).min()) II, AA, BB, CC, mass, RR, vec = InertiaTensor_from_shape(hlm, rho, i_core, quiet=False) print('I = ', II) print('A, B, C = ', AA, BB, CC) print('A, B, C / (mass_mars r0^2) = ', (AA, BB, CC) / mass_mars / r_mars**2) print('mass of core (kg) = ', mass) print('R core (m) = ', RR) # --- Calculate relief, with respect to hydrostatic solution --- # --- at i_lith and i_core print('\n=== Difference between fluid planet and planet with a ' 'lithosphere ===') diff_ilith = hlm[i_lith] - hlm_fluid[i_lith].pad(lmax=lmax_hydro) grid_ilith = diff_ilith.expand() print('Maximum and minimum difference at i_lith (km) =- ', grid_ilith.max() / 1.e3, grid_ilith.min() / 1.e3) diff_icore = hlm[i_core] - hlm_fluid[i_core].pad(lmax=lmax_hydro) grid_icore = diff_icore.expand() print('Maximum and minimum difference at i_core (km) =- ', grid_icore.max() / 1.e3, grid_icore.min() / 1.e3) # ---- Write data to files --- print('\n=== Output gridded data for use with GMT ===') print('Output grid sizes = ', geoid.nlat, geoid.nlon) (geoid / 1000).to_file('figs/Mars_geoid.dat') diff = (geoid - hlm_fluid[n].pad(lmax=lmax).expand(grid='DH2') + radius[n]) (diff / 1000).to_file('figs/Mars_geoid_diff.dat') diff = hlm[i_lith].pad(lmax=lmax).expand(grid='DH2') - radius[i_lith] (diff / 1000).to_file('figs/hydro_ilith.dat') diff = hlm[i_core].pad(lmax=lmax).expand(grid='DH2') - radius[i_core] (diff / 1000).to_file('figs/hydro_icore.dat') diff = hlm[i_lith] - hlm_fluid[i_lith].pad(lmax=lmax_hydro) (diff.expand(grid='DH2', lmax=lmax) / 1000).to_file('figs/hydro_ilith_diff.dat') diff = hlm[i_core] - hlm_fluid[i_core].pad(lmax=lmax_hydro) (diff.expand(grid='DH2', lmax=lmax) / 1000).to_file('figs/hydro_icore_diff.dat') # Sensitivity tests print('\n=== Sensitivity tests ===') r_sigma = topo.r0 hlm2, clm_hydro2, mass_model2 = \ HydrostaticShapeLith(radius, rho, i_lith, potential, topo, rho_crust, r_sigma, omega, lmax_hydro) print('d_sigma = 0') print('Minimum and maximum differences at i_lith (m) = ', (hlm2[i_lith] - hlm[i_lith]).expand().min(), (hlm2[i_lith] - hlm[i_lith]).expand().max()) print('Minimum and maximum differences at i_core (m) = ', (hlm2[i_core] - hlm[i_core]).expand().min(), (hlm2[i_core] - hlm[i_core]).expand().max()) r_sigma = topo.r0 - 100.e3 hlm2, clm_hydro2, mass_model2 = \ HydrostaticShapeLith(radius, rho, i_lith, potential, topo, rho_crust, r_sigma, omega, lmax_hydro) print('d_sigma = 100 km') print('Minimum and maximum differences at i_lith (m) = ', (hlm2[i_lith] - hlm[i_lith]).expand().min(), (hlm2[i_lith] - hlm[i_lith]).expand().max()) print('Minimum and maximum differences at i_core (m) = ', (hlm2[i_core] - hlm[i_core]).expand().min(), (hlm2[i_core] - hlm[i_core]).expand().max()) r_sigma = topo.r0 - d_sigma hlm2, clm_hydro2, mass_model2 = \ HydrostaticShapeLith(radius, rho, i_lith, potential, topo, 2500., r_sigma, omega, lmax_hydro) print('rho = 2500 kg / m3') print('Minimum and maximum differences at i_lith (m) = ', (hlm2[i_lith] - hlm[i_lith]).expand().min(), (hlm2[i_lith] - hlm[i_lith]).expand().max()) print('Minimum and maximum differences at i_core (m) = ', (hlm2[i_core] - hlm[i_core]).expand().min(), (hlm2[i_core] - hlm[i_core]).expand().max()) r_sigma = topo.r0 - d_sigma hlm2, clm_hydro2, mass_model2 = \ HydrostaticShapeLith(radius, rho, i_lith, potential, topo, 3300., r_sigma, omega, lmax_hydro) print('rho = 3300 kg / m3') print('Minimum and maximum differences at i_lith (m) = ', (hlm2[i_lith] - hlm[i_lith]).expand().min(), (hlm2[i_lith] - hlm[i_lith]).expand().max()) print('Minimum and maximum differences at i_core (m) = ', (hlm2[i_core] - hlm[i_core]).expand().min(), (hlm2[i_core] - hlm[i_core]).expand().max())
def main(): gravfile = 'Data/gmm3_120_sha.tab' topofile = 'Data/MarsTopo719.shape' densityfile = 'Data/dichotomy_359.sh' model_name = ['DWThot', 'DWThotCrust1', 'DWThotCrust1r', 'EH45Tcold', 'EH45TcoldCrust1', 'EH45TcoldCrust1r', 'EH45ThotCrust2', 'EH45ThotCrust2r', 'LFAK', 'SANAK', 'TAYAK', 'DWAK', 'ZG_DW'] spec = 'Data/Mars-reference-interior-models/Smrekar/' interior_file = [spec + name + '.deck' for name in model_name] lmax_calc = 90 lmax = lmax_calc * 4 potential = pyshtools.SHGravCoeffs.from_file(gravfile, header_units='km') print('Gravity file = {:s}'.format(gravfile)) print('Lmax of potential coefficients = {:d}'.format(potential.lmax)) print('Reference radius (km) = {:f}'.format(potential.r0 / 1.e3)) print('GM = {:e}\n'.format(potential.gm)) topo = pyshtools.SHCoeffs.from_file(topofile, lmax=lmax) topo.r0 = topo.coeffs[0, 0, 0] print('Topography file = {:s}'.format(topofile)) print('Lmax of topography coefficients = {:d}'.format(topo.lmax)) print('Reference radius (km) = {:f}\n'.format(topo.r0 / 1.e3)) density = pyshtools.SHCoeffs.from_file(densityfile, lmax=lmax) print('Lmax of density coefficients = {:d}\n'.format(density.lmax)) lat_insight = 4.502384 lon_insight = 135.623447 filter = 1 half = 50 nmax = 7 lmax_hydro = 15 t0_sigma = 5. # maximum difference between minimum crustal thickness omega = pyshtools.constant.omega_mars.value d_lith = 150.e3 d_sigma = 45.e3 t0 = 1.e3 # minimum crustal thickness model = 10 # identifier for the interior reference model # --- read 1D reference interior model --- with open(interior_file[model], 'r') as f: lines = f.readlines() print(lines[0].strip()) data = lines[1].split() if float(data[2]) != 1: raise RuntimeError('Program not capable of reading polynomial ' + 'files') num_file = int(lines[2].split()[0]) crust_index_file = int(lines[2].split()[3]) core_index_file = int(lines[2].split()[2]) i_crust_file = crust_index_file - 1 i_core_file = core_index_file - 1 radius = np.zeros(num_file) rho = np.zeros(num_file) num = 0 for i in range(0, num_file-1): data = lines[i+3].split() rb = float(data[0]) rhob = float(data[1]) data = lines[i+4].split() rt = float(data[0]) rhot = float(data[1]) if rb == rt: if i == i_core_file: i_core = num if i == i_crust_file: i_crust = num else: radius[num] = rb rho[num] = (rhot + rhob) / 2. num += 1 radius[num] = rt rho[num] = 0. # the density above the surface is zero num += 1 n = num - 1 radius = radius[:n+1] rho = rho[:n+1] r0_model = radius[n] print('Surface radius of model (km) = {:f}'.format(r0_model / 1.e3)) for i in range(0, n+1): if radius[i] <= (r0_model - d_lith) and \ radius[i+1] > (r0_model - d_lith): if radius[i] == (r0_model - d_lith): i_lith = i elif (r0_model - d_lith) - radius[i] <= radius[i+1] -\ (r0_model - d_lith): i_lith = i else: i_lith = i + 1 break rho_mantle = rho[i_crust-1] rho_core = rho[i_core-1] print('Mantle density (kg/m3) = {:f}'.format(rho_mantle)) print('Mantle radius (km) = {:f}'.format(radius[i_crust]/1.e3)) print('Core density (kg/m3) = {:f}'.format(rho_core)) print('Core radius (km) = {:f}'.format(radius[i_core]/1.e3)) print('Assumed depth of lithosphere (km) = {:f}'.format(d_lith / 1.e3)) print('Actual depth of lithosphere in discretized model (km) = {:f}' .format((r0_model - radius[i_lith]) / 1.e3)) # --- Compute gravity contribution from hydrostatic density interfaces --- thickave = 44.e3 # initial guess of average crustal thickness r_sigma = topo.r0 - thickave rho_c = 2900. if True: # compute values for a planet that is completely fluid hlm_fluid, clm_fluid, mass_model = \ HydrostaticShape(radius, rho, omega, potential.gm, potential.r0) print('--- Hydrostatic potential coefficients for a fluid planet ---') print('c20 = {:e}\nc40 = {:e}'.format(clm_fluid.coeffs[0, 2, 0], clm_fluid.coeffs[0, 4, 0])) print('--- Hydrostatic relief of surface for a fluid planet ---') print('h20 = {:e}\nh40 = {:e}'.format(hlm_fluid[n].coeffs[0, 2, 0], hlm_fluid[n].coeffs[0, 4, 0])) hlm, clm_hydro, mass_model = \ HydrostaticShapeLith(radius, rho, i_lith, potential, topo, rho_c, r_sigma, omega, lmax_hydro) print('Total mass of model (kg) = {:e}'.format(mass_model)) print('% of J2 arising from beneath lithosphere = {:f}' .format(clm_hydro.coeffs[0, 2, 0]/potential.coeffs[0, 2, 0] * 100.)) potential.coeffs[:, :lmax_hydro+1, :lmax_hydro+1] -= \ clm_hydro.coeffs[:, :lmax_hydro+1, :lmax_hydro+1] # --- Constant density model --- rho_c = 2900. print('-- Constant density model --\nrho_c = {:f}'.format(rho_c)) tmin = 1.e9 thickave = 44.e3 # initial guess of average crustal thickness while abs(tmin - t0) > t0_sigma: # iterate to fit assumed minimum crustal thickness moho = pyMoho.pyMoho(potential, topo, lmax, rho_c, rho_mantle, thickave, filter_type=filter, half=half, lmax_calc=lmax_calc, nmax=nmax, quiet=True) thick_grid = (topo.pad(lmax) - moho.pad(lmax)).expand(grid='DH2') print('Average crustal thickness (km) = {:f}'.format(thickave / 1.e3)) print('Crustal thickness at InSight landing sites (km) = {:f}' .format((topo.pad(lmax) - moho.pad(lmax)) .expand(lat=lat_insight, lon=lon_insight) / 1.e3)) tmin = thick_grid.min() tmax = thick_grid.max() print('Minimum thickness (km) = {:e}'.format(tmin / 1.e3)) print('Maximum thickness (km) = {:e}'.format(tmax / 1.e3)) thickave += t0 - tmin thick_grid.plot(show=False, fname='Thick-Mars-1.png') moho.plot_spectrum(show=False, fname='Moho-spectrum-Mars-1.png') # --- Model with variable density --- rho_south = 2900. rho_north = 2900. porosity = 0.0 print('-- Variable density model ---\n' + 'rho_south = {:f}\n'.format(rho_south) + 'rho_north = {:f}'.format(rho_north)) density = density * (rho_north - rho_south) density.coeffs[0, 0, 0] += rho_south tmin = 1.e9 thickave = 44.e3 # initial guess of average crustal thickness while abs(tmin - t0) > t0_sigma: # iterate to fit assumed minimum crustal thickness moho = pyMoho.pyMohoRho(potential, topo, density, porosity, lmax, rho_mantle, thickave, filter_type=filter, half=half, lmax_calc=lmax_calc, quiet=True, nmax=nmax) thick_grid = (topo.pad(lmax) - moho.pad(lmax)).expand(grid='DH2') print('Average crustal thickness (km) = {:e}'.format(thickave / 1.e3)) print('Crustal thickness at InSight landing sites (km) = {:e}' .format((topo.pad(lmax) - moho.pad(lmax)) .expand(lat=lat_insight, lon=lon_insight) / 1.e3)) tmin = thick_grid.data.min() tmax = thick_grid.data.max() print('Minimum thickness (km) = {:e}'.format(tmin / 1.e3)) print('Maximum thickness (km) = {:e}'.format(tmax / 1.e3)) thickave += t0 - tmin thick_grid.plot(show=False, fname='Thick-Mars-2.png') moho.plot_spectrum(show=False, fname='Moho-spectrum-Mars-2.png')
def calc_crust(mantlefile, # filename for mantle profile input fnam_out_model, # Output file name for thickness map gravfile='Data/gmm3_120_sha.tab', topofile='Data/MarsTopo719.shape', densityfile='Data/dichotomy_359.sh', fnam_out_plot=None, # Output file name for plot of map t0=1.e3, # minimum crustal thickness d_lith=300.e3 # Lithosphere thickness ): lmax_calc = 90 lmax = lmax_calc * 4 potcoefs, lmaxp, header = pyshtools.shio.shread(gravfile, header=True, lmax=lmax) potential = pyshtools.SHCoeffs.from_array(potcoefs) potential.r_ref = float(header[0]) * 1.e3 potential.gm = float(header[1]) * 1.e9 potential.mass = potential.gm / float(pyshtools.constant.grav_constant) print('Gravity file = {:s}'.format(gravfile)) print('Lmax of potential coefficients = {:d}'.format(lmaxp)) print('Reference radius (km) = {:f}'.format(potential.r_ref / 1.e3)) print('GM = {:e}\n'.format(potential.gm)) topo = pyshtools.SHCoeffs.from_file(topofile, lmax=lmax) topo.r0 = topo.coeffs[0, 0, 0] print('Topography file = {:s}'.format(topofile)) print('Lmax of topography coefficients = {:d}'.format(topo.lmax)) print('Reference radius (km) = {:f}\n'.format(topo.r0 / 1.e3)) density = pyshtools.SHCoeffs.from_file(densityfile, lmax=lmax) print('Lmax of density coefficients = {:d}\n'.format(density.lmax)) lat_insight = 4.43 lon_insight = 135.84 filter = 1 half = 50 nmax = 7 lmax_hydro = 15 t0_sigma = 5. # maximum difference between minimum crustal thickness omega = float(pyshtools.constant.omega_mars) # --- read 1D reference interior model --- print('=== Reading model {:s} ==='.format(mantlefile)) with open(mantlefile, 'r') as f: lines = f.readlines() ncomments = 4 # Remove initial four lines in AxiSEM files nlines = len(lines) nlayer = nlines - ncomments radius = np.zeros(nlayer) rho = np.zeros(nlayer) vp = np.zeros(nlayer) vs = np.zeros(nlayer) lines = lines[::-1] crust_index = nlayer - 6 for i in range(0, nlayer): data = lines[i].split() radius[i] = float(data[0]) rho[i] = float(data[1]) vp[i] = float(data[2]) vs[i] = float(data[3]) # Q = float(data[4]) # if (Q in (500, 600)) and Q_last not in (500, 600): # crust_index = i # Q_last = Q # Correct the sub-Moho parameters radius[-8] = radius[-7] # Calculate crustal density mass_crust = 0 for i in range(crust_index, nlayer-1): vol_layer = (radius[i+1] - radius[i]) * 1e3 * 4 * np.pi mass_crust += rho[i] * vol_layer vol_crust = (radius[-1] - radius[crust_index]) * 1e3 * 4 * np.pi rho_c = mass_crust / vol_crust print('Crustal density: = {:8.1f}'.format(rho_c)) r0_model = radius[nlayer-1] print('Surface radius of model (km) = {:8.1f}'.format(r0_model / 1.e3)) # Find layer at bottom of lithosphere for i in range(0, nlayer): if radius[i] <= (r0_model - d_lith) and \ radius[i+1] > (r0_model - d_lith): if radius[i] == (r0_model - d_lith): i_lith = i elif (r0_model - d_lith) - radius[i] <= \ radius[i+1] - (r0_model - d_lith): i_lith = i else: i_lith = i + 1 break n = nlayer - 1 rho[n] = 0. # the density above the surface is zero rho_mantle = rho[crust_index-1] print('Mantle density (kg/m3) = {:8.1f}'.format(rho_mantle)) print('Assumed depth of lithosphere (km) = {:6.1f}'.format(d_lith / 1.e3)) print('Actual depth of lithosphere in discretized model (km) = {:6.1f}' .format((r0_model - radius[i_lith]) / 1.e3)) # initial guess of average crustal thickness thickave = r0_model - radius[crust_index] print('Crustal thickness (km) = {:5.1f}'.format(thickave / 1e3)) print('Moho layer: {:d}'.format(crust_index)) # --- Compute gravity contribution from hydrostatic density interfaces --- hlm, clm_hydro, mass_model = HydrostaticShapeLith(radius, rho, i_lith, potential, omega, lmax_hydro, finiteamplitude=False) print('Total mass of model (kg) = {:e}'.format(mass_model)) print('% of J2 arising from beneath lithosphere = {:f}' .format(clm_hydro.coeffs[0, 2, 0]/potential.coeffs[0, 2, 0] * 100.)) potential.coeffs[:, :lmax_hydro+1, :lmax_hydro+1] -= \ clm_hydro.coeffs[:, :lmax_hydro+1, :lmax_hydro+1] # --- Constant density model --- print('-- Constant density model --\nrho_c = {:f}'.format(rho_c)) tmin = 1.e9 converged = False while not converged: # iterate to fit assumed minimum crustal thickness moho = pyMoho.pyMoho(potential, topo, lmax, rho_c, rho_mantle, thickave, filter_type=filter, half=half, lmax_calc=lmax_calc, nmax=nmax, quiet=True) thick = topo.pad(lmax) - moho.pad(lmax) print('Average crustal thickness (km) = {:6.2f}'.format(thickave / 1.e3)) thick_insight = thick.expand(lat=lat_insight, lon=lon_insight) print('Crustal thickness at InSight landing sites (km) = {:6.2f}' .format(thick_insight / 1.e3)) thick_grid = thick.expand(grid='DH2') tmin = thick_grid.data.min() tmax = thick_grid.data.max() print('Minimum thickness (km) = {:6.2f}'.format(tmin / 1.e3)) print('Maximum thickness (km) = {:6.2f}'.format(tmax / 1.e3)) if tmin - t0 < - t0_sigma: thickave += t0 - tmin else: converged = True if fnam_out_plot: thick_grid.plot(show=False, fname=fnam_out_plot, vmin=0.0, vmax=120.e3) # Write Model to disk # lmax_out = 17 # 89 # topo_grid = (topo.pad(lmax)).expand(grid='DH2', lmax=lmax_out) # moho_grid = (moho.pad(lmax)).expand(grid='DH2', lmax=lmax_out) # lats = topo_grid._lats() # lons = topo_grid._lons() lats = np.arange(-87.5, 90., 5.) lons = np.arange(0, 360, 5) # Apply tapered anti-aliasing filter to SH before transformation lmax_filter = 36 # 17 order = 2 lvals = np.zeros_like(topo.coeffs) for i in range(0, lvals.shape[1]): for j in range(0, lvals.shape[2]): l = np.max([i, j]) lvals[:, i, j] = np.exp(-2. * np.pi * l ** order / (2. * lmax_filter) ** order) topo.coeffs *= lvals lvals = np.zeros_like(moho.coeffs) for i in range(0, lvals.shape[1]): for j in range(0, lvals.shape[2]): l = np.max([i, j]) lvals[:, i, j] = np.exp(-2. * np.pi * l ** order / (2. * lmax_filter) ** order) moho.coeffs *= lvals #moho.plot_spectrum(show=False, fname='%s.png' % fnam_out_model) lats_grid, lons_grid = np.meshgrid(lats, lons) topo_grid = (topo).expand(lat=lats_grid, lon=lons_grid) moho_grid = (moho).expand(lat=lats_grid, lon=lons_grid) moho.expand(grid='DH2').plot(show=False, fname='%s_moho.png' % fnam_out_model) topo.expand(grid='DH2').plot(show=False, fname='%s_topo.png' % fnam_out_model) (topo.pad(lmax) - moho.pad(lmax)).expand(grid='DH2').plot(show=False, fname='%s_thick.png' % fnam_out_model) with h5py.File(fnam_out_model, 'w') as f: print('Writing to %s' % fnam_out_model) grp_crust = f.create_group('crust') grp_crust.create_dataset('moho', data=moho_grid.data) grp_crust.create_dataset('topo', data=topo_grid.data) grp_crust.create_dataset('latitudes', data=lats) grp_crust.create_dataset('longitudes', data=lons) grp_mantle = f.create_group('mantle') grp_mantle.create_dataset('radius', data=radius) grp_mantle.create_dataset('rho', data=rho) grp_mantle.create_dataset('vp', data=vp) grp_mantle.create_dataset('vs', data=vs) grp_status = f.create_group('status') grp_status.create_dataset('thickness_insight', data=thick_insight) grp_status.create_dataset('thickness_average_pycrust', data=thickave) grp_status.create_dataset('thickness_average_input', data=r0_model - radius[crust_index]) grp_status.create_dataset('thickness_lithosphere', data=d_lith) grp_status.create_dataset('thickness_minimum', data=tmin) grp_status.create_dataset('thickness_maximum', data=tmax) grp_status.create_dataset('rho_crust', data=rho_c) grp_status.create_dataset('rho_mantle', data=rho_mantle)
def main(): lmax = 20 lmax_grid = 719 omega = pyshtools.constant.omega_moon.value rem = pyshtools.constant.a_orbit_moon.value mass_earth = pyshtools.constant.mass_egm2008.value cthick = 34.e3 # 43.e3 or 34.0e3 rho_crust = 2550. out_rc_fc = "figs/rc_fc_34_2550.dat" out_rc_rhoc = "figs/rc_rhoc_34_2550.dat" out_rc_beta = "figs/rc_beta_34_2550.dat" sh_core = "figs/core_34.sh" core_shape_wo_d1 = "figs/core_shape_wo_d1_330_34.dat" core_shape = "figs/core_shape_330_34.dat" rcore_int = 1.e3 rcore_start = 250.e3 rcore_end = 450.e3 rhocore_start = 5000. rhocore_end = 8000. rhocore_int = 1. pot_file = 'Data/JGGRAIL_900C11A_SHA.TAB' topo_file = 'Data/LOLA1500p.sh' potential = pyshtools.SHGravCoeffs.from_file(pot_file, header_units='km') topo = pyshtools.SHCoeffs.from_file(topo_file, lmax=900) r0 = topo.coeffs[0, 0, 0] r_sigma = r0 - cthick ismr2 = 0.3927280 # Williams et al. (2014) ismr2 = ismr2 * (1738.e3 / r0)**2 print("Mean planetary radius (km) = {:e}".format(r0 / 1.e3)) print("Is/MR2 (solid Moon using mean radius) = {:e}".format(ismr2)) print("Lmax of Gravitational potential = {:d}".format(potential.lmax)) print("Reference radius of potential model (km) = {:e}".format( potential.r0 / 1.e3)) print("GM = {:e}".format(potential.gm)) mass = potential.gm / pyshtools.constant.G.value print("Mass (kg) = {:e}".format(mass)) print("Omega = {:e}".format(omega)) print("Period (days) = {:e}".format(2. * np.pi / omega / 60. / 60. / 24.)) print("Average crustal thickness (km) = {:e}".format(cthick / 1.e3)) print("Crustal density (kg/m3) = {:e}".format(rho_crust)) radius = np.zeros(4) radius[0] = 0. radius[2] = r0 - cthick radius[3] = r0 rho = np.zeros(4) rho[2] = rho_crust mass_crust = 4. * np.pi / 3. * rho_crust * (radius[3]**3 - radius[2]**3) n = 3 i_lith = 2 i_core = 1 # For each core radius, find rho_mantle and rho_core that fit total mass # and moment of inertia f_rc_fc = open(out_rc_fc, 'w') f_rc_rhoc = open(out_rc_rhoc, 'w') f_rc_beta = open(out_rc_beta, 'w') for r_core in np.arange(rcore_start, rcore_end + rcore_int, rcore_int, dtype=float): radius[1] = r_core first = True for rho_core in np.arange(rhocore_start, rhocore_end + rhocore_int, rhocore_int, dtype=float): mass_core = 4. * np.pi / 3. * rho_core * r_core**3 mass_mantle = mass - mass_crust - mass_core rho_mantle = mass_mantle * 3. / np.pi / 4. / (radius[2]**3 - r_core**3) rho[0] = rho_core rho[1] = rho_mantle if rho_mantle >= rho_core: continue ismr2_model = moi_solid(radius, rho, n) if first is True: diff_old = ismr2 - ismr2_model first = False else: diff_new = ismr2 - ismr2_model if diff_new * diff_old <= 0.: # interpolate to get the best fitting core density rho_core_final = (rho_core - rhocore_int) - diff_old * \ (rhocore_int) / (diff_new - diff_old) rho[0] = rho_core_final mass_core = 4. * np.pi / 3. * rho[0] * r_core**3 mass_mantle = mass - mass_crust - mass_core rho_mantle = mass_mantle * 3. / np.pi / 4. / \ (radius[2]**3 - r_core**3) rho[1] = rho_mantle hlm, clm_hydro, mass_model = \ HydrostaticShapeLith(radius, rho, i_lith, potential, topo, rho_crust, r_sigma, omega, lmax, rp=rem, mp=mass_earth) # set degree-1 terms to zero hlm[1].coeffs[:, 1, :] = 0. a = hlm[1].expand(lat=0., lon=0., lmax_calc=lmax) b = hlm[1].expand(lat=0., lon=90., lmax_calc=lmax) c = hlm[1].expand(lat=90., lon=0., lmax_calc=lmax) f_core = ((a + b) / 2. - c) / ((a + b) / 2.) beta_core = (a**2 - b**2) / (a**2 + b**2) print(r_core / 1.e3, rho[0], rho[1], f_core, beta_core) f_rc_fc.write('{:e}, {:e}\n'.format(r_core / 1.e3, f_core)) f_rc_rhoc.write('{:e}, {:e}\n'.format( r_core / 1.e3, rho[0])) f_rc_beta.write('{:e}, {:e}\n'.format( r_core / 1.e3, beta_core)) if r_core == 330.e3: print("Rcore (km) = {:e}".format(r_core / 1.e3)) print("A (km) = {:e}".format(a / 1.e3)) print("B (km) = {:e}".format(b / 1.e3)) print("C (km) = {:e}".format(c / 1.e3)) print("rho_core (kg/m3) = {:e}".format(rho[0])) II, AA, BB, CC, mass_model, RR, vec = \ InertiaTensor_from_shape(hlm, rho, 1, quiet=False) grid = hlm[i_core].expand(lmax=lmax_grid, grid='DH2') grid.to_file(core_shape_wo_d1) print("Size of output grid = {:d}, {:d}".format( grid.nlat, grid.nlon)) print("Maximum = {:e}\nMinimum = {:e}".format( grid.max(), grid.min())) hlm, clm_hydro, mass_model = \ HydrostaticShapeLith(radius, rho, i_lith, potential, topo, rho_crust, r_sigma, omega, lmax, rp=rem, mp=mass_earth) hlm_fluid, clm_fluid, mass_model = \ HydrostaticShape(radius, rho, omega, potential.gm, potential.r0, rp=rem, mp=mass_earth) grid = hlm[i_core].expand(lmax=lmax_grid, grid='DH2') grid_fluid = hlm_fluid[i_core].expand(lmax=lmax_grid, grid='DH2') a_fluid = hlm_fluid[1].expand(lat=0., lon=0.) b_fluid = hlm_fluid[1].expand(lat=0., lon=90.) c_fluid = hlm_fluid[1].expand(lat=90., lon=0.) f_core_fluid = (((a_fluid + b_fluid) / 2. - c_fluid) / ((a_fluid + b_fluid) / 2.)) beta_core_fluid = ((a_fluid**2 - b_fluid**2) / (a_fluid**2 + b_fluid**2)) print('f_core for a fluid planet = ', f_core_fluid) print('beta_core for a fluid planet = ', beta_core_fluid) diff = grid - grid_fluid print( 'Maximuim and miniumum core relief for ' 'a fluid planet (m) = ', grid_fluid.max(), grid_fluid.min()) print( 'Maximuim and miniumum difference with respect ' 'to a fluid planet (m) = ', diff.max(), diff.min()) hlm[i_core].to_file(sh_core) grid.to_file(core_shape) print("Maximum = {:e}\nMinimum = {:e}".format( grid.max(), grid.min())) for l in range(0, 4): for m in range(0, l + 1): print(l, m, hlm[i_core].coeffs[0, l, m], hlm[i_core].coeffs[1, l, m]) diff_old = diff_new
def main(): gravfile = 'Data/gmm3_120_sha.tab' topofile = 'Data/MarsTopo719.shape' densityfile = 'Data/dichotomy_359.sh' model_name = [ 'DWThot', 'DWThotCrust1', 'DWThotCrust1r', 'EH45Tcold', 'EH45TcoldCrust1', 'EH45TcoldCrust1r', 'EH45ThotCrust2', 'EH45ThotCrust2r', 'LFAK', 'SANAK', 'TAYAK', 'DWAK', 'ZG_DW' ] spec = 'Data/Mars-reference-interior-models/Smrekar/' interior_file = [spec + name + '.deck' for name in model_name] lmax_calc = 90 lmax = lmax_calc * 4 potential = pyshtools.SHGravCoeffs.from_file(gravfile, header_units='km') print('Gravity file = {:s}'.format(gravfile)) print('Lmax of potential coefficients = {:d}'.format(potential.lmax)) print('Reference radius (km) = {:f}'.format(potential.r0 / 1.e3)) print('GM = {:e}\n'.format(potential.gm)) topo = pyshtools.SHCoeffs.from_file(topofile, lmax=lmax) topo.r0 = topo.coeffs[0, 0, 0] print('Topography file = {:s}'.format(topofile)) print('Lmax of topography coefficients = {:d}'.format(topo.lmax)) print('Reference radius (km) = {:f}\n'.format(topo.r0 / 1.e3)) density = pyshtools.SHCoeffs.from_file(densityfile, lmax=lmax) print('Lmax of density coefficients = {:d}\n'.format(density.lmax)) lat_insight = 4.502384 lon_insight = 135.623447 filter = 1 half = 50 nmax = 7 lmax_hydro = 15 t0_sigma = 5. # maximum difference between minimum crustal thickness omega = pyshtools.constant.omega_mars.value d_lith = 150.e3 d_sigma = 45.e3 t0 = 1.e3 # minimum crustal thickness model = 10 # identifier for the interior reference model # --- read 1D reference interior model --- radius, rho, i_crust, i_core, i_lith = ReadRefModel(interior_file[model], depth=d_lith, quiet=False) rho_mantle = rho[i_crust - 1] rho_core = rho[i_core - 1] n = len(radius) - 1 r0_model = radius[n] # --- Compute gravity contribution from hydrostatic density interfaces --- thickave = 44.e3 # initial guess of average crustal thickness r_sigma = topo.r0 - thickave rho_c = 2900. if True: # compute values for a planet that is completely fluid hlm_fluid, clm_fluid, mass_model = \ HydrostaticShape(radius, rho, omega, potential.gm, potential.r0) print('--- Hydrostatic potential coefficients for a fluid planet ---') print('c20 = {:e}\nc40 = {:e}'.format(clm_fluid.coeffs[0, 2, 0], clm_fluid.coeffs[0, 4, 0])) print('--- Hydrostatic relief of surface for a fluid planet ---') print('h20 = {:e}\nh40 = {:e}'.format(hlm_fluid[n].coeffs[0, 2, 0], hlm_fluid[n].coeffs[0, 4, 0])) hlm, clm_hydro, mass_model = \ HydrostaticShapeLith(radius, rho, i_lith, potential, topo, rho_c, r_sigma, omega, lmax_hydro) print('Total mass of model (kg) = {:e}'.format(mass_model)) print('% of J2 arising from beneath lithosphere = {:f}'.format( clm_hydro.coeffs[0, 2, 0] / potential.coeffs[0, 2, 0] * 100.)) potential.coeffs[:, :lmax_hydro+1, :lmax_hydro+1] -= \ clm_hydro.coeffs[:, :lmax_hydro+1, :lmax_hydro+1] # --- Constant density model --- rho_c = 2900. print('-- Constant density model --\nrho_c = {:f}'.format(rho_c)) tmin = 1.e9 thickave = 44.e3 # initial guess of average crustal thickness while abs(tmin - t0) > t0_sigma: # iterate to fit assumed minimum crustal thickness moho = pyMoho.pyMoho(potential, topo, lmax, rho_c, rho_mantle, thickave, filter_type=filter, half=half, lmax_calc=lmax_calc, nmax=nmax, quiet=True) thick_grid = (topo.pad(lmax) - moho.pad(lmax)).expand(grid='DH2') print('Average crustal thickness (km) = {:f}'.format(thickave / 1.e3)) print('Crustal thickness at InSight landing sites (km) = {:f}'.format( (topo.pad(lmax) - moho.pad(lmax)).expand(lat=lat_insight, lon=lon_insight) / 1.e3)) tmin = thick_grid.min() tmax = thick_grid.max() print('Minimum thickness (km) = {:e}'.format(tmin / 1.e3)) print('Maximum thickness (km) = {:e}'.format(tmax / 1.e3)) thickave += t0 - tmin thick_grid.plot(show=False, fname='Thick-Mars-1.png') moho.plot_spectrum(show=False, fname='Moho-spectrum-Mars-1.png') # --- Model with variable density --- rho_south = 2900. rho_north = 2900. porosity = 0.0 print('-- Variable density model ---\n' + 'rho_south = {:f}\n'.format(rho_south) + 'rho_north = {:f}'.format(rho_north)) density = density * (rho_north - rho_south) density.coeffs[0, 0, 0] += rho_south tmin = 1.e9 thickave = 44.e3 # initial guess of average crustal thickness while abs(tmin - t0) > t0_sigma: # iterate to fit assumed minimum crustal thickness moho = pyMoho.pyMohoRho(potential, topo, density, porosity, lmax, rho_mantle, thickave, filter_type=filter, half=half, lmax_calc=lmax_calc, quiet=True, nmax=nmax) thick_grid = (topo.pad(lmax) - moho.pad(lmax)).expand(grid='DH2') print('Average crustal thickness (km) = {:e}'.format(thickave / 1.e3)) print('Crustal thickness at InSight landing sites (km) = {:e}'.format( (topo.pad(lmax) - moho.pad(lmax)).expand(lat=lat_insight, lon=lon_insight) / 1.e3)) tmin = thick_grid.data.min() tmax = thick_grid.data.max() print('Minimum thickness (km) = {:e}'.format(tmin / 1.e3)) print('Maximum thickness (km) = {:e}'.format(tmax / 1.e3)) thickave += t0 - tmin thick_grid.plot(show=False, fname='Thick-Mars-2.png') moho.plot_spectrum(show=False, fname='Moho-spectrum-Mars-2.png')