Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
5b60739
build: migrate from setup.py/requirements.txt to uv + pyproject.toml
TAJD Feb 26, 2026
8f43a31
ci: modernize publish workflow with uv build + trusted publishers
TAJD Feb 26, 2026
95ca0dc
ci: migrate test workflow from pip to uv
TAJD Feb 26, 2026
2f96e28
docs: fix install instructions and add uv as primary method (fixes #43)
TAJD Feb 26, 2026
f5bda36
fix: raise proper RuntimeError instead of string literal (fixes #46)
TAJD Feb 26, 2026
4864d53
fix: replace deprecated scipy interp1d with make_interp_spline
TAJD Feb 26, 2026
8c3db4a
fix: replace deprecated scipy interp2d with RegularGridInterpolator
TAJD Feb 26, 2026
bb236d2
style: auto-fix lint issues with ruff (import sorting, whitespace)
TAJD Feb 26, 2026
37b5e3e
docs: add docstrings to sail classes (addresses #53)
TAJD Feb 26, 2026
cb1aaa3
docs: add docstrings to yacht and appendage classes
TAJD Feb 26, 2026
b4064ad
docs: add docstrings to AeroMod and HydroMod classes
TAJD Feb 26, 2026
33009cf
docs: expand Sphinx docs to cover all source modules
TAJD Feb 26, 2026
b5638a3
ci: require Python >=3.11 and install flask for API tests
TAJD Feb 26, 2026
e38f5bd
fix(ci): bump nlopt>=2.9.1 and numpy>=2.0 for Python 3.13 support
TAJD Feb 26, 2026
becc544
chore: remove implementation plan file
TAJD Feb 26, 2026
c6508a1
feat: make GZ curve per-yacht with optional parameter
TAJD Feb 27, 2026
8e82778
feat: make crew weight configurable with optional parameter
TAJD Feb 27, 2026
c3d1103
test: use Agg backend and verify plot files are created
TAJD Feb 27, 2026
ba0c9ec
feat: add Daring 5.5m yacht definition with estimated parameters
TAJD Feb 27, 2026
8c56a6c
feat: add Daring preset to Streamlit UI
TAJD Feb 27, 2026
f3c7097
feat: add Daring baseline performance prediction results
TAJD Feb 27, 2026
dcdb43f
refactor: make resid() accept flat and RED parameters
TAJD Feb 27, 2026
54b8520
feat: make phi_max configurable in set_analysis()
TAJD Feb 27, 2026
f04604f
feat: add iterative depowering with heel limit enforcement
TAJD Feb 27, 2026
7dd6cbe
fix: clamp initial guess within bounds for depowering solver
TAJD Feb 27, 2026
686918f
chore: add .claude/ to .gitignore
TAJD Feb 27, 2026
89bf5b7
docs: add project guidelines and Daring VPP planning doc
TAJD Feb 27, 2026
54579be
feat: update results and plots with depowering
TAJD Feb 27, 2026
be433b0
fix: add input validation and error handling across VPP stack
TAJD Feb 28, 2026
186079a
test: add validation and error handling tests
TAJD Feb 28, 2026
cfad869
fix: add flask to base dependencies for Streamlit Cloud deploy
TAJD Feb 28, 2026
8a208fe
fix: add streamlit to base dependencies for cloud deploy
TAJD Feb 28, 2026
a8b15ed
fix: regenerate uv.lock with flask and streamlit in base deps
TAJD Feb 28, 2026
a0aaf7d
fix: add ORC docs link, drop boat name from TWS legend, remove defaul…
TAJD Feb 28, 2026
c3a9c64
feat: add comparison page to Streamlit UI
TAJD Feb 28, 2026
0908520
feat: dynamic tabs with change highlighting on comparison page
TAJD Feb 28, 2026
8026c71
feat: add ShortKeel appendage for hull-integrated keels
TAJD Feb 28, 2026
ba98992
fix: swap keel input fields when keel type changes in UI
TAJD Feb 28, 2026
1d59ebb
chore: gitignore .beads, AGENTS.md, CLAUDE.md; track .gitattributes
TAJD Feb 28, 2026
4bd9980
refactor: shared render_keel_inputs for VPP and Compare pages
TAJD Feb 28, 2026
d1422f8
refactor: extract shared run_vpp, environment inputs, and validation
TAJD Feb 28, 2026
e034351
fix: remove leeway clamp, clarify radians conversion, drop dead _cl
TAJD Feb 28, 2026
562c16f
fix: depowering now progresses past first phi_max solution
TAJD Feb 28, 2026
d2aaed4
fix: detect short keel from payload keys, not just type field
TAJD Feb 28, 2026
3f7199c
test: add API tests for short keel type detection
TAJD Feb 28, 2026
178b4bf
feat: replace NLopt with scipy 5-DOF optimizer and improve sail coeff…
TAJD Feb 28, 2026
df554eb
fix: remove heel/leeway jumps at sail crossover and add legends to al…
TAJD Feb 28, 2026
29033e3
fix: add sail set colour legend to middle polar plot
TAJD Feb 28, 2026
cbb527a
fix: move sail set legend to bottom of figure
TAJD Feb 28, 2026
8d4753b
feat: add ORC spinnaker variants and low-performance sail coefficients
TAJD Mar 1, 2026
8b515d8
feat: add sail_type selectors to demo UI and API tests
TAJD Mar 1, 2026
9476a81
feat: add performance modelling, match racing simulation, and Streaml…
TAJD Mar 1, 2026
9e11a2b
fix: eliminate draws in match race with pin-win start offset
TAJD Mar 1, 2026
324d390
fix: improve match race plot quality and differentiation
TAJD Mar 1, 2026
40645d4
feat: solver optimizations, match race analytics, and UI help text
TAJD Mar 2, 2026
6e71231
feat: add LaTeX mathematical notation to all UI parameter labels
TAJD Mar 2, 2026
22a8500
feat: interactive Plotly polar, st.status progress, roughness per-yac…
TAJD Mar 2, 2026
00c4060
feat: TWS-level progress reporting, inclusive wind range, s/NM deltas
TAJD Mar 3, 2026
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
40 changes: 40 additions & 0 deletions .beads/issues.jsonl

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

# Use bd merge for beads JSONL files
.beads/issues.jsonl merge=beads
35 changes: 11 additions & 24 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,18 @@
# This workflows will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

name: Upload Python Package
name: Publish to PyPI

on:
release:
types: [created]

jobs:
deploy:

runs-on: self-hosted

publish:
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
python setup.py sdist bdist_wheel
twine upload dist/*
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
- name: Build package
run: uv build
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
38 changes: 17 additions & 21 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
name: Run tests

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

jobs:
example-1:
name: Testing (${{ matrix.python-version }}, ${{ matrix.os }})
test:
name: Test (Python ${{ matrix.python-version }}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: ["ubuntu-latest"]
python-version: ["3.10"]
os: [ubuntu-latest]
python-version: ["3.11", "3.12", "3.13"]
steps:
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Check repo out
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
fetch-depth: 0
- name: Install dependencies
run: |
pip install -r requirements.txt
- name: Run tests
shell: bash -l {0}
run: |
pytest -vv
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: uv sync --extra dev --extra api
- name: Run tests
run: uv run pytest -vv
40 changes: 31 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
ORC_VPP_2019.pdf
sphinx/_build/
src/__pycache__/
dev.py
venv
.vscode
# Python
__pycache__/
*.pyc
*.pyo
*.egg-info/
dist/
build/

# Environments
.venv/
venv/

# IDE
.vscode/
.idea/

# Sphinx
sphinx/_build/

# pytest
.pytest_cache/

# Claude Code
.claude/
CLAUDE.md
AGENTS.md
.beads/

# Project
ORC_VPP_2019.pdf
dev.py
/.pytest_cache
/__pycache__/
.pytest_cache

.playwright-cli/
48 changes: 48 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Project Guidelines

## Running Commands

- Always use `uv run` to execute Python commands (e.g., `uv run python runVPP.py`, `uv run pytest tests/ -v`)
- Do not use bare `python` or `pytest` — the project uses `uv` for dependency management
- When you fix a bug or implement a feature write a test to prove that it works.

## BEADS

This project uses **bd** (beads) for issue tracking. Run `bd onboard` to get started.

## Quick Reference

```bash
bd ready # Find available work
bd show <id> # View issue details
bd update <id> --status in_progress # Claim work
bd close <id> # Complete work
bd sync # Sync with git
```

## Landing the Plane (Session Completion)

**When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds.

**MANDATORY WORKFLOW:**

1. **File issues for remaining work** - Create issues for anything that needs follow-up
2. **Run quality gates** (if code changed) - Tests, linters, builds
3. **Update issue status** - Close finished work, update in-progress items
4. **PUSH TO REMOTE** - This is MANDATORY:
```bash
git pull --rebase
bd sync
git push
git status # MUST show "up to date with origin"
```
5. **Clean up** - Clear stashes, prune remote branches
6. **Verify** - All changes committed AND pushed
7. **Hand off** - Provide context for next session

**CRITICAL RULES:**
- Work is NOT complete until `git push` succeeds
- NEVER stop before pushing - that leaves work stranded locally
- NEVER say "ready to push when you are" - YOU must push
- If push fails, resolve and retry until it succeeds

Binary file modified Polars.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 Polars_5dof.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 Polars_iterative.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,16 @@ Follow the steps below to contribute to this project.

### Install dependencies

Install the required dependencies from the `requirements.txt` file.
Install the project using [uv](https://docs.astral.sh/uv/):

If using `pip` then `pip install requirements.txt`.
```bash
uv sync --extra dev
```

If using `conda` then follow these steps to create an environment with the right dependencies:
If using `pip`:

```bash
conda create --name Python-VPP \
&& conda config --add channels conda-forge \
&& conda activate Python-VPP \
&& conda install -y --file requirements.txt
pip install -e ".[dev]"
```

### Run tests
Expand Down
Binary file modified SailChart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions dat/Daring/righting_moment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"Heel": [0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0],
"GZ": [0.000, 0.120, 0.230, 0.310, 0.350, 0.330, 0.260]
}
5 changes: 5 additions & 0 deletions dat/orc/asym_cl_kite.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# asymmetric spinnaker centerline tack lift and drag coefficients (ORC VPP). first row is awa
0.02639,,,,,,,,,,,
0.0000,28.000,41.000,50.000,60.000,67.000,75.000,100.000,115.000,130.000,150.000,180.000
0.0000,0.19100,0.28000,0.36600,0.52300,0.44800,0.55600,0.75700,0.79000,0.77600,0.62000,0.40000
0.0000,0.02600,1.01800,1.27700,1.47100,1.51300,1.44400,1.13700,0.82900,0.56000,0.25000,-0.12000
5 changes: 5 additions & 0 deletions dat/orc/asym_pole_kite.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# asymmetric spinnaker pole tack lift and drag coefficients (ORC VPP). first row is awa
0.02639,,,,,,,,,,,
0.0000,28.000,41.000,50.000,60.000,67.000,75.000,100.000,115.000,130.000,150.000,180.000
0.0000,0.17000,0.23800,0.30600,0.45900,0.39200,0.49300,0.79100,0.89400,0.93600,0.93600,0.93600
0.0000,0.08500,1.11400,1.36000,1.51300,1.54800,1.47900,1.20700,0.95600,0.70600,0.42500,0.00000
5 changes: 5 additions & 0 deletions dat/orc/jib.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# jib lift drag and lift coefficient (high). first row is awa
0.016,,,,,,,,,
0.00000,7.0000,15.0000,20.0000,27.0000,50.0000,60.0000,100.0000,150.0000,180.0000
0.003,0.05000,0.03200,0.03100,0.03700,0.25000,0.35000,0.73000,0.95000,0.90000
0.00000,0.00000,1.10000,1.47500,1.50000,1.45000,1.25000,0.40000,0.00000,-0.10000
5 changes: 5 additions & 0 deletions dat/orc/jib_low.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# jib lift drag and lift coefficient (low performance rig). first row is awa
0.016,,,,,,,,,
0.00000,7.0000,15.0000,20.0000,27.0000,50.0000,60.0000,100.0000,150.0000,180.0000
0.003,0.05000,0.03200,0.03100,0.03700,0.25000,0.35000,0.73000,0.95000,0.90000
0.00000,0.00000,1.00000,1.37500,1.45000,1.43000,1.25000,0.40000,0.00000,-0.10000
5 changes: 5 additions & 0 deletions dat/orc/kite.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# kite lift drag and lift coefficient (high). first row is awa
0.02639,,,,,,,,,,,,
0.0000,28.000,41.000,50.000,60.000,67.000,75.000,100.000,115.000,130.000,150.000,170.000,180.000
0.0000,0.19152,0.28152,0.35496,0.43920,0.48960,0.53280,0.61920,0.65880,0.67320,0.67320,0.67320,0.67320
0.0000,-0.02484,0.69437,0.90677,1.04400,1.08000,1.08000,0.95760,0.81360,0.61200,0.32400,0.10800,0.00000
5 changes: 5 additions & 0 deletions dat/orc/main.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# mainsail lift drag and lift coefficient (high). first row is awa
0.01379,,,,,,,,,
0.00000,7.0000,9.0000,12.0000,28.0000,60.0000,90.0000,120.0000,150.0000,180.000
0.03448,0.01724,0.01466,0.01466,0.02586,0.11302,0.38250,0.96888,1.31578,1.34483
0.00000,0.94828,1.13793,1.25000,1.42681,1.38319,1.26724,0.93103,0.38793,-0.11207
5 changes: 5 additions & 0 deletions dat/orc/main_low.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# mainsail lift drag and lift coefficient (low performance rig). first row is awa
0.01379,,,,,,,,,
0.00000,7.0000,9.0000,12.0000,28.0000,60.0000,90.0000,120.0000,150.0000,180.000
0.04300,0.02600,0.02300,0.02300,0.03300,0.11302,0.38250,0.96888,1.31578,1.34483
0.00000,0.86200,1.05200,1.16400,1.34700,1.23900,1.12500,0.83800,0.29600,-0.11207
5 changes: 5 additions & 0 deletions dat/orc/sym_kite.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# symmetric spinnaker lift and drag coefficients (ORC VPP). first row is awa
0.02639,,,,,,,,,,,
0.0000,28.000,41.000,50.000,60.000,67.000,75.000,100.000,115.000,130.000,150.000,180.000
0.0000,0.21300,0.32100,0.42500,0.58700,0.59800,0.61900,0.85000,0.91100,0.93500,0.93500,0.93500
0.0000,0.00000,0.97800,1.24100,1.45400,1.45600,1.43700,1.19000,0.95100,0.70600,0.42500,0.00000
1 change: 1 addition & 0 deletions dat/polars_Daring_5.5m.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dat/polars_YD41.json

Large diffs are not rendered by default.

Loading