diff --git a/E3SM-Project b/E3SM-Project index 752f281b15..31f771c5ca 160000 --- a/E3SM-Project +++ b/E3SM-Project @@ -1 +1 @@ -Subproject commit 752f281b15e3e65a373881aa866537bcb06f8957 +Subproject commit 31f771c5cae07a02d93ea138743ada03eb989880 diff --git a/compass/ocean/cached_files.json b/compass/ocean/cached_files.json index ce477f27df..8d05ad98d8 100644 --- a/compass/ocean/cached_files.json +++ b/compass/ocean/cached_files.json @@ -179,21 +179,21 @@ "ocean/global_ocean/Icos240/WOA23/init/initial_state/initial_state.nc": "global_ocean/Icos240/WOA23/init/initial_state/initial_state.240312.nc", "ocean/global_ocean/Icos240/WOA23/init/initial_state/init_mode_forcing_data.nc": "global_ocean/Icos240/WOA23/init/initial_state/init_mode_forcing_data.240312.nc", "ocean/global_ocean/Icos240/WOA23/init/initial_state/graph.info": "global_ocean/Icos240/WOA23/init/initial_state/graph.240312.info", - "ocean/global_ocean/IcoswISC240/mesh/base_mesh/mesh.msh": "global_ocean/IcoswISC240/mesh/base_mesh/mesh.240312.msh", - "ocean/global_ocean/IcoswISC240/mesh/base_mesh/base_mesh.nc": "global_ocean/IcoswISC240/mesh/base_mesh/base_mesh.240312.nc", - "ocean/global_ocean/IcoswISC240/mesh/base_mesh/cellWidthVsLatLon.nc": "global_ocean/IcoswISC240/mesh/base_mesh/cellWidthVsLatLon.240312.nc", - "ocean/global_ocean/IcoswISC240/mesh/base_mesh/graph.info": "global_ocean/IcoswISC240/mesh/base_mesh/graph.240312.info", - "ocean/global_ocean/IcoswISC240/mesh/cull_mesh/culled_mesh.nc": "global_ocean/IcoswISC240/mesh/cull_mesh/culled_mesh.240312.nc", - "ocean/global_ocean/IcoswISC240/mesh/cull_mesh/culled_graph.info": "global_ocean/IcoswISC240/mesh/cull_mesh/culled_graph.240312.info", - "ocean/global_ocean/IcoswISC240/mesh/cull_mesh/critical_passages_mask_final.nc": "global_ocean/IcoswISC240/mesh/cull_mesh/critical_passages_mask_final.240312.nc", - "ocean/global_ocean/IcoswISC240/mesh/cull_mesh/land_ice_mask.nc": "global_ocean/IcoswISC240/mesh/cull_mesh/land_ice_mask.240312.nc", - "ocean/global_ocean/IcoswISC240/mesh/cull_mesh/topography_culled.nc": "global_ocean/IcoswISC240/mesh/cull_mesh/topography_culled.240312.nc", - "ocean/global_ocean/IcoswISC240/mesh/cull_mesh/map_culled_to_base.nc": "global_ocean/IcoswISC240/mesh/cull_mesh/map_culled_to_base.240312.nc", - "ocean/global_ocean/IcoswISC240/mesh/remap_topography/topography_remapped.nc": "global_ocean/IcoswISC240/mesh/remap_topography/topography_remapped.240312.nc", - "ocean/global_ocean/IcoswISC240/WOA23/init/initial_state/initial_state.nc": "global_ocean/IcoswISC240/WOA23/init/initial_state/initial_state.240312.nc", - "ocean/global_ocean/IcoswISC240/WOA23/init/initial_state/init_mode_forcing_data.nc": "global_ocean/IcoswISC240/WOA23/init/initial_state/init_mode_forcing_data.240312.nc", - "ocean/global_ocean/IcoswISC240/WOA23/init/initial_state/graph.info": "global_ocean/IcoswISC240/WOA23/init/initial_state/graph.240312.info", - "ocean/global_ocean/IcoswISC240/WOA23/init/remap_ice_shelf_melt/prescribed_ismf_paolo2023.nc": "global_ocean/IcoswISC240/WOA23/init/remap_ice_shelf_melt/prescribed_ismf_paolo2023.240312.nc", + "ocean/global_ocean/IcoswISC240/mesh/base_mesh/mesh.msh": "global_ocean/IcoswISC240/mesh/base_mesh/mesh.240509.msh", + "ocean/global_ocean/IcoswISC240/mesh/base_mesh/base_mesh.nc": "global_ocean/IcoswISC240/mesh/base_mesh/base_mesh.240509.nc", + "ocean/global_ocean/IcoswISC240/mesh/base_mesh/cellWidthVsLatLon.nc": "global_ocean/IcoswISC240/mesh/base_mesh/cellWidthVsLatLon.240509.nc", + "ocean/global_ocean/IcoswISC240/mesh/base_mesh/graph.info": "global_ocean/IcoswISC240/mesh/base_mesh/graph.240509.info", + "ocean/global_ocean/IcoswISC240/mesh/cull_mesh/culled_mesh.nc": "global_ocean/IcoswISC240/mesh/cull_mesh/culled_mesh.240509.nc", + "ocean/global_ocean/IcoswISC240/mesh/cull_mesh/culled_graph.info": "global_ocean/IcoswISC240/mesh/cull_mesh/culled_graph.240509.info", + "ocean/global_ocean/IcoswISC240/mesh/cull_mesh/critical_passages_mask_final.nc": "global_ocean/IcoswISC240/mesh/cull_mesh/critical_passages_mask_final.240509.nc", + "ocean/global_ocean/IcoswISC240/mesh/cull_mesh/land_ice_mask.nc": "global_ocean/IcoswISC240/mesh/cull_mesh/land_ice_mask.240509.nc", + "ocean/global_ocean/IcoswISC240/mesh/cull_mesh/topography_culled.nc": "global_ocean/IcoswISC240/mesh/cull_mesh/topography_culled.240509.nc", + "ocean/global_ocean/IcoswISC240/mesh/cull_mesh/map_culled_to_base.nc": "global_ocean/IcoswISC240/mesh/cull_mesh/map_culled_to_base.240509.nc", + "ocean/global_ocean/IcoswISC240/mesh/remap_topography/topography_remapped.nc": "global_ocean/IcoswISC240/mesh/remap_topography/topography_remapped.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/initial_state/initial_state.nc": "global_ocean/IcoswISC240/WOA23/init/initial_state/initial_state.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/initial_state/init_mode_forcing_data.nc": "global_ocean/IcoswISC240/WOA23/init/initial_state/init_mode_forcing_data.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/initial_state/graph.info": "global_ocean/IcoswISC240/WOA23/init/initial_state/graph.240509.info", + "ocean/global_ocean/IcoswISC240/WOA23/init/remap_ice_shelf_melt/prescribed_ismf_paolo2023.nc": "global_ocean/IcoswISC240/WOA23/init/remap_ice_shelf_melt/prescribed_ismf_paolo2023.240509.nc", "ocean/global_ocean/IcoswISC240/WOA23/init/ssh_adjustment/adjusted_init.nc": "global_ocean/IcoswISC240/WOA23/init/ssh_adjustment/adjusted_init.240312.nc", "ocean/global_ocean/Icos/mesh/base_mesh/mesh.msh": "global_ocean/Icos/mesh/base_mesh/mesh.240312.msh", "ocean/global_ocean/Icos/mesh/base_mesh/base_mesh.nc": "global_ocean/Icos/mesh/base_mesh/base_mesh.240312.nc", @@ -208,20 +208,60 @@ "ocean/global_ocean/Icos/WOA23/init/initial_state/initial_state.nc": "global_ocean/Icos/WOA23/init/initial_state/initial_state.240312.nc", "ocean/global_ocean/Icos/WOA23/init/initial_state/init_mode_forcing_data.nc": "global_ocean/Icos/WOA23/init/initial_state/init_mode_forcing_data.240312.nc", "ocean/global_ocean/Icos/WOA23/init/initial_state/graph.info": "global_ocean/Icos/WOA23/init/initial_state/graph.240312.info", - "ocean/global_ocean/IcoswISC/mesh/base_mesh/mesh.msh": "global_ocean/IcoswISC/mesh/base_mesh/mesh.240312.msh", - "ocean/global_ocean/IcoswISC/mesh/base_mesh/base_mesh.nc": "global_ocean/IcoswISC/mesh/base_mesh/base_mesh.240312.nc", - "ocean/global_ocean/IcoswISC/mesh/base_mesh/cellWidthVsLatLon.nc": "global_ocean/IcoswISC/mesh/base_mesh/cellWidthVsLatLon.240312.nc", - "ocean/global_ocean/IcoswISC/mesh/base_mesh/graph.info": "global_ocean/IcoswISC/mesh/base_mesh/graph.240312.info", - "ocean/global_ocean/IcoswISC/mesh/cull_mesh/culled_mesh.nc": "global_ocean/IcoswISC/mesh/cull_mesh/culled_mesh.240312.nc", - "ocean/global_ocean/IcoswISC/mesh/cull_mesh/culled_graph.info": "global_ocean/IcoswISC/mesh/cull_mesh/culled_graph.240312.info", - "ocean/global_ocean/IcoswISC/mesh/cull_mesh/critical_passages_mask_final.nc": "global_ocean/IcoswISC/mesh/cull_mesh/critical_passages_mask_final.240312.nc", - "ocean/global_ocean/IcoswISC/mesh/cull_mesh/land_ice_mask.nc": "global_ocean/IcoswISC/mesh/cull_mesh/land_ice_mask.240312.nc", - "ocean/global_ocean/IcoswISC/mesh/cull_mesh/topography_culled.nc": "global_ocean/IcoswISC/mesh/cull_mesh/topography_culled.240312.nc", - "ocean/global_ocean/IcoswISC/mesh/cull_mesh/map_culled_to_base.nc": "global_ocean/IcoswISC/mesh/cull_mesh/map_culled_to_base.240312.nc", - "ocean/global_ocean/IcoswISC/mesh/remap_topography/topography_remapped.nc": "global_ocean/IcoswISC/mesh/remap_topography/topography_remapped.240312.nc", - "ocean/global_ocean/IcoswISC/WOA23/init/initial_state/initial_state.nc": "global_ocean/IcoswISC/WOA23/init/initial_state/initial_state.240312.nc", - "ocean/global_ocean/IcoswISC/WOA23/init/initial_state/init_mode_forcing_data.nc": "global_ocean/IcoswISC/WOA23/init/initial_state/init_mode_forcing_data.240312.nc", - "ocean/global_ocean/IcoswISC/WOA23/init/initial_state/graph.info": "global_ocean/IcoswISC/WOA23/init/initial_state/graph.240312.info", - "ocean/global_ocean/IcoswISC/WOA23/init/remap_ice_shelf_melt/prescribed_ismf_paolo2023.nc": "global_ocean/IcoswISC/WOA23/init/remap_ice_shelf_melt/prescribed_ismf_paolo2023.240312.nc", - "ocean/global_ocean/IcoswISC/WOA23/init/ssh_adjustment/adjusted_init.nc": "global_ocean/IcoswISC/WOA23/init/ssh_adjustment/adjusted_init.240312.nc" + "ocean/global_ocean/IcoswISC/mesh/base_mesh/mesh.msh": "global_ocean/IcoswISC/mesh/base_mesh/mesh.240509.msh", + "ocean/global_ocean/IcoswISC/mesh/base_mesh/base_mesh.nc": "global_ocean/IcoswISC/mesh/base_mesh/base_mesh.240509.nc", + "ocean/global_ocean/IcoswISC/mesh/base_mesh/cellWidthVsLatLon.nc": "global_ocean/IcoswISC/mesh/base_mesh/cellWidthVsLatLon.240509.nc", + "ocean/global_ocean/IcoswISC/mesh/base_mesh/graph.info": "global_ocean/IcoswISC/mesh/base_mesh/graph.240509.info", + "ocean/global_ocean/IcoswISC/mesh/cull_mesh/culled_mesh.nc": "global_ocean/IcoswISC/mesh/cull_mesh/culled_mesh.240509.nc", + "ocean/global_ocean/IcoswISC/mesh/cull_mesh/culled_graph.info": "global_ocean/IcoswISC/mesh/cull_mesh/culled_graph.240509.info", + "ocean/global_ocean/IcoswISC/mesh/cull_mesh/critical_passages_mask_final.nc": "global_ocean/IcoswISC/mesh/cull_mesh/critical_passages_mask_final.240509.nc", + "ocean/global_ocean/IcoswISC/mesh/cull_mesh/land_ice_mask.nc": "global_ocean/IcoswISC/mesh/cull_mesh/land_ice_mask.240509.nc", + "ocean/global_ocean/IcoswISC/mesh/cull_mesh/topography_culled.nc": "global_ocean/IcoswISC/mesh/cull_mesh/topography_culled.240509.nc", + "ocean/global_ocean/IcoswISC/mesh/cull_mesh/map_culled_to_base.nc": "global_ocean/IcoswISC/mesh/cull_mesh/map_culled_to_base.240509.nc", + "ocean/global_ocean/IcoswISC/mesh/remap_topography/topography_remapped.nc": "global_ocean/IcoswISC/mesh/remap_topography/topography_remapped.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/initial_state/initial_state.nc": "global_ocean/IcoswISC/WOA23/init/initial_state/initial_state.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/initial_state/init_mode_forcing_data.nc": "global_ocean/IcoswISC/WOA23/init/initial_state/init_mode_forcing_data.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/initial_state/graph.info": "global_ocean/IcoswISC/WOA23/init/initial_state/graph.240509.info", + "ocean/global_ocean/IcoswISC/WOA23/init/remap_ice_shelf_melt/prescribed_ismf_paolo2023.nc": "global_ocean/IcoswISC/WOA23/init/remap_ice_shelf_melt/prescribed_ismf_paolo2023.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/ssh_adjustment/adjusted_init.nc": "global_ocean/IcoswISC/WOA23/init/ssh_adjustment/adjusted_init.240312.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/01_init_with_draft_from_constant_density/initial_state.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/01_init_with_draft_from_constant_density/initial_state.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/01_init_with_draft_from_constant_density/init_mode_forcing_data.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/01_init_with_draft_from_constant_density/init_mode_forcing_data.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/01_init_with_draft_from_constant_density/graph.info": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/01_init_with_draft_from_constant_density/graph.240509.info", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/02_ssh_from_surface_density/topography_culled.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/02_ssh_from_surface_density/topography_culled.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/03_init/initial_state.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/03_init/initial_state.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/03_init/init_mode_forcing_data.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/03_init/init_mode_forcing_data.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/03_init/graph.info": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/03_init/graph.240509.info", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/04_adjust_ssh/topography_culled.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/04_adjust_ssh/topography_culled.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/05_init/initial_state.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/05_init/initial_state.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/05_init/init_mode_forcing_data.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/05_init/init_mode_forcing_data.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/05_init/graph.info": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/05_init/graph.240509.info", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/06_adjust_ssh/topography_culled.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/06_adjust_ssh/topography_culled.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/07_init/initial_state.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/07_init/initial_state.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/07_init/init_mode_forcing_data.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/07_init/init_mode_forcing_data.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/07_init/graph.info": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/07_init/graph.240509.info", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/08_adjust_ssh/topography_culled.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/08_adjust_ssh/topography_culled.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/09_init/initial_state.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/09_init/initial_state.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/09_init/init_mode_forcing_data.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/09_init/init_mode_forcing_data.240509.nc", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/09_init/graph.info": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/09_init/graph.240509.info", + "ocean/global_ocean/IcoswISC/WOA23/init/adjust_ssh/10_adjust_ssh/topography_culled.nc": "global_ocean/IcoswISC/WOA23/init/adjust_ssh/10_adjust_ssh/topography_culled.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/01_init_with_draft_from_constant_density/initial_state.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/01_init_with_draft_from_constant_density/initial_state.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/01_init_with_draft_from_constant_density/init_mode_forcing_data.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/01_init_with_draft_from_constant_density/init_mode_forcing_data.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/01_init_with_draft_from_constant_density/graph.info": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/01_init_with_draft_from_constant_density/graph.240509.info", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/02_ssh_from_surface_density/topography_culled.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/02_ssh_from_surface_density/topography_culled.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/03_init/initial_state.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/03_init/initial_state.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/03_init/init_mode_forcing_data.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/03_init/init_mode_forcing_data.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/03_init/graph.info": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/03_init/graph.240509.info", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/04_adjust_ssh/topography_culled.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/04_adjust_ssh/topography_culled.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/05_init/initial_state.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/05_init/initial_state.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/05_init/init_mode_forcing_data.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/05_init/init_mode_forcing_data.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/05_init/graph.info": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/05_init/graph.240509.info", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/06_adjust_ssh/topography_culled.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/06_adjust_ssh/topography_culled.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/07_init/initial_state.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/07_init/initial_state.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/07_init/init_mode_forcing_data.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/07_init/init_mode_forcing_data.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/07_init/graph.info": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/07_init/graph.240509.info", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/08_adjust_ssh/topography_culled.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/08_adjust_ssh/topography_culled.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/09_init/initial_state.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/09_init/initial_state.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/09_init/init_mode_forcing_data.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/09_init/init_mode_forcing_data.240509.nc", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/09_init/graph.info": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/09_init/graph.240509.info", + "ocean/global_ocean/IcoswISC240/WOA23/init/adjust_ssh/10_adjust_ssh/topography_culled.nc": "global_ocean/IcoswISC240/WOA23/init/adjust_ssh/10_adjust_ssh/topography_culled.240509.nc" } diff --git a/compass/ocean/iceshelf.py b/compass/ocean/iceshelf.py index 403803b7bf..8a69efa617 100644 --- a/compass/ocean/iceshelf.py +++ b/compass/ocean/iceshelf.py @@ -87,7 +87,7 @@ def adjust_ssh(variable, iteration_count, step, update_pio=True, on_a_sphere = ds.attrs['on_a_sphere'].lower() == 'yes' modify_mask = numpy.logical_and(ds.maxLevelCell > 0, - ds.modifyLandIcePressureMask == 1) + ds.sshAdjustmentMask == 1) for iter_index in range(iteration_count): logger.info(f" * Iteration {iter_index + 1}/{iteration_count}") diff --git a/compass/ocean/mesh/cull.py b/compass/ocean/mesh/cull.py index 2ff60f8496..e33f665484 100644 --- a/compass/ocean/mesh/cull.py +++ b/compass/ocean/mesh/cull.py @@ -501,9 +501,7 @@ def _land_mask_from_topo(with_cavities, topo_filename, mask_filename): # we want the mask to be 1 where there's not ocean cull_mask = xr.where(ocean_frac < 0.5, 1, 0) else: - land_ice_frac = ds_topo.landIceFracObserved - grounded_ice_frac = ds_topo.landIceGroundedFracObserved - floating_ice_frac = land_ice_frac - grounded_ice_frac + floating_ice_frac = ds_topo.landIceFloatingFracObserved no_cavities_ocean_frac = ocean_frac - floating_ice_frac # we want the mask to be 1 where there's not open ocean @@ -558,7 +556,7 @@ def _add_land_ice_mask_and_mask_draft(ds_topo, ds_base_mesh, logger): land_ice_draft_mask = ds_mask.cellSeedMask ds_topo['landIceDraftMask'] = land_ice_draft_mask ds_topo['landIceDraftObserved'] = ( - land_ice_mask * ds_topo.landIceDraftObserved) + land_ice_draft_mask * ds_topo.landIceDraftObserved) def _land_mask_from_geojson(with_cavities, process_count, logger, diff --git a/compass/ocean/mesh/remap_topography.cfg b/compass/ocean/mesh/remap_topography.cfg index 3427134356..de659dabd4 100644 --- a/compass/ocean/mesh/remap_topography.cfg +++ b/compass/ocean/mesh/remap_topography.cfg @@ -2,17 +2,17 @@ [remap_topography] # the name of the topography file in the bathymetry database -topo_filename = BedMachineAntarctica_v3_and_GEBCO_2023_0.0125_degree_20230831.nc +topo_filename = BedMachineAntarctica_v3_and_GEBCO_2023_0.0125_degree_20240611.nc # variable names in topo_filename lon_var = lon lat_var = lat bathymetry_var = bathymetry -ice_draft_var = ice_draft ice_thickness_var = thickness ice_frac_var = ice_mask grounded_ice_frac_var = grounded_mask ocean_frac_var = ocean_mask +bathy_frac_var = bathymetry_mask # the description to include in metadata description = Bathymetry is from GEBCO 2023, combined with BedMachine @@ -28,3 +28,6 @@ method = conserve # threshold of what fraction of an MPAS cell must contain ocean in order to # perform renormalization of elevation variables renorm_threshold = 0.01 + +# the density of land ice from MALI (kg/m^3) +ice_density = 910.0 diff --git a/compass/ocean/mesh/remap_topography.py b/compass/ocean/mesh/remap_topography.py index 52ce7d64bc..e1c164b93e 100644 --- a/compass/ocean/mesh/remap_topography.py +++ b/compass/ocean/mesh/remap_topography.py @@ -2,6 +2,7 @@ import numpy as np import xarray as xr +from mpas_tools.cime.constants import constants from mpas_tools.io import write_netcdf from pyremap import LatLonGridDescriptor, MpasCellMeshDescriptor, Remapper @@ -57,7 +58,8 @@ def setup(self): dependencies. """ super().setup() - topo_filename = self.config.get('remap_topography', 'topo_filename') + config = self.config + topo_filename = config.get('remap_topography', 'topo_filename') self.add_input_file( filename='topography.nc', target=topo_filename, @@ -69,7 +71,6 @@ def setup(self): target = os.path.join(base_path, base_filename) self.add_input_file(filename='base_mesh.nc', work_dir_target=target) - config = self.config self.ntasks = config.getint('remap_topography', 'ntasks') self.min_tasks = config.getint('remap_topography', 'min_tasks') @@ -101,6 +102,9 @@ def run(self): method = config.get('remap_topography', 'method') renorm_threshold = config.getfloat('remap_topography', 'renorm_threshold') + ice_density = config.getfloat('remap_topography', 'ice_density') + ocean_density = constants['SHR_CONST_RHOSW'] + g = constants['SHR_CONST_G'] in_descriptor = LatLonGridDescriptor.read(fileName='topography.nc', lonVarName=lon_var, @@ -128,27 +132,44 @@ def run(self): ds_in = ds_in.rename({'ncol': 'nCells'}) ds_out = xr.Dataset() rename = {'bathymetry_var': 'bed_elevation', - 'ice_draft_var': 'landIceDraftObserved', 'ice_thickness_var': 'landIceThkObserved', 'ice_frac_var': 'landIceFracObserved', 'grounded_ice_frac_var': 'landIceGroundedFracObserved', - 'ocean_frac_var': 'oceanFracObserved'} + 'ocean_frac_var': 'oceanFracObserved', + 'bathy_frac_var': 'bathyFracObserved'} - for option in rename: + for option, out_var in rename.items(): in_var = config.get('remap_topography', option) - out_var = rename[option] ds_out[out_var] = ds_in[in_var] + ds_out['landIceFloatingFracObserved'] = \ + ds_out.landIceFracObserved - ds_out.landIceGroundedFracObserved + # make sure fractions don't exceed 1 for var in ['landIceFracObserved', 'landIceGroundedFracObserved', - 'oceanFracObserved']: + 'landIceFloatingFracObserved', 'oceanFracObserved', + 'bathyFracObserved']: ds_out[var] = np.minimum(ds_out[var], 1.) # renormalize elevation variables - norm = ds_out.oceanFracObserved + norm = ds_out.bathyFracObserved valid = norm > renorm_threshold - for var in ['bed_elevation', 'landIceDraftObserved', - 'landIceThkObserved']: + for var in ['bed_elevation', 'landIceThkObserved']: ds_out[var] = xr.where(valid, ds_out[var] / norm, 0.) + thickness = ds_out.landIceThkObserved + ds_out['landIcePressureObserved'] = ice_density * g * thickness + + # compute the ice draft to be consistent with the land ice pressure + # and using E3SM's density of seawater + draft = - (ice_density / ocean_density) * thickness + bed = ds_out.bed_elevation + + # can't be deeper than the bed + draft = xr.where(draft >= bed, draft, bed) + + ds_out['landIceDraftObserved'] = draft + + ds_out['ssh'] = draft + write_netcdf(ds_out, 'topography_remapped.nc') diff --git a/compass/ocean/tests/global_ocean/forward.py b/compass/ocean/tests/global_ocean/forward.py index 43cc8d9ada..22c4ca3ca3 100644 --- a/compass/ocean/tests/global_ocean/forward.py +++ b/compass/ocean/tests/global_ocean/forward.py @@ -139,12 +139,8 @@ def __init__(self, test_case, mesh, time_integrator, init=None, work_dir_target=f'{mesh_path}/culled_mesh.nc') if init is not None: - if mesh.with_ice_shelf_cavities: - initial_state_target = \ - f'{init.path}/ssh_adjustment/adjusted_init.nc' - else: - initial_state_target = \ - f'{init.path}/initial_state/initial_state.nc' + initial_state_target = \ + f'{init.path}/initial_state/initial_state.nc' self.add_input_file(filename='init.nc', work_dir_target=initial_state_target) self.add_input_file( diff --git a/compass/ocean/tests/global_ocean/global_ocean.cfg b/compass/ocean/tests/global_ocean/global_ocean.cfg index 3c7a0e6de5..3a3bcda6a2 100644 --- a/compass/ocean/tests/global_ocean/global_ocean.cfg +++ b/compass/ocean/tests/global_ocean/global_ocean.cfg @@ -21,7 +21,7 @@ sweep_count = 20 [ssh_adjustment] # the number of iterations of ssh adjustment to perform -iterations = 10 +iterations = 4 # Whether to convert adjusted initial condition files to CDF5 format during # ssh adjustment under ice shelves @@ -54,8 +54,10 @@ btr_dt_per_km = 1.5 min_levels = 3 cavity_min_levels = ${min_levels} -# minimum thickness of layers in ice-shelf cavities -cavity_min_layer_thickness = 1.0 +# minimum thickness of layers in ice-shelf cavities at the beginning and end +# of iterative ssh init +cavity_min_layer_thickness_initial = 10.0 +cavity_min_layer_thickness_final = 3.0 # Maximum allowed Haney number for configurations with ice-shelf cavities rx1_max = 20.0 diff --git a/compass/ocean/tests/global_ocean/init/__init__.py b/compass/ocean/tests/global_ocean/init/__init__.py index c59841abeb..358b987f74 100644 --- a/compass/ocean/tests/global_ocean/init/__init__.py +++ b/compass/ocean/tests/global_ocean/init/__init__.py @@ -5,6 +5,9 @@ RemapIceShelfMelt, ) from compass.ocean.tests.global_ocean.init.ssh_adjustment import SshAdjustment +from compass.ocean.tests.global_ocean.init.ssh_from_surface_density import ( + SshFromSurfaceDensity, +) from compass.testcase import TestCase from compass.validate import compare_variables @@ -50,17 +53,6 @@ def __init__(self, test_group, mesh, initial_condition): self.mesh = mesh self.initial_condition = initial_condition - self.add_step( - InitialState( - test_case=self, mesh=mesh, - initial_condition=initial_condition)) - - if mesh.with_ice_shelf_cavities: - self.add_step(RemapIceShelfMelt(test_case=self, mesh=mesh)) - - self.add_step( - SshAdjustment(test_case=self)) - def configure(self, config=None): """ Modify the configuration options for this test case @@ -68,11 +60,14 @@ def configure(self, config=None): config : compass.config.CompassConfigParser, optional Configuration options to update if not those for this test case """ + add_steps = config is None if config is None: config = self.config + mesh = self.mesh + # set mesh-relate config options - self.mesh.configure(config=config) + mesh.configure(config=config) initial_condition = self.initial_condition descriptions = {'WOA23': 'World Ocean Atlas 2023 climatology ' @@ -84,6 +79,72 @@ def configure(self, config=None): config.set('global_ocean', 'init_description', descriptions[initial_condition]) + if add_steps: + # add the steps for ssh adjustment + if mesh.with_ice_shelf_cavities: + step_index = 1 + name = \ + f'{step_index:02d}_init_with_draft_from_constant_density' + subdir = f'adjust_ssh/{name}' + init_const_rho = InitialState( + test_case=self, mesh=mesh, + initial_condition=initial_condition, + name=name, subdir=subdir, + adjustment_fraction=0.) + self.add_step(init_const_rho) + + # Recompute ssh using surface density + step_index += 1 + name = f'{step_index:02d}_ssh_from_surface_density' + subdir = f'adjust_ssh/{name}' + ssh_from_surf_rho = SshFromSurfaceDensity( + test_case=self, init_path=init_const_rho.path, + name=name, subdir=subdir) + self.add_step(ssh_from_surf_rho) + + culled_topo_path = ssh_from_surf_rho.path + + iteration_count = config.getint('ssh_adjustment', 'iterations') + for iter_index in range(iteration_count): + fraction = iter_index / iteration_count + + step_index += 1 + name = f'{step_index:02d}_init' + subdir = f'adjust_ssh/{name}' + init_step = InitialState( + test_case=self, mesh=mesh, + initial_condition=initial_condition, + culled_topo_path=culled_topo_path, + name=name, subdir=subdir, + adjustment_fraction=fraction) + self.add_step(init_step) + + step_index += 1 + name = f'{step_index:02d}_adjust_ssh' + subdir = f'adjust_ssh/{name}' + adjust_ssh = SshAdjustment( + test_case=self, init_path=init_step.path, + name=name, subdir=subdir) + self.add_step(adjust_ssh) + culled_topo_path = adjust_ssh.path + + name = 'initial_state' + subdir = 'initial_state' + init_step = InitialState( + test_case=self, mesh=mesh, + initial_condition=initial_condition, + culled_topo_path=culled_topo_path, + name=name, subdir=subdir, + adjustment_fraction=1.0) + self.add_step(init_step) + + self.add_step(RemapIceShelfMelt(test_case=self, mesh=mesh)) + else: + self.add_step( + InitialState( + test_case=self, mesh=mesh, + initial_condition=initial_condition)) + def validate(self): """ Test cases can override this method to perform validation of variables @@ -92,8 +153,3 @@ def validate(self): variables = ['temperature', 'salinity', 'layerThickness'] compare_variables(test_case=self, variables=variables, filename1='initial_state/initial_state.nc') - - if self.mesh.with_ice_shelf_cavities: - variables = ['ssh', 'landIcePressure'] - compare_variables(test_case=self, variables=variables, - filename1='ssh_adjustment/adjusted_init.nc') diff --git a/compass/ocean/tests/global_ocean/init/initial_state.py b/compass/ocean/tests/global_ocean/init/initial_state.py index 17511846c1..71f47e94c6 100644 --- a/compass/ocean/tests/global_ocean/init/initial_state.py +++ b/compass/ocean/tests/global_ocean/init/initial_state.py @@ -28,8 +28,14 @@ class InitialState(Step): initial_condition : {'WOA23', 'PHC', 'EN4_1900'} The initial condition dataset to use + + adjustment_fraction : float + The fraction of the way through iterative ssh adjustment for this + step """ - def __init__(self, test_case, mesh, initial_condition): + def __init__(self, test_case, mesh, initial_condition, + culled_topo_path=None, name='initial_state', subdir=None, + adjustment_fraction=None): """ Create the step @@ -43,13 +49,30 @@ def __init__(self, test_case, mesh, initial_condition): initial_condition : {'WOA23', 'PHC', 'EN4_1900'} The initial condition dataset to use + + culled_topo_path : str, optional + The path to a step where ``topography_culled.nc`` is provided + + name : str, optional + The name of the step + + subdir : str, optional + The subdirectory for the step + + adjustment_fraction : float, optional + The fraction of the way through iterative ssh adjustment for this + step """ if initial_condition not in ['WOA23', 'PHC', 'EN4_1900']: raise ValueError(f'Unknown initial_condition {initial_condition}') - super().__init__(test_case=test_case, name='initial_state') + super().__init__(test_case=test_case, name=name, subdir=subdir) self.mesh = mesh self.initial_condition = initial_condition + if mesh.with_ice_shelf_cavities and adjustment_fraction is None: + raise ValueError('Must provide adjustment_fraction for ' + 'initializing meshes with ice-shelf cavities') + self.adjustment_fraction = adjustment_fraction package = 'compass.ocean.tests.global_ocean.init' @@ -83,8 +106,10 @@ def __init__(self, test_case, mesh, initial_condition): self.add_namelist_options(options, mode='init') self.add_streams_file(package, 'streams.topo', mode='init') - cull_step = self.mesh.steps['cull_mesh'] - target = os.path.join(cull_step.path, 'topography_culled.nc') + if culled_topo_path is None: + cull_step = self.mesh.steps['cull_mesh'] + culled_topo_path = cull_step.path + target = os.path.join(culled_topo_path, 'topography_culled.nc') self.add_input_file(filename='topography_culled.nc', work_dir_target=target) @@ -168,6 +193,7 @@ def run(self): Run this step of the testcase """ config = self.config + section = config['global_ocean'] self._smooth_topography() interfaces = generate_1d_grid(config=config) @@ -185,10 +211,14 @@ def run(self): namelist = {'config_global_ocean_minimum_depth': f'{min_depth}'} if self.mesh.with_ice_shelf_cavities: - cavity_min_levels = \ - config.getint('global_ocean', 'cavity_min_levels') - cavity_min_layer_thickness = \ - config.getfloat('global_ocean', 'cavity_min_layer_thickness') + frac = self.adjustment_fraction + cavity_min_levels = section.getint('cavity_min_levels') + min_thick_init = section.getfloat( + 'cavity_min_layer_thickness_initial') + min_thick_final = section.getfloat( + 'cavity_min_layer_thickness_final') + cavity_min_layer_thickness = ( + (1.0 - frac) * min_thick_init + frac * min_thick_final) namelist['config_rx1_min_levels'] = f'{cavity_min_levels}' namelist['config_rx1_min_layer_thickness'] = \ f'{cavity_min_layer_thickness}' diff --git a/compass/ocean/tests/global_ocean/init/namelist.wisc b/compass/ocean/tests/global_ocean/init/namelist.wisc index b40088e3e0..c668dce71b 100644 --- a/compass/ocean/tests/global_ocean/init/namelist.wisc +++ b/compass/ocean/tests/global_ocean/init/namelist.wisc @@ -1,15 +1,5 @@ config_land_ice_flux_mode = 'standalone' config_init_vertical_grid_type = 'haney-number' config_global_ocean_depress_by_land_ice = .true. -config_global_ocean_land_ice_topo_file = 'topography.nc' -config_global_ocean_land_ice_topo_nlat_dimname = 'lat' -config_global_ocean_land_ice_topo_nlon_dimname = 'lon' -config_global_ocean_land_ice_topo_latlon_degrees = .true. -config_global_ocean_land_ice_topo_lat_varname = 'lat' -config_global_ocean_land_ice_topo_lon_varname = 'lon' -config_global_ocean_land_ice_topo_draft_varname = 'ice_draft' -config_global_ocean_land_ice_topo_thickness_varname = 'thickness' -config_global_ocean_land_ice_topo_ice_frac_varname = 'ice_mask' -config_global_ocean_land_ice_topo_grounded_frac_varname = 'grounded_mask' config_global_ocean_use_constant_land_ice_cavity_temperature = .true. config_global_ocean_constant_land_ice_cavity_temperature = -1.8 diff --git a/compass/ocean/tests/global_ocean/init/ssh_adjustment.py b/compass/ocean/tests/global_ocean/init/ssh_adjustment.py index 2d988a887e..3074dfc345 100644 --- a/compass/ocean/tests/global_ocean/init/ssh_adjustment.py +++ b/compass/ocean/tests/global_ocean/init/ssh_adjustment.py @@ -1,6 +1,11 @@ from importlib.resources import contents -from compass.ocean.iceshelf import adjust_ssh +import numpy as np +import xarray as xr +from mpas_tools.io import write_netcdf +from mpas_tools.logging import check_call + +from compass.model import partition, run_model from compass.ocean.tests.global_ocean.forward import ForwardStep @@ -9,7 +14,8 @@ class SshAdjustment(ForwardStep): A step for iteratively adjusting the pressure from the weight of the ice shelf to match the sea-surface height as part of ice-shelf 2D test cases """ - def __init__(self, test_case): + def __init__(self, test_case, init_path, name='ssh_adjustment', + subdir=None): """ Create the step @@ -17,16 +23,24 @@ def __init__(self, test_case): ---------- test_case : compass.ocean.tests.global_ocean.init.Init The test case this step belongs to + + init_path : str + The path to the initial state to use for forward runs + + name : str, optional + The name of the step + + subdir : str, optional + The subdirectory for the step """ super().__init__(test_case=test_case, mesh=test_case.mesh, time_integrator='split_explicit_ab2', - name='ssh_adjustment') + name=name, subdir=subdir) self.add_namelist_options({'config_AM_globalStats_enable': '.false.'}) self.add_namelist_file('compass.ocean.namelists', 'namelist.ssh_adjust') - self.add_streams_file('compass.ocean.streams', 'streams.ssh_adjust') self.add_streams_file('compass.ocean.tests.global_ocean.init', 'streams.ssh_adjust') @@ -41,10 +55,9 @@ def __init__(self, test_case): self.add_streams_file(mesh_package, mesh_streams) mesh_path = test_case.mesh.get_cull_mesh_path() - init_path = test_case.steps['initial_state'].path self.add_input_file( - filename='adjusting_init0.nc', + filename='init.nc', work_dir_target=f'{init_path}/initial_state.nc') self.add_input_file( filename='forcing_data.nc', @@ -53,17 +66,91 @@ def __init__(self, test_case): filename='graph.info', work_dir_target=f'{mesh_path}/culled_graph.info') - self.add_output_file(filename='adjusted_init.nc') + self.add_input_file( + filename='original_topograpy.nc', + work_dir_target=f'{mesh_path}/topography_culled.nc') + + self.add_output_file(filename='topography_culled.nc') def run(self): """ Run this step of the testcase """ config = self.config - iteration_count = config.getint('ssh_adjustment', 'iterations') update_pio = config.getboolean('global_ocean', 'forward_update_pio') convert_to_cdf5 = config.getboolean('ssh_adjustment', 'convert_to_cdf5') - adjust_ssh(variable='landIcePressure', iteration_count=iteration_count, - step=self, update_pio=update_pio, - convert_to_cdf5=convert_to_cdf5) + + self._adjust_ssh(update_pio=update_pio, + convert_to_cdf5=convert_to_cdf5) + + def _adjust_ssh(self, update_pio, convert_to_cdf5): + """ + Adjust the sea surface height to be dynamically consistent with + land-ice pressure. + """ + ntasks = self.ntasks + config = self.config + logger = self.logger + + if update_pio: + self.update_namelist_pio('namelist.ocean') + partition(ntasks, config, logger) + + with xr.open_dataset('init.nc') as ds: + ds = ds.isel(Time=0) + init_ssh = ds.ssh + modify_mask = np.logical_and(ds.maxLevelCell > 0, + ds.sshAdjustmentMask == 1) + land_ice_pressure = ds.landIcePressure + + logger.info(" * Running forward model") + run_model(self, update_pio=False, partition_graph=False) + logger.info(" - Complete") + + logger.info(" * Updating SSH") + + with xr.open_dataset('output_ssh.nc') as ds_ssh: + # get the last time entry + ds_ssh = ds_ssh.isel(Time=ds_ssh.sizes['Time'] - 1) + final_ssh = ds_ssh.ssh + + delta_ssh = modify_mask * (final_ssh - init_ssh) + + with xr.open_dataset('original_topograpy.nc') as ds_out: + + ds_out['ssh'] = modify_mask * final_ssh + + if convert_to_cdf5: + write_filename = 'topography_before_cdf5.nc' + else: + write_filename = 'topography_culled.nc' + write_netcdf(ds_out, write_filename) + if convert_to_cdf5: + args = ['ncks', '-O', '-5', 'topography_before_cdf5.nc', + 'topography_culled.nc'] + check_call(args, logger=logger) + + # Write the largest change in SSH and its lon/lat to a file + with open('maxDeltaSSH.log', 'w') as log_file: + + icell = np.abs(delta_ssh).argmax().values + + ds_cell = ds.isel(nCells=icell) + delta_ssh_max = delta_ssh.isel(nCells=icell).values + + coords = (f'lon/lat: ' + f'{np.rad2deg(ds_cell.lonCell.values):f} ' + f'{np.rad2deg(ds_cell.latCell.values):f}') + string = (f'delta_ssh_max: ' + f'{delta_ssh_max:g}, {coords}') + + logger.info(f' {string}') + log_file.write(f'{string}\n') + string = (f'ssh: {final_ssh.isel(nCells=icell).values:g}, ' + f'landIcePressure: ' + f'{land_ice_pressure.isel(nCells=icell).values:g}') + logger.info(f' {string}') + log_file.write(f'{string}\n') + + logger.info(" - Complete\n") diff --git a/compass/ocean/tests/global_ocean/init/ssh_from_surface_density.py b/compass/ocean/tests/global_ocean/init/ssh_from_surface_density.py new file mode 100644 index 0000000000..dc715ccf48 --- /dev/null +++ b/compass/ocean/tests/global_ocean/init/ssh_from_surface_density.py @@ -0,0 +1,102 @@ + +import numpy as np +import xarray as xr +from mpas_tools.cime.constants import constants +from mpas_tools.io import write_netcdf +from mpas_tools.logging import check_call + +from compass.step import Step + + +class SshFromSurfaceDensity(Step): + """ + Compute the sea surface height that is in approximate hydrostatic balance + with a given land-ice pressure using the density in the top layer of the + ocean + + Attributes + ---------- + mesh : compass.ocean.tests.global_ocean.mesh.mesh.MeshStep + The step for creating the mesh + """ + def __init__(self, test_case, init_path, name, subdir): + """ + Create the step + + Parameters + ---------- + test_case : compass.ocean.tests.global_ocean.init.Init + The test case this step belongs to + + init_path : str + The path to the initial state from which to get the land ice + pressure and surface density + + name : str + The name of the step + + subdir : str + The subdirectory for the step + """ + super().__init__(test_case=test_case, name=name, subdir=subdir) + self.mesh = test_case.mesh + self.add_input_file( + filename='init.nc', + work_dir_target=f'{init_path}/initial_state.nc') + + mesh_path = self.mesh.get_cull_mesh_path() + + self.add_input_file( + filename='mesh.nc', + work_dir_target=f'{mesh_path}/culled_mesh.nc') + + self.add_input_file( + filename='original_topograpy.nc', + work_dir_target=f'{mesh_path}/topography_culled.nc') + + self.add_output_file(filename='topography_culled.nc') + + def run(self): + """ + Run this step of the testcase + """ + config = self.config + logger = self.logger + + convert_to_cdf5 = config.getboolean('ssh_adjustment', + 'convert_to_cdf5') + + g = constants['SHR_CONST_G'] + + with xr.open_dataset('init.nc') as ds_init: + ds_init = ds_init.isel(Time=0) + modify_mask = np.logical_and( + ds_init.maxLevelCell > 0, + ds_init.sshAdjustmentMask == 1) + land_ice_pressure = ds_init.landIcePressure + + if 'minLevelCell' in ds_init: + min_level_cell = ds_init.minLevelCell - 1 + else: + min_level_cell = xr.zeros_like(ds_init.maxLevelCell) + + top_density = ds_init.density.isel(nVertLevels=min_level_cell) + + ssh = xr.where(modify_mask, + - land_ice_pressure / (top_density * g), + 0.) + + with xr.open_dataset('original_topograpy.nc') as ds_topo: + + ds_topo['ssh'] = ssh + + if convert_to_cdf5: + write_filename = 'topography_before_cdf5.nc' + else: + write_filename = 'topography_culled.nc' + write_netcdf(ds_topo, write_filename) + + if convert_to_cdf5: + args = ['ncks', '-O', '-5', 'topography_before_cdf5.nc', + 'topography_culled.nc'] + check_call(args, logger=logger) diff --git a/compass/ocean/tests/global_ocean/init/streams.init b/compass/ocean/tests/global_ocean/init/streams.init index c105b6041e..92109e59cd 100644 --- a/compass/ocean/tests/global_ocean/init/streams.init +++ b/compass/ocean/tests/global_ocean/init/streams.init @@ -28,9 +28,10 @@ + - + @@ -38,7 +39,7 @@ - + diff --git a/compass/ocean/tests/global_ocean/init/streams.ssh_adjust b/compass/ocean/tests/global_ocean/init/streams.ssh_adjust index 6199d4cbb8..f752dd1c93 100644 --- a/compass/ocean/tests/global_ocean/init/streams.ssh_adjust +++ b/compass/ocean/tests/global_ocean/init/streams.ssh_adjust @@ -1,5 +1,31 @@ + + + + + + + + + + + + + + diff --git a/compass/ocean/tests/global_ocean/init/streams.topo b/compass/ocean/tests/global_ocean/init/streams.topo index 64ec8f1f64..13fd2e36a1 100644 --- a/compass/ocean/tests/global_ocean/init/streams.topo +++ b/compass/ocean/tests/global_ocean/init/streams.topo @@ -4,12 +4,14 @@ filename_template="topography.nc" input_interval="initial_only" > - - - - - - + + + + + + + + diff --git a/compass/ocean/tests/global_ocean/mesh/__init__.py b/compass/ocean/tests/global_ocean/mesh/__init__.py index da9884177a..280bf49b9d 100644 --- a/compass/ocean/tests/global_ocean/mesh/__init__.py +++ b/compass/ocean/tests/global_ocean/mesh/__init__.py @@ -147,6 +147,7 @@ def configure(self, config=None): description = 'Bathymetry is from GEBCO 2022, combined with ' \ 'BedMachine Antarctica v2 around Antarctica.' config.set('remap_topography', 'topo_filename', filename) + config.set('remap_topography', 'bathy_frac_var', 'ocean_mask') config.set('remap_topography', 'description', description) config.set('remap_topography', 'ntasks', '64') config.set('remap_topography', 'min_tasks', '4') diff --git a/compass/ocean/tests/ice_shelf_2d/initial_state.py b/compass/ocean/tests/ice_shelf_2d/initial_state.py index 57a9763896..d245f3c9c8 100644 --- a/compass/ocean/tests/ice_shelf_2d/initial_state.py +++ b/compass/ocean/tests/ice_shelf_2d/initial_state.py @@ -122,7 +122,7 @@ def run(self): ds['fCell'] = xarray.zeros_like(ds.xCell) ds['fEdge'] = xarray.zeros_like(ds.xEdge) ds['fVertex'] = xarray.zeros_like(ds.xVertex) - ds['modifyLandIcePressureMask'] = modify_mask + ds['sshAdjustmentMask'] = modify_mask ds['landIceFraction'] = landIceFraction ds['landIceFloatingFraction'] = landIceFloatingFraction ds['landIceMask'] = landIceMask diff --git a/compass/ocean/tests/isomip_plus/initial_state.py b/compass/ocean/tests/isomip_plus/initial_state.py index 1160fc0761..955651040b 100644 --- a/compass/ocean/tests/isomip_plus/initial_state.py +++ b/compass/ocean/tests/isomip_plus/initial_state.py @@ -109,7 +109,7 @@ def _compute_initial_condition(self): ds['landIceFloatingFraction'] = \ ds['landIceFloatingFraction'].expand_dims(dim='Time', axis=0) - ds['modifyLandIcePressureMask'] = \ + ds['sshAdjustmentMask'] = \ (ds['landIceFraction'] > 0.01).astype(int) # This inequality needs to be > rather than >= to ensure correctness diff --git a/compass/ocean/tests/tides/init/streams.init b/compass/ocean/tests/tides/init/streams.init index 78b43f83fb..e66e3e669c 100644 --- a/compass/ocean/tests/tides/init/streams.init +++ b/compass/ocean/tests/tides/init/streams.init @@ -43,21 +43,21 @@ + - + - + - @@ -93,4 +93,3 @@ - diff --git a/compass/run/serial.py b/compass/run/serial.py index 24f435baa8..ab91f54861 100644 --- a/compass/run/serial.py +++ b/compass/run/serial.py @@ -314,8 +314,10 @@ def _log_and_run_test(test_case, logger, test_logger, quiet, # noqa: C901 if test_pass: log_function_call(function=_run_test, logger=test_logger) test_logger.info('') - test_list = ', '.join(test_case.steps_to_run) - test_logger.info(f'Running steps: {test_list}') + test_logger.info('Running steps:') + for step in test_case.steps_to_run: + test_logger.info(f' {step}') + test_logger.info('') try: _run_test(test_case, available_resources) run_status = success_str diff --git a/docs/developers_guide/ocean/api.rst b/docs/developers_guide/ocean/api.rst index 66afd72a84..710c81c4fe 100644 --- a/docs/developers_guide/ocean/api.rst +++ b/docs/developers_guide/ocean/api.rst @@ -249,6 +249,8 @@ test cases and steps init.ssh_adjustment.SshAdjustment init.ssh_adjustment.SshAdjustment.setup init.ssh_adjustment.SshAdjustment.run + init.ssh_from_surface_density.SshFromSurfaceDensity + init.ssh_from_surface_density.SshFromSurfaceDensity.run mesh.Mesh mesh.Mesh.configure diff --git a/docs/developers_guide/ocean/test_groups/global_ocean.rst b/docs/developers_guide/ocean/test_groups/global_ocean.rst index c5690e4a7c..2dd28ffc74 100644 --- a/docs/developers_guide/ocean/test_groups/global_ocean.rst +++ b/docs/developers_guide/ocean/test_groups/global_ocean.rst @@ -712,9 +712,9 @@ The default config options for these meshes are: prefix = RRS # a description of the mesh and initial condition mesh_description = MPAS Eddy Closure mesh for E3SM version ${e3sm_version} with - enhanced resolution around the equator (30 km), South pole - (35 km), Greenland (${min_res} km), ${max_res}-km resolution - at mid latitudes, and ${levels} vertical levels + enhanced resolution around the equator (30 km), South pole + (35 km), Greenland (${min_res} km), ${max_res}-km resolution + at mid latitudes, and ${levels} vertical levels # E3SM version that the mesh is intended for e3sm_version = 3 # The revision number of the mesh, which should be incremented each time the @@ -998,15 +998,32 @@ defines the step for creating the initial state, including defining the topography, wind stress, shortwave, potential temperature, salinity, and ecosystem input data files. +If a mesh has ice-shelf cavities, iterative adjustment of the sea-surface height +is performed to prevent tsunamis in forward runs. + +First, a step defined by +:py:class:`compass.ocean.tests.global_ocean.init.ssh_from_surface_density.SshFromSurfaceDensity` +is called to update the ``ssh`` variable in the topography dataset based +on the surface pressure, rather than the constant reference density. + +Then, for each iteration, first a new ``InitialState`` step is called with the +updated ``ssh``. Next, a step with the +:py:class:`compass.ocean.tests.global_ocean.init.ssh_adjustment.SshAdjustment` +class is called to perform a short (typically 1-hour) forward run. The +``ssh`` at the end of that run, masked to be modified only under ice shelves, +is used as the new ``ssh`` for the next iteration. The idea is that the +main cause of dynamics in the sea-surface height in the first hour of +simulation is due to the hydrostatic imbalance between ``landIcePressure`` and +``ssh``, and that this can be reduced by updating the ``ssh`` with this +iterative procedure. + +Finally, another ``InitialState`` step creates the initial condition to be +used in subsequent forward simulations in Compass. + The class :py:class:`compass.ocean.tests.global_ocean.init.remap_ice_shelf_melt.RemapIceShelfMelt` defines a step that remaps melt rates from the satellite-derived dataset from `Paolo et al. (2023) `_. -The class :py:class:`compass.ocean.tests.global_ocean.init.ssh_adjustment.SshAdjustment` -defines a step to adjust the ``landIcePressure`` variable to be in closer to -dynamical balance with the sea-surface height (SSH) in configurations with -:ref:`dev_ocean_framework_iceshelf`. - If the test case is being compared with a baseline, the potential temperature, salinity, and layerThickness are compared with those in the baseline initial condition to make sure they are identical. In simulations with ice-shelf diff --git a/docs/users_guide/ocean/test_groups/global_ocean.rst b/docs/users_guide/ocean/test_groups/global_ocean.rst index 186e6c1a96..b86063163d 100644 --- a/docs/users_guide/ocean/test_groups/global_ocean.rst +++ b/docs/users_guide/ocean/test_groups/global_ocean.rst @@ -56,7 +56,7 @@ Note that meshes and test cases may modify these options, as noted below. [ssh_adjustment] # the number of iterations of ssh adjustment to perform - iterations = 10 + iterations = 4 # Whether to convert adjusted initial condition files to CDF5 format during # ssh adjustment under ice shelves