source: codes/icosagcm/devel/Python/test/py/Baroclinic_3D_ullrich.py @ 763

Last change on this file since 763 was 763, checked in by jisesh, 6 years ago

devel/Python : writing data in parallel

File size: 4.9 KB
Line 
1from dynamico import unstructured as unst
2from dynamico import dyn
3from dynamico import time_step
4from dynamico import DCMIP
5from dynamico import meshes
6from dynamico import xios
7from dynamico import precision as prec
8from dynamico.meshes import Cartesian_mesh as Mesh
9
10import math as math
11import numpy as np
12import time
13from numpy import pi, log, exp, sin, cos
14
15# Baroclinic instability test based on Ullrich et al. 2015, QJRMS
16
17def baroclinic_3D(Lx,nx,Ly,ny,llm,ztop=25000.):
18    Rd    = 287.0      # Gas constant for dryy air (j kg^-1 K^-1)
19    T0    = 288.0      # Reference temperature (K)
20    lap   = 0.005      # Lapse rate (K m^-1)
21    b     = 2.         # Non dimensional vertical width parameter
22    u0    = 35.        # Reference zonal wind speed (m s^-1)
23    a     = 6.371229e6 # Radius of the Earth (m)
24    ptop  = 2000.
25    y0    = Ly*0.5
26    Cpd   = 1004.5
27    p0    = 1e5
28
29    omega  = 7.292e-5  # Angular velocity of the Earth (s^-1)   
30    phi0   = 45.       # Reference latitude North pi/4 (deg)
31    f0     = 2*omega*np.sin(phi0) 
32    beta0  = 2*omega*np.cos(phi0)/a
33    fb     = 2*omega*np.sin(phi0) - y0*2*omega*np.cos(phi0)/a
34
35    def Phi_xy(x,y):
36        fc = y*y - (Ly*y/pi)*sin(2*pi*y/Ly)
37        fd = Ly*Ly/(2*pi*pi)*cos(2*pi*y/Ly)
38        return .5*u0*( fb*(y-y0-Ly/(2*pi)*sin(2*pi*y/Ly)) + .5*beta0*(fc-fd-(Ly*Ly/3.)- Ly*Ly/(2*pi*pi)) )
39
40    def Phi_xyeta(x,y,eta): return T0*g/lap*(1-eta**(Rd*lap/g)) + Phi_xy(x,y)*log(eta)*exp(-((log(eta)/b)**2))
41    def ulon(x,y,eta): return -u0*(sin(pi*y/Ly)**2)*log(eta)*(eta**(-log(eta)/b/b))
42    def tmean(eta) : return T0*eta**(Rd*lap/g)
43    def T(x,y,eta) : return tmean(eta)+(Phi_xy(x,y)/Rd)*(((2/(b*b))*(log(eta))**2)-1)*exp(-((0.5*log(eta))**2)) 
44    def p(eta): return p0*eta     # eta  = p/p_s
45
46    def eta(alpha) : return (1-(lap*ztop*alpha/(T0)))**(g/(Rd*lap)) # roughly equispaced levels
47
48    filename = 'cart_%03d_%03d.nc'%(nx,ny)
49    print 'Reading Cartesian mesh ...'
50    def coriolis(lon,lat): return f0+0.*lon
51    meshfile = meshes.DYNAMICO_Format(filename)
52    nqdyn, radius = 1, None
53    pmesh = meshes.Unstructured_PMesh(comm,meshfile)
54    pmesh.partition_curvilinear(args.mpi_ni,args.mpi_nj)
55    mesh  = meshes.Local_Mesh(pmesh, llm, nqdyn, radius, coriolis)
56
57    alpha_k = (np.arange(llm)  +.5)/llm
58    alpha_l = (np.arange(llm+1)+ 0.)/llm
59    x_ik, alpha_ik = np.meshgrid(mesh.lon_i, alpha_k, indexing='ij')
60    y_ik, alpha_ik = np.meshgrid(mesh.lat_i, alpha_k, indexing='ij')
61    x_il, alpha_il = np.meshgrid(mesh.lon_i, alpha_l, indexing='ij')
62    y_il, alpha_il = np.meshgrid(mesh.lat_i, alpha_l, indexing='ij')
63    x_ek, alpha_ek = np.meshgrid(mesh.lon_e, alpha_k, indexing='ij')
64    y_ek, alpha_ek = np.meshgrid(mesh.lat_e, alpha_k, indexing='ij')
65
66    print('----------------')
67    print 'ztop(ptop) according to Eq. 7:', T0/lap*(1.-(ptop/p0)**(Rd*lap/g)) 
68    print(np.shape(alpha_k),np.shape(alpha_l))
69    print(mesh.__dict__.keys())
70    thermo = dyn.Ideal_perfect(Cpd, Rd, p0, T0)
71
72    eta_il = eta(alpha_il)
73    eta_ik = eta(alpha_ik)
74    eta_ek = eta(alpha_ek)
75    print('min max eta_il', np.min(eta_il),np.max(eta_il))
76
77    Phi_il = Phi_xyeta(x_il, y_il, eta_il)
78    Phi_ik = Phi_xyeta(x_ik, y_ik, eta_ik)
79    p_ik = p(eta_ik)
80    T_ik = T(x_ik, y_ik, eta_ik)  #ik full level(40), il(41)
81
82    gas = thermo.set_pT(p_ik,T_ik)
83    mass_ik = mesh.field_mass()
84    for l in range(llm): 
85        mass_ik[:,l]=(Phi_il[:,l+1]-Phi_il[:,l])/(g*gas.v[:,l])
86    Sik, ujk, Wil  = gas.s*mass_ik, mesh.field_u(), mesh.field_w()
87   
88    print(np.shape(ujk))
89    print('P_ik',p_ik[0,:])
90
91    u_ek = mesh.ucov3D(ulon(x_ek, y_ek, eta_ek), 0.*eta_ek)
92
93    print(np.shape(u_ek))
94
95    print 'ztop (m) = ', Phi_il[0,-1]/g, ztop
96    ptop = p(eta(1.))
97    print 'ptop (Pa) = ', gas.p[0,-1], ptop
98
99    params=dyn.Struct()
100    params.ptop=ptop
101    params.dx=dx
102    params.dx_g0=dx/g
103    params.g = g
104
105    # define parameters for lower BC
106    pbot = p(eta_il[:,0])
107    print 'min p, T :', pbot.min(), tmean(pbot/p0)
108    gas_bot = thermo.set_pT(pbot, tmean(pbot/p0))
109    params.pbot = gas_bot.p
110    params.rho_bot = 1e6/gas_bot.v
111   
112    return thermo, mesh, params, prec.asnum([mass_ik,Sik,ujk,Phi_il,Wil]), gas
113
114with xios.Client() as client: # setup XIOS which creates the DYNAMICO communicator
115    comm = client.comm
116    mpi_rank, mpi_size = comm.Get_rank(), comm.Get_size()
117    print '%d/%d starting'%(mpi_rank,mpi_size)
118
119    g, Lx, Ly = 9.81, 4e7, 6e6
120    nx, ny, llm = 200, 30, 22
121    dx,dy=Lx/nx,Ly/ny
122
123    unst.setvar('g',g)
124
125    thermo, mesh, params, flow0, gas0 = baroclinic_3D(Lx,nx,Ly,ny,llm)
126
127    T, nslice, dt = 3600., 1, 3600.
128
129    with xios.Context_Curvilinear(mesh,1, dt) as context:
130        # now XIOS knows about the mesh and we can write to disk
131        for i in range(48):
132            context.update_calendar(i)
133            print 'send_field', i, gas0.T.shape
134    #    context.send_field_primal('ps', lat_i)
135            context.send_field_primal('temp', gas0.T)
136            context.send_field_primal('p', gas0.p)
Note: See TracBrowser for help on using the repository browser.