Release 1.2.1 Bryan W. Weber - ThermoState's documentation!

63
thermostate Documentation Release 1.2.1 Bryan W. Weber Jul 21, 2020

Transcript of Release 1.2.1 Bryan W. Weber - ThermoState's documentation!

thermostate DocumentationRelease 1.2.1

Bryan W. Weber

Jul 21, 2020

CONTENTS:

1 Installation 31.1 Conda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Pip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3 From Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Tutorial 52.1 Pint and Units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2 ThermoState . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.3 Other Common Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3 Examples 133.1 Air-Standard Brayton Cycle Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.2 Cold-Air Standard Brayton Cycle Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163.3 Diesel Cycle Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193.4 Rankine Cycle Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233.5 Regen-Reheat Rankine Cycle Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283.6 Cascade Refrigeration Cycle Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

4 ThermoState 374.1 thermostate.thermostate module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374.2 thermostate.abbreviations module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

5 Change Log 415.1 1.2.1 - 21-JUL-2020 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415.2 1.2.0 - 14-JUL-2020 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415.3 1.1.0 - 12-APR-2020 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425.4 1.0.0 - 03-MAR-2020 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425.5 0.5.3 - 04-MAR-2019 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435.6 0.5.2 - 01-FEB-2019 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435.7 0.5.1 - 05-JAN-2019 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435.8 0.5.0 - 23-OCT-2018 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445.9 0.4.2 - 21-SEP-2018 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445.10 0.4.1 - 21-SEP-2018 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455.11 0.4.0 - 21-SEP-2018 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455.12 0.3.0 - 09-JUL-2018 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455.13 0.2.4 - 08-JUL-2018 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465.14 0.2.3 - 24-SEP-2017 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465.15 0.2.2 - 13-APR-2017 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465.16 0.2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

i

5.17 0.2.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475.18 0.1.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475.19 0.1.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475.20 0.1.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485.21 0.1.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485.22 0.1.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485.23 0.1.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485.24 0.1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485.25 0.1.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

6 Contributor Covenant Code of Conduct 516.1 Our Pledge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516.2 Our Standards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516.3 Our Responsibilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516.4 Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526.5 Enforcement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526.6 Attribution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

7 Contributing 537.1 Bug Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537.2 Pull Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537.3 Meta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

8 Indices and tables 55

Python Module Index 57

Index 59

ii

thermostate Documentation, Release 1.2.1

ThermoState is a Python package that provides easy management of thermodynamic states of simple compressiblesystems. ThermoState relies on CoolProp and Pint to provide the equations of state and units handling, respectively.ThermoState replaces tables that are typically used in engineering courses to evaluate properties when solving for thebehavior of systems.

CONTENTS: 1

thermostate Documentation, Release 1.2.1

2 CONTENTS:

CHAPTER

ONE

INSTALLATION

1.1 Conda

The preferred installation method is to use conda. Using Conda, ThermoState can be installed for either Python 3.5,3.6, or 3.7. If you have an existing Conda environment with one of those Python versions, installing ThermoState canbe done by

conda install -c bryanwweber thermostate conda-forge::pint

This installs Pint from the conda-forge channel; if you would like to use another channel to install Pint, changethe conda-forge to be the name of the channel you prefer. If Pint is already installed in your environment, theconda-forge::pint can be omitted entirely.

If you do not have an environment with Python 3.6 or higher you can create a new environment with

conda create -n thermostate -c bryanwweber thermostate conda-forge::pint

1.2 Pip

Alternatively, ThermoState can be installed with pip.

pip install thermostate

1.3 From Source

ThermoState is a pure-Python package that supports any Python version 3.6 and higher. To install from source, clonethe source code repository and install using pip.

git clone https://github.com/bryanwweber/thermostatecd thermostatepip install .

3

thermostate Documentation, Release 1.2.1

4 Chapter 1. Installation

CHAPTER

TWO

TUTORIAL

This tutorial will guide you in the basic use of ThermoState. The ThermoState package is designed to ease theevaluation of thermodynamic properties for common substances used in Mechanical Engineering courses. Rather thanlooking up the information in a table and interpolating, we can input properties for the states directly, and all unknownvalues are automatically calculated.

ThermoState uses CoolProp and Pint to enable easy property evaluation in any unit system. The first thing we need todo is import the parts of ThermoState that we will use. This adds them to the set of local variables

[1]: from thermostate import State, Q_, units

2.1 Pint and Units

Now that the interface has been imported, we can create some properties. For instance, let’s say we’re given thepressure and temperature properties for water, and asked to determine the specific volume. First, let’s create variablesthat set the pressure and temperature. We will use the Pint Quantity function, which we have called Q_. The syntaxfor the Q_ function is Q_(value, 'units').

[2]: p_1 = Q_(101325, 'Pa')

We can use whatever units we’d like, Pint supports a wide variety of units.

[3]: p_1 = Q_(1.01325, 'bar')p_1 = Q_(14.7, 'psi')p_1 = Q_(1.0, 'atm')

Another way to specify the units is to use the units class that we imported. This class has a number of attributes(text following a period) that can be used to create a quantity with units by multiplying a number with the unit.

units.degR# ^^^^# This is the attribute

Let’s set the temperature now. The available units of temperature are degF (fahrenheit), degR (rankine),degC (celsius), and K (kelvin).

[4]: T_1 = 460*units.degRT_1 = 25*units.degCT_1 = 75*units.degFT_1 = 400*units.K

The two ways of creating the units are equivalent. The following cell should print True to demonstrate this.

5

thermostate Documentation, Release 1.2.1

[5]: Q_(101325, 'Pa') == 1.0*units.atm

[5]: True

Note the convention we are using here: the variables are named with the property, followed by an underscore, then thenumber of the state. In this case, we are setting properties for state 1, hence T_1 and p_1.

2.2 ThermoState

Now that we have defined two properties with units, let’s define a state. First, we create a variable to hold the Stateand tell ThermoState what substance we want to use with that state. The available substances are:

• water

• air

• R134a

• R22

• propane

• ammonia

• isobutane

• carbondioxide

• oxygen

• nitrogen

Note that the name of the substance is case-insensitive (it doesn’t matter whether you use lower case or upper case). Itis often easiest to set the name of the substance in a variable, like:

[6]: substance = 'water'

Now we need to create the State and assign values for the properties. Properties of the state are set as arguments tothe State class, and they must always be set in pairs, we cannot set a single property at a time. The syntax is

st = State(substance, property_1=value, property_2=value)

Warning

Remember that two independent and intensive properties are required to set the state!

To demonstrate, we will set the T and p properties of the state and set them equal to the temperature and pressure wedefined above. Note that the capitalization of the properties is important! The p is lower case while the T is upper case(lower case t means time).

[7]: print('T = {}, p = {}'.format(T_1, p_1))

T = 400 kelvin, p = 1.0 standard_atmosphere

[8]: st_1 = State(substance, T=T_1, p=p_1)

6 Chapter 2. Tutorial

thermostate Documentation, Release 1.2.1

Note again the convention we are using here: The state is labeled by st, then an underscore, then the number of thestate.

The variables that we use on the right side of the equal sign in the State function can be named anything we want.For instance, the following code is exactly equivalent to what we did before.

[9]: luke = Q_(1.0, 'atm')leia = Q_(400.0, 'K')print('Does luke equal p_1?', luke == p_1)print('Does leia equal T_1?', leia == T_1)st_starwars = State(substance, T=leia, p=luke)print('Does st_starwars equal st_1?', st_starwars == st_1)

Does luke equal p_1? TrueDoes leia equal T_1? TrueDoes st_starwars equal st_1? True

Warning

To avoid confusing yourself, name your variables to something useful. For instance, use the property symbol, thenan underscore, then the state number, as in p_1 = Q_(1.0, 'atm') to indicate the pressure at state 1. In mynotes and solutions, this is the convention that I will follow, and I will use st_# to indicate a State (e.g., st_1is state 1, st_2 is state 2, and so forth).

In theory, any two pairs of independent properties can be used to set the state. In reality, the pairs of properties availableto set the state is slightly limited because of the way the equation of state is written. The available pairs of propertiesare

• Tp

• Ts

• Tv

• Tx

• pu

• ps

• pv

• ph

• px

• uv

• sv

• hs

• hv

The reverse of any of these pairs is also possible and totally equivalent.

By setting two properties in this way, the State class will calculate all the other properties we might be interestedin. We can access the value of any property by getting the attribute for that property. The available properties are T(temperature), p (pressure), v (mass-specific volume), u (mass-specific internal energy), h (mass-specific enthalpy),s (mass-specific entropy), x (quality), cp (specific heat at constant pressure), cv (specific heat at constant volume),and phase (the phase of this state). The syntax is

2.2. ThermoState 7

thermostate Documentation, Release 1.2.1

State.property

or

st_1.T # Gets the temperaturest_1.p # Gets the pressurest_1.v # Gets the specific volumest_1.u # Gets the internal energyst_1.h # Gets the enthalpyst_1.s # Gets the entropyst_1.x # Gets the qualityst_1.cp # Gets the specific heat at constant pressurest_1.cv # Gets the specific heat at constant volumest_1.phase # Gets the phase at this state

Note

Capitalization is important! The temperature has upper case T, while the other properties are lower case to indicatethat they are mass-specific quantities.

[10]: print('T_1 = {}'.format(st_1.T))print('p_1 = {}'.format(st_1.p))print('v_1 = {}'.format(st_1.v))print('u_1 = {}'.format(st_1.u))print('h_1 = {}'.format(st_1.h))print('s_1 = {}'.format(st_1.s))print('x_1 = {}'.format(st_1.x))print('cp_1 = {}'.format(st_1.cp))print('cv_1 = {}'.format(st_1.cv))print('phase_1 = {}'.format(st_1.phase))

