Skip to content

Commit e46b9ad

Browse files
authored
Merge pull request #2719 from rafmudaf/python_upgrades
Python infrastructure improvements
2 parents ec32088 + b115641 commit e46b9ad

File tree

15 files changed

+199
-82
lines changed

15 files changed

+199
-82
lines changed

.github/workflows/automated-dev-tests.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ jobs:
5050
- name: Install dependencies
5151
run: |
5252
pip install -r requirements.txt
53+
pip install glue-codes/python/. # Installs the interface library
5354
sudo apt-get update -y
5455
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
5556
- name: Setup workspace
@@ -347,6 +348,7 @@ jobs:
347348
- name: Install dependencies
348349
run: |
349350
pip install -r requirements.txt
351+
pip install glue-codes/python/. # Installs the interface library
350352
sudo apt-get update -y
351353
sudo apt-get install -y libopenblas-dev
352354
- name: Setup workspace
@@ -406,6 +408,7 @@ jobs:
406408
- name: Install dependencies
407409
run: |
408410
pip install -r requirements.txt
411+
pip install glue-codes/python/. # Installs the interface library
409412
sudo apt-get update -y
410413
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
411414
sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev
@@ -462,6 +465,7 @@ jobs:
462465
- name: Install dependencies
463466
run: |
464467
pip install -r requirements.txt
468+
pip install glue-codes/python/. # Installs the interface library
465469
sudo apt-get update -y
466470
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
467471
sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev
@@ -521,6 +525,7 @@ jobs:
521525
- name: Install dependencies
522526
run: |
523527
pip install -r requirements.txt
528+
pip install glue-codes/python/. # Installs the interface library
524529
sudo apt-get update -y
525530
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
526531
sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev
@@ -568,6 +573,7 @@ jobs:
568573
- name: Install dependencies
569574
run: |
570575
pip install -r requirements.txt
576+
pip install glue-codes/python/. # Installs the interface library
571577
sudo apt-get update -y
572578
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
573579
sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev
@@ -618,6 +624,7 @@ jobs:
618624
- name: Install dependencies
619625
run: |
620626
pip install -r requirements.txt
627+
pip install glue-codes/python/. # Installs the interface library
621628
sudo apt-get update -y
622629
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
623630
sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev
@@ -696,6 +703,7 @@ jobs:
696703
- name: Install dependencies
697704
run: |
698705
python -m pip install --upgrade pip
706+
pip install glue-codes/python/. # Installs the interface library
699707
pip install numpy "Bokeh>=2.4,!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3"
700708
sudo apt-get update -y
701709
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
@@ -744,6 +752,7 @@ jobs:
744752
- name: Install dependencies
745753
run: |
746754
pip install -r requirements.txt
755+
pip install glue-codes/python/. # Installs the interface library
747756
sudo apt-get update -y
748757
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
749758
sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev
@@ -792,6 +801,7 @@ jobs:
792801
- name: Install dependencies
793802
run: |
794803
pip install -r requirements.txt
804+
pip install glue-codes/python/. # Installs the interface library
795805
sudo apt-get update -y
796806
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
797807
sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev
@@ -840,6 +850,7 @@ jobs:
840850
- name: Install dependencies
841851
run: |
842852
pip install -r requirements.txt
853+
pip install glue-codes/python/. # Installs the interface library
843854
sudo apt-get update -y
844855
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
845856
sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev
@@ -888,6 +899,7 @@ jobs:
888899
- name: Install dependencies
889900
run: |
890901
pip install -r requirements.txt
902+
pip install glue-codes/python/. # Installs the interface library
891903
sudo apt-get update -y
892904
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
893905
sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev
@@ -936,6 +948,7 @@ jobs:
936948
- name: Install dependencies
937949
run: |
938950
pip install -r requirements.txt
951+
pip install glue-codes/python/. # Installs the interface library
939952
sudo apt-get update -y
940953
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
941954
sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev
@@ -984,6 +997,7 @@ jobs:
984997
- name: Install dependencies
985998
run: |
986999
pip install -r requirements.txt
1000+
pip install glue-codes/python/. # Installs the interface library
9871001
sudo apt-get update -y
9881002
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
9891003
sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev
@@ -1031,6 +1045,7 @@ jobs:
10311045
- name: Install dependencies
10321046
run: |
10331047
pip install -r requirements.txt
1048+
pip install glue-codes/python/. # Installs the interface library
10341049
sudo apt-get update -y
10351050
sudo apt-get install -y libopenblas-dev libopenblas-openmp-dev
10361051
sudo apt-get install -y libhdf5-dev libnetcdf-dev libopenmpi-dev libyaml-cpp-dev

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
*.app
3030
__pycache__/*
3131
*.pyc
32+
*.egg-info
3233

3334
# Build specific files
3435
build*/

