Beispiel #1
0
class SolverSettings(NumericalModel):
    tFinal = F.Quantity('Bio_Time',
                        default=(0.0, 'day'),
                        minValue=(0, 'day'),
                        maxValue=(1000, 'day'),
                        label='simulation time')
    tPrint = F.Quantity('Bio_Time',
                        default=(0.0, 'day'),
                        minValue=(1e-5, 'day'),
                        maxValue=(100, 'day'),
                        label='print interval')

    absTol = F.Quantity('Bio_Time',
                        default=(0.0, 'day'),
                        minValue=(1e-16, 'day'),
                        maxValue=(1e-5, 'day'),
                        label='absolute tolerance')
    relTol = F.Quantity('Bio_Time',
                        default=(0.0, 'day'),
                        minValue=(1e-16, 'day'),
                        maxValue=(1e-3, 'day'),
                        label='relative tolerance')

    FG = F.FieldGroup([tFinal, tPrint, absTol, relTol], label='Solver')
    SG = F.SuperGroup([FG], label='Settings')

    modelBlocks = []
Beispiel #2
0
class CycleIterator(NumericalModel):
    hTolerance = F.Quantity('SpecificEnthalpy',
                            default=1.0,
                            label='enthalpy tolerance')
    maxNumIter = F.Quantity(default=500,
                            label='max iterations',
                            description='maximum number of iterations')
    convSettings = F.FieldGroup([hTolerance, maxNumIter],
                                label='Convergence settings')
    solverSettings = F.SuperGroup([convSettings], label='Solver')
    modelBlocks = []

    def run(self):
        self.converged = False
        self.ncp = len(self.cycle.fp)
        self.old_h = np.zeros((self.ncp))
        self.old_T = np.zeros((self.ncp))
        self.old_p = np.zeros((self.ncp))
        self.hHistory = []
        self.change_h = np.zeros((self.ncp))
        self.change_hHistory = []
        i = 0
        self.cycle.computeCycle()
        while (i < self.maxNumIter):
            self.saveOldValues()
            self.cycle.computeCycle()
            self.checkConvergence()
            if (self.converged):
                break
            i += 1

        if (not self.converged):
            raise E.ConvergenceError(
                'Solution did not converge, delta_h = {:e}'.format(
                    self.change_hHistory[-1]))

    def saveOldValues(self):
        for i in range(self.ncp):
            self.old_h[i] = self.cycle.fp[i].h
            self.old_T[i] = self.cycle.fp[i].T
            self.old_p[i] = self.cycle.fp[i].p
        #self.hHistory.append(self.old_h)

    def computeChange(self):
        for i in range(self.ncp):
            self.change_h[i] = self.cycle.fp[i].h - self.old_h[i]
        change = np.sqrt(np.sum(self.change_h**2))
        self.hHistory.append([x for x in self.change_h])
        self.change_hHistory.append(change)
        return change

    def checkConvergence(self):
        self.converged = self.computeChange() < self.hTolerance
        return self.converged

    def printValues(self):
        print[fp.T for fp in self.cycle.fp]
        print[fl.mDot for fl in self.cycle.flows]
Beispiel #3
0
class FiniteVolumeSolverSettings(NumericalModel):
    tolerance = F.Quantity(default=1e-6, label='tolerance')
    maxNumIterations = F.Integer(default=100, label='max number iterations')
    relaxationFactor = F.Quantity(default=1.0, label='relaxation factor')

    FG = F.FieldGroup([tolerance, maxNumIterations, relaxationFactor],
                      label='Settings')

    modelBlocks = []
Beispiel #4
0
class TankRes(NumericalModel):
    compositeMass = F.Quantity('Mass',
                               default=(0., 'kg'),
                               label='composite mass',
                               description='composite mass')
    linerMass = F.Quantity('Mass',
                           default=(0., 'kg'),
                           label='liner mass',
                           description='liner mass')

    FG = F.FieldGroup([linerMass, compositeMass], label='Pressure vessel')

    modelBlocks = []
Beispiel #5
0
class BlockGeometry(NumericalModel):
    diameter = F.Quantity('Length',
                          default=(0., 'mm'),
                          label='diameter',
                          description='block diameter')
    length = F.Quantity('Length',
                        default=(0., 'm'),
                        label='length',
                        description='block length')

    FG = F.FieldGroup([diameter, length], label='Block geometry')

    modelBlocks = []
class FluidSource_TP(CycleComponent):
    T = F.Quantity('Temperature', label='temperature')
    p = F.Quantity('Pressure', label='pressure')
    mDot = F.Quantity('MassFlowRate', label='mass flow rate')
    FG = F.FieldGroup([T, p, mDot], label='Compressor')
    modelBlocks = []
    #================== Ports =================#
    outlet = F.Port(P.ThermodynamicPort)

    #================== Methods =================#
    def compute(self):
        self.outlet.flow.mDot = self.mDot
        self.outlet.state.update_Tp(self.T, self.p)
class IsobaricHeatExchanger(CycleComponent2FlowPorts):
    etaThermal = F.Quantity(default=1.0,
                            label='thermal efficiency',
                            minValue=0,
                            maxValue=1,
                            show='self.computeMethod == "eta"')
    TExt = F.Quantity('Temperature',
                      default=(30, 'degC'),
                      label='external temperature',
                      show='self.computeMethod == "eta"')
    qOutlet = F.Quantity(default=0,
                         minValue=0,
                         maxValue=1,
                         label='outlet vapor quality',
                         show='self.computeMethod == "Q"')
    TOutlet = F.Quantity('Temperature',
                         default=(40, 'degC'),
                         label='outlet temperature',
                         show='self.computeMethod == "T"')
    hOutlet = F.Quantity('SpecificEnthalpy',
                         default=(100, 'kJ/kg'),
                         minValue=-1e10,
                         label='outlet enthalpy',
                         show='self.computeMethod == "H"')
    modelBlocks = []

    #================== Methods =================#
    def compute(self):
        CycleComponent2FlowPorts.compute(self)
        pIn = self.inlet.state.p
        if (self.computeMethod == 'eta'):
            self.outlet.state.update_Tp(self.TExt, pIn)
            hOut = (
                1 - self.etaThermal
            ) * self.inlet.state.h + self.etaThermal * self.outlet.state.h
            self.outlet.state.update_ph(pIn, hOut)
        elif (self.computeMethod == 'dT'):
            self.outlet.state.update('P', pIn, 'dT', self.dTOutlet)
        elif (self.computeMethod == 'Q'):
            self.outlet.state.update_pq(pIn, self.qOutlet)
        elif (self.computeMethod == 'T'):
            self.outlet.state.update_Tp(self.TOutlet, pIn)
        elif (self.computeMethod == 'H'):
            self.outlet.state.update_ph(pIn, self.hOutlet)
        else:
            raise ValueError('Unknown compute method {}'.format(
                self.computeMethod))

        self.qIn = self.outlet.state.h - self.inlet.state.h
        self.delta_h = self.qIn
        self.w = 0
