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

WISDEM / WEIS / 9244539224

26 May 2024 04:03PM UTC coverage: 80.482% (+9.6%) from 70.847%
9244539224

push

github

web-flow
Merge pull request #279 from WISDEM/wisdem_315

5 of 7 new or added lines in 2 files covered. (71.43%)

689 existing lines in 18 files now uncovered.

21615 of 26857 relevant lines covered (80.48%)

0.8 hits per line

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

45.34
/weis/glue_code/gc_PoseOptimization.py
1
from wisdem.glue_code.gc_PoseOptimization import PoseOptimization
1✔
2
import numpy as np
1✔
3

4
class PoseOptimizationWEIS(PoseOptimization):
1✔
5

6
    def __init__(self, wt_init, modeling_options, analysis_options):
1✔
7
        
8
        self.level_flags = np.array([modeling_options[level]['flag'] for level in ['Level1','Level2','Level3']])
1✔
9
        # if sum(self.level_flags) > 1:
10
            # raise Exception('Only one level in WEIS can be enabled at the same time')
11

12
        super(PoseOptimizationWEIS, self).__init__(wt_init, modeling_options, analysis_options)
1✔
13

14
        # Set solve component for some optimization constraints, and merit figures (RAFT or openfast)
15
        if modeling_options['Level3']['flag']:
1✔
16
            self.floating_solve_component = 'aeroelastic'
1✔
17
        elif modeling_options['Level1']['flag']:
1✔
18
            self.floating_solve_component = 'raft'
1✔
19
        else:
20
            self.floating_solve_component = 'floatingse'
×
21

22
        # aeroelastic won't compute floating period, execpt in special sims
23
        if modeling_options['Level1']['flag']:
1✔
24
            self.floating_period_solve_component = 'raft'
1✔
25
        else:
26
            self.floating_period_solve_component = 'floatingse'
1✔
27
        
28
        
29
    def get_number_design_variables(self):
1✔
30
        # Determine the number of design variables
31
        n_DV = super(PoseOptimizationWEIS, self).get_number_design_variables()
×
32

33
        n_add = 0
×
34
        if self.opt['design_variables']['control']['servo']['pitch_control']['omega']['flag']:
×
35
            n_add += 1
×
36
        if self.opt['design_variables']['control']['servo']['pitch_control']['zeta']['flag']:
×
37
            n_add += 1
×
38
        if self.opt['design_variables']['control']['servo']['pitch_control']['Kp_float']['flag']:
×
39
            n_add += 1
×
40
        if self.opt['design_variables']['control']['servo']['pitch_control']['ptfm_freq']['flag']:
×
41
            n_add += 1
×
42
        if self.opt['design_variables']['control']['servo']['torque_control']['omega']['flag']:
×
43
            n_add += 1
×
44
        if self.opt['design_variables']['control']['servo']['torque_control']['zeta']['flag']:
×
45
            n_add += 1
×
46
        if self.opt['design_variables']['control']['servo']['flap_control']['flp_kp_norm']['flag']:
×
47
            n_add += 1
×
48
        if self.opt['design_variables']['control']['servo']['flap_control']['flp_tau']['flag']:
×
49
            n_add += 1
×
50
        if self.opt['design_variables']['control']['flaps']['te_flap_end']['flag']:
×
51
            n_add += self.modeling['WISDEM']['RotorSE']['n_te_flaps']
×
52
        if self.opt['design_variables']['control']['flaps']['te_flap_ext']['flag']:
×
53
            n_add += self.modeling['WISDEM']['RotorSE']['n_te_flaps']
×
54
        if self.opt['design_variables']['control']['ps_percent']['flag']:
×
55
            n_add += 1
×
56
        
57
        if self.opt['driver']['optimization']['form'] == 'central':
×
58
            n_add *= 2
×
59

60
        # TMD DVs
61
        if self.opt['design_variables']['TMDs']['flag']:
×
62
            TMD_opt = self.opt['design_variables']['TMDs']
