• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

WISDEM / WEIS / 10927734534

18 Sep 2024 06:09PM UTC coverage: 79.235% (-0.4%) from 79.668%
10927734534

Pull #315

github

web-flow
Merge 397ba5241 into f779fa594
Pull Request #315: WEIS 1.3.1

21 of 180 new or added lines in 4 files covered. (11.67%)

8 existing lines in 4 files now uncovered.

21647 of 27320 relevant lines covered (79.23%)

0.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.31
/weis/glue_code/glue_code.py
1
import numpy as np
1✔
2
import os
1✔
3
import openmdao.api as om
1✔
4
from wisdem.glue_code.glue_code import WindPark as wisdemPark
1✔
5
#from wisdem.glue_code.gc_WT_DataStruc import WindTurbineOntologyOpenMDAO
6
#from wisdem.ccblade.ccblade_component import CCBladeTwist
7
#from wisdem.commonse.turbine_class import TurbineClass
8
from wisdem.drivetrainse.drivetrain import DrivetrainSE
1✔
9
from wisdem.commonse.cylinder_member import CylinderPostFrame
1✔
10
#from wisdem.nrelcsm.nrel_csm_cost_2015 import Turbine_CostsSE_2015
11
#from wisdem.orbit.api.wisdem.fixed import Orbit
12
#from wisdem.landbosse.landbosse_omdao.landbosse import LandBOSSE
13
from wisdem.plant_financese.plant_finance import PlantFinance
1✔
14
from wisdem.commonse.turbine_constraints  import TurbineConstraints
1✔
15
from weis.aeroelasticse.openmdao_openfast import FASTLoadCases
1✔
16
from weis.control.dac import RunXFOIL
1✔
17
from wisdem.rotorse.rotor_power import NoStallConstraint
1✔
18
from weis.control.tune_rosco import ServoSE_ROSCO, ROSCO_Turbine
1✔
19
#from wisdem.rotorse.rotor_elasticity import RotorElasticity
20
from weis.aeroelasticse.utils import RotorLoadsDeflStrainsWEIS
1✔
21
from wisdem.glue_code.gc_RunTools import Convergence_Trends_Opt
1✔
22
from weis.glue_code.gc_RunTools import Outputs_2_Screen
1✔
23
from weis.frequency.raft_wrapper import RAFT_WEIS
1✔
24
from weis.control.tmd import TMD_group
1✔
25
from rosco.toolbox.inputs.validation import load_rosco_yaml
1✔
26
from wisdem.inputs import load_yaml
1✔
27
from wisdem.commonse.cylinder_member import get_nfull
1✔
28

29

30
weis_dir = os.path.realpath(os.path.join(os.path.dirname(__file__),'../../'))
1✔
31

32
class WindPark(om.Group):
1✔
33
    # Openmdao group to run the analysis of the wind turbine
34

35
    def initialize(self):
1✔
36
        self.options.declare('modeling_options')
1✔
37
        self.options.declare('opt_options')
1✔
38

39
    def setup(self):
1✔
40
        modeling_options = self.options['modeling_options']
1✔
41
        opt_options      = self.options['opt_options']
1✔
42

43
        #self.linear_solver = lbgs = om.LinearBlockGS()
44
        #self.nonlinear_solver = nlbgs = om.NonlinearBlockGS()
45
        #nlbgs.options['maxiter'] = 2
46
        #nlbgs.options['atol'] = nlbgs.options['atol'] = 1e-2
47

48
        dac_ivc = om.IndepVarComp()
1✔
49
        n_te_flaps = modeling_options['WISDEM']['RotorSE']['n_te_flaps']
1✔
50
        dac_ivc.add_output('te_flap_ext',   val = np.ones(n_te_flaps))
1✔
51
        dac_ivc.add_output('te_flap_start', val=np.zeros(n_te_flaps),               desc='1D array of the start positions along blade span of the trailing edge flap(s). Only values between 0 and 1 are meaningful.')
1✔
52
        dac_ivc.add_output('te_flap_end',   val=np.zeros(n_te_flaps),               desc='1D array of the end positions along blade span of the trailing edge flap(s). Only values between 0 and 1 are meaningful.')
1✔
53
        dac_ivc.add_output('chord_start',   val=np.zeros(n_te_flaps),               desc='1D array of the positions along chord where the trailing edge flap(s) start. Only values between 0 and 1 are meaningful.')
1✔
54
        dac_ivc.add_output('delta_max_pos', val=np.zeros(n_te_flaps), units='rad',  desc='1D array of the max angle of the trailing edge flaps.')
1✔
55
        dac_ivc.add_output('delta_max_neg', val=np.zeros(n_te_flaps), units='rad',  desc='1D array of the min angle of the trailing edge flaps.')
1✔
56
        self.add_subsystem('dac_ivc',dac_ivc)
1✔
57

58
        # ROSCO tuning parameters
59
        # Apply tuning yaml input if available, this needs to be here for sizing tune_rosco_ivc
60
        if os.path.split(modeling_options['ROSCO']['tuning_yaml'])[1] != 'none':  # default is none
1✔
61
            inps = load_rosco_yaml(modeling_options['ROSCO']['tuning_yaml'])  # tuning yaml validated in here
1✔
62
            modeling_options['ROSCO'].update(inps['controller_params'])
1✔
63

64
            # Apply changes in modeling options, should have already been validated
65
            modopts_no_defaults = load_yaml(modeling_options['fname_input_modeling'])  
1✔
66
            skip_options = ['tuning_yaml']  # Options to skip loading, tuning_yaml path has been updated, don't overwrite
1✔
67
            for option, value in modopts_no_defaults['ROSCO'].items():
1✔
68
                if option not in skip_options:
1✔
69
                    modeling_options['ROSCO'][option] = value
1✔
70

71

72
        tune_rosco_ivc = om.IndepVarComp()
1✔
73
        if modeling_options['ROSCO']['linmodel_tuning']['type'] == 'robust':
1✔
74
            n_PC = 1
×
75
        else:
76
            n_PC = len(modeling_options['ROSCO']['U_pc'])
1✔
77
        tune_rosco_ivc.add_output('omega_pc',         val=np.zeros(n_PC), units='rad/s',     desc='Pitch controller natural frequency')
1✔
78
        tune_rosco_ivc.add_output('zeta_pc',          val=np.zeros(n_PC),                    desc='Pitch controller damping ratio')
1✔
79
        tune_rosco_ivc.add_output('omega_vs',         val=0.0, units='rad/s',     desc='Generator torque controller natural frequency')
1✔
80
        tune_rosco_ivc.add_output('zeta_vs',          val=0.0,                    desc='Generator torque controller damping ratio')
1✔
81
        tune_rosco_ivc.add_output('flp_kp_norm',      val=0.0,                    desc='Flap controller normalized gain')
1✔
82
        tune_rosco_ivc.add_output('flp_tau',          val=0.0, units='s',         desc='Flap controller integral gain time constant')
1✔
83
        tune_rosco_ivc.add_output('IPC_Kp1p',         val=0.0, units='s',         desc='Individual pitch controller 1p proportional gain')
1✔
84
        tune_rosco_ivc.add_output('IPC_Ki1p',         val=0.0,                    desc='Individual pitch controller 1p integral gain')
1✔
85
        tune_rosco_ivc.add_output('stability_margin', val=0.0,                    desc='Stability margin for robust tuning')
1✔
86
        tune_rosco_ivc.add_output('omega_pc_max',     val=0.0,                    desc='Maximum allowable omega for robust tuning')
1✔
87
        # optional inputs - not connected right now!!
88
        tune_rosco_ivc.add_output('max_pitch',        val=0.0, units='rad',       desc='Maximum pitch angle , {default = 90 degrees}')
1✔
89
        tune_rosco_ivc.add_output('min_pitch',        val=0.0, units='rad',       desc='Minimum pitch angle [rad], {default = 0 degrees}')
1✔
90
        tune_rosco_ivc.add_output('vs_minspd',        val=0.0, units='rad/s',     desc='Minimum rotor speed [rad/s], {default = 0 rad/s}')
1✔
91
        tune_rosco_ivc.add_output('ss_cornerfreq',    val=0.0, units='rad/s',     desc='First order low-pass filter cornering frequency for setpoint smoother [rad/s]')
1✔
92
        tune_rosco_ivc.add_output('ss_vsgain',        val=0.0,                    desc='Torque controller setpoint smoother gain bias percentage [%, <= 1 ], {default = 100%}')
1✔
93
        tune_rosco_ivc.add_output('ss_pcgain',        val=0.0,                    desc='Pitch controller setpoint smoother gain bias percentage  [%, <= 1 ], {default = 0.1%}')
1✔
94
        tune_rosco_ivc.add_output('ps_percent',       val=0.0,                    desc='Percent peak shaving  [%, <= 1 ], {default = 80%}')
1✔
95
        tune_rosco_ivc.add_output('sd_maxpit',        val=0.0, units='rad',       desc='Maximum blade pitch angle to initiate shutdown [rad], {default = bld pitch at v_max}')
1✔
96
        tune_rosco_ivc.add_output('sd_cornerfreq',    val=0.0, units='rad/s',     desc='Cutoff Frequency for first order low-pass filter for blade pitch angle [rad/s], {default = 0.41888 ~ time constant of 15s}')
1✔
97
        tune_rosco_ivc.add_output('Kp_flap',          val=0.0, units='s',         desc='Proportional term of the PI controller for the trailing-edge flaps')
1✔
98
        tune_rosco_ivc.add_output('Ki_flap',          val=0.0,                    desc='Integral term of the PI controller for the trailing-edge flaps')
1✔
99
        tune_rosco_ivc.add_output('twr_freq',         val=3.2, units='rps',     desc='Tower natural frequency')
1✔
100
        tune_rosco_ivc.add_output('ptfm_freq',        val=0.2, units='rad/s',     desc='Platform natural frequency')
1✔
101
        tune_rosco_ivc.add_output('Kp_float',         val=0.0, units='s',         desc='Floating feedback gain')
1✔
102

103
        self.add_subsystem('tune_rosco_ivc',tune_rosco_ivc)
1✔
104

105
        # Analysis components
106
        self.add_subsystem('wisdem',   wisdemPark(modeling_options = modeling_options, opt_options = opt_options), promotes=['*'])
1✔
107

108
        # XFOIL
109
        self.add_subsystem('xf',        RunXFOIL(modeling_options = modeling_options, opt_options = opt_options)) # Recompute polars with xfoil (for flaps)
1✔
110
        # Connections to run xfoil for te flaps
111
        if not modeling_options['Level3']['from_openfast']:
1✔
112
            self.connect('blade.pa.chord_param',                  'xf.chord')
1✔
113
            self.connect('blade.outer_shape_bem.s',               'xf.s')
1✔
114
            self.connect('blade.interp_airfoils.coord_xy_interp', 'xf.coord_xy_interp')
1✔
115
            self.connect('airfoils.aoa',                          'xf.aoa')
1✔
116
            self.connect("blade.high_level_blade_props.r_blade",  "xf.r")
1✔
117
            self.connect('dac_ivc.te_flap_end',                   'xf.span_end')
