-
Notifications
You must be signed in to change notification settings - Fork 97
/
Copy path23_structural_control.py
109 lines (89 loc) · 3.61 KB
/
23_structural_control.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
"""
23_structural_control
---------------------
Run openfast with ROSCO and structural control
Set up and run simulation with pitch offsets, check outputs
ROSCO currently supports user-defined hooks for structural control control actuation, if StC\_Mode = 1.
The control logic can be determined in Controllers.f90 with the StructrualControl subroutine.
In the DISCON input, users must specify StC\_GroupIndex relating to the control ChannelID.
These indices can be found in the ServoDyn summary file (\*SrvD.sum)
In the example below, we implement a smooth step change mimicing the exchange of ballast from the
upwind column to the down wind columns
OpenFAST v3.5.0 is required to run this example
"""
import os
from rosco.toolbox.ofTools.case_gen.run_FAST import run_FAST_ROSCO
from rosco.toolbox.ofTools.case_gen import CaseLibrary as cl
#import numpy as np
from rosco.toolbox.ofTools.fast_io.FAST_reader import InputReader_OpenFAST
from rosco.toolbox.inputs.validation import load_rosco_yaml
from rosco.toolbox.controller import OpenLoopControl
def main():
#directories
this_dir = os.path.dirname(os.path.abspath(__file__))
rosco_dir = os.path.dirname(this_dir)
example_out_dir = os.path.join(this_dir,'examples_out')
os.makedirs(example_out_dir,exist_ok=True)
# Input yaml and output directory
parameter_filename = os.path.join(this_dir,'Tune_Cases/IEA15MW_ballast.yaml')
run_dir = os.path.join(example_out_dir,'23_structural_control')
os.makedirs(run_dir,exist_ok=True)
# Read initial input file
inps = load_rosco_yaml(parameter_filename)
path_params = inps['path_params']
# Change inputs programatically, read first
reader = InputReader_OpenFAST()
reader.FAST_InputFile = path_params['FAST_InputFile']
reader.FAST_directory = os.path.join(this_dir,'Tune_Cases',path_params['FAST_directory'])
# reader.FAST_directory = '/Users/dzalkind/Tools/ROSCO1/Test_Cases/ptfm_control_archive/IEA-15-240-RWT-UMaineSemi_ballast'
reader.execute()
reader.fst_vt['ServoDyn']['NumSStC'] = 3
reader.fst_vt['ServoDyn']['SStCfiles'] = ['StC-Force-Col1.dat', 'StC-Force-Col2.dat', 'StC-Force-Col3.dat']
# Add SStC file inputs
for StC_file in reader.fst_vt['ServoDyn']['SStCfiles']:
reader.fst_vt['SStC'].append(reader.read_StC(StC_file))
# Set up open loop inputs to ROSCO
t_trans = 60
t_sigma = 80
t_max = 200
applied_force = [-2e6, 1e6, 1e6]
olc = OpenLoopControl(t_max=t_max)
olc.interp_timeseries(
'struct_control_1',
[0,t_trans,t_trans+t_sigma],
[0,0,applied_force[0]] ,
'sigma'
)
olc.interp_timeseries(
'struct_control_2',
[0,t_trans,t_trans+t_sigma],
[0,0,applied_force[1]] ,
'sigma'
)
olc.interp_timeseries(
'struct_control_3',
[0,t_trans,t_trans+t_sigma],
[0,0,applied_force[2]] ,
'sigma'
)
ol_params = olc.write_input(os.path.join(run_dir,'open_loop_ballast.dat'))
controller_params = {}
controller_params['open_loop'] = ol_params
controller_params['StC_Mode'] = 2
# simulation set up
r = run_FAST_ROSCO()
r.tuning_yaml = parameter_filename
r.wind_case_fcn = cl.simp_step # single step wind input
r.wind_case_fcn = cl.power_curve
r.wind_case_opts = {
'U': [9],
'TMax': t_max,
}
r.case_inputs = {}
r.fst_vt = reader.fst_vt
r.save_dir = run_dir
r.rosco_dir = rosco_dir
r.controller_params = controller_params
r.run_FAST()
if __name__=="__main__":
main()