Exemple #1
0
class RegenerativeRankineCycle(RankineCycle):
	label = "Regenerative Rankine cycle"
	figure = F.ModelFigure(src="ThermoFluids/img/ModuleImages/RankineCycle_Recuperator.svg",  height = 300)
	description = F.ModelDescription("Rankine cycle with recuperator, \
		using the temperature of the hot steam before the condenser to pre-heat the fluid before entering the boiler", show = True)
	#================ Inputs ================#
	#---------------- Fields ----------------#
	# FieldGroup
	recuperator = F.SubModelGroup(TC.HeatExchangerTwoStreams, 'FG', label = 'Recuperator')
	inputs = F.SuperGroup(['workingFluidGroup', 'pump', recuperator, 'boiler', 'turbine', 'condenser'], label = 'Cycle defininition')
	#--------------- Model view ---------------#

	#================ Results ================#
	#---------------- Energy flows -----------#
	recuperatorHeat = F.Quantity('HeatFlowRate', default = (0, 'kW'), label = 'recuperator heat rate')
	flowFieldGroup = F.FieldGroup(['pumpPower', recuperatorHeat, 'boilerHeat', 'turbinePower', 'condenserHeat'], label = 'Energy flows')
	#---------------- Scheme -----------------#
	scheme_Rankine_recup = F.Image(default="static/ThermoFluids/img/ModuleImages/RankineCycle_Recuperator.png")
	SchemeVG = F.ViewGroup([scheme_Rankine_recup], label="Process Scheme")
	SchemeSG = F.SuperGroup([SchemeVG], label="Scheme")
	
	resultView = F.ModelView(ioType = "output", superGroups = ['resultDiagrams', SchemeSG, 'resultStates', 'resultEnergy', 'solverStats'])
	#================ Methods ================#
	def compute(self):
		self.initCompute(self.fluidName)
		# Connect components
		self.connectPorts(self.condenser.outlet, self.pump.inlet)
		self.connectPorts(self.pump.outlet, self.recuperator.inlet1)
		self.connectPorts(self.recuperator.outlet1, self.boiler.inlet)
		self.connectPorts(self.boiler.outlet, self.turbine.inlet)
		self.connectPorts(self.turbine.outlet, self.recuperator.inlet2)
		self.connectPorts(self.recuperator.outlet2, self.condenser.inlet)
		# Initial guess
		for fl in self.flows:
			fl.mDot = self.mDot
		self.condenser.outlet.state.update_pq(self.pLow, 0)
		self.boiler.outlet.state.update_pq(self.pHigh, 1)
		self.turbine.compute(self.pLow)
		# Cycle iterations
		self.solver.run()
		# Results
		self.postProcess()
		
	def computeCycle(self):
		self.pump.compute(self.pHigh)
		self.recuperator.compute()
		self.recuperator.computeStream1()
		self.boiler.compute()	
		self.turbine.compute(self.pLow)
		self.recuperator.computeStream2()
		self.condenser.compute()
		
	def postProcess(self):
		super(RegenerativeRankineCycle, self).postProcess()
		self.recuperatorHeat = self.recuperator.QDot 

	def SteamPlant(self):
		RankineCycle.SteamPlant(self)
		self.pLow = (2, 'bar')
		self.boiler.TOutlet = (600, 'degC')
