Skip to content

Commit

Permalink
First draft of inertial electro-chemical potential concept
Browse files Browse the repository at this point in the history
  • Loading branch information
MarekMatejak committed Nov 25, 2023
1 parent 47fd6bc commit 9633aa5
Show file tree
Hide file tree
Showing 8 changed files with 2,976 additions and 438 deletions.
1,670 changes: 1,670 additions & 0 deletions Chemical/Boundaries.mo

Large diffs are not rendered by default.

45 changes: 45 additions & 0 deletions Chemical/DropOfCommons.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
within Chemical;
model DropOfCommons "Model for global parameters"

parameter Chemical.Utilities.Units.Inertance L=1e-5 "Inertance of the molar flow through electro-chemical process" annotation (Dialog(tab="Advanced"));

parameter Modelica.Units.SI.MolarFlowRate n_flow_reg = 0.01 "Regularization threshold of molar flow rate"
annotation(Dialog(group="Regularization"));

parameter AssertionLevel assertionLevel = AssertionLevel.error "Global assertion level";

annotation (defaultComponentName="dropOfCommons",
defaultComponentPrefixes="inner",
missingInnerMessage="
Your model is using an outer \"dropOfCommons\" component but
an inner \"dropOfCommons\" component is not defined.
Use Chemical.DropOfCommons in your model
to specify system properties.",Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Ellipse(
extent={{-80,-60},{80,-100}},
fillColor={175,175,175},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Polygon(
points={{0,100},{16,36},{80,-32},{0,-100},{-82,-30},{-18,36},{0,100}},
lineColor={194,138,221},
smooth=Smooth.Bezier,
fillColor={158,66,200},
fillPattern=FillPattern.Solid),
Polygon(
points={{6,42},{20,16},{44,-14},{22,-38},{6,42}},
smooth=Smooth.Bezier,
fillColor={194,138,221},
fillPattern=FillPattern.Solid,
pattern=LinePattern.None),
Polygon(
points={{-6,-76},{-40,-62},{-56,-30},{-30,-44},{-6,-76}},
pattern=LinePattern.None,
smooth=Smooth.Bezier,
fillColor={90,34,117},
fillPattern=FillPattern.Solid)}), Diagram(
coordinateSystem(preserveAspectRatio=false)),
Documentation(revisions="<html>
<p>2023, Marek Mateják</p>
</html>"));
end DropOfCommons;
101 changes: 91 additions & 10 deletions Chemical/Examples.mo
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ extends Modelica.Icons.ExamplesPackage;
{-30,-90},{60,-90},{60,-98}},color={127,127,0}));