T_1 = 400.0 kelvinp_1 = 101324.99999999953 pascalv_1 = 1.801983936953226 meter ** 3 / kilogramu_1 = 2547715.3635084038 joule / kilogramh_1 = 2730301.3859201893 joule / kilograms_1 = 7496.2021523754065 joule / kelvin / kilogramx_1 = Nonecp_1 = 2009.2902478486988 joule / kelvin / kilogramcv_1 = 1509.1482452129906 joule / kelvin / kilogramphase_1 = gas

In this case, the value for the quality is the special Python value None. This is because at 400 K and 101325 Pa,the state of water is a superheated vapor and the quality is undefined except in the vapor dome. To access states inthe vapor dome, we cannot use T and p as independent properties, because they are not independent inside the vapordome. Instead, we have to use the pairs involving the other properties (possibly including the quality) to set the state.When we define the quality, the units are dimensionless or percent. For instance:

[11]: T_2 = Q_(100.0, 'degC')x_2 = Q_(0.1, 'dimensionless')st_2 = State('water', T=T_2, x=x_2)print('T_2 = {}'.format(st_2.T))print('p_2 = {}'.format(st_2.p))print('v_2 = {}'.format(st_2.v))print('u_2 = {}'.format(st_2.u))

(continues on next page)

8 Chapter 2. Tutorial

thermostate Documentation, Release 1.2.1

(continued from previous page)

print('h_2 = {}'.format(st_2.h))print('s_2 = {}'.format(st_2.s))print('x_2 = {}'.format(st_2.x))

T_2 = 373.15 kelvinp_2 = 101417.99665788244 pascalv_2 = 0.16811572834411825 meter ** 3 / kilogramu_2 = 627756.5746698529 joule / kilogramh_2 = 644806.535045544 joule / kilograms_2 = 1911.9019425021506 joule / kelvin / kilogramx_2 = 0.1 dimensionless

In addition, whether you use the 'dimensionless' “units” for the quality as above, or use the 'percent'“units”, the result is exactly equivalent. The next cell should print True to the screen to demonstrate this.

[12]: x_2 == Q_(10.0, 'percent')

[12]: True

From these results, we can see that the units of the units of the properties stored in the State are always SI units -Kelvin, Pascal, m3/kg, J/kg, and J/(kg-Kelvin). We can use the to function to convert the units to anything we want,provided the dimensions are compatible. The syntax is State.property.to('units').

[13]: print(st_2.T.to('degF'))print(st_2.s.to('BTU/(lb*degR)'))

211.99999999999991 degree_Fahrenheit0.4566498699316826 british_thermal_unit / degree_Rankine / pound

Note

The values are always converted in the State to SI units, no matter what the input units are. Therefore, if you wantEE units as an output, you have to convert.

If we try to convert to a unit with incompatible dimensions, Pint will raise a DimenstionalityError exception.

Warning

If you get a DimensionalityError, examine your conversion very closely. The error message will tell youwhy the dimensions are incompatible!

[14]: print(st_2.T.to('joule'))

---------------------------------------------------------------------------DimensionalityError Traceback (most recent call last)<ipython-input-14-9725ac474279> in <module>----> 1 print(st_2.T.to('joule'))

DimensionalityError: Cannot convert from 'kelvin' ([temperature]) to 'joule'→˓([length] ** 2 * [mass] / [time] ** 2)

Here we have tried to convert from 'kelvin' to 'joule' and the error message which is the last line says

DimensionalityError: Cannot convert from 'kelvin' ([temperature]) to 'joule'→˓([length] ** 2 * [mass] / [time] ** 2)

2.2. ThermoState 9

thermostate Documentation, Release 1.2.1

The dimensions of a temperature are, well, temperature. The formula for energy (Joule) is 𝑚 * 𝑎 * 𝑑 (mass timesacceleration times distance), and in terms of dimensions, 𝑀 * 𝐿/𝑇 2 * 𝐿 = 𝐿2 *𝑀/𝑇 2 (where in dimensions, capital𝑇 is time). Clearly, these dimensions are incompatible. A more subtle case might be trying to convert energy to power(again, not allowed):

[15]: Q_(1000.0, 'joule').to('watt')

---------------------------------------------------------------------------DimensionalityError Traceback (most recent call last)<ipython-input-15-352febbe91fd> in <module>----> 1 Q_(1000.0, 'joule').to('watt')

DimensionalityError: Cannot convert from 'joule' ([length] ** 2 * [mass] / [time] **→˓2) to 'watt' ([length] ** 2 * [mass] / [time] ** 3)

2.3 Other Common Errors

Other common errors generated from using ThermoState will raise StateErrors. These errors may be due to

1. Not specifying enough properties to fix the state, or specifying too many properties to fix the state

2. Specifying a pair of properties that are not independent at the desired condtions

3. Entering an unsupported pair of property inputs (the currently unsupported pairs are Tu, Th, and us, due tolimitations in CoolProp)

4. Specifying a Quantity with incorrect dimensions for the property input

An example demonstrating #4 from above:

[16]: State('water', v=Q_(1000.0, 'degC'), p=Q_(1.0, 'bar'))

---------------------------------------------------------------------------StateError Traceback (most recent call last)<ipython-input-16-95363eb6e667> in <module>----> 1 State('water', v=Q_(1000.0, 'degC'), p=Q_(1.0, 'bar'))

StateError: The dimensions for v must be [length] ** 3 / [mass]

2.4 Summary

In summary, we need to use two (2) independent and intensive properties to fix the state of any simple compressiblesystem. We need to define these quantities with units using Pint, and then use them to set the conditions of a State.Then, we can access the other properties of the State by using the attributes.

[17]: h_3 = Q_(2000.0, 'kJ/kg')s_3 = Q_(3.10, 'kJ/(kg*K)')st_3 = State('water', h=h_3, s=s_3)print('T_3 = {}'.format(st_3.T))print('p_3 = {}'.format(st_3.p))print('v_3 = {}'.format(st_3.v))print('u_3 = {}'.format(st_3.u))print('h_3 = {}'.format(st_3.h))print('s_3 = {}'.format(st_3.s))print('x_3 = {}'.format(st_3.x))

10 Chapter 2. Tutorial

thermostate Documentation, Release 1.2.1

T_3 = 666.0536816976213 kelvinp_3 = 669560197.2594368 pascalv_3 = 0.0010136928689306822 meter ** 3 / kilogramu_3 = 1321271.6027173032 joule / kilogramh_3 = 1999999.9999990154 joule / kilograms_3 = 3100.0000000000005 joule / kelvin / kilogramx_3 = None

2.4. Summary 11

thermostate Documentation, Release 1.2.1

12 Chapter 2. Tutorial

CHAPTER

THREE

EXAMPLES

These examples show possible use cases for ThermoState in solving somewhat involved Applied Thermodynamicsproblems. These types of problems would be very difficult to solve by hand using tables, due to the number ofcalculations required from the property tables.

3.1 Air-Standard Brayton Cycle Example

3.1.1 Imports

[1]: from thermostate import State, Q_, unitsimport numpy as np%matplotlib inlineimport matplotlib.pyplot as plt

3.1.2 Definitions

[2]: substance = 'air'p_1 = Q_(1.0, 'bar')T_1 = Q_(300.0, 'K')T_3 = Q_(1700.0, 'K')p2_p1 = Q_(8.0, 'dimensionless')p_low = Q_(2.0, 'dimensionless')p_high = Q_(50.0, 'dimensionless')

3.1.3 Problem Statement

An ideal air-standard Brayton cycle operates at steady state with compressor inlet conditions of 300.0 K and 1.0 barand a fixed turbine inlet temperature of 1700.0 K and a compressor pressure ratio of 8.0. For the cycle,

1. determine the net work developed per unit mass flowing, in kJ/kg

2. determine the thermal efficiency

3. plot the net work developed per unit mass flowing, in kJ/kg, as a function of the compressor pressure ratio from2.0 to 50.0

4. plot the thermal efficiency as a function of the compressor pressure ratio from 2.0 to 50.0

13

thermostate Documentation, Release 1.2.1

5. Discuss any trends you find in parts 3 and 4

3.1.4 Solution

1. the net work developed per unit mass flowing

In the ideal Brayton cycle, work occurs in the isentropic compression and expansion. Therefore, the works are

�̇�𝑐

�̇�= ℎ1 − ℎ2

�̇�𝑡

�̇�= ℎ3 − ℎ4

First, fixing the four states

[3]: st_1 = State(substance, T=T_1, p=p_1)h_1 = st_1.h.to('kJ/kg')s_1 = st_1.s.to('kJ/(kg*K)')

s_2 = s_1p_2 = p_1*p2_p1st_2 = State(substance, p=p_2, s=s_2)h_2 = st_2.h.to('kJ/kg')T_2 = st_2.T

p_3 = p_2st_3 = State(substance, p=p_3, T=T_3)h_3 = st_3.h.to('kJ/kg')s_3 = st_3.s.to('kJ/(kg*K)')

s_4 = s_3p_4 = p_1st_4 = State(substance, p=p_4, s=s_4)h_4 = st_4.h.to('kJ/kg')T_4 = st_4.T

Summarizing the states,

