예제 #1
0
    def __init__(self):
        """
        Load up the necessary sub-structures to be filled with
        the code that follows
        """
        self.Compressor = CompressorClass()

        #Outdoor coil is a Condenser in cooling mode and evaporator in heating mode

        self.CoolingCoil = CoolingCoilClass()
        self.CoolingCoil.Fins = FinInputs()
        self.Pump = PumpClass()
        #Add both types of internal heat exchangers
        self.CoaxialIHX = CoaxialHXClass()
        self.PHEIHX = PHEHXClass()
        self.LineSetSupply = LineSetOptionClass()
        self.LineSetReturn = LineSetOptionClass()
        self.LineSetSuction = LineSetOptionClass()
        self.LineSetDischarge = LineSetOptionClass()
        self.LineSetLiquid = LineSetOptionClass()

        #Make IHX an empty class for holding parameters common to PHE and Coaxial IHX
        class struct:
            pass

        self.IHX = struct()
예제 #2
0
파일: PHECycle.py 프로젝트: tongue01/ACHP
 def __init__(self):
     """
     Load up the necessary sub-structures to be filled with
     the code that follows
     """
     self.Compressor = CompressorClass()
     self.CoolingCoil = CoolingCoilClass()
     self.CoolingCoil.Fins = FinInputs()
     self.PHEHX = PHEHXClass()
     self.Pump = PumpClass()
예제 #3
0
FinsTubes.Fins.Pd = 0.001
FinsTubes.Fins.xf = 0.001
FinsTubes.Fins.t = 0.00011
FinsTubes.Fins.k_fin = 237

FinsTubes.Air.Vdot_ha = 0.5663
FinsTubes.Air.Tmean = 299.8
FinsTubes.Air.Tdb = 299.8
FinsTubes.Air.p = 101325  #Air pressure in Pa
FinsTubes.Air.RH = 0.51
FinsTubes.Air.RHmean = 0.51
FinsTubes.Air.FanPower = 438  #fan power in Watts

# Here are two equivalent methods for setting parameters
# 1. Create an empty instance of the class, then set parameters CC=CoolingCoilClass()
CC = CoolingCoilClass()
CC.Fins = FinsTubes
CC.FinsType = 'WavyLouveredFins'  #Choose fin Type: 'WavyLouveredFins' or 'HerringboneFins'or 'PlainFins'
CC.Ref_g = 'Water'
CC.mdot_g = 0.15
CC.Tin_g = 278
CC.pin_g = 300000  #Refrigerant vapor pressure in Pa
CC.Verbosity = 3
CC.Calculate()

print "Method 1:"
print "Cooling Coil Q: " + str(CC.Q) + " W"
print "Cooling Coil SHR: " + str(CC.SHR) + " "

