py_windblade_opa 0.6.6__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.
Files changed (146) hide show
  1. py_windblade_opa-0.6.6/.gitignore +93 -0
  2. py_windblade_opa-0.6.6/.python-version +1 -0
  3. py_windblade_opa-0.6.6/CHANGELOG.md +18 -0
  4. py_windblade_opa-0.6.6/History.md +47 -0
  5. py_windblade_opa-0.6.6/LICENSE +21 -0
  6. py_windblade_opa-0.6.6/PKG-INFO +135 -0
  7. py_windblade_opa-0.6.6/README.md +108 -0
  8. py_windblade_opa-0.6.6/design/.gitkeep +1 -0
  9. py_windblade_opa-0.6.6/design/TODOs-NOTE.md +79 -0
  10. py_windblade_opa-0.6.6/design/architecture.md +390 -0
  11. py_windblade_opa-0.6.6/design/archive/PerformancePostProcessor-and-MDReport.md +313 -0
  12. py_windblade_opa-0.6.6/design/archive/Stage1-OrchestratorFixUpdatingAndUT.md +784 -0
  13. py_windblade_opa-0.6.6/design/next_refactor/Stage3-AirfoilProvider.md +265 -0
  14. py_windblade_opa-0.6.6/design/next_refactor/Stage4-RotorAssembly.md +285 -0
  15. py_windblade_opa-0.6.6/design/ongoing/IMPLEMENTATION-STATUS.md +119 -0
  16. py_windblade_opa-0.6.6/design/ongoing/Stage2-AddingGeometryV2.md +491 -0
  17. py_windblade_opa-0.6.6/docs/Makefile +21 -0
  18. py_windblade_opa-0.6.6/docs/make.bat +35 -0
  19. py_windblade_opa-0.6.6/docs/source/_static/.gitkeep +0 -0
  20. py_windblade_opa-0.6.6/docs/source/api/airfoils.md +19 -0
  21. py_windblade_opa-0.6.6/docs/source/api/bem_hansen.md +37 -0
  22. py_windblade_opa-0.6.6/docs/source/api/blade_designer.md +16 -0
  23. py_windblade_opa-0.6.6/docs/source/api/blade_geometry.md +21 -0
  24. py_windblade_opa-0.6.6/docs/source/api/deol_orch.md +53 -0
  25. py_windblade_opa-0.6.6/docs/source/api/index.md +13 -0
  26. py_windblade_opa-0.6.6/docs/source/api/support.md +14 -0
  27. py_windblade_opa-0.6.6/docs/source/api/utils.md +8 -0
  28. py_windblade_opa-0.6.6/docs/source/conf.py +65 -0
  29. py_windblade_opa-0.6.6/docs/source/examples/bem_workflow.md +189 -0
  30. py_windblade_opa-0.6.6/docs/source/examples/deol_workflow.md +194 -0
  31. py_windblade_opa-0.6.6/docs/source/examples/index.md +10 -0
  32. py_windblade_opa-0.6.6/docs/source/examples/sample_performance_report.md +35 -0
  33. py_windblade_opa-0.6.6/docs/source/index.md +51 -0
  34. py_windblade_opa-0.6.6/docs/source/installation.md +54 -0
  35. py_windblade_opa-0.6.6/docs/source/quickstart.md +112 -0
  36. py_windblade_opa-0.6.6/docs/source/theory/bem.md +131 -0
  37. py_windblade_opa-0.6.6/docs/source/theory/blade_design.md +119 -0
  38. py_windblade_opa-0.6.6/docs/source/theory/deol.md +178 -0
  39. py_windblade_opa-0.6.6/docs/source/theory/index.md +39 -0
  40. py_windblade_opa-0.6.6/examples/_data/FFA-W3-CL_CD_CM_long.xlsx +0 -0
  41. py_windblade_opa-0.6.6/examples/_data/bladedata.txt +18 -0
  42. py_windblade_opa-0.6.6/examples/airfoils/plot_cl_cd.py +46 -0
  43. py_windblade_opa-0.6.6/examples/bem_hansen/bem_hansen_geom2_poc.py +95 -0
  44. py_windblade_opa-0.6.6/examples/bem_hansen/bem_hansen_v18_poc.py +185 -0
  45. py_windblade_opa-0.6.6/examples/bem_hansen/data/FFA-W3-CL_CD_CM_long.xlsx +0 -0
  46. py_windblade_opa-0.6.6/examples/bem_hansen/data/bladedata.txt +18 -0
  47. py_windblade_opa-0.6.6/examples/bem_hansen/data/v18_ut_res/v1_8_T7P3df10_py.csv +11 -0
  48. py_windblade_opa-0.6.6/examples/bem_hansen/example_v18_contour_plots.py +220 -0
  49. py_windblade_opa-0.6.6/examples/bem_hansen/example_v18_cp_vs_ws.py +202 -0
  50. py_windblade_opa-0.6.6/examples/bem_hansen/hansen_markdown.md +85 -0
  51. py_windblade_opa-0.6.6/examples/deol_orch/blade_geom1.json +41 -0
  52. py_windblade_opa-0.6.6/examples/deol_orch/diag_deol_attack_angle_range.py +78 -0
  53. py_windblade_opa-0.6.6/examples/deol_orch/e105-blade_withgenerator/blade_geom1.json +41 -0
  54. py_windblade_opa-0.6.6/examples/deol_orch/e105-blade_withgenerator/example105-bladeGenerator.py +106 -0
  55. py_windblade_opa-0.6.6/examples/deol_orch/e106-pitch_variation/blade_geom1.json +41 -0
  56. py_windblade_opa-0.6.6/examples/deol_orch/e106-pitch_variation/example106-pitchvariation.py +85 -0
  57. py_windblade_opa-0.6.6/examples/deol_orch/e107-tests_confg/example107-test_config.py +134 -0
  58. py_windblade_opa-0.6.6/examples/deol_orch/example101.py +45 -0
  59. py_windblade_opa-0.6.6/examples/deol_orch/example102-bladeGeom.py +121 -0
  60. py_windblade_opa-0.6.6/examples/deol_orch/example103-benchmarking.py +28 -0
  61. py_windblade_opa-0.6.6/examples/energies-2999366/bg_koumgioutzoglou.json +43 -0
  62. py_windblade_opa-0.6.6/examples/energies-2999366/calcs-2999366.py +87 -0
  63. py_windblade_opa-0.6.6/examples/naca4415-blade1/bem_v18_blade1.py +196 -0
  64. py_windblade_opa-0.6.6/examples/naca4415-blade1/blade1_geom.json +43 -0
  65. py_windblade_opa-0.6.6/examples/naca4415-blade1/deol_blade1.py +180 -0
  66. py_windblade_opa-0.6.6/examples/naca4415-blade1/results/blade1_performance_data.csv +1201 -0
  67. py_windblade_opa-0.6.6/examples/naca4415-blade1/results/blade1_performance_data.xlsx +0 -0
  68. py_windblade_opa-0.6.6/examples/naca4415-blade1/results/cp_vs_lambda.csv +22 -0
  69. py_windblade_opa-0.6.6/justfile +40 -0
  70. py_windblade_opa-0.6.6/pyproject.toml +63 -0
  71. py_windblade_opa-0.6.6/reference/articles/36900.pdf +0 -0
  72. py_windblade_opa-0.6.6/reference/articles/Blade calculation.pdf +0 -0
  73. py_windblade_opa-0.6.6/reference/articles/Blade design.pdf +0 -0
  74. py_windblade_opa-0.6.6/reference/articles/blade.pdf +0 -0
  75. py_windblade_opa-0.6.6/reference/mermaid/Blade_Refactored.md +50 -0
  76. py_windblade_opa-0.6.6/reference/mermaid/Quantities.xlsx +0 -0
  77. py_windblade_opa-0.6.6/reference/mermaid/all_in_one/BladeClass.md +345 -0
  78. py_windblade_opa-0.6.6/reference/mermaid/all_in_one/s1_main_calculation.md +196 -0
  79. py_windblade_opa-0.6.6/reference/mermaid/all_in_one/s2_calculate_i_flow.md +115 -0
  80. py_windblade_opa-0.6.6/reference/mermaid/all_in_one/step3_eleven_coeffs.md +180 -0
  81. py_windblade_opa-0.6.6/reference/mermaid/all_in_one/step4_coeffs_collection.md +93 -0
  82. py_windblade_opa-0.6.6/reference/mermaid/all_in_one/step5_rpm_power.md +94 -0
  83. py_windblade_opa-0.6.6/reference/mermaid/all_in_one/step6_torque_calcs.md +94 -0
  84. py_windblade_opa-0.6.6/reference/mermaid/refactored/Calculate_Cf_Cm_L0.md +77 -0
  85. py_windblade_opa-0.6.6/reference/mermaid/refactored/blade_calc.docx +0 -0
  86. py_windblade_opa-0.6.6/reference/mermaid/refactored/blade_calc.md +309 -0
  87. py_windblade_opa-0.6.6/reference/mermaid/refactored/calc_Alternate.md +153 -0
  88. py_windblade_opa-0.6.6/reference/notes/airloils_reasoning.md +75 -0
  89. py_windblade_opa-0.6.6/reference/notes/flow_angles.md +55 -0
  90. py_windblade_opa-0.6.6/reference/notes/flow_angles.pdf +0 -0
  91. py_windblade_opa-0.6.6/reference/notes/images/energies-16-00945-g002.png +0 -0
  92. py_windblade_opa-0.6.6/reference/notes/readme.txt +1 -0
  93. py_windblade_opa-0.6.6/reference/wind_opa.docx +0 -0
  94. py_windblade_opa-0.6.6/reference/wind_opa.md +635 -0
  95. py_windblade_opa-0.6.6/src/py_windblade_opa/__init__.py +19 -0
  96. py_windblade_opa-0.6.6/src/py_windblade_opa/airfoils/__init__.py +1 -0
  97. py_windblade_opa-0.6.6/src/py_windblade_opa/airfoils/af_naca4415.py +75 -0
  98. py_windblade_opa-0.6.6/src/py_windblade_opa/airfoils/af_naca4415_test.py +78 -0
  99. py_windblade_opa-0.6.6/src/py_windblade_opa/airfoils/airfoil_abstract.py +48 -0
  100. py_windblade_opa-0.6.6/src/py_windblade_opa/airfoils/obsolete_cl.py +24 -0
  101. py_windblade_opa-0.6.6/src/py_windblade_opa/bem_hansen/__init__.py +5 -0
  102. py_windblade_opa-0.6.6/src/py_windblade_opa/bem_hansen/aero_coefficient_interpolator.py +219 -0
  103. py_windblade_opa-0.6.6/src/py_windblade_opa/bem_hansen/blade_aux_functions.py +257 -0
  104. py_windblade_opa-0.6.6/src/py_windblade_opa/bem_hansen/blade_performance_calculator.py +253 -0
  105. py_windblade_opa-0.6.6/src/py_windblade_opa/bem_hansen/data_models.py +25 -0
  106. py_windblade_opa-0.6.6/src/py_windblade_opa/bem_hansen/support_functions.py +16 -0
  107. py_windblade_opa-0.6.6/src/py_windblade_opa/blade_geometry.py +122 -0
  108. py_windblade_opa-0.6.6/src/py_windblade_opa/blade_geometry_v2.py +268 -0
  109. py_windblade_opa-0.6.6/src/py_windblade_opa/blade_plotter.py +146 -0
  110. py_windblade_opa-0.6.6/src/py_windblade_opa/deol_orch/__init__.py +0 -0
  111. py_windblade_opa-0.6.6/src/py_windblade_opa/deol_orch/_common.py +72 -0
  112. py_windblade_opa-0.6.6/src/py_windblade_opa/deol_orch/_components_array.py +63 -0
  113. py_windblade_opa-0.6.6/src/py_windblade_opa/deol_orch/_components_loop.py +127 -0
  114. py_windblade_opa-0.6.6/src/py_windblade_opa/deol_orch/blade_calc_orchestrator.py +249 -0
  115. py_windblade_opa-0.6.6/src/py_windblade_opa/deol_orch/data_models.py +35 -0
  116. py_windblade_opa-0.6.6/src/py_windblade_opa/deol_orch/refactoring.md +158 -0
  117. py_windblade_opa-0.6.6/src/py_windblade_opa/performance/__init__.py +12 -0
  118. py_windblade_opa-0.6.6/src/py_windblade_opa/performance/curve_data.py +30 -0
  119. py_windblade_opa-0.6.6/src/py_windblade_opa/performance/formulas.py +82 -0
  120. py_windblade_opa-0.6.6/src/py_windblade_opa/performance/post_processor.py +127 -0
  121. py_windblade_opa-0.6.6/src/py_windblade_opa/performance/report.py +94 -0
  122. py_windblade_opa-0.6.6/src/py_windblade_opa/support.py +79 -0
  123. py_windblade_opa-0.6.6/src/py_windblade_opa/utils.py +66 -0
  124. py_windblade_opa-0.6.6/src/py_windblade_opa/wel_blade_designer.py +177 -0
  125. py_windblade_opa-0.6.6/tests/airfoils/test_airfoils.py +23 -0
  126. py_windblade_opa-0.6.6/tests/bem_hansen/conftest.py +59 -0
  127. py_windblade_opa-0.6.6/tests/bem_hansen/test_aero_coefficient_interpolator.py +99 -0
  128. py_windblade_opa-0.6.6/tests/bem_hansen/test_blade_aux_functions.py +62 -0
  129. py_windblade_opa-0.6.6/tests/bem_hansen/test_blade_perofrmance_calculator.py +45 -0
  130. py_windblade_opa-0.6.6/tests/bem_hansen/test_performance_postprocessor.py +63 -0
  131. py_windblade_opa-0.6.6/tests/bem_hansen/test_support_functions.py +17 -0
  132. py_windblade_opa-0.6.6/tests/deol/conftest.py +46 -0
  133. py_windblade_opa-0.6.6/tests/deol/flow_components/test_flow_component.py +86 -0
  134. py_windblade_opa-0.6.6/tests/deol/test_blade_calc_L4.py +70 -0
  135. py_windblade_opa-0.6.6/tests/deol/test_blade_calc_l0.py +29 -0
  136. py_windblade_opa-0.6.6/tests/deol/test_blade_calc_l5_df_long.py +101 -0
  137. py_windblade_opa-0.6.6/tests/deol/test_blade_calc_uLCpNP.py +95 -0
  138. py_windblade_opa-0.6.6/tests/deol/test_blade_energy_yield.py +126 -0
  139. py_windblade_opa-0.6.6/tests/deol/test_blade_geometry.py +64 -0
  140. py_windblade_opa-0.6.6/tests/deol/test_cp_vs_lambda.py +87 -0
  141. py_windblade_opa-0.6.6/tests/deol/test_orchestrator_equivalence.py +221 -0
  142. py_windblade_opa-0.6.6/tests/deol/test_wel_designer.py +66 -0
  143. py_windblade_opa-0.6.6/tests/performance/test_report.py +52 -0
  144. py_windblade_opa-0.6.6/tests/test_blade_geometry_v2.py +95 -0
  145. py_windblade_opa-0.6.6/tests/test_support_classes.py +61 -0
  146. py_windblade_opa-0.6.6/uv.lock +4057 -0
