Changeset 807


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

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

Location:
codes/icosagcm/devel/Python
Files:
6 edited

Legend:

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

    r794 r807  
    1717            if ci > c1 : m[i]=0. 
    1818        return m 
     19    def relax_RSW(self, llm, step, flow): 
     20        beta_i, beta_e = self.beta_i, self.beta_e 
     21        m,u=flow 
     22        step.mass[:]        = beta_i*step.mass[:]        + (1.-beta_i)*m[:] 
     23        step.theta_rhodz[:] = beta_i*step.theta_rhodz[:] + (1.-beta_i)*m[:] 
     24        step.u[:]           = beta_e*step.u[:]           + (1.-beta_e)*u[:] 
     25    def relax_hydro(self, llm, step, flow): 
     26        beta_i, beta_e = self.beta_i, self.beta_e 
     27        m,S,u=flow 
     28        for l in range(llm): 
     29            step.mass[:,l]        = beta_i*step.mass[:,l]        + (1.-beta_i)*m[:,l] 
     30            step.theta_rhodz[:,l] = beta_i*step.theta_rhodz[:,l] + (1.-beta_i)*S[:,l] 
     31            step.u[:,l]           = beta_e*step.u[:,l]           + (1.-beta_e)*u[:,l] 
    1932    def relax(self, llm, step, flow): 
    2033        beta_i, beta_e = self.beta_i, self.beta_e 
  • codes/icosagcm/devel/Python/dynamico/dev/meshes.py

    r805 r807  
    22 
    33from dynamico import meshes 
    4 from dynamico.meshes import MPAS_Format, Unstructured_PMesh, compute_hybrid_coefs 
     4from dynamico.meshes import Unstructured_PMesh, compute_hybrid_coefs 
     5from dynamico.meshes import DYNAMICO_Format, MPAS_Format 
    56from dynamico import unstructured as unst 
    67from dynamico.dev import numba 
  • 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 
  • codes/icosagcm/devel/Python/dynamico/meshes.py

    r805 r807  
    431431        """Before calling apply_map, lat and lon are coordinates in the reference domain. 
    432432        After calling apply_map, lat and lon are coordinates in the physical domain.""" 
    433         factor_e = mapping.map_factor(self.lon_e, self.lat_e) 
    434         factor2_i = mapping.map_factor(self.lon_i, self.lat_i)**2 
    435         factor2_v = mapping.map_factor(self.lon_v, self.lat_v)**2 
     433        lat_i, lat_e, lat_v = self.lat_i, self.lat_e, self.lat_v 
     434        lon_i, lon_e, lon_v = self.lon_i, self.lon_e, self.lon_v 
     435        factor_e = mapping.map_factor(lon_e, lat_e) 
     436        factor2_i = mapping.map_factor(lon_i, lat_i)**2 
     437        factor2_v = mapping.map_factor(lon_v, lat_v)**2 
    436438        self.le, self.de, self.Av, self.Ai = self.le*factor_e, self.de*factor_e, self.Av*factor2_v, self.Ai*factor2_i 
    437         self.lon_i, self.lat_i = mapping.map(self.lon_i, self.lat_i) 
    438         self.lon_v, self.lat_v = mapping.map(self.lon_v, self.lat_v) 
    439         self.lon_e, self.lat_e = mapping.map(self.lon_e, self.lat_e) 
     439        self.angle_e += mapping.map_angle(lon_e, lat_e) 
     440        self.lon_i, self.lat_i = mapping.map(lon_i, lat_i) 
     441        self.lon_v, self.lat_v = mapping.map(lon_v, lat_v) 
     442        self.lon_e, self.lat_e = mapping.map(lon_e, lat_e) 
     443        self.ref_lon_i, self.ref_lat_i = lon_i, lat_i 
     444        self.ref_lon_e, self.ref_lat_e = lon_e, lat_e 
     445        self.ref_lon_v, self.ref_lat_v = lon_v, lat_v 
    440446 
    441447class Unstructured_Mesh(Abstract_Mesh): 
  • codes/icosagcm/devel/Python/test/py/RSW2_MPAS_W02.py

    r805 r807  
    11from dynamico import getargs 
     2getargs.add("--LAM", action='store_true') 
     3# Args for global mesh 
     4getargs.add("--grid", type=int, help='Number of hexagons', default=2562) 
     5# Args for LAM 
     6getargs.add("--nx", type=int, help='Zonal dimension of LAM mesh', default=100) 
     7getargs.add("--ny", type=int, help='Meridional dimension of LAM mesh', default=100) 
     8getargs.add("--dx", type=float, help='Resolution at center of LAM domain', default=1e5) 
     9getargs.add("--center_lat", type=float, help='Latitude in degrees of LAM center', default=0.) 
     10getargs.add("--Davies_N1", type=int, default=3) 
     11getargs.add("--Davies_N2", type=int, default=3) 
     12 
     13args = getargs.parse() 
     14 
    215log_master, log_world = getargs.getLogger() 
    316INFO, DEBUG, ERROR = log_master.info, log_master.debug, log_world.error 
     
    1427from dynamico import unstructured as unst 
    1528from dynamico.dev.meshes import MPAS_Format, Unstructured_PMesh as PMesh, Local_Mesh as Mesh 
     29from dynamico.dev import meshes 
    1630from dynamico import time_step 
    1731from dynamico import maps 
     32from dynamico.LAM import Davies 
     33 
    1834print '...Done' 
    1935 
     
    2440print '...Done' 
    2541 
    26 grid, llm, nqdyn = 2562, 1,1 # 2562, 10242, 40962 
     42#--------------------------- functions and classes ----------------------------- 
     43 
     44class myDavies(Davies): 
     45    def mask(self,X,Y): 
     46        # X and Y are coordinates in the reference domain (cell = unit square) 
     47        # numerical domain extends from -nx/2 ... nx/2 and -ny/2 ... ny/2 
     48        # useful domain extends from -X0 ... X0 and -Y0 ... Y0 
     49        N3 = args.Davies_N1+args.Davies_N2 
     50        X0 = args.nx/2. - N3 
     51        Y0 = args.ny/2. - N3 
     52        mask  = self.mask0( X,X0,1.)  # Western boundary 
     53        mask *= self.mask0(-X,X0,1.) # Eastern boundary 
     54        mask *= self.mask0( Y,Y0,1.) # Northern boundary 
     55        mask *= self.mask0(-Y,Y0,1.) # Southern boundary 
     56        return mask 
     57 
     58#----------------------------- main program -------------------------------- 
     59 
     60llm, nqdyn = 1,1 # 2562, 10242, 40962 
    2761Omega, radius, g, gh0 = 2.*np.pi/86400., 6.4e6, 1., 2.94e4 
    2862N, T, courant = 40, 10400., 1.2 # simulation length = N*T 
    2963 
    3064print 'Omega, planetary PV', Omega, 2*Omega/gh0 
    31 planet = maps.SphereMap(radius, Omega) 
    3265 
    33 print 'Reading MPAS mesh ...' 
    34 meshfile = MPAS_Format('grids/x1.%d.grid.nc'%grid) 
    35 pmesh = PMesh(comm,meshfile) 
    36 pmesh.partition_metis() 
     66if args.LAM: 
     67    nx, ny = args.nx, args.ny 
     68    filename = 'cart_%03d_%03d.nc'%(nx,ny) 
     69    INFO('Reading Cartesian mesh ...') 
     70    meshfile = meshes.DYNAMICO_Format(filename) 
     71    pmesh = meshes.Unstructured_PMesh(comm,meshfile) 
     72    pmesh.partition_curvilinear(args.mpi_ni,args.mpi_nj) 
     73    planet = maps.PolarStereoMap(radius,Omega, args.dx, args.center_lat*np.pi/180.) 
     74else: 
     75    planet = maps.SphereMap(radius, Omega) 
     76    print 'Reading MPAS mesh ...' 
     77    meshfile = MPAS_Format('grids/x1.%d.grid.nc'%args.grid) 
     78    pmesh = PMesh(comm,meshfile) 
     79    pmesh.partition_metis() 
     80 
    3781mesh = Mesh(pmesh, llm, nqdyn, planet) 
     82 
    3883print '...Done' 
    3984lon, lat = mesh.lon_i, mesh.lat_i 
     
    5398scheme = time_step.RK4(None, dt) 
    5499print dt, scheme.csjl, scheme.cfjl 
    55 step = unst.caldyn_step_TRSW(mesh,scheme,nt) 
     100step = unst.caldyn_step_TRSW(mesh,scheme,1) 
    56101 
    57102u0 = Omega*radius/12. # cf Williamson (1991), p.13 
     
    59104print 'Williamson (1991) test 2, u0=', u0 
    60105ulon = u0*np.cos(mesh.lat_e) 
    61 Phi0 = gh0 - gh1*(np.sin(mesh.lat_i)**2) 
    62 zeta0 = (2*u0/radius+2*Omega)*np.sin(mesh.lat_v) 
    63 Phi0v = gh0 - (radius*Omega*u0+.5*u0**2)*(np.sin(mesh.lat_v)**2) 
    64 q0 = zeta0/Phi0v 
    65 fu_perp = mesh.ucov2D(0.*ulon,2*Omega*np.sin(mesh.lat_e)*ulon) 
    66106 
    67 # initial condition 
    68 step.mass[:]=Phi0 
    69 step.theta_rhodz[:]=Phi0 
    70 step.u[:]=mesh.ucov2D(ulon,0.*ulon) 
     107gh_ini = gh0 - gh1*(np.sin(mesh.lat_i)**2) 
     108u_ini = mesh.ucov2D(ulon,0.*ulon) 
    71109 
    72 gh,u = step.mass.copy(), step.u.copy() 
     110# unst.ker.dynamico_update_halo(mesh.com_edges.index, 1, u.shape[0], u)  
    73111 
     112if args.LAM: 
     113    davies = myDavies(args.Davies_N1, args.Davies_N2,  
     114                      mesh.ref_lon_i, mesh.ref_lat_i, mesh.ref_lon_e,mesh.ref_lat_e) 
     115    def relax(): 
     116        davies.relax_RSW(llm, step, (gh_ini, u_ini) ) 
     117else: 
     118    def relax(): pass 
     119 
     120def next_flow(Phi, u): 
     121    step.mass[:], step.theta_rhodz[:], step.u[:] = Phi, Phi, u 
     122    for i in range(nt): 
     123        step.next() 
     124        relax() 
     125    return step.mass.copy(), step.u.copy() 
     126 
     127gh, u = gh_ini, u_ini 
    74128print gh.shape, gh.min(), gh.max(), u.min(), u.max() 
    75 flow=gh,u 
    76129 
    77 unst.ker.dynamico_update_halo(mesh.com_edges.index, 1, u.shape[0], u)  
    78                                    
    79130for i in range(20): 
    80131    if True: 
    81         step.next() 
    82         gh,u = step.mass, step.u 
     132        gh, u = next_flow(gh,u) 
     133        # step.next() 
     134        # gh,u = step.mass, step.u 
    83135        print i, gh.shape, gh.min(), gh.max(), u.min(), u.max() 
    84         mesh.plot_i(gh-Phi0) ; plt.title('err(gh)'); 
     136        mesh.plot_i(gh-gh_ini) ; plt.title('err(gh)'); 
    85137        plt.savefig('%s_err_gh_%02d.png'%(prefix,i)) 
    86138        plt.close() 
  • codes/icosagcm/devel/Python/test/py/write_Cartesian_mesh.py

    r790 r807  
    2424 
    2525dx,dy=Lx/nx,Ly/ny 
    26 mesh = meshes.Cartesian_mesh(nx,ny,llm,nqdyn,Lx,Ly,0.) 
     26mesh = meshes.Cartesian_Mesh(nx,ny,llm,nqdyn,Lx,Ly,0.) 
    2727print('Successfully initialized Cartesian mesh') 
    2828mesh.ncwrite('cart_%03d_%03d.nc'%(nx,ny)) 
Note: See TracChangeset for help on using the changeset viewer.