Beispiel #8
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')
Beispiel #9
0
class Compressor(NumericalModel):
    etaS = F.Quantity('Efficiency',
                      default=(0., '-'),
                      label='isentropic efficiency',
                      description='isentropic efficiency')
    fQ = F.Quantity('Fraction',
                    default=(0., '-'),
                    label='heat loss fraction',
                    description='heat loss fraction to ambient')
    V = F.Quantity('Volume',
                   default=(0., 'L'),
                   maxValue=(1e6, 'L'),
                   label='displacement volume',
                   description='displacement volume')

    FG = F.FieldGroup([etaS, fQ, V], label='Parameters')

    modelBlocks = []
Beispiel #10
0
class FluidStateSource(NumericalModel):
    sourceTypeTxt = F.Choices(OrderedDict((
        ('TP', 'temperature, pressure'),
        ('PQ', 'pressure, vapour quality'),
        ('TQ', 'temperature, vapour quality'),
    )),
                              label='state variables',
                              description='choose the initial state variables')

    @property
    def sourceType(self):
        if self.sourceTypeTxt == 'TP':
            return DM.FluidStateSource.TP
        if self.sourceTypeTxt == 'PQ':
            return DM.FluidStateSource.PQ
        if self.sourceTypeTxt == 'TQ':
            return DM.FluidStateSource.TQ
        else:
            raise ValueError('Unsupported source type of FluidStateSource.')

    T = F.Quantity(
        'Temperature',
        default=(0., 'degC'),
        label='temperature',
        description='temperature',
        show="self.sourceTypeTxt == 'TP' || self.sourceTypeTxt == 'TQ'")
    p = F.Quantity(
        'Pressure',
        default=(0., 'bar'),
        label='pressure',
        description='pressure',
        show="self.sourceTypeTxt == 'TP' || self.sourceTypeTxt == 'PQ'")
    q = F.Quantity(
        'VaporQuality',
        default=(0., '-'),
        minValue=0,
        maxValue=1,
        label='vapour quality',
        description='vapour quality',
        show="self.sourceTypeTxt == 'TQ' || self.sourceTypeTxt == 'PQ'")

    FG = F.FieldGroup([sourceTypeTxt, T, p, q], label='Parameters')

    modelBlocks = []
class Compressor(CycleComponent2FlowPorts):
    modelType = F.Choices(OrderedDict((
        ('S', 'isentropic'),
        ('T', 'isothermal'),
    )),
                          label='compressor model')
    etaS = F.Quantity('Efficiency',
                      label='isentropic efficiency',
                      show="self.modelType == 'S'")
    fQ = F.Quantity('Fraction',
                    default=0.,
                    label='heat loss factor',
                    show="self.modelType == 'S'")
    etaT = F.Quantity('Efficiency',
                      label='isosthermal efficiency',
                      show="self.modelType == 'T'")
    dT = F.Quantity('TemperatureDifference',
                    default=0,
                    label='temperature increase',
                    show="self.modelType == 'T'")
    FG = F.FieldGroup([modelType, etaS, fQ, etaT, dT], label='Compressor')
    modelBlocks = []

    #================== Methods =================#
    def compute(self, pOut):
        CycleComponent2FlowPorts.compute(self)
        if (pOut < self.inlet.state.p):
            raise ValueError(
                'Outlet pressure must be higher than inlet pressure')
        if (self.modelType == 'S'):
            self.outlet.state.update_ps(pOut, self.inlet.state.s)
            wIdeal = self.outlet.state.h - self.inlet.state.h
            self.w = wIdeal / self.etaS
            self.qIn = -self.fQ * self.w
            self.delta_h = self.w + self.qIn
            self.outlet.state.update_ph(pOut,
                                        self.inlet.state.h + self.delta_h)
        else:
            self.outlet.state.update_Tp(self.inlet.state.T + self.dT, pOut)
            self.qIn = (self.outlet.state.s -
                        self.inlet.state.s) * self.inlet.state.T
            wIdeal = self.outlet.state.h - self.inlet.state.h - self.qIn
            self.w = wIdeal / self.etaT
            self.qIn -= (self.w - wIdeal)
Beispiel #12
0
class SectionResultsSettings(NumericalModel):
    setTRange = F.Boolean(
        False,
        label='set temperature range',
        description=
        'set temperature range (Tmin, Tmax) of the section results plots')
    Tmin = F.Quantity('Temperature',
                      default=(0, 'K'),
                      label='min temperature',
                      description='minimum temperature',
                      show='self.setTRange')
    Tmax = F.Quantity('Temperature',
                      default=(0, 'K'),
                      label='max temperature',
                      description='maximum temperature',
                      show='self.setTRange')

    FG = F.FieldGroup([setTRange, Tmin, Tmax], label='Settings')

    modelBlocks = []
class FlowSplitter(CycleComponent):
    frac1 = F.Quantity('Fraction', label='fraction to outlet 1')
    frac2 = F.Quantity('Fraction', label='fraction to outlet 2')
    FG = F.FieldGroup([frac1, frac2])
    modelBlocks = []
    #================== Ports =================#
    inlet = F.Port(P.ThermodynamicPort)
    outlet1 = F.Port(P.ThermodynamicPort)
    outlet2 = F.Port(P.ThermodynamicPort)

    #================== Methods =================#
    def compute(self):
        self.outlet1.flow.mDot = self.inlet.flow.mDot * self.frac1 / (
            self.frac1 + self.frac2)
        self.outlet2.flow.mDot = self.inlet.flow.mDot * self.frac2 / (
            self.frac1 + self.frac2)
        self.outlet1.state.update_Trho(self.inlet.state.T,
                                       self.inlet.state.rho)
        self.outlet2.state.update_Trho(self.inlet.state.T,
                                       self.inlet.state.rho)
