def load_titer(self, titer):
     """
     Load titer specification
     
     Parameters
     ----------
     titer : float
         Titer for fermentors in g products / L effluent.
     
     Notes
     -----
     Substrate concentration in bioreactor feed is adjusted to satisfy this 
     specification. 
     
     Warnings
     --------
     Changing the titer affects the productivity.
     
     """
     f = self._titer_objective_function
     feed = self.feed
     feed.imol[self.products] = 0.
     substates = feed.imass[self.substrates].sum()
     self.titer = titer
     try:
         flx.aitken_secant(f, substates, ytol=1e-5)
     except:
         flx.IQ_interpolation(f, 1e-12, 0.50 * feed.F_mass, ytol=1e-5, maxiter=100)
         
     self.reactor.tau = titer / self.productivity
Esempio n. 2
0
def solve_payment(payment, loan, interest, years):
    principal = initial_loan_principal(loan, interest)
    payment = flx.aitken_secant(final_loan_principal,
                                payment, payment+10., 1., 10.,
                                args=(principal, interest, years),
                                maxiter=200, checkiter=False)
    return payment
Esempio n. 3
0
 def solve_incentive(self):
     """
     Return the required incentive (USD) to reach the break even point (NPV = 0)
     through cash flow analysis. 
     
     """
     discount_factors = (1 + self.IRR)**self._get_duration_array()
     sales_coefficients = np.ones_like(discount_factors)
     start = self._start
     sales_coefficients[:start] = 0
     w0 = self._startup_time
     sales_coefficients[self._start] = w0 * self.startup_VOCfrac + (1 - w0)
     sales = self._sales
     if not sales or np.isnan(sales): sales = 0.
     taxable_cashflow, nontaxable_cashflow = self._taxable_and_nontaxable_cashflow_arrays(
     )
     args = (taxable_cashflow, nontaxable_cashflow, sales_coefficients,
             discount_factors)
     sales = flx.aitken_secant(self._NPV_with_sales,
                               sales,
                               1.0001 * sales + 1e-4,
                               xtol=1e-6,
                               ytol=10.,
                               maxiter=300,
                               args=args,
                               checkiter=False)
     self._sales = sales
     return sales
Esempio n. 4
0
 def solve_incentive(self, TEA=None):
     """
     Return the required incentive (USD) to reach the break even point (NPV = 0)
     through cash flow analysis. 
     
     Parameters
     ----------
     TEA=None : TEA, optional
           Incentive will be added using settings from given TEA. Defaults to
           first TEA object in the `TEAs` attribute.
     
     """
     IRR = self.IRR
     if not TEA: TEA = self.TEAs[0]
     discount_factors = (1. + IRR)**TEA._get_duration_array()
     sales_coefficients = np.ones_like(discount_factors)
     start = TEA._start
     sales_coefficients[:start] = 0
     w0 = TEA._startup_time
     sales_coefficients[TEA._start] = w0 * TEA.startup_VOCfrac + (1 - w0)
     sales = self._sales
     if not sales or np.isnan(sales): sales = 0.
     taxable_cashflow, nontaxable_cashflow = self.taxable_and_nontaxable_cashflow_arrays
     args = (self.income_tax, taxable_cashflow, nontaxable_cashflow,
             sales_coefficients, discount_factors)
     sales = flx.aitken_secant(NPV_with_sales,
                               sales,
                               1.0001 * sales + 1e-4,
                               xtol=1e-6,
                               ytol=10.,
                               maxiter=300,
                               args=args,
                               checkiter=False)
     self._sales = sales
     return sales
Esempio n. 5
0
def Tmax_Lakshmi_Prasad(MW):
    """
    Returns the maximum temperature at which the Lakshmi Prasad method is
    valid.
    """
    T_max = flx.aitken_secant(Lakshmi_Prasad.function, 298.15, args=(MW, ))
    return T_max - 10  # As an extra precaution
