コード例 #1
0
def mainEnginePowerCalculation(processed, CONSTANTS):
    print("Started calculating main engine power...", end="", flush=True)
    # This function calculates the Power of the engine starting from the efficiency of the engine,
    # which is calcualted starting from other available data
    for system in CONSTANTS["General"]["NAMES"]["MainEngines"]:
        # Calculate fuel flow-based engine load
        fuel_based_load = processed[d2df(
            system, "Cyl", "FuelPh_in",
            "mdot")] / CONSTANTS["MainEngines"]["MFR_FUEL_DES_ISO"]
        # Calculate ISO bsfc (break specific fuel consumption)
        bsfc_iso = fuel_based_load.apply(
            polyvalHelperFunction,
            args=(CONSTANTS["MainEngines"]["POLY_FUEL_LOAD_2_BSFC_ISO"], ))
        # Corrects the bsfc from ISO conditions to "real" conditions
        (bsfc, LHV) = ppo.bsfcISOCorrection(
            bsfc_iso, processed[d2df(system, "CAC_LT", "Air_out", "T")],
            processed[d2df(system, "CAC_LT", "LTWater_in", "T")],
            processed[d2df(system, "Cyl", "FuelPh_in", "T")], CONSTANTS)
        # Calculates the real fuel flow using the ISO conversion
        processed[d2df(system, "Cyl", "FuelPh_in", "mdot")] = processed[d2df(
            system, "Cyl", "FuelPh_in", "mdot")] * bsfc / bsfc_iso
        # Calculates the power of the engine as mfr/bsfc, with unit conversion to get the output in kW
        # Shaft energy out
        processed[d2df(system, "Cyl", "Power_out", "Edot")] = processed[d2df(
            system, "Cyl", "FuelPh_in", "mdot")] / bsfc * 1000 * 3600
        # Chemical energy in the fuel
        processed[d2df(system, "Cyl", "FuelCh_in", "Edot")] = processed[d2df(
            system, "Cyl", "FuelPh_in", "mdot")] * LHV
    print("...done!")
    return processed
コード例 #2
0
def mainEngineFuelFlowCalculation(raw, processed, CONSTANTS, hd):
    print("Started calculating main engine fuel flows...", end="", flush=True)
    # This function calculates the engine
    for system in CONSTANTS["General"]["NAMES"]["MainEngines"]:
        # This function calculates the fuel flow of the main engines
        # In the case of the main engines, the fuel flow of an engine is calculated given its fuel
        # rack position and its rotating speed.
        fuel_rack_position = CONSTANTS["MainEngines"]["FRP_2_MFR"]["FRP_MIN"][
            system] + (CONSTANTS["MainEngines"]["FRP_2_MFR"]["FRP_MAX"][system]
                       - CONSTANTS["MainEngines"]["FRP_2_MFR"]["FRP_MIN"]
                       [system]) * raw[hd[system + "__FRP_"]] / 100
        # Temporarily, only the ISO fuel flow is calculated
        processed[d2df(
            system, "Cyl", "FuelPh_in",
            "mdot")] = CONSTANTS["MainEngines"]["MFR_FUEL_DES_ISO"] * (
                (CONSTANTS["MainEngines"]["FRP_2_MFR"]["POLY"][system][0] +
                 CONSTANTS["MainEngines"]["FRP_2_MFR"]["POLY"][system][1] *
                 fuel_rack_position) /
                (CONSTANTS["MainEngines"]["FRP_2_MFR"]["POLY"][system][0] +
                 CONSTANTS["MainEngines"]["FRP_2_MFR"]["POLY"][system][1] *
                 CONSTANTS["MainEngines"]["FRP_DES"][system])) * (
                     processed[d2df(system, "Cyl", "Power_out", "omega")] /
                     CONSTANTS["MainEngines"]["RPM_DES"])
    print("...done!")
    return processed
コード例 #3
0
def mainEngineAirFlowPostCalculation(processed, dict_structure, CONSTANTS):
    # This function does the post-analysis after the various properties have been calculated
    print("Started calculating main engine air and exhaust flows...", end="", flush=True)
    for system in CONSTANTS["General"]["NAMES"]["MainEngines"]:
        # Calculating the turbine's power output to the compressor
        processed[d2df(system, "Turbine", "Power_out", "Edot")] = processed[d2df(system,"BPmerge","Mix_out","mdot")] * (
            processed[d2df(system, "Turbine", "Mix_in", "h")] - processed[d2df(system,"Turbine","Mix_out","h")])
        # Calculating the compressor's power input.
        processed[d2df(system, "Comp", "Power_in", "Edot")] = processed[d2df(system, "BPsplit", "Air_in", "mdot")] * (
            processed[d2df(system, "Comp", "Air_out", "h")] - processed[d2df(system, "Comp", "Air_in", "h")])
        # Losses at the TC shaft level are calculated
        processed[d2df(system, "TCshaft", "Losses_out", "Edot")] = processed[d2df(system, "Turbine", "Power_out", "Edot")] - processed[d2df(system, "Comp", "Power_in", "Edot")]
    return processed
コード例 #4
0
def massBalance(processed, dict_structure, CONSTANTS):
    # This function checks that the mass balance is respected.
    # Errors are shown:
    # - On an occurrence basis: every time that the balance is not respected counts as 1
    # - On an "average error" basis
    text_file = open(CONSTANTS["filenames"]["consistency_check_report"], "a")
    text_file.write("\n *** CHECKING THE MASS BALANCE *** \n")
    print("Started checking mass balances...", end="", flush=True)
    for system in dict_structure["systems"]:
        for unit in dict_structure["systems"][system]["units"]:
            if (system == "Steam" and unit == "SteamDistribution"):
                aaa = 0
            balance = pd.Series(index=processed.index)
            balance[:] = 0
            max_value = 0
            counter = 0
            for flow in dict_structure["systems"][system]["units"][unit][
                    "flows"]:
                if dict_structure["systems"][system]["units"][unit]["flows"][
                        flow]["type"] in {"CPF", "IPF", "SF"}:
                    counter = counter + 1
                    balance = balance + processed[d2df(
                        system, unit, flow,
                        "mdot")] * (2 * float("out" not in flow) - 1)
                    max_value = max(
                        max_value,
                        max(processed[d2df(system, unit, flow, "mdot")]))
            balance_occ = np.sum(
                balance < 0.001 * max_value) / len(balance) * 100
            balance_ave = np.sum(balance) / (len(balance) *
                                             (100 - balance_occ) /
                                             100) / max_value * 100
            if balance_occ == 100:
                text_file.write(
                    "The mass balance is fine for {}_{} unit \n".format(
                        system, unit))
            elif (balance_occ >= 99) or (balance_ave <= 1):
                text_file.write(
                    "The mass balance is ALMOST fine for {}_{} unit \n".format(
                        system, unit))
            elif counter == 0:
                text_file.write(
                    "There is no mass balance for {}_{} unit \n".format(
                        system, unit))
            else:
                text_file.write(
                    "---Mass balance for {}_{} unit is respected {}% of the times, with {}% average error \n"
                    .format(system, unit, str(balance_occ), str(balance_ave)))
    print("...done!")
    text_file.close()
コード例 #5
0
def connectionAssignment(processed, dict_structure, CONSTANTS, system, unit,
                         call_ID):
    text_file = open(CONSTANTS["filenames"]["consistency_check_report"],
                     "a")  # Opens the log file
    counter = 0
    for flow in dict_structure["systems"][system]["units"][unit]["flows"]:
        if "Connections" in dict_structure["systems"][system]["units"][unit][
                "flows"][flow]:
            for connected_flow in dict_structure["systems"][system]["units"][
                    unit]["flows"][flow]["Connections"]:
                for property in CONSTANTS["General"]["PROPERTY_LIST"][
                        dict_structure["systems"][system]["units"][unit]
                    ["flows"][flow]["type"]]:
                    ID = d2df(
                        system, unit, flow, property
                    )  # Writing the property full ID of the flow we are checking
                    ID_c = connected_flow + ":" + property  # Writing the property full ID of the flow connected to the flow we are checking
                    if processed[ID].isnull().sum() != len(
                            processed[ID]):  # If the flow is not empty
                        if (processed[ID_c].isnull().sum() == len(
                                processed[ID_c])) or (
                                    sum(processed[ID_c])
                                    == 0):  # If the connected flow IS empty
                            processed[ID_c] = processed[ID]
                            counter = counter + 1
                        elif (processed[ID] -
                              processed[ID_c]).sum() > processed[ID].max():
                            text_file.write(
                                "ERROR. FUN: ppo.connectionAssignment. Something is wrong. Flows {} and {} should be the same, they are not. \n"
                                .format(ID, ID_c))
    text_file.close()
    return (counter, processed)
コード例 #6
0
def unitOffCheck(processed, dict_structure, CONSTANTS, system_set, call_ID):
    # Assigns to 0 all values related to components when they are off
    for system in system_set:
        if processed[system + ":" + "on"].isnull().sum() == 0:
            for unit in dict_structure["systems"][system]["units"]:
                for flow in dict_structure["systems"][system]["units"][unit][
                        "flows"]:
                    try:
                        for property in dict_structure["systems"][system][
                                "units"][unit]["flows"][flow]["properties"]:
                            if processed[d2df(system, unit, flow,
                                              property)].isnull().sum() == len(
                                                  processed[d2df(
                                                      system, unit, flow,
                                                      property)]):
                                pass  # the value is still untouched, better leave it that way
                            elif property == "T":
                                processed.loc[~processed[system + ":" + "on"],
                                              d2df(system, unit, flow, property
                                                   )] = processed.loc[
                                                       ~processed[system +
                                                                  ":" + "on"],
                                                       "T_0"]
                            else:
                                processed.loc[
                                    ~processed[system + ":" + "on"],
                                    d2df(system, unit, flow, property
                                         )] = CONSTANTS["General"][
                                             "PROPERTY_LIST"]["REF"][property]
                    except KeyError:
                        print(
                            "Something went wrong when checking the engine on/off"
                        )
        elif processed[system + ":" + "on"].isnull().sum() < len(
                processed[system + ":" + "on"]):
            print(
                "Something went wrong here, the system -on- field has NaNs for system {}"
                .format(system))
        else:
            pass
    return processed
コード例 #7
0
def plottingFunction(plot_info, processed, data_type):
    # Here we go
    if data_type == "processed":
        for figure in plot_info:
            if figure["plot_mode"] == "sankey":
                print("Plot Sankey diagram...as if this was easy")
            else:
                fig = plt.figure()
                for plot in figure["variables"]:
                    x = processed[d2df(plot["system"], plot["unit"],
                                       plot["flow"], plot["property"])]
                    if figure["plot_mode"] == "hist":
                        num_bins = 50
                        # the histogram of the data
                        n, bins, patches = plt.hist(x,
                                                    num_bins,
                                                    normed=1,
                                                    alpha=0.5)
                        # add a 'best fit' line
                        plt.xlabel(plot["property"] + " of " + plot["flow"] +
                                   " of " + plot["unit"] + " in " +
                                   plot["system"])
                        plt.ylabel('Probability')
                    if figure["plot_mode"] == "timeSeries":
                        plt.plot(x)
                        plt.ylabel("Time [YYY:MM]")
                        plt.ylabel(plot["property"] + " of " + plot["flow"] +
                                   " of " + plot["unit"] + " in " +
                                   plot["system"])

            plt.show()
    elif data_type == "raw":
        for figure in plot_info:
            if figure["plot_mode"] == "sankey":
                print("Plot Sankey diagram...as if this was easy")
            else:
                fig = plt.figure()
                for plot in figure["variables"]:
                    x = processed[plot]
                    if figure["plot_mode"] == "hist":
                        num_bins = 50
                        # the histogram of the data
                        n, bins, patches = plt.hist(x,
                                                    num_bins,
                                                    normed=1,
                                                    alpha=0.5)
                        # add a 'best fit' line
                        plt.xlabel("Variable of interest")
                        plt.ylabel('Probability')
                    if figure["plot_mode"] == "timeSeries":
                        x.plot()
    else:
        print("Data type is wrong. It should be either -raw- or -processed-")
コード例 #8
0
def auxEnginePowerCalculation(processed, CONSTANTS):
    print("Started calculating auxiliary engine power...", end="", flush=True)
    # Calculating the power of the auxiliary engines
    for system in CONSTANTS["General"]["NAMES"]["AuxEngines"]:
        load = processed[d2df(system,"AG","Power_out","Edot")] / CONSTANTS["AuxEngines"]["MCR"]
        eta_AG =  CONSTANTS["AuxEngines"]["AG"]["ETA_DES"] - CONSTANTS["AuxEngines"]["AG"]["A"] * np.exp(
            -CONSTANTS["AuxEngines"]["AG"]["k"] * (load))
        processed[d2df(system,"AG","Power_in","Edot")] = processed[d2df(system,"AG","Power_out","Edot")] / eta_AG
        processed[d2df(system,"AG","Losses_out","Edot")] = processed[d2df(system,"AG","Power_in","Edot")] - processed[d2df(system,"AG","Power_out","Edot")]
        processed[d2df(system,"Cyl","Power_out","Edot")] = processed[d2df(system,"AG","Power_in","Edot")]
    print("...done!")
    return processed
コード例 #9
0
def energyBalance(processed, dict_structure, CONSTANTS):
    # This function checks that the mass balance is respected
    text_file = open(CONSTANTS["filenames"]["consistency_check_report"], "a")
    text_file.write("\n *** CHECKING THE ENERGY BALANCE *** \n")
    print("Started checking the energy balances...", end="", flush=True)
    for system in dict_structure["systems"]:
        for unit in dict_structure["systems"][system]["units"]:
            balance = pd.Series(index=processed.index)
            balance[:] = 0
            max_value = 0
            for flow in dict_structure["systems"][system]["units"][unit][
                    "flows"]:
                balance = balance + processed[d2df(
                    system, unit, flow,
                    "Edot")] * (2 * float("out" not in flow) - 1)
                max_value = max(
                    max_value, max(processed[d2df(system, unit, flow,
                                                  "Edot")]))
            balance_occ = np.sum(balance < 0.001 * max_value) / max(
                1, len(balance)) * 100
            balance_ave = np.sum(balance) / (len(balance) *
                                             (100 - balance_occ) /
                                             100) / max_value * 100
            if balance_occ == 100:
                text_file.write(
                    "The energy balance is fine for {}_{} unit \n".format(
                        system, unit))
            elif (balance_occ >= 99) or (balance_ave <= 1):
                text_file.write(
                    "The energy balance is ALMOST fine for {}_{} unit \n".
                    format(system, unit))
            else:
                text_file.write(
                    "---energy balance for {}_{} unit is respected {}% of the times, with {}% average error \n"
                    .format(system, unit, str(balance_occ), str(balance_ave)))
    print("...done!")
    text_file.close()
コード例 #10
0
def missingValues(processed, dict_structure, CONSTANTS):
    text_file = open(CONSTANTS["filenames"]["consistency_check_report"], "a")
    text_file.write("\n *** LIST OF MISSING VALUES *** \n")
    print("Started looking for missing values...", end="", flush=True)
    for system in dict_structure["systems"]:
        for unit in dict_structure["systems"][system]["units"]:
            for flow in dict_structure["systems"][system]["units"][unit][
                    "flows"]:
                for property in dict_structure["systems"][system]["units"][
                        unit]["flows"][flow]["properties"]:
                    if processed[d2df(system, unit, flow,
                                      property)].isnull().sum() == len(
                                          processed[system + ":" + "on"]):
                        text_file.write(
                            "The field {}:{}:{}:{} is still empty \n".format(
                                system, unit, flow, property))
    text_file.close()
    print("...done!")