Beispiel #14
0
class LiquefactionCycle(ThermodynamicalCycle):
    abstract = True
    #================ Inputs ================#
    fluidName = F.Choices(Fluids, default='R134a', label='liquefied fluid')
    mDot = F.Quantity('MassFlowRate',
                      default=(1, 'kg/min'),
                      label='inlet flow rate')
    pIn = F.Quantity('Pressure',
                     default=(1, 'bar'),
                     label='inlet gas pressure')
    TIn = F.Quantity('Temperature',
                     default=(15, 'degC'),
                     label='inlet gas temperature')
    pHigh = F.Quantity('Pressure',
                       default=(40, 'bar'),
                       label='compressor high pressure')
    pLiquid = F.Quantity('Pressure',
                         default=(2, 'bar'),
                         label='liquid pressure')
    TAmbient = F.Quantity(
        'Temperature',
        default=(15, 'degC'),
        label='ambient temperature',
        description='used as reference temperature to calculate exergy')
    workingFluidGroup = F.FieldGroup(
        ['fluidName', 'mDot', pIn, TIn, pHigh, pLiquid, TAmbient],
        label='Cycle parameters')
    #================ Results ================#
    liqEnergy = F.Quantity('SpecificEnergy',
                           default=(1, 'kJ/kg'),
                           label='liquefaction energy')
    minLiqEnergy = F.Quantity(
        'SpecificEnergy',
        default=(1, 'kJ/kg'),
        label='min. liquefaction energy',
        description=
        'minimum energy required for liquefaction in an ideal carnot cycle; \
			equal to the difference in exergies between initial and final state')
    etaSecondLaw = F.Quantity(
        'Efficiency',
        label='figure of merit (FOM)',
        description=
        'minimum energy required for liquefaction to the actual energy required \
			in the cycle; equivalent to second law efficiency')
    efficiencyFieldGroup = F.FieldGroup(
        [liqEnergy, minLiqEnergy, etaSecondLaw], label='Efficiency')
class CycleComponent2FlowPorts(CycleComponent):
    abstract = True
    w = F.Quantity('SpecificEnergy',
                   default=(0, 'kJ/kg'),
                   label='specific work')
    qIn = F.Quantity('SpecificEnergy',
                     default=(0, 'kJ/kg'),
                     label='specific heat in')
    delta_h = F.Quantity('SpecificEnthalpy', label='enthalpy change (fluid)')
    WDot = F.Quantity('Power', default=(0, 'kW'), label='power')
    QDotIn = F.Quantity('HeatFlowRate',
                        default=(0, 'kW'),
                        label='heat flow rate in')
    deltaHDot = F.Quantity('Power', label='enthalpy change (fluid)')
    #================== Ports =================#
    inlet = F.Port(P.ThermodynamicPort)
    outlet = F.Port(P.ThermodynamicPort)

    #================== Methods =================#
    def compute(self):
        self.outlet.flow.mDot = self.inlet.flow.mDot

    def postProcess(self):
        self.WDot = self.w * self.inlet.flow.mDot
        self.QDotIn = self.qIn * self.inlet.flow.mDot
        self.deltaHDot = self.delta_h * self.inlet.flow.mDot
Beispiel #16
0
class Cooler(NumericalModel):
    workingState = F.Choices(OrderedDict((
        (0, 'no'),
        (1, 'yes'),
    )),
                             label='enable cooler',
                             description='enable cooler')

    epsilon = F.Quantity('Efficiency',
                         default=(0., '-'),
                         label='effectiveness',
                         description='effectiveness',
                         show="self.workingState")
    TCooler = F.Quantity('Temperature',
                         default=(0., 'degC'),
                         label='coolant temperature',
                         description='coolant temperature',
                         show="self.workingState")

    FG = F.FieldGroup([workingState, epsilon, TCooler], label='Parameters')

    modelBlocks = []
Beispiel #17
0
class HeatFlowChannels(NumericalModel):
    QDotPrimaryChannels = F.Quantity(
        'HeatFlowRate',
        default=(1.0, 'kW'),
        label='Primary channels',
        description='heat flow rate to the primary channels')
    QDotSecondaryChannels = F.Quantity(
        'HeatFlowRate',
        default=(1.0, 'kW'),
        label='Secondary channels',
        description='heat flow rate to the secondary channels')
    QDotExternalChannel = F.Quantity(
        'HeatFlowRate',
        default=(1.0, 'kW'),
        label='External channel',
        description='heat flow rate from the external channel')

    FG = F.FieldGroup(
        [QDotPrimaryChannels, QDotSecondaryChannels, QDotExternalChannel],
        label='Parameters')

    modelBlocks = []
Beispiel #18
0
class BlockProperties(NumericalModel):
    material = F.ObjectReference(Solids,
                                 default='Aluminium6061',
                                 label='material',
                                 description='block material')
    divisionStep = F.Quantity('Length',
                              default=(0., 'm'),
                              minValue=(1, 'mm'),
                              label='division step (axial)',
                              description='axial division step')

    FG = F.FieldGroup([material, divisionStep], label='Block properties')

    modelBlocks = []
Beispiel #19
0
class ExternalChannelGeometry(NumericalModel):
    widthAxial = F.Quantity(
        'Length',
        default=(0., 'mm'),
        label='width (axial)',
        description='axial width of the spiral rectangular channel')
    heightRadial = F.Quantity(
        'Length',
        default=(0., 'mm'),
        label='radial height',
        description='radial height of the spiral rectangular channel')
    coilPitch = F.Quantity(
        'Length',
        default=(0., 'mm'),
        label='coil pitch',
        description='coil pitch of the spiral rectangular channel')

    cellSize = F.Quantity(
        'Length',
        default=(0., 'mm'),
        label='mesh cell size',
        description='mesh cell size near the outer block circle')
    meshFineness = F.Integer(
        default=1,
        minValue=1,
        maxValue=10,
        label='mesh fineness',
        description='mesh fineness near the outer side of the block')

    FG = F.FieldGroup([widthAxial, heightRadial, coilPitch, meshFineness],
                      label='Channel geometry')

    modelBlocks = []

    def compute(self, blockDiameter):
        self.averageCoilDiameter = blockDiameter + self.heightRadial
        self.cellSize = self.averageCoilDiameter / (self.meshFineness * 10.)