×
63

64
            # We only support one TMD for now
65
            for tmd_group in TMD_opt['groups']:
×
66
                if 'mass' in tmd_group:
×
67
                    n_add += 1
×
68
                if 'stiffness' in tmd_group:
×
69
                    n_add += 1
×
70
                if 'damping' in tmd_group:
×
71
                    n_add += 1
×
72

73

74

75
        
76

77
        return n_DV+n_add
×
78

79

80
    
81
    def set_objective(self, wt_opt):
1✔
82
        # Set merit figure. Each objective has its own scaling.  Check first for user override
83
        if self.opt["merit_figure_user"]["name"] != "":
1✔
NEW
84
            coeff = -1.0 if self.opt["merit_figure_user"]["max_flag"] else 1.0
×
NEW
85
            wt_opt.model.add_objective(self.opt["merit_figure_user"]["name"],
×
86
                                       ref=coeff*np.abs(self.opt["merit_figure_user"]["ref"]))
87
            
88
        elif self.opt['merit_figure'] == 'blade_tip_deflection':
1✔
UNCOV
89
            wt_opt.model.add_objective('tcons_post.tip_deflection_ratio')
×
90
            
91
        elif self.opt['merit_figure'] == 'DEL_RootMyb':   # for DAC optimization on root-flap-bending moments
1✔
92
            wt_opt.model.add_objective('aeroelastic.DEL_RootMyb', ref = 1.e3)
×
93
            
94
        elif self.opt['merit_figure'] == 'DEL_TwrBsMyt':   # for pitch controller optimization
1✔
95
            wt_opt.model.add_objective('aeroelastic.DEL_TwrBsMyt', ref=1.e4)
1✔
96
            
97
        elif self.opt['merit_figure'] == 'rotor_overspeed':
1✔
98
            if not any(self.level_flags):
×
99
                raise Exception('Please turn on the call to OpenFAST or RAFT if you are trying to optimize rotor overspeed constraints.')
×
100
            wt_opt.model.add_objective(f'{self.floating_solve_component}.rotor_overspeed')
×
101
        
102
        elif self.opt['merit_figure'] == 'Std_PtfmPitch':
1✔
103
            wt_opt.model.add_objective('aeroelastic.Std_PtfmPitch')
1✔
104
        
105
        elif self.opt['merit_figure'] == 'Max_PtfmPitch':
1✔
106
            wt_opt.model.add_objective('aeroelastic.Max_PtfmPitch')
×
107

108
        elif self.opt['merit_figure'] == 'Cp':
1✔
109
            wt_opt.model.add_objective('aeroelastic.Cp_out', ref=-1.)
×
110
        
111
        elif self.opt['merit_figure'] == 'weis_lcoe' or self.opt['merit_figure'].lower() == 'lcoe':
1✔
112
            wt_opt.model.add_objective('financese_post.lcoe')
×
113
        
114
        elif self.opt['merit_figure'] == 'OL2CL_pitch':
1✔
115
            wt_opt.model.add_objective('aeroelastic.OL2CL_pitch')
×
116
        
117
        else:
118
            super(PoseOptimizationWEIS, self).set_objective(wt_opt)
1✔
119
                
120
        return wt_opt
1✔
121

122
    
123
    def set_design_variables(self, wt_opt, wt_init):
1✔
124
        super(PoseOptimizationWEIS, self).set_design_variables(wt_opt, wt_init)
1✔
125

126
        # -- Control --
127
        control_opt = self.opt['design_variables']['control']
1✔
128
        if control_opt['servo']['pitch_control']['omega']['flag']:
1✔
129
            wt_opt.model.add_design_var('tune_rosco_ivc.omega_pc', lower=control_opt['servo']['pitch_control']['omega']['min'], 
1✔
130
                                                            upper=control_opt['servo']['pitch_control']['omega']['max'])
131
        if control_opt['servo']['pitch_control']['zeta']['flag']:                            