Esempio n. 6
0
 def solve_price(self, stream):
     """Return the price (USD/kg) of stream at the break even point (NPV = 0) through cash flow analysis. 
     
     Parameters
     ----------
     stream : :class:`~thermosteam.Stream`
         Stream with variable selling price.
         
     """
     price2cost = self._price2cost(stream)
     cashflow = self.cashflow
     discount_factors = (1 + self.IRR)**self._duration_array
     NPV = (cashflow / discount_factors).sum()
     coefficients = np.ones_like(discount_factors)
     start = self._start
     coefficients[:start] = 0
     w0 = self._startup_time
     coefficients[self._start] = w0 * self.startup_VOCfrac + (1 - w0)
     args = (NPV, coefficients, discount_factors)
     sales = self._sales or stream.price * price2cost
     sales = flx.aitken_secant(NPV_with_sales,
                               sales,
                               1.0001 * sales + 1e-4,
                               ytol=10.,
                               maxiter=200,
                               args=args,
                               checkiter=False)
     self._sales = sales
     if stream.sink:
         return stream.price - sales / price2cost
     elif stream.source:
         return stream.price + sales / price2cost
     else:
         raise ValueError("stream must be either a feed or a product")
Esempio n. 7
0
    def solve_Px(self, z, T):
        """
        Dew point given composition and temperature.

        Parameters
        ----------
        z : ndarray
            Molar composition.
        T : float
            Temperature (K).
        
        Returns
        -------
        P : float
            Dew point pressure (Pa).
        x : ndarray
            Liquid phase molar composition.

        Examples
        --------
        >>> import thermosteam as tmo
        >>> import numpy as np
        >>> chemicals = tmo.Chemicals(['Water', 'Ethanol'], cache=True)
        >>> tmo.settings.set_thermo(chemicals)
        >>> DP = tmo.equilibrium.DewPoint(chemicals)
        >>> DP.solve_Px(z=np.array([0.5, 0.5]), T=352.28)
        (82444.29876, array([0.853, 0.147]))
 
       """
        z_norm = z / z.sum()
        Psats = array([i(T) for i in self.Psats], dtype=float)
        z_over_Psats = z / Psats
        args = (T, z_norm, z_over_Psats)
        self.T = T
        f = self._P_error
        P_guess = self.P or self._P_ideal(z_over_Psats)
        try:
            P = flx.aitken_secant(f,
                                  P_guess,
                                  P_guess - 10,
                                  1e-3,
                                  5e-12,
                                  args,
                                  checkiter=False)
        except (InfeasibleRegion, DomainError):
            Pmin = self.Pmin
            Pmax = self.Pmax
            P = flx.IQ_interpolation(f,
                                     Pmin,
                                     Pmax,
                                     f(Pmin, *args),
                                     f(Pmax, *args),
                                     P_guess,
                                     1e-3,
                                     5e-12,
                                     args,
                                     checkiter=False,
                                     checkbounds=False)
        self.x = fn.normalize(self.x)
        return P, self.x.copy()
Esempio n. 8
0
 def solve_sales(self):
     """
     Return the required additional sales (USD) to reach the breakeven 
     point (NPV = 0) through cash flow analysis. 
     
     """
     discount_factors = (1 + self.IRR)**self._get_duration_array()
     sales_coefficients = np.ones_like(discount_factors)
     start = self._start
     sales_coefficients[:start] = 0
     w0 = self._startup_time
     sales_coefficients[self._start] = w0 * self.startup_VOCfrac + (1 - w0)
     sales = self._sales
     if not np.isfinite(sales): sales = 0.
     taxable_cashflow, nontaxable_cashflow = self._taxable_and_nontaxable_cashflow_arrays(
     )
     args = (taxable_cashflow, nontaxable_cashflow, sales_coefficients,
             discount_factors, self._fill_tax_and_incentives)
     x0 = sales
     x1 = 1.01 * sales + 10
     f = NPV_with_sales
     try:
         sales = flx.aitken_secant(f,
                                   x0,
                                   x1,
                                   xtol=10,
                                   ytol=1000.,
                                   maxiter=1000,
                                   args=args,
                                   checkiter=True)
     except Exception as e:
         y0 = f(x0, *args)
         y1 = f(x1, *args)
         if y0 == y1 and y0 < 0.:
             x0 = -y1 / self._years
         else:
             raise e
         sales = flx.aitken_secant(f,
                                   x0,
                                   x1,
                                   xtol=10,
                                   ytol=1000.,
                                   maxiter=1000,
                                   args=args,
                                   checkiter=True)
     self._sales = sales
     return sales
