Zero-Dimensional Reactor Networks#

Caution

The MATLAB toolbox is an experimental part of the Cantera API and may be changed without notice. It includes breaking changes from the legacy MATLAB API. While almost all features of the legacy MATLAB API are implemented, the toolbox does not include all functionality available for the C++ and Python interfaces.

Defining Functions#

class ct.Func1(typ, varargin)#

Bases: handle

Func1 Class

>> x = ct.Func1(typ, coeff)

A functor is an object that behaves like a function. Cantera defines a set of functors to use to create arbitrary functions to specify things like heat fluxes, piston speeds, etc., in reactor network simulations. Of course, they can be used for other things too.

The main feature of a functor class is that it overloads the () operator to evaluate the function. For example, suppose object f is a functor that evaluates the polynomial \(2x^2 - 3x + 1\). Then writing f(2) would cause the method that evaluates the function to be invoked, and would pass it the argument 2. The return value would of course be 3.

The types of functors you can create in Cantera are these:

  • Basic functors: 'sin', 'cos', 'exp', 'log', 'pow', 'constant'. Use no or scalar parameters, for example:

    >> x = ct.Func1('cos')
    >> x = ct.Func1('sin', 2)
    
  • Advanced functors: 'polynomial3', 'Fourier', 'Gaussian', 'Arrhenius'. Use vector parameter, for example:

    >> x = ct.Func1('polynomial3', [1 2 3])  % x^2 + 2x + 3
    
  • Tabulation functors: 'tabulated-linear', 'tabulated-previous'. Use pair of vector parameters, for example:

    >> x = ct.Func1('tabulated-linear', [0 2 4], [1 3 5])
    
  • Compounding functors: 'sum', 'diff', 'product', 'ratio', 'composite'. Use two functor parameters or a corresponding operator, for example:

    >> x = ct.Func1('sum', ct.Func1('sin', 2.), ct.Func1('cos', 3.))
    >> x = ct.Func1('sin', 2.) + ct.Func1('cos', 3.)  % alternative
    
  • Modifying functors: 'times-constant', 'plus-constant', 'periodic'. Use one functor and one scalar, for example:

    >> x = ct.Func1('times-constant', ct.Func1('sin', 2.), 2.)
    

Note: this MATLAB class shadows underlying C++ Cantera classes derived from “Func1”. See the Cantera C++ documentation for more details.

Parameters:
  • typ – String indicating type of functor to create.

  • varargin – Parameters required for the functor; values depend on definition.

Returns:

Instance of class ct.Func1.

Property Summary
id#
type#
Method Summary
delete()#

Delete the ct.Func1 object.

display()#

Display the equation of the input function on the terminal.

minus(f2)#
mrdivide(f2)#
mtimes(f2)#
plus(f2)#
subsref(s)#

Implement subscripted reference behavior for functors.

>> b = f(x)

MATLAB calls this method automatically to resolve a subscripted expression on a functor. Its purpose is to make a functor callable like a function, so that f(x) evaluates it. Users normally reach it this way rather than calling subsref directly. All other reference forms, such as reading a property with f.type, behave as they do for any object.

Parameters:
  • f – Instance of class ct.Func1.

  • s – Subscript-reference struct array that MATLAB passes to subsref (see the built-in subsref documentation). For a function call, s(1).type is '()' and s(1).subs holds the point(s) at which to evaluate the function.

Returns:

For a () reference, a vector holding the function evaluated at each requested point. For any other reference, whatever the default subsref returns.

write()#

Get the formatted string to display the function.

>> s = f.write
Parameters:

f – Instance of class ct.Func1.

Returns:

LaTeX-formatted string displaying the function.

Reactor Networks#

class ct.zeroD.ReactorNet(reactors)#

Bases: handle

ReactorNet class

>> r = ct.zeroD.ReactorNet(reactors)

A ct.zeroD.ReactorNet object is a container that holds one or more ct.zeroD.ReactorBase objects in a network. ct.zeroD.ReactorNet objects are used to simultaneously advance the state of one or more coupled reactors.

Parameters:

reactors – An instance of or a cell array of instances of class ct.zeroD.ReactorBase.

Property Summary
atol#

Absolute error tolerance.

id#
maxTimeStep#

Max time step [s].

