# -*- coding: utf-8 -*-
"""
Created on Mon Oct 16 11:13:12 2023

@author: atakan
"""

import numpy as np
import carbatpy as cb

import pandas as pd
import seaborn as sbn
import matplotlib.pyplot as plt
import datetime
if __name__ == "__main__":
    dir_name = cb._RESULTS_DIR + "\\optimal_hp_fluid"
    fname = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M")+"threeAlkanes"
    plt.style.use('seaborn-v0_8-poster')  # 'seaborn-v0_8-poster')
    
    FLUID_COMP = "Propane * Butane * Pentane"  # " * Hexane"
    comp = [.5, 0., 0.5]  # , 0.0]
    # comp =[0.000,1.0,0.00,0.0]
    
    FLS = "Water"  #
    FLCOLD = "Methanol"  # "Water"  #
    
    flm = cb.fprop.fluid_model(FLUID_COMP)
    my_fluid = cb.fprop.Fluid(flm, comp)
    
    secFlm = cb.fprop.fluid_model(FLS)
    secondary_fluid = cb.fprop.Fluid(secFlm, [1.])
    
    coldFlm = cb.fprop.fluid_model(FLCOLD)
    cold_fluid_act = cb.fprop.Fluid(coldFlm, [1.])
    
    # Condenser(c) and storage (s), secondary fluids fix all, temperatures(T in K),
    # pressures (p in Pa)
    
    SECONDARY_TEMP_IN = 290.0
    COLD_TEMP_IN = SECONDARY_TEMP_IN
    SECONDARY_TEMP_OUT = 363.  # 395.0
    COLD_TEMP_OUT = 257.
    SP_IN = 5E5
    CP_IN = 5E5
    DH_MIN = 1E3  # AND HEAT_FLOW RATE (W)
    ETA_S = 0.65
    D_TEMPMIN = 1.530  # MINIMUM APPROACH TEMPERATURE (PINCH POINT)
    Q_DOT_H = 3000.
    
    state_sec_in = secondary_fluid.set_state([SECONDARY_TEMP_IN, SP_IN], "TP")
    state_cold_in = cold_fluid_act.set_state([COLD_TEMP_IN, CP_IN], "TP")
    
    # working fluid
    D_TEMPSUPER = 5.  # super heating of working fluid
    TEMP_DEW = SECONDARY_TEMP_OUT
    state_in_act = my_fluid.set_state([TEMP_DEW, 1.], "TQ")  # find minimum pressure
    
    TEMP_IN = TEMP_DEW + D_TEMPSUPER
    state_in_act = my_fluid.set_state([my_fluid.properties.pressure,
                                  my_fluid.properties.temperature + D_TEMPSUPER], "PT")
    p_high_act = state_in_act[1]
    
    state_in_act = my_fluid.set_state(
        [SECONDARY_TEMP_IN - D_TEMPSUPER, 1.], "TQ")  # find minimum pressure
    p_low_act = state_in_act[1]
    
    state_in_act = my_fluid.set_state([p_low_act,
                                  SECONDARY_TEMP_IN - D_TEMPMIN], "PT")
    print(f"p-ratio: {p_high_act/p_low_act: .2f}, p_low: {p_low_act/1e5: .2} bar")
    
    state_in_act = my_fluid.set_state([p_low_act, TEMP_IN], "PT")
    
    fixed_points_act = {"eta_s": ETA_S,
                    "p_low": p_low_act,
                    "temp_hh": SECONDARY_TEMP_OUT,
                    "temp_hl": SECONDARY_TEMP_IN,
                    "temp_lh": SECONDARY_TEMP_IN,
                    "temp_ll": COLD_TEMP_OUT,
                    "q_dot_h": Q_DOT_H,
                    "d_tempmin": D_TEMPMIN}
    
    hp0_act = cb.hp_simple.heat_pump([my_fluid, secondary_fluid, cold_fluid_act],
                                 fixed_points_act)
    cop_act = hp0_act.calc_p_high(p_high_act)
    hp0_act.hp_plot()
    out = hp0_act.evaluation
    print(
        f"COP: {out[0]/out[1]:.2f},p-ratio: { out[2]/out[3]:.2f}, p_low {out[3]/1e5:.2f} bar")


def hp_comp_cop(composition, work_fluid, sec_fluid, cold_fluid,
                fixed_points, d_tempsuper=5.0, opt=+1):
    # working fluid
    sum3 = np.sum(composition)
    if sum3 > 1:
        return 0

    last = 1-sum3
    new_composition = np.array([*composition, last])

    work_fluid.set_composition(new_composition)
    temp_dew = fixed_points["temp_hh"]
    state_in = work_fluid.set_state(
        [temp_dew, 1.], "TQ")  # find minimum pressure

    # TEMP_IN = temp_dew + D_TEMPSUPER
    state_in = work_fluid.set_state([work_fluid.properties.pressure,
                                    work_fluid.properties.temperature + D_TEMPSUPER], "PT")
    p_high = state_in[1]

    state_in = work_fluid.set_state(
        [fixed_points["temp_lh"] - d_tempsuper, 1.], "TQ")  # find minimum pressure
    p_low = state_in[1]

    state_in = my_fluid.set_state([p_low,
                                  SECONDARY_TEMP_IN - D_TEMPMIN], "PT")
    fixed_points["p_low"] = p_low
    hp0 = cb.hp_simple.heat_pump(
        [work_fluid, sec_fluid, cold_fluid], fixed_points)
    cop = hp0.calc_p_high(p_high)
    print("Result-hp-opt:", new_composition, np.sum(new_composition),
          cop, p_low, p_high, p_high/p_low)
    if opt == -1:
        return cop * opt

    return cop, p_low/1e5, p_high/1e5

if __name__ == "__main__":
    all_res = []
    x0_range = np.linspace(0.0, 0.6, 12)
    x1_range = np.linspace(0, 0.6, 10)
    for x0 in x0_range:
        for x1 in x1_range:
            if x0+x1 <= 1:
                x2 = 1-(x0+x1)
                comp = np.array([x0, x1])
                results = hp_comp_cop(comp, my_fluid, secondary_fluid,
                                      cold_fluid_act,
                                      fixed_points_act,
                                      d_tempsuper=D_TEMPSUPER,
                                      opt=+1)
                if results[0] > 1:
                    new = np.array([*results, x0, x1, x2,
                                    *fixed_points_act.values()])
                    all_res.append(new)
    
    names = ["COP", "$p_{low}$", "$p_{high}$", "$x_{Propane}$",
             "$x_{Butane}$", "$x_{Pentane}$", *fixed_points_act.keys()]
    all_res = np.array(all_res)
    dframe = pd.DataFrame(all_res, columns=names)
    dframe.to_csv(dir_name+"\\"+fname+".csv")
    dframe2 = dframe.round(3)
    f, ax = plt.subplots(figsize=(10, 6), layout="constrained")
    fff = sbn.scatterplot(x=names[4], y=names[5],
                          hue=names[2], size=names[0], data=dframe2, ax=ax)
    sbn.move_legend(fff, "upper left", bbox_to_anchor=(1, 1))
    f.savefig(dir_name+"\\"+fname+".png")
    # bounds = ((0.05, 0.95), (0.00, 0.65))
    
    
    # def constr(comp):
    #     print(comp, np.sum(comp))
    #     return 1-np.sum(comp)
    
    # res = opt.differential_evolution(hp_comp_cop, bounds,
    #                args=(my_fluid, secFluid, cold_fluid_act, fixed_points)
    #                )
    # print(res)