コード例 #11
0
def auxEngineFuelFlowCalculation(raw, processed, CONSTANTS):
    print("Started calculating auxiliary engine fuel flows...", end="", flush=True)
    # Proceeding with the auxiliary engines
    for system in CONSTANTS["General"]["NAMES"]["AuxEngines"]:
        # First we calculate the ISO break specific fuel consumption (BSFC)
        bsfc_iso = processed[system+":"+"load"].apply(ppo.polyvalHelperFunction, args=(CONSTANTS["AuxEngines"][
                                                                          "POLY_LOAD_2_ISO_BSFC"],))
        (bsfc, LHV) = ppo.bsfcISOCorrection(bsfc_iso, processed[d2df(system,"Cyl","Air_in","T")], processed[d2df(system,"CAC_LT",
                "LTWater_in","T")], processed[d2df(system,"Cyl","FuelPh_in","T")], CONSTANTS)
        processed[d2df(system,"Cyl","FuelPh_in","mdot")] = bsfc * processed[d2df(system,"Cyl","Power_out","Edot")] / 3600 / 1000
        processed[d2df(system,"Cyl","FuelCh_in","Edot")] = processed[d2df(system,"Cyl","FuelPh_in","mdot")] * LHV
    print("...done!")
    return processed
コード例 #12
0
def SteamCheck(processed, CONSTANTS, dict_structure):
    # This function checks that all relative values are consistent
    tot = len(processed.index)
    text_file = open(CONSTANTS["filenames"]["consistency_check_report"], "a")
    print("Started consistency check for the steam systems...",
          end="",
          flush=True)
    text_file.write("\n *** CONSISTENTCY CHECK FOR THE STEAM SYSTEMS *** \n")
    for unit in dict_structure["systems"]["Steam"]["units"]:
        if unit in {
                "TankHeating", "OtherTanks", "HFOtankHeating",
                "MachinerySpaceHeaters", "HFOheater", "Galley"
        }:
            temp = sum(processed[d2df("Steam", unit, "Steam_in", "mdot")] >= 0
                       ) / tot * 100
            warn = "WARNING " if temp < 95 else ""
            text_file.write(warn + unit +
                            "Steam mass flows are consistent for " +
                            str(temp) + " % of the datapoints \n")
    text_file.close()
    print("...done!")
コード例 #13
0
def auxEngineAirFlowCalculation(raw, processed, CONSTANTS):
    print("Started calculating auxiliary engine air and exhaust flows...", end="", flush=True)
    # This function calculates the different air and exhaust gas flows in the main engines, taking into account the
    # presence of air bypass and exhaust wastegate valves
    for system in CONSTANTS["General"]["NAMES"]["AuxEngines"]:
        # Calculating the compressor's compression ratio
        beta_comp = processed[d2df(system,"Comp","Air_out","p")] / processed[d2df(system,"Comp","Air_in","p")]
        # Calculating the compressor isentropic efficiency
        comp_isentropic_efficiency = beta_comp.apply(ppo.polyvalHelperFunction, args=(CONSTANTS["AuxEngines"]["POLY_PIN_2_ETA_IS"],))
        # Calculating the temperature after the compressor, based on ideal gas assumption
        T_Comp_out_iso = processed[d2df(system, "Comp", "Air_in", "T")] * beta_comp ** ((CONSTANTS["General"]["K_AIR"] - 1) / CONSTANTS["General"]["K_AIR"])
        T_Comp_out = processed[d2df(system, "Comp", "Air_in", "T")] + (T_Comp_out_iso - processed[d2df(system, "Comp", "Air_in", "T")]) / comp_isentropic_efficiency
        #### NOTE: HERE WE MAKE THE ASSUMPTION THAT THE COMPRESSOR OUTLET TEMPERATURE CANNOT BE LOWER THAN THE CYLINDER INLET TEMPERATURE
        T_Comp_out[T_Comp_out < processed[d2df(system, "Cyl", "Air_in", "T")]] = processed.loc[T_Comp_out < processed[d2df(system, "Cyl", "Air_in", "T")], d2df(system, "Cyl", "Air_in", "T")]
        processed[d2df(system, "Comp", "Air_out", "T")] = T_Comp_out
        # Calculating the air inflow aspired by the cylinder: calculated as inlet air density times the maximum volume,
        # times the engine speed
        processed[d2df(system,"Cyl","Air_in","mdot")] = CONSTANTS["AuxEngines"]["V_MAX"] * (
            processed[d2df(system,"Comp","Air_out","p")]) / (
            CONSTANTS["General"]["R_AIR"] * processed[d2df(system,"Cyl","Air_in","T")]) * (
            processed[d2df(system,"Cyl","Power_out","omega")] / 60 / 2 * CONSTANTS["General"]["ETA_VOL"]) * (
            CONSTANTS["AuxEngines"]["N_CYL"])
        # Exhaust gas flow after the cylinders
        processed[d2df(system,"Cyl","EG_out","mdot")] = processed[d2df(system,"Cyl","Air_in","mdot")] + processed[d2df(system,"Cyl","FuelPh_in","mdot")]
        # Here we calculate the bypass mass flow. THIS NEEDS TO BE CHECKED FOR CONSISTENCY (i.e. the bypass mass flow
        #  should always be kind of low, and anyway only be seen at low to medium load).
        # The equation is the result of a mass and energy balance over the whole engine
        # dT_comp = processed[d2df(system,"Comp","Air_out","T")] - processed[d2df(system,"Comp","Air_in","T")]
        # dT_turb = processed[d2df(system,"Turbine","Mix_in","T")] - processed[d2df(system,"Turbine","Mix_out","T")]
        # processed[d2df(system, "BPsplit", "BP_out", "mdot")] = (processed[d2df(system, "Cyl", "Air_in", "mdot")] * CONSTANTS["General"]["CP_AIR"] * dT_comp -
        #     processed[d2df(system,"Cyl","EG_out","mdot")] * CONSTANTS["General"]["CP_EG"] * dT_turb * CONSTANTS["MainEngines"]["ETA_MECH_TC"]) / (
        #     CONSTANTS["General"]["CP_AIR"] * (CONSTANTS["MainEngines"]["ETA_MECH_TC"] * dT_turb - dT_comp))
        processed.loc[:, d2df(system, "BPmerge", "BP_in", "mdot")] = 0
        # The air mass flow going through the compressor is equal to the sum of the air flow through the bypass valve and
        # to the cylinders
        processed[d2df(system,"BPsplit","Air_in","mdot")] = processed[d2df(system, "BPmerge", "BP_in", "mdot")] + processed[d2df(system,"Cyl","Air_in","mdot")]
        # The flow through the turbine is equal to the sum of the bypass flow and the exhaust coming from the cylinders
        processed[d2df(system,"BPmerge","Mix_out","mdot")] = processed[d2df(system,"BPmerge","BP_in","mdot")] + processed[d2df(system,"Cyl","EG_out","mdot")]
        # Calculating the temperature of the mixture after the merge between bypass and exhaust gas from the cylinders
        processed[d2df(system,"Cyl","EG_out","T")] = ((processed[d2df(system,"Cyl","EG_out","mdot")] * CONSTANTS["General"]["CP_EG"] +
            processed[d2df(system,"BPmerge","BP_in","mdot")] * CONSTANTS["General"]["CP_AIR"]) * processed[d2df(system,"Turbine","Mix_in","T")] -
            processed[d2df(system,"BPmerge","BP_in","mdot")] * CONSTANTS["General"]["CP_AIR"] * processed[d2df(system, "Comp", "Air_out", "T")]) / (
            processed[d2df(system,"Cyl","EG_out","mdot")] * CONSTANTS["General"]["CP_EG"])
        # Assiging the mass flow values for the HRSGs otherwise it makes a mess
        processed[d2df(system, "HRSG", "Mix_in", "mdot")] = processed[d2df(system, "BPmerge", "Mix_out", "mdot")]
        processed[d2df(system, "HRSG", "Mix_out", "mdot")] = processed[d2df(system, "BPmerge", "Mix_out", "mdot")]
    print("...done!")
    return processed