class VaporCompressionCycleWithRecuperator(VaporCompressionCycle):
    label = "Vapor compression cycle (recuperator)"
    figure = F.ModelFigure(
        src=
        "ThermoFluids/img/ModuleImages/VaporCompressionCycle_Recuperator.svg")
    description = F.ModelDescription(
        "Vapor compression cycle with a recuperator. The stream \
	 before the throttle valve is precooled, using the cold stream at the evaporator outlet. \
	 This increases the compressor cooling/heating capacity of the cycle and improves slightly the COP",
        show=True)
    #================ Inputs ================#
    #---------------- Fields ----------------#
    recuperator = F.SubModelGroup(TC.HeatExchangerTwoStreams,
                                  'FG',
                                  label='Recuperator')
    inputs = F.SuperGroup([
        'workingFluidGroup', 'compressor', recuperator, 'condenser',
        'evaporator'
    ],
                          label='Cycle definition')
    #--------------- Model view ---------------#

    #================ Results ================#
    #---------------- Energy flows -----------#
    recuperatorHeat = F.Quantity('HeatFlowRate',
                                 default=(0, 'kW'),
                                 label='recuperator heat rate')
    flowFieldGroup = F.FieldGroup([
        'compressorPower', recuperatorHeat, 'condenserHeat', 'evaporatorHeat'
    ],
                                  label='Energy flows')

    #---------------- Scheme -----------------#
    scheme_VaporCompression_recup = F.Image(
        default=
        "static/ThermoFluids/img/ModuleImages/VaporCompressionCycle_Recuperator.png"
    )
    SchemeVG = F.ViewGroup([scheme_VaporCompression_recup],
                           label="Process Scheme")
    SchemeSG = F.SuperGroup([SchemeVG], label="Scheme")

    resultView = F.ModelView(ioType="output",
                             superGroups=[
                                 'resultDiagrams', SchemeSG, 'resultStates',
                                 'resultEnergy', 'solverStats'
                             ])

    #================ Methods ================#
    def compute(self):
        if (self.cycleTranscritical and self.condenser.computeMethod == 'dT'):
            raise ValueError(
                'In transcritical cycle, condenser sub-cooling cannot be used as input'
            )
        self.initCompute(fluid=self.fluidName)
        # Connect components
        self.connectPorts(self.evaporator.outlet, self.recuperator.inlet1)
        self.connectPorts(self.recuperator.outlet1, self.compressor.inlet)
        self.connectPorts(self.compressor.outlet, self.condenser.inlet)
        self.connectPorts(self.condenser.outlet, self.recuperator.inlet2)
        self.connectPorts(self.recuperator.outlet2, self.throttleValve.inlet)
        self.connectPorts(self.throttleValve.outlet, self.evaporator.inlet)
        # Initial guess
        for fl in self.flows:
            fl.mDot = self.mDot
        self.evaporator.outlet.state.update_pq(self.pLow, 1)
        if (self.cycleTranscritical):
            self.condenser.outlet.state.update_Tp(
                1.05 * self.fluid.critical['T'], self.pHigh)
        else:
            self.condenser.outlet.state.update_pq(self.pHigh, 0)
        # Cycle iterations
        self.solver.run()
        # Results
        self.postProcess()

    def computeCycle(self):
        self.recuperator.compute()
        self.recuperator.computeStream1()
        self.compressor.compute(self.pHigh)
        self.condenser.compute()
        self.recuperator.computeStream2()
        self.throttleValve.compute(self.pLow)
        self.evaporator.compute()

        if (self.cycleTranscritical and self.condenser.computeMethod == 'dT'):
            raise ValueError(
                'In transcritical cycle, condenser sub-cooling cannot be used as input'
            )

    def postProcess(self):
        super(VaporCompressionCycleWithRecuperator, self).postProcess()
        self.recuperatorHeat = self.recuperator.QDot

    def R134aCycle(self):
        super(VaporCompressionCycleWithRecuperator, self).R134aCycle()
        self.recuperator.eta = 0.7
