flow-props 0.1.2__tar.gz → 0.3.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.
- flow_props-0.3.0/.github/workflows/package.yml +41 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/.github/workflows/publish.yml +8 -8
- {flow_props-0.1.2 → flow_props-0.3.0}/.github/workflows/test.yml +1 -1
- {flow_props-0.1.2 → flow_props-0.3.0}/CITATION.cff +0 -1
- {flow_props-0.1.2 → flow_props-0.3.0}/PKG-INFO +32 -9
- {flow_props-0.1.2 → flow_props-0.3.0}/README.md +27 -5
- flow_props-0.3.0/docs/api/architecture.md +39 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/api/index.md +2 -1
- flow_props-0.3.0/docs/api/shock.md +46 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/index.md +3 -3
- flow_props-0.3.0/docs/theory/shock.md +143 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/user-guide/basic-usage.md +26 -1
- flow_props-0.3.0/docs/user-guide/cli.md +60 -0
- flow_props-0.3.0/docs/user-guide/config-files.md +93 -0
- flow_props-0.3.0/docs/user-guide/output.md +38 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/mkdocs.yml +2 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/pyproject.toml +6 -4
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props/__init__.py +14 -2
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props/bl.py +0 -26
- flow_props-0.3.0/src/flow_props/calculators/__init__.py +67 -0
- flow_props-0.3.0/src/flow_props/calculators/bl.py +274 -0
- flow_props-0.3.0/src/flow_props/calculators/common.py +508 -0
- flow_props-0.3.0/src/flow_props/calculators/entropy_layer.py +172 -0
- flow_props-0.3.0/src/flow_props/calculators/profiles.py +147 -0
- flow_props-0.3.0/src/flow_props/calculators/shock.py +427 -0
- flow_props-0.3.0/src/flow_props/cli/app.py +61 -0
- flow_props-0.3.0/src/flow_props/cli/callbacks.py +39 -0
- flow_props-0.3.0/src/flow_props/cli/cmd_calculator.py +107 -0
- flow_props-0.3.0/src/flow_props/cli/examples_command.py +186 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props/entropy_layer.py +0 -34
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props/output.py +51 -1
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props/profiles/__init__.py +0 -2
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props/profiles/api.py +1 -24
- flow_props-0.3.0/src/flow_props/shock.py +768 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props/wall.py +0 -12
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props.egg-info/PKG-INFO +32 -9
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props.egg-info/SOURCES.txt +19 -15
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props.egg-info/scm_file_list.json +19 -15
- flow_props-0.3.0/src/flow_props.egg-info/scm_version.json +8 -0
- flow_props-0.3.0/tests/synthetic.py +119 -0
- flow_props-0.3.0/tests/test_calculators.py +184 -0
- flow_props-0.3.0/tests/test_cli.py +408 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/tests/test_output.py +19 -1
- flow_props-0.3.0/tests/test_shock.py +410 -0
- flow_props-0.1.2/docs/api/architecture.md +0 -26
- flow_props-0.1.2/docs/user-guide/cli.md +0 -100
- flow_props-0.1.2/docs/user-guide/config-files.md +0 -47
- flow_props-0.1.2/docs/user-guide/output.md +0 -48
- flow_props-0.1.2/src/flow_props/cli/app.py +0 -48
- flow_props-0.1.2/src/flow_props/cli/cmd_examples.py +0 -55
- flow_props-0.1.2/src/flow_props/cli/cmd_init.py +0 -110
- flow_props-0.1.2/src/flow_props/cli/cmd_run.py +0 -51
- flow_props-0.1.2/src/flow_props/cli/common.py +0 -427
- flow_props-0.1.2/src/flow_props/cli/config_init.py +0 -208
- flow_props-0.1.2/src/flow_props/config.py +0 -50
- flow_props-0.1.2/src/flow_props/examples/__init__.py +0 -1
- flow_props-0.1.2/src/flow_props/io/__init__.py +0 -13
- flow_props-0.1.2/src/flow_props/io/examples.py +0 -72
- flow_props-0.1.2/src/flow_props/pipeline.py +0 -315
- flow_props-0.1.2/src/flow_props/schema.py +0 -117
- flow_props-0.1.2/src/flow_props.egg-info/scm_version.json +0 -8
- flow_props-0.1.2/tests/test_cli.py +0 -108
- flow_props-0.1.2/tests/test_station_selection.py +0 -62
- {flow_props-0.1.2 → flow_props-0.3.0}/.github/workflows/docs.yml +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/.gitignore +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/.vscode/settings.json +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/LICENSE +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/api/boundary-layer.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/api/entropy-layer.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/api/profiles.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/api/wall.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/cli-reference/index.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/examples.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/installation.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/javascripts/mathjax.js +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/nomenclature.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/theory/boundary-layer.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/theory/entropy-layer.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/theory/index.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/theory/wall-quantities.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/user-guide/configuration.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/user-guide/index.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/user-guide/workflow.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/vnv/index.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/vnv/validation/index.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/docs/vnv/verification/index.md +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/setup.cfg +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props/cli/__init__.py +0 -0
- /flow_props-0.1.2/src/flow_props/examples/cone_7deg_m14.toml → /flow_props-0.3.0/src/flow_props/examples/bl/cone_7deg_m14/bl.toml +0 -0
- /flow_props-0.1.2/src/flow_props/examples/ogive_m5pt3.toml → /flow_props-0.3.0/src/flow_props/examples/bl/ogive_m5pt3/bl.toml +0 -0
- /flow_props-0.1.2/src/flow_props/examples/sharp_flat_plate_m5.toml → /flow_props-0.3.0/src/flow_props/examples/bl/sharp_flat_plate_m5/bl.toml +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props/profiles/geometry.py +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props/profiles/grid_line.py +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props/profiles/wall_normal.py +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props.egg-info/dependency_links.txt +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props.egg-info/entry_points.txt +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props.egg-info/requires.txt +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/src/flow_props.egg-info/top_level.txt +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/tests/test_bl.py +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/tests/test_entropy_layer.py +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/tests/test_profiles.py +0 -0
- {flow_props-0.1.2 → flow_props-0.3.0}/tests/test_wall.py +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# GPL-3.0-or-later - see LICENSE
|
|
2
|
+
name: Package
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [main]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v6
|
|
16
|
+
with:
|
|
17
|
+
fetch-depth: 0
|
|
18
|
+
|
|
19
|
+
- uses: actions/setup-python@v6
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.11"
|
|
22
|
+
|
|
23
|
+
- name: Build distributions
|
|
24
|
+
run: |
|
|
25
|
+
python -m pip install build twine
|
|
26
|
+
python -m build
|
|
27
|
+
python -m twine check dist/*
|
|
28
|
+
|
|
29
|
+
- name: Smoke-test wheel
|
|
30
|
+
run: |
|
|
31
|
+
python -m venv "${RUNNER_TEMP}/wheel-test"
|
|
32
|
+
"${RUNNER_TEMP}/wheel-test/bin/python" -m pip install dist/*.whl
|
|
33
|
+
cd "${RUNNER_TEMP}"
|
|
34
|
+
"${RUNNER_TEMP}/wheel-test/bin/python" -c "import flow_props"
|
|
35
|
+
"${RUNNER_TEMP}/wheel-test/bin/flow-props" --help
|
|
36
|
+
|
|
37
|
+
- name: Upload distributions
|
|
38
|
+
uses: actions/upload-artifact@v7
|
|
39
|
+
with:
|
|
40
|
+
name: distributions
|
|
41
|
+
path: dist/
|
|
@@ -10,12 +10,12 @@ jobs:
|
|
|
10
10
|
runs-on: ubuntu-latest
|
|
11
11
|
strategy:
|
|
12
12
|
matrix:
|
|
13
|
-
python-version: ["3.11", "3.12", "3.13"]
|
|
13
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
14
14
|
steps:
|
|
15
|
-
- uses: actions/checkout@
|
|
15
|
+
- uses: actions/checkout@v6
|
|
16
16
|
|
|
17
17
|
- name: Set up Python ${{ matrix.python-version }}
|
|
18
|
-
uses: actions/setup-python@
|
|
18
|
+
uses: actions/setup-python@v6
|
|
19
19
|
with:
|
|
20
20
|
python-version: ${{ matrix.python-version }}
|
|
21
21
|
|
|
@@ -32,10 +32,10 @@ jobs:
|
|
|
32
32
|
needs: test
|
|
33
33
|
runs-on: ubuntu-latest
|
|
34
34
|
steps:
|
|
35
|
-
- uses: actions/checkout@
|
|
35
|
+
- uses: actions/checkout@v6
|
|
36
36
|
|
|
37
37
|
- name: Set up Python
|
|
38
|
-
uses: actions/setup-python@
|
|
38
|
+
uses: actions/setup-python@v6
|
|
39
39
|
with:
|
|
40
40
|
python-version: "3.11"
|
|
41
41
|
|
|
@@ -46,7 +46,7 @@ jobs:
|
|
|
46
46
|
run: python -m build
|
|
47
47
|
|
|
48
48
|
- name: Upload dist artifacts
|
|
49
|
-
uses: actions/upload-artifact@
|
|
49
|
+
uses: actions/upload-artifact@v7
|
|
50
50
|
with:
|
|
51
51
|
name: dist
|
|
52
52
|
path: dist/
|
|
@@ -60,7 +60,7 @@ jobs:
|
|
|
60
60
|
|
|
61
61
|
steps:
|
|
62
62
|
- name: Download dist artifacts
|
|
63
|
-
uses: actions/download-artifact@
|
|
63
|
+
uses: actions/download-artifact@v8
|
|
64
64
|
with:
|
|
65
65
|
name: dist
|
|
66
66
|
path: dist/
|
|
@@ -74,7 +74,7 @@ jobs:
|
|
|
74
74
|
permissions:
|
|
75
75
|
contents: write
|
|
76
76
|
steps:
|
|
77
|
-
- uses: actions/checkout@
|
|
77
|
+
- uses: actions/checkout@v6
|
|
78
78
|
- name: Create GitHub Release (skip if it already exists)
|
|
79
79
|
run: |
|
|
80
80
|
if gh release view "${{ github.ref_name }}" >/dev/null 2>&1; then
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flow-props
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: Extract flow properties from CFD data: boundary layer
|
|
5
|
-
Author-email: Christoph Hader <
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Extract flow properties from CFD data: boundary layer, entropy layer, shock
|
|
5
|
+
Author-email: Christoph Hader <christoph.hader@gmail.com>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
7
7
|
Project-URL: Homepage, https://github.com/uahypersonics/flow-props
|
|
8
8
|
Project-URL: Repository, https://github.com/uahypersonics/flow-props
|
|
9
|
-
Keywords: boundary-layer,entropy-layer,cfd,flow-properties,aerodynamics
|
|
9
|
+
Keywords: boundary-layer,entropy-layer,shock,cfd,flow-properties,aerodynamics
|
|
10
10
|
Classifier: Development Status :: 1 - Planning
|
|
11
11
|
Classifier: Intended Audience :: Science/Research
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
17
|
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
17
18
|
Requires-Python: >=3.11
|
|
18
19
|
Description-Content-Type: text/markdown
|
|
@@ -30,7 +31,7 @@ Dynamic: license-file
|
|
|
30
31
|
|
|
31
32
|
# flow-props
|
|
32
33
|
|
|
33
|
-
Python tool suite to extract flow properties from CFD data, such as boundary layer thickness
|
|
34
|
+
Python tool suite to extract flow properties from CFD data, such as boundary layer thickness, entropy layer thickness and the shock.
|
|
34
35
|
|
|
35
36
|
[](https://github.com/uahypersonics/flow-props/actions/workflows/test.yml)
|
|
36
37
|
[](https://pypi.org/project/flow-props/)
|
|
@@ -45,15 +46,37 @@ Python tool suite to extract flow properties from CFD data, such as boundary lay
|
|
|
45
46
|
pip install flow-props
|
|
46
47
|
```
|
|
47
48
|
|
|
49
|
+
To upgrade an existing installation:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install --upgrade flow-props
|
|
53
|
+
```
|
|
54
|
+
|
|
48
55
|
## Quick Start
|
|
49
56
|
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
Every calculation is a command group (`bl`, `entropy-layer`, `profiles`, `shock`):
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
flow-props bl init # writes bl.toml, every key documented
|
|
61
|
+
flow-props bl run # reads bl.toml
|
|
62
|
+
flow-props shock init # shock curve of a solution (for grid-generator's [shock] curve)
|
|
63
|
+
flow-props shock run
|
|
52
64
|
```
|
|
53
65
|
|
|
54
|
-
|
|
66
|
+
`flow-props -v <calculation> run` adds debug output.
|
|
67
|
+
|
|
68
|
+
## Documentation
|
|
69
|
+
|
|
70
|
+
Full documentation: https://uahypersonics.github.io/flow-props
|
|
71
|
+
|
|
72
|
+
## Testing
|
|
55
73
|
|
|
56
|
-
|
|
74
|
+
Run the ruff check and pytest check in the project root:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
ruff check
|
|
78
|
+
pytest --cov
|
|
79
|
+
```
|
|
57
80
|
|
|
58
81
|
## Documentation
|
|
59
82
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# flow-props
|
|
2
2
|
|
|
3
|
-
Python tool suite to extract flow properties from CFD data, such as boundary layer thickness
|
|
3
|
+
Python tool suite to extract flow properties from CFD data, such as boundary layer thickness, entropy layer thickness and the shock.
|
|
4
4
|
|
|
5
5
|
[](https://github.com/uahypersonics/flow-props/actions/workflows/test.yml)
|
|
6
6
|
[](https://pypi.org/project/flow-props/)
|
|
@@ -15,15 +15,37 @@ Python tool suite to extract flow properties from CFD data, such as boundary lay
|
|
|
15
15
|
pip install flow-props
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
To upgrade an existing installation:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install --upgrade flow-props
|
|
22
|
+
```
|
|
23
|
+
|
|
18
24
|
## Quick Start
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
Every calculation is a command group (`bl`, `entropy-layer`, `profiles`, `shock`):
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
flow-props bl init # writes bl.toml, every key documented
|
|
30
|
+
flow-props bl run # reads bl.toml
|
|
31
|
+
flow-props shock init # shock curve of a solution (for grid-generator's [shock] curve)
|
|
32
|
+
flow-props shock run
|
|
22
33
|
```
|
|
23
34
|
|
|
24
|
-
|
|
35
|
+
`flow-props -v <calculation> run` adds debug output.
|
|
36
|
+
|
|
37
|
+
## Documentation
|
|
38
|
+
|
|
39
|
+
Full documentation: https://uahypersonics.github.io/flow-props
|
|
40
|
+
|
|
41
|
+
## Testing
|
|
25
42
|
|
|
26
|
-
|
|
43
|
+
Run the ruff check and pytest check in the project root:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
ruff check
|
|
47
|
+
pytest --cov
|
|
48
|
+
```
|
|
27
49
|
|
|
28
50
|
## Documentation
|
|
29
51
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
`flow_props` follows a narrow pipeline:
|
|
4
|
+
|
|
5
|
+
1. `cfd-io` reads a CFD dataset
|
|
6
|
+
2. `flow_props.profiles.extract_profiles` slices wall-normal profiles at chosen stations
|
|
7
|
+
3. reduction modules compute derived quantities from those profiles
|
|
8
|
+
|
|
9
|
+
## Module Layout
|
|
10
|
+
|
|
11
|
+
- `profiles/`: wall-normal profile extraction (along grid lines or interpolated normals)
|
|
12
|
+
- `bl.py`: boundary-layer edge detection and integral thicknesses
|
|
13
|
+
- `entropy_layer.py`: entropy-layer thickness
|
|
14
|
+
- `shock.py`: shock point per grid line and the shock curve
|
|
15
|
+
- `wall.py`: wall shear and thermal quantities
|
|
16
|
+
- `output.py`: Tecplot ASCII writers
|
|
17
|
+
- `calculators/`: one module per CLI calculation (`bl`, `entropy_layer`, `profiles`,
|
|
18
|
+
`shock`) with its pydantic config model, its `init` template and its `run_case`;
|
|
19
|
+
`common.py` holds the shared parts (input files, `[stations]`, `[gas]`), and
|
|
20
|
+
`__init__.py` the registry the CLI is built from
|
|
21
|
+
- `cli/`: Typer app (`app.py`), callbacks (`--version`, `--verbose`), the command-group
|
|
22
|
+
factory (`cmd_calculator.py`) and the `examples` command
|
|
23
|
+
- `examples/<calculation>/<name>/`: bundled cases; the folders are the registry
|
|
24
|
+
|
|
25
|
+
## Adding a Calculation
|
|
26
|
+
|
|
27
|
+
Write `calculators/<name>.py` with a config model, a `TEMPLATE` and
|
|
28
|
+
`run_case(config, config_dir) -> list[str]`, and add one entry to `CALCULATORS` in
|
|
29
|
+
`calculators/__init__.py`. The CLI then has `flow-props <name> init` and `run`.
|
|
30
|
+
|
|
31
|
+
## Design Intent
|
|
32
|
+
|
|
33
|
+
The package is deliberately lightweight.
|
|
34
|
+
|
|
35
|
+
- it does not own CFD file I/O
|
|
36
|
+
- it assumes `cfd-io` has already constructed a dataset
|
|
37
|
+
- it focuses on profile-based property extraction rather than general field operations
|
|
38
|
+
|
|
39
|
+
That separation keeps `flow_props` easy to reason about and consistent with the rest of the workspace.
|
|
@@ -7,6 +7,7 @@ The public API is intentionally small and organized around the main post-process
|
|
|
7
7
|
- `flow_props.profiles` for wall-normal profile extraction
|
|
8
8
|
- `flow_props.bl` for boundary-layer edge detection and integral thicknesses
|
|
9
9
|
- `flow_props.entropy_layer` for entropy-layer thickness
|
|
10
|
+
- `flow_props.shock` for the shock point on each grid line and the shock curve
|
|
10
11
|
- `flow_props.wall` for wall shear and heat-transfer quantities
|
|
11
12
|
- `flow_props.cli` for command-line entry points
|
|
12
13
|
|
|
@@ -15,7 +16,7 @@ The public API is intentionally small and organized around the main post-process
|
|
|
15
16
|
The package re-exports the most common functions through `flow_props` itself, so this style works:
|
|
16
17
|
|
|
17
18
|
```python
|
|
18
|
-
from flow_props import extract_profiles, run_bl, run_entropy, run_wall
|
|
19
|
+
from flow_props import extract_profiles, extract_shock, run_bl, run_entropy, run_wall
|
|
19
20
|
```
|
|
20
21
|
|
|
21
22
|
Use the pages in this section for a module-by-module view.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Shock
|
|
2
|
+
|
|
3
|
+
Module: `flow_props.shock`
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
This module finds the shock on each wall-normal grid line of a structured solution and
|
|
8
|
+
writes the shock curve (see [Shock Extraction](../theory/shock.md) for the method).
|
|
9
|
+
|
|
10
|
+
## Main Functions
|
|
11
|
+
|
|
12
|
+
- `find_shock_on_line(values, level=0.5, min_rise=0.05, max_thickness=20.0, method="walk",
|
|
13
|
+
indicator_threshold=0.0025)`: the shock on one line, as a `ShockCrossing` (fractional
|
|
14
|
+
`j`, `j_tail`, the outer edge `j_foot`, `thickness_cells`, `detected_by`, and each
|
|
15
|
+
detector's own point `j_walk`, `j_indicator`, whatever the method), or `None`
|
|
16
|
+
- `extract_shock(ds, quantity="pressure", ..., method="walk", indicator_threshold=0.0025)`:
|
|
17
|
+
every line of a dataset, as a `ShockExtraction` (station, x, y, j, distance,
|
|
18
|
+
thickness_cells, detected_by, and the stations without a shock)
|
|
19
|
+
- `smoothness_indicator(values, reference)`: the WENO smoothness indicator along a line,
|
|
20
|
+
divided by 5040 reference^2
|
|
21
|
+
- `smooth_shock(ds, extraction, length)`: the same points moved, along their grid lines,
|
|
22
|
+
onto local quadratics fitted in the shock's frame over `length` wall-to-shock distances
|
|
23
|
+
(see
|
|
24
|
+
[Smoothing the Curve](../theory/shock.md#smoothing-the-curve))
|
|
25
|
+
- `write_shock_curve(path, extraction)`: the x, y CSV that grid-generator's `[shock] curve`
|
|
26
|
+
reads
|
|
27
|
+
|
|
28
|
+
## Example
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
import cfd_io
|
|
32
|
+
from flow_props import extract_shock, smooth_shock, write_shock_curve
|
|
33
|
+
|
|
34
|
+
dataset = cfd_io.read_file("solution.h5")
|
|
35
|
+
extraction = extract_shock(dataset)
|
|
36
|
+
smoothed = smooth_shock(dataset, extraction, length=0.5)
|
|
37
|
+
write_shock_curve("shock_cfd.csv", smoothed)
|
|
38
|
+
|
|
39
|
+
print(extraction.thickness_cells.max(), extraction.stations_without_shock)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Notes
|
|
43
|
+
|
|
44
|
+
- the dataset must use a `StructuredGrid` with $j = 0$ at the wall (cfd-io's canonical
|
|
45
|
+
orientation) and the outer boundary in the freestream
|
|
46
|
+
- the quantity's field is looked up as `pres`, `pressure`, `p` (or `dens`, `density`, `rho`)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# flow_props
|
|
2
2
|
|
|
3
|
-
`flow_props` extracts physically meaningful boundary-layer and
|
|
3
|
+
`flow_props` extracts physically meaningful boundary-layer, entropy-layer and shock quantities from structured CFD datasets.
|
|
4
4
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
@@ -15,8 +15,8 @@ pip install flow-props
|
|
|
15
15
|
=== "CLI"
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
flow-props init
|
|
19
|
-
flow-props run
|
|
18
|
+
flow-props bl init
|
|
19
|
+
flow-props bl run
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
=== "API"
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Shock Extraction
|
|
2
|
+
|
|
3
|
+
`flow-props shock` finds the shock of a CFD solution on every wall-normal grid line. Each
|
|
4
|
+
line runs from the wall ($j = 0$) to the outer boundary, which must lie in the freestream.
|
|
5
|
+
A shock-capturing solver smears the shock over a few cells, so along the line the
|
|
6
|
+
quantity $q$ (pressure by default, or density) climbs from its freestream value to the
|
|
7
|
+
post-shock value over a short stretch.
|
|
8
|
+
|
|
9
|
+
## Finding the Jump
|
|
10
|
+
|
|
11
|
+
Walking inward from the line's outer end, where $q_\infty$ is $q$ at the outer end, a
|
|
12
|
+
detector proposes where a jump starts (`method`):
|
|
13
|
+
|
|
14
|
+
- **walk** (default): the first point where $q > (1 + \text{min\_rise})\, q_\infty$;
|
|
15
|
+
- **indicator**: the first point whose smoothness indicator reaches
|
|
16
|
+
`indicator_threshold` (see [Smoothness Indicator](#smoothness-indicator));
|
|
17
|
+
- **hybrid**: both detectors, and the outermost jump either finds, since the shock is
|
|
18
|
+
the first jump from outside. The report says which detector found each line.
|
|
19
|
+
|
|
20
|
+
From the proposed start, the steepest cell within `max_thickness` cells inward is the
|
|
21
|
+
jump's core. Walking on inward, the rise per cell shrinks across the jump's rounded
|
|
22
|
+
shoulder; once past the jump's center (the rise below half the steepest), the jump ends
|
|
23
|
+
where the rise shrinks by less than 1 % of the steepest from one cell to the next: at the
|
|
24
|
+
knee into the post-shock plateau or the top of an overshoot. $q_t$ is the post-shock
|
|
25
|
+
value there. The profile is flat
|
|
26
|
+
there, so $q_t$ barely changes when the shock drifts by a cell from one grid line to the
|
|
27
|
+
next. (Ending the jump on the shoulder instead makes $q_t$, and with it the shock point,
|
|
28
|
+
jump at every such drift: a staircase along the shock.)
|
|
29
|
+
|
|
30
|
+
Because the walk starts outside, the first jump it meets is the shock: the boundary layer,
|
|
31
|
+
the entropy layer and any inner compression are never reached.
|
|
32
|
+
|
|
33
|
+
## Placing the Shock Point
|
|
34
|
+
|
|
35
|
+
The shock point is where $q$ crosses
|
|
36
|
+
|
|
37
|
+
$$
|
|
38
|
+
q_\text{level} = q_\infty + \text{level}\,(q_t - q_\infty),
|
|
39
|
+
$$
|
|
40
|
+
|
|
41
|
+
interpolated linearly between the two grid points around the crossing. `level = 0.5`
|
|
42
|
+
puts it in the middle of the captured jump, which is where a grid line should sit; values
|
|
43
|
+
toward 0 move it to the freestream side, toward 1 to the post-shock side.
|
|
44
|
+
|
|
45
|
+
Only this crossing places the point; the foot and tail just bracket the jump. The point
|
|
46
|
+
therefore doesn't depend on `min_rise`, and is placed the same way for a shock of 40 times
|
|
47
|
+
freestream pressure at the nose and a weak one far downstream. On synthetic captured
|
|
48
|
+
shocks (jumps 0.3 to 40 times freestream) it lands within 0.1 cell of the jump's center
|
|
49
|
+
for shocks captured over up to about 5 cells; with a post-shock gradient, a shock smeared
|
|
50
|
+
over more cells comes out inward by up to about 2 % of its thickness. As a shock drifts
|
|
51
|
+
across the cells from one grid line to the next, its point moves smoothly; what remains
|
|
52
|
+
is a small error that repeats with the shock's position inside a cell (about 0.03 to
|
|
53
|
+
0.07 cell for shocks captured over 1 to 2 cells), which the smoothing removes.
|
|
54
|
+
|
|
55
|
+
## Thickness and Smooth Compressions
|
|
56
|
+
|
|
57
|
+
The captured thickness is the distance, in cells, between the crossings of 10 % and 90 %
|
|
58
|
+
of the jump. A rise spread over more than `max_thickness` cells (default 20) is a smooth
|
|
59
|
+
compression, not a shock: for example the pressure rise toward the stagnation point on a
|
|
60
|
+
line that ends inside the shock layer. Such lines are reported as having no shock.
|
|
61
|
+
|
|
62
|
+
## Comparison with a Shock-Line Grid
|
|
63
|
+
|
|
64
|
+
On a shock-line grid the shock is meant to lie on grid line `shock_line_j`. The report
|
|
65
|
+
gives each line's offset $j_\text{shock} - j_s$ in cells, and the run summary the range of
|
|
66
|
+
offsets and the number of lines more than a quarter cell off.
|
|
67
|
+
|
|
68
|
+
## Checks in the Report
|
|
69
|
+
|
|
70
|
+
Both detectors run on every line, whichever the method, so each result can be checked
|
|
71
|
+
against the other. The run summary warns when
|
|
72
|
+
|
|
73
|
+
- the shock's outer edge (where $q$ crosses 10 % of the jump) lies within 5 cells of the
|
|
74
|
+
outer boundary: too little freestream outside it to read $q_\infty$ from, or a
|
|
75
|
+
disturbance ahead of the shock was taken for it;
|
|
76
|
+
- the walk and the indicator differ by more than 3 cells on a line: one of them found
|
|
77
|
+
something else. A smooth compression ahead of the shock (e.g. freestream compressed
|
|
78
|
+
against a bent symmetry line) is met first by the walk, while the indicator, which
|
|
79
|
+
only flags sharp jumps, finds the shock.
|
|
80
|
+
|
|
81
|
+
It also counts how often the shock's outer edge changes grid row along the body and, on
|
|
82
|
+
a shock-line grid, how often it crosses the shock line `shock_line_j`. A captured shock
|
|
83
|
+
that moves between rows makes a solver's wall quantities wave; on a converged
|
|
84
|
+
shock-line grid the edge stays on one side of the shock line.
|
|
85
|
+
|
|
86
|
+
## Solutions at Cell Centres
|
|
87
|
+
|
|
88
|
+
A finite-volume solution holds cell values. Read through cfd-io as fields at the cell
|
|
89
|
+
centres of the vertex grid (association `cell`: one point fewer than the grid in each
|
|
90
|
+
direction), they are put on a grid of the cell centres, each the mean of its cell's
|
|
91
|
+
corners, and the shock is found along the lines through them. Those lines lie half a
|
|
92
|
+
cell from the vertex grid's lines, so:
|
|
93
|
+
|
|
94
|
+
- the shock line `shock_line_j` counts vertices, and cell $j$ lies at $j + 0.5$ on the
|
|
95
|
+
vertex grid; the report's `j_shock` and the offsets use that, and the run summary
|
|
96
|
+
says the solution was at cell centres;
|
|
97
|
+
- the first line runs half a cell off the symmetry axis, so the curve starts there;
|
|
98
|
+
grid-generator continues a curve that starts slightly off the axis to it.
|
|
99
|
+
|
|
100
|
+
A solution whose grid is the cell centres themselves (stored as an ordinary grid)
|
|
101
|
+
can't be told from vertex data; write cell values on the vertex grid instead.
|
|
102
|
+
|
|
103
|
+
## Smoothing the Curve
|
|
104
|
+
|
|
105
|
+
The extracted curve becomes a grid line of the next grid, so line-to-line jitter of the
|
|
106
|
+
points would become wiggles in the grid. With `smoothing_length = a` (default 0.5), each
|
|
107
|
+
point is moved onto a quadratic fitted, by least squares, through the shock points within
|
|
108
|
+
a stretch of the shock $a\,d$ long, with $d$ the local wall-to-shock distance, and the
|
|
109
|
+
curve that is written is the smoothed one.
|
|
110
|
+
|
|
111
|
+
The stretch scales with $d$ because the shock bends on scales of $d$: tightly around a
|
|
112
|
+
blunt nose, gently far downstream. A fixed number of grid lines fails one way or the
|
|
113
|
+
other: a precursor grid's lines are dense on the body compared with a shock-line grid's
|
|
114
|
+
cells, so a short window leaves wiggles a few millimetres long that the new grid resolves
|
|
115
|
+
(its shock line zig-zags), and a long one flattens the nose.
|
|
116
|
+
|
|
117
|
+
The fit is made in the shock's own local frame: the tangent along the chord of the window
|
|
118
|
+
and the normal to it. The point then moves along its own grid line onto the fitted
|
|
119
|
+
quadratic, so there is still one point per grid line. Fitting the distance along the grid
|
|
120
|
+
lines instead would be wrong where the body's curvature jumps: at a nose-body tangency
|
|
121
|
+
the wall normals stop turning, and the distance along them bends although the shock is
|
|
122
|
+
smooth. A straight shock over such lines stays exactly where it is.
|
|
123
|
+
|
|
124
|
+
The report keeps the raw and the smoothed points, and the run summary says how far the
|
|
125
|
+
smoothing moved them, in cells; `smoothing_length = 0` writes the points as found.
|
|
126
|
+
|
|
127
|
+
## Smoothness Indicator
|
|
128
|
+
|
|
129
|
+
A WENO smoothness indicator measures how far a stencil is from smooth. flow-props uses the
|
|
130
|
+
central five-point measure of ninth-order WENO (Balsara and Shu, J. Comput. Phys. 160,
|
|
131
|
+
2000) divided by $5040\, q_\infty^2$, which on a smooth ramp equals
|
|
132
|
+
$(\Delta q_\text{cell} / q_\infty)^2$, with $\Delta q_\text{cell}$ the rise per cell; a jump
|
|
133
|
+
captured over fewer cells scores higher. The default threshold 0.0025 is thus a rise of
|
|
134
|
+
5 % of freestream per cell. Dividing by $q_\infty^2$ makes one threshold work for any
|
|
135
|
+
freestream pressure.
|
|
136
|
+
|
|
137
|
+
Its peak scales with $(\text{jump} / \text{thickness})^2$, so the threshold that finds
|
|
138
|
+
the shock depends on how strong and how smeared it is: on synthetic captured shocks a
|
|
139
|
+
jump of $0.3\, q_\infty$ peaks at about 0.06 when captured over 2 cells and at about
|
|
140
|
+
0.0015 over 9 cells. Along a body, from the strong nose shock to a weak, smeared shock
|
|
141
|
+
downstream, a single threshold can miss part of the shock; lower it, or use the walk (its
|
|
142
|
+
`min_rise` is a total rise, whatever the width) or the hybrid. Where the walk and the
|
|
143
|
+
indicator find the same jump, the shock point is the same: the level crossing places it.
|
|
@@ -17,7 +17,7 @@ For split solution/grid formats, provide the separate grid file through `cfd-io`
|
|
|
17
17
|
```python
|
|
18
18
|
from flow_props import extract_profiles
|
|
19
19
|
|
|
20
|
-
profiles = extract_profiles(dataset, stations=[10, 50, 100]
|
|
20
|
+
profiles = extract_profiles(dataset, stations=[10, 50, 100])
|
|
21
21
|
print(profiles[0].keys())
|
|
22
22
|
```
|
|
23
23
|
|
|
@@ -27,6 +27,19 @@ Each extracted profile includes:
|
|
|
27
27
|
- `eta`
|
|
28
28
|
- one array per flow field available in the input dataset
|
|
29
29
|
|
|
30
|
+
For config-driven extraction, `flow-props bl init` creates `bl.toml`. Set
|
|
31
|
+
`fname` to a structured HDF5 file, then run `flow-props bl run`. To look at the
|
|
32
|
+
profiles behind the table, `flow-props profiles init` / `run` writes them, for the
|
|
33
|
+
same stations, as multi-zone Tecplot ASCII.
|
|
34
|
+
`cfd-io` handles file reading; `flow-props` does not convert CFD formats.
|
|
35
|
+
Leave `[stations]` empty to process all i-indices from 0 through `Nx - 1` with
|
|
36
|
+
step 1, or choose one station-selection mode to limit the run.
|
|
37
|
+
|
|
38
|
+
Only the `htot_derivative` criterion requires gas constants. The tool reads
|
|
39
|
+
`gamma` and `r_gas` from HDF5 attributes, fills missing values from an adjacent
|
|
40
|
+
`flow_conditions.json`, and allows optional `[gas]` overrides. The default
|
|
41
|
+
`velocity_ratio` criterion does not require those values.
|
|
42
|
+
|
|
30
43
|
## Compute Boundary-Layer Properties
|
|
31
44
|
|
|
32
45
|
```python
|
|
@@ -58,6 +71,18 @@ entropy_results = run_entropy(
|
|
|
58
71
|
)
|
|
59
72
|
```
|
|
60
73
|
|
|
74
|
+
## Extract the Shock
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from flow_props import extract_shock, write_shock_curve
|
|
78
|
+
|
|
79
|
+
extraction = extract_shock(dataset, quantity="pressure", level=0.5)
|
|
80
|
+
write_shock_curve("shock_cfd.csv", extraction)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`extraction.j` holds the fractional grid index of the shock on each line, for comparing
|
|
84
|
+
with a shock-line grid's shock line.
|
|
85
|
+
|
|
61
86
|
## Compute Wall Quantities
|
|
62
87
|
|
|
63
88
|
```python
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# CLI
|
|
2
|
+
|
|
3
|
+
The command-line interface is exposed through `flow-props`. Every calculation is a
|
|
4
|
+
command group with the same commands:
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
flow-props <calculation> init # write <calculation>.toml, every key documented
|
|
8
|
+
flow-props <calculation> run # run <calculation>.toml
|
|
9
|
+
flow-props <calculation> examples # bundled cases (calculations that ship some)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Calculations
|
|
13
|
+
|
|
14
|
+
| Command | What it computes | Default config |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| `bl` | boundary-layer edge $\delta$, $\delta^*$, $\theta$, $H$ and edge state per station | `bl.toml` |
|
|
17
|
+
| `entropy-layer` | entropy-layer thickness per station | `entropy-layer.toml` |
|
|
18
|
+
| `profiles` | wall-normal profiles of every flow variable per station | `profiles.toml` |
|
|
19
|
+
| `shock` | the shock curve, and its offset from a shock-line grid's shock line | `shock.toml` |
|
|
20
|
+
|
|
21
|
+
## Global Options
|
|
22
|
+
|
|
23
|
+
Global options go before the calculation:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
flow-props --version # or -V
|
|
27
|
+
flow-props -v shock run # --verbose: debug output from flow-props (not from cfd-io)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## init
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
flow-props bl init # writes bl.toml
|
|
34
|
+
flow-props bl init -o ogive_bl.toml # another name (then: flow-props bl run -c ogive_bl.toml)
|
|
35
|
+
flow-props bl init --force # overwrite an existing file
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## run
|
|
39
|
+
|
|
40
|
+
`run` reads the calculation's default config, or the one named with `--config` / `-c`.
|
|
41
|
+
Paths in the config (solution file, outputs) are relative to the config file's folder.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
flow-props bl run
|
|
45
|
+
flow-props shock run -c precursor.toml
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Bad input (a misspelled key, a missing solution file, a missing field) is reported as one
|
|
49
|
+
`error: ...` line with exit code 1.
|
|
50
|
+
|
|
51
|
+
## examples
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
flow-props bl examples # list the bundled cases
|
|
55
|
+
flow-props bl examples sharp_flat_plate_m5 # copy its files here (as bl.toml)
|
|
56
|
+
flow-props bl run
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
An example is copied into the current folder; it refuses to overwrite existing files
|
|
60
|
+
unless `--force` is given.
|