コード例 #14
0
def predefinedPlots(processed, dataset_raw, CONSTANTS, dict_structure,
                    filenames):
    for filename in filenames:
        fig, ax = plt.subplots()

        ### TIME SERIES ###

        if filename == "TimeSeries:Heat_vs_time":
            # Contribution from the HRSGs
            temp = (processed["ME2:HRSG:Steam_in:mdot"] *
                    CONSTANTS["Steam"]["DH_STEAM"] +
                    processed["ME3:HRSG:Steam_in:mdot"] *
                    CONSTANTS["Steam"]["DH_STEAM"] +
                    processed["AE1:HRSG:Steam_in:mdot"] *
                    CONSTANTS["Steam"]["DH_STEAM"] +
                    processed["AE2:HRSG:Steam_in:mdot"] *
                    CONSTANTS["Steam"]["DH_STEAM"] +
                    processed["AE3:HRSG:Steam_in:mdot"] *
                    CONSTANTS["Steam"]["DH_STEAM"] +
                    processed["AE4:HRSG:Steam_in:mdot"] *
                    CONSTANTS["Steam"]["DH_STEAM"])
            hrsg = temp.resample("D").sum() * 60 * 15
            # Contribution from the HTHR
            temp = processed["HTHR:HTHR13:HRWater_in:mdot"] * CONSTANTS[
                "General"]["CP_WATER"] * (
                    processed["HTHR:HTHR13:HRWater_out:T"] -
                    processed["HTHR:HTHR24:HRWater_in:T"])
            hthr = temp.resample("D").sum() * 60 * 15
            # Maximum theoretical contribution from the HT systems
            engine_set = {
                "ME1", "ME2", "ME3", "ME4", "AE1", "AE2", "AE3", "AE4"
            }
            temp = (sum((processed[d2df(idx, "CAC_HT", "HTWater_out", "T")] -
                         processed[d2df(idx, "JWC", "HTWater_in", "T")]) *
                        processed[d2df(idx, "CAC_HT", "HTWater_out", "mdot")] *
                        CONSTANTS["General"]["CP_WATER"]
                        for idx in engine_set))
            hthr_max = temp.resample("D").sum() * 60 * 15
            # Contribution from the auxiliary boilers
            boilers_measured = (
                dataset_raw["Boiler_Port"].resample("D").mean() +
                dataset_raw["Boiler_starbord"].resample("D").mean()
            ) * CONSTANTS["General"]["HFO"]["LHV"]
            boilers_calculated = processed[
                "Steam:Boiler1:FuelPh_in:mdot"].resample(
                    "D").sum() * 60 * 15 * CONSTANTS["General"]["HFO"]["LHV"]
            # Total demand
            total = processed["Demands:Heat:Total:Edot"].resample(
                "D").sum() * 60 * 15
            # Actual plotting
            ax.plot(hrsg, 'k-', label="HRSG")
            ax.plot(hthr, 'b-', label="HTHR")
            # plt.plot(hthr_max, 'b:', label="HTHR max")
            ax.plot(boilers_measured, 'r-', label="Boilers (M)")
            ax.plot(boilers_calculated, 'r:', label="Boilers (C)")
            ax.plot(total, 'g-', label='Total heating demand')
            plt.legend()

        if filename == "TimeSeries:TypicalWinterDay":
            ax.plot(processed["Demands:Mechanical:Total:Edot"]["2014-01-31"],
                    "g-",
                    label="Propulsion power")
            ax.plot(processed["Demands:Electricity:Total:Edot"]["2014-01-31"],
                    "b--",
                    label="Electric power")
            ax.plot(processed["Demands:Heat:Total:Edot"]["2014-01-31"],
                    "r:",
                    label="Heat")
            fig.autofmt_xdate()
            plt.xlabel("Time [MM-DD HH]")
            plt.ylabel("Power [kW]")
            plt.legend()

        if filename == "TimeSeries:TypicalSummerDay":
            ax.plot(processed["Demands:Mechanical:Total:Edot"]["2014-07-31"],
                    "g-",
                    label="Propulsion power")
            ax.plot(processed["Demands:Electricity:Total:Edot"]["2014-07-31"],
                    "b--",
                    label="Electric power")
            ax.plot(processed["Demands:Heat:Total:Edot"]["2014-07-31"],
                    "r:",
                    label="Heat")
            fig.autofmt_xdate()
            plt.xlabel("Time, [MM-DD HH]")
            plt.ylabel("Power [kW]")
            plt.legend()

        if filename == "TimeSeries:El+Tair_vs_time":
            # Plotting with two different y axis
            ax.plot(processed["Demands:Electricity:Total:Edot"]
                    ["2014-04-01":"2014-11-01"].resample('D').mean(),
                    "b--",
                    label="Electric power")
            ax.set_xlabel('Time [YYYY:MM]')
            ax.set_ylabel('Power [kW]')
            plt.legend()
            # Adding the second axis
            ax2 = ax.twinx()
            ax2.plot(processed["T_air"]["2014-04-01":"2014-11-01"].resample(
                'D').mean(),
                     'r--',
                     label="Ambient air temperature")
            ax2.set_ylabel('Temperature [K]')
            plt.legend()

        if filename == "TimeSeries:HeatBalance":
            # Contribution from the HRSGs
            Qdot_hrsg = (processed["ME2:HRSG:Steam_in:mdot"] *
                         CONSTANTS["Steam"]["DH_STEAM"] +
                         processed["ME3:HRSG:Steam_in:mdot"] *
                         CONSTANTS["Steam"]["DH_STEAM"] +
                         processed["AE1:HRSG:Steam_in:mdot"] *
                         CONSTANTS["Steam"]["DH_STEAM"] +
                         processed["AE2:HRSG:Steam_in:mdot"] *
                         CONSTANTS["Steam"]["DH_STEAM"] +
                         processed["AE3:HRSG:Steam_in:mdot"] *
                         CONSTANTS["Steam"]["DH_STEAM"] +
                         processed["AE4:HRSG:Steam_in:mdot"] *
                         CONSTANTS["Steam"]["DH_STEAM"])
            # Contribution from the HTHR
            Qdot_hthr = processed["HTHR:HTHR13:HRWater_in:mdot"] * CONSTANTS[
                "General"]["CP_WATER"] * (
                    processed["HTHR:HTHR13:HRWater_out:T"] -
                    processed["HTHR:HTHR24:HRWater_in:T"])
            Qdot_ab = processed["Steam:Boiler1:FuelPh_in:mdot"] * CONSTANTS[
                "General"]["HFO"]["LHV"] * CONSTANTS["OtherUnits"]["BOILER"][
                    "ETA_DES"]
            Qdot_dumped = processed["Steam:HotWell:LTWater_in:mdot"] * (
                processed["Steam:HotWell:LTWater_out:T"] -
                processed["Steam:HotWell:LTWater_in:T"]
            ) * CONSTANTS["General"]["CP_WATER"]
            Qdot_balance = Qdot_hrsg + Qdot_hthr + Qdot_ab - processed[
                "Demands:Heat:Total:Edot"] - Qdot_dumped
            Qdot_balance.plot()
            ax.plot(Qdot_balance.cumsum())
            plt.title("Heat balance")
            plt.xlabel("Time")
            plt.ylabel("Heat balance [kW]")

        if filename == "TimeSeries:HeatGenerationStacked":
            Qdot_hrsg = (processed["ME2:HRSG:Steam_in:mdot"] *
                         CONSTANTS["Steam"]["DH_STEAM"] +
                         processed["ME3:HRSG:Steam_in:mdot"] *
                         CONSTANTS["Steam"]["DH_STEAM"] +
                         processed["AE1:HRSG:Steam_in:mdot"] *
                         CONSTANTS["Steam"]["DH_STEAM"] +
                         processed["AE2:HRSG:Steam_in:mdot"] *
                         CONSTANTS["Steam"]["DH_STEAM"] +
                         processed["AE3:HRSG:Steam_in:mdot"] *
                         CONSTANTS["Steam"]["DH_STEAM"] +
                         processed["AE4:HRSG:Steam_in:mdot"] *
                         CONSTANTS["Steam"]["DH_STEAM"]).resample('D').mean()
            Qdot_hthr = (
                processed["HTHR:HTHR13:HRWater_in:mdot"] *
                CONSTANTS["General"]["CP_WATER"] *
                (processed["HTHR:HTHR13:HRWater_out:T"] -
                 processed["HTHR:HTHR24:HRWater_in:T"])).resample('D').mean()
            Qdot_ab = (processed["Steam:Boiler1:Steam_HotWell_in:mdot"] *
                       CONSTANTS["Steam"]["DH_STEAM"]).resample('D').mean()
            x = Qdot_ab.index
            ax.stackplot(
                x, Qdot_hrsg, Qdot_hthr, Qdot_ab,
                colors=("0.66", "0.33",
                        "0"))  # label = ["HRSG", "HTHR", "Aux boiler"]
            p1 = Rectangle((0, 0), 1, 1, fc="0.66")
            p2 = Rectangle((0, 0), 1, 1, fc="0.33")
            p3 = Rectangle((0, 0), 1, 1, fc="0")
            plt.legend([p1, p2, p3], ["HRSG", "HTHR", "Aux boiler"])
            plt.xlabel("Time [YYYY-MM]")
            plt.ylabel("Power [kW]")
        ### PIE CHARTS ###

        if filename == "Pie:TotalEnergySimple":
            quantities = [
                processed["Demands:Mechanical:Total:Edot"].sum(),
                processed["Demands:Electricity:Total:Edot"].sum(),
                processed["Demands:Heat:Total:Edot"].sum()
            ]
            labels = ["Mechanical Power", "Electric Power", "Thermal Power"]
            explode = (0.05, 0.05, 0.05)
            ax.pie(
                quantities,
                labels=labels,
                explode=explode,
                autopct='%1.1f%%',
                shadow=True,
            )

        if filename == "Pie:DemandFull":
            quantities = [
                processed["Demands:Mechanical:Propeller1:Edot"].sum(),
                processed["Demands:Mechanical:Propeller2:Edot"].sum(),
                processed["Demands:Electricity:HVAC:Edot"].sum(),
                processed["Demands:Electricity:Thrusters:Edot"].sum(),
                processed["Demands:Electricity:Other:Edot"].sum(),
                processed["Demands:Heat:HVACpreheater:Edot"].sum(),
                processed["Demands:Heat:HVACreheater:Edot"].sum(),
                processed["Demands:Heat:HotWaterHeater:Edot"].sum(),
                processed["Demands:Heat:MachinerySpaceHeaters:Edot"].sum(),
                processed["Demands:Heat:OtherTanks:Edot"].sum(),
                processed["Demands:Heat:TankHeating:Edot"].sum(),
                processed["Demands:Heat:HFOheater:Edot"].sum(),
                processed["Demands:Heat:HFOtankHeating:Edot"].sum(),
                processed["Demands:Heat:Galley:Edot"].sum()
            ]
            labels = [
                "Propeller-1", "Propeller-2", "HVAC", "Thrusters",
                "Other users", "HVAC Preheater", "HVAC Reheater",
                "Hot water heater", "Machinery space heaters",
                "Other tanks heating", "Fuel tanks heating",
                "HFO tanks heating", "HFO pre-injection heating", "Galley"
            ]
            #explode = [0, 0, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]
            explode = []
            for idx in range(len(labels)):
                explode.append(
                    (1 - (quantities[idx] / sum(quantities))) * 0.05)
            colors = [
                "green", "green", "blue", "blue", "blue", "sandybrown",
                "sandybrown", "sandybrown", "red", "red", "red", "red", "red",
                "red"
            ]
            patches, texts, autotexts = ax.pie(quantities,
                                               labels=labels,
                                               explode=explode,
                                               autopct='%1.1f%%',
                                               colors=colors,
                                               pctdistance=0.9)
            [_.set_fontsize(14) for _ in texts]
            [_.set_fontsize(14) for _ in autotexts]
        if filename == "Pie:GenerationFull":
            quantities = [
                processed["ME1:Cyl:FuelPh_in:mdot"].sum(),
                processed["ME2:Cyl:FuelPh_in:mdot"].sum(),
                processed["ME3:Cyl:FuelPh_in:mdot"].sum(),
                processed["ME4:Cyl:FuelPh_in:mdot"].sum(),
                processed["AE1:Cyl:FuelPh_in:mdot"].sum(),
                processed["AE2:Cyl:FuelPh_in:mdot"].sum(),
                processed["AE3:Cyl:FuelPh_in:mdot"].sum(),
                processed["AE4:Cyl:FuelPh_in:mdot"].sum(),
                processed["Steam:Boiler1:FuelPh_in:mdot"].sum()
            ]
            labels = [
                "ME1", "ME2", "ME3", "ME4", "AE1", "AE2", "AE3", "AE4", "AB"
            ]
            colors = [
                "0.33", "0.33", "0.33", "0.33", "0.66", "0.66", "0.66", "0.66",
                "black"
            ]
            ax.pie(quantities,
                   labels=labels,
                   explode=(0.05, ) * len(labels),
                   autopct='%1.1f%%',
                   colors=colors)

        if filename == "Pie:HeatDemand":
            quantities = []
            labels = []
            explode = []
            for demand in dict_structure["systems"]["Demands"]["units"][
                    "Heat"]["flows"]:
                quantities.append(processed[d2df("Demands", "Heat", demand,
                                                 "Edot")].sum())
                labels.append(demand)
                explode.append(0.05)
            ax.pie(quantities,
                   labels=labels,
                   explode=tuple(explode),
                   autopct='%1.1f%%',
                   shadow=True)

        if filename == "Pie:HeatGeneration":
            quantities = []
            quantities.append((processed["ME2:HRSG:Steam_in:mdot"] *
                               CONSTANTS["Steam"]["DH_STEAM"]).sum())
            quantities.append((processed["ME3:HRSG:Steam_in:mdot"] *
                               CONSTANTS["Steam"]["DH_STEAM"]).sum())
            quantities.append((processed["AE1:HRSG:Steam_in:mdot"] *
                               CONSTANTS["Steam"]["DH_STEAM"]).sum())
            quantities.append((processed["AE2:HRSG:Steam_in:mdot"] *
                               CONSTANTS["Steam"]["DH_STEAM"]).sum())
            quantities.append((processed["AE3:HRSG:Steam_in:mdot"] *
                               CONSTANTS["Steam"]["DH_STEAM"]).sum())
            quantities.append((processed["AE4:HRSG:Steam_in:mdot"] *
                               CONSTANTS["Steam"]["DH_STEAM"]).sum())
            quantities.append((processed["HTHR:HTHR13:HRWater_in:mdot"] *
                               CONSTANTS["General"]["CP_WATER"] *
                               (processed["HTHR:HTHR13:HRWater_out:T"] -
                                processed["HTHR:HTHR13:HRWater_in:T"])).sum())
            quantities.append((processed["HTHR:HTHR13:HRWater_in:mdot"] *
                               CONSTANTS["General"]["CP_WATER"] *
                               (processed["HTHR:HTHR24:HRWater_out:T"] -
                                processed["HTHR:HTHR24:HRWater_in:T"])).sum())
            quantities.append(
                (processed["Steam:Boiler1:Steam_HotWell_in:mdot"] *
                 CONSTANTS["Steam"]["DH_STEAM"]).sum())
            labels = [
                "HRSG - ME2", "HRSG - ME3", "HRSG - AE1", "HRSG - AE2",
                "HRSG - AE3", "HRSG - AE4", "HTHR - ER13", "HTHR - ER24",
                "Aux Boiler"
            ]
            explode = (0.05, ) * len(labels)
            colors = ("0.33", "0.33", "0.33", "0.33", "0.33", "0.33", "0.66",
                      "0.66", "1.0")
            ax.pie(quantities,
                   labels=labels,
                   explode=tuple(explode),
                   autopct='%1.1f%%',
                   shadow=True,
                   colors=colors)

        if filename == "Pie:OperationalMode":
            quantities = []
            labels = []
            colors = []
            temp = pd.Series(processed["operationalMode"].values,
                             dtype="category")
            for category in temp.cat.categories:
                quantities.append(sum(temp == category))
                labels.append(category)
                colors.append("gray")
            patches = ax.pie(quantities,
                             labels=labels,
                             explode=(0.05, 0.05, 0.05, 0.05),
                             autopct='%1.1f%%',
                             shadow=True,
                             colors=colors)[0]
            patches[0].set_hatch('/')
            patches[1].set_hatch('\\')
            patches[2].set_hatch('x')

        ### HISTOGRAMS ###

        if filename == "Hist:WHR":
            temp = processed["HTHR:HTHR13:HRWater_in:mdot"] * CONSTANTS[
                "General"]["CP_WATER"] * (
                    processed["HTHR:HTHR13:HRWater_out:T"] -
                    processed["HTHR:HTHR24:HRWater_in:T"])
            temp2 = (processed["ME2:HRSG:Steam_in:mdot"] *
                     CONSTANTS["Steam"]["DH_STEAM"] +
                     processed["ME3:HRSG:Steam_in:mdot"] *
                     CONSTANTS["Steam"]["DH_STEAM"] +
                     processed["AE1:HRSG:Steam_in:mdot"] *
                     CONSTANTS["Steam"]["DH_STEAM"] +
                     processed["AE2:HRSG:Steam_in:mdot"] *
                     CONSTANTS["Steam"]["DH_STEAM"] +
                     processed["AE3:HRSG:Steam_in:mdot"] *
                     CONSTANTS["Steam"]["DH_STEAM"] +
                     processed["AE4:HRSG:Steam_in:mdot"] *
                     CONSTANTS["Steam"]["DH_STEAM"])
            ax.hist(temp, 50, normed=1, alpha=0.5, label="HTHR")
            ax.hist(temp2, 50, normed=1, alpha=0.5, label="HRSG")
            plt.legend()

        if filename == "Hist:AuxEngines":
            temp1 = []
            for engine in {"AE1", "AE2", "AE3", "AE4"}:
                temp1.append(
                    processed[engine +
                              ":Cyl:Power_out:Edot"][processed[engine + ":on"]]
                    / CONSTANTS["AuxEngines"]["MCR"])
            ax.hist(tuple(temp1),
                    normed=False,
                    alpha=0.8,
                    label=["AE1", "AE2", "AE3", "AE4"])
            plt.legend()
            plt.xlabel("Engine load")
            plt.ylabel("Number of observations")

        if filename == "Hist:MainEngines":
            temp1 = []
            for engine in {"ME1", "ME2", "ME3", "ME4"}:
                temp1.append(
                    processed[engine +
                              ":Cyl:Power_out:Edot"][processed[engine + ":on"]]
                    / CONSTANTS["MainEngines"]["MCR"])
            ax.hist(tuple(temp1),
                    normed=False,
                    alpha=0.8,
                    label=["ME1", "ME2", "ME3", "ME4"])
            plt.legend()
            plt.xlabel("Engine load")
            plt.ylabel("Number of observations")

        ### SCATTER PLOTS ###

        if filename == "Scatter:Pmech_vs_Vship":
            enginesOn = processed["ME1:on"].astype(int) + processed[
                "ME2:on"].astype(int) + processed["ME3:on"].astype(
                    int) + processed["ME4:on"].astype(int)
            for idx in range(5):
                ax.scatter(dataset_raw["SHIPS SPEED:79025:knot:Average:900"][
                    enginesOn == idx],
                           processed["Demands:Mechanical:Total:Edot"][enginesOn
                                                                      == idx],
                           label=(str(idx) + "Engines on"))
            plt.legend()

        ### BAR CHARTS ###

        if filename == "Bar:PercentageWHR":
            # Exhaust gas
            Qdot_hrsg = 0
            Qdot_eg = 0
            Qdot_eg160 = 0
            Bdot_hrsg = 0
            Bdot_eg = 0
            Bdot_eg160diff = 0
            Qdot_hthr = (processed["HTHR:HTHR13:HRWater_out:Edot"] -
                         processed["HTHR:HTHR24:HRWater_in:Edot"]).sum()
            Qdot_ht = 0
            Qdot_lt = 0
            Bdot_hthr = (processed["HTHR:HTHR13:HRWater_out:Bdot"] -
                         processed["HTHR:HTHR24:HRWater_in:Bdot"]).sum()
            Bdot_ht = 0
            Bdot_lt = 0
            for system in {
                    "AE1", "AE2", "AE3", "AE4", "ME1", "ME2", "ME3", "ME4"
            }:
                # Exhaust gas, Energy
                if system in {"AE1", "AE2", "AE3", "AE4", "ME2", "ME3"}:
                    Qdot_hrsg = Qdot_hrsg + (
                        processed[system + ":HRSG:Steam_in:mdot"] *
                        CONSTANTS["Steam"]["DH_STEAM"]).sum()
                    Bdot_hrsg = Bdot_hrsg + (
                        processed[system + ":HRSG:Steam_out:Bdot"] -
                        processed[system + ":HRSG:Steam_in:Bdot"]).sum()
                Qdot_eg = Qdot_eg + processed[system +
                                              ":Turbine:Mix_out:Edot"].sum()
                Qdot_eg160 = Qdot_eg160 + (
                    processed[system + ":Turbine:Mix_out:mdot"] *
                    CONSTANTS["General"]["CP_EG"] *
                    (processed[system + ":Turbine:Mix_out:T"] - 160 -
                     273.15)).sum()
                # Exhaust gas, Exergy
                Bdot_eg = Bdot_eg + processed[system +
                                              ":Turbine:Mix_out:Bdot"].sum()
                Bdot_eg160diff = Bdot_eg160diff + (
                    processed[system + ":Turbine:Mix_out:mdot"] *
                    CONSTANTS["General"]["CP_EG"] * np.log(
                        (160 + 237.15) / (processed["T_0"])) *
                    ((160 + 237.15 - processed["T_0"]) / np.log(
                        (160 + 237.15) /
                        (processed["T_0"])) - processed["T_0"])).sum()
                # Heating systems, Energy
                Qdot_ht = Qdot_ht + (
                    processed[system + ":CAC_HT:HTWater_out:Edot"] -
                    processed[system + ":JWC:HTWater_in:Edot"]).sum()
                Qdot_lt = Qdot_lt + (
                    processed[system + ":LOC:LTWater_out:Edot"] -
                    processed[system + ":CAC_LT:LTWater_in:Edot"]).sum()
                # Heating systems, Exergy
                Bdot_ht = Bdot_ht + (
                    processed[system + ":CAC_HT:HTWater_out:Bdot"] -
                    processed[system + ":JWC:HTWater_in:Bdot"]).sum()
                Bdot_lt = Bdot_lt + (
                    processed[system + ":LOC:LTWater_out:Bdot"] -
                    processed[system + ":CAC_LT:LTWater_in:Bdot"]).sum()
            Bdot_eg160 = Bdot_eg - Bdot_eg160diff
            Qdot_cool = Qdot_ht + Qdot_lt
            Bdot_cool = Bdot_ht + Bdot_lt
            # Exhast gas, efficiencies
            eta_hrsg = Qdot_hrsg / Qdot_eg
            eta_hrsg160 = Qdot_hrsg / Qdot_eg160
            eps_hrsg = Bdot_hrsg / Bdot_eg
            eps_hrsg160 = Bdot_hrsg / Bdot_eg160
            # Cooling systems, efficiencies
            eta_hthr_ht = Qdot_hthr / Qdot_ht
            eta_hthr_lt = Qdot_hthr / Qdot_cool
            eps_hthr_ht = Bdot_hthr / Bdot_ht
            eps_hthr_lt = Bdot_hthr / Bdot_cool
            # Now we plot for real
            n_groups = 4
            bar_width = 0.4
            opacity = 0.4
            index = np.arange(n_groups)
            labels = ("HT water", "All cooling water",
                      "Exhaust Gas, to 160 degC",
                      "Exhaust gas, to environment")
            group1 = ax.bar(index,
                            [eta_hthr_ht, eta_hthr_lt, eta_hrsg160, eta_hrsg],
                            bar_width,
                            alpha=opacity,
                            color='b',
                            label="Energy-based efficiency")
            group2 = ax.bar(index + bar_width,
                            [eps_hthr_ht, eps_hthr_lt, eps_hrsg160, eps_hrsg],
                            bar_width,
                            alpha=opacity,
                            color='r',
                            label="Exergy-based efficiency")
            plt.ylabel('Proportion of available heat recovered')
            plt.xticks(index + bar_width / 2, labels, rotation=10)
            plt.legend()
        plt.show()