1✔
118
            self.connect('dac_ivc.te_flap_ext',                   'xf.span_ext')
1✔
119
            self.connect('dac_ivc.chord_start',                   'xf.chord_start')
1✔
120
            self.connect('dac_ivc.delta_max_pos',                 'xf.delta_max_pos')
1✔
121
            self.connect('dac_ivc.delta_max_neg',                 'xf.delta_max_neg')
1✔
122
            self.connect('env.speed_sound_air',                   'xf.speed_sound_air')
1✔
123
            self.connect('env.rho_air',                           'xf.rho_air')
1✔
124
            self.connect('env.mu_air',                            'xf.mu_air')
1✔
125
            self.connect('control.rated_TSR',                     'xf.rated_TSR')
1✔
126
            if modeling_options['flags']['control']:
1✔
127
                self.connect('control.max_TS',                        'xf.max_TS')
1✔
128
            self.connect("af_3d.cl_corrected", "xf.cl_interp")
1✔
129
            self.connect("af_3d.cd_corrected", "xf.cd_interp")
1✔
130
            self.connect("af_3d.cm_corrected", "xf.cm_interp")
1✔
131

132
        # ROSCO can be used at all levels
133
        if modeling_options['ROSCO']['flag']:
1✔
134
            if modeling_options['Level3']['from_openfast']:  # not using WISDEM turbine info
1✔
135
                self.add_subsystem('rosco_turbine',          ROSCO_Turbine(modeling_options = modeling_options)) # ROSCO tuning
1✔
136

137
            self.add_subsystem('sse_tune',          ServoSE_ROSCO(modeling_options = modeling_options, opt_options = opt_options)) # ROSCO tuning
1✔
138

139
            if not modeling_options['Level3']['from_openfast']:     #from WISDEM models
1✔
140
                self.connect('rotorse.rp.powercurve.rated_V',         ['sse_tune.tune_rosco.v_rated'])
1✔
141
                #self.connect('rotorse.rp.gust.V_gust',                ['freq_rotor.aero_gust.V_load', 'freq_rotor.aero_hub_loads.V_load'])
142
                self.connect('rotorse.rp.powercurve.rated_Omega',     'sse_tune.tune_rosco.rated_rotor_speed')
1✔
143
                #self.connect('rotorse.rp.powercurve.rated_pitch',     ['freq_rotor.pitch_load', 'freq_rotor.tot_loads_gust.aeroloads_pitch'])
144
                self.connect('rotorse.rp.powercurve.rated_Q',          'sse_tune.tune_rosco.rated_torque')
1✔
145
                
146
                self.connect("blade.high_level_blade_props.r_blade",  "sse_tune.r")
1✔
147
                self.connect("blade.high_level_blade_props.rotor_radius", "sse_tune.Rtip")
1✔
148
                self.connect('hub.radius',                     'sse_tune.Rhub')
1✔
149
                self.connect("high_level_tower_props.hub_height", "sse_tune.hub_height")
1✔
150
                self.connect('hub.cone',                       'sse_tune.precone')
1✔
151
                self.connect('nacelle.uptilt',                 'sse_tune.tilt')
1✔
152
                self.connect('airfoils.aoa',                   'sse_tune.airfoils_aoa')
1✔
153
                self.connect('airfoils.Re',                    'sse_tune.airfoils_Re')
1✔
154
                self.connect('xf.cl_interp_flaps',             'sse_tune.airfoils_cl')
1✔
155
                self.connect('xf.cd_interp_flaps',             'sse_tune.airfoils_cd')
1✔
156
                self.connect('xf.cm_interp_flaps',             'sse_tune.airfoils_cm')
1✔
157
                self.connect('configuration.n_blades',         'sse_tune.nBlades')
1✔
158
                self.connect('env.rho_air',                    'sse_tune.rho')
1✔
159
                self.connect('env.mu_air',                     'sse_tune.mu')
1✔
160
                self.connect('blade.pa.chord_param',           'sse_tune.chord')
1✔
161
                self.connect('blade.pa.twist_param',           'sse_tune.theta')
1✔
162

163
                self.connect('control.V_in' ,                   'sse_tune.v_min')
1✔
164
                self.connect('control.V_out' ,                  'sse_tune.v_max')
1✔
165
                self.connect("blade.high_level_blade_props.prebend", 'sse_tune.precurve')
1✔
166
                self.connect("blade.high_level_blade_props.prebendTip", 'sse_tune.precurveTip')
1✔
167
                self.connect("blade.high_level_blade_props.presweep", 'sse_tune.presweep')
1✔
168
                self.connect("blade.high_level_blade_props.presweepTip", 'sse_tune.presweepTip')
1✔
169
                self.connect('xf.flap_angles',                  'sse_tune.airfoils_Ctrl')
1✔
170
                self.connect('control.minOmega',                'sse_tune.omega_min')
1✔
171
                self.connect('control.rated_TSR',               'sse_tune.tsr_operational')
1✔
172
                self.connect('configuration.rated_power',       'sse_tune.rated_power')
1✔
173

174
                self.connect('nacelle.gear_ratio',              'sse_tune.tune_rosco.gear_ratio')
1✔
175
                self.connect("blade.high_level_blade_props.rotor_radius", "sse_tune.tune_rosco.R")
1✔
176
                self.connect('rotorse.I_all_blades',            'sse_tune.tune_rosco.rotor_inertia', src_indices=[0])
1✔
177
                self.connect('rotorse.rs.frame.flap_mode_freqs','sse_tune.tune_rosco.flap_freq', src_indices=[0])
1✔
178
                self.connect('rotorse.rs.frame.edge_mode_freqs','sse_tune.tune_rosco.edge_freq', src_indices=[0])
1✔
179
                self.connect('rotorse.rp.powercurve.rated_efficiency', 'sse_tune.tune_rosco.generator_efficiency')
1✔
180
                self.connect('tower_grid.height',               'sse_tune.tune_rosco.TowerHt')
1✔
181
                self.connect('nacelle.gearbox_efficiency',      'sse_tune.tune_rosco.gearbox_efficiency')
1✔
182
                self.connect('control.max_pitch_rate' ,         'sse_tune.tune_rosco.max_pitch_rate')
1✔
183
                self.connect('control.max_torque_rate' ,        'sse_tune.tune_rosco.max_torque_rate')
1✔
184

185
            else:       # reading openfast model using ROSCO toolbox via rosco_turbine
186
                self.connect('rosco_turbine.v_rated'            ,   ['sse_tune.tune_rosco.v_rated'])
1✔
187
                self.connect('rosco_turbine.rated_rotor_speed'  ,   'sse_tune.tune_rosco.rated_rotor_speed')
1✔
188
                self.connect('rosco_turbine.rated_torque'       ,   'sse_tune.tune_rosco.rated_torque')
1✔
189
                self.connect('rosco_turbine.rotor_inertia',         'sse_tune.tune_rosco.rotor_inertia', src_indices=[0])
1✔
190
                self.connect('rosco_turbine.flap_freq',             'sse_tune.tune_rosco.flap_freq', src_indices=[0])
1✔
191
                self.connect('rosco_turbine.edge_freq',             'sse_tune.tune_rosco.edge_freq', src_indices=[0])
1✔
192
                self.connect('rosco_turbine.generator_efficiency',  'sse_tune.tune_rosco.generator_efficiency')                
1✔
193
                self.connect('rosco_turbine.rho',                   'sse_tune.rho')
1✔
194
                self.connect('rosco_turbine.R',                     'sse_tune.tune_rosco.R')
1✔
195
                self.connect('rosco_turbine.rated_power',           'sse_tune.rated_power')
1✔
196
                self.connect('rosco_turbine.v_min' ,                'sse_tune.v_min')
1✔
197
                self.connect('rosco_turbine.v_max' ,                'sse_tune.v_max')
1✔
198
                self.connect('rosco_turbine.max_pitch_rate' ,       'sse_tune.tune_rosco.max_pitch_rate')
1✔
199
                self.connect('rosco_turbine.max_torque_rate' ,      'sse_tune.tune_rosco.max_torque_rate')
1✔
200
                self.connect('rosco_turbine.omega_min',             'sse_tune.omega_min')
1✔
201
                self.connect('rosco_turbine.tsr_operational',       'sse_tune.tsr_operational')
1✔
202
            
203
                # Performance tables
204
                self.connect('rosco_turbine.Cp_table',        'sse_tune.tune_rosco.Cp_table')
1✔
205
                self.connect('rosco_turbine.Ct_table',        'sse_tune.tune_rosco.Ct_table')
1✔
206
                self.connect('rosco_turbine.Cq_table',        'sse_tune.tune_rosco.Cq_table')
1✔
207
                self.connect('rosco_turbine.pitch_vector',    'sse_tune.tune_rosco.pitch_vector')
1✔
208
                self.connect('rosco_turbine.tsr_vector',      'sse_tune.tune_rosco.tsr_vector')
1✔
209
                self.connect('rosco_turbine.U_vector',        'sse_tune.tune_rosco.U_vector')
1✔
210

211
                self.connect('rosco_turbine.gear_ratio',              'sse_tune.tune_rosco.gear_ratio')
1✔
212
                self.connect('rosco_turbine.gearbox_efficiency',      'sse_tune.tune_rosco.gearbox_efficiency')
1✔
213

214
                self.connect('rosco_turbine.TowerHt',               'sse_tune.tune_rosco.TowerHt')
1✔
215

216

217
            # ROSCO Independent Vars
218
            self.connect('tune_rosco_ivc.max_pitch',        'sse_tune.tune_rosco.max_pitch') 
1✔
219
            self.connect('tune_rosco_ivc.min_pitch',        'sse_tune.tune_rosco.min_pitch')
1✔
220
            self.connect('tune_rosco_ivc.vs_minspd',        'sse_tune.tune_rosco.vs_minspd') 
1✔
221
            self.connect('tune_rosco_ivc.ss_vsgain',        'sse_tune.tune_rosco.ss_vsgain') 
1✔
222
            self.connect('tune_rosco_ivc.ss_pcgain',        'sse_tune.tune_rosco.ss_pcgain') 
1✔
223
            self.connect('tune_rosco_ivc.ps_percent',       'sse_tune.tune_rosco.ps_percent') 
1✔
224
            self.connect('tune_rosco_ivc.omega_pc',         'sse_tune.tune_rosco.omega_pc')
1✔
225
            self.connect('tune_rosco_ivc.zeta_pc',          'sse_tune.tune_rosco.zeta_pc')
1✔
226
            self.connect('tune_rosco_ivc.omega_vs',         'sse_tune.tune_rosco.omega_vs')
1✔
227
            self.connect('tune_rosco_ivc.zeta_vs',          'sse_tune.tune_rosco.zeta_vs')
1✔
228
            self.connect('tune_rosco_ivc.IPC_Kp1p',         'sse_tune.tune_rosco.IPC_Kp1p')
1✔
229
            self.connect('tune_rosco_ivc.IPC_Ki1p',         'sse_tune.tune_rosco.IPC_Ki1p')
1✔
230
            self.connect('tune_rosco_ivc.stability_margin', 'sse_tune.tune_rosco.stability_margin')
