Optimization run problems

Dear all,

I was exploring the capabilities of Wisdem/Weis software. I am relatively new to this code and I’m experiencing some problems in setting up a simple test case taken from the Weis GitHub repository. I am using the “weis_driver_umaine_semi.py” driver in the “06_IEA-15-240-RWT” repository at the link: https://github.com/WISDEM/WEIS/tree/main/examples/06_IEA-15-240-RWT.
My goal was to execute an optimization study on the internal structure of the blade (spar cap thickness).
I have run the code from the example changing the section of the analysis_options.yaml file as follows:

design_variables:
design_variables:
blade:
structure:
spar_cap_ss:
flag: False # Flag to optimize the spar cap thickness on the suction side
n_opt: 8 # Number of control points along blade span
max_decrease: 0.2 # Nondimensional maximum decrease at the n_opt locations
max_increase: 2.0 # Nondimensional maximum increase at the n_opt locations

            spar_cap_ps:
                flag: False     # Flag to optimize the spar cap thickness on the pressure side
                equal_to_suction: True # Flag to impose the spar cap thickness on pressure and suction sides equal
                n_opt: 8        # Number of control points along blade span
                max_decrease: 0.2   # Nondimensional maximum decrease at the n_opt locations
                max_increase: 2.0   # Nondimensional maximum increase at the n_opt locations

merit_figure: LCOE

driver:
optimization:
flag: True # Flag to enable optimization
design_of_experiments:
flag: False # Flag to enable design of experiments
run_parallel: False # Flag to run using parallel processing
generator: Uniform # FullFact # Type of input generator. (Uniform)
num_samples: 2 # number of samples for (Uniform only)

recorder:
flag: True # Flag to activate OpenMDAO recorder
file_name: log_opt.sql # Name of OpenMDAO recorder

The modeling_options yaml file has been left unchanged.
However, when running the modified example, the code generates the following errors:

I am probably missing some settings, but I was not able to find the error looking at the documentation.
Could you please give me some suggestions to properly set up the case?

Thanks in advance.
Best regards,

Hello,
there might be a few things going on here. First, please confirm that you’ve compiled WEIS from the main branch of GitHub - WISDEM/WEIS: Wind Energy with Integrated Servo-controls Toolset, without manually switching WISDEM to an older version. The error that you report might be pointing in this direction… A conda list command in your terminal will tell you what WISDEM you are using. Ideally you are on v3.16.4. Next, please refer to this analysis_options.yaml WISDEM/examples/03_blade/analysis_options_struct.yaml at master · WISDEM/WISDEM · GitHub for a blade structural optimization. Your section above is not formatted correctly, but it seems that your spar caps flags are set to False. Also, LCOE will be not too sensitive to spar cap thickness, I’d pick blade mass if that’s all you are optimizing.
I hope this helps

Dear @Pietro.Bortolotti ,

thank you very much for your suggestions.
I have tried to modify the analysis options file, following your indications and the example.

However, I still have troubles in setting up the optimization run.
Using the following settings for analysis options:

general:
folder_output: outputs/06_IEA15_single_run
fname_output: refturb_output

design_variables:
blade:
structure:
- layer_name: spar_cap_ss
flag: True
n_opt: 4 # Number of control points along blade span
max_decrease: 0.7 # Maximum nondimensional decrease at the n_opt locations
max_increase: 1.3 # Maximum nondimensional increase at the n_opt locations
index_start: 1 # Lock the first DV from blade root
index_end: 3 # The last DV at blade tip is locked

        - layer_name: spar_cap_ps 
          flag: True
          n_opt: 4               # Number of control points along blade span
          max_decrease: 0.7      # Maximum nondimensional decrease at the n_opt locations
          max_increase: 1.3      # Maximum nondimensional increase at the n_opt locations
          index_start: 1         # Lock the first DV from blade root
          index_end: 3           # The last DV at blade tip is locked

