Version 0.5.0#
Version 0.5.0 ships the new ccp application, a Django web app that replaces the Streamlit app and runs as a desktop window or in the browser. It also adds automatic digitizing of performance-curve PDFs, an agent API so AI agents can work with the case open in the app, a faster thermodynamic core and a more robust point solver.
Highlights#
The new ccp application (
ccp_web) is included in the package. Install it (python >= 3.10) withpip install "ccp-performance[desktop]"(or[web]for the browser only) and start it withccp-app.ccp-appnow opens the new application. The Streamlit app is still available withccp-app --streamlit.New
ccp.digitizereads vendor performance-curve PDFs, with a curves digitizer page in the app.AI agents can read and change the case open in the app, run its calculation and post notes, through
ccp-web agentor an MCP server.Point creation converges for every polytropic method and fluid of the Evans and Huble case set, and the calculation pipelines are faster.
head_isentropic/eff_isentropicreturn the exact isentropic head defined by PTC 10 and ISO 5389 instead of a closed-form approximation.
Running the application#
pip install "ccp-performance[desktop]" # native window (pywebview)
pip install "ccp-performance[web]" # browser only
ccp-app # desktop window, or the browser if it cannot open
ccp-web serve --port 8000 # always the browser, on a chosen port
python -m ccp_web # same as ccp-app, where console scripts are not on the PATH
The web, desktop and hosted extras need python >= 3.10; on python 3.9
they install nothing, and ccp-web says so. ccp-app, ccp-web and
python -m ccp_web open the desktop window when pywebview, a GUI toolkit for
it and a display are available (on Linux the desktop extra installs no
toolkit: install pywebview[qt], or pywebview[gtk] with the WebKit2GTK
system libraries) and fall back to the browser otherwise; ccp-web desktop
reports the missing piece instead. The app applies its migrations at start
and keeps cases, files and results in the user data directory
(CCP_DATA_DIR overrides it). REFPROP is optional: without RPPREFIX ccp
uses CoolProp. The curves digitizer page also needs the digitize extra and
the Tesseract OCR binary.
New features#
ccp web application (#170) — the
ccp_webDjango app ports the four Streamlit pages: straight-through and back-to-back performance tests (ASME PTC 10), curves conversion, and performance evaluation of plant data with online monitoring and the HTML report. Calculations run as background jobs with progress and cancel..ccpfiles import and export losslessly in both apps. The app runs as a single-user desktop application (SQLite in the user data directory, secrets in the OS keyring) or, withCCP_PROFILE=hostedand thehostedextra, as a multi-user service (deploy/hosted/). New console scriptccp-web(desktop,serve,worker,manage,agent) and new extrasweb,desktopandhosted.Curves digitizing (#171) —
ccp.digitize(digitize_pdf) reads a vendor performance-curve document and returns every operating case with its speed lines, legend speeds and suction conditions, from the PDF vector content or from the rendered image for scans. The app gets a curves digitizer page with a plot editor to review the traced points. Needs the newdigitizeextra and Tesseract OCR.Agent API (#174) — AI agents can see what the user has open in the app, read inputs and results, change the open case, run its calculation and post notes the user sees. Every agent write is undoable from the app. The desktop launcher issues a fresh token at each start (
--no-agentturns it off); theccp-web agentCLI and the MCP server (ccp-web agent mcp) need only the base package. The agent skill gains alive_apprecipe.Faster thermodynamic core (#168) — states built without a phase get it imposed after the first flash (
ccp.config.DEFAULT_PHASE), which removes the phase-stability analysis from the point solver flashes, andImpellerinterpolates and shares points instead of deep-copying them.
Bug fixes#
Exact isentropic head (#172) —
ccp.point.head_isentropicreturned Schultz’s closed form \(\frac{n_s}{n_s-1}(p_2 v_{2s} - p_1 v_1)\) instead of the isentropic enthalpy rise \(h(p_2, s_1) - h_1\) that ASME PTC 10-1997 (para. 2.6.2) and ISO 5389 define. The closed form assumes a constant isentropic exponent along the path, which fails for dense or near-critical gases: for CO2 at 80 → 250 bareff_isentropicgave 0.800 against an exact 0.779. The difference is negligible for near-ideal gases (0.07 % for N2 at low pressure).Point,f_schultzand everyhead_pol_*method are not affected.Point solver robustness (#169) — every discharge closure is bracketed by the suction and the isentropic discharge and solved with
ccp.roots.solve_monotone, so Point creation converges for every polytropic method and fluid of the Evans and Huble 2017 case set.sandberg_colby_multisteppoints (#164) —Pointwithpolytropic_method="sandberg_colby_multistep"no longer raisesTypeError.Point solver errors (#166) — a point that cannot be calculated raises
ValueErrornaming the solver error instead of anAttributeErrorlater on.State.T_criticalunits (#167) — theunitsargument is honored; docs now state that the default polytropic method issandberg_colby.Lossless compressor test points (#170) —
StraightThroughandBackToBacksave points defined by a measured discharge withdisch_panddisch_T, so a reloaded compressor converts its points exactly; older files still load.
API changes#
ccp-appopens the new application instead of the Streamlit app; the Streamlit app is started withccp-app --streamlit(appextra) (#170).Without the
webextra (or on python 3.9),ccp-webprints how to install it instead of failing withModuleNotFoundError;ccp-appruns the Streamlit app when only theappextra is installed and otherwise prints the same hint.States built without a phase get
ccp.config.DEFAULT_PHASE = "gas"imposed when the density check confirms it; setccp.config.DEFAULT_PHASE = Noneto restore the previous behaviour, or passphase=Falseto a single state (#168).Impellershares the points it is given instead of deep-copying them (#168).Pointraises aValueErrorfor a suction with vapour quality between 0 and 1 before solving;Evaluationinstead emits aPhaseWarningfor a wet cluster-centre suction and converts with the unconstrained state (#169, #170).head_pol_sandberg_colby_multistepandeff_pol_sandberg_colby_multisteptakedisch_sas their third argument;nstepmoved to the fourth position (#164).check_similarityreports the PTC 10-2022 Reynolds envelope shared withPoint.reynolds_limits, and the unusedphi3was removed (#169).head_isentropicandeff_isentropicreturn the exact values; the previous closed form is available ashead_isentropic_pvn/eff_isentropic_pvn.head_pol/eff_pol(the \(pv^n\) closed form without correction) are renamedhead_pol_pvn/eff_pol_pvn; the old names are deprecated aliases that emit aDeprecationWarning(#172).
Infrastructure and packaging#
The wheel ships
ccp_web(#175) — the published wheel and sdist contain theccp_webpackage with its templates, static files and migrations. The release workflow builds the wheel from the sdist and checks both before upload: every file git tracks underccp/andccp_web/must be in them, and no compiled bytecode may be. A CI job installs the wheel with thewebextra in a clean environment (python 3.10 and 3.13), applies the migrations and serves a page.packagingis now a declared dependency (it was only installed through plotly), and thewebextra requiresdjango-allauth>=65.5, the first version that honours the hosted profile’s e-mail login settings. The license is declared as an SPDX expression (setuptools >= 77 to build), and the Python classifiers list 3.9 to 3.13.CI runs the web app tests in both the desktop and the hosted profile (#170).
A PyInstaller spec for the desktop app (
build/ccp_web.spec) and a Docker setup for hosted deployments (deploy/hosted/) were added to the repository (#170).