1✔
231
            self.connect('tune_rosco_ivc.omega_pc_max', 'sse_tune.tune_rosco.omega_pc_max')
1✔
232

233
            # Someday, if we want to get ptfm_freq from Level 1, we'd switch that here
234
            self.connect('tune_rosco_ivc.ptfm_freq',        'sse_tune.tune_rosco.ptfm_freq')
1✔
235

236
            self.connect('tune_rosco_ivc.Kp_float',         'sse_tune.tune_rosco.Kp_float')
1✔
237
            self.connect('dac_ivc.delta_max_pos',           'sse_tune.tune_rosco.delta_max_pos')
1✔
238
            if modeling_options['ROSCO']['Flp_Mode'] > 0:
1✔
239
                self.connect('tune_rosco_ivc.flp_kp_norm',    'sse_tune.tune_rosco.flp_kp_norm')
×
240
                self.connect('tune_rosco_ivc.flp_tau',     'sse_tune.tune_rosco.flp_tau')
×
241

242
        if modeling_options['Level1']['flag']:
1✔
243
            self.add_subsystem('raft', RAFT_WEIS(modeling_options = modeling_options, analysis_options=opt_options))
1✔
244

245
            n_span = modeling_options["WISDEM"]["RotorSE"]["n_span"]
1✔
246
            self.connect('configuration.turb_class',        'raft.turbulence_class')
1✔
247
            self.connect('configuration.ws_class' ,         'raft.turbine_class')
1✔
248
            self.connect('drivese.rna_mass', 'raft.turbine_mRNA')
1✔
249
            self.connect('drivese.rna_I_TT', 'raft.rna_I_TT')
1✔
250
            self.connect('drivese.rna_cm', 'raft.rna_cm')
1✔
251
            self.connect("nacelle.overhang", "raft.turbine_overhang")
1✔
252
            self.connect("nacelle.distance_tt_hub", "raft.drive_height")
1✔
253
            self.connect('drivese.base_F', 'raft.turbine_Fthrust', src_indices=[0], flat_src_indices=True) # TODO: Multiple DLCs
1✔
254
            self.connect("high_level_tower_props.hub_height", "raft.turbine_hHub")
1✔
255
            self.connect("tower.layer_thickness", "raft.tower_layer_thickness")
1✔
256
            self.connect("tower_grid.s", "raft.turbine_tower_stations")
1✔
257
            self.connect('tower.diameter', 'raft.turbine_tower_d')
1✔
258
            self.connect('env.water_depth', 'raft.mooring_water_depth')
1✔
259
            self.connect('env.rho_water', 'raft.rho_water')
1✔
260
            self.connect('env.rho_air', 'raft.rho_air')
1✔
261
            self.connect('env.mu_air', 'raft.mu_air')
1✔
262
            self.connect('env.shear_exp', 'raft.shear_exp')
1✔
263
            self.connect('sse_tune.tune_rosco.PC_GS_angles',    'raft.rotor_PC_GS_angles')
1✔
264
            self.connect('sse_tune.tune_rosco.PC_GS_Kp',        'raft.rotor_PC_GS_Kp')
1✔
265
            self.connect('sse_tune.tune_rosco.PC_GS_Ki',        'raft.rotor_PC_GS_Ki')
1✔
266
            self.connect('sse_tune.tune_rosco.Fl_Kp',           'raft.Fl_Kp')
1✔
267
            self.connect('sse_tune.tune_rosco.VS_Kp',           'raft.rotor_TC_VS_Kp')
1✔
268
            self.connect('sse_tune.tune_rosco.VS_Ki',           'raft.rotor_TC_VS_Ki')
1✔
269
            self.connect('rotorse.I_all_blades',     'raft.rotor_inertia', src_indices=[0])
1✔
270
            self.connect('rotorse.rp.powercurve.rated_V',       'raft.Vrated')
1✔
271
            self.connect('control.V_in',                    'raft.V_cutin')
1✔
272
            self.connect('control.V_out',                   'raft.V_cutout')
1✔
273
            self.connect('rotorse.rp.powercurve.rated_Omega',     'raft.rated_rotor_speed')
1✔
274

275
            if modeling_options["flags"]["blade"]:
1✔
276
                self.connect("configuration.n_blades", "raft.nBlades")
1✔
277
                self.connect("hub.cone", "raft.precone")
1✔
278
                self.connect("nacelle.uptilt", "raft.tilt")
1✔
279
                self.connect("nacelle.gear_ratio", "raft.gear_ratio")
1✔
280
                self.connect("blade.high_level_blade_props.r_blade",  "raft.blade_r")
1✔
281
                self.connect("blade.high_level_blade_props.rotor_radius", "raft.blade_Rtip")
1✔
282
                self.connect("hub.radius", "raft.hub_radius")
1✔
283
                self.connect("blade.pa.chord_param", "raft.blade_chord")
1✔
284
                self.connect("blade.pa.twist_param", "raft.blade_theta")
1✔
285
                self.connect("blade.high_level_blade_props.prebend", "raft.blade_precurve")
1✔
286
                self.connect("blade.high_level_blade_props.prebendTip", "raft.blade_precurveTip")
1✔
287
                self.connect("blade.high_level_blade_props.presweep", "raft.blade_presweep")
1✔
288
                self.connect("blade.high_level_blade_props.presweepTip", "raft.blade_presweepTip")
1✔
289
                self.connect("airfoils.name", "raft.airfoils_name")
1✔
290
                self.connect("airfoils.r_thick", "raft.airfoils_r_thick")
1✔
291
                self.connect("blade.opt_var.af_position", "raft.airfoils_position")
1✔
292
                self.connect("airfoils.aoa", "raft.airfoils_aoa")
1✔
293
                self.connect("airfoils.cl", "raft.airfoils_cl")
1✔
294
                self.connect("airfoils.cd", "raft.airfoils_cd")
1✔
295
                self.connect("airfoils.cm", "raft.airfoils_cm")
1✔
296
                self.connect("high_level_tower_props.hub_height", "raft.wind_reference_height")
1✔
297
                self.connect("rotorse.rp.powercurve.V", "raft.rotor_powercurve_v")
1✔
298
                self.connect("rotorse.rp.powercurve.Omega", "raft.rotor_powercurve_omega_rpm")
1✔
299
                self.connect("rotorse.rp.powercurve.pitch", "raft.rotor_powercurve_pitch")
1✔
300

301
            if modeling_options["flags"]["tower"]:
1✔
302
                self.connect('towerse.member.rho', 'raft.tower_rho')
1✔
303
                self.connect('towerse.tower_section_height', 'raft.tower_section_height')
1✔
304
                self.connect('towerse.member.tor_stff', 'raft.tower_torsional_stiffness')
1✔
305
                self.connect('towerse.z_param',        'raft.wind.z')
1✔
306
                self.connect("rotorse.rp.gust.V_gust", "raft.Uref")
1✔
307
                self.connect("high_level_tower_props.hub_height", "raft.zref")
1✔
308
                self.connect("high_level_tower_props.tower_ref_axis", "raft.turbine_tower_rA", src_indices=om.slicer[0,:])
1✔
309
                self.connect("high_level_tower_props.tower_ref_axis", "raft.turbine_tower_rB", src_indices=om.slicer[-1,:])
1✔
310
                
311
            if modeling_options["flags"]["floating"]:
1✔
312
                self.connect("floatingse.member_variable_height", "raft.member_variable_height")
1✔
313

314
                for k, kname in enumerate(modeling_options["floating"]["members"]["name"]):
1✔
315
                    idx = modeling_options["floating"]["members"]["name2idx"][kname]
1✔
316
                    self.connect(f"floating.memgrid{idx}.layer_thickness", f"raft.member{k}:layer_thickness")
1✔
317
                    self.connect(f"floatingse.member{k}.height", f"raft.member{k}:height")
1✔
318
                    self.connect(f"floatingse.member{k}.rho", f"raft.member{k}:rho")
1✔
319
                    self.connect(f"floating.memgrp{idx}.s", f"raft.platform_member{k+1}_stations")
1✔
320
                    self.connect(f"floating.memgrp{idx}.ring_stiffener_web_height", f"raft.member{k}:ring_stiffener_web_height")
1✔
321
                    self.connect(f"floating.memgrp{idx}.ring_stiffener_web_thickness", f"raft.member{k}:ring_stiffener_web_thickness")
1✔
322
                    self.connect(f"floating.memgrp{idx}.ring_stiffener_flange_width", f"raft.member{k}:ring_stiffener_flange_width")
1✔
323
                    self.connect(f"floating.memgrp{idx}.ring_stiffener_flange_thickness", f"raft.member{k}:ring_stiffener_flange_thickness")
1✔
324
                    self.connect(f"floating.memgrp{idx}.ring_stiffener_spacing", f"raft.member{k}:ring_stiffener_spacing")
1✔
325
                    self.connect(f"floating.memgrp{idx}.bulkhead_grid", f"raft.platform_member{k+1}_cap_stations")
1✔
326
                    self.connect(f"floating.memgrp{idx}.bulkhead_thickness", f"raft.platform_member{k+1}_cap_t")
1✔
327
                    self.connect(f"floating.member_{kname}:joint1", f"raft.platform_member{k+1}_rA")
1✔
328
                    self.connect(f"floating.member_{kname}:joint2", f"raft.platform_member{k+1}_rB")
1✔
329
                    self.connect(f"floating.member_{kname}:s_ghost1", f"raft.platform_member{k+1}_s_ghostA")
1✔
330
                    self.connect(f"floating.member_{kname}:s_ghost2", f"raft.platform_member{k+1}_s_ghostB")
1✔
331
                    self.connect(f"floating.memgrp{idx}.ballast_grid", f"raft.member{k}:ballast_grid")
1✔
332
                    self.connect(f"floatingse.member{k}.ballast_height", f"raft.member{k}:ballast_height")
1✔
333
                    self.connect(f"floatingse.member{k}.ballast_density", f"raft.member{k}:ballast_density")
1✔
334

335
                    if modeling_options['floating']['members']['outer_shape'][k] == "circular":
1✔
336
                        self.connect(f"floatingse.member{k}.outer_diameter", f"raft.member{k}:outer_diameter")
1✔
337
                        self.connect(f"floating.memgrid{idx}.ca_usr_grid", f"raft.member{k}:Ca")
1✔
338
                        self.connect(f"floating.memgrid{idx}.cd_usr_grid", f"raft.member{k}:Cd")
1✔
339
                    elif modeling_options['floating']['members']['outer_shape'][k] == "rectangular":
×
340
                        self.connect(f"floatingse.member{k}.side_length_a", f"raft.member{k}:side_length_a")
×
341
                        self.connect(f"floatingse.member{k}.side_length_b", f"raft.member{k}:side_length_b")
×
342
                        self.connect(f"floating.memgrid{idx}.ca_usr_grid", f"raft.member{k}:Ca")
×
343
                        self.connect(f"floating.memgrid{idx}.cd_usr_grid", f"raft.member{k}:Cd")
