Skip to content
Merged
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
14 changes: 14 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "friday"

- package-ecosystem: "uv"
directory: "/"
schedule:
interval: "weekly"
day: "friday"
36 changes: 36 additions & 0 deletions .github/workflows/code_style.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Lint and Format

on:
push:
branches: [ main ]

pull_request:
branches: [ main ]
paths: [ '**/*.py' ]

workflow_dispatch:

concurrency:
group: ${{ github.workflow }}/${{ github.ref }}
cancel-in-progress: true

jobs:
python-format:
name: Ruff Lint and Format
runs-on: ubuntu-latest

steps:
- name: Checkout Repository
uses: actions/checkout@v6

- name: Setup Ruff
uses: astral-sh/ruff-action@v3
with:
args: --version

- name: Enforce Lint
run: ruff check .

- name: Enforce Format
run: |
ruff format --diff .
96 changes: 96 additions & 0 deletions .github/workflows/code_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: Code Test

on:
push:
branches: [ main ]

pull_request:
branches: [ main ]

workflow_dispatch:
workflow_call:
outputs:
artifact_name:
value: ${{ jobs.fresh_build.outputs.artifact_name }}
artifact_run_id:
value: ${{ jobs.fresh_build.outputs.run_id }}

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:

setup:
runs-on: ubuntu-latest

steps:
- name: Fetch Supported Python
id: fetch-versions
run: |
versions=$(curl -fsSL https://endoflife.date/api/v1/products/python/ \
| jq '[ .result.releases[] | select(.isEol == false) | .label ]')

echo "supported_versions=$(echo $versions |jq -c '.')" >> $GITHUB_OUTPUT
echo "bound_versions=$(echo $versions |jq -c '[.[0],.[-1]]')" >> $GITHUB_OUTPUT

outputs:
supported_versions: ${{ steps.fetch-versions.outputs.supported_versions }}
bound_versions: ${{ steps.fetch-versions.outputs.bound_versions }}

fresh_build:
uses: ./.github/workflows/dist_build.yml

testing:
runs-on: ${{ matrix.os }}

permissions:
id-token: write # for working of oidc of codecov

strategy:
matrix:
os: [ ubuntu-latest ]
py-version: ${{ fromJson(needs.setup.outputs.supported_versions) }}
include:
- os: windows-latest
py-version: ${{ fromJson(needs.setup.outputs.bound_versions)[0] }}
- os: windows-latest
py-version: ${{ fromJson(needs.setup.outputs.bound_versions)[1] }}
- os: macos-latest
py-version: ${{ fromJson(needs.setup.outputs.bound_versions)[0] }}
- os: macos-latest
py-version: ${{ fromJson(needs.setup.outputs.bound_versions)[1] }}

needs:
- fresh_build
- setup

steps:
- uses: actions/checkout@v6

- name: Download Build Artifacts
uses: actions/download-artifact@v7
with:
name: ${{ needs.fresh_build.outputs.artifact_name }}
run-id: ${{ needs.fresh_build.outputs.run_id }}
path: ./dist

- uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.py-version }}

