source: codes/icosagcm/devel/Python/test/py/DCMIP2008c5_MPI.py @ 697

Last change on this file since 697 was 697, checked in by dubos, 6 years ago

devel/unstructured : MPI+XIOS for DCMIP2008c5

File size: 8.5 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
6import dynamico.xios as xios
7
8import math as math
9import matplotlib.pyplot as plt
10import numpy as np
11import time
12
13from mpi4py import MPI
14comm = MPI.COMM_WORLD
15mpi_rank, mpi_size = comm.Get_rank(), comm.Get_size()
16print '%d/%d starting'%(mpi_rank,mpi_size)
17
18#------------------------ initial condition -------------------------
19
20# Parameters for the simulation
21g              = 9.80616   # gravitational acceleration in meters per second squared
22omega          = 7.29211e-5  # Earth's angular velocity in radians per second
23f0             = 2.0*omega   # Coriolis parameter
24u_0            = 20.0        # velocity in meters per second
25T_0            = 288.0       # temperature in Kelvin
26d2             = 1.5e6**2    # square of half width of Gaussian mountain profile in meters
27h_0            = 2.0e3       # mountain height in meters
28lon_c          = np.pi/2.0   # mountain peak longitudinal location in radians
29lat_c          = np.pi/6.0   # mountain peak latitudinal location in radians
30radius         = 6.371229e6  # mean radius of the Earth in meters
31ref_press      = 100145.6    # reference pressure (mean surface pressure) in Pascals
32ref_surf_press = 930.0e2     # South Pole surface pressure in Pascals
33Rd             = 287.04      # ideal gas constant for dry air in joules per kilogram Kelvin
34Cpd            = 1004.64     # specific heat at constant pressure in joules per kilogram Kelvin
35kappa          = Rd/Cpd      # kappa=R_d/c_p
36N_freq         = np.sqrt(g**2/(Cpd*T_0)) # Brunt-Vaisala buoyancy frequency
37N2, g2kappa = N_freq**2, g*g*kappa
38
39def DCMIP2008c5(grid,llm):
40    def Phis(lon,lat): 
41        rgrc = radius*np.arccos(np.sin(lat_c)*np.sin(lat)+np.cos(lat_c)*np.cos(lat)*np.cos(lon-lon_c))
42        return g*h_0*np.exp(-rgrc**2/d2)
43    def ps(lon, lat, Phis): 
44        return ref_surf_press * np.exp(
45            - radius*N2*u_0/(2.0*g2kappa)*(u_0/radius+f0)*(np.sin(lat)**2-1.)
46            - N2/(g2kappa)*Phis )
47    def ulon(lat): return u_0*np.cos(lat)
48    def ulat(lat): return 0.*lat
49    def f(lon,lat): return f0*np.sin(lat) # Coriolis parameter
50
51    nqdyn, preff, Treff = 1, 1e5, 300.
52    thermo = dyn.Ideal_perfect(Cpd, Rd, preff, Treff)
53
54    meshfile = meshes.MPAS_Format('grids/x1.%d.grid.nc'%grid)
55#    mesh = meshes.Unstructured_Mesh(meshfile, llm, nqdyn, radius, f)
56    pmesh = meshes.Unstructured_PMesh(comm,meshfile)
57    mesh = meshes.Local_Mesh(pmesh, llm, nqdyn, radius, f)
58    mesh.pmesh=pmesh
59
60    lev,levp1 = np.arange(llm),np.arange(llm+1)
61    lon_i, lat_i, lon_e, lat_e =  mesh.lon_i, mesh.lat_i, mesh.lon_e, mesh.lat_e
62    lat_ik,k_i = np.meshgrid(mesh.lat_i,lev, indexing='ij')
63    lon_ik,k_i = np.meshgrid(mesh.lon_i,lev, indexing='ij')
64    lat_il,l_i = np.meshgrid(mesh.lat_i,levp1, indexing='ij')           
65    lon_il,l_i = np.meshgrid(mesh.lon_i,levp1, indexing='ij')
66    lat_ek,k_e = np.meshgrid(mesh.lat_e,lev, indexing='ij')
67
68    Phis_i = Phis(lon_i, lat_i)
69    ps_i = ps(lon_i, lat_i, Phis_i)
70
71    if llm==18:
72        ap_l=[0.00251499, 0.00710361, 0.01904260, 0.04607560, 0.08181860,
73              0.07869805, 0.07463175, 0.06955308, 0.06339061, 0.05621774, 0.04815296,
74              0.03949230, 0.03058456, 0.02193336, 0.01403670, 0.007458598, 0.002646866,
75              0.0, 0.0 ]
76        bp_l=[0.0, 0.0, 0.0, 0.0, 0.0, 0.03756984, 0.08652625, 0.1476709, 0.221864,
77              0.308222, 0.4053179, 0.509588, 0.6168328, 0.7209891, 0.816061, 0.8952581, 
78              0.953189, 0.985056, 1.0 ]
79    if llm==26:
80        ap_l=[0.002194067, 0.004895209, 0.009882418, 0.01805201, 0.02983724, 0.04462334, 0.06160587, 
81               0.07851243, 0.07731271, 0.07590131, 0.07424086, 0.07228744, 0.06998933, 0.06728574, 0.06410509, 
82               0.06036322, 0.05596111, 0.05078225, 0.04468960, 0.03752191, 0.02908949, 0.02084739, 0.01334443, 
83               0.00708499, 0.00252136, 0.0, 0.0 ]
84        bp_l=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01505309, 0.03276228, 0.05359622, 
85                0.07810627, 0.1069411, 0.1408637, 0.1807720, 0.2277220, 0.2829562, 0.3479364, 0.4243822, 
86                0.5143168, 0.6201202, 0.7235355, 0.8176768, 0.8962153, 0.9534761, 0.9851122, 1.0 ]
87
88    ap_l, bp_l = ref_press*np.asarray(ap_l[-1::-1]), bp_l[-1::-1] # reverse indices
89    ptop = ap_l[-1] # pressure BC
90   
91    print ptop, ap_l, bp_l
92    ps_il,ap_il = np.meshgrid(ps_i,ap_l, indexing='ij')
93    ps_il,bp_il = np.meshgrid(ps_i,bp_l, indexing='ij')
94    hybrid_coefs = meshes.mass_coefs_from_pressure_coefs(g, ap_il, bp_il)
95    pb_il = ap_il + bp_il*ps_il
96    mass_ik, pb_ik = mesh.field_mass(), mesh.field_mass()
97    for l in range(llm):
98        pb_ik[:,l]=.5*(pb_il[:,l]+pb_il[:,l+1])
99        mass_ik[:,l]=(pb_il[:,l]-pb_il[:,l+1])/g
100    Tb_ik = T_0 + 0.*pb_ik
101    gas = thermo.set_pT(pb_ik,Tb_ik)
102    Sik  = gas.s*mass_ik
103# start at hydrostatic geopotential
104    Phi_il = mesh.field_w()
105    Phi_il[:,0]=Phis_i
106    for l in range(llm):
107        Phi_il[:,l+1] = Phi_il[:,l] + g*mass_ik[:,l]*gas.v[:,l]
108
109    ujk, Wil = mesh.ucov3D(ulon(lat_ek),ulat(lat_ek)), mesh.field_w()
110   
111    print 'ztop (m) = ', Phi_il[0,-1]/g
112    print 'ptop (Pa) = ', gas.p[0,-1], ptop
113    dx=mesh.de.min()
114    params=dyn.Struct()
115    params.g, params.ptop = g, ptop
116    params.dx, params.dx_g0 = dx, dx/g
117    params.pbot, params.rho_bot = 1e5+0.*mesh.lat_i, 1e6+0.*mesh.lat_i
118    return thermo, mesh, hybrid_coefs, params, (mass_ik,Sik,ujk,Phi_il,Wil), gas
119
120
121#------------------------ main program -------------------------
122
123#grid, llm = 40962, 26
124nqtot, llm, grid = 1, 26, 2562
125T, Nslice, courant = 14400, 24, 3.0
126caldyn_thermo, caldyn_eta = unst.thermo_entropy, unst.eta_lag
127#caldyn_thermo, caldyn_eta = unst.thermo_entropy, unst.eta_mass
128thermo, mesh, hybrid_coefs, params, flow0, gas0 = DCMIP2008c5(grid,llm)
129llm, dx = mesh.llm, params.dx
130print 'llm, nb_hex, dx =', llm, mesh.Ai.size, dx
131if caldyn_eta == unst.eta_lag:
132    print 'Lagrangian coordinate.'
133else:
134    print 'Mass-based coordinate.'
135
136unst.ker.dynamico_init_hybrid(*hybrid_coefs)
137   
138dt = courant*.5*dx/np.sqrt(gas0.c2.max())
139
140nt = int(math.ceil(T/dt))
141dt = T/nt
142print 'Time step : %g s' % dt
143
144#mesh.plot_e(mesh.le/mesh.de) ; plt.title('le/de')
145#plt.savefig('fig_DCMIP2008c5/le_de.png'); plt.close()
146
147#mesh.plot_i(mesh.Ai) ; plt.title('Ai')
148#plt.savefig('fig_DCMIP2008c5/Ai.png'); plt.close()
149
150scheme = time_step.ARK2(None, dt, a32=0.7)
151caldyn_step = unst.caldyn_step_HPE(mesh,scheme,nt, caldyn_thermo,caldyn_eta, thermo,params,params.g)
152def next_flow(m,S,u):
153    caldyn_step.mass[:,:], caldyn_step.theta_rhodz[:,:], caldyn_step.u[:,:] = m,S,u
154    caldyn_step.remap()
155    caldyn_step.next()
156    return (caldyn_step.mass.copy(), caldyn_step.theta_rhodz.copy(), 
157            caldyn_step.u.copy(), caldyn_step.geopot.copy())
158
159def plots(it):
160    s=S/m
161    for l in range(llm):
162        z[:,l]=.5*(Phi[:,l+1]+Phi[:,l])/params.g
163        vol[:,l]=(Phi[:,l+1]-Phi[:,l])/params.g/m[:,l] # specific volume
164    gas = thermo.set_vs(vol, s)
165    s=.5*(s+abs(s))
166    t = (it*T)/3600
167    print( 'ptop, model top (m) :', unst.getvar('ptop'), Phi.max()/unst.getvar('g') )
168    mesh.plot_i(gas.T[:,llm/2])
169    plt.title('T at t=%dh'%(t))
170    plt.savefig('fig_DCMIP2008c5/T%02d.png'%it)
171    plt.close()
172
173    mesh.plot_i(m[:,llm/2])
174    plt.title('mass at t=%dh'%(t))
175    plt.savefig('fig_DCMIP2008c5/m%02d.png'%it)
176    plt.close()
177
178    mesh.plot_i(Phi[:,0])
179    plt.title('Surface geopotential at t=%dh'%(t))
180    plt.savefig('fig_DCMIP2008c5/Phis%02d.png'%it)
181    plt.close()
182
183z, vol = mesh.field_mass(), mesh.field_mass()
184m,S,u,Phi,W = flow0
185caldyn_step.geopot[:,0]=Phi[:,0]
186#plots(0)
187
188context=xios.XIOS_Context(mesh.pmesh,mesh,nqtot, T)
189
190for it in range(Nslice):
191    context.update_calendar(it)
192    unst.setvar('debug_hevi_solver',False)
193    time1, elapsed1 =time.time(), unst.getvar('elapsed')
194    m,S,u,Phi = next_flow(m,S,u)
195    time2, elapsed2 = time.time(), unst.getvar('elapsed')
196    factor = 1000./nt
197    print 'ms per full time step : ', factor*(time2-time1), factor*(elapsed2-elapsed1)
198    factor = 1e9/(4*nt*m.size)
199    print 'nanosec per gridpoint per call to caldyn_hevi : ', factor*(time2-time1), factor*(elapsed2-elapsed1)
200   
201    s=S/m
202    s=.5*(s+abs(s))
203    for l in range(llm):
204        z[:,l]=.5*(Phi[:,l+1]+Phi[:,l])/params.g
205        vol[:,l]=(Phi[:,l+1]-Phi[:,l])/params.g/m[:,l] # specific volume
206    gas = thermo.set_vs(vol, s)
207    ss = np.asarray(gas.T, dtype=np.double)
208    context.send_field_primal('theta', ss)
209    #plots(it+1)
210
211print 'xios.context_finalize()'
212context.finalize()
213print 'xios.finalize()'
214xios.finalize()
215print 'Done'
Note: See TracBrowser for help on using the repository browser.