×
344
                        self.connect(f"floating.memgrid{idx}.cay_usr_grid", f"raft.member{k}:Cay")
×
345
                        self.connect(f"floating.memgrid{idx}.cdy_usr_grid", f"raft.member{k}:Cdy")
×
346

347
                self.connect("mooring.mooring_nodes", 'raft.mooring_nodes')
1✔
348
                self.connect("mooring.unstretched_length", 'raft.unstretched_length')
1✔
349
                for var in ['diameter','mass_density','stiffness','breaking_load','cost_rate',
1✔
350
                            'transverse_added_mass','tangential_added_mass','transverse_drag','tangential_drag']:
351
                    self.connect(f'mooring.line_{var}', f'raft.line_{var}')
1✔
352

353
        # TMD connections to openmdao_openfast
354
        if modeling_options['flags']['TMDs']:
1✔
355
            self.add_subsystem('TMDs',  TMD_group(modeling_options = modeling_options, opt_options = opt_options))
1✔
356

357
            self.connect('TMDs.mass',               'aeroelastic.TMD_mass')
1✔
358
            self.connect('TMDs.stiffness',          'aeroelastic.TMD_stiffness')
1✔
359
            self.connect('TMDs.damping',            'aeroelastic.TMD_damping')
1✔
360

361
        if modeling_options['Level3']['flag'] or modeling_options['Level2']['flag']:
1✔
362
            self.add_subsystem('aeroelastic',       FASTLoadCases(modeling_options = modeling_options, opt_options = opt_options))
1✔
363
            self.add_subsystem('stall_check_of',    NoStallConstraint(modeling_options = modeling_options))
1✔
364
            
365
            if modeling_options['WISDEM']['RotorSE']['flag']: 
1✔
366
                self.add_subsystem('rlds_post',      RotorLoadsDeflStrainsWEIS(modeling_options = modeling_options, opt_options = opt_options))
1✔
367

368
                # Connections from blade struct parametrization to rotor load anlysis
369
                spars_tereinf = modeling_options["WISDEM"]["RotorSE"]["spars_tereinf"]
1✔
370
                self.connect("blade.opt_var.s_opt_layer_%d"%spars_tereinf[0], "rotorse.rs.constr.s_opt_spar_cap_ss")
1✔
371
                self.connect("blade.opt_var.s_opt_layer_%d"%spars_tereinf[1], "rotorse.rs.constr.s_opt_spar_cap_ps")
1✔
372

373

374
                # Connections to the stall check 
375
                self.connect('blade.outer_shape_bem.s',        'stall_check_of.s')
1✔
376
                self.connect('airfoils.aoa',                   'stall_check_of.airfoils_aoa')
1✔
377
                self.connect('xf.cl_interp_flaps',             'stall_check_of.airfoils_cl')
1✔
378
                self.connect('xf.cd_interp_flaps',             'stall_check_of.airfoils_cd')
1✔
379
                self.connect('xf.cm_interp_flaps',             'stall_check_of.airfoils_cm')
1✔
380
                self.connect('aeroelastic.max_aoa',            'stall_check_of.aoa_along_span')
1✔
381
        
382
            if  modeling_options["flags"]["nacelle"]:
1✔
383
                self.add_subsystem('drivese_post',   DrivetrainSE(modeling_options=modeling_options))
1✔
384

385
            # TODO: FIX NDLC HERE
386
            if modeling_options["flags"]["tower"]:
1✔
387
                # This is needed for some reason because TowerSE isn't already called?  Should probably re-use that
388
                n_height = modeling_options['WISDEM']['TowerSE']["n_height"]
1✔
389
                n_refine = modeling_options['WISDEM']['TowerSE']["n_refine"]
1✔
390
                n_full = get_nfull(n_height, nref=n_refine)
1✔
391
                self.add_subsystem('towerse_post',   CylinderPostFrame(modeling_options=modeling_options["WISDEM"]["TowerSE"], n_dlc=1, n_full = n_full))
1✔
392
                
393
            if modeling_options["flags"]["monopile"]:
1✔
394
                n_height = modeling_options['WISDEM']['FixedBottomSE']["n_height"]
1✔
395
                n_refine = modeling_options['WISDEM']['FixedBottomSE']["n_refine"]
1✔
396
                n_full = get_nfull(n_height, nref=n_refine)
1✔
397
                
398
                self.add_subsystem('fixedse_post',   CylinderPostFrame(modeling_options=modeling_options["WISDEM"]["FixedBottomSE"], n_dlc=1, n_full = n_full))
1✔
399
                
400
            if not modeling_options['Level3']['from_openfast']:
1✔
401
                self.add_subsystem('tcons_post',     TurbineConstraints(modeling_options = modeling_options))
1✔
402
                self.add_subsystem('financese_post', PlantFinance(verbosity=modeling_options['General']['verbosity']))
1✔
403
            
404
            # Post-processing
405
            self.add_subsystem('outputs_2_screen_weis',  Outputs_2_Screen(modeling_options = modeling_options, opt_options = opt_options))
1✔
406
            if opt_options['opt_flag']:
1✔
407
                self.add_subsystem('conv_plots_weis',    Convergence_Trends_Opt(opt_options = opt_options))
1✔
408

409
            if modeling_options['ROSCO']['Flp_Mode']:
1✔
410
                # Connections to blade 
411
                self.connect('dac_ivc.te_flap_end',             'blade.outer_shape_bem.span_end')
×
412
                self.connect('dac_ivc.te_flap_ext',             'blade.outer_shape_bem.span_ext')
×
413

414

415

416
            if modeling_options['ROSCO']['flag']==False:
1✔
417
                raise Exception("ERROR: WISDEM does not support openfast without the tuning of ROSCO")
×
418

419
            # Configuration parameters needed if model comes from openfast
420
            self.connect('control.V_in',                    'aeroelastic.V_cutin')
1✔
421
            self.connect('control.V_out',                   'aeroelastic.V_cutout')
1✔
422
            self.connect('env.shear_exp',                   'aeroelastic.shearExp')
1✔
423
            
424
            # Connections to aeroelasticse
425
            self.connect('configuration.turb_class',        'aeroelastic.turbulence_class')
1✔
426
            self.connect('configuration.ws_class' ,         'aeroelastic.turbine_class')
1✔
427

428
            if not modeling_options['Level3']['from_openfast']:
1✔
429
                self.connect('blade.outer_shape_bem.ref_axis',  'aeroelastic.ref_axis_blade')
1✔
430
                self.connect('configuration.rotor_orientation', 'aeroelastic.rotor_orientation')
1✔
431
                self.connect("blade.high_level_blade_props.r_blade",  "aeroelastic.r")
1✔
432
                self.connect('blade.outer_shape_bem.pitch_axis','aeroelastic.le_location')
1✔
433
                self.connect('blade.pa.chord_param',            'aeroelastic.chord')
1✔
434
                self.connect('blade.pa.twist_param',            'aeroelastic.theta')
1✔
435
                self.connect('blade.interp_airfoils.coord_xy_interp', 'aeroelastic.coord_xy_interp')
1✔
436
                self.connect('env.rho_air',                     'aeroelastic.rho')
1✔
437
                self.connect('env.speed_sound_air',             'aeroelastic.speed_sound_air')
1✔
438
                self.connect('env.mu_air',                      'aeroelastic.mu')
1✔
439
                self.connect('env.water_depth',                 'aeroelastic.water_depth')
1✔
440
                self.connect('env.rho_water',                   'aeroelastic.rho_water')
1✔
441
                self.connect('env.mu_water',                    'aeroelastic.mu_water')
1✔
442
                self.connect('env.Hsig_wave',                    'aeroelastic.Hsig_wave')     # TODO: these depend on wind speed
1✔
443
                self.connect('env.Tsig_wave',                    'aeroelastic.Tsig_wave')
1✔
444
                #self.connect('env.beta_wave',                    'aeroelastic.beta_wave') # TODO: NEED ONTOLOGY INPUT HERE
445
                self.connect("blade.high_level_blade_props.rotor_radius", "aeroelastic.Rtip")
1✔
446
                self.connect('hub.radius',                      'aeroelastic.Rhub')
1✔
447
                self.connect('hub.cone',                        'aeroelastic.cone')
1✔
448
                self.connect('drivese.hub_system_mass',         'aeroelastic.hub_system_mass')
1✔
449
                self.connect('drivese.hub_system_I',            'aeroelastic.hub_system_I')
1✔
450
                # TODO: Create these outputs in DriveSE: hub_system_cm needs 3-dim, not s-coord.  Need adder for rna-yaw_mass?
451
                #self.connect('drivese_post.hub_system_cm',                    'aeroelastic.hub_system_cm')
452
                self.connect('drivese.above_yaw_mass',          'aeroelastic.above_yaw_mass')
1✔
453
                self.connect('drivese.yaw_mass',                'aeroelastic.yaw_mass')
1✔
454
                self.connect('drivese.rna_I_TT',                'aeroelastic.rna_I_TT')
1✔
455
                self.connect('drivese.above_yaw_I_TT',          'aeroelastic.nacelle_I_TT')
1✔
456
                self.connect('drivese.above_yaw_cm',            'aeroelastic.nacelle_cm')
1✔
457
                self.connect('drivese.generator_rotor_I',       'aeroelastic.GenIner', src_indices=[0])
1✔
458
                self.connect('nacelle.gear_ratio',              'aeroelastic.gearbox_ratio')
1✔
459
                self.connect('rotorse.rp.powercurve.rated_efficiency',  'aeroelastic.generator_efficiency')
1✔
460
                self.connect('control.max_pitch_rate' ,         'aeroelastic.max_pitch_rate')
1✔
461
                self.connect('nacelle.gearbox_efficiency',      'aeroelastic.gearbox_efficiency')
1✔
462
                self.connect('nacelle.uptilt',                  'aeroelastic.tilt')
1✔
463
                self.connect('nacelle.overhang',                'aeroelastic.overhang')
1✔
464
                self.connect('nacelle.distance_tt_hub',         'aeroelastic.distance_tt_hub')
1✔
465
                self.connect('drivese.drivetrain_spring_constant', 'aeroelastic.drivetrain_spring_constant')
1✔
466
                self.connect('drivese.drivetrain_damping_coefficient', 'aeroelastic.drivetrain_damping_coefficient')
1✔
467

468
                self.connect("high_level_tower_props.hub_height", "aeroelastic.hub_height")
1✔
469
                if modeling_options["flags"]["tower"]:
1✔
470
                    self.connect('towerse.member.mass_den',                'aeroelastic.mass_den')
1✔
471
                    self.connect('towerse.member.foreaft_stff',            'aeroelastic.foreaft_stff')
1✔
472
                    self.connect('towerse.member.sideside_stff',           'aeroelastic.sideside_stff')
1✔
473
                    self.connect('towerse.member.tor_stff',                'aeroelastic.tor_stff')
1✔
474
                    self.connect('towerse.tower_outer_diameter',    'aeroelastic.tower_outer_diameter')
1✔
475
                    self.connect('towerse.z_param',                 'aeroelastic.tower_z')
1✔
476
                    self.connect('towerse.z_full',                  'aeroelastic.tower_z_full')
