@@ -100,7 +100,7 @@ def remap_paolo(in_filename, base_mesh_filename, culled_mesh_filename,
100
100
map_culled_to_base_filename = None ):
101
101
"""
102
102
Remap the Paolo et al. (2023; https://doi.org/10.5194/tc-17-3409-2023)
103
- melt rates at 1 km resolution to an MPAS mesh
103
+ melt rates at ~2 km resolution to an MPAS mesh
104
104
105
105
Parameters
106
106
----------
@@ -163,8 +163,9 @@ def remap_paolo(in_filename, base_mesh_filename, culled_mesh_filename,
163
163
164
164
lx = np .abs (1e-3 * (x [- 1 ] - x [0 ])).values
165
165
ly = np .abs (1e-3 * (y [- 1 ] - y [0 ])).values
166
+ dx = np .abs (1e-3 * (x [1 ] - x [0 ])).values
166
167
167
- in_grid_name = f'{ lx } x{ ly } km_0.5km_Antarctic_stereo '
168
+ in_grid_name = f'{ lx :.1f } x{ ly :.1f } km_ { dx :.3f } km_Antarctic_stereo '
168
169
169
170
projection = pyproj .Proj ('+proj=stere +lat_ts=-71.0 +lat_0=-90 +lon_0=0.0 '
170
171
'+k_0=1.0 +x_0=0.0 +y_0=0.0 +ellps=WGS84' )
@@ -174,6 +175,32 @@ def remap_paolo(in_filename, base_mesh_filename, culled_mesh_filename,
174
175
projection = projection , x = x .values , y = y .values , meshName = in_grid_name )
175
176
logger .info ('done.' )
176
177
178
+ out_descriptor = MpasCellMeshDescriptor (base_mesh_filename , mesh_name )
179
+
180
+ mapping_filename = \
181
+ f'{ mapping_directory } /map_{ in_grid_name } _to_{ mesh_name } _base.nc'
182
+
183
+ logger .info (f'Creating the mapping file { mapping_filename } ...' )
184
+ remapper = Remapper (in_descriptor , out_descriptor , mapping_filename )
185
+
186
+ remapper .build_mapping_file (method = method , mpiTasks = mpi_tasks ,
187
+ tempdir = mapping_directory , logger = logger ,
188
+ esmf_parallel_exec = parallel_executable ,
189
+ include_logs = True )
190
+ logger .info ('done.' )
191
+
192
+ dx = np .abs (in_descriptor .xCorner [1 :] - in_descriptor .xCorner [:- 1 ])
193
+ dy = np .abs (in_descriptor .yCorner [1 :] - in_descriptor .yCorner [:- 1 ])
194
+ dx , dy = np .meshgrid (dx , dy )
195
+ planar_area = xr .DataArray (dims = ('y' , 'x' ), data = dx * dy )
196
+
197
+ with xr .open_dataset (mapping_filename ) as ds_map :
198
+ earth_radius = constants ['SHR_CONST_REARTH' ]
199
+ map_src_area = ds_map .area_a .values * earth_radius ** 2
200
+ map_dst_area = ds_map .area_b .values * earth_radius ** 2
201
+ sphere_area = xr .DataArray (
202
+ dims = ('y' , 'x' ), data = map_src_area .reshape (planar_area .shape ))
203
+
177
204
logger .info ('Creating the source xarray dataset...' )
178
205
ds = xr .Dataset ()
179
206
@@ -185,9 +212,15 @@ def remap_paolo(in_filename, base_mesh_filename, culled_mesh_filename,
185
212
latent_heat_of_fusion = constants ['SHR_CONST_LATICE' ]
186
213
ds ['x' ] = x
187
214
ds ['y' ] = y
188
- field = 'dataLandIceFreshwaterFlux'
215
+ area_ratio = planar_area / sphere_area
216
+ logger .info (f'min projected area ratio: { area_ratio .min ().values } ' )
217
+ logger .info (f'max projected area ratio: { area_ratio .max ().values } ' )
218
+ logger .info ('' )
219
+
189
220
# original field is negative for melt
190
- ds [field ] = - melt_rate * rho_ice / s_per_yr
221
+ fwf = - melt_rate * rho_ice / s_per_yr
222
+ field = 'dataLandIceFreshwaterFlux'
223
+ ds [field ] = area_ratio * fwf
191
224
ds [field ].attrs ['units' ] = 'kg m^-2 s^-1'
192
225
field = 'dataLandIceHeatFlux'
193
226
ds [field ] = (latent_heat_of_fusion *
@@ -196,24 +229,47 @@ def remap_paolo(in_filename, base_mesh_filename, culled_mesh_filename,
196
229
logger .info ('Writing the source dataset...' )
197
230
write_netcdf (ds , 'Paolo_2023_ismf_1992-2017_v1.0.nc' )
198
231
logger .info ('done.' )
232
+ logger .info ('' )
199
233
200
- out_descriptor = MpasCellMeshDescriptor (base_mesh_filename , mesh_name )
234
+ planar_flux = (fwf * planar_area ).sum ().values
235
+ sphere_flux = (ds .dataLandIceFreshwaterFlux * sphere_area ).sum ().values
201
236
202
- mapping_filename = \
203
- f'{ mapping_directory } /map_{ in_grid_name } _to_{ mesh_name } _base.nc'
204
-
205
- logger .info (f'Creating the mapping file { mapping_filename } ...' )
206
- remapper = Remapper (in_descriptor , out_descriptor , mapping_filename )
207
-
208
- remapper .build_mapping_file (method = method , mpiTasks = mpi_tasks ,
209
- tempdir = mapping_directory , logger = logger ,
210
- esmf_parallel_exec = parallel_executable )
211
- logger .info ('done.' )
237
+ logger .info (f'Area of a cell (m^2): { planar_area [0 ,0 ]:.1f} ' )
238
+ logger .info (f'Total flux on plane (kg/s): { planar_flux :.1f} ' )
239
+ logger .info (f'Total flux on sphere (kg/s): { sphere_flux :.1f} ' )
240
+ logger .info ('' )
212
241
213
242
logger .info ('Remapping...' )
214
243
ds_remap = remapper .remap (
215
244
ds , renormalizationThreshold = renormalization_threshold )
216
245
logger .info ('done.' )
246
+ logger .info ('' )
247
+
248
+ with xr .open_dataset (base_mesh_filename ) as ds_mesh :
249
+ mpas_area_cell = ds_mesh .areaCell
250
+ sphere_area_cell = xr .DataArray (
251
+ dims = ('nCells' ,), data = map_dst_area )
252
+
253
+ area_ratio = sphere_area_cell / mpas_area_cell
254
+ logger .info (f'min MPAS area ratio: { area_ratio .min ().values } ' )
255
+ logger .info (f'max MPAS area ratio: { area_ratio .max ().values } ' )
256
+ logger .info ('' )
257
+
258
+ sphere_fwf = ds_remap .dataLandIceFreshwaterFlux
259
+
260
+ field = 'dataLandIceFreshwaterFlux'
261
+ ds_remap [field ] = area_ratio * sphere_fwf
262
+ ds_remap [field ].attrs ['units' ] = 'kg m^-2 s^-1'
263
+ field = 'dataLandIceHeatFlux'
264
+ ds_remap [field ] = area_ratio * ds_remap [field ]
265
+ ds_remap [field ].attrs ['units' ] = 'W m^-2'
266
+
267
+ mpas_flux = (ds_remap .dataLandIceFreshwaterFlux *
268
+ mpas_area_cell ).sum ().values
269
+ sphere_flux = (sphere_fwf * sphere_area_cell ).sum ().values
270
+
271
+ logger .info (f'Total flux w/ MPAS area (kg/s): { mpas_flux :.1f} ' )
272
+ logger .info (f'Total flux w/ sphere area (kg/s): { sphere_flux :.1f} ' )
217
273
218
274
if map_culled_to_base_filename is None :
219
275
map_culled_to_base_filename = 'map_culled_to_base.nc'
@@ -436,11 +492,11 @@ def _reroute_missing_flux(base_mesh_filename, map_culled_to_base_filename,
436
492
count = np .sum (reroute_mask .values )
437
493
logger .info (f'Rerouting fluxes from { count } cells' )
438
494
fwf_land_ice = (land_ice_mask * fwf * area ).sum ().values
439
- logger .info (f'Captured flux (kg/s): { fwf_land_ice :.1f} ' )
495
+ logger .info (f'Captured flux (kg/s): { fwf_land_ice :.1f} ' )
440
496
fwf_rerouted = fw_mass_rerouted .sum ().values
441
- logger .info (f'Rerouted flux (kg/s): { fwf_rerouted :.1f} ' )
497
+ logger .info (f'Rerouted flux (kg/s): { fwf_rerouted :.1f} ' )
442
498
fwf_total = (fwf * area ).sum ().values
443
- logger .info (f'Total flux (kg/s): { fwf_total :.1f} ' )
499
+ logger .info (f'Total flux (kg/s): { fwf_total :.1f} ' )
444
500
ds_to_route = xr .Dataset ()
445
501
ds_to_route ['rerouteMask' ] = reroute_mask
446
502
write_netcdf (ds_to_route , 'route_mask.nc' )
@@ -481,4 +537,5 @@ def _reroute_missing_flux(base_mesh_filename, map_culled_to_base_filename,
481
537
482
538
fwf_total = (ds_out .dataLandIceFreshwaterFlux *
483
539
area .isel (nCells = map_culled_to_base )).sum ().values
484
- logger .info (f'Total after rerouting (kg/s): { fwf_total :.1f} ' )
540
+ logger .info (f'Total after rerouting (kg/s): { fwf_total :.1f} ' )
541
+ logger .info ('' )
0 commit comments