State T p h s1 300.00 K 1.00 bar 426.30 kJ/kg 3.89 kJ/(K kg)2 540.13 K 8.00 bar 670.65 kJ/kg 3.89 kJ/(K kg)3 1700.00 K 8.00 bar 2007.09 kJ/kg 5.19 kJ/(K kg)4 1029.42 K 1.00 bar 1206.17 kJ/kg 5.19 kJ/(K kg)

Then, the net work is calculated by

[4]: W_c = h_1 - h_2W_t = h_3 - h_4W_net = W_c + W_t

Answer: The works are �̇�𝑐/�̇� = -244.35 kJ/kg, �̇�𝑡/�̇� = 800.92 kJ/kg, and �̇�𝑛𝑒𝑡/�̇� = 556.57 kJ/kg

14 Chapter 3. Examples

thermostate Documentation, Release 1.2.1

2. the thermal efficiency

[5]: Q_23 = h_3 - h_2eta = W_net/Q_23

Answer: The thermal efficiency is 𝜂 = 0.42 = 41.65%

3. and 4. plot the net work per unit mass flowing and thermal efficiency

[6]: p_range = np.linspace(p_low, p_high, 50)eta_l = np.zeros(shape=p_range.shape) * units.dimensionlessW_net_l = np.zeros(shape=p_range.shape) * units.kJ / units.kgfor i, p_ratio in enumerate(p_range):

s_2 = s_1p_2 = p_1*p_ratiost_2 = State(substance, p=p_2, s=s_2)h_2 = st_2.h.to('kJ/kg')T_2 = st_2.T

p_3 = p_2st_3 = State(substance, p=p_3, T=T_3)h_3 = st_3.h.to('kJ/kg')s_3 = st_3.s.to('kJ/(kg*K)')

s_4 = s_3p_4 = p_1st_4 = State(substance, p=p_4, s=s_4)h_4 = st_4.h.to('kJ/kg')T_4 = st_4.T

W_c = h_1 - h_2W_t = h_3 - h_4W_net = W_c + W_tW_net_l[i] = W_net

Q_23 = h_3 - h_2eta = W_net/Q_23eta_l[i] = eta

[7]: fig, work_ax = plt.subplots()work_ax.plot(p_range, W_net_l, label='Net work per unit mass flowing', color='C0')eta_ax = work_ax.twinx()eta_ax.plot(p_range, eta_l, label='Thermal efficiency', color='C1')work_ax.set_xlabel('Pressure ratio $p_2/p_1$')work_ax.set_ylabel('Net work per unit mass flowing (kJ/kg)')eta_ax.set_ylabel('Thermal efficiency')lines, labels = work_ax.get_legend_handles_labels()lines2, labels2 = eta_ax.get_legend_handles_labels()work_ax.legend(lines + lines2, labels + labels2, loc='best');

3.1. Air-Standard Brayton Cycle Example 15

thermostate Documentation, Release 1.2.1

We note from this graph that the thermal efficiency of the cycle increases continuously as the pressure ratio increases.However, because there is a fixed turbine inlet temperature, the work per unit mass flowing has a maximum around𝑝2/𝑝1 = 20.

3.2 Cold-Air Standard Brayton Cycle Example

3.2.1 Imports

[1]: from thermostate import State, Q_, unitsimport numpy as np%matplotlib inlineimport matplotlib.pyplot as plt

3.2.2 Definitions

[2]: substance = 'air'p_1 = Q_(1.0, 'bar')T_1 = Q_(300.0, 'K')mdot = Q_(6.0, 'kg/s')T_3 = Q_(1400.0, 'K')p2_p1 = Q_(10.0, 'dimensionless')T_3_low = Q_(1000.0, 'K')T_3_high = Q_(1800.0, 'K')

16 Chapter 3. Examples

thermostate Documentation, Release 1.2.1

3.2.3 Problem Statement

An ideal cold air-standard Brayton cycle operates at steady state with compressor inlet conditions of 300.0 kelvin and1.0 bar and a fixed turbine inlet temperature of 1400.0 kelvin and a compressor pressure ratio of 10.0 dimensionless.The mass flow rate of the air is 6.0 kilogram / second. For the cycle,

1. determine the back work ratio

2. determine the net power output, in kW

3. determine the thermal efficiency

4. plot the net power output, in kW, and the thermal efficiency, as a function of the turbine inlet temperature from1000.0 kelvin to 1800.0 kelvin. Discuss any trends you find.

3.2.4 Solution

1. the back work ratio

In the ideal Brayton cycle, work occurs in the isentropic compression and expansion. Therefore, the works are

�̇�𝑐

�̇�= ℎ1 − ℎ2 = 𝑐𝑝(𝑇1 − 𝑇2)

�̇�𝑡

�̇�= ℎ3 − ℎ4 = 𝑐𝑝(𝑇3 − 𝑇4)

First, fixing the four states using a cold air-standard analysis

[3]: st_amb = State(substance, T=T_1, p=p_1)c_v = st_amb.cvc_p = st_amb.cpk = c_p/c_v

T_2 = T_1*p2_p1**((k - 1)/k)p_2 = p2_p1*p_1

p_3 = p_2

p_4 = p_1T_4 = T_3*(p_4/p_3)**((k - 1)/k)

Summarizing the states,

State T p1 300.00 K 1.00 bar2 580.34 K 10.00 bar3 1400.00 K 10.00 bar4 723.71 K 1.00 bar

Then, the back work ratio can be found by

[4]: Wdot_c = (mdot*c_p*(T_1 - T_2)).to('kW')Wdot_t = (mdot*c_p*(T_3 - T_4)).to('kW')bwr = abs(Wdot_c)/Wdot_t

Answer: The power outputs are �̇�𝑐 = -1692.75 kW, �̇�𝑡 = 4083.53 kW, and the back work ratio is bwr = 0.41 =41.45%

3.2. Cold-Air Standard Brayton Cycle Example 17

thermostate Documentation, Release 1.2.1

2. the net power output

[5]: Wdot_net = Wdot_c + Wdot_t

Answer: The net power output is �̇�𝑛𝑒𝑡 = 2390.78 kW

3. the thermal efficiency

[6]: Qdot_23 = (mdot*c_p*(T_3 - T_2)).to('kW')eta = Wdot_net/Qdot_23

Answer: The thermal efficiency is 𝜂 = 0.48 = 48.31%

4. plot the net power output and thermal efficiency

[7]: T_range = np.linspace(T_3_low, T_3_high, 200)Wdot_net_l = np.zeros(T_range.shape) * units.kWeta_l = np.zeros(T_range.shape) * units.dimensionlessfor i, T_3 in enumerate(T_range):

T_4 = T_3*(p_4/p_3)**((k - 1)/k)Wdot_t = (mdot*c_p*(T_3 - T_4)).to('kW')Wdot_net = Wdot_c + Wdot_tWdot_net_l[i] = Wdot_net

Qdot_23 = (mdot*c_p*(T_3 - T_2)).to('kW')eta = Wdot_net/Qdot_23eta_l[i] = eta

[8]: fig, power_ax = plt.subplots()power_ax.plot(T_range, Wdot_net_l, label='Net power output', color='C0')eta_ax = power_ax.twinx()eta_ax.plot(T_range, eta_l, label='Thermal efficiency', color='C1')power_ax.set_xlabel('Turbine Inlet Temperature (K)')power_ax.set_ylabel('Net power output (kW)')eta_ax.set_ylabel('Thermal efficiency')lines, labels = power_ax.get_legend_handles_labels()lines2, labels2 = eta_ax.get_legend_handles_labels()power_ax.legend(lines + lines2, labels + labels2, loc='best');

18 Chapter 3. Examples

thermostate Documentation, Release 1.2.1

From this graph, we note that for a fixed compressor pressure ratio, the thermal efficiency is constant, while the netpower output increases with increasing turbine temperature.

3.3 Diesel Cycle Example

3.3.1 Imports

[1]: from thermostate import State, Q_, units%matplotlib inlineimport matplotlib.pyplot as pltfrom numpy import arange

3.3.2 Definitions

[2]: substance = 'air'T_1 = Q_(25.0, 'degC')p_1 = Q_(95.0, 'kPa')V_1 = Q_(3.0, 'L')r = Q_(18.0, 'dimensionless')r_c = Q_(3.0, 'dimensionless')rpm = Q_(1700.0, 'rpm')n_C = Q_(4, 'dimensionless')units.define('cycle = 2*revolution') # Define a four-stroke cycler_c_low = Q_(1.1, 'dimensionless')r_c_high = Q_(4.5, 'dimensionless')

3.3. Diesel Cycle Example 19

thermostate Documentation, Release 1.2.1

3.3.3 Problem Statement

A four-cylinder Diesel engine has a BDC volume of 3.0 L per cylinder. The engine operates on the air-standard Dieselcycle with a compression ratio of 18.0 and a cutoff ratio of 3.0 . Air is at 25.0 celsius and 95.0 kPa at the beginning ofthe compression process. Determine

1. the amount of power delivered by the engine, in kW, at 1700.0 rpm

2. the thermal efficiency

3. plot the power output as a function of the cutoff ratio, with values for 𝑟𝑐 from 1.1 to 4.5 , holding all other givenvalues constant

4. plot the thermal efficiency as a function of the cutoff ratio, with values for 𝑟𝑐 from 1.1 to 4.5 , holding all othergiven values constant

3.3.4 Solution

1. the power delivered

The power output can be found by taking the product of the net work per cylinder, the number of cylinders, and thenet work per revolution

�̇�𝑛𝑒𝑡 = 𝑛𝐶𝑁

2𝑊𝑛𝑒𝑡