1✔
477
                    self.connect('tower.cd',                        'aeroelastic.tower_cd')
1✔
478
                    self.connect('tower_grid.height',               'aeroelastic.tower_height')
1✔
479
                    self.connect('tower_grid.foundation_height',    'aeroelastic.tower_base_height')
1✔
480
                    self.connect('towerse.tower_I_base',            'aeroelastic.tower_I_base')
1✔
481
                    if modeling_options["flags"]["monopile"] or modeling_options["flags"]["jacket"]:
1✔
482
                        self.connect('fixedse.torsion_freqs',      'aeroelastic.tor_freq', src_indices=[0])
1✔
483
                        self.connect('fixedse.tower_fore_aft_modes',     'aeroelastic.fore_aft_modes')
1✔
484
                        self.connect('fixedse.tower_side_side_modes',    'aeroelastic.side_side_modes')
1✔
485
                        self.connect('fixedse.f1',         'sse_tune.tune_rosco.twr_freq')
1✔
486

487
                    elif modeling_options["flags"]["floating"]:
1✔
488
                        self.connect('floatingse.torsion_freqs',      'aeroelastic.tor_freq', src_indices=[0])
1✔
489
                        self.connect('floatingse.fore_aft_modes',     'aeroelastic.fore_aft_modes')
1✔
490
                        self.connect('floatingse.side_side_modes',    'aeroelastic.side_side_modes')
1✔
491
                        self.connect('floatingse.f1',         'sse_tune.tune_rosco.twr_freq')
1✔
492
                    else:
493
                        self.connect('towerse.tower.torsion_freqs',      'aeroelastic.tor_freq', src_indices=[0])
1✔
494
                        self.connect('towerse.tower.fore_aft_modes',     'aeroelastic.fore_aft_modes')
1✔
495
                        self.connect('towerse.tower.side_side_modes',    'aeroelastic.side_side_modes')
1✔
496
                        self.connect('towerse.tower.f1',         'sse_tune.tune_rosco.twr_freq')
1✔
497
                        
498
                if modeling_options['flags']['monopile']:
1✔
499
                    self.connect('monopile.transition_piece_mass',  'aeroelastic.transition_piece_mass')
1✔
500
                    self.connect('fixedse.transition_piece_I',      'aeroelastic.transition_piece_I', src_indices=[0,1,2])
1✔
501
                    self.connect('monopile.gravity_foundation_mass', 'aeroelastic.gravity_foundation_mass')
1✔
502
                    self.connect('fixedse.gravity_foundation_I',    'aeroelastic.gravity_foundation_I', src_indices=[0,1,2])
1✔
503
                    self.connect('fixedse.z_param',                 'aeroelastic.monopile_z')
1✔
504
                    self.connect('fixedse.z_full',                  'aeroelastic.monopile_z_full')
1✔
505
                    self.connect('fixedse.monopile_outer_diameter',    'aeroelastic.monopile_outer_diameter')
1✔
506
                    self.connect('fixedse.monopile_wall_thickness',    'aeroelastic.monopile_wall_thickness')
1✔
507
                    self.connect('fixedse.member.E',                       'aeroelastic.monopile_E')
1✔
508
                    self.connect('fixedse.member.G',                       'aeroelastic.monopile_G')
1✔
509
                    self.connect('fixedse.member.rho',                     'aeroelastic.monopile_rho')
1✔
510
                        
511
                elif modeling_options['flags']['floating']:
1✔
512
                    self.connect("floatingse.platform_nodes", "aeroelastic.platform_nodes")
1✔
513
                    self.connect("floatingse.platform_elem_n1", "aeroelastic.platform_elem_n1")
1✔
514
                    self.connect("floatingse.platform_elem_n2", "aeroelastic.platform_elem_n2")
1✔
515
                    self.connect("floatingse.platform_elem_D", "aeroelastic.platform_elem_D")
1✔
516
                    self.connect("floatingse.platform_elem_t", "aeroelastic.platform_elem_t")
1✔
517
                    self.connect("floatingse.platform_elem_rho", "aeroelastic.platform_elem_rho")
1✔
518
                    self.connect("floatingse.platform_elem_E", "aeroelastic.platform_elem_E")
1✔
519
                    self.connect("floatingse.platform_elem_G", "aeroelastic.platform_elem_G")
1✔
520
                    if modeling_options['Level1']['flag']:
1✔
UNCOV
521
                        ptfm_data_source = 'raft'
×
522
                    else:
523
                        ptfm_data_source = 'floatingse'
1✔
524
                    self.connect(f"{ptfm_data_source}.platform_mass", "aeroelastic.platform_mass")
1✔
525
                    self.connect(f"{ptfm_data_source}.platform_total_center_of_mass", "aeroelastic.platform_total_center_of_mass")
1✔
526
                    self.connect(f"{ptfm_data_source}.platform_I_total", "aeroelastic.platform_I_total")
1✔
527
                    self.connect(f"{ptfm_data_source}.platform_displacement", "aeroelastic.platform_displacement")
1✔
528
                    self.connect("floating.transition_node", "aeroelastic.transition_node")
1✔
529

530
                    for k, kname in enumerate(modeling_options["floating"]["members"]["name"]):
1✔
531
                        idx = modeling_options["floating"]["members"]["name2idx"][kname]
1✔
532
                        #self.connect(f"floating.memgrp{idx}.outer_diameter", f"floatingse.member{k}.outer_diameter_in")
533
                        self.connect(f"floating.memgrp{idx}.s", f"aeroelastic.member{k}:s")
1✔
534
                        self.connect(f"floatingse.member{k}.outer_diameter", f"aeroelastic.member{k}:outer_diameter")
1✔
535
                        self.connect(f"floatingse.member{k}.wall_thickness", f"aeroelastic.member{k}:wall_thickness")
1✔
536

537
                        for var in ["joint1", "joint2", "s_ghost1", "s_ghost2"]:
1✔
538
                            self.connect(f"floating.member_{kname}:{var}", f"aeroelastic.member{k}:{var}")
1✔
539
                    
540
                    if modeling_options["flags"]["tower"]:
1✔
541
                        self.connect('floating.transition_piece_mass',  'aeroelastic.transition_piece_mass')
1✔
542
                        self.connect('floatingse.transition_piece_I',      'aeroelastic.transition_piece_I', src_indices=[0,1,2])
1✔
543
                        
544
                self.connect('airfoils.aoa',                    'aeroelastic.airfoils_aoa')
1✔
545
                self.connect('airfoils.Re',                     'aeroelastic.airfoils_Re')
1✔
546
                self.connect('xf.cl_interp_flaps',              'aeroelastic.airfoils_cl')
1✔
547
                self.connect('xf.cd_interp_flaps',              'aeroelastic.airfoils_cd')
1✔
548
                self.connect('xf.cm_interp_flaps',              'aeroelastic.airfoils_cm')
1✔
549
                self.connect('blade.interp_airfoils.r_thick_interp', 'aeroelastic.rthick')
1✔
550
                self.connect('blade.interp_airfoils.ac_interp', 'aeroelastic.ac')
1✔
551
                self.connect('rotorse.rhoA',                    'aeroelastic.beam:rhoA')
1✔
552
                self.connect('rotorse.EIxx',                    'aeroelastic.beam:EIxx')
1✔
553
                self.connect('rotorse.EIyy',                    'aeroelastic.beam:EIyy')
1✔
554
                self.connect('rotorse.rs.frame.flap_mode_shapes',       'aeroelastic.flap_mode_shapes')
1✔
555
                self.connect('rotorse.rs.frame.edge_mode_shapes',       'aeroelastic.edge_mode_shapes')
1✔
556
                self.connect('rotorse.rp.powercurve.V',                'aeroelastic.U')
1✔
557
                self.connect('rotorse.rp.powercurve.Omega',            'aeroelastic.Omega')
1✔
558
                self.connect('rotorse.rp.powercurve.pitch',            'aeroelastic.pitch')
1✔
559
                self.connect('rotorse.rp.powercurve.V_R25',            'aeroelastic.V_R25')
1✔
560
                self.connect('rotorse.rp.powercurve.rated_V',          'aeroelastic.Vrated')
1✔
561
                self.connect('rotorse.rp.powercurve.Ct_aero', 'aeroelastic.Ct_aero')
1✔
562
                self.connect('rotorse.rp.gust.V_gust',                 'aeroelastic.Vgust')
1✔
563
                self.connect('rotorse.wt_class.V_extreme1',             'aeroelastic.V_extreme1')
1✔
564
                self.connect('rotorse.wt_class.V_extreme50',            'aeroelastic.V_extreme50')
1✔
565
                self.connect('rotorse.wt_class.V_mean',                 'aeroelastic.V_mean_iec')
1✔
566
                self.connect('configuration.rated_power',       'aeroelastic.control_ratedPower')
1✔
567
                self.connect('control.max_TS',                  'aeroelastic.control_maxTS')
1✔
568
                self.connect('control.maxOmega',                'aeroelastic.control_maxOmega')
1✔
569
                self.connect('sse_tune.aeroperf_tables.pitch_vector','aeroelastic.pitch_vector')
1✔
570
                self.connect('sse_tune.aeroperf_tables.tsr_vector', 'aeroelastic.tsr_vector')
1✔
571
                self.connect('sse_tune.aeroperf_tables.U_vector', 'aeroelastic.U_vector')
1✔
572
                self.connect('sse_tune.aeroperf_tables.Cp',     'aeroelastic.Cp_aero_table')
1✔
573
                self.connect('sse_tune.aeroperf_tables.Ct',     'aeroelastic.Ct_aero_table')
1✔
574
                self.connect('sse_tune.aeroperf_tables.Cq',     'aeroelastic.Cq_aero_table')
1✔
575
                self.connect('xf.flap_angles',                  'aeroelastic.airfoils_Ctrl')
1✔
576

577
                if modeling_options['flags']['mooring']:
1✔
578
                    self.connect("mooring.line_diameter", "aeroelastic.line_diameter")
1✔
579
                    self.connect("mooring.line_mass_density", "aeroelastic.line_mass_density")
1✔
580
                    self.connect("mooring.line_stiffness", "aeroelastic.line_stiffness")
1✔
581
                    self.connect("mooring.line_transverse_added_mass", "aeroelastic.line_transverse_added_mass")
1✔
582
                    self.connect("mooring.line_tangential_added_mass", "aeroelastic.line_tangential_added_mass")
1✔
583
                    self.connect("mooring.line_transverse_drag", "aeroelastic.line_transverse_drag")
1✔
584
                    self.connect("mooring.line_tangential_drag", "aeroelastic.line_tangential_drag")
1✔
585
                    self.connect("mooring.mooring_nodes", "aeroelastic.nodes_location_full")
1✔
586
                    self.connect("mooring.nodes_mass", "aeroelastic.nodes_mass")
1✔
587
                    self.connect("mooring.nodes_volume", "aeroelastic.nodes_volume")
1✔
588
                    self.connect("mooring.nodes_added_mass", "aeroelastic.nodes_added_mass")
1✔
589
                    self.connect("mooring.nodes_drag_area", "aeroelastic.nodes_drag_area")
