# WISDEM blade optimization example: my output plot not like in the example

**URL:** <https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530>\
**Category:** Computer-Aided Engineering Software Tools\
**Created:** [August 26, 2021, 5:19am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530 "2021-08-26T05:19:34Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Henny.Bottini](https://dub1.discourse-cdn.com/nrel/user_avatar/forums.nlr.gov/henny.bottini/32/3236_2.png) [@Henny.Bottini](https://forums.nlr.gov/u/Henny.Bottini)\
**Post date:** [August 26, 2021, 5:19am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/1 "2021-08-26T05:19:34Z")

</div>

I have run the Blade Optimization Example found in [https://wisdem.readthedocs.io/en/master/examples/blade/tutorial.html](https://wisdem.readthedocs.io/en/master/examples/blade/tutorial.html) for the three cases baseline, aerodynamic optimization, and structural optimization.

My problem is that my output plots are not like the ones shown in the example.

For all the runs I use the input .yaml files provided in my WISDEM folder “examples\03\_blade”.

The baseline calculation succeds, the Simple Aerodynamic Optimization fails with the max\_iter optimization parameter set to 2 (as expected, I have understood from the example text), but also with max\_iter set to 10 or 20, and the Simple Structural Optimization succeds with max\_iter set to 10.

Then, for the successful structural optimization, I generated the plots to compare the optimized variables to the baseline ones with the command

> [@](#):
>
> compare\_designs outputs\blade\_out.yaml outputs\_struct\blade\_out.yaml

and, for the unsuccessful aerodynamic optimization, with the command

> [@](#):
>
> compare\_designs outputs\blade\_out.yaml outputs\_aero\blade\_out.yaml

Now, for the structural optimization, my plot of unit mass vs. blade non-dimensional span is exactly like Fig. 4 in the example, but the plot of spar cap thickness vs. blade non-dim span is not like Fig. 3, and shows no difference between the baseline case and the optimized case (see attachment sc\_opt.png).  
Since I haven’t changed anything in the .yaml files except max\_iter value, I would like to know why this plot does not match that reported in the example.

Similarly, for the failed aerodynamic optimization, my plot of twist vs non-dimensional blade span, unlike Fig. 2 in the example, shows no difference between the baseline case and the optimized case (see attachment twist\_opt.png). However, the plot of axial induction vs. blade non-dim span does show a difference between the two cases, but is not the same as in Fig. 1 (see attachment induction.png).  
In this case I wonder whether I should expect my plots to be like figures 1 and 2 only in case of succesfull optimization; I have not understood that from the example text.

Thank you for your time and attention.  
 ![induction.png](https://europe1.discourse-cdn.com/nrel/original/2X/9/950b102a40d4a8e8941a889fbc638e3531003ce3.png)  
 ![twist_opt.png](https://europe1.discourse-cdn.com/nrel/original/2X/6/6761c9c032af2b9ceddb22b49b4d55b1cecf630e.png)  
 ![sc_opt.png](https://europe1.discourse-cdn.com/nrel/original/2X/2/2159dc065a515d5f26d05bbcd8cadff00ef2c19e.png)

---

<div class="post-metadata">

**Author:** ![Garrett.Barter](https://avatars.discourse-cdn.com/v4/letter/g/958977/32.png) [@Garrett.Barter](https://forums.nlr.gov/u/Garrett.Barter)\
**Post date:** [August 26, 2021, 11:41pm UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/2 "2021-08-26T23:41:08Z")

</div>

I obtain the same plots as you when I walk through the example. This is partly due to (1) the baseline design and code shifting a bit since those example plots in the documentation were generated, and (2) the compare\_design script has slowly crept out of date. Thanks to your question, I have fixed some of the plotting issues in the “develop” branch. If you do “git checkout develop” and then “git pull”, that might help.

---

<div class="post-metadata">

**Author:** ![Henny.Bottini](https://dub1.discourse-cdn.com/nrel/user_avatar/forums.nlr.gov/henny.bottini/32/3236_2.png) [@Henny.Bottini](https://forums.nlr.gov/u/Henny.Bottini)\
**Post date:** [August 30, 2021, 2:50am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/3 "2021-08-30T02:50:14Z")

</div>

> [@Garrett.Barter](#):
>
> I obtain the same plots as you when I walk through the example. This is partly due to (1) the baseline design and code shifting a bit since those example plots in the documentation were generated, and (2) the compare\_design script has slowly crept out of date. Thanks to your question, I have fixed some of the plotting issues in the “develop” branch. If you do “git checkout develop” and then “git pull”, that might help.

Thank you for your fast reply.  
I have never used git before, and would like to be sure of what those two commands do before issuying them, so, please, clarify to me the following points.

“git checkout develop” should bring me into my local “develop” branch of WISDEM (I guess that I have worked in the master branch so far…).  
Then, “git pull” should merge all the changes present in the remote “develop” branch to my local “develop” branch leaving untouched my master branch files. Is this correct? i want to be sure of this because I have modified some of the WISDEM codes, and do not want them to be accidentally overwritten/rolled-back.

I am using WISDEM via an anaconda environment, and have git available in this environment, so I will issue those commands from there.  
Now, once the “develop” branches’ merge is done, do I simply re-issue

> [@](#):
>
> wisdem BAR0.yaml modeling\_options.yaml analysis\_options\_struct.yaml

from my wisdem environment to run the example on the updated files?  
Do I need to issue “git checkout master” to come back to and work in my master branch?

I am on a Windows 10 machine.

Thank you for your patience.

---

<div class="post-metadata">

**Author:** ![Garrett.Barter](https://avatars.discourse-cdn.com/v4/letter/g/958977/32.png) [@Garrett.Barter](https://forums.nlr.gov/u/Garrett.Barter)\
**Post date:** [August 31, 2021, 2:24am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/4 "2021-08-31T02:24:18Z")

</div>

Yes, your description of the git commands is accurate. Git will never overwrite your changes without giving you ample warnings, so not to worry. If you want to be doubly cautious, you can always create a new conda environment that installs a separate WISDEM checkout that points to the develop branch.

---

<div class="post-metadata">

**Author:** ![Henny.Bottini](https://dub1.discourse-cdn.com/nrel/user_avatar/forums.nlr.gov/henny.bottini/32/3236_2.png) [@Henny.Bottini](https://forums.nlr.gov/u/Henny.Bottini)\
**Post date:** [September 1, 2021, 4:41am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/5 "2021-09-01T04:41:01Z")

</div>

I have re-run the simple structural optimization example with the following updated files:

> [@](#):
>
> BAR0.yaml  
> analysis\_options\_struct.yaml  
> modeling\_options.yaml  
> compare\_designs.py

and I had to add as well

> [@](#):
>
> wisdem\_get.py

to my wsidem\postprocessing folder.  
The optimization is succesfull (with max\_iter=20), and I get the spar cap thickness vs blade non-dim span plot showing difference between the baseline and the optimized case (see sc\_opt.png attachment).  
Thank you for your prompt action on this.

I also re-run the simple aerodynamic optimization case with the updated files and

> [@](#):
>
> analysis\_options\_aero.yaml

instead of

> [@](#):
>
> analysis\_options\_struct.yaml

The optimization failed again (as per message on the command line at the end of the run), but now I get also the twist vs non-dimensional blade span plot showing differences between the baseline case and the optimized case (see attachment twist\_opt.png).

Finally, I run the aero-structural optimization case as well with

> [@](#):
>
> analysis\_options\_aerostruct.yaml

and the updated files, but it fails.

May I have some clues on how to succeed in the aerodynamic and aero-structural optimization cases, which are, actually, the ones I am mostly interested in now?

Thank you again for your support  
 ![twist_opt.png](https://europe1.discourse-cdn.com/nrel/original/2X/3/381fe311126b10c81801e519c3c654896343fd69.png)  
 ![sc_opt.png](https://europe1.discourse-cdn.com/nrel/original/2X/8/861ac93b2e8cf5252a81737fb019c91a469366cf.png)

---

<div class="post-metadata">

**Author:** ![Garrett.Barter](https://avatars.discourse-cdn.com/v4/letter/g/958977/32.png) [@Garrett.Barter](https://forums.nlr.gov/u/Garrett.Barter)\
**Post date:** [September 2, 2021, 4:25pm UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/6 "2021-09-02T16:25:01Z")

</div>

You are treading into the area where optimization becomes an art as much of a science. I would suggest adjusting finite difference step sizes, central/forward methods, experimenting with different optimizers, experimenting with different objectives (e.g. blade mass instead of LCOE), slowly adding constraints one-by-one to prior solutions, etc. Usually launching into the full optimization leads to poorly posed problems for the optimizers.

---

<div class="post-metadata">

**Author:** ![Henny.Bottini](https://dub1.discourse-cdn.com/nrel/user_avatar/forums.nlr.gov/henny.bottini/32/3236_2.png) [@Henny.Bottini](https://forums.nlr.gov/u/Henny.Bottini)\
**Post date:** [September 3, 2021, 5:19am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/7 "2021-09-03T05:19:44Z")

</div>

thank you for your suggestions.  
I will try them and report on the results.

---

<div class="post-metadata">

**Author:** ![Henny.Bottini](https://dub1.discourse-cdn.com/nrel/user_avatar/forums.nlr.gov/henny.bottini/32/3236_2.png) [@Henny.Bottini](https://forums.nlr.gov/u/Henny.Bottini)\
**Post date:** [September 8, 2021, 1:44am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/8 "2021-09-08T01:44:04Z")

</div>

The aerodynamic optimization case succeded with just the following changes in analysis\_options\_aero.yaml:  
max\_iter = 20  
tol = 0.1  
In attachment are the plots of axial induction vs blade span and twist vs blade span. The former is different to the one from the failed case, but the latter is the same as the one from the failed case (see previous posts).  
I also tried tol=0.01, but the optimization failed as for the default value 0.001.

Now, to better understand what I am doing, I would like to ask someone to confirm my understanding of the meaning of those two parameters:

1. max\_iter: according to the documentaion this is the maximum number of major iterations before termination. And I understand this definition as: max\_iter is the maximum number of times the calculation to find the optimum will be attempted before stopping the optimization run and yielding a result; this result can be successful optimization or failed optimization
2. tol: this is tolerance for termination, and I have found also the definition convergence accuracy in the scipy documentation. I understand this as: if the difference between consecutive optimal values of the objective function, found iteration after iteration, is within the tol value, the optimization is considered succesfull and the run is stopped

Thank you.  
 ![induction.png](https://europe1.discourse-cdn.com/nrel/original/2X/c/c97336c850454149eebae6847333c8523f003389.png)  
 ![twist_opt.png](https://europe1.discourse-cdn.com/nrel/original/2X/4/4a29b33c4d13884ed0dce1c15e43600d20c6415e.png)

---

<div class="post-metadata">

**Author:** ![Garrett.Barter](https://avatars.discourse-cdn.com/v4/letter/g/958977/32.png) [@Garrett.Barter](https://forums.nlr.gov/u/Garrett.Barter)\
**Post date:** [September 8, 2021, 11:16am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/9 "2021-09-08T11:16:59Z")

</div>

Your understanding of the options is correct. Those two parameters are linked in that a lower tolerance will usually require more iterations to converge. A vale of tol = 0.1 is a little high for doing a detailed design study, but fine if you just want a short demo optimization.

---

<div class="post-metadata">

**Author:** ![Henny.Bottini](https://dub1.discourse-cdn.com/nrel/user_avatar/forums.nlr.gov/henny.bottini/32/3236_2.png) [@Henny.Bottini](https://forums.nlr.gov/u/Henny.Bottini)\
**Post date:** [September 9, 2021, 7:33am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/10 "2021-09-09T07:33:38Z")

</div>

> [@Garrett.Barter](#):
>
> Your understanding of the options is correct. Those two parameters are linked in that a lower tolerance will usually require more iterations to converge. A vale of tol = 0.1 is a little high for doing a detailed design study, but fine if you just want a short demo optimization.

Thank you Garrett.

The optimization succeded also for tol = 0.05 and 0.02, and both values output the same identical plots and table values.  
Below is the axial induction vs. blade span plot: run\_0 is the baseline case; run\_1 is tol=0.1; run\_2 is tol=0.05; run\_3 is tol=0.02.

The final AEP values are :

- baseline: 24.128 [GWh]
- optimized (tol=0.1): 23.967 [GWh]
- optimized (tol=0.05 and 0.02): 23.975 [GWh]

so the optimized designs show a very slightly lower value of AEP, and this very slight decrease in AEP is also reported in the comment to the example.  
AEP, however, is the figure of merit of the optimization (which, I assume, means the maximization of AEP), so the optimized designs shouldn’t feature an AEP higher than the AEP of the baseline design? In other words, how is the optimization succesfull, if the AEP is not higher than the baseline value?

I realize that I have questions after questions… 😊😒  
Thank you for your patience  
 ![induction.png](https://europe1.discourse-cdn.com/nrel/original/2X/e/ed7a68140a4a97a14ba780fe435687f76957fb95.png)

---

<div class="post-metadata">

**Author:** ![Garrett.Barter](https://avatars.discourse-cdn.com/v4/letter/g/958977/32.png) [@Garrett.Barter](https://forums.nlr.gov/u/Garrett.Barter)\
**Post date:** [September 9, 2021, 10:19am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/11 "2021-09-09T10:19:24Z")

</div>

There are likely constraints that are not fully satisfied in the baseline design that are satisfied in the final designs, just at a higher AEP value. Also, we decreasing the tolerance, try decreasing on a logarithmic scale (1e-2, then 1e-3, etc).

---

<div class="post-metadata">

**Author:** ![Henny.Bottini](https://dub1.discourse-cdn.com/nrel/user_avatar/forums.nlr.gov/henny.bottini/32/3236_2.png) [@Henny.Bottini](https://forums.nlr.gov/u/Henny.Bottini)\
**Post date:** [September 14, 2021, 2:08am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/12 "2021-09-14T02:08:13Z")

</div>

My aerodynamic optimization fails if I decrease the tolerance to 1e-3; the lowest tol I could succeed with is still 0.02.

Regarding the tol value, I’d like to have a further clarification: in this example, is the objective function automatically scaled to an order of magnitude ~1 and the solution algorithm applies the tol value on this scaled value, or there is no scaling?  
In fact, according to my searches tol should be an absolute tolerance, and this should mean that the optimization is succesfull when

> [@](#):
>
> | objFunMinValue\_i+1 - objFunMinValue\_i | \< tol

with i the iteration number.  
Now, if my objective function is AEP or LCoE its value is ~10^1 GWh or $/MWh, so, if there is no scaling, do I really need to go to absolute tolerances of the order of 1e-3 (~1MW and ~0.1 cent $) to have a meaningful optimization result?

Thank you.

---

<div class="post-metadata">

**Author:** ![Garrett.Barter](https://avatars.discourse-cdn.com/v4/letter/g/958977/32.png) [@Garrett.Barter](https://forums.nlr.gov/u/Garrett.Barter)\
**Post date:** [September 14, 2021, 11:49am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/13 "2021-09-14T11:49:58Z")

</div>

You have to increase the number of iterations (sometimes by an order of magnitude) as you lower the convergence tolerance. The tolerance is relative on the scaled quantity.

---

<div class="post-metadata">

**Author:** ![Henny.Bottini](https://dub1.discourse-cdn.com/nrel/user_avatar/forums.nlr.gov/henny.bottini/32/3236_2.png) [@Henny.Bottini](https://forums.nlr.gov/u/Henny.Bottini)\
**Post date:** [October 5, 2021, 2:19am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/14 "2021-10-05T02:19:38Z")

</div>

As suggested in a previous post I removed some constraints and tried the optimization with some more realistic tolerance values.  
As a result the optimization succeded with the following settings:

- constraints:  
-) removed: stall margin  
-) kept: pressure side and suction side spar-caps maximum strain; tip deflection
- max iterations: 20
- tolerance: 1e-3
- twist, chord, spar-caps control points number (n\_opt): 30

So, just removing the constraint on the stall margin made possible the optimization with the optimality tolerance at 1e-3 and 30 control points for the design variables.

However, even setting stall margin as the sole constraint, and keeping the other settings as above, makes the optimization fail. Tried to change the stall margin value, but still failure, so I tried the inverse setting for the design variable twist as follow:

```auto
design_variables:
    rotor_diameter:
        flag: True # False @ 3 Sept 2021 
        minimum: 190
        maximum: 240
    blade:
        aero_shape:
            twist:
                flag: False # Flag to optimize the twist;
                inverse: True # Flag to determine twist from the user-defined desired margin to stall (defined in constraints)
                n_opt: 30 # 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: 4 # All DVs close to blade tip are active
 .
 .
 .
     constraints:
    blade:
        strains_spar_cap_ss:
            flag: False # 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: False # 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: False # True
            margin: 1.4175
        stall:
            flag: True # Constraint on minimum stall margin 
            margin: 0.087 # Value of minimum stall margin in [rad]             
```

and this time the optimization succeded, but, at the very beginning of the calculation I had this warning:

> [@](#):
>
> WARNING: the margin to stall is set to be constrained, but twist is not an active design variable. The constraint is not enforced.

which doesn’t sound as I have set the calculation as I intended…  
The documentation ([https://wisdem.readthedocs.io/en/master/inputs/analysis\_schema.html#constraints](https://wisdem.readthedocs.io/en/master/inputs/analysis_schema.html#constraints)) on the inverse setting, says

> [@](#):
>
> When set to True, the twist is defined inverting the blade-element momentum equations to achieve a desired margin to stall, which is defined among the constraints. flag and inverse cannot simultaneously be set to True

which is why I set the twist flag to False, and inverse to True.  
I think I am mistaking the inverse setting: how should I set it correctly and have the stall margin constraint enforced?

Thank you in advance

---

<div class="post-metadata">

**Author:** ![Garrett.Barter](https://avatars.discourse-cdn.com/v4/letter/g/958977/32.png) [@Garrett.Barter](https://forums.nlr.gov/u/Garrett.Barter)\
**Post date:** [October 5, 2021, 3:10am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/15 "2021-10-05T03:10:37Z")

</div>

When the optimization says “failed”, it means it did not converge. You need to adjust tolerances, iterations, constraint values, design variable bounds, and the solver to coax the optimization to converge. There is no magic recipe I can give you that will work for every problem. That is the art of optimization.

You are not doing an inverse design problem, so leave inverse=False.

---

<div class="post-metadata">

**Author:** ![Henny.Bottini](https://dub1.discourse-cdn.com/nrel/user_avatar/forums.nlr.gov/henny.bottini/32/3236_2.png) [@Henny.Bottini](https://forums.nlr.gov/u/Henny.Bottini)\
**Post date:** [October 12, 2021, 2:29am UTC](https://forums.nlr.gov/t/wisdem-blade-optimization-example-my-output-plot-not-like-in-the-example/2530/16 "2021-10-12T02:29:32Z")

</div>

I succeded in running the optimization with:

- tol=1e-3
- n\_opt=30 for the design variables chord, twist, and spar caps
- max\_iter=100
- constraints: max strain on spar\_cap\_ss and spar\_cap\_ps; tip deflection; stall  
And inverse= False .

The reason of the failure was that I did not update the index\_end setting for the design variables when I increased n\_opt from 4 to 30.

Thank you Garret for your constant support.