merit_figure: blade_mass

constraints:
blade:
strains_spar_cap_ss:
flag: True # Flag to impose constraints on maximum strains (absolute value) in the spar cap on the blade suction side
max: 3500.e-6 # Value of maximum strains [-]
index_start: 1 # Do not enforce constraint at the first station from blade root of the n_opt from spar_cap_ss
index_end: 3 # Do not enforce constraint at the last station at blade tip of the n_opt from spar_cap_ss
strains_spar_cap_ps:
flag: True # Flag to impose constraints on maximum strains (absolute value) in the spar cap on the blade pressure side
max: 3500.e-6 # Value of maximum strains [-]
index_start: 1 # Do not enforce constraint at the first station from blade root of the n_opt from spar_cap_ps
index_end: 3 # Do not enforce constraint at the last station at blade tip of the n_opt from spar_cap_ps
tip_deflection:
flag: True
margin: 1.134 #1.4175

driver:
optimization:
flag: True # Flag to enable optimization
tol: 1.e-3 # Optimality tolerance
# max_major_iter: 10 # Maximum number of major design iterations (SNOPT)
# max_minor_iter: 100 # Maximum number of minor design iterations (SNOPT)
max_iter: 30 # Maximum number of iterations (SLSQP)
solver: SLSQP # Optimization solver. Other options are ‘SLSQP’ - ‘CONMIN’
step_size: 1.e-3 # Step size for finite differencing
form: forward # Finite differencing mode, either forward or central
design_of_experiments:
flag: False # Flag to enable design of experiments
run_parallel: False # Flag to run using parallel processing
generator: Uniform # FullFact # Type of input generator. (Uniform)
num_samples: 2 # number of samples for (Uniform only)

recorder:
flag: True # Flag to activate OpenMDAO recorder
file_name: log_opt.sql # Name of OpenMDAO recorder

and the following ones for modelling options:

General:
verbosity: False # When set to True, the code prints to screen many infos
openfast_configuration:
use_exe: True
allow_fails: True
fail_value: 9999

WISDEM:
RotorSE:
flag: True
spar_cap_ss: spar_cap_ss
spar_cap_ps: spar_cap_ps
te_ss: TE_reinforcement_SS
te_ps: TE_reinforcement_PS
n_span: 60
DriveSE:
flag: True
TowerSE:
flag: True
wind: PowerWind # Wind used
gamma_f: 1.35 # Safety factor for fatigue loads
gamma_m: 1.3 # Safety factor for material properties
gamma_n: 1.0 # Safety factor for …
gamma_b: 1.1 # Safety factor for …
gamma_fatigue: 1.755 # Safety factor for fatigue loads
buckling_length: 30 # Buckling parameter
soil_springs: True
gravity_foundation: False
frame3dd:
shear: True
geom: True
tol: 1e-9
FixedBottomSE:
flag: False
FloatingSE:
flag: True
rank_and_file: True
# BOS:
# flag: True