First, we need to fix the four states. State 1 uses 𝑝 and 𝑇 , state 2 uses 𝑠 and 𝑣, state 3 uses 𝑝 and 𝑣, and state 4 uses 𝑣and 𝑠. We need to calculate the mass of air in one cylinder using the ideal gas law

𝑚 =𝑝𝑉

𝑅𝑇

where 𝑅 = 𝑅/𝑀𝑊 is the gas-specific constant.

[3]: MW_air = Q_(28.97, 'kg/kmol')R = units.molar_gas_constant/MW_airm = (p_1*V_1/(R*T_1)).to('mg')

v_1 = (V_1/m).to('m**3/kg')st_1 = State(substance, p=p_1, T=T_1)s_1 = st_1.s.to('kJ/(kg*K)')u_1 = st_1.u.to('kJ/kg')

v_2 = v_1/rs_2 = s_1st_2 = State(substance, v=v_2, s=s_2)T_2 = st_2.Tp_2 = st_2.p.to('kPa')u_2 = st_2.u.to('kJ/kg')

v_3 = r_c*v_2p_3 = p_2st_3 = State(substance, p=p_3, v=v_3)T_3 = st_3.Ts_3 = st_3.s.to('kJ/(kg*K)')u_3 = st_3.u.to('kJ/kg')

(continues on next page)

20 Chapter 3. Examples

thermostate Documentation, Release 1.2.1

(continued from previous page)

s_4 = s_3v_4 = v_1st_4 = State(substance, v=v_4, s=s_4)T_4 = st_4.Tp_4 = st_4.p.to('kPa')u_4 = st_4.u.to('kJ/kg')

The mass of air in one cylinder is 𝑚 = 3330.61 mg. Summarizing the states:

State T p u v s1 298.15 K 95.00 kPa 338.89 kJ/kg 0.90 m3/kg 3.90 kJ/(K kg)2 900.45 K 5256.76 kPa 799.36 kJ/kg 0.05 m3/kg 3.90 kJ/(K kg)3 2730.75 K 5256.76 kPa 2522.03 kJ/kg 0.15 m3/kg 5.25 kJ/(K kg)4 1602.36 K 511.21 kPa 1426.75 kJ/kg 0.90 m3/kg 5.25 kJ/(K kg)

[4]: W_12 = (m*(u_1 - u_2)).to('kJ')W_23 = (m*p_2*(v_3 - v_2)).to('kJ')W_34 = (m*(u_3 - u_4)).to('kJ')

W_net = W_12 + W_23 + W_34

Q_23 = (m*(u_3 - u_2) + W_23).to('kJ')Q_41 = (m*(u_1 - u_4)).to('kJ')

Summarizing the energy transfers,

Process Work Heat Transfer1 → 2 -1.53 kJ 0.0 kJ2 → 3 1.75 kJ 7.49 kJ3 → 4 3.65 kJ 0.0 kJ4 → 1 0.0 kJ -3.62 kJ

and the net work output per cylinder per cycle is 𝑊𝑛𝑒𝑡 = 3.87 kJ. Then, calculating the power output

[5]: Wdot_net = (n_C*rpm*W_net/units.cycle).to('kW')

Answer: The net power output is �̇�𝑛𝑒𝑡 = 219.10 kW

2. the thermal efficiency

[6]: eta = W_net/Q_23

Answer: The thermal efficiency is 𝜂 = 0.52 = 51.62%

3.3. Diesel Cycle Example 21

thermostate Documentation, Release 1.2.1

3. plot the net power output as a function of 𝑟𝑐

For this part (and the next one), only states 3 and 4 are changed by changing the cutoff ratio. Therefore, we onlyre-compute those states, and the associated work and heat transfer values, in the following loop.

[7]: eta_l = []Wdot_net_l = []r_c_l = arange(r_c_low.magnitude, r_c_high.magnitude+0.1, 0.1)for r_c in r_c_l:

v_3 = r_c*v_2p_3 = p_2st_3 = State(substance, p=p_3, v=v_3)s_3 = st_3.s.to('kJ/(kg*K)')u_3 = st_3.u.to('kJ/kg')

s_4 = s_3v_4 = v_1st_4 = State(substance, v=v_4, s=s_4)u_4 = st_4.u.to('kJ/kg')

W_23 = (m*p_2*(v_3 - v_2)).to('kJ')W_34 = (m*(u_3 - u_4)).to('kJ')

W_net = W_12 + W_23 + W_34Wdot_net = (n_C*rpm*W_net/units.cycle).to('kW')Wdot_net_l.append(Wdot_net.magnitude)

Q_23 = (m*(u_3 - u_2) + W_23).to('kJ')eta = W_net/Q_23eta_l.append(eta.magnitude)

[8]: plt.figure()plt.plot(r_c_l, Wdot_net_l, label='$\dot{W}_{net}$')plt.legend(loc='best')plt.title('$\dot{W}_{net}$ vs. $r_c$')plt.xlabel('$r_c$ ($v_3/v_2$)')plt.ylabel('$\dot{W}_{net}$ (kW)');

22 Chapter 3. Examples

thermostate Documentation, Release 1.2.1

4. plot 𝜂 vs. 𝑟𝑐

[9]: plt.figure()plt.plot(r_c_l, eta_l, label='$\eta$')plt.legend(loc='best')plt.title('$\eta$ vs. $r_c$')plt.xlabel('$r_c$ ($v_3/v_2$)')plt.ylabel('$\eta$');

From these graphs, we note that as the cutoff ratio increases, the power delivered increases but the thermal efficiencydecreases.

3.4 Rankine Cycle Example

3.4.1 Imports

[1]: from thermostate import State, Q_, units, SystemInternational as SI%matplotlib inlineimport matplotlib.pyplot as pltimport numpy as np

3.4.2 Definitions

[2]: substance = 'water'T_1 = Q_(560.0, 'degC')p_1 = Q_(16.0, 'MPa')mdot_1 = Q_(120.0, 'kg/s')p_2 = Q_(1.0, 'MPa')p_3 = Q_(8.0, 'kPa')x_4 = Q_(0.0, 'percent')x_6 = Q_(0.0, 'percent')

(continues on next page)

3.4. Rankine Cycle Example 23

thermostate Documentation, Release 1.2.1

(continued from previous page)

p_low = Q_(0.1, 'MPa')p_high = Q_(7.5, 'MPa')

3.4.3 Problem Statement

Water is the working fluid in an ideal regenerative Rankine cycle with one open feedwater heater. Superheated vaporenters the first-stage turbine at 16.0 MPa, 560.0 celsius with a mass flow rate of 120.0 kg/s. Steam expands through thefirst-stage turbine to 1.0 MPa where it is extracted and diverted to the open feedwater heater. The remainder expandsthrough the second-stage turbine to the condenser pressure of 8.0 kPa. Saturated liquid exits the feedwater heater at1.0 MPa. Determine

1. the net power developed, in MW

2. the rate of heat transfer to the steam passing through the boiler, in MW

3. the overall cycle thermal efficiency

4. For extraction pressures (𝑝2) ranging from 𝑝𝑙𝑜𝑤 = 0.1 MPa to 𝑝ℎ𝑖𝑔ℎ = 7.5 MPa, calculate the extracted massfraction 𝑦 and the overall cycle thermal efficiency. Sketch a plot of 𝜂 (on the y-axis) vs. 𝑦 (on the x-axis). Useat least 10 values to construct the plot. Discuss any trends you find.

3.4.4 Hint

To do the plotting, we will construct a list that contains pressures from 0.1 MPa to 7.5 MPa and use a for loop toiterate over that list. As we do the iteration, we will fix the values for the states that have changed, and re-compute 𝑦and 𝜂 on each iteration. We will store the value for 𝑦 and 𝜂 at each pressure in a list, then plot the lists.

To create the list of pressures, we will use a function from the numpy library called linspace that creates a rangeof numbers when the start, stop, and number of values are input. If we multiply the range by the units that we want,it will work out. Note: Not all of the state change every time the extraction pressure is changed. You only need torecompute the states that change. The code will look something like this:

y_values = []eta_values = []for p_2 in linspace(p_low, p_high, 10)*units.MPa:

# State 2 is definitely going to change :-)st_2 = State(substance, p=p_2, s=s_2)

# Now fix the rest of the states that have changed...y = ...y_values.append(y)

Wdot_net = ...Qdot_in = ...eta = ...eta_values.append(eta)

plt.plot(y_values, eta_values, label='eta')plt.legend(loc='best')plt.title('$\eta$ vs. $y$')

(continues on next page)

24 Chapter 3. Examples

thermostate Documentation, Release 1.2.1

(continued from previous page)

plt.xlabel('$y$ ($\dot{m}_2/\dot{m}_1$)')plt.ylabel('$\eta$');

The syntax for the plotting function is

plt.plot(x_values, y_values, label='line label name')

The rest of the code below the plotting is to make the plot look nicer. Feel free to copy-paste this code into yoursolution.

3.4.5 Solution

1. the net power developed

The first step is to fix all of the states, then calculate the value for 𝑦.

[3]: # State 1st_1 = State(substance, T=T_1, p=p_1)h_1 = st_1.h.to(SI.h)s_1 = st_1.s.to(SI.s)

# State 2s_2 = s_1st_2 = State(substance, p=p_2, s=s_2)h_2 = st_2.h.to(SI.h)T_2 = st_2.T.to(SI.T)x_2 = st_2.x

# State 3s_3 = s_2st_3 = State(substance, p=p_3, s=s_3)h_3 = st_3.h.to(SI.h)T_3 = st_3.T.to(SI.T)x_3 = st_3.x