Esempio n. 9
0
    def solve_Tx(self, z, P):
        """
        Dew point given composition and pressure.

        Parameters
        ----------
        z : ndarray
            Molar composition.
        P : float
            Pressure [Pa].

        Returns
        -------
        T : float
            Dew point temperature [K].
        x : numpy.ndarray
            Liquid phase molar composition.

        Examples
        --------
        >>> import thermosteam as tmo
        >>> import numpy as np
        >>> chemicals = tmo.Chemicals(['Water', 'Ethanol'], cache=True)
        >>> tmo.settings.set_thermo(chemicals)
        >>> DP = tmo.equilibrium.DewPoint(chemicals)
        >>> DP.solve_Tx(z=np.array([0.5, 0.5]), P=101325)
        (357.451847, array([0.849, 0.151]))
        """
        f = self._T_error
        z_norm = z / z.sum()
        zP = z * P
        args = (P, z_norm, zP)
        self.P = P
        T_guess = self.T or self._T_ideal(zP)
        try:
            T = flx.aitken_secant(f,
                                  T_guess,
                                  T_guess + 1e-3,
                                  1e-9,
                                  5e-12,
                                  args,
                                  checkiter=False)
        except (InfeasibleRegion, DomainError):
            Tmin = self.Tmin
            Tmax = self.Tmax
            T = flx.IQ_interpolation(f,
                                     Tmin,
                                     Tmax,
                                     f(Tmin, *args),
                                     f(Tmax, *args),
                                     T_guess,
                                     1e-9,
                                     5e-12,
                                     args,
                                     checkiter=False,
                                     checkbounds=False)
        self.x = fn.normalize(self.x)
        return T, self.x.copy()
Esempio n. 10
0
 def _run(self):
     steam = self.ins[1]
     steam_mol = steam.F_mol
     steam_mol = flx.aitken_secant(self.pressure_objective_function,
                                   steam_mol,
                                   steam_mol + 0.1,
                                   1e-4,
                                   1e-4,
                                   checkroot=False)
Esempio n. 11
0
 def solve_IRR(self):
     """Return the IRR at the break even point (NPV = 0) through cash flow analysis."""
     IRR = self._IRR
     if not IRR or np.isnan(IRR) or IRR < 0.: IRR = self.IRR
     if not IRR or np.isnan(IRR) or IRR < 0.: IRR = 0.10
     args = (self.cashflow_array, self._get_duration_array())
     self._IRR = flx.aitken_secant(NPV_at_IRR,
                                   IRR, 1.0001 * IRR + 1e-3, xtol=1e-6, ytol=10.,
                                   maxiter=200, args=args, checkiter=False)
     return self._IRR
Esempio n. 12
0
    def correct_mass_balance(self, variable=None):
        """
        Make sure mass is not created or destroyed by varying the 
        reactant stoichiometric coefficient.
        """
        if variable:
            index = self.chemicals.get_index(variable)
        else:
            index = self._X_index
        stoichiometry_by_wt = self._get_stoichiometry_by_wt()

        def f(x):
            stoichiometry_by_wt[index] = x
            return stoichiometry_by_wt.sum()

        flx.aitken_secant(f, 1)
        if self._basis == 'mol':
            self._stoichiometry[:] = stoichiometry_by_wt / self.MWs
        self._rescale()
Esempio n. 13
0
def adjust_F402_V():
    H2O_molfrac = D404_P.outs[0].get_molar_composition('H2O')
    V0 = H2O_molfrac
    F402.V = aitken_secant(f=purity_at_V,
                           x0=V0,
                           x1=V0 + 0.001,
                           xtol=0.001,
                           ytol=0.001,
                           maxiter=50,
                           args=())
Esempio n. 14
0
 def _run(self):
     feed, steam = self._ins
     steam_mol = steam.F_mol
     mixed = self.outs[0]
     steam_mol = aitken_secant(self._P_at_flow,
                               steam_mol, steam_mol+0.1, 
                               1e-4, 1e-4,
                               args=(self.P, steam, mixed, feed))
     mixed.P = self.P      
     hu = self.heat_utilities[0]
     hu(steam.Hvap, mixed.T)
