1

I have the following function (Class Shape Transformation):

cst[wl, wu, dz]

where wl and wu are lists of undefined length:

wl = {wl1, wl2, wl3, ... }

wu = {wu1, wu2, wu3, ... }

and the elements of these lists are all real numbers varying from 0 to 1; and dz is another real number.

n = 100;
n1 = 0.5; n2 = 1;
z = ConstantArray[0, n + 1];
x = ConstantArray[1, n + 1];
For[i = 1, i < n + 1, i++; 
  z[[i]] = 2 Pi / n (i - 1); 
  x[[i]] = 0.5 (Cos[z[[i]]] + 1 )];
ind0 = Position[x, 0. ]; 
a = ind0[[1]] - 1; 
xl = Take[x, a[[1]]]; 
xu = Flatten[List[0, Take[x, -a[[1]]]]];
class[x_] := x^n1 (1 - x)^n2;
nw[w_] := Length[w] - 1;
shape[w_, x_] := Sum[BernsteinBasis[nw[w], j - 1, x] w[[j]], {j, nw[w] + 1}];
y[w_, x_, dz_] := class[x] shape[w, x] + x dz;
cst[wl_, wu_, dz_] := Transpose[{x, Flatten[{y[wl, xl, -dz], y[wu, xu, dz]}]}];

I would like to manipulate wl and wu elements with a 0 to 1 range, specifying their lengths together with dz with a menu. I tried something like this, but it didn't work out:

Manipulate[
  ListPlot[cst[wl, wu, dz]], 
  {{wu[[1]], 0, 0.1, 1}, ...}, 
  {{wl[[1]], 0, 0.1, 1}, ...}, 
  {nu, Length[wl]}, 
  {nl, Length[wu]}, 
  {dz}, ControlType -> {PopupMenu}]

This is an example of how cst fuctio works, as suggested by Goldberg.

dz = 0.0002;
wu = {0.19, 0.20, 0.29, 0.27, 0.31, 0.16};
wl = {-0.12, -0.13, -0.14, -0.16, -0.15, 0.1};

The output with a plot would be:

ListPlot[cst[wl, wu, dz]]

enter image description here

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
Mirko Aveta
  • 2,192
  • 11
  • 26
  • 1
    ...I don't see a definition for cst anywhere. – J. M.'s missing motivation Apr 21 '16 at 13:18
  • I've just added the definition, thank you. If anyone is interested it's a code for Brenda Kulfan's Class Shape Transformation (CST). – Mirko Aveta Apr 21 '16 at 13:22
  • 1
    The first thing you should do is get the code you wrote to provide the constructs to be manipulated working. What you show in your post does not work and must be fixed before it is reasonable to attempt interacting with it. For instance, x and z have fixed lengths n + 1, so n must be specified, but you don't do that. You give For three arguments, but it requires four. Until you correct these simple errors, I don't think there is much we do to help you build your interactive code. – m_goldberg Apr 21 '16 at 13:57
  • I beg your pardon, you're right. I forgot to insert n. The rest should work. You may verify, plotting: ListPlot[cst[wl, wu, dz]] – Mirko Aveta Apr 21 '16 at 13:58
  • Your code won't work when n is an odd number. But you don't say anything about the parity of n. Do you have a policy for handling odd n? – m_goldberg Apr 21 '16 at 22:05
  • Please give an example of a call to cst and that gives a result you know to be correct and that we can use when working with your code. I'm asking for this because I am having trouble finding any set of arguments that I can give to cst that doesn't produce an error. – m_goldberg Apr 21 '16 at 22:42
  • Yes. Will add quickly. – Mirko Aveta Apr 22 '16 at 07:33
  • Yes @m_goldberg the code works only with n not being an odd umber. It has to be even because half of the points must be on the upper surface and the other half in the lower. Thaks for pointing this out. – Mirko Aveta Apr 22 '16 at 07:41
  • 1
    Thanks for the update. I now believe I understand what you trying to accomplish. You want to be able to manipulate the shape of an airfoil, right? I have some ideas. If you hang in for a little while, I will be back a proposal on how a Manipulate might work. Meanwhile, I will post an interim answer that will let look at shape variations fairly easily without using Manipulate. – m_goldberg Apr 22 '16 at 15:27

1 Answers1

2

