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

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

devel/unstructured : use command line parameters for test case DCMIP2008c5

File size: 10.7 KB
Line 
1# apparently we should initialize MPI before doing anything else
2from mpi4py import MPI
3comm = MPI.COMM_WORLD
4mpi_rank, mpi_size = comm.Get_rank(), comm.Get_size()
5print '%d/%d starting'%(mpi_rank,mpi_size)
6
7# now start doing something useful
8from dynamico import unstructured as unst
9from dynamico import dyn
10from dynamico import time_step
11from dynamico import DCMIP
12from dynamico import meshes
13#import dynamico.xios as xios
14
15import math as math
16import matplotlib.pyplot as plt
17import numpy as np
18import time
19import argparse
20
21#------------------------ initial condition -------------------------
22
23# Parameters for the simulation
24g              = 9.80616   # gravitational acceleration in meters per second squared
25omega          = 7.29211e-5  # Earth's angular velocity in radians per second
26f0             = 2.0*omega   # Coriolis parameter
27u_0            = 20.0        # velocity in meters per second
28T_0            = 288.0       # temperature in Kelvin
29d2             = 1.5e6**2    # square of half width of Gaussian mountain profile in meters
30h_0            = 2.0e3       # mountain height in meters
31lon_c          = np.pi/2.0   # mountain peak longitudinal location in radians
32lat_c          = np.pi/6.0   # mountain peak latitudinal location in radians
33radius         = 6.371229e6  # mean radius of the Earth in meters
34ref_press      = 100145.6    # reference pressure (mean surface pressure) in Pascals
35ref_surf_press = 930.0e2     # South Pole surface pressure in Pascals
36Rd             = 287.04      # ideal gas constant for dry air in joules per kilogram Kelvin
37Cpd            = 1004.64     # specific heat at constant pressure in joules per kilogram Kelvin
38kappa          = Rd/Cpd      # kappa=R_d/c_p
39N_freq         = np.sqrt(g**2/(Cpd*T_0)) # Brunt-Vaisala buoyancy frequency
40N2, g2kappa = N_freq**2, g*g*kappa
41
42def DCMIP2008c5(grid,llm):
43    def Phis(lon,lat): 
44        rgrc = radius*np.arccos(np.sin(lat_c)*np.sin(lat)+np.cos(lat_c)*np.cos(lat)*np.cos(lon-lon_c))
45        return g*h_0*np.exp(-rgrc**2/d2)
46    def ps(lon, lat, Phis): 
47        return ref_surf_press * np.exp(
48            - radius*N2*u_0/(2.0*g2kappa)*(u_0/radius+f0)*(np.sin(lat)**2-1.)
49            - N2/(g2kappa)*Phis )
50    def ulon(lat): return u_0*np.cos(lat)
51    def ulat(lat): return 0.*lat
52    def f(lon,lat): return f0*np.sin(lat) # Coriolis parameter
53
54    nqdyn, preff, Treff = 1, 1e5, 300.
55    thermo = dyn.Ideal_perfect(Cpd, Rd, preff, Treff)
56
57    meshfile = meshes.MPAS_Format('grids/x1.%d.grid.nc'%grid)
58#    mesh = meshes.Unstructured_Mesh(meshfile, llm, nqdyn, radius, f)
59    pmesh = meshes.Unstructured_PMesh(comm,meshfile)
60    mesh = meshes.Local_Mesh(pmesh, llm, nqdyn, radius, f)
61    mesh.pmesh=pmesh
62
63    lev,levp1 = np.arange(llm),np.arange(llm+1)
64    lon_i, lat_i, lon_e, lat_e =  mesh.lon_i, mesh.lat_i, mesh.lon_e, mesh.lat_e
65    lat_ik,k_i = np.meshgrid(mesh.lat_i,lev, indexing='ij')
66    lon_ik,k_i = np.meshgrid(mesh.lon_i,lev, indexing='ij')
67    lat_il,l_i = np.meshgrid(mesh.lat_i,levp1, indexing='ij')           
68    lon_il,l_i = np.meshgrid(mesh.lon_i,levp1, indexing='ij')
69    lat_ek,k_e = np.meshgrid(mesh.lat_e,lev, indexing='ij')
70
71    Phis_i = Phis(lon_i, lat_i)
72    ps_i = ps(lon_i, lat_i, Phis_i)
73
74    if llm==18:
75        ap_l=[0.00251499, 0.00710361, 0.01904260, 0.04607560, 0.08181860,
76              0.07869805, 0.07463175, 0.06955308, 0.06339061, 0.05621774, 0.04815296,
77              0.03949230, 0.03058456, 0.02193336, 0.01403670, 0.007458598, 0.002646866,
78              0.0, 0.0 ]
79        bp_l=[0.0, 0.0, 0.0, 0.0, 0.0, 0.03756984, 0.08652625, 0.1476709, 0.221864,
80              0.308222, 0.4053179, 0.509588, 0.6168328, 0.7209891, 0.816061, 0.8952581, 
81              0.953189, 0.985056, 1.0 ]
82    if llm==26:
83        ap_l=[0.002194067, 0.004895209, 0.009882418, 0.01805201, 0.02983724, 0.04462334, 0.06160587, 
84               0.07851243, 0.07731271, 0.07590131, 0.07424086, 0.07228744, 0.06998933, 0.06728574, 0.06410509, 
85               0.06036322, 0.05596111, 0.05078225, 0.04468960, 0.03752191, 0.02908949, 0.02084739, 0.01334443, 
86               0.00708499, 0.00252136, 0.0, 0.0 ]
87        bp_l=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01505309, 0.03276228, 0.05359622, 
88                0.07810627, 0.1069411, 0.1408637, 0.1807720, 0.2277220, 0.2829562, 0.3479364, 0.4243822, 
89                0.5143168, 0.6201202, 0.7235355, 0.8176768, 0.8962153, 0.9534761, 0.9851122, 1.0 ]
90    if llm==49:
91        ap_l=[0.002251865, 0.003983890, 0.006704364, 0.01073231, 0.01634233, 0.02367119, 
92              0.03261456, 0.04274527, 0.05382610, 0.06512175, 0.07569850, 0.08454283, 
93              0.08396310, 0.08334103, 0.08267352, 0.08195725, 0.08118866, 0.08036393, 
94              0.07947895, 0.07852934, 0.07751036, 0.07641695, 0.07524368, 0.07398470, 
95              0.07263375, 0.07118414, 0.06962863, 0.06795950, 0.06616846, 0.06424658, 
96              0.06218433, 0.05997144, 0.05759690, 0.05504892, 0.05231483, 0.04938102, 
97              0.04623292, 0.04285487, 0.03923006, 0.03534049, 0.03116681, 0.02668825, 
98              0.02188257, 0.01676371, 0.01208171, 0.007959612, 0.004510297, 0.001831215, 
99              0.0, 0.0 ]
100        bp_l=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
101              0.006755112, 0.01400364, 0.02178164, 0.03012778, 0.03908356, 0.04869352, 
102              0.05900542, 0.07007056, 0.08194394, 0.09468459, 0.1083559, 0.1230258, 
103              0.1387673, 0.1556586, 0.1737837, 0.1932327, 0.2141024, 0.2364965, 
104              0.2605264, 0.2863115, 0.3139801, 0.3436697, 0.3755280, 0.4097133, 
105              0.4463958, 0.4857576, 0.5279946, 0.5733168, 0.6219495, 0.6741346, 
106              0.7301315, 0.7897776, 0.8443334, 0.8923650, 0.9325572, 0.9637744, 
107              0.9851122, 1.0]
108
109    ap_l, bp_l = ref_press*np.asarray(ap_l[-1::-1]), bp_l[-1::-1] # reverse indices
110    ptop = ap_l[-1] # pressure BC
111   
112    if mpi_rank==0: print ptop, ap_l, bp_l
113    ps_il,ap_il = np.meshgrid(ps_i,ap_l, indexing='ij')
114    ps_il,bp_il = np.meshgrid(ps_i,bp_l, indexing='ij')
115    hybrid_coefs = meshes.mass_coefs_from_pressure_coefs(g, ap_il, bp_il)
116    pb_il = ap_il + bp_il*ps_il
117    mass_ik, pb_ik = mesh.field_mass(), mesh.field_mass()
118    for l in range(llm):
119        pb_ik[:,l]=.5*(pb_il[:,l]+pb_il[:,l+1])
120        mass_ik[:,l]=(pb_il[:,l]-pb_il[:,l+1])/g
121    Tb_ik = T_0 + 0.*pb_ik
122    gas = thermo.set_pT(pb_ik,Tb_ik)
123    Sik  = gas.s*mass_ik
124# start at hydrostatic geopotential
125    Phi_il = mesh.field_w()
126    Phi_il[:,0]=Phis_i
127    for l in range(llm):
128        Phi_il[:,l+1] = Phi_il[:,l] + g*mass_ik[:,l]*gas.v[:,l]
129
130    ujk, Wil = mesh.ucov3D(ulon(lat_ek),ulat(lat_ek)), mesh.field_w()
131   
132    if mpi_rank==0: 
133        print 'ztop (m) = ', Phi_il[0,-1]/g
134        print 'ptop (Pa) = ', gas.p[0,-1], ptop
135    dx=mesh.de.min()
136    params=dyn.Struct()
137    params.g, params.ptop = g, ptop
138    params.dx, params.dx_g0 = dx, dx/g
139    params.pbot, params.rho_bot = 1e5+0.*mesh.lat_i, 1e6+0.*mesh.lat_i
140    return thermo, mesh, hybrid_coefs, params, (mass_ik,Sik,ujk,Phi_il,Wil), gas
141
142#------------------------ main program -------------------------
143
144unst.setvar('dynamico_mpi_rank', mpi_rank)
145
146parser = argparse.ArgumentParser()
147parser.add_argument("-r", "--refinement", type=int, 
148                    default=5, choices=[4, 5, 6, 7],
149                    help="grid refinement level")
150parser.add_argument("-l", "--llm", type=int, 
151                    default=49, choices=[18, 26, 49],
152                    help="number of vertical levels")
153args = parser.parse_args()
154nqtot, llm, grid = 1, args.llm, 2+10*(4**args.refinement)
155#nqtot, llm, grid = 1,26,40962
156
157T, Nslice, courant = 14400, 24, 3.0
158caldyn_thermo, caldyn_eta = unst.thermo_entropy, unst.eta_lag
159#caldyn_thermo, caldyn_eta = unst.thermo_entropy, unst.eta_mass
160
161thermo, mesh, hybrid_coefs, params, flow0, gas0 = DCMIP2008c5(grid,llm)
162llm, dx = mesh.llm, params.dx
163if mpi_rank==0: 
164    print 'grid, llm, local_gridsize, dx =', grid, llm, mesh.Ai.size, dx
165    if caldyn_eta == unst.eta_lag:
166        print 'Lagrangian coordinate.'
167    else:
168        print 'Mass-based coordinate.'
169
170unst.ker.dynamico_init_hybrid(*hybrid_coefs)
171   
172dt = courant*.5*dx/np.sqrt(gas0.c2.max())
173
174if False:
175    nt = int(math.ceil(T/dt))
176    dt = T/nt
177else:
178    nt=100
179if mpi_rank==0: print 'Time step : %g s' % dt
180
181#mesh.plot_e(mesh.le/mesh.de) ; plt.title('le/de')
182#plt.savefig('fig_DCMIP2008c5/le_de.png'); plt.close()
183
184#mesh.plot_i(mesh.Ai) ; plt.title('Ai')
185#plt.savefig('fig_DCMIP2008c5/Ai.png'); plt.close()
186
187scheme = time_step.ARK2(None, dt, a32=0.7)
188caldyn_step = unst.caldyn_step_HPE(mesh,scheme,nt, caldyn_thermo,caldyn_eta, thermo,params,params.g)
189
190def next_flow(m,S,u):
191    caldyn_step.mass[:,:], caldyn_step.theta_rhodz[:,:], caldyn_step.u[:,:] = m,S,u
192#    caldyn_step.remap()
193    caldyn_step.next()
194    return (caldyn_step.mass.copy(), caldyn_step.theta_rhodz.copy(), 
195            caldyn_step.u.copy(), caldyn_step.geopot.copy())
196
197def plots(it):
198    s=S/m
199    for l in range(llm):
200        z[:,l]=.5*(Phi[:,l+1]+Phi[:,l])/params.g
201        vol[:,l]=(Phi[:,l+1]-Phi[:,l])/params.g/m[:,l] # specific volume
202    gas = thermo.set_vs(vol, s)
203    s=.5*(s+abs(s))
204    t = (it*T)/3600
205    print( 'ptop, model top (m) :', unst.getvar('ptop'), Phi.max()/unst.getvar('g') )
206    mesh.plot_i(gas.T[:,llm/2])
207    plt.title('T at t=%dh'%(t))
208    plt.savefig('fig_DCMIP2008c5/T%02d.png'%it)
209    plt.close()
210
211    mesh.plot_i(m[:,llm/2])
212    plt.title('mass at t=%dh'%(t))
213    plt.savefig('fig_DCMIP2008c5/m%02d.png'%it)
214    plt.close()
215
216    mesh.plot_i(Phi[:,0])
217    plt.title('Surface geopotential at t=%dh'%(t))
218    plt.savefig('fig_DCMIP2008c5/Phis%02d.png'%it)
219    plt.close()
220
221z, vol = mesh.field_mass(), mesh.field_mass()
222m,S,u,Phi,W = flow0
223caldyn_step.geopot[:,0]=Phi[:,0]
224#plots(0)
225
226#context=xios.XIOS_Context(mesh.pmesh,mesh,nqtot, T)
227
228for it in range(Nslice):
229#    context.update_calendar(it)
230    unst.setvar('debug_hevi_solver',False)
231    time1, elapsed1 =time.time(), unst.getvar('elapsed')
232    m,S,u,Phi = next_flow(m,S,u)
233    time2, elapsed2 = time.time(), unst.getvar('elapsed')
234    if mpi_rank==0: 
235        factor = 1000./nt
236        print 'ms per full time step : ', factor*(time2-time1), factor*(elapsed2-elapsed1)
237        factor = 1e9/(4*nt*m.size)
238        print 'nanosec per gridpoint per call to caldyn_hevi : ', factor*(time2-time1), factor*(elapsed2-elapsed1)
239   
240    if False:
241        s=S/m
242        s=.5*(s+abs(s))
243        for l in range(llm):
244            z[:,l]=.5*(Phi[:,l+1]+Phi[:,l])/params.g
245            vol[:,l]=(Phi[:,l+1]-Phi[:,l])/params.g/m[:,l] # specific volume
246        gas = thermo.set_vs(vol, s)
247        ss = np.asarray(gas.T, dtype=np.double)
248        #    context.send_field_primal('theta', ss)
249        #plots(it+1)
250
251unst.ker.dynamico_print_trace()
252 
253#print 'xios.context_finalize()'
254#context.finalize()
255#print 'xios.finalize()'
256#xios.finalize()
257print 'MPI Rank %d Done'%mpi_rank
Note: See TracBrowser for help on using the repository browser.