glue-codes/python/OpenFAST.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11

2-
import openfast_library
2+
from pyOpenFAST import fast
33

4-
project_root = '/Users/rmudafor/Development/weis'
4+
project_root = '/Users/rmudafor/Development/openfast'
55
library_path = project_root + '/build/modules/openfast-library/libopenfastlib.dylib'
66

77
def serial(input_file):
88
input_file_name = input_file # "/Users/rmudafor/Development/weis/reg_tests/r-test/glue-codes/openfast/AOC_YFix_WSt/AOC_YFix_WSt.fst"
9-
openfastlib = openfast_library.FastLibAPI(library_path, input_file_name)
10-
openfastlib.fast_run()
9+
fastlib = fast.FastLibAPI(library_path, input_file_name)
10+
fastlib.run()
1111

1212
# Display the outputs
13-
# for i, c in enumerate(openfastlib.output_channel_names):
13+
# for i, c in enumerate(fastlib.output_channel_names):
1414
# print(i, c)
15-
# print(openfastlib.output_channel_names)
16-
# print(openfastlib.output_values)
17-
# print(openfastlib.output_values[:,0]) # Prints the time steps
15+
# print(fastlib.output_channel_names)
16+
# print(fastlib.output_values)
17+
# print(fastlib.output_values[:,0]) # Prints the time steps
1818

1919
def parallel():
2020
## Parallel with MPI
@@ -24,25 +24,26 @@ def parallel():
2424

2525
if rank == 0:
2626
input_file_name = "{}/reg_tests/r-test/glue-codes/openfast/AOC_WSt/AOC_WSt.fst".format(project_root)
27-
openfastlib = openfast_library.FastLibAPI(library_path, input_file_name)
28-
openfastlib.fast_run()
27+
fastlib = fast.FastLibAPI(library_path, input_file_name)
28+
fastlib.run()
2929
elif rank == 1:
3030
input_file_name = "{}/reg_tests/r-test/glue-codes/openfast/AOC_YFix_WSt/AOC_YFix_WSt.fst".format(project_root)
31-
openfastlib = openfast_library.FastLibAPI(library_path, input_file_name)
32-
openfastlib.fast_run()
31+
fastlib = fast.FastLibAPI(library_path, input_file_name)
32+
fastlib.run()
3333
elif rank == 2:
3434
input_file_name = "{}/reg_tests/r-test/glue-codes/openfast/AOC_YFree_WTurb/AOC_YFree_WTurb.fst".format(project_root)
35-
openfastlib = openfast_library.FastLibAPI(library_path, input_file_name)
36-
openfastlib.fast_run()
35+
fastlib = fast.FastLibAPI(library_path, input_file_name)
36+
fastlib.run()
3737
elif rank == 3:
3838
input_file_name = "{}/reg_tests/r-test/glue-codes/openfast/AWT_YFix_WSt/AWT_YFix_WSt.fst".format(project_root)
39-
openfastlib = openfast_library.FastLibAPI(library_path, input_file_name)
40-
openfastlib.fast_run()
39+
fastlib = fast.FastLibAPI(library_path, input_file_name)
40+
fastlib.run()
4141

4242
if __name__=="__main__":
4343
import sys
4444
if len(sys.argv) > 1:
4545
input_file = sys.argv[1]
4646
serial(input_file)
47+
# parallel()
4748
else:
4849
print("No cases run. Check the driver code.")

glue-codes/python/pyOpenFAST/__init__.py

Whitespace-only changes.
File renamed without changes.
Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
12
from ctypes import (
2-
CDLL,
33
POINTER,
44
create_string_buffer,
55
byref,
@@ -9,22 +9,24 @@
99
c_char,
1010
c_bool
1111
)
12-
import os
1312
from typing import List, Tuple
1413
import numpy as np
1514
import math
15+
from pathlib import Path
16+
17+
from .interface_abc import OpenFASTInterfaceType
1618

1719

1820
IntfStrLen = 1025 # FAST_Library global
1921
NumFixedInputs = 51 # FAST_Library global
2022

2123

22-
class FastLibAPI(CDLL):
24+
class FastLibAPI(OpenFASTInterfaceType):
2325

2426
def __init__(self, library_path: str, input_file_name: str):
2527
super().__init__(library_path)
26-
self.library_path = library_path
27-
self.input_file_name = create_string_buffer(os.path.abspath(input_file_name).encode('utf-8'))
28+
29+
self.input_file_name = create_string_buffer(str(Path(input_file_name).absolute()).encode('utf-8'))
2830

