FCSys.Phases

Mixtures of species

Information

The graphite, ionomer, and liquid phases can only be used with a compressible phase (gas).

Extends from Modelica.Icons.Package (Icon for standard packages).

Package Content

NameDescription
FCSys.Phases.Gas Gas Gas phase
FCSys.Phases.Graphite Graphite Graphite phase
FCSys.Phases.Ionomer Ionomer Ionomer phase
FCSys.Phases.Liquid Liquid Liquid phase
PartialPhase Base model for a phase
FCSys.Phases.ExchangeParams ExchangeParams Independence factors for an exchange process

FCSys.Phases.Gas FCSys.Phases.Gas

Gas phase FCSys.Phases.Gas

Information

It is usually appropriate to assume that species exist at the same temperature within a phase. The time constants for thermal exchange (τQE) are usually much shorter than the time span of interest due to the very small coupling resistances. If this is the case, set common.k_Q to zero. This will reduce the index of the problem, so it may be necessary to eliminate some initial conditions.

In bulk flow, it is usually appropriate to assume that species travel with the same velocity within a phase. If this is the case, set the entries of common.k_Phi to zero. This will reduce the index of the problem, so it may be necessary to eliminate some initial conditions.

Please see the documentation of the PartialPhase model.

Extends from Icons.Phases.Gas (Icon for a gas phase), PartialPhase (Base model for a phase).

Parameters

