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

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

devel/Python : block-wise partitioning

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    pmesh.partition_metis()
61    mesh = meshes.Local_Mesh(pmesh, llm, nqdyn, radius, f)
62    mesh.pmesh=pmesh
63
64    lev,levp1 = np.arange(llm),np.arange(llm+1)
65    lon_i, lat_i, lon_e, lat_e =  mesh.lon_i, mesh.lat_i, mesh.lon_e, mesh.lat_e
66    lat_ik,k_i = np.meshgrid(mesh.lat_i,lev, indexing='ij')
67    lon_ik,k_i = np.meshgrid(mesh.lon_i,lev, indexing='ij')
68    lat_il,l_i = np.meshgrid(mesh.lat_i,levp1, indexing='ij')           
69    lon_il,l_i = np.meshgrid(mesh.lon_i,levp1, indexing='ij')
70    lat_ek,k_e = np.meshgrid(mesh.lat_e,lev, indexing='ij')
71
72    Phis_i = Phis(lon_i, lat_i)
73    ps_i = ps(lon_i, lat_i, Phis_i)
74
75    if llm==18:
76        ap_l=[0.00251499, 0.00710361, 0.01904260, 0.04607560, 0.08181860,
77              0.07869805, 0.07463175, 0.06955308, 0.06339061, 0.05621774, 0.04815296,
78              0.03949230, 0.03058456, 0.02193336, 0.01403670, 0.007458598, 0.002646866,
79              0.0, 0.0 ]
80        bp_l=[0.0, 0.0, 0.0, 0.0, 0.0, 0.03756984, 0.08652625, 0.1476709, 0.221864,
81              0.308222, 0.4053179, 0.509588, 0.6168328, 0.7209891, 0.816061, 0.8952581, 
82              0.953189, 0.985056, 1.0 ]
83    if llm==26:
84        ap_l=[0.002194067, 0.004895209, 0.009882418, 0.01805201, 0.02983724, 0.04462334, 0.06160587, 
85               0.07851243, 0.07731271, 0.07590131, 0.07424086, 0.07228744, 0.06998933, 0.06728574, 0.06410509, 
86               0.06036322, 0.05596111, 0.05078225, 0.04468960, 0.03752191, 0.02908949, 0.02084739, 0.01334443, 
87               0.00708499, 0.00252136, 0.0, 0.0 ]
88        bp_l=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01505309, 0.03276228, 0.05359622, 
89                0.07810627, 0.1069411, 0.1408637, 0.1807720, 0.2277220, 0.2829562, 0.3479364, 0.4243822, 
90                0.5143168, 0.6201202, 0.7235355, 0.8176768, 0.8962153, 0.9534761, 0.9851122, 1.0 ]
91    if llm==49:
92        ap_l=[0.002251865, 0.003983890, 0.006704364, 0.01073231, 0.01634233, 0.02367119, 
93              0.03261456, 0.04274527, 0.05382610, 0.06512175, 0.07569850, 0.08454283, 
94              0.08396310, 0.08334103, 0.08267352, 0.08195725, 0.08118866, 0.08036393, 
95              0.07947895, 0.07852934, 0.07751036, 0.07641695, 0.07524368, 0.07398470, 
96              0.07263375, 0.07118414, 0.06962863, 0.06795950, 0.06616846, 0.06424658, 
97              0.06218433, 0.05997144, 0.05759690, 0.05504892, 0.05231483, 0.04938102, 
98              0.04623292, 0.04285487, 0.03923006, 0.03534049, 0.03116681, 0.02668825, 
99              0.02188257, 0.01676371, 0.01208171, 0.007959612, 0.004510297, 0.001831215, 
100              0.0, 0.0 ]
101        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, 
102              0.006755112, 0.01400364, 0.02178164, 0.03012778, 0.03908356, 0.04869352, 
103              0.05900542, 0.07007056, 0.08194394, 0.09468459, 0.1083559, 0.1230258, 
104              0.1387673, 0.1556586, 0.1737837, 0.1932327, 0.2141024, 0.2364965, 
105              0.2605264, 0.2863115, 0.3139801, 0.3436697, 0.3755280, 0.4097133, 
106              0.4463958, 0.4857576, 0.5279946, 0.5733168, 0.6219495, 0.6741346, 
107              0.7301315, 0.7897776, 0.8443334, 0.8923650, 0.9325572, 0.9637744, 
108              0.9851122, 1.0]
109
110    ap_l, bp_l = ref_press*np.asarray(ap_l[-1::-1]), bp_l[-1::-1] # reverse indices
111    ptop = ap_l[-1] # pressure BC
112   
113    if mpi_rank==0: print ptop, ap_l, bp_l
114    ps_il,ap_il = np.meshgrid(ps_i,ap_l, indexing='ij')
115    ps_il,bp_il = np.meshgrid(ps_i,bp_l, indexing='ij')
116    hybrid_coefs = meshes.mass_coefs_from_pressure_coefs(g, ap_il, bp_il)
117    pb_il = ap_il + bp_il*ps_il
118    mass_ik, pb_ik = mesh.field_mass(), mesh.field_mass()
119    for l in range(llm):
120        pb_ik[:,l]=.5*(pb_il[:,l]+pb_il[:,l+1])
121        mass_ik[:,l]=(pb_il[:,l]-pb_il[:,l+1])/g
122    Tb_ik = T_0 + 0.*pb_ik
123    gas = thermo.set_pT(pb_ik,Tb_ik)
124    Sik  = gas.s*mass_ik
125# start at hydrostatic geopotential
126    Phi_il = mesh.field_w()
127    Phi_il[:,0]=Phis_i
128    for l in range(llm):
129        Phi_il[:,l+1] = Phi_il[:,l] + g*mass_ik[:,l]*gas.v[:,l]
130
131    ujk, Wil = mesh.ucov3D(ulon(lat_ek),ulat(lat_ek)), mesh.field_w()
132   
133    if mpi_rank==0: 
134        print 'ztop (m) = ', Phi_il[0,-1]/g
135        print 'ptop (Pa) = ', gas.p[0,-1], ptop
136    dx=mesh.de.min()
137    params=dyn.Struct()
138    params.g, params.ptop = g, ptop
139    params.dx, params.dx_g0 = dx, dx/g
140    params.pbot, params.rho_bot = 1e5+0.*mesh.lat_i, 1e6+0.*mesh.lat_i
141    return thermo, mesh, hybrid_coefs, params, (mass_ik,Sik,ujk,Phi_il,Wil), gas
142
143#------------------------ main program -------------------------
144
145unst.setvar('dynamico_mpi_rank', mpi_rank)
146
147parser = argparse.ArgumentParser()
148parser.add_argument("-r", "--refinement", type=int, 
149                    default=5, choices=[4, 5, 6, 7],
150                    help="grid refinement level")
151parser.add_argument("-l", "--llm", type=int, 
152                    default=49, choices=[18, 26, 49],
153                    help="number of vertical levels")
154args = parser.parse_args()
155nqtot, llm, grid = 1, args.llm, 2+10*(4**args.refinement)
156#nqtot, llm, grid = 1,26,40962
157
158T, Nslice, courant = 14400, 24, 3.0
159caldyn_thermo, caldyn_eta = unst.thermo_entropy, unst.eta_lag
160#caldyn_thermo, caldyn_eta = unst.thermo_entropy, unst.eta_mass
161
162thermo, mesh, hybrid_coefs, params, flow0, gas0 = DCMIP2008c5(grid,llm)
163llm, dx = mesh.llm, params.dx
164if mpi_rank==0: 
165    print 'grid, llm, local_gridsize, dx =', grid, llm, mesh.Ai.size, dx
166    if caldyn_eta == unst.eta_lag:
167        print 'Lagrangian coordinate.'
168    else:
169        print 'Mass-based coordinate.'
170
171unst.ker.dynamico_init_hybrid(*hybrid_coefs)
172   
173dt = courant*.5*dx/np.sqrt(gas0.c2.max())
174
175if False:
176    nt = int(math.ceil(T/dt))
177    dt = T/nt
178else:
179    nt=100
180if mpi_rank==0: print 'Time step : %g s' % dt
181
182#mesh.plot_e(mesh.le/mesh.de) ; plt.title('le/de')
183#plt.savefig('fig_DCMIP2008c5/le_de.png'); plt.close()
184
185#mesh.plot_i(mesh.Ai) ; plt.title('Ai')
186#plt.savefig('fig_DCMIP2008c5/Ai.png'); plt.close()
187
188scheme = time_step.ARK2(None, dt, a32=0.7)
189caldyn_step = unst.caldyn_step_HPE(mesh,scheme,nt, caldyn_thermo,caldyn_eta, thermo,params,params.g)
190
191def next_flow(m,S,u):
192    caldyn_step.mass[:,:], caldyn_step.theta_rhodz[:,:], caldyn_step.u[:,:] = m,S,u
193#    caldyn_step.remap()
194    caldyn_step.next()
195    return (caldyn_step.mass.copy(), caldyn_step.theta_rhodz.copy(), 
196            caldyn_step.u.copy(), caldyn_step.geopot.copy())
197
198def plots(it):
199    s=S/m
200    for l in range(llm):
201        z[:,l]=.5*(Phi[:,l+1]+Phi[:,l])/params.g
202        vol[:,l]=(Phi[:,l+1]-Phi[:,l])/params.g/m[:,l] # specific volume
203    gas = thermo.set_vs(vol, s)
204    s=.5*(s+abs(s))
205    t = (it*T)/3600
206    print( 'ptop, model top (m) :', unst.getvar('ptop'), Phi.max()/unst.getvar('g') )
207    mesh.plot_i(gas.T[:,llm/2])
208    plt.title('T at t=%dh'%(t))
209    plt.savefig('fig_DCMIP2008c5/T%02d.png'%it)
210    plt.close()
211
212    mesh.plot_i(m[:,llm/2])
213    plt.title('mass at t=%dh'%(t))
214    plt.savefig('fig_DCMIP2008c5/m%02d.png'%it)
215    plt.close()
216
217    mesh.plot_i(Phi[:,0])
218    plt.title('Surface geopotential at t=%dh'%(t))
219    plt.savefig('fig_DCMIP2008c5/Phis%02d.png'%it)
220    plt.close()
221
222z, vol = mesh.field_mass(), mesh.field_mass()
223m,S,u,Phi,W = flow0
224caldyn_step.geopot[:,0]=Phi[:,0]
225#plots(0)
226
227#context=xios.XIOS_Context(mesh.pmesh,mesh,nqtot, T)
228
229for it in range(Nslice):
230#    context.update_calendar(it)
231    unst.setvar('debug_hevi_solver',False)
232    time1, elapsed1 =time.time(), unst.getvar('elapsed')
233    m,S,u,Phi = next_flow(m,S,u)
234    time2, elapsed2 = time.time(), unst.getvar('elapsed')
235    if mpi_rank==0: 
236        factor = 1000./nt
237        print 'ms per full time step : ', factor*(time2-time1), factor*(elapsed2-elapsed1)
238        factor = 1e9/(4*nt*m.size)
239        print 'nanosec per gridpoint per call to caldyn_hevi : ', factor*(time2-time1), factor*(elapsed2-elapsed1)
240   
241    if False:
242        s=S/m
243        s=.5*(s+abs(s))
244        for l in range(llm):
245            z[:,l]=.5*(Phi[:,l+1]+Phi[:,l])/params.g
246            vol[:,l]=(Phi[:,l+1]-Phi[:,l])/params.g/m[:,l] # specific volume
247        gas = thermo.set_vs(vol, s)
248        ss = np.asarray(gas.T, dtype=np.double)
249        #    context.send_field_primal('theta', ss)
250        #plots(it+1)
251
252unst.ker.dynamico_print_trace()
253 
254#print 'xios.context_finalize()'
255#context.finalize()
256#print 'xios.finalize()'
257#xios.finalize()
258print 'MPI Rank %d Done'%mpi_rank
Note: See TracBrowser for help on using the repository browser.