Esempio n. 15
0
 def solve_IRR(self):
     """Return the IRR at the break even point (NPV = 0) through cash flow analysis."""
     IRR = self._IRR
     args = (self.cashflow, self._duration_array)
     IRR = flx.aitken_secant(NPV_at_IRR,
                             IRR,
                             1.0001 * IRR + 1e-3,
                             xtol=1e-6,
                             ytol=10.,
                             maxiter=200,
                             args=args,
                             checkiter=False)
     self._IRR = IRR
     return IRR
Esempio n. 16
0
 def solve_IRR(self):
     """Return the IRR at the break even point (NPV = 0) through cash flow analysis."""
     IRR = self._IRR
     args = (tuple([i.cashflow for i in self.TEAs]),
             tuple([i._duration_array for i in self.TEAs]))
     self._IRR = flx.aitken_secant(sum_NPV_at_IRR,
                                   IRR,
                                   1.0001 * IRR + 1e-3,
                                   xtol=1e-6,
                                   ytol=10.,
                                   maxiter=200,
                                   args=args,
                                   checkiter=False)
     return self._IRR
Esempio n. 17
0
    def solve_Py(self, z, T):
        """
        Bubble point at given composition and temperature.

        Parameters
        ----------
        z : ndarray
            Molar composotion.
        T : float
            Temperature [K].
        
        Returns
        -------
        P : float
            Bubble point pressure [Pa].
        y : ndarray
            Vapor phase molar composition.

        Examples
        --------
        >>> import thermosteam as tmo
        >>> import numpy as np
        >>> chemicals = tmo.Chemicals(['Water', 'Ethanol'], cache=True)
        >>> tmo.settings.set_thermo(chemicals)
        >>> BP = tmo.equilibrium.BubblePoint(chemicals)
        >>> BP.solve_Py(z=np.array([0.703, 0.297]), T=352.28)
        (91830.9798, array([0.419, 0.581]))
        
        """
        self.T = T
        Psat = array([i(T) for i in self.Psats])
        z_norm = z / z.sum()
        z_Psat_gamma_pcf = z * Psat * self.gamma(z_norm, T) * self.pcf(z_norm, T)
        f = self._P_error
        args = (T, z_Psat_gamma_pcf)
        P_guess = self.P or self._P_ideal(z_Psat_gamma_pcf)
        try:
            P = flx.aitken_secant(f, P_guess, P_guess-1, 1e-3, 1e-9,
                                  args, checkiter=False)
        except (InfeasibleRegion, DomainError):
            Pmin = self.Pmin; Pmax = self.Pmax
            P = flx.IQ_interpolation(f, Pmin, Pmax,
                                     f(Pmin, *args), f(Pmax, *args),
                                     P_guess, 1e-3, 5e-12, args,
                                     checkiter=False, checkbounds=False)
        self.y = fn.normalize(self.y)
        return P, self.y.copy()
Esempio n. 18
0
    def solve_Ty(self, z, P):
        """
        Bubble point at given composition and pressure.

        Parameters
        ----------
        z : ndarray
            Molar composotion.
        P : float
            Pressure [Pa].
        
        Returns
        -------
        T : float 
            Bubble point temperature [K].
        y : ndarray
            Vapor phase molar composition.

        Examples
        --------
        >>> import thermosteam as tmo
        >>> import numpy as np
        >>> chemicals = tmo.Chemicals(['Water', 'Ethanol'], cache=True)
        >>> tmo.settings.set_thermo(chemicals)
        >>> BP = tmo.equilibrium.BubblePoint(chemicals)
        >>> BP.solve_Ty(z=np.array([0.6, 0.4]), P=101325)
        (353.7543, array([0.381, 0.619]))
        
        """
        self.P = P
        f = self._T_error
        z_norm = z / z.sum()
        z_over_P = z_norm/P
        args = (P, z_over_P, z_norm)
        T_guess = self.T or self._T_ideal(z_over_P) 
        try:
            T = flx.aitken_secant(f, T_guess, T_guess + 1e-3,
                                  1e-9, 5e-12, args,
                                  checkiter=False)
        except (InfeasibleRegion, DomainError):
            Tmin = self.Tmin; Tmax = self.Tmax
            T = flx.IQ_interpolation(f, Tmin, Tmax,
                                     f(Tmin, *args), f(Tmax, *args),
                                     T_guess, 1e-9, 5e-12, args, 
                                     checkiter=False, checkbounds=False)
        self.y = fn.normalize(self.y)
        return T, self.y.copy()