# State 4p_4 = p_3st_4 = State(substance, p=p_4, x=x_4)h_4 = st_4.h.to(SI.h)s_4 = st_4.s.to(SI.s)T_4 = st_4.T.to(SI.T)

# State 5p_5 = p_2s_5 = s_4st_5 = State(substance, p=p_5, s=s_5)h_5 = st_5.h.to(SI.h)T_5 = st_5.T.to(SI.T)

# State 6p_6 = p_2st_6 = State(substance, p=p_6, x=x_6)h_6 = st_6.h.to(SI.h)

(continues on next page)

3.4. Rankine Cycle Example 25

thermostate Documentation, Release 1.2.1

(continued from previous page)

s_6 = st_6.s.to(SI.s)T_6 = st_6.T.to(SI.T)

# State 7p_7 = p_1s_7 = s_6st_7 = State(substance, p=p_7, s=s_7)h_7 = st_7.h.to(SI.h)T_7 = st_7.T.to(SI.T)

y = (h_6 - h_5)/(h_2 - h_5)

Summarizing the states:

State T p h s x phase1 560.00 celsius 16.00 MPa 3467.17 kJ/kg 6.5163 kJ/(K kg) — supercritical2 179.88 celsius 1.00 MPa 2745.98 kJ/kg 6.5163 kJ/(K kg) 98.45% twophase3 41.51 celsius 8.00 kPa 2037.82 kJ/kg 6.5163 kJ/(K kg) 77.59% twophase4 41.51 celsius 8.00 kPa 173.84 kJ/kg 0.5925 kJ/(K kg) 0.00% pct twophase5 41.54 celsius 1.00 MPa 174.84 kJ/kg 0.5925 kJ/(K kg) — liquid6 179.88 celsius 1.00 MPa 762.52 kJ/kg 2.1381 kJ/(K kg) 0.00% pct twophase7 181.95 celsius 16.00 MPa 779.35 kJ/kg 2.1381 kJ/(K kg) — liquid

This gives a value for 𝑦 = 0.2286 = 22.86% of the flow being directed into the feedwater heater. Then, the net workoutput of the cycle is

�̇�𝑛𝑒𝑡 = �̇�1(ℎ1 − ℎ2) + �̇�3(ℎ2 − ℎ3) + �̇�3(ℎ4 − ℎ5) + �̇�1(ℎ6 − ℎ7)

�̇�𝑛𝑒𝑡 = �̇�1 [(ℎ1 − ℎ2) + (1− 𝑦)(ℎ2 − ℎ3) + (1− 𝑦)(ℎ4 − ℎ5) + (ℎ6 − ℎ7)]

[4]: Wdot_net = (mdot_1*(h_1 - h_2 + (1 - y)*(h_2 - h_3) + (1 - y)*(h_4 - h_5) + (h_6 - h_→˓7))).to('MW')

Answer: The net work output from the cycle is �̇�𝑛𝑒𝑡 = 149.99 MW

2. the heat transfer input

The heat transfer input is

�̇�𝑖𝑛 = �̇�1(ℎ1 − ℎ7)

[5]: Qdot_in = (mdot_1*(h_1 - h_7)).to('MW')

Answer: The heat transfer input is �̇�𝑖𝑛 = 322.54 MW

26 Chapter 3. Examples

thermostate Documentation, Release 1.2.1

3. the overall cycle thermal efficiency

[6]: eta = Wdot_net/Qdot_in

Answer: The thermal efficiency is 𝜂 = 0.4650 = 46.50%

4. plot 𝜂 vs 𝑦

[7]: p_range = np.linspace(p_low, p_high, 100)y_values = np.zeros(shape=p_range.shape) * units.dimensionlesseta_values = np.zeros(shape=p_range.shape) * units.dimensionlessfor i, p_2 in enumerate(p_range):

# State 2s_2 = s_1st_2 = State(substance, p=p_2, s=s_2)h_2 = st_2.h

# State 5p_5 = p_2s_5 = s_4st_5 = State(substance, p=p_5, s=s_5)h_5 = st_5.h

# State 6p_6 = p_2st_6 = State(substance, p=p_6, x=x_6)h_6 = st_6.hs_6 = st_6.s

# State 7p_7 = p_1s_7 = s_6st_7 = State(substance, p=p_7, s=s_7)h_7 = st_7.h

y = (h_6 - h_5)/(h_2 - h_5)y_values[i] = y

Wdot_net = (mdot_1*(h_1 - h_2 + (1 - y)*(h_2 - h_3) + (1 - y)*(h_4 - h_5) + (h_6 -→˓ h_7))).to('MW')

Qdot_in = (mdot_1*(h_1 - h_7)).to('MW')eta = Wdot_net/Qdot_ineta_values[i] = eta

[8]: plt.plot(y_values, eta_values, label='eta')plt.legend(loc='best')plt.title('$\eta$ vs. $y$')plt.xlabel('$y$ ($\dot{m}_2/\dot{m}_1$)')plt.ylabel('$\eta$');

3.4. Rankine Cycle Example 27

thermostate Documentation, Release 1.2.1

Answer: Interestingly, as we vary the mass flow rate extracted to the feedwater heater, the overall thermal efficiencyfirst increases, then decreases. The reason is because the thermal efficiency is the ratio of the work divided by theheat transfer. As 𝑦 increases from 0.10 to 0.20, the work output decreases slightly, but the heat transfer decreasessignificantly. After about 𝑦 = 0.25, the work output decreases more quickly than the heat transfer decreases, and thethermal efficiency goes down.

3.5 Regen-Reheat Rankine Cycle Example

3.5.1 Imports

[1]: from thermostate import State, Q_, units, SystemInternational as SI

3.5.2 Definitions

[2]: substance = 'water'T_1 = Q_(480.0, 'degC')p_1 = Q_(12.0, 'MPa')p_2 = Q_(2.0, 'MPa')p_3 = p_2T_3 = Q_(440.0, 'degC')p_4 = p_7 = p_8 = p_12 = Q_(0.3, 'MPa')p_5 = Q_(6.0, 'kPa')x_6 = Q_(0.0, 'dimensionless')x_8 = Q_(0.0, 'dimensionless')p_10 = Q_(12.0, 'MPa')T_10 = Q_(210.0, 'degC')x_11 = Q_(0.0, 'dimensionless')p_11 = p_2

28 Chapter 3. Examples

thermostate Documentation, Release 1.2.1

3.5.3 Problem Statement

Consider a regenerative vapor power cycle with two feedwater heaters, a closed one and an open one, and reheat.Steam enters the first turbine stage at 12.0 MPa, 480.0 celsius, and expands to 2.0 MPa. Some steam is extracted at 2.0MPa and bled to the closed feedwater heater. The remainder is reheated at 2.0 MPa to 440.0 celsius and then expandsthrough the second stage turbine, where an additional amount of steam is extracted and bled into the open feedwaterheater operating at 0.3 MPa. The steam expanding through the third stage turbine exits at the condenser pressure of6.0 kPa, and the steam exits the condenser as a saturated liquid at 6.0 kPa. Feedwater leaves the closed heater at210.0 celsius, 12.0 MPa, and condensate exiting as saturated liquid at 2.0 MPa is trapped into the open feedwaterheater. Saturated liquid at 0.3 MPa leaves the open feedwater heater. Assume all pumps and turbine stages operateisentropically. Determine for the cycle

1. the heat transfer to the working fluid passing through the steam generator and reheater, in kJ per kg of steamentering the first stage turbine

2. the thermal efficiency

3. the heat transfer from the working fluid passing through the condenser to the cooling water, in kJ per kg of steamentering the first stage turbine

3.5.4 Solution

1. the heat transfer in the steam generator and reheater

The heat transfer can be found by drawing a control volume around the boiler/steam generator, including the reheatportion. Then, the first law reduces to

�̇�𝑖𝑛 = �̇�1 (ℎ1 − ℎ10) + �̇�3 (ℎ3 − ℎ2)

�̇�𝑖𝑛

�̇�1= (ℎ1 − ℎ10) + (1− 𝑦′) (ℎ3 − ℎ2)

where 𝑦′ is the fraction of the flow extracted to the closed feedwater heater. To find the value of 𝑦′, we draw a controlvolume around the closed feedwater heater and solve for 𝑦′

𝑦′ =ℎ10 − ℎ9

ℎ2 − ℎ11

First, fix the values for all the states using given information.

[3]: # State 1st_1 = State(substance, T=T_1, p=p_1)h_1 = st_1.h.to(SI.h)s_1 = st_1.s.to(SI.s)

# State 2s_2 = s_1st_2 = State(substance, p=p_2, s=s_2)h_2 = st_2.h.to(SI.h)T_2 = st_2.T.to(SI.T)x_2 = st_2.x

# State 3st_3 = State(substance, p=p_3, T=T_3)h_3 = st_3.h.to(SI.h)

(continues on next page)

3.5. Regen-Reheat Rankine Cycle Example 29

thermostate Documentation, Release 1.2.1

(continued from previous page)

s_3 = st_3.s.to(SI.s)

# State 4s_4 = s_3st_4 = State(substance, p=p_4, s=s_4)h_4 = st_4.h.to(SI.h)T_4 = st_4.T.to(SI.T)x_4 = st_4.x

# State 5s_5 = s_4st_5 = State(substance, p=p_5, s=s_5)h_5 = st_5.h.to(SI.h)T_5 = st_5.T.to(SI.T)x_5 = st_5.x

# State 6p_6 = p_5st_6 = State(substance, p=p_6, x=x_6)h_6 = st_6.h.to(SI.h)s_6 = st_6.s.to(SI.s)T_6 = st_6.T.to(SI.T)

