예제 #1
0
def spreading(discharge_mw, ds_lsm, ds_wf):
    """
    !!! The spreading is done on m3/s data !!!
    From an initial discharge cube return a new cube with meltwater collected and spreaded over new regions adding the
    waterfix.
    :param discharge_mw: Initial discharge cube [t*lat*lon].
    :param ds_lsm: Land sea mask.
    :param ds_wf: Waterfix.
    :return: Discharge cube with the waterfix [t*lat*lon].
    """
    
    print("__ Spreading algorithm")
    
    # Land sea mask
    lon_lsm, lat_lsm, depth, lsm = \
        ds_lsm.longitude.values, ds_lsm.latitude.values, ds_lsm.depthdepth.values, ds_lsm.lsm.values
    
    # Waterfix
    lon_wf, lat_wf, wfix = ds_wf.longitude.values, ds_wf.latitude.values, ds_wf.field672.isel(depth=0).isel(t=0).values
    lon_wf, wfix = lon_wf[:-2], wfix[:, :-2]  # remove 2 extra lon points
    # Converting the waterfix (kg/m2/s1) to discharge unit (m3/s)
    wfix_3d = convert_waterfix(wfix, discharge_mw, tb.surface_matrix(lon_lsm, lat_lsm))
    
    # Test that the three files use the same coordinate system
    assert (np.array_equal(lat_wf, lat_lsm) and np.array_equal(lon_wf, lon_lsm))
    
    # Coordinate system
    lat, lon = LatAxis(lat_wf[:]), LonAxis(lon_wf[:])
    umgrid = Grid(lat, lon)
    
    # Land sea mask and surface matrix
    masked = np.copy(lsm)  # land mask True (1) on land
    depthm = np.ma.masked_less(depth, 500.0)  # mask areas shallower than 500m
    masked_500m = np.copy(depthm.mask) + masked  # create binary mask from depth data
    surface_matrix = tb.surface_matrix(lon_lsm, lat_lsm)
    
    # Step 1 : Generate collection and spreading zones
    collection_boxes = generate_collection_boxes()
    spread_regions = generate_spreading_regions(collection_boxes, umgrid, masked, masked_500m)
    
    # Step 2 : Spread the collected freshwater in the spreading zones
    spreaded_mw = spreading_method(discharge_mw, spread_regions, surface_matrix)
    
    # Step 3 : Add waterfix to the spreaded mask
    total_mw = spreaded_mw + wfix_3d
    
    # Step 4 : Calculate the loss and check the algorithm
    discharge_others_mw = get_discharge_others(discharge_mw, spread_regions)
    flux_check(discharge_mw, spreaded_mw, discharge_others_mw, wfix_3d, total_mw)
    
    return total_mw
예제 #2
0
def hi_to_discharge(ds_hice, t, flux_mode):
    """
    Convert ice thickness difference in a flux, including multiplying the flux and removing the negative values.
    :param ds_hice: Ice sheet reconstruction represented by ice thickness.
    :param t: Time step
    :param flux_mode: cf main method
    :return: [lat*lon] numpy array
    """

    # Water density
    d = 1000

    print(f"__ Computation time step : {t}.")

    # Computation of the flux for the time step and conversion from years to seconds.
    if t != len(ds_hice.HGLOBH.T122KP1) - 1:
        delta_t = (ds_hice.T122KP1[t + 1].values -
                   ds_hice.T122KP1[t].values) * 365 * 24 * 3600 * 1000
        if flux_mode == "kg/s":
            flux = -(ds_hice.HGLOBH[t + 1].values -
                     ds_hice.HGLOBH[t].values) * d / delta_t
        elif flux_mode == "sv":
            flux = -(ds_hice.HGLOBH[t + 1].values -
                     ds_hice.HGLOBH[t].values) * 10**(-6) / delta_t
        elif flux_mode == "m3/s":
            flux = -(ds_hice.HGLOBH[t + 1].values -
                     ds_hice.HGLOBH[t].values) / delta_t
        else:
            print("Mode not recognized")
            flux = -(ds_hice.HGLOBH[t + 1].values -
                     ds_hice.HGLOBH[t].values) / delta_t

    else:
        delta_t = (ds_hice.T122KP1[t].values -
                   ds_hice.T122KP1[t - 1].values) * 365 * 24 * 3600 * 1000
        if flux_mode == "kg/s":
            flux = -(ds_hice.HGLOBH[t].values -
                     ds_hice.HGLOBH[t - 1].values) * d / delta_t
        elif flux_mode == "sv":
            flux = -(ds_hice.HGLOBH[t].values -
                     ds_hice.HGLOBH[t - 1].values) * 10**(-6) / delta_t
        elif flux_mode == "m3/s":
            flux = -(ds_hice.HGLOBH[t].values -
                     ds_hice.HGLOBH[t - 1].values) / delta_t
        else:
            print("Mode not recognized")
            flux = -(ds_hice.HGLOBH[t].values -
                     ds_hice.HGLOBH[t - 1].values) / delta_t

    # Multiplying by the surface
    flux = np.multiply(
        flux,
        tb.surface_matrix(ds_hice.XLONGLOBP5.values,
                          ds_hice.YLATGLOBP25.values))

    # Remove the negative values
    flux = np.where(flux < 0, 0, flux)

    return flux
예제 #3
0
def m3s_to_kgm2s(discharge, lon, lat):
    """
    Convert a discharge volume flux to a discharge surface mass flux.
    :param discharge: [t*lat*lon] numpy array.
    :param lon: Longitude series of discharge.
    :param lat: Latitude series of discharge.
    :return: Discharge surface mass flux [t*lat*lon] numpy array.
    """
    d = 1000  # water density
    return np.divide(discharge * d, tb.surface_matrix(lon, lat))
예제 #4
0
def convert_discharge_values(ds_discharge, ds_waterfix, unit):
    """
    !!!!!!!!!ADD WATERFIX TO SV AND M3/S!!!!!!!!!!!!!!!!
    :param ds_discharge:
    :param ds_waterfix:
    :param unit:
    :return:
    """
    if unit == "Sv":
        values = ds_discharge.discharge.values
    elif unit == "m3/s":
        values = ds_discharge.discharge.values * 10**(-6)
    elif unit == "kg/m2/s":
        ds_values = ds_discharge.discharge.values - np.resize(
            ds_waterfix.isel(t=0).isel(depth=0).field672.values[:, :-2],
            ds_discharge.discharge.values.shape)
        ds_values = np.where(np.isnan(ds_values), 0, ds_values)
        values = np.multiply(
            ds_values / 1000 * 10**(-6),
            tb.surface_matrix(ds_discharge.longitude.values,
                              ds_discharge.latitude.values))
    else:
        values = ds_discharge.discharge.values
    return values