Esempio n. 19
0
 def _run(self):
     ins = self._ins
     steam = ins[1]
     steam_mol = steam.molnet
     mixed = self.outs[0]
     index_water = mixed.index('7732-18-5')
     steam_mol = aitken_secant(self._P_at_flow,
                               steam_mol,
                               steam_mol + 0.1,
                               1e-4,
                               1e-4,
                               args=(self.P, steam.mol, index_water, mixed,
                                     ins))
     mixed.P = self.P
     hu = self._heat_utilities[0]
     hu.ID = 'Low pressure steam'
     hu.flow = steam_mol
     hu.cost = steam_mol * bst.HeatUtility.heating_agents[
         'Low pressure steam'].price_kmol
Esempio n. 20
0
 def solve_price(self, stream, TEA=None):
     """Return the price (USD/kg) of stream at the break even point (NPV = 0) through cash flow analysis. 
     
     Parameters
     ----------
     stream : :class:`~thermosteam.Stream`
              Stream with variable selling price.
     TEA : TEA, optional
           Stream should belong here.
         
     """
     TEAs = self.TEAs
     if not TEA:
         for TEA in TEAs:
             if stream in TEA.system.feeds or stream in TEA.system.products:
                 break
     price2cost = TEA._price2cost(stream)
     IRR = self.IRR
     NPV = self.NPV
     discount_factors = (1. + IRR)**TEA._duration_array
     coefficients = np.ones_like(discount_factors)
     start = TEA._start
     coefficients[:start] = 0
     w0 = TEA._startup_time
     coefficients[TEA._start] = w0 * TEA.startup_VOCfrac + (1 - w0)
     args = (NPV, coefficients, discount_factors)
     sales = self._sales or stream.price * price2cost
     sales = flx.aitken_secant(NPV_with_sales,
                               sales,
                               1.0001 * sales + 1e-4,
                               ytol=10.,
                               maxiter=200,
                               args=args,
                               checkiter=False)
     self._sales = sales
     if stream.sink:
         return stream.price - sales / price2cost
     elif stream.source:
         return stream.price + sales / price2cost
     else:
         raise ValueError("stream must be either a feed or a product")
Esempio n. 21
0
    def solve_Ty(self, z, P):
        """
        Bubble point at given composition and pressure.

        Parameters
        ----------
        z : ndarray
            Molar composition.
        P : float
            Pressure [Pa].
        
        Returns
        -------
        T : float 
            Bubble point temperature [K].
        y : ndarray
            Vapor phase molar composition.

        Examples
        --------
        >>> import thermosteam as tmo
        >>> import numpy as np
        >>> chemicals = tmo.Chemicals(['Water', 'Ethanol'], cache=True)
        >>> tmo.settings.set_thermo(chemicals)
        >>> BP = tmo.equilibrium.BubblePoint(chemicals)
        >>> BP.solve_Ty(z=np.array([0.6, 0.4]), P=101325)
        (353.7543, array([0.381, 0.619]))
        
        """
        positives = z > 0.
        N = positives.sum()
        if N == 0:
            raise ValueError('no components present')
        if N == 1:
            T = self.chemicals[fn.first_true_index(positives)].Tsat(P)
            y = z.copy()
        else:
            if P > self.Pmax: P = self.Pmax
            elif P < self.Pmin: P = self.Pmin
            f = self._T_error
            z_norm = z / z.sum()
            z_over_P = z / P
            T_guess, y = self._Ty_ideal(z_over_P)
            args = (P, z_over_P, z_norm, y)
            try:
                T = flx.aitken_secant(f,
                                      T_guess,
                                      T_guess + 1e-3,
                                      1e-9,
                                      5e-12,
                                      args,
                                      checkiter=False)
            except (InfeasibleRegion, DomainError):
                Tmin = self.Tmin
                Tmax = self.Tmax
                T = flx.IQ_interpolation(f,
                                         Tmin,
                                         Tmax,
                                         f(Tmin, *args),
                                         f(Tmax, *args),
                                         T_guess,
                                         1e-9,
                                         5e-12,
                                         args,
                                         checkiter=False,
                                         checkbounds=False)
        return T, fn.normalize(y)
