Exemplo n.º 1
0
    def _design(self):
        feed_solids, feed_gases, lime, ammonia, boiler_chems, bag, natural_gas, \
            makeup_water = self.ins
        emission, ash, blowdown_water = self.outs
        side_streams_to_heat = self.side_streams_to_heat
        side_streams_lps = self.side_streams_lps
        system_heating_utilities = self.system_heating_utilities = {}
        lps = HeatUtility.get_heating_agent('low_pressure_steam')
        hps = HeatUtility.get_heating_agent('high_pressure_steam')

        # Use combustion reactions to create outs
        combustion_rxns = self.chemicals.get_combustion_reactions()
        combustible_feeds = Stream(None)
        emission.mol = feed_solids.mol + feed_gases.mol
        combustible_feeds.copy_flow(emission,
                                    tuple(self.combustibles),
                                    remove=True)
        combustion_rxns.force_reaction(combustible_feeds.mol)
        emission.mol += (combustible_feeds.mol + ammonia.mol)

        self.emission_rxns.force_reaction(emission.mol)

        # FGD lime scaled based on SO2 generated,
        # 20% stoichiometetric excess based on P52 of ref [1]
        lime.imol['Lime'] = max(0, -emission.imol['Lime'] * 1.2)
        emission.mol += lime.mol

        # Air/O2 usage not rigorously modeled
        emission.imol['O2'] = 0

        ash.empty()
        for chemical in emission.chemicals:
            if chemical.ID not in ('Water',
                                   'H2O') and chemical.locked_state != 'g':
                ash.imol[chemical.ID] = emission.imol[chemical.ID]
                emission.imol[chemical.ID] = 0
        emission.imol[
            'Water'] = feed_solids.imol['Water'] + feed_gases.imol['Water']

        ash.mol += boiler_chems.mol

        emission.phase = 'g'
        ash.phase = 's'
        # Assume T of emission and ash are the same as hps, which
        # has highest T amont all heating agents
        emission.T = ash.T = hps.T

        # Total heat generated by the boiler (kJ/hr)
        H_in = feed_solids.H + feed_gases.H
        H_out = emission.H + ash.H
        # Water evaporation energy is already accounted for in emission enthalpy
        heat_from_combustion = -(feed_solids.HHV + feed_gases.HHV)
        heat_generated = self.heat_generated = \
            (H_in+heat_from_combustion)*self.B_eff - H_out

        for u in self.system.units:
            if u is self: continue
            if hasattr(u, 'heat_utilities'):
                for hu in u.heat_utilities:
                    # Including low/medium/high_pressure_steam
                    if hu.flow * hu.duty > 0:
                        system_heating_utilities[f'{u.ID} - {hu.ID}'] = hu

        # Use lps to account for the energy needed for the side steam
        if side_streams_to_heat:
            if not side_streams_lps:
                side_streams_lps = self.side_streams_lps = HeatUtility()
                side_streams_lps.load_agent(lps)
            side_streams_lps(duty=sum([i.H for i in side_streams_to_heat]),
                             T_in=298.15)
            system_heating_utilities[
                'CHP - side_streams_lps'] = side_streams_lps

        system_heating_demand = self.system_heating_demand = \
            sum([i.duty for i in system_heating_utilities.values()])

        CHP_heat_surplus = self.CHP_heat_surplus = heat_generated - system_heating_demand
        self.system_steam_demand = sum(
            [i.flow for i in system_heating_utilities.values()])

        hu_cooling = HeatUtility()

        # CHP can meet system heating/steam demand
        if CHP_heat_surplus > 0:
            # 3600 is conversion of kJ/hr to kW (kJ/s)
            electricity_generated = self.electricity_generated = \
                CHP_heat_surplus * self.TG_eff / 3600

            # Take the opposite for cooling duty (i.e., cooling duty should be negative)
            # this is to condense the unused steam
            cooling_need = self.cooling_need = -(CHP_heat_surplus -
                                                 electricity_generated)
            hu_cooling(duty=cooling_need, T_in=lps.T)
            natural_gas.empty()

        # CHP cannot meet system heating/steam demand, supplement with natural gas
        else:
            CH4_LHV = natural_gas.chemicals.CH4.LHV
            natural_gas.imol['CH4'] = CHP_heat_surplus / (CH4_LHV * self.B_eff)
            emission.imol['CO2'] += natural_gas.imol['CH4']
            emission.imol['H2O'] += 2 * natural_gas.imol['CH4']
            electricity_generated = self.electricity_generated = 0

        heating_utilities = HeatUtility.sum_by_agent(
            system_heating_utilities.values())
        for i in heating_utilities:
            i.reverse()

        if hu_cooling.duty != 0:
            self.heat_utilities = tuple([hu_cooling, *heating_utilities])
        else:
            self.heat_utilities = tuple(heating_utilities)

        total_steam_mol = sum(
            [i.flow for i in system_heating_utilities.values()])
        total_steam = total_steam_mol * self.chemicals.H2O.MW
        blowdown_water.imass['H2O'] = total_steam * self.blowdown
        blowdown_water.T = 373.15

        # Additional need for making lime slurry
        makeup_water.imol[
            'H2O'] = blowdown_water.imol['H2O'] + lime.F_mol / 0.2 * 0.8

        # 1.23 is $2007/hour and 2.2661 is 2007$/lb from Table 30 in ref [1],
        # 144.629 is the total duty from Page 131 in ref [1],
        # 2.20462 is kg to lb, 4.184 is kcal to kJ,
        ratio = system_heating_demand / (144.629 * 1e6 * 4.184)
        boiler_chems.imass['BoilerChems'] = 1.23 / 2.2661 / 2.20462 * ratio
        bag.imass['BaghouseBag'] = ratio

        self.design_results['Flow rate'] = total_steam
        self.design_results['Work'] = electricity_generated