Exemple #3
0
class ThermodynamicalCycle(NumericalModel):
    abstract = True
    #================ Inputs ================#
    # Cycle diagram
    cycleDiagram = F.SubModelGroup(TC.CycleDiagram,
                                   'inputs',
                                   label='Diagram settings')
    # Solver settings
    solver = F.SubModelGroup(CycleIterator, 'solverSettings', label='Solver')
    #================ Results ================#
    #---------------- Fields ----------------#
    cycleStatesTable = F.TableView(
        (('T', F.Quantity('Temperature', default=(1, 'degC'))),
         ('p', F.Quantity('Pressure', default=(1, 'bar'))),
         ('rho', F.Quantity('Density', default=(1, 'kg/m**3'))),
         ('h', F.Quantity('SpecificEnthalpy', default=(1, 'kJ/kg'))),
         ('s', F.Quantity('SpecificEntropy', default=(1, 'kJ/kg-K'))),
         ('q', F.Quantity()),
         ('dT', F.Quantity('TemperatureDifference', default=(1, 'degC'))),
         ('mDot', F.Quantity('MassFlowRate', default=(1, 'kg/min'))),
         ('b', F.Quantity('SpecificEnergy', default=(1, 'kJ/kg')))),
        label="Cycle states")

    cycleStates = F.ViewGroup([cycleStatesTable], label="States")
    resultStates = F.SuperGroup([cycleStates], label="States")
    #---------------- Cycle diagram -----------#
    phDiagram = F.Image(default='')
    cycleDiagramVG = F.ViewGroup([phDiagram], label="P-H Diagram")
    resultDiagrams = F.SuperGroup([cycleDiagramVG], label="Diagrams")
    #---------------- Convergence parameters -----------#
    residualPlot = F.PlotView((('iteration #', F.Quantity('Dimensionless')),
                               ('h change', F.Quantity('SpecificEnthalpy'))),
                              label='Residual (plot)',
                              ylog=True)
    iterationTable = F.TableView((
        ('h1', F.Quantity('SpecificEnthalpy')),
        ('h2', F.Quantity('SpecificEnthalpy')),
        ('h3', F.Quantity('SpecificEnthalpy')),
        ('h4', F.Quantity('SpecificEnthalpy')),
        ('h5', F.Quantity('SpecificEnthalpy')),
        ('h6', F.Quantity('SpecificEnthalpy')),
        ('h7', F.Quantity('SpecificEnthalpy')),
        ('h8', F.Quantity('SpecificEnthalpy')),
        ('h9', F.Quantity('SpecificEnthalpy')),
        ('h10', F.Quantity('SpecificEnthalpy')),
        ('h11', F.Quantity('SpecificEnthalpy')),
        ('h12', F.Quantity('SpecificEnthalpy')),
        ('h13', F.Quantity('SpecificEnthalpy')),
        ('h14', F.Quantity('SpecificEnthalpy')),
        ('h15', F.Quantity('SpecificEnthalpy')),
        ('h16', F.Quantity('SpecificEnthalpy')),
        ('h17', F.Quantity('SpecificEnthalpy')),
        ('h18', F.Quantity('SpecificEnthalpy')),
        ('h19', F.Quantity('SpecificEnthalpy')),
        ('h20', F.Quantity('SpecificEnthalpy')),
    ),
                                 label='Residual (table)',
                                 options={'formats': (['0.0000E0'] * 20)})
    residualGroup = F.ViewGroup([residualPlot, iterationTable],
                                label='Iterations')
    solverStats = F.SuperGroup([residualGroup], label='Convergence')

    # Info fields
    cycleTranscritical = F.Boolean(default=False)
    cycleSupercritical = F.Boolean(default=False)

    def initCompute(self, fluid):
        # Create fluid points
        self.fluid = Fluid(fluid)
        self.fp = []  #[FluidState(fluid) for _ in range(numPoints)]
        self.flows = []
        self.solver.cycle = self

    def connectPorts(self, port1, port2, fluid=None):
        if fluid == None:
            fluid = self.fluid
        fp = FluidState(fluid)
        flow = P.FluidFlow()
        self.fp.append(fp)
        self.flows.append(flow)
        port1.state = fp
        port2.state = fp
        port1.flow = flow
        port2.flow = flow

    def solve(self):
        self.solver.run()
        self.residualPlot.resize(len(self.solver.change_hHistory))
        for i in range(len(self.solver.change_hHistory)):
            self.residualPlot[i] = (i + 1, self.solver.change_hHistory[i])
        self.iterationTable.resize(len(self.solver.hHistory))
        v = self.iterationTable.view(dtype=np.float).reshape(
            -1, len(self.iterationTable.dtype))
        numCols = len(self.solver.hHistory[0])
        for i in range(len(self.solver.hHistory)):
            v[i, :numCols] = self.solver.hHistory[i]