Level3: # Options for WEIS fidelity level 3 = nonlinear time domain
flag: True
simulation:
DT: 0.01
CompElast: 1
CompInflow: 1
CompAero: 2
CompServo: 1
CompHydro: 1
CompSub: 0
CompMooring: 3
CompIce: 0
OutFileFmt: 3
NumCrctn: 1
linearization:
Linearize: False
ElastoDyn:
FlapDOF1: True
FlapDOF2: True
EdgeDOF: True
TeetDOF: False
DrTrDOF: False
GenDOF: True
YawDOF: False
TwFADOF1 : True
TwFADOF2 : True
TwSSDOF1 : True
TwSSDOF2 : True
PtfmSgDOF: True
PtfmSwDOF: True
PtfmHvDOF: True
PtfmRDOF : True
PtfmPDOF : True
PtfmYDOF : True
HydroDyn:
WvLowCOff: 0.15708
WvHiCOff: 3.2
WaveSeed1: 123456789
AddBQuad1: [9.23e5, 0.0, 0.0, 0.0, -8.92e6, 0.0]
AddBQuad2: [0.0, 9.23e5, 0.0, 8.92e6, 0.0, 0.0]
AddBQuad3: [0.0, 0.0, 2.3e6, 0.0, 0.0, 0.0]
AddBQuad4: [0.0, 8.92e6, 0.0, 1.68e10, 0.0, 0.0]
AddBQuad5: [-8.92e6, 0.0, 0.0, 0.0, 1.68e10, 0.0]
AddBQuad6: [0.0, 0.0, 0.0, 0.0, 0.0, 4.8e10]
PotMod: 1
# WaveMod: 0
PotFile: /home/sp/WEIS/examples/01_aeroelasticse/OpenFAST_models/IEA-15-240-RWT/IEA-15-240-RWT-UMaineSemi/HydroData/IEA-15-240-RWT-UMaineSemi
# …/01_aeroelasticse/OpenFAST_models/IEA-15-240-RWT/IEA-15-240-RWT-UMaineSemi/HydroData/IEA-15-240-RWT-UMaineSemi

Level1:
flag: False
potential_model_override: 2

ROSCO:
flag: True
tuning_yaml: /home/sp/WEIS/examples/01_aeroelasticse/OpenFAST_models/IEA-15-240-RWT/IEA-15-240-RWT-UMaineSemi/IEA15MW-UMaineSemi.yaml
#…/01_aeroelasticse/OpenFAST_models/IEA-15-240-RWT/IEA-15-240-RWT-UMaineSemi/IEA15MW-UMaineSemi.yaml

DLC_driver:
metocean_conditions:
wind_speed: [4., 6., 8., 10., 12., 14., 16., 18., 20., 22., 24.]
wave_height_NSS: [0.83, 0.88, 0.94, 1.03, 1.16, 1.34, 1.57, 1.86, 2.22, 2.62, 3.07]
wave_period_NSS: [6.9, 6.96, 7.02, 7.12, 7.25, 7.43, 7.66, 7.94, 8.27, 8.63, 9.01]
wave_height_SSS: [6.3, 8, 8, 8.1, 8.5, 8.5, 9.8, 9.8, 9.8, 9.8, 9.9]
wave_period_SSS: [11.5, 12.7, 12.7, 12.8, 13.1, 13.1, 14.1, 14.1, 14.1, 14.1, 14.1]
wave_height1: 6.98
wave_period1: 11.7
wave_height50: 10.68
wave_period50: 14.2
DLCs:
# - DLC: “1.1”
# wind_speed: [24]
# wave_height: [9]
# wave_period: [14]
# n_seeds: 6
# analysis_time: 600
# transient_time: 120
# turbulent_wind:
# HubHt: 140
# GridHeight: 300
# GridWidth: 300
# - DLC: “1.3”
# n_seeds: 6
# - DLC: “1.4”
# - DLC: “1.5”
- DLC: “1.6”
wind_speed: [12]
transient_time: 0.
analysis_time: 10.
# - DLC: “6.1”
# n_seeds: 6
# - DLC: “6.3”
# n_seeds: 6

I still have the following error:

Thanks in advance for your support.
Best regards,

Well, thank you for helping us fix an outdated part of the code.
I’ve fixed things here GitHub - WISDEM/WEIS at blade_struct_opt
If you are comfortable with git, in a terminal go to your WEIS folder and type git fetch origin followed by a git checkout blade_struct_opt. We’ll merge this branch into develop in the next few days. Also, in your analysis options yaml make sure to increase n_opt to 8 or so. 4 is too coarse of a discretization. This documentation might help https://wisdem.readthedocs.io/en/master/examples/03_blade/tutorial.html

Once ready, give your code a new shot and let us know if you are able to run things

Thanks again,
Pietro