1✔
590
                    self.connect("mooring.unstretched_length", "aeroelastic.unstretched_length")
1✔
591
                    self.connect("mooring.node_names", "aeroelastic.node_names")
1✔
592
            
593
                # For fatigue
594
                self.connect('configuration.lifetime', 'aeroelastic.lifetime')
1✔
595
                self.connect('blade.fatigue.sparU_sigma_ult', 'aeroelastic.blade_sparU_ultstress')
1✔
596
                self.connect('blade.fatigue.sparU_wohlerexp', 'aeroelastic.blade_sparU_wohlerexp')
1✔
597
                self.connect('blade.fatigue.sparU_wohlerA', 'aeroelastic.blade_sparU_wohlerA')
1✔
598
                self.connect('blade.fatigue.sparL_sigma_ult', 'aeroelastic.blade_sparL_ultstress')
1✔
599
                self.connect('blade.fatigue.sparL_wohlerexp', 'aeroelastic.blade_sparL_wohlerexp')
1✔
600
                self.connect('blade.fatigue.sparL_wohlerA', 'aeroelastic.blade_sparL_wohlerA')
1✔
601
                self.connect('blade.fatigue.teU_sigma_ult', 'aeroelastic.blade_teU_ultstress')
1✔
602
                self.connect('blade.fatigue.teU_wohlerexp', 'aeroelastic.blade_teU_wohlerexp')
1✔
603
                self.connect('blade.fatigue.teU_wohlerA', 'aeroelastic.blade_teU_wohlerA')
1✔
604
                self.connect('blade.fatigue.teL_sigma_ult', 'aeroelastic.blade_teL_ultstress')
1✔
605
                self.connect('blade.fatigue.teL_wohlerexp', 'aeroelastic.blade_teL_wohlerexp')
1✔
606
                self.connect('blade.fatigue.teL_wohlerA', 'aeroelastic.blade_teL_wohlerA')
1✔
607
                self.connect('rotorse.rs.strains.axial_root_sparU_load2stress', 'aeroelastic.blade_root_sparU_load2stress')
1✔
608
                self.connect('rotorse.rs.strains.axial_root_sparL_load2stress', 'aeroelastic.blade_root_sparL_load2stress')
1✔
609
                self.connect('rotorse.rs.strains.axial_maxc_teU_load2stress', 'aeroelastic.blade_maxc_teU_load2stress')
1✔
610
                self.connect('rotorse.rs.strains.axial_maxc_teL_load2stress', 'aeroelastic.blade_maxc_teL_load2stress')
1✔
611
                self.connect('drivese.lss_wohler_exp', 'aeroelastic.lss_wohlerexp')
1✔
612
                self.connect('drivese.lss_wohler_A', 'aeroelastic.lss_wohlerA')
1✔
613
                self.connect('drivese.lss_Xt', 'aeroelastic.lss_ultstress')
1✔
614
                self.connect('drivese.lss_axial_load2stress', 'aeroelastic.lss_axial_load2stress')
1✔
615
                self.connect('drivese.lss_shear_load2stress', 'aeroelastic.lss_shear_load2stress')
1✔
616
                if modeling_options["flags"]["tower"]:
1✔
617
                    self.connect('towerse.member.wohler_exp', 'aeroelastic.tower_wohlerexp')
1✔
618
                    self.connect('towerse.member.wohler_A', 'aeroelastic.tower_wohlerA')
1✔
619
                    self.connect('towerse.member.sigma_ult', 'aeroelastic.tower_ultstress')
1✔
620
                    self.connect('towerse.member.axial_load2stress', 'aeroelastic.tower_axial_load2stress')
1✔
621
                    self.connect('towerse.member.shear_load2stress', 'aeroelastic.tower_shear_load2stress')
1✔
622
                if modeling_options["flags"]["monopile"]:
1✔
623
                    self.connect('fixedse.member.wohler_exp', 'aeroelastic.monopile_wohlerexp')
1✔
624
                    self.connect('fixedse.member.wohler_A', 'aeroelastic.monopile_wohlerA')
1✔
625
                    self.connect('fixedse.member.sigma_ult', 'aeroelastic.monopile_ultstress')
1✔
626
                    self.connect('fixedse.member.axial_load2stress', 'aeroelastic.monopile_axial_load2stress')
1✔
627
                    self.connect('fixedse.member.shear_load2stress', 'aeroelastic.monopile_shear_load2stress')
1✔
628

629
                # Connections to rotor load analysis
630
                self.connect('aeroelastic.blade_maxTD_Mx', 'rlds_post.m2pa.Mx')
1✔
631
                self.connect('aeroelastic.blade_maxTD_My', 'rlds_post.m2pa.My')
1✔
632
                self.connect('aeroelastic.blade_maxTD_Fz', 'rlds_post.strains.F3')
1✔
633

634
                self.connect("rotorse.rs.frame.alpha", "rlds_post.alpha")
1✔
635
                self.connect('rotorse.EA', 'rlds_post.strains.EA')
1✔
636
                self.connect('rotorse.A', 'rlds_post.strains.A')
1✔
637
                self.connect('blade.pa.chord_param',  'rlds_post.strains.chord')
1✔
638
                self.connect('rotorse.rs.frame.EI11', 'rlds_post.strains.EI11')
1✔
639
                self.connect('rotorse.rs.frame.EI22', 'rlds_post.strains.EI22')
1✔
640
                self.connect('rotorse.xu_spar', 'rlds_post.strains.xu_spar')
1✔
641
                self.connect('rotorse.xl_spar', 'rlds_post.strains.xl_spar')
1✔
642
                self.connect('rotorse.yu_spar', 'rlds_post.strains.yu_spar')
1✔
643
                self.connect('rotorse.yl_spar', 'rlds_post.strains.yl_spar')
1✔
644
                self.connect('rotorse.xu_te', 'rlds_post.strains.xu_te')
1✔
645
                self.connect('rotorse.xl_te', 'rlds_post.strains.xl_te')
1✔
646
                self.connect('rotorse.yu_te', 'rlds_post.strains.yu_te')
1✔
647
                self.connect('rotorse.yl_te', 'rlds_post.strains.yl_te')
1✔
648
                self.connect('blade.outer_shape_bem.s','rlds_post.constr.s')
1✔
649
                self.connect("blade.internal_structure_2d_fem.d_f", "rlds_post.brs.d_f")
1✔
650
                self.connect("blade.internal_structure_2d_fem.sigma_max", "rlds_post.brs.sigma_max")
1✔
651
                self.connect("blade.pa.chord_param", "rlds_post.brs.rootD", src_indices=[0])
1✔
652
                self.connect("blade.ps.layer_thickness_param", "rlds_post.brs.layer_thickness")
1✔
653
                self.connect("blade.internal_structure_2d_fem.layer_start_nd", "rlds_post.brs.layer_start_nd")
1✔
654
                self.connect("blade.internal_structure_2d_fem.layer_end_nd", "rlds_post.brs.layer_end_nd")
1✔
655

656
                # Connections to DriveSE
657
                if modeling_options['WISDEM']['DriveSE']['flag']:
1✔
658
                    self.connect('hub.diameter'                    , 'drivese_post.hub_diameter')
1✔
659
                    self.connect('hub.hub_in2out_circ'             , 'drivese_post.hub_in2out_circ')
1✔
660
                    self.connect('hub.flange_t2shell_t'            , 'drivese_post.flange_t2shell_t')
1✔
661
                    self.connect('hub.flange_OD2hub_D'             , 'drivese_post.flange_OD2hub_D')
1✔
662
                    self.connect('hub.flange_ID2flange_OD'         , 'drivese_post.flange_ID2flange_OD')
1✔
663
                    self.connect('hub.hub_stress_concentration'    , 'drivese_post.hub_stress_concentration')
1✔
664
                    self.connect('hub.n_front_brackets'            , 'drivese_post.n_front_brackets')
1✔
665
                    self.connect('hub.n_rear_brackets'             , 'drivese_post.n_rear_brackets')
1✔
666
                    self.connect('hub.clearance_hub_spinner'       , 'drivese_post.clearance_hub_spinner')
1✔
667
                    self.connect('hub.spin_hole_incr'              , 'drivese_post.spin_hole_incr')
1✔
668
                    self.connect('hub.pitch_system_scaling_factor' , 'drivese_post.pitch_system_scaling_factor')
1✔
669
                    self.connect("rotorse.wt_class.V_extreme50", "drivese.spinner_gust_ws")
1✔
670
                    self.connect('configuration.n_blades',          'drivese_post.n_blades')
1✔
671
                    self.connect("blade.high_level_blade_props.rotor_diameter", "drivese_post.rotor_diameter")
1✔
672
                    self.connect('configuration.upwind',       'drivese_post.upwind')
1✔
673
                    self.connect('control.minOmega' ,          'drivese_post.minimum_rpm')
1✔
674
                    self.connect('rotorse.rp.powercurve.rated_Omega',  'drivese_post.rated_rpm')
1✔
675
                    self.connect('rotorse.rp.powercurve.rated_Q',      'drivese_post.rated_torque')
1✔
676
                    self.connect('configuration.rated_power',  'drivese_post.machine_rating')    
1✔
677
                    self.connect('tower.diameter',             'drivese_post.D_top', src_indices=[-1])
1✔
678
                    self.connect('aeroelastic.hub_Fxyz',       'drivese_post.F_hub')
1✔
679
                    self.connect('aeroelastic.hub_Mxyz',       'drivese_post.M_hub')
1✔
680
                    self.connect('aeroelastic.max_RootMyb',     'drivese_post.pitch_system.BRFM')
1✔
681
                    self.connect('blade.pa.chord_param',        'drivese_post.blade_root_diameter', src_indices=[0])
1✔
682
                    self.connect('rotorse.blade_mass',          'drivese_post.blade_mass')
1✔
683
                    self.connect('rotorse.mass_all_blades',     'drivese_post.blades_mass')
1✔
684
                    self.connect('rotorse.I_all_blades',        'drivese_post.blades_I')
1✔
685

686
                    self.connect('nacelle.distance_hub_mb',           'drivese_post.L_h1')
1✔
687
                    self.connect('nacelle.distance_mb_mb',            'drivese_post.L_12')
1✔
688
                    self.connect('nacelle.L_generator',               'drivese_post.L_generator')
1✔
689
                    self.connect('nacelle.overhang',                  'drivese_post.overhang')
1✔
690
                    self.connect('nacelle.distance_tt_hub',           'drivese_post.drive_height')
1✔
691
                    self.connect('nacelle.uptilt',                    'drivese_post.tilt')
1✔
692
                    self.connect('nacelle.gear_ratio',                'drivese_post.gear_ratio')
1✔
693
                    self.connect('nacelle.mb1Type',                   'drivese_post.bear1.bearing_type')
1✔
694
                    self.connect('nacelle.mb2Type',                   'drivese_post.bear2.bearing_type')
1✔
695
                    self.connect('nacelle.lss_diameter',              'drivese_post.lss_diameter')
1✔
696
                    self.connect('nacelle.lss_wall_thickness',        'drivese_post.lss_wall_thickness')
