Tutorial#

import ccp

Q_ = ccp.Q_

ccp uses pint to handle units. Q_ is a pint quantity.

Here lets define a suction pressure ps and a suction temperature Ts.

For the suction pressure we are going to use pint\(.\)

ps = Q_(3, "bar")
Ts = 300

The pint objects hold the magnitude and units for a variable and can be used for unit conversion:

print(
    f"ps: {ps}\n"
    f"ps magnitude: {ps.magnitude}\n"
    f"ps units: {ps.units}\n"
    f"convert to atm: {ps.to('atm')}\n"
)
ps: 3 bar
ps magnitude: 3
ps units: bar
convert to atm: 2.960769800148039 standard_atmosphere

We define the fluid composition is defined as a dictionary:

fluid = {
    "CarbonDioxide": 0.79585,
    "Nitrogen": 0.16751,
    "Oxygen": 0.02903,
}

We can create the suction and discharge states using the State class:

suc0 = ccp.State(fluid=fluid, p=ps, T=Ts)
disch0 = ccp.State(fluid=fluid, p=Q_(7.255, "bar"), T=391.1)

Notice that in the cell above we defined the states using pint quantities mixed with pure floats.

The way that ccp works is by assuming that float are in the SI units system, so

disch0 = ccp.State(fluid=fluid, p=Q_(7.255, 'bar'), T=391.1)

is the same as

disch0 = ccp.State(fluid=fluid, p=Q_(7.255, 'bar'), T=Q_(391.1, 'degK'))

Create performance point(s):

point0 = ccp.Point(
    suc=suc0,
    disch=disch0,
    speed=Q_(7941, "RPM"),
    flow_m=Q_(34203.6, "kg/hr"),
    b=0.0285,
    D=0.365,
)
point1 = ccp.Point(
    suc=suc0,
    disch=disch0,
    speed=Q_(7941, "RPM"),
    flow_m=Q_(37203.6, "kg/hr"),
    b=0.0285,
    D=0.365,
)

Now we can create an impeller, which is basically a container for points.

imp = ccp.Impeller([point0, point1])
imp
<ccp.impeller.Impeller at 0x7fdaab15e2f0>

To show other ccp features we are going to load an impeller from csv files created with the Engauge Digitizer application. For more information on how to use ccp with Engaguge Digitizer see this How-to Guide

imp = ccp.impeller.impeller_example()

The impeller object stores all points in the .points attribute.

It is also possible to get an specific point in the performance map using the .point() method:

p = imp.point(flow_v=5.5, speed=900)
p
Point(suc=State(p=Q_("408000 Pa"), T=Q_("307 K"), fluid={"METHANE": 0.58976, "CO2": 0.36605, "ETHANE": 0.03099, "PROPANE": 0.00600, "NITROGEN": 0.00550, "BUTANE": 0.00080, "ISOBUTAN": 0.00050, "H2S": 0.00020, "PENTANE": 0.00010, "IPENTANE": 0.00010}), speed=Q_("900 rad/s"), flow_v=Q_("5.50 m³/s"), head=Q_("110601 J/kg"), eff=Q_("0.780"), power_losses=Q_("0 W"))

We can access the suction or discharge condition for this point with p.suc or p.disch and get some properties for this states:

p.disch.rho()
9.228766787073013 kilogram/meter3

We can also plot the phase envelope:

p.disch.plot_envelope()

We can also plot performance parameters such as the polytropic head. In this case we can choose a flow and speed and the correspondent curve and point will also be plotted:

fig = imp.head_plot(flow_v=5.5, speed=900)
fig

It is also possible to plot discharge parameters such as T (temperature), p (pressure), rho (specific mass) and so on:

fig = imp.disch.T_plot(flow_v=5.5, speed=900)
fig

In this plots we can also choose the units used for plotting:

fig = imp.disch.rho_plot(
    flow_v=5.5, speed=900, flow_v_units="m³/h", speed_units="RPM", rho_units="g/cm³"
)
fig

Notice that by default the units used in the flow_v and speed arguments are the SI units, but you can also provide pint quantities:

fig = imp.disch.rho_plot(
    flow_v=Q_(20000, "m³/h"),
    speed=Q_(8594, "RPM"),
    flow_v_units="m³/h",
    speed_units="RPM",
    rho_units="g/cm³",
)
fig

Now we are going to convert the performance map from an impeller to a different suction condition:

new_fluid = {
    "co2": 0.7,
    "n2": 0.3
}
new_suc = ccp.State(p=Q_(10, 'bar'), T=Q_(40, 'degC'), fluid=new_fluid)

imp_conv = ccp.Impeller.convert_from(imp, suc=new_suc)

The conversion calculates new speeds based on similarity.

The new impeller has the same attributes and methods as the original one:

imp_conv.disch.p_plot(speed_units="RPM")

There is also an option to keep the same speeds as the original impeller during the conversion:

imp_conv = ccp.Impeller.convert_from(imp, suc=new_suc, speed="same")

We can also compare the curves from the original impeller with the converted one using the _compare methods:

imp.head_compare(imp_conv)