예제 #1
0
def function_inner_loop(pressure,
                        temperature,
                        global_molar_fraction,
                        max_iter=100,
                        tolerance=1.0e-12,
                        stability=False):
    T = temperature
    P = pressure
    logging.debug('pressure' + str(P))
    yi = z = global_molar_fraction
    f_V, Z_V = eos_obj.calculate_fugacities_with_minimum_gibbs_energy(
        P, T, yi, 'vapor')
    PHI_V = f_V / (yi * P)
    initial_K_values = calculate_K_values_wilson(P, T, eos_obj.Pc, eos_obj.Tc,
                                                 eos_obj.ω)
    is_stable, K_michelsen = michelsen_obj(eos_obj, P, T, z, initial_K_values,
                                           max_iter, tolerance)
    if stability:
        if not is_stable:
            msg = str('===> two-phases can be in equilibrium')
        else:
            msg = str('===> one phase in this @')
        print(msg)
    logging.debug('K_michelsen' + str(K_michelsen))
    logging.debug('One-phase = ' + str(is_stable))
    xi = yi  #yi / K_michelsen
    Sx = np.sum(xi)
    Sx0 = 2 * Sx
    itermax = 2
    for counter in np.arange(itermax):
        if is_stable:
            Sx = (
                Sx + 3.0
            )  # To force the program stores wrong Sx's value [avoid the solver seeks minimum values of (Sx - 1)]
            break
        else:
            pass
        f_L, Z_L = eos_obj.calculate_fugacities_with_minimum_gibbs_energy(
            P, T, xi, 'liquid')
        PHI_L = f_L / (xi * P)
        K = PHI_L / PHI_V
        xi = yi / K
        Sx = np.sum(xi)
        logging.debug('iteracao' + str(counter))
        logging.debug('K' + str(K))
        logging.debug('xi' + str(xi))
        logging.debug('Sx = ' + str(Sx) + '\n----')
        if (np.abs(Sx - Sx0) < tolerance):
            break
        else:
            xi /= Sx
            Sx0 = np.copy(Sx)
    return Sx, xi
예제 #2
0
    def inner_loop(self, eos_obj, p, T, z, iteration_michelsen,
                   tolerance_michelsen):
        '''
        This function is responsible for a more realistic K (vapor-liquid ratio) value. So, the first estimation
        of K is made with Wilson equation. After that, this K_Wilson is fed in Michelsen's code. This, on the other hand,
         notifies us if this mixture is stable. Besides that, in case of not stable phase (split in 2 phases),
         Michelsen's code also provides a better K estimation.

        :iteration_michelsen: is max iteration number used in Michelsen algorithm
        :tolerance_michelsen: is the tolerance exigence in Michelsen algorithm
        '''
        K_wilson = calculate_K_values_wilson(p, T, self.pC, self.Tc, self.AcF)
        is_stable, K = michelsen_obj(eos_obj, p, T, z, K_wilson,
                                     iteration_michelsen, tolerance_michelsen)
        return is_stable, K
def getting_the_results_from_FlashAlgorithm_main(p, T, pC, Tc, AcF, z):
    initial_K_values = calculate_K_values_wilson(p, T, pC, Tc, AcF)
    is_stable, K_michelsen = michelsen_obj(eos_obj,
                                           p,
                                           T,
                                           z,
                                           initial_K_values,
                                           max_iter=100,
                                           tolerance=1.0e-12)
    K_flash, F_V_flash = flash_obj(rr_obj, eos_obj, p, T, z, K_michelsen)
    Vector_ToBe_Optimized = np.append(K_flash, F_V_flash)
    result = fsolve(func=flash_obj.flash_residual_function,
                    x0=Vector_ToBe_Optimized,
                    args=(T, p, eos_obj, z))
    size = result.shape[0]
    K_values_newton = np.array(result[0:size - 1])
    F_V = result[-1]
    return (F_V, is_stable, K_values_newton, initial_K_values)
예제 #4
0
def function_inner_loop(temperature, pressure, global_molar_fraction, max_iter = 100, tolerance = 1.0e-12, stability=False):
    P = pressure
    T = temperature
    xi = z = global_molar_fraction
    f_L, Z_L = eos_obj.calculate_fugacities_with_minimum_gibbs_energy(P, T, xi, 'liquid')
    PHI_L = f_L / (xi * P)
    initial_K_values = calculate_K_values_wilson(P, T, eos_obj.Pc, eos_obj.Tc, eos_obj.ω)
    is_stable, K_michelsen = michelsen_obj(eos_obj, P, T, z, initial_K_values, max_iter, tolerance)
    if stability:
        if not is_stable:
            msg = str('===> two-phases can be in equilibrium')
        else:
            msg = str('===> one phase in this @')
        print(str(msg))
    logging.debug('temperature' + str(T))
    logging.debug('K_michelsen' + str(K_michelsen))
    logging.debug('One-phase = ' + str(is_stable))
    yi = xi * K_michelsen
    Sy = np.sum(yi)
    Sy0 = 2 * Sy
    itermax = 2
    for counter in np.arange(itermax):
        if is_stable:
            break
        else:
            pass
        f_V, Z_V = eos_obj.calculate_fugacities_with_minimum_gibbs_energy(P, T, yi, 'vapor')
        PHI_V = f_V / (yi * P)
        K = PHI_L / PHI_V
        yi = xi * K
        Sy = np.sum(yi)
        logging.debug('iteracao' + str(counter))
        logging.debug('K' + str(K))
        logging.debug('yi' + str(yi))
        logging.debug('Sy' + str(Sy) + '\n----')
        if (np.abs(Sy - Sy0) < tolerance):
            break
        else:
            yi /= Sy
            Sy0 = np.copy(Sy)
    return Sy, yi