Dear @Pietro.Bortolotti ,
thanks for your help, I downloaded the blade_struct_opt version of gc_PoseOptimization.py from the repository and I was able to run an optimization without errors. At first I used SLSQP method as optimzation driver, but I noticed that the optimization run ended after just one iteration without any improvement on the structural mass. So, I changed the driver to CONMIN and in this case the optimization led to an improved blade mass, with the iteration sequence reported in the graph below.
opt_output

Are there any guidelines for a proper choice of optimization method? Or are there any errors on my analysis options file for the SLSQP method? I attached below the file.

general:
folder_output: outputs/06_IEA15_single_run
fname_output: refturb_output

design_variables:
blade:
structure:
- layer_name: spar_cap_ss
flag: True
n_opt: 10 # Number of control points along blade span
max_decrease: 0.7 # Maximum nondimensional decrease at the n_opt locations
max_increase: 1.3 # Maximum nondimensional increase at the n_opt locations
index_start: 1 # Lock the first DV from blade root
index_end: 3 # The last DV at blade tip is locked

        - layer_name: spar_cap_ps 
          flag: True
          n_opt: 10               # Number of control points along blade span
          max_decrease: 0.7      # Maximum nondimensional decrease at the n_opt locations
          max_increase: 1.3      # Maximum nondimensional increase at the n_opt locations
          index_start: 1         # Lock the first DV from blade root
          index_end: 3           # The last DV at blade tip is locked

merit_figure: blade_mass

constraints:
blade:
strains_spar_cap_ss:
flag: True # Flag to impose constraints on maximum strains (absolute value) in the spar cap on the blade suction side
max: 3500.e-6 # Value of maximum strains [-]
index_start: 1 # Do not enforce constraint at the first station from blade root of the n_opt from spar_cap_ss
index_end: 3 # Do not enforce constraint at the last station at blade tip of the n_opt from spar_cap_ss
strains_spar_cap_ps:
flag: True # Flag to impose constraints on maximum strains (absolute value) in the spar cap on the blade pressure side
max: 3500.e-6 # Value of maximum strains [-]
index_start: 1 # Do not enforce constraint at the first station from blade root of the n_opt from spar_cap_ps
index_end: 3 # Do not enforce constraint at the last station at blade tip of the n_opt from spar_cap_ps
tip_deflection:
flag: True
margin: 1.134 #1.4175

driver:
optimization:
flag: True # Flag to enable optimization
tol: 1.e-3 # Optimality tolerance
# max_major_iter: 10 # Maximum number of major design iterations (SNOPT)
# max_minor_iter: 100 # Maximum number of minor design iterations (SNOPT)
max_iter: 30 # Maximum number of iterations (SLSQP)
solver: CONMIN # Optimization solver. Other options are ‘SLSQP’ - ‘CONMIN’
step_size: 1.e-3 # Step size for finite differencing
form: forward # Finite differencing mode, either forward or central
design_of_experiments:
flag: False # Flag to enable design of experiments
run_parallel: False # Flag to run using parallel processing
generator: Uniform # FullFact # Type of input generator. (Uniform)
num_samples: 2 # number of samples for (Uniform only)

recorder:
flag: True # Flag to activate OpenMDAO recorder
file_name: log_opt.sql # Name of OpenMDAO recorder

Thanks again for your support,

Aeroelastic simulations can generate noisy gradients, especially in the presence of turbulent wind. Gradient based optimizers such as SLSQP often struggle to converge, and we usually end up favoring gradient free optimizers such as Cobyla, see this recent publication
https://doi.org/10.1088/1742-6596/2767/8/082020

An alternative approach consists of building a more complex optimization workflows, as described in these other publications
https://doi.org/10.5194/wes-1-71-2016

Dear @Pietro.Bortolotti ,
Thanks for your suggestions, I’ll try to use COBYLA method for my optimization, following the indications of these publications.
Best regards,