1 | #!/usr/bin/env python3 |
---|
2 | |
---|
3 | import math |
---|
4 | import pyoasis |
---|
5 | from pyoasis import OASIS |
---|
6 | import numpy as np |
---|
7 | import netCDF4 |
---|
8 | from mpi4py import MPI |
---|
9 | from utils import * |
---|
10 | |
---|
11 | try: |
---|
12 | import cartopy |
---|
13 | import cartopy.crs as ccrs |
---|
14 | import matplotlib.pyplot as plt |
---|
15 | import matplotlib.collections |
---|
16 | from matplotlib.colors import ListedColormap |
---|
17 | import os |
---|
18 | has_graphics = True |
---|
19 | except ImportError: |
---|
20 | has_graphics = False |
---|
21 | |
---|
22 | |
---|
23 | def caramelbleucm(): |
---|
24 | if not has_graphics: |
---|
25 | return |
---|
26 | rcol = np.hstack((np.linspace(0.1, 0.0, 30 - 0 + 1)[:-1], |
---|
27 | np.linspace(0.0, 0.8, 47 - 30 + 1)[:-1], |
---|
28 | np.linspace(0.8, 1.0, 52 - 47 + 1)[:-1], |
---|
29 | np.linspace(1.0, 1.0, 70 - 52 + 1)[:-1], |
---|
30 | np.linspace(1.0, 1.0, 100 - 70 + 1))) |
---|
31 | gcol = np.hstack((np.linspace(0.1, 0.9, 30 - 0 + 1)[:-1], |
---|
32 | np.linspace(0.9, 1.0, 47 - 30 + 1)[:-1], |
---|
33 | np.linspace(1.0, 1.0, 52 - 47 + 1)[:-1], |
---|
34 | np.linspace(1.0, 0.9, 70 - 52 + 1)[:-1], |
---|
35 | np.linspace(0.9, 0.1, 100 - 70 + 1))) |
---|
36 | bcol = np.hstack((np.linspace(1.0, 1.0, 30 - 0 + 1)[:-1], |
---|
37 | np.linspace(1.0, 1.0, 47 - 30 + 1)[:-1], |
---|
38 | np.linspace(1.0, 0.8, 52 - 47 + 1)[:-1], |
---|
39 | np.linspace(0.8, 0.0, 70 - 52 + 1)[:-1], |
---|
40 | np.linspace(0.0, 0.1, 100 - 70 + 1))) |
---|
41 | alph = np.linspace(1.0, 1.0, 101) |
---|
42 | |
---|
43 | cm = np.array((np.transpose(rcol), np.transpose(gcol), |
---|
44 | np.transpose(bcol), np.transpose(alph))) |
---|
45 | cm = np.transpose(cm) |
---|
46 | newmap = ListedColormap(cm, name='CaramelBleu') |
---|
47 | return newmap |
---|
48 | |
---|
49 | |
---|
50 | comm = MPI.COMM_WORLD |
---|
51 | |
---|
52 | has_graphics = comm.bcast(has_graphics, root=comm.rank) |
---|
53 | |
---|
54 | dgrid = None |
---|
55 | dgrid = comm.bcast(dgrid, root=0) |
---|
56 | ll_plot = False |
---|
57 | ll_plot = comm.bcast(ll_plot, root=0) |
---|
58 | |
---|
59 | gf = netCDF4.Dataset('grids.nc', 'r') |
---|
60 | lons = gf.variables[dgrid + '.lon'][:, :].flatten() |
---|
61 | lats = gf.variables[dgrid + '.lat'][:, :].flatten() |
---|
62 | n_points = lons.size |
---|
63 | dgrid_corners = len(gf.dimensions['crn_' + dgrid]) |
---|
64 | dlon = gf.variables[dgrid + '.clo'][:].reshape(dgrid_corners, -1) |
---|
65 | dlon = np.where(dlon > 180, dlon - 360, dlon) |
---|
66 | dlat = gf.variables[dgrid + '.cla'][:].reshape(dgrid_corners, -1) |
---|
67 | lonspan = np.abs(np.max(dlon, axis=0) - np.min(dlon, axis=0)) |
---|
68 | for i, span in enumerate(lonspan): |
---|
69 | if span > 180: |
---|
70 | if np.mean(dlon[:, i]) > 0.: |
---|
71 | dlon[:, i] = np.where(dlon[:, i] < 0, dlon[:, i] + 360, dlon[:, i]) |
---|
72 | else: |
---|
73 | dlon[:, i] = np.where(dlon[:, i] > 0, dlon[:, i] - 360, dlon[:, i]) |
---|
74 | gf.close() |
---|
75 | |
---|
76 | mf = netCDF4.Dataset('masks.nc', 'r') |
---|
77 | msi = mf.variables[dgrid + '.msk'][:].flatten() |
---|
78 | da_msk = msi == 1 |
---|
79 | mf.close() |
---|
80 | |
---|
81 | da_lonlat = np.transpose(np.array([dlon, dlat])) |
---|
82 | da_lonlat = np.delete(da_lonlat, np.where(da_msk), axis=0) |
---|
83 | |
---|
84 | component_name = "receiver" |
---|
85 | comp = pyoasis.Component(component_name, True, comm) |
---|
86 | |
---|
87 | print(comp, flush=True) |
---|
88 | print("n_points on destination side is {}".format(n_points), flush=True) |
---|
89 | |
---|
90 | partition = pyoasis.SerialPartition(n_points) |
---|
91 | |
---|
92 | variable = pyoasis.Var("FRECVANA", partition, OASIS.IN, bundle_size=2) |
---|
93 | comp.enddef() |
---|
94 | |
---|
95 | date = int(0) |
---|
96 | |
---|
97 | field = pyoasis.asarray(np.zeros((n_points, 2))) |
---|
98 | |
---|
99 | variable.get(date, field) |
---|
100 | |
---|
101 | print('Receiver: shape of received field', field.shape) |
---|
102 | field = np.delete(field, np.where(da_msk), axis=0) |
---|
103 | |
---|
104 | dp_conv = math.pi / 180. |
---|
105 | expected_field1 = 2.0 + np.sin(2.0 * lats * dp_conv) ** 4.0 * \ |
---|
106 | np.cos(4.0 * lons * dp_conv) |
---|
107 | |
---|
108 | expected_field1 = np.delete(expected_field1, np.where(da_msk)) |
---|
109 | |
---|
110 | expected_field2 = 2.0 - np.cos(math.pi * |
---|
111 | (np.arccos(np.cos(lons * dp_conv) * |
---|
112 | np.cos(lats * dp_conv)) / |
---|
113 | (1.2 * math.pi))) |
---|
114 | |
---|
115 | expected_field2 = np.delete(expected_field2, np.where(da_msk)) |
---|
116 | |
---|
117 | expected_field = np.array([expected_field1, expected_field2]).transpose() |
---|
118 | |
---|
119 | error = np.average(np.abs((field - expected_field)/expected_field)) |
---|
120 | print("Average relative error is {}".format(error)) |
---|
121 | if error < 1.e-3: |
---|
122 | print("Data received successfully at time {}".format(date)) |
---|
123 | |
---|
124 | if not (has_graphics and ll_plot): |
---|
125 | exit() |
---|
126 | |
---|
127 | cartopy.config['data_dir'] = os.path.join('.', 'cartopy') |
---|
128 | |
---|
129 | for img in range(2): |
---|
130 | ti_str = "Test interpolation with PyOASIS\nBundle field {}".format(img + 1) |
---|
131 | |
---|
132 | fig = plt.figure(img, figsize=(8.25, 11.75), frameon=True) |
---|
133 | plt.suptitle(ti_str) |
---|
134 | cmap = caramelbleucm() |
---|
135 | |
---|
136 | sd_proj = ccrs.PlateCarree() |
---|
137 | sd_lwdt = 0.0 |
---|
138 | |
---|
139 | di_ax = plt.subplot(211, projection=sd_proj) |
---|
140 | di_ax.set_global() |
---|
141 | di_ax.coastlines(resolution='110m', linewidth=0.5) |
---|
142 | |
---|
143 | di_pc = matplotlib.collections.PolyCollection(da_lonlat) |
---|
144 | di_pc.set_array(np.array(field[..., img])) |
---|
145 | di_pc.set_cmap(cmap) |
---|
146 | |
---|
147 | di_ax.add_collection(di_pc) |
---|
148 | di_gl = di_ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, |
---|
149 | linewidth=sd_lwdt, linestyle=':', color='gray') |
---|
150 | di_gl.top_labels = False |
---|
151 | di_gl.right_labels = False |
---|
152 | di_ax.set_title('Interpolated function on {} grid'.format(grid_longname(dgrid))) |
---|
153 | fig.colorbar(di_pc, ax=di_ax, shrink=.7) |
---|
154 | |
---|
155 | da_ax = plt.subplot(212, projection=sd_proj) |
---|
156 | da_ax.set_global() |
---|
157 | da_ax.coastlines(resolution='110m', linewidth=0.5) |
---|
158 | |
---|
159 | da_pc = matplotlib.collections.PolyCollection(da_lonlat) |
---|
160 | da_pc.set_array(np.array(expected_field[..., img])) |
---|
161 | da_pc.set_cmap(cmap) |
---|
162 | |
---|
163 | da_ax.add_collection(da_pc) |
---|
164 | da_gl = da_ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, |
---|
165 | linewidth=sd_lwdt, linestyle=':', color='gray') |
---|
166 | da_gl.top_labels = False |
---|
167 | da_gl.right_labels = False |
---|
168 | da_ax.set_title('Analytical function on {} grid'.format(grid_longname(dgrid))) |
---|
169 | fig.colorbar(da_pc, ax=da_ax, shrink=.7) |
---|
170 | |
---|
171 | plt.subplots_adjust(left=0.10, right=1.00, wspace=0.05, hspace=0.) |
---|
172 | |
---|
173 | plt.show() |
---|
174 | |
---|
175 | del comp |
---|