FCSys.Subregions

Control volumes with multi-species transfer and storage

Information

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

Package Content

NameDescription
FCSys.Subregions.Examples Examples Examples
FCSys.Subregions.Subregion Subregion Subregion with all phases
FCSys.Subregions.SubregionIonomer SubregionIonomer Subregion with only the ionomer phase
FCSys.Subregions.SubregionNoIonomer SubregionNoIonomer Subregion with all phases except ionomer
FCSys.Subregions.PartialSubregion PartialSubregion Base model for multi-dimensional, multi-species storage, transport, and exchange

FCSys.Subregions.Subregion FCSys.Subregions.Subregion

Subregion with all phases FCSys.Subregions.Subregion

Information

Assumptions:

  1. The oxygen reduction reaction generates liquid water if it is included; otherwise, it generates H2O vapor. Since phase change is a dynamic, nonequilibrium process, there is a difference.

Please see the documentation of the PartialSubregion model.

Extends from PartialSubregion (Base model for multi-dimensional, multi-species storage, transport, and exchange).

Parameters

TypeNameDefaultDescription
CapillaryVolumevolume Volume with capillary pressure included
Geometry
LengthL[Axis]{U.cm,U.cm,U.cm}Lengths [L]
Phases (click to edit)
Gasgas Gas
Graphitegraphite Graphite
Ionomerionomer Ionomer
Liquidliquid Liquid
Independence factors
ExchangeParamscommon Among all phases
ExchangeParamsgasLiq Between gas and liquid
Assumptions
Included transport axes
BooleaninclTransXtrueX
BooleaninclTransYtrueY
BooleaninclTransZtrueZ

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

Modelica definition

model Subregion "Subregion with all phases"
  import Modelica.Constants.inf;

  extends PartialSubregion(final n_spec=gas.n_spec + graphite.n_spec + ionomer.n_spec
         + liquid.n_spec);

  FCSys.Phases.Gas gas(
    n_inter=2,
    final n_trans=n_trans,
    final k_inter_Phi={common.k_Phi[cartTrans],gasLiq.k_Phi[cartTrans]},
    final k_inter_Q={common.k_Q,gasLiq.k_Q}) "Gas";

  FCSys.Phases.Graphite graphite(
    n_inter=1,
    final n_trans=n_trans,
    'incle-Transfer'=inclHOR or inclORR,
    final k_inter_Phi={common.k_Phi[cartTrans]},
    final k_inter_Q={common.k_Q}) "Graphite";

  FCSys.Phases.Ionomer ionomer(
    n_inter=1,
    final n_trans=n_trans,
    final k_inter_Phi={common.k_Phi[cartTrans]},
    final k_inter_Q={common.k_Q}) "Ionomer";

  FCSys.Phases.Liquid liquid(
    n_inter=2,
    final n_trans=n_trans,
    final k_inter_Phi={common.k_Phi[cartTrans],gasLiq.k_Phi[cartTrans]},
    final k_inter_Q={common.k_Q,gasLiq.k_Q}) "Liquid";

  Chemistry.HOR HOR(final n_trans=n_trans) if inclHOR 
    "Hydrogen oxidation reaction";
  Chemistry.ORR ORR(final n_trans=n_trans) if inclORR 
    "Oxygen reduction reaction";

  // Independence factors
  Phases.ExchangeParams common(k_Phi={1.7,1.7,1.7}) "Among all phases";
  Phases.ExchangeParams gasLiq(k_Phi={inf,inf,inf}) "Between gas and liquid";

  Connectors.BoundaryBus xNegative if inclTransX 
    "Negative boundary along the x axis";
  Connectors.BoundaryBus yNegative if inclTransY 
    "Negative boundary along the y axis";
  Connectors.BoundaryBus zNegative if inclTransZ 
    "Negative boundary along the z axis";
  Connectors.BoundaryBus xPositive if inclTransX 
    "Positive boundary along the x axis";
  Connectors.BoundaryBus yPositive if inclTransY 
    "Positive boundary along the y axis";
  Connectors.BoundaryBus zPositive if inclTransZ 
    "Positive boundary along the z axis";

  Chemistry.CapillaryVolume volume(
    final V=V,
    final inclGas=gas.n_spec > 0,
    final inclLiquid=liquid.n_spec > 0,
    final inclSolid=graphite.n_spec + ionomer.n_spec > 0) 
    "Volume with capillary pressure included";

