I have installed WISDEM on a Ubuntu 48-CPU workstation to run optimization in parallel.
To test it, I first launched the serial optimization that succeded on the WISDEM installed on my Windows-10 PC, that is, the aerostructural optimization in the WISDEM example nr 3.
The successful run on Windows took about 1 hour and 30 minutes to complete, the one on Ubuntu was still running after 10 hours…
Of course, the optimization input files are the same, and I followed the same procedure in the documentation for both WISDEM installations.
I installed WISDEM on Windows in May (10 May 2021) and on Ubuntu two weeks ago (1 October 2021). The Ubuntu version is 20.04.
After the installation on Ubuntu, I run the installation tests and one test failed (see screenshot in attachment): perhaps, this can be a hint on something wrong in my Ubuntu installation.
I am not sure why your Ubuntu WISDEM installation was taking so long. Was this with Anaconda or the native Ubuntu python packages? In my experience, the Windows simulations usually take longer because the open-source compilers aren’t great on Windows. Are you absolutely sure all of the input files were identical? Without some more detailed comparison regarding packages, compilers, problem setup, it will be almost impossible for me to be able to diagnose what the problem was. We could try to slowly go through that on the forum or maybe you are content to use your Windows installation?
I tried few other tests of my Ubuntu installation of WISDEM, but let’go in order:
With Anaconda.
Yes. I re-run twice the same input files on Windows and on Ubuntu, and optimizations converged in ~1h30min on Windows, and kept running hours and hours on Ubuntu.
Now, my other tests were:
two basics optimization cases coded directly in openMDAO
the simple aerodynamic blade optimization in the WISDEM example nr. 3
Both openMDAO optimizations succeded on Ubuntu and were faster than when run on Windows. And also the simple aerodynamic blade optimization succeded on Ubuntu and gave the same results as on WIndows (it was a little slower, 5min50sec against 5min25sec on WIndows, but I do not see this as much of a problem).
My WISDEM version on Windows is 3.2.0 dev_0, but the one on Ubuntu is 3.3.0 dev_0: I am thinking to install WISDEM 3.2.0 in an other conda environment and re-run the test case in it… May it help?
Yes, you would have to be using the same version of WISDEM to make a fair comparison between the platforms. I would sync both to either the same Anaconda release or to the current develop-branch.
Just a forewarning, we might not be able to get to the bottom of the issue. This is the type of problem that is very difficult to diagnose.
I installed the WISDEM version that I have on my Windows 10 PC (WISDEM=3.2.0, python=3.7.4, conda=4.8.1) on my Ubuntu workstation with the procedure detailed below. conda list confirms that I have wisdem version 3.2.0 in the wisdem-320-env-bis conda environment.
But, when I run WISDEM test_all.py to check the installation, it soon stops with the error in the screenshot.
nlopt version 2.7.0 is installed.
What is wrong in my installation procedure?
Thank you for your time Garrett.
WISDEM 3.2.0 installation procedure (started from within the newly created folder ~/wisdem320/):
Looks like some of the dependencies may have gotten out of step with one another. Perhaps try: ‘conda update --all’ to be sure you have the latest version of everything.
and got the updates, but then, a series of errors about modules not installed started appearing in sequence, as I tried to launch an optimization. To solve these errors I installed numpy, openmdao, sortedcontainers in the wisdem environment, and then the next error asked for the yaml module, which, however, conda refused to install because it is already installed …
Regarding version 3.3.0, then, I managed to run successfully the aerostructural optimization example that shipped with the installation (not the one I run on Windows). I succeded both the serial and the parallel calculations.
Then I reduced the optimality tolerance from 1e-5 to 1e-3 and increased the maximum number of iterations to 20: the parallel (10 cores) calculation succeded even faster, ~5min instead of ~31min.
The analysis options for this optimization have the number of control points for chord, twist, sparcaps thicness, and trailing-edge thickness set to 4. I increased this number to 10, adjusted index_end to 9, and run with tol=1e-3, and max_iter=20, but the parallel (10 cores) optimization failed because of "iteration limit reached " . Setting max_iter to 100 did not help neither: again failure because of "iteration limit reached " , after 5h40min of calculation.
Are there some more settings to adjust to have the aerostructural optimization working also with more control points?
At this point, since version 3.3.0 is at least operative on my PC, I prefer to focus on this problem rather than the one of version 3.2.0.
general:
folder_output: outputs_aerostruct_tol0001_allCtrlPnts10_allCnstrnt_iter100_5
fname_output: blade_out
design_variables:
rotor_diameter:
flag: True # False @ 3 Sept 2021
minimum: 190
maximum: 240
blade:
aero_shape:
twist:
flag: True # Flag to optimize the twist; True if 'inverse'=False and viceversa
inverse: False # Flag to determine twist from the user-defined desired margin to stall (defined in constraints) False
n_opt: 10 # Number of control points along blade span; default=4
max_decrease: 0.08722222222222221 # Maximum decrease for the twist in [rad] at the n_opt locations
max_increase: 0.08722222222222221 # Maximum increase for the twist in [rad] at the n_opt locations
index_start: 2 # Lock the first two DVs from blade root
index_end: 10 # All DVs close to blade tip are active
chord:
flag: True # Flag to optimize the chord
n_opt: 10 # Number of control points along blade span; default=4
max_decrease: 0.3 # Minimum multiplicative gain on existing chord at the n_opt locations
max_increase: 3. # Maximum multiplicative gain on existing chord at the n_opt locations
index_start: 2 # Lock the first two DVs from blade root
index_end: 9 # The last DV at blade tip is locked;
# It is recommended to lock the last point close to blade tip, setting index_end to n_opt minus 1
structure:
spar_cap_ss:
flag: True # Flag to optimize the spar cap thickness on the suction side
n_opt: 10 # Number of control points along blade span; default=4
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: 9 # The last DV at blade tip is locked
# It is recommended to lock the last point close to blade tip, setting index_end to n_opt minus 1
spar_cap_ps:
flag: True # 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: 10 # Number of control points along blade span; default=4
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: 9 # The last DV at blade tip is locked
te_ss:
flag: True # Flag to optimize the spar cap thickness on the pressure side
n_opt: 10 # Number of control points along blade span; default=4
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: 9 # The last DV at blade tip is locked
te_ps:
flag: True # Flag to optimize the spar cap thickness on the pressure side
n_opt: 10 # Number of control points along blade span; default=4
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: 9 # The last DV at blade tip is locked
merit_figure: LCOE
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: 9 # 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: 9 # Do not enforce constraint at the last station at blade tip of the n_opt from spar_cap_ps
strains_te_ss:
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: 9 # Do not enforce constraint at the last station at blade tip of the n_opt from spar_cap_ps
strains_te_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: 9 # Do not enforce constraint at the last station at blade tip of the n_opt from spar_cap_ps
tip_deflection:
flag: True # True
margin: 1.4175
stall:
flag: True # Constraint on minimum stall margin
margin: 0.087 # Value of minimum stall margin in [rad] default=0.05233 range=[0.0:0.5]
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: 100 # 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
# check_partials: # 1 Sept 2021
# flag: True
recorder:
flag: False # Flag to activate OpenMDAO recorder
file_name: log_opt.sql # Name of OpenMDAO recorder
Turn on the openmdao recorder at the end of your analysis option yaml. That will create log file in your output folder. Next, create a .py script in your run directory with these lines.
import openmdao.api as om
from wisdem.glue_code.gc_RunTools import PlotRecorder
import wisdem.inputs as sch
import os
mydir = os.path.dirname(os.path.realpath(__file__)) # get path to this file
fname_analysis_options = mydir + os.sep + "analysis_options.yaml"
analysis_options = sch.load_analysis_yaml(fname_analysis_options)
wt_opt = om.Problem(model=PlotRecorder(opt_options=analysis_options))
wt_opt.setup(derivatives=False)
wt_opt.run_model()
When you run this file from your wisdem environment, in the output folder a series of convergence plots will appear, showing you the design variables, constraints, and figure of merit against across the iterations. This will likely show why the optimizer is not stopping.
Try simplifying your optimization problem, running the aerodynamic only test first and then the structural only test. Do those tests converge? Slowly move up in complexity of your problem
I apologize for the late reply (the workstation has been unavailable for some weeks).
The aerodynamic-only test fails as I increase twist and chord control points from 4 to 10 because of Iteration limit reached, even if I set max_iter to 100 (tol=1E-3).
The structural-only test, instead, succeeds for 20 and 30 control points for spar caps and trailing edge thicknesses with max_iter set to 100 (tol=1E-3).
Looking at the convergence trends (two of them, representative of all the trends, in attachment), the ones of the succeeded optimization proceed smoothly towards the final values, while those of the failed optimization after initial large changes stay almost flat with some peaks.
I noted also that, despite my max_iter settings, the number of iterations reported in the plot of the failed optimization is much larger than 100, while 25 is the number of iterations that the successful optimization needed for convergence, as per CLI output.
What can I change in the settings of the aerodynamic-only optimization to have convergence?
This is the analysis_options_aero.yaml file:
general:
folder_output: outputs_aero_計算番号2
fname_output: blade_out
design_variables:
blade:
aero_shape:
twist:
flag: True # Flag to optimize the twist
inverse: False # Flag to determine twist from the user-defined desired margin to stall (defined in constraints)
n_opt: 10 # Number of control points along blade span
max_decrease: 0.08722222222222221 # Maximum decrease for the twist in [rad] at the n_opt locations
max_increase: 0.08722222222222221 # Maximum increase for the twist in [rad] at the n_opt locations
index_start: 2 # Lock the first two DVs from blade root
index_end: 10 # All DVs close to blade tip are active
chord:
flag: True # Flag to optimize the chord
n_opt: 10 # Number of control points along blade span; 元の数値= 4
max_decrease: 0.3 # Minimum multiplicative gain on existing chord at the n_opt locations
max_increase: 3. # Maximum multiplicative gain on existing chord at the n_opt locations
index_start: 0 # Start by optimizing chord at blade root
index_end: 9 # Lock chord at blade tip
merit_figure: AEP
constraints:
blade:
stall:
flag: True # Constraint on minimum stall margin
margin: 0.087 # Value of minimum stall margin in [rad]
chord:
flag: True # Constraint max chord to its default value (4.75 m)
root_circle_diameter:
flag: True # Constraint for the minimum blade root circle diameter
max_ratio: 1.2 # The recommended value can be up to 20% larger than the actual
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: 20 # 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
recorder:
flag: True #False # Flag to activate OpenMDAO recorder
file_name: log_opt.sql # Name of OpenMDAO recorder
Dear Henny,
my apologies for the slow reply.
I believe that the aerodynamic optimization is not able to satisfy one (or more) constraint among the ones that you’ve set active
constraints:
blade:
stall:
flag: True # Constraint on minimum stall margin
margin: 0.087 # Value of minimum stall margin in [rad]
chord:
flag: True # Constraint max chord to its default value (4.75 m)
root_circle_diameter:
flag: True # Constraint for the minimum blade root circle diameter
max_ratio: 1.2 # The recommended value can be up to 20% larger than the actual
Could you please try turning the constraints off and rerun? Once you identify what cannot be satisfied, we can focus on why that is.
Thank you!
Pietro
If the message is “Iteration limit reached” with “Optimization FAILED” it means it did not reach the tolerance in the allowed number of iterations. You would need to relax the tolerance or extend the number of iterations. With your settings, I would suggest more than 20 iterations.
I didn’t see an attachment for the Frame3DD error. Usually that means needing to narrow your design variable bounds.
the optimization with only blade root_circle_diameter constrained succeeds
the optimization with blade root_circle_diameter and chord constrained succeeds
reducing the twist and chord values of max_decrease, max_increase to 2/3 of their previous values prevents the crash of the optimization with only blade stall constrained, but it still fails after 20 or 100 iterations. So the problem seems to be in the stall constrain set along with ten control points for the twist and chord design variables.