Exemplo n.º 2
0
    def _design(self):
        feed, natural_gas, air = self.ins
        emission, ash = self.outs
        for i in (natural_gas, air, ash):
            i.empty()
        feed.phase = natural_gas.phase = air.phase = emission.phase = 'g'
        ash.phase = 's'
        emission.P = ash.P = 101325
        emission.T = ash.T = 298.15
        self._refresh_sys()

        cmps = self.components
        rxns = []
        for cmp in cmps:
            if cmp.locked_state in ('l', 's') and (
                    not cmp.organic or cmp.degradability == 'Undegradable'):
                continue
            rxn = cmp.get_combustion_reaction()
            if rxn:
                rxns.append(rxn)
        combustion_rxns = self.combustion_reactions = ParallelReaction(rxns)

        def react(natural_gas_flow=0):
            emission.copy_flow(feed)
            emission.imol['CH4'] += natural_gas_flow
            natural_gas.imol['CH4'] = natural_gas_flow
            combustion_rxns.force_reaction(emission.mol)
            air.imol['O2'] = -emission.imol['O2']
            emission.imol['N2'] = air.imol['N2'] = air.imol['O2'] / 0.21 * 0.79
            emission.imol['O2'] = 0
            H_net_feed = feed.H + feed.HHV - emission.H  # substracting the energy in emission
            return H_net_feed

        # Calculate extra natural gas needed to supplement the utilities
        supp_utility = self.supplement_utility
        kwds = dict(system=self.system,
                    operating_hours=1.,
                    exclude_units=(self, ))
        hus = self.heat_utilities
        pu = self.power_utility
        if supp_utility:
            H_needs = self.H_needs = sum_system_utility(
                **kwds, utility='heating',
                result_unit='kJ') / self.combustion_eff
            if supp_utility == 'power':
                pu.production = sum_system_utility(**kwds,
                                                   utility='power',
                                                   result_unit='kWh')
                H_needs += pu.production / self.combined_eff
            # Objective function to calculate the excess heat at a given natural gas flow rate
            def H_excess_at_natural_gas_flow(flow):
                return H_needs - react(flow)

            lb = 0
            ub = react() / cmps.CH4.LHV * 2
            while H_excess_at_natural_gas_flow(ub) < H_needs:
                lb = ub
                ub *= 2
            IQ_interpolation(H_excess_at_natural_gas_flow,
                             x0=lb,
                             x1=ub,
                             xtol=1e-3,
                             ytol=1)
            # Update heating and power utilities
            hus = HeatUtility.sum_by_agent(
                tuple([i for i in self.sys_heating_utilities]))
            for hu in hus:
                hu.reverse()

        else:
            H_needs = self.H_needs = 0.
            self.H_net_feed = react(0)
            hus = ()
            pu.production = 0

        ash_IDs = [i.ID for i in cmps if not i.formula]
        ash.copy_flow(emission, IDs=tuple(ash_IDs), remove=True)
