Ignore:
Timestamp:
02/08/19 18:53:34 (5 years ago)
Author:
jisesh
Message:

devel/Python : polar projection + Williamson test case 2 on LAM

File:
1 edited

Legend:

Unmodified
Added
Removed
  • codes/icosagcm/devel/Python/dynamico/maps.py

    r801 r807  
    1414    def map(self, x, y): 
    1515        """x,y are coordinates in the reference domain.""" 
    16         return self.xc + self.scale*x, self.yc + self.scale*y  
     16        return self.xc + self.scale*x, self.yc + self.scale*y 
    1717    def map_factor(self, lon,lat): return 0.*lon + self.scale 
     18    def map_angle(self, lon, lat): return 0.*lon 
    1819 
    1920class SphereMap: 
     
    2728    def map(self, lon,lat): return lon, lat 
    2829    def map_factor(self, lon,lat): return 0.*lon + self.radius 
     30    def map_angle(self, lon, lat): return 0.*lon 
    2931 
    3032# https://en.wikipedia.org/wiki/Mercator_projection 
     33# https://en.wikipedia.org/wiki/Stereographic_projection 
     34class PolarStereoMap: 
     35    def __init__(self, radius,Omega, delta, phic=0., lonc=0.): 
     36        self.a, self.delta, self.Omega = radius, delta, Omega 
     37        self.phic, self.lonc = phic, lonc # latitude of domain center 
     38    def coriolis(self, lon, lat): 
     39        return 2.*self.Omega*np.sin(lat) 
     40    def map_factor(self,X,Y): 
     41        lon, lat, factor, angle = self.compute_map_factor_angle(X,Y) 
     42        return factor 
     43    def map_angle(self,X,Y): 
     44        lon, lat, factor, angle = self.compute_map_factor_angle(X,Y) 
     45        return angle 
     46    def map(self,X,Y): 
     47        lon, lat, factor, angle = self.compute_map_factor_angle(X,Y) 
     48        return lon, lat 
     49    def compute_map_factor_angle(self,X,Y): 
     50        """ X, Y : reference coordinates on a mesh where cells have unit size""" 
     51        alpha = .5*self.delta/self.a 
     52        X, Y = alpha*X, alpha*Y # scale X and Y to obtain desired resolution delta at domain center 
     53        # now X and Y are as in wikipedia 
     54        # we let (x,y) => (-y,x) to align X axis with equator when phic=0. 
     55        factor =  1./(1.+X*X+Y*Y) 
     56        y = 2.*X*factor 
     57        x = -2.*Y*factor 
     58        z = (1.-X*X-Y*Y)*factor 
     59        # compute d/dX to track mesh orientation 
     60        f2 = factor**2 
     61        dy = 2.*(1.-X*X+Y*Y)*f2 
     62        dx = 4.*X*Y*f2 
     63        dz = -4.*X*f2 
     64        # TODO : rotate x,y,z about polar axis 
     65        x,y,z = self.RotationPhi(x,y,z) 
     66        dx,dy,dz = self.RotationPhi(dx,dy,dz) 
     67        cos_angle = (dy*x-dx*y)/np.sqrt((dx**2+dy**2+dz**2)*(x**2+y**2)) 
     68        sin_angle = (dz*(1.-z**2)-z*(dy*y+dx*x))/np.sqrt((dx**2+dy**2+dz**2)*(x**2+y**2)) 
     69        angle = np.arctan2(dz*(1.-z**2)-z*(dy*y+dx*x), dy*x-dx*y) 
     70        err = cos_angle-np.cos(angle) 
     71        print 'Consistency check :', err.min(), err.max() 
     72        # TODO : rotate x,y,z so that North Pole gets to desired latitude 
     73        lat = np.arcsin(z) 
     74        lon = np.arctan2(y,x) + self.lonc 
     75        return lon, lat, self.delta*factor, angle 
     76    def RotationPhi(self,x2,y2,z2): 
     77        cos, sin = np.cos(self.phic), np.sin(self.phic) 
     78        x3 = sin * x2 + cos*z2 
     79        z3 = -cos * x2 + sin*z2 
     80        return x3,y2,z3 
Note: See TracChangeset for help on using the changeset viewer.