コード例 #15
0
def readMainEnginesExistingValues(raw, processed, CONSTANTS, hd):
    print("Started reading main engines raw values...", end="", flush=True)
    # This function only reads existing series. It does not do any pre-processing action.
    for system in CONSTANTS["General"]["NAMES"]["MainEngines"]:
        # Reading main engines exhaust gas temperature, TC inlet and outlet
        processed[d2df(system, "Cyl", "EG_out", "T")] = raw[hd[
            system +
            "-TC_EG_T_IN"]] + 273.15  # Measured before mixer with flow form bypass
        processed[d2df(system, "Turbine", "Mix_out", "T")] = raw[hd[
            system +
            "-TC_EG_T_OUT"]] + 273.15  # Measured after mixer with waste gate
        # Reading main engines exhaust gas temperature, after HRSG. Only two of the four main engines have the HRSG
        if system == "ME2" or system == "ME3":
            processed[d2df(system, "HRSG", "Mix_out",
                           "T")] = raw[hd[system + "-EGB_EG_T_OUT"]] + 273.15
            processed[d2df(system, "HRSG", "Mix_in",
                           "T")] = raw[hd[system + "-TC_EG_T_OUT"]] + 273.15
        # Temperature in the engine room, i.e. inlet to the compressor of the TC
        processed[d2df(system, "Comp", "Air_in",
                       "T")] = raw[hd["ER-FWD_AIR_T_"]] + 273.15
        # Reading the HT temperature before and after the main engine
        processed[d2df(system, "JWC", "HTWater_in",
                       "T")] = raw[hd[system + "-HT_FW_T_IN"]] + 273.15
        #processed[d2df(system, "CAC_HT", "HTWater_out", "T")] = raw[hd[system + "-HT_FW_T_OUT"]] + 273.15
        # Reading the LT temperature before the main engine
        processed[d2df(system, "CAC_LT", "LTWater_in",
                       "T")] = raw[hd[system + "-LT_FW_T_IN"]] + 273.15
        # Reading the Lubricating oil temperature before and after the Lubricating Oil Cooler (hence, In is higher)
        processed[d2df(system, "LOC", "LubOil_out",
                       "T")] = raw[hd[system + "-LOC_OIL_T_OUT"]] + 273.15
        # Reading fuel oil temperature before injection
        processed[d2df(system, "Cyl", "FuelPh_in",
                       "T")] = raw[hd[system + "-CYL_FUEL_T_IN"]] + 273.15
        # Reading charge air temperature, after the charge air cooler (or at cylinder inlet)
        processed[d2df(system, "CAC_LT", "Air_out",
                       "T")] = raw[hd[system + "-CAC_AIR_T_OUT"]] + 273.15
        # Reading Engine rpm
        processed[d2df(system, "Cyl", "Power_out",
                       "omega")] = raw[hd[system + "__RPM_"]]
        # Pressure of the charge air, at the compressor outlet (and, hence, at the cylinder inlet)
        processed[d2df(
            system, "Comp", "Air_out",
            "p")] = (raw[hd[system + "-CAC_AIR_P_OUT"]] + 1.01325) * 100000
        # Reading the pressure of the lubricating oil
        # processed[d2df(system, "LOC", "LubOil_out", "p")] = (raw[hd[system + "-LOC_OIL_P_IN"]] + 1.01325) * 100000
        # Reading the pressure in the cooling flows
        processed[d2df(
            system, "CAC_LT", "LTWater_in",
            "p")] = (raw[hd[system + "-LT-CAC_FW_P_IN"]] + 1.01325) * 100000
        processed[d2df(
            system, "JWC", "HTWater_in",
            "p")] = (raw[hd[system + "-HT-JWC_FW_P_IN"]] + 1.01325) * 100000
        # Reading turbocharger speed
        processed[d2df(system, "TCshaft", "Power_in",
                       "omega")] = raw[hd[system + "-TC__RPM_"]]
        processed[d2df(system, "TCshaft", "Power_out",
                       "omega")] = raw[hd[system + "-TC__RPM_"]]
        processed[d2df(system, "Turbine", "Power_out",
                       "omega")] = raw[hd[system + "-TC__RPM_"]]
        processed[d2df(system, "Compressor", "Power_in",
                       "omega")] = raw[hd[system + "-TC__RPM_"]]

    print("...done!")
    return processed
コード例 #16
0
def assumptions(raw, processed, CONSTANTS, hd):
    # This function includes generic assumed values in the main structure
    # ALL ENGINES
    for system in {"ME1", "ME2", "ME3", "ME4", "AE1", "AE2", "AE3", "AE4"}:
        # The pressure at the turbocharger air inlet and exhaust outlet is equal to the atmospheric pressure
        processed.loc[:,d2df(system,"Comp","Air_in","p")] = CONSTANTS["General"]["P_ATM"]
        processed.loc[:,d2df(system, "Turbine", "Mix_out", "p")] = CONSTANTS["General"]["P_ATM"]
        # Temperature in the engine room, i.e. inlet to the compressor of the TC
        processed[d2df(system, "Comp", "Air_in", "T")] = raw[hd["ER_AIR_T_"]] + 273.15
        # Assuming that the pressure in the exhaust gas is 90% of the pressure in the inlet manifold. Somewhat reasonable
        processed[d2df(system, "Cyl", "EG_out", "p")] = (0.98 * raw[hd[system + "-CAC_AIR_P_OUT"]] + 1.01325) * 100000
        # Assuming the pressure of the fuel to be around 9 barg, based on measurements from ME4
        processed.loc[:,d2df(system, "Cyl", "FuelPh_in", "p")] = (9 + 1.01325) * 10e5
        # Assuming the temperature of the cylinder wall to be 150 degC
        processed.loc[:,d2df(system, "Cyl", "QdotJW_out", "T")] = 150 + 273.15
        processed.loc[:,d2df(system, "JWC", "QdotJW_in", "T")] = 150 + 273.15
        # Assuming a temperature of 100 degC for heat losses from the TC shaft
        processed.loc[:,d2df(system, "TCshaft", "Losses_out", "T")] = 100 + 273.15
        # We assume the mixgin temperature at the LT inlet of the HT mixer to be constant
        processed.loc[:,d2df(system, "HTmerge", "LTWater_in", "T")] = CONSTANTS["MainEngines"]["T_COOLING_MIX"]
        if system in {"ME1", "ME2", "ME3", "ME4"}:
            processed.loc[:,d2df(system, "Cyl", "QdotRad_out", "Edot")] = 0.01 * CONSTANTS["MainEngines"]["MCR"]
        # Assuming the steam pressure and temperature in the HRSG to be constant...
        hrsg_pressure_assumption = (6 + 1.01325) * 100000
        # Adding radiative losses
        processed.loc[:, d2df(system, "Cyl", "QdotRad_out", "T")] = 100 + 273.15
        if system in {"AE1", "AE2", "AE3", "AE4"}:
            processed.loc[:,d2df(system, "AG", "Losses_out", "T")] = 100 + 273.15
            processed.loc[:,d2df(system, "Cyl", "Power_out", "omega")] = 750
            processed.loc[:, d2df(system, "Cyl", "QdotRad_out", "Edot")] = 0.01 * CONSTANTS["AuxEngines"]["MCR"]
    # Others
    processed.loc[:,"T_0"] = raw[hd["water_T_forsmark_smhi-opendata"]] + 273.15
    processed.loc[:,"T_air"] = raw[hd["air_T_sv_hogarna_smhi-opendata"]] + 273.15
    processed.loc[:,"ShipSpeed"] = raw[hd["SHIP_SPEED_KNOT_"]]
    processed[d2df("CoolingSystems","SWC13","SeaWater_out","T")] = raw[hd["SWC13_SW_T_OUT"]] + 273.15 # CHECK IF IT IS IN OR OUT
    processed[d2df("CoolingSystems","SWC24","SeaWater_out","T")] = raw[hd["SWC24_SW_T_OUT"]] + 273.15 # CHECK IF IT IS IN OR OUT
    # Boilers
    processed.loc[:, "Steam:Boiler1:EG_out:p"] = 101325 + 10000
    processed.loc[:, "Steam:Boiler1:Air_in:T"] = raw[hd["ER_AIR_T_"]] + 273.15
    processed.loc[:, "Steam:Boiler1:Air_in:p"] = 101325
    # HTHR system
    processed.loc[:,"HTHR:SteamHeater:HRWater_out:T"] = 90 + 273.15 # From the heat balance, the temperature needs to rise at 90 degrees
    # processed.loc[:,"HTHR:SteamHeater:HRWater_out:mdot"] = 298 / 3600 * CONSTANTS["General"]["RHO_W"] # the original value is in m3/h
    processed.loc[:,"HTHR:HTHR24:HRWater_in:T"] = CONSTANTS["OtherUnits"]["HEAT_DEMAND"]["HTHR_INLET_TEMPERATURE"] # Assumption on the Temperature at the HTHR-24 inlet (HT side)
    processed.loc[:, "HTHR:HVACpreheater:Qdot_out:T"] = (50 - 23) / np.log((50+273.15)/(23+273.15))
    processed.loc[:, "HTHR:HVACreheater:Qdot_out:T"] = (80 - 60) / np.log((80 + 273.15) / (60 + 273.15))
    processed.loc[:, "HTHR:HotWaterHeater:Qdot_out:T"] = 70 + 273.15
    processed.loc[:, "Steam:TankHeating:Qdot_out:T"] = 60 + 273.15
    processed.loc[:, "Steam:MachinerySpaceHeaters:Qdot_out:T"] = processed["HTHR:HVACpreheater:Qdot_out:T"]
    processed.loc[:, "Steam:Galley:Qdot_out:T"] = 90 + 273.15
    processed.loc[:, "Steam:OtherTanks:Qdot_out:T"] = 60 + 273.15
    processed.loc[:, "Steam:HFOtankHeating:Qdot_out:T"] = 75 + 273.15 # some sort of average value...
    processed.loc[:, "Steam:HFOheater:Qdot_out:T"] = (110 - 75) / np.log((110 + 273.15) / (75 + 273.15))
    return processed
コード例 #17
0
def engineCoolingSystemsCalculation(processed, CONSTANTS, engine_type):
    print("Started calculating analysis for {} cooling systems...".format(engine_type), end="", flush=True)
    # This function calculates the different flows related to the cooling systems of the main engines.
    for system in CONSTANTS["General"]["NAMES"][engine_type]:
        # Calculating the total energy flow going to the cooling systems, based on the energy balance on the engine
        energy_2_cooling = (processed[d2df(system,"Cyl","FuelCh_in","Edot")] +
            CONSTANTS["General"]["HFO"]["CP"] * processed[d2df(system,"Cyl","FuelPh_in","mdot")] * (processed[d2df(system,"Cyl","FuelPh_in","T")] - processed["T_0"]) -
            processed[d2df(system, "Cyl", "Power_out", "Edot")] -
            processed[d2df(system,"Turbine","Mix_out","Edot")] +
            processed[d2df(system,"Comp","Air_in","Edot")] -
            processed[d2df(system, "Cyl", "QdotRad_out", "Edot")])
        # Calculating the energy going to the charge air cooler, based on the estimated temperatures on the air line
        energy_2_cac = CONSTANTS["General"]["CP_AIR"] * processed[d2df(system,"Cyl","Air_in","mdot")] * (processed[d2df(system,"Comp","Air_out","T")] - processed[d2df(system,"Cyl","Air_in","T")])
        # Calculating the energy going to the HT cooling systems, based on interpolation from the project guide
        energy_2_ht_theoric = processed[system+":"+"load"].apply(polyvalHelperFunction,args=(CONSTANTS[engine_type]["POLY_LOAD_2_QDOT_HT"],)) * CONSTANTS[engine_type]["QDOT_HT_DES"]
        energy_2_lt_theoric = processed[system+":"+"load"].apply(polyvalHelperFunction,args=(CONSTANTS[engine_type]["POLY_LOAD_2_QDOT_LT"],)) * CONSTANTS[engine_type]["QDOT_LT_DES"]
        # The values calculated based on the project guide are reconciled based on the energy balance
        energy_2_ht = energy_2_cooling * energy_2_ht_theoric / (energy_2_ht_theoric + energy_2_lt_theoric)
        energy_2_ht[energy_2_ht.isnull()] = 0
        energy_2_lt = energy_2_cooling - energy_2_ht
        # The energy going to the CAC, HT stage is calculated assuming a 85% effectiveness of the heat exchanger
        energy_2_cac_ht = CONSTANTS[engine_type]["EPS_CAC_HTSTAGE"] * processed[d2df(system,"Comp","Air_in","mdot")] * CONSTANTS["General"]["CP_AIR"] * (
            processed[d2df(system,"Comp","Air_out","T")] - processed[d2df(system,"JWC","HTWater_in","T")])
        energy_2_cac_ht[energy_2_cac_ht<0] = 0
        # The energy going to the CAC, LT stage results as a consequence by thermal balance over the CAC
        energy_2_cac_lt = energy_2_cac - energy_2_cac_ht
        # The energy to the JWC results as a balance over the HT cooling systems
        # energy_2_jwc = energy_2_ht - energy_2_cac_ht
        energy_2_jwc = (energy_2_cooling - energy_2_cac) / 2
        processed[d2df(system,"JWC","QdotJW_in","Edot")] = energy_2_jwc
        processed[d2df(system, "Cyl", "QdotJW_out", "Edot")] = energy_2_jwc
        # The energy to the LOC results as a balance over the LT cooling systems
        # energy_2_loc = energy_2_lt - energy_2_cac_lt
        energy_2_loc = (energy_2_cooling - energy_2_cac) / 2
        # Finally, the temperatures in the flows are calculated based on the calculated energy and mass flow values
        # For LT, first we have the CAC, then the LOC
        processed[d2df(system,"CAC_LT","LTWater_out","T")] = processed[d2df(system,"CAC_LT","LTWater_in","T")] + energy_2_cac_lt / processed[d2df(system,"CAC_LT","LTWater_out","mdot")] / CONSTANTS["General"]["CP_WATER"]
        processed[d2df(system,"LOC","LTWater_out","T")] = processed[d2df(system,"CAC_LT","LTWater_out","T")] + energy_2_loc / processed[d2df(system,"LOC","LTWater_out","mdot")] / CONSTANTS["General"]["CP_WATER"]
        # For HT, first we have the JWC, then the CAC, HT
        processed[d2df(system,"JWC","HTWater_out","T")] = processed[d2df(system,"JWC","HTWater_in","T")] + energy_2_jwc / processed[d2df(system,"JWC","HTWater_out","mdot")] / CONSTANTS["General"]["CP_WATER"]
        processed[d2df(system,"CAC_HT","HTWater_out","T")] = processed[d2df(system,"JWC","HTWater_out","T")] + energy_2_cac_ht / processed[d2df(system,"CAC_HT","HTWater_out","mdot")] / CONSTANTS["General"]["CP_WATER"]
        # For the LOC, we know the outlet (lower) temperature, we calculate the inlet temperature
        processed[d2df(system,"LOC","LubOil_in","T")] = processed[d2df(system,"LOC","LubOil_out","T")] + energy_2_loc / processed[d2df(system,"LOC","LubOil_out","mdot")] / CONSTANTS["General"]["CP_LO"]
        # Now calculating the temperature of the air in the charge air cooler
        processed[d2df(system, "CAC_HT", "Air_out", "T")] = processed[d2df(system, "Comp", "Air_out", "T")] - energy_2_cac_ht / processed[d2df(system,"Cyl","Air_in","mdot")] / CONSTANTS["General"]["CP_AIR"]
        processed[d2df(system, "CAC_LT", "Air_out", "T")] = processed[d2df(system, "CAC_HT", "Air_out", "T")] - energy_2_cac_lt / processed[d2df(system, "Cyl", "Air_in", "mdot")] / CONSTANTS["General"]["CP_AIR"]
        # Finally, we have the HRSG (for some cases)
        if system == "ME1":
            aaa = 0
        if engine_type == "AuxEngines" or system in {"ME2", "ME3"}:
            processed[d2df(system,"HRSG","Steam_in","mdot")] = ((processed[d2df(system,"HRSG","Mix_in","h")] - processed[d2df(system,"HRSG","Mix_out","h")]) *
                processed[d2df(system, "HRSG", "Mix_in", "mdot")]  /
                (CONSTANTS["Steam"]["H_STEAM_VS"] - CONSTANTS["Steam"]["H_STEAM_LS"]))
            processed.loc[processed[d2df(system, "HRSG", "Steam_in", "mdot")]<0, d2df(system, "HRSG", "Steam_in", "mdot")] = 0
        # Calculation of the mass recirculating from the LT outlet to the HT inlet (not exactly...)
        processed[d2df(system, "HTmerge", "LTWater_in", "mdot")] = processed[d2df(system,"JWC","HTWater_out","mdot")] * (
            processed[d2df(system, "CAC_HT", "HTWater_out", "T")] - processed[d2df(system,"JWC","HTWater_in","T")]) / (
            processed[d2df(system, "CAC_HT", "HTWater_out", "T")] - CONSTANTS[engine_type]["T_COOLING_MIX"])
    print("...done!")
    return processed
