Thermodynamics with ASCEND: Difference between revisions
No edit summary |
|||
| (22 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
The ASCEND [[ModelLibrary]] includes a range of models for dealing with chemical and physical properties of materials, phase equilibrium, and reaction kinetics. | The ASCEND [[ModelLibrary]] includes a range of models for dealing with chemical and physical properties of materials, phase equilibrium, and reaction kinetics. | ||
We have a brief 'HOW TO' guide for doing thermodynamics calculations with ASCEND, thanks for [http://pedro.valelima.com/phd/ Pedro Vale Lima], here: [[Media:Howto_thermo.pdf|howto_thermo.pdf]]. The following text is our partial (ongoing) transcription of that document into wikitext. | We have a brief 'HOW TO' guide for doing thermodynamics calculations with ASCEND, thanks for [http://pedro.valelima.com/phd/ Pedro Vale Lima], here: [[Media:Howto_thermo.pdf|howto_thermo.pdf]]. ''The following text is our partial (ongoing) transcription of that document into wikitext.'' The same ASCEND thermodynamics library is also covered in Chapter 11 of the [[Media:Book.pdf|ASCEND user's manual]]. | ||
In addition to the methods described in this page, there are other ways of calculating thermodynamic properties using ASCEND. See [[FPROPS]] and [[freesteam]] for example. | In addition to the methods described in this page, there are other ways of calculating thermodynamic properties using ASCEND. See [[FPROPS]] and [[freesteam]] for example. | ||
| Line 24: | Line 23: | ||
Here is the meaning of the constants that are used in the components models: | Here is the meaning of the constants that are used in the components models: | ||
{| | {| border="1" cellpadding="3" cellspacing="0" | ||
|- | |- | ||
! constant | ! constant || meaning | ||
|- | |- | ||
| rpp_index | Index in the Reid et al book | | rpp_index || Index in the Reid et al book | ||
|- | |- | ||
| formula | Chemical formula (optional, informational only) | | formula || Chemical formula (optional, informational only) | ||
|- | |- | ||
| subgroups | Component subgroups for the [[UNIFAC model]]. | | subgroups || Component subgroups for the [[UNIFAC model]]. | ||
|- | |- | ||
| wilson_set | Wilson groups for the [[Wilson liquid model]]. | | wilson_set || Wilson groups for the [[Wilson liquid model]]. | ||
|- | |- | ||
| mw | Molecular weight | | mw || Molecular weight | ||
|- | |- | ||
| Tb | Boiling-point temperature (at what pressure??) | | Tb || Boiling-point temperature (at what pressure??) | ||
|- | |- | ||
| Tc | Temperature at critical point | | Tc || Temperature at critical point | ||
|- | |- | ||
| Pc | Pressure at critical point | | Pc || Pressure at critical point | ||
|- | |- | ||
| Vc | (Molar?) volume at critical point | | Vc || (Molar?) volume at critical point | ||
|- | |- | ||
| Zc | Compressibility factor at critical point. | | Zc || Compressibility factor at critical point. | ||
|- | |- | ||
| omega | Pitzer acentric factor | | omega || Pitzer acentric factor | ||
|- | |- | ||
| cpvap''a..d'' | Constants for vapour-phase < | | cpvap''a..d'' || Constants for vapour-phase <math>c_p</math> calculation. | ||
<math>c_p = a + bT +c T^2 + d T^3</math>. | |||
|- | |- | ||
| Hf | Enthalpy of formation | | Hf || Enthalpy of formation | ||
|- | |- | ||
| Gf | Gibbs free energy of formation | | Gf || Gibbs free energy of formation | ||
|- | |- | ||
| vp''a..d'' | Constants for vapour pressure calculation (three equations can be used) | | vp''a..d'' || Constants for vapour pressure calculation (three equations can be used) | ||
|- | |- | ||
| vp_correlation | Number that represents which correlation is used for calculation of vapour pressure | | vp_correlation || Number that represents which correlation is used for calculation of vapour pressure | ||
|- | |- | ||
| Hv | Enthalpy of vapourisation | | Hv || Enthalpy of vapourisation | ||
|- | |- | ||
| lden | Liquid density | | lden || Liquid density | ||
|- | |- | ||
| Tliq | Temperature at which the liquid density (lden) is specified. | | Tliq || Temperature at which the liquid density (lden) is specified. | ||
|} | |} | ||
Finally, add the name of your new component in the check list of <tt>components</tt> model: | Finally, add the name of your new component in the check list of <tt>components</tt> model: | ||
| Line 85: | Line 80: | ||
The ASCEND thermodynamics library has two models for vapour components ('''<tt>ideal_vapour_component</tt>''' and '''<tt>Pitzer_vapor_component</tt>''') and one model for liquid components ('''<tt>Rackett_liquid_component</tt>'''). All these models are similar in concept; only the EOS changes. We'll use the ideal vapour model to illustrate the main concepts. | The ASCEND thermodynamics library has two models for vapour components ('''<tt>ideal_vapour_component</tt>''' and '''<tt>Pitzer_vapor_component</tt>''') and one model for liquid components ('''<tt>Rackett_liquid_component</tt>'''). All these models are similar in concept; only the EOS changes. We'll use the ideal vapour model to illustrate the main concepts. | ||
The model defines the equations needed to calculate the molar volume <math>{\bar v}</math>, enthalpy <math>{\bar h}</math> and Gibbs free energy <math>{\bar g}</math>, based on the temperature <math>T</math>, pressure <math>p</math> and component properties. | |||
The model defines the equations needed to calculate the molar volume <math>{\bar v}</math>, enthalpy <math>{\bar h}</math> and Gibbs free energy <math>{\bar g}</math>, based on the temperature < | |||
The first equation needed by the ideal gas model is the well known equation of state, | The first equation needed by the ideal gas model is the well known equation of state, | ||
:<math>p{\bar v}={\bar R}T</math> | {{eq|:|<math>p{\bar v}={\bar R}T</math>|1}} | ||
where <math>{\bar R}</math> is the ideal gas constant. To define <math>{\bar h}</math>, one can use the constant-pressure molar heat capacity, <math>{\bar c}_p</math>. The heat capacity is define implicitly as a polynomial function of temperature: | where <math>{\bar R}</math> is the ideal gas constant. To define <math>{\bar h}</math>, one can use the constant-pressure molar heat capacity, <math>{\bar c}_p</math>. The heat capacity is define implicitly as a polynomial function of temperature: | ||
{{eq|:|<math>{\bar c}_p = a + b T + c T^2 + d T^3</math>|2}} | |||
:<math>{\bar c}_p = a + b T + c T^2 + d T^3</math> | |||
where ''a'', ''b'', ''c'', and ''d'' are defined (as <tt>cpvap''a..d''</tt>) in the components data file. Remembering that, for an ideal gas, <math>{\bar h}</math> is defined as | where ''a'', ''b'', ''c'', and ''d'' are defined (as <tt>cpvap''a..d''</tt>) in the components data file. Remembering that, for an ideal gas, <math>{\bar h}</math> is defined as | ||
{{eq|:|<math>{\bar h} - {\bar h}_0 = \int_{T_0}^{T} {\bar c}_p dT</math>|3}} | |||
:<math>{\bar h} - {\bar h}_0 = \int_{T_0}^{T} {\bar c}_p dT</math> | |||
results in the following explicit equation for <math>{\bar h}</math>: | results in the following explicit equation for <math>{\bar h}</math>: | ||
:<math>{\bar h} = {\bar h}_0 + a (T-T_0) + \frac{1}{2}{b (T^2 - T_0^2)} + \frac{1}{3}c (T^3 - T_0^3) + \frac{1}{4}d (T^4 - T_0^4)</math> | {{eq|:|<math>{\bar h} = {\bar h}_0 + a (T-T_0) + \frac{1}{2}{b (T^2 - T_0^2)} + \frac{1}{3}c (T^3 - T_0^3) + \frac{1}{4}d (T^4 - T_0^4)</math>|4}} | ||
Note that, if it were ''not'' an ideal gas, <math>{\bar h}</math> would also depend on <span class="texhtml">''p''</span>. Looking back again to your old thermodynamics textbook, it can then be proven that | Note that, if it were ''not'' an ideal gas, <math>{\bar h}</math> would also depend on <span class="texhtml">''p''</span>. Looking back again to your old thermodynamics textbook, it can then be proven that | ||
:<math>d ( \frac{\bar g}{{\bar R}T} ) = \frac{\bar v}{{\bar R}T} dp - \frac{\bar h}{{\bar R}T^2}dT</math> | {{eq|:|<math>d ( \frac{\bar g}{{\bar R}T} ) = \frac{\bar v}{{\bar R}T} dp - \frac{\bar h}{{\bar R}T^2}dT</math>|5}} | ||
Substitution of equations 1 and 4 on equation 5 followed by equation yields an equation for <math>{\bar g}</math> with the form | Substitution of equations 1 and 4 on equation 5 followed by equation yields an equation for <math>{\bar g}</math> with the form | ||
:<math>\bar g = {\bar g}(p,T)</math> | {{eq|:|<math>\bar g = {\bar g}(p,T)</math>|6}} | ||
As a summary, this model has three equations ({{eqref|1}}, {{eqref|4}}, {{eqref|6}}), and five variables (<math>p</math>, <math>T</math>, <math>\bar g</math>, <math>\bar h</math>, <math>\bar v</math>). | |||
=== ASCEND implementation === | === ASCEND implementation === | ||
| Line 146: | Line 125: | ||
The [[Object-oriented_modelling|parametric model declaration]] above tells you that if you want to instantiate an 'ideal_vapor_component', then you need to first declare variables for pressure 'P' and temperature 'T', as well as the thermodynamic data 'data'. Hence, we can create out little model for evaluating these properties as follows: | The [[Object-oriented_modelling|parametric model declaration]] above tells you that if you want to instantiate an 'ideal_vapor_component', then you need to first declare variables for pressure 'P' and temperature 'T', as well as the thermodynamic data 'data'. Hence, we can create out little model for evaluating these properties as follows: | ||
<source lang="a4c">(* Simple example for vapour properties of water from ideal gas equation *) | <source lang="a4c">(* Simple example for vapour properties of water from ideal gas equation *) | ||
REQUIRE | REQUIRE "thermodynamics.a4l"; | ||
REQUIRE | REQUIRE "johnpye/thermo_types.a4c"; | ||
MODEL my_props; | MODEL my_props; | ||
| Line 183: | Line 161: | ||
We can now use this model to solve a simple example problem: | We can now use this model to solve a simple example problem: | ||
=== Example 1 === | === Example 1 === | ||
| Line 216: | Line 192: | ||
END example_1;</source> | END example_1;</source> | ||
This model gives the result that the change in molar enthalpy <math>\Delta {\bar h}</math> (which in the model we call 'dh_m') is equal to 3.4902 kJ/kmol. And we calculate the change in specific enthalpy < | This model gives the result that the change in molar enthalpy <math>\Delta {\bar h}</math> (which in the model we call 'dh_m') is equal to 3.4902 kJ/kmol. And we calculate the change in specific enthalpy <math>\Delta h</math> to be 193.74 kJ/kg. This value compares fairly well with values from steam tables: for this process, Heywood gives <math>\Delta h</math> = 199 kJ/kg, so the error is ~3%. | ||
The standard model for liquid components in ASCEND ('''<tt>Rackett_liquid_component</tt>''') has one slight difference from the vapour model present. As the enthalpy and free energy depend on knowledge of the vapor pressure, there is an additional equation with the correlation to calculate this value. You still have two degrees of freedom, but now you have six variables and four equations. | The standard model for liquid components in ASCEND ('''<tt>Rackett_liquid_component</tt>''') has one slight difference from the vapour model present. As the enthalpy and free energy depend on knowledge of the vapor pressure, there is an additional equation with the correlation to calculate this value. You still have two degrees of freedom, but now you have six variables and four equations. | ||
=== Example 2 === | === Example 2 === | ||
| Line 265: | Line 239: | ||
Solving this model gives the result that <span class="texhtml">''T''</span> = 373.14 K, which is close enough (0.014 K) to the expected value of 100 °C or 273.15 K. | Solving this model gives the result that <span class="texhtml">''T''</span> = 373.14 K, which is close enough (0.014 K) to the expected value of 100 °C or 273.15 K. | ||
== Mixtures == | == Mixtures == | ||
| Line 272: | Line 245: | ||
To understand this model, we present an example. Suppose you have a mixture of two components and want to calculate the molar volume. For each component you first calculate the molar volume for each pure species <math>{\bar v}_i^p</math>, where <span class="texhtml">''i''</span> is the index for the component, and <span class="texhtml">''p''</span> signifies 'pure'), using the models from the previous section. Then you calculate the molar volume for the species ''in the mixture'', <math>{\bar v}_i</math>, assuming some model for the mixing. At last, the molar volume is the sum of all species contributions weighted by the molar fraction of the species in the mixture. | To understand this model, we present an example. Suppose you have a mixture of two components and want to calculate the molar volume. For each component you first calculate the molar volume for each pure species <math>{\bar v}_i^p</math>, where <span class="texhtml">''i''</span> is the index for the component, and <span class="texhtml">''p''</span> signifies 'pure'), using the models from the previous section. Then you calculate the molar volume for the species ''in the mixture'', <math>{\bar v}_i</math>, assuming some model for the mixing. At last, the molar volume is the sum of all species contributions weighted by the molar fraction of the species in the mixture. | ||
For example, for an ideal gas mixture, we would have the following: | For example, for an ideal gas mixture, we would have the following: | ||
:<math>p {\bar v}_i^p = {\bar R} T</math> | {{eq|:|<math>p {\bar v}_i^p = {\bar R} T</math>|7}} | ||
{{eq|:|<math>{\bar v}_i = {\bar v}_i^p</math>|8}} | |||
{{eq|:|<math>{\bar v} = \sum_i {y_i {\bar v}_i}</math>|9}} | |||
The first equation comes from the <tt>ideal_vapor_component</tt> model (and there is one such equation for each component in the mixture). The second equation comes from the <tt>ideal_vapor_mixture</tt> model (again, one for each component). The last one is generic for all mixture models (and is part of the <tt>phase_partials</tt> model from which all mixture models are inherited). | The first equation comes from the <tt>ideal_vapor_component</tt> model (and there is one such equation for each component in the mixture). The second equation comes from the <tt>ideal_vapor_mixture</tt> model (again, one for each component). The last one is generic for all mixture models (and is part of the <tt>phase_partials</tt> model from which all mixture models are inherited). | ||
| Line 288: | Line 258: | ||
The same concepts apply to enthalpy and Gibbs free energy. The equations for ideal vapour mixing and mixture calculation are the following: | The same concepts apply to enthalpy and Gibbs free energy. The equations for ideal vapour mixing and mixture calculation are the following: | ||
{{eq|:|<math>p {\bar h}_i^p = {\bar h}_i^p</math>|10}} | |||
{{eq|:|<math>{\bar h} = \sum_i {y_i {\bar h}_i}</math>|11}} | |||
:<math>{\bar h} = \sum_i {y_i {\bar h}_i}</math> | |||
{{eq|:|<math>{\bar g}_i = {\bar g}_i^p + {\bar R} T \ln(y_i)</math>|12}} | |||
{{eq|:|<math>{\bar g} = \sum_i {y_i {\bar g}_i}</math>|13}} | |||
This model has one extra special equation whose meaning will be easier to understand after talking about phase equilibria: | This model has one extra special equation whose meaning will be easier to understand after talking about phase equilibria: | ||
{{eq|:|<math>\sum_{i} {y_i + s = 1}</math>|14}} | |||
{| | |||
This equation introduces a new variable <span class="texhtml">''s''</span> called <tt>slack_PhaseDisappearance</tt>. With this formulation of the molar fraction sum, when <span class="texhtml">''s''</span> is fixed at 0, normal calculations are performed; when <span class="texhtml">''s''</span> is free, if the phase ceases to exist, <span class="texhtml">''s''</span> will be different from zero but simulation can continue. It's a clever and important trick for multi-phase equilibria. We will return to this issue later. | This equation introduces a new variable <span class="texhtml">''s''</span> called <tt>slack_PhaseDisappearance</tt>. With this formulation of the molar fraction sum, when <span class="texhtml">''s''</span> is fixed at 0, normal calculations are performed; when <span class="texhtml">''s''</span> is free, if the phase ceases to exist, <span class="texhtml">''s''</span> will be different from zero but simulation can continue. It's a clever and important trick for multi-phase equilibria. We will return to this issue later. | ||
To review the variables and equations present in an idea gas mixture, note that for <span class="texhtml">''n''</span> components, we have <span class="texhtml">3''n''</span> ideal vapour component equations, and <span class="texhtml">3''n'' + 4</span> mixture equations. As far as variables, we have these values for the overall mixture: p, T, h, v, g,s ; then we have these values for each component: (FIXME). | To review the variables and equations present in an idea gas mixture, note that for <span class="texhtml">''n''</span> components, we have <span class="texhtml">3''n''</span> ideal vapour component equations, and <span class="texhtml">3''n'' + 4</span> mixture equations. As far as variables, we have these values for the overall mixture: p, T, h, v, g,s ; then we have these values for each component: (FIXME). | ||
Just a minor warning: when using models where <span class="texhtml">''n'' − 1</span> components are fixed, usually the un-fixed one is the 'reference component'. But be sure to check this and save yourself some trouble later. Let's see this mixture code in action now. | Just a minor warning: when using models where <span class="texhtml">''n'' − 1</span> components are fixed, usually the un-fixed one is the 'reference component'. But be sure to check this and save yourself some trouble later. Let's see this mixture code in action now. | ||
=== Example 3 === | === Example 3 === | ||
| Line 375: | Line 330: | ||
This gives us the slightly different result of <math>\Delta {\bar h}</math> = 5.724 kJ/mol. | This gives us the slightly different result of <math>\Delta {\bar h}</math> = 5.724 kJ/mol. | ||
=== Liquid mixtures === | === Liquid mixtures === | ||
For mixtures involving liquids, ASCEND provides the [http://en.wikipedia.org/wiki/UNIFAC UNIFAC] mixture model, which is used together with the Rackett model for liquid properties. The number of equations in the UNIFAC model depends on the number of 'UNIFAC groups', <span class="texhtml">''l''</span>. For a mixture of <span class="texhtml">''n''</span> components, we end up with <span class="texhtml">9''n'' + 2''l'' + 4</span> equations and <span class="texhtml">10''n'' + 2''l'' + 6</span> variables, requiring us to fix <span class="texhtml">''n'' + 2</span> of those variables. | For mixtures involving liquids, ASCEND provides the [http://en.wikipedia.org/wiki/UNIFAC UNIFAC] mixture model, which is used together with the Rackett model for liquid properties. The number of equations in the UNIFAC model depends on the number of 'UNIFAC groups', <span class="texhtml">''l''</span>. For a mixture of <span class="texhtml">''n''</span> components, we end up with <span class="texhtml">9''n'' + 2''l'' + 4</span> equations and <span class="texhtml">10''n'' + 2''l'' + 6</span> variables, requiring us to fix <span class="texhtml">''n'' + 2</span> of those variables. | ||
== Phase Equilibria == | == Phase Equilibria == | ||
| Line 388: | Line 340: | ||
To model phase equilibria, one uses the '''<tt>thermodynamics</tt>''' model in the library. This model is the generic model for thermodynamics calculations, in that it can be used both for phase equilibria as well as for just single component properties or multi-phase mixtures. Of course, if you do choose to use the <tt>thermodynamics</tt> model for these simpler cases then you will be carrying around some unnecessary and redundant equations, but that's a price you might choose to pay for flexibility. The model has a generic interface and equilibrium relations that are only used for systems with at least two phases. | To model phase equilibria, one uses the '''<tt>thermodynamics</tt>''' model in the library. This model is the generic model for thermodynamics calculations, in that it can be used both for phase equilibria as well as for just single component properties or multi-phase mixtures. Of course, if you do choose to use the <tt>thermodynamics</tt> model for these simpler cases then you will be carrying around some unnecessary and redundant equations, but that's a price you might choose to pay for flexibility. The model has a generic interface and equilibrium relations that are only used for systems with at least two phases. | ||
=== Generic interface === | === Generic interface === | ||
| Line 394: | Line 345: | ||
As mixtures are models that group simple components, phase equilibria groups the same mixture at different phases. By defining <span class="texhtml">γ<sup>''j''</sup></span> to be the molar fraction of phase <span class="texhtml">''j''</span> we have the usual fraction relation: | As mixtures are models that group simple components, phase equilibria groups the same mixture at different phases. By defining <span class="texhtml">γ<sup>''j''</sup></span> to be the molar fraction of phase <span class="texhtml">''j''</span> we have the usual fraction relation: | ||
:<math>\sum_{i=1}^n{\gamma^j} = 1</math> | {{eq|:|<math>\sum_{i=1}^n{\gamma^j} = 1</math>|15}} | ||
Now you must have another three equations to account for the phases: | Now you must have another three equations to account for the phases: | ||
:<math>{\bar v}^p = \sum_i{\gamma^i {\bar v}^i}</math> | {{eq|:|<math>{\bar v}^p = \sum_i{\gamma^i {\bar v}^i}</math>|16}} | ||
{{eq|:|<math>{\bar h}^p = \sum_i{\gamma^i {\bar h}^i}</math>|17}} | |||
{{eq|:|<math>{\bar g}^p = \sum_i{\gamma^i {\bar g}^i}</math>|18}} | |||
where <math>{\bar v}^p</math>, <math>{\bar h}^p</math>, <math>{\bar g}^p</math> are the mixture properties defined by equations 8, 11 and 13 for each phase. | where <math>{\bar v}^p</math>, <math>{\bar h}^p</math>, <math>{\bar g}^p</math> are the mixture properties defined by equations 8, 11 and 13 for each phase. | ||
Another group of equations (one for each component) are needed to define a global fraction for a component. | Another group of equations (one for each component) are needed to define a global fraction for a component. | ||
:<math>y_i = \sum_p {\gamma^p y_i^p}</math> | {{eq|:|<math>y_i = \sum_p {\gamma^p y_i^p}</math>|19}} | ||
=== Relative volatility model === | === Relative volatility model === | ||
| Line 421: | Line 365: | ||
This model has extra equations for multi-phase systems in equilibrium. The first group just equates pressures and temperature on all phases to the ones in the reference phase. | This model has extra equations for multi-phase systems in equilibrium. The first group just equates pressures and temperature on all phases to the ones in the reference phase. | ||
:< | {{eq|:|<math>p^j = p^{ref}</math>|20}} | ||
{{eq|:|<math>T^j = T^{ref}</math>|21}} | |||
This accounts for <span class="texhtml">''m'' − 1</span> equations where <span class="texhtml">''m''</span> is the number of phases (the reference phase is excluded). | This accounts for <span class="texhtml">''m'' − 1</span> equations where <span class="texhtml">''m''</span> is the number of phases (the reference phase is excluded). | ||
Now, recall the variable <span class="texhtml">''s''</span>, a.k.a. <tt>slack_PhaseDisappearance</tt>. There is one of these for each mixture. One problem with multiphase models is that models are written thinking of the existence of a phase, and if by some thermodynamics change the phase ceases to exist the equations become invalid. By using the following equation for each phase | Now, recall the variable <span class="texhtml">''s''</span>, a.k.a. <tt>slack_PhaseDisappearance</tt>. There is one of these for each mixture. One problem with multiphase models is that models are written thinking of the existence of a phase, and if by some thermodynamics change the phase ceases to exist the equations become invalid. By using the following equation for each phase | ||
:< | {{eq|:|<math>s^j = \gamma^j</math>|22}} | ||
It's possible for a phase to ''disappear''. If <math>\gamma^j</math> is not null, which means the phase exists, then <span class="texhtml">''s''<sup>''j''</sup></span> must be zero and by the already-presented relation <math>\sum_{i}{y_i + s} = 1</math> the mixture properties must be properly calculated. On the other hand, if <math>\gamma^j</math> becomes zero then <math>s^j</math> can be relaxed and the model continues to bee solved without regard for that mixture. | |||
The library can be used to perform just <math>T</math> and <math>p</math> equilibrium and fractions are computed by specification of relative volatilities. This kind of equilibrium is easier to compute and can be used as a first guess to solve the full equilibrium. | |||
The library can be used to perform just < | |||
The following set of equations is a special representation of relative volatilities | The following set of equations is a special representation of relative volatilities | ||
:<math>{\bar \alpha}^j y_i^j = {\bar \alpha}_i^j y_i^{\mathrm{ref}}</math> | {{eq|:|<math>{\bar \alpha}^j y_i^j = {\bar \alpha}_i^j y_i^{\mathrm{ref}}</math>|23}} | ||
where <math>j=1,..n_{\mathrm{phases}} - 1</math>, and <math>i = 1,..n_{\mathrm{components}}</math>. To make it easier to understand the goal of this representation let's see what these equations represent for a two phase system (V,L) of the two components (A,B). | |||
:<math>{\bar \alpha} | {{eq|:|<math>{\bar \alpha} y_A^V = \alpha_A^V y_A^L</math>|24}} | ||
{{eq|:|<math>{\bar \alpha} y_B^V = \alpha_B^V y_B^L</math>|25}} | |||
in the relative volatility model you fix the <math>\alpha</math> values and compute the <math>\bar \alpha</math>. Note that <math>\alpha_A^V / {\bar \alpha}</math> will be a K-value. Before seeing the model in action let's do some accounting. To simplify, we suppose a two-phase system, since ASCEND is not yet able to compute liquid-liquid models. | |||
'''FIXME: add the equation-counting table here.''' | |||
FIXME: add the equation-counting table here. | |||
=== Chemical potential equilibrium === | === Chemical potential equilibrium === | ||
| Line 473: | Line 397: | ||
In the full equilibrium model, the Gibbs free energy for each phase is equated. To choose full equilibrium, you should set the variable '''<tt>equilibrated</tt>''' to <tt>TRUE</tt>. | In the full equilibrium model, the Gibbs free energy for each phase is equated. To choose full equilibrium, you should set the variable '''<tt>equilibrated</tt>''' to <tt>TRUE</tt>. | ||
:<math>{\bar g}_i^j = {\bar g}_i^{\mathrm{ref}}</math> | {{eq|:|<math>{\bar g}_i^j = {\bar g}_i^{\mathrm{ref}}</math>|26}} | ||
for each partial component and each phase except the reference one. | for each partial component and each phase except the reference one. | ||
When using this model <math>\bar \alpha</math> is fixed and equal to one and the < | When using this model <math>\bar \alpha</math> is fixed and equal to one and the <math>\alpha</math>'s are released and computed by equation 23. This equation becomes a computation of K-values. Now let's see the infamous accounting table for this model. | ||
FIXME equation-counting for VL-equilibrium G-model. | FIXME equation-counting for VL-equilibrium G-model. | ||
Now let's look at some more examples. | Now let's look at some more examples. | ||
=== Example 4 === | === Example 4 === | ||
| Line 525: | Line 446: | ||
END howto_thermo_ex8;</source> | END howto_thermo_ex8;</source> | ||
Use of the thermodynamics model is slightly more complex. First, you should define the components data, then you choose the models for the phases with the <tt>phases_data</tt> model. This model's first parameter is a phase definition (it can be <tt>V</tt>, <tt>L</tt> | Use of the thermodynamics model is slightly more complex. First, you should define the components data, then you choose the models for the phases with the <tt>phases_data</tt> model. This model's first parameter is a phase definition (it can be <tt>'V'</tt>, <tt>'L'</tt> or <tt>'VL'</tt>), then the name for the vapour model (or <tt>none</tt> if there's not vapour phase), and then the liquid model name. The last parameter is for a second liquid phase model when <tt>'LL'</tt> equilibrium is implemented; for now, you should just use <tt>none</tt>. | ||
The <tt>select_mixture_type</tt> model builds the chosen models so that they can be sent to the main thermodynamic model as a parameter. This may seem complicated at first, but as you probable will never need to change that piece of code, you don't need to worry about it too much. Just peek at the library code when you feel brave enough. | The <tt>select_mixture_type</tt> model builds the chosen models so that they can be sent to the main thermodynamic model as a parameter. This may seem complicated at first, but as you probable will never need to change that piece of code, you don't need to worry about it too much. Just peek at the library code when you feel brave enough. | ||
| Line 534: | Line 454: | ||
When solving multi-phase models you should always check <tt>state.slack_PhaseDisappearance</tt>. Only if it's zero the phase exists. Sometimes you can get strange results if you're looking at properties of a non-existent phase. | When solving multi-phase models you should always check <tt>state.slack_PhaseDisappearance</tt>. Only if it's zero the phase exists. Sometimes you can get strange results if you're looking at properties of a non-existent phase. | ||
If you run the model, you'll get only a liquid phase and < | If you run the model, you'll get only a liquid phase and <math>\bar h</math> = -282.351 kJ/mol. With <math>T</math> = 400 K, you'll get <math>\bar h</math> = -233.022 kJ/mol, and so <math>\Delta \bar h</math> = 49.329 kJ/mol. | ||
=== Example 5 === | === Example 5 === | ||
| Line 542: | Line 460: | ||
'''Build the VL equilibrium chart for water-ethanol at atmospheric pressure.''' | '''Build the VL equilibrium chart for water-ethanol at atmospheric pressure.''' | ||
The model presented in the last example specifies < | The model presented in the last example specifies <math>p</math> and <math>T</math>. To build an equilibrium chart, it's better to specify <math>p</math> and a mole fraction, and to free <math>T</math>. That way, we can be sure to have an equilibrium. The following method, added to the last example model, uses that trick. We'll also use the Pitzer vapour model, in the hope of improving accuracy. | ||
<source lang="a4c">MODEL howto_thermo_ex9 REFINES cmumodel; | <source lang="a4c">MODEL howto_thermo_ex9 REFINES cmumodel; | ||
| Line 563: | Line 480: | ||
state.P := 1 {atm}; | state.P := 1 {atm}; | ||
state.y['ethanol'] | state.y['ethanol'] := 0.5; | ||
state.phase['liquid1'].y['water'] | state.phase['liquid1'].y['water'] := 0.6; | ||
END reset_Px; | END reset_Px; | ||
| Line 571: | Line 488: | ||
Now, instead of calling <tt>reset</tt> and <tt>values</tt> just run <tt>reset_Px</tt>. We'll run the model several times and build a table like the following: | Now, instead of calling <tt>reset</tt> and <tt>values</tt> just run <tt>reset_Px</tt>. We'll run the model several times and build a table like the following: | ||
{| class="wikitable" | {| class="wikitable" | ||
| Line 577: | Line 493: | ||
! <math>y_w^L</math> | ! <math>y_w^L</math> | ||
! <math>y_w^V</math> | ! <math>y_w^V</math> | ||
! < | ! <math>T</math> / [K] | ||
|- | |- | ||
| 0.99 | | 0.99 | ||
| Line 600: | Line 516: | ||
When building the table, you must take some care for a phase not to disappear. You can do that by changing the variable <tt>state.phase['liquid1'].y['water']</tt>. | When building the table, you must take some care for a phase not to disappear. You can do that by changing the variable <tt>state.phase['liquid1'].y['water']</tt>. | ||
[[Category:Documentation]] | |||
[[Category:Examples]] | [[Category:Examples]] | ||
Latest revision as of 00:33, 10 April 2012
The ASCEND ModelLibrary includes a range of models for dealing with chemical and physical properties of materials, phase equilibrium, and reaction kinetics.
We have a brief 'HOW TO' guide for doing thermodynamics calculations with ASCEND, thanks for Pedro Vale Lima, here: howto_thermo.pdf. The following text is our partial (ongoing) transcription of that document into wikitext. The same ASCEND thermodynamics library is also covered in Chapter 11 of the ASCEND user's manual.
In addition to the methods described in this page, there are other ways of calculating thermodynamic properties using ASCEND. See FPROPS and freesteam for example.
You can access the models from the HOW TO in the ModelLibrary as models/thermodynamics_example.a4c.
Physical property data
Physical property data from the book Reid, Prausnitz & Polling, The Properties of Gases and Liquids, 4th Ed.,McGraw-Hill, 1987, are included in the ASCEND model file models/components.a4l.
To add support for a new fluid component, it is suggested that you create your own copy of that file, and add some new code. First add your component to the supported_components list:
supported_components :== [ 'hydrogen' ,'carbon_dioxide' ,(* add another one here *) ];
Then, add a CASE in the SWITCH statement to define the constants for your particular substance:
CASE 'my_new_substance': rpp_index :== 111; (* add your data here... *)
Here is the meaning of the constants that are used in the components models:
| constant | meaning |
|---|---|
| rpp_index | Index in the Reid et al book |
| formula | Chemical formula (optional, informational only) |
| subgroups | Component subgroups for the UNIFAC model. |
| wilson_set | Wilson groups for the Wilson liquid model. |
| mw | Molecular weight |
| Tb | Boiling-point temperature (at what pressure??) |
| Tc | Temperature at critical point |
| Pc | Pressure at critical point |
| Vc | (Molar?) volume at critical point |
| Zc | Compressibility factor at critical point. |
| omega | Pitzer acentric factor |
| cpvapa..d | Constants for vapour-phase <math>c_p</math> calculation.
<math>c_p = a + bT +c T^2 + d T^3</math>. |
| Hf | Enthalpy of formation |
| Gf | Gibbs free energy of formation |
| vpa..d | Constants for vapour pressure calculation (three equations can be used) |
| vp_correlation | Number that represents which correlation is used for calculation of vapour pressure |
| Hv | Enthalpy of vapourisation |
| lden | Liquid density |
| Tliq | Temperature at which the liquid density (lden) is specified. |
Finally, add the name of your new component in the check list of components model:
FOR i IN components DO ASSERT (i IN ['hydrogen', 'carbon_dioxide' (* others here *)) == TRUE; END FOR;
Calculating properties for a single component
The simples state to model is the one that represents a single component in a single phase. To elaborate this model, one needs an equation of state (EOS). As there is no universal equation of state, the thermodynamic libraries in ASCEND contain several models, and leave the decision about which one to use up to the user.
The ASCEND thermodynamics library has two models for vapour components (ideal_vapour_component and Pitzer_vapor_component) and one model for liquid components (Rackett_liquid_component). All these models are similar in concept; only the EOS changes. We'll use the ideal vapour model to illustrate the main concepts.
The model defines the equations needed to calculate the molar volume <math>{\bar v}</math>, enthalpy <math>{\bar h}</math> and Gibbs free energy <math>{\bar g}</math>, based on the temperature <math>T</math>, pressure <math>p</math> and component properties.
The first equation needed by the ideal gas model is the well known equation of state,
- ([[#equation_{{{3}}}|{{{3}}}]])1
where <math>{\bar R}</math> is the ideal gas constant. To define <math>{\bar h}</math>, one can use the constant-pressure molar heat capacity, <math>{\bar c}_p</math>. The heat capacity is define implicitly as a polynomial function of temperature:
- ([[#equation_{{{3}}}|{{{3}}}]])2
where a, b, c, and d are defined (as cpvapa..d) in the components data file. Remembering that, for an ideal gas, <math>{\bar h}</math> is defined as
- ([[#equation_{{{3}}}|{{{3}}}]])3
results in the following explicit equation for <math>{\bar h}</math>:
- ([[#equation_{{{3}}}|{{{3}}}]])4
Note that, if it were not an ideal gas, <math>{\bar h}</math> would also depend on p. Looking back again to your old thermodynamics textbook, it can then be proven that
- ([[#equation_{{{3}}}|{{{3}}}]]){{{2}}}</math>. To make it easier to understand the goal of this representation let's see what these equations represent for a two phase system (V,L) of the two components (A,B).
- ([[#equation_{{{3}}}|{{{3}}}]])24
- ([[#equation_{{{3}}}|{{{3}}}]])25
in the relative volatility model you fix the <math>\alpha</math> values and compute the <math>\bar \alpha</math>. Note that <math>\alpha_A^V / {\bar \alpha}</math> will be a K-value. Before seeing the model in action let's do some accounting. To simplify, we suppose a two-phase system, since ASCEND is not yet able to compute liquid-liquid models.
FIXME: add the equation-counting table here.
Chemical potential equilibrium
In the full equilibrium model, the Gibbs free energy for each phase is equated. To choose full equilibrium, you should set the variable equilibrated to TRUE.
- ([[#equation_{{{3}}}|{{{3}}}]]){{{2}}}</math>|26}}
for each partial component and each phase except the reference one.
When using this model <math>\bar \alpha</math> is fixed and equal to one and the <math>\alpha</math>'s are released and computed by equation 23. This equation becomes a computation of K-values. Now let's see the infamous accounting table for this model.
FIXME equation-counting for VL-equilibrium G-model.
Now let's look at some more examples.
Example 4
Calculate the change of enthalpy for a 50% water, 50% ethanol being heated from 300 K to 400 K at constant atmospheric pressure.
This is a simple problem but it's useful for introducing the correct way to use the thermodynamics model.
MODEL howto_thermo_ex8 REFINES cmumodel; cd IS_A components_data(['water','ethanol'], 'water'); pd IS_A phases_data('VL', 'ideal_vapor_mixture', 'UNIFAC_liquid_mixture', 'none'); equilibrated IS_A boolean; phases ALIASES pd.phases; FOR j IN phases CREATE smt[j] IS_A select_mixture_type(cd, pd.phase_type[j]); END FOR; FOR j IN phases CREATE phase[j] ALIASES smt[j].phase; END FOR; state IS_A thermodynamics(cd, pd,phase, equilibrated); METHODS (* ... *) METHOD values; state.P := 1 {atm}; state.T := 300 {K}; state.y['ethanol'] := 0.5; equilibrated := TRUE; END values; (* ... *) END howto_thermo_ex8;
Use of the thermodynamics model is slightly more complex. First, you should define the components data, then you choose the models for the phases with the phases_data model. This model's first parameter is a phase definition (it can be 'V', 'L' or 'VL'), then the name for the vapour model (or none if there's not vapour phase), and then the liquid model name. The last parameter is for a second liquid phase model when 'LL' equilibrium is implemented; for now, you should just use none.
The select_mixture_type model builds the chosen models so that they can be sent to the main thermodynamic model as a parameter. This may seem complicated at first, but as you probable will never need to change that piece of code, you don't need to worry about it too much. Just peek at the library code when you feel brave enough.
The value definitions are very simple; just notice the newly introduced equilibrated variable.
When solving multi-phase models you should always check state.slack_PhaseDisappearance. Only if it's zero the phase exists. Sometimes you can get strange results if you're looking at properties of a non-existent phase.
If you run the model, you'll get only a liquid phase and <math>\bar h</math> = -282.351 kJ/mol. With <math>T</math> = 400 K, you'll get <math>\bar h</math> = -233.022 kJ/mol, and so <math>\Delta \bar h</math> = 49.329 kJ/mol.
Example 5
Build the VL equilibrium chart for water-ethanol at atmospheric pressure.
The model presented in the last example specifies <math>p</math> and <math>T</math>. To build an equilibrium chart, it's better to specify <math>p</math> and a mole fraction, and to free <math>T</math>. That way, we can be sure to have an equilibrium. The following method, added to the last example model, uses that trick. We'll also use the Pitzer vapour model, in the hope of improving accuracy.
MODEL howto_thermo_ex9 REFINES cmumodel; cd IS_A components_data(['water','ethanol'], 'water'); pd IS_A phases_data('VL', 'Pitzer_vapor_mixture', 'UNIFAC_liquid_mixture', 'none'); equilibrated IS_A boolean; phases ALIASES pd.phases; (*...*) METHOD reset_Px; equilibrated := TRUE; RUN state.specify; state.T.fixed := FALSE; state.phase['liquid1'].y['water'].fixed := TRUE; state.P := 1 {atm}; state.y['ethanol'] := 0.5; state.phase['liquid1'].y['water'] := 0.6; END reset_Px; END howto_thermo_ex9;
Now, instead of calling reset and values just run reset_Px. We'll run the model several times and build a table like the following:
| <math>y_w^L</math> | <math>y_w^V</math> | <math>T</math> / [K] |
|---|---|---|
| 0.99 | 0.8786 | 369.764 |
| 0.95 | 0.652 | 362.471 |
| 0.9 | 0.5517 | 358.80 |
| : | : | : |
When building the table, you must take some care for a phase not to disappear. You can do that by changing the variable state.phase['liquid1'].y['water'].