Closed rebeccamccabe closed 6 months ago
The residual (dynamic equations) is small, but the dynamics are wrong. I am thinking is this an issue with scaling.
Possible solution:
The spikiness originates from the imaginary part of the last frequency component... I don't know why the solver converges to have content there in x_opt. When artificially removing the very last component we get what we'd expect:
x_opt[-1] = 0
x_wec[-1] = 0
res_artificial = results[0]
res_artificial.x = np.concatenate([x_wec, x_opt])
res_wec_fd, res_wec_td = wec.post_process(res_artificial,wave,nsubsteps=nsubsteps)
res_pto_fd, res_pto_td = pto.post_process(wec,res_artificial,wave,nsubsteps=nsubsteps)
plt.figure()
res_wec_td.pos.plot()
res_wec_td.vel.plot()
res_wec_td.acc.plot()
res_pto_td.force.plot()
res_pto_td.power.sel(type='elec').plot.line('--',x='time')
plt.legend([res_wec_td.pos.long_name, res_wec_td.vel.long_name,
res_wec_td.acc.long_name, res_pto_td.force.long_name,
res_pto_td.power.long_name])
might be related to #225?
This is not a bug. If you use average mechanical power as the objective function, an unstructured controller, and no constraints, then the Nyquist component of the PTO force and the WEC position is arbitrary. This is the high frequency component you are observing. If you re-run this case you should see a different magnitude for it each time. The Nyquist component of the velocity is zero which is why you don't see the high frequency oscillations.
@dtgaebe and I wrote this up showing that these components are arbitrary in this case: Power_last_frequency.pdf. We are also documenting this in #225 and closing it.
The Nyquist component of the velocity is zero which is why you don't see the high frequency oscillations.
Does this mean that acceleration is not expected to match the derivative of velocity? If I want them to match, would I need to redefine the derivative matrix so that the second derivative is phase shifted 90°?
Correct, the acceleration does not match the derivative of the velocity at the Nyquist frequency. There is no way of making position-velocity-acceleration consistent at the Nyquist frequency. However if you truncate your Fourier expansion at a high enough frequency, the Nyquist component should not be significant. The problem here is that for this specific problem the Nyquist component is arbitrary and can be quiet large. The best option if you want to use average mechanical power as the objective and an unstructured controller might be to constraint the Nyquist components to be equal to zero. Here is more info on FFT-based differentiation.
Describe the bug There are some combinations of inputs (I haven't been fully systematic but it seems like it happens when there are no user defined constraints and I'm optimizing for mechanical not electrical power) that create strange high frequency oscillations in the force and acceleration signals, while the position and velocity signals do not have these oscillations. The existence of the spiky oscillations is a minor annoyance, but the bigger problem is that the velocity and acceleration are inconsistent (derivative condition not adequately enforced), even though the residual to the dynamics equality constraint is quite small.
To Reproduce
Observed behavior Run code as-is:
The optimization converges and the residual is small, but the discrepancy between velocity and acceleration is a problem. I also plotted the three component forces, and the excitation force is smooth, while the PTO and intrinsic impedance forces have the spikes.
Also, this version is very sensitive to initial conditions, and using a different x0 results in a different (still spiky and still not obeying dynamics) solution:
Run code with
obj_fun = pto.average_power
: So optimizing for electrical power apparently solves the problem.Run code with
f_max = np.array( [0.94] )
So adding a force limit also apparently solves the problem.Expected behavior When optimizing only for mechanical power with no force limit, I think that it is actually perhaps expected to have high frequency force harmonics in the PTO force, because there is nothing in the objective preventing the controller from applying them (they do not affect power). They would only go away when optimizing for electrical power, since the extra unnecessary motion would add dissipation and reduce power, or when there is a force constraint since the extra amplitude would violate the constraints. So the problem is not the presence of the spikes, but the fact that the spikes are not present in the velocity and position waveforms, indicating that the
dv/dt = a
portion of the dynamics is not being properly enforced, whileF=ma
seems to be fine.Separately, if we wanted to get rid of the spikes, perhaps it makes sense to add a tiny norm of PTO force harmonics term to the
pto.mechanical_average_power
objective function, scaled such that it will have negligible effect on results and just will ensure that the additional high frequency harmonics don't occur when optimizing mechanical power. I did observe that the frequency of the spikes increases when I increasenfreq
, so maybe it is only the highest harmonic where these oscillations occur.System:
main
branch at 598e875cd48751ddb652657391205f6e208714f0