Beispiel #20
0
class FluidFlowOutput(NumericalModel):
    VDot = F.Quantity('VolumetricFlowRate',
                      minValue=(0., 'm**3/h'),
                      default=(1., 'm**3/h'),
                      label='volume flow',
                      description='volume flow rate')
    mDot = F.Quantity('MassFlowRate',
                      minValue=(0, 'kg/h'),
                      default=(1., 'kg/h'),
                      label='mass flow',
                      description='mass flow rate')
    T = F.Quantity('Temperature', default=(300., 'K'), label='temperature')
    p = F.Quantity('Pressure', default=(1., 'bar'), label='pressure')

    FG = F.FieldGroup([mDot, VDot, T, p], label='Parameters')

    modelBlocks = []

    def compute(self, fState, mDot):
        self.fState = fState
        self.T = fState.T
        self.p = fState.p
        self.mDot = mDot
        self.VDot = mDot / fState.rho
Beispiel #21
0
    def redefineFileds(self):
        # Create tuples for species
        speciesTuples = (('time', F.Quantity('Time', default=(1, 's'))), )
        datasetColumns = ['t']
        for itSpecies in self.species:
            X = itSpecies[0]  #species variable
            speciesTuple = (('%s' % X,
                             F.Quantity('Bio_MolarConcentration',
                                        default=(1, 'M'))), )
            speciesTuples += speciesTuple
            datasetColumns.append('%s' % X)

        # Redefine Fields
        redefinedStorage = F.HdfStorage(
            hdfFile='BioReactors_SimulationResults.h5',
            hdfGroup='/BiochemicalReactions',
            datasetColumns=datasetColumns)
        self.redefineField('storage', 'storageVG', redefinedStorage)

        redefinedPlot = F.PlotView(speciesTuples,
                                   label='Plot',
                                   options={
                                       'ylabel': 'concentration',
                                       'title': ''
                                   },
                                   useHdfStorage=True,
                                   storage='storage')
        self.redefineField('plot', 'resultsVG', redefinedPlot)

        redefinedTable = F.TableView(
            speciesTuples,
            label='Table',
            options={'formats': ['0.000', '0.000', '0.000', '0.000']},
            useHdfStorage=True,
            storage='storage')
        self.redefineField('table', 'resultsVG', redefinedTable)
Beispiel #22
0
class ThermodynamicalProcessTwoStreams(ThermodynamicalCycle):
    ############# Inputs #############
    fluidSource1 = F.SubModelGroup(TC.FluidSource, 'FG', label='Inlet 1')
    fluidSource2 = F.SubModelGroup(TC.FluidSource, 'FG', label='Inlet 2')
    fluidSink1 = F.SubModelGroup(TC.FluidSink, 'FG', label='Outlet 1')
    fluidSink2 = F.SubModelGroup(TC.FluidSink, 'FG', label='Outlet 2')
    inputs = F.SuperGroup([fluidSource1, fluidSource2, fluidSink1, fluidSink2])

    # Model View
    inputView = F.ModelView(ioType="input",
                            superGroups=[inputs],
                            autoFetch=True)

    ############# Results #############
    QDot = F.Quantity('HeatFlowRate',
                      default=(0, 'kW'),
                      label='heat flow rate in')
    NTU = F.Quantity(label='NTU')
    Cr = F.Quantity(label='capacity ratio')
    energyResults = F.FieldGroup([QDot, NTU, Cr], label="Energy")
    energyBalanceResults = F.SuperGroup([energyResults],
                                        label="Energy balance")

    # Model View
    resultView = F.ModelView(
        ioType="output", superGroups=['resultStates', energyBalanceResults])

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

    ############# Methods ###############
    def postProcess(self, component):
        super(ThermodynamicalProcessTwoStreams, self).postProcess(300)
        self.QDot = component.QDot
        self.NTU = component.NTU
        self.Cr = component.Cr
Beispiel #23
0
class ChannelGroupGeometry(NumericalModel):
    number = F.Integer(default=0,
                       minValue=0,
                       maxValue=30,
                       label='number',
                       description='number of channels')
    radialPosition = F.Quantity('Length',
                                default=(0., 'mm'),
                                minValue=(0, 'mm'),
                                label='radial position',
                                description='radial position of the channels')
    startingAngle = F.Quantity('Angle',
                               default=(0., 'deg'),
                               minValue=(-1e6, 'deg'),
                               label='starting angle',
                               description='starting angle of the first')

    cellSize = F.Quantity('Length',
                          default=(0., 'mm'),
                          label='mesh cell size',
                          description='mesh cell size near the channels')
    meshFineness = F.Integer(default=1,
                             minValue=1,
                             maxValue=10,
                             label='mesh fineness',
                             description='mesh fineness near the channels')

    externalDiameter = F.Quantity(
        'Length',
        default=(0., 'mm'),
        label='external diameter',
        description='external diameter of the channels')
    sections = F.RecordArray((
        ('internalDiameter',
         F.Quantity('Length',
                    default=(0, 'mm'),
                    minValue=(0, 'mm'),
                    label='internal diameter')),
        ('length', F.Quantity('Length', default=(0.2, 'm'), label='length')),
    ),
                             label='sections',
                             numRows=5)

    channelName = F.String()

    FG = F.FieldGroup([
        number, radialPosition, startingAngle, externalDiameter, sections,
        meshFineness
    ],
                      label='Parameters')

    modelBlocks = []

    def compute(self):
        self.cellSize = self.externalDiameter / (self.meshFineness * 2.5)
        self.length = np.sum(self.sections['length'])