# 		print self.iterationTable
# 		iterRecord = np.zeros(1, dtype = self.iterationTable.dtype)
# 		numCols = len(self.solver.hHistory[0])
# 		for i in range(len(self.solver.hHistory)):
# 			for j in range(numCols):
# 				iterRecord[j] = self.solver.hHistory[i][j]
# 			self.iterationTable[i] = iterRecord

    def postProcess(self, TAmbient):
        ## State diagram
        if (self.cycleDiagram.enable):
            self.createStateDiagram()
        ## Table of states
        self.cycleStatesTable.resize(len(self.fp))
        for i in range(len(self.fp)):
            fp = self.fp[i]
            self.cycleStatesTable[i] = (fp.T, fp.p, fp.rho, fp.h, fp.s, fp.q,
                                        fp.dT, self.flows[i].mDot,
                                        fp.b(TAmbient))
        # Select the zero for the exergy scale
        fp = FluidState(self.fluid)
        fp.update_Tp(TAmbient, 1e5)
        b0 = fp.b(TAmbient)
        self.cycleStatesTable['b'] -= b0

    def createStateDiagram(self):
        ncp = len(self.fp)
        fluidLines = []
        for i in range(ncp):
            fluidLines.append((self.fp[i], self.fp[(i + 1) % ncp]))
        self.phDiagram = self.cycleDiagram.draw(self.fluid, self.fp,
                                                fluidLines)

    def setPLow(self, p):
        if (self.fluid.tripple['p'] < p < self.fluid.critical['p']):
            self.pLow = p
            sat = self.fluid.saturation_p(p)
            self.TEvaporation = sat['TsatL']
        elif (p > self.fluid.critical['p']):
            self.pLow = p
            self.cycleSupercritical = True
        else:
            raise ValueError(
                'PLow  ({} bar) must be between {} bar and {} bar'.format(
                    p / 1e5, self.fluid.tripple['p'] / 1e5,
                    self.fluid.critical['p'] / 1e5))

    def setPHigh(self, p):
        if (self.fluid.tripple['p'] < p < self.fluid.critical['p']):
            self.pHigh = p
            sat = self.fluid.saturation_p(p)
            self.TCondensation = sat['TsatL']
        elif (p > self.fluid.critical['p']):
            self.pHigh = p
            self.cycleTranscritical = True
        else:
            raise ValueError(
                'PHigh  ({} bar) must be between {} bar and {} bar'.format(
                    p / 1e5, self.fluid.tripple['p'] / 1e5,
                    self.fluid.critical['p'] / 1e5))