Exemplo n.º 3
0
 def __init__(self, ID='', ins=None, outs=()):
     Facility.__init__(self, ID, ins, outs)
     self.agent = HeatUtility.get_cooling_agent('cooling_water')
Exemplo n.º 4
0
    def _cost(self):
        # def _design(self):

        # min_app_T = self.min_app_T
        sys = self.system
        # Flow_vector = []

        # T_in_vector = []
        # VF_in_vector = []

        # T_out_vector = []
        # VF_out_vector = []

        # Cp_vector = []
        # LH_vector = []
        # Tb_vector = []
        # Td_vector = []
        # duties = []

        hx_utils = bst.process_tools.heat_exchanger_utilities_from_units(
            sys.units)
        hx_utils.sort(key=lambda x: x.duty)

        matches_hs, matches_cs, Q_hot_side, Q_cold_side, unavailables, act_hot_util_load,\
        act_cold_util_load, HXs_hot_side, HXs_cold_side, new_HX_utils, hxs, T_in_arr,\
            T_out_arr, pinch_T_arr, C_flow_vector, hx_utils_rearranged, streams, stream_HXs_dict,\
                hot_indices, cold_indices = synthesize_network(hx_utils, T_min_app = self.T_min_app)

        original_purchase_costs = [hx.purchase_cost for hx in hxs]
        original_installed_costs = [hx.installed_cost for hx in hxs]
        # original_utility_costs = [hx.utility_cost for hx in hxs]

        new_purchase_costs_HXp = []
        # new_purchase_costs_HXu = list(original_purchase_costs)
        new_purchase_costs_HXu = []
        new_installed_costs_HXp = []
        # new_installed_costs_HXu = list(original_installed_costs)
        new_installed_costs_HXu = []

        # new_utility_costs = copy.deepcopy(original_utility_costs)
        new_utility_costs = []
        # new_heat_utilities = copy.deepcopy(original_heat_utilities)

        for hx in new_HX_utils:
            new_installed_costs_HXu.append(hx.installed_cost)
            new_purchase_costs_HXu.append(hx.purchase_cost)
            new_utility_costs.append(hx.utility_cost)

        new_HXs = HXs_hot_side + HXs_cold_side

        for new_HX in new_HXs:
            new_purchase_costs_HXp.append(new_HX.purchase_cost)
            new_installed_costs_HXp.append(new_HX.installed_cost)
        # init_heating_sum, init_cooling_sum = init_hot_util_load, init_cold_util_load


        self.purchase_costs['Heat exchangers'] = (sum(new_purchase_costs_HXp) + sum(new_purchase_costs_HXu)) \
            - (sum(original_purchase_costs))

        hu_sums1 = HeatUtility.sum_by_agent(hx_utils_rearranged)

        # hx_utils_applicable2 = [HeatUtility() for i in range(len(hx_utils_rearranged))]

        # QTs2 = []
        # for hx_util in new_HX_utils:
        #     QTs2.append((hx_util.Q, hx_util.T))
        # for hu, (Q, T) in zip(hx_utils_applicable2, QTs2): hu(Q, T)
        # hu_sums2 = HeatUtility.sum_by_agent(hx_utils_applicable2)

        # for hu, hx in zip(hx_utils_applicable2, new_HX_utils): hu(hx.Q, hx.T)
        hu_sums2 = HeatUtility.sum_by_agent(
            sum([hx.heat_utilities for hx in new_HX_utils], ()))

        # to change sign on duty without switching heat/cool (i.e. negative costs):
        for hu in hu_sums1:
            hu.reverse()

        hus_final = tuple(HeatUtility.sum_by_agent(hu_sums1 + hu_sums2))



        self._installed_cost = (sum(new_installed_costs_HXp) + sum(new_installed_costs_HXu)) \
            - (sum(original_installed_costs))

        self.heat_utilities = hus_final
        self.new_HXs = new_HXs
        self.new_HX_utils = new_HX_utils
        self.orig_heat_utils = hx_utils_rearranged
        self.original_purchase_costs = original_purchase_costs
        self.original_utility_costs = hu_sums1
        self.new_purchase_costs_HXp = new_purchase_costs_HXp
        self.new_purchase_costs_HXu = new_purchase_costs_HXu
        self.new_utility_costs = hu_sums2
        self.stream_HXs_dict = stream_HXs_dict