Esempio n. 22
0
    def solve_Tx(self, z, P):
        """
        Dew point given composition and pressure.

        Parameters
        ----------
        z : ndarray
            Molar composition.
        P : float
            Pressure [Pa].

        Returns
        -------
        T : float
            Dew point temperature [K].
        x : numpy.ndarray
            Liquid phase molar composition.

        Examples
        --------
        >>> import thermosteam as tmo
        >>> import numpy as np
        >>> chemicals = tmo.Chemicals(['Water', 'Ethanol'], cache=True)
        >>> tmo.settings.set_thermo(chemicals)
        >>> DP = tmo.equilibrium.DewPoint(chemicals)
        >>> DP.solve_Tx(z=np.array([0.5, 0.5]), P=101325)
        (357.451847, array([0.849, 0.151]))
        
        """
        positives = z > 0.
        N = positives.sum()
        if N == 0:
            raise ValueError('no positive components present')
        if N == 1:
            T = self.chemicals[fn.first_true_index(positives)].Tsat(P)
            x = z.copy()
        else:
            if P > self.Pmax: P = self.Pmax
            elif P < self.Pmin: P = self.Pmin
            f = self._T_error
            z_norm = z / z.sum()
            zP = z * P
            T_guess, x = self._Tx_ideal(zP)
            args = (P, z_norm, zP, x)
            try:
                T = flx.aitken_secant(f,
                                      T_guess,
                                      T_guess + 1e-3,
                                      1e-9,
                                      5e-12,
                                      args,
                                      checkiter=False)
            except (InfeasibleRegion, DomainError):
                Tmin = self.Tmin
                Tmax = self.Tmax
                T = flx.IQ_interpolation(f,
                                         Tmin,
                                         Tmax,
                                         f(Tmin, *args),
                                         f(Tmax, *args),
                                         T_guess,
                                         1e-9,
                                         5e-12,
                                         args,
                                         checkiter=False,
                                         checkbounds=False)
        return T, fn.normalize(x)
Esempio n. 23
0
    def solve_Px(self, z, T):
        """
        Dew point given composition and temperature.

        Parameters
        ----------
        z : ndarray
            Molar composition.
        T : float
            Temperature (K).
        
        Returns
        -------
        P : float
            Dew point pressure (Pa).
        x : ndarray
            Liquid phase molar composition.

        Examples
        --------
        >>> import thermosteam as tmo
        >>> import numpy as np
        >>> chemicals = tmo.Chemicals(['Water', 'Ethanol'], cache=True)
        >>> tmo.settings.set_thermo(chemicals)
        >>> DP = tmo.equilibrium.DewPoint(chemicals)
        >>> DP.solve_Px(z=np.array([0.5, 0.5]), T=352.28)
        (82444.29876, array([0.853, 0.147]))
 
       """
        positives = z > 0.
        N = positives.sum()
        if N == 0:
            raise ValueError('no positive components present')
        if N == 1:
            P = self.chemicals[fn.first_true_index(z)].Psat(T)
            x = z.copy()
        else:
            if T > self.Tmax: T = self.Tmax
            elif T < self.Tmin: T = self.Tmin
            z_norm = z / z.sum()
            Psats = np.array([i(T) for i in self.Psats], dtype=float)
            z_over_Psats = z / Psats
            P_guess, x = self._Px_ideal(z_over_Psats)
            args = (T, z_norm, z_over_Psats, x)
            f = self._P_error
            try:
                P = flx.aitken_secant(f,
                                      P_guess,
                                      P_guess - 10,
                                      1e-3,
                                      5e-12,
                                      args,
                                      checkiter=False)
            except (InfeasibleRegion, DomainError):
                Pmin = self.Pmin
                Pmax = self.Pmax
                P = flx.IQ_interpolation(f,
                                         Pmin,
                                         Pmax,
                                         f(Pmin, *args),
                                         f(Pmax, *args),
                                         P_guess,
                                         1e-3,
                                         5e-12,
                                         args,
                                         checkiter=False,
                                         checkbounds=False)
        return P, fn.normalize(x)
