-
Notifications
You must be signed in to change notification settings - Fork 0
/
spherical_area.py
74 lines (53 loc) · 2.83 KB
/
spherical_area.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import numpy as np
def cal_area(lon,lat,dlon,dlat) :
# input : lon, lat (not array, but single element)
# output : area that matches the [lon,lat] coordinate
# units in cm^2
# constant
arad = np.float64(6.371E8) #cm
dlon = np.float64(dlon*np.pi/180.)
dlat = np.float64(dlat*np.pi/180.)
lat = (90.-lat)*np.pi/180.
area = arad*arad*np.sin(lat)*dlon*dlat
return area
def da_area(da_var, lonname='lon', latname='lat', xname='x', yname='y', model=None):
"""
calculate spherical area
"""
r_earth = 6.371*1E8 # cm
if model in ['gfdl']:
# calculate dy
dy = da_var[latname].copy()+np.nan
dyl = da_var[latname].diff(yname,1,label='lower')
dyu = da_var[latname].diff(yname,1,label='upper')
dy.values[0,:] = dyl.values[0,:] # forward differences
dy.values[1:-1,:] = (dyl+dyu).values/2. # central differences
dy.values[-1,:] = dyu.values[-1,:] # backward differences
da_dy = dy/180.*np.pi*r_earth/100. # m (2D)
# calculate dx
dx = da_var[lonname].copy()+np.nan
dxl = da_var[lonname].diff(xname,1,label='lower')
dxu = da_var[lonname].diff(xname,1,label='upper')
dx.values[:,0] = dxl.values[:,0] # forward differences
dx.values[:,1:-1] = (dxl+dxu).values/2. # central differences
dx.values[:,-1] = dxu.values[:,-1] # backward differences
da_dx = dx/180.*np.pi*r_earth*np.cos(da_var[latname]/180.*np.pi)/100. # m (2D)
else :
# calculate dy
dy = da_var[latname].copy()+np.nan
dyl = da_var[latname].diff(yname,1,label='lower')
dyu = da_var[latname].diff(yname,1,label='upper')
dy.values[0] = dyl.values[0] # forward differences
dy.values[1:-1] = (dyl+dyu).values/2. # central differences
dy.values[-1] = dyu.values[-1] # backward differences
da_dy = dy/180.*np.pi*r_earth/100. # m (2D)
# calculate dx
dx = da_var[lonname].copy()+np.nan
dxl = da_var[lonname].diff(xname,1,label='lower')
dxu = da_var[lonname].diff(xname,1,label='upper')
dx.values[0] = dxl.values[0] # forward differences
dx.values[1:-1] = (dxl+dxu).values/2. # central differences
dx.values[-1] = dxu.values[-1] # backward differences
da_dx = dx/180.*np.pi*r_earth*np.cos(da_var[latname]/180.*np.pi)/100. # m (2D)
da_area = da_dx*da_dy
return da_area