Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: CI

on:
push:
branches: [master, main]
pull_request:
branches: [master, main]

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Lint with ruff
run: ruff check src/ tests/

- name: Type check with mypy
run: mypy src/viscot/ --strict --ignore-missing-imports

- name: Run tests with coverage
run: |
pytest tests/ -v --cov=viscot --cov-report=term-missing --cov-fail-under=80
11 changes: 9 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
__pycache__
parser.out
parsetab.py
parsetab.py
flow_picture
.vscode
.vscode
.coverage
*.egg-info/
test_output/
.mypy_cache/
.ruff_cache/
.pytest_cache/
.venv/
27 changes: 27 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.PHONY: all test clean install lint svg

all: test

install:
pip install -e ".[dev]" --break-system-packages

test:
python3 -m pytest tests/ -q

svg:
python3 -m pytest tests/test_canvas.py::TestExhaustive \
tests/test_canvas.py::TestNoSplineCrossings \
tests/test_canvas.py::TestSmallCrossings \
tests/test_canvas.py::TestStress \
-v --save-images=test_output/svg --image-format=svg

lint:
python3 -m ruff check src/ tests/
python3 -m mypy src/

clean:
$(RM) -rf src/viscot/__pycache__ src/viscot/core/__pycache__
$(RM) -rf tests/__pycache__ .pytest_cache
$(RM) -f .coverage
$(RM) -f src/viscot/core/parser.out src/viscot/core/parsetab.py
$(RM) -rf test_output/
99 changes: 70 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,87 @@
# Visualization program of tree representation of structurally stable incompressible flow in two dimensional multiply-connected domain
# visCOT

このプログラムは2次元多重連結領域内における構造安定な非圧縮流れの木表現の入力に対して,同一のトポロジーを表す2次元上の図を作図するものです.
想定されている入力は,Consで繋がれた木を同一の高さとして見た場合の,深さが3までの木です.
**COT(Combinatorial Orbit Topology)表記から流線図を自動生成する可視化ツール**

2次元多重連結領域上の構造安定な非圧縮流れのトポロジーを、COT木表現から自動的に描画します。
深さに制限はなく、再帰的に任意の深さの木を可視化できます。

## 出力例

| 一様流 `A0()` | 閉軌道を含む一様流 `A0(a+(l+))` | 2つの閉軌道 `A0(a+(l+).a+(l+))` |
|:---:|:---:|:---:|
| ![一様流](examples/example_uniform.png) | ![閉軌道](examples/example_closed_orbit.png) | ![2つの閉軌道](examples/example_two_orbits.png) |

| 鞍点結合 `B0+(l+,c-(l-,).c-(l-,))` | 3つの鞍点結合 | 障害物を含む流れ `A0(a+(b++(B+{},B+{})))` |
|:---:|:---:|:---:|
| ![鞍点結合](examples/example_saddle.png) | ![3つの鞍点結合](examples/example_three_saddle.png) | ![障害物を含む流れ](examples/example_complex_multiply.png) |


## 特徴

- **COT表記のパース** — PLY(Python Lex-Yacc)ベースのパーサで木構造を構文解析
- **自動レイアウト** — 高さベースのスペーシングにより流線の重なりを防止
- **スプライン補間** — scipy による滑らかな流線の描画
- **レイアウト最適化** — Nelder-Mead 法による自動パラメータ最適化
- **多彩な出力形式** — PNG, SVG, PDF, EPS に対応
- **対話モード** — 式を入力して即座にプレビュー

## Requirements
+ Python3
+ Matplotlib
+ PLY

## Linux Ubuntuにてインストール例
+ 本プログラムをダウンロード
```
git clone https://github.com/yokoyama-lab/Visualization-program-of-flow.git
```
- Python 3.10+
- matplotlib 3.7+
- numpy 1.24+
- scipy 1.10+
- PLY 3.11+

+ Python をインストール
```
sudo apt install python3
```
## インストール

+ Matplotlib をインストール
```
cd Thesis_program
pip3 install Matplotlib
pip3 install numpy
pip3 install scipy
```bash
git clone https://github.com/yokoyama-lab/visCOT.git
cd visCOT
pip install -e . --break-system-packages
```

+ PLY をインストール
開発用の依存パッケージ(pytest, ruff, mypy)も合わせてインストールする場合:

```bash
pip install -e ".[dev]" --break-system-packages
```
pip3 install PLY

## 使い方

COT木表現を標準入力から与えて可視化する:

```bash
echo "A0(a2(c+(l+,).c+(l+,),c-(l-,).c-(l-,)))" | viscot
```

## 実行例
プログラムを起動し,木表現を入力する.
ファイルに保存する場合:

```bash
echo "A0(a2(c+(l+,).c+(l+,),c-(l-,).c-(l-,)))" | viscot -o output.png
```
python3 visualize.py

ベクター形式で出力する場合:

```bash
echo "A0(a2(c+(l+,).c+(l+,),c-(l-,).c-(l-,)))" | viscot -o output.svg
echo "A0(a2(c+(l+,).c+(l+,),c-(l-,).c-(l-,)))" | viscot -o output.pdf
```

木表現は,例えば次のように入力する.
対話モードで起動する場合:

```bash
viscot -i
```
a0(cons(a2(cons(c+(l,n),cons(c+(l,n),n)),cons(c-(l,n),cons(c-(l,n),n))),n))

## テスト

```bash
make test
```

入力用の木表現が「test.txt」に用意されているので試してみてください.
## Lint

```bash
make lint
```
Binary file added examples/example_closed_orbit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/example_complex_multiply.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/example_saddle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/example_three_saddle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/example_two_orbits.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/example_uniform.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
59 changes: 59 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "viscot"
version = "0.2.0"
description = "Visualization of tree representation of structurally stable incompressible flows"
requires-python = ">=3.10"
dependencies = [
"numpy>=1.24",
"matplotlib>=3.7",
"scipy>=1.10",
"ply>=3.11",
]

[project.optional-dependencies]
dev = [
"pytest>=7.0",
"pytest-cov>=4.0",
"mypy>=1.5",
"ruff>=0.1",
]
eval = [
"pandas>=2.0",
]

[project.scripts]
viscot = "viscot.cli:main"

[tool.setuptools.packages.find]
where = ["src"]

[tool.mypy]
strict = true
warn_return_any = true
warn_unused_configs = true

[[tool.mypy.overrides]]
module = ["ply", "ply.*", "scipy", "scipy.*"]
ignore_missing_imports = true

[tool.ruff]
target-version = "py310"
line-length = 100

[tool.ruff.lint]
select = ["E", "F", "W", "I", "N", "UP", "B", "A", "SIM"]

[tool.ruff.lint.per-file-ignores]
# PLY requires t_XXX and p_xxx naming conventions
"src/viscot/core/lexer.py" = ["N816"]
"src/viscot/core/parser.py" = ["N802", "N816"]
# Node class names mirror COT notation (B0_plus, C_minus, etc.)
# B027: plot_arrow is intentionally a no-op default, not abstract
"src/viscot/core/nodes.py" = ["N801", "B027"]

[tool.pytest.ini_options]
testpaths = ["tests"]
1 change: 0 additions & 1 deletion src/__init__.py

This file was deleted.

Loading