コード例 #18
0
def propertyCalculator(processed, dict_structure, CONSTANTS, system_list):
    print("Started calculating flow properties...", end="", flush=True)
    df_index = processed.index
    for system in system_list:
        for unit in dict_structure["systems"][system]["units"]:
            for flow in dict_structure["systems"][system]["units"][unit][
                    "flows"]:
                if system + ":" + unit + ":" + flow == "Steam:Boiler1:Air_in":
                    aaa = 0
                #  The calculation of the properties is done if and only if the exergy flow is completely empty
                if processed[d2df(system, unit, flow,
                                  "Bdot")].isnull().sum() == len(
                                      processed[d2df(system, unit, flow,
                                                     "Bdot")]):
                    if dict_structure["systems"][system]["units"][unit][
                            "flows"][flow]["type"] == "CPF":
                        # Only doing the calculations if the values for p and T are not NaN
                        if processed[d2df(system, unit, flow,
                                          "T")].isnull().sum() != len(
                                              processed[d2df(
                                                  system, unit, flow, "T")]):
                            temp = processed[d2df(system, unit, flow,
                                                  "T")]  # .values()
                            press = processed[d2df(system, unit, flow,
                                                   "p")]  # .values()
                            # If the specific enthalpy is available already, it needs to be calculated
                            if ("Air" in flow) or ("BP" in flow):
                                # print("Calculating properties for " + system + "_" + unit + "_" + flow)
                                # dh = pd.Series(cp.PropsSI('H','T',np.array(temp),'P',np.array(press), 'Air.mix'), index=df_index) - pd.Series(cp.PropsSI('H', 'T', np.array(processed["T_0"]), 'P', CONSTANTS["General"]["P_ATM"], 'Air.mix'), index=df_index)
                                # ds = pd.Series(cp.PropsSI('S', 'T', np.array(temp), 'P', np.array(press), 'Air.mix'), index=df_index) - pd.Series(cp.PropsSI('S', 'T', np.array(processed["T_0"]), 'P', CONSTANTS["General"]["P_ATM"], 'Air.mix'), index=df_index)
                                R = CONSTANTS["General"]["R_0"] / 29
                                dh = (
                                    pd.Series(enthalpyCalculator(
                                        np.array(temp), CONSTANTS),
                                              index=df_index) -
                                    pd.Series(enthalpyCalculator(
                                        np.array(processed["T_0"]), CONSTANTS),
                                              index=df_index))
                                ds = (
                                    pd.Series(entropyCalculator(
                                        np.array(temp), CONSTANTS),
                                              index=df_index) -
                                    pd.Series(entropyCalculator(
                                        np.array(processed["T_0"]), CONSTANTS),
                                              index=df_index) -
                                    R * np.log(
                                        np.array(press) /
                                        CONSTANTS["General"]["P_ATM"]))
                            elif ("Mix" in flow) or ("EG" in flow):
                                if system in CONSTANTS["General"]["NAMES"][
                                        "MainEngines"].union(
                                            CONSTANTS["General"]["NAMES"]
                                            ["AuxEngines"]):
                                    mixture = ppo.mixtureCompositionNew(
                                        processed[d2df(system, unit, flow,
                                                       "mdot")],
                                        processed[d2df(system, "Cyl",
                                                       "FuelPh_in", "mdot")],
                                        processed[d2df(system, "Cyl",
                                                       "FuelPh_in",
                                                       "T")], CONSTANTS)
                                elif system == "Steam":
                                    mixture = ppo.mixtureCompositionNew(
                                        processed[d2df(system, unit, flow,
                                                       "mdot")],
                                        processed[d2df(system, "Boiler1",
                                                       "FuelPh_in", "mdot")],
                                        processed[d2df(system, "Boiler1",
                                                       "FuelPh_in",
                                                       "T")], CONSTANTS)
                                R = CONSTANTS["General"]["R_0"] * sum(
                                    mixture[idx] /
                                    CONSTANTS["General"]["MOLAR_MASSES"][idx]
                                    for idx in {"N2", "O2", "CO2", "H2O"})
                                dh = pd.Series(enthalpyCalculator(
                                    np.array(temp), CONSTANTS, mixture),
                                               index=df_index) - pd.Series(
                                                   enthalpyCalculator(
                                                       np.array(
                                                           processed["T_0"]),
                                                       CONSTANTS, mixture),
                                                   index=df_index)
                                ds = pd.Series(
                                    entropyCalculator(np.array(temp),
                                                      CONSTANTS, mixture),
                                    index=df_index) - pd.Series(
                                        entropyCalculator(
                                            np.array(processed["T_0"]),
                                            CONSTANTS, mixture),
                                        index=df_index) - (R * np.log(
                                            np.array(press) /
                                            CONSTANTS["General"]["P_ATM"]))
                            #elif "Steam" in flow:
                            #    if "in" in flow:
                            #    dh = CONSTANTS["Steam"]["DH_STEAM"] + CONSTANTS["General"]["CP_WATER"] * (processed[d2df(system, unit, flow, "T")] - processed["T_0"])
                            #    ds = CONSTANTS["Steam"]["DS_STEAM"] + CONSTANTS["General"]["CP_WATER"] * np.log((processed[d2df(system, unit, flow, "T")] / processed["T_0"]))
                            #elif "out" in flow:
                            #    dh = CONSTANTS["General"]["CP_WATER"] * (processed[d2df(system, unit, flow, "T")] - processed["T_0"])
                            #    ds = CONSTANTS["General"]["CP_WATER"] * np.log((processed[d2df(system, unit, flow, "T")] / processed["T_0"]))
                            if system + ":" + unit + ":on" in processed.keys():
                                dh.loc[~processed[system + ":" + unit +
                                                  ":on"]] = 0
                                ds.loc[~processed[system + ":" + unit +
                                                  ":on"]] = 0
                            processed[d2df(system, unit, flow, "h")] = dh
                            processed[d2df(system, unit, flow,
                                           "b")] = dh - processed["T_0"] * ds
                            processed[d2df(system, unit, flow,
                                           "Edot")] = processed[d2df(
                                               system, unit, flow,
                                               "mdot")] * processed[d2df(
                                                   system, unit, flow, "h")]
                            processed[d2df(system, unit, flow,
                                           "Bdot")] = processed[d2df(
                                               system, unit, flow,
                                               "mdot")] * processed[d2df(
                                                   system, unit, flow, "b")]
                        else:
                            pass
                            # print("Couldn't calculate the properties for the {} flow, didn't have all what I needed, {}% of the values are NaN".format(system+":"+unit+":"+flow, processed[d2df(system,unit,flow,"T")].isnull().sum()/len(processed[d2df(system,unit,flow,"T")])*100))
                    elif dict_structure["systems"][system]["units"][unit][
                            "flows"][flow]["type"] == "IPF":
                        if processed[d2df(system, unit, flow,
                                          "T")].isnull().sum() != len(
                                              processed[d2df(
                                                  system, unit, flow, "T")]):
                            if "Water" in flow:
                                if flow == "SeaWater_in":
                                    dh = pd.Series(index=df_index)
                                    ds = pd.Series(index=df_index)
                                    dh[:] = 0
                                    ds[:] = 0
                                dh = CONSTANTS["General"]["CP_WATER"] * (
                                    processed[d2df(system, unit, flow, "T")] -
                                    processed["T_0"])
                                ds = CONSTANTS["General"]["CP_WATER"] * np.log(
                                    (processed[d2df(system, unit, flow, "T")] /
                                     processed["T_0"]))
                            if "LubOil" in flow:
                                dh = CONSTANTS["General"]["CP_LO"] * (
                                    processed[d2df(system, unit, flow, "T")] -
                                    processed["T_0"])
                                ds = CONSTANTS["General"]["CP_LO"] * np.log(
                                    (processed[d2df(system, unit, flow, "T")] /
                                     processed["T_0"]))
                            if "Fuel" in flow:
                                dh = CONSTANTS["General"]["HFO"]["CP"] * (
                                    processed[d2df(system, unit, flow, "T")] -
                                    processed["T_0"])
                                ds = CONSTANTS["General"]["HFO"]["CP"] * np.log(
                                    (processed[d2df(system, unit, flow, "T")] /
                                     processed["T_0"]))
                            if system + ":" + unit + ":on" in processed.keys():
                                dh.loc[~processed[system + ":" + unit +
                                                  ":on"]] = 0
                                ds.loc[~processed[system + ":" + unit +
                                                  ":on"]] = 0
                            processed[d2df(system, unit, flow, "h")] = dh
                            processed[d2df(system, unit, flow,
                                           "b")] = dh - processed["T_0"] * ds
                            processed[d2df(system, unit, flow,
                                           "Edot")] = processed[d2df(
                                               system, unit, flow,
                                               "mdot")] * processed[d2df(
                                                   system, unit, flow, "h")]
                            processed[d2df(system, unit, flow,
                                           "Bdot")] = processed[d2df(
                                               system, unit, flow,
                                               "mdot")] * processed[d2df(
                                                   system, unit, flow, "b")]
                        else:
                            pass
                            #print("Couldn't calculate the properties for the {} flow, didn't have all what I needed, {}% of the values are NaN".format(system + ":" + unit + ":" + flow, processed[d2df(system,unit,flow,"T")].isnull().sum()/len(processed[d2df(system,unit,flow,"T")])*100))
                    elif dict_structure["systems"][system]["units"][unit][
                            "flows"][flow]["type"] == "SF":
                        if dict_structure["systems"][system]["units"][unit][
                                "flows"][flow]["state"] == "SL":
                            dh = CONSTANTS["Steam"]["H_STEAM_LS"] - CONSTANTS[
                                "General"]["CP_WATER"] * (processed["T_0"] -
                                                          273.15)
                            ds = CONSTANTS["Steam"]["S_STEAM_LS"] - CONSTANTS[
                                "General"]["CP_WATER"] * np.log(
                                    processed["T_0"] / 273.15)
                        elif dict_structure["systems"][system]["units"][unit][
                                "flows"][flow]["state"] == "SV":
                            dh = CONSTANTS["Steam"]["H_STEAM_VS"] - CONSTANTS[
                                "General"]["CP_WATER"] * (processed["T_0"] -
                                                          273.15)
                            ds = CONSTANTS["Steam"]["S_STEAM_VS"] - CONSTANTS[
                                "General"]["CP_WATER"] * np.log(
                                    processed["T_0"] / 273.15)
                        else:
                            print(
                                "Steam can be either saturated liquid or saturated vapor, nothing in between"
                            )
                        processed[d2df(system, unit, flow, "h")] = dh
                        processed[d2df(system, unit, flow,
                                       "b")] = dh - processed["T_0"] * ds
                        processed[d2df(
                            system, unit, flow, "Edot")] = processed[d2df(
                                system, unit, flow, "mdot")] * processed[d2df(
                                    system, unit, flow, "h")]
                        processed[d2df(
                            system, unit, flow, "Bdot")] = processed[d2df(
                                system, unit, flow, "mdot")] * processed[d2df(
                                    system, unit, flow, "b")]
                    elif dict_structure["systems"][system]["units"][unit][
                            "flows"][flow]["type"] == "Qdot":
                        processed[d2df(
                            system, unit, flow, "Bdot")] = processed[d2df(
                                system, unit, flow, "Edot")] * (
                                    1 - processed["T_0"] /
                                    processed[d2df(system, unit, flow, "T")])
                    elif dict_structure["systems"][system]["units"][unit][
                            "flows"][flow]["type"] in {"Wdot", "CEF"}:
                        processed[d2df(system, unit, flow,
                                       "Bdot")] = processed[d2df(
                                           system, unit, flow, "Edot")]
    print("...done!")
    return processed