def calculate_vapor_liquid_equilibrium(eos_obj,
                                       michelsen_obj,
                                       flash_obj,
                                       prop_obj,
                                       pressure,
                                       temperature,
                                       molar_mass,
                                       global_molar_fractions,
                                       max_iter,
                                       tolerance,
                                       print_statistics=None):
    P = pressure
    T = temperature
    z = global_molar_fractions
    Mi = molar_mass

    #size = z.shape[0]

    # Estimate initial K-values
    initial_K_values = calculate_K_values_wilson(pressure, temperature,
                                                 eos_obj.Pc, eos_obj.Tc,
                                                 eos_obj.ω)

    # Check if the mixture is stable and takes Michelsen's K
    is_stable, K_michelsen = michelsen_obj(eos_obj, P, T, z, initial_K_values,
                                           max_iter, tolerance)

    # Executing the Flash
    K_flash, F_V_flash = flash_obj(rr_obj, eos_obj, pressure, temperature,
                                   global_molar_fractions, K_michelsen)

    # Good estimate!
    Vector_ToBe_Optimized = np.append(K_flash, F_V_flash)

    ## Use estimates from flash (successive substitutions)!!!
    if 0.0 <= F_V_flash <= 1.0:
        result, infodict, ier, mesg = fsolve(
            func=flash_obj.flash_residual_function,
            x0=Vector_ToBe_Optimized,
            args=(T, P, eos_obj, z),
            full_output=True)

        size = result.shape[0]
        K_values_newton = result[0:size - 1]
        F_V = result[size - 1]
        x_i = global_molar_fractions / (F_V * (K_values_newton - 1) + 1)
        y_i = K_values_newton * x_i
        f_L, Z_L = eos_obj.calculate_fugacities_with_minimum_gibbs_energy(
            P, T, x_i, 'liquid')
        f_V, Z_V = eos_obj.calculate_fugacities_with_minimum_gibbs_energy(
            P, T, y_i, 'vapor')
        rho_L = prop_obj.calculate_density_phase(P, T, Mi, x_i, 'liquid')
        rho_V = prop_obj.calculate_density_phase(P, T, Mi, y_i, 'vapor')
        if print_statistics:
            print('Newton flash converged? %d, %s' % (ier, mesg))

    elif F_V_flash < 0.0:
        x_i = z
        y_i = np.zeros_like(z)
        K_values_newton = initial_K_values
        rho_L = prop_obj.calculate_densite_phase(P, T, Mi, x_i, 'liquid')
        rho_V = 0.0
        F_V = 0.0
    elif F_V_flash > 1.0:
        y_i = z
        x_i = np.zeros_like(z)
        K_values_newton = initial_K_values
        rho_L = 0.0
        rho_V = prop_obj.calculate_densite_phase(P, T, Mi, y_i, 'vapor')
        F_V = 1.0
    else:
        raise Exception(
            "Nenhuma das @ foram dectadas na calculate_vapor_liquid_equilibrium"
        )

    return F_V, K_values_newton, x_i, y_i, rho_V, rho_L
예제 #6
0
def function_inner_loop(p,
                        T,
                        z,
                        max_iter=20,
                        tolerance=1.0e-20,
                        stability=False):
    '''
    These function_inner_loop and function_outer_loop are functions based on Elliott's BUBBLE P algorithm (pg 595)

    INTRODUCTORY CHEMICAL ENGINEERING THERMODYNAMICS, 2nd edition, 2012
    J. RICHARD ELLIOTT and CARL T. LIRA
    '''
    logging.debug('Updating the Pressure =====> ' + str(p))
    xi = z
    Sz = np.sum(z)
    assert np.abs(
        Sz - 1.0
    ) < 1.e-5, 'YOUR GLOBAL MOLAR FRACTION MUST BE EQUAL = 1. Check your data' + str(
        Sz)
    initial_K_values = calculate_K_values_wilson(p, T, pC, Tc, AcF)
    is_stable, K = michelsen_obj(eos_obj, p, T, z, initial_K_values, max_iter,
                                 tolerance)
    if is_stable == True:
        Sy = 1e10
        yi = np.zeros_like(z)
    else:
        if stability:
            if not is_stable:
                msg = str('===> two-phases can be in equilibrium')
            else:
                msg = str('===> one phase in this @')
            print(str(msg))
        logging.debug('K_wilson = ' + str(initial_K_values))
        logging.debug('K_michelsen = ' + str(K))
        logging.debug(
            'One-phase ================================================ > ' +
            str(is_stable))
        yi = xi * K
        f_L, Z_L = eos_obj.calculate_fugacities_with_minimum_gibbs_energy(
            p, T, xi, 'liquid')
        Sy = np.sum(yi)
        Sy0 = 2 * Sy
        max_loop = 2
        for counter in np.arange(max_loop):
            f_V, Z_V = eos_obj.calculate_fugacities_with_minimum_gibbs_energy(
                p, T, yi, 'vapor')
            np.seterr(
                divide='ignore', invalid='ignore'
            )  #Because we can have PHI_V near zero for the no volatile component
            K *= f_L / f_V
            yi = xi * K
            Sy = np.sum(yi)
            logging.debug('iteracao' + str(counter))
            logging.debug('K' + str(K))
            logging.debug('yi' + str(yi))
            logging.debug('Sy = ' + str(Sy) + '\n----')
            if (np.abs(Sy - Sy0) < tolerance):
                break
            else:
                yi /= Sy
                Sy0 = np.copy(Sy)
    return Sy, yi