1✔
132
            wt_opt.model.add_design_var('tune_rosco_ivc.zeta_pc', lower=control_opt['servo']['pitch_control']['zeta']['min'], 
1✔
133
                                                           upper=control_opt['servo']['pitch_control']['zeta']['max'])
134
        if control_opt['servo']['torque_control']['omega']['flag']:
1✔
135
            wt_opt.model.add_design_var('tune_rosco_ivc.omega_vs', lower=control_opt['servo']['torque_control']['omega']['min'], 
×
136
                                                            upper=control_opt['servo']['torque_control']['omega']['max'])
137
        if control_opt['servo']['torque_control']['zeta']['flag']:                                                    
1✔
138
            wt_opt.model.add_design_var('tune_rosco_ivc.zeta_vs', lower=control_opt['servo']['torque_control']['zeta']['min'], 
×
139
                                                           upper=control_opt['servo']['torque_control']['zeta']['max'])
140
        if control_opt['servo']['ipc_control']['Kp']['flag']:
1✔
141
            wt_opt.model.add_design_var('tune_rosco_ivc.IPC_Kp1p', lower=control_opt['servo']['ipc_control']['Kp']['min'],
×
142
                                                            upper=control_opt['servo']['ipc_control']['Kp']['max'],
143
                                                            ref=control_opt['servo']['ipc_control']['Kp']['ref'])
144
        if control_opt['servo']['ipc_control']['Ki']['flag']:
1✔
145
            wt_opt.model.add_design_var('tune_rosco_ivc.IPC_Ki1p', lower=control_opt['servo']['ipc_control']['Ki']['min'],
×
146
                                                            upper=control_opt['servo']['ipc_control']['Ki']['max'],
147
                                                            ref=control_opt['servo']['ipc_control']['Kp']['ref'])
148
        if control_opt['servo']['pitch_control']['stability_margin']['flag']:
1✔
149
            wt_opt.model.add_design_var('tune_rosco_ivc.stability_margin', lower=control_opt['servo']['pitch_control']['stability_margin']['min'],
×
150
                                                            upper=control_opt['servo']['pitch_control']['stability_margin']['max'])
151
        if control_opt['flaps']['te_flap_end']['flag']:
1✔
152
            wt_opt.model.add_design_var('dac_ivc.te_flap_end', lower=control_opt['flaps']['te_flap_end']['min'],
×
153
                                                            upper=control_opt['flaps']['te_flap_end']['max'])
154
        if control_opt['flaps']['te_flap_ext']['flag']:
1✔
155
            wt_opt.model.add_design_var('dac_ivc.te_flap_ext', lower=control_opt['flaps']['te_flap_ext']['min'],
×
156
                                                            upper=control_opt['flaps']['te_flap_ext']['max'])
157
        if 'flap_control' in control_opt['servo']:
1✔
158
            if control_opt['servo']['flap_control']['flp_kp_norm']['flag']:
1✔
159
                wt_opt.model.add_design_var('tune_rosco_ivc.flp_kp_norm', 
×
160
                                    lower=control_opt['servo']['flap_control']['flp_kp_norm']['min'], 
161
                                    upper=control_opt['servo']['flap_control']['flp_kp_norm']['max'])
162
            if control_opt['servo']['flap_control']['flp_tau']['flag']:
1✔
163
                wt_opt.model.add_design_var('tune_rosco_ivc.flp_tau', 
×
164
                                    lower=control_opt['servo']['flap_control']['flp_tau']['min'], 
165
                                    upper=control_opt['servo']['flap_control']['flp_tau']['max'])
166

167
        if control_opt['ps_percent']['flag']:
1✔
168
            wt_opt.model.add_design_var('tune_rosco_ivc.ps_percent', lower=control_opt['ps_percent']['lower_bound'],
×
169
                                                            upper=control_opt['ps_percent']['upper_bound'])
170

171
        if control_opt['servo']['pitch_control']['Kp_float']['flag']:
1✔
172
            wt_opt.model.add_design_var('tune_rosco_ivc.Kp_float', lower=control_opt['servo']['pitch_control']['Kp_float']['min'], 
1✔
173
                                                           upper=control_opt['servo']['pitch_control']['Kp_float']['max'])
174

175
        if control_opt['servo']['pitch_control']['ptfm_freq']['flag']:
1✔
176
            wt_opt.model.add_design_var('tune_rosco_ivc.ptfm_freq', lower=control_opt['servo']['pitch_control']['ptfm_freq']['min'], 
1✔
177
                                                           upper=control_opt['servo']['pitch_control']['ptfm_freq']['max'])
178

179
        if self.opt['design_variables']['TMDs']['flag']:
1✔
180
            TMD_opt = self.opt['design_variables']['TMDs']
1✔
181

182
            # We only support one TMD for now
183
            for i_group, tmd_group in enumerate(TMD_opt['groups']):
1✔
184
                if 'mass' in tmd_group:
1✔
185
                    wt_opt.model.add_design_var(
1✔
186
                        f'TMDs.TMD_IVCs.group_{i_group}_mass', 
187
                        lower=tmd_group['mass']['lower_bound'],
188
                        upper=tmd_group['mass']['upper_bound'],
189
                        )
190
                if 'stiffness' in tmd_group:
1✔
UNCOV
191
                    wt_opt.model.add_design_var(
×
192
                        f'TMDs.TMD_IVCs.group_{i_group}_stiffness', 
193
                        lower=tmd_group['stiffness']['lower_bound'],
194
                        upper=tmd_group['stiffness']['upper_bound']
195
                        )
196
                    if 'natural_frequency' in tmd_group:
×
197
                        raise Exception("natural_frequency and stiffness can not be design variables in the same group")
×
198
                if 'damping' in tmd_group:
1✔
UNCOV
199
                    wt_opt.model.add_design_var(
×
200
                        f'TMDs.TMD_IVCs.group_{i_group}_damping', 
201
                        lower=tmd_group['damping']['lower_bound'],
202
                        upper=tmd_group['damping']['upper_bound']
203
                        )
204
                    if 'damping_ratio' in tmd_group:
×
205
                        raise Exception("damping_ratio and damping can not be design variables in the same group")
×
206
                if 'natural_frequency' in tmd_group:
1✔
207
                    wt_opt.model.add_design_var(
1✔
208
                        f'TMDs.TMD_IVCs.group_{i_group}_natural_frequency', 
209
                        lower=tmd_group['natural_frequency']['lower_bound'],
210
                        upper=tmd_group['natural_frequency']['upper_bound']
211
                        )
212
                if 'damping_ratio' in tmd_group:
1✔
213
                    wt_opt.model.add_design_var(
1✔
214
                        f'TMDs.TMD_IVCs.group_{i_group}_damping_ratio', 
215
                        lower=tmd_group['damping_ratio']['lower_bound'],
216
                        upper=tmd_group['damping_ratio']['upper_bound']
217
                        )
218
        
219
        return wt_opt
1✔
220

221
    
222
    def set_constraints(self, wt_opt):
1✔
223
        super(PoseOptimizationWEIS, self).set_constraints(wt_opt)
1✔
224

225
        blade_opt = self.opt["design_variables"]["blade"]
1✔
226
        blade_constr = self.opt["constraints"]["blade"]
1✔
227
        if blade_constr['tip_deflection']['flag']:
1✔
228
            # Remove generic WISDEM one
229
            name = 'tcons.tip_deflection_ratio'
×
230
            if name in wt_opt.model._responses:
×
231
                wt_opt.model._responses.pop( name )
×
232
            if name in wt_opt.model._static_responses:
×
233
                wt_opt.model._static_responses.pop( name )
×
234
                
235
            if blade_opt['structure']['spar_cap_ss']['flag'] or blade_opt['structure']['spar_cap_ps']['flag']:
×
236
                wt_opt.model.add_constraint('tcons_post.tip_deflection_ratio', upper=1.0)
×
237
            else:
238
                print('WARNING: the tip deflection is set to be constrained, but spar caps thickness is not an active design variable. The constraint is not enforced.')
×
239

240
        if blade_constr["strains_spar_cap_ss"]["flag"]:
1✔
241
            # Remove generic WISDEM one
242
            name = 'rotorse.rs.constr.constr_max_strainU_spar'
×
243
            if name in wt_opt.model._responses:
×
244
                wt_opt.model._responses.pop( name )
×
245
            if name in wt_opt.model._static_responses:
×
246
                wt_opt.model._static_responses.pop( name )
×
247
            if blade_opt["structure"]["spar_cap_ss"]["flag"]:
×
248
                indices_strains_spar_cap_ss = range(blade_constr["strains_spar_cap_ss"]["index_start"], blade_constr["strains_spar_cap_ss"]["index_end"])
×
249
                wt_opt.model.add_constraint("rlds_post.constr.constr_max_strainU_spar", indices = indices_strains_spar_cap_ss, upper=1.0)
×
250

251
        if blade_constr["strains_spar_cap_ps"]["flag"]:
1✔
UNCOV
252
            if (
×
253
                blade_opt["structure"]["spar_cap_ps"]["flag"]
254
                or blade_opt["structure"]["spar_cap_ps"]["equal_to_suction"]
255
            ):
256
                # Remove generic WISDEM one
UNCOV
257
                name = 'rotorse.rs.constr.constr_max_strainL_spar'
×
UNCOV
258
                if name in wt_opt.model._responses:
×
UNCOV
259
                    wt_opt.model._responses.pop( name )
×
UNCOV
260
                if name in wt_opt.model._static_responses:
×
UNCOV
261
                    wt_opt.model._static_responses.pop( name )
×
UNCOV
262
                indices_strains_spar_cap_ps = range(blade_constr["strains_spar_cap_ps"]["index_start"], blade_constr["strains_spar_cap_ps"]["index_end"])
×
UNCOV
263
                wt_opt.model.add_constraint("rlds_post.constr.constr_max_strainL_spar", indices = indices_strains_spar_cap_ps, upper=1.0)
×
264

265
        ### CONTROL CONSTRAINTS
266
        control_constraints = self.opt['constraints']['control']
1✔
267
        
268
        # Flap control
269
        if control_constraints['flap_control']['flag']:
1✔
UNCOV
270
            if self.modeling['Level3']['flag'] != True:
×
UNCOV
271
                raise Exception('Please turn on the call to OpenFAST if you are trying to optimize trailing edge flaps.')
×
UNCOV
272
            wt_opt.model.add_constraint('sse_tune.tune_rosco.flptune_coeff1',
×
273
                lower = control_constraints['flap_control']['min'],
274
                upper = control_constraints['flap_control']['max'])
275
            wt_opt.model.add_constraint('sse_tune.tune_rosco.flptune_coeff2', 
×
276
                lower = control_constraints['flap_control']['min'],
277
                upper = control_constraints['flap_control']['max'])    
278
        
279
        # Rotor overspeed
280
        if control_constraints['rotor_overspeed']['flag']:
1✔
281
            if not any(self.level_flags):
1✔
282
                raise Exception('Please turn on the call to OpenFAST or RAFT if you are trying to optimize rotor overspeed constraints.')
×
283
            wt_opt.model.add_constraint(f'{self.floating_solve_component}.rotor_overspeed',
1✔
284
                lower = control_constraints['rotor_overspeed']['min'],
285
                upper = control_constraints['rotor_overspeed']['max'])
286
        
287
        # Add PI gains if overspeed is merit_figure or constraint
288
        if control_constraints['rotor_overspeed']['flag'] or self.opt['merit_figure'] == 'rotor_overspeed':
1✔
289
            wt_opt.model.add_constraint('sse_tune.tune_rosco.PC_Kp',
1✔
290
                upper = 0.0)