# State 7s_7 = s_6st_7 = State(substance, p=p_7, s=s_7)h_7 = st_7.h.to(SI.h)T_7 = st_7.T.to(SI.T)

# State 8st_8 = State(substance, p=p_8, x=x_8)h_8 = st_8.h.to(SI.h)s_8 = st_8.s.to(SI.s)T_8 = st_8.T.to(SI.T)

# State 9s_9 = s_8p_9 = p_10st_9 = State(substance, p=p_9, s=s_9)h_9 = st_9.h.to(SI.h)T_9 = st_9.T.to(SI.T)

# State 10st_10 = State(substance, p=p_10, T=T_10)h_10 = st_10.h.to(SI.h)s_10 = st_10.s.to(SI.s)

# State 11st_11 = State(substance, p=p_11, x=x_11)h_11 = st_11.h.to(SI.h)s_11 = st_11.s.to(SI.s)T_11 = st_11.T.to(SI.T)

# State 12h_12 = h_11st_12 = State(substance, p=p_12, h=h_12)s_12 = st_12.s.to(SI.s)

(continues on next page)

30 Chapter 3. Examples

thermostate Documentation, Release 1.2.1

(continued from previous page)

T_12 = st_12.T.to(SI.T)x_12 = st_12.x

Summarizing the states,

State T p h s x phase1 480.00 celsius 12.00 MPa 3295.29 kJ/kg 6.4186 kJ/(K kg) — supercritical2 225.46 celsius 2.00 MPa 2837.44 kJ/kg 6.4186 kJ/(K kg) — gas3 440.00 celsius 2.00 MPa 3336.25 kJ/kg 7.2560 kJ/(K kg) — supercritical4 187.07 celsius 0.30 MPa 2839.24 kJ/kg 7.2560 kJ/(K kg) — gas5 36.16 celsius 6.00 kPa 2234.74 kJ/kg 7.2560 kJ/(K kg) 86.26% twophase6 36.16 celsius 6.00 kPa 151.48 kJ/kg 0.5208 kJ/(K kg) 0.00% twophase7 36.17 celsius 0.30 MPa 151.77 kJ/kg 0.5208 kJ/(K kg) — liquid8 133.52 celsius 0.30 MPa 561.43 kJ/kg 1.6717 kJ/(K kg) 0.00% twophase9 134.62 celsius 12.00 MPa 573.95 kJ/kg 1.6717 kJ/(K kg) — liquid10 210.00 celsius 12.00 MPa 901.29 kJ/kg 2.4077 kJ/(K kg) — liquid11 212.38 celsius 2.00 MPa 908.50 kJ/kg 2.4468 kJ/(K kg) 0.00% twophase12 133.52 celsius 0.30 MPa 908.50 kJ/kg 2.5252 kJ/(K kg) 16.04% twophase

[4]: y_p = (h_10 - h_9)/(h_2 - h_11)Qdot_in = (h_1 - h_10 + (1 - y_p)*(h_3 - h_2)).to('kJ/kg')

Answer: The heat transfer input is �̇�𝑖𝑛/�̇� = 2808.15 kJ/kg

2. the thermal efficiency

To find the thermal efficiency, we need to calculate the net work output of the power plant. This involves all threeturbine stages and both of the pump stages. First, we need to calculate the mass fractions of the flow, 𝑦′ and 𝑦′′. Tofind these values, we need to draw control volumes around the feedwater heaters, moving from high pressure to lowpressure. 𝑦′ has already been found, so we need to find 𝑦′′

0 = �̇�7ℎ7 + �̇�12ℎ12 + �̇�4ℎ4 − �̇�8ℎ8

Dividing through by �̇�1 and noting that �̇�8 = �̇�1, �̇�12 = �̇�2, and �̇�7 = �̇�5,

0 = (1− 𝑦′ − 𝑦′′)ℎ7 + 𝑦′ℎ12 + 𝑦′′ℎ4 − ℎ8

𝑦′′ =ℎ8 − ℎ7 + 𝑦′(ℎ7 − ℎ12)

ℎ4 − ℎ7

[5]: y_pp = (h_8 - h_7 + y_p*(h_7 - h_12))/(h_4 - h_7)

Now, for the turbine stages,

�̇�𝑡 = �̇�1(ℎ1 − ℎ2) + �̇�3(ℎ3 − ℎ4) + �̇�5(ℎ4 − ℎ5)

�̇�𝑡

�̇�1= ℎ1 − ℎ2 + (1− 𝑦′)(ℎ3 − ℎ4) + (1− 𝑦′ − 𝑦′′)(ℎ4 − ℎ5)

[6]: Wdot_t = h_1 - h_2 + (1 - y_p)*(h_3 - h_4) + (1 - y_p - y_pp)*(h_4 - h_5)

3.5. Regen-Reheat Rankine Cycle Example 31

thermostate Documentation, Release 1.2.1

and for the pump stages

�̇�𝑝 = �̇�6(ℎ6 − ℎ7) + �̇�8(ℎ8 − ℎ9)

�̇�𝑝

�̇�1= (1− 𝑦′ − 𝑦′′)(ℎ6 − ℎ7) + ℎ8 − ℎ9

[7]: Wdot_p = (1 - y_p - y_pp)*(h_6 - h_7) + h_8 - h_9eta = ((Wdot_t + Wdot_p)/Qdot_in).to('dimensionless')

Answer: The thermal efficiency of the cycle is 𝜂 = 0.4617 = 46.17%

3. the rate of heat transfer out of the condenser into the cooling water

Drawing a control volume around the condenser, we can find the rate of heat transfer as

�̇�𝑜𝑢𝑡 = �̇�5(ℎ6 − ℎ5)

�̇�𝑜𝑢𝑡

�̇�1= (1− 𝑦′ − 𝑦′′)(ℎ6 − ℎ5)

[8]: Qdot_out = (1 - y_p - y_pp)*(h_6 - h_5).to('kJ/kg')

Answer: The rate of heat transfer is �̇�𝑜𝑢𝑡/�̇�1 = -1511.72 kJ/kg

3.6 Cascade Refrigeration Cycle Example

3.6.1 Imports

[1]: from thermostate import State, Q_, units, EnglishEngineering as EE

3.6.2 Definitions

[2]: sub_hiT = 'R22'sub_loT = 'R134A'

T_1 = Q_(-30.0, 'degF')x_1 = Q_(1.0, 'dimensionless')

p_2 = Q_(50.0, 'psi')

p_3 = p_2x_3 = Q_(0.0, 'dimensionless')

delta_T_5 = Q_(-5.0, 'delta_degF')x_5 = Q_(1.0, 'dimensionless')

p_6 = Q_(250.0, 'psi')

(continues on next page)

32 Chapter 3. Examples

thermostate Documentation, Release 1.2.1

(continued from previous page)

p_7 = p_6x_7 = Q_(0.0, 'dimensionless')

Qdot_in = Q_(20.0, 'refrigeration_tons')

3.6.3 Problem Statement

A two-stage cascade vapor-compression refrigeration system operates with R22 as the working fluid in the high-temperature cycle and R134A in the low-temperature cycle. For the R134A cycle, the working fluid enters the com-pressor as a saturated vapor at -30.0 fahrenheit and is compressed isentropically to 50 lbf/in.2 Saturated liquid leavesthe intermediate heat exchanger at 50 lbf/in.2 and enters the expansion valve. For the R22 cycle, the working fluidenters the compressor as saturated vapor at a temperature 5 fahrenheit below that of the condensing temperature of theR134A in the intermediate heat exchanger. The R22 is compressed isentropically to 250 lbf/in.2 Saturated liquid thenenters the expansion valve at 250 lbf/in.2. The refrigerating capacity of the cascade system is 20 ton_of_refrigeration.Determine

1. the power input to each compressor, in BTU/min

2. the overall coefficient of performance of the cascade cycle

3.6.4 Solution

1. the power input to each compressor

The power input to each compressor can be found by

�̇�𝑐𝑣 = �̇�(ℎ𝑖 − ℎ𝑒)

To find the enthalpies, we need to fix all of the states.

[3]: st_1 = State(sub_loT, x=x_1, T=T_1)h_1 = st_1.h.to(EE.h)s_1 = st_1.s.to(EE.s)p_1 = st_1.p.to(EE.p)

s_2 = s_1st_2 = State(sub_loT, p=p_2, s=s_1)h_2 = st_2.h.to(EE.h)T_2 = st_2.T.to(EE.T)

st_3 = State(sub_loT, p=p_3, x=x_3)T_3 = st_3.T.to(EE.T)h_3 = st_3.h.to(EE.h)s_3 = st_3.s.to(EE.s)

h_4 = h_3p_4 = p_1st_4 = State(sub_loT, p=p_4, h=h_4)

(continues on next page)

3.6. Cascade Refrigeration Cycle Example 33

thermostate Documentation, Release 1.2.1

(continued from previous page)

T_4 = st_4.T.to(EE.T)s_4 = st_4.s.to(EE.s)x_4 = st_4.x

T_5 = T_3 + delta_T_5st_5 = State(sub_hiT, T=T_5, x=x_5)h_5 = st_5.h.to(EE.h)p_5 = st_5.p.to(EE.p)s_5 = st_5.s.to(EE.s)

s_6 = s_5st_6 = State(sub_hiT, s=s_6, p=p_6)h_6 = st_6.h.to(EE.h)T_6 = st_6.T.to(EE.T)

st_7 = State(sub_hiT, p=p_7, x=x_7)T_7 = st_7.T.to(EE.T)h_7 = st_7.h.to(EE.h)s_7 = st_7.s.to(EE.s)