コード例 #19
0
def mainEngineAirFlowCalculation(raw, processed, dict_structure, CONSTANTS):
    print("Started calculating main engine air and exhaust flows...",
          end="",
          flush=True)
    # This function calculates the different air and exhaust gas flows in the main engines, taking into account the
    # presence of air bypass and exhaust wastegate valves
    for system in CONSTANTS["General"]["NAMES"]["MainEngines"]:
        # Calculating the compressor's compression ratio
        beta_comp = processed[d2df(system, "Comp", "Air_out",
                                   "p")] / processed[d2df(
                                       system, "Comp", "Air_in", "p")]
        # Calculating the turbocharger's mechancial efficiency based on the regression
        eta_tc = (
            processed[d2df(system, "TCshaft", "Power_in", "omega")] /
            CONSTANTS["MainEngines"]["RPM_TC_DES"]).apply(
                polyvalHelperFunction,
                args=(CONSTANTS["MainEngines"]["POLY_TC_RPM_2_ETA_MECH"], ))
        #  Calculating the compressor isentropic efficiency
        comp_isentropic_efficiency = beta_comp.apply(
            polyvalHelperFunction,
            args=(CONSTANTS["MainEngines"]["POLY_PIN_2_ETA_IS"], ))
        # Calculating the temperature after the compressor, based on ideal gas assumption
        T_Comp_out_iso = processed[d2df(
            system, "Comp", "Air_in", "T")] * beta_comp**(
                (CONSTANTS["General"]["K_AIR"] - 1) /
                CONSTANTS["General"]["K_AIR"])
        T_Comp_out = processed[d2df(
            system, "Comp", "Air_in", "T")] + (T_Comp_out_iso - processed[d2df(
                system, "Comp", "Air_in", "T")]) / comp_isentropic_efficiency
        #### NOTE: HERE WE MAKE THE ASSUMPTION THAT THE COMPRESSOR OUTLET TEMPERATURE CANNOT BE LOWER THAN THE CYLINDER INLET TEMPERATURE
        T_Comp_out[T_Comp_out < processed[d2df(
            system, "Cyl", "Air_in", "T")]] = processed.loc[
                T_Comp_out < processed[d2df(system, "Cyl", "Air_in", "T")],
                d2df(system, "Cyl", "Air_in", "T")]
        processed[d2df(system, "Comp", "Air_out", "T")] = T_Comp_out
        # Calculating the air inflow aspired by the cylinder: calculated as inlet air density times the maximum volume,
        # times the engine speed
        processed[d2df(
            system, "Cyl", "Air_in",
            "mdot")] = CONSTANTS["MainEngines"]["AIR_FLOW_MULT"] * CONSTANTS[
                "MainEngines"]["V_MAX"] * (processed[d2df(
                    system, "Comp", "Air_out", "p")]) / (
                        CONSTANTS["General"]["R_AIR"] *
                        processed[d2df(system, "Cyl", "Air_in", "T")]
                    ) * (processed[d2df(system, "Cyl", "Power_out", "omega")] /
                         60 / 2 * CONSTANTS["General"]["ETA_VOL"]) * (
                             CONSTANTS["MainEngines"]["N_CYL"])
        processed[d2df(system, "Cyl", "EG_out", "mdot")] = processed[d2df(
            system, "Cyl", "Air_in", "mdot")] + processed[d2df(
                system, "Cyl", "FuelPh_in", "mdot")]
        # Calculating the bypass flow
        #processed[d2df(system,"BPsplit","BP_out","mdot")] = (
        #    CONSTANTS["General"]["CP_AIR"] * processed[d2df(system,"Cyl","Air_in","mdot")] * (processed[d2df(system,"Comp","Air_out","T")] - processed[d2df(system,"Comp","Air_in","T")]) +
        #   CONSTANTS["General"]["CP_EG"] * CONSTANTS["MainEngines"]["ETA_MECH_TC"] * (processed[d2df(system,"Cyl","Air_in","mdot")] + processed[d2df(system,"Cyl","FuelPh_in","mdot")]) *
        #    (processed[d2df(system,"Turbine","Mix_out","T")] - processed[d2df(system,"Cyl","EG_out","T")])) / (
        #    CONSTANTS["General"]["CP_AIR"] * (
        #        processed[d2df(system,"Comp","Air_in","T")] - CONSTANTS["MainEngines"]["ETA_MECH_TC"] * processed[d2df(system,"Turbine","Mix_out","T")] -
        #        (CONSTANTS["MainEngines"]["ETA_MECH_TC"] - 1) * processed[d2df(system,"Comp","Air_out","T")]))
        num1 = eta_tc * processed[d2df(
            system, "Cyl", "EG_out",
            "mdot")] * CONSTANTS["General"]["CP_EG"] * (
                processed[d2df(system, "Cyl", "EG_out", "T")] -
                processed[d2df(system, "Turbine", "Mix_out", "T")])
        num2 = processed[d2df(
            system, "Cyl", "Air_in",
            "mdot")] * CONSTANTS["General"]["CP_AIR"] * (
                processed[d2df(system, "Comp", "Air_out", "T")] -
                processed[d2df(system, "Comp", "Air_in", "T")])
        den1 = CONSTANTS["General"]["CP_AIR"] * (
            processed[d2df(system, "Comp", "Air_out", "T")] -
            processed[d2df(system, "Comp", "Air_in", "T")])
        den2 = eta_tc * CONSTANTS["General"]["CP_AIR"] * (
            processed[d2df(system, "Turbine", "Mix_out", "T")] -
            processed[d2df(system, "Comp", "Air_out", "T")])
        processed[d2df(system, "BPsplit", "BP_out",
                       "mdot")] = (num1 - num2) / (den1 + den2)
        # Calculating the temperature of the mixture after the merge between bypass and exhaust gas from the cylinders
        processed[d2df(
            system, "Turbine", "Mix_in",
            "T")] = (processed[d2df(system, "BPsplit", "BP_out", "mdot")] *
                     CONSTANTS["General"]["CP_AIR"] *
                     processed[d2df(system, "Comp", "Air_out", "T")] +
                     processed[d2df(system, "Cyl", "EG_out", "mdot")] *
                     CONSTANTS["General"]["CP_EG"] *
                     processed[d2df(system, "Cyl", "EG_out", "T")]) / (
                         processed[d2df(system, "Cyl", "EG_out", "mdot")] *
                         CONSTANTS["General"]["CP_EG"] +
                         processed[d2df(system, "BPsplit", "BP_out", "mdot")] *
                         CONSTANTS["General"]["CP_AIR"])
        # The air mass flow going through the compressor is equal to the sum of the air flow through the bypass valve and to the cylinders
        processed[d2df(system, "BPsplit", "Air_in", "mdot")] = processed[d2df(
            system, "BPsplit", "BP_out", "mdot")] + processed[d2df(
                system, "Cyl", "Air_in", "mdot")]
        # The flow through the turbine is equal to the sum of the bypass flow and the exhaust coming from the cylinders
        processed[d2df(system, "BPmerge", "Mix_out", "mdot")] = processed[d2df(
            system, "BPsplit", "BP_out", "mdot")] + processed[d2df(
                system, "Cyl", "EG_out", "mdot")]
        # Assiging the mass flow values for the HRSGs otherwise it makes a mess
        if system in {"ME2", "ME3"}:
            processed[d2df(system, "HRSG", "Mix_in",
                           "mdot")] = processed[d2df(system, "BPmerge",
                                                     "Mix_out", "mdot")]
            processed[d2df(system, "HRSG", "Mix_out",
                           "mdot")] = processed[d2df(system, "BPmerge",
                                                     "Mix_out", "mdot")]

    print("...done!")
    return processed
コード例 #20
0
def seaWaterCoolers(processed, CONSTANTS, dict_structure):
    # Calculations for the seaWaterCoolers
    processed[d2df("CoolingSystems", "SWC13", "SeaWater_in", "T")] = processed.loc[:, "T_0"]  # Inlet temperature equal to the sea water temperature
    processed[d2df("CoolingSystems", "SWC24", "SeaWater_in", "T")] = processed.loc[:, "T_0"]  # Inlet temperature equal to the sea water temperature
    dT_13 = processed[d2df("CoolingSystems", "SWC13", "SeaWater_out", "T")] - processed[d2df("CoolingSystems", "SWC13", "SeaWater_in", "T")]
    dT_13[dT_13 < 5] = 5
    dT_24 = processed[d2df("CoolingSystems", "SWC24", "SeaWater_out", "T")] - processed[d2df("CoolingSystems", "SWC24", "SeaWater_in", "T")]
    dT_24[dT_24 < 5] = 5
    processed[d2df("CoolingSystems", "SWC13", "SeaWater_in", "mdot")] = (
        processed[d2df("CoolingSystems", "SWC13", "LTWater_out", "mdot")] *
        (processed[d2df("CoolingSystems", "SWC13", "LTWater_in", "T")] - processed[d2df("CoolingSystems", "SWC13", "LTWater_out", "T")]) /
        (dT_13))
    processed[d2df("CoolingSystems", "SWC13", "SeaWater_out", "mdot")] = processed[d2df("CoolingSystems", "SWC13", "SeaWater_in", "mdot")]
    processed[d2df("CoolingSystems", "SWC24", "SeaWater_in", "mdot")] = (
        processed[d2df("CoolingSystems", "SWC24", "LTWater_out", "mdot")] *
        (processed[d2df("CoolingSystems", "SWC24", "LTWater_in", "T")] - processed[d2df("CoolingSystems", "SWC24", "LTWater_out", "T")]) /
        (dT_24))
    processed[d2df("CoolingSystems", "SWC24", "SeaWater_out", "mdot")] = processed[d2df("CoolingSystems", "SWC24", "SeaWater_in", "mdot")]
    # Extra calls to the mass balance calculation function to make sure all values are calculated
    (counter, processed) = ff.massFill(processed, dict_structure, CONSTANTS, "CoolingSystems", "SWC13", dict_structure["systems"]["CoolingSystems"]["units"]["SWC13"]["streams"], "extra-1")
    processed[d2df("CoolingSystems", "LTcollector13", "LTWater_out", "mdot")] = processed[d2df("CoolingSystems", "SWC13", "LTWater_in", "mdot")]
    (counter, processed) = ff.massFill(processed, dict_structure, CONSTANTS, "CoolingSystems", "LTcollector13", dict_structure["systems"]["CoolingSystems"]["units"]["LTcollector13"]["streams"],"extra-1")
    processed[d2df("CoolingSystems", "LTHTmerge13", "LTWater_in", "mdot")] = processed[d2df("CoolingSystems", "LTcollector13", "HTWater_out", "mdot")]
    return processed
コード例 #21
0
def predefinedTables(processed, name, CONSTANTS, dict_structure, system,
                     load_vector):
    file = open(CONSTANTS["filenames"]["latex_table"], "w")
    if name == "MainEnginesModel":
        for unit in dict_structure["systems"]["ME1"]["units"]:
            for flow in dict_structure["systems"]["ME1"]["units"][unit][
                    "flows"]:
                if dict_structure["systems"]["ME1"]["units"][unit]["flows"][
                        flow]["type"] in {"IPF", "CPF"}:
                    for property in {"T", "mdot"}:
                        value = []
                        for load in [0.3, 0.5, 0.7, 0.9]:
                            if property == "T":
                                rounding = 1
                            else:
                                rounding = 2
                            value.append(
                                round(
                                    processed[d2df("ME1", unit, flow,
                                                   property)]
                                    [(processed["ME1:load"] < load + 0.005)
                                     & (processed["ME1:load"] > load -
                                        0.005)].mean(), rounding))
                        print(property + "_" + unit + "_" + flow + " = " +
                              str(value[0]) + " & " + str(value[1]) + " & " +
                              str(value[2]) + " & " + str(value[3]) + " \\\\ ")

    if name == "MainEnginesEnergyFlows":
        df = pd.DataFrame(index=processed.index)
        df["Wdot_mech"] = processed[d2df(system, "Cyl", "Power_out", "Edot")]
        df["Qdot_eg"] = processed[d2df(system, "Turbine", "Mix_out", "Edot")]
        df["Qdot_jwc"] = processed[d2df(system, "Cyl", "QdotJW_out", "Edot")]
        df["Qdot_loc"] = processed[d2df(
            system, "LOC", "LTWater_out", "Edot")] - processed[d2df(
                system, "LOC", "LTWater_in", "Edot")]
        df["Qdot_caclt"] = processed[d2df(
            system, "CAC_LT", "LTWater_out", "Edot")] - processed[d2df(
                system, "CAC_LT", "LTWater_in", "Edot")]
        df["Qdot_cacht"] = processed[d2df(
            system, "CAC_HT", "HTWater_out", "Edot")] - processed[d2df(
                system, "CAC_HT", "HTWater_in", "Edot")]
        df["Qdot_ht"] = df["Qdot_cacht"] + df["Qdot_jwc"]
        df["Qdot_lt"] = df["Qdot_caclt"] + df["Qdot_loc"]
        output = {}
        load_vector = [0.3, 0.5, 0.7, 0.9]
        for flow in df.keys():
            output[flow] = []
            string = flow + " = "
            for load in load_vector:
                value = round(
                    df[flow][(processed[system + ":load"] < load + 0.005) & (
                        processed[system + ":load"] > load - 0.005)].mean(), 0)
                output[flow].append(value)
                string = string + " & " + str(value)
            print(string)
        plt.figure()
        for flow in output:
            plt.plot(load_vector, output[flow], label=flow)
        plt.xlabel("Engine load")
        plt.ylabel("Energy flow [kW]")
        plt.legend()
        plt.grid()
コード例 #22
0
ファイル: Main.py プロジェクト: tungu/Ecos2015PaperExtension
                     ["TimeSeries:HeatGenerationStacked"])

# processed = ea.efficiencyCalculator(processed, dict_structure, CONSTANTS)

## PLAYGROUND ##
#%%

import matplotlib
matplotlib.style.use('ggplot')

#%%

k_1_3 = 927.27
k_2_4 = 903.65

ME1_FO = processed[d2df('ME1', 'Cyl', 'FuelPh_in', 'mdot')]
ME2_FO = processed[d2df('ME1', 'Cyl', 'FuelPh_in', 'mdot')]
ME3_FO = processed[d2df('ME1', 'Cyl', 'FuelPh_in', 'mdot')]
ME4_FO = processed[d2df('ME1', 'Cyl', 'FuelPh_in', 'mdot')]
AE1_FO = processed[d2df('ME1', 'Cyl', 'FuelPh_in', 'mdot')]
AE2_FO = processed[d2df('ME1', 'Cyl', 'FuelPh_in', 'mdot')]
AE3_FO = processed[d2df('ME1', 'Cyl', 'FuelPh_in', 'mdot')]
AE4_FO = processed[d2df('ME1', 'Cyl', 'FuelPh_in', 'mdot')]

FO1_flow = dataset_raw[
    'FO BOOST 1 CONSUMPT:6165:m3/h:Average:900'] / 3.600 * k_1_3
FO2_flow = dataset_raw[
    'FO BOOST 2 CONSUMPT:6166:m3/h:Average:900'] / 3.600 * k_2_4

tot_ME13 = (ME1_FO + ME3_FO + AE1_FO) * 1000
tot_ME24 = (ME2_FO + ME4_FO + AE2_FO + AE4_FO) * 1000
コード例 #23
0
def engineLoadCalculation(type, raw, processed, CONSTANTS, hd):
    for system in CONSTANTS["General"]["NAMES"][type]:
        processed[system + ":" + "load"] = processed[d2df(
            system, "Cyl", "Power_out", "Edot")] / CONSTANTS[type]["MCR"]
    return processed