# 2. Build a dictionary of values, then use that to initialize the class
kwds = {
예제 #4
0
파일: PHECycle.py 프로젝트: tongue01/ACHP
class SecondaryCycleClass():
    def __init__(self):
        """
        Load up the necessary sub-structures to be filled with
        the code that follows
        """
        self.Compressor = CompressorClass()
        self.CoolingCoil = CoolingCoilClass()
        self.CoolingCoil.Fins = FinInputs()
        self.PHEHX = PHEHXClass()
        self.Pump = PumpClass()

    def Update(self):
        '''
        Update cycle class with selected HX type
        Update cyle class with Abstract State
        '''
        if self.EvapSolver == 'Moving-Boundary':
            if self.EvapType == 'Fin-tube':
                self.Evaporator = EvaporatorClass()
                self.Evaporator.Fins = FinInputs()
            elif self.EvapType == 'Micro-channel':
                raise
            else:
                raise
        elif self.EvapSolver == 'Finite-Element':
            raise
        else:
            raise

        if self.CondSolver == 'Moving-Boundary':
            if self.CondType == 'Fin-tube':
                self.Condenser = CondenserClass()
                self.Condenser.Fins = FinInputs()
            elif self.CondType == 'Micro-channel':
                self.Condenser = MicroCondenserClass()
                self.Condenser.Fins = MicroFinInputs()
            else:
                raise
        elif self.CondSolver == 'Finite-Element':
            raise
        else:
            raise

        #Abstract State
        self.AS = CP.AbstractState(self.Backend, self.Ref)
        if hasattr(self, 'MassFrac'):
            self.AS.set_mass_fractions([self.MassFrac])
        elif hasattr(self, 'VoluFrac'):
            self.AS.set_volu_fractions([self.VoluFrac])
        #Abstract State for SecLoopFluid
        self.AS_SLF = CP.AbstractState(self.Backend_SLF, self.SecLoopFluid)
        if hasattr(self, 'MassFrac_SLF'):
            self.AS_SLF.set_mass_fractions([self.MassFrac_SLF])
        elif hasattr(self, 'VoluFrac_SLF'):
            self.AS_SLF.set_volu_fractions([self.VoluFrac_SLF])

    def Calculate(self, DT_evap, DT_cond, Tin_IHX):
        """
        Inputs are differences in temperature [K] between HX air inlet temperature 
        and the dew temperature for the heat exchanger.
        
        Required Inputs:
            DT_evap: 
                Difference in temperature [K] between cooling coil air inlet temperature and refrigerant dew temperature
            DT_cond:
                Difference in temperature [K] between condenser air inlet temperature and refrigeant dew temperature
            Tin_IHX:
                Inlet "glycol" temperature to IHX   
        """
        if self.Verbosity > 1:
            print('Inputs: DTevap %7.4f DTcond %7.4f fT_IHX %7.4f' %
                  (DT_evap, DT_cond, Tin_IHX))

        #AbstractState
        AS = self.AS
        #AbstractState for SecLoopFluid
        AS_SLF = self.AS_SLF
        """
        The coldest the glycol entering the cooling coil could be would be the 
        """
        self.Tdew_cond = self.Condenser.Fins.Air.Tdb + DT_cond
        self.Tdew_evap = self.CoolingCoil.Fins.Air.Tdb - DT_evap
        AS.update(CP.QT_INPUTS, 1.0, self.Tdew_cond)
        psat_cond = AS.p()  #[Pa]
        AS.update(CP.QT_INPUTS, 1.0, self.Tdew_evap)
        psat_evap = AS.p()  #[Pa]
        AS.update(CP.PQ_INPUTS, psat_evap, 0.0)
        self.Tbubble_evap = AS.T()  #[K]

        params={               #dictionary -> key:value, e.g. 'key':2345,
            'pin_r': psat_evap,
            'pout_r': psat_cond,
            'Tin_r': self.Tdew_evap+self.Compressor.DT_sh,
            'AS': AS,
        }
        self.Compressor.Update(**params)
        self.Compressor.Calculate()

        params = {
            'mdot_r': self.Compressor.mdot_r,
            'Tin_r': self.Compressor.Tout_r,
            'psat_r': psat_cond,
            'AS': AS,
        }
        self.Condenser.Update(**params)
        self.Condenser.Calculate()

        AS.update(CP.QT_INPUTS, 0.0, self.Tbubble_evap)
        hL = AS.hmass()  #[J/kg]
        AS.update(CP.QT_INPUTS, 1.0, self.Tdew_evap)
        hV = AS.hmass()  #[J/kg]
        xin_r = (self.Condenser.hout_r - hL) / (hV - hL)
        AS_SLF.update(CP.PT_INPUTS, 300000, Tin_IHX)
        h_in = AS_SLF.hmass()  #[J/kg]
        params = {
            'mdot_h': self.Pump.mdot_g,
            'hin_h': h_in,
            'hin_c': self.Condenser.hout_r,
            'mdot_c': self.Compressor.mdot_r,
            'pin_c': psat_evap,
            'xin_c': xin_r,
            'AS_c': AS,
            'AS_h': AS_SLF,
        }
        self.PHEHX.Update(**params)
        self.PHEHX.Calculate()

        #Now run CoolingCoil to predict inlet glycol temperature to IHX
        params = {
            'mdot_g': self.Pump.mdot_g,
            'Tin_g': self.PHEHX.Tout_h,
            'AS_g': AS_SLF,
        }
        self.CoolingCoil.Update(**params)
        self.CoolingCoil.Calculate()

        params = {
            'DP_g': self.PHEHX.DP_h + self.CoolingCoil.DP_g,
            'Tin_g': self.CoolingCoil.Tout_g,
            'AS_g': AS_SLF,
        }
        self.Pump.Update(**params)
        self.Pump.Calculate()

        self.Charge = self.Condenser.Charge + self.PHEHX.Charge_c
        self.EnergyBalance = self.Compressor.CycleEnergyIn + self.Condenser.Q + self.PHEHX.Q

        resid = np.zeros((3))
        resid[0] = self.EnergyBalance

        if self.ImposedVariable == 'Subcooling':
            resid[1] = self.Condenser.DT_sc - self.DT_sc_target
        elif self.ImposedVariable == 'Charge':
            resid[1] = self.Charge - self.Charge_target
        resid[2] = self.PHEHX.Q - self.CoolingCoil.Q

        if self.Verbosity > 1:
            print(
                'Qres % 12.6e Resid2: % 12.6e ResSL %10.4f Charge %10.4f SC: %8.4f'
                % (resid[0], resid[1], resid[2], self.Charge,
                   self.Condenser.DT_sc))

        self.Capacity = self.CoolingCoil.Capacity
        self.COP = self.CoolingCoil.Q / self.Compressor.W
        self.COSP = self.CoolingCoil.Capacity / (
            self.Compressor.W + self.Pump.W +
            self.CoolingCoil.Fins.Air.FanPower +
            self.Condenser.Fins.Air.FanPower)
        self.SHR = self.CoolingCoil.SHR
        return resid

    def PreconditionedSolve(self):
        # Takes the place of a lambda function since lambda functions do not
        # bubble the error up properly
        def OBJECTIVE(x):
            return self.Calculate(x[0], x[1], x[2])

        # Increase DT_evap in increments of 0.5 K until the system solves, and
        # two steps cause a sign change in cycle energy balance
        # Should give a starting point quite close to the "right" soluton
        oldDT_evap = None
        oldQresid = None
        Tin_IHX = None
        for DT_evap in np.linspace(12, 25, 21):
            try:
                #Run the cooler to get a good starting inlet temperature for IHX
                self.CoolingCoil.mdot_g = self.Pump.mdot_g
                self.CoolingCoil.Tin_g = self.CoolingCoil.Fins.Air.Tdb - DT_evap
                self.CoolingCoil.AS_g = self.AS_SLF
                self.CoolingCoil.Calculate()
                Tin_IHX = self.CoolingCoil.Tout_g
                resid = self.Calculate(DT_evap, 8, Tin_IHX)
            except Exception, e:
                if self.Verbosity > 1:
                    print('Failed: ', e.__str__())
                raise
                pass
            else:
                #Not set yet, first one that works
                if oldQresid == None:
                    oldQresid = resid[0]
                    oldDT_evap = DT_evap
                #Has been set, and sign changes, use average of old and new DT
                elif oldQresid * resid[0] < 0:
                    DT_evap = (DT_evap + oldDT_evap) / 2
                    break

        #Run the Newton-Raphson solver to solve the system
        x = fsolve(OBJECTIVE, [DT_evap, 20, Tin_IHX])

        if self.Verbosity > 1:
            print('Capacity: ', self.Capacity)
            print('COP: ', self.COP)
            print('COP (w/ both fans): ', self.COSP)
            print('SHR: ', self.SHR)
예제 #5
0
FinsTubes.Fins.Pd=0.001
FinsTubes.Fins.xf=0.001
FinsTubes.Fins.t=0.00011
FinsTubes.Fins.k_fin=237

FinsTubes.Air.Vdot_ha=0.5663
FinsTubes.Air.Tmean=299.8
FinsTubes.Air.Tdb= 299.8
FinsTubes.Air.p=101325              #Air pressure in Pa
FinsTubes.Air.RH=0.51
FinsTubes.Air.RHmean=0.51
FinsTubes.Air.FanPower=438          #fan power in Watts

# Here are two equivalent methods for setting parameters
# 1. Create an empty instance of the class, then set parameters CC=CoolingCoilClass()
CC=CoolingCoilClass()
CC.Fins = FinsTubes
CC.FinsType = 'WavyLouveredFins'    #Choose fin Type: 'WavyLouveredFins' or 'HerringboneFins'or 'PlainFins'
CC.Ref_g = 'Water'
CC.mdot_g = 0.15
CC.Tin_g = 278
CC.pin_g = 300000                   #Refrigerant vapor pressure in Pa
CC.Verbosity = 3
CC.Calculate()

print "Method 1:"
print "Cooling Coil Q: " + str(CC.Q) + " W"
print "Cooling Coil SHR: " + str(CC.SHR) + " "

# 2. Build a dictionary of values, then use that to initialize the class
kwds={'Fins':FinsTubes,
예제 #6
0
class SecondaryCycleClass():
    def __init__(self):
        """
        Load up the necessary sub-structures to be filled with
        the code that follows
        """
        self.Compressor = CompressorClass()

        #Outdoor coil is a Condenser in cooling mode and evaporator in heating mode

        self.CoolingCoil = CoolingCoilClass()
        self.CoolingCoil.Fins = FinInputs()
        self.Pump = PumpClass()
        #Add both types of internal heat exchangers
        self.CoaxialIHX = CoaxialHXClass()
        self.PHEIHX = PHEHXClass()
        self.LineSetSupply = LineSetOptionClass()
        self.LineSetReturn = LineSetOptionClass()
        self.LineSetSuction = LineSetOptionClass()
        self.LineSetDischarge = LineSetOptionClass()
        self.LineSetLiquid = LineSetOptionClass()

        #Make IHX an empty class for holding parameters common to PHE and Coaxial IHX
        class struct:
            pass

        self.IHX = struct()

    def Update(self):
        '''
        Update cycle class with selected HX type
        Update cycle class with Abstract State
        '''
        if self.EvapSolver == 'Moving-Boundary':
            if self.EvapType == 'Fin-tube':
                self.Evaporator = EvaporatorClass()
                self.Evaporator.Fins = FinInputs()
            elif self.EvapType == 'Micro-channel':
                raise
            else:
                raise
        elif self.EvapSolver == 'Finite-Element':
            raise
        else:
            raise

        if self.CondSolver == 'Moving-Boundary':
            if self.CondType == 'Fin-tube':
                self.Condenser = CondenserClass()
                self.Condenser.Fins = FinInputs()
            elif self.CondType == 'Micro-channel':
                self.Condenser = MicroCondenserClass()
                self.Condenser.Fins = MicroFinInputs()
            else:
                raise
        elif self.CondSolver == 'Finite-Element':
            raise
        else:
            raise

        #Abstract State
        self.AS = CP.AbstractState(self.Backend, self.Ref)
        if hasattr(self, 'MassFrac'):
            self.AS.set_mass_fractions([self.MassFrac])
        elif hasattr(self, 'VoluFrac'):
            self.AS.set_volu_fractions([self.VoluFrac])
        #Abstract State for SecLoopFluid
        self.AS_SLF = CP.AbstractState(self.Backend_SLF, self.SecLoopFluid)
        if hasattr(self, 'MassFrac_SLF'):
            self.AS_SLF.set_mass_fractions([self.MassFrac_SLF])
        elif hasattr(self, 'VoluFrac_SLF'):
            self.AS_SLF.set_volu_fractions([self.VoluFrac_SLF])

    def OutputList(self):
        """
            Return a list of parameters for this component for further output
            
            It is a list of tuples, and each tuple is formed of items:
                [0] Description of value
                [1] Units of value
                [2] The value itself
        """
        return [
            ('Charge', 'kg', self.Charge),
            ('Condenser Subcooling', 'K', self.DT_sc),
            ('Primary Ref.', '-', self.Ref),
            ('Secondary Ref.', '-', self.SecLoopFluid),
            ('Imposed Variable', '-', self.ImposedVariable),
            ('IHX Type', '-', self.IHXType),
            ('COP', '-', self.COP),
            ('COSP', '-', self.COSP),
            ('Net Capacity', 'W', self.CoolingCoil.Capacity),
            ('Net Power', 'W', self.Power),
            ('SHR', '-', self.SHR),
            ('Condensation temp (dew)', 'K', self.Tdew_cond),
            ('Evaporation temp (dew)', 'K', self.Tdew_evap),
        ]

    def Calculate(self, DT_evap, DT_cond, Tin_CC):
        """
        Inputs are differences in temperature [K] between HX air inlet temperature 
        and the dew temperature for the heat exchanger.
        
        Required Inputs:
            DT_evap: 
                Difference in temperature [K] between cooling coil air inlet temperature and refrigerant dew temperature
            DT_cond:
                Difference in temperature [K] between condenser air inlet temperature and refrigerant dew temperature
            Tin_CC:
                Inlet "glycol" temperature to line set feeding cooling coil   
        """
        if self.Verbosity > 1:
            print('Inputs: DTevap %7.4f DTcond %7.4f fT_IHX %7.4f' %
                  (DT_evap, DT_cond, Tin_CC))

        #AbstractState
        AS = self.AS
        #AbstractState for SecLoopFluid
        AS_SLF = self.AS_SLF

        #Store the values to save on computation for later
        self.DT_evap = DT_evap
        self.DT_cond = DT_cond
        self.Tin_CC = Tin_CC

        #If the user doesn't include the Mode, set it to Air Conditioning
        if not hasattr(self, 'Mode'):
            self.Mode = 'AC'

        if self.Mode == 'AC':
            self.Tdew_cond = self.Condenser.Fins.Air.Tdb + DT_cond
            self.Tdew_evap = self.CoolingCoil.Fins.Air.Tdb - DT_evap
        elif self.Mode == 'HP':
            self.Tdew_cond = Tin_CC + DT_cond
            self.Tdew_evap = self.Evaporator.Fins.Air.Tdb - DT_evap
        else:
            raise ValueError('Mode must be AC or HP')

        #Evaporator and condeser saturation pressures
        AS.update(CP.QT_INPUTS, 1.0, self.Tdew_cond)
        psat_cond = AS.p()  #[Pa]
        AS.update(CP.QT_INPUTS, 1.0, self.Tdew_evap)
        psat_evap = AS.p()  #[Pa]

        #Evaporator and condeser bubble temepratures
        AS.update(CP.PQ_INPUTS, psat_evap, 0.0)
        self.Tbubble_evap = AS.T()  #[K]
        AS.update(CP.PQ_INPUTS, psat_cond, 0.0)
        self.Tbubble_cond = AS.T()  #[K]

        #Cycle solver for 'AC' mode
        if self.Mode == 'AC':
            if not hasattr(self.Compressor,
                           'mdot_r') or self.Compressor.mdot_r < 0.00001:
                # The first run of model, run the compressor just so you can get a preliminary value
                # for the mass flow rate for the line set
                params={               #dictionary -> key:value, e.g. 'key':2345,
                    'pin_r': psat_evap,
                    'pout_r': psat_cond,
                    'Tin_r': self.Tdew_evap+self.DT_sh,
                    'AS': AS,
                }
                self.Compressor.Update(**params)
                self.Compressor.Calculate()

            #Calculate inlet enthalpy
            AS.update(CP.PT_INPUTS, psat_evap, self.Tdew_evap + self.DT_sh)
            h_in = AS.hmass()  #[J/kg]
            params = {
                'Tin': self.Tdew_evap + self.DT_sh,
                'pin': psat_evap,
                'hin': h_in,
                'mdot': self.Compressor.mdot_r,
                'AS': AS,
                'Name': 'Suction Line'
            }
            self.LineSetSuction.Update(**params)
            self.LineSetSuction.Calculate()

            params = {  #dictionary -> key:value, e.g. 'key':2345,
                'pin_r':
                psat_evap + self.DP_low,
                'pout_r':
                psat_cond - self.DP_high,
                'Tin_r':
                TrhoPhase_ph(self.AS, psat_evap, self.LineSetSuction.hout,
                             self.Tbubble_evap, self.Tdew_evap)[0],
                'AS':
                AS
            }
            self.Compressor.Update(**params)
            self.Compressor.Calculate()

            params = {
                'Tin': self.Compressor.Tout_r,
                'pin': psat_cond,
                'hin': self.Compressor.hout_r,
                'mdot': self.Compressor.mdot_r,
                'AS': AS,
                'Name': 'Discharge Line'
            }
            self.LineSetDischarge.Update(**params)
            self.LineSetDischarge.Calculate()

            params = {
                'mdot_r': self.Compressor.mdot_r,
                'Tin_r': self.Compressor.Tout_r,
                'psat_r': psat_cond,
                'AS': AS,
                #'Oil': self.Oil,
                #'shell_pressure':self.shell_pressure,
            }
            self.Condenser.Update(**params)
            self.Condenser.Calculate()

            params = {
                'Tin': self.Condenser.Tout_r,
                'pin': psat_cond,
                'hin': self.Condenser.hout_r,
                'mdot': self.Compressor.mdot_r,
                'AS': AS,
                'Name': 'Liquid Line'
            }
            self.LineSetLiquid.Update(**params)
            self.LineSetLiquid.Calculate()

            #Inlet enthalpy to LineSetSupply
            AS_SLF.update(CP.PT_INPUTS, self.Pump.pin_g, Tin_CC)
            h_in_LineSetSupply = AS_SLF.hmass()  #[J/kg]
            params = {
                'Tin': Tin_CC,
                'mdot': self.Pump.mdot_g,
                'hin': h_in_LineSetSupply,
                'pin': self.Pump.pin_g,
                'AS': AS_SLF,
                'Name': 'Supply Line'
            }
            self.LineSetSupply.Update(**params)
            self.LineSetSupply.Calculate()

            #Now run CoolingCoil to predict inlet glycol temperature to IHX
            params = {
                'mdot_g': self.Pump.mdot_g,
                'Tin_g': self.LineSetSupply.Tout,
                'pin_g': self.CoolingCoil.pin_g,
                'AS_g': AS_SLF
            }
            self.CoolingCoil.Update(**params)
            self.CoolingCoil.Calculate()

            #Inlet enthalpy to LineSetReturn
            AS_SLF.update(CP.PT_INPUTS, self.Pump.pin_g,
                          self.CoolingCoil.Tout_g)
            h_in_LineSetReturn = AS_SLF.hmass()  #[J/kg]
            params = {
                'Tin': self.CoolingCoil.Tout_g,
                'mdot': self.Pump.mdot_g,
                'hin': h_in_LineSetReturn,
                'pin': self.CoolingCoil.pin_g,
                'AS': AS_SLF,
                'Name': 'Return Line'
            }
            self.LineSetReturn.Update(**params)
            self.LineSetReturn.Calculate()

            if self.IHXType == 'Coaxial':
                params = {
                    'mdot_g': self.Pump.mdot_g,
                    'Tin_g': self.CoolingCoil.Tout_g,
                    'pin_g': self.Pump.pin_g,
                    'AS_g': AS_SLF,
                    'pin_r': psat_evap,
                    'hin_r': self.LineSetLiquid.hout,
                    'AS_r': AS,
                    'mdot_r': self.Compressor.mdot_r,
                }
                self.CoaxialIHX.Update(**params)
                self.CoaxialIHX.Calculate()
                self.IHX.Charge_r = self.CoaxialIHX.Charge_r
                self.IHX.Q = self.CoaxialIHX.Q
                self.IHX.Tout_g = self.CoaxialIHX.Tout_g
                self.IHX.DP_g = self.CoaxialIHX.DP_g
                self.IHX.hout_r = self.CoaxialIHX.hout_r
                self.IHX.Tout_r = self.CoaxialIHX.Tout_r
                self.IHX.DP_r = self.CoaxialIHX.DP_r
                if hasattr(self, 'PHEIHX'):
                    del self.PHEIHX
            elif self.IHXType == 'PHE':
                #Inlet enthalpy to PHEIHX
                AS_SLF.update(CP.PT_INPUTS, self.PHEIHX.pin_h,
                              self.CoolingCoil.Tout_g)
                h_in_PHEIHX = AS_SLF.hmass()  #[J/kg]
                params = {
                    'mdot_h': self.Pump.mdot_g,
                    'hin_h': h_in_PHEIHX,
                    'pin_h': self.PHEIHX.pin_h,
                    'AS_h': AS_SLF,
                    'mdot_c': self.Compressor.mdot_r,
                    'pin_c': psat_evap,
                    'hin_c': self.LineSetLiquid.hout,
                    'AS_c': AS
                }
                self.PHEIHX.Update(**params)
                self.PHEIHX.Calculate()
                self.IHX.Charge_r = self.PHEIHX.Charge_c
                self.IHX.Q = self.PHEIHX.Q
                self.IHX.Tout_g = self.PHEIHX.Tout_h
                self.IHX.DP_g = self.PHEIHX.DP_h
                self.IHX.DP_r = self.PHEIHX.DP_c
                self.IHX.hout_r = self.PHEIHX.hout_c
                self.IHX.Tout_r = self.PHEIHX.Tout_c
                if hasattr(self, 'CoaxialIHX'):
                    del self.CoaxialIHX

            params = {
                'DP_g':
                self.IHX.DP_g + self.CoolingCoil.DP_g + self.LineSetSupply.DP +
                self.LineSetReturn.DP,
                'Tin_g':
                self.CoolingCoil.Tout_g,
                'pin_g':
                self.Pump.pin_g,
                'AS_g':
                AS_SLF,
            }
            self.Pump.Update(**params)
            self.Pump.Calculate()

            self.Charge = self.Compressor.Charge + self.Condenser.Charge + self.IHX.Charge_r + self.LineSetSuction.Charge + self.LineSetDischarge.Charge + self.LineSetLiquid.Charge
            self.EnergyBalance = self.Compressor.CycleEnergyIn + self.Condenser.Q + self.IHX.Q + self.LineSetSuction.Q + self.LineSetDischarge.Q + self.LineSetLiquid.Q
            #Calculate properties:
            AS.update(CP.QT_INPUTS, 0.0, self.Tbubble_cond)
            h_L = AS.hmass()  #[J/kg]
            cp_L = AS.cpmass()  #[J/kg-K]
            AS.update(CP.PT_INPUTS, psat_cond,
                      self.Tbubble_cond - self.DT_sc_target)
            h_target = AS.hmass()  #[J/kg]
            self.DT_sc = (h_L - self.Condenser.hout_r) / cp_L
            deltaH_sc = self.Compressor.mdot_r * (h_L - h_target)

            resid = np.zeros((3))
            resid[0] = self.Compressor.mdot_r * (self.IHX.hout_r -
                                                 self.LineSetSuction.hin)

            if self.ImposedVariable == 'Subcooling':
                resid[1] = self.Condenser.DT_sc - self.DT_sc_target
            elif self.ImposedVariable == 'Charge':
                resid[1] = self.Charge - self.Charge_target


#            resid[2]=self.IHX.Q-self.CoolingCoil.Q+self.Pump.W

            self.residSL = self.IHX.Q - self.CoolingCoil.Q + self.Pump.W + self.LineSetSupply.Q + self.LineSetReturn.Q
            resid[2] = self.residSL

            if self.Verbosity > 7:
                print('Wcomp % 12.6e Qcond: % 12.6e QPHE %10.4f ' %
                      (self.Compressor.W, self.Condenser.Q, self.IHX.Q))
            if self.Verbosity > 1:
                print(
                    'Qres % 12.6e Resid2: % 12.6e ResSL %10.4f  Charge %10.4f SC: %8.4f'
                    % (resid[0], resid[1], self.residSL, self.Charge,
                       self.Condenser.DT_sc))

            self.Capacity = self.CoolingCoil.Capacity
            self.COP = self.CoolingCoil.Q / self.Compressor.W
            self.COSP = self.CoolingCoil.Capacity / (
                self.Compressor.W + self.Pump.W +
                self.CoolingCoil.Fins.Air.FanPower +
                self.Condenser.Fins.Air.FanPower)
            self.SHR = self.CoolingCoil.SHR
            self.Power = self.Compressor.W + self.Pump.W + self.CoolingCoil.Fins.Air.FanPower + self.Condenser.Fins.Air.FanPower
            self.DP_high_Model = self.Condenser.DP_r + self.LineSetDischarge.DP + self.LineSetLiquid.DP  #[Pa]
            self.DP_low_Model = self.IHX.DP_r + self.LineSetSuction.DP  #[Pa]

        #Cycle solver for 'HP' mode
        elif self.Mode == 'HP':
            if psat_evap + self.DP_low < 0:
                raise ValueError('Compressor inlet pressure less than zero [' +
                                 str(psat_evap + self.DP_low) +
                                 ' Pa] - is low side pressure drop too high?')

            if not hasattr(self.Compressor,
                           'mdot_r') or self.Compressor.mdot_r < 0.00001:
                # The first run of model, run the compressor just so you can get a preliminary value
                # for the mass flow rate for the line set
                params={               #dictionary -> key:value, e.g. 'key':2345,
                    'pin_r': psat_evap,
                    'pout_r': psat_cond,
                    'Tin_r': self.Tdew_evap+self.DT_sh,
                    'AS': AS,
                }
                self.Compressor.Update(**params)
                self.Compressor.Calculate()

            #Calculate inlet enthalpy
            AS.update(CP.PT_INPUTS, psat_evap, self.Tdew_evap + self.DT_sh)
            h_in = AS.hmass()  #[J/kg]
            params = {
                'Tin': self.Tdew_evap + self.DT_sh,
                'pin': psat_evap,
                'hin': h_in,
                'mdot': self.Compressor.mdot_r,
                'AS': AS,
                'Name': 'Suction Line'
            }
            self.LineSetSuction.Update(**params)
            self.LineSetSuction.Calculate()

            params = {  #dictionary -> key:value, e.g. 'key':2345,
                'pin_r':
                psat_evap + self.DP_low,
                'pout_r':
                psat_cond - self.DP_high,
                'Tin_r':
                TrhoPhase_ph(self.AS, psat_evap, self.LineSetSuction.hout,
                             self.Tbubble_evap, self.Tdew_evap)[0],
                'AS':
                AS
            }
            self.Compressor.Update(**params)
            self.Compressor.Calculate()

            params = {
                'Tin': self.Compressor.Tout_r,
                'pin': psat_cond,
                'hin': self.Compressor.hout_r,
                'mdot': self.Compressor.mdot_r,
                'AS': AS,
                'Name': 'Discharge Line'
            }
            self.LineSetDischarge.Update(**params)
            self.LineSetDischarge.Calculate()

            #Inlet enthalpy to LineSetSupply
            AS_SLF.update(CP.PT_INPUTS, self.Pump.pin_g, Tin_CC)
            h_in_LineSetSupply = AS_SLF.hmass()  #[J/kg]
            params = {
                'Tin': Tin_CC,
                'mdot': self.Pump.mdot_g,
                'hin': h_in_LineSetSupply,
                'AS': AS_SLF,
                'Name': 'Supply Line'
            }
            self.LineSetSupply.Update(**params)
            self.LineSetSupply.Calculate()

            #Now run CoolingCoil to predict inlet glycol temperature to IHX
            params = {
                'mdot_g': self.Pump.mdot_g,
                'Tin_g': self.LineSetSupply.Tout,
                'pin_g': self.PHEIHX.pin_c,
                'AS_g': AS_SLF
            }
            self.CoolingCoil.Update(**params)
            self.CoolingCoil.Calculate()

            #Inlet enthalpy to LineSetReturn
            AS_SLF.update(CP.PT_INPUTS, self.Pump.pin_g,
                          self.CoolingCoil.Tout_g)
            h_in_LineSetReturn = AS_SLF.hmass()  #[J/kg]
            params = {
                'Tin': self.CoolingCoil.Tout_g,
                'mdot': self.Pump.mdot_g,
                'hin': h_in_LineSetReturn,
                'AS': AS_SLF,
                'Name': 'Return Line'
            }
            self.LineSetReturn.Update(**params)
            self.LineSetReturn.Calculate()

            #Inlet enthalpy to PHEIHX
            AS_SLF.update(CP.PT_INPUTS, self.PHEIHX.pin_c,
                          self.LineSetReturn.Tout)
            h_in_PHEIHX = AS_SLF.hmass()  #[J/kg]
            params = {
                'mdot_h': self.Compressor.mdot_r,
                'hin_h': self.LineSetDischarge.hout,
                'pin_h': psat_cond,
                'AS_h': AS,
                'mdot_c': self.Pump.mdot_g,
                'hin_c': h_in_PHEIHX,
                'pin_c': self.Pump.pin_g,
                'AS_c': AS_SLF,
            }
            self.PHEIHX.Update(**params)
            self.PHEIHX.Calculate()

            params = {
                'Tin': self.PHEIHX.Tout_h,
                'pin': psat_cond,
                'hin': self.PHEIHX.hout_h,
                'mdot': self.Compressor.mdot_r,
                'AS': AS,
                'Name': 'Liquid Line'
            }
            self.LineSetLiquid.Update(**params)
            self.LineSetLiquid.Calculate()

            params = {
                'mdot_r': self.Compressor.mdot_r,
                'psat_r': psat_evap,
                'hin_r': self.LineSetLiquid.hout,
                'AS': AS,
            }
            self.Evaporator.Update(**params)
            self.Evaporator.Calculate()

            params = {
                'DP_g':
                self.PHEIHX.DP_c + self.CoolingCoil.DP_g +
                self.LineSetSupply.DP + self.LineSetReturn.DP,
                'Tin_g':
                self.CoolingCoil.Tout_g,
                'pin_g':
                self.Pump.pin_g,
                'AS_g':
                AS_SLF
            }
            self.Pump.Update(**params)
            self.Pump.Calculate()

            self.Charge = self.Compressor.Charge + self.Evaporator.Charge + self.PHEIHX.Charge_h + self.LineSetSuction.Charge + self.LineSetDischarge.Charge + self.LineSetLiquid.Charge

            #Calculate properties:
            AS.update(CP.QT_INPUTS, 0.0, self.Tbubble_cond)
            h_L = AS.hmass()  #[J/kg]
            cp_L = AS.cpmass()  #[J/kg-K]
            AS.update(CP.PT_INPUTS, psat_cond,
                      self.Tbubble_cond - self.DT_sc_target)
            h_target = AS.hmass()  #[J/kg]
            #Calculate an effective subcooling amount by deltah/cp_satL
            #Can be positive or negative (negative is quality at outlet
            self.DT_sc = self.PHEIHX.DT_sc_h  #(PropsSI('H','T',self.Tbubble_cond,'Q',0,self.Ref)-self.PHEIHX.hout_h)/(PropsSI('C','T',self.Tbubble_cond,'Q',0,self.Ref)) #*1000 #*1000
            deltaH_sc = self.Compressor.mdot_r * (h_L - h_target)

            resid = np.zeros((3))
            resid[0] = self.Compressor.mdot_r * (self.Evaporator.hout_r -
                                                 self.LineSetSuction.hin)

            if self.ImposedVariable == 'Subcooling':
                resid[1] = self.DT_sc - self.DT_sc_target
            elif self.ImposedVariable == 'Charge':
                resid[1] = self.Charge - self.Charge_target
            self.residSL = self.PHEIHX.Q + self.CoolingCoil.Q + self.Pump.W + self.LineSetSupply.Q + self.LineSetReturn.Q
            resid[2] = self.residSL

            if self.Verbosity > 1:
                print(
                    'Qres % 12.6e Resid2: % 12.6e ResSL %10.4f Charge %10.4f SC: %8.4f'
                    % (resid[0], resid[1], self.residSL, self.Charge,
                       self.DT_sc))

            self.Capacity = -self.CoolingCoil.Q + self.CoolingCoil.Fins.Air.FanPower
            self.COP = -self.CoolingCoil.Q / self.Compressor.W
            self.COSP = self.Capacity / (self.Compressor.W + self.Pump.W +
                                         self.CoolingCoil.Fins.Air.FanPower +
                                         self.Evaporator.Fins.Air.FanPower)
            self.Power = self.Compressor.W + self.Pump.W + self.CoolingCoil.Fins.Air.FanPower + self.Evaporator.Fins.Air.FanPower
            self.SHR = -self.CoolingCoil.SHR
            self.DP_high_Model = self.PHEIHX.DP_h + self.LineSetDischarge.DP + self.LineSetLiquid.DP  #[Pa]
            self.DP_low_Model = self.Evaporator.DP_r + self.LineSetSuction.DP  #[Pa]
        self.DT_evap = DT_evap
        self.DT_cond = DT_cond
        return resid

    def PreconditionedSolve(self, PrecondValues=None):
        '''
        PrecondValues = dictionary of values DT_evap, DT_cond and Tin_CC
        '''
        def OBJECTIVE(x):
            """
            Takes the place of a lambda function since lambda functions do not bubble error properly
            """
            return self.Calculate(x[0], x[1], x[2])

        def OBJECTIVE2(x, Tin):
            """
            Takes the place of a lambda function since lambda functions do not bubble error properly
            """
            return self.Calculate(x[0], x[1], Tin)

        def OBJECTIVE_SL(Tin_CC):
            """
            Objective function for the inner loop of the vapor compression system
            
            Using the MultiDimNewtRaph function will re-evaluate the Jacobian at 
            every step.  Slower, but more robust since the solution surfaces aren't
            smooth enough
            
            Note: This function is not currently used!
            """
            x = MultiDimNewtRaph(OBJECTIVE2, [self.DT_evap, self.DT_cond],
                                 args=(Tin_CC, ))

            # Update the guess values for Delta Ts starting
            # at the third step (after at least one update away
            # from the boundaries)
            if self.OBJ_SL_counter >= 0:
                self.DT_evap = x[0]
                self.DT_cond = x[1]
                pass
            self.OBJ_SL_counter += 1
            return self.residSL

        def PrintDPs():
            print('DP_LP :: Input:', self.DP_low, 'Pa / Model calc:',
                  self.DP_low_Model, 'Pa')
            print('DP_HP :: Input:', self.DP_high, 'Pa / Model calc:',
                  self.DP_high_Model, 'Pa')

        #Some variables need to be initialized
        self.DP_low = 0  #The actual low-side pressure drop to be used in Pa
        self.DP_high = 0  #The actual low-side pressure drop to be used in Pa
        self.OBJ_SL_counter = 0

        #Run the preconditioner to get guess values for the temperatures
        if PrecondValues is None:
            self.DT_evap, self.DT_cond, Tin_CC = SecondaryLoopPreconditioner(
                self)
        else:
            self.DT_evap = PrecondValues['DT_evap']
            self.DT_cond = PrecondValues['DT_cond']
            Tin_CC = PrecondValues['Tin_CC']

        #Remove the other, non-used IHX class if found
        if self.IHXType == 'PHE':
            if hasattr(self, 'CoaxialIHX'):
                del self.CoaxialIHX
        else:
            if hasattr(self, 'PHEIHX'):
                del self.PHEIHX

        #Remove the condenser if in heating mode and condenser found
        if self.Mode == 'HP':
            if hasattr(self, 'Condenser'):
                del self.Condenser
        iter = 1
        max_error_DP = 999
        #Outer loop with a more relaxed convergence criterion
        while max_error_DP > 0.5:
            iter_inner = 1
            #Inner loop to determine pressure drop for high and low sides
            while max_error_DP > 0.05 and iter_inner < 10:

                #Run to calculate the pressure drop as starting point
                OBJECTIVE([self.DT_evap, self.DT_cond, Tin_CC])

                #Calculate the max error
                max_error_DP = max([
                    abs(self.DP_low_Model - self.DP_low),
                    abs(self.DP_high_Model - self.DP_high)
                ])

                if self.Verbosity > 0:
                    PrintDPs()
                    print('Max pressure drop error [inner loop] is',
                          max_error_DP, 'Pa')

                #Update the pressure drop terms
                self.DP_low = self.DP_low_Model  #/1000
                self.DP_high = self.DP_high_Model  #/1000

                iter_inner += 1

            if self.Verbosity > 0:
                print("Done with the inner loop on pressure drop")

            # Use Newton-Raphson solver
            (self.DT_evap, self.DT_cond,
             Tin_CC) = MultiDimNewtRaph(OBJECTIVE,
                                        [self.DT_evap, self.DT_cond, Tin_CC],
                                        dx=0.1)

            #Calculate the error
            max_error_DP = max([
                abs(self.DP_low_Model - self.DP_low),
                abs(self.DP_high_Model - self.DP_high)
            ])

            if self.Verbosity > 0:
                PrintDPs()
                print('Max pressure drop error [outer loop] is', max_error_DP,
                      'Pa')

        if self.Verbosity > 1:
            print('Capacity: ', self.Capacity)
            print('COP: ', self.COP)
            print('COP (w/ both fans): ', self.COSP)
            print('SHR: ', self.SHR)

        print('-------------------------------------')
        print('     Simulation Completed            ')
        print('-------------------------------------')

        return