protected 
  final parameter Boolean inclHOR=graphite.'incle-' and ionomer.'inclH+' and 
      gas.inclH2 "Include the hydrogen oxidation reaction";
  final parameter Boolean inclORR=graphite.'incle-' and ionomer.'inclH+' and 
      gas.inclO2 and (gas.inclH2O or liquid.inclH2O) 
    "Include the oxygen reduction reaction";

  outer Conditions.Environment environment "Environmental conditions";
  Connectors.InertNode exchCommon "Connector for exchange among all species";
  Connectors.InertNode exchGasLiq 
    "Connector for exchange between gas and liquid";

equation 
  // Boundaries
  // ----------
  // Gas
  connect(gas.yNegative, yNegative.gas);
  connect(gas.zPositive, zPositive.gas);
  connect(gas.xNegative, xNegative.gas);
  connect(gas.yPositive, yPositive.gas);
  connect(gas.zNegative, zNegative.gas);
  connect(gas.xPositive, xPositive.gas);
  // Graphite
  connect(graphite.yNegative, yNegative.graphite);
  connect(graphite.yPositive, yPositive.graphite);
  connect(graphite.zNegative, zNegative.graphite);
  connect(graphite.zPositive, zPositive.graphite);
  connect(graphite.xNegative, xNegative.graphite);
  connect(graphite.xPositive, xPositive.graphite);
  // Ionomer
  connect(ionomer.yNegative, yNegative.ionomer);
  connect(ionomer.yPositive, yPositive.ionomer);
  connect(ionomer.zNegative, zNegative.ionomer);
  connect(ionomer.zPositive, zPositive.ionomer);
  connect(ionomer.xNegative, xNegative.ionomer);
  connect(ionomer.xPositive, xPositive.ionomer);
  // Liquid
  connect(liquid.yNegative, yNegative.liquid);
  connect(liquid.yPositive, yPositive.liquid);
  connect(liquid.zNegative, zNegative.liquid);
  connect(liquid.zPositive, zPositive.liquid);
  connect(liquid.xNegative, xNegative.liquid);
  connect(liquid.xPositive, xPositive.liquid);

  // Mixing
  connect(gas.dalton, volume.gas);
  connect(liquid.amagat, volume.liquid);
  connect(volume.solid, graphite.amagat);
  connect(volume.solid, ionomer.amagat);

  // Inert exchange
  // --------------
  // Common
  connect(gas.inter[1], exchCommon.node);
  connect(graphite.inter[1], exchCommon.node);
  connect(ionomer.inter[1], exchCommon.node);
  connect(liquid.inter[1], exchCommon.node);
  // Gas-liquid
  connect(gas.inter[2], exchGasLiq.node);
  connect(liquid.inter[2], exchGasLiq.node);

  // Reactions and phase change (not shown in diagram)
  // -------------------------------------------------
  connect(gas.chemH2[1], HOR.chemH2);
  connect(gas.chemO2[1], ORR.chemO2);
  connect(liquid.chemH2O[1], ORR.chemH2O);
  if liquid.inclH2O then
    if gas.inclH2O then
      connect(liquid.chemH2O[2], gas.chemH2O[2]);
    end if;
    if ionomer.inclH2O then
      connect(liquid.chemH2O[3], ionomer.chemH2O[1]);
    end if;
  elseif gas.inclH2O then
    connect(gas.chemH2O[1], ORR.chemH2O);
  end if;
  connect(graphite.'cheme-'[1], HOR.'cheme-');
  connect(graphite.'cheme-'[1], ORR.'cheme-');
  connect(ionomer.'chemH+'[1], HOR.'chemH+');
  connect(ionomer.'chemH+'[1], ORR.'chemH+');
end Subregion;

FCSys.Subregions.SubregionIonomer FCSys.Subregions.SubregionIonomer

Subregion with only the ionomer phase FCSys.Subregions.SubregionIonomer

Information

Please see the documentation of the PartialSubregion model.

Extends from PartialSubregion (Base model for multi-dimensional, multi-species storage, transport, and exchange).

Parameters

TypeNameDefaultDescription
CapillaryVolumevolume Volume with capillary pressure included
Geometry
LengthL[Axis]{U.cm,U.cm,U.cm}Lengths [L]
Phases (click to edit)
Ionomerionomer Ionomer
Assumptions
Included transport axes
BooleaninclTransXtrueX
BooleaninclTransYtrueY
BooleaninclTransZtrueZ

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

Modelica definition

