DESC icon indicating copy to clipboard operation
DESC copied to clipboard

Ideas to make `ProximalProjection` more robust

Open f0uriest opened this issue 1 year ago • 9 comments
trafficstars

Right now we still have cases where the proximal optimizer keeps trying smaller and smaller steps until eventually it quits saying Warning: A bad approximation caused failure to predict improvement.

This seems to be due to inconsistent linearizations or a possibly instability, where small changes in the boundary (the x variable the optimizer sees) lead to large changes in the volume (the f values the optimizer sees).

Some possible ideas to make this better:

  • Have some "patience" criteria, where if the perturb/solve stuff doesn't find an acceptable step in N steps, we go back and do a full continuation solve.
  • Have some check on the step size in both boundary and volume and reject steps if the ratio is too large.
  • Use the 2nd order perturbations to do the above, where we reject a step if the 2nd order correction is larger than some fraction of the first order step (similar to geodesic acceleration).
  • If several attempts don't find an acceptable step, return a smaller function value to force it to accept a "bad" step in the hopes that linearizing around the new point will be better.

f0uriest avatar Dec 12 '23 01:12 f0uriest

Case for a precise-QA-like equilibrium in free boundary, each step in the proximal just gives a bad approximation, files are here: https://drive.google.com/drive/folders/19-F7cVb1yxks42eCI1Nx7DlxjCkyxaaf?usp=drive_link

dpanici avatar Apr 29 '24 18:04 dpanici

@dpanici check thru notebooks and link here along with current commit that it occurs at

dpanici avatar Aug 20 '24 19:08 dpanici

  • https://desc-docs--1189.org.readthedocs.build/en/1189/notebooks/tutorials/free_boundary_equilibrium.html#Solovev-Tokamak SOLOVEV free bdry (on PR #1189 )
  • https://desc-docs--1189.org.readthedocs.build/en/1189/notebooks/tutorials/advanced_optimization.html#Multigrid-method-with-proximal-optimizer QH proximal optimization (again on #1189 )

dpanici avatar Aug 21 '24 15:08 dpanici

Something I have seen in a case where I get a bad approx error is when the eq subproblem default xtol=1e-6 is actually a larger xtol than the outer optimization loop's xtol (in my case I had it at like 1e-8), obviously this is stupid on my part as I don't let the eq change by the same size steps I allow the outer optimizer to take, but imo this can be easy to forget. Maybe we could change the default eq subproblem ftol and xtol to match the outer optimizer's, if it the optimizer has tighter tolerances?

(I have not tested that tightening the xtol fixes the bad approx yet, doing it now, but I suspect it should)

I also have not tested with #1073 though which maybe would help in this case?

dpanici avatar Nov 20 '24 20:11 dpanici

Try setting ftol=xtol=0 in subproblem, and only allow inner problem to end on gtol

dpanici avatar Feb 10 '25 19:02 dpanici

Another approach can be to apply the perturbation in multiple steps, (so first try normal 1 step, if the force error is not in the appropriate range, then use 2 3 steps). Also, I think we should have a default for ftol since it is assumed 0 in the later steps. What I mean is, set solve_option["ftol"]=1e-5 always, and to prevent early termination due to gtol or xtol set them 0. Make sure that the result is actually a good equilibrium.

If the multi-step perturbation approach doesn't work, instead of having a automatic_continuation we can use eq.solve, by initialising a new equilibrium with the surface. automatic_continuation is a lot slower and I don't think that level of force balance is needed for each step of the optimization. eq.solve is fast and compared to perturb method, it starts with nested flux surfaces. The thing is, our current method uses previous equilibrium as warm start but when the boundary changes, it automatically becomes un-nested like,

Image

This is exaggerated but in a nutshell, this is what is happening. Fresh initialised eq is at least nested and has lower error.

For finite-beta case, we can try a new initial guess with Shafranov shift. I don't know what is the best approach but maybe find geometric center axis, shift it and then use initial_guess with surface and axis

YigitElma avatar Mar 13 '25 06:03 YigitElma

We can also try seting tr_ratio differently from the default 0.1 when doing perturb. I find in some cases where larger steps are taken that it can be helpful to try different combinations of ratios, like [0.2, 0.15] instead (for 2nd order)

dpanici avatar Mar 21 '25 17:03 dpanici