The integrator chooses a step size based on the desired error tolerance and the rate at which the solution is changing. In some cases, the solution changes very slowly at first, then very rapidly (ignition problems). In such cases, the integrator may choose a timestep that is too large, which leads to numerical problems later. Use this method to set an upper bound on the timestep.

nVars#

Number of state variables (equations) in the network, that is, the length of its global state vector. Equal to the sum of the ct.zeroD.ReactorBase.nVars of the reactors it contains.

reactors#

Cell array of the ct.zeroD.ReactorBase objects that make up the network, in the order in which they were installed.

rtol#

Relative error tolerance.

time#

Current time [s]. The setter method sets the time at which integration should be restarted, using the current state as the initial condition.

Method Summary
advance(tout)#

Advance the state of the reactor network in time.

>> n.advance(tout)

Method advance integrates the system of ODEs that determine the rate of change of the volume, the mass of each species, and the total energy for each reactor. The integration is carried out from the current time to “tout”. (Note: “tout” is an absolute time, not a time interval.) The integrator may take many internal timesteps before reaching tout.

Parameters:

tout – End time [s] of the integration.

componentName(i)#

Name of a component of the global state vector of the network, given its index.

>> s = n.componentName(i)
Parameters:

i – Integer, 1-based index of the component within the global state vector of the network.

Returns:

Character array naming the component, prefixed with the name of the reactor it belongs to, for example 'reactor1: temperature'. The unprefixed name is what ct.zeroD.ReactorNet.globalComponentIndex() and ct.zeroD.ReactorNet.sensitivity() accept.

delete()#

Delete the ct.zeroD.ReactorNet object object.

globalComponentIndex(component, r)#

Index of a component of the global state vector of the network, given the name of the component and the reactor it belongs to.

>> i = n.globalComponentIndex(component)
>> i = n.globalComponentIndex(component, r)

This is the inverse of ct.zeroD.ReactorNet.componentName(), except that the name given here is not prefixed with the name of the reactor.

Parameters:
  • component – Name of the component within the reactor r, given as a character array or a string, for example 'temperature' or a species name.

  • r – The reactor in which component is to be found, given either as an instance of ct.zeroD.ReactorBase belonging to this network or as its 1-based position within the network. Defaults to the first reactor in the network.

Returns:

Integer, 1-based index of the component within the global state vector of the network.

sensitivity(component, p, r)#

Sensitivity of a solution variable with respect to a sensitivity parameter.

>> s = n.sensitivity(component, p)
>> s = n.sensitivity(component, p, r)
Parameters:
  • component – Name of the solution variable, given as a character array or a string, for example 'temperature' or a species name. It is resolved within the reactor r. Alternatively, an integer giving the 1-based index of the variable in the global state vector of the network, in which case r is not used.

  • p – Integer, 1-based index of the sensitivity parameter.

  • r – The reactor in which component is to be found, given either as an instance of ct.zeroD.ReactorBase belonging to this network or as its 1-based position within the network. Defaults to the first reactor in the network.

Returns:

Scalar normalized sensitivity coefficient.

setSensitivityTolerances(rerr, aerr)#

Set the error tolerance for sensitivity analysis.

>> n.setSensitivityTOlerances(nerr, aerr)
Parameters:
  • rerr – Scalar relative error tolerance.

  • aerr – Scalar absolute error tolerance.

step()#

Take a single internal step.

>> n.step()

The time/distance after taking the step is returned.

Reactors#

ReactorBase#

class ct.zeroD.ReactorBase(id)#

Bases: handle

ReactorBase Class.

Base class for objects representing reactors. The constructor is called by derived classes and cannot be used directly.

ReactorBase Class

Parameters:

id – ID of reactor object instantiated by specialization.

Property Summary
D#

Density [kg/m³] of the reactor contents at the end of the last call to “advance” or “step”.

H#

Mass specific enthalpy [J/kg] of the reactor contents at the end of the last call to “advance” or “step”.

M#

Mass [kg] of the reactor contents at the end of the last call to “advance” or “step”.

P#

Pressure [Pa] of the reactor contents at the end of the last call to “advance” or “step”.

T#

Temperature [K] of the reactor contents at the end of the last call to “advance” or “step”.

U#

Mass specific internal energy [J/kg] of the reactor contents at the end of the last call to “advance” or “step”.

V#

Volume [m³] of the reactor contents at the end of the last call to “advance” or “step”.