Beispiel #24
0
class FluidFlowInput(NumericalModel):
    fluidName = F.Choices(Fluids, default='ParaHydrogen', label='fluid')
    flowRateChoice = F.Choices(OrderedDict((
        ('V', 'volume'),
        ('m', 'mass'),
    )),
                               label='flow rate based on')
    mDot = F.Quantity('MassFlowRate',
                      minValue=(0, 'kg/h'),
                      default=(1., 'kg/h'),
                      label='mass flow',
                      description='mass flow rate',
                      show='self.flowRateChoice == "m"')
    VDot = F.Quantity('VolumetricFlowRate',
                      minValue=(0., 'm**3/h'),
                      default=(1., 'm**3/h'),
                      label='volume flow',
                      description='volume flow rate',
                      show='self.flowRateChoice == "V"')
    T = F.Quantity('Temperature', default=(300., 'K'), label='temperature')
    p = F.Quantity('Pressure', default=(1., 'bar'), label='pressure')
    FG = F.FieldGroup([fluidName, flowRateChoice, mDot, VDot, T, p],
                      label='Parameters')

    modelBlocks = []

    def createFluidState(self):
        return CP.FluidState(self.fluidName)

    def compute(self):
        self.fState = self.createFluidState()
        self.fState.update_Tp(self.T, self.p)
        if (self.flowRateChoice == 'm'):
            self.VDot = self.mDot / self.fState.rho
        else:
            self.mDot = self.VDot * self.fState.rho
class Turbine(CycleComponent2FlowPorts):
    eta = F.Quantity(default=1, minValue=0, maxValue=1, label='efficiency')
    FG = F.FieldGroup([eta], label='Turbine')
    modelBlocks = []

    #================== Methods =================#
    def compute(self, pOut):
        if (pOut > self.inlet.state.p):
            raise ValueError(
                'Outlet pressure must be lower than inlet pressure')
        CycleComponent2FlowPorts.compute(self)
        self.outlet.state.update_ps(pOut, self.inlet.state.s)
        wIdeal = self.outlet.state.h - self.inlet.state.h
        self.w = wIdeal * self.eta
        self.qIn = 0
        self.delta_h = self.w + self.qIn
        self.outlet.state.update_ph(pOut, self.inlet.state.h + self.delta_h)
Beispiel #26
0
class IncompressibleSolutionFlowInput(FluidFlowInput):
    solName = F.Choices(IncompressibleSolutions,
                        default='MEG',
                        label='fluid (name)',
                        description='fluid (incompressible solutions)')
    solMassFraction = F.Quantity(
        'Fraction',
        default=(0, '%'),
        label='fluid (mass fraction)',
        description='mass fraction of the substance other than water')

    incomSolFG = F.FieldGroup(
        [solName, solMassFraction, 'flowRateChoice', 'mDot', 'VDot', 'T', 'p'],
        label='Parameters')

    def createFluidState(self):
        return CP5.FluidStateFactory.createIncompressibleSolution(
            self.solName, self.solMassFraction)
Beispiel #27
0
class Controller(NumericalModel):
    initialState = F.Choices(
        OrderedDict((
            (TC.FUELING, 'fueling'),
            (TC.EXTRACTION, 'extraction'),
        )),
        label='start with',
        description='start the simulation with fueling or extraction')
    tWaitBeforeExtraction = F.Quantity(
        'Time',
        default=(0., 's'),
        minValue=(0., 's'),
        maxValue=(1.e6, 's'),
        label='&#964 (extraction)',
        description='waiting time before each extraction')
    tWaitBeforeFueling = F.Quantity(
        'Time',
        default=(0., 's'),
        minValue=(0., 's'),
        maxValue=(1.e6, 's'),
        label='&#964 (fueling)',
        description='waiting time before each fueling')
    pMin = F.Quantity(
        'Pressure',
        default=(0., 'bar'),
        label='minimum pressure</sub>',
        description='minimum pressure in the gas storage for starting fueling')
    pMax = F.Quantity(
        'Pressure',
        default=(0., 'bar'),
        label='maximum pressure',
        description='maximum pressure in the gas storage for stopping fueling')
    mDotExtr = F.Quantity('MassFlowRate',
                          default=(0., 'kg/h'),
                          label='extraction mass flow rate',
                          description='extraction mass flow rate')
    nCompressor = F.Quantity('AngularVelocity',
                             default=(0., 'rev/s'),
                             minValue=(0, 'rev/s'),
                             maxValue=(1e4, 'rev/s'),
                             label='compressor speed',
                             description='compressor speed')

    FG = F.FieldGroup([
        initialState, pMin, pMax, mDotExtr, nCompressor, tWaitBeforeExtraction,
        tWaitBeforeFueling
    ],
                      label='Parameters')

    SG = F.SuperGroup([FG], label="Parameters")

    modelBlocks = []
Beispiel #28
0
class ThermodynamicalProcess(ThermodynamicalCycle):
    ############# Inputs #############
    fluidSource = F.SubModelGroup(TC.FluidSource, 'FG', label='Initial State')
    fluidSink = F.SubModelGroup(TC.FluidSink, 'FG', label='Final State')
    inputs = F.SuperGroup([fluidSource, fluidSink])

    # Model View
    inputView = F.ModelView(ioType="input",
                            superGroups=[inputs],
                            autoFetch=True)

    ############# Results #############
    w = F.Quantity('SpecificEnergy',
                   default=(0, 'kJ/kg'),
                   label='specific work')
    qIn = F.Quantity('SpecificEnergy',
                     default=(0, 'kJ/kg'),
                     label='specific heat in')
    delta_h = F.Quantity('SpecificEnthalpy', label='enthalpy change (fluid)')
    WDot = F.Quantity('Power', default=(0, 'kW'), label='power')
    QDotIn = F.Quantity('HeatFlowRate',
                        default=(0, 'kW'),
                        label='heat flow rate in')
    deltaHDot = F.Quantity('Power', label='enthalpy change (fluid)')
    # Specific energy quantities
    specificEnergyResults = F.FieldGroup(
        [w, delta_h, qIn], label="Heat/work (specific quantities)")
    # Energy flow quantities
    energyFlowResults = F.FieldGroup([WDot, deltaHDot, QDotIn],
                                     label="Heat/work flows")
    energyBalanceResults = F.SuperGroup(
        [specificEnergyResults, energyFlowResults], label="Energy balance")

    # Model View
    resultView = F.ModelView(
        ioType="output",
        superGroups=['resultDiagrams', 'resultStates', energyBalanceResults])

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

    ############# Methods ###############
    def postProcess(self, component):
        super(ThermodynamicalProcess, self).postProcess(300)
        component.postProcess()
        self.w = component.w
        self.qIn = component.qIn
        self.delta_h = component.delta_h
        self.WDot = component.WDot
        self.QDotIn = component.QDotIn
        self.deltaHDot = component.deltaHDot