Here is some code that will let you vary the shape you are rendering fairly easily but does not use Manipulate. It might be useful to you in the short term. I will put more work in this problem, and try to build a useful interactive version with Manipulate. I will update this answer when I have such code.

With[{n = 100},
  z = Subdivide[0, 2 Pi, n];
  x = .5 (1 + Cos[#]) & /@ z;
  {xl, xu} = TakeDrop[x, n/2];]

With[{n1 = .5, n2 = 1.}, class[x_] := x^n1 (1 - x)^n2]

shape[w_, x_] := With[{n = Length[w]}, Sum[BernsteinBasis[n - 1, j - 1, x] w[[j]], {j, n}]] y[w_, x_, dz_] := class[x] shape[w, x] + x dz cst[wl_, wu_, dz_] := Transpose[{x, Flatten[{y[wl, xl, -dz], y[wu, xu, dz]}]}]

Note that the above code simplifies and speeds up the computation of x, xu and xl.

I recommend expressing the plot within a With expression that assigns the parameters.

With[
  {dz = 0.0002,
   wup = {.19, .20, .29, .27, .31, .16},
   wlo = {-.12, -.13, -.14, -.16, -.15, .1}},
  ListPlot[cst[wlo, wup, dz]]]

plot-1

Using With makes it easy to specify a new design by simply editing the parameter definitions. For example,

With[
  {dz = 0.0005,
   wup = {.19, .21, .29, .27, .3, .2, .1},
   wlo = {-.12, -.13, -.14, -.16, -.15, -.2, -.1}},
  ListPlot[cst[wlo, wup, dz]]]

plot-2

This is not too bad a way to explore the design space, even if it is not as sexy as interactive manipulation.

Update

Here is an interactive version. It's pretty simple but I think it is usable. I decided that inputs fields would be an easy and simple way to get the user's inputs. Input fields are something everyone can be expected to understand, but have the disadvantage of being hard to make bullet-proof. I implemented only a minimum of input checking — just enough to give a hint of how it might done. I think implementing elaborate input checking is out of scope for this question. I leave it as an exercise to the reader.

I only show the new code. Everything else is as it was before.

test = List[RepeatedNull[_Real?(Between[#, {-1., 1.}] &)]];
badParamMsg = 
  "one of the inputs, w-upper, w-lower or dz, is invalid";
okMsg = Invisible[
   "one of the inputs, w-upper, w-lower or dz, is invalid"];

Manipulate[ If[MatchQ[wlo, test] && MatchQ[wup, test] && MatchQ[dz, _Real], pts = cst[wlo, wup, dz]; msg = okMsg, pts = {}; msg = badParamMsg]; Column[ {ListPlot[pts, Frame -> True, ImageSize -> {500, Automatic}], Style[Row[{"Message ", Framed[msg]}], "SR", 11]}, Center], {{wup, {.19, .21, .29, .27, .3, .2, .1}, "w-upper"}, InputField, ImageSize -> {500, Automatic}}, {{wlo, {-.12, -.13, -.14, -.16, -.15, -.2, -.1}, "w-lower"}, InputField, ImageSize -> {500, Automatic}}, {{dz, .0002, "dz"}, InputField, ImageSize -> {50, Automatic}}, {{pts, {}}, None}, {{msg, okMsg}, None}, TrackedSymbols :> {wlo, wup, dz}, SaveDefinitions -> True]

interactive

To get a edit to an input field recognized, you must Tab out of the field. Do not press Return — that will result in a new Manipulate panel being generated.

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
  • There is still an issue here. The lengths of the wup and wlow don't necessarily have to be the same. The only restriction given is to the parameter n (needs to be an even number), yet we have considered it constant. – Mirko Aveta Apr 23 '16 at 06:26
  • Indeed, the length of these vectors assign the complexity of the polynomials and therefore of the shape of the upper and lower lines of the airfoil. It may be possible that such complexity may differ between upper and lower lines. Often lower lines are more complex than upper. – Mirko Aveta Apr 23 '16 at 06:32
  • I've made your code plot the airfoil even under this condition. – Mirko Aveta Apr 23 '16 at 06:37
  • 1
    @MirkoAveta. My bad. I was only trying show how simple input validation might work. I have corrected the Manipulate code to use a somewhat more complex, but more useful, test. It now permits wlo and wup to vary independently, as you see from the new image. – m_goldberg Apr 23 '16 at 07:22