h_8 = h_7p_8 = p_5st_8 = State(sub_hiT, p=p_8, h=h_8)T_8 = st_8.T.to(EE.T)s_8 = st_8.s.to(EE.s)x_8 = st_8.x

Summarizing the states:

State T p h s x phase1 -30.00

degF9.86pound_force_per_square_inch

162.30 btu /pound

0.4196 btu / degR /pound

100.00% twophase

2 58.23degF

50.00pound_force_per_square_inch

176.42 btu /pound

0.4196 btu / degR /pound

— gas

3 40.27degF

50.00pound_force_per_square_inch

88.65 btu /pound

0.2442 btu / degR /pound

0.00% twophase

4 -30.00degF

9.86pound_force_per_square_inch

88.65 btu /pound

0.2482 btu / degR /pound

22.96% twophase

5 35.27degF

76.59pound_force_per_square_inch

174.42 btu /pound

0.4175 btu / degR /pound

100.00% twophase

6 146.75degF

250.00pound_force_per_square_inch

187.12 btu /pound

0.4175 btu / degR /pound

— gas

7 112.76degF

250.00pound_force_per_square_inch

110.14 btu /pound

0.2834 btu / degR /pound

0.00% twophase

8 35.27degF

76.59pound_force_per_square_inch

110.14 btu /pound

0.2876 btu / degR /pound

26.55% twophase

The mass flow rate of the R134a is found from the refrigeration capacity

�̇�R134A =�̇�𝑖𝑛

ℎ1 − ℎ4

while the mass flow rate of the R22 is found from the intermediate heat exchanger

�̇�R22 =�̇�R134A (ℎ2 − ℎ3)

ℎ5 − ℎ8

34 Chapter 3. Examples

thermostate Documentation, Release 1.2.1

[4]: mdot_r134a = (Qdot_in/(h_1 - h_4)).to('lb/min')Wdot_loT = (mdot_r134a*(h_1 - h_2)).to('BTU/min')

mdot_r22 = mdot_r134a*(h_2 - h_3)/(h_5 - h_8)Wdot_hiT = (mdot_r22*(h_5 - h_6)).to('BTU/min')

Answer: The compressor work for the low-temperature cycle is �̇�R134A = -766.52 btu / minute and the work for thehigh temperature cycle is �̇�R22 = -941.38 btu / minute

2. The coefficient of performance

The coefficient of performance of this refrigeration cycle is defined as

𝛽 =�̇�𝑖𝑛

|�̇�R134A + �̇�R22|

[5]: beta = (Qdot_in/abs(Wdot_loT + Wdot_hiT)).to('dimensionless')beta_max = (T_4/(T_7 - T_4)).to('dimensionless')

Answer: The coefficient of performance is 𝛽 = 2.34, while the maximum coefficient of performance for a refrigerationcycle operating between 𝑇𝐶 = -30.00 degF and 𝑇𝐻 = 112.76 degF is 𝛽max = 3.01 dimensionless. The actual cyclehas a lower COP, so it is possible.

3.6. Cascade Refrigeration Cycle Example 35

thermostate Documentation, Release 1.2.1

36 Chapter 3. Examples

CHAPTER

FOUR

THERMOSTATE

4.1 thermostate.thermostate module

Base ThermoState module.

class thermostate.thermostate.State(substance, **kwargs)Basic State manager for thermodyanmic states.

Parameters

• substance (str) – One of the substances supported by CoolProp

• T (pint.UnitRegistry.Quantity) – Temperature

• p (pint.UnitRegistry.Quantity) – Pressure

• u (pint.UnitRegistry.Quantity) – Mass-specific internal energy

• s (pint.UnitRegistry.Quantity) – Mass-specific entropy

• v (pint.UnitRegistry.Quantity) – Mass-specific volume

• h (pint.UnitRegistry.Quantity) – Mass-specific enthalpy

• x (pint.UnitRegistry.Quantity) – Quality

to_PropsSI(prop, value)CoolProp can’t handle Pint Quantites so return the magnitude only.

Convert to the appropriate SI units first.

to_SI(prop, value)Convert the input value to the appropriate SI base units.

exception thermostate.thermostate.StateErrorErrors associated with setting the State object.

thermostate.thermostate.isclose_quant(a, b, *args, **kwargs)Compare Pint Quantities to each other using math.isclose.

The Quantities must be in the same units.

thermostate.thermostate.munge_coolprop_input_prop(prop)Munge an input property pair from CoolProp into our format.

Example CoolProp input: XY_INPUTS, where X and Y are one of T, P, Dmass, Hmass, Umass, Q, or Smass.For use in ThermoState, we use lower case letters (except for T), replace D with v, and replace Q with x.

37

thermostate Documentation, Release 1.2.1

Examples

• DmassHmass_INPUTS: vh

• DmassT_INPUTS: vT

• PUmass_INPUTS: pu

thermostate.thermostate.render_traceback(self)Render a minimized version of the DimensionalityError traceback.

The default Jupyter/IPython traceback includes a lot of context from within pint that actually raises the Dimen-sionalityError. This context isn’t really needed for this particular error, since the problem is almost certainly inthe user code. This function removes the additional context.

4.2 thermostate.abbreviations module

This module contains classes with attributes representing the common property units.

Example

These classes are shortcuts to the units for common properties:

>>> st = State("water", T=Q_(300.0, "K"), p=Q_(101325, "Pa"))>>> h = st.h.to(SI.h)>>> u = st.u.to(EE.u)

class thermostate.abbreviations.EnglishEngineeringString representations of common units.

The attributes of this class are strings that represent the common units for thermodynamics calculations.

hBTU/lb

Type str

ppsi

Type str

sBTU/(lb*degR)

Type str

TdegF

Type str

uBTU/lb

Type str

vft**3/lb

38 Chapter 4. ThermoState

thermostate Documentation, Release 1.2.1

Type str

class thermostate.abbreviations.SystemInternationalString representations of common units.

The attributes of this class are strings that represent the common units for thermodynamics calculations.

hkJ/kg

Type str

pbar

Type str

skJ/(kg*K)

Type str

TdegC

Type str

ukJ/kg

Type str

vm**3/lb

Type str

4.2. thermostate.abbreviations module 39

thermostate Documentation, Release 1.2.1

40 Chapter 4. ThermoState

CHAPTER

FIVE

CHANGE LOG

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog and this project adheres to Semantic Versioning.

5.1 1.2.1 - 21-JUL-2020

5.1.1 Changed

• Allow Pint up to 1.0, they seem to be pretty stable between minor version releases

5.1.2 Fixed

• Typo in pythonpackage.yml

5.2 1.2.0 - 14-JUL-2020

5.2.1 Added

• Build CoolProp from the master branch to avoid any regressions

• Cache the built CoolProp wheel, based on the CoolProp master commit hash

5.2.2 Changed

• CoolProp 6.4.0 was released which supports Python 3.8 with their built wheels. Move the tests for Python 3.8to the main test build.

• The default branch is now called main.

41

thermostate Documentation, Release 1.2.1

5.2.3 Fixed

• Bump the MACOSX_DEPLOYMENT_TARGET for GitHub Actions, seems like they moved to 10.14

• Bump Pint version in the Conda recipe

• Add Matplotlib as a dependency in the Conda recipe

5.3 1.1.0 - 12-APR-2020

5.3.1 Added

• Build CoolProp and run the tests on Python 3.8

• Set up the Matplotlib functionality built into Pint. This bumps the minimum Pint version to 0.9 and addsMatplotlib as a dependency

5.3.2 Changed

• Updated documentation links in README and conda recipe to ReadTheDocs

5.3.3 Fixed

• The Rankine cycle example had a dimensionality error due to better NumPy support in Pint. Fixes #24.

5.4 1.0.0 - 03-MAR-2020

5.4.1 Added

• Switch to ReadTheDocs for documentation website

• Use setup.cfg and pyproject.toml for PEP 517 compliance

5.4.2 Changed

• Switch to src directory source layout

• Move tests outside of the package

• Apply Black formatter to tests

• Use tox to test against multiple Python versions

• Use GitHub Actions for CI services

• Run Black formatter on abbreviations.py and _version.py

• License year in LICENSE.md. Happy New Year :tada:

42 Chapter 5. Change Log

thermostate Documentation, Release 1.2.1

5.4.3 Fixed

• README.md and CHANGELOG.md are now included in the sdist

• hx and xh are added to the disallowed property pairs because they raise ValueErrors in CoolProp

• Missing docstrings from some functions in thermostate.py

5.5 0.5.3 - 04-MAR-2019

5.5.1 Added

• Check if temperature, pressure, and specific volume are positive (in absolute units)

• Check if the quality is between 0 and 1

5.5.2 Changed

• Bump maximum allowed version of Pint

5.6 0.5.2 - 01-FEB-2019

5.6.1 Added

• Install conda-verify on Travis when building tags to fix a warning from conda-build

5.6.2 Changed

• Formatted thermostate.py with the Black formatter

5.6.3 Fixed

• Broken link in CONTRIBUTING.md to LICENSE.md

• Installation instructions for CoolProp updated for Python 3.7

