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
45 changes: 14 additions & 31 deletions .github/workflows/python-release.yml
Original file line number Diff line number Diff line change
@@ -1,47 +1,30 @@
name: Create and upload release

on:
push:
tags:
- 'v*'
workflow_run:
workflows: ["Python Package using pip"]
types:
- completed

jobs:
test-linux:
release:
# Only run if the triggering run was for a tag starting with v
if: >
github.event.workflow_run.conclusion == 'success' &&
startsWith(github.event.workflow_run.head_branch, 'v')
runs-on: ubuntu-latest
strategy:
max-parallel: 5

steps:
- uses: actions/checkout@v4

- name: Set up Python 3.11.2
uses: actions/setup-python@v3
- name: Download pytest-results artifact from previous workflow
uses: actions/download-artifact@v4
with:
python-version: '3.11.2'

- name: Add conda to system path
run: |
# $CONDA is an environment variable pointing to the root of the miniconda directory
echo $CONDA/bin >> $GITHUB_PATH

- name: Install dependencies
run: |
conda env update --file environment.yaml

- name: Lint with flake8
run: |
conda install flake8
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

- name: Test with pytest
run: |
source activate bemol
pytest tests/ -vvs
# store the latest run results as release artifact
zip -r pytest-results.zip tests/results/
name: pytest-results
run-id: ${{ github.event.workflow_run.id }}
path: .

- name: Create Release
id: create_release
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
name: Python Package using Conda
name: Python Package using pip

on:
push:
branches:
- '*'
tags:
- '*'

on: [push]

jobs:
test-linux:
Expand All @@ -16,15 +22,11 @@ jobs:
with:
python-version: '3.11.2'

- name: Add conda to system path
run: |
# $CONDA is an environment variable pointing to the root of the miniconda directory
echo $CONDA/bin >> $GITHUB_PATH

- name: Install dependencies
run: |
conda env update --file environment.yaml
conda install flake8
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install flake8

- name: Lint with flake8
run: |
Expand All @@ -33,15 +35,27 @@ jobs:
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

# TODO: conside the latest release, not a hardcoded one!
# considers the latest release, not a hardcoded one!
- name: Get reference results
run: |
curl -L -o pytest-results.zip "https://github.com/ifpen/bemol/releases/download/v0.0.1/pytest-results.zip"
URL=$(curl -s https://api.github.com/repos/ifpen/bemol/releases/latest \
| jq -r '.assets[] | select(.name=="pytest-results.zip") | .browser_download_url')
if [ -z "$URL" ] || [ "$URL" = "null" ]; then
echo "pytest-results.zip not found in latest release assets"
exit 1
fi
curl -L -o pytest-results.zip "$URL"
unzip pytest-results.zip
mv tests/results tests/ref/

- name: Test with pytest
run: |
source activate bemol
pytest tests/ -vvs --reference tests/ref/

zip -r pytest-results.zip tests/results

- name: Upload pytest-results artifact
uses: actions/upload-artifact@v4
with:
name: pytest-results
path: pytest-results.zip
retention-days: 0.020833 # 30 minutes
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
**/__pycache__/
**/.pytest_cache/
**/.pytest_cache/

/.bemol/
23 changes: 17 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,25 @@ The library is based on [Numpy](https://numpy.org/), [Scipy](https://scipy.org/)
[pytest](https://pytest.org/) is as well optional, used for the evaluation
of the tests inside the `tests` sub-folder.

The list of considered/tested versions are available in environment.yaml.
For use with conda:
The list of considered/tested versions are available in conda and pip formats.

```bash
conda env create -f environment.yaml
```
- For use with conda:

```bash
conda env create -f environment.yaml
```

Use `conda activate bemol` to use the env.

- Using pip and venv:

```bash
python3 -m venv .bemol
source .bemol/bin/activate
pip install -r requirements.txt
```

Use `conda activate bemol` to use the env.
Use `source .bemol/bin/activate` to use the env.

## Authors

Expand Down
53 changes: 2 additions & 51 deletions bemol/bem.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,60 +5,11 @@
import numpy as np

from . import rotor
from . import secondary
from . import correction
from . import tools




class Corrections(object):
"""Class for storing corrections.

Consider all the corrections available in the secondary
models module. If not given by the user considers the base (empty)
correction with the default parameters.

Parameters
----------
corrections : optional
dictionary or list with the secondary corrections, either classes of
instances - in case of custom parameters. If dictionary is
given, the key must be the name of the correction as defined in
secondary.py with a lower first letter.

"""
def __init__(self,corrections:dict={}):
for name, obj in inspect.getmembers(secondary):
if inspect.isclass(obj):
_name = name[0].lower() + name[1:]
if type(corrections) is dict:
if _name in corrections:
# instantiation of correction with default values
corr = corrections[_name]
corr = corr() if isinstance(corr,type) else corr
setattr(self,_name,corr)
else:
setattr(self,_name,obj.Dummy())
else:
effect_name = obj.__qualname__
setattr(self,_name,obj.Dummy())
# loop for all effects to check if any of the input
# corrections are inner of the available corrections
for corr in corrections:
# instantiation of correction with default values
corr = corr() if isinstance(corr,type) else corr
correction_name = type(corr).__qualname__
if effect_name in correction_name:
setattr(self,_name,corr)
break


def __iter__(self):
"""Iterate corrections."""
for value in self.__dict__.values():
yield value


class BaseBEM:
"""Base BEM class.

Expand Down Expand Up @@ -89,7 +40,7 @@ def __init__(self,rotor:rotor.Rotor,rho:float=1.225,corrections:dict=None):
self.n = len(rotor.sections)

if corrections is None: corrections = {}
self.corrections = Corrections(corrections)
self.corrections = correction.Corrections(corrections)



Expand Down
55 changes: 55 additions & 0 deletions bemol/correction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@

import inspect
from types import ModuleType

from . import secondary


class Corrections(object):
"""Class for storing corrections.

Consider all the corrections available in the secondary
models module. If not given by the user considers the base (empty)
correction with the default parameters.

Parameters
----------
corrections : optional
dictionary or list with the secondary corrections, either classes of
instances - in case of custom parameters. If dictionary is
given, the key must be the name of the correction as defined in
secondary.py with a lower first letter.

"""
def __init__(self,corrections:dict={}):

for name_mod, mod in inspect.getmembers(secondary):
if not isinstance(mod,ModuleType): continue
effect_name = name_mod[0].lower() + name_mod[1:]
for name_obj, obj in inspect.getmembers(mod):
if inspect.isclass(obj):
if type(corrections) is dict:
if effect_name in corrections:
# instantiation of correction with default values
corr = corrections[effect_name]
corr = corr() if isinstance(corr,type) else corr
setattr(self,effect_name,corr)
else:
setattr(self,effect_name,mod.Dummy())
else:
setattr(self,effect_name,mod.Dummy())
# loop for all effects to check if any of the input
# corrections are classes of the available corrections
for corr in corrections:
# instantiation of correction with default values
# TODO: check name before instanciating!
corr = corr() if isinstance(corr,type) else corr
if effect_name in corr.__module__:
setattr(self,effect_name,corr)
break


def __iter__(self):
"""Iterate corrections."""
for value in self.__dict__.values():
yield value
Loading
Loading