Y#

Mass fractions of the reactor contents at the end of the last call to “advance” or “step”.

area#

Area of the reactor [m²].

chemistryEnabled#

Boolean to enable or disable changing reactor composition by reactions.

If the chemistry is disabled, no reactions take place. Note that the composition can still change due to mass transfer at inlets and outlets.

energyEnabled#

Boolean to enable or disable solving the energy equation.

If the energy equation is disabled, then the reactor temperature is constant.

id#

ID of reactor.

nVars#

Number of state variables (equations) for this reactor, that is, the length of its state vector.

For a ct.zeroD.Reactor or ct.zeroD.IdealGasReactor, this is the number of species plus three (mass, volume, and internal energy or temperature). For a ct.zeroD.ConstPressureReactor or ct.zeroD.IdealGasConstPressureReactor, it is the number of species plus two (mass, and enthalpy or temperature). Reactor types that have no state vector of their own, such as ct.zeroD.Reservoir, report zero.

name#

Name of reactor.

phase#

The Solution object used to represent the contents of this reactor. If the clone parameter of the reactor constructor is true, a new instance of ct.Solution will be created for this reactor. Otherwise, the same instance as passed to the constructor will be used.

type#

reactor type.

Method Summary
addSensitivityReaction(m)#

Specifies that the sensitivity of the state variables with respect to reaction m should be computed. The reactor must be part of a network first.

>> r.addSensitivityReaction(m)
Parameters:

m – Integer, 1-based index of the reaction within the reactor’s Kinetics object.

componentIndex(name)#

Index of a state-vector component of this reactor, given its name.

>> n = r.componentIndex(name)
Parameters:

name – String name of the component, without the reactor-name prefix that ct.zeroD.ReactorNet.componentName() adds. Which names are accepted depends on the reactor type; a species name always is, as are 'mass' and 'volume' for a ct.zeroD.Reactor and its descendants. Reactor types that have no state vector of their own, such as ct.zeroD.Reservoir, raise an error.

Returns:

Integer, 1-based index of the component within the state vector of this reactor. Use ct.zeroD.ReactorNet.globalComponentIndex() to get the corresponding index within the state vector of a network.

componentName(k)#

Name of a state-vector component of this reactor, given its index.

>> s = r.componentName(k)
Parameters:

k – Integer, 1-based index of the component within the state vector of this reactor.

Returns:

Character array naming the component, for example 'int_energy' for a ct.zeroD.Reactor or 'temperature' for a ct.zeroD.IdealGasReactor. The name is not prefixed with the name of the reactor; compare ct.zeroD.ReactorNet.componentName().

delete()#

Delete the ct.zeroD.ReactorBase object.

massFraction(species)#

Get the mass fraction of a species.

Parameters:

species – String/Char array name of the species.

Reservoir#

class ct.zeroD.Reservoir(phase[, name][, clone=true])#

Bases: ct.zeroD.ReactorBase

Create a ct.zeroD.Reservoir object.

>> r = ct.zeroD.Reservoir(phase, name, clone)

A ct.zeroD.Reservoir is an instance of class ct.zeroD.ReactorBase configured so that its intensive state is constant in time. A reservoir may be thought of as infinite in extent, perfectly mixed, and non-reacting, so that fluid may be extracted or added without changing the composition or thermodynamic state. Note that even if the reaction mechanism associated with the fluid in the reactor defines reactions, they are disabled within reservoirs. Examples:

r2 = ct.zeroD.Reservoir(gas)    % a reservoir containing a gas

See also: ct.zeroD.ReactorBase

Parameters:
  • phase – Cantera ct.Solution to be set as the contents of the reactor.

  • name – Reservoir name (optional; default is (none)).

  • clone – Determines whether to clone phase so that the internal state of this reactor is independent of the original Solution object and any Solution objects used by other reactors in the network. (optional; default is true).

Reactor#

class ct.zeroD.Reactor(phase[, name][, clone=true])#

Bases: ct.zeroD.ReactorBase

Reactor Class

>> r = ct.zeroD.Reactor(phase, name, clone)

A ct.zeroD.Reactor object simulates a perfectly-stirred reactor. It has a time-dependent state, and may be coupled to other reactors through flow lines or through walls that may expand or contract and/or conduct heat.