Esempio n. 24
0
 x0, x1 = [-5, 5]
 f = lambda x: x**3 - 40 + 2*x 
 p = flx.Profiler(f)
 x_brentq = opt.brentq(p, x0, x1, xtol=1e-8)
 p.archive('[Scipy] Brent-Q') # Save/archive results with given name
 x_brenth = opt.brenth(p, x0, x1)
 p.archive('[Scipy] Brent-H')
 x_IQ = flx.IQ_interpolation(p, x0, x1)
 p.archive('IQ-interpolation')
 x_false_position = flx.false_position(p, x0, x1)
 p.archive('False position')
 p.plot(r'$f(x) = 0 = x^3 + 2 \cdot x - 40$ where $-5 < x < 5$')
 
 p = flx.Profiler(f)
 x_guess = -5
 x_aitken_secant = flx.aitken_secant(p, x_guess)
 p.archive('Aitken')
 x_secant = flx.secant(p, x_guess)
 p.archive('Secant')
 x_newton = opt.newton(p, x_guess)
 p.archive('[Scipy] Newton')
 p.plot(r'$f(x) = 0 = x^3 + 2 \cdot x - 40$')
 
 # Note that x = 40/x^2 - 2/x is the same
 # objective function as x**3 - 40 + 2*x = 0
 f = lambda x: 40/x**2 - 2/x
 p = flx.Profiler(f)
 x_guess = 5.
 x_wegstein = flx.wegstein(p, x_guess)
 p.archive('Wegstein')
 x_aitken = flx.aitken(p, x_guess)
Esempio n. 25
0
    def solve_Py(self, z, T):
        """
        Bubble point at given composition and temperature.

        Parameters
        ----------
        z : ndarray
            Molar composition.
        T : float
            Temperature [K].
        
        Returns
        -------
        P : float
            Bubble point pressure [Pa].
        y : ndarray
            Vapor phase molar composition.

        Examples
        --------
        >>> import thermosteam as tmo
        >>> import numpy as np
        >>> chemicals = tmo.Chemicals(['Water', 'Ethanol'], cache=True)
        >>> tmo.settings.set_thermo(chemicals)
        >>> BP = tmo.equilibrium.BubblePoint(chemicals)
        >>> BP.solve_Py(z=np.array([0.703, 0.297]), T=352.28)
        (91830.9798, array([0.419, 0.581]))
        
        """
        positives = z > 0.
        N = positives.sum()
        if N == 0:
            raise ValueError('no components present')
        if N == 1:
            P = self.chemicals[fn.first_true_index(positives)].Psat(T)
            y = z.copy()
        else:
            if T > self.Tmax: T = self.Tmax
            elif T < self.Tmin: T = self.Tmin
            Psat = np.array([i(T) for i in self.Psats])
            z_norm = z / z.sum()
            z_Psat_gamma_pcf = z * Psat * self.gamma(z_norm, T) * self.pcf(
                z_norm, T)
            f = self._P_error
            P_guess, y = self._Py_ideal(z_Psat_gamma_pcf)
            args = (T, z_Psat_gamma_pcf, y)
            try:
                P = flx.aitken_secant(f,
                                      P_guess,
                                      P_guess - 1,
                                      1e-3,
                                      1e-9,
                                      args,
                                      checkiter=False)
            except (InfeasibleRegion, DomainError):
                Pmin = self.Pmin
                Pmax = self.Pmax
                P = flx.IQ_interpolation(f,
                                         Pmin,
                                         Pmax,
                                         f(Pmin, *args),
                                         f(Pmax, *args),
                                         P_guess,
                                         1e-3,
                                         5e-12,
                                         args,
                                         checkiter=False,
                                         checkbounds=False)
        return P, fn.normalize(y)