1✔
697
                    if modeling_options['WISDEM']['DriveSE']['direct']:
1✔
698
                        self.connect('nacelle.nose_diameter',              'drivese_post.bear1.D_shaft', src_indices=[0])
1✔
699
                        self.connect('nacelle.nose_diameter',              'drivese_post.bear2.D_shaft', src_indices=[-1])
1✔
700
                    else:
701
                        self.connect('nacelle.lss_diameter',              'drivese_post.bear1.D_shaft', src_indices=[0])
1✔
702
                        self.connect('nacelle.lss_diameter',              'drivese_post.bear2.D_shaft', src_indices=[-1])
1✔
703
                    self.connect('nacelle.uptower',                   'drivese_post.uptower')
1✔
704
                    self.connect('nacelle.brake_mass_user',           'drivese_post.brake_mass_user')
1✔
705
                    self.connect('nacelle.hvac_mass_coeff',           'drivese_post.hvac_mass_coeff')
1✔
706
                    self.connect('nacelle.converter_mass_user',       'drivese_post.converter_mass_user')
1✔
707
                    self.connect('nacelle.transformer_mass_user',     'drivese_post.transformer_mass_user')
1✔
708

709
                    if modeling_options['WISDEM']['DriveSE']['direct']:
1✔
710
                        self.connect('nacelle.nose_diameter',             'drivese_post.nose_diameter') # only used in direct
1✔
711
                        self.connect('nacelle.nose_wall_thickness',       'drivese_post.nose_wall_thickness') # only used in direct
1✔
712
                        self.connect('nacelle.bedplate_wall_thickness',   'drivese_post.bedplate_wall_thickness') # only used in direct
1✔
713
                    else:
714
                        self.connect('nacelle.hss_length', 'drivese_post.L_hss') # only used in geared
1✔
715
                        self.connect('nacelle.hss_diameter', 'drivese_post.hss_diameter') # only used in geared
1✔
716
                        self.connect('nacelle.hss_wall_thickness', 'drivese_post.hss_wall_thickness') # only used in geared
1✔
717
                        self.connect('nacelle.hss_material', 'drivese_post.hss_material')
1✔
718
                        self.connect('nacelle.planet_numbers', 'drivese_post.planet_numbers') # only used in geared
1✔
719
                        self.connect('nacelle.gear_configuration', 'drivese_post.gear_configuration') # only used in geared
1✔
720
                        self.connect('nacelle.bedplate_flange_width', 'drivese_post.bedplate_flange_width') # only used in geared
1✔
721
                        self.connect('nacelle.bedplate_flange_thickness', 'drivese_post.bedplate_flange_thickness') # only used in geared
1✔
722
                        self.connect('nacelle.bedplate_web_thickness', 'drivese_post.bedplate_web_thickness') # only used in geared
1✔
723
                        self.connect("nacelle.gearbox_mass_user", "drivese_post.gearbox_mass_user")
1✔
724
                        self.connect("nacelle.gearbox_torque_density", "drivese_post.gearbox_torque_density")
1✔
725
                        self.connect("nacelle.gearbox_radius_user", "drivese_post.gearbox_radius_user")
1✔
726
                        self.connect("nacelle.gearbox_length_user", "drivese_post.gearbox_length_user")
1✔
727
                            
728
                    self.connect('hub.hub_material',                  'drivese_post.hub_material')
1✔
729
                    self.connect('hub.spinner_material',              'drivese_post.spinner_material')
1✔
730
                    self.connect('nacelle.lss_material',              'drivese_post.lss_material')
1✔
731
                    self.connect('nacelle.bedplate_material',         'drivese_post.bedplate_material')
1✔
732
                    self.connect('materials.name',                    'drivese_post.material_names')
1✔
733
                    self.connect('materials.E',                       'drivese_post.E_mat')
1✔
734
                    self.connect('materials.G',                       'drivese_post.G_mat')
1✔
735
                    self.connect('materials.rho',                     'drivese_post.rho_mat')
1✔
736
                    self.connect('materials.sigma_y',                 'drivese_post.Xy_mat')
1✔
737
                    self.connect("materials.Xt",                      "drivese_post.Xt_mat")
1✔
738
                    self.connect("materials.wohler_exp",              "drivese_post.wohler_exp_mat")
1✔
739
                    self.connect("materials.wohler_intercept",        "drivese_post.wohler_A_mat")
1✔
740
                    self.connect('materials.unit_cost',               'drivese_post.unit_cost_mat')
1✔
741

742
                    if modeling_options['flags']['generator']:
1✔
743

744
                        self.connect('generator.B_r'          , 'drivese_post.generator.B_r')
1✔
745
                        self.connect('generator.P_Fe0e'       , 'drivese_post.generator.P_Fe0e')
1✔
746
                        self.connect('generator.P_Fe0h'       , 'drivese_post.generator.P_Fe0h')
1✔
747
                        self.connect('generator.S_N'          , 'drivese_post.generator.S_N')
1✔
748
                        self.connect('generator.alpha_p'      , 'drivese_post.generator.alpha_p')
1✔
749
                        self.connect('generator.b_r_tau_r'    , 'drivese_post.generator.b_r_tau_r')
1✔
750
                        self.connect('generator.b_ro'         , 'drivese_post.generator.b_ro')
1✔
751
                        self.connect('generator.b_s_tau_s'    , 'drivese_post.generator.b_s_tau_s')
1✔
752
                        self.connect('generator.b_so'         , 'drivese_post.generator.b_so')
1✔
753
                        self.connect('generator.cofi'         , 'drivese_post.generator.cofi')
1✔
754
                        self.connect('generator.freq'         , 'drivese_post.generator.freq')
1✔
755
                        self.connect('generator.h_i'          , 'drivese_post.generator.h_i')
1✔
756
                        self.connect('generator.h_sy0'        , 'drivese_post.generator.h_sy0')
1✔
757
                        self.connect('generator.h_w'          , 'drivese_post.generator.h_w')
1✔
758
                        self.connect('generator.k_fes'        , 'drivese_post.generator.k_fes')
1✔
759
                        self.connect('generator.k_fillr'      , 'drivese_post.generator.k_fillr')
1✔
760
                        self.connect('generator.k_fills'      , 'drivese_post.generator.k_fills')
1✔
761
                        self.connect('generator.k_s'          , 'drivese_post.generator.k_s')
1✔
762
                        self.connect('generator.m'            , 'drivese_post.generator.m')
1✔
763
                        self.connect('generator.mu_0'         , 'drivese_post.generator.mu_0')
1✔
764
                        self.connect('generator.mu_r'         , 'drivese_post.generator.mu_r')
1✔
765
                        self.connect('generator.p'            , 'drivese_post.generator.p')
1✔
766
                        self.connect('generator.phi'          , 'drivese_post.generator.phi')
1✔
767
                        self.connect('generator.q1'           , 'drivese_post.generator.q1')
1✔
768
                        self.connect('generator.q2'           , 'drivese_post.generator.q2')
1✔
769
                        self.connect('generator.ratio_mw2pp'  , 'drivese_post.generator.ratio_mw2pp')
1✔
770
                        self.connect('generator.resist_Cu'    , 'drivese_post.generator.resist_Cu')
1✔
771
                        self.connect('generator.sigma'        , 'drivese_post.generator.sigma')
1✔
772
                        self.connect('generator.y_tau_p'      , 'drivese_post.generator.y_tau_p')
1✔
773
                        self.connect('generator.y_tau_pr'     , 'drivese_post.generator.y_tau_pr')
1✔
774

775
                        self.connect('generator.I_0'          , 'drivese_post.generator.I_0')
1✔
776
                        self.connect('generator.d_r'          , 'drivese_post.generator.d_r')
1✔
777
                        self.connect('generator.h_m'          , 'drivese_post.generator.h_m')
1✔
778
                        self.connect('generator.h_0'          , 'drivese_post.generator.h_0')
1✔
779
                        self.connect('generator.h_s'          , 'drivese_post.generator.h_s')
1✔
780
                        self.connect('generator.len_s'        , 'drivese_post.generator.len_s')
1✔
781
                        self.connect('generator.n_r'          , 'drivese_post.generator.n_r')
1✔
782
                        self.connect('generator.rad_ag'       , 'drivese_post.generator.rad_ag')
1✔
783
                        self.connect('generator.t_wr'         , 'drivese_post.generator.t_wr')
1✔
784

785
                        self.connect('generator.n_s'          , 'drivese_post.generator.n_s')
1✔
786
                        self.connect('generator.b_st'         , 'drivese_post.generator.b_st')
1✔
787
                        self.connect('generator.d_s'          , 'drivese_post.generator.d_s')
1✔
788
                        self.connect('generator.t_ws'         , 'drivese_post.generator.t_ws')
1✔
789

790
                        self.connect('generator.rho_Copper'   , 'drivese_post.generator.rho_Copper')
1✔
791
                        self.connect('generator.rho_Fe'       , 'drivese_post.generator.rho_Fe')
1✔
792
                        self.connect('generator.rho_Fes'      , 'drivese_post.generator.rho_Fes')
1✔
793
                        self.connect('generator.rho_PM'       , 'drivese_post.generator.rho_PM')
1✔
794

795
                        self.connect('generator.C_Cu'         , 'drivese_post.generator.C_Cu')
1✔
796
                        self.connect('generator.C_Fe'         , 'drivese_post.generator.C_Fe')
1✔
797
                        self.connect('generator.C_Fes'        , 'drivese_post.generator.C_Fes')
1✔
798
                        self.connect('generator.C_PM'         , 'drivese_post.generator.C_PM')
1✔
799

800
                        if modeling_options['WISDEM']['GeneratorSE']['type'] in ['pmsg_outer']:
1✔
801
                            self.connect('generator.N_c'          , 'drivese_post.generator.N_c')
1✔
802
                            self.connect('generator.b'            , 'drivese_post.generator.b')
1✔
803
                            self.connect('generator.c'            , 'drivese_post.generator.c')
1✔
804
                            self.connect('generator.E_p'          , 'drivese_post.generator.E_p')
1✔
805
                            self.connect('generator.h_yr'         , 'drivese_post.generator.h_yr')
1✔
806
                            self.connect('generator.h_ys'         , 'drivese_post.generator.h_ys')
1✔
807
                            self.connect('generator.h_sr'         , 'drivese_post.generator.h_sr')
1✔
808
                            self.connect('generator.h_ss'         , 'drivese_post.generator.h_ss')
1✔
809
                            self.connect('generator.t_r'          , 'drivese_post.generator.t_r')
1✔
810
                            self.connect('generator.t_s'          , 'drivese_post.generator.t_s')
1✔
811

812
                            self.connect('generator.u_allow_pcent', 'drivese_post.generator.u_allow_pcent')
1✔
813
                            self.connect('generator.y_allow_pcent', 'drivese_post.generator.y_allow_pcent')
1✔
814
                            self.connect('generator.z_allow_deg'  , 'drivese_post.generator.z_allow_deg')
1✔
815
                            self.connect('generator.B_tmax'       , 'drivese_post.generator.B_tmax')