model SubregionIonomer "Subregion with only the ionomer phase"

  extends PartialSubregion(final n_spec=ionomer.n_spec);

  FCSys.Phases.Ionomer ionomer(n_inter=0, final n_trans=n_trans) "Ionomer";

  Connectors.BoundaryBus xNegative if inclTransX 
    "Negative boundary along the x axis";
  Connectors.BoundaryBus yNegative if inclTransY 
    "Negative boundary along the y axis";
  Connectors.BoundaryBus zNegative if inclTransZ 
    "Negative boundary along the z axis";
  Connectors.BoundaryBus xPositive if inclTransX 
    "Positive boundary along the x axis";
  Connectors.BoundaryBus yPositive if inclTransY 
    "Positive boundary along the y axis";
  Connectors.BoundaryBus zPositive if inclTransZ 
    "Positive boundary along the z axis";

  Chemistry.CapillaryVolume volume(
    final V=V,
    final inclSolid=ionomer.n_spec > 0,
    final inclGas=false,
    final inclLiquid=false) "Volume with capillary pressure included";

equation 
  // Boundaries
  // ----------
  // Ionomer

  connect(ionomer.yNegative, yNegative.ionomer);

  connect(ionomer.yPositive, yPositive.ionomer);
  connect(ionomer.zNegative, zNegative.ionomer);
  connect(ionomer.zPositive, zPositive.ionomer);

  connect(ionomer.xNegative, xNegative.ionomer);
  connect(ionomer.xPositive, xPositive.ionomer);

  connect(volume.solid, ionomer.amagat);
end SubregionIonomer;

FCSys.Subregions.SubregionNoIonomer FCSys.Subregions.SubregionNoIonomer

Subregion with all phases except ionomer FCSys.Subregions.SubregionNoIonomer

Information

Please see the documentation of the PartialSubregion model.

Extends from PartialSubregion (Base model for multi-dimensional, multi-species storage, transport, and exchange).

Parameters

TypeNameDefaultDescription
Geometry
LengthL[Axis]{U.cm,U.cm,U.cm}Lengths [L]
Phases (click to edit)
Gasgas Gas
Graphitegraphite Graphite
Liquidliquid Liquid
Independence factors
ExchangeParamscommon Among all phases
ExchangeParamsgasLiq Between gas and liquid
Assumptions
Included transport axes
BooleaninclTransXtrueX
BooleaninclTransYtrueY
BooleaninclTransZtrueZ

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

Modelica definition

model SubregionNoIonomer "Subregion with all phases except ionomer"
  import Modelica.Constants.inf;

  extends PartialSubregion(final n_spec=gas.n_spec + graphite.n_spec + liquid.n_spec);

  FCSys.Phases.Gas gas(
    n_inter=2,
    final n_trans=n_trans,
    final k_inter_Phi={common.k_Phi[cartTrans],gasLiq.k_Phi[cartTrans]},
    final k_inter_Q={common.k_Q,gasLiq.k_Q}) "Gas";

  FCSys.Phases.Graphite graphite(
    n_inter=1,
    final n_trans=n_trans,
    final k_inter_Phi={common.k_Phi[cartTrans]},
    final k_inter_Q={common.k_Q}) "Graphite";

  FCSys.Phases.Liquid liquid(
    n_inter=2,
    final n_trans=n_trans,
    final k_inter_Phi={common.k_Phi[cartTrans],gasLiq.k_Phi[cartTrans]},
    final k_inter_Q={common.k_Q,gasLiq.k_Q}) "Liquid";

  // Independence factors
  Phases.ExchangeParams common(k_Phi={1.7,1.7,1.7}) "Among all phases";
  Phases.ExchangeParams gasLiq(k_Phi={inf,inf,inf}) "Between gas and liquid";

  Connectors.BoundaryBus xNegative if inclTransX 
    "Negative boundary along the x axis";
  Connectors.BoundaryBus yNegative if inclTransY 
    "Negative boundary along the y axis";
  Connectors.BoundaryBus zNegative if inclTransZ 
    "Negative boundary along the z axis";
  Connectors.BoundaryBus xPositive if inclTransX 
    "Positive boundary along the x axis";
  Connectors.BoundaryBus yPositive if inclTransY 
    "Positive boundary along the y axis";
  Connectors.BoundaryBus zPositive if inclTransZ 
    "Positive boundary along the z axis";

  Chemistry.CapillaryVolume volume(
    final V=V,
    final inclGas=gas.n_spec > 0,
    final inclLiquid=liquid.n_spec > 0,
    final inclSolid=graphite.n_spec > 0) 
    "Volume with capillary pressure included";