connect(B.port_a, reaction.substrates[1]) annotation (Line(
points={{-14,-14},{-10,-14},{-10,4},{4,4}},
points={{-14,-14},{-10,-14},{-10,1},{4,1}},
color={158,66,200},
thickness=1));
connect(A.port_a, reaction.substrates[2]) annotation (Line(
points={{-14,12},{-10,12},{-10,0},{4,0}},
points={{-14,12},{-10,12},{-10,3},{4,3}},
color={158,66,200},
thickness=1));
annotation ( Documentation(revisions="<html>
Expand Down Expand Up @@ -6221,23 +6221,20 @@ extends Modelica.Icons.ExamplesPackage;
Chemical.Components.Solution solution
annotation (Placement(transformation(extent={{-100,-100},{100,100}})));

Chemical.Components.SubstanceS A(
Chemical.Boundaries.Substance A(
useInlet=false,
useOutlet=true,
substanceData(MolarWeight=1),
use_mass_start=false,
amountOfSubstance_start=0.9)
annotation (Placement(transformation(extent={{-52,-8},{-32,12}})));
amountOfSubstance_start=0.9) annotation (Placement(transformation(extent={{-52,-8},{-32,12}})));

Chemical.Components.Process reaction(n_flow_0=7000)
annotation (Placement(transformation(extent={{-10,-8},{10,12}})));
Chemical.Components.SubstanceS B(
Chemical.Processes.Process reaction(n_flow_0=7000) annotation (Placement(transformation(extent={{-10,-8},{10,12}})));
Chemical.Boundaries.Substance B(
useInlet=true,
useOutlet=false,
substanceData(DfG=-R*T_25degC*log(K), MolarWeight=1),
use_mass_start=false,
amountOfSubstance_start=0.1)
annotation (Placement(transformation(extent={{42,-10},{62,10}})));
amountOfSubstance_start=0.1) annotation (Placement(transformation(extent={{42,-10},{62,10}})));

Components.Solution solution1
annotation (Placement(transformation(extent={{118,-98},{318,102}})));
Expand All @@ -6253,6 +6250,7 @@ extends Modelica.Icons.ExamplesPackage;
use_mass_start=false,
amountOfSubstance_start=0.1)
annotation (Placement(transformation(extent={{280,-6},{260,14}})));
inner DropOfCommons dropOfCommons(assertionLevel=AssertionLevel.warning) annotation (Placement(transformation(extent={{40,60},{60,80}})));
equation
connect(A.solution, solution.solution) annotation (Line(
points={{-48,-8},{-48,-92},{60,-92},{60,-98}},
Expand Down Expand Up @@ -6285,4 +6283,87 @@ extends Modelica.Icons.ExamplesPackage;
Icon(coordinateSystem(extent={{-100,-100},{340,100}})),
__Dymola_experimentSetupOutput);
end SimpleReactionS;

model SimpleReaction2S "The simple chemical reaction A+B<->C with equilibrium [C]/([A]*[B]) = 2, where [A] is molar concentration of A in water"
extends Modelica.Icons.Example;

constant Real Kb(unit="kg/mol") = 2
"Molarity based dissociation constant of the reaction with one more reactant";

constant Real Kx(unit="1") = Kb*55.508
"Mole fraction based dissociation constant of the reaction with one more reactant in the pure water";

constant Modelica.Units.SI.Temperature T_25degC=298.15 "Temperature";
constant Real R = Modelica.Constants.R "Gas constant";

Chemical.Components.Solution solution
annotation (Placement(transformation(extent={{-100,-100},{100,100}})));

Boundaries.Substance A(
useInlet=false,
useOutlet=true,
use_mass_start=false,
amountOfSubstance_start=0.1) annotation (Placement(transformation(extent={{-34,2},{-14,22}})));
Chemical.Components.Reaction reaction(nS=2, nP=1)
annotation (Placement(transformation(extent={{4,-8},{24,12}})));
Boundaries.Substance B(
useInlet=false,
useOutlet=true,
use_mass_start=false,
amountOfSubstance_start=0.1) annotation (Placement(transformation(extent={{-34,-24},{-14,-4}})));
Boundaries.Substance C(
useInlet=true,
useOutlet=false,
substanceData(DfG=-R*T_25degC*log(Kx)),
use_mass_start=false,
amountOfSubstance_start=0.1) annotation (Placement(transformation(extent={{48,-8},{68,12}})));

Components.Solution solution1
annotation (Placement(transformation(extent={{138,-100},{338,100}})));
Components.Substance A1(use_mass_start=false, amountOfSubstance_start=0.1)
annotation (Placement(transformation(extent={{204,2},{224,22}})));
Components.Reaction reaction1(nS=2, nP=1)
annotation (Placement(transformation(extent={{242,-8},{262,12}})));
Components.Substance B1(use_mass_start=false, amountOfSubstance_start=0.1)
annotation (Placement(transformation(extent={{204,-24},{224,-4}})));
Components.Substance C1(
substanceData(DfG=-R*T_25degC*log(Kx)),
use_mass_start=false,
amountOfSubstance_start=0.1)
annotation (Placement(transformation(extent={{306,-8},{286,12}})));
equation
connect(A.solution, solution.solution) annotation (Line(
points={{-30,2},{-30,-90},{60,-90},{60,-98}},
color={127,127,0}));
connect(C.solution, solution.solution) annotation (Line(points={{52,-8},{66,-8},{66,-90},{60,-90},{60,-98}},
color={127,127,0}));
connect(B.solution, solution.solution) annotation (Line(points={{-30,-24},
{-30,-90},{60,-90},{60,-98}},color={127,127,0}));

connect(reaction1.products[1], C1.port_a) annotation (Line(
points={{262,2},{286,2}},
color={158,66,200},
thickness=1));
connect(A1.solution, solution1.solution) annotation (Line(points={{208,2},{132,2},{132,-106},{298,-106},{298,-98}}, color={127,127,0}));
connect(C1.solution, solution1.solution) annotation (Line(points={{302,-8},{344,-8},{344,-106},{298,-106},{298,-98}}, color={127,127,0}));
connect(B1.solution, solution1.solution) annotation (Line(points={{208,-24},{132,-24},{132,-106},{298,-106},{298,-98}}, color={127,127,0}));
connect(B1.port_a, reaction1.substrates[1])
annotation (Line(
points={{224,-14},{224,-16},{232,-16},{232,1},{242,1}},
color={158,66,200},
thickness=1));
connect(A1.port_a, reaction1.substrates[2]) annotation (Line(
points={{224,12},{234,12},{234,3},{242,3}},
color={158,66,200},
thickness=1));
annotation ( Documentation(revisions="<html>
<p><i>2015-2018</i></p>
<p>Marek Matejak, Charles University, Prague, Czech Republic </p>
</html>", info="<html>
<p>Simple reaction demonstrating equilibria between substance A, B, and substance C, mixed in one solution. Observe the molar concentration (A.c) and molar fraction. Note, that molar fractions (A.x and B.x and C.x) are always summed to 1 for the whole solution.</p>
</html>"),
experiment(StopTime=0.0001, __Dymola_Algorithm="Dassl"),
Diagram(coordinateSystem(extent={{-100,-100},{340,100}})),
Icon(coordinateSystem(extent={{-100,-100},{340,100}})));
end SimpleReaction2S;
end Examples;
211 changes: 211 additions & 0 deletions Chemical/Processes.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
within Chemical;
package Processes
model Process "Electro-chemical process"
extends Interfaces.SISOFlow;
extends Interfaces.ConditionalKinetics;

parameter Real kE(unit="mol/J")=0 "Kinetic turnover coefficient";

equation
//the main equation

n_flow = - kC * du * exp(-kE*abs(du));

annotation ( Documentation(revisions="<html>
<p><i>2009-2015 by </i>Marek Matejak, Charles University, Prague, Czech Republic </p>
</html>", info="<html>
<p>Diffusion of the substance as equilibration of electro-chemical potentials.</p>
</html>"),
Icon(graphics={Rectangle(extent={{-100,40},{100,-40}}, lineColor={28,108,200})}));
end Process;

model Reaction "Chemical Reaction"
extends Interfaces.ConditionalKinetics;
import Chemical.Utilities.Types.InitializationMethods;

parameter StateSelect n_flowStateSelect = StateSelect.default "State select for n_flow"
annotation(Dialog(tab="Advanced"));
parameter InitializationMethods initN_flow = Chemical.Utilities.Types.InitializationMethods.none "Initialization method for n_flow"
annotation(Dialog(tab= "Initialization", group="Molar flow"));
parameter Modelica.Units.SI.MolarFlowRate n_flow_0 = 0 "Initial value for n_flow"
annotation(Dialog(tab= "Initialization", group="Molar flow", enable=(initN_flow == InitializationMethods.state)));
parameter Utilities.Units.MolarFlowAcceleration n_acceleration_0 = 0 "Initial value for der(n_flow)"
annotation(Dialog(tab= "Initialization", group="Molar flow", enable=(initN_flow == InitializationMethods.derivative)));


parameter Modelica.Units.SI.Time TC=0.1 "Time constant for electro-chemical potential adaption" annotation (Dialog(tab="Advanced"));
parameter Utilities.Units.Inertance L = dropOfCommons.L "Inertance of the flow"
annotation(Dialog(tab="Advanced"));

parameter Integer nS=0 "Number of substrate types"
annotation ( HideResult=true, Evaluate=true, Dialog(connectorSizing=true, tab="General",group="Ports"));

parameter Modelica.Units.SI.StoichiometricNumber s[nS]=ones(nS)
"Stoichiometric reaction coefficient for substrates"
annotation (HideResult=true);

parameter Integer nP=0 "Number of product types"
annotation ( HideResult=true, Evaluate=true, Dialog(connectorSizing=true, tab="General",group="Ports"));

parameter Modelica.Units.SI.StoichiometricNumber p[nP]=ones(nP)
"Stoichiometric reaction coefficients for products"
annotation (HideResult=true);

parameter Real kE(unit="mol/J")=0 "Kinetic turnover coefficient"
annotation(Dialog(group="Chemical kinetics"));

Modelica.Units.SI.MolarFlowRate rr(stateSelect=n_flowStateSelect) "Reaction molar flow rate";

Interfaces.Inlet substrates[nS] annotation (Placement(transformation(
extent={{10,-10},{-10,10}},
rotation=180,
origin={-100,0}), iconTransformation(
extent={{10,-10},{-10,10}},
rotation=180,
origin={-100,0})));

Interfaces.Outlet products[nP] annotation (Placement(transformation(
extent={{10,-10},{-10,10}},
rotation=180,
origin={100,0}), iconTransformation(
extent={{10,-10},{-10,10}},
rotation=180,
origin={100,0})));

Modelica.Units.SI.MolarEnthalpy h_mix;

protected
outer DropOfCommons dropOfCommons;
Modelica.Units.SI.ChemicalPotential du;

initial equation
if initN_flow == InitializationMethods.state then
rr = n_flow_0;
elseif initN_flow == InitializationMethods.derivative then
der(rr) = n_acceleration_0;
elseif initN_flow == InitializationMethods.steadyState then
der(rr) = 0;
end if;

equation
//the main equation
du = ((p * products.u) - (s * substrates.u));
rr = - kC * du * exp(-kE*abs(du));

//reaction molar rates
rr*s = substrates.n_flow;
rr*p = -products.n_flow;

products.h = h_mix*ones(nP);

if
(rr>0) then
h_mix*(products.n_flow*ones(nP)) + substrates.n_flow*substrates.h = 0;
else
h_mix = 0;
end if;

if nP>0 then
(p * products.r) = (s * substrates.r) - der(rr)*L;
for i in 2:nP loop
//first product is based on inertial potential,
//other products are provided as source
der(products[i].u).*TC = products[i].r;
end for;
end if;

annotation (
Icon(coordinateSystem(preserveAspectRatio=false,extent={{-100,-100},{
100,100}}), graphics={
Rectangle(
extent={{-100,-30},{100,30}},
lineColor={0,0,127},
fillColor={255,255,255},
fillPattern=FillPattern.Solid),
Text(
extent={{-100,-72},{100,-40}},
lineColor={128,0,255},
textString="%name"),
Polygon(
points={{-60,6},{-60,4},{54,4},{54,4},{18,14},{18,6},{-60,6}},
lineColor={0,0,0},
fillColor={0,0,0},
fillPattern=FillPattern.Solid),
Polygon(
points={{54,-8},{54,-6},{-60,-6},{-60,-6},{-24,-16},{-24,-8},{54,-8}},
lineColor={0,0,0},
fillColor={0,0,0},
fillPattern=FillPattern.Solid)}),
Documentation(revisions="<html>
<p><i>2013-2020 by </i>Marek Matejak, Charles University, Prague, Czech Republic </p>
</html>", info="<html>
<p><b>s<sub>1</sub>&middot;S<sub>1</sub> + .. + s<sub>nS</sub>&middot;S<sub>nS</sub> &lt;-&gt; p<sub>1</sub>&middot;P<sub>1</sub> + .. + p<sub>nP</sub>&middot;P<sub>nP</sub></b> </p>
<p>By redefinition of stoichometry as v<sub>i</sub> = -s<sub>i</sub>, A<sub>i</sub> = S<sub>i</sub> for i=1..nS v<sub>i</sub> = p<sub>i-nS</sub>, A<sub>i</sub> = P<sub>i-nS</sub> for i=nS+1..nS+nP </p>
<p>So the reaction can be written also as 0 = &sum; (v<sub>i</sub> &middot; A<sub>i</sub>) </p>
<h4><span style=\"color:#008000\">Equilibrium equation</span></h4>
<table cellspacing=\"2\" cellpadding=\"0\" border=\"0\"><tr>
<td><p>K = <a href=\"modelica://ModelicaReference.Operators.'product()'\">product</a>(a(S)<a href=\"modelica://ModelicaReference.Operators.ElementaryOperators\">.^</a>s) / <a href=\"modelica://ModelicaReference.Operators.'product()'\">product</a>( a(P)<a href=\"modelica://ModelicaReference.Operators.ElementaryOperators\">.^</a>s ) = <a href=\"modelica://ModelicaReference.Operators.'product()'\">product</a>(a(A)<a href=\"modelica://ModelicaReference.Operators.ElementaryOperators\">.^</a>v)&nbsp;</p></td>
<td><p>dissociation constant</p></td>
</tr>
<tr>
<td><p>&Delta;<sub>r</sub>G = &sum; (v<sub>i</sub> &middot; &Delta;<sub>f</sub>G<sub>i</sub>) = &Delta;<sub>r</sub>H - T&middot;&Delta;<sub>r</sub>S = -R&middot;T&middot;<a href=\"modelica://ModelicaReference.Operators.'log()'\">log</a>(K) </p></td>
<td><p>molar Gibb&apos;s energy of the reaction</p></td>
</tr>
<tr>
<td><p>&Delta;<sub>r</sub>H = &sum; (v<sub>i</sub> &middot; &Delta;<sub>f</sub>H<sub>i</sub>) </p></td>
<td><p>molar enthalpy of the reaction</p></td>
</tr>
<tr>
<td><p>&Delta;<sub>r</sub>S = &sum; (v<sub>i</sub> &middot; &Delta;<sub>f</sub>S<sub>i</sub>) = <a href=\"modelica://Modelica.Constants\">k</a>&middot;<a href=\"modelica://ModelicaReference.Operators.'log()'\">log</a>(&Delta;<sub>r</sub>&omega;) </p></td>
<td><p>molar entropy of the reaction</p></td>
</tr>
</table>
<h4><span style=\"color:#008000\">Notations</span></h4>
<table cellspacing=\"2\" cellpadding=\"0\" border=\"0\"><tr>
<td><p>A<sub>i</sub></p></td>
<td><p>i-th substance</p></td>
</tr>
<tr>
<td><p>v<sub>i</sub></p></td>
<td><p>stochiometric coefficients of i-th substance</p></td>
</tr>
<tr>
<td><p>K</p></td>
<td><p>dissociation constant (activity based)</p></td>
</tr>
<tr>
<td><p>a(A<sub>i</sub>)=f<sub>i</sub>*x<sub>i</sub></p></td>
<td><p>activity of the substance A</p></td>
</tr>
<tr>
<td><p>f<sub>i</sub></p></td>
<td><p>activity coefficient of the substance A</p></td>
</tr>
<tr>
<td><p>x<sub>i</sub></p></td>
<td><p>mole fraction of the substance A</p></td>
</tr>
<tr>
<td><p>&Delta;<sub>f</sub>H<sub>i</sub></p></td>
<td><p>molar enthalpy of formation of i-th substance</p></td>
</tr>
<tr>
<td><p>&Delta;<sub>f</sub>G<sub>i</sub></p></td>
<td><p>molar Gibbs energy of formation of i-th substance</p></td>
</tr>
<tr>
<td><p>&Delta;<sub>f</sub>S<sub>i</sub></p></td>
<td><p>molar entropy of formation of i-th substance</p></td>
</tr>
<tr>
<td><p>&Delta;<sub>r</sub>&omega;</p></td>
<td><p>change of number of microstates of particles by reaction</p></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</table>
</html>"));
end Reaction;
end Processes;
Loading

0 comments on commit 9633aa5

Please sign in to comment.