class Condenser(IsobaricHeatExchanger):
    computeMethod = F.Choices(OrderedDict((
        ('dT', 'sub-cooling'),
        ('Q', 'vapor quality'),
        ('eta', 'thermal efficiency'),
        ('T', 'temperature'),
        ('H', 'enthalpy'),
    )),
                              label='compute outlet by')
    dTOutlet = F.Quantity('TemperatureDifference',
                          default=(-10, 'degC'),
                          minValue=-1e10,
                          maxValue=-1e-3,
                          label='outlet subcooling',
                          show='self.computeMethod == "dT"')
    FG = F.FieldGroup([
        'computeMethod', 'etaThermal', 'TExt', 'dTOutlet', 'TOutlet',
        'qOutlet', 'hOutlet'
    ],
                      label='Condenser')
    modelBlocks = []
Beispiel #30
0
class ADM1H2CH4Bioreactors(NumericalModel):
    label = "(H2,CH4) Bioreactors"
    description = F.ModelDescription(
        "A model of the process of hydrogen and methane production by anaerobic digestion of organic wastes in a cascade of two continuously stirred bioreactors.",
        show=True)
    figure = F.ModelFigure(
        src="BioReactors/img/ModuleImages/ADM1H2CH4Bioreactors.png", show=True)

    async = True
    progressOptions = {'suffix': 'day', 'fractionOutput': True}

    #1. ############ Inputs ###############
    #1.1 Fields - Input values
    parametersRH2 = F.SubModelGroup(H2Bioreactor,
                                    'parametersSG',
                                    label='Parameters (R-H2)')
    concentrationsRH2 = F.SubModelGroup(H2Bioreactor,
                                        'concentrationsSG',
                                        label='Concentrations (R-H2)')

    parametersRCH4 = F.SubModelGroup(CH4Bioreactor,
                                     'parametersSG',
                                     label='Parameters (R-CH4)')
    concentrationsRCH4 = F.SubModelGroup(CH4Bioreactor,
                                         'concentrationsSG',
                                         label='Concentrations (R-CH4)')

    #1.3 Fields - Settings
    solverSettings = F.SubModelGroup(SolverSettings,
                                     'FG',
                                     label='H2 & CH4 - Bioreactors')
    settingsSG = F.SuperGroup([solverSettings], label='Solver settings')

    #1.4 Model view
    exampleAction = A.ServerAction(
        "loadEg",
        label="Examples",
        options=(
            #('exampleDef', 'Reset to default values'),
            ('exampleADM1', 'Reset to ADM1 values'), ))

    inputView = F.ModelView(
        ioType="input",
        superGroups=[
            parametersRH2, concentrationsRH2, parametersRCH4,
            concentrationsRCH4, settingsSG
        ],
        autoFetch=True,
        actionBar=A.ActionBar([exampleAction]),
    )

    #2. ############ Results ###############
    storage = F.HdfStorage(hdfFile=DM.dataStorageFilePath,
                           hdfGroup=DM.dataStorageDatasetPath)

    varTuples = (
        ('time', F.Quantity('Bio_Time', default=(1, 'day'))),  #0
        ('S_su_RH2', F.Quantity('Bio_CODConcentration',
                                default=(1, 'gCOD/L'))),  #1
        ('S_aa_RH2', F.Quantity('Bio_CODConcentration',
                                default=(1, 'gCOD/L'))),  #2
        ('S_fa_RH2', F.Quantity('Bio_CODConcentration',
                                default=(1, 'gCOD/L'))),  #3
        ('S_ac_RH2', F.Quantity('Bio_CODConcentration',
                                default=(1, 'gCOD/L'))),  #4
        ('X_c_RH2', F.Quantity('Bio_CODConcentration',
                               default=(1, 'gCOD/L'))),  #5
        ('X_ch_RH2', F.Quantity('Bio_CODConcentration',
                                default=(1, 'gCOD/L'))),  #6
        ('X_pr_RH2', F.Quantity('Bio_CODConcentration',
                                default=(1, 'gCOD/L'))),  #7
        ('X_li_RH2', F.Quantity('Bio_CODConcentration',
                                default=(1, 'gCOD/L'))),  #8
        ('X_suaa_RH2', F.Quantity('Bio_MassConcentration',
                                  default=(1, 'g/L'))),  #9
        ('X_fa_RH2', F.Quantity('Bio_MassConcentration',
                                default=(1, 'g/L'))),  #10
        ('intQ_h2_RH2',
         F.Quantity('Bio_CODConcentration', default=(1, 'gCOD/L'))),  #11
        ('S_ac_RCH4', F.Quantity('Bio_CODConcentration',
                                 default=(1, 'gCOD/L'))),  #12   
        ('X_ac_RCH4', F.Quantity('Bio_MassConcentration',
                                 default=(1, 'g/L'))),  #13
        ('intQ_ch4_RCH4',
         F.Quantity('Bio_CODConcentration', default=(1, 'gCOD/L'))),  #14
        ('Q_h2_RH2',
         F.Quantity('Bio_CODConcentrationFlowRate',
                    default=(1, 'gCOD/L/day'))),  #15
        ('Q_ch4_RCH4',
         F.Quantity('Bio_CODConcentrationFlowRate',
                    default=(1, 'gCOD/L/day'))),  #16
        ('D_RH2', F.Quantity('Bio_TimeRate', default=(1, '1/day'))),  #17
        ('D_RCH4', F.Quantity('Bio_TimeRate', default=(1, '1/day'))),  #18
    )

    plot1RH2 = F.PlotView(
        varTuples,
        label='R-H2 (S<sub>su</sub>, S<sub>aa</sub>, S<sub>fa</sub>)',
        options={'ylabel': None},
        visibleColumns=[0, 1, 2, 3],
        useHdfStorage=True,
        storage='storage',
    )

    plot2RH2 = F.PlotView(
        varTuples,
        label='R-H2 (X<sub>ch</sub>, X<sub>pr</sub>, X<sub>li</sub>)',
        options={'ylabel': None},
        visibleColumns=[0, 6, 7, 8],
        useHdfStorage=True,
        storage='storage',
    )

    plot3RH2 = F.PlotView(
        varTuples,
        label='R-H2 (X<sub>su-aa</sub>,X<sub>fa</sub>)',
        options={'ylabel': None},
        visibleColumns=[0, 9, 10],
        useHdfStorage=True,
        storage='storage',
    )

    plot4RH2 = F.PlotView(
        varTuples,
        label='R-H2 (H<sub>2</sub>)',
        options={'ylabel': None},
        visibleColumns=[0, 11, 15],
        useHdfStorage=True,
        storage='storage',
    )

    plot1RCH4 = F.PlotView(
        varTuples,
        label='R-CH4 (S<sub>ac</sub>, X<sub>ac</sub>)',
        options={'ylabel': None},
        visibleColumns=[0, 12, 13],
        useHdfStorage=True,
        storage='storage',
    )

    plot2RCH4 = F.PlotView(
        varTuples,
        label='R-CH4 (CH<sub>4</sub>)',
        options={'ylabel': None},
        visibleColumns=[0, 14, 16],
        useHdfStorage=True,
        storage='storage',
    )

    plotD = F.PlotView(
        varTuples,
        label='(D<sub>RH2</sub>, D<sub>RCH4</sub>)',
        options={'ylabel': None},
        visibleColumns=[0, 17, 18],
        useHdfStorage=True,
        storage='storage',
    )

    table = F.TableView(
        varTuples,
        label='Table',
        options={
            'title': 'Bioreactors',
            'formats': ['0.000']
        },
        useHdfStorage=True,
        storage='storage',
    )

    storageVG = F.ViewGroup([storage], show="false")
    resultsVG = F.ViewGroup([
        plot1RH2, plot2RH2, plot3RH2, plot4RH2, plot1RCH4, plot2RCH4, plotD,
        table
    ])
    resultsSG = F.SuperGroup([resultsVG, storageVG], label='Results')

    #2.1 Model view
    resultView = F.ModelView(ioType="output", superGroups=[resultsSG])

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

    ############# Methods ###############
    def __init__(self):
        self.exampleADM1()

    def exampleDef(self):
        ############# H2 Bioreactor ###############
        #Stoichiometric parameter values
        self.parametersRH2.f_ch_xc = 0.5  #-
        self.parametersRH2.f_pr_xc = 0.15  #-
        self.parametersRH2.f_li_xc = 0.15  #-

        self.parametersRH2.f_su_li = 0.05  #-
        self.parametersRH2.f_fa_li = 0.9  #-

        self.parametersRH2.f_ac_su = 0.41  #-

        self.parametersRH2.f_ac_aa = 0.4  #-

        self.parametersRH2.Y_suaa = 0.1  #-
        self.parametersRH2.Y_fa = 0.06  #-

        #Biochemical parameter values
        self.parametersRH2.k_dis = (0.5, '1/day')

        self.parametersRH2.k_hyd_ch = (10.0, '1/day')
        self.parametersRH2.k_hyd_pr = (10.0, '1/day')
        self.parametersRH2.k_hyd_li = (10.0, '1/day')

        self.parametersRH2.k_m_suaa = (30.0, '1/day')
        self.parametersRH2.K_S_suaa = (0.5, 'g/L')

        self.parametersRH2.k_m_fa = (6.0, '1/day')
        self.parametersRH2.K_S_fa = (0.4, 'g/L')

        # Physiochemical parameter values
        self.parametersRH2.Y_h2_su = 1.0  #-
        self.parametersRH2.Y_h2_aa = 1.0  #-
        self.parametersRH2.Y_h2_fa = 1.0  #-

        # Volumetric flow rate values
        self.parametersRH2.D_liq_arr[0] = (10.0, 0.0)  #(day, 1/day)
        self.parametersRH2.D_liq_arr[1] = (10.0, 0.1)  #(day, 1/day)
        self.parametersRH2.D_liq_arr[2] = (10.0, 0.05)  #(day, 1/day)
        self.parametersRH2.D_liq_arr[3] = (10.0, 0.15)  #(day, 1/day)

        # Input concentrations
        self.concentrationsRH2.S_su_in = (0.0, 'gCOD/L')
        self.concentrationsRH2.S_aa_in = (0.0, 'gCOD/L')
        self.concentrationsRH2.S_fa_in = (0.0, 'gCOD/L')
        self.concentrationsRH2.S_ac_in = (0.0, 'gCOD/L')
        self.concentrationsRH2.X_c_in = (2.0, 'gCOD/L')
        self.concentrationsRH2.X_ch_in = (0.0, 'gCOD/L')
        self.concentrationsRH2.X_pr_in = (0.0, 'gCOD/L')
        self.concentrationsRH2.X_li_in = (0.0, 'gCOD/L')
        self.concentrationsRH2.X_suaa_in = (0.0, 'g/L')
        self.concentrationsRH2.X_fa_in = (0.0, 'g/L')

        # Initial values of state variables
        self.concentrationsRH2.S_su_0 = (0.012, 'gCOD/L')
        self.concentrationsRH2.S_aa_0 = (0.005, 'gCOD/L')
        self.concentrationsRH2.S_fa_0 = (0.099, 'gCOD/L')
        self.concentrationsRH2.S_ac_0 = (0.20, 'gCOD/L')
        self.concentrationsRH2.X_c_0 = (30.0, 'gCOD/L')
        self.concentrationsRH2.X_ch_0 = (0.028, 'gCOD/L')
        self.concentrationsRH2.X_pr_0 = (0.10, 'gCOD/L')
        self.concentrationsRH2.X_li_0 = (0.03, 'gCOD/L')
        self.concentrationsRH2.X_suaa_0 = (0.42, 'g/L')
        self.concentrationsRH2.X_fa_0 = (0.24, 'g/L')

        ############# CH4 Bioreactor ###############
        #Stoichiometric parameter values
        self.parametersRCH4.Y_ac = 0.5  #-

        #Biochemical parameter values
        self.parametersRCH4.k_m_ac = (8.0, '1/day')
        self.parametersRCH4.K_S_ac = (0.15, 'g/L')

        # Physiochemical parameter values
        self.parametersRCH4.Y_ch4_ac = 1.0  #-

        # Physical parameter values
        self.parametersRCH4.V_liq_RCH4_del_V_liq_RH2 = (50.0, '-')  #L/L

        # Input concentrations
        self.concentrationsRCH4.X_ac_in = (0.0, 'g/L')

        # Initial values of state variables
        self.concentrationsRCH4.S_ac_0 = (0.0, 'gCOD/L')
        self.concentrationsRCH4.X_ac_0 = (2.0, 'g/L')

        ############# Solver settings ###############
        self.solverSettings.tFinal = (50.0, 'day')
        self.solverSettings.tPrint = (0.1, 'day')
        self.solverSettings.absTol = (1e-9, 'day')
        self.solverSettings.relTol = (1e-7, 'day')

    def exampleADM1(self):
        ############# H2 Bioreactor ###############
        #Stoichiometric parameter values
        self.parametersRH2.f_ch_xc = 0.2  #-
        self.parametersRH2.f_pr_xc = 0.2  #-
        self.parametersRH2.f_li_xc = 0.3  #-

        self.parametersRH2.f_su_li = 0.05  #-
        self.parametersRH2.f_fa_li = 0.95  #-

        self.parametersRH2.f_ac_su = 0.41  #-

        self.parametersRH2.f_ac_aa = 0.4  #-

        self.parametersRH2.Y_suaa = 0.1  #-
        self.parametersRH2.Y_fa = 0.06  #-

        #Biochemical parameter values
        self.parametersRH2.k_dis = (0.5, '1/day')

        self.parametersRH2.k_hyd_ch = (10.0, '1/day')
        self.parametersRH2.k_hyd_pr = (10.0, '1/day')
        self.parametersRH2.k_hyd_li = (10.0, '1/day')

        self.parametersRH2.k_m_suaa = (30.0, '1/day')
        self.parametersRH2.K_S_suaa = (0.5, 'g/L')

        self.parametersRH2.k_m_fa = (6.0, '1/day')
        self.parametersRH2.K_S_fa = (0.4, 'g/L')

        # Physiochemical parameter values
        self.parametersRH2.Y_h2_su = 1.0  #-
        self.parametersRH2.Y_h2_aa = 1.0  #-
        self.parametersRH2.Y_h2_fa = 1.0  #-

        # Volumetric flow rate values
        self.parametersRH2.D_liq_arr[0] = (10.0, 0.0)  #(day, 1/day)
        self.parametersRH2.D_liq_arr[1] = (10.0, 0.1)  #(day, 1/day)
        self.parametersRH2.D_liq_arr[2] = (10.0, 0.05)  #(day, 1/day)
        self.parametersRH2.D_liq_arr[3] = (10.0, 0.15)  #(day, 1/day)

        # Input concentrations
        self.concentrationsRH2.S_su_in = (0.01, 'gCOD/L')
        self.concentrationsRH2.S_aa_in = (0.001, 'gCOD/L')
        self.concentrationsRH2.S_fa_in = (0.001, 'gCOD/L')
        self.concentrationsRH2.S_ac_in = (0.001, 'gCOD/L')
        self.concentrationsRH2.X_c_in = (2.0, 'gCOD/L')
        self.concentrationsRH2.X_ch_in = (5.0, 'gCOD/L')
        self.concentrationsRH2.X_pr_in = (20.0, 'gCOD/L')
        self.concentrationsRH2.X_li_in = (5.0, 'gCOD/L')
        self.concentrationsRH2.X_suaa_in = (0.0, 'g/L')
        self.concentrationsRH2.X_fa_in = (0.01, 'g/L')

        # Initial values of state variables
        self.concentrationsRH2.S_su_0 = (0.012, 'gCOD/L')
        self.concentrationsRH2.S_aa_0 = (0.005, 'gCOD/L')
        self.concentrationsRH2.S_fa_0 = (0.099, 'gCOD/L')
        self.concentrationsRH2.S_ac_0 = (0.20, 'gCOD/L')
        self.concentrationsRH2.X_c_0 = (0.31, 'gCOD/L')
        self.concentrationsRH2.X_ch_0 = (0.028, 'gCOD/L')
        self.concentrationsRH2.X_pr_0 = (0.10, 'gCOD/L')
        self.concentrationsRH2.X_li_0 = (0.03, 'gCOD/L')
        self.concentrationsRH2.X_suaa_0 = (0.42, 'g/L')
        self.concentrationsRH2.X_fa_0 = (0.24, 'g/L')

        ############# CH4 Bioreactor ###############
        #Stoichiometric parameter values
        self.parametersRCH4.Y_ac = 0.05  #-

        #Biochemical parameter values
        self.parametersRCH4.k_m_ac = (8.0, '1/day')
        self.parametersRCH4.K_S_ac = (0.15, 'g/L')

        # Physiochemical parameter values
        self.parametersRCH4.Y_ch4_ac = 1.0  #-

        # Physical parameter values
        self.parametersRCH4.V_liq_RCH4_del_V_liq_RH2 = (50.0, '-')  #L/L

        # Input concentrations
        self.concentrationsRCH4.X_ac_in = (0.0, 'g/L')

        # Initial values of state variables
        self.concentrationsRCH4.S_ac_0 = (0.0, 'gCOD/L')
        self.concentrationsRCH4.X_ac_0 = (0.76, 'g/L')

        ############# Solver settings ###############
        self.solverSettings.tFinal = (50.0, 'day')
        self.solverSettings.tPrint = (0.1, 'day')
        self.solverSettings.absTol = (1e-12, 'day')
        self.solverSettings.relTol = (1e-10, 'day')

    def computeAsync(self):
        # Simulate RH2 and RCH4 Bioreactors
        bioreactor = DM.ADM1H2CH4Bioreactors(self, self.parametersRH2,
                                             self.concentrationsRH2,
                                             self.parametersRCH4,
                                             self.concentrationsRCH4)

        bioreactor.prepareSimulation(self.solverSettings)
        bioreactor.run(self.solverSettings)

        # Show results
        self.storage = bioreactor.resultStorage.simulationName