2020-06-15 15:30:56 +00:00
# toy model for use on stream
# Please give me your Twitch prime sub!
# CLimate Analysis using Digital Estimations (CLAuDE)
import numpy as np
import matplotlib . pyplot as plt
2020-06-24 20:08:16 +00:00
import time , sys , pickle
2020-06-15 15:30:56 +00:00
2020-08-19 19:54:05 +00:00
######## CONTROL ########
2020-07-01 20:18:16 +00:00
2020-06-24 20:08:16 +00:00
day = 60 * 60 * 24 # define length of day (used for calculating Coriolis as well) (s)
2020-08-27 08:24:39 +00:00
resolution = 3 # how many degrees between latitude and longitude gridpoints
nlevels = 10 # how many vertical layers in the atmosphere
top = 50E3 # top of atmosphere (m)
2020-06-24 20:08:16 +00:00
planet_radius = 6.4E6 # define the planet's radius (m)
insolation = 1370 # TOA radiation from star (W m^-2)
2020-08-10 12:55:54 +00:00
gravity = 9.81 # define surface gravity for planet (m s^-2)
2020-08-27 08:24:39 +00:00
axial_tilt = - 23.5 # tilt of rotational axis w.r.t. solar plane
year = 365 * day # length of year (s)
2020-06-15 15:30:56 +00:00
2020-08-19 19:54:05 +00:00
###
2020-08-10 12:55:54 +00:00
advection = True # if you want to include advection set this to be True
2020-08-27 08:24:39 +00:00
advection_boundary = 4 # how many gridpoints away from poles to apply advection
2020-06-15 15:30:56 +00:00
2020-08-27 08:24:39 +00:00
save = True
2020-08-19 19:54:05 +00:00
load = False
2020-08-27 08:24:39 +00:00
plot = False
2020-08-19 19:54:05 +00:00
level_plots = False
2020-06-15 15:30:56 +00:00
2020-06-24 20:08:16 +00:00
###########################
2020-06-15 15:30:56 +00:00
# define coordinate arrays
lat = np . arange ( - 90 , 91 , resolution )
lon = np . arange ( 0 , 360 , resolution )
nlat = len ( lat )
nlon = len ( lon )
lon_plot , lat_plot = np . meshgrid ( lon , lat )
2020-08-10 12:55:54 +00:00
heights = np . arange ( 0 , top , top / nlevels )
2020-07-08 19:59:08 +00:00
heights_plot , lat_z_plot = np . meshgrid ( lat , heights )
2020-06-15 15:30:56 +00:00
# initialise arrays for various physical fields
2020-08-27 08:24:39 +00:00
temperature_planet = np . zeros ( ( nlat , nlon ) ) + 290
2020-08-19 19:54:05 +00:00
temperature_atmosp = np . zeros ( ( nlat , nlon , nlevels ) )
2020-07-01 20:18:16 +00:00
air_pressure = np . zeros_like ( temperature_atmosp )
u = np . zeros_like ( temperature_atmosp )
v = np . zeros_like ( temperature_atmosp )
w = np . zeros_like ( temperature_atmosp )
2020-08-10 12:55:54 +00:00
air_density = np . zeros_like ( temperature_atmosp )
2020-08-19 19:54:05 +00:00
# #######################
def profile ( a ) :
return np . mean ( np . mean ( a , axis = 0 ) , axis = 0 )
2020-08-12 19:53:41 +00:00
2020-08-10 12:55:54 +00:00
# read temperature and density in from standard atmosphere
f = open ( " standard_atmosphere.txt " , " r " )
standard_height = [ ]
standard_temp = [ ]
standard_density = [ ]
for x in f :
h , t , r = x . split ( )
standard_height . append ( float ( h ) )
standard_temp . append ( float ( t ) )
standard_density . append ( float ( r ) )
f . close ( )
density_profile = np . interp ( x = heights / 1E3 , xp = standard_height , fp = standard_density )
temp_profile = np . interp ( x = heights / 1E3 , xp = standard_height , fp = standard_temp )
for k in range ( nlevels ) :
air_density [ : , : , k ] = density_profile [ k ]
temperature_atmosp [ : , : , k ] = temp_profile [ k ]
2020-06-24 20:08:16 +00:00
2020-08-19 19:54:05 +00:00
###########################
2020-08-27 08:24:39 +00:00
# weight_above = np.interp(x=heights/1E3,xp=standard_height,fp=standard_density)
# top_index = np.argmax(np.array(standard_height) >= top/1E3)
# if standard_height[top_index] == top/1E3:
# weight_above = np.trapz(np.interp(x=standard_height[top_index:],xp=standard_height,fp=standard_density),standard_height[top_index:])*gravity*1E3
# else:
# weight_above = np.trapz(np.interp(x=np.insert(standard_height[top_index:], 0, top/1E3),xp=standard_height,fp=standard_density),np.insert(standard_height[top_index:], 0, top/1E3))*gravity*1E3
2020-08-19 19:54:05 +00:00
###########################
2020-08-27 08:24:39 +00:00
albedo = np . zeros_like ( temperature_planet ) + 0.2
heat_capacity_earth = np . zeros_like ( temperature_planet ) + 1E6
2020-06-24 20:08:16 +00:00
albedo_variance = 0.001
for i in range ( nlat ) :
for j in range ( nlon ) :
albedo [ i , j ] + = np . random . uniform ( - albedo_variance , albedo_variance )
2020-06-15 15:30:56 +00:00
specific_gas = 287
thermal_diffusivity_roc = 1.5E-6
sigma = 5.67E-8
2020-08-12 19:53:41 +00:00
air_pressure = air_density * specific_gas * temperature_atmosp
2020-06-15 15:30:56 +00:00
# define planet size and various geometric constants
circumference = 2 * np . pi * planet_radius
circle = np . pi * planet_radius * * 2
sphere = 4 * np . pi * planet_radius * * 2
# define how far apart the gridpoints are: note that we use central difference derivatives, and so these distances are actually twice the distance between gridboxes
dy = circumference / nlat
dx = np . zeros ( nlat )
coriolis = np . zeros ( nlat ) # also define the coriolis parameter here
angular_speed = 2 * np . pi / day
for i in range ( nlat ) :
dx [ i ] = dy * np . cos ( lat [ i ] * np . pi / 180 )
2020-06-15 21:10:59 +00:00
coriolis [ i ] = angular_speed * np . sin ( lat [ i ] * np . pi / 180 )
2020-07-01 20:18:16 +00:00
dz = np . zeros ( nlevels )
for k in range ( nlevels - 1 ) : dz [ k ] = heights [ k + 1 ] - heights [ k ]
dz [ - 1 ] = dz [ - 2 ]
2020-06-15 15:30:56 +00:00
2020-06-24 20:08:16 +00:00
###################### FUNCTIONS ######################
2020-06-15 15:30:56 +00:00
# define various useful differential functions:
# gradient of scalar field a in the local x direction at point i,j
2020-07-01 20:18:16 +00:00
def scalar_gradient_x ( a , i , j , k = 999 ) :
if k == 999 :
return ( a [ i , ( j + 1 ) % nlon ] - a [ i , ( j - 1 ) % nlon ] ) / dx [ i ]
else :
return ( a [ i , ( j + 1 ) % nlon , k ] - a [ i , ( j - 1 ) % nlon , k ] ) / dx [ i ]
2020-06-24 20:08:16 +00:00
2020-06-15 15:30:56 +00:00
# gradient of scalar field a in the local y direction at point i,j
2020-07-01 20:18:16 +00:00
def scalar_gradient_y ( a , i , j , k = 999 ) :
if k == 999 :
if i == 0 :
return 2 * ( a [ i + 1 , j ] - a [ i , j ] ) / dy
elif i == nlat - 1 :
return 2 * ( a [ i , j ] - a [ i - 1 , j ] ) / dy
else :
return ( a [ i + 1 , j ] - a [ i - 1 , j ] ) / dy
else :
if i == 0 :
return 2 * ( a [ i + 1 , j , k ] - a [ i , j , k ] ) / dy
elif i == nlat - 1 :
return 2 * ( a [ i , j , k ] - a [ i - 1 , j , k ] ) / dy
else :
return ( a [ i + 1 , j , k ] - a [ i - 1 , j , k ] ) / dy
def scalar_gradient_z ( a , i , j , k ) :
2020-08-12 19:53:41 +00:00
output = np . zeros_like ( a )
if output . ndim == 1 :
if k == 0 :
return ( a [ k + 1 ] - a [ k ] ) / dz [ k ]
elif k == nlevels - 1 :
return ( a [ k ] - a [ k - 1 ] ) / dz [ k ]
else :
return ( a [ k + 1 ] - a [ k - 1 ] ) / ( 2 * dz [ k ] )
2020-06-15 15:30:56 +00:00
else :
2020-08-12 19:53:41 +00:00
if k == 0 :
return ( a [ i , j , k + 1 ] - a [ i , j , k ] ) / dz [ k ]
elif k == nlevels - 1 :
return ( a [ i , j , k ] - a [ i , j , k - 1 ] ) / dz [ k ]
else :
return ( a [ i , j , k + 1 ] - a [ i , j , k - 1 ] ) / ( 2 * dz [ k ] )
2020-06-24 20:08:16 +00:00
2020-07-01 20:18:16 +00:00
# laplacian of scalar field a
2020-06-15 15:30:56 +00:00
def laplacian ( a ) :
output = np . zeros_like ( a )
2020-07-01 20:18:16 +00:00
if output . ndim == 2 :
for i in np . arange ( 1 , nlat - 1 ) :
for j in range ( nlon ) :
2020-08-12 19:53:41 +00:00
output [ i , j ] = ( scalar_gradient_x ( a , i , ( j + 1 ) % nlon ) - scalar_gradient_x ( a , i , ( j - 1 ) % nlon ) ) / dx [ i ] + ( scalar_gradient_y ( a , i + 1 , j ) - scalar_gradient_y ( a , i - 1 , j ) ) / dy
2020-07-01 20:18:16 +00:00
return output
if output . ndim == 3 :
for i in np . arange ( 1 , nlat - 1 ) :
for j in range ( nlon ) :
for k in range ( nlevels - 1 ) :
2020-08-19 19:54:05 +00:00
output [ i , j , k ] = ( scalar_gradient_x ( a , i , ( j + 1 ) % nlon , k ) - scalar_gradient_x ( a , i , ( j - 1 ) % nlon , k ) ) / dx [ i ] + ( scalar_gradient_y ( a , i + 1 , j , k ) - scalar_gradient_y ( a , i - 1 , j , k ) ) / dy + ( scalar_gradient_z ( a , i , j , k + 1 ) - scalar_gradient_z ( a , i , j , k - 1 ) ) / ( 2 * dz [ k ] )
2020-07-01 20:18:16 +00:00
return output
2020-06-24 20:08:16 +00:00
2020-06-15 15:30:56 +00:00
# divergence of (a*u) where a is a scalar field and u is the atmospheric velocity field
def divergence_with_scalar ( a ) :
output = np . zeros_like ( a )
2020-07-01 20:18:16 +00:00
for i in range ( nlat ) :
for j in range ( nlon ) :
for k in range ( nlevels ) :
2020-08-27 08:24:39 +00:00
output [ i , j ] = scalar_gradient_x ( a * u , i , j , k ) + scalar_gradient_y ( a * v , i , j , k ) #+ 0.1*scalar_gradient_z(a*w,i,j,k)
2020-06-15 15:30:56 +00:00
return output
2020-06-24 20:08:16 +00:00
# power incident on (lat,lon) at time t
def solar ( insolation , lat , lon , t ) :
sun_longitude = - t % day
sun_longitude * = 360 / day
2020-08-27 08:24:39 +00:00
sun_latitude = axial_tilt * np . cos ( t * 2 * np . pi / year )
2020-06-24 20:08:16 +00:00
2020-08-27 08:24:39 +00:00
value = insolation * np . cos ( ( lat - sun_latitude ) * np . pi / 180 )
2020-08-12 19:53:41 +00:00
2020-08-27 08:24:39 +00:00
if value < 0 :
return 0
else :
2020-08-19 19:54:05 +00:00
2020-08-27 08:24:39 +00:00
lon_diff = lon - sun_longitude
value * = np . cos ( lon_diff * np . pi / 180 )
if value < 0 :
if lat + sun_latitude > 90 :
return insolation * np . cos ( ( lat + sun_latitude ) * np . pi / 180 ) * np . cos ( lon_diff * np . pi / 180 )
elif lat + sun_latitude < - 90 :
return insolation * np . cos ( ( lat + sun_latitude ) * np . pi / 180 ) * np . cos ( lon_diff * np . pi / 180 )
else :
return 0
else :
return value
2020-08-19 19:54:05 +00:00
2020-08-27 08:24:39 +00:00
def surface_optical_depth ( lat ) :
return 4 + np . cos ( lat * np . pi / 90 ) * 2.5 / 2
2020-08-19 19:54:05 +00:00
2020-08-27 08:24:39 +00:00
def smooth ( a , window ) :
output = np . zeros_like ( a )
diff = int ( np . floor ( window / 2 ) )
for i in range ( len ( output ) ) :
if i - diff < 0 :
output [ i ] = np . mean ( a [ i : i + diff + 1 ] )
elif i + diff + 1 > len ( output ) :
output [ i ] = np . mean ( a [ i - diff : i ] )
else :
output [ i ] = np . mean ( a [ i - diff : i + diff + 1 ] )
return output
2020-08-19 19:54:05 +00:00
2020-08-27 08:24:39 +00:00
def thermal_radiation ( a ) :
return sigma * ( a * * 4 )
2020-08-19 19:54:05 +00:00
2020-08-27 08:24:39 +00:00
#################### SHOW TIME ####################
2020-08-19 19:54:05 +00:00
if plot :
# set up plot
2020-08-27 08:24:39 +00:00
f , ax = plt . subplots ( 2 , figsize = ( 9 , 9 ) )
2020-08-19 19:54:05 +00:00
f . canvas . set_window_title ( ' CLAuDE ' )
ax [ 0 ] . contourf ( lon_plot , lat_plot , temperature_planet , cmap = ' seismic ' )
ax [ 1 ] . contourf ( lon_plot , lat_plot , temperature_atmosp [ : , : , 0 ] , cmap = ' seismic ' )
plt . subplots_adjust ( left = 0.1 , right = 0.75 )
ax [ 0 ] . set_title ( ' Ground temperature ' )
ax [ 1 ] . set_title ( ' Atmosphere temperature ' )
# allow for live updating as calculations take place
if level_plots :
2020-08-27 08:24:39 +00:00
g , bx = plt . subplots ( nlevels , figsize = ( 9 , 7 ) , sharex = True )
2020-08-19 19:54:05 +00:00
g . canvas . set_window_title ( ' CLAuDE atmospheric levels ' )
2020-08-27 08:24:39 +00:00
for k in range ( nlevels ) :
2020-08-19 19:54:05 +00:00
bx [ k ] . contourf ( lon_plot , lat_plot , temperature_atmosp [ : , : , k ] , cmap = ' seismic ' )
bx [ k ] . set_title ( str ( heights [ k ] ) + ' km ' )
bx [ k ] . set_ylabel ( ' Latitude ' )
bx [ - 1 ] . set_xlabel ( ' Longitude ' )
plt . ion ( )
plt . show ( )
2020-06-15 15:30:56 +00:00
2020-06-24 20:08:16 +00:00
# INITIATE TIME
t = 0
if load :
# load in previous save file
2020-08-19 19:54:05 +00:00
temperature_atmosp , temperature_planet , u , v , w , t , air_density , albedo = pickle . load ( open ( " save_file.p " , " rb " ) )
2020-06-15 15:30:56 +00:00
while True :
2020-06-24 20:08:16 +00:00
initial_time = time . time ( )
2020-06-17 16:17:11 +00:00
2020-08-27 08:24:39 +00:00
if t < 30 * day :
dt = 60 * 137
2020-06-17 16:17:11 +00:00
velocity = False
else :
2020-06-24 20:08:16 +00:00
dt = 60 * 9
2020-06-17 16:17:11 +00:00
velocity = True
2020-06-15 15:30:56 +00:00
2020-06-24 20:08:16 +00:00
# print current time in simulation to command line
2020-08-10 12:55:54 +00:00
print ( " +++ t = " + str ( round ( t / day , 2 ) ) + " days +++ " , end = ' \r ' )
2020-08-27 08:24:39 +00:00
print ( ' T: ' , round ( temperature_planet . max ( ) - 273.15 , 1 ) , ' - ' , round ( temperature_planet . min ( ) - 273.15 , 1 ) , ' C ' )
print ( ' U: ' , round ( u . max ( ) , 2 ) , ' - ' , round ( u . min ( ) , 2 ) , ' V: ' , round ( v . max ( ) , 2 ) , ' - ' , round ( v . min ( ) , 2 ) , ' W: ' , round ( w . max ( ) , 2 ) , ' - ' , round ( w . min ( ) , 2 ) )
# print(profile(air_density))
# print(profile(air_pressure)/100)
2020-06-24 20:08:16 +00:00
2020-06-15 15:30:56 +00:00
# calculate change in temperature of ground and atmosphere due to radiative imbalance
for i in range ( nlat ) :
for j in range ( nlon ) :
2020-08-12 19:53:41 +00:00
2020-08-27 08:24:39 +00:00
upward_radiation = np . zeros ( nlevels )
downward_radiation = np . zeros ( nlevels )
optical_depth = np . zeros ( nlevels )
Q = np . zeros ( nlevels )
2020-08-19 19:54:05 +00:00
# calculate optical depth
2020-08-12 19:53:41 +00:00
pressure_profile = air_pressure [ i , j , : ]
2020-08-19 19:54:05 +00:00
density_profile = air_density [ i , j , : ]
2020-08-12 19:53:41 +00:00
fl = 0.1
optical_depth = surface_optical_depth ( lat [ i ] ) * ( fl * ( pressure_profile / pressure_profile [ 0 ] ) + ( 1 - fl ) * ( pressure_profile / pressure_profile [ 0 ] ) * * 4 )
2020-08-27 08:24:39 +00:00
2020-08-19 19:54:05 +00:00
# calculate upward longwave flux, bc is thermal radiation at surface
2020-08-27 08:24:39 +00:00
upward_radiation [ 0 ] = thermal_radiation ( temperature_planet [ i , j ] )
2020-08-12 19:53:41 +00:00
for k in np . arange ( 1 , nlevels ) :
2020-08-27 08:24:39 +00:00
upward_radiation [ k ] = ( upward_radiation [ k - 1 ] - ( optical_depth [ k ] - optical_depth [ k - 1 ] ) * ( thermal_radiation ( temperature_atmosp [ i , j , k ] ) ) ) / ( 1 + optical_depth [ k - 1 ] - optical_depth [ k ] )
2020-08-19 19:54:05 +00:00
# calculate downward longwave flux, bc is zero at TOA (in model)
2020-08-27 08:24:39 +00:00
downward_radiation [ - 1 ] = 0
2020-08-12 19:53:41 +00:00
for k in np . arange ( 0 , nlevels - 1 ) [ : : - 1 ] :
2020-08-27 08:24:39 +00:00
downward_radiation [ k ] = ( downward_radiation [ k + 1 ] - thermal_radiation ( temperature_atmosp [ i , j , k ] ) * ( optical_depth [ k + 1 ] - optical_depth [ k ] ) ) / ( 1 + optical_depth [ k ] - optical_depth [ k + 1 ] )
2020-08-19 19:54:05 +00:00
# gradient of difference provides heating at each level
2020-08-12 19:53:41 +00:00
for k in np . arange ( nlevels ) :
Q [ k ] = - scalar_gradient_z ( upward_radiation - downward_radiation , 0 , 0 , k ) / ( 1E3 * density_profile [ k ] )
2020-08-27 08:24:39 +00:00
# make sure model does not have a higher top than 50km!!
# approximate SW heating of ozone
if heights [ k ] > 20E3 :
Q [ k ] + = solar ( 5 , lat [ i ] , lon [ j ] , t ) * ( ( ( ( heights [ k ] - 20E3 ) / 1E3 ) * * 2 ) / ( 30 * * 2 ) ) / ( 24 * 60 * 60 )
2020-06-17 16:17:11 +00:00
2020-08-27 08:24:39 +00:00
temperature_atmosp [ i , j , : ] + = Q * dt
2020-08-19 19:54:05 +00:00
2020-08-27 08:24:39 +00:00
# update surface temperature with shortwave radiation flux
temperature_planet [ i , j ] + = dt * ( ( 1 - albedo [ i , j ] ) * ( solar ( insolation , lat [ i ] , lon [ j ] , t ) + downward_radiation [ 0 ] ) - upward_radiation [ 0 ] ) / heat_capacity_earth [ i , j ]
2020-08-19 19:54:05 +00:00
2020-06-15 15:30:56 +00:00
# update air pressure
2020-08-27 08:24:39 +00:00
old_pressure = np . copy ( air_pressure )
2020-06-15 15:30:56 +00:00
air_pressure = air_density * specific_gas * temperature_atmosp
2020-06-24 20:08:16 +00:00
2020-06-17 16:17:11 +00:00
if velocity :
2020-06-24 20:08:16 +00:00
# introduce temporary arrays to update velocity in the atmosphere
2020-06-17 16:17:11 +00:00
u_temp = np . zeros_like ( u )
v_temp = np . zeros_like ( v )
2020-07-01 20:18:16 +00:00
w_temp = np . zeros_like ( w )
2020-06-15 15:30:56 +00:00
2020-06-17 16:17:11 +00:00
# calculate acceleration of atmosphere using primitive equations on beta-plane
2020-06-24 20:08:16 +00:00
for i in np . arange ( 1 , nlat - 1 ) :
2020-06-17 16:17:11 +00:00
for j in range ( nlon ) :
2020-08-12 19:53:41 +00:00
for k in range ( nlevels ) :
2020-08-19 19:54:05 +00:00
u_temp [ i , j , k ] + = dt * ( - u [ i , j , k ] * scalar_gradient_x ( u , i , j , k ) - v [ i , j , k ] * scalar_gradient_y ( u , i , j , k ) + coriolis [ i ] * v [ i , j , k ] - scalar_gradient_x ( air_pressure , i , j , k ) / air_density [ i , j , k ] )
v_temp [ i , j , k ] + = dt * ( - u [ i , j , k ] * scalar_gradient_x ( v , i , j , k ) - v [ i , j , k ] * scalar_gradient_y ( v , i , j , k ) - coriolis [ i ] * u [ i , j , k ] - scalar_gradient_y ( air_pressure , i , j , k ) / air_density [ i , j , k ] )
2020-08-27 08:24:39 +00:00
w_temp [ i , j , k ] + = - ( air_pressure [ i , j , k ] - old_pressure [ i , j , k ] ) / ( dt * air_density [ i , j , k ] * gravity )
# plt.plot(w_temp[i,j,:],heights)
# plt.title('Vertical acceleration')
# plt.show()
# sys.exit()
2020-06-15 17:24:09 +00:00
2020-06-17 16:17:11 +00:00
u + = u_temp
v + = v_temp
2020-08-27 08:24:39 +00:00
w + = w_temp
2020-06-15 15:30:56 +00:00
2020-08-27 08:24:39 +00:00
# approximate friction
u * = 0.95
v * = 0.95
2020-06-24 20:08:16 +00:00
if advection :
# allow for thermal advection in the atmosphere, and heat diffusion in the atmosphere and the ground
2020-07-08 19:59:08 +00:00
# atmosp_addition = dt*(thermal_diffusivity_air*laplacian(temperature_atmosp))
2020-08-10 12:55:54 +00:00
atmosp_addition = dt * divergence_with_scalar ( temperature_atmosp )
temperature_atmosp [ advection_boundary : - advection_boundary , : , : ] - = atmosp_addition [ advection_boundary : - advection_boundary , : , : ]
temperature_atmosp [ advection_boundary - 1 , : , : ] - = 0.5 * atmosp_addition [ advection_boundary - 1 , : , : ]
temperature_atmosp [ - advection_boundary , : , : ] - = 0.5 * atmosp_addition [ - advection_boundary , : , : ]
2020-06-24 20:08:16 +00:00
# as density is now variable, allow for mass advection
density_addition = dt * divergence_with_scalar ( air_density )
2020-07-01 20:18:16 +00:00
air_density [ advection_boundary : - advection_boundary , : , : ] - = density_addition [ advection_boundary : - advection_boundary , : , : ]
air_density [ ( advection_boundary - 1 ) , : , : ] - = 0.5 * density_addition [ advection_boundary - 1 , : , : ]
air_density [ - advection_boundary , : , : ] - = 0.5 * density_addition [ - advection_boundary , : , : ]
2020-06-24 20:08:16 +00:00
temperature_planet + = dt * ( thermal_diffusivity_roc * laplacian ( temperature_planet ) )
2020-08-19 19:54:05 +00:00
if plot :
# update plot
test = ax [ 0 ] . contourf ( lon_plot , lat_plot , temperature_planet , cmap = ' seismic ' )
2020-08-27 08:24:39 +00:00
ax [ 0 ] . streamplot ( lon_plot , lat_plot , u [ : , : , 0 ] , v [ : , : , 0 ] , color = ' white ' , density = 1 )
2020-08-19 19:54:05 +00:00
ax [ 0 ] . set_title ( ' $ \ it {Ground} \ quad \ it {temperature} $ ' )
ax [ 0 ] . set_xlim ( ( lon . min ( ) , lon . max ( ) ) )
ax [ 0 ] . set_ylim ( ( lat . min ( ) , lat . max ( ) ) )
ax [ 0 ] . set_ylabel ( ' Latitude ' )
ax [ 0 ] . axhline ( y = 0 , color = ' black ' , alpha = 0.3 )
ax [ 0 ] . set_xlabel ( ' Longitude ' )
ax [ 1 ] . contourf ( heights_plot , lat_z_plot , np . transpose ( np . mean ( temperature_atmosp , axis = 1 ) ) , cmap = ' seismic ' )
2020-08-27 08:24:39 +00:00
ax [ 1 ] . contour ( heights_plot , lat_z_plot , np . transpose ( np . mean ( u , axis = 1 ) ) , colors = ' white ' , levels = 20 , linewidths = 1 , alpha = 0.8 )
ax [ 1 ] . streamplot ( heights_plot , lat_z_plot , np . transpose ( np . mean ( v , axis = 1 ) ) , np . transpose ( np . mean ( 10 * w , axis = 1 ) ) , color = ' black ' , density = 0.75 )
2020-08-19 19:54:05 +00:00
ax [ 1 ] . set_title ( ' $ \ it {Atmospheric} \ quad \ it {temperature} $ ' )
ax [ 1 ] . set_xlim ( ( - 90 , 90 ) )
ax [ 1 ] . set_ylim ( ( 0 , heights . max ( ) ) )
ax [ 1 ] . set_ylabel ( ' Height (m) ' )
ax [ 1 ] . set_xlabel ( ' Latitude ' )
cbar_ax = f . add_axes ( [ 0.85 , 0.15 , 0.05 , 0.7 ] )
f . colorbar ( test , cax = cbar_ax )
cbar_ax . set_title ( ' Temperature (K) ' )
f . suptitle ( ' Time ' + str ( round ( 24 * t / day , 2 ) ) + ' hours ' )
if level_plots :
2020-08-27 08:24:39 +00:00
for k in range ( nlevels ) :
2020-08-19 19:54:05 +00:00
index = nlevels - 1 - k
test = bx [ index ] . contourf ( lon_plot , lat_plot , temperature_atmosp [ : , : , k ] , cmap = ' seismic ' )
2020-08-27 08:24:39 +00:00
bx [ index ] . streamplot ( lon_plot , lat_plot , u [ : , : , k ] , v [ : , : , k ] , density = 0.5 , color = ' black ' )
2020-08-19 19:54:05 +00:00
# g.colorbar(test,cax=bx[nlevels-1-k])
bx [ index ] . set_title ( str ( heights [ k ] / 1E3 ) + ' km ' )
bx [ index ] . set_ylabel ( ' Latitude ' )
bx [ index ] . set_xlim ( ( lon . min ( ) , lon . max ( ) ) )
bx [ index ] . set_ylim ( ( lat . min ( ) , lat . max ( ) ) )
bx [ - 1 ] . set_xlabel ( ' Longitude ' )
plt . pause ( 0.01 )
ax [ 0 ] . cla ( )
ax [ 1 ] . cla ( )
if level_plots :
for k in range ( nlevels ) :
bx [ k ] . cla ( )
2020-06-15 15:30:56 +00:00
# advance time by one timestep
2020-06-24 20:08:16 +00:00
t + = dt
time_taken = float ( round ( time . time ( ) - initial_time , 3 ) )
print ( ' Time: ' , str ( time_taken ) , ' s ' )
if save :
2020-08-19 19:54:05 +00:00
pickle . dump ( ( temperature_atmosp , temperature_planet , u , v , w , t , air_density , albedo ) , open ( " save_file.p " , " wb " ) )
2020-08-12 19:53:41 +00:00
# sys.exit()