291
            wt_opt.model.add_constraint('sse_tune.tune_rosco.PC_Ki', 
1✔
292
                upper = 0.0)  
293
        
294
        # Nacelle Accelleration magnitude
295
        if control_constraints['nacelle_acceleration']['flag']:
1✔
296
            if not any(self.level_flags):
×
297
                raise Exception('Please turn on the call to OpenFAST or RAFT if you are trying to optimize with nacelle_acceleration constraint.')
×
298
            wt_opt.model.add_constraint(f'{self.floating_solve_component}.max_nac_accel',
×
299
                    upper = control_constraints['nacelle_acceleration']['max'])
300
        
301
        # Max platform pitch
302
        if control_constraints['Max_PtfmPitch']['flag']:
1✔
303
            if not any(self.level_flags):
1✔
304
                raise Exception('Please turn on the call to OpenFAST or RAFT if you are trying to optimize Max_PtfmPitch constraints.')
×
305
            wt_opt.model.add_constraint(f'{self.floating_solve_component}.Max_PtfmPitch',
1✔
306
                upper = control_constraints['Max_PtfmPitch']['max'])
307
        
308
        # Platform pitch motion
309
        if control_constraints['Std_PtfmPitch']['flag']:
1✔
310
            if not any(self.level_flags):
×
311
                raise Exception('Please turn on the call to OpenFAST or RAFT if you are trying to optimize Std_PtfmPitch constraints.')
×
312
            wt_opt.model.add_constraint(f'{self.floating_solve_component}.Std_PtfmPitch',
×
313
                upper = control_constraints['Std_PtfmPitch']['max'])
314
        if control_constraints['Max_TwrBsMyt']['flag']:
1✔
315
            if self.modeling['Level3']['flag'] != True:
×
316
                raise Exception('Please turn on the call to OpenFAST if you are trying to optimize Max_TwrBsMyt constraints.')
×
317
            wt_opt.model.add_constraint('aeroelastic.max_TwrBsMyt_ratio', 
×
318
                upper = 1.0)
319
        if control_constraints['DEL_TwrBsMyt']['flag']:
1✔
320
            if self.modeling['Level3']['flag'] != True:
×
321
                raise Exception('Please turn on the call to OpenFAST if you are trying to optimize Max_TwrBsMyt constraints.')
×
322
            wt_opt.model.add_constraint('aeroelastic.DEL_TwrBsMyt_ratio', 
×
323
                upper = 1.0)
324
            
325
        # Blade pitch travel
326
        if control_constraints['avg_pitch_travel']['flag']:
1✔
327
            if self.modeling['Level3']['flag'] != True:
×
328
                raise Exception('Please turn on the call to OpenFAST if you are trying to optimize avg_pitch_travel constraints.')
×
329
            wt_opt.model.add_constraint('aeroelastic.avg_pitch_travel',
×
330
                upper = control_constraints['avg_pitch_travel']['max'])
331

332
        # Blade pitch duty cycle (number of direction changes)
333
        if control_constraints['pitch_duty_cycle']['flag']:
1✔
334
            if self.modeling['Level3']['flag'] != True:
×
335
                raise Exception('Please turn on the call to OpenFAST if you are trying to optimize pitch_duty_cycle constraints.')
×
336
            wt_opt.model.add_constraint('aeroelastic.pitch_duty_cycle',
×
337
                upper = control_constraints['pitch_duty_cycle']['max'])
338

339
        # OpenFAST failure
340
        if self.opt['constraints']['openfast_failed']['flag']:
1✔
341
            if self.modeling['Level3']['flag'] != True:
1✔
342
                raise Exception('Please turn on the call to OpenFAST if you are trying to optimize with openfast_failed constraint.')
×
343
            wt_opt.model.add_constraint('aeroelastic.openfast_failed',upper = 1.)
1✔
344

345
        # Max offset
346
        if self.opt['constraints']['floating']['Max_Offset']['flag']:
1✔
347
            if not any(self.level_flags):
×
348
                raise Exception('Please turn on the call to OpenFAST or RAFT if you are trying to optimize with openfast_failed constraint.')
×
UNCOV
349
            wt_opt.model.add_constraint(
×
350
                f'{self.floating_solve_component}.Max_Offset',
351
                upper = self.opt['constraints']['floating']['Max_Offset']['max']
352
                )
353
                
354
        # Tower constraints
355
        tower_opt = self.opt["design_variables"]["tower"]
1✔
356
        tower_constr = self.opt["constraints"]["tower"]
1✔
357
        if tower_constr["global_buckling"]["flag"] and self.modeling['Level3']['flag']:
1✔
358
            # Remove generic WISDEM one
359
            name = 'towerse.post.constr_global_buckling'
×
360
            if name in wt_opt.model._responses:
×
361
                wt_opt.model._responses.pop( name )
×
362
            if name in wt_opt.model._static_responses:
×
363
                wt_opt.model._static_responses.pop( name )
×
364
                
365
            wt_opt.model.add_constraint("towerse_post.constr_global_buckling", upper=1.0)
×
366
        
367
        if tower_constr["shell_buckling"]["flag"] and self.modeling['Level3']['flag']:
1✔
368
            # Remove generic WISDEM one
369
            name = 'towerse.post.constr_shell_buckling'
×
370
            if name in wt_opt.model._responses:
×
371
                wt_opt.model._responses.pop( name )
×
372
            if name in wt_opt.model._static_responses:
×
373
                wt_opt.model._static_responses.pop( name )
×
374
                
375
            wt_opt.model.add_constraint("towerse_post.constr_shell_buckling", upper=1.0)
×
376
        
377
        if tower_constr["stress"]["flag"] and self.modeling['Level3']['flag']:
1✔
378
            # Remove generic WISDEM one
379
            name = 'towerse.post.constr_stress'
×
380
            if name in wt_opt.model._responses:
×
381
                wt_opt.model._responses.pop( name )
×
382
            if name in wt_opt.model._static_responses:
×
383
                wt_opt.model._static_responses.pop( name )
×
384
                
385
            wt_opt.model.add_constraint("towerse_post.constr_stress", upper=1.0)
×
386

387
        # Damage constraints
388
        damage_constraints = self.opt['constraints']['damage']
1✔
389
        if damage_constraints['tower_base']['flag'] and (self.modeling['Level2']['flag'] or self.modeling['Level3']['flag']):
1✔
390
            if self.modeling['Level3']['flag'] != True:
1✔
391
                raise Exception('Please turn on the call to OpenFAST if you are trying to optimize with tower_base damage constraint.')
×
392

393
            tower_base_damage_max = damage_constraints['tower_base']['max']
1✔
394
            if damage_constraints['tower_base']['log']:
1✔
395
                tower_base_damage_max = np.log(tower_base_damage_max)
1✔
396

397
            wt_opt.model.add_constraint('aeroelastic.damage_tower_base',upper = tower_base_damage_max)
1✔
398

399
        return wt_opt
1✔
400

401

402
    def set_initial_weis(self, wt_opt):
1✔
403

404
        if self.modeling["flags"]["blade"]:
1✔
405
            blade_constr = self.opt["constraints"]["blade"]
1✔
406
            wt_opt["rlds_post.constr.max_strainU_spar"] = blade_constr["strains_spar_cap_ss"]["max"]
1✔
407
            wt_opt["rlds_post.constr.max_strainL_spar"] = blade_constr["strains_spar_cap_ps"]["max"]
1✔
408
            wt_opt["stall_check_of.stall_margin"] = blade_constr["stall"]["margin"] * 180.0 / np.pi
1✔
409
            wt_opt["tcons_post.max_allowable_td_ratio"] = blade_constr["tip_deflection"]["margin"]
1✔
410

411
        return wt_opt
1✔
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

© 2026 Coveralls, Inc