Parameters:
  • phase – Instance of ct.Solution representing the contents of the reactor.

  • name – Reactor name (optional; default is (none)).

  • clone – Determines whether to clone phase so that the internal state of this reactor is independent of the original Solution object and any Solution objects used by other reactors in the network. (optional; default is true).

IdealGasReactor#

class ct.zeroD.IdealGasReactor(phase[, name][, clone=true])#

Bases: ct.zeroD.ReactorBase

Create a reactor with an ideal gas.

>> r = ct.zeroD.IdealGasReactor(phase, name, clone)

An ct.zeroD.IdealGasReactor is an instance of ct.zeroD.ReactorBase where the governing equations are specialized for the ideal gas equation of state (and do not work correctly with other thermodynamic models). Examples:

r2 = ct.zeroD.IdealGasReactor(gas)    % a reactor containing a gas

See also: ct.zeroD.ReactorBase

Parameters:
  • phase – Cantera ct.Solution to be set as the contents of the reactor.

  • name – Reactor name (optional; default is (none)).

  • clone – Determines whether to clone phase so that the internal state of this reactor is independent of the original Solution object and any Solution objects used by other reactors in the network. (optional; default is true).

ConstPressureReactor#

class ct.zeroD.ConstPressureReactor(phase[, name][, clone=true])#

Bases: ct.zeroD.ReactorBase

Create a constant pressure reactor object.

>> r = ct.zeroD.ConstPressureReactor(phase, name, clone)

A ct.zeroD.ConstPressureReactor is an instance of class ct.zeroD.ReactorBase where the pressure is held constant. The volume is not a state variable, but instead takes on whatever value is consistent with holding the pressure constant. Examples:

r2 = ct.zeroD.ConstPressureReactor(phase)    % a reactor containing contents

See also: ct.zeroD.ReactorBase

Parameters:
  • phase – Cantera ct.Solution to be set as the contents of the reactor.

  • name – Reactor name (optional; default is (none)).

  • clone – Determines whether to clone phase so that the internal state of this reactor is independent of the original Solution object and any Solution objects used by other reactors in the network. (optional; default is true).

IdealGasConstPressureReactor#

class ct.zeroD.IdealGasConstPressureReactor(phase[, name][, clone=true])#

Bases: ct.zeroD.ReactorBase

Create a constant pressure reactor with an ideal gas.

>> r = ct.zeroD.IdealGasConstPressureReactor(phase, name, clone)

An ct.zeroD.IdealGasConstPressureReactor is an instance of ct.zeroD.ReactorBase where the pressure is held constant. The volume is not a state variable, but instead takes on whatever value is consistent with holding the pressure constant. Additionally, its governing equations are specialized for the ideal gas equation of state (and do not work correctly with other thermodynamic models). Examples:

r2 = ct.zeroD.IdealGasConstPressureReactor(gas) % a reactor containing a gas

See also: ct.zeroD.ReactorBase

Parameters:
  • phase – Cantera ct.Solution to be set as the contents of the reactor.

  • name – Reactor name (optional; default is (none)).

  • clone – Determines whether to clone phase so that the internal state of this reactor is independent of the original Solution object and any Solution objects used by other reactors in the network. (optional; default is true).

FlowReactor#

class ct.zeroD.FlowReactor(phase[, name][, clone=true])#

Bases: ct.zeroD.ReactorBase

Create a flow reactor object.

>> r = ct.zeroD.FlowReactor(phase, name, clone)

A reactor representing adiabatic plug flow in a constant-area duct. Examples:

r2 = ct.zeroD.FlowReactor(gas)    % a reactor containing a gas

See also: ct.zeroD.ReactorBase

Parameters:
  • phase – Cantera ct.Solution to be set as the contents of the reactor.

  • name – Reactor name (optional; default is (none)).

  • clone – Determines whether to clone phase so that the internal state of this reactor is independent of the original Solution object and any Solution objects used by other reactors in the network. (optional; default is true).

Property Summary
massFlowRate#

Mass flow rate through the reactor [kg/s].

Setting the mass flow rate sets the flow speed based on the current density of the reactor contents and the reactor area. The value read back is computed from the flow speed, density and area at the end of the last call to “advance” or “step”.

Surfaces#

ReactorSurface#

class ct.zeroD.ReactorSurface(surf, reactors[, name][, clone=true])#