1✔
816
                            self.connect('rotorse.rp.powercurve.rated_mech', 'drivese_post.generator.P_mech')
1✔
817

818
                        if modeling_options['WISDEM']['GeneratorSE']['type'] in ['eesg','pmsg_arms','pmsg_disc']:
1✔
819
                            self.connect('generator.tau_p'        , 'drivese_post.generator.tau_p')
×
820
                            self.connect('generator.h_ys'         , 'drivese_post.generator.h_ys')
×
821
                            self.connect('generator.h_yr'         , 'drivese_post.generator.h_yr')
×
822
                            self.connect('generator.b_arm'        , 'drivese_post.generator.b_arm')
×
823

824
                        elif modeling_options['WISDEM']['GeneratorSE']['type'] in ['scig','dfig']:
1✔
825
                            self.connect('generator.B_symax'      , 'drivese_post.generator.B_symax')
1✔
826
                            self.connect('generator.S_Nmax'      , 'drivese_post.generator.S_Nmax')
1✔
827

828
                        if modeling_options['WISDEM']['DriveSE']['direct']:
1✔
829
                            self.connect('nacelle.nose_diameter',             'drivese_post.generator.D_nose', src_indices=[-1])
1✔
830
                            self.connect('nacelle.lss_diameter',              'drivese_post.generator.D_shaft', src_indices=[0])
1✔
831
                        else:
832
                            self.connect('nacelle.hss_diameter',              'drivese_post.generator.D_shaft', src_indices=[-1])
1✔
833

834
                    else:
835
                        self.connect('generator.generator_mass_user', 'drivese_post.generator_mass_user')
×
836
                        self.connect('generator.generator_efficiency_user', 'drivese_post.generator_efficiency_user')
×
837

838
                # Connections to TowerSE
839
                if modeling_options["flags"]["tower"]:
1✔
840
                    tow_params = ["z_full","outer_diameter_full","t_full",
1✔
841
                                  "E_full","G_full","rho_full","sigma_y_full",
842
                                  "section_A", "section_Asx","section_Asy",
843
                                  "section_Ixx", "section_Iyy", "section_J0",
844
                                  "section_rho", "section_E", "section_G", "section_L",
845
                                  ]
846
                    for k in tow_params:
1✔
847
                        self.connect(f'towerse.{k}', f'towerse_post.{k}')
1✔
848
                    self.connect("towerse.env.qdyn", "towerse_post.qdyn")
1✔
849
                    self.connect("tower_grid.height", "towerse_post.bending_height")
1✔
850
                    
851
                    self.connect("aeroelastic.tower_maxMy_Fz", "towerse_post.cylinder_Fz")
1✔
852
                    self.connect("aeroelastic.tower_maxMy_Fx", "towerse_post.cylinder_Vx")
1✔
853
                    self.connect("aeroelastic.tower_maxMy_Fy", "towerse_post.cylinder_Vy")
1✔
854
                    self.connect("aeroelastic.tower_maxMy_Mx", "towerse_post.cylinder_Mxx")
1✔
855
                    self.connect("aeroelastic.tower_maxMy_My", "towerse_post.cylinder_Myy")
1✔
856
                    self.connect("aeroelastic.tower_maxMy_Mz", "towerse_post.cylinder_Mzz")
1✔
857

858
                if modeling_options["flags"]["monopile"]:
1✔
859
                    mono_params = ["z_full","outer_diameter_full","t_full",
1✔
860
                                  "E_full","G_full","rho_full","sigma_y_full"]
861
                    for k in mono_params:
1✔
862
                        self.connect(f'fixedse.{k}', f'fixedse_post.{k}')
1✔
863
                    self.connect("fixedse.env.qdyn", "fixedse_post.qdyn")
1✔
864
                    self.connect("monopile.height", "fixedse_post.bending_height")
1✔
865

866
                    self.connect("aeroelastic.monopile_maxMy_Fz", "fixedse_post.cylinder_Fz")
1✔
867
                    self.connect("aeroelastic.monopile_maxMy_Fx", "fixedse_post.cylinder_Vx")
1✔
868
                    self.connect("aeroelastic.monopile_maxMy_Fy", "fixedse_post.cylinder_Vy")
1✔
869
                    self.connect("aeroelastic.monopile_maxMy_Mx", "fixedse_post.cylinder_Mxx")
1✔
870
                    self.connect("aeroelastic.monopile_maxMy_My", "fixedse_post.cylinder_Myy")
1✔
871
                    self.connect("aeroelastic.monopile_maxMy_Mz", "fixedse_post.cylinder_Mzz")
1✔
872

873
                #self.connect('yield_stress',            'tow.sigma_y') # TODO- materials
874
                #self.connect('max_taper_ratio',         'max_taper') # TODO- 
875
                #self.connect('min_diameter_thickness_ratio', 'min_d_to_t')
876
                                        
877
                # Connections to turbine constraints
878
                self.connect('configuration.rotor_orientation', 'tcons_post.rotor_orientation')
1✔
879
                self.connect('aeroelastic.max_TipDxc',          'tcons_post.tip_deflection')
1✔
880
                self.connect("blade.high_level_blade_props.rotor_radius", "tcons_post.Rtip")
1✔
881
                self.connect('blade.outer_shape_bem.ref_axis',  'tcons_post.ref_axis_blade')
1✔
882
                self.connect('hub.cone',                        'tcons_post.precone')
1✔
883
                self.connect('nacelle.uptilt',                  'tcons_post.tilt')
1✔
884
                self.connect('nacelle.overhang',                'tcons_post.overhang')
1✔
885
                self.connect('tower.ref_axis',                  'tcons_post.ref_axis_tower')
1✔
886
                self.connect('tower.diameter',                  'tcons_post.outer_diameter_full')
1✔
887
                
888
            else:  # connections from outside WISDEM
889
                self.connect('rosco_turbine.v_rated',               'aeroelastic.Vrated')
1✔
890
                self.connect('rosco_turbine.R',                     'aeroelastic.Rtip')
1✔
891
                self.connect('rosco_turbine.hub_height',            'aeroelastic.hub_height')
1✔
892
                self.connect('rosco_turbine.twr_freq',              'sse_tune.tune_rosco.twr_freq')
1✔
893
            
894
            # Inputs to plantfinancese from wt group
895
            if not modeling_options['Level3']['from_openfast']:
1✔
896

897
                # Connect computed AEP only if DLC 1.1 is used, otherwise use rotorse
898
                if modeling_options['DLC_driver']['n_ws_dlc11'] > 0:
1✔
899
                    self.connect('aeroelastic.AEP', 'financese_post.turbine_aep')
1✔
900
                else:
901
                    self.connect('rotorse.rp.AEP', 'financese_post.turbine_aep')
1✔
902

903
                self.connect('tcc.turbine_cost_kW',     'financese_post.tcc_per_kW')
1✔
904
                if modeling_options["flags"]["bos"]:
1✔
905
                    if modeling_options['flags']['offshore']:
1✔
906
                        self.connect('orbit.total_capex_kW',    'financese_post.bos_per_kW')
1✔
907
                    else:
908
                        self.connect('landbosse.bos_capex_kW',  'financese_post.bos_per_kW')
1✔
909
                else:
910
                    self.connect("costs.bos_per_kW", "financese_post.bos_per_kW")
1✔
911

912
            # Inputs to plantfinancese from input yaml
913
            if modeling_options['flags']['control'] and not modeling_options['Level3']['from_openfast']:
1✔
914
                self.connect('configuration.rated_power',     'financese_post.machine_rating')
1✔
915

916
            if not modeling_options['Level3']['from_openfast']:    
1✔
917
                self.connect('costs.turbine_number',    'financese_post.turbine_number')
1✔
918
                self.connect('costs.opex_per_kW',       'financese_post.opex_per_kW')
1✔
919
                self.connect('costs.offset_tcc_per_kW', 'financese_post.offset_tcc_per_kW')
1✔
920
                self.connect('costs.wake_loss_factor',  'financese_post.wake_loss_factor')
1✔
921
                self.connect('costs.fixed_charge_rate', 'financese_post.fixed_charge_rate')
1✔
922

923
            if modeling_options['DLC_driver']['n_ws_dlc11'] > 0:
1✔
924
                self.connect('aeroelastic.AEP',     'outputs_2_screen_weis.aep')
1✔
925

926
            # Connections to outputs to screen
927
            if not modeling_options['Level3']['from_openfast']:
1✔
928
                self.connect('financese_post.lcoe',          'outputs_2_screen_weis.lcoe')
1✔
929

930
                self.connect('rotorse.blade_mass',  'outputs_2_screen_weis.blade_mass')
1✔
931
                self.connect('aeroelastic.max_TipDxc', 'outputs_2_screen_weis.tip_deflection')
1✔
932

933
            if modeling_options['General']['openfast_configuration']['model_only'] == False:
1✔
934
                self.connect('aeroelastic.DEL_RootMyb',        'outputs_2_screen_weis.DEL_RootMyb')
1✔
935
                self.connect('aeroelastic.DEL_TwrBsMyt',       'outputs_2_screen_weis.DEL_TwrBsMyt')
1✔
936
                self.connect('aeroelastic.rotor_overspeed',    'outputs_2_screen_weis.rotor_overspeed')
1✔
937
                self.connect('aeroelastic.Std_PtfmPitch',      'outputs_2_screen_weis.Std_PtfmPitch')
1✔
938
                self.connect('aeroelastic.Max_PtfmPitch',      'outputs_2_screen_weis.Max_PtfmPitch')
1✔
939
                self.connect('tune_rosco_ivc.omega_pc',        'outputs_2_screen_weis.omega_pc')
1✔
940
                self.connect('tune_rosco_ivc.zeta_pc',         'outputs_2_screen_weis.zeta_pc')
1✔
941
                self.connect('tune_rosco_ivc.omega_vs',        'outputs_2_screen_weis.omega_vs')
1✔
942
                self.connect('tune_rosco_ivc.zeta_vs',         'outputs_2_screen_weis.zeta_vs')
1✔
943
                self.connect('tune_rosco_ivc.Kp_float',        'outputs_2_screen_weis.Kp_float')
1✔
944
                self.connect('tune_rosco_ivc.ptfm_freq',       'outputs_2_screen_weis.ptfm_freq')
1✔
945
                self.connect('tune_rosco_ivc.flp_kp_norm',       'outputs_2_screen_weis.flp_kp_norm')
1✔
946
                self.connect('tune_rosco_ivc.flp_tau',        'outputs_2_screen_weis.flp_tau')
1✔
947
                self.connect('tune_rosco_ivc.IPC_Kp1p',        'outputs_2_screen_weis.IPC_Kp1p')
1✔
948
                self.connect('tune_rosco_ivc.IPC_Ki1p',        'outputs_2_screen_weis.IPC_Ki1p')
1✔
949
                self.connect('dac_ivc.te_flap_end',            'outputs_2_screen_weis.te_flap_end')
1✔
950
                if modeling_options['OL2CL']['flag']:
1✔
951
                    self.connect('aeroelastic.OL2CL_pitch',      'outputs_2_screen_weis.OL2CL_pitch')
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc