mfcblend 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mfcblend-0.1.0/.github/ISSUE_TEMPLATE/bug.yml +27 -0
- mfcblend-0.1.0/.github/ISSUE_TEMPLATE/dataset.yml +26 -0
- mfcblend-0.1.0/.github/ISSUE_TEMPLATE/feature.yml +20 -0
- mfcblend-0.1.0/.github/ISSUE_TEMPLATE/macos.yml +52 -0
- mfcblend-0.1.0/.github/ISSUE_TEMPLATE/scientific.yml +26 -0
- mfcblend-0.1.0/.github/dependabot.yml +10 -0
- mfcblend-0.1.0/.github/workflows/ci.yml +140 -0
- mfcblend-0.1.0/.github/workflows/macos.yml +96 -0
- mfcblend-0.1.0/.github/workflows/release.yml +66 -0
- mfcblend-0.1.0/.gitignore +12 -0
- mfcblend-0.1.0/CHANGELOG.md +11 -0
- mfcblend-0.1.0/CITATION.cff +16 -0
- mfcblend-0.1.0/CONTRIBUTING.md +29 -0
- mfcblend-0.1.0/LICENSE +21 -0
- mfcblend-0.1.0/PKG-INFO +230 -0
- mfcblend-0.1.0/README.md +169 -0
- mfcblend-0.1.0/SECURITY.md +15 -0
- mfcblend-0.1.0/docs/assets/social-preview.png +0 -0
- mfcblend-0.1.0/docs/macos.md +58 -0
- mfcblend-0.1.0/docs/research/naming-audit.md +59 -0
- mfcblend-0.1.0/docs/scientific-basis.md +69 -0
- mfcblend-0.1.0/docs/validation.md +16 -0
- mfcblend-0.1.0/examples/co2_hydrogen_system.json +28 -0
- mfcblend-0.1.0/examples/infeasible_target.json +7 -0
- mfcblend-0.1.0/examples/setpoints_5co2_20h2.json +7 -0
- mfcblend-0.1.0/examples/target_5co2_20h2.json +7 -0
- mfcblend-0.1.0/pyproject.toml +87 -0
- mfcblend-0.1.0/scripts/generate_preview.py +18 -0
- mfcblend-0.1.0/src/mfcblend/__init__.py +37 -0
- mfcblend-0.1.0/src/mfcblend/__main__.py +3 -0
- mfcblend-0.1.0/src/mfcblend/application/__init__.py +5 -0
- mfcblend-0.1.0/src/mfcblend/application/service.py +38 -0
- mfcblend-0.1.0/src/mfcblend/cli.py +79 -0
- mfcblend-0.1.0/src/mfcblend/core/__init__.py +31 -0
- mfcblend-0.1.0/src/mfcblend/core/derived.py +42 -0
- mfcblend-0.1.0/src/mfcblend/core/mixing.py +259 -0
- mfcblend-0.1.0/src/mfcblend/core/models.py +172 -0
- mfcblend-0.1.0/src/mfcblend/core/standard.py +47 -0
- mfcblend-0.1.0/src/mfcblend/gui/__init__.py +31 -0
- mfcblend-0.1.0/src/mfcblend/gui/__main__.py +45 -0
- mfcblend-0.1.0/src/mfcblend/gui/app.py +199 -0
- mfcblend-0.1.0/src/mfcblend/io/__init__.py +5 -0
- mfcblend-0.1.0/src/mfcblend/io/config.py +189 -0
- mfcblend-0.1.0/src/mfcblend/plotting/__init__.py +5 -0
- mfcblend-0.1.0/src/mfcblend/plotting/feed_diagram.py +139 -0
- mfcblend-0.1.0/src/mfcblend/py.typed +1 -0
- mfcblend-0.1.0/tests/conftest.py +8 -0
- mfcblend-0.1.0/tests/gui_widget_smoke.py +33 -0
- mfcblend-0.1.0/tests/integration/test_io_cli.py +117 -0
- mfcblend-0.1.0/tests/macos/test_gui_backend_policy.py +23 -0
- mfcblend-0.1.0/tests/test_project_policy.py +39 -0
- mfcblend-0.1.0/tests/unit/test_mixing.py +112 -0
- mfcblend-0.1.0/tests/unit/test_standard_and_derived.py +39 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report reproducible incorrect behavior unrelated to scientific interpretation.
|
|
3
|
+
title: "[Bug]: "
|
|
4
|
+
labels: [bug]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: Do not upload confidential, proprietary, export-controlled, or unpublished research data.
|
|
9
|
+
- type: textarea
|
|
10
|
+
id: behavior
|
|
11
|
+
attributes:
|
|
12
|
+
label: Observed and expected behavior
|
|
13
|
+
validations:
|
|
14
|
+
required: true
|
|
15
|
+
- type: textarea
|
|
16
|
+
id: reproduce
|
|
17
|
+
attributes:
|
|
18
|
+
label: Minimal reproduction
|
|
19
|
+
description: Redact sensitive cylinder and facility information.
|
|
20
|
+
validations:
|
|
21
|
+
required: true
|
|
22
|
+
- type: input
|
|
23
|
+
id: version
|
|
24
|
+
attributes:
|
|
25
|
+
label: MFCBlend and Python versions
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Real dataset compatibility
|
|
2
|
+
description: Propose or report a public catalytic-reactor feed dataset.
|
|
3
|
+
title: "[Dataset]: "
|
|
4
|
+
labels: [dataset]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: Only link data you are authorized to share. Do not upload confidential or unpublished data.
|
|
9
|
+
- type: input
|
|
10
|
+
id: identifier
|
|
11
|
+
attributes:
|
|
12
|
+
label: DOI or stable identifier
|
|
13
|
+
validations:
|
|
14
|
+
required: true
|
|
15
|
+
- type: input
|
|
16
|
+
id: license
|
|
17
|
+
attributes:
|
|
18
|
+
label: Dataset license
|
|
19
|
+
validations:
|
|
20
|
+
required: true
|
|
21
|
+
- type: textarea
|
|
22
|
+
id: scope
|
|
23
|
+
attributes:
|
|
24
|
+
label: Files, checksum, and proposed validation scope
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Propose a focused gas-feed planning workflow.
|
|
3
|
+
title: "[Feature]: "
|
|
4
|
+
labels: [enhancement]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: Do not include confidential facility or research information.
|
|
9
|
+
- type: textarea
|
|
10
|
+
id: workflow
|
|
11
|
+
attributes:
|
|
12
|
+
label: Research workflow and decision supported
|
|
13
|
+
validations:
|
|
14
|
+
required: true
|
|
15
|
+
- type: textarea
|
|
16
|
+
id: science
|
|
17
|
+
attributes:
|
|
18
|
+
label: Definitions, units, assumptions, and references
|
|
19
|
+
validations:
|
|
20
|
+
required: true
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: macOS or GUI issue
|
|
2
|
+
description: Report installation, Tkinter, backend, lifecycle, or export problems on macOS.
|
|
3
|
+
title: "[macOS/GUI]: "
|
|
4
|
+
labels: [macos, gui]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: Do not upload confidential data. Include the full traceback after removing sensitive paths.
|
|
9
|
+
- type: input
|
|
10
|
+
id: macos
|
|
11
|
+
attributes:
|
|
12
|
+
label: macOS version
|
|
13
|
+
validations:
|
|
14
|
+
required: true
|
|
15
|
+
- type: dropdown
|
|
16
|
+
id: architecture
|
|
17
|
+
attributes:
|
|
18
|
+
label: Architecture
|
|
19
|
+
options: [Apple Silicon, Intel]
|
|
20
|
+
validations:
|
|
21
|
+
required: true
|
|
22
|
+
- type: input
|
|
23
|
+
id: python
|
|
24
|
+
attributes:
|
|
25
|
+
label: Python version
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
28
|
+
- type: input
|
|
29
|
+
id: package
|
|
30
|
+
attributes:
|
|
31
|
+
label: MFCBlend version
|
|
32
|
+
validations:
|
|
33
|
+
required: true
|
|
34
|
+
- type: input
|
|
35
|
+
id: framework
|
|
36
|
+
attributes:
|
|
37
|
+
label: Tk/Tcl version
|
|
38
|
+
validations:
|
|
39
|
+
required: true
|
|
40
|
+
- type: textarea
|
|
41
|
+
id: install
|
|
42
|
+
attributes:
|
|
43
|
+
label: Installation method and command
|
|
44
|
+
validations:
|
|
45
|
+
required: true
|
|
46
|
+
- type: textarea
|
|
47
|
+
id: traceback
|
|
48
|
+
attributes:
|
|
49
|
+
label: Full traceback
|
|
50
|
+
render: shell
|
|
51
|
+
validations:
|
|
52
|
+
required: true
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Scientific result question
|
|
2
|
+
description: Ask about an equation, convention, unit basis, or calculated result.
|
|
3
|
+
title: "[Scientific result]: "
|
|
4
|
+
labels: [scientific-question]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: Do not upload unpublished or confidential research data. MFCBlend is not a process-safety assessment.
|
|
9
|
+
- type: textarea
|
|
10
|
+
id: definition
|
|
11
|
+
attributes:
|
|
12
|
+
label: Equation, definition, and unit basis in question
|
|
13
|
+
validations:
|
|
14
|
+
required: true
|
|
15
|
+
- type: textarea
|
|
16
|
+
id: reference
|
|
17
|
+
attributes:
|
|
18
|
+
label: Authoritative reference or hand calculation
|
|
19
|
+
validations:
|
|
20
|
+
required: true
|
|
21
|
+
- type: textarea
|
|
22
|
+
id: minimal
|
|
23
|
+
attributes:
|
|
24
|
+
label: Minimal non-confidential input and result
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
name: DGX CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: mfcblend-dgx-${{ github.event.pull_request.number || github.ref }}
|
|
15
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
required:
|
|
19
|
+
name: DGX / required
|
|
20
|
+
if: >-
|
|
21
|
+
github.event_name != 'pull_request' ||
|
|
22
|
+
(github.actor == github.repository_owner &&
|
|
23
|
+
github.event.pull_request.head.repo.full_name == github.repository)
|
|
24
|
+
runs-on: [self-hosted, Linux, ARM64, dgx-spark]
|
|
25
|
+
timeout-minutes: 60
|
|
26
|
+
env:
|
|
27
|
+
PIP_NO_CACHE_DIR: "1"
|
|
28
|
+
PYTHONDONTWRITEBYTECODE: "1"
|
|
29
|
+
steps:
|
|
30
|
+
- name: Check out source
|
|
31
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
32
|
+
with:
|
|
33
|
+
clean: true
|
|
34
|
+
fetch-depth: 0
|
|
35
|
+
persist-credentials: false
|
|
36
|
+
- name: Set up Python
|
|
37
|
+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
38
|
+
with:
|
|
39
|
+
python-version: "3.13"
|
|
40
|
+
- name: Configure validated shared Tk and Xvfb runtime
|
|
41
|
+
env:
|
|
42
|
+
MFCBLEND_GUI_RUNTIME: /opt/catalysttwin-actions/shared-gui-runtime
|
|
43
|
+
run: |
|
|
44
|
+
set -eu
|
|
45
|
+
test -x "$MFCBLEND_GUI_RUNTIME/usr/bin/Xvfb"
|
|
46
|
+
test -x "$MFCBLEND_GUI_RUNTIME/usr/bin/xvfb-run"
|
|
47
|
+
test -d "$MFCBLEND_GUI_RUNTIME/usr/lib/aarch64-linux-gnu"
|
|
48
|
+
test -d "$MFCBLEND_GUI_RUNTIME/usr/share/tcltk/tk8.6"
|
|
49
|
+
echo "$MFCBLEND_GUI_RUNTIME/usr/bin" >> "$GITHUB_PATH"
|
|
50
|
+
{
|
|
51
|
+
echo "LD_LIBRARY_PATH=$MFCBLEND_GUI_RUNTIME/usr/lib/aarch64-linux-gnu${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
|
52
|
+
echo "TK_LIBRARY=$MFCBLEND_GUI_RUNTIME/usr/share/tcltk/tk8.6"
|
|
53
|
+
} >> "$GITHUB_ENV"
|
|
54
|
+
- name: Create isolated job environments
|
|
55
|
+
run: |
|
|
56
|
+
export MFCBLEND_CI_ROOT="$RUNNER_TEMP/mfcblend-ci-$GITHUB_RUN_ID-$GITHUB_RUN_ATTEMPT"
|
|
57
|
+
echo "MFCBLEND_CI_ROOT=$MFCBLEND_CI_ROOT" >> "$GITHUB_ENV"
|
|
58
|
+
python - <<'PY'
|
|
59
|
+
import os
|
|
60
|
+
from pathlib import Path
|
|
61
|
+
|
|
62
|
+
root = Path(os.environ["MFCBLEND_CI_ROOT"]).resolve()
|
|
63
|
+
runner_temp = Path(os.environ["RUNNER_TEMP"]).resolve()
|
|
64
|
+
if root.parent != runner_temp or not root.name.startswith("mfcblend-ci-"):
|
|
65
|
+
raise RuntimeError(f"Unsafe CI root: {root}")
|
|
66
|
+
root.mkdir()
|
|
67
|
+
PY
|
|
68
|
+
python -m venv "$MFCBLEND_CI_ROOT/dev-venv"
|
|
69
|
+
python -m venv "$MFCBLEND_CI_ROOT/wheel-venv"
|
|
70
|
+
- name: Install development environment
|
|
71
|
+
run: |
|
|
72
|
+
"$MFCBLEND_CI_ROOT/dev-venv/bin/python" -m pip install --upgrade pip
|
|
73
|
+
"$MFCBLEND_CI_ROOT/dev-venv/bin/python" -m pip install -e ".[dev]"
|
|
74
|
+
"$MFCBLEND_CI_ROOT/dev-venv/bin/python" -m pip check
|
|
75
|
+
xvfb-run -a "$MFCBLEND_CI_ROOT/dev-venv/bin/python" -c 'import tkinter; print(tkinter.TkVersion)'
|
|
76
|
+
- name: Ruff format
|
|
77
|
+
run: >-
|
|
78
|
+
"$MFCBLEND_CI_ROOT/dev-venv/bin/python" -m ruff format --check .
|
|
79
|
+
- name: Ruff lint
|
|
80
|
+
run: >-
|
|
81
|
+
"$MFCBLEND_CI_ROOT/dev-venv/bin/python" -m ruff check .
|
|
82
|
+
- name: Strict type check
|
|
83
|
+
run: >-
|
|
84
|
+
"$MFCBLEND_CI_ROOT/dev-venv/bin/python" -m mypy src
|
|
85
|
+
- name: Unit, integration, and scientific regression tests
|
|
86
|
+
run: >-
|
|
87
|
+
"$MFCBLEND_CI_ROOT/dev-venv/bin/python" -m pytest
|
|
88
|
+
- name: CLI and example workflow smoke
|
|
89
|
+
run: |
|
|
90
|
+
"$MFCBLEND_CI_ROOT/dev-venv/bin/mfcblend" --help
|
|
91
|
+
"$MFCBLEND_CI_ROOT/dev-venv/bin/mfcblend" validate examples/co2_hydrogen_system.json
|
|
92
|
+
"$MFCBLEND_CI_ROOT/dev-venv/bin/mfcblend" inverse \
|
|
93
|
+
examples/co2_hydrogen_system.json examples/target_5co2_20h2.json \
|
|
94
|
+
--output "$MFCBLEND_CI_ROOT/example.json"
|
|
95
|
+
test -s "$MFCBLEND_CI_ROOT/example.json"
|
|
96
|
+
- name: Real Tk widget workflow and exit smoke
|
|
97
|
+
run: |
|
|
98
|
+
xvfb-run -a "$MFCBLEND_CI_ROOT/dev-venv/bin/python" tests/gui_widget_smoke.py \
|
|
99
|
+
examples/co2_hydrogen_system.json examples/target_5co2_20h2.json \
|
|
100
|
+
"$MFCBLEND_CI_ROOT/gui.json"
|
|
101
|
+
test -s "$MFCBLEND_CI_ROOT/gui.json"
|
|
102
|
+
- name: Build and validate distributions
|
|
103
|
+
run: |
|
|
104
|
+
"$MFCBLEND_CI_ROOT/dev-venv/bin/python" -m build --outdir "$MFCBLEND_CI_ROOT/dist" .
|
|
105
|
+
"$MFCBLEND_CI_ROOT/dev-venv/bin/python" -m twine check "$MFCBLEND_CI_ROOT"/dist/*
|
|
106
|
+
- name: Clean wheel installation on ARM64
|
|
107
|
+
run: |
|
|
108
|
+
"$MFCBLEND_CI_ROOT/wheel-venv/bin/python" -m pip install --upgrade pip
|
|
109
|
+
"$MFCBLEND_CI_ROOT/wheel-venv/bin/python" -m pip install "$MFCBLEND_CI_ROOT"/dist/*.whl
|
|
110
|
+
"$MFCBLEND_CI_ROOT/wheel-venv/bin/python" -m pip check
|
|
111
|
+
"$MFCBLEND_CI_ROOT/wheel-venv/bin/python" - <<'PY'
|
|
112
|
+
import platform
|
|
113
|
+
import sys
|
|
114
|
+
import mfcblend
|
|
115
|
+
import mfcblend.cli
|
|
116
|
+
|
|
117
|
+
assert platform.machine().lower() in {"arm64", "aarch64"}
|
|
118
|
+
assert mfcblend.__version__ == "0.1.0"
|
|
119
|
+
assert "tkinter" not in sys.modules
|
|
120
|
+
assert "matplotlib.pyplot" not in sys.modules
|
|
121
|
+
PY
|
|
122
|
+
"$MFCBLEND_CI_ROOT/wheel-venv/bin/mfcblend" forward \
|
|
123
|
+
examples/co2_hydrogen_system.json examples/setpoints_5co2_20h2.json \
|
|
124
|
+
--output "$MFCBLEND_CI_ROOT/wheel.csv"
|
|
125
|
+
test -s "$MFCBLEND_CI_ROOT/wheel.csv"
|
|
126
|
+
- name: Clean isolated job environment
|
|
127
|
+
if: always()
|
|
128
|
+
run: |
|
|
129
|
+
python - <<'PY'
|
|
130
|
+
import os
|
|
131
|
+
import shutil
|
|
132
|
+
from pathlib import Path
|
|
133
|
+
|
|
134
|
+
root = Path(os.environ["MFCBLEND_CI_ROOT"]).resolve()
|
|
135
|
+
runner_temp = Path(os.environ["RUNNER_TEMP"]).resolve()
|
|
136
|
+
if root.parent != runner_temp or not root.name.startswith("mfcblend-ci-"):
|
|
137
|
+
raise RuntimeError(f"Unsafe cleanup target: {root}")
|
|
138
|
+
shutil.rmtree(root, ignore_errors=True)
|
|
139
|
+
PY
|
|
140
|
+
test -z "$(git status --porcelain)"
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
name: macOS GUI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: mfcblend-macos-${{ github.event.pull_request.number || github.ref }}
|
|
15
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
macos-gui:
|
|
19
|
+
name: macOS / ${{ matrix.arch }} / Python ${{ matrix.python-version }} / Tk
|
|
20
|
+
if: >-
|
|
21
|
+
github.event_name != 'pull_request' ||
|
|
22
|
+
(github.actor == github.repository_owner &&
|
|
23
|
+
github.event.pull_request.head.repo.full_name == github.repository)
|
|
24
|
+
runs-on: ${{ matrix.os }}
|
|
25
|
+
timeout-minutes: 30
|
|
26
|
+
strategy:
|
|
27
|
+
fail-fast: false
|
|
28
|
+
matrix:
|
|
29
|
+
include:
|
|
30
|
+
- os: macos-15
|
|
31
|
+
arch: arm64
|
|
32
|
+
python-version: "3.10"
|
|
33
|
+
- os: macos-15
|
|
34
|
+
arch: arm64
|
|
35
|
+
python-version: "3.14"
|
|
36
|
+
- os: macos-15-intel
|
|
37
|
+
arch: x86_64
|
|
38
|
+
python-version: "3.13"
|
|
39
|
+
env:
|
|
40
|
+
PIP_NO_CACHE_DIR: "1"
|
|
41
|
+
MPLBACKEND: Agg
|
|
42
|
+
steps:
|
|
43
|
+
- name: Check out source
|
|
44
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
45
|
+
with:
|
|
46
|
+
persist-credentials: false
|
|
47
|
+
- name: Set up Python
|
|
48
|
+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
49
|
+
with:
|
|
50
|
+
python-version: ${{ matrix.python-version }}
|
|
51
|
+
- name: Record native platform and Tk runtime
|
|
52
|
+
run: |
|
|
53
|
+
sw_vers
|
|
54
|
+
uname -m
|
|
55
|
+
test "$(uname -m)" = "${{ matrix.arch }}"
|
|
56
|
+
python -VV
|
|
57
|
+
python -c 'import tkinter; print("Tk", tkinter.TkVersion)'
|
|
58
|
+
- name: Install source with GUI and development dependencies
|
|
59
|
+
run: |
|
|
60
|
+
python -m pip install --upgrade pip
|
|
61
|
+
python -m pip install -e ".[dev,gui]"
|
|
62
|
+
python -m pip check
|
|
63
|
+
- name: Scientific and import-isolation tests
|
|
64
|
+
run: |
|
|
65
|
+
python -m pytest tests/unit tests/integration tests/macos
|
|
66
|
+
python -c "import sys, mfcblend.cli; assert 'tkinter' not in sys.modules; assert 'PySide6' not in sys.modules; assert 'PyQt6' not in sys.modules"
|
|
67
|
+
- name: CLI smoke without GUI initialization
|
|
68
|
+
run: |
|
|
69
|
+
mfcblend validate examples/co2_hydrogen_system.json
|
|
70
|
+
mfcblend inverse examples/co2_hydrogen_system.json \
|
|
71
|
+
examples/target_5co2_20h2.json --output /tmp/mfcblend-macos-cli.json
|
|
72
|
+
test -s /tmp/mfcblend-macos-cli.json
|
|
73
|
+
- name: Native Tk window, workflow, export, and clean exit
|
|
74
|
+
run: |
|
|
75
|
+
python -m mfcblend.gui --smoke-test \
|
|
76
|
+
--system examples/co2_hydrogen_system.json \
|
|
77
|
+
--values examples/target_5co2_20h2.json \
|
|
78
|
+
--mode inverse --output /tmp/mfcblend-macos-gui.json
|
|
79
|
+
test -s /tmp/mfcblend-macos-gui.json
|
|
80
|
+
- name: Explicit noninteractive Matplotlib backend smoke
|
|
81
|
+
run: |
|
|
82
|
+
python scripts/generate_preview.py
|
|
83
|
+
python -c "from PIL import Image; image=Image.open('docs/assets/social-preview.png'); assert image.size == (1280, 640), image.size"
|
|
84
|
+
- name: Build and clean wheel install
|
|
85
|
+
run: |
|
|
86
|
+
python -m build --outdir /tmp/mfcblend-dist .
|
|
87
|
+
python -m twine check /tmp/mfcblend-dist/*
|
|
88
|
+
python -m venv /tmp/mfcblend-clean-wheel
|
|
89
|
+
/tmp/mfcblend-clean-wheel/bin/python -m pip install /tmp/mfcblend-dist/*.whl matplotlib
|
|
90
|
+
/tmp/mfcblend-clean-wheel/bin/python -m pip check
|
|
91
|
+
/tmp/mfcblend-clean-wheel/bin/mfcblend --version
|
|
92
|
+
/tmp/mfcblend-clean-wheel/bin/python -m mfcblend.gui --smoke-test \
|
|
93
|
+
--system examples/co2_hydrogen_system.json \
|
|
94
|
+
--values examples/target_5co2_20h2.json \
|
|
95
|
+
--mode inverse --output /tmp/mfcblend-clean-wheel-gui.json
|
|
96
|
+
test -s /tmp/mfcblend-clean-wheel-gui.json
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: Release package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
if: github.event.release.prerelease == false
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
steps:
|
|
14
|
+
- name: Check out source
|
|
15
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
16
|
+
with:
|
|
17
|
+
persist-credentials: false
|
|
18
|
+
- name: Set up Python
|
|
19
|
+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.13"
|
|
22
|
+
- name: Build and validate
|
|
23
|
+
run: |
|
|
24
|
+
python -m pip install --upgrade pip build twine
|
|
25
|
+
python -m build
|
|
26
|
+
python -m twine check dist/*
|
|
27
|
+
- name: Clean wheel CLI smoke
|
|
28
|
+
env:
|
|
29
|
+
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
|
30
|
+
run: |
|
|
31
|
+
python -m venv /tmp/mfcblend-release
|
|
32
|
+
/tmp/mfcblend-release/bin/python -m pip install dist/*.whl
|
|
33
|
+
/tmp/mfcblend-release/bin/python -m pip check
|
|
34
|
+
/tmp/mfcblend-release/bin/python - <<'PY'
|
|
35
|
+
import os
|
|
36
|
+
import mfcblend
|
|
37
|
+
|
|
38
|
+
expected = os.environ["RELEASE_TAG"].removeprefix("v")
|
|
39
|
+
assert mfcblend.__version__ == expected
|
|
40
|
+
PY
|
|
41
|
+
/tmp/mfcblend-release/bin/mfcblend inverse \
|
|
42
|
+
examples/co2_hydrogen_system.json examples/target_5co2_20h2.json \
|
|
43
|
+
--output /tmp/mfcblend-release-result.json
|
|
44
|
+
- name: Upload distributions
|
|
45
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
46
|
+
with:
|
|
47
|
+
name: python-package-distributions
|
|
48
|
+
path: dist/
|
|
49
|
+
if-no-files-found: error
|
|
50
|
+
|
|
51
|
+
publish:
|
|
52
|
+
needs: build
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
environment:
|
|
55
|
+
name: pypi
|
|
56
|
+
url: https://pypi.org/p/mfcblend
|
|
57
|
+
permissions:
|
|
58
|
+
id-token: write
|
|
59
|
+
steps:
|
|
60
|
+
- name: Download distributions
|
|
61
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
62
|
+
with:
|
|
63
|
+
name: python-package-distributions
|
|
64
|
+
path: dist/
|
|
65
|
+
- name: Publish with PyPI Trusted Publishing
|
|
66
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes will be documented here. Versioning follows semantic
|
|
4
|
+
versioning while the scientific interface remains in 0.x development.
|
|
5
|
+
|
|
6
|
+
## [Unreleased] — planned 0.1.0
|
|
7
|
+
|
|
8
|
+
- Initial forward and constrained inverse gas-feed planning core.
|
|
9
|
+
- Explicit MFC ranges, turndown, reference conditions, and infeasibility status.
|
|
10
|
+
- Python API, CLI, Tkinter GUI, JSON/CSV export, and result plotting.
|
|
11
|
+
- DGX and macOS verification workflows and scientific regression tests.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use MFCBlend in research, please cite the software and version used."
|
|
3
|
+
title: "MFCBlend"
|
|
4
|
+
type: software
|
|
5
|
+
authors:
|
|
6
|
+
- family-names: "Kim"
|
|
7
|
+
given-names: "Hyun Dong"
|
|
8
|
+
repository-code: "https://github.com/hdkim99/MFCBlend"
|
|
9
|
+
url: "https://github.com/hdkim99/MFCBlend"
|
|
10
|
+
version: 0.1.0
|
|
11
|
+
license: MIT
|
|
12
|
+
keywords:
|
|
13
|
+
- catalysis
|
|
14
|
+
- gas mixtures
|
|
15
|
+
- mass flow controller
|
|
16
|
+
- reaction engineering
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Contributions are welcome. Do not post unpublished, export-controlled,
|
|
4
|
+
proprietary, or confidential experimental data in a public issue.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
python -m venv .venv
|
|
8
|
+
source .venv/bin/activate
|
|
9
|
+
python -m pip install -e ".[dev]"
|
|
10
|
+
ruff format --check .
|
|
11
|
+
ruff check .
|
|
12
|
+
mypy src
|
|
13
|
+
pytest
|
|
14
|
+
python -m build
|
|
15
|
+
twine check dist/*
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
A scientific-core change must state the equation or definition, units and basis,
|
|
19
|
+
assumptions, validity boundary, authoritative reference or derivation, numerical
|
|
20
|
+
validation, and regression test. Do not add an empirical threshold, coefficient,
|
|
21
|
+
uncertainty, or confidence interval without a verifiable source and applicability
|
|
22
|
+
range.
|
|
23
|
+
|
|
24
|
+
A GUI change must additionally document platform support, dependency/backend
|
|
25
|
+
impact, macOS smoke evidence, and CLI/core import isolation. Do not move formulas
|
|
26
|
+
into the GUI or initialize Tk/Matplotlib from a scientific-core import.
|
|
27
|
+
|
|
28
|
+
External fork pull requests do not execute on the persistent DGX runner. A
|
|
29
|
+
maintainer must review untrusted code before trusted-hardware execution.
|
mfcblend-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Hyun Dong Kim
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|