protected 
  outer Conditions.Environment environment "Environmental conditions";

  // Exchange
  Connectors.InertNode exchCommon "Among all phases";
  Connectors.InertNode exchGasLiq "Between gas and liquid";

equation 
  // Boundaries
  // ----------
  // Gas
  connect(gas.yNegative, yNegative.gas);
  connect(gas.zPositive, zPositive.gas);
  connect(gas.xNegative, xNegative.gas);
  connect(gas.yPositive, yPositive.gas);
  connect(gas.zNegative, zNegative.gas);
  connect(gas.xPositive, xPositive.gas);
  // Graphite
  connect(graphite.yNegative, yNegative.graphite);
  connect(graphite.yPositive, yPositive.graphite);
  connect(graphite.zNegative, zNegative.graphite);
  connect(graphite.zPositive, zPositive.graphite);
  connect(graphite.xNegative, xNegative.graphite);
  connect(graphite.xPositive, xPositive.graphite);
  // Liquid
  connect(liquid.yNegative, yNegative.liquid);
  connect(liquid.yPositive, yPositive.liquid);
  connect(liquid.zNegative, zNegative.liquid);
  connect(liquid.zPositive, zPositive.liquid);
  connect(liquid.xNegative, xNegative.liquid);
  connect(liquid.xPositive, xPositive.liquid);

  // Mixing
  connect(liquid.amagat, volume.liquid);
  connect(gas.dalton, volume.gas);
  connect(volume.solid, graphite.amagat);

  // Inert exchange
  // --------------
  // Common
  connect(gas.inter[1], exchCommon.node);
  connect(graphite.inter[1], exchCommon.node);
  connect(liquid.inter[1], exchCommon.node);
  // Gas-liquid
  connect(gas.inter[2], exchGasLiq.node);
  connect(liquid.inter[2], exchGasLiq.node);

  // Phase change (not shown in diagram)
  // -----------------------------------
  if gas.inclH2O and liquid.inclH2O then
    connect(gas.chemH2O[2], liquid.chemH2O[2]);
  end if;

end SubregionNoIonomer;

FCSys.Subregions.PartialSubregion FCSys.Subregions.PartialSubregion

Base model for multi-dimensional, multi-species storage, transport, and exchange

Information

At least one component of translational momentum must be included. All of the components are included by default.

This model should be extended to include the appropriate phases, reactions, etc.

Parameters

TypeNameDefaultDescription
Geometry
LengthL[Axis]{U.cm,U.cm,U.cm}Lengths [L]
Assumptions
Included transport axes
BooleaninclTransXtrueX
BooleaninclTransYtrueY
BooleaninclTransZtrueZ

Modelica definition

partial model PartialSubregion 
  "Base model for multi-dimensional, multi-species storage, transport, and exchange"
  import Modelica.Math.BooleanVectors.countTrue;
  import Modelica.Math.BooleanVectors.enumerate;
  import Modelica.Math.BooleanVectors.index;
  // extends FCSys.Icons.Names.Top3;

  // Geometric parameters
  inner parameter Q.Length L[Axis](each min=Modelica.Constants.small) = {U.cm,U.cm,
    U.cm} "Lengths";

  // Assumptions
  // -----------
  // Included boundaries
  parameter Boolean inclTransX=true "X";
  parameter Boolean inclTransY=true "Y";
  parameter Boolean inclTransZ=true "Z";

  // Auxiliary variables (for analysis)
  final inner parameter Q.Volume V=product(L) "Volume";
  final parameter Q.Area A[Axis]=fill(V, 3) ./ L "Cross-sectional areas";

protected 
  parameter Integer n_spec(start=0) "Number of species";
  final inner parameter Boolean inclTrans[Axis]={inclTransX,inclTransY,
      inclTransZ} "true, if each pair of boundaries is included";
  final inner parameter Boolean inclRot[Axis]={inclTransY and inclTransZ,
      inclTransZ and inclTransX,inclTransX and inclTransY} 
    "true, if each axis of rotation has all its tangential boundaries included";
  final parameter Integer n_trans=countTrue(inclTrans) 
    "Number of transport axes";
  final inner parameter Integer cartRot[:]=index(inclRot) 
    "Cartesian-axis indices of the components of rotational momentum";
  final inner parameter Integer cartTrans[n_trans]=index(inclTrans) 
    "Cartesian-axis indices of the transport axes";
  final inner parameter Integer transCart[Axis]=enumerate(inclTrans) 
    "Transport-axis indices of the Cartesian axes";

end PartialSubregion;