- name: Install Packages
shell: bash
run: |
uv sync --no-dev --group test
uv pip install -v ./dist/*.whl

- name: Run Tests
run: uv run --no-sync pytest -v -n auto --cov --cov-report=xml

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
fail_ci_if_error: true
use_oidc: true
verbose: true
40 changes: 40 additions & 0 deletions .github/workflows/dist_build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Build Distribution

on:
workflow_call:
outputs:
artifact_name:
value: ${{ jobs.build.outputs.artifact_name }}
run_id:
value: ${{ github.run_id }}

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Setup uv
uses: astral-sh/setup-uv@v7

- name: Build distribution
run: uv build -v --clear .

- name: Set Artifact Name
id: artifact-name
run: |
echo "artifact_name=${{ github.run_id }}[${{ github.run_attempt }}]--build-artifacts" \
| tee -a $GITHUB_OUTPUT

- name: Upload Build Artifacts
uses: actions/upload-artifact@v6
with:
name: ${{ steps.artifact-name.outputs.artifact_name }}
path: dist
if-no-files-found: error

outputs:
artifact_name: ${{ steps.artifact-name.outputs.artifact_name }}
52 changes: 52 additions & 0 deletions .github/workflows/docs_build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Build Documentation
permissions:
pages: write
id-token: write

on:
pull_request:
branches: [ main ]
workflow_call:
inputs: &build-docs-inputs
deploy:
type: boolean
required: false
default: false

workflow_dispatch:
inputs: *build-docs-inputs

concurrency:
group: docs-build

jobs:

build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6

- name: Setup uv
uses: astral-sh/setup-uv@v7

- name: Build Documentation
run: uv run --no-dev --group docs mkdocs build --clean --strict

- name: Set Artifact Name
id: artifact-name
run: |
echo "artifact_name=${{ github.run_id }}[${{ github.run_attempt }}]--docs-artifacts" \
| tee -a $GITHUB_OUTPUT

- name: Upload Pages Artifacts
uses: actions/upload-pages-artifact@v4
with:
name: ${{ steps.artifact-name.outputs.artifact_name }}
path: site/

- name: Deploy to GitHub Pages
if: ${{ inputs.deploy }}
uses: actions/deploy-pages@v4
with:
artifact_name: ${{ steps.artifact-name.outputs.artifact_name }}
56 changes: 56 additions & 0 deletions .github/workflows/publish_dist.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Publish to PyPI

on:
release:
types: [published]

permissions:
id-token: write

concurrency:
group: ${{ github.workflow }}

jobs:
testing:
uses: ./.github/workflows/code_test.yml

publish-to-pypi:
runs-on: ubuntu-latest

environment:
name: pypi

needs: testing

steps:

- &download_dist
name: Download Distributions
uses: actions/download-artifact@v7
with:
name: ${{ needs.testing.outputs.artifact_name }}
run-id: ${{ needs.testing.outputs.artifact_run_id }}
path: ./dist

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
verbose: true

- name: Smoke Test on PyPI
shell: bash
run: |
sleep 60
pip install -v --index-url https://pypi.org/simple/ sparse_grid
python -c "import sparse_grid;print(sparse_grid.__version__)"

publish_docs:
needs: publish-to-pypi

permissions:
pages: write
id-token: write

uses: ./.github/workflows/docs_build.yml
with:
deploy: true
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.10
3 changes: 3 additions & 0 deletions docs/api/grid.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# sparse_grid.grid

::: sparse_grid.grid
10 changes: 10 additions & 0 deletions docs/api/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# API Reference

API documentation is generated with `mkdocstrings` from module docstrings and
signatures.

Use the pages in this section for module-level details:

- `sparse_grid.grid`
- `sparse_grid.point`
- `sparse_grid.utils`
3 changes: 3 additions & 0 deletions docs/api/point.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# sparse_grid.point

::: sparse_grid.point
3 changes: 3 additions & 0 deletions docs/api/utils.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# sparse_grid.utils

::: sparse_grid.utils
44 changes: 44 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Getting Started

## Installation

```bash
pip install sparse_grid
```

## Create a sparse grid

```python
from sparse_grid import SparseGrid

sg = SparseGrid(dim=3, level=3)
sg.generate_points()
print(len(sg.indices))
```

## Assign nodal values

Populate nodal values (`fv`) at each sparse-grid point.

```python
for index in sg.indices:
pos = sg.g_p[tuple(index)].pos
value = 1.0
for coord in pos:
value *= 4.0 * coord * (1.0 - coord)
sg.g_p[tuple(index)].fv = value
```

## Convert to hierarchical values

```python
sg.nodal_2_hier()
```

## Evaluate the sparse-grid interpolant

```python
x = [0.2, 0.4, 0.8]
y = sg.eval_funct(x)
print(y)
```
Loading