• Equality checking for States now considers the substance [#17]. Resolves #16 (Thanks @egurra!)

5.7 0.5.1 - 05-JAN-2019

5.7.1 Added

• JOSE badge to README

5.5. 0.5.3 - 04-MAR-2019 43

thermostate Documentation, Release 1.2.1

5.7.2 Changed

• Allow version 6.2.* of CoolProp

• Install CoolProp package for Python 3.7 from conda

5.7.3 Fixed

• License year in LICENSE.md. Happy new year! :tada:

5.8 0.5.0 - 23-OCT-2018

5.8.1 Added

• Add JOSE paper

• Add installation, documentation, code of conduct, and contributing links to README

• Document the classes in the abbreviations module

• Example of a cascade refrigeration cycle using EE units

• Test on Python 3.7 using the nightly version of CoolProp

5.8.2 Changed

• Use the generic Python 3 for the intersphinx config rather than version specific

5.8.3 Fixed

• Fix numpy and matplotlib need to be installed on Travis to build the docs

• Fix typo in code of conduct

5.8.4 Removed

• Don’t load the Sphinx coverage extensions

5.9 0.4.2 - 21-SEP-2018

5.9.1 Fixed

• Travis PyPI password

44 Chapter 5. Change Log

thermostate Documentation, Release 1.2.1

5.10 0.4.1 - 21-SEP-2018

5.10.1 Added

• Add codemeta.json

5.10.2 Fixed

• Fix builds in .travis.yml

• Can’t use Python 3.6 type hinting with Python 3.5

5.11 0.4.0 - 21-SEP-2018

5.11.1 Added

• _render_traceback_ function added to StateError to improve formatting of the traceback in IPythonand Jupyter

• Add several examples demonstrating the use of ThermoState

5.11.2 Changed

• Bump intersphinx mapping to Python 3.7

• Change docs license to CC-BY 4.0

5.11.3 Fixed

• Ignore more pytest files

5.12 0.3.0 - 09-JUL-2018

5.12.1 Fixed

• Added flake8 configuration to setup.cfg since linter-flake8 reads it and ignores built-in options

• Only define _render_traceback_ if IPython is installed

5.10. 0.4.1 - 21-SEP-2018 45

thermostate Documentation, Release 1.2.1

5.13 0.2.4 - 08-JUL-2018

5.13.1 Added

• Added _render_traceback_ function to improve traceback formatting of pint.DimensionalityError

5.13.2 Fixed

• Added oxygen, nitrogen, and carbondioxide as available substances to the Tutorial

5.14 0.2.3 - 24-SEP-2017

5.14.1 Added

• Distributions are now uploaded to PyPI

5.14.2 Changed

• Conda packages are noarch builds

• Appveyor tests run in a single job to speed them up

• Minimum Python version is 3.5

5.15 0.2.2 - 13-APR-2017

5.15.1 Added

• Oxygen (O2) is available as a substance

• Nitrogen (N2) is available as a substance

5.15.2 Fixed

• Deploy doctr to the root directory (see drdoctr/doctr#157 and drdoctr/doctr#160)

5.16 0.2.1

5.16.1 Added

• Carbon dioxide is available as a substance

• The software version is available as the module-level __version__ attribute

46 Chapter 5. Change Log

thermostate Documentation, Release 1.2.1

5.17 0.2.0

5.17.1 Added

• Equality comparison of State instances

5.17.2 Changed

• Improve several error messages

• Refactor property getting/setting to use less boilerplate code

• Preface all class attributes with _

• Refactor _set_properties to use CoolProp low-level API

5.18 0.1.7

5.18.1 Added

• Phase as a gettable attribute of the State

• Isobutane is an available substance

• Add cp and cv to Tutorial

5.18.2 Changed

• Updated Tutorial with more detail of setting properties

• Fail Travis when a single command fails

5.19 0.1.6

5.19.1 Added

• Tutorial in the docs using nbsphinx for formatting

• Specific heat capacities at constant pressure and volume are now accessible via cp and cv attributes

5.19.2 Changed

• Offset units are automatically converted to base units in Pint

5.17. 0.2.0 47

thermostate Documentation, Release 1.2.1

5.20 0.1.5

5.20.1 Changed

• Unknown property pairs are no longer allowed to be set

5.21 0.1.4

5.21.1 Fixed

• Rename units module to abbreviations so it no longer shadows units registry in thermostate

5.22 0.1.3

5.22.1 Added

• Common unit abbreviations in thermostate.EnglishEngineering and thermostate.SystemInternational

5.22.2 Fixed

• Typo in CHANGELOG.md

5.23 0.1.2

5.23.1 Fixed

• Fix Anaconda.org upload keys

5.24 0.1.1

5.24.1 Fixed

• Only load pytest-runner if tests are being run

48 Chapter 5. Change Log

thermostate Documentation, Release 1.2.1

5.25 0.1.0

5.25.1 Added

• First Release

5.25. 0.1.0 49

thermostate Documentation, Release 1.2.1

50 Chapter 5. Change Log

CHAPTER

SIX

CONTRIBUTOR COVENANT CODE OF CONDUCT

6.1 Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to makingparticipation in our project and our community a harassment-free experience for everyone, regardless of age, bodysize, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race,religion, or sexual identity and orientation.

6.2 Our Standards

Examples of behavior that contributes to creating a positive environment include:

• Using welcoming and inclusive language

• Being respectful of differing viewpoints and experiences

• Gracefully accepting constructive criticism

• Focusing on what is best for the community

• Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

• The use of sexualized language or imagery and unwelcome sexual attention or advances

• Trolling, insulting/derogatory comments, and personal or political attacks

• Public or private harassment

• Publishing others’ private information, such as a physical or electronic address, without explicit permission

• Other conduct which could reasonably be considered inappropriate in a professional setting

6.3 Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appro-priate and fair corrective action in response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits,issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently anycontributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

51

thermostate Documentation, Release 1.2.1

6.4 Scope

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing theproject or its community. Examples of representing a project or community include using an official project e-mailaddress, posting via an official social media account, or acting as an appointed representative at an online or offlineevent. Representation of a project may be further defined and clarified by project maintainers.

6.5 Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project teamat [email protected]. All complaints will be reviewed and investigated and will result in a response that isdeemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality withregard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanentrepercussions as determined by other members of the project’s leadership.

6.6 Attribution

This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at http://contributor-covenant.org/version/1/4

52 Chapter 6. Contributor Covenant Code of Conduct

CHAPTER

SEVEN

CONTRIBUTING

We welcome contributions in the form of bug reports, bug fixes, improvements to the documentation, ideas for en-hancements, or the enhancements themselves!

You can find a list of current issues in the project’s GitHub repository. Feel free to tackle any existing bugs orenhancement ideas by submitting a pull request. Some issues are marked as beginner-friendly. These issuesare a great place to start working with PyKED and ChemKED, if you’re new here.

7.1 Bug Reports

• Please include a short (but detailed) Python snippet or explanation for reproducing the problem. Attach orinclude a link to any input files that will be needed to reproduce the error.

• Explain the behavior you expected, and how what you got differed.

• Include the full text of any error messages that are printed on the screen.

7.2 Pull Requests

• If you’re unfamiliar with Pull Requests, please take a look at the GitHub documentation for them.

• Make sure the test suite passes on your computer, and that test coverage doesn’t go down. To do this, runpytest -vv --cov=./ from the top-level directory.

• Always add tests and docs for your code.

• Please reference relevant GitHub issues in your commit messages using GH123 or #123.

• Changes should be PEP8 and PEP257 compatible.

• Keep style fixes to a separate commit to make your pull request more readable.

• Add your changes into the CHANGELOG

• Docstrings are required and should follow the NumPy style.

• When you start working on a pull request, start by creating a new branch pointing at the latest commit on GitHubmaster.

• The copyright policy is detailed in the LICENSE.

53

thermostate Documentation, Release 1.2.1

7.3 Meta

Thanks to the useful contributing guide of pyrk, which served as an inspiration and starting point for this guide.

54 Chapter 7. Contributing

CHAPTER

EIGHT

INDICES AND TABLES

• genindex

• modindex

• search

55

thermostate Documentation, Release 1.2.1

56 Chapter 8. Indices and tables

PYTHON MODULE INDEX

tthermostate.abbreviations, 38thermostate.thermostate, 37

57

thermostate Documentation, Release 1.2.1

58 Python Module Index

INDEX

EEnglishEngineering (class in ther-

mostate.abbreviations), 38

Hh (thermostate.abbreviations.EnglishEngineering at-

tribute), 38h (thermostate.abbreviations.SystemInternational at-

tribute), 39

Iisclose_quant() (in module ther-

mostate.thermostate), 37

Mmodule

thermostate.abbreviations, 38thermostate.thermostate, 37

munge_coolprop_input_prop() (in module ther-mostate.thermostate), 37

Pp (thermostate.abbreviations.EnglishEngineering at-

tribute), 38p (thermostate.abbreviations.SystemInternational at-

tribute), 39

Rrender_traceback() (in module ther-

mostate.thermostate), 38

Ss (thermostate.abbreviations.EnglishEngineering at-

tribute), 38s (thermostate.abbreviations.SystemInternational at-

tribute), 39State (class in thermostate.thermostate), 37StateError, 37SystemInternational (class in ther-

mostate.abbreviations), 39

TT (thermostate.abbreviations.EnglishEngineering at-

tribute), 38T (thermostate.abbreviations.SystemInternational at-

tribute), 39thermostate.abbreviations

module, 38thermostate.thermostate

module, 37to_PropsSI() (thermostate.thermostate.State

method), 37to_SI() (thermostate.thermostate.State method), 37

Uu (thermostate.abbreviations.EnglishEngineering at-

tribute), 38u (thermostate.abbreviations.SystemInternational at-

tribute), 39

Vv (thermostate.abbreviations.EnglishEngineering at-

tribute), 38v (thermostate.abbreviations.SystemInternational at-

tribute), 39

59