Bases: ct.zeroD.ReactorBase

ReactorSurface Class

>> s = ct.zeroD.ReactorSurface(surf, reactor, name, clone)

A surface on which heterogeneous reactions take place. The mechanism object (typically an instance of ct.Interface) must be constructed so that it is properly linked to the object representing the fluid in the reactor. The surface temperature on each side is taken to be equal to the temperature of the reactor.

Parameters:
  • surf – Surface reaction mechanisms for the left-facing surface. This must bean instance of class ct.Kinetics, or of a class derived from Kinetics, such as ct.Interface.

  • reactors – An instance of or a cell array of instances of class ct.zeroD.ReactorBase.

  • name – Reactor surface name (optional; default is (none)).

  • clone – Determines whether to clone surf so that the internal state of this reactor is independent of the original Solution object and any Solution objects used by other reactors in the network. (optional; default is true).

Connectors#

Connector#

class ct.zeroD.Connector(typ, r1, r2[, name])#

Bases: handle

Connector Class.

Base class for walls and flow devices. The constructor is called by derived classes and cannot be used directly.

See also: ct.zeroD.FlowDevice, ct.zeroD.Wall

Parameters:
  • typ – Type of connector.

  • r1 – Reactor one.

  • r2 – Reactor two.

  • name – Connector name (optional; default is (none)).

Property Summary
id#

ID of Connector object.

name#

Name of connector.

type#

Name of connector.

Method Summary
delete()#

Delete the ct.zeroD.Connector object.

Wall#

class ct.zeroD.Wall(l, r[, name])#

Bases: ct.zeroD.Connector

Wall Class

>> x = ct.zeroD.Wall(l, r, name)

A Wall separates two reactors, or a reactor and a reservoir. A Wall has a finite area, may conduct heat between the two reactors on either side, and may move like a piston.

Walls are stateless objects in Cantera, meaning that no differential equation is integrated to determine any wall property. Since it is the wall (piston) velocity that enters the energy equation, this means that it is the velocity, not the acceleration or displacement, that is specified. The wall velocity is computed from:

\[v = K(P_{left} - P_{right}) + v_0(t),\]

where K is a non-negative constant, and \(v_0\) is a specified function of time. The velocity is positive if the wall is moving to the right.

The heat flux through the wall is computed from:

\[q = U(T_{left} - T_{right}) + q_0(t),\]

where U is the overall heat transfer coefficient for conduction/convection, and \(q_0\) is a specified function of time. The heat flux is positive when heat flows from the reactor on the left to the reactor on the right.

Note: the Wall class constructor only assign default values to various properties. The user could specify those properties after initial construction by using the various methods of the Wall class.

Parameters:
  • l – Instance of class ct.zeroD.ReactorBase to be used as the bulk phase on the left side of the wall.

  • r – Instance of class ct.zeroD.ReactorBase to be used as the bulk phase on the right side of the wall.

  • name – Wall name (optional; default is (none)).

Property Summary
area#

Area of the wall [m²].

emissivity#

Emissivity [-].

expansionRate#

Rate of volumetric change [m³/s] at the current time.

expansionRateCoeff#

Expansion rate coefficient [m/s/Pa].

heatFlux#

Heat flux [W/m²].

Must be set by an instance of ct.Func1, which allows the heat flux to be an arbitrary function of time. It is possible to specify a constant heat flux by using the polynomial functor with only the first term specified.

heatRate#

Total heat transfer rate [W] through the wall at the current time.

heatTransferCoeff#

Heat transfer coefficient [W/m²/K].

left#

Reactor on the left.

right#

Reactor on the right.

thermalResistance#

Thermal resistance [K·m²/W].

velocity#

Velocity [m/s].

Must be set by an instance of ct.Func1, which allows the velocity to be an arbitrary function of time. It is possible to specify a constant velocity by using the polynomial functor with only the first term specified.

FlowDevice#

class ct.zeroD.FlowDevice(typ, upstream, downstream[, name])#

Bases: ct.zeroD.Connector

FlowDevice Class.

Base class for devices that allow flow between reactors. The constructor is called by derived classes and cannot be used directly.