2931
self._initialize_routines()
3032

@@ -34,7 +36,7 @@ def __init__(self, library_path: str, input_file_name: str):
3436
self.dt = c_double(0.0)
3537
self.dt_out = c_double(0.0)
3638
self.t_max = c_double(0.0)
37-
self.abort_error_level = c_int(4) # Initialize to 4 (ErrID_Fatal) and reset to user-given value in FAST_Sizes
39+
# self.abort_error_level = c_int(4) # Initialize to 4 (ErrID_Fatal) and reset to user-given value in FAST_Sizes
3840
self.end_early = c_bool(False)
3941
self.num_outs = c_int(0)
4042
self.output_channel_names = []
@@ -123,11 +125,7 @@ def _initialize_routines(self) -> None:
123125
self.FAST_HubPosition.restype = c_int
124126

125127

126-
def fatal_error(self, error_status) -> bool:
127-
return error_status.value >= self.abort_error_level.value
128-
129-
130-
def fast_init(self) -> None:
128+
def init(self) -> None:
131129
_error_status = c_int(0)
132130
_error_message = create_string_buffer(IntfStrLen)
133131

@@ -172,7 +170,7 @@ def fast_init(self) -> None:
172170
del _error_message
173171
del channel_names
174172

175-
def fast_sim(self) -> None:
173+
def sim(self) -> None:
176174
_error_status = c_int(0)
177175
_error_message = create_string_buffer(IntfStrLen)
178176

@@ -186,7 +184,7 @@ def fast_sim(self) -> None:
186184
_error_message
187185
)
188186
if self.fatal_error(_error_status):
189-
self.fast_deinit()
187+
self.deinit()
190188
raise RuntimeError(f"Error {_error_status.value}: {_error_message.value}")
191189

192190
# Calculate output frequency and initialize output index
@@ -207,13 +205,13 @@ def fast_sim(self) -> None:
207205
if i%output_frequency == 0:
208206
i_out += 1
209207
if self.fatal_error(_error_status):
210-
self.fast_deinit()
208+
self.deinit()
211209
raise RuntimeError(f"Error {_error_status.value}: {_error_message.value}")
212210
if self.end_early:
213211
break
214212

215213

216-
def fast_deinit(self) -> None:
214+
def deinit(self) -> None:
217215
_error_status = c_int(0)
218216
_error_message = create_string_buffer(IntfStrLen)
219217

@@ -236,26 +234,26 @@ def fast_deinit(self) -> None:
236234
raise RuntimeError(f"Error {_error_status.value}: {_error_message.value}")
237235

238236

239-
def fast_run(self) -> None:
240-
self.fast_init()
241-
self.fast_sim()
242-
self.fast_deinit()
243-
244-
245-
@property
246-
def total_time_steps(self) -> int:
247-
# From FAST_Subs FAST_Init:
248-
# p%n_TMax_m1 = CEILING( ( (p%TMax - t_initial) / p%DT ) ) - 1 ! We're going to go from step 0 to n_TMax (thus the -1 here)
249-
# Then in FAST_Prog:
250-
# TIME_STEP_LOOP: DO n_t_global = Restart_step, Turbine(1)%p_FAST%n_TMax_m1
251-
#
252-
# Note that Fortran indexing starts at 1 and includes the upper bound
253-
# Python indexing starts at 0 and does not include the upper bound
254-
# The for-loop in this interface begins at 1 (there's an init step before)
255-
# and that's why we have the +1 below
256-
#
257-
# We assume here t_initial is always 0
258-
return math.ceil( self.t_max.value / self.dt.value) + 1
237+
def run(self) -> None:
238+
self.init()
239+
self.sim()
240+
self.deinit()
241+
242+
243+
# @property
244+
# def total_time_steps(self) -> int:
245+
# # From FAST_Subs FAST_Init:
246+
# # p%n_TMax_m1 = CEILING( ( (p%TMax - t_initial) / p%DT ) ) - 1 ! We're going to go from step 0 to n_TMax (thus the -1 here)
247+
# # Then in FAST_Prog:
248+
# # TIME_STEP_LOOP: DO n_t_global = Restart_step, Turbine(1)%p_FAST%n_TMax_m1
249+
# #
250+
# # Note that Fortran indexing starts at 1 and includes the upper bound
251+
# # Python indexing starts at 0 and does not include the upper bound
252+
# # The for-loop in this interface begins at 1 (there's an init step before)
253+
# # and that's why we have the +1 below
254+
# #
255+
# # We assume here t_initial is always 0
256+
# return math.ceil( self.t_max.value / self.dt.value) + 1
259257

260258

261259
@property
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)