Exemple #4
0
class ClaudeCycle(LindeHampsonCycle):
    label = "Claude cycle"
    figure = F.ModelFigure(src="ThermoFluids/img/ModuleImages/ClaudeCycle.svg",
                           height=300)
    description = F.ModelDescription(
        "Liquefaction cycle using an expander and 3 recurperators for increased efficiency",
        show=True)

    #================ Inputs ================#
    #---------------- Fields ----------------#
    # FieldGroup
    recuperator2 = F.SubModelGroup(TC.HeatExchangerTwoStreams,
                                   'FG',
                                   label='Recuperator 2')
    recuperator3 = F.SubModelGroup(TC.HeatExchangerTwoStreams,
                                   'FG',
                                   label='Recuperator 3')
    expander = F.SubModelGroup(TC.Turbine, 'FG', label='Expander')
    expanderFlowFraction = F.Quantity('Fraction', label='flow fraction')
    expanderEta = F.Quantity('Efficiency', label='efficiency')
    expanderFG = F.FieldGroup([expanderFlowFraction, expanderEta],
                              label='Expander')
    expanderSplitter = F.SubModelGroup(TC.FlowSplitter, 'FG')
    expanderJunction = F.SubModelGroup(TC.FlowJunction, 'FG')
    inputs = F.SuperGroup([
        'workingFluidGroup', 'compressor', 'cooler', expanderFG, 'recuperator',
        recuperator2, recuperator3
    ],
                          label='Cycle definition')
    #---------------- Actions ----------------#
    exampleAction = ServerAction(
        "loadEg",
        label="Examples",
        options=(
            ('NitrogenMediumP',
             'Nitrogen medium pressure (30 bar) liquefaction cycle'),
            ('NitrogenLowP',
             'Nitrogen low pressure (8 bar) liquefacton cycle'),
        ))
    #--------------- Model view ---------------#
    inputView = F.ModelView(ioType="input",
                            superGroups=[inputs, 'cycleDiagram', 'solver'],
                            actionBar=ActionBar([exampleAction]),
                            autoFetch=True)

    #================ Results ================#
    #---------------- Scheme -----------------#
    scheme_Claude = F.Image(
        default="static/ThermoFluids/img/ModuleImages/ClaudeCycle.png")
    SchemeVG = F.ViewGroup([scheme_Claude], label="Process Scheme")
    SchemeSG = F.SuperGroup([SchemeVG], label="Scheme")

    resultView = F.ModelView(ioType="output",
                             superGroups=[
                                 'resultDiagrams', SchemeSG, 'resultStates',
                                 'resultEnergy', 'solverStats'
                             ])

    def __init__(self):
        self.cooler.computeMethod = 'eta'
        self.cooler.TExt = self.TAmbient
        self.NitrogenMediumP()

    def compute(self):
        self.initCompute(self.fluidName)
        self.expanderSplitter.frac1 = 1 - self.expanderFlowFraction
        self.expanderSplitter.frac2 = self.expanderFlowFraction
        self.expander.eta = self.expanderEta
        # Connect components
        self.connectPorts(self.gasSource.outlet, self.inletJunct.inletMain)
        self.connectPorts(self.inletJunct.outlet, self.compressor.inlet)
        self.connectPorts(self.compressor.outlet, self.cooler.inlet)
        self.connectPorts(self.cooler.outlet, self.recuperator.inlet1)
        self.connectPorts(self.recuperator.outlet1,
                          self.expanderSplitter.inlet)
        self.connectPorts(self.expanderSplitter.outlet1,
                          self.recuperator2.inlet1)
        self.connectPorts(self.recuperator2.outlet1, self.recuperator3.inlet1)
        self.connectPorts(self.recuperator3.outlet1, self.throttleValve.inlet)
        self.connectPorts(self.throttleValve.outlet, self.liqSeparator.inlet)
        self.connectPorts(self.liqSeparator.outletVapor,
                          self.secThrottleValve.inlet)
        self.connectPorts(self.secThrottleValve.outlet,
                          self.recuperator3.inlet2)
        self.connectPorts(self.recuperator3.outlet2,
                          self.expanderJunction.inletMain)
        self.connectPorts(self.expanderJunction.outlet,
                          self.recuperator2.inlet2)
        self.connectPorts(self.recuperator2.outlet2, self.recuperator.inlet2)
        self.connectPorts(self.recuperator.outlet2, self.inletJunct.inlet2)
        self.connectPorts(self.expanderSplitter.outlet2, self.expander.inlet)
        self.connectPorts(self.expander.outlet, self.expanderJunction.inlet2)
        self.connectPorts(self.liqSeparator.outletLiquid,
                          self.liquidSink.inlet)

        # Initial guess
        liqFractionGuess = 0.5
        for fl in self.flows:
            fl.mDot = 1.0 / liqFractionGuess * self.mDot
        for fp in self.fp:
            fp.update_Tp(self.TAmbient, self.pIn)

        # Initialize source
        self.gasSource.T = self.TIn
        self.gasSource.p = self.pIn
        self.gasSource.mDot = self.mDot
        self.gasSource.compute()
        # Run solver
        self.solve()
        # Results
        self.postProcess(self.TAmbient)

    def computeCycle(self):
        self.compressor.compute(self.pHigh)
        self.cooler.compute()
        self.recuperator.compute()
        self.recuperator.computeStream1()
        self.expanderSplitter.compute()
        self.recuperator2.compute()
        self.recuperator2.computeStream1()
        self.recuperator3.compute()
        self.recuperator3.computeStream1()
        self.throttleValve.compute(self.pLiquid)
        self.liqSeparator.compute()
        self.secThrottleValve.compute(self.pIn)
        self.recuperator3.computeStream2()
        self.expander.compute(self.pIn)
        self.expanderJunction.compute()
        self.recuperator2.computeStream2()
        self.recuperator.computeStream2()
        self.inletJunct.compute()

    def createStateDiagram(self):
        lineNumbers = [(2, 3), (3, 4), (4, 5), (6, 7), (7, 8), (8, 9), (9, 10),
                       (9, 18), (10, 11), (11, 12), (13, 14), (14, 15),
                       (16, 17)]
        fluidLines = []
        for i, j in lineNumbers:
            fluidLines.append((self.fp[i - 1], self.fp[j - 1]))
        self.phDiagram = self.cycleDiagram.draw(self.fluid, self.fp,
                                                fluidLines)

    def NitrogenLiquefaction(self):
        self.fluidName = "Nitrogen"
        self.pIn = (1, 'bar')
        self.TIn = self.TAmbient
        self.pHigh = (30, 'bar')
        self.pLiquid = (1.2, 'bar')
        self.compressor.modelType = 'T'
        self.compressor.etaT = 0.8
        self.compressor.dT = 50.
        self.cycleDiagram.defaultMaxP = False
        self.cycleDiagram.defaultMaxT = False
        self.cycleDiagram.maxPressure = (500, 'bar')
        self.cycleDiagram.maxTemperature = 350

    def NitrogenMediumP(self):
        self.fluidName = "Nitrogen"
        self.pIn = (1, 'bar')
        self.TIn = self.TAmbient
        self.mDot = (0.188, 'kg/s')
        self.pHigh = (30, 'bar')
        self.pLiquid = (1.2, 'bar')
        self.compressor.modelType = 'T'
        self.compressor.etaT = 0.8
        self.compressor.dT = 50
        self.cooler.computeMethod = 'eta'
        self.cooler.etaThermal = 1.
        self.cooler.TExt = (30, 'degC')
        self.expanderEta = 0.8
        self.expanderFlowFraction = 0.66
        self.recuperator.computeMethod = 'EG'
        self.recuperator.epsGiven = 0.99
        self.recuperator2.computeMethod = 'EN'
        self.recuperator2.UA = (1950, 'W/K')
        self.recuperator3.computeMethod = 'EG'
        self.recuperator3.epsGiven = 0
        self.cycleDiagram.defaultMaxT = False
        self.cycleDiagram.maxTemperature = 400

    def NitrogenLowP(self):
        self.fluidName = "Nitrogen"
        self.pIn = (1.1, 'bar')
        self.TIn = (300, 'K')
        self.mDot = (12.8, 'kg/h')
        self.pHigh = (8, 'bar')
        self.pLiquid = (1.2, 'bar')
        self.TAmbient = (300, 'K')
        self.compressor.modelType = 'S'
        self.compressor.etaS = 0.8
        self.compressor.fQ = 0.3
        self.cooler.computeMethod = 'eta'
        self.cooler.etaThermal = 1.
        self.cooler.TExt = (310, 'K')
        self.expanderEta = 0.5
        self.expanderFlowFraction = 0.94
        self.recuperator.computeMethod = 'EN'
        self.recuperator.UA = (1280, 'W/K')
        self.recuperator2.computeMethod = 'EN'
        self.recuperator2.UA = (90, 'W/K')
        self.recuperator3.computeMethod = 'EG'
        self.recuperator3.epsGiven = 0
        self.cycleDiagram.defaultMaxT = False
        self.cycleDiagram.maxTemperature = 550