コード例 #24
0
def enginesCheck(processed, CONSTANTS):
    # This function checks that all relative values are consistent
    text_file = open(CONSTANTS["filenames"]["consistency_check_report"], "a")
    print("Started consistency check for the engines...", end="", flush=True)
    text_file.write("\n *** CONSISTENTCY CHECK FOR ENGINES *** \n")
    for type in ["MainEngines", "AuxEngines"]:
        for name in CONSTANTS["General"]["NAMES"][type]:
            on = processed[name + ":" + "on"]
            tot = sum(on)
            # Compressor outlet temperature must be higher than compressor inlet temperature
            temp = sum(
                processed[d2df(name, "Comp", "Air_out", "T")][on] >= processed[
                    d2df(name, "Comp", "Air_in", "T")][on]) / tot * 100
            warn = "WARNING " if temp < 95 else ""
            text_file.write(warn + name +
                            " Compressor temperatures are consistent for " +
                            str(temp) + " % of the datapoints \n")
            # Exhaust temperature should be higher closer to the engine exhaust valve
            temp = sum(
                processed[d2df(name, "Cyl", "EG_out", "T")][on] >= processed[
                    d2df(name, "Turbine", "Mix_in", "T")][on]) / tot * 100
            warn = "WARNING " if temp < 95 else ""
            text_file.write(
                warn + name +
                " Exhaust temperatures (Cyl->TC are consistent for " +
                str(temp) + " % of the datapoints \n")
            temp = sum(processed[d2df(name, "Turbine", "Mix_in", "T")][on] >=
                       processed[d2df(name, "Turbine", "Mix_out", "T")][on]
                       ) / tot * 100
            warn = "WARNING " if temp < 95 else ""
            text_file.write(warn + name +
                            " Turbine temperatures are consistent for " +
                            str(temp) + " % of the datapoints \n")
            # Checking the consistency of the LOC temperatures
            temp = sum(processed[d2df(name, "LOC", "LubOil_in", "T")][on] >=
                       processed[d2df(name, "LOC", "LubOil_out", "T")][on]
                       ) / tot * 100
            warn = "WARNING " if temp < 95 else ""
            text_file.write(
                warn + name +
                " LOC temperatures (oil side) are consistent for " +
                str(temp) + " % of the datapoints \n")
            temp = sum(processed[d2df(name, "LOC", "LTWater_out", "T")][on] >=
                       processed[d2df(name, "LOC", "LTWater_in", "T")][on]
                       ) / tot * 100
            warn = "WARNING " if temp < 95 else ""
            text_file.write(
                warn + name +
                " LOC temperatures (LT water side) are consistent for " +
                str(temp) + " % of the datapoints \n")
            # Checking the consistency of the CAC_LT temperatures
            temp = sum(processed[d2df(name, "CAC_LT", "Air_in", "T")][on] >=
                       processed[d2df(name, "CAC_LT", "Air_out", "T")][on]
                       ) / tot * 100
            warn = "WARNING " if temp < 95 else ""
            text_file.write(
                warn + name +
                " CAC_LT temperatures (air side) are consistent for " +
                str(temp) + " % of the datapoints \n")
            temp = sum(processed[d2df(
                name, "CAC_LT", "LTWater_out", "T")][on] >= processed[d2df(
                    name, "CAC_LT", "LTWater_in", "T")][on]) / tot * 100
            warn = "WARNING " if temp < 95 else ""
            text_file.write(
                warn + name +
                " CAC_LT temperatures (LT water side) are consistent for " +
                str(temp) + " % of the datapoints \n")
            # Checking the consistency of the CAC_HT temperatures
            temp = sum(processed[d2df(name, "CAC_HT", "Air_in", "T")][on] >=
                       processed[d2df(name, "CAC_HT", "Air_out", "T")][on]
                       ) / tot * 100
            warn = "WARNING " if temp < 95 else ""
            text_file.write(
                warn + name +
                " CAC_HT temperatures (air side) are consistent for " +
                str(temp) + " % of the datapoints \n")
            temp = sum(processed[d2df(
                name, "CAC_HT", "HTWater_out", "T")][on] >= processed[d2df(
                    name, "CAC_HT", "HTWater_in", "T")][on]) / tot * 100
            warn = "WARNING " if temp < 95 else ""
            text_file.write(
                warn + name +
                " CAC_HT temperatures (HT water side) are consistent for " +
                str(temp) + " % of the datapoints \n")
            # Checking the overall engine balance
            energyOutput = (
                processed[d2df(name, "Cyl", "Power_out", "Edot")] +
                processed[d2df(name, "Turbine", "Mix_out", "Edot")] +
                (processed[d2df(name, "LOC", "LTWater_out", "Edot")] -
                 processed[d2df(name, "CAC_LT", "LTWater_in", "Edot")]) +
                (processed[d2df(name, "CAC_HT", "HTWater_out", "Edot")] -
                 processed[d2df(name, "JWC", "HTWater_in", "Edot")]) +
                processed[d2df(name, "Cyl", "QdotRad_out", "Edot")])
            energyInput = (processed[d2df(name, "Cyl", "FuelCh_in", "Edot")] +
                           processed[d2df(name, "Cyl", "FuelPh_in", "Edot")] +
                           processed[d2df(name, "Comp", "Air_in", "Edot")])
            energyBalance = abs(((energyInput - energyOutput) / energyInput))
            temp = sum(
                energyBalance[processed[name + ":on"]] <= 0.01) / tot * 100
            warn = "WARNING " if temp < 95 else ""
            text_file.write(
                warn + name +
                " The overall energy balance of the engine is consistent for "
                + str(temp) + " % of the datapoints \n")

    text_file.close()
    print("...done!")
コード例 #25
0
def auxEngineAirFlowPostCalculation(processed, CONSTANTS):
    print("Started calculating auxiliary engine air and exhaust flows...", end="", flush=True)
    # This function calculates the different air and exhaust gas flows in the main engines, taking into account the
    # presence of air bypass and exhaust wastegate valves
    for system in CONSTANTS["General"]["NAMES"]["AuxEngines"]:
        # Calculating the turbine's power outpput to the compressor
        processed[d2df(system, "Turbine", "Power_out", "Edot")] = processed[d2df(system, "BPmerge", "Mix_out", "mdot")] * (
            processed[d2df(system, "Turbine", "Mix_in", "h")] - processed[d2df(system, "Turbine", "Mix_out", "h")])
        # Calculating the compressor's power input.
        processed[d2df(system, "Comp", "Power_in", "Edot")] = processed[d2df(system, "BPsplit", "Air_in", "mdot")] * (
            processed[d2df(system, "Comp", "Air_out", "h")] - processed[d2df(system, "Comp", "Air_in", "h")])
        # Losses at the TC shaft level are calculated
        etaTcMech = (processed[d2df(system, "TCshaft", "Power_in", "omega")]/CONSTANTS["AuxEngines"]["RPM_TC_DES"]).apply(polyvalHelperFunction,args=(CONSTANTS["MainEngines"]["POLY_TC_RPM_2_ETA_MECH"],))
        processed[d2df(system, "TCshaft", "Losses_out", "Edot")] = processed[d2df(system, "Turbine", "Power_out", "Edot")] * (1 - etaTcMech)

    return processed
コード例 #26
0
def readAuxEnginesExistingValues(raw, processed,CONSTANTS,hd):
    print("Started reading raw values for auxiliary engines...", end="", flush=True)
    for system in CONSTANTS["General"]["NAMES"]["AuxEngines"]:
        # Reading main engines exhaust gas temperature, TC inlet and outlet
        processed[d2df(system,"Turbine","Mix_in","T")] = raw[hd[system + "-TC_EG_T_IN1"]] + 273.15
        processed[d2df(system,"Turbine","Mix_out","T")] = raw[hd[system + "-TC_EG_T_OUT"]] + 273.15
        # Reading main engines exhaust gas temperature, after HRSG
        processed[d2df(system,"HRSG","Mix_out","T")] = raw[hd[system + "-EGB_EG_T_OUT"]] + 273.15
        # Reading the HT temperature before and after the main engine
        processed[d2df(system,"JWC","HTWater_in","T")] = raw[hd[system + "-HT_FW_T_IN"]] + 273.15
        #processed[d2df(system, "CAC_HT", "HTWater_out", "T")] = raw[hd[system + "-HT_FW_T_OUT2"]] + 273.15
        # Reading the LT temperature before the main engine
        processed[d2df(system,"CAC_LT","LTWater_in","T")] = raw[hd[system + "-LT-CAC_FW_T_IN"]] + 273.15
        # Reading the Lubricating oil temperature before and after the Lubricating oil cooler
        processed[d2df(system,"LOC","LubOil_out","T")] = raw[hd[system + "-LOC_OIL_T_OUT"]] + 273.15
        # Reading fuel oil temperature before injection
        processed[d2df(system,"Cyl","FuelPh_in","T")] = raw[hd[system + "-CYL_FUEL_T_IN"]] + 273.15
        # Reading charge air temperature.
        processed[d2df(system,"CAC_LT","Air_out","T")] = raw[hd[system + "-CAC_AIR_T_OUT"]] + 273.15
        # Reading power output
        processed[d2df(system,"AG","Power_out","Edot")] = raw[hd[system + "_POWER_Wdot_OUT"]]
        # Reading Engine rpm
        # processed[d2df(system, "Cyl", "Power_out", "omega")] = raw[hd[system + "__RPM_"]]
        # Reading the pressure in the cooling flows
        processed[d2df(system, "CAC_LT", "LTWater_in", "p")] = (raw[hd[system + "-LT-CAC_FW_P_IN"]] + 1.01325) * 100000
        processed[d2df(system, "JWC", "HTWater_in", "p")] = raw[hd[system + "-HT-JWC_FW_P_IN"]] + 273.15
        processed[d2df(system, "Comp", "Air_out", "p")] = (raw[hd[system + "-CAC_AIR_P_OUT"]] + 1.01325) * 100000
        # Reading the pressure of the lubricating oil
        processed[d2df(system, "LOC", "LubOil_out", "p")] = (raw[hd[system + "-LOC_OIL_P_IN"]] + 1.01325) * 100000
        # Reading the pressure in the cooling flows
        processed[d2df(system, "CAC_LT", "LTWater_in", "p")] = (raw[hd[system + "-LT-CAC_FW_P_IN"]] + 1.01325) * 100000
        processed[d2df(system, "JWC", "HTWater_in", "p")] = (raw[hd[system + "-HT-JWC_FW_P_IN"]] + 1.01325) * 100000
        # Reading turbocharger speed
        processed[d2df(system, "TCshaft", "Power_in", "omega")] = raw[hd[system + "-TC__RPM_"]]
        processed[d2df(system, "TCshaft", "Power_out", "omega")] = raw[hd[system + "-TC__RPM_"]]
        processed[d2df(system, "Turbine", "Power_out", "omega")] = raw[hd[system + "-TC__RPM_"]]
        processed[d2df(system, "Compressor", "Power_in", "omega")] = raw[hd[system + "-TC__RPM_"]]
        # TEMPORARY: Filter on fuel temperature
        if system == "AE3":
            processed.loc[
                processed[d2df(system, "Cyl", "FuelPh_in", "T")] < 300, d2df(system, "Cyl", "FuelPh_in", "T")] = 300
        else:
            processed.loc[
                processed[d2df(system, "Cyl", "FuelPh_in", "T")] < 350, d2df(system, "Cyl", "FuelPh_in", "T")] = 350
        print("...done!")
    return processed
コード例 #27
0
def coolingFlows(processed, CONSTANTS, engine_type):
    print("Started calculating cooling flows for the {}...".format(engine_type), end="", flush=True)
    # This function calculates the different flows related to the cooling systems of the main engines.
    for system in CONSTANTS["General"]["NAMES"][engine_type]:
        processed.loc[processed[d2df(system, "JWC", "HTWater_in", "p")] < 150000,d2df(system, "JWC", "HTWater_in", "p")] = 190000
        processed.loc[processed[d2df(system, "CAC_LT", "LTWater_in", "p")] < 150000, d2df(system, "CAC_LT", "LTWater_in", "p")] = 190000
        head_HT = processed[d2df(system, "JWC", "HTWater_in", "p")][~processed[system+":on"]].mean()
        heat_LT = processed[d2df(system, "CAC_LT", "LTWater_in", "p")][~processed[system+":on"]].mean()
        # Mass flow in the LT water cooling systems
        processed[d2df(system, "CAC_LT", "LTWater_in", "mdot")] = pumpFlow(processed[d2df(system, "Cyl", "Power_out", "omega")],
                       processed[d2df(system, "CAC_LT", "LTWater_in", "p")], heat_LT, CONSTANTS, engine_type)
        processed.loc[:,d2df(system, "CAC_LT", "LTWater_in", "mdot")] = processed[d2df(system, "CAC_LT", "LTWater_in", "mdot")] / max(processed[d2df(system, "CAC_LT", "LTWater_in", "mdot")]) * CONSTANTS[engine_type]["MFR_LT"]
        processed.loc[processed[d2df(system, "CAC_LT", "LTWater_in", "mdot")] < 0,d2df(system, "CAC_LT", "LTWater_in", "mdot")] = 0
        processed.loc[processed[d2df(system, "CAC_LT", "LTWater_in", "mdot")] > CONSTANTS[engine_type]["MFR_LT"], d2df(system, "CAC_LT", "LTWater_in","mdot")] = CONSTANTS[engine_type]["MFR_LT"]
        # Mass flow in the HT water cooling systems
        processed[d2df(system, "JWC", "HTWater_in", "mdot")] = pumpFlow(processed[d2df(system, "Cyl", "Power_out", "omega")],
                       processed[d2df(system, "JWC", "HTWater_in", "p")], head_HT, CONSTANTS, engine_type)
        processed.loc[:, d2df(system, "JWC", "HTWater_in", "mdot")] = processed[d2df(system, "JWC", "HTWater_in","mdot")] / max(processed[d2df(system, "JWC", "HTWater_in", "mdot")]) * CONSTANTS[engine_type]["MFR_HT"] * 2
        processed.loc[processed[d2df(system, "JWC", "HTWater_in", "mdot")] < 0, d2df(system, "JWC", "HTWater_in","mdot")] = 0
        processed.loc[processed[d2df(system, "JWC", "HTWater_in", "mdot")] > CONSTANTS[engine_type]["MFR_HT"], d2df(system,"JWC","HTWater_in","mdot")] = CONSTANTS[engine_type]["MFR_HT"]
        # Mass flow in the lubricating oil cooler
        processed.loc[:, d2df(system, "LOC", "LubOil_out", "mdot")] = CONSTANTS[engine_type]["MFR_LO"]
    print("done!")
    return processed