TypeNameDefaultDescription
Integern_speccountTrue({inclH2,inclH2O,in…Number of species
Integern_trans1Number of transport axes
Geometry
NumberAbsolutek[Axis]{1,1,1}Length factors for transport [1]
Independence factors
NumberAbsolutek_inter_Phi[n_inter, n_trans]ones(n_inter, n_trans)For translational exchange with other phases [1]
NumberAbsolutek_inter_Q[n_inter]ones(n_inter)For thermal exchange with other phases [1]
ExchangeParamscommon Among species in the phase
Species
BooleaninclH2falseInclude H2
FixedH2redeclare FCSys.Species.H2.G…H2 model
BooleaninclH2OfalseInclude H2O
FixedH2Oredeclare FCSys.Species.H2O….H2O model
BooleaninclN2falseInclude N2
FixedN2redeclare FCSys.Species.N2.G…N2 model
BooleaninclO2falseInclude O2
FixedO2redeclare FCSys.Species.O2.G…O2 model

Connectors

TypeNameDescription
BoundaryBusxNegativeNegative boundary along the x axis
BoundaryBusyNegativeNegative boundary along the y axis
BoundaryBuszNegativeNegative boundary along the z axis
BoundaryBusxPositivePositive boundary along the x axis
BoundaryBusyPositivePositive boundary along the y axis
BoundaryBuszPositivePositive boundary along the z axis
AmagatamagatConnector for additivity of volume
Interinter[n_inter]Connector to exchange momentum and energy with other phases
ChemicalchemH2[1]Chemical connector for H2
ChemicalchemH2O[3]Chemical connector for H2O
ChemicalchemO2[1]Chemical connector for O2

Modelica definition

model Gas "Gas phase"
  import Modelica.Math.BooleanVectors.countTrue;

  extends Icons.Phases.Gas;
  extends PartialPhase(final n_spec=countTrue({inclH2,inclH2O,inclN2,inclO2}));

  // Conditionally include species.
  parameter Boolean inclH2=false "Include H2";
  replaceable FCSys.Species.H2.Gas.Fixed H2(
    final n_trans,
    final n_inter,
    final kL,
    final n_chem,
    final k_intra_Phi,
    final k_intra_Q) if inclH2 constrainedby FCSys.Species.Fluid(
    n_trans=n_trans,
    n_intra=1,
    n_inter=n_inter,
    kL=kL,
    k_intra_Phi={common.k_Phi[cartTrans]},
    k_intra_Q={common.k_Q}) "H2 model";

  parameter Boolean inclH2O=false "Include H2O";

  replaceable FCSys.Species.H2O.Gas.Fixed H2O(
    final n_trans,
    final n_inter,
    final kL,
    final n_chem,
    final k_intra_Phi,
    final k_intra_Q) if inclH2O constrainedby FCSys.Species.Fluid(
    n_trans=n_trans,
    n_intra=1,
    n_inter=n_inter,
    kL=kL,
    k_intra_Phi={common.k_Phi[cartTrans]},
    k_intra_Q={common.k_Q}) "H2O model";

  parameter Boolean inclN2=false "Include N2";

  replaceable FCSys.Species.N2.Gas.Fixed N2(
    final n_trans,
    final n_inter,
    final kL,
    final n_chem,
    final k_intra_Phi,
    final k_intra_Q) if inclN2 constrainedby FCSys.Species.Fluid(
    n_trans=n_trans,
    n_intra=1,
    n_inter=n_inter,
    kL=kL,
    k_intra_Phi={common.k_Phi[cartTrans]},
    k_intra_Q={common.k_Q}) "N2 model";

  parameter Boolean inclO2=false "Include O2";

  replaceable FCSys.Species.O2.Gas.Fixed O2(
    final n_trans,
    final n_inter,
    final kL,
    final n_chem,
    final k_intra_Phi,
    final k_intra_Q) if inclO2 constrainedby FCSys.Species.Fluid(
    n_trans=n_trans,
    n_intra=1,
    n_inter=n_inter,
    kL=kL,
    k_intra_Phi={common.k_Phi[cartTrans]},
    k_intra_Q={common.k_Q}) "O2 model";

  // Independence factors
  ExchangeParams common(k_Phi={2,2,2}, k_Q=0) if n_spec > 0 
    "Among species in the phase";

  Connectors.BoundaryBus xNegative if inclTrans[Axis.x] 
    "Negative boundary along the x axis";
  Connectors.BoundaryBus yNegative if inclTrans[Axis.y] 
    "Negative boundary along the y axis";
  Connectors.BoundaryBus zNegative if inclTrans[Axis.z] 
    "Negative boundary along the z axis";
  Connectors.BoundaryBus xPositive if inclTrans[Axis.x] 
    "Positive boundary along the x axis";
  Connectors.BoundaryBus yPositive if inclTrans[Axis.y] 
    "Positive boundary along the y axis";
  Connectors.BoundaryBus zPositive if inclTrans[Axis.z] 
    "Positive boundary along the z axis";
  Connectors.Amagat amagat(final V=-V) if n_spec > 0 
    "Connector for additivity of volume";
  Connectors.Inter inter[n_inter](each final n_trans=n_trans) if n_spec > 0 
    "Connector to exchange momentum and energy with other phases";

  // Auxiliary variables (for analysis)
  output Q.PressureAbsolute p(stateSelect=StateSelect.never) = amagat.p if 
    n_spec > 0 and environment.analysis "Total thermodynamic pressure";

  Connectors.Chemical chemH2[1](each final n_trans=n_trans) if inclH2 
    "Chemical connector for H2";
  Connectors.Chemical chemH2O[3](each final n_trans=n_trans) if inclH2O 
    "Chemical connector for H2O";
  Connectors.Chemical chemO2[1](each final n_trans=n_trans) if inclO2 
    "Chemical connector for O2";

protected 
  Conditions.Adapters.AmagatDalton amagatDalton if n_spec > 0 
    "Adapter between additivity of volume and additivity of pressure";
  Connectors.InertNode commonExch 
    "Connector for exchange among species in the phase";

equation 
  // Chemical exchange
  connect(O2.chemical, chemO2);
  connect(H2.chemical, chemH2);
  connect(H2O.chemical, chemH2O);

  // Inert exchange
  connect(H2.inter, inter);
  connect(H2O.inter, inter);
  connect(N2.inter, inter);
  connect(O2.inter, inter);
  connect(H2.intra[1], commonExch.node);
  connect(H2O.intra[1], commonExch.node);
  connect(N2.intra[1], commonExch.node);
  connect(O2.intra[1], commonExch.node);

  // Mixing
  connect(H2.dalton, amagatDalton.dalton);
  connect(H2O.dalton, amagatDalton.dalton);
  connect(N2.dalton, amagatDalton.dalton);
  connect(O2.dalton, amagatDalton.dalton);
  connect(amagatDalton.amagat, amagat);

  // Transport
  // ---------
  // H2
  connect(H2.boundaries[transCart[Axis.x], Side.n], xNegative.H2);

  connect(H2.boundaries[transCart[Axis.x], Side.p], xPositive.H2);

  connect(H2.boundaries[transCart[Axis.y], Side.n], yNegative.H2);

  connect(H2.boundaries[transCart[Axis.y], Side.p], yPositive.H2);

  connect(H2.boundaries[transCart[Axis.z], Side.n], zNegative.H2);
  connect(H2.boundaries[transCart[Axis.z], Side.p], zPositive.H2);
  // H2O
  connect(H2O.boundaries[transCart[Axis.x], Side.n], xNegative.H2O);

  connect(H2O.boundaries[transCart[Axis.x], Side.p], xPositive.H2O);

  connect(H2O.boundaries[transCart[Axis.y], Side.n], yNegative.H2O);

  connect(H2O.boundaries[transCart[Axis.y], Side.p], yPositive.H2O);

  connect(H2O.boundaries[transCart[Axis.z], Side.n], zNegative.H2O);
  connect(H2O.boundaries[transCart[Axis.z], Side.p], zPositive.H2O);
  // N2
  connect(N2.boundaries[transCart[Axis.x], Side.n], xNegative.N2);

  connect(N2.boundaries[transCart[Axis.x], Side.p], xPositive.N2);

  connect(N2.boundaries[transCart[Axis.y], Side.n], yNegative.N2);

  connect(N2.boundaries[transCart[Axis.y], Side.p], yPositive.N2);
  connect(N2.boundaries[transCart[Axis.z], Side.n], zNegative.N2);
  connect(N2.boundaries[transCart[Axis.z], Side.p], zPositive.N2);
  // O2
  connect(O2.boundaries[transCart[Axis.x], Side.n], xNegative.O2);
  connect(O2.boundaries[transCart[Axis.x], Side.p], xPositive.O2);
  connect(O2.boundaries[transCart[Axis.y], Side.n], yNegative.O2);
  connect(O2.boundaries[transCart[Axis.y], Side.p], yPositive.O2);
  connect(O2.boundaries[transCart[Axis.z], Side.n], zNegative.O2);
  connect(O2.boundaries[transCart[Axis.z], Side.p], zPositive.O2);
end Gas;

FCSys.Phases.Graphite FCSys.Phases.Graphite

Graphite phase FCSys.Phases.Graphite

Information

From a physical standpoint, the electrolytic double layer is probably best considered its own phase, but it is modeled as a part of the graphite phase in order to reduce the number of connections. It is assumed to store no material, translational momentum, or thermal energy. It only stores electrical energy due to a charge difference.

C+ and e- are assumed to have the same temperature. C+ should be used to initialize the temperature.

See Species.'e-'.Graphite.Fixed for assumptions. For more information, please see the PartialPhase model.

Extends from Icons.Phases.Solid (Icon for a solid phase), PartialPhase (Base model for a phase).

Parameters

TypeNameDefaultDescription
Integern_speccountTrue({'inclC+','incle-'})Number of species
Integern_trans1Number of transport axes
Geometry
NumberAbsolutek[Axis]{1,1,1}Length factors for transport [1]
Independence factors
NumberAbsolutek_inter_Phi[n_inter, n_trans]ones(n_inter, n_trans)For translational exchange with other phases [1]
NumberAbsolutek_inter_Q[n_inter]ones(n_inter)For thermal exchange with other phases [1]
Species
Boolean'inclC+'falseInclude C+
Fixed'C+'redeclare FCSys.Species.'C+'…C+ model
Boolean'incle-'falseInclude e-
Fixed'e-'redeclare FCSys.Species.'e-'…e- model
Assumptions
Boolean'incle-Transfer'falseInclude electron transfer
BooleaninclDLfalseInclude the double-layer capacitance
Advanced
BooleaninclAmagattrueInclude the connector for additivity of volume

Connectors

TypeNameDescription
BoundaryBusxNegativeNegative boundary along the x axis
BoundaryBusyNegativeNegative boundary along the y axis
BoundaryBuszNegativeNegative boundary along the z axis
BoundaryBusxPositivePositive boundary along the x axis
BoundaryBusyPositivePositive boundary along the y axis
BoundaryBuszPositivePositive boundary along the z axis
Interinter[n_inter]Connector to exchange momentum and energy with other phases
AmagatamagatConnector for additivity of volume
Chemical'cheme-'[1]Chemical connector for e-

Modelica definition

model Graphite "Graphite phase"
  import assert = FCSys.Utilities.assertEval;
  import Modelica.Math.BooleanVectors.countTrue;

  extends Icons.Phases.Solid;
  extends PartialPhase(final n_spec=countTrue({'inclC+','incle-'}));

  // Conditionally include species.
  parameter Boolean 'inclC+'=false "Include C+";

  replaceable FCSys.Species.'C+'.Graphite.Fixed 'C+'(
    final n_trans,
    final n_inter,
    final kL) if 'inclC+' constrainedby FCSys.Species.Solid(
    n_trans=n_trans,
    n_intra=1,
    n_inter=n_inter,
    kL=kL,
    final k_intra_Phi={ones(n_trans)},
    final k_intra_Q={0}) "C+ model";

  parameter Boolean 'incle-'=false "Include e-";
  replaceable FCSys.Species.'e-'.Graphite.Fixed 'e-'(final n_trans, final 
      n_inter) if 'incle-' constrainedby FCSys.Species.Fluid(
    n_trans=n_trans,
    n_intra=1,
    n_inter=0,
    final k_intra_Phi={ones(n_trans)},
    final k_intra_Q={0}) "e- model";

  parameter Boolean 'incle-Transfer'=false "Include electron transfer";

  parameter Boolean inclDL=false "Include the double-layer capacitance";

  Chemistry.Electrochemistry.ElectronTransfer 'e-Transfer'(redeclare constant Integer
      n_trans=1) if 'incle-' and 'incle-Transfer' "Electron transfer";
  Chemistry.Electrochemistry.DoubleLayer doubleLayer(redeclare constant Integer
      n_trans=1) if 'incle-' and 'incle-Transfer' and inclDL 
    "Electrolytic double layer";
  // Note:  n_trans must be constant in Dymola 2014 to prevent errors such as
  // "Failed to expand the variable
  // subregion.graphite.'e-Transfer'.negative.phi".  The setting of n_trans=1
  // must be manually changed at instantiation if additional transport axes
  //  are enabled.

  // Advanced parameters
  parameter Boolean inclAmagat=true 
    "Include the connector for additivity of volume";

  Connectors.BoundaryBus xNegative if inclTrans[Axis.x] 
    "Negative boundary along the x axis";
  Connectors.BoundaryBus yNegative if inclTrans[Axis.y] 
    "Negative boundary along the y axis";
  Connectors.BoundaryBus zNegative if inclTrans[Axis.z] 
    "Negative boundary along the z axis";
  Connectors.BoundaryBus xPositive if inclTrans[Axis.x] 
    "Positive boundary along the x axis";
  Connectors.BoundaryBus yPositive if inclTrans[Axis.y] 
    "Positive boundary along the y axis";
  Connectors.BoundaryBus zPositive if inclTrans[Axis.z] 
    "Positive boundary along the z axis";
  Connectors.Inter inter[n_inter](each final n_trans=n_trans) if n_spec > 0 
    "Connector to exchange momentum and energy with other phases";

  Connectors.Amagat amagat if n_spec > 0 and inclAmagat 
    "Connector for additivity of volume";

  Connectors.Chemical 'cheme-'[1](each final n_trans=n_trans) if 'incle-' and 
    'incle-Transfer' "Chemical connector for e-";

protected 
  Conditions.Adapters.AmagatDalton amagatDalton if n_spec > 0 and inclAmagat 
    "Adapter between additivity of volume and additivity of pressure";
  Connectors.InertNode commonExch 
    "Connector for exchange among all species in the phase";
  Connectors.DaltonNode dalton(final V=V) if n_spec > 0 
    "Internal node for additivity of volume";

equation 
  // Chemical exchange
  connect('e-Transfer'.negative, doubleLayer.negative);
  connect('e-Transfer'.positive, doubleLayer.positive);
  connect('e-Transfer'.negative, 'e-'.chemical[1]);
  connect('e-Transfer'.positive, 'cheme-'[1]);

  // Inert exchange
  connect('C+'.inter, inter);
  connect('C+'.intra[1], commonExch.node);
  connect('e-'.intra[1], commonExch.node);
  connect('e-Transfer'.intra, 'C+'.intra[1]);
  connect(doubleLayer.intra, 'e-Transfer'.intra);

  // Mixing
  connect(amagatDalton.amagat, amagat);
  connect(dalton, 'C+'.dalton);
  connect(dalton, 'e-'.dalton);
  connect(doubleLayer.amagat, amagat);

  // Transport
  // ---------
  // C+
  connect('C+'.boundaries[transCart[Axis.x], Side.n], xNegative.'C+');
  connect('C+'.boundaries[transCart[Axis.x], Side.p], xPositive.'C+');

  connect('C+'.boundaries[transCart[Axis.y], Side.n], yNegative.'C+');

  connect('C+'.boundaries[transCart[Axis.y], Side.p], yPositive.'C+');

  connect('C+'.boundaries[transCart[Axis.z], Side.n], zNegative.'C+');
  connect('C+'.boundaries[transCart[Axis.z], Side.p], zPositive.'C+');

  // e-
  connect('e-'.boundaries[transCart[Axis.x], Side.n], xNegative.'e-');

  connect('e-'.boundaries[transCart[Axis.x], Side.p], xPositive.'e-');

  connect('e-'.boundaries[transCart[Axis.y], Side.n], yNegative.'e-');

  connect('e-'.boundaries[transCart[Axis.y], Side.p], yPositive.'e-');

  connect('e-'.boundaries[transCart[Axis.z], Side.n], zNegative.'e-');
  connect('e-'.boundaries[transCart[Axis.z], Side.p], zPositive.'e-');

  connect(dalton, amagatDalton.dalton);
end Graphite;

FCSys.Phases.Ionomer FCSys.Phases.Ionomer

Ionomer phase FCSys.Phases.Ionomer

Information

Assumptions:

  1. The water in the ionomer does not directly participate in the reaction (only the water vapor does).
  2. See Species.'H+'.Ionomer.Fixed for additional assumptions. For more information, please see the PartialPhase model.

    Extends from Icons.Phases.Solid (Icon for a solid phase), PartialPhase (Base model for a phase).

    Parameters

    TypeNameDefaultDescription
    Integern_speccountTrue({'inclSO3-','inclH…Number of species
    Integern_trans1Number of transport axes
    Geometry
    NumberAbsolutek[Axis]{1,1,1}Length factors for transport [1]
    Independence factors
    NumberAbsolutek_inter_Phi[n_inter, n_trans]ones(n_inter, n_trans)For translational exchange with other phases [1]
    NumberAbsolutek_inter_Q[n_inter]ones(n_inter)For thermal exchange with other phases [1]
    Species
    Boolean'inclSO3-'falseInclude C19HF37O5S- (abbreviated as SO3-)
    Fixed'SO3-'redeclare FCSys.Species.'SO3…SO3- model
    Boolean'inclH+'falseInclude H+
    Fixed'H+'redeclare FCSys.Species.'H+'…H+ model
    BooleaninclH2OfalseInclude H2O
    FixedH2Oredeclare FCSys.Species.H2O….H2O model
    Exchange (click to edit)
    ExchangeParamscommon Among all species in the phase
    ExchangeParamsprotonsSolid Between H+ and SO3-)
    ExchangeParamsprotonsWater Between H+ and H2O
    ExchangeParamswaterSolid Between H2O and SO3-
    Advanced
    BooleaninclAmagattrueInclude the connector for additivity of volume

    Connectors

    TypeNameDescription
    BoundaryBusxNegativeNegative boundary along the x axis
    BoundaryBusyNegativeNegative boundary along the y axis
    BoundaryBuszNegativeNegative boundary along the z axis
    BoundaryBusxPositivePositive boundary along the x axis
    BoundaryBusyPositivePositive boundary along the y axis
    BoundaryBuszPositivePositive boundary along the z axis
    AmagatamagatConnector for additivity of volume
    Interinter[n_inter]Connector to exchange momentum and energy with other phases
    ChemicalchemH2O[1]Chemical connector for H2O
    Chemical'chemH+'[1]Chemical connector for H+

    Modelica definition

    model Ionomer "Ionomer phase"
      import Modelica.Math.BooleanVectors.countTrue;
    
      extends Icons.Phases.Solid;
      extends PartialPhase(final n_spec=countTrue({'inclSO3-','inclH+',inclH2O}),
          n_inter=1);
    
      // Conditionally include species.
      parameter Boolean 'inclSO3-'=false 
        "Include C19HF37O5S- (abbreviated as SO3-)";
    
      replaceable FCSys.Species.'SO3-'.Ionomer.Fixed 'SO3-'(
        final n_trans,
        final n_inter,
        final kL,
        final k_intra_Phi,
        final k_intra_Q) if 'inclSO3-' constrainedby FCSys.Species.Solid(
        n_trans=n_trans,
        n_intra=3,
        n_inter=n_inter,
        kL=kL,
        k_intra_Phi={common.k_Phi[cartTrans],protonsSolid.k_Phi[cartTrans],
            waterSolid.k_Phi[cartTrans]},
        k_intra_Q={common.k_Q,protonsSolid.k_Q,waterSolid.k_Q}) "SO3- model";
    
      parameter Boolean 'inclH+'=false "Include H+";
    
      replaceable FCSys.Species.'H+'.Ionomer.Fixed 'H+'(
        final n_trans,
        final n_inter,
        final n_chem,
        final kL,
        final k_intra_Phi,
        final k_intra_Q) if 'inclH+' constrainedby FCSys.Species.Fluid(
        n_trans=n_trans,
        n_intra=3,
        n_inter=n_inter,
        kL=kL,
        k_intra_Phi={common.k_Phi[cartTrans],protonsSolid.k_Phi[cartTrans],
            protonsWater.k_Phi[cartTrans]},
        k_intra_Q={common.k_Q,protonsSolid.k_Q,protonsWater.k_Q}) "H+ model";
    
      parameter Boolean inclH2O=false "Include H2O";
    
      replaceable FCSys.Species.H2O.Ionomer.Fixed H2O(
        final n_trans,
        final n_inter,
        final n_chem,
        final kL,
        final k_intra_Phi,
        final k_intra_Q) if inclH2O constrainedby FCSys.Species.Fluid(
        n_trans=n_trans,
        n_intra=3,
        n_inter=0,
        kL=kL,
        k_intra_Phi={common.k_Phi[cartTrans],protonsWater.k_Phi[cartTrans],
            waterSolid.k_Phi[cartTrans]},
        k_intra_Q={common.k_Q,protonsWater.k_Q,waterSolid.k_Q}) "H2O model";
    
      Connectors.BoundaryBus xNegative if inclTrans[Axis.x] 
        "Negative boundary along the x axis";
      Connectors.BoundaryBus yNegative if inclTrans[Axis.y] 
        "Negative boundary along the y axis";
      Connectors.BoundaryBus zNegative if inclTrans[Axis.z] 
        "Negative boundary along the z axis";
      Connectors.BoundaryBus xPositive if inclTrans[Axis.x] 
        "Positive boundary along the x axis";
      Connectors.BoundaryBus yPositive if inclTrans[Axis.y] 
        "Positive boundary along the y axis";
      Connectors.BoundaryBus zPositive if inclTrans[Axis.z] 
        "Positive boundary along the z axis";
      Connectors.Amagat amagat if n_spec > 0 and inclAmagat 
        "Connector for additivity of volume";
      Connectors.Inter inter[n_inter](each final n_trans=n_trans) if n_spec > 0 
        "Connector to exchange momentum and energy with other phases";
      Connectors.Chemical chemH2O[1](each final n_trans=n_trans) if inclH2O 
        "Chemical connector for H2O";
      Connectors.Chemical 'chemH+'[1](each final n_trans=n_trans) if 'inclH+' 
        "Chemical connector for H+";
    
      // Advanced parameters
      parameter Boolean inclAmagat=true 
        "Include the connector for additivity of volume";
    
      // Independence factors
      ExchangeParams common(k_Q=0) if n_spec > 0 "Among all species in the phase";
      ExchangeParams protonsSolid(final k_Phi, k_Q=Modelica.Constants.inf) if 
        'inclSO3-' or 'inclH+' 
        "Between H+ and SO3-)";
      ExchangeParams protonsWater(k_Phi=fill(200, 3), k_Q=Modelica.Constants.inf) 
        if 'inclH+' or inclH2O 
        "Between H+ and H2O";
    
      ExchangeParams waterSolid(k_Q=Modelica.Constants.inf) if 'inclSO3-' or 
        inclH2O 
        "Between H2O and SO3-";
    
    protected 
      Conditions.Adapters.AmagatDalton amagatDalton if n_spec > 0 and inclAmagat 
        "Adapter between additivity of volume and additivity of pressure";
    
      Connectors.InertNode commonExch 
        "Connector for exchange among all species in the phase";
      Connectors.InertNode protonsSolidExch 
        "Connector for exchange between H+ and SO3-";
      Connectors.InertNode protonsWaterExch 
        "Connector for exchange between H+ and H2O";
      Connectors.InertNode waterSolidExch 
        "Connector for exchange between H2O and SO3-";
    
      Connectors.DaltonNode dalton(final V=V) if n_spec > 0 
        "Internal node for additivity of volume";
    equation 
      // Chemical exchange
      connect(H2O.chemical, chemH2O);
      connect('H+'.chemical, 'chemH+');
    
      // Inert exchange
      connect('SO3-'.inter, inter);
    
      connect('SO3-'.intra[1], commonExch.node);
      connect('SO3-'.intra[2], protonsSolidExch.node);
      connect('SO3-'.intra[3], waterSolidExch.node);
      connect('H+'.intra[1], commonExch.node);
      connect('H+'.intra[2], protonsSolidExch.node);
      connect('H+'.intra[3], protonsWaterExch.node);
    
      connect(H2O.intra[1], commonExch.node);
      connect(H2O.intra[2], waterSolidExch.node);
      connect(H2O.intra[3], protonsWaterExch.node);
    
      // Mixing
      connect('SO3-'.dalton, dalton);
      connect('H+'.dalton, dalton);
      connect(H2O.dalton, dalton);
      connect(amagatDalton.amagat, amagat);
    
      // Transport
      // ---------
      // SO3-
      connect('SO3-'.boundaries[transCart[Axis.x], Side.n], xNegative.'SO3-');
    
      connect('SO3-'.boundaries[transCart[Axis.x], Side.p], xPositive.'SO3-');
    
      connect('SO3-'.boundaries[transCart[Axis.y], Side.n], yNegative.'SO3-');
    
      connect('SO3-'.boundaries[transCart[Axis.y], Side.p], yPositive.'SO3-');
    
      connect('SO3-'.boundaries[transCart[Axis.z], Side.n], zNegative.'SO3-');
      connect('SO3-'.boundaries[transCart[Axis.z], Side.p], zPositive.'SO3-');
      // 'H+'
      connect('H+'.boundaries[transCart[Axis.x], Side.n], xNegative.'H+');
    
      connect('H+'.boundaries[transCart[Axis.x], Side.p], xPositive.'H+');
    
      connect('H+'.boundaries[transCart[Axis.y], Side.n], yNegative.'H+');
    
      connect('H+'.boundaries[transCart[Axis.y], Side.p], yPositive.'H+');
    
      connect('H+'.boundaries[transCart[Axis.z], Side.n], zNegative.'H+');
      connect('H+'.boundaries[transCart[Axis.z], Side.p], zPositive.'H+');
      // H2O
      connect(H2O.boundaries[transCart[Axis.x], Side.n], xNegative.H2O);
    
      connect(H2O.boundaries[transCart[Axis.x], Side.p], xPositive.H2O);
    
      connect(H2O.boundaries[transCart[Axis.y], Side.n], yNegative.H2O);
    
      connect(H2O.boundaries[transCart[Axis.y], Side.p], yPositive.H2O);
    
      connect(H2O.boundaries[transCart[Axis.z], Side.n], zNegative.H2O);
      connect(H2O.boundaries[transCart[Axis.z], Side.p], zPositive.H2O);
    
      connect(dalton, amagatDalton.dalton);
    end Ionomer;
    

    FCSys.Phases.Liquid FCSys.Phases.Liquid

    Liquid phase FCSys.Phases.Liquid

    Information

    Please see the documentation of the PartialPhase model.

    Extends from Icons.Phases.Liquid (Icon for a liquid phase), PartialPhase (Base model for a phase).

    Parameters

    TypeNameDefaultDescription
    Integern_specif inclH2O then 1 else 0Number of species
    Integern_trans1Number of transport axes
    Geometry
    NumberAbsolutek[Axis]{1,1,1}Length factors for transport [1]
    Independence factors
    NumberAbsolutek_inter_Phi[n_inter, n_trans]ones(n_inter, n_trans)For translational exchange with other phases [1]
    NumberAbsolutek_inter_Q[n_inter]ones(n_inter)For thermal exchange with other phases [1]
    Species
    BooleaninclH2OfalseInclude H2O
    FixedH2Oredeclare FCSys.Species.H2O….H2O model

    Connectors

    TypeNameDescription
    BoundaryBusxNegativeNegative boundary along the x axis
    BoundaryBusyNegativeNegative boundary along the y axis
    BoundaryBuszNegativeNegative boundary along the z axis
    BoundaryBusxPositivePositive boundary along the x axis
    BoundaryBusyPositivePositive boundary along the y axis
    BoundaryBuszPositivePositive boundary along the z axis
    Interinter[n_inter]Connector to exchange momentum and energy with other phases
    AmagatamagatConnector for additivity of volume
    ChemicalchemH2O[1]Chemical connector for H2O

    Modelica definition

    model Liquid "Liquid phase"
      extends Icons.Phases.Liquid;
      extends PartialPhase(final n_spec=if inclH2O then 1 else 0);
    
      // Conditionally include species.
      parameter Boolean inclH2O=false "Include H2O";
    
      // Auxiliary variables (for analysis)
      output Q.PressureAbsolute p(stateSelect=StateSelect.never) = amagat.p if 
        n_spec > 0 and environment.analysis "Total thermodynamic pressure";
    
      replaceable FCSys.Species.H2O.Liquid.Fixed H2O(
        final n_trans,
        final n_inter,
        final kL,
        final n_chem) if inclH2O constrainedby FCSys.Species.Fluid(
        n_trans=n_trans,
        n_inter=n_inter,
        kL=kL) "H2O model";
    
      Connectors.BoundaryBus xNegative if inclTrans[Axis.x] 
        "Negative boundary along the x axis";
      Connectors.BoundaryBus yNegative if inclTrans[Axis.y] 
        "Negative boundary along the y axis";
      Connectors.BoundaryBus zNegative if inclTrans[Axis.z] 
        "Negative boundary along the z axis";
      Connectors.BoundaryBus xPositive if inclTrans[Axis.x] 
        "Positive boundary along the x axis";
      Connectors.BoundaryBus yPositive if inclTrans[Axis.y] 
        "Positive boundary along the y axis";
      Connectors.BoundaryBus zPositive if inclTrans[Axis.z] 
        "Positive boundary along the z axis";
      Connectors.Inter inter[n_inter](each final n_trans=n_trans) if n_spec > 0 
        "Connector to exchange momentum and energy with other phases";
      Connectors.Amagat amagat(final V=-V) if n_spec > 0 
        "Connector for additivity of volume";
      Connectors.Chemical chemH2O[1](each final n_trans=n_trans) if inclH2O 
        "Chemical connector for H2O";
    
    protected 
      Conditions.Adapters.AmagatDalton amagatDalton if n_spec > 0 
        "Adapter between additivity of volume and additivity of pressure";
    
    equation 
      // Chemical exchange
    
      // Inert exchange
      connect(H2O.inter, inter);
    
      // Mixing
      connect(amagatDalton.amagat, amagat);
      connect(amagatDalton.dalton, H2O.dalton);
    
      // Transport
      // ---------
      // H2O
      connect(H2O.boundaries[transCart[Axis.x], Side.n], xNegative.H2O);
    
      connect(H2O.boundaries[transCart[Axis.x], Side.p], xPositive.H2O);
    
      connect(H2O.boundaries[transCart[Axis.y], Side.n], yNegative.H2O);
    
      connect(H2O.boundaries[transCart[Axis.y], Side.p], yPositive.H2O);
    
      connect(H2O.boundaries[transCart[Axis.z], Side.n], zNegative.H2O);
      connect(H2O.boundaries[transCart[Axis.z], Side.p], zPositive.H2O);
    
      connect(H2O.chemical, chemH2O);
    end Liquid;
    

    FCSys.Phases.PartialPhase

    Base model for a phase

    Information

    The scaling factor for diffusive transport (k) is a vector which directly affects the resistance associated with the transport of material, transverse translational momentum, and energy of all of the species within the phase. It can be used to introduce minor head loss or the effects of porosity or tortousity. These effects may be anisotropic. Using Bruggeman correction [Weber2004, p. 4696], the factor (k) within a phase should be set to ε-1/2 along each axis, where ε is the volumetric filling ratio, or the ratio of the volume of the phase to the total volume of the subregion. The Bruggeman factor itself increases resistance by a ε-3/2, but a factor of ε-1 is included inherently.

    Parameters

    TypeNameDefaultDescription
    Integern_spec Number of species
    Integern_trans1Number of transport axes
    Geometry
    NumberAbsolutek[Axis]{1,1,1}Length factors for transport [1]
    Independence factors
    NumberAbsolutek_inter_Phi[n_inter, n_trans]ones(n_inter, n_trans)For translational exchange with other phases [1]
    NumberAbsolutek_inter_Q[n_inter]ones(n_inter)For thermal exchange with other phases [1]

    Modelica definition

    partial model PartialPhase "Base model for a phase"
      import Modelica.Math.BooleanVectors.index;
    
      parameter Integer n_spec(start=0) "Number of species";
      parameter Integer n_inter=0 
        "Number of exchange connections with other phases";
    
      // Geometric parameters
      parameter Q.NumberAbsolute k[Axis](
        each min=Modelica.Constants.small,
        each final nominal=1) = {1,1,1} if n_spec > 0 
        "Length factors for transport";
      parameter Integer n_trans=1 "Number of transport axes";
      // This can't be an inner/outer parameter in Dymola 2014.
      inner Q.Volume V if n_spec > 0 "Volume of the phase";
    
      // Independence factors
      inner parameter Q.NumberAbsolute k_inter_Phi[n_inter, n_trans]=ones(n_inter,
          n_trans) if n_spec > 0 "For translational exchange with other phases";
      inner parameter Q.NumberAbsolute k_inter_Q[n_inter]=ones(n_inter) if n_spec >
        0 "For thermal exchange with other phases";
    
      // Auxiliary variables (for analysis)
      output Q.NumberAbsolute epsilon=V/product(L) if n_spec > 0 and environment.analysis
        "Volumetric fill fraction";
    
    protected 
      outer parameter Q.Length L[Axis] if n_spec > 0 "Length of the subregion";
      final parameter Q.Length kL[:]=k[cartTrans] .* L[cartTrans] if n_spec > 0 
        "Effective transport lengths";
      final inner Q.Area Aprime[n_trans]=fill(V, n_trans) ./ L[cartTrans] if n_spec >
        0 "Effective cross-sectional areas";
      outer parameter Integer cartTrans[:] 
        "Cartesian-axis indices of the components of translational momentum";
      outer parameter Integer transCart[:] 
        "Boundary-pair indices of the Cartesian axes";
      outer parameter Boolean inclTrans[Axis] 
        "true, if each pair of boundaries is included";
    
      outer Conditions.Environment environment "Environmental conditions";
    
    end PartialPhase;
    

    FCSys.Phases.ExchangeParams FCSys.Phases.ExchangeParams

    Independence factors for an exchange process

    Information

    Extends from Modelica.Icons.Record (Icon for records).

    Parameters

    TypeNameDefaultDescription
    NumberAbsolutek_Phi[Axis]{1,1,1}Translational [1]
    NumberAbsolutek_Q1Thermal [1]

    Modelica definition

    record ExchangeParams "Independence factors for an exchange process"
      extends Modelica.Icons.Record;
    
      parameter Q.NumberAbsolute k_Phi[Axis]={1,1,1} "Translational";
      parameter Q.NumberAbsolute k_Q=1 "Thermal";
    
    end ExchangeParams;