Exemple #5
0
class LindeHampsonCycle(LiquefactionCycle):
    label = "Linde-Hampson cycle"
    figure = F.ModelFigure(
        src="ThermoFluids/img/ModuleImages/LindeHampson.svg", height=300)
    description = F.ModelDescription(
        "Basic liquefaction cycle used e.g. for air liquefaction", show=True)

    #================ Inputs ================#
    #---------------- Fields ----------------#
    # FieldGroup
    gasSource = F.SubModelGroup(TC.FluidSource_TP, 'FG')
    inletJunct = F.SubModelGroup(TC.FlowJunction, 'FG')
    compressor = F.SubModelGroup(TC.Compressor, 'FG', label='Compressor')
    cooler = F.SubModelGroup(TC.Condenser, 'FG', label='Cooler')
    recuperator = F.SubModelGroup(TC.HeatExchangerTwoStreams,
                                  'FG',
                                  label='Recuperator')
    throttleValve = F.SubModelGroup(TC.ThrottleValve, 'FG', label='JT valve')
    liqSeparator = F.SubModelGroup(TC.PhaseSeparator,
                                   'FG',
                                   label='Liquid separator')
    secThrottleValve = F.SubModelGroup(TC.ThrottleValve,
                                       'FG',
                                       label='JT valve')
    liquidSink = F.SubModelGroup(TC.FluidSink, 'FG')
    inputs = F.SuperGroup(
        ['workingFluidGroup', compressor, cooler, recuperator],
        label='Cycle definition')

    #---------------- Actions ----------------#
    exampleAction = ServerAction("loadEg",
                                 label="Examples",
                                 options=(
                                     ('ArgonLiquefaction',
                                      'Argon liquefaction cycle'),
                                     ('NitrogenLiquefaction',
                                      'Nitrogen liquefacton cycle'),
                                 ))
    #--------------- Model view ---------------#
    inputView = F.ModelView(ioType="input",
                            superGroups=[inputs, 'cycleDiagram', 'solver'],
                            actionBar=ActionBar([exampleAction]),
                            autoFetch=True)

    #================ Results ================#
    compressorPower = F.Quantity('Power',
                                 default=(1, 'kW'),
                                 label='compressor power')
    compressorHeat = F.Quantity('HeatFlowRate',
                                default=(1, 'kW'),
                                label='compressor heat')
    coolerHeat = F.Quantity('HeatFlowRate',
                            default=(1, 'kW'),
                            label='cooler heat out')
    flowFieldGroup = F.FieldGroup(
        [compressorPower, compressorHeat, coolerHeat], label='Flows')
    resultEnergy = F.SuperGroup([flowFieldGroup, 'efficiencyFieldGroup'],
                                label='Energy')
    #---------------- Scheme -----------------#
    scheme_LindeHampson = F.Image(
        default="static/ThermoFluids/img/ModuleImages/LindeHampson.png")
    SchemeVG = F.ViewGroup([scheme_LindeHampson], label="Process Scheme")
    SchemeSG = F.SuperGroup([SchemeVG], label="Scheme")

    resultView = F.ModelView(ioType="output",
                             superGroups=[
                                 'resultDiagrams', SchemeSG, 'resultStates',
                                 resultEnergy, 'solverStats'
                             ])

    #============= Page structure =============#
    modelBlocks = [inputView, resultView]

    #================ Methods ================#
    def __init__(self):
        self.cooler.computeMethod = 'eta'
        self.cooler.TExt = self.TAmbient
        self.ArgonLiquefaction()

    def compute(self):
        self.initCompute(self.fluidName)
        # Connect components
        self.connectPorts(self.gasSource.outlet, self.inletJunct.inletMain)
        self.connectPorts(self.inletJunct.outlet, self.compressor.inlet)
        self.connectPorts(self.compressor.outlet, self.cooler.inlet)
        self.connectPorts(self.cooler.outlet, self.recuperator.inlet1)
        self.connectPorts(self.recuperator.outlet1, self.throttleValve.inlet)
        self.connectPorts(self.throttleValve.outlet, self.liqSeparator.inlet)
        self.connectPorts(self.liqSeparator.outletVapor,
                          self.secThrottleValve.inlet)
        self.connectPorts(self.secThrottleValve.outlet,
                          self.recuperator.inlet2)
        self.connectPorts(self.recuperator.outlet2, self.inletJunct.inlet2)
        self.connectPorts(self.liqSeparator.outletLiquid,
                          self.liquidSink.inlet)
        # Initialize source
        self.gasSource.T = self.TIn
        self.gasSource.p = self.pIn
        self.gasSource.mDot = self.mDot
        self.gasSource.compute()
        # Initial guess
        liqFractionGuess = 0.5
        for fl in self.flows:
            fl.mDot = 1.0 / liqFractionGuess * self.mDot
        for fp in self.fp:
            fp.update_Tp(self.TAmbient, self.pIn)