@@ -0,0 +1,93 @@
1
+ # --- Core Python ---
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ .installed.cfg
8
+ *.egg
9
+ *.manifest
10
+ *.spec
11
+
12
+ # --- Distribution / Packaging ---
13
+ build/
14
+ develop-eggs/
15
+ dist/
16
+ downloads/
17
+ eggs/
18
+ .eggs/
19
+ lib/
20
+ lib64/
21
+ parts/
22
+ sdist/
23
+ var/
24
+ wheels/
25
+ share/python-wheels/
26
+ *.egg-info/
27
+ MANIFEST
28
+
29
+ # --- Installer Logs ---
30
+ pip-log.txt
31
+ pip-delete-this-directory.txt
32
+
33
+ # --- Testing & Code Quality ---
34
+ htmlcov/
35
+ .tox/
36
+ .nox/
37
+ .coverage
38
+ .coverage.*
39
+ .cache
40
+ nosetests.xml
41
+ coverage.xml
42
+ *.cover
43
+ *.py,cover
44
+ .hypothesis/
45
+ .pytest_cache/
46
+ cover/
47
+
48
+ # --- Modern Tooling (2026 Standards) ---
49
+ # Ruff (Linter/Formatter cache)
50
+ .ruff_cache/
51
+
52
+ # MyPy (Type checking cache)
53
+ .mypy_cache/
54
+ .dmypy.json
55
+ dmypy.json
56
+
57
+ # Hatch (Build artifacts)
58
+ .hatch/
59
+
60
+ # --- Documentation ---
61
+ # Sphinx
62
+ docs/_build/
63
+ # MkDocs
64
+ /site
65
+
66
+ # --- Jupyter Notebooks ---
67
+ .ipynb_checkpoints
68
+ profile_default/
69
+ ipython_config.py
70
+
71
+ # --- Environments ---
72
+ # Note: We do NOT ignore uv.lock. Commit it!
73
+ .env
74
+ .venv
75
+ env/
76
+ venv/
77
+ ENV/
78
+
79
+ # --- IDEs & Editors ---
80
+ # VS Code (User settings)
81
+ .vscode/
82
+ # PyCharm
83
+ .idea/
84
+ # Spyder
85
+ .spyderproject
86
+ .spyproject
87
+ # Rope
88
+ .ropeproject
89
+
90
+ # --- OS Generated Files (Windows/Mac) ---
91
+ Thumbs.db
92
+ Desktop.ini
93
+ .DS_Store
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,18 @@
1
+ # Work in progress
2
+
3
+ - [x] replace logging with the recommended logger pattern in all src
4
+
5
+ # v0.6.5
6
+
7
+ **MAIN CHANGES:**:
8
+
9
+ - [x] Add a functionality that export into an md file the results of the analysis for the deol and the bem hansen
10
+ - [x] Streamlined the deol_orch and bem_hansen to use the new PerformanceCurve contract and remove the clean_data param from the PerformancePostProcessor. See design/ongoing/PerformancePostProcessor-and-MDReport.md §5.
11
+
12
+
13
+
14
+ # v0.6.1
15
+
16
+ **Main changes:**
17
+
18
+ - refactor: Cleaning up the deol code, to use the orchestrator version which is cleaner and more maintanable.
@@ -0,0 +1,47 @@
1
+ # History/TODO
2
+
3
+ # TODO
4
+
5
+ - [ ] BladeGeometry v2
6
+ - Create a class method for reading from json file
7
+ - Create Save to json method.
8
+ - Modifyt BladeAuxFunction class to have (composition) a BladeGeometryContainer instance.
9
+ - Decide whether this class will only hold geometry data or if it will alos provide convenience methods (that the BladeAuxFunction class currently implements)
10
+ - modify the deol code to use the BladeGeometryContainer class (instead of the previous implementation.)
11
+
12
+
13
+ - [ ] FEAT: add airfoils in geometry JSON (Use Airfoil Factory)
14
+ - [ ] REF: merge steps 2 and 3 (create a single method for the calculation of the Cf, Cm and lambda0_final parametes)
15
+ - [ ] REF: merge steps 4,5
16
+ - [ ] FEAT: Save data to file in a useful way
17
+ - [ ] xlsx or csv
18
+ - [ ] decide if wide or long format is better (maybe provie both options?)
19
+
20
+
21
+
22
+ ## DONE:
23
+ - Blade Geometry Container class
24
+ - Refactored BladeCalc Class
25
+ - [x] REF: merge steps 5,6 (create a single method for the all curves)
26
+
27
+ Testing:
28
+ - [x] TEST: test the curves_df method (brutal)
29
+ - [x] TEST: test the curves_df method (clean)
30
+ - [x] FEAT: add option for cleaning the data
31
+ - [x] TEST: Test option for cleaning the data (step5_curves_to_df)
32
+ - [x] FEAT: Added a state machine that will allow software to automatically collect only the curves_df data that have a physical meaning
33
+ - [x] FEAT: add an argument that enables or disables the state machine (Defaults to true)
34
+ - [x] FEAT: USE_LOOPS attribute inside class to allow quicker change
35
+ - [x] TEST: Added tests of LOOPS and ARRAY versions of code
36
+ - [x] TEST: use @pytest.mark.parametrize to reduce repetition in the tests (the loops and arrays methods should yield the same results)
37
+
38
+
39
+ ## 0.1 (2024/07/03)
40
+
41
+ Released v0.1 which:
42
+ - has a Separate Blade Geometry Container class which is separate from the BladeCalc class
43
+ - Refactored BladeCalc Class to be more readble
44
+ - Different airfoils for a specific $\lambda_0$ are permitted (in the loops version - not yet in the arrays)
45
+ - Added an option for Using the different versions (arrays or loops) in the as aa module constant.
46
+ - Have enough tests
47
+ - Added several mermaid flowcharts for the main calculation steps (for the original and refactored)
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Nikolaos Papadakis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,135 @@
1
+ Metadata-Version: 2.4
2
+ Name: py_windblade_opa
3
+ Version: 0.6.6
4
+ Summary: A package for the performance analysis and optimisation of wind turbine blades performance
5
+ Project-URL: Documentation, https://npapnet.github.io/py_windblade_opa/
6
+ Project-URL: Source, https://github.com/npapnet/py_windblade_opa
7
+ Author-email: "N. Papadakis" <npapnet@gmail.com>
8
+ License: MIT
9
+ License-File: LICENSE
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Requires-Python: >=3.10
14
+ Requires-Dist: matplotlib
15
+ Requires-Dist: numpy
16
+ Requires-Dist: openpyxl
17
+ Requires-Dist: pandas
18
+ Requires-Dist: plotnine>=0.15.2
19
+ Requires-Dist: scipy
20
+ Provides-Extra: docs
21
+ Requires-Dist: furo; extra == 'docs'
22
+ Requires-Dist: myst-parser; extra == 'docs'
23
+ Requires-Dist: sphinx-autobuild; extra == 'docs'
24
+ Requires-Dist: sphinx>=7.0; extra == 'docs'
25
+ Requires-Dist: sphinxcontrib-mermaid; extra == 'docs'
26
+ Description-Content-Type: text/markdown
27
+
28
+ # py_windblade_opa
29
+
30
+ A python package for Windblade Optimization and Performance Assessment
31
+
32
+ Author: [N. Papadakis](https://github.com/npapnet).
33
+
34
+ ## Scope
35
+
36
+ This package is intended to provide a set of tools for the optimization and performance assessment of wind turbine blades.
37
+
38
+ ## Installation
39
+
40
+ ## For Users
41
+ If you just want to use py_windblade_opa in your own projects, install the latest stable version from PyPI:
42
+
43
+ > pip install py-windblade-opa
44
+
45
+ ## For Developers and Contributors
46
+
47
+ We offer two ways to set up the development environment. We strongly recommend using uv (the modern method) as it guarantees you are using the exact same dependencies and Python version as the maintainers.
48
+
49
+ ### Option A: Using uv (Recommended)
50
+
51
+ This method automatically handles Python version management and dependency locking.
52
+
53
+ 1. **Clone the repository**:
54
+
55
+ ```bash
56
+ git clone https://github.com/npapnet/py_windblade_opa.git
57
+ cd py_windblade_opa
58
+ ```
59
+
60
+ 2. **Sync the environment**: This command creates the virtual environment, installs the specific Python version required, and sets up the package in editable mode, installing also all the development dependencies.
61
+
62
+ ```Bash
63
+ uv sync --extra dev
64
+ ```
65
+
66
+ 3. **Run tests or scripts**: You can run commands inside the environment using `uv run`:
67
+
68
+
69
+ ```Bash
70
+ # Run the test suite
71
+ uv run pytest
72
+
73
+
74
+ # Run a script
75
+ uv run python examples/my_script.py
76
+ ```
77
+
78
+ ### Option B: Using Conda (Legacy)
79
+ If you prefer managing your own environments with Conda, you can install the package in "editable" mode using standard pip.
80
+
81
+ 1. Clone the repository:
82
+
83
+ ```Bash
84
+ git clone https://github.com/npapnet/py_windblade_opa.git
85
+ cd py_windblade_opa
86
+ ```
87
+
88
+ 2. Create and activate your Conda environment:
89
+
90
+ ```Bash
91
+ conda create -n windblade python=3.13
92
+ conda activate windblade
93
+ ```
94
+
95
+ Install in editable mode: Note: You must use the [dev] flag to get testing tools like pytest and ruff.
96
+
97
+ ```Bash
98
+ pip install -e .[dev]
99
+ ```
100
+
101
+ Verify Installation
102
+ To confirm everything is working, run the following command (works for both methods):
103
+
104
+ ```cmd
105
+ python -c "import py_windblade_opa; print(f'Successfully installed version {py_windblade_opa.__version__}')"
106
+ ```
107
+
108
+ ## Usage
109
+
110
+ The package is still under development. The following is an example of how to use the package:
111
+
112
+ ```python
113
+ import py_windblade_opa as wbo
114
+
115
+ power = 1000
116
+ Cp = 0.45
117
+ n_elec = 0.95
118
+ v_nom = 10
119
+ reqs = Reqs(power_w=power, n_elec=n_elec, v_nom=v_nom, Cp=Cp)
120
+
121
+ constants = .wbo.Constants()
122
+ config = wbo.Config(lambda0=4.8, no_blades=3, pitch=0)
123
+ r_m = wbo.reqs.estimate_blade_r()
124
+ blade = wbo.Blade(r_m=r_m, wt_config=config)
125
+ blade_calc = wbo.BladeCalc(blade=blade)
126
+
127
+ blade.main_calculation()
128
+ blade_calc.calculate_i_flow(verbosePlot=False)
129
+ blade_calc.step3_eleven_coeffs(verbosePlot=False)
130
+ blade_calc.step4_coeffs_collection()
131
+ blade_calc.step5_rpm_power(verbosePlot=False)
132
+ blade_calc.step6_torque_calcs(verbosePlot=True)
133
+
134
+ plt.show()
135
+ ```
@@ -0,0 +1,108 @@
1
+ # py_windblade_opa
2
+
3
+ A python package for Windblade Optimization and Performance Assessment
4
+
5
+ Author: [N. Papadakis](https://github.com/npapnet).
6
+
7
+ ## Scope
8
+
9
+ This package is intended to provide a set of tools for the optimization and performance assessment of wind turbine blades.
10
+
11
+ ## Installation
12
+
13
+ ## For Users
14
+ If you just want to use py_windblade_opa in your own projects, install the latest stable version from PyPI:
15
+
16
+ > pip install py-windblade-opa
17
+
18
+ ## For Developers and Contributors
19
+
20
+ We offer two ways to set up the development environment. We strongly recommend using uv (the modern method) as it guarantees you are using the exact same dependencies and Python version as the maintainers.
21
+
22
+ ### Option A: Using uv (Recommended)
23
+
24
+ This method automatically handles Python version management and dependency locking.
25
+
26
+ 1. **Clone the repository**:
27
+
28
+ ```bash
29
+ git clone https://github.com/npapnet/py_windblade_opa.git
30
+ cd py_windblade_opa
31
+ ```
32
+
33
+ 2. **Sync the environment**: This command creates the virtual environment, installs the specific Python version required, and sets up the package in editable mode, installing also all the development dependencies.
34
+
35
+ ```Bash
36
+ uv sync --extra dev
37
+ ```
38
+
39
+ 3. **Run tests or scripts**: You can run commands inside the environment using `uv run`:
40
+
41
+
42
+ ```Bash
43
+ # Run the test suite
44
+ uv run pytest
45
+
46
+
47
+ # Run a script
48
+ uv run python examples/my_script.py
49
+ ```
50
+
51
+ ### Option B: Using Conda (Legacy)
52
+ If you prefer managing your own environments with Conda, you can install the package in "editable" mode using standard pip.
53
+
54
+ 1. Clone the repository:
55
+
56
+ ```Bash
57
+ git clone https://github.com/npapnet/py_windblade_opa.git
58
+ cd py_windblade_opa
59
+ ```
60
+
61
+ 2. Create and activate your Conda environment:
62
+
63
+ ```Bash
64
+ conda create -n windblade python=3.13
65
+ conda activate windblade
66
+ ```
67
+
68
+ Install in editable mode: Note: You must use the [dev] flag to get testing tools like pytest and ruff.
69
+
70
+ ```Bash
71
+ pip install -e .[dev]
72
+ ```
73
+
74
+ Verify Installation
75
+ To confirm everything is working, run the following command (works for both methods):
76
+
77
+ ```cmd
78
+ python -c "import py_windblade_opa; print(f'Successfully installed version {py_windblade_opa.__version__}')"
79
+ ```
80
+
81
+ ## Usage
82
+
83
+ The package is still under development. The following is an example of how to use the package:
84
+
85
+ ```python
86
+ import py_windblade_opa as wbo
87
+
88
+ power = 1000
89
+ Cp = 0.45
90
+ n_elec = 0.95
91
+ v_nom = 10
92
+ reqs = Reqs(power_w=power, n_elec=n_elec, v_nom=v_nom, Cp=Cp)
93
+
94
+ constants = .wbo.Constants()
95
+ config = wbo.Config(lambda0=4.8, no_blades=3, pitch=0)
96
+ r_m = wbo.reqs.estimate_blade_r()
97
+ blade = wbo.Blade(r_m=r_m, wt_config=config)
98
+ blade_calc = wbo.BladeCalc(blade=blade)
99
+
100
+ blade.main_calculation()
101
+ blade_calc.calculate_i_flow(verbosePlot=False)
102
+ blade_calc.step3_eleven_coeffs(verbosePlot=False)
103
+ blade_calc.step4_coeffs_collection()
104
+ blade_calc.step5_rpm_power(verbosePlot=False)
105
+ blade_calc.step6_torque_calcs(verbosePlot=True)
106
+
107
+ plt.show()
108
+ ```
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,79 @@
1
+ # Design Vision
2
+
3
+ - I am inclined to move away from delegating to the engine the job of getting the
4
+ power curve. As this project pans out it makes more sense to have an overall object
5
+ that **HAS-A** geometry, an engine that consumes that geometry, and a post-processor
6
+ that consumes the output from the engine's contract. That will require reworking the
7
+ examples, so it might make sense to delegate that elsewhere. Develop contracts for
8
+ the geometry, engine, and post-processor.
9
+ - The current architecture, contracts, and the rule that **pitch and airfoil are not
10
+ part of geometry** are written up in [architecture.md](architecture.md). Keep it
11
+ current.
12
+
13
+ # Roadmap
14
+
15
+ **New session? Start with
16
+ [next_refactor/IMPLEMENTATION-STATUS.md](next_refactor/IMPLEMENTATION-STATUS.md)**
17
+ (status, house rules, decision log). Full rationale: [architecture.md](architecture.md)
18
+ §6. Four staged plans, 0.6.5 → 0.10.0:
19
+
20
+ - **Stage 2** — geometry V2 + pitch decoupling →
21
+ [next_refactor/Stage2-AddingGeometryV2.md](next_refactor/Stage2-AddingGeometryV2.md)
22
+ - **Stage 3** — airfoil abstraction (`AirfoilPolar` / `AirfoilProvider`; single +
23
+ family + custom data) →
24
+ [next_refactor/Stage3-AirfoilProvider.md](next_refactor/Stage3-AirfoilProvider.md)
25
+ - **Stage 4** — `Blade`/`Rotor` assembly + declarative definition →
26
+ [next_refactor/Stage4-RotorAssembly.md](next_refactor/Stage4-RotorAssembly.md)
27
+ - **Stage 5 / future** — top-level analysis object.
28
+
29
+ # Tasks
30
+
31
+ [x] Create an architecture.md describing the overall architecture → `design/architecture.md`.
32
+
33
+ [ ] **Stage 2** — geometry unification + pitch/airfoil decoupling (see doc; 0.6.5 → 0.8.0):
34
+ [ ] `BladeGeometryContainer` accepts scalar / `None` tcratio + extrapolating interpolators (`fix` 0.6.6).
35
+ [ ] Remove `pitch_deg` from geometry; designer twist is pitch-free; pitch applied once at the engine (`fix` 0.6.6).
36
+ [ ] `WELBladeDesigner.main_calculation()` returns `BladeGeometrySpec` with `to_v1()` / `to_v2()` (`feat` 0.6.7).
37
+ [ ] D1: add `NACA4415poly` (poly-sampled table), delete `NACAtest`; DEOL airfoil re-baseline on V1 (breaking minor 0.7.0).
38
+ [ ] D2: DEOL `BladeCalcOrchestrator` consumes V2 geometry; airfoil a separate (single) arg; `delta_r`/`np.trapz` grid re-baseline (breaking minor 0.8.0).
39
+ [ ] Update deol tests, fixtures, examples, docs.
40
+
41
+
42
+
43
+ [ ] **Stage 3** — airfoil abstraction (see doc; 0.8.0 → 0.9.0):
44
+ [ ] R1 `feat` 0.8.1 — `AirfoilPolar` + `AirfoilProvider` + `UniformAirfoil` + `ThicknessInterpolatedFamily` + custom-data loaders (CSV/arrays/df/files); equivalence-gated vs `NACA4415` / `NACA4415poly` / `AeroCoefficientInterpolator`.
45
+ [ ] R2 `feat` 0.8.2 — engines + designer consume the provider; `t/c`→fraction normalization (BEM Cp–λ unchanged); WEL schedule isolated; DEOL family path enabled.
46
+ [ ] R3 minor 0.9.0 — retire V1 `BladeGeometry` (value-neutral, breaking API).
47
+
48
+ [ ] **Stage 4** — Blade/Rotor assembly + declarative definition (see doc; 0.9.0 → 0.10.0):
49
+ [ ] R1 `feat` 0.9.1 — `Blade`, `Rotor`, `OperatingPoint` (additive) + `Rotor.from_definition`/`to_definition` schema; `from_dtu`/`from_json` become adapters.
50
+ [ ] R2 minor 0.10.0 — engines adopt `analyze(rotor, op)`; `B`/set-pitch relocated to `Rotor`; geometry becomes single-blade; values unchanged vs 0.9.0.
51
+ [x] Naming review: `Blade` kept (decided 2026-06-19). `Rotor`/`OperatingPoint` names still open for Stage 4.
52
+
53
+ [ ] **Stage 5 / Future** — top-level analysis object (`RotorAnalysis`, name TBD) that
54
+ HAS-A {rotor, engine, post-processor}; reworks examples to one high-level API.
55
+ Formalize the GeometryProvider / AirfoilProvider / Engine→PerformanceCurve contracts.
56
+
57
+ # Chores
58
+
59
+ # Agent behaviour
60
+
61
+ - [x] make sure that the agent **recommends** freely a rename of the classes when a clearer name is available, and that it **does not** freely rename. The agent should be able to explain why a rename is recommended or not. *(Recorded as policy in architecture.md §7.)*
62
+
63
+ # REVISIT
64
+
65
+ [ ] **REVISIT (post Stage 2): fixed assembly-time pitch in `WELBladeDesigner`.**
66
+ Phase B made the designer twist pitch-free and moved pitch to a *runtime* engine
67
+ condition (removing the DEOL double-count). But `WELBladeDesigner` was intended for
68
+ **fixed-pitch blades**, where a `pitch` argument is meaningful: a fixed build/mounting
69
+ pitch baked into the *manufactured* twist, so `bl_a_i = bl_IiFlow - bl_ir - pitch` is
70
+ the as-built installed twist. The original term is preserved (commented, with a term
71
+ explanation) at `wel_blade_designer.py` `bl_a_i`. Decide later whether the designer
72
+ should expose an explicit *assembly-time* pitch (distinct from the engine's runtime
73
+ pitch) — likely settles alongside Stage 4 `Rotor`/`OperatingPoint` (where pitch lives).
74
+ Raised by N. Papadakis 2026-06-20.
75
+
76
+ # Private notes — (agent: do not modify this section and below without explicit instruction)
77
+
78
+ - scrub abandoned contracts, classes, and methods from the documents. e.g. cl_approx or cl_model in the airfoil context, after verifying the abandoment.
79
+ - consolidate the design notes to remove duplication, redudancy, and outdated information. Ensure that the design notes reflect the current architecture and decisions made. check numbering consistency, etc.