コード例 #28
0
def centralCoolingSystems(processed, CONSTANTS):

    # Doing the calculations for the 1-3 engine room
    ER13set = {"AE1", "AE3", "ME1", "ME3", "AB1"}
    # Calculating the temperature at the LT collector outlet
    mdot_temp = sum(processed[d2df("CoolingSystems", "LTcollector13", "LTWater_" + idx + "_in", "mdot")] for idx in ER13set)
    processed[d2df("CoolingSystems", "LTcollector13", "LTWater_out", "T")] = (
        (sum(processed[d2df("CoolingSystems", "LTcollector13", "LTWater_"+idx+"_in", "T")] *
            processed[d2df("CoolingSystems", "LTcollector13", "LTWater_"+idx+"_in", "mdot")] for idx in ER13set)) / (
            mdot_temp))
    processed.loc[mdot_temp == 0, d2df("CoolingSystems", "LTcollector13", "LTWater_out", "T")] = processed['T_0']
    # The temperature at the other output of the collector is the same
    processed["CoolingSystems:LTcollector13:HTWater_out:T"] = processed["CoolingSystems:LTcollector13:LTWater_out:T"]
    # Note that the temperature at the LT distribution inlet is calculated based on the average temperature at the LT collector outlets.
    # The idea is that we have different temperatures at different instants, and we need to average them
    mdot_temp = sum(processed[d2df("CoolingSystems", "LTdistribution13", "LTWater_" + idx + "_out", "mdot")] for idx in ER13set)
    processed[d2df("CoolingSystems", "LTdistribution13", "LTWater_in", "T")] = (
        sum(processed[d2df("CoolingSystems", "LTdistribution13", "LTWater_" + idx + "_out", "T")] *
            processed[d2df("CoolingSystems", "LTdistribution13", "LTWater_" + idx + "_out", "mdot")] for idx in ER13set) / (
        mdot_temp))
    processed.loc[mdot_temp==0, d2df("CoolingSystems", "LTdistribution13", "LTWater_in", "T")] = processed['T_0']
    # The temperature at the Sea water cooler outlet is then equal to the inlet to the distribution systems
    #processed[d2df("CoolingSystems", "SWC13", "LTWater_out", "T")] = processed[d2df("CoolingSystems", "LTdistribution13", "LTWater_in", "T")]

    # Doing the calculations for the "2-4 engine room
    ER24set = {"AE2", "AE4", "ME2", "ME4"}
    # Calculating the temperature at the LT collector outlet
    mdot_temp = sum(processed[d2df("CoolingSystems", "LTcollector24", "LTWater_" + idx + "_in", "mdot")] for idx in ER24set)
    processed[d2df("CoolingSystems", "LTcollector24", "LTWater_out", "T")] = (
        (sum(processed[d2df("CoolingSystems", "LTcollector24", "LTWater_" + idx + "_in", "T")] *
             processed[d2df("CoolingSystems", "LTcollector24", "LTWater_" + idx + "_in", "mdot")] for idx in ER24set)) / (
            mdot_temp))
    processed.loc[mdot_temp==0, d2df("CoolingSystems", "LTcollector24", "LTWater_out", "T")] = processed['T_0']
    processed["CoolingSystems:LTcollector24:HTWater_out:T"] = processed["CoolingSystems:LTcollector24:LTWater_out:T"]
    # Note that the temperature at the LT distribution inlet is calculated based on the average temperature at the LT collector outlets
    mdot_temp = sum(processed[d2df("CoolingSystems", "LTdistribution24", "LTWater_" + idx + "_out", "mdot")] for idx in ER24set)
    processed[d2df("CoolingSystems", "LTdistribution24", "LTWater_in", "T")] = (
        sum(processed[d2df("CoolingSystems", "LTdistribution24", "LTWater_" + idx + "_out", "T")] *
            processed[d2df("CoolingSystems", "LTdistribution24", "LTWater_" + idx + "_out", "mdot")] for idx in ER24set) / (
        mdot_temp))
    processed.loc[mdot_temp == 0, d2df("CoolingSystems", "LTdistribution24", "LTWater_in", "T")] = processed['T_0']

    # We can now calculate the flows into the LTHT merge for the ER 13
    mdot_HTHR13_tot = processed["CoolingSystems:LTHTmerge13:HTWater_ME1_out:mdot"] + processed["CoolingSystems:LTHTmerge13:HTWater_ME3_out:mdot"] + processed["CoolingSystems:LTHTmerge13:HTWater_AE1_out:mdot"] + processed["CoolingSystems:LTHTmerge13:HTWater_AE3_out:mdot"]
    #processed["CoolingSystems:LTHTmerge13:HTWater_in:mdot"] = mdot_HTHR13_tot * (
    #    CONSTANTS["MainEngines"]["T_COOLING_MIX"] - processed["CoolingSystems:LTcollector13:HTWater_out:T"]) / (
    #    processed["CoolingSystems:LTHTmerge13:HTWater_in:T"] - processed["CoolingSystems:LTcollector13:HTWater_out:T"])
    # If the previously calculated mass flow is NaN, we set it equal to 0
    processed.loc[np.isnan(processed["CoolingSystems:LTHTmerge13:HTWater_in:mdot"]), "CoolingSystems:LTHTmerge13:HTWater_in:mdot"] = 0
    processed["CoolingSystems:LTHTmerge13:LTWater_in:mdot"] = mdot_HTHR13_tot - processed["CoolingSystems:LTHTmerge13:HTWater_in:mdot"]

    # We can now calculate the flows into the LTHT merge for the ER 24
    mdot_HTHR24_tot = processed["CoolingSystems:LTHTmerge24:HTWater_ME2_out:mdot"] + processed["CoolingSystems:LTHTmerge24:HTWater_ME4_out:mdot"] + processed["CoolingSystems:LTHTmerge24:HTWater_AE2_out:mdot"] + processed["CoolingSystems:LTHTmerge24:HTWater_AE4_out:mdot"]
    #processed["CoolingSystems:LTHTmerge24:HTWater_in:mdot"] = mdot_HTHR24_tot * (
    #    CONSTANTS["MainEngines"]["T_COOLING_MIX"] - processed["CoolingSystems:LTcollector24:HTWater_out:T"]) / (
    #    processed["CoolingSystems:LTHTmerge24:HTWater_in:T"] - processed["CoolingSystems:LTcollector24:HTWater_out:T"])
    # If the previously calculated mass flow is NaN, we set it equal to 0
    processed.loc[np.isnan(processed["CoolingSystems:LTHTmerge24:HTWater_in:mdot"]), "CoolingSystems:LTHTmerge24:HTWater_in:mdot"] = 0
    processed["CoolingSystems:LTHTmerge24:LTWater_in:mdot"] = mdot_HTHR24_tot - processed["CoolingSystems:LTHTmerge24:HTWater_in:mdot"]

    return processed
コード例 #29
0
def efficiencyCalculator(processed, dict_structure, CONSTANTS):
    text_file = open(CONSTANTS["filenames"]["consistency_check_report"], "a")
    text_file.write("\n *** CALCULATING EFFICIENCIES *** \n")
    df_index = processed.index
    for system in dict_structure["systems"]:
        for unit in dict_structure["systems"][system]["units"]:
            if system + ":" + unit == "CoolingSystems:LTdistribution13":
                aaa = 0
            # Here I create eight (8) series: 4 Edot and 4 Bdot. 2 "Full" and 2 "useful".
            temp_flow_list = {
                "Edot_in", "Edot_in_useful", "Edot_out", "Edot_out_useful",
                "Bdot_in", "Bdot_in_useful", "Bdot_out", "Bdot_out_useful"
            }
            temp_df = pd.DataFrame(0, columns=temp_flow_list, index=df_index)
            for flow in dict_structure["systems"][system]["units"][unit][
                    "flows"]:
                dict_structure["systems"][system]["units"][unit][
                    "flows"][flow]["E"] = processed[d2df(
                        system, unit, flow, "Edot")].sum() * 60 * 15 * 1e-6
                dict_structure["systems"][system]["units"][unit][
                    "flows"][flow]["B"] = processed[d2df(
                        system, unit, flow, "Bdot")].sum() * 60 * 15 * 1e-6
                if flow[-2:] == "in":
                    temp_df['Edot_in'] = temp_df['Edot_in'] + processed[d2df(
                        system, unit, flow, "Edot")]
                    temp_df['Bdot_in'] = temp_df['Bdot_in'] + processed[d2df(
                        system, unit, flow, "Bdot")]
                elif flow[-3:] == "out":
                    temp_df['Edot_out'] = temp_df['Edot_out'] + processed[d2df(
                        system, unit, flow, "Edot")]
                    temp_df['Bdot_out'] = temp_df['Bdot_out'] + processed[d2df(
                        system, unit, flow, "Bdot")]
                else:
                    text_file.write(
                        "Flow {}:{}:{} is not recognised as either input or output \n"
                        .format(system, unit, flow))
                # The "Edot_useful" and "Bdot_useful" inputs and outputs are only assigned when defined
                if "IO" in dict_structure["systems"][system]["units"][unit][
                        "flows"][flow]:
                    if dict_structure["systems"][system]["units"][unit][
                            "flows"][flow]["IO"] == "input":
                        if flow[-2:] == "in":
                            temp_df['Edot_in_useful'] = temp_df[
                                'Edot_in_useful'] + processed[d2df(
                                    system, unit, flow, "Edot")]
                            temp_df['Bdot_in_useful'] = temp_df[
                                'Bdot_in_useful'] + processed[d2df(
                                    system, unit, flow, "Bdot")]
                        elif flow[-3:] == "out":
                            temp_df['Edot_in_useful'] = temp_df[
                                'Edot_in_useful'] - processed[d2df(
                                    system, unit, flow, "Edot")]
                            temp_df['Bdot_in_useful'] = temp_df[
                                'Bdot_in_useful'] - processed[d2df(
                                    system, unit, flow, "Bdot")]
                        else:
                            text_file.write(
                                "Flow {}:{}:{} is not recognised as either input or output \n"
                                .format(system, unit, flow))
                    elif dict_structure["systems"][system]["units"][unit][
                            "flows"][flow]["IO"] == "output":
                        if flow[-2:] == "in":
                            temp_df['Edot_out_useful'] = temp_df[
                                'Edot_out_useful'] - processed[d2df(
                                    system, unit, flow, "Edot")]
                            temp_df['Bdot_out_useful'] = temp_df[
                                'Bdot_out_useful'] - processed[d2df(
                                    system, unit, flow, "Bdot")]
                        elif flow[-3:] == "out":
                            temp_df['Edot_out_useful'] = temp_df[
                                'Edot_out_useful'] + processed[d2df(
                                    system, unit, flow, "Edot")]
                            temp_df['Bdot_out_useful'] = temp_df[
                                'Bdot_out_useful'] + processed[d2df(
                                    system, unit, flow, "Bdot")]
                        else:
                            text_file.write(
                                "Flow {}:{}:{} is not recognised as either input or output \n"
                                .format(system, unit, flow))
                    else:
                        text_file.write(
                            "Flow {}:{}:{} is not recognised as either USEFEUL input or output \n"
                            .format(system, unit, flow))
                        # Saving the total energy flows
                        dict_structure["systems"][system]["units"][unit][
                            "E_in"] = temp_df["Edot_in"].sum() * 60 * 15 * 1e-6
            dict_structure["systems"][system]["units"][unit][
                "E_out"] = temp_df["Edot_out"].sum() * 60 * 15 * 1e-6
            dict_structure["systems"][system][
                "units"][unit]["E_in_useful"] = temp_df["Edot_in_useful"].sum(
                ) * 60 * 15 * 1e-6
            dict_structure["systems"][system]["units"][unit][
                "E_out_useful"] = temp_df["Edot_out_useful"].sum(
                ) * 60 * 15 * 1e-6
            # Saving total exergy flows
            dict_structure["systems"][system]["units"][unit][
                "B_in"] = temp_df["Bdot_in"].sum() * 60 * 15 * 1e-6
            dict_structure["systems"][system]["units"][unit][
                "B_out"] = temp_df["Bdot_out"].sum() * 60 * 15 * 1e-6
            dict_structure["systems"][system][
                "units"][unit]["B_in_useful"] = temp_df["Bdot_in_useful"].sum(
                ) * 60 * 15 * 1e-6
            dict_structure["systems"][system]["units"][unit][
                "B_out_useful"] = temp_df["Bdot_out_useful"].sum(
                ) * 60 * 15 * 1e-6

            # We first calculate the energy efficiency (if possible)
            if system + ":" + unit + ":" + "eta" in processed.columns:
                processed[system + ":" + unit + ":" + "eta"] = temp_df[
                    'Edot_out_useful'] / temp_df['Edot_in_useful']
                processed.loc[temp_df['Edot_in_useful'] == 0,
                              system + ":" + unit + ":" + "eta"] = 0
                # Calculating the average value
                if dict_structure["systems"][system]["units"][unit][
                        "E_in_useful"] == 0:
                    dict_structure["systems"][system]["units"][unit]["eta"] = 0
                else:
                    dict_structure["systems"][system]["units"][unit][
                        "eta"] = dict_structure["systems"][system]["units"][
                            unit]["E_out_useful"] / dict_structure["systems"][
                                system]["units"][unit]["E_in_useful"]

            # Then exergy efficiency (again, if possible)
            if system + ":" + unit + ":" + "eps" in processed.columns:
                processed[system + ":" + unit + ":" + "eps"] = temp_df[
                    'Bdot_out_useful'] / temp_df['Bdot_in_useful']
                processed.loc[temp_df['Bdot_in_useful'] == 0,
                              system + ":" + unit + ":" + "eps"] = 0
                # Calculating the average value
                if dict_structure["systems"][system]["units"][unit][
                        "B_in_useful"] == 0:
                    dict_structure["systems"][system]["units"][unit]["eps"] = 0
                else:
                    dict_structure["systems"][system]["units"][unit][
                        "eps"] = dict_structure["systems"][system]["units"][
                            unit]["B_out_useful"] / dict_structure["systems"][
                                system]["units"][unit]["B_in_useful"]

            # We calculate also the irreversibility ratio. Might come in handy
            processed[system + ":" + unit + ":" +
                      "Idot"] = temp_df['Bdot_in'] - temp_df['Bdot_out']
            dict_structure["systems"][system]["units"][unit][
                "Idot"] = processed[system + ":" + unit + ":" +
                                    "Idot"].sum() * 60 * 15 * 1e-6

            # Finally, we calculate the lambda
            processed[system + ":" + unit + ":" +
                      "lambda"] = (temp_df['Bdot_in'] -
                                   temp_df['Bdot_out']) / temp_df['Bdot_in']
            processed.loc[temp_df['Bdot_in'] == 0,
                          system + ":" + unit + ":" + "lambda"] = 0
            # Calculate the average value
            if dict_structure["systems"][system]["units"][unit]["B_in"] == 0:
                dict_structure["systems"][system]["units"][unit]["lambda"] = 0
            else:
                dict_structure["systems"][system]["units"][unit][
                    "lambda"] = 1 - dict_structure["systems"][system]["units"][
                        unit]["B_out"] / dict_structure["systems"][system][
                            "units"][unit]["B_in"]

            #### ADD THE CALCULATION OF THE DELTA #####
    temp_total_idot = sum(
        processed[system + ":" + unit + ":" + "Idot"]
        for system in dict_structure["systems"]
        for unit in dict_structure["systems"][system]["units"])
    for system in dict_structure["systems"]:
        temp_system_idot = sum(
            processed[system + ":" + unit + ":" + "Idot"]
            for unit in dict_structure["systems"][system]["units"])
        processed[system + ":delta"] = temp_system_idot / temp_total_idot
        dict_structure["systems"][system]["delta"] = temp_system_idot.sum(
        ) / temp_total_idot.sum()
        for unit in dict_structure["systems"][system]["units"]:
            processed[system + ":" + unit + ":" +
                      "delta"] = processed[system + ":" + unit + ":" +
                                           "Idot"] / temp_system_idot
            processed.loc[temp_system_idot == 0,
                          system + ":" + unit + ":" + "Idot"] = 0
            if temp_system_idot.sum() == 0:
                dict_structure["systems"][system]["units"][unit]["delta"] = 0
            else:
                dict_structure["systems"][system]["units"][unit][
                    "delta"] = dict_structure["systems"][system]["units"][
                        unit]["Idot"] / temp_system_idot.sum() / 60 / 15 / 1e-6
    text_file.close()
    return processed