# 		liqFractionGuess = 0.2
# 		self.compressor.inlet.flow.mDot = 1.0 / liqFractionGuess * self.gasSource.outlet.flow.mDot
# 		self.liqSeparator.outletVapor.flow.mDot = liqFractionGuess * self.mDot
#
# 		self.compressor.inlet.state.update_Tp(
# 			self.gasSource.outlet.state.T, self.gasSource.outlet.state.p)
# 		self.secThrottleValve.outlet.state.update_pq(self.pIn, 1)
# Run solver
        self.solve()
        # Results
        self.postProcess(self.TAmbient)

    def computeCycle(self):
        self.compressor.compute(self.pHigh)
        self.cooler.compute()
        self.recuperator.compute()
        self.recuperator.computeStream1()
        self.throttleValve.compute(self.pLiquid)
        self.liqSeparator.compute()
        self.secThrottleValve.compute(self.pIn)
        self.recuperator.computeStream2()
        self.inletJunct.compute()

    def postProcess(self, TAmbient):
        LiquefactionCycle.postProcess(self, TAmbient)
        self.compressor.postProcess()
        self.cooler.postProcess()
        # Flows
        self.compressorPower = self.compressor.WDot
        self.compressorHeat = -self.compressor.QDotIn
        self.coolerHeat = -self.cooler.QDotIn
        # Efficiencies
        self.liqEnergy = self.compressor.WDot / self.liqSeparator.outletLiquid.flow.mDot
        self.minLiqEnergy = self.liqSeparator.outletLiquid.state.b(self.TAmbient) \
         - self.gasSource.outlet.state.b(self.TAmbient)
        self.etaSecondLaw = self.minLiqEnergy / self.liqEnergy

    def createStateDiagram(self):
        lineNumbers = [(2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (6, 10), (7, 8),
                       (8, 9)]
        fluidLines = []
        for i, j in lineNumbers:
            fluidLines.append((self.fp[i - 1], self.fp[j - 1]))
        self.phDiagram = self.cycleDiagram.draw(self.fluid, self.fp,
                                                fluidLines)

    def ArgonLiquefaction(self):
        self.fluidName = "Argon"
        self.pIn = (1, 'bar')
        self.TIn = self.TAmbient
        self.pHigh = (200, 'bar')
        self.pLiquid = (1.2, 'bar')
        self.compressor.modelType = 'T'
        self.compressor.etaT = 0.8
        self.compressor.dT = 50.
        self.recuperator.eta = 0.99
        self.cycleDiagram.defaultMaxP = False
        self.cycleDiagram.maxPressure = (300, 'bar')

    def NitrogenLiquefaction(self):
        self.fluidName = "Nitrogen"
        self.pIn = (1, 'bar')
        self.TIn = self.TAmbient
        self.pHigh = (300, 'bar')
        self.pLiquid = (1.2, 'bar')
        self.compressor.modelType = 'T'
        self.compressor.etaT = 0.8
        self.compressor.dT = 50.
        self.recuperator.eta = 0.99
        self.cycleDiagram.defaultMaxP = False
        self.cycleDiagram.defaultMaxT = False
        self.cycleDiagram.maxPressure = (500, 'bar')
        self.cycleDiagram.maxTemperature = 350