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

WISDEM / WEIS / 11975795765

22 Nov 2024 03:50PM UTC coverage: 78.802% (-0.9%) from 79.662%
11975795765

push

github

web-flow
WEIS v1.4 (#322)

* Viz tool integration (#301)

* utils update for viz tool

* hotfix for length error in viz utils

* slightly improved hotfix

* trim edge case

* working integration with weis

* add text field for reloading diff yaml file

* f-string typo fix to pass py3.11 unit test

* remove duplicated fields on raft opt

* elevate 'weis_viz' to a command within the conda env

* add optimization type

* reformating vizgen and adding 'weis_viz_input_gen' as a command

---------

Co-authored-by: Cory Frontin <cory.frontin@nrel.gov>
Co-authored-by: sryu <Sora.Ryu@nrel.gov>
Co-authored-by: Sora Ryu <sryu@x1007c0s0b0n0.hsn.cm.kestrel.hpc.nrel.gov>
Co-authored-by: Sora Ryu <sryu@kl3.head.cm.kestrel.hpc.nrel.gov>

* bug fix in vizFileGen and changes to handle Jul 2024 Kestrel updates (#306)

* bug fix in vizFileGen and fixes to handle Jul 2024 Kestrel updates

* change type settings and default channels

* match type with WEIS level

* minor update on type setting - dlc

---------

Co-authored-by: Sora Ryu <sryu@x1000c0s0b0n0.hsn.cm.kestrel.hpc.nrel.gov>
Co-authored-by: Sora Ryu <sryu@kl2.head.cm.kestrel.hpc.nrel.gov>

* no need to manipulate turbsim grid for olaf anymore (#313)

* Debug arg parsing error while launching the app & Contribute Initial Documentation (#307)

* fix bug of args parse while running app

* delete unnecessary prints

* change horizontal subplots to vertical ones

* initial documentation

* delete readme file

* minor changes on graph layout

* update on kestrel set up

* merge weis viz docs into existing weis docs

* delete initial weis viz documentation

* update on docs after changing opt type setting

* Revise documentation

---------

Co-authored-by: sryu <Sora.Ryu@nrel.gov>
Co-authored-by: dzalkind <dzalkind@nrel.gov>

* Remove duplicate numpydoc

* Sync readthedocs yaml with WISDEM

* Add numpydoc to environment

* Set up readthedocs inputs... (continued)

43 of 375 new or added lines in 12 files covered. (11.47%)

6 existing lines in 3 files now uncovered.

21658 of 27484 relevant lines covered (78.8%)

0.79 hits per line

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

97.29
/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
        tune_rosco_ivc = om.IndepVarComp()
1✔
59
        if modeling_options['ROSCO']['linmodel_tuning']['type'] == 'robust':
1✔
60
            n_PC = 1
×
61
        else:
62
            n_PC = len(modeling_options['ROSCO']['U_pc'])
1✔
63
        tune_rosco_ivc.add_output('omega_pc',         val=np.zeros(n_PC), units='rad/s',     desc='Pitch controller natural frequency')
1✔
64
        tune_rosco_ivc.add_output('zeta_pc',          val=np.zeros(n_PC),                    desc='Pitch controller damping ratio')
1✔
65
        tune_rosco_ivc.add_output('omega_vs',         val=0.0, units='rad/s',     desc='Generator torque controller natural frequency')
1✔
66
        tune_rosco_ivc.add_output('zeta_vs',          val=0.0,                    desc='Generator torque controller damping ratio')
1✔
67
        tune_rosco_ivc.add_output('flp_kp_norm',      val=0.0,                    desc='Flap controller normalized gain')
1✔
68
        tune_rosco_ivc.add_output('flp_tau',          val=0.0, units='s',         desc='Flap controller integral gain time constant')
1✔
69
        tune_rosco_ivc.add_output('IPC_Kp1p',         val=0.0, units='s',         desc='Individual pitch controller 1p proportional gain')
1✔
70
        tune_rosco_ivc.add_output('IPC_Ki1p',         val=0.0,                    desc='Individual pitch controller 1p integral gain')
1✔
71
        tune_rosco_ivc.add_output('stability_margin', val=0.0,                    desc='Stability margin for robust tuning')
1✔
72
        tune_rosco_ivc.add_output('omega_pc_max',     val=0.0,                    desc='Maximum allowable omega for robust tuning')
1✔
73
        # optional inputs - not connected right now!!
74
        tune_rosco_ivc.add_output('max_pitch',        val=0.0, units='rad',       desc='Maximum pitch angle , {default = 90 degrees}')
1✔
75
        tune_rosco_ivc.add_output('min_pitch',        val=0.0, units='rad',       desc='Minimum pitch angle [rad], {default = 0 degrees}')
1✔
76
        tune_rosco_ivc.add_output('vs_minspd',        val=0.0, units='rad/s',     desc='Minimum rotor speed [rad/s], {default = 0 rad/s}')
1✔
77
        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✔
78
        tune_rosco_ivc.add_output('ss_vsgain',        val=0.0,                    desc='Torque controller setpoint smoother gain bias percentage [%, <= 1 ], {default = 100%}')
1✔
79
        tune_rosco_ivc.add_output('ss_pcgain',        val=0.0,                    desc='Pitch controller setpoint smoother gain bias percentage  [%, <= 1 ], {default = 0.1%}')
1✔
80
        tune_rosco_ivc.add_output('ps_percent',       val=0.0,                    desc='Percent peak shaving  [%, <= 1 ], {default = 80%}')
1✔
81
        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✔
82
        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✔
83
        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✔
84
        tune_rosco_ivc.add_output('Ki_flap',          val=0.0,                    desc='Integral term of the PI controller for the trailing-edge flaps')
1✔
85
        tune_rosco_ivc.add_output('twr_freq',         val=3.2, units='rps',     desc='Tower natural frequency')
1✔
86
        tune_rosco_ivc.add_output('ptfm_freq',        val=0.2, units='rad/s',     desc='Platform natural frequency')
1✔
87
        tune_rosco_ivc.add_output('Kp_float',         val=0.0, units='s',         desc='Floating feedback gain')
1✔
88

89
        self.add_subsystem('tune_rosco_ivc',tune_rosco_ivc)
1✔
90

91
        # Analysis components
92
        self.add_subsystem('wisdem',   wisdemPark(modeling_options = modeling_options, opt_options = opt_options), promotes=['*'])
1✔
93

94
        # XFOIL
95
        self.add_subsystem('xf',        RunXFOIL(modeling_options = modeling_options, opt_options = opt_options)) # Recompute polars with xfoil (for flaps)
1✔
96
        # Connections to run xfoil for te flaps
97
        if not modeling_options['Level3']['from_openfast']:
1✔
98
            self.connect('blade.pa.chord_param',                  'xf.chord')
1✔
99
            self.connect('blade.outer_shape_bem.s',               'xf.s')
1✔
100
            self.connect('blade.interp_airfoils.coord_xy_interp', 'xf.coord_xy_interp')
1✔
101
            self.connect('airfoils.aoa',                          'xf.aoa')
1✔
102
            self.connect("blade.high_level_blade_props.r_blade",  "xf.r")
1✔
103
            self.connect('dac_ivc.te_flap_end',                   'xf.span_end')
1✔
104
            self.connect('dac_ivc.te_flap_ext',                   'xf.span_ext')
1✔
105
            self.connect('dac_ivc.chord_start',                   'xf.chord_start')
1✔
106
            self.connect('dac_ivc.delta_max_pos',                 'xf.delta_max_pos')
1✔
107
            self.connect('dac_ivc.delta_max_neg',                 'xf.delta_max_neg')
1✔
108
            self.connect('env.speed_sound_air',                   'xf.speed_sound_air')
1✔
109
            self.connect('env.rho_air',                           'xf.rho_air')
1✔
110
            self.connect('env.mu_air',                            'xf.mu_air')
1✔
111
            self.connect('control.rated_TSR',                     'xf.rated_TSR')
1✔
112
            if modeling_options['flags']['control']:
1✔
113
                self.connect('control.max_TS',                        'xf.max_TS')
1✔
114
            self.connect("af_3d.cl_corrected", "xf.cl_interp")
1✔
115
            self.connect("af_3d.cd_corrected", "xf.cd_interp")
1✔
116
            self.connect("af_3d.cm_corrected", "xf.cm_interp")
1✔
117

118
        # ROSCO can be used at all levels
119
        if modeling_options['ROSCO']['flag']:
1✔
120
            if modeling_options['Level3']['from_openfast']:  # not using WISDEM turbine info
1✔
121
                self.add_subsystem('rosco_turbine',          ROSCO_Turbine(modeling_options = modeling_options)) # ROSCO tuning
1✔
122

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

125
            if not modeling_options['Level3']['from_openfast']:     #from WISDEM models
1✔
126
                self.connect('rotorse.rp.powercurve.rated_V',         ['sse_tune.tune_rosco.v_rated'])
1✔
127
                #self.connect('rotorse.rp.gust.V_gust',                ['freq_rotor.aero_gust.V_load', 'freq_rotor.aero_hub_loads.V_load'])
128
                self.connect('rotorse.rp.powercurve.rated_Omega',     'sse_tune.tune_rosco.rated_rotor_speed')
1✔
129
                #self.connect('rotorse.rp.powercurve.rated_pitch',     ['freq_rotor.pitch_load', 'freq_rotor.tot_loads_gust.aeroloads_pitch'])
130
                self.connect('rotorse.rp.powercurve.rated_Q',          'sse_tune.tune_rosco.rated_torque')
1✔
131
                
132
                self.connect("blade.high_level_blade_props.r_blade",  "sse_tune.r")
1✔
133
                self.connect("blade.high_level_blade_props.rotor_radius", "sse_tune.Rtip")
1✔
134
                self.connect('hub.radius',                     'sse_tune.Rhub')
1✔
135
                self.connect("high_level_tower_props.hub_height", "sse_tune.hub_height")
1✔
136
                self.connect('hub.cone',                       'sse_tune.precone')
1✔
137
                self.connect('nacelle.uptilt',                 'sse_tune.tilt')
1✔
138
                self.connect('airfoils.aoa',                   'sse_tune.airfoils_aoa')
1✔
139
                self.connect('airfoils.Re',                    'sse_tune.airfoils_Re')
1✔
140
                self.connect('xf.cl_interp_flaps',             'sse_tune.airfoils_cl')
1✔
141
                self.connect('xf.cd_interp_flaps',             'sse_tune.airfoils_cd')
1✔
142
                self.connect('xf.cm_interp_flaps',             'sse_tune.airfoils_cm')
1✔
143
                self.connect('configuration.n_blades',         'sse_tune.nBlades')
1✔
144
                self.connect('env.rho_air',                    'sse_tune.rho')
1✔
145
                self.connect('env.mu_air',                     'sse_tune.mu')
1✔
146
                self.connect('blade.pa.chord_param',           'sse_tune.chord')
1✔
147
                self.connect('blade.pa.twist_param',           'sse_tune.theta')
1✔
148

149
                self.connect('control.V_in' ,                   'sse_tune.v_min')
1✔
150
                self.connect('control.V_out' ,                  'sse_tune.v_max')
1✔
151
                self.connect("blade.high_level_blade_props.prebend", 'sse_tune.precurve')
1✔
152
                self.connect("blade.high_level_blade_props.prebendTip", 'sse_tune.precurveTip')
1✔
153
                self.connect("blade.high_level_blade_props.presweep", 'sse_tune.presweep')
1✔
154
                self.connect("blade.high_level_blade_props.presweepTip", 'sse_tune.presweepTip')
1✔
155
                self.connect('xf.flap_angles',                  'sse_tune.airfoils_Ctrl')
1✔
156
                self.connect('control.minOmega',                'sse_tune.omega_min')
1✔
157
                self.connect('control.rated_TSR',               'sse_tune.tsr_operational')
1✔
158
                self.connect('configuration.rated_power',       'sse_tune.rated_power')
1✔
159

160
                self.connect('nacelle.gear_ratio',              'sse_tune.tune_rosco.gear_ratio')
1✔
161
                self.connect("blade.high_level_blade_props.rotor_radius", "sse_tune.tune_rosco.R")
1✔
162
                self.connect('rotorse.I_all_blades',            'sse_tune.tune_rosco.rotor_inertia', src_indices=[0])
1✔
163
                self.connect('rotorse.rs.frame.flap_mode_freqs','sse_tune.tune_rosco.flap_freq', src_indices=[0])
1✔
164
                self.connect('rotorse.rs.frame.edge_mode_freqs','sse_tune.tune_rosco.edge_freq', src_indices=[0])
1✔
165
                self.connect('rotorse.rp.powercurve.rated_efficiency', 'sse_tune.tune_rosco.generator_efficiency')
1✔
166
                self.connect('tower_grid.height',               'sse_tune.tune_rosco.TowerHt')
1✔
167
                self.connect('nacelle.gearbox_efficiency',      'sse_tune.tune_rosco.gearbox_efficiency')
1✔
168
                self.connect('control.max_pitch_rate' ,         'sse_tune.tune_rosco.max_pitch_rate')
1✔
169
                self.connect('control.max_torque_rate' ,        'sse_tune.tune_rosco.max_torque_rate')
1✔
170

171
            else:       # reading openfast model using ROSCO toolbox via rosco_turbine
172
                self.connect('rosco_turbine.v_rated'            ,   ['sse_tune.tune_rosco.v_rated'])
1✔
173
                self.connect('rosco_turbine.rated_rotor_speed'  ,   'sse_tune.tune_rosco.rated_rotor_speed')
1✔
174
                self.connect('rosco_turbine.rated_torque'       ,   'sse_tune.tune_rosco.rated_torque')
1✔
175
                self.connect('rosco_turbine.rotor_inertia',         'sse_tune.tune_rosco.rotor_inertia', src_indices=[0])
1✔
176
                self.connect('rosco_turbine.flap_freq',             'sse_tune.tune_rosco.flap_freq', src_indices=[0])
1✔
177
                self.connect('rosco_turbine.edge_freq',             'sse_tune.tune_rosco.edge_freq', src_indices=[0])
1✔
178
                self.connect('rosco_turbine.generator_efficiency',  'sse_tune.tune_rosco.generator_efficiency')                
1✔
179
                self.connect('rosco_turbine.rho',                   'sse_tune.rho')
1✔
180
                self.connect('rosco_turbine.R',                     'sse_tune.tune_rosco.R')
1✔
181
                self.connect('rosco_turbine.rated_power',           'sse_tune.rated_power')
1✔
182
                self.connect('rosco_turbine.v_min' ,                'sse_tune.v_min')
1✔
183
                self.connect('rosco_turbine.v_max' ,                'sse_tune.v_max')
1✔
184
                self.connect('rosco_turbine.max_pitch_rate' ,       'sse_tune.tune_rosco.max_pitch_rate')
1✔
185
                self.connect('rosco_turbine.max_torque_rate' ,      'sse_tune.tune_rosco.max_torque_rate')
1✔
186
                self.connect('rosco_turbine.omega_min',             'sse_tune.omega_min')
1✔
187
                self.connect('rosco_turbine.tsr_operational',       'sse_tune.tsr_operational')
1✔
188
            
189
                # Performance tables
190
                self.connect('rosco_turbine.Cp_table',        'sse_tune.tune_rosco.Cp_table')
1✔
191
                self.connect('rosco_turbine.Ct_table',        'sse_tune.tune_rosco.Ct_table')
1✔
192
                self.connect('rosco_turbine.Cq_table',        'sse_tune.tune_rosco.Cq_table')
1✔
193
                self.connect('rosco_turbine.pitch_vector',    'sse_tune.tune_rosco.pitch_vector')
1✔
194
                self.connect('rosco_turbine.tsr_vector',      'sse_tune.tune_rosco.tsr_vector')
1✔
195
                self.connect('rosco_turbine.U_vector',        'sse_tune.tune_rosco.U_vector')
1✔
196

197
                self.connect('rosco_turbine.gear_ratio',              'sse_tune.tune_rosco.gear_ratio')
1✔
198
                self.connect('rosco_turbine.gearbox_efficiency',      'sse_tune.tune_rosco.gearbox_efficiency')
1✔
199

200
                self.connect('rosco_turbine.TowerHt',               'sse_tune.tune_rosco.TowerHt')
1✔
201

202

203
            # ROSCO Independent Vars
204
            self.connect('tune_rosco_ivc.max_pitch',        'sse_tune.tune_rosco.max_pitch') 
1✔
205
            self.connect('tune_rosco_ivc.min_pitch',        'sse_tune.tune_rosco.min_pitch')
1✔
206
            self.connect('tune_rosco_ivc.vs_minspd',        'sse_tune.tune_rosco.vs_minspd') 
1✔
207
            self.connect('tune_rosco_ivc.ss_vsgain',        'sse_tune.tune_rosco.ss_vsgain') 
1✔
208
            self.connect('tune_rosco_ivc.ss_pcgain',        'sse_tune.tune_rosco.ss_pcgain') 
1✔
209
            self.connect('tune_rosco_ivc.ps_percent',       'sse_tune.tune_rosco.ps_percent') 
1✔
210
            self.connect('tune_rosco_ivc.omega_pc',         'sse_tune.tune_rosco.omega_pc')
1✔
211
            self.connect('tune_rosco_ivc.zeta_pc',          'sse_tune.tune_rosco.zeta_pc')
1✔
212
            self.connect('tune_rosco_ivc.omega_vs',         'sse_tune.tune_rosco.omega_vs')
1✔
213
            self.connect('tune_rosco_ivc.zeta_vs',          'sse_tune.tune_rosco.zeta_vs')
1✔
214
            self.connect('tune_rosco_ivc.IPC_Kp1p',         'sse_tune.tune_rosco.IPC_Kp1p')
1✔
215
            self.connect('tune_rosco_ivc.IPC_Ki1p',         'sse_tune.tune_rosco.IPC_Ki1p')
1✔
216
            self.connect('tune_rosco_ivc.stability_margin', 'sse_tune.tune_rosco.stability_margin')
1✔
217
            self.connect('tune_rosco_ivc.omega_pc_max', 'sse_tune.tune_rosco.omega_pc_max')
1✔
218

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

222
            self.connect('tune_rosco_ivc.Kp_float',         'sse_tune.tune_rosco.Kp_float')
1✔
223
            self.connect('dac_ivc.delta_max_pos',           'sse_tune.tune_rosco.delta_max_pos')
1✔
224
            if modeling_options['ROSCO']['Flp_Mode'] > 0:
1✔
225
                self.connect('tune_rosco_ivc.flp_kp_norm',    'sse_tune.tune_rosco.flp_kp_norm')
×
226
                self.connect('tune_rosco_ivc.flp_tau',     'sse_tune.tune_rosco.flp_tau')
×
227

228
        if modeling_options['Level1']['flag']:
1✔
229
            self.add_subsystem('raft', RAFT_WEIS(modeling_options = modeling_options, analysis_options=opt_options))
1✔
230

231
            n_span = modeling_options["WISDEM"]["RotorSE"]["n_span"]
1✔
232
            self.connect('configuration.turb_class',        'raft.turbulence_class')
1✔
233
            self.connect('configuration.ws_class' ,         'raft.turbine_class')
1✔
234
            self.connect('drivese.rna_mass', 'raft.turbine_mRNA')
1✔
235
            self.connect('drivese.rna_I_TT', 'raft.rna_I_TT')
1✔
236
            self.connect('drivese.rna_cm', 'raft.rna_cm')
1✔
237
            self.connect("nacelle.overhang", "raft.turbine_overhang")
1✔
238
            self.connect("nacelle.distance_tt_hub", "raft.drive_height")
1✔
239
            self.connect('drivese.base_F', 'raft.turbine_Fthrust', src_indices=[0], flat_src_indices=True) # TODO: Multiple DLCs
1✔
240
            self.connect("high_level_tower_props.hub_height", "raft.turbine_hHub")
1✔
241
            self.connect("tower.layer_thickness", "raft.tower_layer_thickness")
1✔
242
            self.connect("tower_grid.s", "raft.turbine_tower_stations")
1✔
243
            self.connect('tower.diameter', 'raft.turbine_tower_d')
1✔
244
            self.connect('env.water_depth', 'raft.mooring_water_depth')
1✔
245
            self.connect('env.rho_water', 'raft.rho_water')
1✔
246
            self.connect('env.rho_air', 'raft.rho_air')
1✔
247
            self.connect('env.mu_air', 'raft.mu_air')
1✔
248
            self.connect('env.shear_exp', 'raft.shear_exp')
1✔
249
            self.connect('sse_tune.tune_rosco.PC_GS_angles',    'raft.rotor_PC_GS_angles')
1✔
250
            self.connect('sse_tune.tune_rosco.PC_GS_Kp',        'raft.rotor_PC_GS_Kp')
1✔
251
            self.connect('sse_tune.tune_rosco.PC_GS_Ki',        'raft.rotor_PC_GS_Ki')
1✔
252
            self.connect('sse_tune.tune_rosco.Fl_Kp',           'raft.Fl_Kp')
1✔
253
            self.connect('sse_tune.tune_rosco.VS_Kp',           'raft.rotor_TC_VS_Kp')
1✔
254
            self.connect('sse_tune.tune_rosco.VS_Ki',           'raft.rotor_TC_VS_Ki')
1✔
255
            self.connect('rotorse.I_all_blades',     'raft.rotor_inertia', src_indices=[0])
1✔
256
            self.connect('rotorse.rp.powercurve.rated_V',       'raft.Vrated')
1✔
257
            self.connect('control.V_in',                    'raft.V_cutin')
1✔
258
            self.connect('control.V_out',                   'raft.V_cutout')
1✔
259
            self.connect('rotorse.rp.powercurve.rated_Omega',     'raft.rated_rotor_speed')
1✔
260

261
            if modeling_options["flags"]["blade"]:
1✔
262
                self.connect("configuration.n_blades", "raft.nBlades")
1✔
263
                self.connect("hub.cone", "raft.precone")
1✔
264
                self.connect("nacelle.uptilt", "raft.tilt")
1✔
265
                self.connect("nacelle.gear_ratio", "raft.gear_ratio")
1✔
266
                self.connect("blade.high_level_blade_props.r_blade",  "raft.blade_r")
1✔
267
                self.connect("blade.high_level_blade_props.rotor_radius", "raft.blade_Rtip")
1✔
268
                self.connect("hub.radius", "raft.hub_radius")
1✔
269
                self.connect("blade.pa.chord_param", "raft.blade_chord")
1✔
270
                self.connect("blade.pa.twist_param", "raft.blade_theta")
1✔
271
                self.connect("blade.high_level_blade_props.prebend", "raft.blade_precurve")
1✔
272
                self.connect("blade.high_level_blade_props.prebendTip", "raft.blade_precurveTip")
1✔
273
                self.connect("blade.high_level_blade_props.presweep", "raft.blade_presweep")
1✔
274
                self.connect("blade.high_level_blade_props.presweepTip", "raft.blade_presweepTip")
1✔
275
                self.connect("airfoils.name", "raft.airfoils_name")
1✔
276
                self.connect("airfoils.r_thick", "raft.airfoils_r_thick")
1✔
277
                self.connect("blade.opt_var.af_position", "raft.airfoils_position")
1✔
278
                self.connect("airfoils.aoa", "raft.airfoils_aoa")
1✔
279
                self.connect("airfoils.cl", "raft.airfoils_cl")
1✔
280
                self.connect("airfoils.cd", "raft.airfoils_cd")
1✔
281
                self.connect("airfoils.cm", "raft.airfoils_cm")
1✔
282
                self.connect("high_level_tower_props.hub_height", "raft.wind_reference_height")
1✔
283
                self.connect("rotorse.rp.powercurve.V", "raft.rotor_powercurve_v")
1✔
284
                self.connect("rotorse.rp.powercurve.Omega", "raft.rotor_powercurve_omega_rpm")
1✔
285
                self.connect("rotorse.rp.powercurve.pitch", "raft.rotor_powercurve_pitch")
1✔
286

287
            if modeling_options["flags"]["tower"]:
1✔
288
                self.connect('towerse.member.rho', 'raft.tower_rho')
1✔
289
                self.connect('towerse.tower_section_height', 'raft.tower_section_height')
1✔
290
                self.connect('towerse.member.tor_stff', 'raft.tower_torsional_stiffness')
1✔
291
                self.connect('towerse.z_param',        'raft.wind.z')
1✔
292
                self.connect("rotorse.rp.gust.V_gust", "raft.Uref")
1✔
293
                self.connect("high_level_tower_props.hub_height", "raft.zref")
1✔
294
                self.connect("high_level_tower_props.tower_ref_axis", "raft.turbine_tower_rA", src_indices=om.slicer[0,:])
1✔
295
                self.connect("high_level_tower_props.tower_ref_axis", "raft.turbine_tower_rB", src_indices=om.slicer[-1,:])
1✔
296
                
297
            if modeling_options["flags"]["floating"]:
1✔
298
                self.connect("floatingse.member_variable_height", "raft.member_variable_height")
1✔
299

300
                for k, kname in enumerate(modeling_options["floating"]["members"]["name"]):
1✔
301
                    idx = modeling_options["floating"]["members"]["name2idx"][kname]
1✔
302
                    self.connect(f"floating.memgrid{idx}.layer_thickness", f"raft.member{k}:layer_thickness")
1✔
303
                    self.connect(f"floatingse.member{k}.height", f"raft.member{k}:height")
1✔
304
                    self.connect(f"floatingse.member{k}.rho", f"raft.member{k}:rho")
1✔
305
                    self.connect(f"floating.memgrp{idx}.s", f"raft.platform_member{k+1}_stations")
1✔
306
                    self.connect(f"floating.memgrp{idx}.ring_stiffener_web_height", f"raft.member{k}:ring_stiffener_web_height")
1✔
307
                    self.connect(f"floating.memgrp{idx}.ring_stiffener_web_thickness", f"raft.member{k}:ring_stiffener_web_thickness")
1✔
308
                    self.connect(f"floating.memgrp{idx}.ring_stiffener_flange_width", f"raft.member{k}:ring_stiffener_flange_width")
1✔
309
                    self.connect(f"floating.memgrp{idx}.ring_stiffener_flange_thickness", f"raft.member{k}:ring_stiffener_flange_thickness")
1✔
310
                    self.connect(f"floating.memgrp{idx}.ring_stiffener_spacing", f"raft.member{k}:ring_stiffener_spacing")
1✔
311
                    self.connect(f"floating.memgrp{idx}.bulkhead_grid", f"raft.platform_member{k+1}_cap_stations")
1✔
312
                    self.connect(f"floating.memgrp{idx}.bulkhead_thickness", f"raft.platform_member{k+1}_cap_t")
1✔
313
                    self.connect(f"floating.member_{kname}:joint1", f"raft.platform_member{k+1}_rA")
1✔
314
                    self.connect(f"floating.member_{kname}:joint2", f"raft.platform_member{k+1}_rB")
1✔
315
                    self.connect(f"floating.member_{kname}:s_ghost1", f"raft.platform_member{k+1}_s_ghostA")
1✔
316
                    self.connect(f"floating.member_{kname}:s_ghost2", f"raft.platform_member{k+1}_s_ghostB")
1✔
317
                    self.connect(f"floating.memgrp{idx}.ballast_grid", f"raft.member{k}:ballast_grid")
1✔
318
                    self.connect(f"floatingse.member{k}.ballast_height", f"raft.member{k}:ballast_height")
1✔
319
                    self.connect(f"floatingse.member{k}.ballast_density", f"raft.member{k}:ballast_density")
1✔
320

321
                    if modeling_options['floating']['members']['outer_shape'][k] == "circular":
1✔
322
                        self.connect(f"floatingse.member{k}.outer_diameter", f"raft.member{k}:outer_diameter")
1✔
323
                        self.connect(f"floating.memgrid{idx}.ca_usr_grid", f"raft.member{k}:Ca")
1✔
324
                        self.connect(f"floating.memgrid{idx}.cd_usr_grid", f"raft.member{k}:Cd")
1✔
325
                    elif modeling_options['floating']['members']['outer_shape'][k] == "rectangular":
×
326
                        self.connect(f"floatingse.member{k}.side_length_a", f"raft.member{k}:side_length_a")
×
327
                        self.connect(f"floatingse.member{k}.side_length_b", f"raft.member{k}:side_length_b")
×
328
                        self.connect(f"floating.memgrid{idx}.ca_usr_grid", f"raft.member{k}:Ca")
×
329
                        self.connect(f"floating.memgrid{idx}.cd_usr_grid", f"raft.member{k}:Cd")
×
330
                        self.connect(f"floating.memgrid{idx}.cay_usr_grid", f"raft.member{k}:Cay")
×
331
                        self.connect(f"floating.memgrid{idx}.cdy_usr_grid", f"raft.member{k}:Cdy")
×
332

333
                self.connect("mooring.mooring_nodes", 'raft.mooring_nodes')
1✔
334
                self.connect("mooring.unstretched_length", 'raft.unstretched_length')
1✔
335
                for var in ['diameter','mass_density','stiffness','breaking_load','cost_rate',
1✔
336
                            'transverse_added_mass','tangential_added_mass','transverse_drag','tangential_drag']:
337
                    self.connect(f'mooring.line_{var}', f'raft.line_{var}')
1✔
338

339
        # TMD connections to openmdao_openfast
340
        if modeling_options['flags']['TMDs']:
1✔
341
            self.add_subsystem('TMDs',  TMD_group(modeling_options = modeling_options, opt_options = opt_options))
1✔
342

343
            self.connect('TMDs.mass',               'aeroelastic.TMD_mass')
1✔
344
            self.connect('TMDs.stiffness',          'aeroelastic.TMD_stiffness')
1✔
345
            self.connect('TMDs.damping',            'aeroelastic.TMD_damping')
1✔
346

347
        if modeling_options['Level3']['flag'] or modeling_options['Level2']['flag']:
1✔
348
            self.add_subsystem('aeroelastic',       FASTLoadCases(modeling_options = modeling_options, opt_options = opt_options))
1✔
349
            self.add_subsystem('stall_check_of',    NoStallConstraint(modeling_options = modeling_options))
1✔
350
            
351
            if modeling_options['WISDEM']['RotorSE']['flag']: 
1✔
352
                self.add_subsystem('rlds_post',      RotorLoadsDeflStrainsWEIS(modeling_options = modeling_options, opt_options = opt_options))
1✔
353

354
                # Connections from blade struct parametrization to rotor load anlysis
355
                spars_tereinf = modeling_options["WISDEM"]["RotorSE"]["spars_tereinf"]
1✔
356
                self.connect("blade.opt_var.s_opt_layer_%d"%spars_tereinf[0], "rotorse.rs.constr.s_opt_spar_cap_ss")
1✔
357
                self.connect("blade.opt_var.s_opt_layer_%d"%spars_tereinf[1], "rotorse.rs.constr.s_opt_spar_cap_ps")
1✔
358

359

360
                # Connections to the stall check 
361
                self.connect('blade.outer_shape_bem.s',        'stall_check_of.s')
1✔
362
                self.connect('airfoils.aoa',                   'stall_check_of.airfoils_aoa')
1✔
363
                self.connect('xf.cl_interp_flaps',             'stall_check_of.airfoils_cl')
1✔
364
                self.connect('xf.cd_interp_flaps',             'stall_check_of.airfoils_cd')
1✔
365
                self.connect('xf.cm_interp_flaps',             'stall_check_of.airfoils_cm')
1✔
366
                self.connect('aeroelastic.max_aoa',            'stall_check_of.aoa_along_span')
1✔
367
        
368
            if  modeling_options["flags"]["nacelle"]:
1✔
369
                self.add_subsystem('drivese_post',   DrivetrainSE(modeling_options=modeling_options))
1✔
370

371
            # TODO: FIX NDLC HERE
372
            if modeling_options["flags"]["tower"]:
1✔
373
                # This is needed for some reason because TowerSE isn't already called?  Should probably re-use that
374
                n_height = modeling_options['WISDEM']['TowerSE']["n_height"]
1✔
375
                n_refine = modeling_options['WISDEM']['TowerSE']["n_refine"]
1✔
376
                n_full = get_nfull(n_height, nref=n_refine)
1✔
377
                self.add_subsystem('towerse_post',   CylinderPostFrame(modeling_options=modeling_options["WISDEM"]["TowerSE"], n_dlc=1, n_full = n_full))
1✔
378
                
379
            if modeling_options["flags"]["monopile"]:
1✔
380
                n_height = modeling_options['WISDEM']['FixedBottomSE']["n_height"]
1✔
381
                n_refine = modeling_options['WISDEM']['FixedBottomSE']["n_refine"]
1✔
382
                n_full = get_nfull(n_height, nref=n_refine)
1✔
383
                
384
                self.add_subsystem('fixedse_post',   CylinderPostFrame(modeling_options=modeling_options["WISDEM"]["FixedBottomSE"], n_dlc=1, n_full = n_full))
1✔
385
                
386
            if not modeling_options['Level3']['from_openfast']:
1✔
387
                self.add_subsystem('tcons_post',     TurbineConstraints(modeling_options = modeling_options))
1✔
388
                self.add_subsystem('financese_post', PlantFinance(verbosity=modeling_options['General']['verbosity']))
1✔
389
            
390
            # Post-processing
391
            self.add_subsystem('outputs_2_screen_weis',  Outputs_2_Screen(modeling_options = modeling_options, opt_options = opt_options))
1✔
392
            if opt_options['opt_flag']:
1✔
393
                self.add_subsystem('conv_plots_weis',    Convergence_Trends_Opt(opt_options = opt_options))
1✔
394

395
            if modeling_options['ROSCO']['Flp_Mode']:
1✔
396
                # Connections to blade 
397
                self.connect('dac_ivc.te_flap_end',             'blade.outer_shape_bem.span_end')
×
398
                self.connect('dac_ivc.te_flap_ext',             'blade.outer_shape_bem.span_ext')
×
399

400

401

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

405
            # Configuration parameters needed if model comes from openfast
406
            self.connect('control.V_in',                    'aeroelastic.V_cutin')
1✔
407
            self.connect('control.V_out',                   'aeroelastic.V_cutout')
1✔
408
            self.connect('env.shear_exp',                   'aeroelastic.shearExp')
1✔
409
            
410
            # Connections to aeroelasticse
411
            self.connect('configuration.turb_class',        'aeroelastic.turbulence_class')
1✔
412
            self.connect('configuration.ws_class' ,         'aeroelastic.turbine_class')
1✔
413

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

454
                self.connect("high_level_tower_props.hub_height", "aeroelastic.hub_height")
1✔
455
                if modeling_options["flags"]["tower"]:
1✔
456
                    self.connect('towerse.member.mass_den',                'aeroelastic.mass_den')
1✔
457
                    self.connect('towerse.member.foreaft_stff',            'aeroelastic.foreaft_stff')
1✔
458
                    self.connect('towerse.member.sideside_stff',           'aeroelastic.sideside_stff')
1✔
459
                    self.connect('towerse.member.tor_stff',                'aeroelastic.tor_stff')
1✔
460
                    self.connect('towerse.tower_outer_diameter',    'aeroelastic.tower_outer_diameter')
1✔
461
                    self.connect('towerse.z_param',                 'aeroelastic.tower_z')
1✔
462
                    self.connect('towerse.z_full',                  'aeroelastic.tower_z_full')
1✔
463
                    self.connect('tower.cd',                        'aeroelastic.tower_cd')
1✔
464
                    self.connect('tower_grid.height',               'aeroelastic.tower_height')
1✔
465
                    self.connect('tower_grid.foundation_height',    'aeroelastic.tower_base_height')
1✔
466
                    self.connect('towerse.tower_I_base',            'aeroelastic.tower_I_base')
1✔
467
                    if modeling_options["flags"]["monopile"] or modeling_options["flags"]["jacket"]:
1✔
468
                        self.connect('fixedse.torsion_freqs',      'aeroelastic.tor_freq', src_indices=[0])
1✔
469
                        self.connect('fixedse.tower_fore_aft_modes',     'aeroelastic.fore_aft_modes')
1✔
470
                        self.connect('fixedse.tower_side_side_modes',    'aeroelastic.side_side_modes')
1✔
471
                        self.connect('fixedse.f1',         'sse_tune.tune_rosco.twr_freq')
1✔
472

473
                    elif modeling_options["flags"]["floating"]:
1✔
474
                        self.connect('floatingse.torsion_freqs',      'aeroelastic.tor_freq', src_indices=[0])
1✔
475
                        self.connect('floatingse.fore_aft_modes',     'aeroelastic.fore_aft_modes')
1✔
476
                        self.connect('floatingse.side_side_modes',    'aeroelastic.side_side_modes')
1✔
477
                        self.connect('floatingse.f1',         'sse_tune.tune_rosco.twr_freq')
1✔
478
                    else:
479
                        self.connect('towerse.tower.torsion_freqs',      'aeroelastic.tor_freq', src_indices=[0])
1✔
480
                        self.connect('towerse.tower.fore_aft_modes',     'aeroelastic.fore_aft_modes')
1✔
481
                        self.connect('towerse.tower.side_side_modes',    'aeroelastic.side_side_modes')
1✔
482
                        self.connect('towerse.tower.f1',         'sse_tune.tune_rosco.twr_freq')
1✔
483
                        
484
                if modeling_options['flags']['monopile']:
1✔
485
                    self.connect('monopile.transition_piece_mass',  'aeroelastic.transition_piece_mass')
1✔
486
                    self.connect('fixedse.transition_piece_I',      'aeroelastic.transition_piece_I', src_indices=[0,1,2])
1✔
487
                    self.connect('monopile.gravity_foundation_mass', 'aeroelastic.gravity_foundation_mass')
1✔
488
                    self.connect('fixedse.gravity_foundation_I',    'aeroelastic.gravity_foundation_I', src_indices=[0,1,2])
1✔
489
                    self.connect('fixedse.z_param',                 'aeroelastic.monopile_z')
1✔
490
                    self.connect('fixedse.z_full',                  'aeroelastic.monopile_z_full')
1✔
491
                    self.connect('fixedse.monopile_outer_diameter',    'aeroelastic.monopile_outer_diameter')
1✔
492
                    self.connect('fixedse.monopile_wall_thickness',    'aeroelastic.monopile_wall_thickness')
1✔
493
                    self.connect('fixedse.member.E',                       'aeroelastic.monopile_E')
1✔
494
                    self.connect('fixedse.member.G',                       'aeroelastic.monopile_G')
1✔
495
                    self.connect('fixedse.member.rho',                     'aeroelastic.monopile_rho')
1✔
496
                        
497
                elif modeling_options['flags']['floating']:
1✔
498
                    self.connect("floatingse.platform_nodes", "aeroelastic.platform_nodes")
1✔
499
                    self.connect("floatingse.platform_elem_n1", "aeroelastic.platform_elem_n1")
1✔
500
                    self.connect("floatingse.platform_elem_n2", "aeroelastic.platform_elem_n2")
1✔
501
                    self.connect("floatingse.platform_elem_D", "aeroelastic.platform_elem_D")
1✔
502
                    self.connect("floatingse.platform_elem_t", "aeroelastic.platform_elem_t")
1✔
503
                    self.connect("floatingse.platform_elem_rho", "aeroelastic.platform_elem_rho")
1✔
504
                    self.connect("floatingse.platform_elem_E", "aeroelastic.platform_elem_E")
1✔
505
                    self.connect("floatingse.platform_elem_G", "aeroelastic.platform_elem_G")
1✔
506
                    if modeling_options['Level1']['flag']:
1✔
UNCOV
507
                        ptfm_data_source = 'raft'
×
508
                    else:
509
                        ptfm_data_source = 'floatingse'
1✔
510
                    self.connect(f"{ptfm_data_source}.platform_mass", "aeroelastic.platform_mass")
1✔
511
                    self.connect(f"{ptfm_data_source}.platform_total_center_of_mass", "aeroelastic.platform_total_center_of_mass")
1✔
512
                    self.connect(f"{ptfm_data_source}.platform_I_total", "aeroelastic.platform_I_total")
1✔
513
                    self.connect(f"{ptfm_data_source}.platform_displacement", "aeroelastic.platform_displacement")
1✔
514
                    self.connect("floating.transition_node", "aeroelastic.transition_node")
1✔
515

516
                    for k, kname in enumerate(modeling_options["floating"]["members"]["name"]):
1✔
517
                        idx = modeling_options["floating"]["members"]["name2idx"][kname]
1✔
518
                        #self.connect(f"floating.memgrp{idx}.outer_diameter", f"floatingse.member{k}.outer_diameter_in")
519
                        self.connect(f"floating.memgrp{idx}.s", f"aeroelastic.member{k}:s")
1✔
520
                        self.connect(f"floatingse.member{k}.outer_diameter", f"aeroelastic.member{k}:outer_diameter")
1✔
521
                        self.connect(f"floatingse.member{k}.wall_thickness", f"aeroelastic.member{k}:wall_thickness")
1✔
522

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

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

615
                # Connections to rotor load analysis
616
                self.connect('aeroelastic.blade_maxTD_Mx', 'rlds_post.m2pa.Mx')
1✔
617
                self.connect('aeroelastic.blade_maxTD_My', 'rlds_post.m2pa.My')
1✔
618
                self.connect('aeroelastic.blade_maxTD_Fz', 'rlds_post.strains.F3')
1✔
619

620
                self.connect("rotorse.rs.frame.alpha", "rlds_post.alpha")
1✔
621
                self.connect('rotorse.EA', 'rlds_post.strains.EA')
1✔
622
                self.connect('rotorse.A', 'rlds_post.strains.A')
1✔
623
                self.connect('blade.pa.chord_param',  'rlds_post.strains.chord')
1✔
624
                self.connect('rotorse.rs.frame.EI11', 'rlds_post.strains.EI11')
1✔
625
                self.connect('rotorse.rs.frame.EI22', 'rlds_post.strains.EI22')
1✔
626
                self.connect('rotorse.xu_spar', 'rlds_post.strains.xu_spar')
1✔
627
                self.connect('rotorse.xl_spar', 'rlds_post.strains.xl_spar')
1✔
628
                self.connect('rotorse.yu_spar', 'rlds_post.strains.yu_spar')
1✔
629
                self.connect('rotorse.yl_spar', 'rlds_post.strains.yl_spar')
1✔
630
                self.connect('rotorse.xu_te', 'rlds_post.strains.xu_te')
1✔
631
                self.connect('rotorse.xl_te', 'rlds_post.strains.xl_te')
1✔
632
                self.connect('rotorse.yu_te', 'rlds_post.strains.yu_te')
1✔
633
                self.connect('rotorse.yl_te', 'rlds_post.strains.yl_te')
1✔
634
                self.connect('blade.outer_shape_bem.s','rlds_post.constr.s')
1✔
635
                self.connect("blade.internal_structure_2d_fem.d_f", "rlds_post.brs.d_f")
1✔
636
                self.connect("blade.internal_structure_2d_fem.sigma_max", "rlds_post.brs.sigma_max")
1✔
637
                self.connect("blade.pa.chord_param", "rlds_post.brs.rootD", src_indices=[0])
1✔
638
                self.connect("blade.ps.layer_thickness_param", "rlds_post.brs.layer_thickness")
1✔
639
                self.connect("blade.internal_structure_2d_fem.layer_start_nd", "rlds_post.brs.layer_start_nd")
1✔
640
                self.connect("blade.internal_structure_2d_fem.layer_end_nd", "rlds_post.brs.layer_end_nd")
1✔
641

642
                # Connections to DriveSE
643
                if modeling_options['WISDEM']['DriveSE']['flag']:
1✔
644
                    self.connect('hub.diameter'                    , 'drivese_post.hub_diameter')
1✔
645
                    self.connect('hub.hub_in2out_circ'             , 'drivese_post.hub_in2out_circ')
1✔
646
                    self.connect('hub.flange_t2shell_t'            , 'drivese_post.flange_t2shell_t')
1✔
647
                    self.connect('hub.flange_OD2hub_D'             , 'drivese_post.flange_OD2hub_D')
1✔
648
                    self.connect('hub.flange_ID2flange_OD'         , 'drivese_post.flange_ID2flange_OD')
1✔
649
                    self.connect('hub.hub_stress_concentration'    , 'drivese_post.hub_stress_concentration')
1✔
650
                    self.connect('hub.n_front_brackets'            , 'drivese_post.n_front_brackets')
1✔
651
                    self.connect('hub.n_rear_brackets'             , 'drivese_post.n_rear_brackets')
1✔
652
                    self.connect('hub.clearance_hub_spinner'       , 'drivese_post.clearance_hub_spinner')
1✔
653
                    self.connect('hub.spin_hole_incr'              , 'drivese_post.spin_hole_incr')
1✔
654
                    self.connect('hub.pitch_system_scaling_factor' , 'drivese_post.pitch_system_scaling_factor')
1✔
655
                    self.connect("rotorse.wt_class.V_extreme50", "drivese.spinner_gust_ws")
1✔
656
                    self.connect('configuration.n_blades',          'drivese_post.n_blades')
1✔
657
                    self.connect("blade.high_level_blade_props.rotor_diameter", "drivese_post.rotor_diameter")
1✔
658
                    self.connect('configuration.upwind',       'drivese_post.upwind')
1✔
659
                    self.connect('control.minOmega' ,          'drivese_post.minimum_rpm')
1✔
660
                    self.connect('rotorse.rp.powercurve.rated_Omega',  'drivese_post.rated_rpm')
1✔
661
                    self.connect('rotorse.rp.powercurve.rated_Q',      'drivese_post.rated_torque')
1✔
662
                    self.connect('configuration.rated_power',  'drivese_post.machine_rating')    
1✔
663
                    self.connect('tower.diameter',             'drivese_post.D_top', src_indices=[-1])
1✔
664
                    self.connect('aeroelastic.hub_Fxyz_aero',       'drivese_post.F_aero_hub')
1✔
665
                    self.connect('aeroelastic.hub_Mxyz_aero',       'drivese_post.M_aero_hub')
1✔
666
                    self.connect('aeroelastic.max_RootMyb',     'drivese_post.pitch_system.BRFM')
1✔
667
                    self.connect('blade.pa.chord_param',        'drivese_post.blade_root_diameter', src_indices=[0])
1✔
668
                    self.connect('rotorse.blade_mass',          'drivese_post.blade_mass')
1✔
669
                    self.connect('rotorse.mass_all_blades',     'drivese_post.blades_mass')
1✔
670
                    self.connect('rotorse.I_all_blades',        'drivese_post.blades_I')
1✔
671

672
                    self.connect('nacelle.distance_hub_mb',           'drivese_post.L_h1')
1✔
673
                    self.connect('nacelle.distance_mb_mb',            'drivese_post.L_12')
1✔
674
                    self.connect('nacelle.L_generator',               'drivese_post.L_generator')
1✔
675
                    self.connect('nacelle.overhang',                  'drivese_post.overhang')
1✔
676
                    self.connect('nacelle.distance_tt_hub',           'drivese_post.drive_height')
1✔
677
                    self.connect('nacelle.uptilt',                    'drivese_post.tilt')
1✔
678
                    self.connect('nacelle.gear_ratio',                'drivese_post.gear_ratio')
1✔
679
                    self.connect('nacelle.mb1Type',                   'drivese_post.bear1.bearing_type')
1✔
680
                    self.connect('nacelle.mb2Type',                   'drivese_post.bear2.bearing_type')
1✔
681
                    self.connect('nacelle.lss_diameter',              'drivese_post.lss_diameter')
1✔
682
                    self.connect('nacelle.lss_wall_thickness',        'drivese_post.lss_wall_thickness')
1✔
683
                    if modeling_options['WISDEM']['DriveSE']['direct']:
1✔
684
                        self.connect('nacelle.nose_diameter',              'drivese_post.bear1.D_shaft', src_indices=[0])
1✔
685
                        self.connect('nacelle.nose_diameter',              'drivese_post.bear2.D_shaft', src_indices=[-1])
1✔
686
                    else:
687
                        self.connect('nacelle.lss_diameter',              'drivese_post.bear1.D_shaft', src_indices=[0])
1✔
688
                        self.connect('nacelle.lss_diameter',              'drivese_post.bear2.D_shaft', src_indices=[-1])
1✔
689
                    self.connect('nacelle.uptower',                   'drivese_post.uptower')
1✔
690
                    self.connect('nacelle.brake_mass_user',           'drivese_post.brake_mass_user')
1✔
691
                    self.connect('nacelle.hvac_mass_coeff',           'drivese_post.hvac_mass_coeff')
1✔
692
                    self.connect('nacelle.converter_mass_user',       'drivese_post.converter_mass_user')
1✔
693
                    self.connect('nacelle.transformer_mass_user',     'drivese_post.transformer_mass_user')
1✔
694

695
                    if modeling_options['WISDEM']['DriveSE']['direct']:
1✔
696
                        self.connect('nacelle.nose_diameter',             'drivese_post.nose_diameter') # only used in direct
1✔
697
                        self.connect('nacelle.nose_wall_thickness',       'drivese_post.nose_wall_thickness') # only used in direct
1✔
698
                        self.connect('nacelle.bedplate_wall_thickness',   'drivese_post.bedplate_wall_thickness') # only used in direct
1✔
699
                    else:
700
                        self.connect('nacelle.hss_length', 'drivese_post.L_hss') # only used in geared
1✔
701
                        self.connect('nacelle.hss_diameter', 'drivese_post.hss_diameter') # only used in geared
1✔
702
                        self.connect('nacelle.hss_wall_thickness', 'drivese_post.hss_wall_thickness') # only used in geared
1✔
703
                        self.connect('nacelle.hss_material', 'drivese_post.hss_material')
1✔
704
                        self.connect('nacelle.planet_numbers', 'drivese_post.planet_numbers') # only used in geared
1✔
705
                        self.connect('nacelle.gear_configuration', 'drivese_post.gear_configuration') # only used in geared
1✔
706
                        self.connect('nacelle.bedplate_flange_width', 'drivese_post.bedplate_flange_width') # only used in geared
1✔
707
                        self.connect('nacelle.bedplate_flange_thickness', 'drivese_post.bedplate_flange_thickness') # only used in geared
1✔
708
                        self.connect('nacelle.bedplate_web_thickness', 'drivese_post.bedplate_web_thickness') # only used in geared
1✔
709
                        self.connect("nacelle.gearbox_mass_user", "drivese_post.gearbox_mass_user")
1✔
710
                        self.connect("nacelle.gearbox_torque_density", "drivese_post.gearbox_torque_density")
1✔
711
                        self.connect("nacelle.gearbox_radius_user", "drivese_post.gearbox_radius_user")
1✔
712
                        self.connect("nacelle.gearbox_length_user", "drivese_post.gearbox_length_user")
1✔
713
                            
714
                    self.connect('hub.hub_material',                  'drivese_post.hub_material')
1✔
715
                    self.connect('hub.spinner_material',              'drivese_post.spinner_material')
1✔
716
                    self.connect('nacelle.lss_material',              'drivese_post.lss_material')
1✔
717
                    self.connect('nacelle.bedplate_material',         'drivese_post.bedplate_material')
1✔
718
                    self.connect('materials.name',                    'drivese_post.material_names')
1✔
719
                    self.connect('materials.E',                       'drivese_post.E_mat')
1✔
720
                    self.connect('materials.G',                       'drivese_post.G_mat')
1✔
721
                    self.connect('materials.rho',                     'drivese_post.rho_mat')
1✔
722
                    self.connect('materials.sigma_y',                 'drivese_post.Xy_mat')
1✔
723
                    self.connect("materials.Xt",                      "drivese_post.Xt_mat")
1✔
724
                    self.connect("materials.wohler_exp",              "drivese_post.wohler_exp_mat")
1✔
725
                    self.connect("materials.wohler_intercept",        "drivese_post.wohler_A_mat")
1✔
726
                    self.connect('materials.unit_cost',               'drivese_post.unit_cost_mat')
1✔
727

728
                    if modeling_options['flags']['generator']:
1✔
729

730
                        self.connect('generator.B_r'          , 'drivese_post.generator.B_r')
1✔
731
                        self.connect('generator.P_Fe0e'       , 'drivese_post.generator.P_Fe0e')
1✔
732
                        self.connect('generator.P_Fe0h'       , 'drivese_post.generator.P_Fe0h')
1✔
733
                        self.connect('generator.S_N'          , 'drivese_post.generator.S_N')
1✔
734
                        self.connect('generator.alpha_p'      , 'drivese_post.generator.alpha_p')
1✔
735
                        self.connect('generator.b_r_tau_r'    , 'drivese_post.generator.b_r_tau_r')
1✔
736
                        self.connect('generator.b_ro'         , 'drivese_post.generator.b_ro')
1✔
737
                        self.connect('generator.b_s_tau_s'    , 'drivese_post.generator.b_s_tau_s')
1✔
738
                        self.connect('generator.b_so'         , 'drivese_post.generator.b_so')
1✔
739
                        self.connect('generator.cofi'         , 'drivese_post.generator.cofi')
1✔
740
                        self.connect('generator.freq'         , 'drivese_post.generator.freq')
1✔
741
                        self.connect('generator.h_i'          , 'drivese_post.generator.h_i')
1✔
742
                        self.connect('generator.h_sy0'        , 'drivese_post.generator.h_sy0')
1✔
743
                        self.connect('generator.h_w'          , 'drivese_post.generator.h_w')
1✔
744
                        self.connect('generator.k_fes'        , 'drivese_post.generator.k_fes')
1✔
745
                        self.connect('generator.k_fillr'      , 'drivese_post.generator.k_fillr')
1✔
746
                        self.connect('generator.k_fills'      , 'drivese_post.generator.k_fills')
1✔
747
                        self.connect('generator.k_s'          , 'drivese_post.generator.k_s')
1✔
748
                        self.connect('generator.m'            , 'drivese_post.generator.m')
1✔
749
                        self.connect('generator.mu_0'         , 'drivese_post.generator.mu_0')
1✔
750
                        self.connect('generator.mu_r'         , 'drivese_post.generator.mu_r')
1✔
751
                        self.connect('generator.p'            , 'drivese_post.generator.p')
1✔
752
                        self.connect('generator.phi'          , 'drivese_post.generator.phi')
1✔
753
                        self.connect('generator.q1'           , 'drivese_post.generator.q1')
1✔
754
                        self.connect('generator.q2'           , 'drivese_post.generator.q2')
1✔
755
                        self.connect('generator.ratio_mw2pp'  , 'drivese_post.generator.ratio_mw2pp')
1✔
756
                        self.connect('generator.resist_Cu'    , 'drivese_post.generator.resist_Cu')
1✔
757
                        self.connect('generator.sigma'        , 'drivese_post.generator.sigma')
1✔
758
                        self.connect('generator.y_tau_p'      , 'drivese_post.generator.y_tau_p')
1✔
759
                        self.connect('generator.y_tau_pr'     , 'drivese_post.generator.y_tau_pr')
1✔
760

761
                        self.connect('generator.I_0'          , 'drivese_post.generator.I_0')
1✔
762
                        self.connect('generator.d_r'          , 'drivese_post.generator.d_r')
1✔
763
                        self.connect('generator.h_m'          , 'drivese_post.generator.h_m')
1✔
764
                        self.connect('generator.h_0'          , 'drivese_post.generator.h_0')
1✔
765
                        self.connect('generator.h_s'          , 'drivese_post.generator.h_s')
1✔
766
                        self.connect('generator.len_s'        , 'drivese_post.generator.len_s')
1✔
767
                        self.connect('generator.n_r'          , 'drivese_post.generator.n_r')
1✔
768
                        self.connect('generator.rad_ag'       , 'drivese_post.generator.rad_ag')
1✔
769
                        self.connect('generator.t_wr'         , 'drivese_post.generator.t_wr')
1✔
770

771
                        self.connect('generator.n_s'          , 'drivese_post.generator.n_s')
1✔
772
                        self.connect('generator.b_st'         , 'drivese_post.generator.b_st')
1✔
773
                        self.connect('generator.d_s'          , 'drivese_post.generator.d_s')
1✔
774
                        self.connect('generator.t_ws'         , 'drivese_post.generator.t_ws')
1✔
775

776
                        self.connect('generator.rho_Copper'   , 'drivese_post.generator.rho_Copper')
1✔
777
                        self.connect('generator.rho_Fe'       , 'drivese_post.generator.rho_Fe')
1✔
778
                        self.connect('generator.rho_Fes'      , 'drivese_post.generator.rho_Fes')
1✔
779
                        self.connect('generator.rho_PM'       , 'drivese_post.generator.rho_PM')
1✔
780

781
                        self.connect('generator.C_Cu'         , 'drivese_post.generator.C_Cu')
1✔
782
                        self.connect('generator.C_Fe'         , 'drivese_post.generator.C_Fe')
1✔
783
                        self.connect('generator.C_Fes'        , 'drivese_post.generator.C_Fes')
1✔
784
                        self.connect('generator.C_PM'         , 'drivese_post.generator.C_PM')
1✔
785

786
                        if modeling_options['WISDEM']['GeneratorSE']['type'] in ['pmsg_outer']:
1✔
787
                            self.connect('generator.N_c'          , 'drivese_post.generator.N_c')
1✔
788
                            self.connect('generator.b'            , 'drivese_post.generator.b')
1✔
789
                            self.connect('generator.c'            , 'drivese_post.generator.c')
1✔
790
                            self.connect('generator.E_p'          , 'drivese_post.generator.E_p')
1✔
791
                            self.connect('generator.h_yr'         , 'drivese_post.generator.h_yr')
1✔
792
                            self.connect('generator.h_ys'         , 'drivese_post.generator.h_ys')
1✔
793
                            self.connect('generator.h_sr'         , 'drivese_post.generator.h_sr')
1✔
794
                            self.connect('generator.h_ss'         , 'drivese_post.generator.h_ss')
1✔
795
                            self.connect('generator.t_r'          , 'drivese_post.generator.t_r')
1✔
796
                            self.connect('generator.t_s'          , 'drivese_post.generator.t_s')
1✔
797

798
                            self.connect('generator.u_allow_pcent', 'drivese_post.generator.u_allow_pcent')
1✔
799
                            self.connect('generator.y_allow_pcent', 'drivese_post.generator.y_allow_pcent')
1✔
800
                            self.connect('generator.z_allow_deg'  , 'drivese_post.generator.z_allow_deg')
1✔
801
                            self.connect('generator.B_tmax'       , 'drivese_post.generator.B_tmax')
1✔
802
                            self.connect('rotorse.rp.powercurve.rated_mech', 'drivese_post.generator.P_mech')
1✔
803

804
                        if modeling_options['WISDEM']['GeneratorSE']['type'] in ['eesg','pmsg_arms','pmsg_disc']:
1✔
805
                            self.connect('generator.tau_p'        , 'drivese_post.generator.tau_p')
×
806
                            self.connect('generator.h_ys'         , 'drivese_post.generator.h_ys')
×
807
                            self.connect('generator.h_yr'         , 'drivese_post.generator.h_yr')
×
808
                            self.connect('generator.b_arm'        , 'drivese_post.generator.b_arm')
×
809

810
                        elif modeling_options['WISDEM']['GeneratorSE']['type'] in ['scig','dfig']:
1✔
811
                            self.connect('generator.B_symax'      , 'drivese_post.generator.B_symax')
1✔
812
                            self.connect('generator.S_Nmax'      , 'drivese_post.generator.S_Nmax')
1✔
813

814
                        if modeling_options['WISDEM']['DriveSE']['direct']:
1✔
815
                            self.connect('nacelle.nose_diameter',             'drivese_post.generator.D_nose', src_indices=[-1])
1✔
816
                            self.connect('nacelle.lss_diameter',              'drivese_post.generator.D_shaft', src_indices=[0])
1✔
817
                        else:
818
                            self.connect('nacelle.hss_diameter',              'drivese_post.generator.D_shaft', src_indices=[-1])
1✔
819

820
                    else:
821
                        self.connect('generator.generator_mass_user', 'drivese_post.generator_mass_user')
×
822
                        self.connect('generator.generator_efficiency_user', 'drivese_post.generator_efficiency_user')
×
823

824
                # Connections to TowerSE
825
                if modeling_options["flags"]["tower"]:
1✔
826
                    tow_params = ["z_full","outer_diameter_full","t_full",
1✔
827
                                  "E_full","G_full","rho_full","sigma_y_full",
828
                                  "section_A", "section_Asx","section_Asy",
829
                                  "section_Ixx", "section_Iyy", "section_J0",
830
                                  "section_rho", "section_E", "section_G", "section_L",
831
                                  ]
832
                    for k in tow_params:
1✔
833
                        self.connect(f'towerse.{k}', f'towerse_post.{k}')
1✔
834
                    self.connect("towerse.env.qdyn", "towerse_post.qdyn")
1✔
835
                    self.connect("tower_grid.height", "towerse_post.bending_height")
1✔
836
                    
837
                    self.connect("aeroelastic.tower_maxMy_Fz", "towerse_post.cylinder_Fz")
1✔
838
                    self.connect("aeroelastic.tower_maxMy_Fx", "towerse_post.cylinder_Vx")
1✔
839
                    self.connect("aeroelastic.tower_maxMy_Fy", "towerse_post.cylinder_Vy")
1✔
840
                    self.connect("aeroelastic.tower_maxMy_Mx", "towerse_post.cylinder_Mxx")
1✔
841
                    self.connect("aeroelastic.tower_maxMy_My", "towerse_post.cylinder_Myy")
1✔
842
                    self.connect("aeroelastic.tower_maxMy_Mz", "towerse_post.cylinder_Mzz")
1✔
843

844
                if modeling_options["flags"]["monopile"]:
1✔
845
                    mono_params = ["z_full","outer_diameter_full","t_full",
1✔
846
                                  "E_full","G_full","rho_full","sigma_y_full"]
847
                    for k in mono_params:
1✔
848
                        self.connect(f'fixedse.{k}', f'fixedse_post.{k}')
1✔
849
                    self.connect("fixedse.env.qdyn", "fixedse_post.qdyn")
1✔
850
                    self.connect("monopile.height", "fixedse_post.bending_height")
1✔
851

852
                    self.connect("aeroelastic.monopile_maxMy_Fz", "fixedse_post.cylinder_Fz")
1✔
853
                    self.connect("aeroelastic.monopile_maxMy_Fx", "fixedse_post.cylinder_Vx")
1✔
854
                    self.connect("aeroelastic.monopile_maxMy_Fy", "fixedse_post.cylinder_Vy")
1✔
855
                    self.connect("aeroelastic.monopile_maxMy_Mx", "fixedse_post.cylinder_Mxx")
1✔
856
                    self.connect("aeroelastic.monopile_maxMy_My", "fixedse_post.cylinder_Myy")
1✔
857
                    self.connect("aeroelastic.monopile_maxMy_Mz", "fixedse_post.cylinder_Mzz")
1✔
858

859
                #self.connect('yield_stress',            'tow.sigma_y') # TODO- materials
860
                #self.connect('max_taper_ratio',         'max_taper') # TODO- 
861
                #self.connect('min_diameter_thickness_ratio', 'min_d_to_t')
862
                                        
863
                # Connections to turbine constraints
864
                self.connect('configuration.rotor_orientation', 'tcons_post.rotor_orientation')
1✔
865
                self.connect('aeroelastic.max_TipDxc',          'tcons_post.tip_deflection')
1✔
866
                self.connect("blade.high_level_blade_props.rotor_radius", "tcons_post.Rtip")
1✔
867
                self.connect('blade.outer_shape_bem.ref_axis',  'tcons_post.ref_axis_blade')
1✔
868
                self.connect('hub.cone',                        'tcons_post.precone')
1✔
869
                self.connect('nacelle.uptilt',                  'tcons_post.tilt')
1✔
870
                self.connect('nacelle.overhang',                'tcons_post.overhang')
1✔
871
                self.connect('tower.ref_axis',                  'tcons_post.ref_axis_tower')
1✔
872
                self.connect('tower.diameter',                  'tcons_post.outer_diameter_full')
1✔
873
                
874
            else:  # connections from outside WISDEM
875
                self.connect('rosco_turbine.v_rated',               'aeroelastic.Vrated')
1✔
876
                self.connect('rosco_turbine.R',                     'aeroelastic.Rtip')
1✔
877
                self.connect('rosco_turbine.hub_height',            'aeroelastic.hub_height')
1✔
878
                self.connect('rosco_turbine.twr_freq',              'sse_tune.tune_rosco.twr_freq')
1✔
879
            
880
            # Inputs to plantfinancese from wt group
881
            if not modeling_options['Level3']['from_openfast']:
1✔
882

883
                # Connect computed AEP only if DLC 1.1 is used, otherwise use rotorse
884
                if modeling_options['DLC_driver']['n_ws_dlc11'] > 0:
1✔
885
                    self.connect('aeroelastic.AEP', 'financese_post.turbine_aep')
1✔
886
                else:
887
                    self.connect('rotorse.rp.AEP', 'financese_post.turbine_aep')
1✔
888

889
                self.connect('tcc.turbine_cost_kW',     'financese_post.tcc_per_kW')
1✔
890
                if modeling_options["flags"]["bos"]:
1✔
891
                    if modeling_options['flags']['offshore']:
1✔
892
                        self.connect('orbit.total_capex_kW',    'financese_post.bos_per_kW')
1✔
893
                    else:
894
                        self.connect('landbosse.bos_capex_kW',  'financese_post.bos_per_kW')
1✔
895
                else:
896
                    self.connect("costs.bos_per_kW", "financese_post.bos_per_kW")
1✔
897

898
            # Inputs to plantfinancese from input yaml
899
            if modeling_options['flags']['control'] and not modeling_options['Level3']['from_openfast']:
1✔
900
                self.connect('configuration.rated_power',     'financese_post.machine_rating')
1✔
901

902
            if not modeling_options['Level3']['from_openfast']:    
1✔
903
                self.connect('costs.turbine_number',    'financese_post.turbine_number')
1✔
904
                self.connect('costs.opex_per_kW',       'financese_post.opex_per_kW')
1✔
905
                self.connect('costs.offset_tcc_per_kW', 'financese_post.offset_tcc_per_kW')
1✔
906
                self.connect('costs.wake_loss_factor',  'financese_post.wake_loss_factor')
1✔
907
                self.connect('costs.fixed_charge_rate', 'financese_post.fixed_charge_rate')
1✔
908

909
            if modeling_options['DLC_driver']['n_ws_dlc11'] > 0:
1✔
910
                self.connect('aeroelastic.AEP',     'outputs_2_screen_weis.aep')
1✔
911

912
            # Connections to outputs to screen
913
            if not modeling_options['Level3']['from_openfast']:
1✔
914
                self.connect('financese_post.lcoe',          'outputs_2_screen_weis.lcoe')
1✔
915

916
                self.connect('rotorse.blade_mass',  'outputs_2_screen_weis.blade_mass')
1✔
917
                self.connect('aeroelastic.max_TipDxc', 'outputs_2_screen_weis.tip_deflection')
1✔
918

919
            if modeling_options['General']['openfast_configuration']['model_only'] == False:
1✔
920
                self.connect('aeroelastic.DEL_RootMyb',        'outputs_2_screen_weis.DEL_RootMyb')
1✔
921
                self.connect('aeroelastic.DEL_TwrBsMyt',       'outputs_2_screen_weis.DEL_TwrBsMyt')
1✔
922
                self.connect('aeroelastic.rotor_overspeed',    'outputs_2_screen_weis.rotor_overspeed')
1✔
923
                self.connect('aeroelastic.Std_PtfmPitch',      'outputs_2_screen_weis.Std_PtfmPitch')
1✔
924
                self.connect('aeroelastic.Max_PtfmPitch',      'outputs_2_screen_weis.Max_PtfmPitch')
1✔
925
                self.connect('tune_rosco_ivc.omega_pc',        'outputs_2_screen_weis.omega_pc')
1✔
926
                self.connect('tune_rosco_ivc.zeta_pc',         'outputs_2_screen_weis.zeta_pc')
1✔
927
                self.connect('tune_rosco_ivc.omega_vs',        'outputs_2_screen_weis.omega_vs')
1✔
928
                self.connect('tune_rosco_ivc.zeta_vs',         'outputs_2_screen_weis.zeta_vs')
1✔
929
                self.connect('tune_rosco_ivc.Kp_float',        'outputs_2_screen_weis.Kp_float')
1✔
930
                self.connect('tune_rosco_ivc.ptfm_freq',       'outputs_2_screen_weis.ptfm_freq')
1✔
931
                self.connect('tune_rosco_ivc.flp_kp_norm',       'outputs_2_screen_weis.flp_kp_norm')
1✔
932
                self.connect('tune_rosco_ivc.flp_tau',        'outputs_2_screen_weis.flp_tau')
1✔
933
                self.connect('tune_rosco_ivc.IPC_Kp1p',        'outputs_2_screen_weis.IPC_Kp1p')
1✔
934
                self.connect('tune_rosco_ivc.IPC_Ki1p',        'outputs_2_screen_weis.IPC_Ki1p')
1✔
935
                self.connect('dac_ivc.te_flap_end',            'outputs_2_screen_weis.te_flap_end')
1✔
936
                if modeling_options['OL2CL']['flag']:
1✔
937
                    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