ct.zeroD.FlowDevice objects are assumed to be adiabatic, non-reactive, and have negligible internal volume, so that they are internally always in steady-state even if the upstream and downstream reactors are not. The fluid enthalpy, chemical composition, and mass flow rate are constant across a ct.zeroD.FlowDevice, and the pressure difference equals the difference in pressure between the upstream and downstream reactors.

See also: ct.zeroD.MassFlowController, ct.zeroD.PressureController, ct.zeroD.Valve

Parameters:
Property Summary
deviceCoefficient#

The coefficient defining the behavior of this ct.zeroD.FlowDevice, with a meaning that depends on the type of the device: the mass flow rate [kg/s] for a ct.zeroD.MassFlowController, the valve coefficient [kg/s/Pa] for a ct.zeroD.Valve, and the pressure coefficient [kg/s/Pa] for a ct.zeroD.PressureController.

downstream#

Downstream object of type ct.zeroD.ReactorBase.

massFlowRate#

The mass flow rate through the ct.zeroD.FlowDevice at the current time.

The setter method can either take a double value or a function represented by an instance of ct.Func1.

upstream#

Upstream object of type ct.zeroD.ReactorBase.

valveCoeff#

Valve coefficient in kg/s/Pa.

The mass flow rate [kg/s] is computed from the expression:

\[\dot{m} = K(P_{upstream} - P_{downstream})\]

as long as this produces a positive value. If this expression is negative, zero is returned.

Method Summary
setPrimary(d)#

Set the primary flow device used to compute this device’s mass flow rate.

>> f.setPrimary(d)
Parameters:

d – Instance of class ct.zeroD.FlowDevice.

MassFlowController#

class ct.zeroD.MassFlowController(upstream, downstream[, name])#

Bases: ct.zeroD.FlowDevice

Create a mass flow controller.

>> m = ct.zeroD.MassFlowController(upstream, downstream, name)

Creates an instance of class ct.zeroD.FlowDevice configured to simulate a mass flow controller that maintains a constant mass flow rate independent of upstream or downstream conditions.

see also: ct.zeroD.FlowDevice, ct.zeroD.Valve

Parameters:

PressureController#

class ct.zeroD.PressureController(upstream, downstream[, name])#

Bases: ct.zeroD.FlowDevice

Create a pressure controller.

>> p = ct.zeroD.PressureController(upstream, downstream, name)

Creates an instance of class ct.zeroD.FlowDevice configured to simulate a pressure controller. A ct.zeroD.PressureController is designed to be used in conjunction with another primary flow device, typically a ct.zeroD.MassFlowController. The primary flow device is installed on the inlet of the reactor, and the corresponding ct.zeroD.PressureController is installed on the outlet of the reactor. The mass flow rate through the ct.zeroD.PressureController is equal to the mass flow rate of the primary device, plus a correction that depends on the pressure difference:

\[\dot{m} = \dot{m}_{primary} + K_v(P_{upstream} - P_{downstream})\]

as long as this produces a positive value. If this expression is negative, zero is returned. The primary device is set using ct.zeroD.FlowDevice.setPrimary() and must be set before the mass flow rate can be evaluated.

see also: ct.zeroD.FlowDevice, ct.zeroD.MassFlowController, ct.zeroD.Valve

Parameters:
Property Summary
pressureCoeff#

Proportionality constant \(K_v\) in kg/s/Pa between the pressure drop and the mass flow rate correction added to the primary device’s mass flow rate.

Valve#

class ct.zeroD.Valve(upstream, downstream[, name])#

Bases: ct.zeroD.FlowDevice

Create a valve.

>> v = ct.zeroD.Valve(upstream, downstream, name)

Create an instance of class ct.zeroD.FlowDevice configured to simulate a valve that produces a flow rate proportional to the pressure difference between the upstream and downstream reactors.

The mass flow rate [kg/s] is computed from the expression

\[\dot{m} = K(P_{upstream} - P_{downstream})\]

as long as this produces a positive value. If this expression is negative, zero is returned. Therefore, the ct.zeroD.Valve object acts as a check valve - flow is always from the upstream reactor to the downstream one. Note: as currently implemented, the Valve object does not model real valve characteristics - in particular, it does not model choked flow. The mass flow rate is always assumed to be linearly proportional to the pressure difference, no matter how large the pressure difference. THIS MAY CHANGE IN A FUTURE RELEASE.

see also: ct.zeroD.FlowDevice, ct.zeroD.MassFlowController

Parameters: